• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
query_formats(AVFilterContext * ctx)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 
convert_dir2latt(BiquadsContext * s)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 
config_filter(AVFilterLink * outlink,int reset)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 
config_output(AVFilterLink * outlink)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 
filter_channel(AVFilterContext * ctx,void * arg,int jobnr,int nb_jobs)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 
filter_frame(AVFilterLink * inlink,AVFrame * buf)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 
process_command(AVFilterContext * ctx,const char * cmd,const char * args,char * res,int res_len,int flags)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 
uninit(AVFilterContext * ctx)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->filter_type = name_;                                             \
877     return 0;                                                           \
878 }                                                                       \
879                                                          \
880 AVFilter ff_af_##name_ = {                               \
881     .name          = #name_,                             \
882     .description   = NULL_IF_CONFIG_SMALL(description_), \
883     .priv_size     = sizeof(BiquadsContext),             \
884     .init          = name_##_init,                       \
885     .uninit        = uninit,                             \
886     .query_formats = query_formats,                      \
887     .inputs        = inputs,                             \
888     .outputs       = outputs,                            \
889     .priv_class    = &name_##_class,                     \
890     .process_command = process_command,                  \
891     .flags         = AVFILTER_FLAG_SLICE_THREADS | AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL, \
892 }
893 
894 #if CONFIG_EQUALIZER_FILTER
895 static const AVOption equalizer_options[] = {
896     {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 999999, FLAGS},
897     {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 999999, FLAGS},
898     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
899     {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
900     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
901     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
902     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
903     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
904     {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
905     {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 99999, FLAGS},
906     {"w",     "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 99999, FLAGS},
907     {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
908     {"g",    "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
909     {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
910     {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
911     {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
912     {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
913     {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
914     {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
915     {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
916     {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
917     {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
918     {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
919     {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
920     {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
921     {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
922     {"r",         "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
923     {"auto", "automatic",            0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"},
924     {"s16", "signed 16-bit",         0, AV_OPT_TYPE_CONST, {.i64=0},  0, 0, AF, "precision"},
925     {"s32", "signed 32-bit",         0, AV_OPT_TYPE_CONST, {.i64=1},  0, 0, AF, "precision"},
926     {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2},  0, 0, AF, "precision"},
927     {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3},  0, 0, AF, "precision"},
928     {NULL}
929 };
930 
931 DEFINE_BIQUAD_FILTER(equalizer, "Apply two-pole peaking equalization (EQ) filter.");
932 #endif  /* CONFIG_EQUALIZER_FILTER */
933 #if CONFIG_BASS_FILTER || CONFIG_LOWSHELF_FILTER
934 static const AVOption bass_lowshelf_options[] = {
935     {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
936     {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
937     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
938     {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
939     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
940     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
941     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
942     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
943     {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
944     {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
945     {"w",     "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
946     {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
947     {"g",    "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
948     {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
949     {"p",     "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
950     {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
951     {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
952     {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
953     {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
954     {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
955     {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
956     {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
957     {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
958     {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
959     {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
960     {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
961     {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
962     {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
963     {"r",         "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
964     {"auto", "automatic",            0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"},
965     {"s16", "signed 16-bit",         0, AV_OPT_TYPE_CONST, {.i64=0},  0, 0, AF, "precision"},
966     {"s32", "signed 32-bit",         0, AV_OPT_TYPE_CONST, {.i64=1},  0, 0, AF, "precision"},
967     {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2},  0, 0, AF, "precision"},
968     {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3},  0, 0, AF, "precision"},
969     {NULL}
970 };
971 
972 #if CONFIG_BASS_FILTER
973 #define bass_options bass_lowshelf_options
974 DEFINE_BIQUAD_FILTER(bass, "Boost or cut lower frequencies.");
975 #endif  /* CONFIG_BASS_FILTER */
976 
977 #if CONFIG_LOWSHELF_FILTER
978 #define lowshelf_options bass_lowshelf_options
979 DEFINE_BIQUAD_FILTER(lowshelf, "Apply a low shelf filter.");
980 #endif  /* CONFIG_LOWSHELF_FILTER */
981 #endif  /* CONFIG_BASS_FILTER || CONFIG LOWSHELF_FILTER */
982 #if CONFIG_TREBLE_FILTER || CONFIG_HIGHSHELF_FILTER
983 static const AVOption treble_highshelf_options[] = {
984     {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
985     {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
986     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
987     {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
988     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
989     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
990     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
991     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
992     {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
993     {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
994     {"w",     "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
995     {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
996     {"g",    "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
997     {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
998     {"p",     "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
999     {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1000     {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1001     {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1002     {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1003     {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1004     {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1005     {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1006     {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1007     {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
1008     {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
1009     {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
1010     {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
1011     {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1012     {"r",         "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1013     {"auto", "automatic",            0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"},
1014     {"s16", "signed 16-bit",         0, AV_OPT_TYPE_CONST, {.i64=0},  0, 0, AF, "precision"},
1015     {"s32", "signed 32-bit",         0, AV_OPT_TYPE_CONST, {.i64=1},  0, 0, AF, "precision"},
1016     {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2},  0, 0, AF, "precision"},
1017     {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3},  0, 0, AF, "precision"},
1018     {NULL}
1019 };
1020 
1021 #if CONFIG_TREBLE_FILTER
1022 #define treble_options treble_highshelf_options
1023 DEFINE_BIQUAD_FILTER(treble, "Boost or cut upper frequencies.");
1024 #endif  /* CONFIG_TREBLE_FILTER */
1025 
1026 #if CONFIG_HIGHSHELF_FILTER
1027 #define highshelf_options treble_highshelf_options
1028 DEFINE_BIQUAD_FILTER(highshelf, "Apply a high shelf filter.");
1029 #endif  /* CONFIG_HIGHSHELF_FILTER */
1030 #endif  /* CONFIG_TREBLE_FILTER || CONFIG_HIGHSHELF_FILTER */
1031 #if CONFIG_BANDPASS_FILTER
1032 static const AVOption bandpass_options[] = {
1033     {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1034     {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1035     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1036     {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1037     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
1038     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
1039     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
1040     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
1041     {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
1042     {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
1043     {"w",     "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
1044     {"csg",   "use constant skirt gain", OFFSET(csg), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1045     {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1046     {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1047     {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1048     {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1049     {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1050     {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1051     {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1052     {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1053     {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
1054     {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
1055     {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
1056     {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
1057     {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1058     {"r",         "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1059     {"auto", "automatic",            0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"},
1060     {"s16", "signed 16-bit",         0, AV_OPT_TYPE_CONST, {.i64=0},  0, 0, AF, "precision"},
1061     {"s32", "signed 32-bit",         0, AV_OPT_TYPE_CONST, {.i64=1},  0, 0, AF, "precision"},
1062     {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2},  0, 0, AF, "precision"},
1063     {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3},  0, 0, AF, "precision"},
1064     {NULL}
1065 };
1066 
1067 DEFINE_BIQUAD_FILTER(bandpass, "Apply a two-pole Butterworth band-pass filter.");
1068 #endif  /* CONFIG_BANDPASS_FILTER */
1069 #if CONFIG_BANDREJECT_FILTER
1070 static const AVOption bandreject_options[] = {
1071     {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1072     {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1073     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1074     {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1075     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
1076     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
1077     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
1078     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
1079     {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
1080     {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
1081     {"w",     "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
1082     {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1083     {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1084     {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1085     {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1086     {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1087     {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1088     {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1089     {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1090     {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
1091     {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
1092     {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
1093     {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
1094     {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1095     {"r",         "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1096     {"auto", "automatic",            0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"},
1097     {"s16", "signed 16-bit",         0, AV_OPT_TYPE_CONST, {.i64=0},  0, 0, AF, "precision"},
1098     {"s32", "signed 32-bit",         0, AV_OPT_TYPE_CONST, {.i64=1},  0, 0, AF, "precision"},
1099     {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2},  0, 0, AF, "precision"},
1100     {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3},  0, 0, AF, "precision"},
1101     {NULL}
1102 };
1103 
1104 DEFINE_BIQUAD_FILTER(bandreject, "Apply a two-pole Butterworth band-reject filter.");
1105 #endif  /* CONFIG_BANDREJECT_FILTER */
1106 #if CONFIG_LOWPASS_FILTER
1107 static const AVOption lowpass_options[] = {
1108     {"frequency", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=500}, 0, 999999, FLAGS},
1109     {"f",         "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=500}, 0, 999999, FLAGS},
1110     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1111     {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1112     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
1113     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
1114     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
1115     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
1116     {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
1117     {"width", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
1118     {"w",     "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
1119     {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
1120     {"p",     "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
1121     {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1122     {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1123     {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1124     {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1125     {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1126     {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1127     {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1128     {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1129     {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
1130     {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
1131     {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
1132     {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
1133     {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1134     {"r",         "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1135     {"auto", "automatic",            0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"},
1136     {"s16", "signed 16-bit",         0, AV_OPT_TYPE_CONST, {.i64=0},  0, 0, AF, "precision"},
1137     {"s32", "signed 32-bit",         0, AV_OPT_TYPE_CONST, {.i64=1},  0, 0, AF, "precision"},
1138     {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2},  0, 0, AF, "precision"},
1139     {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3},  0, 0, AF, "precision"},
1140     {NULL}
1141 };
1142 
1143 DEFINE_BIQUAD_FILTER(lowpass, "Apply a low-pass filter with 3dB point frequency.");
1144 #endif  /* CONFIG_LOWPASS_FILTER */
1145 #if CONFIG_HIGHPASS_FILTER
1146 static const AVOption highpass_options[] = {
1147     {"frequency", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1148     {"f",         "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1149     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1150     {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1151     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
1152     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
1153     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
1154     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
1155     {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
1156     {"width", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
1157     {"w",     "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
1158     {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
1159     {"p",     "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
1160     {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1161     {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1162     {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1163     {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1164     {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1165     {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1166     {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1167     {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1168     {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
1169     {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
1170     {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
1171     {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
1172     {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1173     {"r",         "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1174     {"auto", "automatic",            0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"},
1175     {"s16", "signed 16-bit",         0, AV_OPT_TYPE_CONST, {.i64=0},  0, 0, AF, "precision"},
1176     {"s32", "signed 32-bit",         0, AV_OPT_TYPE_CONST, {.i64=1},  0, 0, AF, "precision"},
1177     {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2},  0, 0, AF, "precision"},
1178     {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3},  0, 0, AF, "precision"},
1179     {NULL}
1180 };
1181 
1182 DEFINE_BIQUAD_FILTER(highpass, "Apply a high-pass filter with 3dB point frequency.");
1183 #endif  /* CONFIG_HIGHPASS_FILTER */
1184 #if CONFIG_ALLPASS_FILTER
1185 static const AVOption allpass_options[] = {
1186     {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1187     {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1188     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=HERTZ}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1189     {"t",          "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=HERTZ}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1190     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
1191     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
1192     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
1193     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
1194     {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
1195     {"width", "set filter-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=707.1}, 0, 99999, FLAGS},
1196     {"w",     "set filter-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=707.1}, 0, 99999, FLAGS},
1197     {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1198     {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1199     {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1200     {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1201     {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1202     {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1203     {"order", "set filter order", OFFSET(order), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
1204     {"o",     "set filter order", OFFSET(order), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
1205     {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1206     {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1207     {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
1208     {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
1209     {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
1210     {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
1211     {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1212     {"r",         "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1213     {"auto", "automatic",            0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"},
1214     {"s16", "signed 16-bit",         0, AV_OPT_TYPE_CONST, {.i64=0},  0, 0, AF, "precision"},
1215     {"s32", "signed 32-bit",         0, AV_OPT_TYPE_CONST, {.i64=1},  0, 0, AF, "precision"},
1216     {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2},  0, 0, AF, "precision"},
1217     {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3},  0, 0, AF, "precision"},
1218     {NULL}
1219 };
1220 
1221 DEFINE_BIQUAD_FILTER(allpass, "Apply a two-pole all-pass filter.");
1222 #endif  /* CONFIG_ALLPASS_FILTER */
1223 #if CONFIG_BIQUAD_FILTER
1224 static const AVOption biquad_options[] = {
1225     {"a0", NULL, OFFSET(oa0), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT32_MIN, INT32_MAX, FLAGS},
1226     {"a1", NULL, OFFSET(oa1), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
1227     {"a2", NULL, OFFSET(oa2), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
1228     {"b0", NULL, OFFSET(ob0), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
1229     {"b1", NULL, OFFSET(ob1), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
1230     {"b2", NULL, OFFSET(ob2), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
1231     {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1232     {"m",   "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1233     {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1234     {"c",        "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1235     {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1236     {"n",         "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1237     {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1238     {"a",         "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1239     {"di",   "direct form I",  0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
1240     {"dii",  "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
1241     {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
1242     {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
1243     {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1244     {"r",         "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1245     {"auto", "automatic",            0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"},
1246     {"s16", "signed 16-bit",         0, AV_OPT_TYPE_CONST, {.i64=0},  0, 0, AF, "precision"},
1247     {"s32", "signed 32-bit",         0, AV_OPT_TYPE_CONST, {.i64=1},  0, 0, AF, "precision"},
1248     {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2},  0, 0, AF, "precision"},
1249     {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3},  0, 0, AF, "precision"},
1250     {NULL}
1251 };
1252 
1253 DEFINE_BIQUAD_FILTER(biquad, "Apply a biquad IIR filter with the given coefficients.");
1254 #endif  /* CONFIG_BIQUAD_FILTER */
1255