• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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