Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright (c) 2013 Paul B Mahol
  3.  * Copyright (c) 2006-2008 Rob Sykes <robs@users.sourceforge.net>
  4.  *
  5.  * This file is part of FFmpeg.
  6.  *
  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.
  11.  *
  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.
  16.  *
  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
  20.  */
  21.  
  22. /*
  23.  * 2-pole filters designed by Robert Bristow-Johnson <rbj@audioimagination.com>
  24.  *   see http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt
  25.  *
  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
  29.  *
  30.  *   low-pass: output[N] = input[N] * A + output[N-1] * B
  31.  *     X = exp(-2.0 * pi * Fc)
  32.  *     A = 1 - X
  33.  *     B = X
  34.  *     Fc = cutoff freq / sample rate
  35.  *
  36.  *     Mimics an RC low-pass filter:
  37.  *
  38.  *     ---/\/\/\/\----------->
  39.  *                   |
  40.  *                  --- C
  41.  *                  ---
  42.  *                   |
  43.  *                   |
  44.  *                   V
  45.  *
  46.  *   high-pass: output[N] = A0 * input[N] + A1 * input[N-1] + B1 * output[N-1]
  47.  *     X  = exp(-2.0 * pi * Fc)
  48.  *     A0 = (1 + X) / 2
  49.  *     A1 = -(1 + X) / 2
  50.  *     B1 = X
  51.  *     Fc = cutoff freq / sample rate
  52.  *
  53.  *     Mimics an RC high-pass filter:
  54.  *
  55.  *         || C
  56.  *     ----||--------->
  57.  *         ||    |
  58.  *               <
  59.  *               > R
  60.  *               <
  61.  *               |
  62.  *               V
  63.  */
  64.  
  65. #include "libavutil/avassert.h"
  66. #include "libavutil/opt.h"
  67. #include "audio.h"
  68. #include "avfilter.h"
  69. #include "internal.h"
  70.  
  71. enum FilterType {
  72.     biquad,
  73.     equalizer,
  74.     bass,
  75.     treble,
  76.     band,
  77.     bandpass,
  78.     bandreject,
  79.     allpass,
  80.     highpass,
  81.     lowpass,
  82. };
  83.  
  84. enum WidthType {
  85.     NONE,
  86.     HERTZ,
  87.     OCTAVE,
  88.     QFACTOR,
  89.     SLOPE,
  90. };
  91.  
  92. typedef struct ChanCache {
  93.     double i1, i2;
  94.     double o1, o2;
  95. } ChanCache;
  96.  
  97. typedef struct {
  98.     const AVClass *class;
  99.  
  100.     enum FilterType filter_type;
  101.     int width_type;
  102.     int poles;
  103.     int csg;
  104.  
  105.     double gain;
  106.     double frequency;
  107.     double width;
  108.  
  109.     double a0, a1, a2;
  110.     double b0, b1, b2;
  111.  
  112.     ChanCache *cache;
  113.  
  114.     void (*filter)(const void *ibuf, void *obuf, int len,
  115.                    double *i1, double *i2, double *o1, double *o2,
  116.                    double b0, double b1, double b2, double a1, double a2);
  117. } BiquadsContext;
  118.  
  119. static av_cold int init(AVFilterContext *ctx)
  120. {
  121.     BiquadsContext *s = ctx->priv;
  122.  
  123.     if (s->filter_type != biquad) {
  124.         if (s->frequency <= 0 || s->width <= 0) {
  125.             av_log(ctx, AV_LOG_ERROR, "Invalid frequency %f and/or width %f <= 0\n",
  126.                    s->frequency, s->width);
  127.             return AVERROR(EINVAL);
  128.         }
  129.     }
  130.  
  131.     return 0;
  132. }
  133.  
  134. static int query_formats(AVFilterContext *ctx)
  135. {
  136.     AVFilterFormats *formats;
  137.     AVFilterChannelLayouts *layouts;
  138.     static const enum AVSampleFormat sample_fmts[] = {
  139.         AV_SAMPLE_FMT_S16P,
  140.         AV_SAMPLE_FMT_S32P,
  141.         AV_SAMPLE_FMT_FLTP,
  142.         AV_SAMPLE_FMT_DBLP,
  143.         AV_SAMPLE_FMT_NONE
  144.     };
  145.     int ret;
  146.  
  147.     layouts = ff_all_channel_layouts();
  148.     if (!layouts)
  149.         return AVERROR(ENOMEM);
  150.     ret = ff_set_common_channel_layouts(ctx, layouts);
  151.     if (ret < 0)
  152.         return ret;
  153.  
  154.     formats = ff_make_format_list(sample_fmts);
  155.     if (!formats)
  156.         return AVERROR(ENOMEM);
  157.     ret = ff_set_common_formats(ctx, formats);
  158.     if (ret < 0)
  159.         return ret;
  160.  
  161.     formats = ff_all_samplerates();
  162.     if (!formats)
  163.         return AVERROR(ENOMEM);
  164.     return ff_set_common_samplerates(ctx, formats);
  165. }
  166.  
  167. #define BIQUAD_FILTER(name, type, min, max, need_clipping)                    \
  168. static void biquad_## name (const void *input, void *output, int len,         \
  169.                             double *in1, double *in2,                         \
  170.                             double *out1, double *out2,                       \
  171.                             double b0, double b1, double b2,                  \
  172.                             double a1, double a2)                             \
  173. {                                                                             \
  174.     const type *ibuf = input;                                                 \
  175.     type *obuf = output;                                                      \
  176.     double i1 = *in1;                                                         \
  177.     double i2 = *in2;                                                         \
  178.     double o1 = *out1;                                                        \
  179.     double o2 = *out2;                                                        \
  180.     int i;                                                                    \
  181.     a1 = -a1;                                                                 \
  182.     a2 = -a2;                                                                 \
  183.                                                                               \
  184.     for (i = 0; i+1 < len; i++) {                                             \
  185.         o2 = i2 * b2 + i1 * b1 + ibuf[i] * b0 + o2 * a2 + o1 * a1;            \
  186.         i2 = ibuf[i];                                                         \
  187.         if (need_clipping && o2 < min) {                                      \
  188.             av_log(NULL, AV_LOG_WARNING, "clipping\n");                       \
  189.             obuf[i] = min;                                                    \
  190.         } else if (need_clipping && o2 > max) {                               \
  191.             av_log(NULL, AV_LOG_WARNING, "clipping\n");                       \
  192.             obuf[i] = max;                                                    \
  193.         } else {                                                              \
  194.             obuf[i] = o2;                                                     \
  195.         }                                                                     \
  196.         i++;                                                                  \
  197.         o1 = i1 * b2 + i2 * b1 + ibuf[i] * b0 + o1 * a2 + o2 * a1;            \
  198.         i1 = ibuf[i];                                                         \
  199.         if (need_clipping && o1 < min) {                                      \
  200.             av_log(NULL, AV_LOG_WARNING, "clipping\n");                       \
  201.             obuf[i] = min;                                                    \
  202.         } else if (need_clipping && o1 > max) {                               \
  203.             av_log(NULL, AV_LOG_WARNING, "clipping\n");                       \
  204.             obuf[i] = max;                                                    \
  205.         } else {                                                              \
  206.             obuf[i] = o1;                                                     \
  207.         }                                                                     \
  208.     }                                                                         \
  209.     if (i < len) {                                                            \
  210.         double o0 = ibuf[i] * b0 + i1 * b1 + i2 * b2 + o1 * a1 + o2 * a2;     \
  211.         i2 = i1;                                                              \
  212.         i1 = ibuf[i];                                                         \
  213.         o2 = o1;                                                              \
  214.         o1 = o0;                                                              \
  215.         if (need_clipping && o0 < min) {                                      \
  216.             av_log(NULL, AV_LOG_WARNING, "clipping\n");                       \
  217.             obuf[i] = min;                                                    \
  218.         } else if (need_clipping && o0 > max) {                               \
  219.             av_log(NULL, AV_LOG_WARNING, "clipping\n");                       \
  220.             obuf[i] = max;                                                    \
  221.         } else {                                                              \
  222.             obuf[i] = o0;                                                     \
  223.         }                                                                     \
  224.     }                                                                         \
  225.     *in1  = i1;                                                               \
  226.     *in2  = i2;                                                               \
  227.     *out1 = o1;                                                               \
  228.     *out2 = o2;                                                               \
  229. }
  230.  
  231. BIQUAD_FILTER(s16, int16_t, INT16_MIN, INT16_MAX, 1)
  232. BIQUAD_FILTER(s32, int32_t, INT32_MIN, INT32_MAX, 1)
  233. BIQUAD_FILTER(flt, float,   -1., 1., 0)
  234. BIQUAD_FILTER(dbl, double,  -1., 1., 0)
  235.  
  236. static int config_output(AVFilterLink *outlink)
  237. {
  238.     AVFilterContext *ctx    = outlink->src;
  239.     BiquadsContext *s       = ctx->priv;
  240.     AVFilterLink *inlink    = ctx->inputs[0];
  241.     double A = exp(s->gain / 40 * log(10.));
  242.     double w0 = 2 * M_PI * s->frequency / inlink->sample_rate;
  243.     double alpha;
  244.  
  245.     if (w0 > M_PI) {
  246.         av_log(ctx, AV_LOG_ERROR,
  247.                "Invalid frequency %f. Frequency must be less than half the sample-rate %d.\n",
  248.                s->frequency, inlink->sample_rate);
  249.         return AVERROR(EINVAL);
  250.     }
  251.  
  252.     switch (s->width_type) {
  253.     case NONE:
  254.         alpha = 0.0;
  255.         break;
  256.     case HERTZ:
  257.         alpha = sin(w0) / (2 * s->frequency / s->width);
  258.         break;
  259.     case OCTAVE:
  260.         alpha = sin(w0) * sinh(log(2.) / 2 * s->width * w0 / sin(w0));
  261.         break;
  262.     case QFACTOR:
  263.         alpha = sin(w0) / (2 * s->width);
  264.         break;
  265.     case SLOPE:
  266.         alpha = sin(w0) / 2 * sqrt((A + 1 / A) * (1 / s->width - 1) + 2);
  267.         break;
  268.     default:
  269.         av_assert0(0);
  270.     }
  271.  
  272.     switch (s->filter_type) {
  273.     case biquad:
  274.         break;
  275.     case equalizer:
  276.         s->a0 =   1 + alpha / A;
  277.         s->a1 =  -2 * cos(w0);
  278.         s->a2 =   1 - alpha / A;
  279.         s->b0 =   1 + alpha * A;
  280.         s->b1 =  -2 * cos(w0);
  281.         s->b2 =   1 - alpha * A;
  282.         break;
  283.     case bass:
  284.         s->a0 =          (A + 1) + (A - 1) * cos(w0) + 2 * sqrt(A) * alpha;
  285.         s->a1 =    -2 * ((A - 1) + (A + 1) * cos(w0));
  286.         s->a2 =          (A + 1) + (A - 1) * cos(w0) - 2 * sqrt(A) * alpha;
  287.         s->b0 =     A * ((A + 1) - (A - 1) * cos(w0) + 2 * sqrt(A) * alpha);
  288.         s->b1 = 2 * A * ((A - 1) - (A + 1) * cos(w0));
  289.         s->b2 =     A * ((A + 1) - (A - 1) * cos(w0) - 2 * sqrt(A) * alpha);
  290.         break;
  291.     case treble:
  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);
  298.         break;
  299.     case bandpass:
  300.         if (s->csg) {
  301.             s->a0 =  1 + alpha;
  302.             s->a1 = -2 * cos(w0);
  303.             s->a2 =  1 - alpha;
  304.             s->b0 =  sin(w0) / 2;
  305.             s->b1 =  0;
  306.             s->b2 = -sin(w0) / 2;
  307.         } else {
  308.             s->a0 =  1 + alpha;
  309.             s->a1 = -2 * cos(w0);
  310.             s->a2 =  1 - alpha;
  311.             s->b0 =  alpha;
  312.             s->b1 =  0;
  313.             s->b2 = -alpha;
  314.         }
  315.         break;
  316.     case bandreject:
  317.         s->a0 =  1 + alpha;
  318.         s->a1 = -2 * cos(w0);
  319.         s->a2 =  1 - alpha;
  320.         s->b0 =  1;
  321.         s->b1 = -2 * cos(w0);
  322.         s->b2 =  1;
  323.         break;
  324.     case lowpass:
  325.         if (s->poles == 1) {
  326.             s->a0 = 1;
  327.             s->a1 = -exp(-w0);
  328.             s->a2 = 0;
  329.             s->b0 = 1 + s->a1;
  330.             s->b1 = 0;
  331.             s->b2 = 0;
  332.         } else {
  333.             s->a0 =  1 + alpha;
  334.             s->a1 = -2 * cos(w0);
  335.             s->a2 =  1 - alpha;
  336.             s->b0 = (1 - cos(w0)) / 2;
  337.             s->b1 =  1 - cos(w0);
  338.             s->b2 = (1 - cos(w0)) / 2;
  339.         }
  340.         break;
  341.     case highpass:
  342.         if (s->poles == 1) {
  343.             s->a0 = 1;
  344.             s->a1 = -exp(-w0);
  345.             s->a2 = 0;
  346.             s->b0 = (1 - s->a1) / 2;
  347.             s->b1 = -s->b0;
  348.             s->b2 = 0;
  349.         } else {
  350.             s->a0 =   1 + alpha;
  351.             s->a1 =  -2 * cos(w0);
  352.             s->a2 =   1 - alpha;
  353.             s->b0 =  (1 + cos(w0)) / 2;
  354.             s->b1 = -(1 + cos(w0));
  355.             s->b2 =  (1 + cos(w0)) / 2;
  356.         }
  357.         break;
  358.     case allpass:
  359.         s->a0 =  1 + alpha;
  360.         s->a1 = -2 * cos(w0);
  361.         s->a2 =  1 - alpha;
  362.         s->b0 =  1 - alpha;
  363.         s->b1 = -2 * cos(w0);
  364.         s->b2 =  1 + alpha;
  365.         break;
  366.     default:
  367.         av_assert0(0);
  368.     }
  369.  
  370.     s->a1 /= s->a0;
  371.     s->a2 /= s->a0;
  372.     s->b0 /= s->a0;
  373.     s->b1 /= s->a0;
  374.     s->b2 /= s->a0;
  375.  
  376.     s->cache = av_realloc_f(s->cache, sizeof(ChanCache), inlink->channels);
  377.     if (!s->cache)
  378.         return AVERROR(ENOMEM);
  379.     memset(s->cache, 0, sizeof(ChanCache) * inlink->channels);
  380.  
  381.     switch (inlink->format) {
  382.     case AV_SAMPLE_FMT_S16P: s->filter = biquad_s16; break;
  383.     case AV_SAMPLE_FMT_S32P: s->filter = biquad_s32; break;
  384.     case AV_SAMPLE_FMT_FLTP: s->filter = biquad_flt; break;
  385.     case AV_SAMPLE_FMT_DBLP: s->filter = biquad_dbl; break;
  386.     default: av_assert0(0);
  387.     }
  388.  
  389.     return 0;
  390. }
  391.  
  392. static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
  393. {
  394.     BiquadsContext *s       = inlink->dst->priv;
  395.     AVFilterLink *outlink   = inlink->dst->outputs[0];
  396.     AVFrame *out_buf;
  397.     int nb_samples = buf->nb_samples;
  398.     int ch;
  399.  
  400.     if (av_frame_is_writable(buf)) {
  401.         out_buf = buf;
  402.     } else {
  403.         out_buf = ff_get_audio_buffer(inlink, nb_samples);
  404.         if (!out_buf)
  405.             return AVERROR(ENOMEM);
  406.         av_frame_copy_props(out_buf, buf);
  407.     }
  408.  
  409.     for (ch = 0; ch < av_frame_get_channels(buf); ch++)
  410.         s->filter(buf->extended_data[ch],
  411.                   out_buf->extended_data[ch], nb_samples,
  412.                   &s->cache[ch].i1, &s->cache[ch].i2,
  413.                   &s->cache[ch].o1, &s->cache[ch].o2,
  414.                   s->b0, s->b1, s->b2, s->a1, s->a2);
  415.  
  416.     if (buf != out_buf)
  417.         av_frame_free(&buf);
  418.  
  419.     return ff_filter_frame(outlink, out_buf);
  420. }
  421.  
  422. static av_cold void uninit(AVFilterContext *ctx)
  423. {
  424.     BiquadsContext *s = ctx->priv;
  425.  
  426.     av_freep(&s->cache);
  427. }
  428.  
  429. static const AVFilterPad inputs[] = {
  430.     {
  431.         .name         = "default",
  432.         .type         = AVMEDIA_TYPE_AUDIO,
  433.         .filter_frame = filter_frame,
  434.     },
  435.     { NULL }
  436. };
  437.  
  438. static const AVFilterPad outputs[] = {
  439.     {
  440.         .name         = "default",
  441.         .type         = AVMEDIA_TYPE_AUDIO,
  442.         .config_props = config_output,
  443.     },
  444.     { NULL }
  445. };
  446.  
  447. #define OFFSET(x) offsetof(BiquadsContext, x)
  448. #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
  449.  
  450. #define DEFINE_BIQUAD_FILTER(name_, description_)                       \
  451. AVFILTER_DEFINE_CLASS(name_);                                           \
  452. static av_cold int name_##_init(AVFilterContext *ctx) \
  453. {                                                                       \
  454.     BiquadsContext *s = ctx->priv;                                      \
  455.     s->class = &name_##_class;                                          \
  456.     s->filter_type = name_;                                             \
  457.     return init(ctx);                                             \
  458. }                                                                       \
  459.                                                          \
  460. AVFilter ff_af_##name_ = {                         \
  461.     .name          = #name_,                             \
  462.     .description   = NULL_IF_CONFIG_SMALL(description_), \
  463.     .priv_size     = sizeof(BiquadsContext),             \
  464.     .init          = name_##_init,                       \
  465.     .uninit        = uninit,                             \
  466.     .query_formats = query_formats,                      \
  467.     .inputs        = inputs,                             \
  468.     .outputs       = outputs,                            \
  469.     .priv_class    = &name_##_class,                     \
  470. }
  471.  
  472. #if CONFIG_EQUALIZER_FILTER
  473. static const AVOption equalizer_options[] = {
  474.     {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 999999, FLAGS},
  475.     {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 999999, FLAGS},
  476.     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"},
  477.     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
  478.     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
  479.     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
  480.     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
  481.     {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 999, FLAGS},
  482.     {"w",     "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 999, FLAGS},
  483.     {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
  484.     {"g",    "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
  485.     {NULL}
  486. };
  487.  
  488. DEFINE_BIQUAD_FILTER(equalizer, "Apply two-pole peaking equalization (EQ) filter.");
  489. #endif  /* CONFIG_EQUALIZER_FILTER */
  490. #if CONFIG_BASS_FILTER
  491. static const AVOption bass_options[] = {
  492.     {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
  493.     {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
  494.     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"},
  495.     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
  496.     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
  497.     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
  498.     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
  499.     {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
  500.     {"w",     "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
  501.     {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
  502.     {"g",    "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
  503.     {NULL}
  504. };
  505.  
  506. DEFINE_BIQUAD_FILTER(bass, "Boost or cut lower frequencies.");
  507. #endif  /* CONFIG_BASS_FILTER */
  508. #if CONFIG_TREBLE_FILTER
  509. static const AVOption treble_options[] = {
  510.     {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  511.     {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  512.     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"},
  513.     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
  514.     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
  515.     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
  516.     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
  517.     {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
  518.     {"w",     "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
  519.     {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
  520.     {"g",    "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
  521.     {NULL}
  522. };
  523.  
  524. DEFINE_BIQUAD_FILTER(treble, "Boost or cut upper frequencies.");
  525. #endif  /* CONFIG_TREBLE_FILTER */
  526. #if CONFIG_BANDPASS_FILTER
  527. static const AVOption bandpass_options[] = {
  528.     {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  529.     {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  530.     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"},
  531.     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
  532.     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
  533.     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
  534.     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
  535.     {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 999, FLAGS},
  536.     {"w",     "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 999, FLAGS},
  537.     {"csg",   "use constant skirt gain", OFFSET(csg), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS},
  538.     {NULL}
  539. };
  540.  
  541. DEFINE_BIQUAD_FILTER(bandpass, "Apply a two-pole Butterworth band-pass filter.");
  542. #endif  /* CONFIG_BANDPASS_FILTER */
  543. #if CONFIG_BANDREJECT_FILTER
  544. static const AVOption bandreject_options[] = {
  545.     {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  546.     {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  547.     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"},
  548.     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
  549.     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
  550.     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
  551.     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
  552.     {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 999, FLAGS},
  553.     {"w",     "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 999, FLAGS},
  554.     {NULL}
  555. };
  556.  
  557. DEFINE_BIQUAD_FILTER(bandreject, "Apply a two-pole Butterworth band-reject filter.");
  558. #endif  /* CONFIG_BANDREJECT_FILTER */
  559. #if CONFIG_LOWPASS_FILTER
  560. static const AVOption lowpass_options[] = {
  561.     {"frequency", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=500}, 0, 999999, FLAGS},
  562.     {"f",         "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=500}, 0, 999999, FLAGS},
  563.     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"},
  564.     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
  565.     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
  566.     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
  567.     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
  568.     {"width", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
  569.     {"w",     "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
  570.     {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
  571.     {"p",     "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
  572.     {NULL}
  573. };
  574.  
  575. DEFINE_BIQUAD_FILTER(lowpass, "Apply a low-pass filter with 3dB point frequency.");
  576. #endif  /* CONFIG_LOWPASS_FILTER */
  577. #if CONFIG_HIGHPASS_FILTER
  578. static const AVOption highpass_options[] = {
  579.     {"frequency", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  580.     {"f",         "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  581.     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"},
  582.     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
  583.     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
  584.     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
  585.     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
  586.     {"width", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
  587.     {"w",     "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
  588.     {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
  589.     {"p",     "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
  590.     {NULL}
  591. };
  592.  
  593. DEFINE_BIQUAD_FILTER(highpass, "Apply a high-pass filter with 3dB point frequency.");
  594. #endif  /* CONFIG_HIGHPASS_FILTER */
  595. #if CONFIG_ALLPASS_FILTER
  596. static const AVOption allpass_options[] = {
  597.     {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  598.     {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  599.     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=HERTZ}, HERTZ, SLOPE, FLAGS, "width_type"},
  600.     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
  601.     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
  602.     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
  603.     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
  604.     {"width", "set filter-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=707.1}, 0, 99999, FLAGS},
  605.     {"w",     "set filter-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=707.1}, 0, 99999, FLAGS},
  606.     {NULL}
  607. };
  608.  
  609. DEFINE_BIQUAD_FILTER(allpass, "Apply a two-pole all-pass filter.");
  610. #endif  /* CONFIG_ALLPASS_FILTER */
  611. #if CONFIG_BIQUAD_FILTER
  612. static const AVOption biquad_options[] = {
  613.     {"a0", NULL, OFFSET(a0), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT16_MIN, INT16_MAX, FLAGS},
  614.     {"a1", NULL, OFFSET(a1), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT16_MIN, INT16_MAX, FLAGS},
  615.     {"a2", NULL, OFFSET(a2), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT16_MIN, INT16_MAX, FLAGS},
  616.     {"b0", NULL, OFFSET(b0), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT16_MIN, INT16_MAX, FLAGS},
  617.     {"b1", NULL, OFFSET(b1), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT16_MIN, INT16_MAX, FLAGS},
  618.     {"b2", NULL, OFFSET(b2), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT16_MIN, INT16_MAX, FLAGS},
  619.     {NULL}
  620. };
  621.  
  622. DEFINE_BIQUAD_FILTER(biquad, "Apply a biquad IIR filter with the given coefficients.");
  623. #endif  /* CONFIG_BIQUAD_FILTER */
  624.