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
25 - remove ppm, pgm, pgmyuv, tga choices from the --screenshot-format and25 - remove ppm, pgm, pgmyuv, tga choices from the --screenshot-format and
26 --vo-image-format options26 --vo-image-format options
27 - the "jpeg" choice in the option above now leads to a ".jpg" file extension27 - 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)
28 --- mpv 0.24.0 ---29 --- mpv 0.24.0 ---
29 - deprecate --hwdec-api and replace it with --opengl-hwdec-interop.30 - deprecate --hwdec-api and replace it with --opengl-hwdec-interop.
30 The new option accepts both --hwdec values, as well as named backends.31 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
319 the mixing matrix at runtime, without reinitializing the entire filter319 the mixing matrix at runtime, without reinitializing the entire filter
320 chain.320 chain.
321 321
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
345``scaletempo[=option1:option2:...]``322``scaletempo[=option1:option2:...]``
346 Scales audio tempo without altering pitch, optionally synced to playback323 Scales audio tempo without altering pitch, optionally synced to playback
347 speed (default).324 speed (default).
DOCS/mplayer-changes.rst+1−1
@@ -212,7 +212,7 @@ Command Line Switches · 211 unmodified lines
212 ``-no<opt>`` ``--no-<opt>`` (add a dash)212 ``-no<opt>`` ``--no-<opt>`` (add a dash)
213 ``-a52drc level`` ``--ad-lavc-ac3drc=level``213 ``-a52drc level`` ``--ad-lavc-ac3drc=level``
214 ``-ac spdifac3`` ``--ad=spdif:ac3`` (see ``--ad=help``)214 ``-ac spdifac3`` ``--ad=spdif:ac3`` (see ``--ad=help``)
215 ``-af volnorm`` ``--af=drc`` (renamed)215 ``-af volnorm`` (removed; use acompressor ffmpeg filter instead)
216 ``-afm hwac3`` ``--ad=spdif:ac3,spdif:dts``216 ``-afm hwac3`` ``--ad=spdif:ac3,spdif:dts``
217 ``-ao alsa:device=hw=0.3`` ``--ao=alsa:device=[hw:0,3]``217 ``-ao alsa:device=hw=0.3`` ``--ao=alsa:device=[hw:0,3]``
218 ``-aspect`` ``--video-aspect``218 ``-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
20script_name = mp.get_script_name()
21
22function 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
30end
31
32function 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
38end
39
40function 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"])
50end
51
52function 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)
61end
62
63function 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 )
76end
77
78function 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 )
85end
86
87function drc_louder_handler()
88 drc_scale_target(2.0)
89end
90
91function drc_quieter_handler()
92 drc_scale_target(0.5)
93end
94
95-- toggle between off, method 1 and method 2
96mp.add_key_binding("\\", "drc_toggle_method", drc_toggle_method_handler)
97-- increase or decrease target volume
98mp.add_key_binding("ctrl+9", "drc_quieter", drc_quieter_handler)
99mp.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
36extern const struct af_info af_info_volume;36extern const struct af_info af_info_volume;
37extern const struct af_info af_info_equalizer;37extern const struct af_info af_info_equalizer;
38extern const struct af_info af_info_pan;38extern const struct af_info af_info_pan;
39extern const struct af_info af_info_drc;
40extern const struct af_info af_info_lavcac3enc;39extern const struct af_info af_info_lavcac3enc;
41extern const struct af_info af_info_lavrresample;40extern const struct af_info af_info_lavrresample;
42extern const struct af_info af_info_scaletempo;41extern const struct af_info af_info_scaletempo;
@@ -50,7 +49,6 @@ static const struct af_info *const filter_list[] = { · 7 unmodified lines
50 &af_info_volume,49 &af_info_volume,
51 &af_info_equalizer,50 &af_info_equalizer,
52 &af_info_pan,51 &af_info_pan,
53 &af_info_drc,
54 &af_info_lavcac3enc,52 &af_info_lavcac3enc,
55 &af_info_lavrresample,53 &af_info_lavrresample,
56#if HAVE_RUBBERBAND54#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
63typedef 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
81static 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
99static 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
141static 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
178static 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
228static 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
274static 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
305static 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
324const 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
124 ( "audio/decode/dec_audio.c" ),124 ( "audio/decode/dec_audio.c" ),
125 ( "audio/filter/af.c" ),125 ( "audio/filter/af.c" ),
126 ( "audio/filter/af_channels.c" ),126 ( "audio/filter/af_channels.c" ),
127 ( "audio/filter/af_drc.c" ),
128 ( "audio/filter/af_equalizer.c" ),127 ( "audio/filter/af_equalizer.c" ),
129 ( "audio/filter/af_format.c" ),128 ( "audio/filter/af_format.c" ),
130 ( "audio/filter/af_lavcac3enc.c" ),129 ( "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