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