|
@@ -54,6 +54,8 @@ typedef struct AudioNLMSContext {
|
|
|
|
|
|
AVFrame *frame[2];
|
|
|
|
|
|
+ int anlmf;
|
|
|
+
|
|
|
AVFloatDSPContext *fdsp;
|
|
|
} AudioNLMSContext;
|
|
|
|
|
@@ -74,7 +76,7 @@ static const AVOption anlms_options[] = {
|
|
|
{ NULL }
|
|
|
};
|
|
|
|
|
|
-AVFILTER_DEFINE_CLASS(anlms);
|
|
|
+AVFILTER_DEFINE_CLASS_EXT(anlms, "anlm(f|s)", anlms_options);
|
|
|
|
|
|
static int query_formats(AVFilterContext *ctx)
|
|
|
{
|
|
@@ -130,6 +132,8 @@ static float process_sample(AudioNLMSContext *s, float input, float desired,
|
|
|
|
|
|
norm = s->eps + sum;
|
|
|
b = mu * e / norm;
|
|
|
+ if (s->anlmf)
|
|
|
+ b *= 4.f * e * e;
|
|
|
|
|
|
memcpy(tmp, delay + offset, order * sizeof(float));
|
|
|
|
|
@@ -241,6 +245,7 @@ static int config_output(AVFilterLink *outlink)
|
|
|
AVFilterContext *ctx = outlink->src;
|
|
|
AudioNLMSContext *s = ctx->priv;
|
|
|
|
|
|
+ s->anlmf = !strcmp(ctx->filter->name, "anlmf");
|
|
|
s->kernel_size = FFALIGN(s->order, 16);
|
|
|
|
|
|
if (!s->offset)
|
|
@@ -312,3 +317,18 @@ const AVFilter ff_af_anlms = {
|
|
|
.flags = AVFILTER_FLAG_SLICE_THREADS,
|
|
|
.process_command = ff_filter_process_command,
|
|
|
};
|
|
|
+
|
|
|
+const AVFilter ff_af_anlmf = {
|
|
|
+ .name = "anlmf",
|
|
|
+ .description = NULL_IF_CONFIG_SMALL("Apply Normalized Least-Mean-Fourth algorithm to first audio stream."),
|
|
|
+ .priv_size = sizeof(AudioNLMSContext),
|
|
|
+ .priv_class = &anlms_class,
|
|
|
+ .init = init,
|
|
|
+ .uninit = uninit,
|
|
|
+ .activate = activate,
|
|
|
+ FILTER_INPUTS(inputs),
|
|
|
+ FILTER_OUTPUTS(outputs),
|
|
|
+ FILTER_QUERY_FUNC(query_formats),
|
|
|
+ .flags = AVFILTER_FLAG_SLICE_THREADS,
|
|
|
+ .process_command = ff_filter_process_command,
|
|
|
+};
|