GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavfilter/af_mcompand.c Lines: 0 317 0.0 %
Date: 2020-10-23 17:01:47 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
            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
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
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
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
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
};