2 * COpyright (c) 2002 Daniel Pouzzner
3 * Copyright (c) 1999 Chris Bagwell
4 * Copyright (c) 1999 Nick Bailey
5 * Copyright (c) 2007 Rob Sykes <robs@users.sourceforge.net>
6 * Copyright (c) 2013 Paul B Mahol
7 * Copyright (c) 2014 Andrew Kelley
9 * This file is part of FFmpeg.
11 * FFmpeg is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * FFmpeg is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with FFmpeg; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
28 * audio multiband compand filter
31 #include "libavutil/avstring.h"
32 #include "libavutil/ffmath.h"
33 #include "libavutil/mem.h"
34 #include "libavutil/opt.h"
35 #include "libavutil/samplefmt.h"
40 typedef struct CompandSegment
{
45 typedef struct CompandT
{
46 CompandSegment
*segments
;
56 typedef struct PrevCrossover
{
60 } PrevCrossover
[N
* 2];
62 typedef struct Crossover
{
63 PrevCrossover
*previous
;
65 double coefs
[3 *(N
+1)];
68 typedef struct CompBand
{
78 ptrdiff_t delay_buf_ptr
;
82 typedef struct MCompandContext
{
89 AVFrame
*band_buf1
, *band_buf2
, *band_buf3
;
91 size_t delay_buf_size
;
94 #define OFFSET(x) offsetof(MCompandContext, x)
95 #define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
97 static const AVOption mcompand_options
[] = {
98 { "args", "set parameters for each band", OFFSET(args
), AV_OPT_TYPE_STRING
, { .str
= "0.005,0.1 6 -47/-40,-34/-34,-17/-33 100 | 0.003,0.05 6 -47/-40,-34/-34,-17/-33 400 | 0.000625,0.0125 6 -47/-40,-34/-34,-15/-33 1600 | 0.0001,0.025 6 -47/-40,-34/-34,-31/-31,-0/-30 6400 | 0,0.025 6 -38/-31,-28/-28,-0/-25 22000" }, 0, 0, A
},
102 AVFILTER_DEFINE_CLASS(mcompand
);
104 static av_cold
void uninit(AVFilterContext
*ctx
)
106 MCompandContext
*s
= ctx
->priv
;
109 av_frame_free(&s
->band_buf1
);
110 av_frame_free(&s
->band_buf2
);
111 av_frame_free(&s
->band_buf3
);
114 for (i
= 0; i
< s
->nb_bands
; i
++) {
115 av_freep(&s
->bands
[i
].attack_rate
);
116 av_freep(&s
->bands
[i
].decay_rate
);
117 av_freep(&s
->bands
[i
].volume
);
118 av_freep(&s
->bands
[i
].transfer_fn
.segments
);
119 av_freep(&s
->bands
[i
].filter
.previous
);
120 av_frame_free(&s
->bands
[i
].delay_buf
);
126 static void count_items(char *item_str
, int *nb_items
, char delimiter
)
131 for (p
= item_str
; *p
; p
++) {
137 static void update_volume(CompBand
*cb
, double in
, int ch
)
139 double delta
= in
- cb
->volume
[ch
];
142 cb
->volume
[ch
] += delta
* cb
->attack_rate
[ch
];
144 cb
->volume
[ch
] += delta
* cb
->decay_rate
[ch
];
147 static double get_volume(CompandT
*s
, double in_lin
)
150 double in_log
, out_log
;
153 if (in_lin
<= s
->in_min_lin
)
154 return s
->out_min_lin
;
156 in_log
= log(in_lin
);
158 for (i
= 1; i
< s
->nb_segments
; i
++)
159 if (in_log
<= s
->segments
[i
].x
)
161 cs
= &s
->segments
[i
- 1];
163 out_log
= cs
->y
+ in_log
* (cs
->a
* in_log
+ cs
->b
);
168 static int parse_points(char *points
, int nb_points
, double radius
,
169 CompandT
*s
, AVFilterContext
*ctx
)
171 int new_nb_items
, num
;
172 char *saveptr
= NULL
;
176 #define S(x) s->segments[2 * ((x) + 1)]
177 for (i
= 0, new_nb_items
= 0; i
< nb_points
; i
++) {
178 char *tstr
= av_strtok(p
, ",", &saveptr
);
180 if (!tstr
|| sscanf(tstr
, "%lf/%lf", &S(i
).x
, &S(i
).y
) != 2) {
181 av_log(ctx
, AV_LOG_ERROR
,
182 "Invalid and/or missing input/output value.\n");
183 return AVERROR(EINVAL
);
185 if (i
&& S(i
- 1).x
> S(i
).x
) {
186 av_log(ctx
, AV_LOG_ERROR
,
187 "Transfer function input values must be increasing.\n");
188 return AVERROR(EINVAL
);
191 av_log(ctx
, AV_LOG_DEBUG
, "%d: x=%f y=%f\n", i
, S(i
).x
, S(i
).y
);
196 /* Add 0,0 if necessary */
197 if (num
== 0 || S(num
- 1).x
)
201 #define S(x) s->segments[2 * (x)]
202 /* Add a tail off segment at the start */
203 S(0).x
= S(1).x
- 2 * s
->curve_dB
;
207 /* Join adjacent colinear segments */
208 for (i
= 2; i
< num
; i
++) {
209 double g1
= (S(i
- 1).y
- S(i
- 2).y
) * (S(i
- 0).x
- S(i
- 1).x
);
210 double g2
= (S(i
- 0).y
- S(i
- 1).y
) * (S(i
- 1).x
- S(i
- 2).x
);
216 for (j
= --i
; j
< num
; j
++)
220 for (i
= 0; i
< s
->nb_segments
; i
+= 2) {
221 s
->segments
[i
].y
+= s
->gain_dB
;
222 s
->segments
[i
].x
*= M_LN10
/ 20;
223 s
->segments
[i
].y
*= M_LN10
/ 20;
226 #define L(x) s->segments[i - (x)]
227 for (i
= 4; i
< s
->nb_segments
; i
+= 2) {
228 double x
, y
, cx
, cy
, in1
, in2
, out1
, out2
, theta
, len
, r
;
231 L(4).b
= (L(2).y
- L(4).y
) / (L(2).x
- L(4).x
);
234 L(2).b
= (L(0).y
- L(2).y
) / (L(0).x
- L(2).x
);
236 theta
= atan2(L(2).y
- L(4).y
, L(2).x
- L(4).x
);
237 len
= hypot(L(2).x
- L(4).x
, L(2).y
- L(4).y
);
238 r
= FFMIN(radius
, len
);
239 L(3).x
= L(2).x
- r
* cos(theta
);
240 L(3).y
= L(2).y
- r
* sin(theta
);
242 theta
= atan2(L(0).y
- L(2).y
, L(0).x
- L(2).x
);
243 len
= hypot(L(0).x
- L(2).x
, L(0).y
- L(2).y
);
244 r
= FFMIN(radius
, len
/ 2);
245 x
= L(2).x
+ r
* cos(theta
);
246 y
= L(2).y
+ r
* sin(theta
);
248 cx
= (L(3).x
+ L(2).x
+ x
) / 3;
249 cy
= (L(3).y
+ L(2).y
+ y
) / 3;
256 in2
= L(2).x
- L(3).x
;
257 out2
= L(2).y
- L(3).y
;
258 L(3).a
= (out2
/ in2
- out1
/ in1
) / (in2
- in1
);
259 L(3).b
= out1
/ in1
- L(3).a
* in1
;
264 s
->in_min_lin
= exp(s
->segments
[1].x
);
265 s
->out_min_lin
= exp(s
->segments
[1].y
);
270 static void square_quadratic(double const *x
, double *y
)
273 y
[1] = 2 * x
[0] * x
[1];
274 y
[2] = 2 * x
[0] * x
[2] + x
[1] * x
[1];
275 y
[3] = 2 * x
[1] * x
[2];
279 static int crossover_setup(AVFilterLink
*outlink
, Crossover
*p
, double frequency
)
281 double w0
= 2 * M_PI
* frequency
/ outlink
->sample_rate
;
282 double Q
= sqrt(.5), alpha
= sin(w0
) / (2*Q
);
287 return AVERROR(EINVAL
);
289 x
[0] = (1 - cos(w0
))/2; /* Cf. filter_LPF in biquads.c */
291 x
[2] = (1 - cos(w0
))/2;
292 x
[3] = (1 + cos(w0
))/2; /* Cf. filter_HPF in biquads.c */
293 x
[4] = -(1 + cos(w0
));
294 x
[5] = (1 + cos(w0
))/2;
299 for (norm
= x
[6], i
= 0; i
< 9; ++i
)
302 square_quadratic(x
, p
->coefs
);
303 square_quadratic(x
+ 3, p
->coefs
+ 5);
304 square_quadratic(x
+ 6, p
->coefs
+ 10);
306 p
->previous
= av_calloc(outlink
->ch_layout
.nb_channels
, sizeof(*p
->previous
));
308 return AVERROR(ENOMEM
);
313 static int config_output(AVFilterLink
*outlink
)
315 AVFilterContext
*ctx
= outlink
->src
;
316 MCompandContext
*s
= ctx
->priv
;
317 int ret
, ch
, i
, k
, new_nb_items
, nb_bands
;
318 char *p
= s
->args
, *saveptr
= NULL
;
319 int max_delay_size
= 0;
321 count_items(s
->args
, &nb_bands
, '|');
322 s
->nb_bands
= FFMAX(1, nb_bands
);
324 s
->bands
= av_calloc(nb_bands
, sizeof(*s
->bands
));
326 return AVERROR(ENOMEM
);
328 for (i
= 0, new_nb_items
= 0; i
< nb_bands
; i
++) {
329 int nb_points
, nb_attacks
, nb_items
= 0;
330 char *tstr2
, *tstr
= av_strtok(p
, "|", &saveptr
);
331 char *p2
, *p3
, *saveptr2
= NULL
, *saveptr3
= NULL
;
335 return AVERROR(EINVAL
);
339 count_items(tstr
, &nb_items
, ' ');
340 tstr2
= av_strtok(p2
, " ", &saveptr2
);
342 av_log(ctx
, AV_LOG_ERROR
, "at least one attacks/decays rate is mandatory\n");
343 return AVERROR(EINVAL
);
348 count_items(tstr2
, &nb_attacks
, ',');
349 if (!nb_attacks
|| nb_attacks
& 1) {
350 av_log(ctx
, AV_LOG_ERROR
, "number of attacks rate plus decays rate must be even\n");
351 return AVERROR(EINVAL
);
354 s
->bands
[i
].attack_rate
= av_calloc(outlink
->ch_layout
.nb_channels
, sizeof(double));
355 s
->bands
[i
].decay_rate
= av_calloc(outlink
->ch_layout
.nb_channels
, sizeof(double));
356 s
->bands
[i
].volume
= av_calloc(outlink
->ch_layout
.nb_channels
, sizeof(double));
357 if (!s
->bands
[i
].attack_rate
|| !s
->bands
[i
].decay_rate
|| !s
->bands
[i
].volume
)
358 return AVERROR(ENOMEM
);
360 for (k
= 0; k
< FFMIN(nb_attacks
/ 2, outlink
->ch_layout
.nb_channels
); k
++) {
361 char *tstr3
= av_strtok(p3
, ",", &saveptr3
);
364 sscanf(tstr3
, "%lf", &s
->bands
[i
].attack_rate
[k
]);
365 tstr3
= av_strtok(p3
, ",", &saveptr3
);
366 sscanf(tstr3
, "%lf", &s
->bands
[i
].decay_rate
[k
]);
368 if (s
->bands
[i
].attack_rate
[k
] > 1.0 / outlink
->sample_rate
) {
369 s
->bands
[i
].attack_rate
[k
] = 1.0 - exp(-1.0 / (outlink
->sample_rate
* s
->bands
[i
].attack_rate
[k
]));
371 s
->bands
[i
].attack_rate
[k
] = 1.0;
374 if (s
->bands
[i
].decay_rate
[k
] > 1.0 / outlink
->sample_rate
) {
375 s
->bands
[i
].decay_rate
[k
] = 1.0 - exp(-1.0 / (outlink
->sample_rate
* s
->bands
[i
].decay_rate
[k
]));
377 s
->bands
[i
].decay_rate
[k
] = 1.0;
381 for (ch
= k
; ch
< outlink
->ch_layout
.nb_channels
; ch
++) {
382 s
->bands
[i
].attack_rate
[ch
] = s
->bands
[i
].attack_rate
[k
- 1];
383 s
->bands
[i
].decay_rate
[ch
] = s
->bands
[i
].decay_rate
[k
- 1];
386 tstr2
= av_strtok(p2
, " ", &saveptr2
);
388 av_log(ctx
, AV_LOG_ERROR
, "transfer function curve in dB must be set\n");
389 return AVERROR(EINVAL
);
391 sscanf(tstr2
, "%lf", &s
->bands
[i
].transfer_fn
.curve_dB
);
393 radius
= s
->bands
[i
].transfer_fn
.curve_dB
* M_LN10
/ 20.0;
395 tstr2
= av_strtok(p2
, " ", &saveptr2
);
397 av_log(ctx
, AV_LOG_ERROR
, "transfer points missing\n");
398 return AVERROR(EINVAL
);
401 count_items(tstr2
, &nb_points
, ',');
402 s
->bands
[i
].transfer_fn
.nb_segments
= (nb_points
+ 4) * 2;
403 s
->bands
[i
].transfer_fn
.segments
= av_calloc(s
->bands
[i
].transfer_fn
.nb_segments
,
404 sizeof(CompandSegment
));
405 if (!s
->bands
[i
].transfer_fn
.segments
)
406 return AVERROR(ENOMEM
);
408 ret
= parse_points(tstr2
, nb_points
, radius
, &s
->bands
[i
].transfer_fn
, ctx
);
410 av_log(ctx
, AV_LOG_ERROR
, "transfer points parsing failed\n");
414 tstr2
= av_strtok(p2
, " ", &saveptr2
);
416 av_log(ctx
, AV_LOG_ERROR
, "crossover_frequency is missing\n");
417 return AVERROR(EINVAL
);
420 new_nb_items
+= sscanf(tstr2
, "%lf", &s
->bands
[i
].topfreq
) == 1;
421 if (s
->bands
[i
].topfreq
< 0 || s
->bands
[i
].topfreq
>= outlink
->sample_rate
/ 2.0) {
422 av_log(ctx
, AV_LOG_ERROR
, "crossover_frequency: %f, should be >=0 and lower than half of sample rate: %f.\n", s
->bands
[i
].topfreq
, outlink
->sample_rate
/ 2.0);
423 return AVERROR(EINVAL
);
426 if (s
->bands
[i
].topfreq
!= 0) {
427 ret
= crossover_setup(outlink
, &s
->bands
[i
].filter
, s
->bands
[i
].topfreq
);
432 tstr2
= av_strtok(p2
, " ", &saveptr2
);
434 sscanf(tstr2
, "%lf", &s
->bands
[i
].delay
);
435 max_delay_size
= FFMAX(max_delay_size
, s
->bands
[i
].delay
* outlink
->sample_rate
);
437 tstr2
= av_strtok(p2
, " ", &saveptr2
);
439 double initial_volume
;
441 sscanf(tstr2
, "%lf", &initial_volume
);
442 initial_volume
= pow(10.0, initial_volume
/ 20);
444 for (k
= 0; k
< outlink
->ch_layout
.nb_channels
; k
++) {
445 s
->bands
[i
].volume
[k
] = initial_volume
;
448 tstr2
= av_strtok(p2
, " ", &saveptr2
);
450 sscanf(tstr2
, "%lf", &s
->bands
[i
].transfer_fn
.gain_dB
);
455 s
->nb_bands
= new_nb_items
;
457 for (i
= 0; max_delay_size
> 0 && i
< s
->nb_bands
; i
++) {
458 s
->bands
[i
].delay_buf
= ff_get_audio_buffer(outlink
, max_delay_size
);
459 if (!s
->bands
[i
].delay_buf
)
460 return AVERROR(ENOMEM
);
462 s
->delay_buf_size
= max_delay_size
;
467 #define CONVOLVE _ _ _ _
469 static void crossover(int ch
, Crossover
*p
,
470 double *ibuf
, double *obuf_low
,
471 double *obuf_high
, size_t len
)
473 double out_low
, out_high
;
476 p
->pos
= p
->pos
? p
->pos
- 1 : N
- 1;
477 #define _ out_low += p->coefs[j] * p->previous[ch][p->pos + j].in \
478 - p->coefs[2*N+2 + j] * p->previous[ch][p->pos + j].out_low, j++;
481 out_low
= p
->coefs
[0] * *ibuf
;
483 *obuf_low
++ = out_low
;
486 #define _ out_high += p->coefs[j+N+1] * p->previous[ch][p->pos + j].in \
487 - p->coefs[2*N+2 + j] * p->previous[ch][p->pos + j].out_high, j++;
490 out_high
= p
->coefs
[N
+1] * *ibuf
;
492 *obuf_high
++ = out_high
;
494 p
->previous
[ch
][p
->pos
+ N
].in
= p
->previous
[ch
][p
->pos
].in
= *ibuf
++;
495 p
->previous
[ch
][p
->pos
+ N
].out_low
= p
->previous
[ch
][p
->pos
].out_low
= out_low
;
496 p
->previous
[ch
][p
->pos
+ N
].out_high
= p
->previous
[ch
][p
->pos
].out_high
= out_high
;
500 static int mcompand_channel(MCompandContext
*c
, CompBand
*l
, double *ibuf
, double *obuf
, int len
, int ch
)
504 for (i
= 0; i
< len
; i
++) {
505 double level_in_lin
, level_out_lin
, checkbuf
;
506 /* Maintain the volume fields by simulating a leaky pump circuit */
507 update_volume(l
, fabs(ibuf
[i
]), ch
);
509 /* Volume memory is updated: perform compand */
510 level_in_lin
= l
->volume
[ch
];
511 level_out_lin
= get_volume(&l
->transfer_fn
, level_in_lin
);
513 if (c
->delay_buf_size
<= 0) {
514 checkbuf
= ibuf
[i
] * level_out_lin
;
517 double *delay_buf
= (double *)l
->delay_buf
->extended_data
[ch
];
519 /* FIXME: note that this lookahead algorithm is really lame:
520 the response to a peak is released before the peak
523 /* because volume application delays differ band to band, but
524 total delay doesn't, the volume is applied in an iteration
525 preceding that in which the sample goes to obuf, except in
526 the band(s) with the longest vol app delay.
528 the offset between delay_buf_ptr and the sample to apply
529 vol to, is a constant equal to the difference between this
530 band's delay and the longest delay of all the bands. */
532 if (l
->delay_buf_cnt
>= l
->delay_size
) {
534 delay_buf
[(l
->delay_buf_ptr
+
536 l
->delay_size
) % c
->delay_buf_size
] * level_out_lin
;
537 delay_buf
[(l
->delay_buf_ptr
+ c
->delay_buf_size
-
538 l
->delay_size
) % c
->delay_buf_size
] = checkbuf
;
540 if (l
->delay_buf_cnt
>= c
->delay_buf_size
) {
541 obuf
[i
] = delay_buf
[l
->delay_buf_ptr
];
545 delay_buf
[l
->delay_buf_ptr
++] = ibuf
[i
];
546 l
->delay_buf_ptr
%= c
->delay_buf_size
;
553 static int filter_frame(AVFilterLink
*inlink
, AVFrame
*in
)
555 AVFilterContext
*ctx
= inlink
->dst
;
556 AVFilterLink
*outlink
= ctx
->outputs
[0];
557 MCompandContext
*s
= ctx
->priv
;
558 AVFrame
*out
, *abuf
, *bbuf
, *cbuf
;
561 out
= ff_get_audio_buffer(outlink
, in
->nb_samples
);
564 return AVERROR(ENOMEM
);
567 if (s
->band_samples
< in
->nb_samples
) {
568 av_frame_free(&s
->band_buf1
);
569 av_frame_free(&s
->band_buf2
);
570 av_frame_free(&s
->band_buf3
);
572 s
->band_buf1
= ff_get_audio_buffer(outlink
, in
->nb_samples
);
573 s
->band_buf2
= ff_get_audio_buffer(outlink
, in
->nb_samples
);
574 s
->band_buf3
= ff_get_audio_buffer(outlink
, in
->nb_samples
);
575 s
->band_samples
= in
->nb_samples
;
578 for (ch
= 0; ch
< outlink
->ch_layout
.nb_channels
; ch
++) {
579 double *a
, *dst
= (double *)out
->extended_data
[ch
];
581 for (band
= 0, abuf
= in
, bbuf
= s
->band_buf2
, cbuf
= s
->band_buf1
; band
< s
->nb_bands
; band
++) {
582 CompBand
*b
= &s
->bands
[band
];
585 crossover(ch
, &b
->filter
, (double *)abuf
->extended_data
[ch
],
586 (double *)bbuf
->extended_data
[ch
], (double *)cbuf
->extended_data
[ch
], in
->nb_samples
);
594 mcompand_channel(s
, b
, (double *)bbuf
->extended_data
[ch
], (double *)abuf
->extended_data
[ch
], out
->nb_samples
, ch
);
595 a
= (double *)abuf
->extended_data
[ch
];
596 for (i
= 0; i
< out
->nb_samples
; i
++) {
600 FFSWAP(AVFrame
*, abuf
, cbuf
);
606 return ff_filter_frame(outlink
, out
);
609 static int request_frame(AVFilterLink
*outlink
)
611 AVFilterContext
*ctx
= outlink
->src
;
614 ret
= ff_request_frame(ctx
->inputs
[0]);
619 static const AVFilterPad mcompand_inputs
[] = {
622 .type
= AVMEDIA_TYPE_AUDIO
,
623 .filter_frame
= filter_frame
,
627 static const AVFilterPad mcompand_outputs
[] = {
630 .type
= AVMEDIA_TYPE_AUDIO
,
631 .request_frame
= request_frame
,
632 .config_props
= config_output
,
637 const FFFilter ff_af_mcompand
= {
638 .p
.name
= "mcompand",
639 .p
.description
= NULL_IF_CONFIG_SMALL(
640 "Multiband Compress or expand audio dynamic range."),
641 .p
.priv_class
= &mcompand_class
,
642 .priv_size
= sizeof(MCompandContext
),
644 FILTER_INPUTS(mcompand_inputs
),
645 FILTER_OUTPUTS(mcompand_outputs
),
646 FILTER_SINGLE_SAMPLEFMT(AV_SAMPLE_FMT_DBLP
),