mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-11-21 10:55:51 +02:00
avfilter/af_adynamicequalizer: set target filter type
This commit is contained in:
parent
4e284837e4
commit
c27123606a
@ -913,6 +913,16 @@ Cut frequencies above detection threshold.
|
|||||||
Boost frequencies bellow detection threshold.
|
Boost frequencies bellow detection threshold.
|
||||||
@end table
|
@end table
|
||||||
Default mode is @samp{cut}.
|
Default mode is @samp{cut}.
|
||||||
|
|
||||||
|
@item tftype
|
||||||
|
Set the type of target filter, can be one of the following:
|
||||||
|
|
||||||
|
@table @samp
|
||||||
|
@item bell
|
||||||
|
@item lowshelf
|
||||||
|
@item highshelf
|
||||||
|
@end table
|
||||||
|
Default type is @samp{bell}.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@subsection Commands
|
@subsection Commands
|
||||||
|
@ -42,6 +42,7 @@ typedef struct AudioDynamicEqualizerContext {
|
|||||||
double attack_coef;
|
double attack_coef;
|
||||||
double release_coef;
|
double release_coef;
|
||||||
int mode;
|
int mode;
|
||||||
|
int type;
|
||||||
|
|
||||||
AVFrame *state;
|
AVFrame *state;
|
||||||
} AudioDynamicEqualizerContext;
|
} AudioDynamicEqualizerContext;
|
||||||
@ -160,6 +161,7 @@ static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo
|
|||||||
const int start = (in->ch_layout.nb_channels * jobnr) / nb_jobs;
|
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 end = (in->ch_layout.nb_channels * (jobnr+1)) / nb_jobs;
|
||||||
const int mode = s->mode;
|
const int mode = s->mode;
|
||||||
|
const int type = s->type;
|
||||||
const double knee = s->knee;
|
const double knee = s->knee;
|
||||||
const double slew = s->slew;
|
const double slew = s->slew;
|
||||||
const double aattack = exp(-1000. / ((s->attack + 2.0 * (slew - 1.)) * sample_rate));
|
const double aattack = exp(-1000. / ((s->attack + 2.0 * (slew - 1.)) * sample_rate));
|
||||||
@ -186,6 +188,7 @@ static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo
|
|||||||
for (int n = 0; n < out->nb_samples; n++) {
|
for (int n = 0; n < out->nb_samples; n++) {
|
||||||
double detect, gain, v, listen;
|
double detect, gain, v, listen;
|
||||||
double fa[3], fm[3];
|
double fa[3], fm[3];
|
||||||
|
double k, g;
|
||||||
|
|
||||||
detect = listen = get_svf(src[n], dm, da, state);
|
detect = listen = get_svf(src[n], dm, da, state);
|
||||||
detect = fabs(detect);
|
detect = fabs(detect);
|
||||||
@ -194,8 +197,9 @@ static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo
|
|||||||
aattack, iratio, knee, range, threshold, slew,
|
aattack, iratio, knee, range, threshold, slew,
|
||||||
&state[4], attack, release, nc);
|
&state[4], attack, release, nc);
|
||||||
|
|
||||||
{
|
switch (type) {
|
||||||
double k = 1. / (tqfactor * gain);
|
case 0:
|
||||||
|
k = 1. / (tqfactor * gain);
|
||||||
|
|
||||||
fa[0] = 1. / (1. + fg * (fg + k));
|
fa[0] = 1. / (1. + fg * (fg + k));
|
||||||
fa[1] = fg * fa[0];
|
fa[1] = fg * fa[0];
|
||||||
@ -204,6 +208,31 @@ static int filter_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo
|
|||||||
fm[0] = 1.;
|
fm[0] = 1.;
|
||||||
fm[1] = k * (gain * gain - 1.);
|
fm[1] = k * (gain * gain - 1.);
|
||||||
fm[2] = 0.;
|
fm[2] = 0.;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
k = 1. / tqfactor;
|
||||||
|
g = fg / sqrt(gain);
|
||||||
|
|
||||||
|
fa[0] = 1. / (1. + g * (g + k));
|
||||||
|
fa[1] = g * fa[0];
|
||||||
|
fa[2] = g * fa[1];
|
||||||
|
|
||||||
|
fm[0] = 1.;
|
||||||
|
fm[1] = k * (gain - 1.);
|
||||||
|
fm[2] = gain * gain - 1.;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
k = 1. / tqfactor;
|
||||||
|
g = fg / sqrt(gain);
|
||||||
|
|
||||||
|
fa[0] = 1. / (1. + g * (g + k));
|
||||||
|
fa[1] = g * fa[0];
|
||||||
|
fa[2] = g * fa[1];
|
||||||
|
|
||||||
|
fm[0] = gain * gain;
|
||||||
|
fm[1] = k * (1. - gain) * gain;
|
||||||
|
fm[2] = 1. - gain * gain;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
v = get_svf(src[n], fm, fa, &state[2]);
|
v = get_svf(src[n], fm, fa, &state[2]);
|
||||||
@ -279,6 +308,10 @@ static const AVOption adynamicequalizer_options[] = {
|
|||||||
{ "listen", 0, 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, 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" },
|
{ "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" },
|
{ "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" },
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user