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/opt.h"
66 #include "libavutil/avassert.h"
67 #include "audio.h"
68 #include "avfilter.h"
69 #include "internal.h"
70 
71 enum FilterType {
82 };
83 
84 enum WidthType {
86  HZ,
90 };
91 
92 typedef struct ChanCache {
93  double i1, i2;
94  double o1, o2;
95 } ChanCache;
96 
97 typedef struct {
98  const AVClass *class;
99 
100  enum FilterType filter_type;
101  enum WidthType width_type;
102  int poles;
103  int csg;
104 
105  double gain;
106  double frequency;
107  double width;
108 
109  double a0, a1, a2;
110  double b0, b1, b2;
111 
113 
114  void (*filter)(const void *ibuf, void *obuf, int len,
115  double *i1, double *i2, double *o1, double *o2,
116  double b0, double b1, double b2, double a1, double a2);
118 
119 static av_cold int init(AVFilterContext *ctx)
120 {
121  BiquadsContext *p = ctx->priv;
122 
123  if (p->filter_type != biquad) {
124  if (p->frequency <= 0 || p->width <= 0) {
125  av_log(ctx, AV_LOG_ERROR, "Invalid frequency %f and/or width %f <= 0\n",
126  p->frequency, p->width);
127  return AVERROR(EINVAL);
128  }
129  }
130 
131  return 0;
132 }
133 
135 {
138  static const enum AVSampleFormat sample_fmts[] = {
144  };
145 
146  layouts = ff_all_channel_layouts();
147  if (!layouts)
148  return AVERROR(ENOMEM);
149  ff_set_common_channel_layouts(ctx, layouts);
150 
151  formats = ff_make_format_list(sample_fmts);
152  if (!formats)
153  return AVERROR(ENOMEM);
154  ff_set_common_formats(ctx, formats);
155 
156  formats = ff_all_samplerates();
157  if (!formats)
158  return AVERROR(ENOMEM);
159  ff_set_common_samplerates(ctx, formats);
160 
161  return 0;
162 }
163 
164 #define BIQUAD_FILTER(name, type, min, max) \
165 static void biquad_## name (const void *input, void *output, int len, \
166  double *in1, double *in2, \
167  double *out1, double *out2, \
168  double b0, double b1, double b2, \
169  double a1, double a2) \
170 { \
171  const type *ibuf = input; \
172  type *obuf = output; \
173  double i1 = *in1; \
174  double i2 = *in2; \
175  double o1 = *out1; \
176  double o2 = *out2; \
177  int i; \
178  a1 = -a1; \
179  a2 = -a2; \
180  \
181  for (i = 0; i+1 < len; i++) { \
182  o2 = i2 * b2 + i1 * b1 + ibuf[i] * b0 + o2 * a2 + o1 * a1; \
183  i2 = ibuf[i]; \
184  if (o2 < min) { \
185  av_log(NULL, AV_LOG_WARNING, "clipping\n"); \
186  obuf[i] = min; \
187  } else if (o2 > max) { \
188  av_log(NULL, AV_LOG_WARNING, "clipping\n"); \
189  obuf[i] = max; \
190  } else { \
191  obuf[i] = o2; \
192  } \
193  i++; \
194  o1 = i1 * b2 + i2 * b1 + ibuf[i] * b0 + o1 * a2 + o2 * a1; \
195  i1 = ibuf[i]; \
196  if (o1 < min) { \
197  av_log(NULL, AV_LOG_WARNING, "clipping\n"); \
198  obuf[i] = min; \
199  } else if (o1 > max) { \
200  av_log(NULL, AV_LOG_WARNING, "clipping\n"); \
201  obuf[i] = max; \
202  } else { \
203  obuf[i] = o1; \
204  } \
205  } \
206  if (i < len) { \
207  double o0 = ibuf[i] * b0 + i1 * b1 + i2 * b2 + o1 * a1 + o2 * a2; \
208  i2 = i1; \
209  i1 = ibuf[i]; \
210  o2 = o1; \
211  o1 = o0; \
212  if (o0 < min) { \
213  av_log(NULL, AV_LOG_WARNING, "clipping\n"); \
214  obuf[i] = min; \
215  } else if (o0 > max) { \
216  av_log(NULL, AV_LOG_WARNING, "clipping\n"); \
217  obuf[i] = max; \
218  } else { \
219  obuf[i] = o0; \
220  } \
221  } \
222  *in1 = i1; \
223  *in2 = i2; \
224  *out1 = o1; \
225  *out2 = o2; \
226 }
227 
228 BIQUAD_FILTER(s16, int16_t, INT16_MIN, INT16_MAX)
229 BIQUAD_FILTER(s32, int32_t, INT32_MIN, INT32_MAX)
230 BIQUAD_FILTER(flt, float, -1., 1.)
231 BIQUAD_FILTER(dbl, double, -1., 1.)
232 
233 static int config_output(AVFilterLink *outlink)
234 {
235  AVFilterContext *ctx = outlink->src;
236  BiquadsContext *p = ctx->priv;
237  AVFilterLink *inlink = ctx->inputs[0];
238  double A = exp(p->gain / 40 * log(10.));
239  double w0 = 2 * M_PI * p->frequency / inlink->sample_rate;
240  double alpha;
241 
242  if (w0 > M_PI) {
243  av_log(ctx, AV_LOG_ERROR,
244  "Invalid frequency %f. Frequency must be less than half the sample-rate %d.\n",
245  p->frequency, inlink->sample_rate);
246  return AVERROR(EINVAL);
247  }
248 
249  switch (p->width_type) {
250  case NONE:
251  alpha = 0.0;
252  break;
253  case HZ:
254  alpha = sin(w0) / (2 * p->frequency / p->width);
255  break;
256  case OCTAVE:
257  alpha = sin(w0) * sinh(log(2.) / 2 * p->width * w0 / sin(w0));
258  break;
259  case QFACTOR:
260  alpha = sin(w0) / (2 * p->width);
261  break;
262  case SLOPE:
263  alpha = sin(w0) / 2 * sqrt((A + 1 / A) * (1 / p->width - 1) + 2);
264  break;
265  default:
266  av_assert0(0);
267  }
268 
269  switch (p->filter_type) {
270  case biquad:
271  break;
272  case equalizer:
273  p->a0 = 1 + alpha / A;
274  p->a1 = -2 * cos(w0);
275  p->a2 = 1 - alpha / A;
276  p->b0 = 1 + alpha * A;
277  p->b1 = -2 * cos(w0);
278  p->b2 = 1 - alpha * A;
279  break;
280  case bass:
281  p->a0 = (A + 1) + (A - 1) * cos(w0) + 2 * sqrt(A) * alpha;
282  p->a1 = -2 * ((A - 1) + (A + 1) * cos(w0));
283  p->a2 = (A + 1) + (A - 1) * cos(w0) - 2 * sqrt(A) * alpha;
284  p->b0 = A * ((A + 1) - (A - 1) * cos(w0) + 2 * sqrt(A) * alpha);
285  p->b1 = 2 * A * ((A - 1) - (A + 1) * cos(w0));
286  p->b2 = A * ((A + 1) - (A - 1) * cos(w0) - 2 * sqrt(A) * alpha);
287  break;
288  case treble:
289  p->a0 = (A + 1) - (A - 1) * cos(w0) + 2 * sqrt(A) * alpha;
290  p->a1 = 2 * ((A - 1) - (A + 1) * cos(w0));
291  p->a2 = (A + 1) - (A - 1) * cos(w0) - 2 * sqrt(A) * alpha;
292  p->b0 = A * ((A + 1) + (A - 1) * cos(w0) + 2 * sqrt(A) * alpha);
293  p->b1 =-2 * A * ((A - 1) + (A + 1) * cos(w0));
294  p->b2 = A * ((A + 1) + (A - 1) * cos(w0) - 2 * sqrt(A) * alpha);
295  break;
296  case bandpass:
297  if (p->csg) {
298  p->a0 = 1 + alpha;
299  p->a1 = -2 * cos(w0);
300  p->a2 = 1 - alpha;
301  p->b0 = sin(w0) / 2;
302  p->b1 = 0;
303  p->b2 = -sin(w0) / 2;
304  } else {
305  p->a0 = 1 + alpha;
306  p->a1 = -2 * cos(w0);
307  p->a2 = 1 - alpha;
308  p->b0 = alpha;
309  p->b1 = 0;
310  p->b2 = -alpha;
311  }
312  break;
313  case bandreject:
314  p->a0 = 1 + alpha;
315  p->a1 = -2 * cos(w0);
316  p->a2 = 1 - alpha;
317  p->b0 = 1;
318  p->b1 = -2 * cos(w0);
319  p->b2 = 1;
320  break;
321  case lowpass:
322  if (p->poles == 1) {
323  p->a0 = 1;
324  p->a1 = -exp(-w0);
325  p->a2 = 0;
326  p->b0 = 1 + p->a1;
327  p->b1 = 0;
328  p->b2 = 0;
329  } else {
330  p->a0 = 1 + alpha;
331  p->a1 = -2 * cos(w0);
332  p->a2 = 1 - alpha;
333  p->b0 = (1 - cos(w0)) / 2;
334  p->b1 = 1 - cos(w0);
335  p->b2 = (1 - cos(w0)) / 2;
336  }
337  break;
338  case highpass:
339  if (p->poles == 1) {
340  p->a0 = 1;
341  p->a1 = -exp(-w0);
342  p->a2 = 0;
343  p->b0 = (1 - p->a1) / 2;
344  p->b1 = -p->b0;
345  p->b2 = 0;
346  } else {
347  p->a0 = 1 + alpha;
348  p->a1 = -2 * cos(w0);
349  p->a2 = 1 - alpha;
350  p->b0 = (1 + cos(w0)) / 2;
351  p->b1 = -(1 + cos(w0));
352  p->b2 = (1 + cos(w0)) / 2;
353  }
354  break;
355  case allpass:
356  p->a0 = 1 + alpha;
357  p->a1 = -2 * cos(w0);
358  p->a2 = 1 - alpha;
359  p->b0 = 1 - alpha;
360  p->b1 = -2 * cos(w0);
361  p->b2 = 1 + alpha;
362  break;
363  default:
364  av_assert0(0);
365  }
366 
367  p->a1 /= p->a0;
368  p->a2 /= p->a0;
369  p->b0 /= p->a0;
370  p->b1 /= p->a0;
371  p->b2 /= p->a0;
372 
373  p->cache = av_realloc_f(p->cache, sizeof(ChanCache), inlink->channels);
374  if (!p->cache)
375  return AVERROR(ENOMEM);
376  memset(p->cache, 0, sizeof(ChanCache) * inlink->channels);
377 
378  switch (inlink->format) {
379  case AV_SAMPLE_FMT_S16P: p->filter = biquad_s16; break;
380  case AV_SAMPLE_FMT_S32P: p->filter = biquad_s32; break;
381  case AV_SAMPLE_FMT_FLTP: p->filter = biquad_flt; break;
382  case AV_SAMPLE_FMT_DBLP: p->filter = biquad_dbl; break;
383  default: av_assert0(0);
384  }
385 
386  return 0;
387 }
388 
389 static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
390 {
391  BiquadsContext *p = inlink->dst->priv;
392  AVFilterLink *outlink = inlink->dst->outputs[0];
393  AVFrame *out_buf;
394  int nb_samples = buf->nb_samples;
395  int ch;
396 
397  if (av_frame_is_writable(buf)) {
398  out_buf = buf;
399  } else {
400  out_buf = ff_get_audio_buffer(inlink, nb_samples);
401  if (!out_buf)
402  return AVERROR(ENOMEM);
403  av_frame_copy_props(out_buf, buf);
404  }
405 
406  for (ch = 0; ch < av_frame_get_channels(buf); ch++)
407  p->filter(buf->extended_data[ch],
408  out_buf->extended_data[ch], nb_samples,
409  &p->cache[ch].i1, &p->cache[ch].i2,
410  &p->cache[ch].o1, &p->cache[ch].o2,
411  p->b0, p->b1, p->b2, p->a1, p->a2);
412 
413  if (buf != out_buf)
414  av_frame_free(&buf);
415 
416  return ff_filter_frame(outlink, out_buf);
417 }
418 
419 static av_cold void uninit(AVFilterContext *ctx)
420 {
421  BiquadsContext *p = ctx->priv;
422 
423  av_freep(&p->cache);
424 }
425 
426 static const AVFilterPad inputs[] = {
427  {
428  .name = "default",
429  .type = AVMEDIA_TYPE_AUDIO,
430  .filter_frame = filter_frame,
431  },
432  { NULL }
433 };
434 
435 static const AVFilterPad outputs[] = {
436  {
437  .name = "default",
438  .type = AVMEDIA_TYPE_AUDIO,
439  .config_props = config_output,
440  },
441  { NULL }
442 };
443 
444 #define OFFSET(x) offsetof(BiquadsContext, x)
445 #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
446 
447 #define DEFINE_BIQUAD_FILTER(name_, description_) \
448 AVFILTER_DEFINE_CLASS(name_); \
449 static av_cold int name_##_init(AVFilterContext *ctx) \
450 { \
451  BiquadsContext *p = ctx->priv; \
452  p->class = &name_##_class; \
453  p->filter_type = name_; \
454  return init(ctx); \
455 } \
456  \
457 AVFilter avfilter_af_##name_ = { \
458  .name = #name_, \
459  .description = NULL_IF_CONFIG_SMALL(description_), \
460  .priv_size = sizeof(BiquadsContext), \
461  .init = name_##_init, \
462  .uninit = uninit, \
463  .query_formats = query_formats, \
464  .inputs = inputs, \
465  .outputs = outputs, \
466  .priv_class = &name_##_class, \
467 }
468 
469 #if CONFIG_EQUALIZER_FILTER
470 static const AVOption equalizer_options[] = {
471  {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 999999, FLAGS},
472  {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 999999, FLAGS},
473  {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HZ, SLOPE, FLAGS, "width_type"},
474  {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HZ}, 0, 0, FLAGS, "width_type"},
475  {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
476  {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
477  {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
478  {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 999, FLAGS},
479  {"w", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 999, FLAGS},
480  {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
481  {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
482  {NULL},
483 };
484 
485 DEFINE_BIQUAD_FILTER(equalizer, "Apply two-pole peaking equalization (EQ) filter.");
486 #endif /* CONFIG_EQUALIZER_FILTER */
487 #if CONFIG_BASS_FILTER
488 static const AVOption bass_options[] = {
489  {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
490  {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
491  {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HZ, SLOPE, FLAGS, "width_type"},
492  {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HZ}, 0, 0, FLAGS, "width_type"},
493  {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
494  {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
495  {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
496  {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
497  {"w", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
498  {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
499  {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
500  {NULL},
501 };
502 
503 DEFINE_BIQUAD_FILTER(bass, "Boost or cut lower frequencies.");
504 #endif /* CONFIG_BASS_FILTER */
505 #if CONFIG_TREBLE_FILTER
506 static const AVOption treble_options[] = {
507  {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
508  {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
509  {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HZ, SLOPE, FLAGS, "width_type"},
510  {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HZ}, 0, 0, FLAGS, "width_type"},
511  {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
512  {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
513  {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
514  {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
515  {"w", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
516  {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
517  {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
518  {NULL},
519 };
520 
521 DEFINE_BIQUAD_FILTER(treble, "Boost or cut upper frequencies.");
522 #endif /* CONFIG_TREBLE_FILTER */
523 #if CONFIG_BANDPASS_FILTER
524 static const AVOption bandpass_options[] = {
525  {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
526  {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
527  {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HZ, SLOPE, FLAGS, "width_type"},
528  {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HZ}, 0, 0, FLAGS, "width_type"},
529  {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
530  {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
531  {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
532  {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 999, FLAGS},
533  {"w", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 999, FLAGS},
534  {"csg", "use constant skirt gain", OFFSET(csg), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS},
535  {NULL},
536 };
537 
538 DEFINE_BIQUAD_FILTER(bandpass, "Apply a two-pole Butterworth band-pass filter.");
539 #endif /* CONFIG_BANDPASS_FILTER */
540 #if CONFIG_BANDREJECT_FILTER
541 static const AVOption bandreject_options[] = {
542  {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
543  {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
544  {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HZ, SLOPE, FLAGS, "width_type"},
545  {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HZ}, 0, 0, FLAGS, "width_type"},
546  {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
547  {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
548  {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
549  {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 999, FLAGS},
550  {"w", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 999, FLAGS},
551  {NULL},
552 };
553 
554 DEFINE_BIQUAD_FILTER(bandreject, "Apply a two-pole Butterworth band-reject filter.");
555 #endif /* CONFIG_BANDREJECT_FILTER */
556 #if CONFIG_LOWPASS_FILTER
557 static const AVOption lowpass_options[] = {
558  {"frequency", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=500}, 0, 999999, FLAGS},
559  {"f", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=500}, 0, 999999, FLAGS},
560  {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HZ, SLOPE, FLAGS, "width_type"},
561  {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HZ}, 0, 0, FLAGS, "width_type"},
562  {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
563  {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
564  {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
565  {"width", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
566  {"w", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
567  {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
568  {"p", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
569  {NULL},
570 };
571 
572 DEFINE_BIQUAD_FILTER(lowpass, "Apply a low-pass filter with 3dB point frequency.");
573 #endif /* CONFIG_LOWPASS_FILTER */
574 #if CONFIG_HIGHPASS_FILTER
575 static const AVOption highpass_options[] = {
576  {"frequency", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
577  {"f", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
578  {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HZ, SLOPE, FLAGS, "width_type"},
579  {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HZ}, 0, 0, FLAGS, "width_type"},
580  {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
581  {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
582  {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
583  {"width", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
584  {"w", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
585  {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
586  {"p", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
587  {NULL},
588 };
589 
590 DEFINE_BIQUAD_FILTER(highpass, "Apply a high-pass filter with 3dB point frequency.");
591 #endif /* CONFIG_HIGHPASS_FILTER */
592 #if CONFIG_ALLPASS_FILTER
593 static const AVOption allpass_options[] = {
594  {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
595  {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
596  {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=HZ}, HZ, SLOPE, FLAGS, "width_type"},
597  {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HZ}, 0, 0, FLAGS, "width_type"},
598  {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
599  {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
600  {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
601  {"width", "set filter-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=707.1}, 0, 99999, FLAGS},
602  {"w", "set filter-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=707.1}, 0, 99999, FLAGS},
603  {NULL},
604 };
605 
606 DEFINE_BIQUAD_FILTER(allpass, "Apply a two-pole all-pass filter.");
607 #endif /* CONFIG_ALLPASS_FILTER */
608 #if CONFIG_BIQUAD_FILTER
609 static const AVOption biquad_options[] = {
610  {"a0", NULL, OFFSET(a0), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT16_MIN, INT16_MAX, FLAGS},
611  {"a1", NULL, OFFSET(a1), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT16_MIN, INT16_MAX, FLAGS},
612  {"a2", NULL, OFFSET(a2), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT16_MIN, INT16_MAX, FLAGS},
613  {"b0", NULL, OFFSET(b0), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT16_MIN, INT16_MAX, FLAGS},
614  {"b1", NULL, OFFSET(b1), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT16_MIN, INT16_MAX, FLAGS},
615  {"b2", NULL, OFFSET(b2), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT16_MIN, INT16_MAX, FLAGS},
616  {NULL},
617 };
618 
619 DEFINE_BIQUAD_FILTER(biquad, "Apply a biquad IIR filter with the given coefficients.");
620 #endif /* CONFIG_BIQUAD_FILTER */
struct ChanCache ChanCache
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:424
This structure describes decoded (raw) audio or video data.
Definition: frame.h:76
AVOption.
Definition: opt.h:251
ChanCache * cache
Definition: af_biquads.c:112
FilterType
Definition: af_biquads.c:71
void * av_realloc_f(void *ptr, size_t nelem, size_t elsize)
Allocate or reallocate a block of memory.
Definition: mem.c:168
#define BIQUAD_FILTER(name, type, min, max)
Definition: af_biquads.c:164
external API header
double i2
Definition: af_biquads.c:93
#define a0
Definition: regdef.h:46
#define a1
Definition: regdef.h:47
static const AVFilterPad inputs[]
Definition: af_biquads.c:426
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:198
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:308
const char * name
Pad name.
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:532
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
#define OFFSET(x)
Definition: af_biquads.c:444
it can be given away to ff_start_frame *A reference passed to ff_filter_frame(or the deprecated ff_start_frame) is given away and must no longer be used.*A reference created with avfilter_ref_buffer belongs to the code that created it.*A reference obtained with ff_get_video_buffer or ff_get_audio_buffer belongs to the code that requested it.*A reference given as return value by the get_video_buffer or get_audio_buffer method is given away and must no longer be used.Link reference fields---------------------The AVFilterLink structure has a few AVFilterBufferRef fields.The cur_buf and out_buf were used with the deprecated start_frame/draw_slice/end_frame API and should no longer be used.src_buf
#define av_cold
Definition: attributes.h:78
AVOptions.
the mask is usually to keep the same permissions Filters should remove permissions on reference they give to output whenever necessary It can be automatically done by setting the rej_perms field on the output pad Here are a few guidelines corresponding to common 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
integer sqrt
Definition: avutil.txt:2
void 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:545
signed 32 bits, planar
Definition: samplefmt.h:59
static void biquad_flt(const void *input, void *output, int len, double *in1, double *in2, double *out1, double *out2, double b0, double b1, double b2, double a1, double a2)
Definition: af_biquads.c:230
#define A(x)
float, planar
Definition: samplefmt.h:60
static const AVFilterPad outputs[]
Definition: af_biquads.c:435
A filter pad used for either input or output.
void(* filter)(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)
Definition: af_biquads.c:114
static av_cold int init(AVFilterContext *ctx)
Definition: af_biquads.c:119
static double alpha(void *priv, double x, double y)
Definition: vf_geq.c:86
#define FLAGS
Definition: af_biquads.c:445
AVFrame * ff_get_audio_buffer(AVFilterLink *link, int nb_samples)
Request an audio samples buffer with a specific set of permissions.
Definition: audio.c:84
void * priv
private data for use by the filter
Definition: avfilter.h:545
int av_frame_is_writable(AVFrame *frame)
Check if the frame data is writable.
Definition: frame.c:361
simple assert() macros that are a bit more flexible than ISO C assert().
void av_log(void *avcl, int level, const char *fmt,...)
Send the specified message to the log if the level is less than or equal to the current av_log_level...
Definition: log.c:246
static void biquad_dbl(const void *input, void *output, int len, double *in1, double *in2, double *out1, double *out2, double b0, double b1, double b2, double a1, double a2)
Definition: af_biquads.c:231
double o1
Definition: af_biquads.c:94
#define a2
Definition: regdef.h:48
AVFilterChannelLayouts * ff_all_channel_layouts(void)
Construct an empty AVFilterChannelLayouts/AVFilterFormats struct – representing any channel layout (...
Definition: formats.c:402
A list of supported channel layouts.
Definition: formats.h:85
1i.*Xphase exp()
NULL
Definition: eval.c:55
enum WidthType width_type
Definition: af_biquads.c:101
static int width
Definition: tests/utils.c:158
typedef void(RENAME(mix_any_func_type))
static int config_output(AVFilterLink *outlink)
Definition: af_biquads.c:233
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
void * buf
Definition: avisynth_c.h:594
Definition: af_biquads.c:86
Describe the class of an AVClass context structure.
Definition: log.h:50
#define DEFINE_BIQUAD_FILTER(name_, description_)
Definition: af_biquads.c:447
int av_frame_get_channels(const AVFrame *s)
Definition: frame.c:38
static void biquad_s32(const void *input, void *output, int len, double *in1, double *in2, double *out1, double *out2, double b0, double b1, double b2, double a1, double a2)
Definition: af_biquads.c:229
static int query_formats(AVFilterContext *ctx)
Definition: af_biquads.c:134
double o2
Definition: af_biquads.c:94
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer 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.Buffer references ownership and permissions
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:539
enum MovChannelLayoutTag * layouts
Definition: mov_chan.c:434
AVFilterFormats * ff_all_samplerates(void)
Definition: formats.c:396
static av_cold void uninit(AVFilterContext *ctx)
Definition: af_biquads.c:419
void ff_set_common_samplerates(AVFilterContext *ctx, AVFilterFormats *samplerates)
Definition: formats.c:533
The official guide to swscale for confused that consecutive non overlapping rectangles of slice_bottom special converter These generally are unscaled converters of common formats
Definition: swscale.txt:33
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:108
AVSampleFormat
Audio Sample Formats.
Definition: samplefmt.h:49
WidthType
Definition: af_biquads.c:84
static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
Definition: af_biquads.c:389
int len
double i1
Definition: af_biquads.c:93
A list of supported formats for one end of a filter link.
Definition: formats.h:64
An instance of a filter.
Definition: avfilter.h:524
signed 16 bits, planar
Definition: samplefmt.h:58
static enum AVSampleFormat sample_fmts[]
Definition: adpcmenc.c:700
double frequency
Definition: af_biquads.c:106
#define M_PI
Definition: mathematics.h:46
static void biquad_s16(const void *input, void *output, int len, double *in1, double *in2, double *out1, double *out2, double b0, double b1, double b2, double a1, double a2)
Definition: af_biquads.c:228
void ff_set_common_channel_layouts(AVFilterContext *ctx, AVFilterChannelLayouts *layouts)
A helper for query_formats() which sets all links to the same list of channel layouts/sample rates...
Definition: formats.c:526
internal API functions
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: frame.h:117
enum FilterType filter_type
Definition: af_biquads.c:100
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:127
double, planar
Definition: samplefmt.h:61