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/avassert.h"
32 #include "libavutil/avstring.h"
33 #include "libavutil/ffmath.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 int query_formats(AVFilterContext *ctx)
128 AVFilterChannelLayouts *layouts;
129 AVFilterFormats *formats;
130 static const enum AVSampleFormat sample_fmts[] = {
136 layouts = ff_all_channel_counts();
138 return AVERROR(ENOMEM);
139 ret = ff_set_common_channel_layouts(ctx, layouts);
143 formats = ff_make_format_list(sample_fmts);
145 return AVERROR(ENOMEM);
146 ret = ff_set_common_formats(ctx, formats);
150 formats = ff_all_samplerates();
152 return AVERROR(ENOMEM);
153 return ff_set_common_samplerates(ctx, formats);
156 static void count_items(char *item_str, int *nb_items, char delimiter)
161 for (p = item_str; *p; p++) {
167 static void update_volume(CompBand *cb, double in, int ch)
169 double delta = in - cb->volume[ch];
172 cb->volume[ch] += delta * cb->attack_rate[ch];
174 cb->volume[ch] += delta * cb->decay_rate[ch];
177 static double get_volume(CompandT *s, double in_lin)
180 double in_log, out_log;
183 if (in_lin <= s->in_min_lin)
184 return s->out_min_lin;
186 in_log = log(in_lin);
188 for (i = 1; i < s->nb_segments; i++)
189 if (in_log <= s->segments[i].x)
191 cs = &s->segments[i - 1];
193 out_log = cs->y + in_log * (cs->a * in_log + cs->b);
198 static int parse_points(char *points, int nb_points, double radius,
199 CompandT *s, AVFilterContext *ctx)
201 int new_nb_items, num;
202 char *saveptr = NULL;
206 #define S(x) s->segments[2 * ((x) + 1)]
207 for (i = 0, new_nb_items = 0; i < nb_points; i++) {
208 char *tstr = av_strtok(p, ",", &saveptr);
210 if (!tstr || sscanf(tstr, "%lf/%lf", &S(i).x, &S(i).y) != 2) {
211 av_log(ctx, AV_LOG_ERROR,
212 "Invalid and/or missing input/output value.\n");
213 return AVERROR(EINVAL);
215 if (i && S(i - 1).x > S(i).x) {
216 av_log(ctx, AV_LOG_ERROR,
217 "Transfer function input values must be increasing.\n");
218 return AVERROR(EINVAL);
221 av_log(ctx, AV_LOG_DEBUG, "%d: x=%f y=%f\n", i, S(i).x, S(i).y);
226 /* Add 0,0 if necessary */
227 if (num == 0 || S(num - 1).x)
231 #define S(x) s->segments[2 * (x)]
232 /* Add a tail off segment at the start */
233 S(0).x = S(1).x - 2 * s->curve_dB;
237 /* Join adjacent colinear segments */
238 for (i = 2; i < num; i++) {
239 double g1 = (S(i - 1).y - S(i - 2).y) * (S(i - 0).x - S(i - 1).x);
240 double g2 = (S(i - 0).y - S(i - 1).y) * (S(i - 1).x - S(i - 2).x);
246 for (j = --i; j < num; j++)
250 for (i = 0; i < s->nb_segments; i += 2) {
251 s->segments[i].y += s->gain_dB;
252 s->segments[i].x *= M_LN10 / 20;
253 s->segments[i].y *= M_LN10 / 20;
256 #define L(x) s->segments[i - (x)]
257 for (i = 4; i < s->nb_segments; i += 2) {
258 double x, y, cx, cy, in1, in2, out1, out2, theta, len, r;
261 L(4).b = (L(2).y - L(4).y) / (L(2).x - L(4).x);
264 L(2).b = (L(0).y - L(2).y) / (L(0).x - L(2).x);
266 theta = atan2(L(2).y - L(4).y, L(2).x - L(4).x);
267 len = hypot(L(2).x - L(4).x, L(2).y - L(4).y);
268 r = FFMIN(radius, len);
269 L(3).x = L(2).x - r * cos(theta);
270 L(3).y = L(2).y - r * sin(theta);
272 theta = atan2(L(0).y - L(2).y, L(0).x - L(2).x);
273 len = hypot(L(0).x - L(2).x, L(0).y - L(2).y);
274 r = FFMIN(radius, len / 2);
275 x = L(2).x + r * cos(theta);
276 y = L(2).y + r * sin(theta);
278 cx = (L(3).x + L(2).x + x) / 3;
279 cy = (L(3).y + L(2).y + y) / 3;
286 in2 = L(2).x - L(3).x;
287 out2 = L(2).y - L(3).y;
288 L(3).a = (out2 / in2 - out1 / in1) / (in2 - in1);
289 L(3).b = out1 / in1 - L(3).a * in1;
294 s->in_min_lin = exp(s->segments[1].x);
295 s->out_min_lin = exp(s->segments[1].y);
300 static void square_quadratic(double const *x, double *y)
303 y[1] = 2 * x[0] * x[1];
304 y[2] = 2 * x[0] * x[2] + x[1] * x[1];
305 y[3] = 2 * x[1] * x[2];
309 static int crossover_setup(AVFilterLink *outlink, Crossover *p, double frequency)
311 double w0 = 2 * M_PI * frequency / outlink->sample_rate;
312 double Q = sqrt(.5), alpha = sin(w0) / (2*Q);
317 return AVERROR(EINVAL);
319 x[0] = (1 - cos(w0))/2; /* Cf. filter_LPF in biquads.c */
321 x[2] = (1 - cos(w0))/2;
322 x[3] = (1 + cos(w0))/2; /* Cf. filter_HPF in biquads.c */
323 x[4] = -(1 + cos(w0));
324 x[5] = (1 + cos(w0))/2;
329 for (norm = x[6], i = 0; i < 9; ++i)
332 square_quadratic(x , p->coefs);
333 square_quadratic(x + 3, p->coefs + 5);
334 square_quadratic(x + 6, p->coefs + 10);
336 p->previous = av_calloc(outlink->channels, sizeof(*p->previous));
338 return AVERROR(ENOMEM);
343 static int config_output(AVFilterLink *outlink)
345 AVFilterContext *ctx = outlink->src;
346 MCompandContext *s = ctx->priv;
347 int ret, ch, i, k, new_nb_items, nb_bands;
348 char *p = s->args, *saveptr = NULL;
349 int max_delay_size = 0;
351 count_items(s->args, &nb_bands, '|');
352 s->nb_bands = FFMAX(1, nb_bands);
354 s->bands = av_calloc(nb_bands, sizeof(*s->bands));
356 return AVERROR(ENOMEM);
358 for (i = 0, new_nb_items = 0; i < nb_bands; i++) {
359 int nb_points, nb_attacks, nb_items = 0;
360 char *tstr2, *tstr = av_strtok(p, "|", &saveptr);
361 char *p2, *p3, *saveptr2 = NULL, *saveptr3 = NULL;
365 return AVERROR(EINVAL);
369 count_items(tstr, &nb_items, ' ');
370 tstr2 = av_strtok(p2, " ", &saveptr2);
372 av_log(ctx, AV_LOG_ERROR, "at least one attacks/decays rate is mandatory\n");
373 return AVERROR(EINVAL);
378 count_items(tstr2, &nb_attacks, ',');
379 if (!nb_attacks || nb_attacks & 1) {
380 av_log(ctx, AV_LOG_ERROR, "number of attacks rate plus decays rate must be even\n");
381 return AVERROR(EINVAL);
384 s->bands[i].attack_rate = av_calloc(outlink->channels, sizeof(double));
385 s->bands[i].decay_rate = av_calloc(outlink->channels, sizeof(double));
386 s->bands[i].volume = av_calloc(outlink->channels, sizeof(double));
387 for (k = 0; k < FFMIN(nb_attacks / 2, outlink->channels); k++) {
388 char *tstr3 = av_strtok(p3, ",", &saveptr3);
391 sscanf(tstr3, "%lf", &s->bands[i].attack_rate[k]);
392 tstr3 = av_strtok(p3, ",", &saveptr3);
393 sscanf(tstr3, "%lf", &s->bands[i].decay_rate[k]);
395 if (s->bands[i].attack_rate[k] > 1.0 / outlink->sample_rate) {
396 s->bands[i].attack_rate[k] = 1.0 - exp(-1.0 / (outlink->sample_rate * s->bands[i].attack_rate[k]));
398 s->bands[i].attack_rate[k] = 1.0;
401 if (s->bands[i].decay_rate[k] > 1.0 / outlink->sample_rate) {
402 s->bands[i].decay_rate[k] = 1.0 - exp(-1.0 / (outlink->sample_rate * s->bands[i].decay_rate[k]));
404 s->bands[i].decay_rate[k] = 1.0;
408 for (ch = k; ch < outlink->channels; ch++) {
409 s->bands[i].attack_rate[ch] = s->bands[i].attack_rate[k - 1];
410 s->bands[i].decay_rate[ch] = s->bands[i].decay_rate[k - 1];
413 tstr2 = av_strtok(p2, " ", &saveptr2);
415 av_log(ctx, AV_LOG_ERROR, "transfer function curve in dB must be set\n");
416 return AVERROR(EINVAL);
418 sscanf(tstr2, "%lf", &s->bands[i].transfer_fn.curve_dB);
420 radius = s->bands[i].transfer_fn.curve_dB * M_LN10 / 20.0;
422 tstr2 = av_strtok(p2, " ", &saveptr2);
424 av_log(ctx, AV_LOG_ERROR, "transfer points missing\n");
425 return AVERROR(EINVAL);
428 count_items(tstr2, &nb_points, ',');
429 s->bands[i].transfer_fn.nb_segments = (nb_points + 4) * 2;
430 s->bands[i].transfer_fn.segments = av_calloc(s->bands[i].transfer_fn.nb_segments,
431 sizeof(CompandSegment));
432 if (!s->bands[i].transfer_fn.segments)
433 return AVERROR(ENOMEM);
435 ret = parse_points(tstr2, nb_points, radius, &s->bands[i].transfer_fn, ctx);
437 av_log(ctx, AV_LOG_ERROR, "transfer points parsing failed\n");
441 tstr2 = av_strtok(p2, " ", &saveptr2);
443 av_log(ctx, AV_LOG_ERROR, "crossover_frequency is missing\n");
444 return AVERROR(EINVAL);
447 new_nb_items += sscanf(tstr2, "%lf", &s->bands[i].topfreq) == 1;
448 if (s->bands[i].topfreq < 0 || s->bands[i].topfreq >= outlink->sample_rate / 2) {
449 av_log(ctx, AV_LOG_ERROR, "crossover_frequency: %f, should be >=0 and lower than half of sample rate: %d.\n", s->bands[i].topfreq, outlink->sample_rate / 2);
450 return AVERROR(EINVAL);
453 if (s->bands[i].topfreq != 0) {
454 ret = crossover_setup(outlink, &s->bands[i].filter, s->bands[i].topfreq);
459 tstr2 = av_strtok(p2, " ", &saveptr2);
461 sscanf(tstr2, "%lf", &s->bands[i].delay);
462 max_delay_size = FFMAX(max_delay_size, s->bands[i].delay * outlink->sample_rate);
464 tstr2 = av_strtok(p2, " ", &saveptr2);
466 double initial_volume;
468 sscanf(tstr2, "%lf", &initial_volume);
469 initial_volume = pow(10.0, initial_volume / 20);
471 for (k = 0; k < outlink->channels; k++) {
472 s->bands[i].volume[k] = initial_volume;
475 tstr2 = av_strtok(p2, " ", &saveptr2);
477 sscanf(tstr2, "%lf", &s->bands[i].transfer_fn.gain_dB);
482 s->nb_bands = new_nb_items;
484 for (i = 0; max_delay_size > 0 && i < s->nb_bands; i++) {
485 s->bands[i].delay_buf = ff_get_audio_buffer(outlink, max_delay_size);
486 if (!s->bands[i].delay_buf)
487 return AVERROR(ENOMEM);
489 s->delay_buf_size = max_delay_size;
494 #define CONVOLVE _ _ _ _
496 static void crossover(int ch, Crossover *p,
497 double *ibuf, double *obuf_low,
498 double *obuf_high, size_t len)
500 double out_low, out_high;
503 p->pos = p->pos ? p->pos - 1 : N - 1;
504 #define _ out_low += p->coefs[j] * p->previous[ch][p->pos + j].in \
505 - p->coefs[2*N+2 + j] * p->previous[ch][p->pos + j].out_low, j++;
508 out_low = p->coefs[0] * *ibuf;
510 *obuf_low++ = out_low;
513 #define _ out_high += p->coefs[j+N+1] * p->previous[ch][p->pos + j].in \
514 - p->coefs[2*N+2 + j] * p->previous[ch][p->pos + j].out_high, j++;
517 out_high = p->coefs[N+1] * *ibuf;
519 *obuf_high++ = out_high;
521 p->previous[ch][p->pos + N].in = p->previous[ch][p->pos].in = *ibuf++;
522 p->previous[ch][p->pos + N].out_low = p->previous[ch][p->pos].out_low = out_low;
523 p->previous[ch][p->pos + N].out_high = p->previous[ch][p->pos].out_high = out_high;
527 static int mcompand_channel(MCompandContext *c, CompBand *l, double *ibuf, double *obuf, int len, int ch)
531 for (i = 0; i < len; i++) {
532 double level_in_lin, level_out_lin, checkbuf;
533 /* Maintain the volume fields by simulating a leaky pump circuit */
534 update_volume(l, fabs(ibuf[i]), ch);
536 /* Volume memory is updated: perform compand */
537 level_in_lin = l->volume[ch];
538 level_out_lin = get_volume(&l->transfer_fn, level_in_lin);
540 if (c->delay_buf_size <= 0) {
541 checkbuf = ibuf[i] * level_out_lin;
544 double *delay_buf = (double *)l->delay_buf->extended_data[ch];
546 /* FIXME: note that this lookahead algorithm is really lame:
547 the response to a peak is released before the peak
550 /* because volume application delays differ band to band, but
551 total delay doesn't, the volume is applied in an iteration
552 preceding that in which the sample goes to obuf, except in
553 the band(s) with the longest vol app delay.
555 the offset between delay_buf_ptr and the sample to apply
556 vol to, is a constant equal to the difference between this
557 band's delay and the longest delay of all the bands. */
559 if (l->delay_buf_cnt >= l->delay_size) {
561 delay_buf[(l->delay_buf_ptr +
563 l->delay_size) % c->delay_buf_size] * level_out_lin;
564 delay_buf[(l->delay_buf_ptr + c->delay_buf_size -
565 l->delay_size) % c->delay_buf_size] = checkbuf;
567 if (l->delay_buf_cnt >= c->delay_buf_size) {
568 obuf[i] = delay_buf[l->delay_buf_ptr];
572 delay_buf[l->delay_buf_ptr++] = ibuf[i];
573 l->delay_buf_ptr %= c->delay_buf_size;
580 static int filter_frame(AVFilterLink *inlink, AVFrame *in)
582 AVFilterContext *ctx = inlink->dst;
583 AVFilterLink *outlink = ctx->outputs[0];
584 MCompandContext *s = ctx->priv;
585 AVFrame *out, *abuf, *bbuf, *cbuf;
588 out = ff_get_audio_buffer(outlink, in->nb_samples);
591 return AVERROR(ENOMEM);
594 if (s->band_samples < in->nb_samples) {
595 av_frame_free(&s->band_buf1);
596 av_frame_free(&s->band_buf2);
597 av_frame_free(&s->band_buf3);
599 s->band_buf1 = ff_get_audio_buffer(outlink, in->nb_samples);
600 s->band_buf2 = ff_get_audio_buffer(outlink, in->nb_samples);
601 s->band_buf3 = ff_get_audio_buffer(outlink, in->nb_samples);
602 s->band_samples = in->nb_samples;
605 for (ch = 0; ch < outlink->channels; ch++) {
606 double *a, *dst = (double *)out->extended_data[ch];
608 for (band = 0, abuf = in, bbuf = s->band_buf2, cbuf = s->band_buf1; band < s->nb_bands; band++) {
609 CompBand *b = &s->bands[band];
612 crossover(ch, &b->filter, (double *)abuf->extended_data[ch],
613 (double *)bbuf->extended_data[ch], (double *)cbuf->extended_data[ch], in->nb_samples);
621 mcompand_channel(s, b, (double *)bbuf->extended_data[ch], (double *)abuf->extended_data[ch], out->nb_samples, ch);
622 a = (double *)abuf->extended_data[ch];
623 for (i = 0; i < out->nb_samples; i++) {
627 FFSWAP(AVFrame *, abuf, cbuf);
633 return ff_filter_frame(outlink, out);
636 static int request_frame(AVFilterLink *outlink)
638 AVFilterContext *ctx = outlink->src;
641 ret = ff_request_frame(ctx->inputs[0]);
646 static const AVFilterPad mcompand_inputs[] = {
649 .type = AVMEDIA_TYPE_AUDIO,
650 .filter_frame = filter_frame,
655 static const AVFilterPad mcompand_outputs[] = {
658 .type = AVMEDIA_TYPE_AUDIO,
659 .request_frame = request_frame,
660 .config_props = config_output,
666 AVFilter ff_af_mcompand = {
668 .description = NULL_IF_CONFIG_SMALL(
669 "Multiband Compress or expand audio dynamic range."),
670 .query_formats = query_formats,
671 .priv_size = sizeof(MCompandContext),
672 .priv_class = &mcompand_class,
674 .inputs = mcompand_inputs,
675 .outputs = mcompand_outputs,