History

af_drc: remove

Remove low quality drc filter. Anyone whishing to have dynamic range compression should use the much more powerful acompressor ffmpeg filter: mpv --af=lavfi=[acompressor] INPUT Or with parameters: mpv --af=lavfi=[acompressor=threshold=-25dB:ratio=3:makeup=8dB] INPUT Refer to https://ffmpeg.org/ffmpeg-filters.html#acompressor for a full list of supported parameters.

Jan Janssen committed 9 years ago

Commit 222899f1 parent d663a0e7 files · +2 −460Browse files

Unified · Split

7 files
  1. DOCS/interface-changes.rst +1 −0
  2. DOCS/man/af.rst +0 −23
  3. DOCS/mplayer-changes.rst +1 −1
  4. TOOLS/lua/drc-control.lua +0 −99
  5. audio/filter/af.c +0 −2
  6. audio/filter/af_drc.c +0 −334
  7. wscript_build.py +0 −1
DOCS/interface-changes.rst+1−0
@@ -25,6 +25,7 @@ Interface changes · 24 unmodified lines
2525 - remove ppm, pgm, pgmyuv, tga choices from the --screenshot-format and
2626 --vo-image-format options
2727 - the "jpeg" choice in the option above now leads to a ".jpg" file extension
28+ - --af=drc is gone (you can use e.g. lavfi/acompressor instead)
2829 --- mpv 0.24.0 ---
2930 - deprecate --hwdec-api and replace it with --opengl-hwdec-interop.
3031 The new option accepts both --hwdec values, as well as named backends.
DOCS/man/af.rst+0−23
@@ -319,29 +319,6 @@ Available filters are: · 318 unmodified lines
319319 the mixing matrix at runtime, without reinitializing the entire filter
320320 chain.
321321
322−``drc[=method:target]``
323− Applies dynamic range compression. This maximizes the volume by compressing
324− the audio signal's dynamic range. (Formerly called ``volnorm``.)
325−
326− ``<method>``
327− Sets the used method.
328−
329− 1
330− Use a single sample to smooth the variations via the standard
331− weighted mean over past samples (default).
332− 2
333− Use several samples to smooth the variations via the standard
334− weighted mean over past samples.
335−
336− ``<target>``
337− Sets the target amplitude as a fraction of the maximum for the sample
338− type (default: 0.25).
339−
340− .. note::
341−
342− This filter can cause distortion with audio signals that have a very
343− large dynamic range.
344−
345322 ``scaletempo[=option1:option2:...]``
346323 Scales audio tempo without altering pitch, optionally synced to playback
347324 speed (default).
DOCS/mplayer-changes.rst+1−1
@@ -212,7 +212,7 @@ Command Line Switches · 211 unmodified lines
212212 ``-no<opt>`` ``--no-<opt>`` (add a dash)
213213 ``-a52drc level`` ``--ad-lavc-ac3drc=level``
214214 ``-ac spdifac3`` ``--ad=spdif:ac3`` (see ``--ad=help``)
215− ``-af volnorm`` ``--af=drc`` (renamed)
215+ ``-af volnorm`` (removed; use acompressor ffmpeg filter instead)
216216 ``-afm hwac3`` ``--ad=spdif:ac3,spdif:dts``
217217 ``-ao alsa:device=hw=0.3`` ``--ao=alsa:device=[hw:0,3]``
218218 ``-aspect`` ``--video-aspect``
TOOLS/lua/drc-control.lua+0−99
@@ -1,99 +0,0 @@
1−-- This script enables live control of the dynamic range compression
2−-- (drc) audio filter while the video is playing back. This can be
3−-- useful to avoid having to stop and restart mpv to adjust filter
4−-- parameters. See the entry for "drc" under the "AUDIO FILTERS"
5−-- section of the man page for a complete description of the filter.
6−--
7−-- This script registers the key-binding "\" to toggle the filter between
8−--
9−-- * off
10−-- * method=1 (single-sample smoothing)
11−-- * method=2 (multi-sample smoothing)
12−--
13−-- It registers the keybindings ctrl+9/ctrl+0 to decrease/increase the
14−-- target ampltiude. These keys will insert the filter at the default
15−-- target amplitude of 0.25 if it was not previously present.
16−--
17−-- OSD feedback of the current filter state is displayed on pressing
18−-- each bound key.
19−
20−script_name = mp.get_script_name()
21−
22−function print_state(params)
23− if params then
24− mp.osd_message(script_name..":\n"
25− .."method = "..params["method"].."\n"
26− .."target = "..params["target"])
27− else
28− mp.osd_message(script_name..":\noff")
29− end
30−end
31−
32−function get_index_of_drc(afs)
33− for i,af in pairs(afs) do
34− if af["label"] == script_name then
35− return i
36− end
37− end
38−end
39−
40−function append_drc(afs)
41− afs[#afs+1] = {
42− name = "drc",
43− label = script_name,
44− params = {
45− method = "1",
46− target = "0.25"
47− }
48− }
49− print_state(afs[#afs]["params"])
50−end
51−
52−function modify_or_create_af(fun)
53− afs = mp.get_property_native("af")
54− i = get_index_of_drc(afs)
55− if not i then
56− append_drc(afs)
57− else
58− fun(afs, i)
59− end
60− mp.set_property_native("af", afs)
61−end
62−
63−function drc_toggle_method_handler()
64− modify_or_create_af(
65− function (afs, i)
66− new_method=(afs[i]["params"]["method"]+1)%3
67− if new_method == 0 then
68− table.remove(afs, i)
69− print_state(nil)
70− else
71− afs[i]["params"]["method"] = tostring((afs[i]["params"]["method"])%2+1)
72− print_state(afs[i]["params"])
73− end
74− end
75− )
76−end
77−
78−function drc_scale_target(factor)
79− modify_or_create_af(
80− function (afs)
81− afs[i]["params"]["target"] = tostring(afs[i]["params"]["target"]*factor)
82− print_state(afs[i]["params"])
83− end
84− )
85−end
86−
87−function drc_louder_handler()
88− drc_scale_target(2.0)
89−end
90−
91−function drc_quieter_handler()
92− drc_scale_target(0.5)
93−end
94−
95−-- toggle between off, method 1 and method 2
96−mp.add_key_binding("\\", "drc_toggle_method", drc_toggle_method_handler)
97−-- increase or decrease target volume
98−mp.add_key_binding("ctrl+9", "drc_quieter", drc_quieter_handler)
99−mp.add_key_binding("ctrl+0", "drc_louder", drc_louder_handler)
audio/filter/af.c+0−2
@@ -36,7 +36,6 @@ extern const struct af_info af_info_format; · 35 unmodified lines
3636 extern const struct af_info af_info_volume;
3737 extern const struct af_info af_info_equalizer;
3838 extern const struct af_info af_info_pan;
39−extern const struct af_info af_info_drc;
4039 extern const struct af_info af_info_lavcac3enc;
4140 extern const struct af_info af_info_lavrresample;
4241 extern const struct af_info af_info_scaletempo;
@@ -50,7 +49,6 @@ static const struct af_info *const filter_list[] = { · 7 unmodified lines
5049 &af_info_volume,
5150 &af_info_equalizer,
5251 &af_info_pan,
53− &af_info_drc,
5452 &af_info_lavcac3enc,
5553 &af_info_lavrresample,
5654 #if HAVE_RUBBERBAND
audio/filter/af_drc.c+0−334
@@ -1,334 +0,0 @@
1−/*
2− * Copyright (C) 2004 Alex Beregszaszi & Pierre Lombard
3− *
4− * This file is part of mpv.
5− *
6− * mpv is free software; you can redistribute it and/or modify
7− * it under the terms of the GNU General Public License as published by
8− * the Free Software Foundation; either version 2 of the License, or
9− * (at your option) any later version.
10− *
11− * mpv is distributed in the hope that it will be useful,
12− * but WITHOUT ANY WARRANTY; without even the implied warranty of
13− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14− * GNU General Public License for more details.
15− *
16− * You should have received a copy of the GNU General Public License along
17− * with mpv. If not, see <http://www.gnu.org/licenses/>.
18− */
19−
20−#include <stdio.h>
21−#include <stdlib.h>
22−#include <string.h>
23−
24−#include <inttypes.h>
25−#include <math.h>
26−#include <limits.h>
27−
28−#include "common/common.h"
29−#include "af.h"
30−
31−// Methods:
32−// 1: uses a 1 value memory and coefficients new=a*old+b*cur (with a+b=1)
33−// 2: uses several samples to smooth the variations (standard weighted mean
34−// on past samples)
35−
36−// Size of the memory array
37−// FIXME: should depend on the frequency of the data (should be a few seconds)
38−#define NSAMPLES 128
39−
40−// If summing all the mem[].len is lower than MIN_SAMPLE_SIZE bytes, then we
41−// choose to ignore the computed value as it's not significant enough
42−// FIXME: should depend on the frequency of the data (0.5s maybe)
43−#define MIN_SAMPLE_SIZE 32000
44−
45−// mul is the value by which the samples are scaled
46−// and has to be in [MUL_MIN, MUL_MAX]
47−#define MUL_INIT 1.0
48−#define MUL_MIN 0.1
49−#define MUL_MAX 5.0
50−
51−// Silence level
52−// FIXME: should be relative to the level of the samples
53−#define SIL_S16 (SHRT_MAX * 0.01)
54−#define SIL_FLOAT 0.01
55−
56−// smooth must be in ]0.0, 1.0[
57−#define SMOOTH_MUL 0.06
58−#define SMOOTH_LASTAVG 0.06
59−
60−#define DEFAULT_TARGET 0.25
61−
62−// Data for specific instances of this filter
63−typedef struct af_volume_s
64−{
65− int method; // method used
66− float mul;
67− // method 1
68− float lastavg; // history value of the filter
69− // method 2
70− int idx;
71− struct {
72− float avg; // average level of the sample
73− int len; // sample size (weight)
74− } mem[NSAMPLES];
75− // "Ideal" level
76− float mid_s16;
77− float mid_float;
78−}af_drc_t;
79−
80−// Initialization and runtime control
81−static int control(struct af_instance* af, int cmd, void* arg)
82−{
83− switch(cmd){
84− case AF_CONTROL_REINIT:
85− // Sanity check
86− if(!arg) return AF_ERROR;
87−
88− mp_audio_force_interleaved_format((struct mp_audio*)arg);
89− mp_audio_copy_config(af->data, (struct mp_audio*)arg);
90−
91− if(((struct mp_audio*)arg)->format != (AF_FORMAT_S16)){
92− mp_audio_set_format(af->data, AF_FORMAT_FLOAT);
93− }
94− return af_test_output(af,(struct mp_audio*)arg);
95− }
96− return AF_UNKNOWN;
97−}
98−
99−static void method1_int16(af_drc_t *s, struct mp_audio *c)
100−{
101− register int i = 0;
102− int16_t *data = (int16_t*)c->planes[0]; // Audio data
103− int len = c->samples*c->nch; // Number of samples
104− float curavg = 0.0, newavg, neededmul;
105− int tmp;
106−
107− for (i = 0; i < len; i++)
108− {
109− tmp = data[i];
110− curavg += tmp * tmp;
111− }
112− curavg = sqrt(curavg / (float) len);
113−
114− // Evaluate an adequate 'mul' coefficient based on previous state, current
115− // samples level, etc
116−
117− if (curavg > SIL_S16)
118− {
119− neededmul = s->mid_s16 / (curavg * s->mul);
120− s->mul = (1.0 - SMOOTH_MUL) * s->mul + SMOOTH_MUL * neededmul;
121−
122− // clamp the mul coefficient
123− s->mul = MPCLAMP(s->mul, MUL_MIN, MUL_MAX);
124− }
125−
126− // Scale & clamp the samples
127− for (i = 0; i < len; i++)
128− {
129− tmp = s->mul * data[i];
130− tmp = MPCLAMP(tmp, SHRT_MIN, SHRT_MAX);
131− data[i] = tmp;
132− }
133−
134− // Evaluation of newavg (not 100% accurate because of values clamping)
135− newavg = s->mul * curavg;
136−
137− // Stores computed values for future smoothing
138− s->lastavg = (1.0 - SMOOTH_LASTAVG) * s->lastavg + SMOOTH_LASTAVG * newavg;
139−}
140−
141−static void method1_float(af_drc_t *s, struct mp_audio *c)
142−{
143− register int i = 0;
144− float *data = (float*)c->planes[0]; // Audio data
145− int len = c->samples*c->nch; // Number of samples
146− float curavg = 0.0, newavg, neededmul, tmp;
147−
148− for (i = 0; i < len; i++)
149− {
150− tmp = data[i];
151− curavg += tmp * tmp;
152− }
153− curavg = sqrt(curavg / (float) len);
154−
155− // Evaluate an adequate 'mul' coefficient based on previous state, current
156− // samples level, etc
157−
158− if (curavg > SIL_FLOAT) // FIXME
159− {
160− neededmul = s->mid_float / (curavg * s->mul);
161− s->mul = (1.0 - SMOOTH_MUL) * s->mul + SMOOTH_MUL * neededmul;
162−
163− // clamp the mul coefficient
164− s->mul = MPCLAMP(s->mul, MUL_MIN, MUL_MAX);
165− }
166−
167− // Scale & clamp the samples
168− for (i = 0; i < len; i++)
169− data[i] *= s->mul;
170−
171− // Evaluation of newavg (not 100% accurate because of values clamping)
172− newavg = s->mul * curavg;
173−
174− // Stores computed values for future smoothing
175− s->lastavg = (1.0 - SMOOTH_LASTAVG) * s->lastavg + SMOOTH_LASTAVG * newavg;
176−}
177−
178−static void method2_int16(af_drc_t *s, struct mp_audio *c)
179−{
180− register int i = 0;
181− int16_t *data = (int16_t*)c->planes[0]; // Audio data
182− int len = c->samples*c->nch; // Number of samples
183− float curavg = 0.0, newavg, avg = 0.0;
184− int tmp, totallen = 0;
185−
186− for (i = 0; i < len; i++)
187− {
188− tmp = data[i];
189− curavg += tmp * tmp;
190− }
191− curavg = sqrt(curavg / (float) len);
192−
193− // Evaluate an adequate 'mul' coefficient based on previous state, current
194− // samples level, etc
195− for (i = 0; i < NSAMPLES; i++)
196− {
197− avg += s->mem[i].avg * (float)s->mem[i].len;
198− totallen += s->mem[i].len;
199− }
200−
201− if (totallen > MIN_SAMPLE_SIZE)
202− {
203− avg /= (float)totallen;
204− if (avg >= SIL_S16)
205− {
206− s->mul = s->mid_s16 / avg;
207− s->mul = MPCLAMP(s->mul, MUL_MIN, MUL_MAX);
208− }
209− }
210−
211− // Scale & clamp the samples
212− for (i = 0; i < len; i++)
213− {
214− tmp = s->mul * data[i];
215− tmp = MPCLAMP(tmp, SHRT_MIN, SHRT_MAX);
216− data[i] = tmp;
217− }
218−
219− // Evaluation of newavg (not 100% accurate because of values clamping)
220− newavg = s->mul * curavg;
221−
222− // Stores computed values for future smoothing
223− s->mem[s->idx].len = len;
224− s->mem[s->idx].avg = newavg;
225− s->idx = (s->idx + 1) % NSAMPLES;
226−}
227−
228−static void method2_float(af_drc_t *s, struct mp_audio *c)
229−{
230− register int i = 0;
231− float *data = (float*)c->planes[0]; // Audio data
232− int len = c->samples*c->nch; // Number of samples
233− float curavg = 0.0, newavg, avg = 0.0, tmp;
234− int totallen = 0;
235−
236− for (i = 0; i < len; i++)
237− {
238− tmp = data[i];
239− curavg += tmp * tmp;
240− }
241− curavg = sqrt(curavg / (float) len);
242−
243− // Evaluate an adequate 'mul' coefficient based on previous state, current
244− // samples level, etc
245− for (i = 0; i < NSAMPLES; i++)
246− {
247− avg += s->mem[i].avg * (float)s->mem[i].len;
248− totallen += s->mem[i].len;
249− }
250−
251− if (totallen > MIN_SAMPLE_SIZE)
252− {
253− avg /= (float)totallen;
254− if (avg >= SIL_FLOAT)
255− {
256− s->mul = s->mid_float / avg;
257− s->mul = MPCLAMP(s->mul, MUL_MIN, MUL_MAX);
258− }
259− }
260−
261− // Scale & clamp the samples
262− for (i = 0; i < len; i++)
263− data[i] *= s->mul;
264−
265− // Evaluation of newavg (not 100% accurate because of values clamping)
266− newavg = s->mul * curavg;
267−
268− // Stores computed values for future smoothing
269− s->mem[s->idx].len = len;
270− s->mem[s->idx].avg = newavg;
271− s->idx = (s->idx + 1) % NSAMPLES;
272−}
273−
274−static int filter(struct af_instance *af, struct mp_audio *data)
275−{
276− af_drc_t *s = af->priv;
277−
278− if (!data)
279− return 0;
280−
281− if (af_make_writeable(af, data) < 0) {
282− talloc_free(data);
283− return -1;
284− }
285−
286− if(af->data->format == (AF_FORMAT_S16))
287− {
288− if (s->method == 2)
289− method2_int16(s, data);
290− else
291− method1_int16(s, data);
292− }
293− else if(af->data->format == (AF_FORMAT_FLOAT))
294− {
295− if (s->method == 2)
296− method2_float(s, data);
297− else
298− method1_float(s, data);
299− }
300− af_add_output_frame(af, data);
301− return 0;
302−}
303−
304−// Allocate memory and set function pointers
305−static int af_open(struct af_instance* af){
306− int i = 0;
307− af->control=control;
308− af->filter_frame = filter;
309− af_drc_t *priv = af->priv;
310−
311− priv->mul = MUL_INIT;
312− priv->lastavg = ((float)SHRT_MAX) * DEFAULT_TARGET;
313− priv->idx = 0;
314− for (i = 0; i < NSAMPLES; i++)
315− {
316− priv->mem[i].len = 0;
317− priv->mem[i].avg = 0;
318− }
319− priv->mid_s16 = ((float)SHRT_MAX) * priv->mid_float;
320− return AF_OK;
321−}
322−
323−#define OPT_BASE_STRUCT af_drc_t
324−const struct af_info af_info_drc = {
325− .info = "Dynamic range compression filter",
326− .name = "drc",
327− .open = af_open,
328− .priv_size = sizeof(af_drc_t),
329− .options = (const struct m_option[]) {
330− OPT_INTRANGE("method", method, 0, 1, 2, OPTDEF_INT(1)),
331− OPT_FLOAT("target", mid_float, 0, OPTDEF_FLOAT(DEFAULT_TARGET)),
332− {0}
333− },
334−};
wscript_build.py+0−1
@@ -124,7 +124,6 @@ def build(ctx): · 123 unmodified lines
124124 ( "audio/decode/dec_audio.c" ),
125125 ( "audio/filter/af.c" ),
126126 ( "audio/filter/af_channels.c" ),
127− ( "audio/filter/af_drc.c" ),
128127 ( "audio/filter/af_equalizer.c" ),
129128 ( "audio/filter/af_format.c" ),
130129 ( "audio/filter/af_lavcac3enc.c" ),

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t