GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavfilter/af_biquads.c Lines: 0 389 0.0 %
Date: 2021-01-22 05:18:52 Branches: 0 266 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
    LATT,
101
    NB_TTYPE,
102
};
103
104
typedef struct ChanCache {
105
    double i1, i2;
106
    double o1, o2;
107
    int clippings;
108
} ChanCache;
109
110
typedef struct BiquadsContext {
111
    const AVClass *class;
112
113
    enum FilterType filter_type;
114
    int width_type;
115
    int poles;
116
    int csg;
117
    int transform_type;
118
    int precision;
119
120
    int bypass;
121
122
    double gain;
123
    double frequency;
124
    double width;
125
    double mix;
126
    uint64_t channels;
127
    int normalize;
128
    int order;
129
130
    double a0, a1, a2;
131
    double b0, b1, b2;
132
133
    double oa0, oa1, oa2;
134
    double ob0, ob1, ob2;
135
136
    ChanCache *cache;
137
    int block_align;
138
139
    void (*filter)(struct BiquadsContext *s, const void *ibuf, void *obuf, int len,
140
                   double *i1, double *i2, double *o1, double *o2,
141
                   double b0, double b1, double b2, double a1, double a2, int *clippings,
142
                   int disabled);
143
} BiquadsContext;
144
145
static int query_formats(AVFilterContext *ctx)
146
{
147
    BiquadsContext *s = ctx->priv;
148
    AVFilterFormats *formats;
149
    AVFilterChannelLayouts *layouts;
150
    static const enum AVSampleFormat auto_sample_fmts[] = {
151
        AV_SAMPLE_FMT_S16P,
152
        AV_SAMPLE_FMT_S32P,
153
        AV_SAMPLE_FMT_FLTP,
154
        AV_SAMPLE_FMT_DBLP,
155
        AV_SAMPLE_FMT_NONE
156
    };
157
    enum AVSampleFormat sample_fmts[] = {
158
        AV_SAMPLE_FMT_S16P,
159
        AV_SAMPLE_FMT_NONE
160
    };
161
    int ret;
162
163
    layouts = ff_all_channel_counts();
164
    if (!layouts)
165
        return AVERROR(ENOMEM);
166
    ret = ff_set_common_channel_layouts(ctx, layouts);
167
    if (ret < 0)
168
        return ret;
169
170
    switch (s->precision) {
171
    case 0:
172
        sample_fmts[0] = AV_SAMPLE_FMT_S16P;
173
        formats = ff_make_format_list(sample_fmts);
174
        break;
175
    case 1:
176
        sample_fmts[0] = AV_SAMPLE_FMT_S32P;
177
        formats = ff_make_format_list(sample_fmts);
178
        break;
179
    case 2:
180
        sample_fmts[0] = AV_SAMPLE_FMT_FLTP;
181
        formats = ff_make_format_list(sample_fmts);
182
        break;
183
    case 3:
184
        sample_fmts[0] = AV_SAMPLE_FMT_DBLP;
185
        formats = ff_make_format_list(sample_fmts);
186
        break;
187
    default:
188
        formats = ff_make_format_list(auto_sample_fmts);
189
        break;
190
    }
191
    if (!formats)
192
        return AVERROR(ENOMEM);
193
    ret = ff_set_common_formats(ctx, formats);
194
    if (ret < 0)
195
        return ret;
196
197
    formats = ff_all_samplerates();
198
    if (!formats)
199
        return AVERROR(ENOMEM);
200
    return ff_set_common_samplerates(ctx, formats);
201
}
202
203
#define BIQUAD_FILTER(name, type, min, max, need_clipping)                    \
204
static void biquad_## name (BiquadsContext *s,                                \
205
                            const void *input, void *output, int len,         \
206
                            double *in1, double *in2,                         \
207
                            double *out1, double *out2,                       \
208
                            double b0, double b1, double b2,                  \
209
                            double a1, double a2, int *clippings,             \
210
                            int disabled)                                     \
211
{                                                                             \
212
    const type *ibuf = input;                                                 \
213
    type *obuf = output;                                                      \
214
    double i1 = *in1;                                                         \
215
    double i2 = *in2;                                                         \
216
    double o1 = *out1;                                                        \
217
    double o2 = *out2;                                                        \
218
    double wet = s->mix;                                                      \
219
    double dry = 1. - wet;                                                    \
220
    double out;                                                               \
221
    int i;                                                                    \
222
    a1 = -a1;                                                                 \
223
    a2 = -a2;                                                                 \
224
                                                                              \
225
    for (i = 0; i+1 < len; i++) {                                             \
226
        o2 = i2 * b2 + i1 * b1 + ibuf[i] * b0 + o2 * a2 + o1 * a1;            \
227
        i2 = ibuf[i];                                                         \
228
        out = o2 * wet + i2 * dry;                                            \
229
        if (disabled) {                                                       \
230
            obuf[i] = i2;                                                     \
231
        } else if (need_clipping && out < min) {                              \
232
            (*clippings)++;                                                   \
233
            obuf[i] = min;                                                    \
234
        } else if (need_clipping && out > max) {                              \
235
            (*clippings)++;                                                   \
236
            obuf[i] = max;                                                    \
237
        } else {                                                              \
238
            obuf[i] = out;                                                    \
239
        }                                                                     \
240
        i++;                                                                  \
241
        o1 = i1 * b2 + i2 * b1 + ibuf[i] * b0 + o1 * a2 + o2 * a1;            \
242
        i1 = ibuf[i];                                                         \
243
        out = o1 * wet + i1 * dry;                                            \
244
        if (disabled) {                                                       \
245
            obuf[i] = i1;                                                     \
246
        } else if (need_clipping && out < min) {                              \
247
            (*clippings)++;                                                   \
248
            obuf[i] = min;                                                    \
249
        } else if (need_clipping && out > max) {                              \
250
            (*clippings)++;                                                   \
251
            obuf[i] = max;                                                    \
252
        } else {                                                              \
253
            obuf[i] = out;                                                    \
254
        }                                                                     \
255
    }                                                                         \
256
    if (i < len) {                                                            \
257
        double o0 = ibuf[i] * b0 + i1 * b1 + i2 * b2 + o1 * a1 + o2 * a2;     \
258
        i2 = i1;                                                              \
259
        i1 = ibuf[i];                                                         \
260
        o2 = o1;                                                              \
261
        o1 = o0;                                                              \
262
        out = o0 * wet + i1 * dry;                                            \
263
        if (disabled) {                                                       \
264
            obuf[i] = i1;                                                     \
265
        } else if (need_clipping && out < min) {                              \
266
            (*clippings)++;                                                   \
267
            obuf[i] = min;                                                    \
268
        } else if (need_clipping && out > max) {                              \
269
            (*clippings)++;                                                   \
270
            obuf[i] = max;                                                    \
271
        } else {                                                              \
272
            obuf[i] = out;                                                    \
273
        }                                                                     \
274
    }                                                                         \
275
    *in1  = i1;                                                               \
276
    *in2  = i2;                                                               \
277
    *out1 = o1;                                                               \
278
    *out2 = o2;                                                               \
279
}
280
281
BIQUAD_FILTER(s16, int16_t, INT16_MIN, INT16_MAX, 1)
282
BIQUAD_FILTER(s32, int32_t, INT32_MIN, INT32_MAX, 1)
283
BIQUAD_FILTER(flt, float,   -1., 1., 0)
284
BIQUAD_FILTER(dbl, double,  -1., 1., 0)
285
286
#define BIQUAD_DII_FILTER(name, type, min, max, need_clipping)                \
287
static void biquad_dii_## name (BiquadsContext *s,                            \
288
                            const void *input, void *output, int len,         \
289
                            double *z1, double *z2,                           \
290
                            double *unused1, double *unused2,                 \
291
                            double b0, double b1, double b2,                  \
292
                            double a1, double a2, int *clippings,             \
293
                            int disabled)                                     \
294
{                                                                             \
295
    const type *ibuf = input;                                                 \
296
    type *obuf = output;                                                      \
297
    double w1 = *z1;                                                          \
298
    double w2 = *z2;                                                          \
299
    double wet = s->mix;                                                      \
300
    double dry = 1. - wet;                                                    \
301
    double in, out, w0;                                                       \
302
                                                                              \
303
    a1 = -a1;                                                                 \
304
    a2 = -a2;                                                                 \
305
                                                                              \
306
    for (int i = 0; i < len; i++) {                                           \
307
        in = ibuf[i];                                                         \
308
        w0 = in + a1 * w1 + a2 * w2;                                          \
309
        out = b0 * w0 + b1 * w1 + b2 * w2;                                    \
310
        w2 = w1;                                                              \
311
        w1 = w0;                                                              \
312
        out = out * wet + in * dry;                                           \
313
        if (disabled) {                                                       \
314
            obuf[i] = in;                                                     \
315
        } else if (need_clipping && out < min) {                              \
316
            (*clippings)++;                                                   \
317
            obuf[i] = min;                                                    \
318
        } else if (need_clipping && out > max) {                              \
319
            (*clippings)++;                                                   \
320
            obuf[i] = max;                                                    \
321
        } else {                                                              \
322
            obuf[i] = out;                                                    \
323
        }                                                                     \
324
    }                                                                         \
325
    *z1 = w1;                                                                 \
326
    *z2 = w2;                                                                 \
327
}
328
329
BIQUAD_DII_FILTER(s16, int16_t, INT16_MIN, INT16_MAX, 1)
330
BIQUAD_DII_FILTER(s32, int32_t, INT32_MIN, INT32_MAX, 1)
331
BIQUAD_DII_FILTER(flt, float,   -1., 1., 0)
332
BIQUAD_DII_FILTER(dbl, double,  -1., 1., 0)
333
334
#define BIQUAD_TDII_FILTER(name, type, min, max, need_clipping)               \
335
static void biquad_tdii_## name (BiquadsContext *s,                           \
336
                            const void *input, void *output, int len,         \
337
                            double *z1, double *z2,                           \
338
                            double *unused1, double *unused2,                 \
339
                            double b0, double b1, double b2,                  \
340
                            double a1, double a2, int *clippings,             \
341
                            int disabled)                                     \
342
{                                                                             \
343
    const type *ibuf = input;                                                 \
344
    type *obuf = output;                                                      \
345
    double w1 = *z1;                                                          \
346
    double w2 = *z2;                                                          \
347
    double wet = s->mix;                                                      \
348
    double dry = 1. - wet;                                                    \
349
    double in, out;                                                           \
350
                                                                              \
351
    a1 = -a1;                                                                 \
352
    a2 = -a2;                                                                 \
353
                                                                              \
354
    for (int i = 0; i < len; i++) {                                           \
355
        in = ibuf[i];                                                         \
356
        out = b0 * in + w1;                                                   \
357
        w1 = b1 * in + w2 + a1 * out;                                         \
358
        w2 = b2 * in + a2 * out;                                              \
359
        out = out * wet + in * dry;                                           \
360
        if (disabled) {                                                       \
361
            obuf[i] = in;                                                     \
362
        } else if (need_clipping && out < min) {                              \
363
            (*clippings)++;                                                   \
364
            obuf[i] = min;                                                    \
365
        } else if (need_clipping && out > max) {                              \
366
            (*clippings)++;                                                   \
367
            obuf[i] = max;                                                    \
368
        } else {                                                              \
369
            obuf[i] = out;                                                    \
370
        }                                                                     \
371
    }                                                                         \
372
    *z1 = w1;                                                                 \
373
    *z2 = w2;                                                                 \
374
}
375
376
BIQUAD_TDII_FILTER(s16, int16_t, INT16_MIN, INT16_MAX, 1)
377
BIQUAD_TDII_FILTER(s32, int32_t, INT32_MIN, INT32_MAX, 1)
378
BIQUAD_TDII_FILTER(flt, float,   -1., 1., 0)
379
BIQUAD_TDII_FILTER(dbl, double,  -1., 1., 0)
380
381
#define BIQUAD_LATT_FILTER(name, type, min, max, need_clipping)               \
382
static void biquad_latt_## name (BiquadsContext *s,                           \
383
                           const void *input, void *output, int len,          \
384
                           double *z1, double *z2,                            \
385
                           double *unused1, double *unused2,                  \
386
                           double v0, double v1, double v2,                   \
387
                           double k0, double k1, int *clippings,              \
388
                           int disabled)                                      \
389
{                                                                             \
390
    const type *ibuf = input;                                                 \
391
    type *obuf = output;                                                      \
392
    double s0 = *z1;                                                          \
393
    double s1 = *z2;                                                          \
394
    double wet = s->mix;                                                      \
395
    double dry = 1. - wet;                                                    \
396
    double in, out;                                                           \
397
    double t0, t1;                                                            \
398
                                                                              \
399
    for (int i = 0; i < len; i++) {                                           \
400
        out  = 0.;                                                            \
401
        in   = ibuf[i];                                                       \
402
        t0   = in - k1 * s0;                                                  \
403
        t1   = t0 * k1 + s0;                                                  \
404
        out += t1 * v2;                                                       \
405
                                                                              \
406
        t0    = t0 - k0 * s1;                                                 \
407
        t1    = t0 * k0 + s1;                                                 \
408
        out  += t1 * v1;                                                      \
409
                                                                              \
410
        out  += t0 * v0;                                                      \
411
        s0    = t1;                                                           \
412
        s1    = t0;                                                           \
413
                                                                              \
414
        out = out * wet + in * dry;                                           \
415
        if (disabled) {                                                       \
416
            obuf[i] = in;                                                     \
417
        } else if (need_clipping && out < min) {                              \
418
            (*clippings)++;                                                   \
419
            obuf[i] = min;                                                    \
420
        } else if (need_clipping && out > max) {                              \
421
            (*clippings)++;                                                   \
422
            obuf[i] = max;                                                    \
423
        } else {                                                              \
424
            obuf[i] = out;                                                    \
425
        }                                                                     \
426
    }                                                                         \
427
    *z1 = s0;                                                                 \
428
    *z2 = s1;                                                                 \
429
}
430
431
BIQUAD_LATT_FILTER(s16, int16_t, INT16_MIN, INT16_MAX, 1)
432
BIQUAD_LATT_FILTER(s32, int32_t, INT32_MIN, INT32_MAX, 1)
433
BIQUAD_LATT_FILTER(flt, float,   -1., 1., 0)
434
BIQUAD_LATT_FILTER(dbl, double,  -1., 1., 0)
435
436
static void convert_dir2latt(BiquadsContext *s)
437
{
438
    double k0, k1, v0, v1, v2;
439
440
    k1 = s->a2;
441
    k0 = s->a1 / (1. + k1);
442
    v2 = s->b2;
443
    v1 = s->b1 - v2 * s->a1;
444
    v0 = s->b0 - v1 * k0 - v2 * k1;
445
446
    s->a1 = k0;
447
    s->a2 = k1;
448
    s->b0 = v0;
449
    s->b1 = v1;
450
    s->b2 = v2;
451
}
452
453
static int config_filter(AVFilterLink *outlink, int reset)
454
{
455
    AVFilterContext *ctx    = outlink->src;
456
    BiquadsContext *s       = ctx->priv;
457
    AVFilterLink *inlink    = ctx->inputs[0];
458
    double A = ff_exp10(s->gain / 40);
459
    double w0 = 2 * M_PI * s->frequency / inlink->sample_rate;
460
    double K = tan(w0 / 2.);
461
    double alpha, beta;
462
463
    s->bypass = (((w0 > M_PI || w0 <= 0.) && reset) || (s->width <= 0.)) && (s->filter_type != biquad);
464
    if (s->bypass) {
465
        av_log(ctx, AV_LOG_WARNING, "Invalid frequency and/or width!\n");
466
        return 0;
467
    }
468
469
    if ((w0 > M_PI || w0 <= 0.) && (s->filter_type != biquad))
470
        return AVERROR(EINVAL);
471
472
    switch (s->width_type) {
473
    case NONE:
474
        alpha = 0.0;
475
        break;
476
    case HERTZ:
477
        alpha = sin(w0) / (2 * s->frequency / s->width);
478
        break;
479
    case KHERTZ:
480
        alpha = sin(w0) / (2 * s->frequency / (s->width * 1000));
481
        break;
482
    case OCTAVE:
483
        alpha = sin(w0) * sinh(log(2.) / 2 * s->width * w0 / sin(w0));
484
        break;
485
    case QFACTOR:
486
        alpha = sin(w0) / (2 * s->width);
487
        break;
488
    case SLOPE:
489
        alpha = sin(w0) / 2 * sqrt((A + 1 / A) * (1 / s->width - 1) + 2);
490
        break;
491
    default:
492
        av_assert0(0);
493
    }
494
495
    beta = 2 * sqrt(A);
496
497
    switch (s->filter_type) {
498
    case biquad:
499
        s->a0 = s->oa0;
500
        s->a1 = s->oa1;
501
        s->a2 = s->oa2;
502
        s->b0 = s->ob0;
503
        s->b1 = s->ob1;
504
        s->b2 = s->ob2;
505
        break;
506
    case equalizer:
507
        s->a0 =   1 + alpha / A;
508
        s->a1 =  -2 * cos(w0);
509
        s->a2 =   1 - alpha / A;
510
        s->b0 =   1 + alpha * A;
511
        s->b1 =  -2 * cos(w0);
512
        s->b2 =   1 - alpha * A;
513
        break;
514
    case bass:
515
        beta = sqrt((A * A + 1) - (A - 1) * (A - 1));
516
    case lowshelf:
517
        if (s->poles == 1) {
518
            double A = ff_exp10(s->gain / 20);
519
            double ro = -sin(w0 / 2. - M_PI_4) / sin(w0 / 2. + M_PI_4);
520
            double n = (A + 1) / (A - 1);
521
            double alpha1 = A == 1. ? 0. : n - FFSIGN(n) * sqrt(n * n - 1);
522
            double beta0 = ((1 + A) + (1 - A) * alpha1) * 0.5;
523
            double beta1 = ((1 - A) + (1 + A) * alpha1) * 0.5;
524
525
            s->a0 = 1 + ro * alpha1;
526
            s->a1 = -ro - alpha1;
527
            s->a2 = 0;
528
            s->b0 = beta0 + ro * beta1;
529
            s->b1 = -beta1 - ro * beta0;
530
            s->b2 = 0;
531
        } else {
532
            s->a0 =          (A + 1) + (A - 1) * cos(w0) + beta * alpha;
533
            s->a1 =    -2 * ((A - 1) + (A + 1) * cos(w0));
534
            s->a2 =          (A + 1) + (A - 1) * cos(w0) - beta * alpha;
535
            s->b0 =     A * ((A + 1) - (A - 1) * cos(w0) + beta * alpha);
536
            s->b1 = 2 * A * ((A - 1) - (A + 1) * cos(w0));
537
            s->b2 =     A * ((A + 1) - (A - 1) * cos(w0) - beta * alpha);
538
        }
539
        break;
540
    case treble:
541
        beta = sqrt((A * A + 1) - (A - 1) * (A - 1));
542
    case highshelf:
543
        if (s->poles == 1) {
544
            double A = ff_exp10(s->gain / 20);
545
            double ro = sin(w0 / 2. - M_PI_4) / sin(w0 / 2. + M_PI_4);
546
            double n = (A + 1) / (A - 1);
547
            double alpha1 = A == 1. ? 0. : n - FFSIGN(n) * sqrt(n * n - 1);
548
            double beta0 = ((1 + A) + (1 - A) * alpha1) * 0.5;
549
            double beta1 = ((1 - A) + (1 + A) * alpha1) * 0.5;
550
551
            s->a0 = 1 + ro * alpha1;
552
            s->a1 = ro + alpha1;
553
            s->a2 = 0;
554
            s->b0 = beta0 + ro * beta1;
555
            s->b1 = beta1 + ro * beta0;
556
            s->b2 = 0;
557
        } else {
558
            s->a0 =          (A + 1) - (A - 1) * cos(w0) + beta * alpha;
559
            s->a1 =     2 * ((A - 1) - (A + 1) * cos(w0));
560
            s->a2 =          (A + 1) - (A - 1) * cos(w0) - beta * alpha;
561
            s->b0 =     A * ((A + 1) + (A - 1) * cos(w0) + beta * alpha);
562
            s->b1 =-2 * A * ((A - 1) + (A + 1) * cos(w0));
563
            s->b2 =     A * ((A + 1) + (A - 1) * cos(w0) - beta * alpha);
564
        }
565
        break;
566
    case bandpass:
567
        if (s->csg) {
568
            s->a0 =  1 + alpha;
569
            s->a1 = -2 * cos(w0);
570
            s->a2 =  1 - alpha;
571
            s->b0 =  sin(w0) / 2;
572
            s->b1 =  0;
573
            s->b2 = -sin(w0) / 2;
574
        } else {
575
            s->a0 =  1 + alpha;
576
            s->a1 = -2 * cos(w0);
577
            s->a2 =  1 - alpha;
578
            s->b0 =  alpha;
579
            s->b1 =  0;
580
            s->b2 = -alpha;
581
        }
582
        break;
583
    case bandreject:
584
        s->a0 =  1 + alpha;
585
        s->a1 = -2 * cos(w0);
586
        s->a2 =  1 - alpha;
587
        s->b0 =  1;
588
        s->b1 = -2 * cos(w0);
589
        s->b2 =  1;
590
        break;
591
    case lowpass:
592
        if (s->poles == 1) {
593
            s->a0 = 1;
594
            s->a1 = -exp(-w0);
595
            s->a2 = 0;
596
            s->b0 = 1 + s->a1;
597
            s->b1 = 0;
598
            s->b2 = 0;
599
        } else {
600
            s->a0 =  1 + alpha;
601
            s->a1 = -2 * cos(w0);
602
            s->a2 =  1 - alpha;
603
            s->b0 = (1 - cos(w0)) / 2;
604
            s->b1 =  1 - cos(w0);
605
            s->b2 = (1 - cos(w0)) / 2;
606
        }
607
        break;
608
    case highpass:
609
        if (s->poles == 1) {
610
            s->a0 = 1;
611
            s->a1 = -exp(-w0);
612
            s->a2 = 0;
613
            s->b0 = (1 - s->a1) / 2;
614
            s->b1 = -s->b0;
615
            s->b2 = 0;
616
        } else {
617
            s->a0 =   1 + alpha;
618
            s->a1 =  -2 * cos(w0);
619
            s->a2 =   1 - alpha;
620
            s->b0 =  (1 + cos(w0)) / 2;
621
            s->b1 = -(1 + cos(w0));
622
            s->b2 =  (1 + cos(w0)) / 2;
623
        }
624
        break;
625
    case allpass:
626
        switch (s->order) {
627
        case 1:
628
            s->a0 = 1.;
629
            s->a1 = -(1. - K) / (1. + K);
630
            s->a2 = 0.;
631
            s->b0 = s->a1;
632
            s->b1 = s->a0;
633
            s->b2 = 0.;
634
            break;
635
        case 2:
636
            s->a0 =  1 + alpha;
637
            s->a1 = -2 * cos(w0);
638
            s->a2 =  1 - alpha;
639
            s->b0 =  1 - alpha;
640
            s->b1 = -2 * cos(w0);
641
            s->b2 =  1 + alpha;
642
        break;
643
        }
644
        break;
645
    default:
646
        av_assert0(0);
647
    }
648
649
    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);
650
651
    s->a1 /= s->a0;
652
    s->a2 /= s->a0;
653
    s->b0 /= s->a0;
654
    s->b1 /= s->a0;
655
    s->b2 /= s->a0;
656
    s->a0 /= s->a0;
657
658
    if (s->normalize && fabs(s->b0 + s->b1 + s->b2) > 1e-6) {
659
        double factor = (s->a0 + s->a1 + s->a2) / (s->b0 + s->b1 + s->b2);
660
661
        s->b0 *= factor;
662
        s->b1 *= factor;
663
        s->b2 *= factor;
664
    }
665
666
    s->cache = av_realloc_f(s->cache, sizeof(ChanCache), inlink->channels);
667
    if (!s->cache)
668
        return AVERROR(ENOMEM);
669
    if (reset)
670
        memset(s->cache, 0, sizeof(ChanCache) * inlink->channels);
671
672
    switch (s->transform_type) {
673
    case DI:
674
        switch (inlink->format) {
675
        case AV_SAMPLE_FMT_S16P:
676
            s->filter = biquad_s16;
677
            break;
678
        case AV_SAMPLE_FMT_S32P:
679
            s->filter = biquad_s32;
680
            break;
681
        case AV_SAMPLE_FMT_FLTP:
682
            s->filter = biquad_flt;
683
            break;
684
        case AV_SAMPLE_FMT_DBLP:
685
            s->filter = biquad_dbl;
686
            break;
687
        default: av_assert0(0);
688
        }
689
        break;
690
    case DII:
691
        switch (inlink->format) {
692
        case AV_SAMPLE_FMT_S16P:
693
            s->filter = biquad_dii_s16;
694
            break;
695
        case AV_SAMPLE_FMT_S32P:
696
            s->filter = biquad_dii_s32;
697
            break;
698
        case AV_SAMPLE_FMT_FLTP:
699
            s->filter = biquad_dii_flt;
700
            break;
701
        case AV_SAMPLE_FMT_DBLP:
702
            s->filter = biquad_dii_dbl;
703
            break;
704
        default: av_assert0(0);
705
        }
706
        break;
707
    case TDII:
708
        switch (inlink->format) {
709
        case AV_SAMPLE_FMT_S16P:
710
            s->filter = biquad_tdii_s16;
711
            break;
712
        case AV_SAMPLE_FMT_S32P:
713
            s->filter = biquad_tdii_s32;
714
            break;
715
        case AV_SAMPLE_FMT_FLTP:
716
            s->filter = biquad_tdii_flt;
717
            break;
718
        case AV_SAMPLE_FMT_DBLP:
719
            s->filter = biquad_tdii_dbl;
720
            break;
721
        default: av_assert0(0);
722
        }
723
        break;
724
    case LATT:
725
        switch (inlink->format) {
726
        case AV_SAMPLE_FMT_S16P:
727
            s->filter = biquad_latt_s16;
728
            break;
729
        case AV_SAMPLE_FMT_S32P:
730
            s->filter = biquad_latt_s32;
731
            break;
732
        case AV_SAMPLE_FMT_FLTP:
733
            s->filter = biquad_latt_flt;
734
            break;
735
        case AV_SAMPLE_FMT_DBLP:
736
            s->filter = biquad_latt_dbl;
737
            break;
738
        default: av_assert0(0);
739
        }
740
        break;
741
    default:
742
        av_assert0(0);
743
     }
744
745
     s->block_align = av_get_bytes_per_sample(inlink->format);
746
747
     if (s->transform_type == LATT)
748
         convert_dir2latt(s);
749
750
    return 0;
751
}
752
753
static int config_output(AVFilterLink *outlink)
754
{
755
    return config_filter(outlink, 1);
756
}
757
758
typedef struct ThreadData {
759
    AVFrame *in, *out;
760
} ThreadData;
761
762
static int filter_channel(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
763
{
764
    AVFilterLink *inlink = ctx->inputs[0];
765
    ThreadData *td = arg;
766
    AVFrame *buf = td->in;
767
    AVFrame *out_buf = td->out;
768
    BiquadsContext *s = ctx->priv;
769
    const int start = (buf->channels * jobnr) / nb_jobs;
770
    const int end = (buf->channels * (jobnr+1)) / nb_jobs;
771
    int ch;
772
773
    for (ch = start; ch < end; ch++) {
774
        if (!((av_channel_layout_extract_channel(inlink->channel_layout, ch) & s->channels))) {
775
            if (buf != out_buf)
776
                memcpy(out_buf->extended_data[ch], buf->extended_data[ch],
777
                       buf->nb_samples * s->block_align);
778
            continue;
779
        }
780
781
        s->filter(s, buf->extended_data[ch], out_buf->extended_data[ch], buf->nb_samples,
782
                  &s->cache[ch].i1, &s->cache[ch].i2, &s->cache[ch].o1, &s->cache[ch].o2,
783
                  s->b0, s->b1, s->b2, s->a1, s->a2, &s->cache[ch].clippings, ctx->is_disabled);
784
    }
785
786
    return 0;
787
}
788
789
static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
790
{
791
    AVFilterContext  *ctx = inlink->dst;
792
    BiquadsContext *s     = ctx->priv;
793
    AVFilterLink *outlink = ctx->outputs[0];
794
    AVFrame *out_buf;
795
    ThreadData td;
796
    int ch;
797
798
    if (s->bypass)
799
        return ff_filter_frame(outlink, buf);
800
801
    if (av_frame_is_writable(buf)) {
802
        out_buf = buf;
803
    } else {
804
        out_buf = ff_get_audio_buffer(outlink, buf->nb_samples);
805
        if (!out_buf) {
806
            av_frame_free(&buf);
807
            return AVERROR(ENOMEM);
808
        }
809
        av_frame_copy_props(out_buf, buf);
810
    }
811
812
    td.in = buf;
813
    td.out = out_buf;
814
    ctx->internal->execute(ctx, filter_channel, &td, NULL, FFMIN(outlink->channels, ff_filter_get_nb_threads(ctx)));
815
816
    for (ch = 0; ch < outlink->channels; ch++) {
817
        if (s->cache[ch].clippings > 0)
818
            av_log(ctx, AV_LOG_WARNING, "Channel %d clipping %d times. Please reduce gain.\n",
819
                   ch, s->cache[ch].clippings);
820
        s->cache[ch].clippings = 0;
821
    }
822
823
    if (buf != out_buf)
824
        av_frame_free(&buf);
825
826
    return ff_filter_frame(outlink, out_buf);
827
}
828
829
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
830
                           char *res, int res_len, int flags)
831
{
832
    AVFilterLink *outlink = ctx->outputs[0];
833
    int ret;
834
835
    ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags);
836
    if (ret < 0)
837
        return ret;
838
839
    return config_filter(outlink, 0);
840
}
841
842
static av_cold void uninit(AVFilterContext *ctx)
843
{
844
    BiquadsContext *s = ctx->priv;
845
846
    av_freep(&s->cache);
847
}
848
849
static const AVFilterPad inputs[] = {
850
    {
851
        .name         = "default",
852
        .type         = AVMEDIA_TYPE_AUDIO,
853
        .filter_frame = filter_frame,
854
    },
855
    { NULL }
856
};
857
858
static const AVFilterPad outputs[] = {
859
    {
860
        .name         = "default",
861
        .type         = AVMEDIA_TYPE_AUDIO,
862
        .config_props = config_output,
863
    },
864
    { NULL }
865
};
866
867
#define OFFSET(x) offsetof(BiquadsContext, x)
868
#define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
869
#define AF AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
870
871
#define DEFINE_BIQUAD_FILTER(name_, description_)                       \
872
AVFILTER_DEFINE_CLASS(name_);                                           \
873
static av_cold int name_##_init(AVFilterContext *ctx)                   \
874
{                                                                       \
875
    BiquadsContext *s = ctx->priv;                                      \
876
    s->filter_type = name_;                                             \
877
    return 0;                                                           \
878
}                                                                       \
879
                                                         \
880
AVFilter ff_af_##name_ = {                               \
881
    .name          = #name_,                             \
882
    .description   = NULL_IF_CONFIG_SMALL(description_), \
883
    .priv_size     = sizeof(BiquadsContext),             \
884
    .init          = name_##_init,                       \
885
    .uninit        = uninit,                             \
886
    .query_formats = query_formats,                      \
887
    .inputs        = inputs,                             \
888
    .outputs       = outputs,                            \
889
    .priv_class    = &name_##_class,                     \
890
    .process_command = process_command,                  \
891
    .flags         = AVFILTER_FLAG_SLICE_THREADS | AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL, \
892
}
893
894
#if CONFIG_EQUALIZER_FILTER
895
static const AVOption equalizer_options[] = {
896
    {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 999999, FLAGS},
897
    {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 999999, FLAGS},
898
    {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
899
    {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
900
    {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
901
    {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
902
    {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
903
    {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
904
    {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
905
    {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 99999, FLAGS},
906
    {"w",     "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 99999, FLAGS},
907
    {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
908
    {"g",    "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
909
    {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
910
    {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
911
    {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
912
    {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
913
    {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
914
    {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
915
    {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
916
    {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
917
    {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
918
    {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
919
    {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
920
    {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
921
    {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
922
    {"r",         "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
923
    {"auto", "automatic",            0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"},
924
    {"s16", "signed 16-bit",         0, AV_OPT_TYPE_CONST, {.i64=0},  0, 0, AF, "precision"},
925
    {"s32", "signed 32-bit",         0, AV_OPT_TYPE_CONST, {.i64=1},  0, 0, AF, "precision"},
926
    {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2},  0, 0, AF, "precision"},
927
    {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3},  0, 0, AF, "precision"},
928
    {NULL}
929
};
930
931
DEFINE_BIQUAD_FILTER(equalizer, "Apply two-pole peaking equalization (EQ) filter.");
932
#endif  /* CONFIG_EQUALIZER_FILTER */
933
#if CONFIG_BASS_FILTER || CONFIG_LOWSHELF_FILTER
934
static const AVOption bass_lowshelf_options[] = {
935
    {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
936
    {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
937
    {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
938
    {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
939
    {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
940
    {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
941
    {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
942
    {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
943
    {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
944
    {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
945
    {"w",     "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
946
    {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
947
    {"g",    "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
948
    {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
949
    {"p",     "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
950
    {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
951
    {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
952
    {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
953
    {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
954
    {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
955
    {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
956
    {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
957
    {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
958
    {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
959
    {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
960
    {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
961
    {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
962
    {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
963
    {"r",         "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
964
    {"auto", "automatic",            0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"},
965
    {"s16", "signed 16-bit",         0, AV_OPT_TYPE_CONST, {.i64=0},  0, 0, AF, "precision"},
966
    {"s32", "signed 32-bit",         0, AV_OPT_TYPE_CONST, {.i64=1},  0, 0, AF, "precision"},
967
    {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2},  0, 0, AF, "precision"},
968
    {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3},  0, 0, AF, "precision"},
969
    {NULL}
970
};
971
972
#if CONFIG_BASS_FILTER
973
#define bass_options bass_lowshelf_options
974
DEFINE_BIQUAD_FILTER(bass, "Boost or cut lower frequencies.");
975
#endif  /* CONFIG_BASS_FILTER */
976
977
#if CONFIG_LOWSHELF_FILTER
978
#define lowshelf_options bass_lowshelf_options
979
DEFINE_BIQUAD_FILTER(lowshelf, "Apply a low shelf filter.");
980
#endif  /* CONFIG_LOWSHELF_FILTER */
981
#endif  /* CONFIG_BASS_FILTER || CONFIG LOWSHELF_FILTER */
982
#if CONFIG_TREBLE_FILTER || CONFIG_HIGHSHELF_FILTER
983
static const AVOption treble_highshelf_options[] = {
984
    {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
985
    {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
986
    {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
987
    {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
988
    {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
989
    {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
990
    {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
991
    {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
992
    {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
993
    {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
994
    {"w",     "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
995
    {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
996
    {"g",    "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
997
    {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
998
    {"p",     "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
999
    {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1000
    {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1001
    {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1002
    {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1003
    {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1004
    {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1005
    {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1006
    {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1007
    {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
1008
    {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
1009
    {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
1010
    {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
1011
    {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1012
    {"r",         "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1013
    {"auto", "automatic",            0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"},
1014
    {"s16", "signed 16-bit",         0, AV_OPT_TYPE_CONST, {.i64=0},  0, 0, AF, "precision"},
1015
    {"s32", "signed 32-bit",         0, AV_OPT_TYPE_CONST, {.i64=1},  0, 0, AF, "precision"},
1016
    {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2},  0, 0, AF, "precision"},
1017
    {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3},  0, 0, AF, "precision"},
1018
    {NULL}
1019
};
1020
1021
#if CONFIG_TREBLE_FILTER
1022
#define treble_options treble_highshelf_options
1023
DEFINE_BIQUAD_FILTER(treble, "Boost or cut upper frequencies.");
1024
#endif  /* CONFIG_TREBLE_FILTER */
1025
1026
#if CONFIG_HIGHSHELF_FILTER
1027
#define highshelf_options treble_highshelf_options
1028
DEFINE_BIQUAD_FILTER(highshelf, "Apply a high shelf filter.");
1029
#endif  /* CONFIG_HIGHSHELF_FILTER */
1030
#endif  /* CONFIG_TREBLE_FILTER || CONFIG_HIGHSHELF_FILTER */
1031
#if CONFIG_BANDPASS_FILTER
1032
static const AVOption bandpass_options[] = {
1033
    {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1034
    {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1035
    {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1036
    {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1037
    {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
1038
    {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
1039
    {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
1040
    {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
1041
    {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
1042
    {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
1043
    {"w",     "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
1044
    {"csg",   "use constant skirt gain", OFFSET(csg), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1045
    {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1046
    {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1047
    {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1048
    {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1049
    {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1050
    {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1051
    {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1052
    {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1053
    {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
1054
    {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
1055
    {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
1056
    {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
1057
    {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1058
    {"r",         "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1059
    {"auto", "automatic",            0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"},
1060
    {"s16", "signed 16-bit",         0, AV_OPT_TYPE_CONST, {.i64=0},  0, 0, AF, "precision"},
1061
    {"s32", "signed 32-bit",         0, AV_OPT_TYPE_CONST, {.i64=1},  0, 0, AF, "precision"},
1062
    {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2},  0, 0, AF, "precision"},
1063
    {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3},  0, 0, AF, "precision"},
1064
    {NULL}
1065
};
1066
1067
DEFINE_BIQUAD_FILTER(bandpass, "Apply a two-pole Butterworth band-pass filter.");
1068
#endif  /* CONFIG_BANDPASS_FILTER */
1069
#if CONFIG_BANDREJECT_FILTER
1070
static const AVOption bandreject_options[] = {
1071
    {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1072
    {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1073
    {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1074
    {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1075
    {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
1076
    {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
1077
    {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
1078
    {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
1079
    {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
1080
    {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
1081
    {"w",     "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
1082
    {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1083
    {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1084
    {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1085
    {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1086
    {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1087
    {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1088
    {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1089
    {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1090
    {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
1091
    {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
1092
    {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
1093
    {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
1094
    {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1095
    {"r",         "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1096
    {"auto", "automatic",            0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"},
1097
    {"s16", "signed 16-bit",         0, AV_OPT_TYPE_CONST, {.i64=0},  0, 0, AF, "precision"},
1098
    {"s32", "signed 32-bit",         0, AV_OPT_TYPE_CONST, {.i64=1},  0, 0, AF, "precision"},
1099
    {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2},  0, 0, AF, "precision"},
1100
    {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3},  0, 0, AF, "precision"},
1101
    {NULL}
1102
};
1103
1104
DEFINE_BIQUAD_FILTER(bandreject, "Apply a two-pole Butterworth band-reject filter.");
1105
#endif  /* CONFIG_BANDREJECT_FILTER */
1106
#if CONFIG_LOWPASS_FILTER
1107
static const AVOption lowpass_options[] = {
1108
    {"frequency", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=500}, 0, 999999, FLAGS},
1109
    {"f",         "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=500}, 0, 999999, FLAGS},
1110
    {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1111
    {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1112
    {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
1113
    {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
1114
    {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
1115
    {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
1116
    {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
1117
    {"width", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
1118
    {"w",     "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
1119
    {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
1120
    {"p",     "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
1121
    {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1122
    {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1123
    {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1124
    {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1125
    {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1126
    {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1127
    {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1128
    {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1129
    {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
1130
    {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
1131
    {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
1132
    {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
1133
    {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1134
    {"r",         "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1135
    {"auto", "automatic",            0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"},
1136
    {"s16", "signed 16-bit",         0, AV_OPT_TYPE_CONST, {.i64=0},  0, 0, AF, "precision"},
1137
    {"s32", "signed 32-bit",         0, AV_OPT_TYPE_CONST, {.i64=1},  0, 0, AF, "precision"},
1138
    {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2},  0, 0, AF, "precision"},
1139
    {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3},  0, 0, AF, "precision"},
1140
    {NULL}
1141
};
1142
1143
DEFINE_BIQUAD_FILTER(lowpass, "Apply a low-pass filter with 3dB point frequency.");
1144
#endif  /* CONFIG_LOWPASS_FILTER */
1145
#if CONFIG_HIGHPASS_FILTER
1146
static const AVOption highpass_options[] = {
1147
    {"frequency", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1148
    {"f",         "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1149
    {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1150
    {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1151
    {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
1152
    {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
1153
    {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
1154
    {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
1155
    {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
1156
    {"width", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
1157
    {"w",     "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
1158
    {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
1159
    {"p",     "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
1160
    {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1161
    {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1162
    {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1163
    {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1164
    {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1165
    {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1166
    {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1167
    {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1168
    {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
1169
    {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
1170
    {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
1171
    {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
1172
    {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1173
    {"r",         "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1174
    {"auto", "automatic",            0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"},
1175
    {"s16", "signed 16-bit",         0, AV_OPT_TYPE_CONST, {.i64=0},  0, 0, AF, "precision"},
1176
    {"s32", "signed 32-bit",         0, AV_OPT_TYPE_CONST, {.i64=1},  0, 0, AF, "precision"},
1177
    {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2},  0, 0, AF, "precision"},
1178
    {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3},  0, 0, AF, "precision"},
1179
    {NULL}
1180
};
1181
1182
DEFINE_BIQUAD_FILTER(highpass, "Apply a high-pass filter with 3dB point frequency.");
1183
#endif  /* CONFIG_HIGHPASS_FILTER */
1184
#if CONFIG_ALLPASS_FILTER
1185
static const AVOption allpass_options[] = {
1186
    {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1187
    {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1188
    {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=HERTZ}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1189
    {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=HERTZ}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1190
    {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
1191
    {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
1192
    {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
1193
    {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
1194
    {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
1195
    {"width", "set filter-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=707.1}, 0, 99999, FLAGS},
1196
    {"w",     "set filter-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=707.1}, 0, 99999, FLAGS},
1197
    {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1198
    {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1199
    {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1200
    {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1201
    {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1202
    {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1203
    {"order", "set filter order", OFFSET(order), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
1204
    {"o",     "set filter order", OFFSET(order), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
1205
    {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1206
    {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1207
    {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
1208
    {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
1209
    {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
1210
    {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
1211
    {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1212
    {"r",         "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1213
    {"auto", "automatic",            0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"},
1214
    {"s16", "signed 16-bit",         0, AV_OPT_TYPE_CONST, {.i64=0},  0, 0, AF, "precision"},
1215
    {"s32", "signed 32-bit",         0, AV_OPT_TYPE_CONST, {.i64=1},  0, 0, AF, "precision"},
1216
    {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2},  0, 0, AF, "precision"},
1217
    {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3},  0, 0, AF, "precision"},
1218
    {NULL}
1219
};
1220
1221
DEFINE_BIQUAD_FILTER(allpass, "Apply a two-pole all-pass filter.");
1222
#endif  /* CONFIG_ALLPASS_FILTER */
1223
#if CONFIG_BIQUAD_FILTER
1224
static const AVOption biquad_options[] = {
1225
    {"a0", NULL, OFFSET(oa0), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT32_MIN, INT32_MAX, FLAGS},
1226
    {"a1", NULL, OFFSET(oa1), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
1227
    {"a2", NULL, OFFSET(oa2), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
1228
    {"b0", NULL, OFFSET(ob0), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
1229
    {"b1", NULL, OFFSET(ob1), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
1230
    {"b2", NULL, OFFSET(ob2), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
1231
    {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1232
    {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1233
    {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1234
    {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1235
    {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1236
    {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1237
    {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1238
    {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1239
    {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
1240
    {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
1241
    {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
1242
    {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
1243
    {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1244
    {"r",         "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1245
    {"auto", "automatic",            0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"},
1246
    {"s16", "signed 16-bit",         0, AV_OPT_TYPE_CONST, {.i64=0},  0, 0, AF, "precision"},
1247
    {"s32", "signed 32-bit",         0, AV_OPT_TYPE_CONST, {.i64=1},  0, 0, AF, "precision"},
1248
    {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2},  0, 0, AF, "precision"},
1249
    {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3},  0, 0, AF, "precision"},
1250
    {NULL}
1251
};
1252
1253
DEFINE_BIQUAD_FILTER(biquad, "Apply a biquad IIR filter with the given coefficients.");
1254
#endif  /* CONFIG_BIQUAD_FILTER */