[FFmpeg-cvslog] avfilter/af_afir: make IR gain control more flexible

Paul B Mahol git at videolan.org
Wed Oct 3 22:49:05 EEST 2018


ffmpeg | branch: master | Paul B Mahol <onemda at gmail.com> | Wed Oct  3 21:43:40 2018 +0200| [9e45364a80f93f174ffa25a8e66abfbe7e05b740] | committer: Paul B Mahol

avfilter/af_afir: make IR gain control more flexible

For this reason introduce two more options.

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

 doc/filters.texi      | 23 +++++++++++++++++++++--
 libavfilter/af_afir.c | 52 +++++++++++++++++++++++++++++++++++++++++----------
 libavfilter/af_afir.h |  2 ++
 3 files changed, 65 insertions(+), 12 deletions(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index 6d3833317e..1c51e42388 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -1147,7 +1147,7 @@ afftfilt="1-clip((b/nb)*b,0,1)"
 Apply an arbitrary Frequency Impulse Response filter.
 
 This filter is designed for applying long FIR filters,
-up to 30 seconds long.
+up to 60 seconds long.
 
 It can be used as component for digital crossover filters,
 room equalization, cross talk cancellation, wavefield synthesis,
@@ -1172,7 +1172,26 @@ Set wet gain. This sets final output gain.
 Set Impulse Response filter length. Default is 1, which means whole IR is processed.
 
 @item again
-Enable applying gain measured from power of IR.
+Enable applying gain measured from power of IR. For approach to use for measuring power
+of IR see next option.
+
+ at item gtype
+Set which approach to use for auto gain measurement.
+
+ at table @option
+ at item peak
+select peak gain, very conservative approach. This is default value.
+
+ at item dc
+select DC gain, limited application.
+
+ at item gn
+select gain to noise approach, this is most popular one.
+ at end table
+
+ at item irgain
+Set gain to be applied to IR coefficients before filtering.
+Allowed range is 0 to 1. This can be set even with @var{again} used.
 
 @item maxir
 Set max allowed Impulse Response filter duration in seconds. Default is 30 seconds.
diff --git a/libavfilter/af_afir.c b/libavfilter/af_afir.c
index bdca9033cf..770b8be9f7 100644
--- a/libavfilter/af_afir.c
+++ b/libavfilter/af_afir.c
@@ -280,6 +280,7 @@ static int convert_coeffs(AVFilterContext *ctx)
 {
     AudioFIRContext *s = ctx->priv;
     int i, ch, n, N;
+    float power = 0;
 
     s->nb_taps = av_audio_fifo_size(s->fifo);
     if (s->nb_taps <= 0)
@@ -333,22 +334,48 @@ static int convert_coeffs(AVFilterContext *ctx)
     if (s->response)
         draw_response(ctx, s->video);
 
+    s->gain = 1;
+
     if (s->again) {
-        float power = 0;
+        switch (s->gtype) {
+        case 0:
+            for (ch = 0; ch < ctx->inputs[1]->channels; ch++) {
+                float *time = (float *)s->in[1]->extended_data[!s->one2many * ch];
+
+                for (i = 0; i < s->nb_taps; i++)
+                    power += FFABS(time[i]);
+            }
+            s->gain = ctx->inputs[1]->channels / power;
+            break;
+        case 1:
+            for (ch = 0; ch < ctx->inputs[1]->channels; ch++) {
+                float *time = (float *)s->in[1]->extended_data[!s->one2many * ch];
 
-        for (ch = 0; ch < ctx->inputs[1]->channels; ch++) {
-            float *time = (float *)s->in[1]->extended_data[!s->one2many * ch];
+                for (i = 0; i < s->nb_taps; i++)
+                    power += time[i];
+            }
+            s->gain = ctx->inputs[1]->channels / power;
+            break;
+        case 2:
+            for (ch = 0; ch < ctx->inputs[1]->channels; ch++) {
+                float *time = (float *)s->in[1]->extended_data[!s->one2many * ch];
 
-            for (i = 0; i < s->nb_taps; i++)
-                power += FFABS(time[i]);
+                for (i = 0; i < s->nb_taps; i++)
+                    power += time[i] * time[i];
+            }
+            s->gain = sqrtf(ch / power);
+            break;
+        default:
+            return AVERROR_BUG;
         }
+    }
 
-        s->gain = sqrtf(1.f / (ctx->inputs[1]->channels * power)) / (sqrtf(ctx->inputs[1]->channels));
-        for (ch = 0; ch < ctx->inputs[1]->channels; ch++) {
-            float *time = (float *)s->in[1]->extended_data[!s->one2many * ch];
+    s->gain = FFMIN(s->gain * s->ir_gain, 1.f);
+    av_log(ctx, AV_LOG_DEBUG, "power %f, gain %f\n", power, s->gain);
+    for (ch = 0; ch < ctx->inputs[1]->channels; ch++) {
+        float *time = (float *)s->in[1]->extended_data[!s->one2many * ch];
 
-            s->fdsp->vector_fmul_scalar(time, time, s->gain, FFALIGN(s->nb_taps, 4));
-        }
+        s->fdsp->vector_fmul_scalar(time, time, s->gain, FFALIGN(s->nb_taps, 4));
     }
 
     for (ch = 0; ch < ctx->inputs[1]->channels; ch++) {
@@ -727,6 +754,11 @@ static const AVOption afir_options[] = {
     { "wet",    "set wet gain",      OFFSET(wet_gain),   AV_OPT_TYPE_FLOAT, {.dbl=1},    0, 10, AF },
     { "length", "set IR length",     OFFSET(length),     AV_OPT_TYPE_FLOAT, {.dbl=1},    0,  1, AF },
     { "again",  "enable auto gain",  OFFSET(again),      AV_OPT_TYPE_BOOL,  {.i64=1},    0,  1, AF },
+    { "gtype",  "set auto gain type",OFFSET(gtype),      AV_OPT_TYPE_INT,   {.i64=0},    0,  2, AF, "gtype" },
+    {  "peak",  "peak gain",         0,                  AV_OPT_TYPE_CONST, {.i64=0},    0,  0, AF, "gtype" },
+    {  "dc",    "DC gain",           0,                  AV_OPT_TYPE_CONST, {.i64=1},    0,  0, AF, "gtype" },
+    {  "gn",    "gain to noise",     0,                  AV_OPT_TYPE_CONST, {.i64=2},    0,  0, AF, "gtype" },
+    { "irgain", "set IR gain",       OFFSET(ir_gain),    AV_OPT_TYPE_FLOAT, {.dbl=1},    0,  1, AF },
     { "maxir",  "set max IR length", OFFSET(max_ir_len), AV_OPT_TYPE_FLOAT, {.dbl=30}, 0.1, 60, 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 },
diff --git a/libavfilter/af_afir.h b/libavfilter/af_afir.h
index 9489ad0b00..9e6f957a8d 100644
--- a/libavfilter/af_afir.h
+++ b/libavfilter/af_afir.h
@@ -39,6 +39,8 @@ typedef struct AudioFIRContext {
     float dry_gain;
     float length;
     int again;
+    int gtype;
+    float ir_gain;
     float max_ir_len;
     int response;
     int w, h;



More information about the ffmpeg-cvslog mailing list