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
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"
36 #include "audio.h"
37 #include "avfilter.h"
38 #include "internal.h"
39
40 typedef struct CompandSegment {
41 double x, y;
42 double a, b;
43 } CompandSegment;
44
45 typedef struct CompandT {
46 CompandSegment *segments;
47 int nb_segments;
48 double in_min_lin;
49 double out_min_lin;
50 double curve_dB;
51 double gain_dB;
52 } CompandT;
53
54 #define N 4
55
56 typedef struct PrevCrossover {
57 double in;
58 double out_low;
59 double out_high;
60 } PrevCrossover[N * 2];
61
62 typedef struct Crossover {
63 PrevCrossover *previous;
64 size_t pos;
65 double coefs[3 *(N+1)];
66 } Crossover;
67
68 typedef struct CompBand {
69 CompandT transfer_fn;
70 double *attack_rate;
71 double *decay_rate;
72 double *volume;
73 double delay;
74 double topfreq;
75 Crossover filter;
76 AVFrame *delay_buf;
77 size_t delay_size;
78 ptrdiff_t delay_buf_ptr;
79 size_t delay_buf_cnt;
80 } CompBand;
81
82 typedef struct MCompandContext {
83 const AVClass *class;
84
85 char *args;
86
87 int nb_bands;
88 CompBand *bands;
89 AVFrame *band_buf1, *band_buf2, *band_buf3;
90 int band_samples;
91 size_t delay_buf_size;
92 } MCompandContext;
93
94 #define OFFSET(x) offsetof(MCompandContext, x)
95 #define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
96
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 },
99 { NULL }
100 };
101
102 AVFILTER_DEFINE_CLASS(mcompand);
103
uninit(AVFilterContext * ctx)104 static av_cold void uninit(AVFilterContext *ctx)
105 {
106 MCompandContext *s = ctx->priv;
107 int i;
108
109 av_frame_free(&s->band_buf1);
110 av_frame_free(&s->band_buf2);
111 av_frame_free(&s->band_buf3);
112
113 if (s->bands) {
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);
121 }
122 }
123 av_freep(&s->bands);
124 }
125
query_formats(AVFilterContext * ctx)126 static int query_formats(AVFilterContext *ctx)
127 {
128 AVFilterChannelLayouts *layouts;
129 AVFilterFormats *formats;
130 static const enum AVSampleFormat sample_fmts[] = {
131 AV_SAMPLE_FMT_DBLP,
132 AV_SAMPLE_FMT_NONE
133 };
134 int ret;
135
136 layouts = ff_all_channel_counts();
137 if (!layouts)
138 return AVERROR(ENOMEM);
139 ret = ff_set_common_channel_layouts(ctx, layouts);
140 if (ret < 0)
141 return ret;
142
143 formats = ff_make_format_list(sample_fmts);
144 if (!formats)
145 return AVERROR(ENOMEM);
146 ret = ff_set_common_formats(ctx, formats);
147 if (ret < 0)
148 return ret;
149
150 formats = ff_all_samplerates();
151 if (!formats)
152 return AVERROR(ENOMEM);
153 return ff_set_common_samplerates(ctx, formats);
154 }
155
count_items(char * item_str,int * nb_items,char delimiter)156 static void count_items(char *item_str, int *nb_items, char delimiter)
157 {
158 char *p;
159
160 *nb_items = 1;
161 for (p = item_str; *p; p++) {
162 if (*p == delimiter)
163 (*nb_items)++;
164 }
165 }
166
update_volume(CompBand * cb,double in,int ch)167 static void update_volume(CompBand *cb, double in, int ch)
168 {
169 double delta = in - cb->volume[ch];
170
171 if (delta > 0.0)
172 cb->volume[ch] += delta * cb->attack_rate[ch];
173 else
174 cb->volume[ch] += delta * cb->decay_rate[ch];
175 }
176
get_volume(CompandT * s,double in_lin)177 static double get_volume(CompandT *s, double in_lin)
178 {
179 CompandSegment *cs;
180 double in_log, out_log;
181 int i;
182
183 if (in_lin <= s->in_min_lin)
184 return s->out_min_lin;
185
186 in_log = log(in_lin);
187
188 for (i = 1; i < s->nb_segments; i++)
189 if (in_log <= s->segments[i].x)
190 break;
191 cs = &s->segments[i - 1];
192 in_log -= cs->x;
193 out_log = cs->y + in_log * (cs->a * in_log + cs->b);
194
195 return exp(out_log);
196 }
197
parse_points(char * points,int nb_points,double radius,CompandT * s,AVFilterContext * ctx)198 static int parse_points(char *points, int nb_points, double radius,
199 CompandT *s, AVFilterContext *ctx)
200 {
201 int new_nb_items, num;
202 char *saveptr = NULL;
203 char *p = points;
204 int i;
205
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);
209 p = NULL;
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);
214 }
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);
219 }
220 S(i).y -= S(i).x;
221 av_log(ctx, AV_LOG_DEBUG, "%d: x=%f y=%f\n", i, S(i).x, S(i).y);
222 new_nb_items++;
223 }
224 num = new_nb_items;
225
226 /* Add 0,0 if necessary */
227 if (num == 0 || S(num - 1).x)
228 num++;
229
230 #undef S
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;
234 S(0).y = S(1).y;
235 num++;
236
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);
241 int j;
242
243 if (fabs(g1 - g2))
244 continue;
245 num--;
246 for (j = --i; j < num; j++)
247 S(j) = S(j + 1);
248 }
249
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;
254 }
255
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;
259
260 L(4).a = 0;
261 L(4).b = (L(2).y - L(4).y) / (L(2).x - L(4).x);
262
263 L(2).a = 0;
264 L(2).b = (L(0).y - L(2).y) / (L(0).x - L(2).x);
265
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);
271
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);
277
278 cx = (L(3).x + L(2).x + x) / 3;
279 cy = (L(3).y + L(2).y + y) / 3;
280
281 L(2).x = x;
282 L(2).y = y;
283
284 in1 = cx - L(3).x;
285 out1 = cy - L(3).y;
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;
290 }
291 L(3).x = 0;
292 L(3).y = L(2).y;
293
294 s->in_min_lin = exp(s->segments[1].x);
295 s->out_min_lin = exp(s->segments[1].y);
296
297 return 0;
298 }
299
square_quadratic(double const * x,double * y)300 static void square_quadratic(double const *x, double *y)
301 {
302 y[0] = x[0] * x[0];
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];
306 y[4] = x[2] * x[2];
307 }
308
crossover_setup(AVFilterLink * outlink,Crossover * p,double frequency)309 static int crossover_setup(AVFilterLink *outlink, Crossover *p, double frequency)
310 {
311 double w0 = 2 * M_PI * frequency / outlink->sample_rate;
312 double Q = sqrt(.5), alpha = sin(w0) / (2*Q);
313 double x[9], norm;
314 int i;
315
316 if (w0 > M_PI)
317 return AVERROR(EINVAL);
318
319 x[0] = (1 - cos(w0))/2; /* Cf. filter_LPF in biquads.c */
320 x[1] = 1 - cos(w0);
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;
325 x[6] = 1 + alpha;
326 x[7] = -2*cos(w0);
327 x[8] = 1 - alpha;
328
329 for (norm = x[6], i = 0; i < 9; ++i)
330 x[i] /= norm;
331
332 square_quadratic(x , p->coefs);
333 square_quadratic(x + 3, p->coefs + 5);
334 square_quadratic(x + 6, p->coefs + 10);
335
336 p->previous = av_calloc(outlink->channels, sizeof(*p->previous));
337 if (!p->previous)
338 return AVERROR(ENOMEM);
339
340 return 0;
341 }
342
config_output(AVFilterLink * outlink)343 static int config_output(AVFilterLink *outlink)
344 {
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;
350
351 count_items(s->args, &nb_bands, '|');
352 s->nb_bands = FFMAX(1, nb_bands);
353
354 s->bands = av_calloc(nb_bands, sizeof(*s->bands));
355 if (!s->bands)
356 return AVERROR(ENOMEM);
357
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;
362 double radius;
363
364 if (!tstr)
365 return AVERROR(EINVAL);
366 p = NULL;
367
368 p2 = tstr;
369 count_items(tstr, &nb_items, ' ');
370 tstr2 = av_strtok(p2, " ", &saveptr2);
371 if (!tstr2) {
372 av_log(ctx, AV_LOG_ERROR, "at least one attacks/decays rate is mandatory\n");
373 return AVERROR(EINVAL);
374 }
375 p2 = NULL;
376 p3 = tstr2;
377
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);
382 }
383
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);
389
390 p3 = NULL;
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]);
394
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]));
397 } else {
398 s->bands[i].attack_rate[k] = 1.0;
399 }
400
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]));
403 } else {
404 s->bands[i].decay_rate[k] = 1.0;
405 }
406 }
407
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];
411 }
412
413 tstr2 = av_strtok(p2, " ", &saveptr2);
414 if (!tstr2) {
415 av_log(ctx, AV_LOG_ERROR, "transfer function curve in dB must be set\n");
416 return AVERROR(EINVAL);
417 }
418 sscanf(tstr2, "%lf", &s->bands[i].transfer_fn.curve_dB);
419
420 radius = s->bands[i].transfer_fn.curve_dB * M_LN10 / 20.0;
421
422 tstr2 = av_strtok(p2, " ", &saveptr2);
423 if (!tstr2) {
424 av_log(ctx, AV_LOG_ERROR, "transfer points missing\n");
425 return AVERROR(EINVAL);
426 }
427
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);
434
435 ret = parse_points(tstr2, nb_points, radius, &s->bands[i].transfer_fn, ctx);
436 if (ret < 0) {
437 av_log(ctx, AV_LOG_ERROR, "transfer points parsing failed\n");
438 return ret;
439 }
440
441 tstr2 = av_strtok(p2, " ", &saveptr2);
442 if (!tstr2) {
443 av_log(ctx, AV_LOG_ERROR, "crossover_frequency is missing\n");
444 return AVERROR(EINVAL);
445 }
446
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);
451 }
452
453 if (s->bands[i].topfreq != 0) {
454 ret = crossover_setup(outlink, &s->bands[i].filter, s->bands[i].topfreq);
455 if (ret < 0)
456 return ret;
457 }
458
459 tstr2 = av_strtok(p2, " ", &saveptr2);
460 if (tstr2) {
461 sscanf(tstr2, "%lf", &s->bands[i].delay);
462 max_delay_size = FFMAX(max_delay_size, s->bands[i].delay * outlink->sample_rate);
463
464 tstr2 = av_strtok(p2, " ", &saveptr2);
465 if (tstr2) {
466 double initial_volume;
467
468 sscanf(tstr2, "%lf", &initial_volume);
469 initial_volume = pow(10.0, initial_volume / 20);
470
471 for (k = 0; k < outlink->channels; k++) {
472 s->bands[i].volume[k] = initial_volume;
473 }
474
475 tstr2 = av_strtok(p2, " ", &saveptr2);
476 if (tstr2) {
477 sscanf(tstr2, "%lf", &s->bands[i].transfer_fn.gain_dB);
478 }
479 }
480 }
481 }
482 s->nb_bands = new_nb_items;
483
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);
488 }
489 s->delay_buf_size = max_delay_size;
490
491 return 0;
492 }
493
494 #define CONVOLVE _ _ _ _
495
crossover(int ch,Crossover * p,double * ibuf,double * obuf_low,double * obuf_high,size_t len)496 static void crossover(int ch, Crossover *p,
497 double *ibuf, double *obuf_low,
498 double *obuf_high, size_t len)
499 {
500 double out_low, out_high;
501
502 while (len--) {
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++;
506 {
507 int j = 1;
508 out_low = p->coefs[0] * *ibuf;
509 CONVOLVE
510 *obuf_low++ = out_low;
511 }
512 #undef _
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++;
515 {
516 int j = 1;
517 out_high = p->coefs[N+1] * *ibuf;
518 CONVOLVE
519 *obuf_high++ = out_high;
520 }
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;
524 }
525 }
526
mcompand_channel(MCompandContext * c,CompBand * l,double * ibuf,double * obuf,int len,int ch)527 static int mcompand_channel(MCompandContext *c, CompBand *l, double *ibuf, double *obuf, int len, int ch)
528 {
529 int i;
530
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);
535
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);
539
540 if (c->delay_buf_size <= 0) {
541 checkbuf = ibuf[i] * level_out_lin;
542 obuf[i] = checkbuf;
543 } else {
544 double *delay_buf = (double *)l->delay_buf->extended_data[ch];
545
546 /* FIXME: note that this lookahead algorithm is really lame:
547 the response to a peak is released before the peak
548 arrives. */
549
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.
554
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. */
558
559 if (l->delay_buf_cnt >= l->delay_size) {
560 checkbuf =
561 delay_buf[(l->delay_buf_ptr +
562 c->delay_buf_size -
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;
566 }
567 if (l->delay_buf_cnt >= c->delay_buf_size) {
568 obuf[i] = delay_buf[l->delay_buf_ptr];
569 } else {
570 l->delay_buf_cnt++;
571 }
572 delay_buf[l->delay_buf_ptr++] = ibuf[i];
573 l->delay_buf_ptr %= c->delay_buf_size;
574 }
575 }
576
577 return 0;
578 }
579
filter_frame(AVFilterLink * inlink,AVFrame * in)580 static int filter_frame(AVFilterLink *inlink, AVFrame *in)
581 {
582 AVFilterContext *ctx = inlink->dst;
583 AVFilterLink *outlink = ctx->outputs[0];
584 MCompandContext *s = ctx->priv;
585 AVFrame *out, *abuf, *bbuf, *cbuf;
586 int ch, band, i;
587
588 out = ff_get_audio_buffer(outlink, in->nb_samples);
589 if (!out) {
590 av_frame_free(&in);
591 return AVERROR(ENOMEM);
592 }
593
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);
598
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;
603 }
604
605 for (ch = 0; ch < outlink->channels; ch++) {
606 double *a, *dst = (double *)out->extended_data[ch];
607
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];
610
611 if (b->topfreq) {
612 crossover(ch, &b->filter, (double *)abuf->extended_data[ch],
613 (double *)bbuf->extended_data[ch], (double *)cbuf->extended_data[ch], in->nb_samples);
614 } else {
615 bbuf = abuf;
616 abuf = cbuf;
617 }
618
619 if (abuf == in)
620 abuf = s->band_buf3;
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++) {
624 dst[i] += a[i];
625 }
626
627 FFSWAP(AVFrame *, abuf, cbuf);
628 }
629 }
630
631 out->pts = in->pts;
632 av_frame_free(&in);
633 return ff_filter_frame(outlink, out);
634 }
635
request_frame(AVFilterLink * outlink)636 static int request_frame(AVFilterLink *outlink)
637 {
638 AVFilterContext *ctx = outlink->src;
639 int ret;
640
641 ret = ff_request_frame(ctx->inputs[0]);
642
643 return ret;
644 }
645
646 static const AVFilterPad mcompand_inputs[] = {
647 {
648 .name = "default",
649 .type = AVMEDIA_TYPE_AUDIO,
650 .filter_frame = filter_frame,
651 },
652 { NULL }
653 };
654
655 static const AVFilterPad mcompand_outputs[] = {
656 {
657 .name = "default",
658 .type = AVMEDIA_TYPE_AUDIO,
659 .request_frame = request_frame,
660 .config_props = config_output,
661 },
662 { NULL }
663 };
664
665
666 AVFilter ff_af_mcompand = {
667 .name = "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,
673 .uninit = uninit,
674 .inputs = mcompand_inputs,
675 .outputs = mcompand_outputs,
676 };
677