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