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