diff --git a/doc/filters.texi b/doc/filters.texi index 28458893e8..12113d7802 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -1054,12 +1054,16 @@ Set the mode of filter operation, can be one of the following: @table @samp @item listen Output only isolated detection signal. -@item cut +@item cutbelow +Cut frequencies below detection threshold. +@item cutabove Cut frequencies above detection threshold. -@item boost -Boost frequencies bellow detection threshold. +@item boostbelow +Boost frequencies below detection threshold. +@item boostabove +Boost frequencies above detection threshold. @end table -Default mode is @samp{cut}. +Default mode is @samp{cutbelow}. @item dftype Set the type of detection filter, can be one of the following: @@ -1082,16 +1086,6 @@ Set the type of target filter, can be one of the following: @end table Default type is @samp{bell}. -@item direction -Set processing direction relative to threshold. -@table @samp -@item downward -Boost/Cut if threshold is higher/lower than detected volume. -@item upward -Boost/Cut if threshold is lower/higher than detected volume. -@end table -Default direction is @samp{downward}. - @item auto Automatically gather threshold from detection filter. By default is @samp{disabled}. diff --git a/libavfilter/adynamicequalizer_template.c b/libavfilter/adynamicequalizer_template.c index 5667b50b1d..617ab95b09 100644 --- a/libavfilter/adynamicequalizer_template.c +++ b/libavfilter/adynamicequalizer_template.c @@ -157,7 +157,6 @@ static int fn(filter_channels)(AVFilterContext *ctx, void *arg, int jobnr, int n const int start = (in->ch_layout.nb_channels * jobnr) / nb_jobs; const int end = (in->ch_layout.nb_channels * (jobnr+1)) / nb_jobs; const int detection = s->detection; - const int direction = s->direction; const int tftype = s->tftype; const int mode = s->mode; const ftype *da = fn(s->da); @@ -177,7 +176,7 @@ static int fn(filter_channels)(AVFilterContext *ctx, void *arg, int jobnr, int n fn(cc->threshold) = threshold; for (int n = 0; n < out->nb_samples; n++) { - ftype detect, v, listen; + ftype detect, v, listen, new_gain = ONE; ftype k, g; detect = listen = fn(get_svf)(src[n], dm, da, dstate); @@ -186,31 +185,38 @@ static int fn(filter_channels)(AVFilterContext *ctx, void *arg, int jobnr, int n if (detection > 0) fn(cc->threshold) = FMAX(fn(cc->threshold), detect); - if (mode >= 0) { - if (direction == 0 && detect < threshold) { - detect = CLIP(ONE + makeup + (threshold - detect) * ratio, ONE, range); - if (!mode) - detect = ONE / detect; - } else if (direction == 1 && detect > threshold) { - detect = CLIP(ONE + makeup + (detect - threshold) * ratio, ONE, range); - if (!mode) - detect = ONE / detect; - } else { - detect = ONE; - } - - { - ftype delta = detect - gain; - - if (delta > EPSILON) - detect = gain + attack * delta; - else if (delta < -EPSILON) - detect = gain + release * delta; - } + switch (mode) { + case LISTEN: + break; + case CUT_BELOW: + if (detect < threshold) + new_gain = ONE / CLIP(ONE + makeup + (threshold - detect) * ratio, ONE, range); + break; + case CUT_ABOVE: + if (detect > threshold) + new_gain = ONE / CLIP(ONE + makeup + (detect - threshold) * ratio, ONE, range); + break; + case BOOST_BELOW: + if (detect < threshold) + new_gain = CLIP(ONE + makeup + (threshold - detect) * ratio, ONE, range); + break; + case BOOST_ABOVE: + if (detect > threshold) + new_gain = CLIP(ONE + makeup + (detect - threshold) * ratio, ONE, range); + break; } - if (gain != detect) { - gain = detect; + if (mode > LISTEN) { + ftype delta = new_gain - gain; + + if (delta > EPSILON) + new_gain = gain + attack * delta; + else if (delta < -EPSILON) + new_gain = gain + release * delta; + } + + if (gain != new_gain) { + gain = new_gain; switch (tftype) { case 0: diff --git a/libavfilter/af_adynamicequalizer.c b/libavfilter/af_adynamicequalizer.c index a84e8e5f57..04c7734c3e 100644 --- a/libavfilter/af_adynamicequalizer.c +++ b/libavfilter/af_adynamicequalizer.c @@ -23,6 +23,15 @@ #include "audio.h" #include "formats.h" +enum FilterModes { + LISTEN = -1, + CUT_BELOW, + CUT_ABOVE, + BOOST_BELOW, + BOOST_ABOVE, + NB_MODES, +}; + typedef struct ChannelContext { double fa_double[3], fm_double[3]; double dstate_double[2]; @@ -52,7 +61,6 @@ typedef struct AudioDynamicEqualizerContext { double attack_coef; double release_coef; int mode; - int direction; int detection; int tftype; int dftype; @@ -179,10 +187,12 @@ static const AVOption adynamicequalizer_options[] = { { "ratio", "set ratio factor", OFFSET(ratio), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 30, FLAGS }, { "makeup", "set makeup gain", OFFSET(makeup), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 100, FLAGS }, { "range", "set max gain", OFFSET(range), AV_OPT_TYPE_DOUBLE, {.dbl=50}, 1, 200, FLAGS }, - { "mode", "set mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=0}, -1, 1, FLAGS, "mode" }, - { "listen", 0, 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, FLAGS, "mode" }, - { "cut", 0, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "mode" }, - { "boost", 0, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "mode" }, + { "mode", "set mode", OFFSET(mode), AV_OPT_TYPE_INT, {.i64=0}, LISTEN,NB_MODES-1,FLAGS, "mode" }, + { "listen", 0, 0, AV_OPT_TYPE_CONST, {.i64=LISTEN}, 0, 0, FLAGS, "mode" }, + { "cutbelow", 0, 0, AV_OPT_TYPE_CONST, {.i64=CUT_BELOW},0, 0, FLAGS, "mode" }, + { "cutabove", 0, 0, AV_OPT_TYPE_CONST, {.i64=CUT_ABOVE},0, 0, FLAGS, "mode" }, + { "boostbelow", 0, 0, AV_OPT_TYPE_CONST, {.i64=BOOST_BELOW},0, 0, FLAGS, "mode" }, + { "boostabove", 0, 0, AV_OPT_TYPE_CONST, {.i64=BOOST_ABOVE},0, 0, FLAGS, "mode" }, { "dftype", "set detection filter type",OFFSET(dftype), AV_OPT_TYPE_INT, {.i64=0}, 0, 3, FLAGS, "dftype" }, { "bandpass", 0, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "dftype" }, { "lowpass", 0, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "dftype" }, @@ -192,9 +202,6 @@ static const AVOption adynamicequalizer_options[] = { { "bell", 0, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "tftype" }, { "lowshelf", 0, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "tftype" }, { "highshelf",0, 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGS, "tftype" }, - { "direction", "set direction", OFFSET(direction), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "direction" }, - { "downward", 0, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "direction" }, - { "upward", 0, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "direction" }, { "auto", "set auto threshold", OFFSET(detection), AV_OPT_TYPE_INT, {.i64=-1}, -1, 1, FLAGS, "auto" }, { "disabled", 0, 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, FLAGS, "auto" }, { "off", 0, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "auto" },