diff options
author | Paul B Mahol <onemda@gmail.com> | 2018-04-17 11:31:34 +0200 |
---|---|---|
committer | Paul B Mahol <onemda@gmail.com> | 2018-04-17 12:40:27 +0200 |
commit | 2fc12f4971a788acbd42861af90858cc0981417a (patch) | |
tree | 6ac36ba5612b7d08be8694ade02538c37ccd3f96 | |
parent | d10cefbfe50e0cee80f96d6c1007b33f3292a698 (diff) | |
download | ffmpeg-streaming-2fc12f4971a788acbd42861af90858cc0981417a.zip ffmpeg-streaming-2fc12f4971a788acbd42861af90858cc0981417a.tar.gz |
avfilter: add lowshelf and highshelf filters
These are old bass and treble filters.
Make bass and treble filters better at boosting.
Signed-off-by: Paul B Mahol <onemda@gmail.com>
-rw-r--r-- | doc/filters.texi | 4 | ||||
-rw-r--r-- | libavfilter/Makefile | 2 | ||||
-rw-r--r-- | libavfilter/af_biquads.c | 78 | ||||
-rw-r--r-- | libavfilter/allfilters.c | 2 | ||||
-rw-r--r-- | libavfilter/version.h | 2 |
5 files changed, 76 insertions, 12 deletions
diff --git a/doc/filters.texi b/doc/filters.texi index fc82ad4..77a1d49 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -2057,7 +2057,7 @@ Change bandreject width. Syntax for the command is : "@var{width}" @end table -@section bass +@section bass, lowshelf Boost or cut the bass (lower) frequencies of the audio using a two-pole shelving filter with a response similar to that of a standard @@ -4432,7 +4432,7 @@ Set LFE input volume. By default, this is @var{1}. Set LFE output volume. By default, this is @var{1}. @end table -@section treble +@section treble, highshelf Boost or cut treble (upper) frequencies of the audio using a two-pole shelving filter with a response similar to that of a standard diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 3a9fb02..7fc3de3 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -99,10 +99,12 @@ OBJS-$(CONFIG_HAAS_FILTER) += af_haas.o OBJS-$(CONFIG_HDCD_FILTER) += af_hdcd.o OBJS-$(CONFIG_HEADPHONE_FILTER) += af_headphone.o OBJS-$(CONFIG_HIGHPASS_FILTER) += af_biquads.o +OBJS-$(CONFIG_HIGHSHELF_FILTER) += af_biquads.o OBJS-$(CONFIG_JOIN_FILTER) += af_join.o OBJS-$(CONFIG_LADSPA_FILTER) += af_ladspa.o OBJS-$(CONFIG_LOUDNORM_FILTER) += af_loudnorm.o ebur128.o OBJS-$(CONFIG_LOWPASS_FILTER) += af_biquads.o +OBJS-$(CONFIG_LOWSHELF_FILTER) += af_biquads.o OBJS-$(CONFIG_LV2_FILTER) += af_lv2.o OBJS-$(CONFIG_MCOMPAND_FILTER) += af_mcompand.o OBJS-$(CONFIG_PAN_FILTER) += af_pan.o diff --git a/libavfilter/af_biquads.c b/libavfilter/af_biquads.c index d5c3823..9dfc16c 100644 --- a/libavfilter/af_biquads.c +++ b/libavfilter/af_biquads.c @@ -78,6 +78,8 @@ enum FilterType { allpass, highpass, lowpass, + lowshelf, + highshelf, }; enum WidthType { @@ -245,7 +247,7 @@ static int config_filter(AVFilterLink *outlink, int reset) AVFilterLink *inlink = ctx->inputs[0]; double A = exp(s->gain / 40 * log(10.)); double w0 = 2 * M_PI * s->frequency / inlink->sample_rate; - double alpha; + double alpha, beta; if (w0 > M_PI) { av_log(ctx, AV_LOG_ERROR, @@ -277,6 +279,8 @@ static int config_filter(AVFilterLink *outlink, int reset) av_assert0(0); } + beta = 2 * sqrt(A); + switch (s->filter_type) { case biquad: break; @@ -289,20 +293,24 @@ static int config_filter(AVFilterLink *outlink, int reset) s->b2 = 1 - alpha * A; break; case bass: - s->a0 = (A + 1) + (A - 1) * cos(w0) + 2 * sqrt(A) * alpha; + beta = sqrt((A * A + 1) - (A - 1) * (A - 1)); + case lowshelf: + s->a0 = (A + 1) + (A - 1) * cos(w0) + beta * alpha; s->a1 = -2 * ((A - 1) + (A + 1) * cos(w0)); - s->a2 = (A + 1) + (A - 1) * cos(w0) - 2 * sqrt(A) * alpha; - s->b0 = A * ((A + 1) - (A - 1) * cos(w0) + 2 * sqrt(A) * alpha); + s->a2 = (A + 1) + (A - 1) * cos(w0) - beta * alpha; + s->b0 = A * ((A + 1) - (A - 1) * cos(w0) + beta * alpha); s->b1 = 2 * A * ((A - 1) - (A + 1) * cos(w0)); - s->b2 = A * ((A + 1) - (A - 1) * cos(w0) - 2 * sqrt(A) * alpha); + s->b2 = A * ((A + 1) - (A - 1) * cos(w0) - beta * alpha); break; case treble: - s->a0 = (A + 1) - (A - 1) * cos(w0) + 2 * sqrt(A) * alpha; + beta = sqrt((A * A + 1) - (A - 1) * (A - 1)); + case highshelf: + s->a0 = (A + 1) - (A - 1) * cos(w0) + beta * alpha; s->a1 = 2 * ((A - 1) - (A + 1) * cos(w0)); - s->a2 = (A + 1) - (A - 1) * cos(w0) - 2 * sqrt(A) * alpha; - s->b0 = A * ((A + 1) + (A - 1) * cos(w0) + 2 * sqrt(A) * alpha); + s->a2 = (A + 1) - (A - 1) * cos(w0) - beta * alpha; + s->b0 = A * ((A + 1) + (A - 1) * cos(w0) + beta * alpha); s->b1 =-2 * A * ((A - 1) + (A + 1) * cos(w0)); - s->b2 = A * ((A + 1) + (A - 1) * cos(w0) - 2 * sqrt(A) * alpha); + s->b2 = A * ((A + 1) + (A - 1) * cos(w0) - beta * alpha); break; case bandpass: if (s->csg) { @@ -459,6 +467,8 @@ static int process_command(AVFilterContext *ctx, const char *cmd, const char *ar if ((!strcmp(cmd, "frequency") || !strcmp(cmd, "f")) && (s->filter_type == equalizer || + s->filter_type == lowshelf || + s->filter_type == highshelf || s->filter_type == bass || s->filter_type == treble || s->filter_type == bandpass || @@ -476,6 +486,8 @@ static int process_command(AVFilterContext *ctx, const char *cmd, const char *ar s->frequency = freq; } else if ((!strcmp(cmd, "gain") || !strcmp(cmd, "g")) && (s->filter_type == equalizer || + s->filter_type == lowshelf || + s->filter_type == highshelf || s->filter_type == bass || s->filter_type == treble)) { double gain; @@ -488,6 +500,8 @@ static int process_command(AVFilterContext *ctx, const char *cmd, const char *ar s->gain = gain; } else if ((!strcmp(cmd, "width") || !strcmp(cmd, "w")) && (s->filter_type == equalizer || + s->filter_type == lowshelf || + s->filter_type == highshelf || s->filter_type == bass || s->filter_type == treble || s->filter_type == bandpass || @@ -505,6 +519,8 @@ static int process_command(AVFilterContext *ctx, const char *cmd, const char *ar s->width = width; } else if ((!strcmp(cmd, "width_type") || !strcmp(cmd, "t")) && (s->filter_type == equalizer || + s->filter_type == lowshelf || + s->filter_type == highshelf || s->filter_type == bass || s->filter_type == treble || s->filter_type == bandpass || @@ -784,6 +800,50 @@ static const AVOption allpass_options[] = { DEFINE_BIQUAD_FILTER(allpass, "Apply a two-pole all-pass filter."); #endif /* CONFIG_ALLPASS_FILTER */ +#if CONFIG_LOWSHELF_FILTER +static const AVOption lowshelf_options[] = { + {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS}, + {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS}, + {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"}, + {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"}, + {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"}, + {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"}, + {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"}, + {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"}, + {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"}, + {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS}, + {"w", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS}, + {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS}, + {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS}, + {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, + {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, + {NULL} +}; + +DEFINE_BIQUAD_FILTER(lowshelf, "Apply a low shelf filter."); +#endif /* CONFIG_LOWSHELF_FILTER */ +#if CONFIG_HIGHSHELF_FILTER +static const AVOption highshelf_options[] = { + {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS}, + {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS}, + {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"}, + {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"}, + {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"}, + {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"}, + {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"}, + {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"}, + {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"}, + {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS}, + {"w", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS}, + {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS}, + {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS}, + {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, + {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS}, + {NULL} +}; + +DEFINE_BIQUAD_FILTER(highshelf, "Apply a high shelf filter."); +#endif /* CONFIG_HIGHSHELF_FILTER */ #if CONFIG_BIQUAD_FILTER static const AVOption biquad_options[] = { {"a0", NULL, OFFSET(a0), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT32_MIN, INT32_MAX, FLAGS}, diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index 68b2992..bd55463 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -94,10 +94,12 @@ extern AVFilter ff_af_haas; extern AVFilter ff_af_hdcd; extern AVFilter ff_af_headphone; extern AVFilter ff_af_highpass; +extern AVFilter ff_af_highshelf; extern AVFilter ff_af_join; extern AVFilter ff_af_ladspa; extern AVFilter ff_af_loudnorm; extern AVFilter ff_af_lowpass; +extern AVFilter ff_af_lowshelf; extern AVFilter ff_af_lv2; extern AVFilter ff_af_mcompand; extern AVFilter ff_af_pan; diff --git a/libavfilter/version.h b/libavfilter/version.h index 8ea68ea..1b37eb6 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -30,7 +30,7 @@ #include "libavutil/version.h" #define LIBAVFILTER_VERSION_MAJOR 7 -#define LIBAVFILTER_VERSION_MINOR 17 +#define LIBAVFILTER_VERSION_MINOR 18 #define LIBAVFILTER_VERSION_MICRO 100 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ |