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