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