[FFmpeg-cvslog] avfilter/af_aiir: export normalize option

Paul B Mahol git at videolan.org
Fri May 22 13:40:25 EEST 2020


ffmpeg | branch: master | Paul B Mahol <onemda at gmail.com> | Fri May 22 12:28:03 2020 +0200| [ffda57b800866f10a60b6e13f9f31e2564e0b09f] | committer: Paul B Mahol

avfilter/af_aiir: export normalize option

And enable it in all modes by default.

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=ffda57b800866f10a60b6e13f9f31e2564e0b09f
---

 doc/filters.texi      |  4 ++++
 libavfilter/af_aiir.c | 37 ++++++++++++++++++++++++++++++++++++-
 2 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index 53303f6867..052f0b97aa 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -1436,6 +1436,10 @@ single-precision floating-point
 16-bit integers
 @end table
 
+ at item n
+Normalize filter coefficients, by default is enabled.
+Enabling it will normalize magnitude response at DC to 0dB.
+
 @item mix
 How much to use filtered signal in output. Default is 1.
 Range is between 0 and 1.
diff --git a/libavfilter/af_aiir.c b/libavfilter/af_aiir.c
index 420deb82de..588b9a6087 100644
--- a/libavfilter/af_aiir.c
+++ b/libavfilter/af_aiir.c
@@ -58,6 +58,7 @@ typedef struct AudioIIRContext {
     char *a_str, *b_str, *g_str;
     double dry_gain, wet_gain;
     double mix;
+    int normalize;
     int format;
     int process;
     int precision;
@@ -430,6 +431,34 @@ static int expand(AVFilterContext *ctx, double *pz, int nb, double *coeffs)
     return 0;
 }
 
+static void normalize_coeffs(AVFilterContext *ctx, int ch)
+{
+    AudioIIRContext *s = ctx->priv;
+    IIRChannel *iir = &s->iir[ch];
+    double sum_den = 0.;
+
+    if (!s->normalize)
+        return;
+
+    for (int i = 0; i < iir->nb_ab[1]; i++) {
+        sum_den += iir->ab[1][i];
+    }
+
+    if (sum_den > 1e-6) {
+        double factor, sum_num = 0.;
+
+        for (int i = 0; i < iir->nb_ab[0]; i++) {
+            sum_num += iir->ab[0][i];
+        }
+
+        factor = sum_num / sum_den;
+
+        for (int i = 0; i < iir->nb_ab[1]; i++) {
+            iir->ab[1][i] *= factor;
+        }
+    }
+}
+
 static int convert_zp2tf(AVFilterContext *ctx, int channels)
 {
     AudioIIRContext *s = ctx->priv;
@@ -466,6 +495,8 @@ static int convert_zp2tf(AVFilterContext *ctx, int channels)
         }
         iir->nb_ab[0]++;
 
+        normalize_coeffs(ctx, ch);
+
 fail:
         av_free(topc);
         av_free(botc);
@@ -601,7 +632,8 @@ static int decompose_zp2biquads(AVFilterContext *ctx, int channels)
             iir->biquads[current_biquad].b[1] = b[2] / a[4];
             iir->biquads[current_biquad].b[2] = b[0] / a[4];
 
-            if (fabs(iir->biquads[current_biquad].b[0] +
+            if (s->normalize &&
+                fabs(iir->biquads[current_biquad].b[0] +
                      iir->biquads[current_biquad].b[1] +
                      iir->biquads[current_biquad].b[2]) > 1e-6) {
                 factor = (iir->biquads[current_biquad].a[0] +
@@ -1009,6 +1041,8 @@ static int config_output(AVFilterLink *outlink)
         for (i = 0; i < iir->nb_ab[1]; i++) {
             iir->ab[1][i] *= iir->g / iir->ab[0][0];
         }
+
+        normalize_coeffs(ctx, ch);
     }
 
     switch (inlink->format) {
@@ -1196,6 +1230,7 @@ static const AVOption aiir_options[] = {
     { "flt", "single-precision floating-point",    0,                AV_OPT_TYPE_CONST,  {.i64=1},     0, 0, AF, "precision" },
     { "i32", "32-bit integers",                    0,                AV_OPT_TYPE_CONST,  {.i64=2},     0, 0, AF, "precision" },
     { "i16", "16-bit integers",                    0,                AV_OPT_TYPE_CONST,  {.i64=3},     0, 0, AF, "precision" },
+    { "n", "normalize coefficients",               OFFSET(normalize),AV_OPT_TYPE_BOOL,   {.i64=1},     0, 1, AF },
     { "mix", "set mix",                            OFFSET(mix),      AV_OPT_TYPE_DOUBLE, {.dbl=1},     0, 1, AF },
     { "response", "show IR frequency response",    OFFSET(response), AV_OPT_TYPE_BOOL,   {.i64=0},     0, 1, VF },
     { "channel", "set IR channel to display frequency response", OFFSET(ir_channel), AV_OPT_TYPE_INT, {.i64=0}, 0, 1024, VF },



More information about the ffmpeg-cvslog mailing list