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);
378 av_log(ctx, AV_LOG_VERBOSE, "a=%lf %lf %lf:b=%lf %lf %lf\n", s->a0, s->a1, s->a2, s->b0, s->b1, s->b2);
387 s->cache = av_realloc_f(s->cache, sizeof(ChanCache), inlink->channels);
389 return AVERROR(ENOMEM);
391 memset(s->cache, 0, sizeof(ChanCache) * inlink->channels);
393 switch (inlink->format) {
394 case AV_SAMPLE_FMT_S16P: s->filter = biquad_s16; break;
395 case AV_SAMPLE_FMT_S32P: s->filter = biquad_s32; break;
396 case AV_SAMPLE_FMT_FLTP: s->filter = biquad_flt; break;
397 case AV_SAMPLE_FMT_DBLP: s->filter = biquad_dbl; break;
398 default: av_assert0(0);
401 s->block_align = av_get_bytes_per_sample(inlink->format);
406 static int config_output(AVFilterLink *outlink)
408 return config_filter(outlink, 1);
411 static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
413 AVFilterContext *ctx = inlink->dst;
414 BiquadsContext *s = ctx->priv;
415 AVFilterLink *outlink = ctx->outputs[0];
417 int nb_samples = buf->nb_samples;
420 if (av_frame_is_writable(buf)) {
423 out_buf = ff_get_audio_buffer(outlink, nb_samples);
426 return AVERROR(ENOMEM);
428 av_frame_copy_props(out_buf, buf);
431 for (ch = 0; ch < buf->channels; ch++) {
432 if (!((av_channel_layout_extract_channel(inlink->channel_layout, ch) & s->channels))) {
434 memcpy(out_buf->extended_data[ch], buf->extended_data[ch], nb_samples * s->block_align);
437 s->filter(s, buf->extended_data[ch],
438 out_buf->extended_data[ch], nb_samples,
439 &s->cache[ch].i1, &s->cache[ch].i2,
440 &s->cache[ch].o1, &s->cache[ch].o2,
441 s->b0, s->b1, s->b2, s->a1, s->a2);
444 if (s->clippings > 0)
445 av_log(ctx, AV_LOG_WARNING, "clipping %d times. Please reduce gain.\n", s->clippings);
451 return ff_filter_frame(outlink, out_buf);
454 static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
455 char *res, int res_len, int flags)
457 BiquadsContext *s = ctx->priv;
458 AVFilterLink *outlink = ctx->outputs[0];
460 if ((!strcmp(cmd, "frequency") || !strcmp(cmd, "f")) &&
461 (s->filter_type == equalizer ||
462 s->filter_type == bass ||
463 s->filter_type == treble ||
464 s->filter_type == bandpass ||
465 s->filter_type == bandreject||
466 s->filter_type == lowpass ||
467 s->filter_type == highpass ||
468 s->filter_type == allpass)) {
471 if (sscanf(args, "%lf", &freq) != 1) {
472 av_log(ctx, AV_LOG_ERROR, "Invalid frequency value.\n");
473 return AVERROR(EINVAL);
477 } else if ((!strcmp(cmd, "gain") || !strcmp(cmd, "g")) &&
478 (s->filter_type == equalizer ||
479 s->filter_type == bass ||
480 s->filter_type == treble)) {
483 if (sscanf(args, "%lf", &gain) != 1) {
484 av_log(ctx, AV_LOG_ERROR, "Invalid gain value.\n");
485 return AVERROR(EINVAL);
489 } else if ((!strcmp(cmd, "width") || !strcmp(cmd, "w")) &&
490 (s->filter_type == equalizer ||
491 s->filter_type == bass ||
492 s->filter_type == treble ||
493 s->filter_type == bandpass ||
494 s->filter_type == bandreject||
495 s->filter_type == lowpass ||
496 s->filter_type == highpass ||
497 s->filter_type == allpass)) {
500 if (sscanf(args, "%lf", &width) != 1) {
501 av_log(ctx, AV_LOG_ERROR, "Invalid width value.\n");
502 return AVERROR(EINVAL);
506 } else if ((!strcmp(cmd, "width_type") || !strcmp(cmd, "t")) &&
507 (s->filter_type == equalizer ||
508 s->filter_type == bass ||
509 s->filter_type == treble ||
510 s->filter_type == bandpass ||
511 s->filter_type == bandreject||
512 s->filter_type == lowpass ||
513 s->filter_type == highpass ||
514 s->filter_type == allpass)) {
517 if (sscanf(args, "%c", &width_type) != 1) {
518 av_log(ctx, AV_LOG_ERROR, "Invalid width_type value.\n");
519 return AVERROR(EINVAL);
522 switch (width_type) {
523 case 'h': width_type = HERTZ; break;
524 case 'q': width_type = QFACTOR; break;
525 case 'o': width_type = OCTAVE; break;
526 case 's': width_type = SLOPE; break;
527 case 'k': width_type = KHERTZ; break;
529 av_log(ctx, AV_LOG_ERROR, "Invalid width_type value: %c\n", width_type);
530 return AVERROR(EINVAL);
533 s->width_type = width_type;
534 } else if ((!strcmp(cmd, "a0") ||
535 !strcmp(cmd, "a1") ||
536 !strcmp(cmd, "a2") ||
537 !strcmp(cmd, "b0") ||
538 !strcmp(cmd, "b1") ||
539 !strcmp(cmd, "b2")) &&
540 s->filter_type == biquad) {
543 if (sscanf(args, "%lf", &value) != 1) {
544 av_log(ctx, AV_LOG_ERROR, "Invalid biquad value.\n");
545 return AVERROR(EINVAL);
548 if (!strcmp(cmd, "a0"))
550 else if (!strcmp(cmd, "a1"))
552 else if (!strcmp(cmd, "a2"))
554 else if (!strcmp(cmd, "b0"))
556 else if (!strcmp(cmd, "b1"))
558 else if (!strcmp(cmd, "b2"))
562 return config_filter(outlink, 0);
565 static av_cold void uninit(AVFilterContext *ctx)
567 BiquadsContext *s = ctx->priv;
572 static const AVFilterPad inputs[] = {
575 .type = AVMEDIA_TYPE_AUDIO,
576 .filter_frame = filter_frame,
581 static const AVFilterPad outputs[] = {
584 .type = AVMEDIA_TYPE_AUDIO,
585 .config_props = config_output,
590 #define OFFSET(x) offsetof(BiquadsContext, x)
591 #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
593 #define DEFINE_BIQUAD_FILTER(name_, description_) \
594 AVFILTER_DEFINE_CLASS(name_); \
595 static av_cold int name_##_init(AVFilterContext *ctx) \
597 BiquadsContext *s = ctx->priv; \
598 s->class = &name_##_class; \
599 s->filter_type = name_; \
603 AVFilter ff_af_##name_ = { \
605 .description = NULL_IF_CONFIG_SMALL(description_), \
606 .priv_size = sizeof(BiquadsContext), \
607 .init = name_##_init, \
609 .query_formats = query_formats, \
611 .outputs = outputs, \
612 .priv_class = &name_##_class, \
613 .process_command = process_command, \
616 #if CONFIG_EQUALIZER_FILTER
617 static const AVOption equalizer_options[] = {
618 {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 999999, FLAGS},
619 {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 999999, FLAGS},
620 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
621 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
622 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
623 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
624 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
625 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
626 {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
627 {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 99999, FLAGS},
628 {"w", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 99999, FLAGS},
629 {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
630 {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
631 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
632 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
636 DEFINE_BIQUAD_FILTER(equalizer, "Apply two-pole peaking equalization (EQ) filter.");
637 #endif /* CONFIG_EQUALIZER_FILTER */
638 #if CONFIG_BASS_FILTER
639 static const AVOption bass_options[] = {
640 {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
641 {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
642 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
643 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
644 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
645 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
646 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
647 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
648 {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
649 {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
650 {"w", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
651 {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
652 {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
653 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
654 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
658 DEFINE_BIQUAD_FILTER(bass, "Boost or cut lower frequencies.");
659 #endif /* CONFIG_BASS_FILTER */
660 #if CONFIG_TREBLE_FILTER
661 static const AVOption treble_options[] = {
662 {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
663 {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
664 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
665 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
666 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
667 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
668 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
669 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
670 {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
671 {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
672 {"w", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
673 {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
674 {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
675 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
676 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
680 DEFINE_BIQUAD_FILTER(treble, "Boost or cut upper frequencies.");
681 #endif /* CONFIG_TREBLE_FILTER */
682 #if CONFIG_BANDPASS_FILTER
683 static const AVOption bandpass_options[] = {
684 {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
685 {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
686 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
687 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
688 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
689 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
690 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
691 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
692 {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
693 {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
694 {"w", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
695 {"csg", "use constant skirt gain", OFFSET(csg), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
696 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
697 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
701 DEFINE_BIQUAD_FILTER(bandpass, "Apply a two-pole Butterworth band-pass filter.");
702 #endif /* CONFIG_BANDPASS_FILTER */
703 #if CONFIG_BANDREJECT_FILTER
704 static const AVOption bandreject_options[] = {
705 {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
706 {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
707 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
708 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
709 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
710 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
711 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
712 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
713 {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
714 {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
715 {"w", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
716 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
717 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
721 DEFINE_BIQUAD_FILTER(bandreject, "Apply a two-pole Butterworth band-reject filter.");
722 #endif /* CONFIG_BANDREJECT_FILTER */
723 #if CONFIG_LOWPASS_FILTER
724 static const AVOption lowpass_options[] = {
725 {"frequency", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=500}, 0, 999999, FLAGS},
726 {"f", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=500}, 0, 999999, FLAGS},
727 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
728 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
729 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
730 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
731 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
732 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
733 {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
734 {"width", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
735 {"w", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
736 {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
737 {"p", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
738 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
739 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
743 DEFINE_BIQUAD_FILTER(lowpass, "Apply a low-pass filter with 3dB point frequency.");
744 #endif /* CONFIG_LOWPASS_FILTER */
745 #if CONFIG_HIGHPASS_FILTER
746 static const AVOption highpass_options[] = {
747 {"frequency", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
748 {"f", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
749 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
750 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
751 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
752 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
753 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
754 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
755 {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
756 {"width", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
757 {"w", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
758 {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
759 {"p", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
760 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
761 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
765 DEFINE_BIQUAD_FILTER(highpass, "Apply a high-pass filter with 3dB point frequency.");
766 #endif /* CONFIG_HIGHPASS_FILTER */
767 #if CONFIG_ALLPASS_FILTER
768 static const AVOption allpass_options[] = {
769 {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
770 {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
771 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=HERTZ}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
772 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=HERTZ}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
773 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
774 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
775 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
776 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
777 {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
778 {"width", "set filter-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=707.1}, 0, 99999, FLAGS},
779 {"w", "set filter-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=707.1}, 0, 99999, FLAGS},
780 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
781 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
785 DEFINE_BIQUAD_FILTER(allpass, "Apply a two-pole all-pass filter.");
786 #endif /* CONFIG_ALLPASS_FILTER */
787 #if CONFIG_BIQUAD_FILTER
788 static const AVOption biquad_options[] = {
789 {"a0", NULL, OFFSET(a0), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT32_MIN, INT32_MAX, FLAGS},
790 {"a1", NULL, OFFSET(a1), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
791 {"a2", NULL, OFFSET(a2), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
792 {"b0", NULL, OFFSET(b0), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
793 {"b1", NULL, OFFSET(b1), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
794 {"b2", NULL, OFFSET(b2), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
795 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
796 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
800 DEFINE_BIQUAD_FILTER(biquad, "Apply a biquad IIR filter with the given coefficients.");
801 #endif /* CONFIG_BIQUAD_FILTER */