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