GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavfilter/af_mcompand.c Lines: 0 327 0.0 %
Date: 2020-08-14 10:39:37 Branches: 0 140 0.0 %

Line Branch Exec Source
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
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
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
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
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
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
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
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
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
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
            uninit(ctx);
366
            return AVERROR(EINVAL);
367
        }
368
        p = NULL;
369
370
        p2 = tstr;
371
        count_items(tstr, &nb_items, ' ');
372
        tstr2 = av_strtok(p2, " ", &saveptr2);
373
        if (!tstr2) {
374
            av_log(ctx, AV_LOG_ERROR, "at least one attacks/decays rate is mandatory\n");
375
            uninit(ctx);
376
            return AVERROR(EINVAL);
377
        }
378
        p2 = NULL;
379
        p3 = tstr2;
380
381
        count_items(tstr2, &nb_attacks, ',');
382
        if (!nb_attacks || nb_attacks & 1) {
383
            av_log(ctx, AV_LOG_ERROR, "number of attacks rate plus decays rate must be even\n");
384
            uninit(ctx);
385
            return AVERROR(EINVAL);
386
        }
387
388
        s->bands[i].attack_rate = av_calloc(outlink->channels, sizeof(double));
389
        s->bands[i].decay_rate = av_calloc(outlink->channels, sizeof(double));
390
        s->bands[i].volume = av_calloc(outlink->channels, sizeof(double));
391
        for (k = 0; k < FFMIN(nb_attacks / 2, outlink->channels); k++) {
392
            char *tstr3 = av_strtok(p3, ",", &saveptr3);
393
394
            p3 = NULL;
395
            sscanf(tstr3, "%lf", &s->bands[i].attack_rate[k]);
396
            tstr3 = av_strtok(p3, ",", &saveptr3);
397
            sscanf(tstr3, "%lf", &s->bands[i].decay_rate[k]);
398
399
            if (s->bands[i].attack_rate[k] > 1.0 / outlink->sample_rate) {
400
                s->bands[i].attack_rate[k] = 1.0 - exp(-1.0 / (outlink->sample_rate * s->bands[i].attack_rate[k]));
401
            } else {
402
                s->bands[i].attack_rate[k] = 1.0;
403
            }
404
405
            if (s->bands[i].decay_rate[k] > 1.0 / outlink->sample_rate) {
406
                s->bands[i].decay_rate[k] = 1.0 - exp(-1.0 / (outlink->sample_rate * s->bands[i].decay_rate[k]));
407
            } else {
408
                s->bands[i].decay_rate[k] = 1.0;
409
            }
410
        }
411
412
        for (ch = k; ch < outlink->channels; ch++) {
413
            s->bands[i].attack_rate[ch] = s->bands[i].attack_rate[k - 1];
414
            s->bands[i].decay_rate[ch]  = s->bands[i].decay_rate[k - 1];
415
        }
416
417
        tstr2 = av_strtok(p2, " ", &saveptr2);
418
        if (!tstr2) {
419
            av_log(ctx, AV_LOG_ERROR, "transfer function curve in dB must be set\n");
420
            uninit(ctx);
421
            return AVERROR(EINVAL);
422
        }
423
        sscanf(tstr2, "%lf", &s->bands[i].transfer_fn.curve_dB);
424
425
        radius = s->bands[i].transfer_fn.curve_dB * M_LN10 / 20.0;
426
427
        tstr2 = av_strtok(p2, " ", &saveptr2);
428
        if (!tstr2) {
429
            av_log(ctx, AV_LOG_ERROR, "transfer points missing\n");
430
            uninit(ctx);
431
            return AVERROR(EINVAL);
432
        }
433
434
        count_items(tstr2, &nb_points, ',');
435
        s->bands[i].transfer_fn.nb_segments = (nb_points + 4) * 2;
436
        s->bands[i].transfer_fn.segments = av_calloc(s->bands[i].transfer_fn.nb_segments,
437
                                                     sizeof(CompandSegment));
438
        if (!s->bands[i].transfer_fn.segments) {
439
            uninit(ctx);
440
            return AVERROR(ENOMEM);
441
        }
442
443
        ret = parse_points(tstr2, nb_points, radius, &s->bands[i].transfer_fn, ctx);
444
        if (ret < 0) {
445
            av_log(ctx, AV_LOG_ERROR, "transfer points parsing failed\n");
446
            uninit(ctx);
447
            return ret;
448
        }
449
450
        tstr2 = av_strtok(p2, " ", &saveptr2);
451
        if (!tstr2) {
452
            av_log(ctx, AV_LOG_ERROR, "crossover_frequency is missing\n");
453
            uninit(ctx);
454
            return AVERROR(EINVAL);
455
        }
456
457
        new_nb_items += sscanf(tstr2, "%lf", &s->bands[i].topfreq) == 1;
458
        if (s->bands[i].topfreq < 0 || s->bands[i].topfreq >= outlink->sample_rate / 2) {
459
            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);
460
            uninit(ctx);
461
            return AVERROR(EINVAL);
462
        }
463
464
        if (s->bands[i].topfreq != 0) {
465
            ret = crossover_setup(outlink, &s->bands[i].filter, s->bands[i].topfreq);
466
            if (ret < 0) {
467
                uninit(ctx);
468
                return ret;
469
            }
470
        }
471
472
        tstr2 = av_strtok(p2, " ", &saveptr2);
473
        if (tstr2) {
474
            sscanf(tstr2, "%lf", &s->bands[i].delay);
475
            max_delay_size = FFMAX(max_delay_size, s->bands[i].delay * outlink->sample_rate);
476
477
            tstr2 = av_strtok(p2, " ", &saveptr2);
478
            if (tstr2) {
479
                double initial_volume;
480
481
                sscanf(tstr2, "%lf", &initial_volume);
482
                initial_volume = pow(10.0, initial_volume / 20);
483
484
                for (k = 0; k < outlink->channels; k++) {
485
                    s->bands[i].volume[k] = initial_volume;
486
                }
487
488
                tstr2 = av_strtok(p2, " ", &saveptr2);
489
                if (tstr2) {
490
                    sscanf(tstr2, "%lf", &s->bands[i].transfer_fn.gain_dB);
491
                }
492
            }
493
        }
494
    }
495
    s->nb_bands = new_nb_items;
496
497
    for (i = 0; max_delay_size > 0 && i < s->nb_bands; i++) {
498
        s->bands[i].delay_buf = ff_get_audio_buffer(outlink, max_delay_size);
499
        if (!s->bands[i].delay_buf)
500
            return AVERROR(ENOMEM);
501
    }
502
    s->delay_buf_size = max_delay_size;
503
504
    return 0;
505
}
506
507
#define CONVOLVE _ _ _ _
508
509
static void crossover(int ch, Crossover *p,
510
                      double *ibuf, double *obuf_low,
511
                      double *obuf_high, size_t len)
512
{
513
    double out_low, out_high;
514
515
    while (len--) {
516
        p->pos = p->pos ? p->pos - 1 : N - 1;
517
#define _ out_low += p->coefs[j] * p->previous[ch][p->pos + j].in \
518
            - p->coefs[2*N+2 + j] * p->previous[ch][p->pos + j].out_low, j++;
519
        {
520
            int j = 1;
521
            out_low = p->coefs[0] * *ibuf;
522
            CONVOLVE
523
            *obuf_low++ = out_low;
524
        }
525
#undef _
526
#define _ out_high += p->coefs[j+N+1] * p->previous[ch][p->pos + j].in \
527
            - p->coefs[2*N+2 + j] * p->previous[ch][p->pos + j].out_high, j++;
528
        {
529
            int j = 1;
530
            out_high = p->coefs[N+1] * *ibuf;
531
            CONVOLVE
532
            *obuf_high++ = out_high;
533
        }
534
        p->previous[ch][p->pos + N].in = p->previous[ch][p->pos].in = *ibuf++;
535
        p->previous[ch][p->pos + N].out_low = p->previous[ch][p->pos].out_low = out_low;
536
        p->previous[ch][p->pos + N].out_high = p->previous[ch][p->pos].out_high = out_high;
537
    }
538
}
539
540
static int mcompand_channel(MCompandContext *c, CompBand *l, double *ibuf, double *obuf, int len, int ch)
541
{
542
    int i;
543
544
    for (i = 0; i < len; i++) {
545
        double level_in_lin, level_out_lin, checkbuf;
546
        /* Maintain the volume fields by simulating a leaky pump circuit */
547
        update_volume(l, fabs(ibuf[i]), ch);
548
549
        /* Volume memory is updated: perform compand */
550
        level_in_lin = l->volume[ch];
551
        level_out_lin = get_volume(&l->transfer_fn, level_in_lin);
552
553
        if (c->delay_buf_size <= 0) {
554
            checkbuf = ibuf[i] * level_out_lin;
555
            obuf[i] = checkbuf;
556
        } else {
557
            double *delay_buf = (double *)l->delay_buf->extended_data[ch];
558
559
            /* FIXME: note that this lookahead algorithm is really lame:
560
               the response to a peak is released before the peak
561
               arrives. */
562
563
            /* because volume application delays differ band to band, but
564
               total delay doesn't, the volume is applied in an iteration
565
               preceding that in which the sample goes to obuf, except in
566
               the band(s) with the longest vol app delay.
567
568
               the offset between delay_buf_ptr and the sample to apply
569
               vol to, is a constant equal to the difference between this
570
               band's delay and the longest delay of all the bands. */
571
572
            if (l->delay_buf_cnt >= l->delay_size) {
573
                checkbuf =
574
                    delay_buf[(l->delay_buf_ptr +
575
                               c->delay_buf_size -
576
                               l->delay_size) % c->delay_buf_size] * level_out_lin;
577
                delay_buf[(l->delay_buf_ptr + c->delay_buf_size -
578
                           l->delay_size) % c->delay_buf_size] = checkbuf;
579
            }
580
            if (l->delay_buf_cnt >= c->delay_buf_size) {
581
                obuf[i] = delay_buf[l->delay_buf_ptr];
582
            } else {
583
                l->delay_buf_cnt++;
584
            }
585
            delay_buf[l->delay_buf_ptr++] = ibuf[i];
586
            l->delay_buf_ptr %= c->delay_buf_size;
587
        }
588
    }
589
590
    return 0;
591
}
592
593
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
594
{
595
    AVFilterContext  *ctx = inlink->dst;
596
    AVFilterLink *outlink = ctx->outputs[0];
597
    MCompandContext *s    = ctx->priv;
598
    AVFrame *out, *abuf, *bbuf, *cbuf;
599
    int ch, band, i;
600
601
    out = ff_get_audio_buffer(outlink, in->nb_samples);
602
    if (!out) {
603
        av_frame_free(&in);
604
        return AVERROR(ENOMEM);
605
    }
606
607
    if (s->band_samples < in->nb_samples) {
608
        av_frame_free(&s->band_buf1);
609
        av_frame_free(&s->band_buf2);
610
        av_frame_free(&s->band_buf3);
611
612
        s->band_buf1 = ff_get_audio_buffer(outlink, in->nb_samples);
613
        s->band_buf2 = ff_get_audio_buffer(outlink, in->nb_samples);
614
        s->band_buf3 = ff_get_audio_buffer(outlink, in->nb_samples);
615
        s->band_samples = in->nb_samples;
616
    }
617
618
    for (ch = 0; ch < outlink->channels; ch++) {
619
        double *a, *dst = (double *)out->extended_data[ch];
620
621
        for (band = 0, abuf = in, bbuf = s->band_buf2, cbuf = s->band_buf1; band < s->nb_bands; band++) {
622
            CompBand *b = &s->bands[band];
623
624
            if (b->topfreq) {
625
                crossover(ch, &b->filter, (double *)abuf->extended_data[ch],
626
                          (double *)bbuf->extended_data[ch], (double *)cbuf->extended_data[ch], in->nb_samples);
627
            } else {
628
                bbuf = abuf;
629
                abuf = cbuf;
630
            }
631
632
            if (abuf == in)
633
                abuf = s->band_buf3;
634
            mcompand_channel(s, b, (double *)bbuf->extended_data[ch], (double *)abuf->extended_data[ch], out->nb_samples, ch);
635
            a = (double *)abuf->extended_data[ch];
636
            for (i = 0; i < out->nb_samples; i++) {
637
                dst[i] += a[i];
638
            }
639
640
            FFSWAP(AVFrame *, abuf, cbuf);
641
        }
642
    }
643
644
    out->pts = in->pts;
645
    av_frame_free(&in);
646
    return ff_filter_frame(outlink, out);
647
}
648
649
static int request_frame(AVFilterLink *outlink)
650
{
651
    AVFilterContext *ctx = outlink->src;
652
    int ret;
653
654
    ret = ff_request_frame(ctx->inputs[0]);
655
656
    return ret;
657
}
658
659
static const AVFilterPad mcompand_inputs[] = {
660
    {
661
        .name           = "default",
662
        .type           = AVMEDIA_TYPE_AUDIO,
663
        .filter_frame   = filter_frame,
664
    },
665
    { NULL }
666
};
667
668
static const AVFilterPad mcompand_outputs[] = {
669
    {
670
        .name          = "default",
671
        .type          = AVMEDIA_TYPE_AUDIO,
672
        .request_frame = request_frame,
673
        .config_props  = config_output,
674
    },
675
    { NULL }
676
};
677
678
679
AVFilter ff_af_mcompand = {
680
    .name           = "mcompand",
681
    .description    = NULL_IF_CONFIG_SMALL(
682
            "Multiband Compress or expand audio dynamic range."),
683
    .query_formats  = query_formats,
684
    .priv_size      = sizeof(MCompandContext),
685
    .priv_class     = &mcompand_class,
686
    .uninit         = uninit,
687
    .inputs         = mcompand_inputs,
688
    .outputs        = mcompand_outputs,
689
};