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 {
100 typedef struct BiquadsContext {
101 const AVClass *class;
103 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);
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) \
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);
452 if (s->clippings > 0)
453 av_log(ctx, AV_LOG_WARNING, "clipping %d times. Please reduce gain.\n", s->clippings);
459 return ff_filter_frame(outlink, out_buf);
462 static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
463 char *res, int res_len, int flags)
465 BiquadsContext *s = ctx->priv;
466 AVFilterLink *outlink = ctx->outputs[0];
468 if ((!strcmp(cmd, "frequency") || !strcmp(cmd, "f")) &&
469 (s->filter_type == equalizer ||
470 s->filter_type == lowshelf ||
471 s->filter_type == highshelf ||
472 s->filter_type == bass ||
473 s->filter_type == treble ||
474 s->filter_type == bandpass ||
475 s->filter_type == bandreject||
476 s->filter_type == lowpass ||
477 s->filter_type == highpass ||
478 s->filter_type == allpass)) {
481 if (sscanf(args, "%lf", &freq) != 1) {
482 av_log(ctx, AV_LOG_ERROR, "Invalid frequency value.\n");
483 return AVERROR(EINVAL);
487 } else if ((!strcmp(cmd, "gain") || !strcmp(cmd, "g")) &&
488 (s->filter_type == equalizer ||
489 s->filter_type == lowshelf ||
490 s->filter_type == highshelf ||
491 s->filter_type == bass ||
492 s->filter_type == treble)) {
495 if (sscanf(args, "%lf", &gain) != 1) {
496 av_log(ctx, AV_LOG_ERROR, "Invalid gain value.\n");
497 return AVERROR(EINVAL);
501 } else if ((!strcmp(cmd, "width") || !strcmp(cmd, "w")) &&
502 (s->filter_type == equalizer ||
503 s->filter_type == lowshelf ||
504 s->filter_type == highshelf ||
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, "%lf", &width) != 1) {
515 av_log(ctx, AV_LOG_ERROR, "Invalid width value.\n");
516 return AVERROR(EINVAL);
520 } else if ((!strcmp(cmd, "width_type") || !strcmp(cmd, "t")) &&
521 (s->filter_type == equalizer ||
522 s->filter_type == lowshelf ||
523 s->filter_type == highshelf ||
524 s->filter_type == bass ||
525 s->filter_type == treble ||
526 s->filter_type == bandpass ||
527 s->filter_type == bandreject||
528 s->filter_type == lowpass ||
529 s->filter_type == highpass ||
530 s->filter_type == allpass)) {
533 if (sscanf(args, "%c", &width_type) != 1) {
534 av_log(ctx, AV_LOG_ERROR, "Invalid width_type value.\n");
535 return AVERROR(EINVAL);
538 switch (width_type) {
539 case 'h': width_type = HERTZ; break;
540 case 'q': width_type = QFACTOR; break;
541 case 'o': width_type = OCTAVE; break;
542 case 's': width_type = SLOPE; break;
543 case 'k': width_type = KHERTZ; break;
545 av_log(ctx, AV_LOG_ERROR, "Invalid width_type value: %c\n", width_type);
546 return AVERROR(EINVAL);
549 s->width_type = width_type;
550 } else if ((!strcmp(cmd, "a0") ||
551 !strcmp(cmd, "a1") ||
552 !strcmp(cmd, "a2") ||
553 !strcmp(cmd, "b0") ||
554 !strcmp(cmd, "b1") ||
555 !strcmp(cmd, "b2")) &&
556 s->filter_type == biquad) {
559 if (sscanf(args, "%lf", &value) != 1) {
560 av_log(ctx, AV_LOG_ERROR, "Invalid biquad value.\n");
561 return AVERROR(EINVAL);
564 if (!strcmp(cmd, "a0"))
566 else if (!strcmp(cmd, "a1"))
568 else if (!strcmp(cmd, "a2"))
570 else if (!strcmp(cmd, "b0"))
572 else if (!strcmp(cmd, "b1"))
574 else if (!strcmp(cmd, "b2"))
578 return config_filter(outlink, 0);
581 static av_cold void uninit(AVFilterContext *ctx)
583 BiquadsContext *s = ctx->priv;
588 static const AVFilterPad inputs[] = {
591 .type = AVMEDIA_TYPE_AUDIO,
592 .filter_frame = filter_frame,
597 static const AVFilterPad outputs[] = {
600 .type = AVMEDIA_TYPE_AUDIO,
601 .config_props = config_output,
606 #define OFFSET(x) offsetof(BiquadsContext, x)
607 #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
609 #define DEFINE_BIQUAD_FILTER(name_, description_) \
610 AVFILTER_DEFINE_CLASS(name_); \
611 static av_cold int name_##_init(AVFilterContext *ctx) \
613 BiquadsContext *s = ctx->priv; \
614 s->class = &name_##_class; \
615 s->filter_type = name_; \
619 AVFilter ff_af_##name_ = { \
621 .description = NULL_IF_CONFIG_SMALL(description_), \
622 .priv_size = sizeof(BiquadsContext), \
623 .init = name_##_init, \
625 .query_formats = query_formats, \
627 .outputs = outputs, \
628 .priv_class = &name_##_class, \
629 .process_command = process_command, \
632 #if CONFIG_EQUALIZER_FILTER
633 static const AVOption equalizer_options[] = {
634 {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 999999, FLAGS},
635 {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 999999, FLAGS},
636 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
637 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
638 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
639 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
640 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
641 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
642 {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
643 {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 99999, FLAGS},
644 {"w", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 99999, FLAGS},
645 {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
646 {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
647 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
648 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
652 DEFINE_BIQUAD_FILTER(equalizer, "Apply two-pole peaking equalization (EQ) filter.");
653 #endif /* CONFIG_EQUALIZER_FILTER */
654 #if CONFIG_BASS_FILTER
655 static const AVOption bass_options[] = {
656 {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
657 {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
658 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
659 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
660 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
661 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
662 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
663 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
664 {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
665 {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
666 {"w", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
667 {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
668 {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
669 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
670 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
674 DEFINE_BIQUAD_FILTER(bass, "Boost or cut lower frequencies.");
675 #endif /* CONFIG_BASS_FILTER */
676 #if CONFIG_TREBLE_FILTER
677 static const AVOption treble_options[] = {
678 {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
679 {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
680 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
681 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
682 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
683 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
684 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
685 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
686 {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
687 {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
688 {"w", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
689 {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
690 {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
691 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
692 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
696 DEFINE_BIQUAD_FILTER(treble, "Boost or cut upper frequencies.");
697 #endif /* CONFIG_TREBLE_FILTER */
698 #if CONFIG_BANDPASS_FILTER
699 static const AVOption bandpass_options[] = {
700 {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
701 {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
702 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
703 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
704 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
705 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
706 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
707 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
708 {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
709 {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
710 {"w", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
711 {"csg", "use constant skirt gain", OFFSET(csg), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
712 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
713 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
717 DEFINE_BIQUAD_FILTER(bandpass, "Apply a two-pole Butterworth band-pass filter.");
718 #endif /* CONFIG_BANDPASS_FILTER */
719 #if CONFIG_BANDREJECT_FILTER
720 static const AVOption bandreject_options[] = {
721 {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
722 {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
723 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
724 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
725 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
726 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
727 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
728 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
729 {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
730 {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
731 {"w", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
732 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
733 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
737 DEFINE_BIQUAD_FILTER(bandreject, "Apply a two-pole Butterworth band-reject filter.");
738 #endif /* CONFIG_BANDREJECT_FILTER */
739 #if CONFIG_LOWPASS_FILTER
740 static const AVOption lowpass_options[] = {
741 {"frequency", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=500}, 0, 999999, FLAGS},
742 {"f", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=500}, 0, 999999, FLAGS},
743 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
744 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
745 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
746 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
747 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
748 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
749 {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
750 {"width", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
751 {"w", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
752 {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
753 {"p", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
754 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
755 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
759 DEFINE_BIQUAD_FILTER(lowpass, "Apply a low-pass filter with 3dB point frequency.");
760 #endif /* CONFIG_LOWPASS_FILTER */
761 #if CONFIG_HIGHPASS_FILTER
762 static const AVOption highpass_options[] = {
763 {"frequency", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
764 {"f", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
765 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
766 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
767 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
768 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
769 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
770 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
771 {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
772 {"width", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
773 {"w", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
774 {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
775 {"p", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
776 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
777 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
781 DEFINE_BIQUAD_FILTER(highpass, "Apply a high-pass filter with 3dB point frequency.");
782 #endif /* CONFIG_HIGHPASS_FILTER */
783 #if CONFIG_ALLPASS_FILTER
784 static const AVOption allpass_options[] = {
785 {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
786 {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
787 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=HERTZ}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
788 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=HERTZ}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
789 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
790 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
791 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
792 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
793 {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
794 {"width", "set filter-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=707.1}, 0, 99999, FLAGS},
795 {"w", "set filter-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=707.1}, 0, 99999, FLAGS},
796 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
797 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
801 DEFINE_BIQUAD_FILTER(allpass, "Apply a two-pole all-pass filter.");
802 #endif /* CONFIG_ALLPASS_FILTER */
803 #if CONFIG_LOWSHELF_FILTER
804 static const AVOption lowshelf_options[] = {
805 {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
806 {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
807 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
808 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
809 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
810 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
811 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
812 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
813 {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
814 {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
815 {"w", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
816 {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
817 {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
818 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
819 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
823 DEFINE_BIQUAD_FILTER(lowshelf, "Apply a low shelf filter.");
824 #endif /* CONFIG_LOWSHELF_FILTER */
825 #if CONFIG_HIGHSHELF_FILTER
826 static const AVOption highshelf_options[] = {
827 {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
828 {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
829 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
830 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
831 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
832 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
833 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
834 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
835 {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
836 {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
837 {"w", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
838 {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
839 {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
840 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
841 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
845 DEFINE_BIQUAD_FILTER(highshelf, "Apply a high shelf filter.");
846 #endif /* CONFIG_HIGHSHELF_FILTER */
847 #if CONFIG_BIQUAD_FILTER
848 static const AVOption biquad_options[] = {
849 {"a0", NULL, OFFSET(a0), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT32_MIN, INT32_MAX, FLAGS},
850 {"a1", NULL, OFFSET(a1), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
851 {"a2", NULL, OFFSET(a2), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
852 {"b0", NULL, OFFSET(b0), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
853 {"b1", NULL, OFFSET(b1), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
854 {"b2", NULL, OFFSET(b2), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
855 {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
856 {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
860 DEFINE_BIQUAD_FILTER(biquad, "Apply a biquad IIR filter with the given coefficients.");
861 #endif /* CONFIG_BIQUAD_FILTER */