]> git.sesse.net Git - ffmpeg/blob - libavfilter/af_biquads.c
6e1da52fb3495ad8dfef6b4d81dda53ef03c87da
[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         if (s->poles == 1) {
518             double A = ff_exp10(s->gain / 20);
519             double ro = -sin(w0 / 2. - M_PI_4 / (sin(w0 / 2. + M_PI_4)));
520             double n = (A + 1) / (A - 1);
521             double alpha1 = A == 1. ? 0. : n - FFSIGN(n) * sqrt(n * n - 1);
522             double beta0 = ((1 + A) + (1 - A) * alpha1) * 0.5;
523             double beta1 = ((1 - A) + (1 + A) * alpha1) * 0.5;
524
525             s->a0 = 1 + ro * alpha1;
526             s->a1 = -ro - alpha1;
527             s->a2 = 0;
528             s->b0 = beta0 + ro * beta1;
529             s->b1 = -beta1 - ro * beta0;
530             s->b2 = 0;
531         } else {
532             s->a0 =          (A + 1) + (A - 1) * cos(w0) + beta * alpha;
533             s->a1 =    -2 * ((A - 1) + (A + 1) * cos(w0));
534             s->a2 =          (A + 1) + (A - 1) * cos(w0) - beta * alpha;
535             s->b0 =     A * ((A + 1) - (A - 1) * cos(w0) + beta * alpha);
536             s->b1 = 2 * A * ((A - 1) - (A + 1) * cos(w0));
537             s->b2 =     A * ((A + 1) - (A - 1) * cos(w0) - beta * alpha);
538         }
539         break;
540     case treble:
541         beta = sqrt((A * A + 1) - (A - 1) * (A - 1));
542     case highshelf:
543         if (s->poles == 1) {
544             double A = ff_exp10(s->gain / 20);
545             double ro = sin(w0 / 2. - M_PI_4 / (sin(w0 / 2. + M_PI_4)));
546             double n = (A + 1) / (A - 1);
547             double alpha1 = A == 1. ? 0. : n - FFSIGN(n) * sqrt(n * n - 1);
548             double beta0 = ((1 + A) + (1 - A) * alpha1) * 0.5;
549             double beta1 = ((1 - A) + (1 + A) * alpha1) * 0.5;
550
551             s->a0 = 1 + ro * alpha1;
552             s->a1 = ro + alpha1;
553             s->a2 = 0;
554             s->b0 = beta0 + ro * beta1;
555             s->b1 = beta1 + ro * beta0;
556             s->b2 = 0;
557         } else {
558             s->a0 =          (A + 1) - (A - 1) * cos(w0) + beta * alpha;
559             s->a1 =     2 * ((A - 1) - (A + 1) * cos(w0));
560             s->a2 =          (A + 1) - (A - 1) * cos(w0) - beta * alpha;
561             s->b0 =     A * ((A + 1) + (A - 1) * cos(w0) + beta * alpha);
562             s->b1 =-2 * A * ((A - 1) + (A + 1) * cos(w0));
563             s->b2 =     A * ((A + 1) + (A - 1) * cos(w0) - beta * alpha);
564         }
565         break;
566     case bandpass:
567         if (s->csg) {
568             s->a0 =  1 + alpha;
569             s->a1 = -2 * cos(w0);
570             s->a2 =  1 - alpha;
571             s->b0 =  sin(w0) / 2;
572             s->b1 =  0;
573             s->b2 = -sin(w0) / 2;
574         } else {
575             s->a0 =  1 + alpha;
576             s->a1 = -2 * cos(w0);
577             s->a2 =  1 - alpha;
578             s->b0 =  alpha;
579             s->b1 =  0;
580             s->b2 = -alpha;
581         }
582         break;
583     case bandreject:
584         s->a0 =  1 + alpha;
585         s->a1 = -2 * cos(w0);
586         s->a2 =  1 - alpha;
587         s->b0 =  1;
588         s->b1 = -2 * cos(w0);
589         s->b2 =  1;
590         break;
591     case lowpass:
592         if (s->poles == 1) {
593             s->a0 = 1;
594             s->a1 = -exp(-w0);
595             s->a2 = 0;
596             s->b0 = 1 + s->a1;
597             s->b1 = 0;
598             s->b2 = 0;
599         } else {
600             s->a0 =  1 + alpha;
601             s->a1 = -2 * cos(w0);
602             s->a2 =  1 - alpha;
603             s->b0 = (1 - cos(w0)) / 2;
604             s->b1 =  1 - cos(w0);
605             s->b2 = (1 - cos(w0)) / 2;
606         }
607         break;
608     case highpass:
609         if (s->poles == 1) {
610             s->a0 = 1;
611             s->a1 = -exp(-w0);
612             s->a2 = 0;
613             s->b0 = (1 - s->a1) / 2;
614             s->b1 = -s->b0;
615             s->b2 = 0;
616         } else {
617             s->a0 =   1 + alpha;
618             s->a1 =  -2 * cos(w0);
619             s->a2 =   1 - alpha;
620             s->b0 =  (1 + cos(w0)) / 2;
621             s->b1 = -(1 + cos(w0));
622             s->b2 =  (1 + cos(w0)) / 2;
623         }
624         break;
625     case allpass:
626         switch (s->order) {
627         case 1:
628             s->a0 = 1.;
629             s->a1 = -(1. - K) / (1. + K);
630             s->a2 = 0.;
631             s->b0 = s->a1;
632             s->b1 = s->a0;
633             s->b2 = 0.;
634             break;
635         case 2:
636             s->a0 =  1 + alpha;
637             s->a1 = -2 * cos(w0);
638             s->a2 =  1 - alpha;
639             s->b0 =  1 - alpha;
640             s->b1 = -2 * cos(w0);
641             s->b2 =  1 + alpha;
642         break;
643         }
644         break;
645     default:
646         av_assert0(0);
647     }
648
649     av_log(ctx, AV_LOG_VERBOSE, "a=%f %f %f:b=%f %f %f\n", s->a0, s->a1, s->a2, s->b0, s->b1, s->b2);
650
651     s->a1 /= s->a0;
652     s->a2 /= s->a0;
653     s->b0 /= s->a0;
654     s->b1 /= s->a0;
655     s->b2 /= s->a0;
656     s->a0 /= s->a0;
657
658     if (s->normalize && fabs(s->b0 + s->b1 + s->b2) > 1e-6) {
659         double factor = (s->a0 + s->a1 + s->a2) / (s->b0 + s->b1 + s->b2);
660
661         s->b0 *= factor;
662         s->b1 *= factor;
663         s->b2 *= factor;
664     }
665
666     s->cache = av_realloc_f(s->cache, sizeof(ChanCache), inlink->channels);
667     if (!s->cache)
668         return AVERROR(ENOMEM);
669     if (reset)
670         memset(s->cache, 0, sizeof(ChanCache) * inlink->channels);
671
672     switch (s->transform_type) {
673     case DI:
674         switch (inlink->format) {
675         case AV_SAMPLE_FMT_S16P:
676             s->filter = biquad_s16;
677             break;
678         case AV_SAMPLE_FMT_S32P:
679             s->filter = biquad_s32;
680             break;
681         case AV_SAMPLE_FMT_FLTP:
682             s->filter = biquad_flt;
683             break;
684         case AV_SAMPLE_FMT_DBLP:
685             s->filter = biquad_dbl;
686             break;
687         default: av_assert0(0);
688         }
689         break;
690     case DII:
691         switch (inlink->format) {
692         case AV_SAMPLE_FMT_S16P:
693             s->filter = biquad_dii_s16;
694             break;
695         case AV_SAMPLE_FMT_S32P:
696             s->filter = biquad_dii_s32;
697             break;
698         case AV_SAMPLE_FMT_FLTP:
699             s->filter = biquad_dii_flt;
700             break;
701         case AV_SAMPLE_FMT_DBLP:
702             s->filter = biquad_dii_dbl;
703             break;
704         default: av_assert0(0);
705         }
706         break;
707     case TDII:
708         switch (inlink->format) {
709         case AV_SAMPLE_FMT_S16P:
710             s->filter = biquad_tdii_s16;
711             break;
712         case AV_SAMPLE_FMT_S32P:
713             s->filter = biquad_tdii_s32;
714             break;
715         case AV_SAMPLE_FMT_FLTP:
716             s->filter = biquad_tdii_flt;
717             break;
718         case AV_SAMPLE_FMT_DBLP:
719             s->filter = biquad_tdii_dbl;
720             break;
721         default: av_assert0(0);
722         }
723         break;
724     case LATT:
725         switch (inlink->format) {
726         case AV_SAMPLE_FMT_S16P:
727             s->filter = biquad_latt_s16;
728             break;
729         case AV_SAMPLE_FMT_S32P:
730             s->filter = biquad_latt_s32;
731             break;
732         case AV_SAMPLE_FMT_FLTP:
733             s->filter = biquad_latt_flt;
734             break;
735         case AV_SAMPLE_FMT_DBLP:
736             s->filter = biquad_latt_dbl;
737             break;
738         default: av_assert0(0);
739         }
740         break;
741     default:
742         av_assert0(0);
743      }
744
745      s->block_align = av_get_bytes_per_sample(inlink->format);
746
747      if (s->transform_type == LATT)
748          convert_dir2latt(s);
749
750     return 0;
751 }
752
753 static int config_output(AVFilterLink *outlink)
754 {
755     return config_filter(outlink, 1);
756 }
757
758 typedef struct ThreadData {
759     AVFrame *in, *out;
760 } ThreadData;
761
762 static int filter_channel(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
763 {
764     AVFilterLink *inlink = ctx->inputs[0];
765     ThreadData *td = arg;
766     AVFrame *buf = td->in;
767     AVFrame *out_buf = td->out;
768     BiquadsContext *s = ctx->priv;
769     const int start = (buf->channels * jobnr) / nb_jobs;
770     const int end = (buf->channels * (jobnr+1)) / nb_jobs;
771     int ch;
772
773     for (ch = start; ch < end; ch++) {
774         if (!((av_channel_layout_extract_channel(inlink->channel_layout, ch) & s->channels))) {
775             if (buf != out_buf)
776                 memcpy(out_buf->extended_data[ch], buf->extended_data[ch],
777                        buf->nb_samples * s->block_align);
778             continue;
779         }
780
781         s->filter(s, buf->extended_data[ch], out_buf->extended_data[ch], buf->nb_samples,
782                   &s->cache[ch].i1, &s->cache[ch].i2, &s->cache[ch].o1, &s->cache[ch].o2,
783                   s->b0, s->b1, s->b2, s->a1, s->a2, &s->cache[ch].clippings, ctx->is_disabled);
784     }
785
786     return 0;
787 }
788
789 static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
790 {
791     AVFilterContext  *ctx = inlink->dst;
792     BiquadsContext *s     = ctx->priv;
793     AVFilterLink *outlink = ctx->outputs[0];
794     AVFrame *out_buf;
795     ThreadData td;
796     int ch;
797
798     if (s->bypass)
799         return ff_filter_frame(outlink, buf);
800
801     if (av_frame_is_writable(buf)) {
802         out_buf = buf;
803     } else {
804         out_buf = ff_get_audio_buffer(outlink, buf->nb_samples);
805         if (!out_buf) {
806             av_frame_free(&buf);
807             return AVERROR(ENOMEM);
808         }
809         av_frame_copy_props(out_buf, buf);
810     }
811
812     td.in = buf;
813     td.out = out_buf;
814     ctx->internal->execute(ctx, filter_channel, &td, NULL, FFMIN(outlink->channels, ff_filter_get_nb_threads(ctx)));
815
816     for (ch = 0; ch < outlink->channels; ch++) {
817         if (s->cache[ch].clippings > 0)
818             av_log(ctx, AV_LOG_WARNING, "Channel %d clipping %d times. Please reduce gain.\n",
819                    ch, s->cache[ch].clippings);
820         s->cache[ch].clippings = 0;
821     }
822
823     if (buf != out_buf)
824         av_frame_free(&buf);
825
826     return ff_filter_frame(outlink, out_buf);
827 }
828
829 static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
830                            char *res, int res_len, int flags)
831 {
832     AVFilterLink *outlink = ctx->outputs[0];
833     int ret;
834
835     ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags);
836     if (ret < 0)
837         return ret;
838
839     return config_filter(outlink, 0);
840 }
841
842 static av_cold void uninit(AVFilterContext *ctx)
843 {
844     BiquadsContext *s = ctx->priv;
845
846     av_freep(&s->cache);
847 }
848
849 static const AVFilterPad inputs[] = {
850     {
851         .name         = "default",
852         .type         = AVMEDIA_TYPE_AUDIO,
853         .filter_frame = filter_frame,
854     },
855     { NULL }
856 };
857
858 static const AVFilterPad outputs[] = {
859     {
860         .name         = "default",
861         .type         = AVMEDIA_TYPE_AUDIO,
862         .config_props = config_output,
863     },
864     { NULL }
865 };
866
867 #define OFFSET(x) offsetof(BiquadsContext, x)
868 #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
869 #define AF AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
870
871 #define DEFINE_BIQUAD_FILTER(name_, description_)                       \
872 AVFILTER_DEFINE_CLASS(name_);                                           \
873 static av_cold int name_##_init(AVFilterContext *ctx)                   \
874 {                                                                       \
875     BiquadsContext *s = ctx->priv;                                      \
876     s->class = &name_##_class;                                          \
877     s->filter_type = name_;                                             \
878     return 0;                                                           \
879 }                                                                       \
880                                                          \
881 AVFilter ff_af_##name_ = {                               \
882     .name          = #name_,                             \
883     .description   = NULL_IF_CONFIG_SMALL(description_), \
884     .priv_size     = sizeof(BiquadsContext),             \
885     .init          = name_##_init,                       \
886     .uninit        = uninit,                             \
887     .query_formats = query_formats,                      \
888     .inputs        = inputs,                             \
889     .outputs       = outputs,                            \
890     .priv_class    = &name_##_class,                     \
891     .process_command = process_command,                  \
892     .flags         = AVFILTER_FLAG_SLICE_THREADS | AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL, \
893 }
894
895 #if CONFIG_EQUALIZER_FILTER
896 static const AVOption equalizer_options[] = {
897     {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 999999, FLAGS},
898     {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 999999, FLAGS},
899     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
900     {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
901     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
902     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
903     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
904     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
905     {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
906     {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 99999, FLAGS},
907     {"w",     "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 99999, FLAGS},
908     {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
909     {"g",    "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
910     {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
911     {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
912     {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
913     {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
914     {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
915     {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
916     {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
917     {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
918     {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
919     {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
920     {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
921     {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
922     {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
923     {"r",         "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
924     {"auto", "automatic",            0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"},
925     {"s16", "signed 16-bit",         0, AV_OPT_TYPE_CONST, {.i64=0},  0, 0, AF, "precision"},
926     {"s32", "signed 32-bit",         0, AV_OPT_TYPE_CONST, {.i64=1},  0, 0, AF, "precision"},
927     {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2},  0, 0, AF, "precision"},
928     {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3},  0, 0, AF, "precision"},
929     {NULL}
930 };
931
932 DEFINE_BIQUAD_FILTER(equalizer, "Apply two-pole peaking equalization (EQ) filter.");
933 #endif  /* CONFIG_EQUALIZER_FILTER */
934 #if CONFIG_BASS_FILTER
935 static const AVOption bass_options[] = {
936     {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
937     {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
938     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
939     {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
940     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
941     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
942     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
943     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
944     {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
945     {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
946     {"w",     "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
947     {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
948     {"g",    "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
949     {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
950     {"p",     "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
951     {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
952     {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
953     {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
954     {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
955     {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
956     {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
957     {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
958     {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
959     {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
960     {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
961     {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
962     {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
963     {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
964     {"r",         "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
965     {"auto", "automatic",            0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"},
966     {"s16", "signed 16-bit",         0, AV_OPT_TYPE_CONST, {.i64=0},  0, 0, AF, "precision"},
967     {"s32", "signed 32-bit",         0, AV_OPT_TYPE_CONST, {.i64=1},  0, 0, AF, "precision"},
968     {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2},  0, 0, AF, "precision"},
969     {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3},  0, 0, AF, "precision"},
970     {NULL}
971 };
972
973 DEFINE_BIQUAD_FILTER(bass, "Boost or cut lower frequencies.");
974 #endif  /* CONFIG_BASS_FILTER */
975 #if CONFIG_TREBLE_FILTER
976 static const AVOption treble_options[] = {
977     {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
978     {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
979     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
980     {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
981     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
982     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
983     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
984     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
985     {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
986     {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
987     {"w",     "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
988     {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
989     {"g",    "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
990     {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
991     {"p",     "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
992     {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
993     {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
994     {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
995     {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
996     {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
997     {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
998     {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
999     {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1000     {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
1001     {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
1002     {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
1003     {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
1004     {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1005     {"r",         "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1006     {"auto", "automatic",            0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"},
1007     {"s16", "signed 16-bit",         0, AV_OPT_TYPE_CONST, {.i64=0},  0, 0, AF, "precision"},
1008     {"s32", "signed 32-bit",         0, AV_OPT_TYPE_CONST, {.i64=1},  0, 0, AF, "precision"},
1009     {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2},  0, 0, AF, "precision"},
1010     {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3},  0, 0, AF, "precision"},
1011     {NULL}
1012 };
1013
1014 DEFINE_BIQUAD_FILTER(treble, "Boost or cut upper frequencies.");
1015 #endif  /* CONFIG_TREBLE_FILTER */
1016 #if CONFIG_BANDPASS_FILTER
1017 static const AVOption bandpass_options[] = {
1018     {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1019     {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1020     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1021     {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1022     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
1023     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
1024     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
1025     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
1026     {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
1027     {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
1028     {"w",     "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
1029     {"csg",   "use constant skirt gain", OFFSET(csg), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1030     {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1031     {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1032     {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1033     {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1034     {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1035     {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1036     {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1037     {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1038     {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
1039     {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
1040     {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
1041     {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
1042     {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1043     {"r",         "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1044     {"auto", "automatic",            0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"},
1045     {"s16", "signed 16-bit",         0, AV_OPT_TYPE_CONST, {.i64=0},  0, 0, AF, "precision"},
1046     {"s32", "signed 32-bit",         0, AV_OPT_TYPE_CONST, {.i64=1},  0, 0, AF, "precision"},
1047     {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2},  0, 0, AF, "precision"},
1048     {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3},  0, 0, AF, "precision"},
1049     {NULL}
1050 };
1051
1052 DEFINE_BIQUAD_FILTER(bandpass, "Apply a two-pole Butterworth band-pass filter.");
1053 #endif  /* CONFIG_BANDPASS_FILTER */
1054 #if CONFIG_BANDREJECT_FILTER
1055 static const AVOption bandreject_options[] = {
1056     {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1057     {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1058     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1059     {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1060     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
1061     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
1062     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
1063     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
1064     {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
1065     {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
1066     {"w",     "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
1067     {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1068     {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1069     {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1070     {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1071     {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1072     {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1073     {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1074     {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1075     {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
1076     {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
1077     {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
1078     {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
1079     {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1080     {"r",         "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1081     {"auto", "automatic",            0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"},
1082     {"s16", "signed 16-bit",         0, AV_OPT_TYPE_CONST, {.i64=0},  0, 0, AF, "precision"},
1083     {"s32", "signed 32-bit",         0, AV_OPT_TYPE_CONST, {.i64=1},  0, 0, AF, "precision"},
1084     {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2},  0, 0, AF, "precision"},
1085     {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3},  0, 0, AF, "precision"},
1086     {NULL}
1087 };
1088
1089 DEFINE_BIQUAD_FILTER(bandreject, "Apply a two-pole Butterworth band-reject filter.");
1090 #endif  /* CONFIG_BANDREJECT_FILTER */
1091 #if CONFIG_LOWPASS_FILTER
1092 static const AVOption lowpass_options[] = {
1093     {"frequency", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=500}, 0, 999999, FLAGS},
1094     {"f",         "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=500}, 0, 999999, FLAGS},
1095     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1096     {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1097     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
1098     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
1099     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
1100     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
1101     {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
1102     {"width", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
1103     {"w",     "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
1104     {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
1105     {"p",     "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
1106     {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1107     {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1108     {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1109     {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1110     {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1111     {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1112     {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1113     {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1114     {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
1115     {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
1116     {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
1117     {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
1118     {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1119     {"r",         "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1120     {"auto", "automatic",            0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"},
1121     {"s16", "signed 16-bit",         0, AV_OPT_TYPE_CONST, {.i64=0},  0, 0, AF, "precision"},
1122     {"s32", "signed 32-bit",         0, AV_OPT_TYPE_CONST, {.i64=1},  0, 0, AF, "precision"},
1123     {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2},  0, 0, AF, "precision"},
1124     {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3},  0, 0, AF, "precision"},
1125     {NULL}
1126 };
1127
1128 DEFINE_BIQUAD_FILTER(lowpass, "Apply a low-pass filter with 3dB point frequency.");
1129 #endif  /* CONFIG_LOWPASS_FILTER */
1130 #if CONFIG_HIGHPASS_FILTER
1131 static const AVOption highpass_options[] = {
1132     {"frequency", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1133     {"f",         "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1134     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1135     {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1136     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
1137     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
1138     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
1139     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
1140     {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
1141     {"width", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
1142     {"w",     "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
1143     {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
1144     {"p",     "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
1145     {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1146     {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1147     {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1148     {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1149     {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1150     {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1151     {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1152     {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1153     {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
1154     {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
1155     {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
1156     {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
1157     {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1158     {"r",         "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1159     {"auto", "automatic",            0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"},
1160     {"s16", "signed 16-bit",         0, AV_OPT_TYPE_CONST, {.i64=0},  0, 0, AF, "precision"},
1161     {"s32", "signed 32-bit",         0, AV_OPT_TYPE_CONST, {.i64=1},  0, 0, AF, "precision"},
1162     {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2},  0, 0, AF, "precision"},
1163     {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3},  0, 0, AF, "precision"},
1164     {NULL}
1165 };
1166
1167 DEFINE_BIQUAD_FILTER(highpass, "Apply a high-pass filter with 3dB point frequency.");
1168 #endif  /* CONFIG_HIGHPASS_FILTER */
1169 #if CONFIG_ALLPASS_FILTER
1170 static const AVOption allpass_options[] = {
1171     {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1172     {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1173     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=HERTZ}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1174     {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=HERTZ}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1175     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
1176     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
1177     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
1178     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
1179     {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
1180     {"width", "set filter-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=707.1}, 0, 99999, FLAGS},
1181     {"w",     "set filter-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=707.1}, 0, 99999, FLAGS},
1182     {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1183     {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1184     {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1185     {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1186     {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1187     {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1188     {"order", "set filter order", OFFSET(order), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
1189     {"o",     "set filter order", OFFSET(order), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
1190     {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1191     {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1192     {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
1193     {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
1194     {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
1195     {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
1196     {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1197     {"r",         "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1198     {"auto", "automatic",            0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"},
1199     {"s16", "signed 16-bit",         0, AV_OPT_TYPE_CONST, {.i64=0},  0, 0, AF, "precision"},
1200     {"s32", "signed 32-bit",         0, AV_OPT_TYPE_CONST, {.i64=1},  0, 0, AF, "precision"},
1201     {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2},  0, 0, AF, "precision"},
1202     {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3},  0, 0, AF, "precision"},
1203     {NULL}
1204 };
1205
1206 DEFINE_BIQUAD_FILTER(allpass, "Apply a two-pole all-pass filter.");
1207 #endif  /* CONFIG_ALLPASS_FILTER */
1208 #if CONFIG_LOWSHELF_FILTER
1209 static const AVOption lowshelf_options[] = {
1210     {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
1211     {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
1212     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1213     {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1214     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
1215     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
1216     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
1217     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
1218     {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
1219     {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
1220     {"w",     "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
1221     {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
1222     {"g",    "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
1223     {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
1224     {"p",     "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
1225     {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1226     {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1227     {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1228     {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1229     {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1230     {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1231     {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1232     {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1233     {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
1234     {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
1235     {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
1236     {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
1237     {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1238     {"r",         "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1239     {"auto", "automatic",            0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"},
1240     {"s16", "signed 16-bit",         0, AV_OPT_TYPE_CONST, {.i64=0},  0, 0, AF, "precision"},
1241     {"s32", "signed 32-bit",         0, AV_OPT_TYPE_CONST, {.i64=1},  0, 0, AF, "precision"},
1242     {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2},  0, 0, AF, "precision"},
1243     {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3},  0, 0, AF, "precision"},
1244     {NULL}
1245 };
1246
1247 DEFINE_BIQUAD_FILTER(lowshelf, "Apply a low shelf filter.");
1248 #endif  /* CONFIG_LOWSHELF_FILTER */
1249 #if CONFIG_HIGHSHELF_FILTER
1250 static const AVOption highshelf_options[] = {
1251     {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1252     {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1253     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1254     {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1255     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
1256     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
1257     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
1258     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
1259     {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
1260     {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
1261     {"w",     "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
1262     {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
1263     {"g",    "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
1264     {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
1265     {"p",     "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
1266     {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1267     {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1268     {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1269     {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1270     {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1271     {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1272     {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1273     {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1274     {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
1275     {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
1276     {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
1277     {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
1278     {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1279     {"r",         "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1280     {"auto", "automatic",            0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"},
1281     {"s16", "signed 16-bit",         0, AV_OPT_TYPE_CONST, {.i64=0},  0, 0, AF, "precision"},
1282     {"s32", "signed 32-bit",         0, AV_OPT_TYPE_CONST, {.i64=1},  0, 0, AF, "precision"},
1283     {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2},  0, 0, AF, "precision"},
1284     {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3},  0, 0, AF, "precision"},
1285     {NULL}
1286 };
1287
1288 DEFINE_BIQUAD_FILTER(highshelf, "Apply a high shelf filter.");
1289 #endif  /* CONFIG_HIGHSHELF_FILTER */
1290 #if CONFIG_BIQUAD_FILTER
1291 static const AVOption biquad_options[] = {
1292     {"a0", NULL, OFFSET(oa0), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT32_MIN, INT32_MAX, FLAGS},
1293     {"a1", NULL, OFFSET(oa1), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
1294     {"a2", NULL, OFFSET(oa2), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
1295     {"b0", NULL, OFFSET(ob0), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
1296     {"b1", NULL, OFFSET(ob1), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
1297     {"b2", NULL, OFFSET(ob2), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
1298     {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1299     {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1300     {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1301     {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1302     {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1303     {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1304     {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1305     {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1306     {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
1307     {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
1308     {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
1309     {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
1310     {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1311     {"r",         "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1312     {"auto", "automatic",            0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"},
1313     {"s16", "signed 16-bit",         0, AV_OPT_TYPE_CONST, {.i64=0},  0, 0, AF, "precision"},
1314     {"s32", "signed 32-bit",         0, AV_OPT_TYPE_CONST, {.i64=1},  0, 0, AF, "precision"},
1315     {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2},  0, 0, AF, "precision"},
1316     {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3},  0, 0, AF, "precision"},
1317     {NULL}
1318 };
1319
1320 DEFINE_BIQUAD_FILTER(biquad, "Apply a biquad IIR filter with the given coefficients.");
1321 #endif  /* CONFIG_BIQUAD_FILTER */