GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavfilter/af_biquads.c Lines: 0 305 0.0 %
Date: 2020-09-25 23:16:12 Branches: 0 205 0.0 %

Line Branch Exec Source
1
/*
2
 * Copyright (c) 2013 Paul B Mahol
3
 * Copyright (c) 2006-2008 Rob Sykes <robs@users.sourceforge.net>
4
 *
5
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with FFmpeg; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21
22
/*
23
 * 2-pole filters designed by Robert Bristow-Johnson <rbj@audioimagination.com>
24
 *   see http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt
25
 *
26
 * 1-pole filters based on code (c) 2000 Chris Bagwell <cbagwell@sprynet.com>
27
 *   Algorithms: Recursive single pole low/high pass filter
28
 *   Reference: The Scientist and Engineer's Guide to Digital Signal Processing
29
 *
30
 *   low-pass: output[N] = input[N] * A + output[N-1] * B
31
 *     X = exp(-2.0 * pi * Fc)
32
 *     A = 1 - X
33
 *     B = X
34
 *     Fc = cutoff freq / sample rate
35
 *
36
 *     Mimics an RC low-pass filter:
37
 *
38
 *     ---/\/\/\/\----------->
39
 *                   |
40
 *                  --- C
41
 *                  ---
42
 *                   |
43
 *                   |
44
 *                   V
45
 *
46
 *   high-pass: output[N] = A0 * input[N] + A1 * input[N-1] + B1 * output[N-1]
47
 *     X  = exp(-2.0 * pi * Fc)
48
 *     A0 = (1 + X) / 2
49
 *     A1 = -(1 + X) / 2
50
 *     B1 = X
51
 *     Fc = cutoff freq / sample rate
52
 *
53
 *     Mimics an RC high-pass filter:
54
 *
55
 *         || C
56
 *     ----||--------->
57
 *         ||    |
58
 *               <
59
 *               > R
60
 *               <
61
 *               |
62
 *               V
63
 */
64
65
#include "libavutil/avassert.h"
66
#include "libavutil/ffmath.h"
67
#include "libavutil/opt.h"
68
#include "audio.h"
69
#include "avfilter.h"
70
#include "internal.h"
71
72
enum FilterType {
73
    biquad,
74
    equalizer,
75
    bass,
76
    treble,
77
    bandpass,
78
    bandreject,
79
    allpass,
80
    highpass,
81
    lowpass,
82
    lowshelf,
83
    highshelf,
84
};
85
86
enum WidthType {
87
    NONE,
88
    HERTZ,
89
    OCTAVE,
90
    QFACTOR,
91
    SLOPE,
92
    KHERTZ,
93
    NB_WTYPE,
94
};
95
96
enum TransformType {
97
    DI,
98
    DII,
99
    TDII,
100
    NB_TTYPE,
101
};
102
103
typedef struct ChanCache {
104
    double i1, i2;
105
    double o1, o2;
106
    int clippings;
107
} ChanCache;
108
109
typedef struct BiquadsContext {
110
    const AVClass *class;
111
112
    enum FilterType filter_type;
113
    int width_type;
114
    int poles;
115
    int csg;
116
    int transform_type;
117
118
    double gain;
119
    double frequency;
120
    double width;
121
    double mix;
122
    uint64_t channels;
123
    int normalize;
124
    int order;
125
126
    double a0, a1, a2;
127
    double b0, b1, b2;
128
129
    ChanCache *cache;
130
    int block_align;
131
132
    void (*filter)(struct BiquadsContext *s, const void *ibuf, void *obuf, int len,
133
                   double *i1, double *i2, double *o1, double *o2,
134
                   double b0, double b1, double b2, double a1, double a2, int *clippings,
135
                   int disabled);
136
} BiquadsContext;
137
138
static av_cold int init(AVFilterContext *ctx)
139
{
140
    BiquadsContext *s = ctx->priv;
141
142
    if (s->filter_type != biquad) {
143
        if (s->frequency <= 0 || s->width <= 0) {
144
            av_log(ctx, AV_LOG_ERROR, "Invalid frequency %f and/or width %f <= 0\n",
145
                   s->frequency, s->width);
146
            return AVERROR(EINVAL);
147
        }
148
    }
149
150
    return 0;
151
}
152
153
static int query_formats(AVFilterContext *ctx)
154
{
155
    AVFilterFormats *formats;
156
    AVFilterChannelLayouts *layouts;
157
    static const enum AVSampleFormat sample_fmts[] = {
158
        AV_SAMPLE_FMT_S16P,
159
        AV_SAMPLE_FMT_S32P,
160
        AV_SAMPLE_FMT_FLTP,
161
        AV_SAMPLE_FMT_DBLP,
162
        AV_SAMPLE_FMT_NONE
163
    };
164
    int ret;
165
166
    layouts = ff_all_channel_counts();
167
    if (!layouts)
168
        return AVERROR(ENOMEM);
169
    ret = ff_set_common_channel_layouts(ctx, layouts);
170
    if (ret < 0)
171
        return ret;
172
173
    formats = ff_make_format_list(sample_fmts);
174
    if (!formats)
175
        return AVERROR(ENOMEM);
176
    ret = ff_set_common_formats(ctx, formats);
177
    if (ret < 0)
178
        return ret;
179
180
    formats = ff_all_samplerates();
181
    if (!formats)
182
        return AVERROR(ENOMEM);
183
    return ff_set_common_samplerates(ctx, formats);
184
}
185
186
#define BIQUAD_FILTER(name, type, min, max, need_clipping)                    \
187
static void biquad_## name (BiquadsContext *s,                                \
188
                            const void *input, void *output, int len,         \
189
                            double *in1, double *in2,                         \
190
                            double *out1, double *out2,                       \
191
                            double b0, double b1, double b2,                  \
192
                            double a1, double a2, int *clippings,             \
193
                            int disabled)                                     \
194
{                                                                             \
195
    const type *ibuf = input;                                                 \
196
    type *obuf = output;                                                      \
197
    double i1 = *in1;                                                         \
198
    double i2 = *in2;                                                         \
199
    double o1 = *out1;                                                        \
200
    double o2 = *out2;                                                        \
201
    double wet = s->mix;                                                      \
202
    double dry = 1. - wet;                                                    \
203
    double out;                                                               \
204
    int i;                                                                    \
205
    a1 = -a1;                                                                 \
206
    a2 = -a2;                                                                 \
207
                                                                              \
208
    for (i = 0; i+1 < len; i++) {                                             \
209
        o2 = i2 * b2 + i1 * b1 + ibuf[i] * b0 + o2 * a2 + o1 * a1;            \
210
        i2 = ibuf[i];                                                         \
211
        out = o2 * wet + i2 * dry;                                            \
212
        if (disabled) {                                                       \
213
            obuf[i] = i2;                                                     \
214
        } else if (need_clipping && out < min) {                              \
215
            (*clippings)++;                                                   \
216
            obuf[i] = min;                                                    \
217
        } else if (need_clipping && out > max) {                              \
218
            (*clippings)++;                                                   \
219
            obuf[i] = max;                                                    \
220
        } else {                                                              \
221
            obuf[i] = out;                                                    \
222
        }                                                                     \
223
        i++;                                                                  \
224
        o1 = i1 * b2 + i2 * b1 + ibuf[i] * b0 + o1 * a2 + o2 * a1;            \
225
        i1 = ibuf[i];                                                         \
226
        out = o1 * wet + i1 * dry;                                            \
227
        if (disabled) {                                                       \
228
            obuf[i] = i1;                                                     \
229
        } else if (need_clipping && out < min) {                              \
230
            (*clippings)++;                                                   \
231
            obuf[i] = min;                                                    \
232
        } else if (need_clipping && out > max) {                              \
233
            (*clippings)++;                                                   \
234
            obuf[i] = max;                                                    \
235
        } else {                                                              \
236
            obuf[i] = out;                                                    \
237
        }                                                                     \
238
    }                                                                         \
239
    if (i < len) {                                                            \
240
        double o0 = ibuf[i] * b0 + i1 * b1 + i2 * b2 + o1 * a1 + o2 * a2;     \
241
        i2 = i1;                                                              \
242
        i1 = ibuf[i];                                                         \
243
        o2 = o1;                                                              \
244
        o1 = o0;                                                              \
245
        out = o0 * wet + i1 * dry;                                            \
246
        if (disabled) {                                                       \
247
            obuf[i] = i1;                                                     \
248
        } else if (need_clipping && out < min) {                              \
249
            (*clippings)++;                                                   \
250
            obuf[i] = min;                                                    \
251
        } else if (need_clipping && out > max) {                              \
252
            (*clippings)++;                                                   \
253
            obuf[i] = max;                                                    \
254
        } else {                                                              \
255
            obuf[i] = out;                                                    \
256
        }                                                                     \
257
    }                                                                         \
258
    *in1  = i1;                                                               \
259
    *in2  = i2;                                                               \
260
    *out1 = o1;                                                               \
261
    *out2 = o2;                                                               \
262
}
263
264
BIQUAD_FILTER(s16, int16_t, INT16_MIN, INT16_MAX, 1)
265
BIQUAD_FILTER(s32, int32_t, INT32_MIN, INT32_MAX, 1)
266
BIQUAD_FILTER(flt, float,   -1., 1., 0)
267
BIQUAD_FILTER(dbl, double,  -1., 1., 0)
268
269
#define BIQUAD_DII_FILTER(name, type, min, max, need_clipping)                \
270
static void biquad_dii_## name (BiquadsContext *s,                            \
271
                            const void *input, void *output, int len,         \
272
                            double *z1, double *z2,                           \
273
                            double *unused1, double *unused2,                 \
274
                            double b0, double b1, double b2,                  \
275
                            double a1, double a2, int *clippings,             \
276
                            int disabled)                                     \
277
{                                                                             \
278
    const type *ibuf = input;                                                 \
279
    type *obuf = output;                                                      \
280
    double w1 = *z1;                                                          \
281
    double w2 = *z2;                                                          \
282
    double wet = s->mix;                                                      \
283
    double dry = 1. - wet;                                                    \
284
    double in, out, w0;                                                       \
285
                                                                              \
286
    a1 = -a1;                                                                 \
287
    a2 = -a2;                                                                 \
288
                                                                              \
289
    for (int i = 0; i < len; i++) {                                           \
290
        in = ibuf[i];                                                         \
291
        w0 = in + a1 * w1 + a2 * w2;                                          \
292
        out = b0 * w0 + b1 * w1 + b2 * w2;                                    \
293
        w2 = w1;                                                              \
294
        w1 = w0;                                                              \
295
        out = out * wet + in * dry;                                           \
296
        if (disabled) {                                                       \
297
            obuf[i] = in;                                                     \
298
        } else if (need_clipping && out < min) {                              \
299
            (*clippings)++;                                                   \
300
            obuf[i] = min;                                                    \
301
        } else if (need_clipping && out > max) {                              \
302
            (*clippings)++;                                                   \
303
            obuf[i] = max;                                                    \
304
        } else {                                                              \
305
            obuf[i] = out;                                                    \
306
        }                                                                     \
307
    }                                                                         \
308
    *z1 = w1;                                                                 \
309
    *z2 = w2;                                                                 \
310
}
311
312
BIQUAD_DII_FILTER(s16, int16_t, INT16_MIN, INT16_MAX, 1)
313
BIQUAD_DII_FILTER(s32, int32_t, INT32_MIN, INT32_MAX, 1)
314
BIQUAD_DII_FILTER(flt, float,   -1., 1., 0)
315
BIQUAD_DII_FILTER(dbl, double,  -1., 1., 0)
316
317
#define BIQUAD_TDII_FILTER(name, type, min, max, need_clipping)               \
318
static void biquad_tdii_## name (BiquadsContext *s,                           \
319
                            const void *input, void *output, int len,         \
320
                            double *z1, double *z2,                           \
321
                            double *unused1, double *unused2,                 \
322
                            double b0, double b1, double b2,                  \
323
                            double a1, double a2, int *clippings,             \
324
                            int disabled)                                     \
325
{                                                                             \
326
    const type *ibuf = input;                                                 \
327
    type *obuf = output;                                                      \
328
    double w1 = *z1;                                                          \
329
    double w2 = *z2;                                                          \
330
    double wet = s->mix;                                                      \
331
    double dry = 1. - wet;                                                    \
332
    double in, out;                                                           \
333
                                                                              \
334
    a1 = -a1;                                                                 \
335
    a2 = -a2;                                                                 \
336
                                                                              \
337
    for (int i = 0; i < len; i++) {                                           \
338
        in = ibuf[i];                                                         \
339
        out = b0 * in + w1;                                                   \
340
        w1 = b1 * in + w2 + a1 * out;                                         \
341
        w2 = b2 * in + a2 * out;                                              \
342
        out = out * wet + in * dry;                                           \
343
        if (disabled) {                                                       \
344
            obuf[i] = in;                                                     \
345
        } else if (need_clipping && out < min) {                              \
346
            (*clippings)++;                                                   \
347
            obuf[i] = min;                                                    \
348
        } else if (need_clipping && out > max) {                              \
349
            (*clippings)++;                                                   \
350
            obuf[i] = max;                                                    \
351
        } else {                                                              \
352
            obuf[i] = out;                                                    \
353
        }                                                                     \
354
    }                                                                         \
355
    *z1 = w1;                                                                 \
356
    *z2 = w2;                                                                 \
357
}
358
359
BIQUAD_TDII_FILTER(s16, int16_t, INT16_MIN, INT16_MAX, 1)
360
BIQUAD_TDII_FILTER(s32, int32_t, INT32_MIN, INT32_MAX, 1)
361
BIQUAD_TDII_FILTER(flt, float,   -1., 1., 0)
362
BIQUAD_TDII_FILTER(dbl, double,  -1., 1., 0)
363
364
static int config_filter(AVFilterLink *outlink, int reset)
365
{
366
    AVFilterContext *ctx    = outlink->src;
367
    BiquadsContext *s       = ctx->priv;
368
    AVFilterLink *inlink    = ctx->inputs[0];
369
    double A = ff_exp10(s->gain / 40);
370
    double w0 = 2 * M_PI * s->frequency / inlink->sample_rate;
371
    double K = tan(w0 / 2.);
372
    double alpha, beta;
373
374
    if (w0 > M_PI) {
375
        av_log(ctx, AV_LOG_ERROR,
376
               "Invalid frequency %f. Frequency must be less than half the sample-rate %d.\n",
377
               s->frequency, inlink->sample_rate);
378
        return AVERROR(EINVAL);
379
    }
380
381
    switch (s->width_type) {
382
    case NONE:
383
        alpha = 0.0;
384
        break;
385
    case HERTZ:
386
        alpha = sin(w0) / (2 * s->frequency / s->width);
387
        break;
388
    case KHERTZ:
389
        alpha = sin(w0) / (2 * s->frequency / (s->width * 1000));
390
        break;
391
    case OCTAVE:
392
        alpha = sin(w0) * sinh(log(2.) / 2 * s->width * w0 / sin(w0));
393
        break;
394
    case QFACTOR:
395
        alpha = sin(w0) / (2 * s->width);
396
        break;
397
    case SLOPE:
398
        alpha = sin(w0) / 2 * sqrt((A + 1 / A) * (1 / s->width - 1) + 2);
399
        break;
400
    default:
401
        av_assert0(0);
402
    }
403
404
    beta = 2 * sqrt(A);
405
406
    switch (s->filter_type) {
407
    case biquad:
408
        break;
409
    case equalizer:
410
        s->a0 =   1 + alpha / A;
411
        s->a1 =  -2 * cos(w0);
412
        s->a2 =   1 - alpha / A;
413
        s->b0 =   1 + alpha * A;
414
        s->b1 =  -2 * cos(w0);
415
        s->b2 =   1 - alpha * A;
416
        break;
417
    case bass:
418
        beta = sqrt((A * A + 1) - (A - 1) * (A - 1));
419
    case lowshelf:
420
        s->a0 =          (A + 1) + (A - 1) * cos(w0) + beta * alpha;
421
        s->a1 =    -2 * ((A - 1) + (A + 1) * cos(w0));
422
        s->a2 =          (A + 1) + (A - 1) * cos(w0) - beta * alpha;
423
        s->b0 =     A * ((A + 1) - (A - 1) * cos(w0) + beta * alpha);
424
        s->b1 = 2 * A * ((A - 1) - (A + 1) * cos(w0));
425
        s->b2 =     A * ((A + 1) - (A - 1) * cos(w0) - beta * alpha);
426
        break;
427
    case treble:
428
        beta = sqrt((A * A + 1) - (A - 1) * (A - 1));
429
    case highshelf:
430
        s->a0 =          (A + 1) - (A - 1) * cos(w0) + beta * alpha;
431
        s->a1 =     2 * ((A - 1) - (A + 1) * cos(w0));
432
        s->a2 =          (A + 1) - (A - 1) * cos(w0) - beta * alpha;
433
        s->b0 =     A * ((A + 1) + (A - 1) * cos(w0) + beta * alpha);
434
        s->b1 =-2 * A * ((A - 1) + (A + 1) * cos(w0));
435
        s->b2 =     A * ((A + 1) + (A - 1) * cos(w0) - beta * alpha);
436
        break;
437
    case bandpass:
438
        if (s->csg) {
439
            s->a0 =  1 + alpha;
440
            s->a1 = -2 * cos(w0);
441
            s->a2 =  1 - alpha;
442
            s->b0 =  sin(w0) / 2;
443
            s->b1 =  0;
444
            s->b2 = -sin(w0) / 2;
445
        } else {
446
            s->a0 =  1 + alpha;
447
            s->a1 = -2 * cos(w0);
448
            s->a2 =  1 - alpha;
449
            s->b0 =  alpha;
450
            s->b1 =  0;
451
            s->b2 = -alpha;
452
        }
453
        break;
454
    case bandreject:
455
        s->a0 =  1 + alpha;
456
        s->a1 = -2 * cos(w0);
457
        s->a2 =  1 - alpha;
458
        s->b0 =  1;
459
        s->b1 = -2 * cos(w0);
460
        s->b2 =  1;
461
        break;
462
    case lowpass:
463
        if (s->poles == 1) {
464
            s->a0 = 1;
465
            s->a1 = -exp(-w0);
466
            s->a2 = 0;
467
            s->b0 = 1 + s->a1;
468
            s->b1 = 0;
469
            s->b2 = 0;
470
        } else {
471
            s->a0 =  1 + alpha;
472
            s->a1 = -2 * cos(w0);
473
            s->a2 =  1 - alpha;
474
            s->b0 = (1 - cos(w0)) / 2;
475
            s->b1 =  1 - cos(w0);
476
            s->b2 = (1 - cos(w0)) / 2;
477
        }
478
        break;
479
    case highpass:
480
        if (s->poles == 1) {
481
            s->a0 = 1;
482
            s->a1 = -exp(-w0);
483
            s->a2 = 0;
484
            s->b0 = (1 - s->a1) / 2;
485
            s->b1 = -s->b0;
486
            s->b2 = 0;
487
        } else {
488
            s->a0 =   1 + alpha;
489
            s->a1 =  -2 * cos(w0);
490
            s->a2 =   1 - alpha;
491
            s->b0 =  (1 + cos(w0)) / 2;
492
            s->b1 = -(1 + cos(w0));
493
            s->b2 =  (1 + cos(w0)) / 2;
494
        }
495
        break;
496
    case allpass:
497
        switch (s->order) {
498
        case 1:
499
            s->a0 = 1.;
500
            s->a1 = -(1. - K) / (1. + K);
501
            s->a2 = 0.;
502
            s->b0 = s->a1;
503
            s->b1 = s->a0;
504
            s->b2 = 0.;
505
            break;
506
        case 2:
507
            s->a0 =  1 + alpha;
508
            s->a1 = -2 * cos(w0);
509
            s->a2 =  1 - alpha;
510
            s->b0 =  1 - alpha;
511
            s->b1 = -2 * cos(w0);
512
            s->b2 =  1 + alpha;
513
        break;
514
        }
515
        break;
516
    default:
517
        av_assert0(0);
518
    }
519
520
    av_log(ctx, AV_LOG_VERBOSE, "a=%f %f %f:b=%f %f %f\n", s->a0, s->a1, s->a2, s->b0, s->b1, s->b2);
521
522
    s->a1 /= s->a0;
523
    s->a2 /= s->a0;
524
    s->b0 /= s->a0;
525
    s->b1 /= s->a0;
526
    s->b2 /= s->a0;
527
    s->a0 /= s->a0;
528
529
    if (s->normalize && fabs(s->b0 + s->b1 + s->b2) > 1e-6) {
530
        double factor = (s->a0 + s->a1 + s->a2) / (s->b0 + s->b1 + s->b2);
531
532
        s->b0 *= factor;
533
        s->b1 *= factor;
534
        s->b2 *= factor;
535
    }
536
537
    s->cache = av_realloc_f(s->cache, sizeof(ChanCache), inlink->channels);
538
    if (!s->cache)
539
        return AVERROR(ENOMEM);
540
    if (reset)
541
        memset(s->cache, 0, sizeof(ChanCache) * inlink->channels);
542
543
544
    switch (s->transform_type) {
545
    case DI:
546
        switch (inlink->format) {
547
        case AV_SAMPLE_FMT_S16P:
548
            s->filter = biquad_s16;
549
            break;
550
        case AV_SAMPLE_FMT_S32P:
551
            s->filter = biquad_s32;
552
            break;
553
        case AV_SAMPLE_FMT_FLTP:
554
            s->filter = biquad_flt;
555
            break;
556
        case AV_SAMPLE_FMT_DBLP:
557
            s->filter = biquad_dbl;
558
            break;
559
        default: av_assert0(0);
560
        }
561
        break;
562
    case DII:
563
        switch (inlink->format) {
564
        case AV_SAMPLE_FMT_S16P:
565
            s->filter = biquad_dii_s16;
566
            break;
567
        case AV_SAMPLE_FMT_S32P:
568
            s->filter = biquad_dii_s32;
569
            break;
570
        case AV_SAMPLE_FMT_FLTP:
571
            s->filter = biquad_dii_flt;
572
            break;
573
        case AV_SAMPLE_FMT_DBLP:
574
            s->filter = biquad_dii_dbl;
575
            break;
576
        default: av_assert0(0);
577
        }
578
        break;
579
    case TDII:
580
        switch (inlink->format) {
581
        case AV_SAMPLE_FMT_S16P:
582
            s->filter = biquad_tdii_s16;
583
            break;
584
        case AV_SAMPLE_FMT_S32P:
585
            s->filter = biquad_tdii_s32;
586
            break;
587
        case AV_SAMPLE_FMT_FLTP:
588
            s->filter = biquad_tdii_flt;
589
            break;
590
        case AV_SAMPLE_FMT_DBLP:
591
            s->filter = biquad_tdii_dbl;
592
            break;
593
        default: av_assert0(0);
594
        }
595
        break;
596
    default:
597
        av_assert0(0);
598
     }
599
600
     s->block_align = av_get_bytes_per_sample(inlink->format);
601
602
    return 0;
603
}
604
605
static int config_output(AVFilterLink *outlink)
606
{
607
    return config_filter(outlink, 1);
608
}
609
610
typedef struct ThreadData {
611
    AVFrame *in, *out;
612
} ThreadData;
613
614
static int filter_channel(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
615
{
616
    AVFilterLink *inlink = ctx->inputs[0];
617
    ThreadData *td = arg;
618
    AVFrame *buf = td->in;
619
    AVFrame *out_buf = td->out;
620
    BiquadsContext *s = ctx->priv;
621
    const int start = (buf->channels * jobnr) / nb_jobs;
622
    const int end = (buf->channels * (jobnr+1)) / nb_jobs;
623
    int ch;
624
625
    for (ch = start; ch < end; ch++) {
626
        if (!((av_channel_layout_extract_channel(inlink->channel_layout, ch) & s->channels))) {
627
            if (buf != out_buf)
628
                memcpy(out_buf->extended_data[ch], buf->extended_data[ch],
629
                       buf->nb_samples * s->block_align);
630
            continue;
631
        }
632
633
        s->filter(s, buf->extended_data[ch], out_buf->extended_data[ch], buf->nb_samples,
634
                  &s->cache[ch].i1, &s->cache[ch].i2, &s->cache[ch].o1, &s->cache[ch].o2,
635
                  s->b0, s->b1, s->b2, s->a1, s->a2, &s->cache[ch].clippings, ctx->is_disabled);
636
    }
637
638
    return 0;
639
}
640
641
static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
642
{
643
    AVFilterContext  *ctx = inlink->dst;
644
    BiquadsContext *s     = ctx->priv;
645
    AVFilterLink *outlink = ctx->outputs[0];
646
    AVFrame *out_buf;
647
    ThreadData td;
648
    int ch;
649
650
    if (av_frame_is_writable(buf)) {
651
        out_buf = buf;
652
    } else {
653
        out_buf = ff_get_audio_buffer(outlink, buf->nb_samples);
654
        if (!out_buf) {
655
            av_frame_free(&buf);
656
            return AVERROR(ENOMEM);
657
        }
658
        av_frame_copy_props(out_buf, buf);
659
    }
660
661
    td.in = buf;
662
    td.out = out_buf;
663
    ctx->internal->execute(ctx, filter_channel, &td, NULL, FFMIN(outlink->channels, ff_filter_get_nb_threads(ctx)));
664
665
    for (ch = 0; ch < outlink->channels; ch++) {
666
        if (s->cache[ch].clippings > 0)
667
            av_log(ctx, AV_LOG_WARNING, "Channel %d clipping %d times. Please reduce gain.\n",
668
                   ch, s->cache[ch].clippings);
669
        s->cache[ch].clippings = 0;
670
    }
671
672
    if (buf != out_buf)
673
        av_frame_free(&buf);
674
675
    return ff_filter_frame(outlink, out_buf);
676
}
677
678
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
679
                           char *res, int res_len, int flags)
680
{
681
    AVFilterLink *outlink = ctx->outputs[0];
682
    int ret;
683
684
    ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags);
685
    if (ret < 0)
686
        return ret;
687
688
    return config_filter(outlink, 0);
689
}
690
691
static av_cold void uninit(AVFilterContext *ctx)
692
{
693
    BiquadsContext *s = ctx->priv;
694
695
    av_freep(&s->cache);
696
}
697
698
static const AVFilterPad inputs[] = {
699
    {
700
        .name         = "default",
701
        .type         = AVMEDIA_TYPE_AUDIO,
702
        .filter_frame = filter_frame,
703
    },
704
    { NULL }
705
};
706
707
static const AVFilterPad outputs[] = {
708
    {
709
        .name         = "default",
710
        .type         = AVMEDIA_TYPE_AUDIO,
711
        .config_props = config_output,
712
    },
713
    { NULL }
714
};
715
716
#define OFFSET(x) offsetof(BiquadsContext, x)
717
#define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
718
#define AF AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
719
720
#define DEFINE_BIQUAD_FILTER(name_, description_)                       \
721
AVFILTER_DEFINE_CLASS(name_);                                           \
722
static av_cold int name_##_init(AVFilterContext *ctx) \
723
{                                                                       \
724
    BiquadsContext *s = ctx->priv;                                      \
725
    s->class = &name_##_class;                                          \
726
    s->filter_type = name_;                                             \
727
    return init(ctx);                                             \
728
}                                                                       \
729
                                                         \
730
AVFilter ff_af_##name_ = {                         \
731
    .name          = #name_,                             \
732
    .description   = NULL_IF_CONFIG_SMALL(description_), \
733
    .priv_size     = sizeof(BiquadsContext),             \
734
    .init          = name_##_init,                       \
735
    .uninit        = uninit,                             \
736
    .query_formats = query_formats,                      \
737
    .inputs        = inputs,                             \
738
    .outputs       = outputs,                            \
739
    .priv_class    = &name_##_class,                     \
740
    .process_command = process_command,                  \
741
    .flags         = AVFILTER_FLAG_SLICE_THREADS | AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL, \
742
}
743
744
#if CONFIG_EQUALIZER_FILTER
745
static const AVOption equalizer_options[] = {
746
    {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 999999, FLAGS},
747
    {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 999999, FLAGS},
748
    {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
749
    {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
750
    {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
751
    {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
752
    {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
753
    {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
754
    {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
755
    {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 99999, FLAGS},
756
    {"w",     "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 99999, FLAGS},
757
    {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
758
    {"g",    "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
759
    {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
760
    {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
761
    {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
762
    {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
763
    {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
764
    {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
765
    {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
766
    {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
767
    {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
768
    {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
769
    {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
770
    {NULL}
771
};
772
773
DEFINE_BIQUAD_FILTER(equalizer, "Apply two-pole peaking equalization (EQ) filter.");
774
#endif  /* CONFIG_EQUALIZER_FILTER */
775
#if CONFIG_BASS_FILTER
776
static const AVOption bass_options[] = {
777
    {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
778
    {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
779
    {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
780
    {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
781
    {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
782
    {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
783
    {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
784
    {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
785
    {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
786
    {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
787
    {"w",     "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
788
    {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
789
    {"g",    "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
790
    {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
791
    {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
792
    {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
793
    {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
794
    {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
795
    {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
796
    {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
797
    {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
798
    {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
799
    {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
800
    {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
801
    {NULL}
802
};
803
804
DEFINE_BIQUAD_FILTER(bass, "Boost or cut lower frequencies.");
805
#endif  /* CONFIG_BASS_FILTER */
806
#if CONFIG_TREBLE_FILTER
807
static const AVOption treble_options[] = {
808
    {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
809
    {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
810
    {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
811
    {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
812
    {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
813
    {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
814
    {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
815
    {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
816
    {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
817
    {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
818
    {"w",     "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
819
    {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
820
    {"g",    "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
821
    {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
822
    {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
823
    {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
824
    {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
825
    {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
826
    {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
827
    {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
828
    {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
829
    {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
830
    {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
831
    {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
832
    {NULL}
833
};
834
835
DEFINE_BIQUAD_FILTER(treble, "Boost or cut upper frequencies.");
836
#endif  /* CONFIG_TREBLE_FILTER */
837
#if CONFIG_BANDPASS_FILTER
838
static const AVOption bandpass_options[] = {
839
    {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
840
    {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
841
    {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
842
    {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
843
    {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
844
    {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
845
    {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
846
    {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
847
    {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
848
    {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
849
    {"w",     "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
850
    {"csg",   "use constant skirt gain", OFFSET(csg), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
851
    {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
852
    {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
853
    {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
854
    {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
855
    {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
856
    {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
857
    {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
858
    {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
859
    {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
860
    {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
861
    {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
862
    {NULL}
863
};
864
865
DEFINE_BIQUAD_FILTER(bandpass, "Apply a two-pole Butterworth band-pass filter.");
866
#endif  /* CONFIG_BANDPASS_FILTER */
867
#if CONFIG_BANDREJECT_FILTER
868
static const AVOption bandreject_options[] = {
869
    {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
870
    {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
871
    {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
872
    {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
873
    {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
874
    {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
875
    {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
876
    {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
877
    {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
878
    {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
879
    {"w",     "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
880
    {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
881
    {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
882
    {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
883
    {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
884
    {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
885
    {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
886
    {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
887
    {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
888
    {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
889
    {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
890
    {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
891
    {NULL}
892
};
893
894
DEFINE_BIQUAD_FILTER(bandreject, "Apply a two-pole Butterworth band-reject filter.");
895
#endif  /* CONFIG_BANDREJECT_FILTER */
896
#if CONFIG_LOWPASS_FILTER
897
static const AVOption lowpass_options[] = {
898
    {"frequency", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=500}, 0, 999999, FLAGS},
899
    {"f",         "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=500}, 0, 999999, FLAGS},
900
    {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
901
    {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
902
    {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
903
    {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
904
    {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
905
    {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
906
    {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
907
    {"width", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
908
    {"w",     "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
909
    {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
910
    {"p",     "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
911
    {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
912
    {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
913
    {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
914
    {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
915
    {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
916
    {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
917
    {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
918
    {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
919
    {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
920
    {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
921
    {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
922
    {NULL}
923
};
924
925
DEFINE_BIQUAD_FILTER(lowpass, "Apply a low-pass filter with 3dB point frequency.");
926
#endif  /* CONFIG_LOWPASS_FILTER */
927
#if CONFIG_HIGHPASS_FILTER
928
static const AVOption highpass_options[] = {
929
    {"frequency", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
930
    {"f",         "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
931
    {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
932
    {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
933
    {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
934
    {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
935
    {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
936
    {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
937
    {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
938
    {"width", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
939
    {"w",     "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
940
    {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
941
    {"p",     "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
942
    {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
943
    {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
944
    {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
945
    {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
946
    {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
947
    {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
948
    {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
949
    {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
950
    {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
951
    {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
952
    {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
953
    {NULL}
954
};
955
956
DEFINE_BIQUAD_FILTER(highpass, "Apply a high-pass filter with 3dB point frequency.");
957
#endif  /* CONFIG_HIGHPASS_FILTER */
958
#if CONFIG_ALLPASS_FILTER
959
static const AVOption allpass_options[] = {
960
    {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
961
    {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
962
    {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=HERTZ}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
963
    {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=HERTZ}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
964
    {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
965
    {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
966
    {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
967
    {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
968
    {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
969
    {"width", "set filter-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=707.1}, 0, 99999, FLAGS},
970
    {"w",     "set filter-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=707.1}, 0, 99999, FLAGS},
971
    {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
972
    {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
973
    {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
974
    {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
975
    {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
976
    {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
977
    {"order", "set filter order", OFFSET(order), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
978
    {"o",     "set filter order", OFFSET(order), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
979
    {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
980
    {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
981
    {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
982
    {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
983
    {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
984
    {NULL}
985
};
986
987
DEFINE_BIQUAD_FILTER(allpass, "Apply a two-pole all-pass filter.");
988
#endif  /* CONFIG_ALLPASS_FILTER */
989
#if CONFIG_LOWSHELF_FILTER
990
static const AVOption lowshelf_options[] = {
991
    {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
992
    {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
993
    {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
994
    {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
995
    {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
996
    {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
997
    {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
998
    {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
999
    {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
1000
    {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
1001
    {"w",     "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
1002
    {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
1003
    {"g",    "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
1004
    {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1005
    {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1006
    {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1007
    {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1008
    {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1009
    {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1010
    {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1011
    {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1012
    {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
1013
    {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
1014
    {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
1015
    {NULL}
1016
};
1017
1018
DEFINE_BIQUAD_FILTER(lowshelf, "Apply a low shelf filter.");
1019
#endif  /* CONFIG_LOWSHELF_FILTER */
1020
#if CONFIG_HIGHSHELF_FILTER
1021
static const AVOption highshelf_options[] = {
1022
    {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1023
    {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1024
    {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1025
    {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1026
    {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
1027
    {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
1028
    {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
1029
    {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
1030
    {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
1031
    {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
1032
    {"w",     "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
1033
    {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
1034
    {"g",    "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
1035
    {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1036
    {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1037
    {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1038
    {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1039
    {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1040
    {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1041
    {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1042
    {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1043
    {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
1044
    {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
1045
    {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
1046
    {NULL}
1047
};
1048
1049
DEFINE_BIQUAD_FILTER(highshelf, "Apply a high shelf filter.");
1050
#endif  /* CONFIG_HIGHSHELF_FILTER */
1051
#if CONFIG_BIQUAD_FILTER
1052
static const AVOption biquad_options[] = {
1053
    {"a0", NULL, OFFSET(a0), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT32_MIN, INT32_MAX, FLAGS},
1054
    {"a1", NULL, OFFSET(a1), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
1055
    {"a2", NULL, OFFSET(a2), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
1056
    {"b0", NULL, OFFSET(b0), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
1057
    {"b1", NULL, OFFSET(b1), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
1058
    {"b2", NULL, OFFSET(b2), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
1059
    {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1060
    {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1061
    {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1062
    {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1063
    {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1064
    {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1065
    {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1066
    {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1067
    {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
1068
    {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
1069
    {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
1070
    {NULL}
1071
};
1072
1073
DEFINE_BIQUAD_FILTER(biquad, "Apply a biquad IIR filter with the given coefficients.");
1074
#endif  /* CONFIG_BIQUAD_FILTER */