2 * Copyright (c) 2013 Paul B Mahol
3 * Copyright (c) 2006-2008 Rob Sykes <robs@users.sourceforge.net>
5 * This file is part of FFmpeg.
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.
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.
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
23 * 2-pole filters designed by Robert Bristow-Johnson <rbj@audioimagination.com>
24 * see http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt
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
30 * low-pass: output[N] = input[N] * A + output[N-1] * B
31 * X = exp(-2.0 * pi * Fc)
34 * Fc = cutoff freq / sample rate
36 * Mimics an RC low-pass filter:
38 * ---/\/\/\/\----------->
46 * high-pass: output[N] = A0 * input[N] + A1 * input[N-1] + B1 * output[N-1]
47 * X = exp(-2.0 * pi * Fc)
51 * Fc = cutoff freq / sample rate
53 * Mimics an RC high-pass filter:
65 #include "libavutil/avassert.h"
66 #include "libavutil/opt.h"
91 typedef struct ChanCache {
96 typedef struct BiquadsContext {
99 enum FilterType filter_type;
116 void (*filter)(struct BiquadsContext *s, const void *ibuf, void *obuf, int len,
117 double *i1, double *i2, double *o1, double *o2,
118 double b0, double b1, double b2, double a1, double a2);
121 static av_cold int init(AVFilterContext *ctx)
123 BiquadsContext *s = ctx->priv;
125 if (s->filter_type != biquad) {
126 if (s->frequency <= 0 || s->width <= 0) {
127 av_log(ctx, AV_LOG_ERROR, "Invalid frequency %f and/or width %f <= 0\n",
128 s->frequency, s->width);
129 return AVERROR(EINVAL);
136 static int query_formats(AVFilterContext *ctx)
138 AVFilterFormats *formats;
139 AVFilterChannelLayouts *layouts;
140 static const enum AVSampleFormat sample_fmts[] = {
149 layouts = ff_all_channel_counts();
151 return AVERROR(ENOMEM);
152 ret = ff_set_common_channel_layouts(ctx, layouts);
156 formats = ff_make_format_list(sample_fmts);
158 return AVERROR(ENOMEM);
159 ret = ff_set_common_formats(ctx, formats);
163 formats = ff_all_samplerates();
165 return AVERROR(ENOMEM);
166 return ff_set_common_samplerates(ctx, formats);
169 #define BIQUAD_FILTER(name, type, min, max, need_clipping) \
170 static void biquad_## name (BiquadsContext *s, \
171 const void *input, void *output, int len, \
172 double *in1, double *in2, \
173 double *out1, double *out2, \
174 double b0, double b1, double b2, \
175 double a1, double a2) \
177 const type *ibuf = input; \
178 type *obuf = output; \
187 for (i = 0; i+1 < len; i++) { \
188 o2 = i2 * b2 + i1 * b1 + ibuf[i] * b0 + o2 * a2 + o1 * a1; \
190 if (need_clipping && o2 < min) { \
193 } else if (need_clipping && o2 > max) { \
200 o1 = i1 * b2 + i2 * b1 + ibuf[i] * b0 + o1 * a2 + o2 * a1; \
202 if (need_clipping && o1 < min) { \
205 } else if (need_clipping && o1 > max) { \
213 double o0 = ibuf[i] * b0 + i1 * b1 + i2 * b2 + o1 * a1 + o2 * a2; \
218 if (need_clipping && o0 < min) { \
221 } else if (need_clipping && o0 > max) { \
234 BIQUAD_FILTER(s16, int16_t, INT16_MIN, INT16_MAX, 1)
235 BIQUAD_FILTER(s32, int32_t, INT32_MIN, INT32_MAX, 1)
236 BIQUAD_FILTER(flt, float, -1., 1., 0)
237 BIQUAD_FILTER(dbl, double, -1., 1., 0)
239 static int config_filter(AVFilterLink *outlink, int reset)
241 AVFilterContext *ctx = outlink->src;
242 BiquadsContext *s = ctx->priv;
243 AVFilterLink *inlink = ctx->inputs[0];
244 double A = exp(s->gain / 40 * log(10.));
245 double w0 = 2 * M_PI * s->frequency / inlink->sample_rate;
249 av_log(ctx, AV_LOG_ERROR,
250 "Invalid frequency %f. Frequency must be less than half the sample-rate %d.\n",
251 s->frequency, inlink->sample_rate);
252 return AVERROR(EINVAL);
255 switch (s->width_type) {
260 alpha = sin(w0) / (2 * s->frequency / s->width);
263 alpha = sin(w0) * sinh(log(2.) / 2 * s->width * w0 / sin(w0));
266 alpha = sin(w0) / (2 * s->width);
269 alpha = sin(w0) / 2 * sqrt((A + 1 / A) * (1 / s->width - 1) + 2);
275 switch (s->filter_type) {
279 s->a0 = 1 + alpha / A;
280 s->a1 = -2 * cos(w0);
281 s->a2 = 1 - alpha / A;
282 s->b0 = 1 + alpha * A;
283 s->b1 = -2 * cos(w0);
284 s->b2 = 1 - alpha * A;
287 s->a0 = (A + 1) + (A - 1) * cos(w0) + 2 * sqrt(A) * alpha;
288 s->a1 = -2 * ((A - 1) + (A + 1) * cos(w0));
289 s->a2 = (A + 1) + (A - 1) * cos(w0) - 2 * sqrt(A) * alpha;
290 s->b0 = A * ((A + 1) - (A - 1) * cos(w0) + 2 * sqrt(A) * alpha);
291 s->b1 = 2 * A * ((A - 1) - (A + 1) * cos(w0));
292 s->b2 = A * ((A + 1) - (A - 1) * cos(w0) - 2 * sqrt(A) * alpha);
295 s->a0 = (A + 1) - (A - 1) * cos(w0) + 2 * sqrt(A) * alpha;
296 s->a1 = 2 * ((A - 1) - (A + 1) * cos(w0));
297 s->a2 = (A + 1) - (A - 1) * cos(w0) - 2 * sqrt(A) * alpha;
298 s->b0 = A * ((A + 1) + (A - 1) * cos(w0) + 2 * sqrt(A) * alpha);
299 s->b1 =-2 * A * ((A - 1) + (A + 1) * cos(w0));
300 s->b2 = A * ((A + 1) + (A - 1) * cos(w0) - 2 * sqrt(A) * alpha);
305 s->a1 = -2 * cos(w0);
309 s->b2 = -sin(w0) / 2;
312 s->a1 = -2 * cos(w0);
321 s->a1 = -2 * cos(w0);
324 s->b1 = -2 * cos(w0);
337 s->a1 = -2 * cos(w0);
339 s->b0 = (1 - cos(w0)) / 2;
341 s->b2 = (1 - cos(w0)) / 2;
349 s->b0 = (1 - s->a1) / 2;
354 s->a1 = -2 * cos(w0);
356 s->b0 = (1 + cos(w0)) / 2;
357 s->b1 = -(1 + cos(w0));
358 s->b2 = (1 + cos(w0)) / 2;
363 s->a1 = -2 * cos(w0);
366 s->b1 = -2 * cos(w0);
379 s->cache = av_realloc_f(s->cache, sizeof(ChanCache), inlink->channels);
381 return AVERROR(ENOMEM);
383 memset(s->cache, 0, sizeof(ChanCache) * inlink->channels);
385 switch (inlink->format) {
386 case AV_SAMPLE_FMT_S16P: s->filter = biquad_s16; break;
387 case AV_SAMPLE_FMT_S32P: s->filter = biquad_s32; break;
388 case AV_SAMPLE_FMT_FLTP: s->filter = biquad_flt; break;
389 case AV_SAMPLE_FMT_DBLP: s->filter = biquad_dbl; break;
390 default: av_assert0(0);
393 s->block_align = av_get_bytes_per_sample(inlink->format);
398 static int config_output(AVFilterLink *outlink)
400 return config_filter(outlink, 1);
403 static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
405 AVFilterContext *ctx = inlink->dst;
406 BiquadsContext *s = ctx->priv;
407 AVFilterLink *outlink = ctx->outputs[0];
409 int nb_samples = buf->nb_samples;
412 if (av_frame_is_writable(buf)) {
415 out_buf = ff_get_audio_buffer(inlink, nb_samples);
418 return AVERROR(ENOMEM);
420 av_frame_copy_props(out_buf, buf);
423 for (ch = 0; ch < buf->channels; ch++) {
424 if (!((av_channel_layout_extract_channel(inlink->channel_layout, ch) & s->channels))) {
426 memcpy(out_buf->extended_data[ch], buf->extended_data[ch], nb_samples * s->block_align);
429 s->filter(s, buf->extended_data[ch],
430 out_buf->extended_data[ch], nb_samples,
431 &s->cache[ch].i1, &s->cache[ch].i2,
432 &s->cache[ch].o1, &s->cache[ch].o2,
433 s->b0, s->b1, s->b2, s->a1, s->a2);
436 if (s->clippings > 0)
437 av_log(ctx, AV_LOG_WARNING, "clipping %d times. Please reduce gain.\n", s->clippings);
443 return ff_filter_frame(outlink, out_buf);
446 static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
447 char *res, int res_len, int flags)
449 BiquadsContext *s = ctx->priv;
450 AVFilterLink *outlink = ctx->outputs[0];
452 if ((!strcmp(cmd, "frequency") || !strcmp(cmd, "f")) &&
453 (s->filter_type == equalizer ||
454 s->filter_type == bass ||
455 s->filter_type == treble ||
456 s->filter_type == bandpass ||
457 s->filter_type == bandreject||
458 s->filter_type == lowpass ||
459 s->filter_type == highpass ||
460 s->filter_type == allpass)) {
463 if (sscanf(args, "%lf", &freq) != 1) {
464 av_log(ctx, AV_LOG_ERROR, "Invalid frequency value.\n");
465 return AVERROR(EINVAL);
469 } else if ((!strcmp(cmd, "gain") || !strcmp(cmd, "g")) &&
470 (s->filter_type == equalizer ||
471 s->filter_type == bass ||
472 s->filter_type == treble)) {
475 if (sscanf(args, "%lf", &gain) != 1) {
476 av_log(ctx, AV_LOG_ERROR, "Invalid gain value.\n");
477 return AVERROR(EINVAL);
481 } else if ((!strcmp(cmd, "width") || !strcmp(cmd, "w")) &&
482 (s->filter_type == equalizer ||
483 s->filter_type == bass ||
484 s->filter_type == treble ||
485 s->filter_type == bandpass ||
486 s->filter_type == bandreject||
487 s->filter_type == lowpass ||
488 s->filter_type == highpass ||
489 s->filter_type == allpass)) {
492 if (sscanf(args, "%lf", &width) != 1) {
493 av_log(ctx, AV_LOG_ERROR, "Invalid width value.\n");
494 return AVERROR(EINVAL);
498 } else if ((!strcmp(cmd, "width_type") || !strcmp(cmd, "t")) &&
499 (s->filter_type == equalizer ||
500 s->filter_type == bass ||
501 s->filter_type == treble ||
502 s->filter_type == bandpass ||
503 s->filter_type == bandreject||
504 s->filter_type == lowpass ||
505 s->filter_type == highpass ||
506 s->filter_type == allpass)) {
509 if (sscanf(args, "%c", &width_type) != 1) {
510 av_log(ctx, AV_LOG_ERROR, "Invalid width_type value.\n");
511 return AVERROR(EINVAL);
514 switch (width_type) {
515 case 'h': width_type = HERTZ; break;
516 case 'q': width_type = QFACTOR; break;
517 case 'o': width_type = OCTAVE; break;
518 case 's': width_type = SLOPE; break;
520 av_log(ctx, AV_LOG_ERROR, "Invalid width_type value: %c\n", width_type);
521 return AVERROR(EINVAL);
524 s->width_type = width_type;
525 } else if ((!strcmp(cmd, "a0") ||
526 !strcmp(cmd, "a1") ||
527 !strcmp(cmd, "a2") ||
528 !strcmp(cmd, "b0") ||
529 !strcmp(cmd, "b1") ||
530 !strcmp(cmd, "b2")) &&
531 s->filter_type == biquad) {
534 if (sscanf(args, "%lf", &value) != 1) {
535 av_log(ctx, AV_LOG_ERROR, "Invalid biquad value.\n");
536 return AVERROR(EINVAL);
539 if (!strcmp(cmd, "a0"))
541 else if (!strcmp(cmd, "a1"))
543 else if (!strcmp(cmd, "a2"))
545 else if (!strcmp(cmd, "b0"))
547 else if (!strcmp(cmd, "b1"))
549 else if (!strcmp(cmd, "b2"))
553 return config_filter(outlink, 0);
556 static av_cold void uninit(AVFilterContext *ctx)
558 BiquadsContext *s = ctx->priv;
563 static const AVFilterPad inputs[] = {
566 .type = AVMEDIA_TYPE_AUDIO,
567 .filter_frame = filter_frame,
572 static const AVFilterPad outputs[] = {
575 .type = AVMEDIA_TYPE_AUDIO,
576 .config_props = config_output,
581 #define OFFSET(x) offsetof(BiquadsContext, x)
582 #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
584 #define DEFINE_BIQUAD_FILTER(name_, description_) \
585 AVFILTER_DEFINE_CLASS(name_); \
586 static av_cold int name_##_init(AVFilterContext *ctx) \
588 BiquadsContext *s = ctx->priv; \
589 s->class = &name_##_class; \
590 s->filter_type = name_; \
594 AVFilter ff_af_##name_ = { \
596 .description = NULL_IF_CONFIG_SMALL(description_), \
597 .priv_size = sizeof(BiquadsContext), \
598 .init = name_##_init, \
600 .query_formats = query_formats, \
602 .outputs = outputs, \
603 .priv_class = &name_##_class, \
604 .process_command = process_command, \
607 #if CONFIG_EQUALIZER_FILTER
608 static const AVOption equalizer_options[] = {
609 {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 999999, FLAGS},
610 {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 999999, FLAGS},
611 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"},
612 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"},
613 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
614 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
615 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
616 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
617 {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 999, FLAGS},
618 {"w", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 999, FLAGS},
619 {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
620 {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
621 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
622 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
626 DEFINE_BIQUAD_FILTER(equalizer, "Apply two-pole peaking equalization (EQ) filter.");
627 #endif /* CONFIG_EQUALIZER_FILTER */
628 #if CONFIG_BASS_FILTER
629 static const AVOption bass_options[] = {
630 {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
631 {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
632 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"},
633 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"},
634 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
635 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
636 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
637 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
638 {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
639 {"w", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
640 {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
641 {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
642 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
643 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
647 DEFINE_BIQUAD_FILTER(bass, "Boost or cut lower frequencies.");
648 #endif /* CONFIG_BASS_FILTER */
649 #if CONFIG_TREBLE_FILTER
650 static const AVOption treble_options[] = {
651 {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
652 {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
653 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"},
654 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"},
655 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
656 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
657 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
658 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
659 {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
660 {"w", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
661 {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
662 {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
663 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
664 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
668 DEFINE_BIQUAD_FILTER(treble, "Boost or cut upper frequencies.");
669 #endif /* CONFIG_TREBLE_FILTER */
670 #if CONFIG_BANDPASS_FILTER
671 static const AVOption bandpass_options[] = {
672 {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
673 {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
674 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"},
675 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"},
676 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
677 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
678 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
679 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
680 {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 999, FLAGS},
681 {"w", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 999, FLAGS},
682 {"csg", "use constant skirt gain", OFFSET(csg), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
683 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
684 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
688 DEFINE_BIQUAD_FILTER(bandpass, "Apply a two-pole Butterworth band-pass filter.");
689 #endif /* CONFIG_BANDPASS_FILTER */
690 #if CONFIG_BANDREJECT_FILTER
691 static const AVOption bandreject_options[] = {
692 {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
693 {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
694 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"},
695 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"},
696 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
697 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
698 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
699 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
700 {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 999, FLAGS},
701 {"w", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 999, FLAGS},
702 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
703 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
707 DEFINE_BIQUAD_FILTER(bandreject, "Apply a two-pole Butterworth band-reject filter.");
708 #endif /* CONFIG_BANDREJECT_FILTER */
709 #if CONFIG_LOWPASS_FILTER
710 static const AVOption lowpass_options[] = {
711 {"frequency", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=500}, 0, 999999, FLAGS},
712 {"f", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=500}, 0, 999999, FLAGS},
713 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"},
714 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"},
715 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
716 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
717 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
718 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
719 {"width", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
720 {"w", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
721 {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
722 {"p", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
723 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
724 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
728 DEFINE_BIQUAD_FILTER(lowpass, "Apply a low-pass filter with 3dB point frequency.");
729 #endif /* CONFIG_LOWPASS_FILTER */
730 #if CONFIG_HIGHPASS_FILTER
731 static const AVOption highpass_options[] = {
732 {"frequency", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
733 {"f", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
734 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"},
735 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"},
736 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
737 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
738 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
739 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
740 {"width", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
741 {"w", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
742 {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
743 {"p", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
744 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
745 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
749 DEFINE_BIQUAD_FILTER(highpass, "Apply a high-pass filter with 3dB point frequency.");
750 #endif /* CONFIG_HIGHPASS_FILTER */
751 #if CONFIG_ALLPASS_FILTER
752 static const AVOption allpass_options[] = {
753 {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
754 {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
755 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=HERTZ}, HERTZ, SLOPE, FLAGS, "width_type"},
756 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=HERTZ}, HERTZ, SLOPE, FLAGS, "width_type"},
757 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
758 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
759 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
760 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
761 {"width", "set filter-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=707.1}, 0, 99999, FLAGS},
762 {"w", "set filter-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=707.1}, 0, 99999, FLAGS},
763 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
764 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
768 DEFINE_BIQUAD_FILTER(allpass, "Apply a two-pole all-pass filter.");
769 #endif /* CONFIG_ALLPASS_FILTER */
770 #if CONFIG_BIQUAD_FILTER
771 static const AVOption biquad_options[] = {
772 {"a0", NULL, OFFSET(a0), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT16_MIN, INT16_MAX, FLAGS},
773 {"a1", NULL, OFFSET(a1), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT16_MIN, INT16_MAX, FLAGS},
774 {"a2", NULL, OFFSET(a2), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT16_MIN, INT16_MAX, FLAGS},
775 {"b0", NULL, OFFSET(b0), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT16_MIN, INT16_MAX, FLAGS},
776 {"b1", NULL, OFFSET(b1), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT16_MIN, INT16_MAX, FLAGS},
777 {"b2", NULL, OFFSET(b2), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT16_MIN, INT16_MAX, FLAGS},
778 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
779 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
783 DEFINE_BIQUAD_FILTER(biquad, "Apply a biquad IIR filter with the given coefficients.");
784 #endif /* CONFIG_BIQUAD_FILTER */