From 258c49d61451236e28a34265195481ef8f00d968 Mon Sep 17 00:00:00 2001 From: Muhammad Faiz Date: Wed, 19 Oct 2016 22:22:36 +0700 Subject: [PATCH] avfilter/firequalizer: use zero phase kernel this makes real-valued kernel Signed-off-by: Muhammad Faiz --- libavfilter/af_firequalizer.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/libavfilter/af_firequalizer.c b/libavfilter/af_firequalizer.c index e799e34191..4988717cd8 100644 --- a/libavfilter/af_firequalizer.c +++ b/libavfilter/af_firequalizer.c @@ -198,20 +198,19 @@ static void fast_convolute(FIREqualizerContext *s, const float *kernel_buf, floa if (nsamples <= s->nsamples_max) { float *buf = conv_buf + idx->buf_idx * s->rdft_len; float *obuf = conv_buf + !idx->buf_idx * s->rdft_len + idx->overlap_idx; + int center = s->fir_len/2; int k; - memcpy(buf, data, nsamples * sizeof(*data)); - memset(buf + nsamples, 0, (s->rdft_len - nsamples) * sizeof(*data)); + memset(buf, 0, center * sizeof(*data)); + memcpy(buf + center, data, nsamples * sizeof(*data)); + memset(buf + center + nsamples, 0, (s->rdft_len - nsamples - center) * sizeof(*data)); av_rdft_calc(s->rdft, buf); buf[0] *= kernel_buf[0]; - buf[1] *= kernel_buf[1]; - for (k = 2; k < s->rdft_len; k += 2) { - float re, im; - re = buf[k] * kernel_buf[k] - buf[k+1] * kernel_buf[k+1]; - im = buf[k] * kernel_buf[k+1] + buf[k+1] * kernel_buf[k]; - buf[k] = re; - buf[k+1] = im; + buf[1] *= kernel_buf[s->rdft_len/2]; + for (k = 1; k < s->rdft_len/2; k++) { + buf[2*k] *= kernel_buf[k]; + buf[2*k+1] *= kernel_buf[k]; } av_rdft_calc(s->irdft, buf); @@ -534,8 +533,8 @@ static int generate_kernel(AVFilterContext *ctx, const char *gain, const char *g } memset(s->analysis_buf + center + 1, 0, (s->analysis_rdft_len - s->fir_len) * sizeof(*s->analysis_buf)); - memcpy(rdft_buf, s->analysis_buf + s->analysis_rdft_len - center, center * sizeof(*s->analysis_buf)); - memcpy(rdft_buf + center, s->analysis_buf, (s->rdft_len - center) * sizeof(*s->analysis_buf)); + memcpy(rdft_buf, s->analysis_buf, s->rdft_len/2 * sizeof(*s->analysis_buf)); + memcpy(rdft_buf + s->rdft_len/2, s->analysis_buf + s->analysis_rdft_len - s->rdft_len/2, s->rdft_len/2 * sizeof(*s->analysis_buf)); av_rdft_calc(s->rdft, rdft_buf); for (k = 0; k < s->rdft_len; k++) { @@ -548,6 +547,11 @@ static int generate_kernel(AVFilterContext *ctx, const char *gain, const char *g } } + rdft_buf[s->rdft_len-1] = rdft_buf[1]; + for (k = 0; k < s->rdft_len/2; k++) + rdft_buf[k] = rdft_buf[2*k]; + rdft_buf[s->rdft_len/2] = rdft_buf[s->rdft_len-1]; + if (dump_fp) dump_fir(ctx, dump_fp, ch);