1 /*
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
8 *
9 * This file is part of FFmpeg.
10 *
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.
15 *
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.
20 *
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
24 */
25
26 /**
27 * @file
28 * audio multiband compand filter
29 */
30
38
43
52
54
60
66
80
83
85
92
93 #define OFFSET(x) offsetof(MCompandContext, x)
94 #define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
95
97 {
"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 },
99 };
100
102
104 {
107
111
113 for (
i = 0;
i <
s->nb_bands;
i++) {
120 }
121 }
123 }
124
125 static void count_items(
char *item_str,
int *nb_items,
char delimiter)
126 {
127 char *p;
128
129 *nb_items = 1;
130 for (p = item_str; *p; p++) {
131 if (*p == delimiter)
132 (*nb_items)++;
133 }
134 }
135
137 {
138 double delta = in -
cb->volume[ch];
139
141 cb->volume[ch] +=
delta *
cb->attack_rate[ch];
142 else
143 cb->volume[ch] +=
delta *
cb->decay_rate[ch];
144 }
145
147 {
149 double in_log, out_log;
151
152 if (in_lin <= s->in_min_lin)
153 return s->out_min_lin;
154
155 in_log = log(in_lin);
156
157 for (
i = 1;
i <
s->nb_segments;
i++)
158 if (in_log <= s->segments[
i].x)
159 break;
160 cs = &
s->segments[
i - 1];
162 out_log = cs->
y + in_log * (cs->
a * in_log + cs->
b);
163
165 }
166
169 {
170 int new_nb_items, num;
171 char *saveptr =
NULL;
172 char *p = points;
174
175 #define S(x) s->segments[2 * ((x) + 1)]
176 for (
i = 0, new_nb_items = 0;
i < nb_points;
i++) {
177 char *tstr =
av_strtok(p,
",", &saveptr);
179 if (!tstr || sscanf(tstr,
"%lf/%lf", &
S(
i).x, &
S(
i).y) != 2) {
181 "Invalid and/or missing input/output value.\n");
183 }
184 if (
i &&
S(
i - 1).x >
S(
i).x) {
186 "Transfer function input values must be increasing.\n");
188 }
191 new_nb_items++;
192 }
193 num = new_nb_items;
194
195 /* Add 0,0 if necessary */
196 if (num == 0 ||
S(num - 1).x)
197 num++;
198
199 #undef S
200 #define S(x) s->segments[2 * (x)]
201 /* Add a tail off segment at the start */
202 S(0).x =
S(1).x - 2 *
s->curve_dB;
204 num++;
205
206 /* Join adjacent colinear segments */
207 for (
i = 2;
i < num;
i++) {
208 double g1 = (
S(
i - 1).y -
S(
i - 2).y) * (
S(
i - 0).x -
S(
i - 1).x);
209 double g2 = (
S(
i - 0).y -
S(
i - 1).y) * (
S(
i - 1).x -
S(
i - 2).x);
210 int j;
211
213 continue;
214 num--;
215 for (j = --
i; j < num; j++)
217 }
218
219 for (
i = 0;
i <
s->nb_segments;
i += 2) {
220 s->segments[
i].y +=
s->gain_dB;
223 }
224
225 #define L(x) s->segments[i - (x)]
226 for (
i = 4;
i <
s->nb_segments;
i += 2) {
227 double x, y, cx, cy, in1, in2, out1, out2, theta,
len,
r;
228
230 L(4).b = (
L(2).y -
L(4).y) / (
L(2).x -
L(4).x);
231
233 L(2).b = (
L(0).y -
L(2).y) / (
L(0).x -
L(2).x);
234
235 theta = atan2(
L(2).y -
L(4).y,
L(2).x -
L(4).x);
238 L(3).x =
L(2).x -
r * cos(theta);
239 L(3).y =
L(2).y -
r * sin(theta);
240
241 theta = atan2(
L(0).y -
L(2).y,
L(0).x -
L(2).x);
244 x =
L(2).x +
r * cos(theta);
245 y =
L(2).y +
r * sin(theta);
246
247 cx = (
L(3).x +
L(2).x + x) / 3;
248 cy = (
L(3).y +
L(2).y + y) / 3;
249
252
255 in2 =
L(2).x -
L(3).x;
256 out2 =
L(2).y -
L(3).y;
257 L(3).a = (out2 / in2 - out1 / in1) / (in2 - in1);
258 L(3).b = out1 / in1 -
L(3).a * in1;
259 }
262
263 s->in_min_lin =
exp(
s->segments[1].x);
264 s->out_min_lin =
exp(
s->segments[1].y);
265
266 return 0;
267 }
268
270 {
271 y[0] = x[0] * x[0];
272 y[1] = 2 * x[0] * x[1];
273 y[2] = 2 * x[0] * x[2] + x[1] * x[1];
274 y[3] = 2 * x[1] * x[2];
275 y[4] = x[2] * x[2];
276 }
277
279 {
281 double Q = sqrt(.5),
alpha = sin(w0) / (2*Q);
282 double x[9], norm;
284
287
288 x[0] = (1 - cos(w0))/2; /* Cf. filter_LPF in biquads.c */
289 x[1] = 1 - cos(w0);
290 x[2] = (1 - cos(w0))/2;
291 x[3] = (1 + cos(w0))/2; /* Cf. filter_HPF in biquads.c */
292 x[4] = -(1 + cos(w0));
293 x[5] = (1 + cos(w0))/2;
295 x[7] = -2*cos(w0);
297
298 for (norm = x[6],
i = 0;
i < 9; ++
i)
300
304
308
309 return 0;
310 }
311
313 {
316 int ret, ch,
i, k, new_nb_items, nb_bands;
317 char *p =
s->args, *saveptr =
NULL;
318 int max_delay_size = 0;
319
321 s->nb_bands =
FFMAX(1, nb_bands);
322
326
327 for (
i = 0, new_nb_items = 0;
i < nb_bands;
i++) {
328 int nb_points, nb_attacks, nb_items = 0;
329 char *tstr2, *tstr =
av_strtok(p,
"|", &saveptr);
330 char *p2, *p3, *saveptr2 =
NULL, *saveptr3 =
NULL;
331 double radius;
332
333 if (!tstr)
336
337 p2 = tstr;
340 if (!tstr2) {
343 }
345 p3 = tstr2;
346
348 if (!nb_attacks || nb_attacks & 1) {
351 }
352
356 if (!
s->bands[
i].attack_rate || !
s->bands[
i].decay_rate || !
s->bands[
i].volume)
358
359 for (k = 0; k <
FFMIN(nb_attacks / 2, outlink->
channels); k++) {
360 char *tstr3 =
av_strtok(p3,
",", &saveptr3);
361
363 sscanf(tstr3,
"%lf", &
s->bands[
i].attack_rate[k]);
365 sscanf(tstr3,
"%lf", &
s->bands[
i].decay_rate[k]);
366
367 if (
s->bands[
i].attack_rate[k] > 1.0 / outlink->
sample_rate) {
368 s->bands[
i].attack_rate[k] = 1.0 -
exp(-1.0 / (outlink->
sample_rate *
s->bands[
i].attack_rate[k]));
369 } else {
370 s->bands[
i].attack_rate[k] = 1.0;
371 }
372
373 if (
s->bands[
i].decay_rate[k] > 1.0 / outlink->
sample_rate) {
374 s->bands[
i].decay_rate[k] = 1.0 -
exp(-1.0 / (outlink->
sample_rate *
s->bands[
i].decay_rate[k]));
375 } else {
376 s->bands[
i].decay_rate[k] = 1.0;
377 }
378 }
379
380 for (ch = k; ch < outlink->
channels; ch++) {
381 s->bands[
i].attack_rate[ch] =
s->bands[
i].attack_rate[k - 1];
382 s->bands[
i].decay_rate[ch] =
s->bands[
i].decay_rate[k - 1];
383 }
384
386 if (!tstr2) {
389 }
390 sscanf(tstr2,
"%lf", &
s->bands[
i].transfer_fn.curve_dB);
391
392 radius =
s->bands[
i].transfer_fn.curve_dB *
M_LN10 / 20.0;
393
395 if (!tstr2) {
398 }
399
401 s->bands[
i].transfer_fn.nb_segments = (nb_points + 4) * 2;
402 s->bands[
i].transfer_fn.segments =
av_calloc(
s->bands[
i].transfer_fn.nb_segments,
404 if (!
s->bands[
i].transfer_fn.segments)
406
411 }
412
414 if (!tstr2) {
417 }
418
419 new_nb_items += sscanf(tstr2,
"%lf", &
s->bands[
i].topfreq) == 1;
420 if (
s->bands[
i].topfreq < 0 ||
s->bands[
i].topfreq >= outlink->
sample_rate / 2) {
423 }
424
425 if (
s->bands[
i].topfreq != 0) {
429 }
430
432 if (tstr2) {
433 sscanf(tstr2,
"%lf", &
s->bands[
i].delay);
435
437 if (tstr2) {
438 double initial_volume;
439
440 sscanf(tstr2, "%lf", &initial_volume);
441 initial_volume = pow(10.0, initial_volume / 20);
442
443 for (k = 0; k < outlink->
channels; k++) {
444 s->bands[
i].volume[k] = initial_volume;
445 }
446
448 if (tstr2) {
449 sscanf(tstr2,
"%lf", &
s->bands[
i].transfer_fn.gain_dB);
450 }
451 }
452 }
453 }
454 s->nb_bands = new_nb_items;
455
456 for (
i = 0; max_delay_size > 0 &&
i <
s->nb_bands;
i++) {
458 if (!
s->bands[
i].delay_buf)
460 }
461 s->delay_buf_size = max_delay_size;
462
463 return 0;
464 }
465
466 #define CONVOLVE _ _ _ _
467
469 double *ibuf, double *obuf_low,
470 double *obuf_high,
size_t len)
471 {
472 double out_low, out_high;
473
476 #define _ out_low += p->coefs[j] * p->previous[ch][p->pos + j].in \
477 - p->coefs[2*N+2 + j] * p->previous[ch][p->pos + j].out_low, j++;
478 {
479 int j = 1;
480 out_low = p->
coefs[0] * *ibuf;
482 *obuf_low++ = out_low;
483 }
484 #undef _
485 #define _ out_high += p->coefs[j+N+1] * p->previous[ch][p->pos + j].in \
486 - p->coefs[2*N+2 + j] * p->previous[ch][p->pos + j].out_high, j++;
487 {
488 int j = 1;
489 out_high = p->
coefs[
N+1] * *ibuf;
491 *obuf_high++ = out_high;
492 }
496 }
497 }
498
500 {
502
503 for (
i = 0;
i <
len;
i++) {
504 double level_in_lin, level_out_lin, checkbuf;
505 /* Maintain the volume fields by simulating a leaky pump circuit */
507
508 /* Volume memory is updated: perform compand */
509 level_in_lin = l->
volume[ch];
511
512 if (
c->delay_buf_size <= 0) {
513 checkbuf = ibuf[
i] * level_out_lin;
515 } else {
517
518 /* FIXME: note that this lookahead algorithm is really lame:
519 the response to a peak is released before the peak
520 arrives. */
521
522 /* because volume application delays differ band to band, but
523 total delay doesn't, the volume is applied in an iteration
524 preceding that in which the sample goes to obuf, except in
525 the band(s) with the longest vol app delay.
526
527 the offset between delay_buf_ptr and the sample to apply
528 vol to, is a constant equal to the difference between this
529 band's delay and the longest delay of all the bands. */
530
532 checkbuf =
535 l->
delay_size) %
c->delay_buf_size] * level_out_lin;
538 }
541 } else {
543 }
546 }
547 }
548
549 return 0;
550 }
551
553 {
559
564 }
565
570
575 }
576
577 for (ch = 0; ch < outlink->
channels; ch++) {
578 double *
a, *dst = (
double *)
out->extended_data[ch];
579
580 for (band = 0, abuf = in, bbuf =
s->band_buf2, cbuf =
s->band_buf1; band < s->nb_bands; band++) {
582
586 } else {
587 bbuf = abuf;
588 abuf = cbuf;
589 }
590
591 if (abuf == in)
597 }
598
600 }
601 }
602
606 }
607
609 {
612
614
616 }
617
619 {
623 },
624 };
625
627 {
632 },
633 };
634
635
639 "Multiband Compress or expand audio dynamic range."),
641 .priv_class = &mcompand_class,
646 };