]> git.sesse.net Git - ffmpeg/blob - libavfilter/af_biquads.c
doc: mark "ADPCM IMA High Voltage Software ALP" as encodable
[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         s0   = t1;                                                            \
392         out += t1 * v2;                                                       \
393                                                                               \
394         t0    = t0 - k0 * s1;                                                 \
395         t1    = t0 * k0 + s1;                                                 \
396         out  += t1 * v1;                                                      \
397         s1    = t1;                                                           \
398                                                                               \
399         out  += t0 * v0;                                                      \
400         s0    = s1;                                                           \
401         s1    = t0;                                                           \
402                                                                               \
403         out = out * wet + in * dry;                                           \
404         if (disabled) {                                                       \
405             obuf[i] = in;                                                     \
406         } else if (need_clipping && out < min) {                              \
407             (*clippings)++;                                                   \
408             obuf[i] = min;                                                    \
409         } else if (need_clipping && out > max) {                              \
410             (*clippings)++;                                                   \
411             obuf[i] = max;                                                    \
412         } else {                                                              \
413             obuf[i] = out;                                                    \
414         }                                                                     \
415     }                                                                         \
416     *z1 = s0;                                                                 \
417     *z2 = s1;                                                                 \
418 }
419
420 BIQUAD_LATT_FILTER(s16, int16_t, INT16_MIN, INT16_MAX, 1)
421 BIQUAD_LATT_FILTER(s32, int32_t, INT32_MIN, INT32_MAX, 1)
422 BIQUAD_LATT_FILTER(flt, float,   -1., 1., 0)
423 BIQUAD_LATT_FILTER(dbl, double,  -1., 1., 0)
424
425 static void convert_dir2latt(BiquadsContext *s)
426 {
427     double k0, k1, v0, v1, v2;
428
429     k1 = s->a2;
430     k0 = s->a1 / (1. + k1);
431     v2 = s->b2;
432     v1 = s->b1 - v2 * s->a1;
433     v0 = s->b0 - v1 * k0 - v2 * k1;
434
435     s->a1 = k0;
436     s->a2 = k1;
437     s->b0 = v0;
438     s->b1 = v1;
439     s->b2 = v2;
440 }
441
442 static int config_filter(AVFilterLink *outlink, int reset)
443 {
444     AVFilterContext *ctx    = outlink->src;
445     BiquadsContext *s       = ctx->priv;
446     AVFilterLink *inlink    = ctx->inputs[0];
447     double A = ff_exp10(s->gain / 40);
448     double w0 = 2 * M_PI * s->frequency / inlink->sample_rate;
449     double K = tan(w0 / 2.);
450     double alpha, beta;
451
452     if (w0 > M_PI) {
453         av_log(ctx, AV_LOG_ERROR,
454                "Invalid frequency %f. Frequency must be less than half the sample-rate %d.\n",
455                s->frequency, inlink->sample_rate);
456         return AVERROR(EINVAL);
457     }
458
459     switch (s->width_type) {
460     case NONE:
461         alpha = 0.0;
462         break;
463     case HERTZ:
464         alpha = sin(w0) / (2 * s->frequency / s->width);
465         break;
466     case KHERTZ:
467         alpha = sin(w0) / (2 * s->frequency / (s->width * 1000));
468         break;
469     case OCTAVE:
470         alpha = sin(w0) * sinh(log(2.) / 2 * s->width * w0 / sin(w0));
471         break;
472     case QFACTOR:
473         alpha = sin(w0) / (2 * s->width);
474         break;
475     case SLOPE:
476         alpha = sin(w0) / 2 * sqrt((A + 1 / A) * (1 / s->width - 1) + 2);
477         break;
478     default:
479         av_assert0(0);
480     }
481
482     beta = 2 * sqrt(A);
483
484     switch (s->filter_type) {
485     case biquad:
486         s->a0 = s->oa0;
487         s->a1 = s->oa1;
488         s->a2 = s->oa2;
489         s->b0 = s->ob0;
490         s->b1 = s->ob1;
491         s->b2 = s->ob2;
492         break;
493     case equalizer:
494         s->a0 =   1 + alpha / A;
495         s->a1 =  -2 * cos(w0);
496         s->a2 =   1 - alpha / A;
497         s->b0 =   1 + alpha * A;
498         s->b1 =  -2 * cos(w0);
499         s->b2 =   1 - alpha * A;
500         break;
501     case bass:
502         beta = sqrt((A * A + 1) - (A - 1) * (A - 1));
503     case lowshelf:
504         s->a0 =          (A + 1) + (A - 1) * cos(w0) + beta * alpha;
505         s->a1 =    -2 * ((A - 1) + (A + 1) * cos(w0));
506         s->a2 =          (A + 1) + (A - 1) * cos(w0) - beta * alpha;
507         s->b0 =     A * ((A + 1) - (A - 1) * cos(w0) + beta * alpha);
508         s->b1 = 2 * A * ((A - 1) - (A + 1) * cos(w0));
509         s->b2 =     A * ((A + 1) - (A - 1) * cos(w0) - beta * alpha);
510         break;
511     case treble:
512         beta = sqrt((A * A + 1) - (A - 1) * (A - 1));
513     case highshelf:
514         s->a0 =          (A + 1) - (A - 1) * cos(w0) + beta * alpha;
515         s->a1 =     2 * ((A - 1) - (A + 1) * cos(w0));
516         s->a2 =          (A + 1) - (A - 1) * cos(w0) - beta * alpha;
517         s->b0 =     A * ((A + 1) + (A - 1) * cos(w0) + beta * alpha);
518         s->b1 =-2 * A * ((A - 1) + (A + 1) * cos(w0));
519         s->b2 =     A * ((A + 1) + (A - 1) * cos(w0) - beta * alpha);
520         break;
521     case bandpass:
522         if (s->csg) {
523             s->a0 =  1 + alpha;
524             s->a1 = -2 * cos(w0);
525             s->a2 =  1 - alpha;
526             s->b0 =  sin(w0) / 2;
527             s->b1 =  0;
528             s->b2 = -sin(w0) / 2;
529         } else {
530             s->a0 =  1 + alpha;
531             s->a1 = -2 * cos(w0);
532             s->a2 =  1 - alpha;
533             s->b0 =  alpha;
534             s->b1 =  0;
535             s->b2 = -alpha;
536         }
537         break;
538     case bandreject:
539         s->a0 =  1 + alpha;
540         s->a1 = -2 * cos(w0);
541         s->a2 =  1 - alpha;
542         s->b0 =  1;
543         s->b1 = -2 * cos(w0);
544         s->b2 =  1;
545         break;
546     case lowpass:
547         if (s->poles == 1) {
548             s->a0 = 1;
549             s->a1 = -exp(-w0);
550             s->a2 = 0;
551             s->b0 = 1 + s->a1;
552             s->b1 = 0;
553             s->b2 = 0;
554         } else {
555             s->a0 =  1 + alpha;
556             s->a1 = -2 * cos(w0);
557             s->a2 =  1 - alpha;
558             s->b0 = (1 - cos(w0)) / 2;
559             s->b1 =  1 - cos(w0);
560             s->b2 = (1 - cos(w0)) / 2;
561         }
562         break;
563     case highpass:
564         if (s->poles == 1) {
565             s->a0 = 1;
566             s->a1 = -exp(-w0);
567             s->a2 = 0;
568             s->b0 = (1 - s->a1) / 2;
569             s->b1 = -s->b0;
570             s->b2 = 0;
571         } else {
572             s->a0 =   1 + alpha;
573             s->a1 =  -2 * cos(w0);
574             s->a2 =   1 - alpha;
575             s->b0 =  (1 + cos(w0)) / 2;
576             s->b1 = -(1 + cos(w0));
577             s->b2 =  (1 + cos(w0)) / 2;
578         }
579         break;
580     case allpass:
581         switch (s->order) {
582         case 1:
583             s->a0 = 1.;
584             s->a1 = -(1. - K) / (1. + K);
585             s->a2 = 0.;
586             s->b0 = s->a1;
587             s->b1 = s->a0;
588             s->b2 = 0.;
589             break;
590         case 2:
591             s->a0 =  1 + alpha;
592             s->a1 = -2 * cos(w0);
593             s->a2 =  1 - alpha;
594             s->b0 =  1 - alpha;
595             s->b1 = -2 * cos(w0);
596             s->b2 =  1 + alpha;
597         break;
598         }
599         break;
600     default:
601         av_assert0(0);
602     }
603
604     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);
605
606     s->a1 /= s->a0;
607     s->a2 /= s->a0;
608     s->b0 /= s->a0;
609     s->b1 /= s->a0;
610     s->b2 /= s->a0;
611     s->a0 /= s->a0;
612
613     if (s->normalize && fabs(s->b0 + s->b1 + s->b2) > 1e-6) {
614         double factor = (s->a0 + s->a1 + s->a2) / (s->b0 + s->b1 + s->b2);
615
616         s->b0 *= factor;
617         s->b1 *= factor;
618         s->b2 *= factor;
619     }
620
621     s->cache = av_realloc_f(s->cache, sizeof(ChanCache), inlink->channels);
622     if (!s->cache)
623         return AVERROR(ENOMEM);
624     if (reset)
625         memset(s->cache, 0, sizeof(ChanCache) * inlink->channels);
626
627     switch (s->transform_type) {
628     case DI:
629         switch (inlink->format) {
630         case AV_SAMPLE_FMT_S16P:
631             s->filter = biquad_s16;
632             break;
633         case AV_SAMPLE_FMT_S32P:
634             s->filter = biquad_s32;
635             break;
636         case AV_SAMPLE_FMT_FLTP:
637             s->filter = biquad_flt;
638             break;
639         case AV_SAMPLE_FMT_DBLP:
640             s->filter = biquad_dbl;
641             break;
642         default: av_assert0(0);
643         }
644         break;
645     case DII:
646         switch (inlink->format) {
647         case AV_SAMPLE_FMT_S16P:
648             s->filter = biquad_dii_s16;
649             break;
650         case AV_SAMPLE_FMT_S32P:
651             s->filter = biquad_dii_s32;
652             break;
653         case AV_SAMPLE_FMT_FLTP:
654             s->filter = biquad_dii_flt;
655             break;
656         case AV_SAMPLE_FMT_DBLP:
657             s->filter = biquad_dii_dbl;
658             break;
659         default: av_assert0(0);
660         }
661         break;
662     case TDII:
663         switch (inlink->format) {
664         case AV_SAMPLE_FMT_S16P:
665             s->filter = biquad_tdii_s16;
666             break;
667         case AV_SAMPLE_FMT_S32P:
668             s->filter = biquad_tdii_s32;
669             break;
670         case AV_SAMPLE_FMT_FLTP:
671             s->filter = biquad_tdii_flt;
672             break;
673         case AV_SAMPLE_FMT_DBLP:
674             s->filter = biquad_tdii_dbl;
675             break;
676         default: av_assert0(0);
677         }
678         break;
679     case LATT:
680         switch (inlink->format) {
681         case AV_SAMPLE_FMT_S16P:
682             s->filter = biquad_latt_s16;
683             break;
684         case AV_SAMPLE_FMT_S32P:
685             s->filter = biquad_latt_s32;
686             break;
687         case AV_SAMPLE_FMT_FLTP:
688             s->filter = biquad_latt_flt;
689             break;
690         case AV_SAMPLE_FMT_DBLP:
691             s->filter = biquad_latt_dbl;
692             break;
693         default: av_assert0(0);
694         }
695         break;
696     default:
697         av_assert0(0);
698      }
699
700      s->block_align = av_get_bytes_per_sample(inlink->format);
701
702      if (s->transform_type == LATT)
703          convert_dir2latt(s);
704
705     return 0;
706 }
707
708 static int config_output(AVFilterLink *outlink)
709 {
710     return config_filter(outlink, 1);
711 }
712
713 typedef struct ThreadData {
714     AVFrame *in, *out;
715 } ThreadData;
716
717 static int filter_channel(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
718 {
719     AVFilterLink *inlink = ctx->inputs[0];
720     ThreadData *td = arg;
721     AVFrame *buf = td->in;
722     AVFrame *out_buf = td->out;
723     BiquadsContext *s = ctx->priv;
724     const int start = (buf->channels * jobnr) / nb_jobs;
725     const int end = (buf->channels * (jobnr+1)) / nb_jobs;
726     int ch;
727
728     for (ch = start; ch < end; ch++) {
729         if (!((av_channel_layout_extract_channel(inlink->channel_layout, ch) & s->channels))) {
730             if (buf != out_buf)
731                 memcpy(out_buf->extended_data[ch], buf->extended_data[ch],
732                        buf->nb_samples * s->block_align);
733             continue;
734         }
735
736         s->filter(s, buf->extended_data[ch], out_buf->extended_data[ch], buf->nb_samples,
737                   &s->cache[ch].i1, &s->cache[ch].i2, &s->cache[ch].o1, &s->cache[ch].o2,
738                   s->b0, s->b1, s->b2, s->a1, s->a2, &s->cache[ch].clippings, ctx->is_disabled);
739     }
740
741     return 0;
742 }
743
744 static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
745 {
746     AVFilterContext  *ctx = inlink->dst;
747     BiquadsContext *s     = ctx->priv;
748     AVFilterLink *outlink = ctx->outputs[0];
749     AVFrame *out_buf;
750     ThreadData td;
751     int ch;
752
753     if (av_frame_is_writable(buf)) {
754         out_buf = buf;
755     } else {
756         out_buf = ff_get_audio_buffer(outlink, buf->nb_samples);
757         if (!out_buf) {
758             av_frame_free(&buf);
759             return AVERROR(ENOMEM);
760         }
761         av_frame_copy_props(out_buf, buf);
762     }
763
764     td.in = buf;
765     td.out = out_buf;
766     ctx->internal->execute(ctx, filter_channel, &td, NULL, FFMIN(outlink->channels, ff_filter_get_nb_threads(ctx)));
767
768     for (ch = 0; ch < outlink->channels; ch++) {
769         if (s->cache[ch].clippings > 0)
770             av_log(ctx, AV_LOG_WARNING, "Channel %d clipping %d times. Please reduce gain.\n",
771                    ch, s->cache[ch].clippings);
772         s->cache[ch].clippings = 0;
773     }
774
775     if (buf != out_buf)
776         av_frame_free(&buf);
777
778     return ff_filter_frame(outlink, out_buf);
779 }
780
781 static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
782                            char *res, int res_len, int flags)
783 {
784     AVFilterLink *outlink = ctx->outputs[0];
785     int ret;
786
787     ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags);
788     if (ret < 0)
789         return ret;
790
791     return config_filter(outlink, 0);
792 }
793
794 static av_cold void uninit(AVFilterContext *ctx)
795 {
796     BiquadsContext *s = ctx->priv;
797
798     av_freep(&s->cache);
799 }
800
801 static const AVFilterPad inputs[] = {
802     {
803         .name         = "default",
804         .type         = AVMEDIA_TYPE_AUDIO,
805         .filter_frame = filter_frame,
806     },
807     { NULL }
808 };
809
810 static const AVFilterPad outputs[] = {
811     {
812         .name         = "default",
813         .type         = AVMEDIA_TYPE_AUDIO,
814         .config_props = config_output,
815     },
816     { NULL }
817 };
818
819 #define OFFSET(x) offsetof(BiquadsContext, x)
820 #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
821 #define AF AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
822
823 #define DEFINE_BIQUAD_FILTER(name_, description_)                       \
824 AVFILTER_DEFINE_CLASS(name_);                                           \
825 static av_cold int name_##_init(AVFilterContext *ctx) \
826 {                                                                       \
827     BiquadsContext *s = ctx->priv;                                      \
828     s->class = &name_##_class;                                          \
829     s->filter_type = name_;                                             \
830     return init(ctx);                                             \
831 }                                                                       \
832                                                          \
833 AVFilter ff_af_##name_ = {                         \
834     .name          = #name_,                             \
835     .description   = NULL_IF_CONFIG_SMALL(description_), \
836     .priv_size     = sizeof(BiquadsContext),             \
837     .init          = name_##_init,                       \
838     .uninit        = uninit,                             \
839     .query_formats = query_formats,                      \
840     .inputs        = inputs,                             \
841     .outputs       = outputs,                            \
842     .priv_class    = &name_##_class,                     \
843     .process_command = process_command,                  \
844     .flags         = AVFILTER_FLAG_SLICE_THREADS | AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL, \
845 }
846
847 #if CONFIG_EQUALIZER_FILTER
848 static const AVOption equalizer_options[] = {
849     {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 999999, FLAGS},
850     {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 999999, FLAGS},
851     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
852     {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
853     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
854     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
855     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
856     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
857     {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
858     {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 99999, FLAGS},
859     {"w",     "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 99999, FLAGS},
860     {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
861     {"g",    "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
862     {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
863     {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
864     {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
865     {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
866     {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
867     {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
868     {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
869     {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
870     {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
871     {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
872     {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
873     {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
874     {NULL}
875 };
876
877 DEFINE_BIQUAD_FILTER(equalizer, "Apply two-pole peaking equalization (EQ) filter.");
878 #endif  /* CONFIG_EQUALIZER_FILTER */
879 #if CONFIG_BASS_FILTER
880 static const AVOption bass_options[] = {
881     {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
882     {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
883     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
884     {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
885     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
886     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
887     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
888     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
889     {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
890     {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
891     {"w",     "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
892     {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
893     {"g",    "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
894     {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
895     {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
896     {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
897     {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
898     {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
899     {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
900     {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
901     {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
902     {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
903     {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
904     {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
905     {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
906     {NULL}
907 };
908
909 DEFINE_BIQUAD_FILTER(bass, "Boost or cut lower frequencies.");
910 #endif  /* CONFIG_BASS_FILTER */
911 #if CONFIG_TREBLE_FILTER
912 static const AVOption treble_options[] = {
913     {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
914     {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
915     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
916     {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
917     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
918     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
919     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
920     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
921     {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
922     {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
923     {"w",     "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
924     {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
925     {"g",    "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
926     {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
927     {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
928     {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
929     {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
930     {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
931     {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
932     {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
933     {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
934     {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
935     {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
936     {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
937     {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
938     {NULL}
939 };
940
941 DEFINE_BIQUAD_FILTER(treble, "Boost or cut upper frequencies.");
942 #endif  /* CONFIG_TREBLE_FILTER */
943 #if CONFIG_BANDPASS_FILTER
944 static const AVOption bandpass_options[] = {
945     {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
946     {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
947     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
948     {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
949     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
950     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
951     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
952     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
953     {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
954     {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
955     {"w",     "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
956     {"csg",   "use constant skirt gain", OFFSET(csg), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
957     {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
958     {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
959     {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
960     {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
961     {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
962     {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
963     {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
964     {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
965     {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
966     {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
967     {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
968     {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
969     {NULL}
970 };
971
972 DEFINE_BIQUAD_FILTER(bandpass, "Apply a two-pole Butterworth band-pass filter.");
973 #endif  /* CONFIG_BANDPASS_FILTER */
974 #if CONFIG_BANDREJECT_FILTER
975 static const AVOption bandreject_options[] = {
976     {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
977     {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
978     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
979     {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
980     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
981     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
982     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
983     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
984     {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
985     {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
986     {"w",     "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
987     {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
988     {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
989     {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
990     {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
991     {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
992     {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
993     {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
994     {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
995     {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
996     {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
997     {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
998     {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
999     {NULL}
1000 };
1001
1002 DEFINE_BIQUAD_FILTER(bandreject, "Apply a two-pole Butterworth band-reject filter.");
1003 #endif  /* CONFIG_BANDREJECT_FILTER */
1004 #if CONFIG_LOWPASS_FILTER
1005 static const AVOption lowpass_options[] = {
1006     {"frequency", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=500}, 0, 999999, FLAGS},
1007     {"f",         "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=500}, 0, 999999, FLAGS},
1008     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1009     {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1010     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
1011     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
1012     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
1013     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
1014     {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
1015     {"width", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
1016     {"w",     "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
1017     {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
1018     {"p",     "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
1019     {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1020     {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1021     {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1022     {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1023     {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1024     {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1025     {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1026     {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1027     {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
1028     {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
1029     {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
1030     {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
1031     {NULL}
1032 };
1033
1034 DEFINE_BIQUAD_FILTER(lowpass, "Apply a low-pass filter with 3dB point frequency.");
1035 #endif  /* CONFIG_LOWPASS_FILTER */
1036 #if CONFIG_HIGHPASS_FILTER
1037 static const AVOption highpass_options[] = {
1038     {"frequency", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1039     {"f",         "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1040     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1041     {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1042     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
1043     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
1044     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
1045     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
1046     {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
1047     {"width", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
1048     {"w",     "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
1049     {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
1050     {"p",     "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
1051     {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1052     {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1053     {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1054     {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1055     {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1056     {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1057     {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1058     {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1059     {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
1060     {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
1061     {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
1062     {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
1063     {NULL}
1064 };
1065
1066 DEFINE_BIQUAD_FILTER(highpass, "Apply a high-pass filter with 3dB point frequency.");
1067 #endif  /* CONFIG_HIGHPASS_FILTER */
1068 #if CONFIG_ALLPASS_FILTER
1069 static const AVOption allpass_options[] = {
1070     {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1071     {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1072     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=HERTZ}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1073     {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=HERTZ}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1074     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
1075     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
1076     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
1077     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
1078     {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
1079     {"width", "set filter-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=707.1}, 0, 99999, FLAGS},
1080     {"w",     "set filter-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=707.1}, 0, 99999, FLAGS},
1081     {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1082     {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1083     {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1084     {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1085     {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1086     {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1087     {"order", "set filter order", OFFSET(order), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
1088     {"o",     "set filter order", OFFSET(order), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
1089     {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1090     {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1091     {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
1092     {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
1093     {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
1094     {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
1095     {NULL}
1096 };
1097
1098 DEFINE_BIQUAD_FILTER(allpass, "Apply a two-pole all-pass filter.");
1099 #endif  /* CONFIG_ALLPASS_FILTER */
1100 #if CONFIG_LOWSHELF_FILTER
1101 static const AVOption lowshelf_options[] = {
1102     {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
1103     {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
1104     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1105     {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1106     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
1107     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
1108     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
1109     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
1110     {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
1111     {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
1112     {"w",     "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
1113     {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
1114     {"g",    "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
1115     {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1116     {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1117     {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1118     {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1119     {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1120     {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1121     {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1122     {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1123     {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
1124     {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
1125     {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
1126     {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
1127     {NULL}
1128 };
1129
1130 DEFINE_BIQUAD_FILTER(lowshelf, "Apply a low shelf filter.");
1131 #endif  /* CONFIG_LOWSHELF_FILTER */
1132 #if CONFIG_HIGHSHELF_FILTER
1133 static const AVOption highshelf_options[] = {
1134     {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1135     {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1136     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1137     {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1138     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
1139     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
1140     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
1141     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
1142     {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
1143     {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
1144     {"w",     "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
1145     {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
1146     {"g",    "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
1147     {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1148     {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1149     {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1150     {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1151     {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1152     {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1153     {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1154     {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1155     {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
1156     {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
1157     {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
1158     {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
1159     {NULL}
1160 };
1161
1162 DEFINE_BIQUAD_FILTER(highshelf, "Apply a high shelf filter.");
1163 #endif  /* CONFIG_HIGHSHELF_FILTER */
1164 #if CONFIG_BIQUAD_FILTER
1165 static const AVOption biquad_options[] = {
1166     {"a0", NULL, OFFSET(oa0), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT32_MIN, INT32_MAX, FLAGS},
1167     {"a1", NULL, OFFSET(oa1), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
1168     {"a2", NULL, OFFSET(oa2), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
1169     {"b0", NULL, OFFSET(ob0), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
1170     {"b1", NULL, OFFSET(ob1), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
1171     {"b2", NULL, OFFSET(ob2), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
1172     {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1173     {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1174     {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1175     {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1176     {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1177     {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1178     {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1179     {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1180     {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
1181     {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
1182     {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
1183     {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
1184     {NULL}
1185 };
1186
1187 DEFINE_BIQUAD_FILTER(biquad, "Apply a biquad IIR filter with the given coefficients.");
1188 #endif  /* CONFIG_BIQUAD_FILTER */