ffmpeg | branch: master | Paul B Mahol <one...@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 +@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 }, _______________________________________________ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog To unsubscribe, visit link above, or email ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".