avfilter/af_adynamicequalizer: add dftype option

Useful for filter selection for detection control.
This commit is contained in:
Paul B Mahol 2023-04-28 16:35:22 +02:00
parent 1b7c13e1a4
commit 51504cf279
2 changed files with 67 additions and 14 deletions

View File

@ -1007,15 +1007,15 @@ A description of the accepted options follows.
@table @option
@item threshold
Set the detection threshold used to trigger equalization.
Threshold detection is using bandpass filter.
Threshold detection is using detection filter.
Default value is 0. Allowed range is from 0 to 100.
@item dfrequency
Set the detection frequency in Hz used for bandpass filter used to trigger equalization.
Set the detection frequency in Hz used for detection filter used to trigger equalization.
Default value is 1000 Hz. Allowed range is between 2 and 1000000 Hz.
@item dqfactor
Set the detection resonance factor for bandpass filter used to trigger equalization.
Set the detection resonance factor for detection filter used to trigger equalization.
Default value is 1. Allowed range is from 0.001 to 1000.
@item tfrequency
@ -1053,7 +1053,7 @@ Set the mode of filter operation, can be one of the following:
@table @samp
@item listen
Output only isolated bandpass signal.
Output only isolated detection signal.
@item cut
Cut frequencies above detection threshold.
@item boost
@ -1061,6 +1061,17 @@ Boost frequencies bellow detection threshold.
@end table
Default mode is @samp{cut}.
@item dftype
Set the type of detection filter, can be one of the following:
@table @samp
@item bandpass
@item lowpass
@item highpass
@item peak
@end table
Default type is @samp{bandpass}.
@item tftype
Set the type of target filter, can be one of the following:

View File

@ -41,7 +41,8 @@ typedef struct AudioDynamicEqualizerContext {
int mode;
int direction;
int detection;
int type;
int tftype;
int dftype;
AVFrame *state;
} AudioDynamicEqualizerContext;
@ -105,12 +106,14 @@ static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo
const int end = (in->ch_layout.nb_channels * (jobnr+1)) / nb_jobs;
const int detection = s->detection;
const int direction = s->direction;
const int dftype = s->dftype;
const int tftype = s->tftype;
const int mode = s->mode;
const int type = s->type;
double da[3], dm[3];
double k, da[3], dm[3];
{
double k = 1. / dqfactor;
switch (dftype) {
case 0:
k = 1. / dqfactor;
da[0] = 1. / (1. + dg * (dg + k));
da[1] = dg * da[0];
@ -119,6 +122,40 @@ static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo
dm[0] = 0.;
dm[1] = k;
dm[2] = 0.;
break;
case 1:
k = 1. / dqfactor;
da[0] = 1. / (1. + dg * (dg + k));
da[1] = dg * da[0];
da[2] = dg * da[1];
dm[0] = 0.;
dm[1] = 0.;
dm[2] = 1.;
break;
case 2:
k = 1. / dqfactor;
da[0] = 1. / (1. + dg * (dg + k));
da[1] = dg * da[0];
da[2] = dg * da[1];
dm[0] = 0.;
dm[1] = -k;
dm[2] = -1.;
break;
case 3:
k = 1. / dqfactor;
da[0] = 1. / (1. + dg * (dg + k));
da[1] = dg * da[0];
da[2] = dg * da[1];
dm[0] = 0.;
dm[1] = -k;
dm[2] = -2.;
break;
}
for (int ch = start; ch < end; ch++) {
@ -169,7 +206,7 @@ static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo
if (state[4] != detect || n == 0) {
state[4] = gain = detect;
switch (type) {
switch (tftype) {
case 0:
k = 1. / (tqfactor * gain);
@ -279,10 +316,15 @@ static const AVOption adynamicequalizer_options[] = {
{ "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" },
{ "tftype", "set target filter type", OFFSET(type), AV_OPT_TYPE_INT, {.i64=0}, 0, 2, FLAGS, "type" },
{ "bell", 0, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "type" },
{ "lowshelf", 0, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "type" },
{ "highshelf",0, 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGS, "type" },
{ "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" },
{ "highpass", 0, 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGS, "dftype" },
{ "peak", 0, 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, FLAGS, "dftype" },
{ "tftype", "set target filter type", OFFSET(tftype), AV_OPT_TYPE_INT, {.i64=0}, 0, 2, FLAGS, "tftype" },
{ "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" },