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"
93 typedef struct ChanCache {
98 typedef struct BiquadsContext {
101 enum FilterType filter_type;
118 void (*filter)(struct BiquadsContext *s, const void *ibuf, void *obuf, int len,
119 double *i1, double *i2, double *o1, double *o2,
120 double b0, double b1, double b2, double a1, double a2);
123 static av_cold int init(AVFilterContext *ctx)
125 BiquadsContext *s = ctx->priv;
127 if (s->filter_type != biquad) {
128 if (s->frequency <= 0 || s->width <= 0) {
129 av_log(ctx, AV_LOG_ERROR, "Invalid frequency %f and/or width %f <= 0\n",
130 s->frequency, s->width);
131 return AVERROR(EINVAL);
138 static int query_formats(AVFilterContext *ctx)
140 AVFilterFormats *formats;
141 AVFilterChannelLayouts *layouts;
142 static const enum AVSampleFormat sample_fmts[] = {
151 layouts = ff_all_channel_counts();
153 return AVERROR(ENOMEM);
154 ret = ff_set_common_channel_layouts(ctx, layouts);
158 formats = ff_make_format_list(sample_fmts);
160 return AVERROR(ENOMEM);
161 ret = ff_set_common_formats(ctx, formats);
165 formats = ff_all_samplerates();
167 return AVERROR(ENOMEM);
168 return ff_set_common_samplerates(ctx, formats);
171 #define BIQUAD_FILTER(name, type, min, max, need_clipping) \
172 static void biquad_## name (BiquadsContext *s, \
173 const void *input, void *output, int len, \
174 double *in1, double *in2, \
175 double *out1, double *out2, \
176 double b0, double b1, double b2, \
177 double a1, double a2) \
179 const type *ibuf = input; \
180 type *obuf = output; \
189 for (i = 0; i+1 < len; i++) { \
190 o2 = i2 * b2 + i1 * b1 + ibuf[i] * b0 + o2 * a2 + o1 * a1; \
192 if (need_clipping && o2 < min) { \
195 } else if (need_clipping && o2 > max) { \
202 o1 = i1 * b2 + i2 * b1 + ibuf[i] * b0 + o1 * a2 + o2 * a1; \
204 if (need_clipping && o1 < min) { \
207 } else if (need_clipping && o1 > max) { \
215 double o0 = ibuf[i] * b0 + i1 * b1 + i2 * b2 + o1 * a1 + o2 * a2; \
220 if (need_clipping && o0 < min) { \
223 } else if (need_clipping && o0 > max) { \
236 BIQUAD_FILTER(s16, int16_t, INT16_MIN, INT16_MAX, 1)
237 BIQUAD_FILTER(s32, int32_t, INT32_MIN, INT32_MAX, 1)
238 BIQUAD_FILTER(flt, float, -1., 1., 0)
239 BIQUAD_FILTER(dbl, double, -1., 1., 0)
241 static int config_filter(AVFilterLink *outlink, int reset)
243 AVFilterContext *ctx = outlink->src;
244 BiquadsContext *s = ctx->priv;
245 AVFilterLink *inlink = ctx->inputs[0];
246 double A = exp(s->gain / 40 * log(10.));
247 double w0 = 2 * M_PI * s->frequency / inlink->sample_rate;
251 av_log(ctx, AV_LOG_ERROR,
252 "Invalid frequency %f. Frequency must be less than half the sample-rate %d.\n",
253 s->frequency, inlink->sample_rate);
254 return AVERROR(EINVAL);
257 switch (s->width_type) {
262 alpha = sin(w0) / (2 * s->frequency / s->width);
265 alpha = sin(w0) / (2 * s->frequency / (s->width * 1000));
268 alpha = sin(w0) * sinh(log(2.) / 2 * s->width * w0 / sin(w0));
271 alpha = sin(w0) / (2 * s->width);
274 alpha = sin(w0) / 2 * sqrt((A + 1 / A) * (1 / s->width - 1) + 2);
280 switch (s->filter_type) {
284 s->a0 = 1 + alpha / A;
285 s->a1 = -2 * cos(w0);
286 s->a2 = 1 - alpha / A;
287 s->b0 = 1 + alpha * A;
288 s->b1 = -2 * cos(w0);
289 s->b2 = 1 - alpha * A;
292 s->a0 = (A + 1) + (A - 1) * cos(w0) + 2 * sqrt(A) * alpha;
293 s->a1 = -2 * ((A - 1) + (A + 1) * cos(w0));
294 s->a2 = (A + 1) + (A - 1) * cos(w0) - 2 * sqrt(A) * alpha;
295 s->b0 = A * ((A + 1) - (A - 1) * cos(w0) + 2 * sqrt(A) * alpha);
296 s->b1 = 2 * A * ((A - 1) - (A + 1) * cos(w0));
297 s->b2 = A * ((A + 1) - (A - 1) * cos(w0) - 2 * sqrt(A) * alpha);
300 s->a0 = (A + 1) - (A - 1) * cos(w0) + 2 * sqrt(A) * alpha;
301 s->a1 = 2 * ((A - 1) - (A + 1) * cos(w0));
302 s->a2 = (A + 1) - (A - 1) * cos(w0) - 2 * sqrt(A) * alpha;
303 s->b0 = A * ((A + 1) + (A - 1) * cos(w0) + 2 * sqrt(A) * alpha);
304 s->b1 =-2 * A * ((A - 1) + (A + 1) * cos(w0));
305 s->b2 = A * ((A + 1) + (A - 1) * cos(w0) - 2 * sqrt(A) * alpha);
310 s->a1 = -2 * cos(w0);
314 s->b2 = -sin(w0) / 2;
317 s->a1 = -2 * cos(w0);
326 s->a1 = -2 * cos(w0);
329 s->b1 = -2 * cos(w0);
342 s->a1 = -2 * cos(w0);
344 s->b0 = (1 - cos(w0)) / 2;
346 s->b2 = (1 - cos(w0)) / 2;
354 s->b0 = (1 - s->a1) / 2;
359 s->a1 = -2 * cos(w0);
361 s->b0 = (1 + cos(w0)) / 2;
362 s->b1 = -(1 + cos(w0));
363 s->b2 = (1 + cos(w0)) / 2;
368 s->a1 = -2 * cos(w0);
371 s->b1 = -2 * cos(w0);
384 s->cache = av_realloc_f(s->cache, sizeof(ChanCache), inlink->channels);
386 return AVERROR(ENOMEM);
388 memset(s->cache, 0, sizeof(ChanCache) * inlink->channels);
390 switch (inlink->format) {
391 case AV_SAMPLE_FMT_S16P: s->filter = biquad_s16; break;
392 case AV_SAMPLE_FMT_S32P: s->filter = biquad_s32; break;
393 case AV_SAMPLE_FMT_FLTP: s->filter = biquad_flt; break;
394 case AV_SAMPLE_FMT_DBLP: s->filter = biquad_dbl; break;
395 default: av_assert0(0);
398 s->block_align = av_get_bytes_per_sample(inlink->format);
403 static int config_output(AVFilterLink *outlink)
405 return config_filter(outlink, 1);
408 static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
410 AVFilterContext *ctx = inlink->dst;
411 BiquadsContext *s = ctx->priv;
412 AVFilterLink *outlink = ctx->outputs[0];
414 int nb_samples = buf->nb_samples;
417 if (av_frame_is_writable(buf)) {
420 out_buf = ff_get_audio_buffer(inlink, nb_samples);
423 return AVERROR(ENOMEM);
425 av_frame_copy_props(out_buf, buf);
428 for (ch = 0; ch < buf->channels; ch++) {
429 if (!((av_channel_layout_extract_channel(inlink->channel_layout, ch) & s->channels))) {
431 memcpy(out_buf->extended_data[ch], buf->extended_data[ch], nb_samples * s->block_align);
434 s->filter(s, buf->extended_data[ch],
435 out_buf->extended_data[ch], nb_samples,
436 &s->cache[ch].i1, &s->cache[ch].i2,
437 &s->cache[ch].o1, &s->cache[ch].o2,
438 s->b0, s->b1, s->b2, s->a1, s->a2);
441 if (s->clippings > 0)
442 av_log(ctx, AV_LOG_WARNING, "clipping %d times. Please reduce gain.\n", s->clippings);
448 return ff_filter_frame(outlink, out_buf);
451 static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
452 char *res, int res_len, int flags)
454 BiquadsContext *s = ctx->priv;
455 AVFilterLink *outlink = ctx->outputs[0];
457 if ((!strcmp(cmd, "frequency") || !strcmp(cmd, "f")) &&
458 (s->filter_type == equalizer ||
459 s->filter_type == bass ||
460 s->filter_type == treble ||
461 s->filter_type == bandpass ||
462 s->filter_type == bandreject||
463 s->filter_type == lowpass ||
464 s->filter_type == highpass ||
465 s->filter_type == allpass)) {
468 if (sscanf(args, "%lf", &freq) != 1) {
469 av_log(ctx, AV_LOG_ERROR, "Invalid frequency value.\n");
470 return AVERROR(EINVAL);
474 } else if ((!strcmp(cmd, "gain") || !strcmp(cmd, "g")) &&
475 (s->filter_type == equalizer ||
476 s->filter_type == bass ||
477 s->filter_type == treble)) {
480 if (sscanf(args, "%lf", &gain) != 1) {
481 av_log(ctx, AV_LOG_ERROR, "Invalid gain value.\n");
482 return AVERROR(EINVAL);
486 } else if ((!strcmp(cmd, "width") || !strcmp(cmd, "w")) &&
487 (s->filter_type == equalizer ||
488 s->filter_type == bass ||
489 s->filter_type == treble ||
490 s->filter_type == bandpass ||
491 s->filter_type == bandreject||
492 s->filter_type == lowpass ||
493 s->filter_type == highpass ||
494 s->filter_type == allpass)) {
497 if (sscanf(args, "%lf", &width) != 1) {
498 av_log(ctx, AV_LOG_ERROR, "Invalid width value.\n");
499 return AVERROR(EINVAL);
503 } else if ((!strcmp(cmd, "width_type") || !strcmp(cmd, "t")) &&
504 (s->filter_type == equalizer ||
505 s->filter_type == bass ||
506 s->filter_type == treble ||
507 s->filter_type == bandpass ||
508 s->filter_type == bandreject||
509 s->filter_type == lowpass ||
510 s->filter_type == highpass ||
511 s->filter_type == allpass)) {
514 if (sscanf(args, "%c", &width_type) != 1) {
515 av_log(ctx, AV_LOG_ERROR, "Invalid width_type value.\n");
516 return AVERROR(EINVAL);
519 switch (width_type) {
520 case 'h': width_type = HERTZ; break;
521 case 'q': width_type = QFACTOR; break;
522 case 'o': width_type = OCTAVE; break;
523 case 's': width_type = SLOPE; break;
524 case 'k': width_type = KHERTZ; break;
526 av_log(ctx, AV_LOG_ERROR, "Invalid width_type value: %c\n", width_type);
527 return AVERROR(EINVAL);
530 s->width_type = width_type;
531 } else if ((!strcmp(cmd, "a0") ||
532 !strcmp(cmd, "a1") ||
533 !strcmp(cmd, "a2") ||
534 !strcmp(cmd, "b0") ||
535 !strcmp(cmd, "b1") ||
536 !strcmp(cmd, "b2")) &&
537 s->filter_type == biquad) {
540 if (sscanf(args, "%lf", &value) != 1) {
541 av_log(ctx, AV_LOG_ERROR, "Invalid biquad value.\n");
542 return AVERROR(EINVAL);
545 if (!strcmp(cmd, "a0"))
547 else if (!strcmp(cmd, "a1"))
549 else if (!strcmp(cmd, "a2"))
551 else if (!strcmp(cmd, "b0"))
553 else if (!strcmp(cmd, "b1"))
555 else if (!strcmp(cmd, "b2"))
559 return config_filter(outlink, 0);
562 static av_cold void uninit(AVFilterContext *ctx)
564 BiquadsContext *s = ctx->priv;
569 static const AVFilterPad inputs[] = {
572 .type = AVMEDIA_TYPE_AUDIO,
573 .filter_frame = filter_frame,
578 static const AVFilterPad outputs[] = {
581 .type = AVMEDIA_TYPE_AUDIO,
582 .config_props = config_output,
587 #define OFFSET(x) offsetof(BiquadsContext, x)
588 #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
590 #define DEFINE_BIQUAD_FILTER(name_, description_) \
591 AVFILTER_DEFINE_CLASS(name_); \
592 static av_cold int name_##_init(AVFilterContext *ctx) \
594 BiquadsContext *s = ctx->priv; \
595 s->class = &name_##_class; \
596 s->filter_type = name_; \
600 AVFilter ff_af_##name_ = { \
602 .description = NULL_IF_CONFIG_SMALL(description_), \
603 .priv_size = sizeof(BiquadsContext), \
604 .init = name_##_init, \
606 .query_formats = query_formats, \
608 .outputs = outputs, \
609 .priv_class = &name_##_class, \
610 .process_command = process_command, \
613 #if CONFIG_EQUALIZER_FILTER
614 static const AVOption equalizer_options[] = {
615 {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 999999, FLAGS},
616 {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 999999, FLAGS},
617 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
618 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
619 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
620 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
621 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
622 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
623 {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
624 {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 99999, FLAGS},
625 {"w", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 99999, FLAGS},
626 {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
627 {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
628 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
629 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
633 DEFINE_BIQUAD_FILTER(equalizer, "Apply two-pole peaking equalization (EQ) filter.");
634 #endif /* CONFIG_EQUALIZER_FILTER */
635 #if CONFIG_BASS_FILTER
636 static const AVOption bass_options[] = {
637 {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
638 {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
639 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
640 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
641 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
642 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
643 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
644 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
645 {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
646 {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
647 {"w", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
648 {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
649 {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
650 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
651 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
655 DEFINE_BIQUAD_FILTER(bass, "Boost or cut lower frequencies.");
656 #endif /* CONFIG_BASS_FILTER */
657 #if CONFIG_TREBLE_FILTER
658 static const AVOption treble_options[] = {
659 {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
660 {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
661 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
662 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
663 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
664 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
665 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
666 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
667 {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
668 {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
669 {"w", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
670 {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
671 {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
672 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
673 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
677 DEFINE_BIQUAD_FILTER(treble, "Boost or cut upper frequencies.");
678 #endif /* CONFIG_TREBLE_FILTER */
679 #if CONFIG_BANDPASS_FILTER
680 static const AVOption bandpass_options[] = {
681 {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
682 {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
683 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
684 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
685 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
686 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
687 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
688 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
689 {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
690 {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
691 {"w", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
692 {"csg", "use constant skirt gain", OFFSET(csg), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
693 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
694 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
698 DEFINE_BIQUAD_FILTER(bandpass, "Apply a two-pole Butterworth band-pass filter.");
699 #endif /* CONFIG_BANDPASS_FILTER */
700 #if CONFIG_BANDREJECT_FILTER
701 static const AVOption bandreject_options[] = {
702 {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
703 {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
704 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
705 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
706 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
707 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
708 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
709 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
710 {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
711 {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
712 {"w", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
713 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
714 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
718 DEFINE_BIQUAD_FILTER(bandreject, "Apply a two-pole Butterworth band-reject filter.");
719 #endif /* CONFIG_BANDREJECT_FILTER */
720 #if CONFIG_LOWPASS_FILTER
721 static const AVOption lowpass_options[] = {
722 {"frequency", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=500}, 0, 999999, FLAGS},
723 {"f", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=500}, 0, 999999, FLAGS},
724 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
725 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
726 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
727 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
728 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
729 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
730 {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
731 {"width", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
732 {"w", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
733 {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
734 {"p", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
735 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
736 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
740 DEFINE_BIQUAD_FILTER(lowpass, "Apply a low-pass filter with 3dB point frequency.");
741 #endif /* CONFIG_LOWPASS_FILTER */
742 #if CONFIG_HIGHPASS_FILTER
743 static const AVOption highpass_options[] = {
744 {"frequency", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
745 {"f", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
746 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
747 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
748 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
749 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
750 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
751 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
752 {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
753 {"width", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
754 {"w", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
755 {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
756 {"p", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
757 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
758 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
762 DEFINE_BIQUAD_FILTER(highpass, "Apply a high-pass filter with 3dB point frequency.");
763 #endif /* CONFIG_HIGHPASS_FILTER */
764 #if CONFIG_ALLPASS_FILTER
765 static const AVOption allpass_options[] = {
766 {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
767 {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
768 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=HERTZ}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
769 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=HERTZ}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
770 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
771 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
772 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
773 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
774 {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
775 {"width", "set filter-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=707.1}, 0, 99999, FLAGS},
776 {"w", "set filter-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=707.1}, 0, 99999, FLAGS},
777 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
778 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
782 DEFINE_BIQUAD_FILTER(allpass, "Apply a two-pole all-pass filter.");
783 #endif /* CONFIG_ALLPASS_FILTER */
784 #if CONFIG_BIQUAD_FILTER
785 static const AVOption biquad_options[] = {
786 {"a0", NULL, OFFSET(a0), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT32_MIN, INT32_MAX, FLAGS},
787 {"a1", NULL, OFFSET(a1), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
788 {"a2", NULL, OFFSET(a2), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
789 {"b0", NULL, OFFSET(b0), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
790 {"b1", NULL, OFFSET(b1), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
791 {"b2", NULL, OFFSET(b2), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
792 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
793 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
797 DEFINE_BIQUAD_FILTER(biquad, "Apply a biquad IIR filter with the given coefficients.");
798 #endif /* CONFIG_BIQUAD_FILTER */