FFmpeg
af_biquads.c
Go to the documentation of this file.
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 {
84 };
85 
86 enum WidthType {
94 };
95 
97  DI,
98  DII,
102 };
103 
104 typedef struct ChanCache {
105  double i1, i2;
106  double o1, o2;
108 } ChanCache;
109 
110 typedef struct BiquadsContext {
111  const AVClass *class;
112 
115  int poles;
116  int csg;
119 
120  int bypass;
121 
122  double gain;
123  double frequency;
124  double width;
125  double mix;
126  uint64_t channels;
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 
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);
144 
146 {
147  BiquadsContext *s = ctx->priv;
150  static const enum AVSampleFormat auto_sample_fmts[] = {
156  };
157  enum AVSampleFormat sample_fmts[] = {
160  };
161  int ret;
162 
164  if (!layouts)
165  return AVERROR(ENOMEM);
167  if (ret < 0)
168  return ret;
169 
170  switch (s->precision) {
171  case 0:
174  break;
175  case 1:
178  break;
179  case 2:
182  break;
183  case 3:
186  break;
187  default:
188  formats = ff_make_format_list(auto_sample_fmts);
189  break;
190  }
191  if (!formats)
192  return AVERROR(ENOMEM);
194  if (ret < 0)
195  return ret;
196 
198  if (!formats)
199  return AVERROR(ENOMEM);
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 
437 {
438  double k0, k1, v0, v1, v2;
439 
440  k1 = s->a2;
441  k0 = s->a1 / (1. + k1);
442  v2 = s->b2;
443  v1 = s->b1 - v2 * s->a1;
444  v0 = s->b0 - v1 * k0 - v2 * k1;
445 
446  s->a1 = k0;
447  s->a2 = k1;
448  s->b0 = v0;
449  s->b1 = v1;
450  s->b2 = v2;
451 }
452 
453 static int config_filter(AVFilterLink *outlink, int reset)
454 {
455  AVFilterContext *ctx = outlink->src;
456  BiquadsContext *s = ctx->priv;
457  AVFilterLink *inlink = ctx->inputs[0];
458  double A = ff_exp10(s->gain / 40);
459  double w0 = 2 * M_PI * s->frequency / inlink->sample_rate;
460  double K = tan(w0 / 2.);
461  double alpha, beta;
462 
463  s->bypass = (((w0 > M_PI || w0 <= 0.) && reset) || (s->width <= 0.)) && (s->filter_type != biquad);
464  if (s->bypass) {
465  av_log(ctx, AV_LOG_WARNING, "Invalid frequency and/or width!\n");
466  return 0;
467  }
468 
469  if ((w0 > M_PI || w0 <= 0.) && (s->filter_type != biquad))
470  return AVERROR(EINVAL);
471 
472  switch (s->width_type) {
473  case NONE:
474  alpha = 0.0;
475  break;
476  case HERTZ:
477  alpha = sin(w0) / (2 * s->frequency / s->width);
478  break;
479  case KHERTZ:
480  alpha = sin(w0) / (2 * s->frequency / (s->width * 1000));
481  break;
482  case OCTAVE:
483  alpha = sin(w0) * sinh(log(2.) / 2 * s->width * w0 / sin(w0));
484  break;
485  case QFACTOR:
486  alpha = sin(w0) / (2 * s->width);
487  break;
488  case SLOPE:
489  alpha = sin(w0) / 2 * sqrt((A + 1 / A) * (1 / s->width - 1) + 2);
490  break;
491  default:
492  av_assert0(0);
493  }
494 
495  beta = 2 * sqrt(A);
496 
497  switch (s->filter_type) {
498  case biquad:
499  s->a0 = s->oa0;
500  s->a1 = s->oa1;
501  s->a2 = s->oa2;
502  s->b0 = s->ob0;
503  s->b1 = s->ob1;
504  s->b2 = s->ob2;
505  break;
506  case equalizer:
507  s->a0 = 1 + alpha / A;
508  s->a1 = -2 * cos(w0);
509  s->a2 = 1 - alpha / A;
510  s->b0 = 1 + alpha * A;
511  s->b1 = -2 * cos(w0);
512  s->b2 = 1 - alpha * A;
513  break;
514  case bass:
515  beta = sqrt((A * A + 1) - (A - 1) * (A - 1));
516  case lowshelf:
517  if (s->poles == 1) {
518  double A = ff_exp10(s->gain / 20);
519  double ro = -sin(w0 / 2. - M_PI_4) / sin(w0 / 2. + M_PI_4);
520  double n = (A + 1) / (A - 1);
521  double alpha1 = A == 1. ? 0. : n - FFSIGN(n) * sqrt(n * n - 1);
522  double beta0 = ((1 + A) + (1 - A) * alpha1) * 0.5;
523  double beta1 = ((1 - A) + (1 + A) * alpha1) * 0.5;
524 
525  s->a0 = 1 + ro * alpha1;
526  s->a1 = -ro - alpha1;
527  s->a2 = 0;
528  s->b0 = beta0 + ro * beta1;
529  s->b1 = -beta1 - ro * beta0;
530  s->b2 = 0;
531  } else {
532  s->a0 = (A + 1) + (A - 1) * cos(w0) + beta * alpha;
533  s->a1 = -2 * ((A - 1) + (A + 1) * cos(w0));
534  s->a2 = (A + 1) + (A - 1) * cos(w0) - beta * alpha;
535  s->b0 = A * ((A + 1) - (A - 1) * cos(w0) + beta * alpha);
536  s->b1 = 2 * A * ((A - 1) - (A + 1) * cos(w0));
537  s->b2 = A * ((A + 1) - (A - 1) * cos(w0) - beta * alpha);
538  }
539  break;
540  case treble:
541  beta = sqrt((A * A + 1) - (A - 1) * (A - 1));
542  case highshelf:
543  if (s->poles == 1) {
544  double A = ff_exp10(s->gain / 20);
545  double ro = sin(w0 / 2. - M_PI_4) / sin(w0 / 2. + M_PI_4);
546  double n = (A + 1) / (A - 1);
547  double alpha1 = A == 1. ? 0. : n - FFSIGN(n) * sqrt(n * n - 1);
548  double beta0 = ((1 + A) + (1 - A) * alpha1) * 0.5;
549  double beta1 = ((1 - A) + (1 + A) * alpha1) * 0.5;
550 
551  s->a0 = 1 + ro * alpha1;
552  s->a1 = ro + alpha1;
553  s->a2 = 0;
554  s->b0 = beta0 + ro * beta1;
555  s->b1 = beta1 + ro * beta0;
556  s->b2 = 0;
557  } else {
558  s->a0 = (A + 1) - (A - 1) * cos(w0) + beta * alpha;
559  s->a1 = 2 * ((A - 1) - (A + 1) * cos(w0));
560  s->a2 = (A + 1) - (A - 1) * cos(w0) - beta * alpha;
561  s->b0 = A * ((A + 1) + (A - 1) * cos(w0) + beta * alpha);
562  s->b1 =-2 * A * ((A - 1) + (A + 1) * cos(w0));
563  s->b2 = A * ((A + 1) + (A - 1) * cos(w0) - beta * alpha);
564  }
565  break;
566  case bandpass:
567  if (s->csg) {
568  s->a0 = 1 + alpha;
569  s->a1 = -2 * cos(w0);
570  s->a2 = 1 - alpha;
571  s->b0 = sin(w0) / 2;
572  s->b1 = 0;
573  s->b2 = -sin(w0) / 2;
574  } else {
575  s->a0 = 1 + alpha;
576  s->a1 = -2 * cos(w0);
577  s->a2 = 1 - alpha;
578  s->b0 = alpha;
579  s->b1 = 0;
580  s->b2 = -alpha;
581  }
582  break;
583  case bandreject:
584  s->a0 = 1 + alpha;
585  s->a1 = -2 * cos(w0);
586  s->a2 = 1 - alpha;
587  s->b0 = 1;
588  s->b1 = -2 * cos(w0);
589  s->b2 = 1;
590  break;
591  case lowpass:
592  if (s->poles == 1) {
593  s->a0 = 1;
594  s->a1 = -exp(-w0);
595  s->a2 = 0;
596  s->b0 = 1 + s->a1;
597  s->b1 = 0;
598  s->b2 = 0;
599  } else {
600  s->a0 = 1 + alpha;
601  s->a1 = -2 * cos(w0);
602  s->a2 = 1 - alpha;
603  s->b0 = (1 - cos(w0)) / 2;
604  s->b1 = 1 - cos(w0);
605  s->b2 = (1 - cos(w0)) / 2;
606  }
607  break;
608  case highpass:
609  if (s->poles == 1) {
610  s->a0 = 1;
611  s->a1 = -exp(-w0);
612  s->a2 = 0;
613  s->b0 = (1 - s->a1) / 2;
614  s->b1 = -s->b0;
615  s->b2 = 0;
616  } else {
617  s->a0 = 1 + alpha;
618  s->a1 = -2 * cos(w0);
619  s->a2 = 1 - alpha;
620  s->b0 = (1 + cos(w0)) / 2;
621  s->b1 = -(1 + cos(w0));
622  s->b2 = (1 + cos(w0)) / 2;
623  }
624  break;
625  case allpass:
626  switch (s->order) {
627  case 1:
628  s->a0 = 1.;
629  s->a1 = -(1. - K) / (1. + K);
630  s->a2 = 0.;
631  s->b0 = s->a1;
632  s->b1 = s->a0;
633  s->b2 = 0.;
634  break;
635  case 2:
636  s->a0 = 1 + alpha;
637  s->a1 = -2 * cos(w0);
638  s->a2 = 1 - alpha;
639  s->b0 = 1 - alpha;
640  s->b1 = -2 * cos(w0);
641  s->b2 = 1 + alpha;
642  break;
643  }
644  break;
645  default:
646  av_assert0(0);
647  }
648 
649  av_log(ctx, AV_LOG_VERBOSE, "a=%f %f %f:b=%f %f %f\n", s->a0, s->a1, s->a2, s->b0, s->b1, s->b2);
650 
651  s->a1 /= s->a0;
652  s->a2 /= s->a0;
653  s->b0 /= s->a0;
654  s->b1 /= s->a0;
655  s->b2 /= s->a0;
656  s->a0 /= s->a0;
657 
658  if (s->normalize && fabs(s->b0 + s->b1 + s->b2) > 1e-6) {
659  double factor = (s->a0 + s->a1 + s->a2) / (s->b0 + s->b1 + s->b2);
660 
661  s->b0 *= factor;
662  s->b1 *= factor;
663  s->b2 *= factor;
664  }
665 
666  s->cache = av_realloc_f(s->cache, sizeof(ChanCache), inlink->channels);
667  if (!s->cache)
668  return AVERROR(ENOMEM);
669  if (reset)
670  memset(s->cache, 0, sizeof(ChanCache) * inlink->channels);
671 
672  switch (s->transform_type) {
673  case DI:
674  switch (inlink->format) {
675  case AV_SAMPLE_FMT_S16P:
676  s->filter = biquad_s16;
677  break;
678  case AV_SAMPLE_FMT_S32P:
679  s->filter = biquad_s32;
680  break;
681  case AV_SAMPLE_FMT_FLTP:
682  s->filter = biquad_flt;
683  break;
684  case AV_SAMPLE_FMT_DBLP:
685  s->filter = biquad_dbl;
686  break;
687  default: av_assert0(0);
688  }
689  break;
690  case DII:
691  switch (inlink->format) {
692  case AV_SAMPLE_FMT_S16P:
693  s->filter = biquad_dii_s16;
694  break;
695  case AV_SAMPLE_FMT_S32P:
696  s->filter = biquad_dii_s32;
697  break;
698  case AV_SAMPLE_FMT_FLTP:
699  s->filter = biquad_dii_flt;
700  break;
701  case AV_SAMPLE_FMT_DBLP:
702  s->filter = biquad_dii_dbl;
703  break;
704  default: av_assert0(0);
705  }
706  break;
707  case TDII:
708  switch (inlink->format) {
709  case AV_SAMPLE_FMT_S16P:
710  s->filter = biquad_tdii_s16;
711  break;
712  case AV_SAMPLE_FMT_S32P:
713  s->filter = biquad_tdii_s32;
714  break;
715  case AV_SAMPLE_FMT_FLTP:
716  s->filter = biquad_tdii_flt;
717  break;
718  case AV_SAMPLE_FMT_DBLP:
719  s->filter = biquad_tdii_dbl;
720  break;
721  default: av_assert0(0);
722  }
723  break;
724  case LATT:
725  switch (inlink->format) {
726  case AV_SAMPLE_FMT_S16P:
727  s->filter = biquad_latt_s16;
728  break;
729  case AV_SAMPLE_FMT_S32P:
730  s->filter = biquad_latt_s32;
731  break;
732  case AV_SAMPLE_FMT_FLTP:
733  s->filter = biquad_latt_flt;
734  break;
735  case AV_SAMPLE_FMT_DBLP:
736  s->filter = biquad_latt_dbl;
737  break;
738  default: av_assert0(0);
739  }
740  break;
741  default:
742  av_assert0(0);
743  }
744 
745  s->block_align = av_get_bytes_per_sample(inlink->format);
746 
747  if (s->transform_type == LATT)
749 
750  return 0;
751 }
752 
753 static int config_output(AVFilterLink *outlink)
754 {
755  return config_filter(outlink, 1);
756 }
757 
758 typedef struct ThreadData {
759  AVFrame *in, *out;
760 } ThreadData;
761 
762 static int filter_channel(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
763 {
764  AVFilterLink *inlink = ctx->inputs[0];
765  ThreadData *td = arg;
766  AVFrame *buf = td->in;
767  AVFrame *out_buf = td->out;
768  BiquadsContext *s = ctx->priv;
769  const int start = (buf->channels * jobnr) / nb_jobs;
770  const int end = (buf->channels * (jobnr+1)) / nb_jobs;
771  int ch;
772 
773  for (ch = start; ch < end; ch++) {
774  if (!((av_channel_layout_extract_channel(inlink->channel_layout, ch) & s->channels))) {
775  if (buf != out_buf)
776  memcpy(out_buf->extended_data[ch], buf->extended_data[ch],
777  buf->nb_samples * s->block_align);
778  continue;
779  }
780 
781  s->filter(s, buf->extended_data[ch], out_buf->extended_data[ch], buf->nb_samples,
782  &s->cache[ch].i1, &s->cache[ch].i2, &s->cache[ch].o1, &s->cache[ch].o2,
783  s->b0, s->b1, s->b2, s->a1, s->a2, &s->cache[ch].clippings, ctx->is_disabled);
784  }
785 
786  return 0;
787 }
788 
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;
815 
816  for (ch = 0; ch < outlink->channels; ch++) {
817  if (s->cache[ch].clippings > 0)
818  av_log(ctx, AV_LOG_WARNING, "Channel %d clipping %d times. Please reduce gain.\n",
819  ch, s->cache[ch].clippings);
820  s->cache[ch].clippings = 0;
821  }
822 
823  if (buf != out_buf)
824  av_frame_free(&buf);
825 
826  return ff_filter_frame(outlink, out_buf);
827 }
828 
829 static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
830  char *res, int res_len, int flags)
831 {
832  AVFilterLink *outlink = ctx->outputs[0];
833  int ret;
834 
835  ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags);
836  if (ret < 0)
837  return ret;
838 
839  return config_filter(outlink, 0);
840 }
841 
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 const 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 */
formats
formats
Definition: signature.h:48
ff_get_audio_buffer
AVFrame * ff_get_audio_buffer(AVFilterLink *link, int nb_samples)
Request an audio samples buffer with a specific set of permissions.
Definition: audio.c:86
AV_SAMPLE_FMT_FLTP
@ AV_SAMPLE_FMT_FLTP
float, planar
Definition: samplefmt.h:69
AVFilterChannelLayouts
A list of supported channel layouts.
Definition: formats.h:86
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:187
td
#define td
Definition: regdef.h:70
ff_exp10
static av_always_inline double ff_exp10(double x)
Compute 10^x for floating point values.
Definition: ffmath.h:42
BiquadsContext::ob1
double ob1
Definition: af_biquads.c:134
mix
static int mix(int c0, int c1)
Definition: 4xm.c:716
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
BiquadsContext::b0
double b0
Definition: af_biquads.c:131
ff_make_format_list
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:286
BiquadsContext::normalize
int normalize
Definition: af_biquads.c:127
DII
@ DII
Definition: af_biquads.c:98
BiquadsContext
Definition: af_biquads.c:110
BiquadsContext::block_align
int block_align
Definition: af_biquads.c:137
BiquadsContext::width_type
int width_type
Definition: af_biquads.c:114
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:978
sample_fmts
static enum AVSampleFormat sample_fmts[]
Definition: adpcmenc.c:953
layouts
enum MovChannelLayoutTag * layouts
Definition: mov_chan.c:434
BiquadsContext::a0
double a0
Definition: af_biquads.c:130
NB_TTYPE
@ NB_TTYPE
Definition: af_biquads.c:101
inlink
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is inlink
Definition: filter_design.txt:212
SLOPE
@ SLOPE
Definition: af_biquads.c:91
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:111
ff_all_channel_counts
AVFilterChannelLayouts * ff_all_channel_counts(void)
Construct an AVFilterChannelLayouts coding for any channel layout, with known or unknown disposition.
Definition: formats.c:429
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:303
AVOption
AVOption.
Definition: opt.h:248
BiquadsContext::csg
int csg
Definition: af_biquads.c:116
AV_SAMPLE_FMT_S32P
@ AV_SAMPLE_FMT_S32P
signed 32 bits, planar
Definition: samplefmt.h:68
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:197
bandreject
@ bandreject
Definition: af_biquads.c:78
ThreadData::out
AVFrame * out
Definition: af_adeclick.c:502
AVFormatContext::internal
AVFormatInternal * internal
An opaque field for libavformat internal usage.
Definition: avformat.h:1554
AVFilterFormats
A list of supported formats for one end of a filter link.
Definition: formats.h:65
A
#define A(x)
Definition: vp56_arith.h:28
ChanCache::i2
double i2
Definition: af_biquads.c:105
convert_dir2latt
static void convert_dir2latt(BiquadsContext *s)
Definition: af_biquads.c:436
v0
#define v0
Definition: regdef.h:26
outputs
static const AVFilterPad outputs[]
Definition: af_biquads.c:858
BiquadsContext::filter
void(* filter)(struct BiquadsContext *s, const void *ibuf, void *obuf, int len, double *i1, double *i2, double *o1, double *o2, double b0, double b1, double b2, double a1, double a2, int *clippings, int disabled)
Definition: af_biquads.c:139
FFSIGN
#define FFSIGN(a)
Definition: common.h:73
BiquadsContext::transform_type
int transform_type
Definition: af_biquads.c:117
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:54
BiquadsContext::bypass
int bypass
Definition: af_biquads.c:120
BiquadsContext::channels
uint64_t channels
Definition: af_biquads.c:126
FilterType
FilterType
Definition: af_adenorm.c:26
avassert.h
av_cold
#define av_cold
Definition: attributes.h:90
ff_set_common_formats
int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
A helper for query_formats() which sets all links to the same list of formats.
Definition: formats.c:580
width
#define width
s
#define s(width, name)
Definition: cbs_vp9.c:257
TransformType
TransformType
Definition: webp.c:110
AVFrame::channels
int channels
number of audio channels, only used for audio.
Definition: frame.h:592
AV_OPT_TYPE_DOUBLE
@ AV_OPT_TYPE_DOUBLE
Definition: opt.h:227
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
BiquadsContext::oa0
double oa0
Definition: af_biquads.c:133
highpass
@ highpass
Definition: af_biquads.c:80
BiquadsContext::precision
int precision
Definition: af_biquads.c:118
NB_WTYPE
@ NB_WTYPE
Definition: af_biquads.c:93
BiquadsContext::a1
double a1
Definition: af_biquads.c:130
ctx
AVFormatContext * ctx
Definition: movenc.c:48
channels
channels
Definition: aptx.h:33
BiquadsContext::width
double width
Definition: af_biquads.c:124
BiquadsContext::poles
int poles
Definition: af_biquads.c:115
arg
const char * arg
Definition: jacosubdec.c:67
av_realloc_f
#define av_realloc_f(p, o, n)
Definition: tableprint_vlc.h:33
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:67
fabs
static __device__ float fabs(float a)
Definition: cuda_runtime.h:182
NULL
#define NULL
Definition: coverity.c:32
biquad
@ biquad
Definition: af_biquads.c:73
av_frame_copy_props
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:536
BiquadsContext::cache
ChanCache * cache
Definition: af_biquads.c:136
allpass
@ allpass
Definition: af_biquads.c:79
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
Definition: af_biquads.c:789
exp
int8_t exp
Definition: eval.c:72
process_command
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
Definition: af_biquads.c:829
BiquadsContext::order
int order
Definition: af_biquads.c:128
KHERTZ
@ KHERTZ
Definition: af_biquads.c:92
ChanCache::i1
double i1
Definition: af_biquads.c:105
BiquadsContext::oa1
double oa1
Definition: af_biquads.c:133
lowpass
@ lowpass
Definition: af_biquads.c:81
AF
#define AF
Definition: af_biquads.c:869
BiquadsContext::ob2
double ob2
Definition: af_biquads.c:134
filter_channel
static int filter_channel(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: af_biquads.c:762
BiquadsContext::b1
double b1
Definition: af_biquads.c:131
NONE
@ NONE
Definition: af_biquads.c:87
AV_SAMPLE_FMT_NONE
@ AV_SAMPLE_FMT_NONE
Definition: samplefmt.h:59
highshelf
@ highshelf
Definition: af_biquads.c:83
av_frame_is_writable
int av_frame_is_writable(AVFrame *frame)
Check if the frame data is writable.
Definition: frame.c:472
ChanCache::o2
double o2
Definition: af_biquads.c:106
bass
@ bass
Definition: af_biquads.c:75
AV_OPT_TYPE_CHANNEL_LAYOUT
@ AV_OPT_TYPE_CHANNEL_LAYOUT
Definition: opt.h:241
ff_filter_process_command
int ff_filter_process_command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
Generic processing of user supplied commands that are set in the same way as the filter options.
Definition: avfilter.c:842
config_output
static int config_output(AVFilterLink *outlink)
Definition: af_biquads.c:753
FFMIN
#define FFMIN(a, b)
Definition: common.h:105
BIQUAD_LATT_FILTER
#define BIQUAD_LATT_FILTER(name, type, min, max, need_clipping)
Definition: af_biquads.c:381
M_PI
#define M_PI
Definition: mathematics.h:52
AV_SAMPLE_FMT_S16P
@ AV_SAMPLE_FMT_S16P
signed 16 bits, planar
Definition: samplefmt.h:67
LATT
@ LATT
Definition: af_biquads.c:100
internal.h
inputs
static const AVFilterPad inputs[]
Definition: af_biquads.c:849
BiquadsContext::mix
double mix
Definition: af_biquads.c:125
QFACTOR
@ QFACTOR
Definition: af_biquads.c:90
normalize
Definition: normalize.py:1
AVFrame::nb_samples
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:369
av_get_bytes_per_sample
int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt)
Return number of bytes per sample.
Definition: samplefmt.c:106
av_channel_layout_extract_channel
uint64_t av_channel_layout_extract_channel(uint64_t channel_layout, int index)
Get the channel with the given index in channel_layout.
Definition: channel_layout.c:271
AVFrame::extended_data
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: frame.h:350
ff_filter_get_nb_threads
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition: avfilter.c:762
BIQUAD_DII_FILTER
#define BIQUAD_DII_FILTER(name, type, min, max, need_clipping)
Definition: af_biquads.c:286
BiquadsContext::ob0
double ob0
Definition: af_biquads.c:134
AVSampleFormat
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
ThreadData
Used for passing data between threads.
Definition: dsddec.c:67
TDII
@ TDII
Definition: af_biquads.c:99
config_filter
static int config_filter(AVFilterLink *outlink, int reset)
Definition: af_biquads.c:453
len
int len
Definition: vorbis_enc_data.h:452
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:60
treble
@ treble
Definition: af_biquads.c:76
OFFSET
#define OFFSET(x)
Definition: af_biquads.c:867
ret
ret
Definition: filter_design.txt:187
WidthType
WidthType
Definition: af_biquads.c:86
BIQUAD_FILTER
#define BIQUAD_FILTER(name, type, min, max, need_clipping)
Definition: af_biquads.c:203
ChanCache
Definition: af_biquads.c:104
DEFINE_BIQUAD_FILTER
#define DEFINE_BIQUAD_FILTER(name_, description_)
Definition: af_biquads.c:871
ff_all_samplerates
AVFilterFormats * ff_all_samplerates(void)
Definition: formats.c:414
BiquadsContext::filter_type
enum FilterType filter_type
Definition: af_biquads.c:113
HERTZ
@ HERTZ
Definition: af_biquads.c:88
BiquadsContext::gain
double gain
Definition: af_biquads.c:122
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:225
avfilter.h
query_formats
static int query_formats(AVFilterContext *ctx)
Definition: af_biquads.c:145
AV_SAMPLE_FMT_DBLP
@ AV_SAMPLE_FMT_DBLP
double, planar
Definition: samplefmt.h:70
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: af_biquads.c:842
ffmath.h
ChanCache::o1
double o1
Definition: af_biquads.c:106
AVFilterContext
An instance of a filter.
Definition: avfilter.h:333
factor
static const int factor[16]
Definition: vf_pp7.c:77
FLAGS
#define FLAGS
Definition: af_biquads.c:868
BiquadsContext::b2
double b2
Definition: af_biquads.c:131
DI
@ DI
Definition: af_biquads.c:97
audio.h
ThreadData::in
AVFrame * in
Definition: af_adenorm.c:223
lowshelf
@ lowshelf
Definition: af_biquads.c:82
alpha
static const int16_t alpha[]
Definition: ilbcdata.h:55
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:242
equalizer
@ equalizer
Definition: af_biquads.c:74
BIQUAD_TDII_FILTER
#define BIQUAD_TDII_FILTER(name, type, min, max, need_clipping)
Definition: af_biquads.c:334
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
ChanCache::clippings
int clippings
Definition: af_biquads.c:107
OCTAVE
@ OCTAVE
Definition: af_biquads.c:89
int32_t
int32_t
Definition: audioconvert.c:56
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:561
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
ff_set_common_samplerates
int ff_set_common_samplerates(AVFilterContext *ctx, AVFilterFormats *samplerates)
Definition: formats.c:568
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:234
BiquadsContext::frequency
double frequency
Definition: af_biquads.c:123
BiquadsContext::a2
double a2
Definition: af_biquads.c:130
BiquadsContext::oa2
double oa2
Definition: af_biquads.c:133
bandpass
@ bandpass
Definition: af_biquads.c:77
ff_set_common_channel_layouts
int ff_set_common_channel_layouts(AVFilterContext *ctx, AVFilterChannelLayouts *channel_layouts)
A helper for query_formats() which sets all links to the same list of channel layouts/sample rates.
Definition: formats.c:561