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 
113  enum FilterType filter_type;
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[] = {
159  AV_SAMPLE_FMT_NONE
160  };
161  int ret;
162 
163  layouts = ff_all_channel_counts();
164  if (!layouts)
165  return AVERROR(ENOMEM);
166  ret = ff_set_common_channel_layouts(ctx, layouts);
167  if (ret < 0)
168  return ret;
169 
170  switch (s->precision) {
171  case 0:
172  sample_fmts[0] = AV_SAMPLE_FMT_S16P;
173  formats = ff_make_format_list(sample_fmts);
174  break;
175  case 1:
176  sample_fmts[0] = AV_SAMPLE_FMT_S32P;
177  formats = ff_make_format_list(sample_fmts);
178  break;
179  case 2:
180  sample_fmts[0] = AV_SAMPLE_FMT_FLTP;
181  formats = ff_make_format_list(sample_fmts);
182  break;
183  case 3:
184  sample_fmts[0] = AV_SAMPLE_FMT_DBLP;
185  formats = ff_make_format_list(sample_fmts);
186  break;
187  default:
188  formats = ff_make_format_list(auto_sample_fmts);
189  break;
190  }
191  if (!formats)
192  return AVERROR(ENOMEM);
193  ret = ff_set_common_formats(ctx, formats);
194  if (ret < 0)
195  return ret;
196 
197  formats = ff_all_samplerates();
198  if (!formats)
199  return AVERROR(ENOMEM);
200  return ff_set_common_samplerates(ctx, formats);
201 }
202 
203 #define BIQUAD_FILTER(name, type, min, max, need_clipping) \
204 static void biquad_## name (BiquadsContext *s, \
205  const void *input, void *output, int len, \
206  double *in1, double *in2, \
207  double *out1, double *out2, \
208  double b0, double b1, double b2, \
209  double a1, double a2, int *clippings, \
210  int disabled) \
211 { \
212  const type *ibuf = input; \
213  type *obuf = output; \
214  double i1 = *in1; \
215  double i2 = *in2; \
216  double o1 = *out1; \
217  double o2 = *out2; \
218  double wet = s->mix; \
219  double dry = 1. - wet; \
220  double out; \
221  int i; \
222  a1 = -a1; \
223  a2 = -a2; \
224  \
225  for (i = 0; i+1 < len; i++) { \
226  o2 = i2 * b2 + i1 * b1 + ibuf[i] * b0 + o2 * a2 + o1 * a1; \
227  i2 = ibuf[i]; \
228  out = o2 * wet + i2 * dry; \
229  if (disabled) { \
230  obuf[i] = i2; \
231  } else if (need_clipping && out < min) { \
232  (*clippings)++; \
233  obuf[i] = min; \
234  } else if (need_clipping && out > max) { \
235  (*clippings)++; \
236  obuf[i] = max; \
237  } else { \
238  obuf[i] = out; \
239  } \
240  i++; \
241  o1 = i1 * b2 + i2 * b1 + ibuf[i] * b0 + o1 * a2 + o2 * a1; \
242  i1 = ibuf[i]; \
243  out = o1 * wet + i1 * dry; \
244  if (disabled) { \
245  obuf[i] = i1; \
246  } else if (need_clipping && out < min) { \
247  (*clippings)++; \
248  obuf[i] = min; \
249  } else if (need_clipping && out > max) { \
250  (*clippings)++; \
251  obuf[i] = max; \
252  } else { \
253  obuf[i] = out; \
254  } \
255  } \
256  if (i < len) { \
257  double o0 = ibuf[i] * b0 + i1 * b1 + i2 * b2 + o1 * a1 + o2 * a2; \
258  i2 = i1; \
259  i1 = ibuf[i]; \
260  o2 = o1; \
261  o1 = o0; \
262  out = o0 * wet + i1 * dry; \
263  if (disabled) { \
264  obuf[i] = i1; \
265  } else if (need_clipping && out < min) { \
266  (*clippings)++; \
267  obuf[i] = min; \
268  } else if (need_clipping && out > max) { \
269  (*clippings)++; \
270  obuf[i] = max; \
271  } else { \
272  obuf[i] = out; \
273  } \
274  } \
275  *in1 = i1; \
276  *in2 = i2; \
277  *out1 = o1; \
278  *out2 = o2; \
279 }
280 
281 BIQUAD_FILTER(s16, int16_t, INT16_MIN, INT16_MAX, 1)
282 BIQUAD_FILTER(s32, int32_t, INT32_MIN, INT32_MAX, 1)
283 BIQUAD_FILTER(flt, float, -1., 1., 0)
284 BIQUAD_FILTER(dbl, double, -1., 1., 0)
285 
286 #define BIQUAD_DII_FILTER(name, type, min, max, need_clipping) \
287 static void biquad_dii_## name (BiquadsContext *s, \
288  const void *input, void *output, int len, \
289  double *z1, double *z2, \
290  double *unused1, double *unused2, \
291  double b0, double b1, double b2, \
292  double a1, double a2, int *clippings, \
293  int disabled) \
294 { \
295  const type *ibuf = input; \
296  type *obuf = output; \
297  double w1 = *z1; \
298  double w2 = *z2; \
299  double wet = s->mix; \
300  double dry = 1. - wet; \
301  double in, out, w0; \
302  \
303  a1 = -a1; \
304  a2 = -a2; \
305  \
306  for (int i = 0; i < len; i++) { \
307  in = ibuf[i]; \
308  w0 = in + a1 * w1 + a2 * w2; \
309  out = b0 * w0 + b1 * w1 + b2 * w2; \
310  w2 = w1; \
311  w1 = w0; \
312  out = out * wet + in * dry; \
313  if (disabled) { \
314  obuf[i] = in; \
315  } else if (need_clipping && out < min) { \
316  (*clippings)++; \
317  obuf[i] = min; \
318  } else if (need_clipping && out > max) { \
319  (*clippings)++; \
320  obuf[i] = max; \
321  } else { \
322  obuf[i] = out; \
323  } \
324  } \
325  *z1 = w1; \
326  *z2 = w2; \
327 }
328 
329 BIQUAD_DII_FILTER(s16, int16_t, INT16_MIN, INT16_MAX, 1)
330 BIQUAD_DII_FILTER(s32, int32_t, INT32_MIN, INT32_MAX, 1)
331 BIQUAD_DII_FILTER(flt, float, -1., 1., 0)
332 BIQUAD_DII_FILTER(dbl, double, -1., 1., 0)
333 
334 #define BIQUAD_TDII_FILTER(name, type, min, max, need_clipping) \
335 static void biquad_tdii_## name (BiquadsContext *s, \
336  const void *input, void *output, int len, \
337  double *z1, double *z2, \
338  double *unused1, double *unused2, \
339  double b0, double b1, double b2, \
340  double a1, double a2, int *clippings, \
341  int disabled) \
342 { \
343  const type *ibuf = input; \
344  type *obuf = output; \
345  double w1 = *z1; \
346  double w2 = *z2; \
347  double wet = s->mix; \
348  double dry = 1. - wet; \
349  double in, out; \
350  \
351  a1 = -a1; \
352  a2 = -a2; \
353  \
354  for (int i = 0; i < len; i++) { \
355  in = ibuf[i]; \
356  out = b0 * in + w1; \
357  w1 = b1 * in + w2 + a1 * out; \
358  w2 = b2 * in + a2 * out; \
359  out = out * wet + in * dry; \
360  if (disabled) { \
361  obuf[i] = in; \
362  } else if (need_clipping && out < min) { \
363  (*clippings)++; \
364  obuf[i] = min; \
365  } else if (need_clipping && out > max) { \
366  (*clippings)++; \
367  obuf[i] = max; \
368  } else { \
369  obuf[i] = out; \
370  } \
371  } \
372  *z1 = w1; \
373  *z2 = w2; \
374 }
375 
376 BIQUAD_TDII_FILTER(s16, int16_t, INT16_MIN, INT16_MAX, 1)
377 BIQUAD_TDII_FILTER(s32, int32_t, INT32_MIN, INT32_MAX, 1)
378 BIQUAD_TDII_FILTER(flt, float, -1., 1., 0)
379 BIQUAD_TDII_FILTER(dbl, double, -1., 1., 0)
380 
381 #define BIQUAD_LATT_FILTER(name, type, min, max, need_clipping) \
382 static void biquad_latt_## name (BiquadsContext *s, \
383  const void *input, void *output, int len, \
384  double *z1, double *z2, \
385  double *unused1, double *unused2, \
386  double v0, double v1, double v2, \
387  double k0, double k1, int *clippings, \
388  int disabled) \
389 { \
390  const type *ibuf = input; \
391  type *obuf = output; \
392  double s0 = *z1; \
393  double s1 = *z2; \
394  double wet = s->mix; \
395  double dry = 1. - wet; \
396  double in, out; \
397  double t0, t1; \
398  \
399  for (int i = 0; i < len; i++) { \
400  out = 0.; \
401  in = ibuf[i]; \
402  t0 = in - k1 * s0; \
403  t1 = t0 * k1 + s0; \
404  out += t1 * v2; \
405  \
406  t0 = t0 - k0 * s1; \
407  t1 = t0 * k0 + s1; \
408  out += t1 * v1; \
409  \
410  out += t0 * v0; \
411  s0 = t1; \
412  s1 = t0; \
413  \
414  out = out * wet + in * dry; \
415  if (disabled) { \
416  obuf[i] = in; \
417  } else if (need_clipping && out < min) { \
418  (*clippings)++; \
419  obuf[i] = min; \
420  } else if (need_clipping && out > max) { \
421  (*clippings)++; \
422  obuf[i] = max; \
423  } else { \
424  obuf[i] = out; \
425  } \
426  } \
427  *z1 = s0; \
428  *z2 = s1; \
429 }
430 
431 BIQUAD_LATT_FILTER(s16, int16_t, INT16_MIN, INT16_MAX, 1)
432 BIQUAD_LATT_FILTER(s32, int32_t, INT32_MIN, INT32_MAX, 1)
433 BIQUAD_LATT_FILTER(flt, float, -1., 1., 0)
434 BIQUAD_LATT_FILTER(dbl, double, -1., 1., 0)
435 
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 
746 
747  if (s->transform_type == LATT)
748  convert_dir2latt(s);
749 
750  return 0;
751 }
752 
753 static int config_output(AVFilterLink *outlink)
754 {
755  return config_filter(outlink, 1);
756 }
757 
758 typedef struct ThreadData {
759  AVFrame *in, *out;
760 } ThreadData;
761 
762 static int filter_channel(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
763 {
764  AVFilterLink *inlink = ctx->inputs[0];
765  ThreadData *td = arg;
766  AVFrame *buf = td->in;
767  AVFrame *out_buf = td->out;
768  BiquadsContext *s = ctx->priv;
769  const int start = (buf->channels * jobnr) / nb_jobs;
770  const int end = (buf->channels * (jobnr+1)) / nb_jobs;
771  int ch;
772 
773  for (ch = start; ch < end; ch++) {
774  if (!((av_channel_layout_extract_channel(inlink->channel_layout, ch) & s->channels))) {
775  if (buf != out_buf)
776  memcpy(out_buf->extended_data[ch], buf->extended_data[ch],
777  buf->nb_samples * s->block_align);
778  continue;
779  }
780 
781  s->filter(s, buf->extended_data[ch], out_buf->extended_data[ch], buf->nb_samples,
782  &s->cache[ch].i1, &s->cache[ch].i2, &s->cache[ch].o1, &s->cache[ch].o2,
783  s->b0, s->b1, s->b2, s->a1, s->a2, &s->cache[ch].clippings, ctx->is_disabled);
784  }
785 
786  return 0;
787 }
788 
790 {
791  AVFilterContext *ctx = inlink->dst;
792  BiquadsContext *s = ctx->priv;
793  AVFilterLink *outlink = ctx->outputs[0];
794  AVFrame *out_buf;
795  ThreadData td;
796  int ch;
797 
798  if (s->bypass)
799  return ff_filter_frame(outlink, buf);
800 
801  if (av_frame_is_writable(buf)) {
802  out_buf = buf;
803  } else {
804  out_buf = ff_get_audio_buffer(outlink, buf->nb_samples);
805  if (!out_buf) {
806  av_frame_free(&buf);
807  return AVERROR(ENOMEM);
808  }
809  av_frame_copy_props(out_buf, buf);
810  }
811 
812  td.in = buf;
813  td.out = out_buf;
814  ctx->internal->execute(ctx, filter_channel, &td, NULL, FFMIN(outlink->channels, ff_filter_get_nb_threads(ctx)));
815 
816  for (ch = 0; ch < outlink->channels; ch++) {
817  if (s->cache[ch].clippings > 0)
818  av_log(ctx, AV_LOG_WARNING, "Channel %d clipping %d times. Please reduce gain.\n",
819  ch, s->cache[ch].clippings);
820  s->cache[ch].clippings = 0;
821  }
822 
823  if (buf != out_buf)
824  av_frame_free(&buf);
825 
826  return ff_filter_frame(outlink, out_buf);
827 }
828 
829 static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
830  char *res, int res_len, int flags)
831 {
832  AVFilterLink *outlink = ctx->outputs[0];
833  int ret;
834 
835  ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags);
836  if (ret < 0)
837  return ret;
838 
839  return config_filter(outlink, 0);
840 }
841 
843 {
844  BiquadsContext *s = ctx->priv;
845 
846  av_freep(&s->cache);
847 }
848 
849 static const AVFilterPad inputs[] = {
850  {
851  .name = "default",
852  .type = AVMEDIA_TYPE_AUDIO,
853  .filter_frame = filter_frame,
854  },
855  { NULL }
856 };
857 
858 static const AVFilterPad outputs[] = {
859  {
860  .name = "default",
861  .type = AVMEDIA_TYPE_AUDIO,
862  .config_props = config_output,
863  },
864  { NULL }
865 };
866 
867 #define OFFSET(x) offsetof(BiquadsContext, x)
868 #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
869 #define AF AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
870 
871 #define DEFINE_BIQUAD_FILTER(name_, description_) \
872 AVFILTER_DEFINE_CLASS(name_); \
873 static av_cold int name_##_init(AVFilterContext *ctx) \
874 { \
875  BiquadsContext *s = ctx->priv; \
876  s->filter_type = name_; \
877  return 0; \
878 } \
879  \
880 AVFilter ff_af_##name_ = { \
881  .name = #name_, \
882  .description = NULL_IF_CONFIG_SMALL(description_), \
883  .priv_size = sizeof(BiquadsContext), \
884  .init = name_##_init, \
885  .uninit = uninit, \
886  .query_formats = query_formats, \
887  .inputs = inputs, \
888  .outputs = outputs, \
889  .priv_class = &name_##_class, \
890  .process_command = process_command, \
891  .flags = AVFILTER_FLAG_SLICE_THREADS | AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL, \
892 }
893 
894 #if CONFIG_EQUALIZER_FILTER
895 static const AVOption equalizer_options[] = {
896  {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 999999, FLAGS},
897  {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 999999, FLAGS},
898  {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
899  {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
900  {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
901  {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
902  {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
903  {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
904  {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
905  {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 99999, FLAGS},
906  {"w", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 99999, FLAGS},
907  {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
908  {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
909  {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
910  {"m", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
911  {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
912  {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
913  {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
914  {"n", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
915  {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
916  {"a", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
917  {"di", "direct form I", 0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
918  {"dii", "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
919  {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
920  {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
921  {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
922  {"r", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
923  {"auto", "automatic", 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"},
924  {"s16", "signed 16-bit", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "precision"},
925  {"s32", "signed 32-bit", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "precision"},
926  {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, AF, "precision"},
927  {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, AF, "precision"},
928  {NULL}
929 };
930 
931 DEFINE_BIQUAD_FILTER(equalizer, "Apply two-pole peaking equalization (EQ) filter.");
932 #endif /* CONFIG_EQUALIZER_FILTER */
933 #if CONFIG_BASS_FILTER || CONFIG_LOWSHELF_FILTER
934 static const AVOption bass_lowshelf_options[] = {
935  {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
936  {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
937  {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
938  {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
939  {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
940  {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
941  {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
942  {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
943  {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
944  {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
945  {"w", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
946  {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
947  {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
948  {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
949  {"p", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
950  {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
951  {"m", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
952  {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
953  {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
954  {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
955  {"n", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
956  {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
957  {"a", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
958  {"di", "direct form I", 0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
959  {"dii", "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
960  {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
961  {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
962  {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
963  {"r", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
964  {"auto", "automatic", 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"},
965  {"s16", "signed 16-bit", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "precision"},
966  {"s32", "signed 32-bit", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "precision"},
967  {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, AF, "precision"},
968  {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, AF, "precision"},
969  {NULL}
970 };
971 
972 #if CONFIG_BASS_FILTER
973 #define bass_options bass_lowshelf_options
974 DEFINE_BIQUAD_FILTER(bass, "Boost or cut lower frequencies.");
975 #endif /* CONFIG_BASS_FILTER */
976 
977 #if CONFIG_LOWSHELF_FILTER
978 #define lowshelf_options bass_lowshelf_options
979 DEFINE_BIQUAD_FILTER(lowshelf, "Apply a low shelf filter.");
980 #endif /* CONFIG_LOWSHELF_FILTER */
981 #endif /* CONFIG_BASS_FILTER || CONFIG LOWSHELF_FILTER */
982 #if CONFIG_TREBLE_FILTER || CONFIG_HIGHSHELF_FILTER
983 static const AVOption treble_highshelf_options[] = {
984  {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
985  {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
986  {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
987  {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
988  {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
989  {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
990  {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
991  {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
992  {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
993  {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
994  {"w", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
995  {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
996  {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
997  {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
998  {"p", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
999  {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1000  {"m", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1001  {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1002  {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1003  {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1004  {"n", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1005  {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1006  {"a", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1007  {"di", "direct form I", 0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
1008  {"dii", "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
1009  {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
1010  {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
1011  {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1012  {"r", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1013  {"auto", "automatic", 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"},
1014  {"s16", "signed 16-bit", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "precision"},
1015  {"s32", "signed 32-bit", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "precision"},
1016  {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, AF, "precision"},
1017  {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, AF, "precision"},
1018  {NULL}
1019 };
1020 
1021 #if CONFIG_TREBLE_FILTER
1022 #define treble_options treble_highshelf_options
1023 DEFINE_BIQUAD_FILTER(treble, "Boost or cut upper frequencies.");
1024 #endif /* CONFIG_TREBLE_FILTER */
1025 
1026 #if CONFIG_HIGHSHELF_FILTER
1027 #define highshelf_options treble_highshelf_options
1028 DEFINE_BIQUAD_FILTER(highshelf, "Apply a high shelf filter.");
1029 #endif /* CONFIG_HIGHSHELF_FILTER */
1030 #endif /* CONFIG_TREBLE_FILTER || CONFIG_HIGHSHELF_FILTER */
1031 #if CONFIG_BANDPASS_FILTER
1032 static const AVOption bandpass_options[] = {
1033  {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1034  {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1035  {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1036  {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1037  {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
1038  {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
1039  {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
1040  {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
1041  {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
1042  {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
1043  {"w", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
1044  {"csg", "use constant skirt gain", OFFSET(csg), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1045  {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1046  {"m", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1047  {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1048  {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1049  {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1050  {"n", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1051  {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1052  {"a", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1053  {"di", "direct form I", 0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
1054  {"dii", "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
1055  {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
1056  {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
1057  {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1058  {"r", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1059  {"auto", "automatic", 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"},
1060  {"s16", "signed 16-bit", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "precision"},
1061  {"s32", "signed 32-bit", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "precision"},
1062  {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, AF, "precision"},
1063  {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, AF, "precision"},
1064  {NULL}
1065 };
1066 
1067 DEFINE_BIQUAD_FILTER(bandpass, "Apply a two-pole Butterworth band-pass filter.");
1068 #endif /* CONFIG_BANDPASS_FILTER */
1069 #if CONFIG_BANDREJECT_FILTER
1070 static const AVOption bandreject_options[] = {
1071  {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1072  {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1073  {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1074  {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1075  {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
1076  {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
1077  {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
1078  {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
1079  {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
1080  {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
1081  {"w", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
1082  {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1083  {"m", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1084  {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1085  {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1086  {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1087  {"n", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1088  {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1089  {"a", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1090  {"di", "direct form I", 0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
1091  {"dii", "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
1092  {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
1093  {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
1094  {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1095  {"r", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1096  {"auto", "automatic", 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"},
1097  {"s16", "signed 16-bit", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "precision"},
1098  {"s32", "signed 32-bit", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "precision"},
1099  {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, AF, "precision"},
1100  {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, AF, "precision"},
1101  {NULL}
1102 };
1103 
1104 DEFINE_BIQUAD_FILTER(bandreject, "Apply a two-pole Butterworth band-reject filter.");
1105 #endif /* CONFIG_BANDREJECT_FILTER */
1106 #if CONFIG_LOWPASS_FILTER
1107 static const AVOption lowpass_options[] = {
1108  {"frequency", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=500}, 0, 999999, FLAGS},
1109  {"f", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=500}, 0, 999999, FLAGS},
1110  {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1111  {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1112  {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
1113  {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
1114  {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
1115  {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
1116  {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
1117  {"width", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
1118  {"w", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
1119  {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
1120  {"p", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
1121  {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1122  {"m", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1123  {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1124  {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1125  {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1126  {"n", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1127  {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1128  {"a", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1129  {"di", "direct form I", 0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
1130  {"dii", "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
1131  {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
1132  {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
1133  {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1134  {"r", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1135  {"auto", "automatic", 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"},
1136  {"s16", "signed 16-bit", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "precision"},
1137  {"s32", "signed 32-bit", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "precision"},
1138  {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, AF, "precision"},
1139  {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, AF, "precision"},
1140  {NULL}
1141 };
1142 
1143 DEFINE_BIQUAD_FILTER(lowpass, "Apply a low-pass filter with 3dB point frequency.");
1144 #endif /* CONFIG_LOWPASS_FILTER */
1145 #if CONFIG_HIGHPASS_FILTER
1146 static const AVOption highpass_options[] = {
1147  {"frequency", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1148  {"f", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1149  {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1150  {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1151  {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
1152  {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
1153  {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
1154  {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
1155  {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
1156  {"width", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
1157  {"w", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
1158  {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
1159  {"p", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, AF},
1160  {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1161  {"m", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1162  {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1163  {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1164  {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1165  {"n", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1166  {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1167  {"a", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1168  {"di", "direct form I", 0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
1169  {"dii", "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
1170  {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
1171  {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
1172  {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1173  {"r", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1174  {"auto", "automatic", 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"},
1175  {"s16", "signed 16-bit", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "precision"},
1176  {"s32", "signed 32-bit", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "precision"},
1177  {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, AF, "precision"},
1178  {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, AF, "precision"},
1179  {NULL}
1180 };
1181 
1182 DEFINE_BIQUAD_FILTER(highpass, "Apply a high-pass filter with 3dB point frequency.");
1183 #endif /* CONFIG_HIGHPASS_FILTER */
1184 #if CONFIG_ALLPASS_FILTER
1185 static const AVOption allpass_options[] = {
1186  {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1187  {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
1188  {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=HERTZ}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1189  {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=HERTZ}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
1190  {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
1191  {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
1192  {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
1193  {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
1194  {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
1195  {"width", "set filter-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=707.1}, 0, 99999, FLAGS},
1196  {"w", "set filter-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=707.1}, 0, 99999, FLAGS},
1197  {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1198  {"m", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1199  {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1200  {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1201  {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1202  {"n", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1203  {"order", "set filter order", OFFSET(order), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
1204  {"o", "set filter order", OFFSET(order), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
1205  {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1206  {"a", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1207  {"di", "direct form I", 0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
1208  {"dii", "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
1209  {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
1210  {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
1211  {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1212  {"r", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1213  {"auto", "automatic", 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"},
1214  {"s16", "signed 16-bit", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "precision"},
1215  {"s32", "signed 32-bit", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "precision"},
1216  {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, AF, "precision"},
1217  {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, AF, "precision"},
1218  {NULL}
1219 };
1220 
1221 DEFINE_BIQUAD_FILTER(allpass, "Apply a two-pole all-pass filter.");
1222 #endif /* CONFIG_ALLPASS_FILTER */
1223 #if CONFIG_BIQUAD_FILTER
1224 static const AVOption biquad_options[] = {
1225  {"a0", NULL, OFFSET(oa0), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT32_MIN, INT32_MAX, FLAGS},
1226  {"a1", NULL, OFFSET(oa1), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
1227  {"a2", NULL, OFFSET(oa2), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
1228  {"b0", NULL, OFFSET(ob0), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
1229  {"b1", NULL, OFFSET(ob1), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
1230  {"b2", NULL, OFFSET(ob2), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
1231  {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1232  {"m", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, FLAGS},
1233  {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1234  {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
1235  {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1236  {"n", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
1237  {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1238  {"a", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"},
1239  {"di", "direct form I", 0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"},
1240  {"dii", "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"},
1241  {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"},
1242  {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"},
1243  {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1244  {"r", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=-1}, -1, 3, AF, "precision"},
1245  {"auto", "automatic", 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"},
1246  {"s16", "signed 16-bit", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "precision"},
1247  {"s32", "signed 32-bit", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "precision"},
1248  {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, AF, "precision"},
1249  {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, AF, "precision"},
1250  {NULL}
1251 };
1252 
1253 DEFINE_BIQUAD_FILTER(biquad, "Apply a biquad IIR filter with the given coefficients.");
1254 #endif /* CONFIG_BIQUAD_FILTER */
float, planar
Definition: samplefmt.h:69
#define NULL
Definition: coverity.c:32
AVFrame * out
Definition: af_adeclick.c:494
This structure describes decoded (raw) audio or video data.
Definition: frame.h:314
#define av_realloc_f(p, o, n)
FilterType
Definition: af_adenorm.c:26
AVOption.
Definition: opt.h:248
TransformType
Definition: webp.c:110
ChanCache * cache
Definition: af_biquads.c:136
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:200
Main libavfilter public API header.
double i2
Definition: af_biquads.c:105
#define a0
Definition: regdef.h:46
double, planar
Definition: samplefmt.h:70
#define a1
Definition: regdef.h:47
static const AVFilterPad inputs[]
Definition: af_biquads.c:849
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:569
GLfloat v0
Definition: opengl_enc.c:106
int is_disabled
the enabled state from the last expression evaluation
Definition: avfilter.h:388
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:287
const char * name
Pad name.
Definition: internal.h:60
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:349
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1091
#define OFFSET(x)
Definition: af_biquads.c:867
#define av_cold
Definition: attributes.h:88
AVOptions.
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:92
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
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:210
channels
Definition: aptx.h:33
#define A(x)
Definition: vp56_arith.h:28
#define BIQUAD_LATT_FILTER(name, type, min, max, need_clipping)
Definition: af_biquads.c:381
#define av_log(a,...)
static const AVFilterPad outputs[]
Definition: af_biquads.c:858
A filter pad used for either input or output.
Definition: internal.h:54
static av_always_inline double ff_exp10(double x)
Compute 10^x for floating point values.
Definition: ffmath.h:42
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:588
#define td
Definition: regdef.h:70
#define FLAGS
Definition: af_biquads.c:868
Definition: af_biquads.c:97
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce then the filter should push the output frames on the output link immediately As an exception to the previous rule if the input frame is enough to produce several output frames then the filter needs output only at least one per link The additional frames can be left buffered in the filter
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
static __device__ float fabs(float a)
Definition: cuda_runtime.h:182
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:203
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:885
void * priv
private data for use by the filter
Definition: avfilter.h:356
const char * arg
Definition: jacosubdec.c:66
simple assert() macros that are a bit more flexible than ISO C assert().
uint64_t channels
Definition: af_biquads.c:126
int8_t exp
Definition: eval.c:72
double o1
Definition: af_biquads.c:106
int channels
number of audio channels, only used for audio.
Definition: frame.h:620
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition: avfilter.c:800
#define FFMIN(a, b)
Definition: common.h:96
signed 32 bits, planar
Definition: samplefmt.h:68
#define width
#define FFSIGN(a)
Definition: common.h:73
typedef void(APIENTRY *FF_PFNGLACTIVETEXTUREPROC)(GLenum texture)
int32_t
AVFormatContext * ctx
Definition: movenc.c:48
#define a2
Definition: regdef.h:48
static double b0(void *priv, double x, double y)
Definition: vf_xfade.c:1664
#define s(width, name)
Definition: cbs_vp9.c:257
#define BIQUAD_DII_FILTER(name, type, min, max, need_clipping)
Definition: af_biquads.c:286
A list of supported channel layouts.
Definition: formats.h:86
static double b1(void *priv, double x, double y)
Definition: vf_xfade.c:1665
static int mix(int c0, int c1)
Definition: 4xm.c:715
#define BIQUAD_FILTER(name, type, min, max, need_clipping)
Definition: af_biquads.c:203
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
static int filter_channel(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: af_biquads.c:762
int av_frame_is_writable(AVFrame *frame)
Check if the frame data is writable.
Definition: frame.c:594
Used for passing data between threads.
Definition: dsddec.c:67
static int config_output(AVFilterLink *outlink)
Definition: af_biquads.c:753
static const int16_t alpha[]
Definition: ilbcdata.h:55
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31))))#define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac){}void ff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map){AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);return NULL;}return ac;}in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;}int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){int use_generic=1;int len=in->nb_samples;int p;if(ac->dc){av_log(ac->avr, AV_LOG_TRACE,"%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
Describe the class of an AVClass context structure.
Definition: log.h:67
#define BIQUAD_TDII_FILTER(name, type, min, max, need_clipping)
Definition: af_biquads.c:334
#define DEFINE_BIQUAD_FILTER(name_, description_)
Definition: af_biquads.c:871
static const int factor[16]
Definition: vf_pp7.c:77
static int query_formats(AVFilterContext *ctx)
Definition: af_biquads.c:145
double o2
Definition: af_biquads.c:106
Definition: af_biquads.c:98
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:353
enum MovChannelLayoutTag * layouts
Definition: mov_chan.c:434
AVFilterFormats * ff_all_samplerates(void)
Definition: formats.c:422
#define flags(name, subs,...)
Definition: cbs_av1.c:561
AVFilterInternal * internal
An opaque struct for libavfilter internal use.
Definition: avfilter.h:381
static av_cold void uninit(AVFilterContext *ctx)
Definition: af_biquads.c:842
int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt)
Return number of bytes per sample.
Definition: samplefmt.c:106
int clippings
Definition: af_biquads.c:107
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
internal math functions header
uint64_t av_channel_layout_extract_channel(uint64_t channel_layout, int index)
Get the channel with the given index in channel_layout.
avfilter_execute_func * execute
Definition: internal.h:136
static int config_filter(AVFilterLink *outlink, int reset)
Definition: af_biquads.c:453
WidthType
Definition: af_biquads.c:86
static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
Definition: af_biquads.c:789
int len
static void convert_dir2latt(BiquadsContext *s)
Definition: af_biquads.c:436
#define AF
Definition: af_biquads.c:869
double i1
Definition: af_biquads.c:105
A list of supported formats for one end of a filter link.
Definition: formats.h:65
An instance of a filter.
Definition: avfilter.h:341
static enum AVSampleFormat sample_fmts[]
Definition: adpcmenc.c:940
FILE * out
Definition: movenc.c:54
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
Definition: af_biquads.c:829
#define av_freep(p)
signed 16 bits, planar
Definition: samplefmt.h:67
double frequency
Definition: af_biquads.c:123
#define M_PI
Definition: mathematics.h:52
AVFrame * in
Definition: af_adenorm.c:223
formats
Definition: signature.h:48
internal API functions
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
AVFilterChannelLayouts * ff_all_channel_counts(void)
Construct an AVFilterChannelLayouts coding for any channel layout, with known or unknown disposition...
Definition: formats.c:437
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: frame.h:361
enum FilterType filter_type
Definition: af_biquads.c:113
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:380
int ff_set_common_samplerates(AVFilterContext *ctx, AVFilterFormats *samplerates)
Definition: formats.c:576
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:658
static double b2(void *priv, double x, double y)
Definition: vf_xfade.c:1666