aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul B Mahol <onemda@gmail.com>2020-05-22 12:28:03 +0200
committerPaul B Mahol <onemda@gmail.com>2020-05-22 12:30:59 +0200
commitffda57b800866f10a60b6e13f9f31e2564e0b09f (patch)
treed9f7a9682aef383094df33c6ec66df2c4b8d81f0
parent1fc5ddf774bbec45add705a8f923e9565cf80bdf (diff)
downloadffmpeg-ffda57b800866f10a60b6e13f9f31e2564e0b09f.tar.gz
avfilter/af_aiir: export normalize option
And enable it in all modes by default.
-rw-r--r--doc/filters.texi4
-rw-r--r--libavfilter/af_aiir.c37
2 files changed, 40 insertions, 1 deletions
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 },