Subversion Repositories Kolibri OS

Rev

Go to most recent revision | 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.     enum WidthType 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 *p = ctx->priv;
  122.  
  123.     if (p->filter_type != biquad) {
  124.         if (p->frequency <= 0 || p->width <= 0) {
  125.             av_log(ctx, AV_LOG_ERROR, "Invalid frequency %f and/or width %f <= 0\n",
  126.                    p->frequency, p->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.  
  146.     layouts = ff_all_channel_layouts();
  147.     if (!layouts)
  148.         return AVERROR(ENOMEM);
  149.     ff_set_common_channel_layouts(ctx, layouts);
  150.  
  151.     formats = ff_make_format_list(sample_fmts);
  152.     if (!formats)
  153.         return AVERROR(ENOMEM);
  154.     ff_set_common_formats(ctx, formats);
  155.  
  156.     formats = ff_all_samplerates();
  157.     if (!formats)
  158.         return AVERROR(ENOMEM);
  159.     ff_set_common_samplerates(ctx, formats);
  160.  
  161.     return 0;
  162. }
  163.  
  164. #define BIQUAD_FILTER(name, type, min, max)                                   \
  165. static void biquad_## name (const void *input, void *output, int len,         \
  166.                             double *in1, double *in2,                         \
  167.                             double *out1, double *out2,                       \
  168.                             double b0, double b1, double b2,                  \
  169.                             double a1, double a2)                             \
  170. {                                                                             \
  171.     const type *ibuf = input;                                                 \
  172.     type *obuf = output;                                                      \
  173.     double i1 = *in1;                                                         \
  174.     double i2 = *in2;                                                         \
  175.     double o1 = *out1;                                                        \
  176.     double o2 = *out2;                                                        \
  177.     int i;                                                                    \
  178.     a1 = -a1;                                                                 \
  179.     a2 = -a2;                                                                 \
  180.                                                                               \
  181.     for (i = 0; i+1 < len; i++) {                                             \
  182.         o2 = i2 * b2 + i1 * b1 + ibuf[i] * b0 + o2 * a2 + o1 * a1;            \
  183.         i2 = ibuf[i];                                                         \
  184.         if (o2 < min) {                                                       \
  185.             av_log(NULL, AV_LOG_WARNING, "clipping\n");                       \
  186.             obuf[i] = min;                                                    \
  187.         } else if (o2 > max) {                                                \
  188.             av_log(NULL, AV_LOG_WARNING, "clipping\n");                       \
  189.             obuf[i] = max;                                                    \
  190.         } else {                                                              \
  191.             obuf[i] = o2;                                                     \
  192.         }                                                                     \
  193.         i++;                                                                  \
  194.         o1 = i1 * b2 + i2 * b1 + ibuf[i] * b0 + o1 * a2 + o2 * a1;            \
  195.         i1 = ibuf[i];                                                         \
  196.         if (o1 < min) {                                                       \
  197.             av_log(NULL, AV_LOG_WARNING, "clipping\n");                       \
  198.             obuf[i] = min;                                                    \
  199.         } else if (o1 > max) {                                                \
  200.             av_log(NULL, AV_LOG_WARNING, "clipping\n");                       \
  201.             obuf[i] = max;                                                    \
  202.         } else {                                                              \
  203.             obuf[i] = o1;                                                     \
  204.         }                                                                     \
  205.     }                                                                         \
  206.     if (i < len) {                                                            \
  207.         double o0 = ibuf[i] * b0 + i1 * b1 + i2 * b2 + o1 * a1 + o2 * a2;     \
  208.         i2 = i1;                                                              \
  209.         i1 = ibuf[i];                                                         \
  210.         o2 = o1;                                                              \
  211.         o1 = o0;                                                              \
  212.         if (o0 < min) {                                                       \
  213.             av_log(NULL, AV_LOG_WARNING, "clipping\n");                       \
  214.             obuf[i] = min;                                                    \
  215.         } else if (o0 > max) {                                                \
  216.             av_log(NULL, AV_LOG_WARNING, "clipping\n");                       \
  217.             obuf[i] = max;                                                    \
  218.         } else {                                                              \
  219.             obuf[i] = o0;                                                     \
  220.         }                                                                     \
  221.     }                                                                         \
  222.     *in1  = i1;                                                               \
  223.     *in2  = i2;                                                               \
  224.     *out1 = o1;                                                               \
  225.     *out2 = o2;                                                               \
  226. }
  227.  
  228. BIQUAD_FILTER(s16, int16_t, INT16_MIN, INT16_MAX)
  229. BIQUAD_FILTER(s32, int32_t, INT32_MIN, INT32_MAX)
  230. BIQUAD_FILTER(flt, float,   -1., 1.)
  231. BIQUAD_FILTER(dbl, double,  -1., 1.)
  232.  
  233. static int config_output(AVFilterLink *outlink)
  234. {
  235.     AVFilterContext *ctx    = outlink->src;
  236.     BiquadsContext *p       = ctx->priv;
  237.     AVFilterLink *inlink    = ctx->inputs[0];
  238.     double A = exp(p->gain / 40 * log(10.));
  239.     double w0 = 2 * M_PI * p->frequency / inlink->sample_rate;
  240.     double alpha;
  241.  
  242.     if (w0 > M_PI) {
  243.         av_log(ctx, AV_LOG_ERROR,
  244.                "Invalid frequency %f. Frequency must be less than half the sample-rate %d.\n",
  245.                p->frequency, inlink->sample_rate);
  246.         return AVERROR(EINVAL);
  247.     }
  248.  
  249.     switch (p->width_type) {
  250.     case NONE:
  251.         alpha = 0.0;
  252.         break;
  253.     case HERTZ:
  254.         alpha = sin(w0) / (2 * p->frequency / p->width);
  255.         break;
  256.     case OCTAVE:
  257.         alpha = sin(w0) * sinh(log(2.) / 2 * p->width * w0 / sin(w0));
  258.         break;
  259.     case QFACTOR:
  260.         alpha = sin(w0) / (2 * p->width);
  261.         break;
  262.     case SLOPE:
  263.         alpha = sin(w0) / 2 * sqrt((A + 1 / A) * (1 / p->width - 1) + 2);
  264.         break;
  265.     default:
  266.         av_assert0(0);
  267.     }
  268.  
  269.     switch (p->filter_type) {
  270.     case biquad:
  271.         break;
  272.     case equalizer:
  273.         p->a0 =   1 + alpha / A;
  274.         p->a1 =  -2 * cos(w0);
  275.         p->a2 =   1 - alpha / A;
  276.         p->b0 =   1 + alpha * A;
  277.         p->b1 =  -2 * cos(w0);
  278.         p->b2 =   1 - alpha * A;
  279.         break;
  280.     case bass:
  281.         p->a0 =          (A + 1) + (A - 1) * cos(w0) + 2 * sqrt(A) * alpha;
  282.         p->a1 =    -2 * ((A - 1) + (A + 1) * cos(w0));
  283.         p->a2 =          (A + 1) + (A - 1) * cos(w0) - 2 * sqrt(A) * alpha;
  284.         p->b0 =     A * ((A + 1) - (A - 1) * cos(w0) + 2 * sqrt(A) * alpha);
  285.         p->b1 = 2 * A * ((A - 1) - (A + 1) * cos(w0));
  286.         p->b2 =     A * ((A + 1) - (A - 1) * cos(w0) - 2 * sqrt(A) * alpha);
  287.         break;
  288.     case treble:
  289.         p->a0 =          (A + 1) - (A - 1) * cos(w0) + 2 * sqrt(A) * alpha;
  290.         p->a1 =     2 * ((A - 1) - (A + 1) * cos(w0));
  291.         p->a2 =          (A + 1) - (A - 1) * cos(w0) - 2 * sqrt(A) * alpha;
  292.         p->b0 =     A * ((A + 1) + (A - 1) * cos(w0) + 2 * sqrt(A) * alpha);
  293.         p->b1 =-2 * A * ((A - 1) + (A + 1) * cos(w0));
  294.         p->b2 =     A * ((A + 1) + (A - 1) * cos(w0) - 2 * sqrt(A) * alpha);
  295.         break;
  296.     case bandpass:
  297.         if (p->csg) {
  298.             p->a0 =  1 + alpha;
  299.             p->a1 = -2 * cos(w0);
  300.             p->a2 =  1 - alpha;
  301.             p->b0 =  sin(w0) / 2;
  302.             p->b1 =  0;
  303.             p->b2 = -sin(w0) / 2;
  304.         } else {
  305.             p->a0 =  1 + alpha;
  306.             p->a1 = -2 * cos(w0);
  307.             p->a2 =  1 - alpha;
  308.             p->b0 =  alpha;
  309.             p->b1 =  0;
  310.             p->b2 = -alpha;
  311.         }
  312.         break;
  313.     case bandreject:
  314.         p->a0 =  1 + alpha;
  315.         p->a1 = -2 * cos(w0);
  316.         p->a2 =  1 - alpha;
  317.         p->b0 =  1;
  318.         p->b1 = -2 * cos(w0);
  319.         p->b2 =  1;
  320.         break;
  321.     case lowpass:
  322.         if (p->poles == 1) {
  323.             p->a0 = 1;
  324.             p->a1 = -exp(-w0);
  325.             p->a2 = 0;
  326.             p->b0 = 1 + p->a1;
  327.             p->b1 = 0;
  328.             p->b2 = 0;
  329.         } else {
  330.             p->a0 =  1 + alpha;
  331.             p->a1 = -2 * cos(w0);
  332.             p->a2 =  1 - alpha;
  333.             p->b0 = (1 - cos(w0)) / 2;
  334.             p->b1 =  1 - cos(w0);
  335.             p->b2 = (1 - cos(w0)) / 2;
  336.         }
  337.         break;
  338.     case highpass:
  339.         if (p->poles == 1) {
  340.             p->a0 = 1;
  341.             p->a1 = -exp(-w0);
  342.             p->a2 = 0;
  343.             p->b0 = (1 - p->a1) / 2;
  344.             p->b1 = -p->b0;
  345.             p->b2 = 0;
  346.         } else {
  347.             p->a0 =   1 + alpha;
  348.             p->a1 =  -2 * cos(w0);
  349.             p->a2 =   1 - alpha;
  350.             p->b0 =  (1 + cos(w0)) / 2;
  351.             p->b1 = -(1 + cos(w0));
  352.             p->b2 =  (1 + cos(w0)) / 2;
  353.         }
  354.         break;
  355.     case allpass:
  356.         p->a0 =  1 + alpha;
  357.         p->a1 = -2 * cos(w0);
  358.         p->a2 =  1 - alpha;
  359.         p->b0 =  1 - alpha;
  360.         p->b1 = -2 * cos(w0);
  361.         p->b2 =  1 + alpha;
  362.         break;
  363.     default:
  364.         av_assert0(0);
  365.     }
  366.  
  367.     p->a1 /= p->a0;
  368.     p->a2 /= p->a0;
  369.     p->b0 /= p->a0;
  370.     p->b1 /= p->a0;
  371.     p->b2 /= p->a0;
  372.  
  373.     p->cache = av_realloc_f(p->cache, sizeof(ChanCache), inlink->channels);
  374.     if (!p->cache)
  375.         return AVERROR(ENOMEM);
  376.     memset(p->cache, 0, sizeof(ChanCache) * inlink->channels);
  377.  
  378.     switch (inlink->format) {
  379.     case AV_SAMPLE_FMT_S16P: p->filter = biquad_s16; break;
  380.     case AV_SAMPLE_FMT_S32P: p->filter = biquad_s32; break;
  381.     case AV_SAMPLE_FMT_FLTP: p->filter = biquad_flt; break;
  382.     case AV_SAMPLE_FMT_DBLP: p->filter = biquad_dbl; break;
  383.     default: av_assert0(0);
  384.     }
  385.  
  386.     return 0;
  387. }
  388.  
  389. static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
  390. {
  391.     BiquadsContext *p       = inlink->dst->priv;
  392.     AVFilterLink *outlink   = inlink->dst->outputs[0];
  393.     AVFrame *out_buf;
  394.     int nb_samples = buf->nb_samples;
  395.     int ch;
  396.  
  397.     if (av_frame_is_writable(buf)) {
  398.         out_buf = buf;
  399.     } else {
  400.         out_buf = ff_get_audio_buffer(inlink, nb_samples);
  401.         if (!out_buf)
  402.             return AVERROR(ENOMEM);
  403.         av_frame_copy_props(out_buf, buf);
  404.     }
  405.  
  406.     for (ch = 0; ch < av_frame_get_channels(buf); ch++)
  407.         p->filter(buf->extended_data[ch],
  408.                   out_buf->extended_data[ch], nb_samples,
  409.                   &p->cache[ch].i1, &p->cache[ch].i2,
  410.                   &p->cache[ch].o1, &p->cache[ch].o2,
  411.                   p->b0, p->b1, p->b2, p->a1, p->a2);
  412.  
  413.     if (buf != out_buf)
  414.         av_frame_free(&buf);
  415.  
  416.     return ff_filter_frame(outlink, out_buf);
  417. }
  418.  
  419. static av_cold void uninit(AVFilterContext *ctx)
  420. {
  421.     BiquadsContext *p = ctx->priv;
  422.  
  423.     av_freep(&p->cache);
  424. }
  425.  
  426. static const AVFilterPad inputs[] = {
  427.     {
  428.         .name         = "default",
  429.         .type         = AVMEDIA_TYPE_AUDIO,
  430.         .filter_frame = filter_frame,
  431.     },
  432.     { NULL }
  433. };
  434.  
  435. static const AVFilterPad outputs[] = {
  436.     {
  437.         .name         = "default",
  438.         .type         = AVMEDIA_TYPE_AUDIO,
  439.         .config_props = config_output,
  440.     },
  441.     { NULL }
  442. };
  443.  
  444. #define OFFSET(x) offsetof(BiquadsContext, x)
  445. #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
  446.  
  447. #define DEFINE_BIQUAD_FILTER(name_, description_)                       \
  448. AVFILTER_DEFINE_CLASS(name_);                                           \
  449. static av_cold int name_##_init(AVFilterContext *ctx) \
  450. {                                                                       \
  451.     BiquadsContext *p = ctx->priv;                                      \
  452.     p->class = &name_##_class;                                          \
  453.     p->filter_type = name_;                                             \
  454.     return init(ctx);                                             \
  455. }                                                                       \
  456.                                                          \
  457. AVFilter avfilter_af_##name_ = {                         \
  458.     .name          = #name_,                             \
  459.     .description   = NULL_IF_CONFIG_SMALL(description_), \
  460.     .priv_size     = sizeof(BiquadsContext),             \
  461.     .init          = name_##_init,                       \
  462.     .uninit        = uninit,                             \
  463.     .query_formats = query_formats,                      \
  464.     .inputs        = inputs,                             \
  465.     .outputs       = outputs,                            \
  466.     .priv_class    = &name_##_class,                     \
  467. }
  468.  
  469. #if CONFIG_EQUALIZER_FILTER
  470. static const AVOption equalizer_options[] = {
  471.     {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 999999, FLAGS},
  472.     {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 999999, FLAGS},
  473.     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"},
  474.     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
  475.     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
  476.     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
  477.     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
  478.     {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 999, FLAGS},
  479.     {"w",     "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 999, FLAGS},
  480.     {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
  481.     {"g",    "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
  482.     {NULL}
  483. };
  484.  
  485. DEFINE_BIQUAD_FILTER(equalizer, "Apply two-pole peaking equalization (EQ) filter.");
  486. #endif  /* CONFIG_EQUALIZER_FILTER */
  487. #if CONFIG_BASS_FILTER
  488. static const AVOption bass_options[] = {
  489.     {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
  490.     {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
  491.     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"},
  492.     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
  493.     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
  494.     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
  495.     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
  496.     {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
  497.     {"w",     "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
  498.     {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
  499.     {"g",    "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
  500.     {NULL}
  501. };
  502.  
  503. DEFINE_BIQUAD_FILTER(bass, "Boost or cut lower frequencies.");
  504. #endif  /* CONFIG_BASS_FILTER */
  505. #if CONFIG_TREBLE_FILTER
  506. static const AVOption treble_options[] = {
  507.     {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  508.     {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  509.     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"},
  510.     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
  511.     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
  512.     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
  513.     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
  514.     {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
  515.     {"w",     "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
  516.     {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
  517.     {"g",    "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
  518.     {NULL}
  519. };
  520.  
  521. DEFINE_BIQUAD_FILTER(treble, "Boost or cut upper frequencies.");
  522. #endif  /* CONFIG_TREBLE_FILTER */
  523. #if CONFIG_BANDPASS_FILTER
  524. static const AVOption bandpass_options[] = {
  525.     {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  526.     {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  527.     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"},
  528.     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
  529.     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
  530.     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
  531.     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
  532.     {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 999, FLAGS},
  533.     {"w",     "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 999, FLAGS},
  534.     {"csg",   "use constant skirt gain", OFFSET(csg), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS},
  535.     {NULL}
  536. };
  537.  
  538. DEFINE_BIQUAD_FILTER(bandpass, "Apply a two-pole Butterworth band-pass filter.");
  539. #endif  /* CONFIG_BANDPASS_FILTER */
  540. #if CONFIG_BANDREJECT_FILTER
  541. static const AVOption bandreject_options[] = {
  542.     {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  543.     {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  544.     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"},
  545.     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
  546.     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
  547.     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
  548.     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
  549.     {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 999, FLAGS},
  550.     {"w",     "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 999, FLAGS},
  551.     {NULL}
  552. };
  553.  
  554. DEFINE_BIQUAD_FILTER(bandreject, "Apply a two-pole Butterworth band-reject filter.");
  555. #endif  /* CONFIG_BANDREJECT_FILTER */
  556. #if CONFIG_LOWPASS_FILTER
  557. static const AVOption lowpass_options[] = {
  558.     {"frequency", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=500}, 0, 999999, FLAGS},
  559.     {"f",         "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=500}, 0, 999999, FLAGS},
  560.     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"},
  561.     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
  562.     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
  563.     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
  564.     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
  565.     {"width", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
  566.     {"w",     "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
  567.     {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
  568.     {"p",     "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
  569.     {NULL}
  570. };
  571.  
  572. DEFINE_BIQUAD_FILTER(lowpass, "Apply a low-pass filter with 3dB point frequency.");
  573. #endif  /* CONFIG_LOWPASS_FILTER */
  574. #if CONFIG_HIGHPASS_FILTER
  575. static const AVOption highpass_options[] = {
  576.     {"frequency", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  577.     {"f",         "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  578.     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, SLOPE, FLAGS, "width_type"},
  579.     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
  580.     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
  581.     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
  582.     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
  583.     {"width", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
  584.     {"w",     "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
  585.     {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
  586.     {"p",     "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
  587.     {NULL}
  588. };
  589.  
  590. DEFINE_BIQUAD_FILTER(highpass, "Apply a high-pass filter with 3dB point frequency.");
  591. #endif  /* CONFIG_HIGHPASS_FILTER */
  592. #if CONFIG_ALLPASS_FILTER
  593. static const AVOption allpass_options[] = {
  594.     {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  595.     {"f",         "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  596.     {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=HERTZ}, HERTZ, SLOPE, FLAGS, "width_type"},
  597.     {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
  598.     {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
  599.     {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
  600.     {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
  601.     {"width", "set filter-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=707.1}, 0, 99999, FLAGS},
  602.     {"w",     "set filter-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=707.1}, 0, 99999, FLAGS},
  603.     {NULL}
  604. };
  605.  
  606. DEFINE_BIQUAD_FILTER(allpass, "Apply a two-pole all-pass filter.");
  607. #endif  /* CONFIG_ALLPASS_FILTER */
  608. #if CONFIG_BIQUAD_FILTER
  609. static const AVOption biquad_options[] = {
  610.     {"a0", NULL, OFFSET(a0), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT16_MIN, INT16_MAX, FLAGS},
  611.     {"a1", NULL, OFFSET(a1), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT16_MIN, INT16_MAX, FLAGS},
  612.     {"a2", NULL, OFFSET(a2), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT16_MIN, INT16_MAX, FLAGS},
  613.     {"b0", NULL, OFFSET(b0), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT16_MIN, INT16_MAX, FLAGS},
  614.     {"b1", NULL, OFFSET(b1), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT16_MIN, INT16_MAX, FLAGS},
  615.     {"b2", NULL, OFFSET(b2), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT16_MIN, INT16_MAX, FLAGS},
  616.     {NULL}
  617. };
  618.  
  619. DEFINE_BIQUAD_FILTER(biquad, "Apply a biquad IIR filter with the given coefficients.");
  620. #endif  /* CONFIG_BIQUAD_FILTER */
  621.