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"
95 typedef struct ChanCache {
101 typedef struct BiquadsContext {
102 const AVClass *class;
104 enum FilterType filter_type;
120 void (*filter)(struct BiquadsContext *s, const void *ibuf, void *obuf, int len,
121 double *i1, double *i2, double *o1, double *o2,
122 double b0, double b1, double b2, double a1, double a2, int *clippings);
125 static av_cold int init(AVFilterContext *ctx)
127 BiquadsContext *s = ctx->priv;
129 if (s->filter_type != biquad) {
130 if (s->frequency <= 0 || s->width <= 0) {
131 av_log(ctx, AV_LOG_ERROR, "Invalid frequency %f and/or width %f <= 0\n",
132 s->frequency, s->width);
133 return AVERROR(EINVAL);
140 static int query_formats(AVFilterContext *ctx)
142 AVFilterFormats *formats;
143 AVFilterChannelLayouts *layouts;
144 static const enum AVSampleFormat sample_fmts[] = {
153 layouts = ff_all_channel_counts();
155 return AVERROR(ENOMEM);
156 ret = ff_set_common_channel_layouts(ctx, layouts);
160 formats = ff_make_format_list(sample_fmts);
162 return AVERROR(ENOMEM);
163 ret = ff_set_common_formats(ctx, formats);
167 formats = ff_all_samplerates();
169 return AVERROR(ENOMEM);
170 return ff_set_common_samplerates(ctx, formats);
173 #define BIQUAD_FILTER(name, type, min, max, need_clipping) \
174 static void biquad_## name (BiquadsContext *s, \
175 const void *input, void *output, int len, \
176 double *in1, double *in2, \
177 double *out1, double *out2, \
178 double b0, double b1, double b2, \
179 double a1, double a2, int *clippings) \
181 const type *ibuf = input; \
182 type *obuf = output; \
191 for (i = 0; i+1 < len; i++) { \
192 o2 = i2 * b2 + i1 * b1 + ibuf[i] * b0 + o2 * a2 + o1 * a1; \
194 if (need_clipping && o2 < min) { \
197 } else if (need_clipping && o2 > max) { \
204 o1 = i1 * b2 + i2 * b1 + ibuf[i] * b0 + o1 * a2 + o2 * a1; \
206 if (need_clipping && o1 < min) { \
209 } else if (need_clipping && o1 > max) { \
217 double o0 = ibuf[i] * b0 + i1 * b1 + i2 * b2 + o1 * a1 + o2 * a2; \
222 if (need_clipping && o0 < min) { \
225 } else if (need_clipping && o0 > max) { \
238 BIQUAD_FILTER(s16, int16_t, INT16_MIN, INT16_MAX, 1)
239 BIQUAD_FILTER(s32, int32_t, INT32_MIN, INT32_MAX, 1)
240 BIQUAD_FILTER(flt, float, -1., 1., 0)
241 BIQUAD_FILTER(dbl, double, -1., 1., 0)
243 static int config_filter(AVFilterLink *outlink, int reset)
245 AVFilterContext *ctx = outlink->src;
246 BiquadsContext *s = ctx->priv;
247 AVFilterLink *inlink = ctx->inputs[0];
248 double A = exp(s->gain / 40 * log(10.));
249 double w0 = 2 * M_PI * s->frequency / inlink->sample_rate;
253 av_log(ctx, AV_LOG_ERROR,
254 "Invalid frequency %f. Frequency must be less than half the sample-rate %d.\n",
255 s->frequency, inlink->sample_rate);
256 return AVERROR(EINVAL);
259 switch (s->width_type) {
264 alpha = sin(w0) / (2 * s->frequency / s->width);
267 alpha = sin(w0) / (2 * s->frequency / (s->width * 1000));
270 alpha = sin(w0) * sinh(log(2.) / 2 * s->width * w0 / sin(w0));
273 alpha = sin(w0) / (2 * s->width);
276 alpha = sin(w0) / 2 * sqrt((A + 1 / A) * (1 / s->width - 1) + 2);
284 switch (s->filter_type) {
288 s->a0 = 1 + alpha / A;
289 s->a1 = -2 * cos(w0);
290 s->a2 = 1 - alpha / A;
291 s->b0 = 1 + alpha * A;
292 s->b1 = -2 * cos(w0);
293 s->b2 = 1 - alpha * A;
296 beta = sqrt((A * A + 1) - (A - 1) * (A - 1));
298 s->a0 = (A + 1) + (A - 1) * cos(w0) + beta * alpha;
299 s->a1 = -2 * ((A - 1) + (A + 1) * cos(w0));
300 s->a2 = (A + 1) + (A - 1) * cos(w0) - beta * alpha;
301 s->b0 = A * ((A + 1) - (A - 1) * cos(w0) + beta * alpha);
302 s->b1 = 2 * A * ((A - 1) - (A + 1) * cos(w0));
303 s->b2 = A * ((A + 1) - (A - 1) * cos(w0) - beta * alpha);
306 beta = sqrt((A * A + 1) - (A - 1) * (A - 1));
308 s->a0 = (A + 1) - (A - 1) * cos(w0) + beta * alpha;
309 s->a1 = 2 * ((A - 1) - (A + 1) * cos(w0));
310 s->a2 = (A + 1) - (A - 1) * cos(w0) - beta * alpha;
311 s->b0 = A * ((A + 1) + (A - 1) * cos(w0) + beta * alpha);
312 s->b1 =-2 * A * ((A - 1) + (A + 1) * cos(w0));
313 s->b2 = A * ((A + 1) + (A - 1) * cos(w0) - beta * alpha);
318 s->a1 = -2 * cos(w0);
322 s->b2 = -sin(w0) / 2;
325 s->a1 = -2 * cos(w0);
334 s->a1 = -2 * cos(w0);
337 s->b1 = -2 * cos(w0);
350 s->a1 = -2 * cos(w0);
352 s->b0 = (1 - cos(w0)) / 2;
354 s->b2 = (1 - cos(w0)) / 2;
362 s->b0 = (1 - s->a1) / 2;
367 s->a1 = -2 * cos(w0);
369 s->b0 = (1 + cos(w0)) / 2;
370 s->b1 = -(1 + cos(w0));
371 s->b2 = (1 + cos(w0)) / 2;
376 s->a1 = -2 * cos(w0);
379 s->b1 = -2 * cos(w0);
386 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);
395 s->cache = av_realloc_f(s->cache, sizeof(ChanCache), inlink->channels);
397 return AVERROR(ENOMEM);
399 memset(s->cache, 0, sizeof(ChanCache) * inlink->channels);
401 switch (inlink->format) {
402 case AV_SAMPLE_FMT_S16P: s->filter = biquad_s16; break;
403 case AV_SAMPLE_FMT_S32P: s->filter = biquad_s32; break;
404 case AV_SAMPLE_FMT_FLTP: s->filter = biquad_flt; break;
405 case AV_SAMPLE_FMT_DBLP: s->filter = biquad_dbl; break;
406 default: av_assert0(0);
409 s->block_align = av_get_bytes_per_sample(inlink->format);
414 static int config_output(AVFilterLink *outlink)
416 return config_filter(outlink, 1);
419 static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
421 AVFilterContext *ctx = inlink->dst;
422 BiquadsContext *s = ctx->priv;
423 AVFilterLink *outlink = ctx->outputs[0];
425 int nb_samples = buf->nb_samples;
428 if (av_frame_is_writable(buf)) {
431 out_buf = ff_get_audio_buffer(outlink, nb_samples);
434 return AVERROR(ENOMEM);
436 av_frame_copy_props(out_buf, buf);
439 for (ch = 0; ch < buf->channels; ch++) {
440 if (!((av_channel_layout_extract_channel(inlink->channel_layout, ch) & s->channels))) {
442 memcpy(out_buf->extended_data[ch], buf->extended_data[ch], nb_samples * s->block_align);
445 s->filter(s, buf->extended_data[ch],
446 out_buf->extended_data[ch], nb_samples,
447 &s->cache[ch].i1, &s->cache[ch].i2,
448 &s->cache[ch].o1, &s->cache[ch].o2,
449 s->b0, s->b1, s->b2, s->a1, s->a2,
450 &s->cache[ch].clippings);
453 for (ch = 0; ch < outlink->channels; ch++) {
454 if (s->cache[ch].clippings > 0)
455 av_log(ctx, AV_LOG_WARNING, "Channel %d clipping %d times. Please reduce gain.\n",
456 ch, s->cache[ch].clippings);
457 s->cache[ch].clippings = 0;
463 return ff_filter_frame(outlink, out_buf);
466 static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
467 char *res, int res_len, int flags)
469 BiquadsContext *s = ctx->priv;
470 AVFilterLink *outlink = ctx->outputs[0];
472 if ((!strcmp(cmd, "frequency") || !strcmp(cmd, "f")) &&
473 (s->filter_type == equalizer ||
474 s->filter_type == lowshelf ||
475 s->filter_type == highshelf ||
476 s->filter_type == bass ||
477 s->filter_type == treble ||
478 s->filter_type == bandpass ||
479 s->filter_type == bandreject||
480 s->filter_type == lowpass ||
481 s->filter_type == highpass ||
482 s->filter_type == allpass)) {
485 if (sscanf(args, "%lf", &freq) != 1) {
486 av_log(ctx, AV_LOG_ERROR, "Invalid frequency value.\n");
487 return AVERROR(EINVAL);
491 } else if ((!strcmp(cmd, "gain") || !strcmp(cmd, "g")) &&
492 (s->filter_type == equalizer ||
493 s->filter_type == lowshelf ||
494 s->filter_type == highshelf ||
495 s->filter_type == bass ||
496 s->filter_type == treble)) {
499 if (sscanf(args, "%lf", &gain) != 1) {
500 av_log(ctx, AV_LOG_ERROR, "Invalid gain value.\n");
501 return AVERROR(EINVAL);
505 } else if ((!strcmp(cmd, "width") || !strcmp(cmd, "w")) &&
506 (s->filter_type == equalizer ||
507 s->filter_type == lowshelf ||
508 s->filter_type == highshelf ||
509 s->filter_type == bass ||
510 s->filter_type == treble ||
511 s->filter_type == bandpass ||
512 s->filter_type == bandreject||
513 s->filter_type == lowpass ||
514 s->filter_type == highpass ||
515 s->filter_type == allpass)) {
518 if (sscanf(args, "%lf", &width) != 1) {
519 av_log(ctx, AV_LOG_ERROR, "Invalid width value.\n");
520 return AVERROR(EINVAL);
524 } else if ((!strcmp(cmd, "width_type") || !strcmp(cmd, "t")) &&
525 (s->filter_type == equalizer ||
526 s->filter_type == lowshelf ||
527 s->filter_type == highshelf ||
528 s->filter_type == bass ||
529 s->filter_type == treble ||
530 s->filter_type == bandpass ||
531 s->filter_type == bandreject||
532 s->filter_type == lowpass ||
533 s->filter_type == highpass ||
534 s->filter_type == allpass)) {
537 if (sscanf(args, "%c", &width_type) != 1) {
538 av_log(ctx, AV_LOG_ERROR, "Invalid width_type value.\n");
539 return AVERROR(EINVAL);
542 switch (width_type) {
543 case 'h': width_type = HERTZ; break;
544 case 'q': width_type = QFACTOR; break;
545 case 'o': width_type = OCTAVE; break;
546 case 's': width_type = SLOPE; break;
547 case 'k': width_type = KHERTZ; break;
549 av_log(ctx, AV_LOG_ERROR, "Invalid width_type value: %c\n", width_type);
550 return AVERROR(EINVAL);
553 s->width_type = width_type;
554 } else if ((!strcmp(cmd, "a0") ||
555 !strcmp(cmd, "a1") ||
556 !strcmp(cmd, "a2") ||
557 !strcmp(cmd, "b0") ||
558 !strcmp(cmd, "b1") ||
559 !strcmp(cmd, "b2")) &&
560 s->filter_type == biquad) {
563 if (sscanf(args, "%lf", &value) != 1) {
564 av_log(ctx, AV_LOG_ERROR, "Invalid biquad value.\n");
565 return AVERROR(EINVAL);
568 if (!strcmp(cmd, "a0"))
570 else if (!strcmp(cmd, "a1"))
572 else if (!strcmp(cmd, "a2"))
574 else if (!strcmp(cmd, "b0"))
576 else if (!strcmp(cmd, "b1"))
578 else if (!strcmp(cmd, "b2"))
582 return config_filter(outlink, 0);
585 static av_cold void uninit(AVFilterContext *ctx)
587 BiquadsContext *s = ctx->priv;
592 static const AVFilterPad inputs[] = {
595 .type = AVMEDIA_TYPE_AUDIO,
596 .filter_frame = filter_frame,
601 static const AVFilterPad outputs[] = {
604 .type = AVMEDIA_TYPE_AUDIO,
605 .config_props = config_output,
610 #define OFFSET(x) offsetof(BiquadsContext, x)
611 #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
613 #define DEFINE_BIQUAD_FILTER(name_, description_) \
614 AVFILTER_DEFINE_CLASS(name_); \
615 static av_cold int name_##_init(AVFilterContext *ctx) \
617 BiquadsContext *s = ctx->priv; \
618 s->class = &name_##_class; \
619 s->filter_type = name_; \
623 AVFilter ff_af_##name_ = { \
625 .description = NULL_IF_CONFIG_SMALL(description_), \
626 .priv_size = sizeof(BiquadsContext), \
627 .init = name_##_init, \
629 .query_formats = query_formats, \
631 .outputs = outputs, \
632 .priv_class = &name_##_class, \
633 .process_command = process_command, \
636 #if CONFIG_EQUALIZER_FILTER
637 static const AVOption equalizer_options[] = {
638 {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 999999, FLAGS},
639 {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 999999, FLAGS},
640 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
641 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
642 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
643 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
644 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
645 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
646 {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
647 {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 99999, FLAGS},
648 {"w", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 99999, FLAGS},
649 {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
650 {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
651 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
652 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
656 DEFINE_BIQUAD_FILTER(equalizer, "Apply two-pole peaking equalization (EQ) filter.");
657 #endif /* CONFIG_EQUALIZER_FILTER */
658 #if CONFIG_BASS_FILTER
659 static const AVOption bass_options[] = {
660 {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
661 {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
662 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
663 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
664 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
665 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
666 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
667 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
668 {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
669 {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
670 {"w", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
671 {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
672 {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
673 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
674 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
678 DEFINE_BIQUAD_FILTER(bass, "Boost or cut lower frequencies.");
679 #endif /* CONFIG_BASS_FILTER */
680 #if CONFIG_TREBLE_FILTER
681 static const AVOption treble_options[] = {
682 {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
683 {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
684 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
685 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
686 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
687 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
688 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
689 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
690 {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
691 {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
692 {"w", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
693 {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
694 {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
695 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
696 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
700 DEFINE_BIQUAD_FILTER(treble, "Boost or cut upper frequencies.");
701 #endif /* CONFIG_TREBLE_FILTER */
702 #if CONFIG_BANDPASS_FILTER
703 static const AVOption bandpass_options[] = {
704 {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
705 {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
706 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
707 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
708 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
709 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
710 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
711 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
712 {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
713 {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
714 {"w", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
715 {"csg", "use constant skirt gain", OFFSET(csg), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, 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(bandpass, "Apply a two-pole Butterworth band-pass filter.");
722 #endif /* CONFIG_BANDPASS_FILTER */
723 #if CONFIG_BANDREJECT_FILTER
724 static const AVOption bandreject_options[] = {
725 {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
726 {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 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 band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
735 {"w", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
736 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
737 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
741 DEFINE_BIQUAD_FILTER(bandreject, "Apply a two-pole Butterworth band-reject filter.");
742 #endif /* CONFIG_BANDREJECT_FILTER */
743 #if CONFIG_LOWPASS_FILTER
744 static const AVOption lowpass_options[] = {
745 {"frequency", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=500}, 0, 999999, FLAGS},
746 {"f", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=500}, 0, 999999, FLAGS},
747 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
748 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
749 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
750 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
751 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
752 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
753 {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
754 {"width", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
755 {"w", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
756 {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
757 {"p", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
758 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
759 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
763 DEFINE_BIQUAD_FILTER(lowpass, "Apply a low-pass filter with 3dB point frequency.");
764 #endif /* CONFIG_LOWPASS_FILTER */
765 #if CONFIG_HIGHPASS_FILTER
766 static const AVOption highpass_options[] = {
767 {"frequency", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
768 {"f", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
769 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
770 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
771 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
772 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
773 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
774 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
775 {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
776 {"width", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
777 {"w", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
778 {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
779 {"p", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, 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(highpass, "Apply a high-pass filter with 3dB point frequency.");
786 #endif /* CONFIG_HIGHPASS_FILTER */
787 #if CONFIG_ALLPASS_FILTER
788 static const AVOption allpass_options[] = {
789 {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
790 {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
791 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=HERTZ}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
792 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=HERTZ}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
793 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
794 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
795 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
796 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
797 {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
798 {"width", "set filter-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=707.1}, 0, 99999, FLAGS},
799 {"w", "set filter-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=707.1}, 0, 99999, FLAGS},
800 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
801 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
805 DEFINE_BIQUAD_FILTER(allpass, "Apply a two-pole all-pass filter.");
806 #endif /* CONFIG_ALLPASS_FILTER */
807 #if CONFIG_LOWSHELF_FILTER
808 static const AVOption lowshelf_options[] = {
809 {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
810 {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
811 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
812 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
813 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
814 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
815 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
816 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
817 {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
818 {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
819 {"w", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
820 {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
821 {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
822 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
823 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
827 DEFINE_BIQUAD_FILTER(lowshelf, "Apply a low shelf filter.");
828 #endif /* CONFIG_LOWSHELF_FILTER */
829 #if CONFIG_HIGHSHELF_FILTER
830 static const AVOption highshelf_options[] = {
831 {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
832 {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
833 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
834 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
835 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
836 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
837 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
838 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
839 {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
840 {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
841 {"w", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
842 {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
843 {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
844 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
845 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
849 DEFINE_BIQUAD_FILTER(highshelf, "Apply a high shelf filter.");
850 #endif /* CONFIG_HIGHSHELF_FILTER */
851 #if CONFIG_BIQUAD_FILTER
852 static const AVOption biquad_options[] = {
853 {"a0", NULL, OFFSET(a0), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT32_MIN, INT32_MAX, FLAGS},
854 {"a1", NULL, OFFSET(a1), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
855 {"a2", NULL, OFFSET(a2), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
856 {"b0", NULL, OFFSET(b0), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
857 {"b1", NULL, OFFSET(b1), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
858 {"b2", NULL, OFFSET(b2), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
859 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
860 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
864 DEFINE_BIQUAD_FILTER(biquad, "Apply a biquad IIR filter with the given coefficients.");
865 #endif /* CONFIG_BIQUAD_FILTER */