[FFmpeg-cvslog] avfilter/af_adeclick: fix window generation

Paul B Mahol git at videolan.org
Sat Aug 12 01:13:07 EEST 2023


ffmpeg | branch: master | Paul B Mahol <onemda at gmail.com> | Fri Aug 11 17:40:46 2023 +0200| [3d85892052607fda3da8e2b3f8958982e669b22e] | committer: Paul B Mahol

avfilter/af_adeclick: fix window generation

Stops adding invalid sinusoids in overlap-add mode.

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

 libavfilter/af_adeclick.c | 64 ++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 61 insertions(+), 3 deletions(-)

diff --git a/libavfilter/af_adeclick.c b/libavfilter/af_adeclick.c
index 822f3065b8..328c347b36 100644
--- a/libavfilter/af_adeclick.c
+++ b/libavfilter/af_adeclick.c
@@ -20,6 +20,7 @@
 
 #include "libavutil/audio_fifo.h"
 #include "libavutil/opt.h"
+#include "libavutil/tx.h"
 #include "avfilter.h"
 #include "audio.h"
 #include "filters.h"
@@ -131,9 +132,66 @@ static int config_input(AVFilterLink *inlink)
     s->window_func_lut = av_calloc(s->window_size, sizeof(*s->window_func_lut));
     if (!s->window_func_lut)
         return AVERROR(ENOMEM);
-    for (i = 0; i < s->window_size; i++)
-        s->window_func_lut[i] = sin(M_PI * i / s->window_size) *
-                                (1. - (s->overlap / 100.)) * M_PI_2;
+
+    {
+        double *tx_in[2], *tx_out[2];
+        AVTXContext *tx, *itx;
+        av_tx_fn tx_fn, itx_fn;
+        int ret, tx_size;
+        double scale;
+
+        tx_size = 1 << (32 - ff_clz(s->window_size));
+
+        scale = 1.0;
+        ret = av_tx_init(&tx, &tx_fn, AV_TX_DOUBLE_RDFT, 0, tx_size, &scale, 0);
+        if (ret < 0)
+            return ret;
+
+        scale = 1.0 / tx_size;
+        ret = av_tx_init(&itx, &itx_fn, AV_TX_DOUBLE_RDFT, 1, tx_size, &scale, 0);
+        if (ret < 0)
+            return ret;
+
+        tx_in[0]  = av_calloc(tx_size + 2, sizeof(*tx_in[0]));
+        tx_in[1]  = av_calloc(tx_size + 2, sizeof(*tx_in[1]));
+        tx_out[0] = av_calloc(tx_size + 2, sizeof(*tx_out[0]));
+        tx_out[1] = av_calloc(tx_size + 2, sizeof(*tx_out[1]));
+        if (!tx_in[0] || !tx_in[1] || !tx_out[0] || !tx_out[1])
+            return AVERROR(ENOMEM);
+
+        for (int n = 0; n < s->window_size - s->hop_size; n++)
+            tx_in[0][n] = 1.0;
+
+        for (int n = 0; n < s->hop_size; n++)
+            tx_in[1][n] = 1.0;
+
+        tx_fn(tx, tx_out[0], tx_in[0], sizeof(double));
+        tx_fn(tx, tx_out[1], tx_in[1], sizeof(double));
+
+        for (int n = 0; n <= tx_size/2; n++) {
+            double re0 = tx_out[0][2*n];
+            double im0 = tx_out[0][2*n+1];
+            double re1 = tx_out[1][2*n];
+            double im1 = tx_out[1][2*n+1];
+
+            tx_in[0][2*n]   = re0 * re1 - im0 * im1;
+            tx_in[0][2*n+1] = re0 * im1 + re1 * im0;
+        }
+
+        itx_fn(itx, tx_out[0], tx_in[0], sizeof(AVComplexDouble));
+
+        scale = 1.0 / (s->window_size - s->hop_size);
+        for (int n = 0; n < s->window_size; n++)
+            s->window_func_lut[n] = tx_out[0][n] * scale;
+
+        av_tx_uninit(&tx);
+        av_tx_uninit(&itx);
+
+        av_freep(&tx_in[0]);
+        av_freep(&tx_in[1]);
+        av_freep(&tx_out[0]);
+        av_freep(&tx_out[1]);
+    }
 
     av_frame_free(&s->in);
     av_frame_free(&s->out);



More information about the ffmpeg-cvslog mailing list