Signed-off-by: Paul B Mahol <one...@gmail.com> --- libavfilter/af_biquads.c | 279 ++++++++++----------------------------- 1 file changed, 68 insertions(+), 211 deletions(-)
diff --git a/libavfilter/af_biquads.c b/libavfilter/af_biquads.c index f3ef3660cc..c998f3e982 100644 --- a/libavfilter/af_biquads.c +++ b/libavfilter/af_biquads.c @@ -138,13 +138,14 @@ typedef struct BiquadsContext { int hop_size; double *window_func_lut; - void (*filter)(struct BiquadsContext *s, const void *ibuf, void *obuf, int len, + void (*filter)(struct BiquadsContext *s, const void *ibuf, void *obuf, void *dst, int len, double *i1, double *i2, double *o1, double *o2, double b0, double b1, double b2, double a1, double a2, int *clippings, int disabled); void (*reverse_filter)(struct BiquadsContext *s, const void *ibuf, void *obuf, void *dst, int len, double *i1, double *i2, double *o1, double *o2, - double b0, double b1, double b2, double a1, double a2, int *clippings); + double b0, double b1, double b2, double a1, double a2, int *clippings, + int disabled); } BiquadsContext; static av_cold int init(AVFilterContext *ctx) @@ -195,97 +196,15 @@ static int query_formats(AVFilterContext *ctx) return ff_set_common_samplerates(ctx, formats); } -#define BIQUAD_FILTER(name, type, min, max, need_clipping) \ +#define BIQUAD_FILTER(name, type, min, max, need_clipping, reverse) \ static void biquad_## name (BiquadsContext *s, \ - const void *input, void *output, int len, \ - double *in1, double *in2, \ - double *out1, double *out2, \ - double b0, double b1, double b2, \ - double a1, double a2, int *clippings, \ - int disabled) \ -{ \ - const type *ibuf = input; \ - type *obuf = output; \ - double i1 = *in1; \ - double i2 = *in2; \ - double o1 = *out1; \ - double o2 = *out2; \ - double wet = s->mix; \ - double dry = 1. - wet; \ - double out; \ - int i; \ - a1 = -a1; \ - a2 = -a2; \ - \ - for (i = 0; i+1 < len; i++) { \ - o2 = i2 * b2 + i1 * b1 + ibuf[i] * b0 + o2 * a2 + o1 * a1; \ - i2 = ibuf[i]; \ - out = o2 * wet + i2 * dry; \ - if (disabled) { \ - obuf[i] = i2; \ - } else if (need_clipping && out < min) { \ - (*clippings)++; \ - obuf[i] = min; \ - } else if (need_clipping && out > max) { \ - (*clippings)++; \ - obuf[i] = max; \ - } else { \ - obuf[i] = out; \ - } \ - i++; \ - o1 = i1 * b2 + i2 * b1 + ibuf[i] * b0 + o1 * a2 + o2 * a1; \ - i1 = ibuf[i]; \ - out = o1 * wet + i1 * dry; \ - if (disabled) { \ - obuf[i] = i1; \ - } else if (need_clipping && out < min) { \ - (*clippings)++; \ - obuf[i] = min; \ - } else if (need_clipping && out > max) { \ - (*clippings)++; \ - obuf[i] = max; \ - } else { \ - obuf[i] = out; \ - } \ - } \ - if (i < len) { \ - double o0 = ibuf[i] * b0 + i1 * b1 + i2 * b2 + o1 * a1 + o2 * a2; \ - i2 = i1; \ - i1 = ibuf[i]; \ - o2 = o1; \ - o1 = o0; \ - out = o0 * wet + i1 * dry; \ - if (disabled) { \ - obuf[i] = i1; \ - } else if (need_clipping && out < min) { \ - (*clippings)++; \ - obuf[i] = min; \ - } else if (need_clipping && out > max) { \ - (*clippings)++; \ - obuf[i] = max; \ - } else { \ - obuf[i] = out; \ - } \ - } \ - *in1 = i1; \ - *in2 = i2; \ - *out1 = o1; \ - *out2 = o2; \ -} - -BIQUAD_FILTER(s16, int16_t, INT16_MIN, INT16_MAX, 1) -BIQUAD_FILTER(s32, int32_t, INT32_MIN, INT32_MAX, 1) -BIQUAD_FILTER(flt, float, -1., 1., 0) -BIQUAD_FILTER(dbl, double, -1., 1., 0) - -#define BIQUAD_FILTER_REVERSE(name, type, min, max, need_clipping) \ -static void biquad_reverse_## name (BiquadsContext *s, \ const void *input, void *output, void *dst, \ int len, \ double *in1, double *in2, \ double *out1, double *out2, \ double b0, double b1, double b2, \ - double a1, double a2, int *clippings) \ + double a1, double a2, int *clippings, \ + int disabled) \ { \ const type *ibuf = input; \ type *obuf = output; \ @@ -305,11 +224,13 @@ static void biquad_reverse_## name (BiquadsContext *s, \ a2 = -a2; \ \ for (i = 0; i+1 < len; i++) { \ - j = len - 1 - i; \ + j = reverse ? len - 1 - i : i; \ o2 = i2 * b2 + i1 * b1 + ibuf[j] * b0 + o2 * a2 + o1 * a1; \ i2 = ibuf[j]; \ out = o2 * wet + i2 * dry; \ - if (need_clipping && out < min) { \ + if (disabled) { \ + obuf[j] = ibuf[j]; \ + } else if (need_clipping && out < min) { \ (*clippings)++; \ obuf[j] = min; \ } else if (need_clipping && out > max) { \ @@ -319,11 +240,13 @@ static void biquad_reverse_## name (BiquadsContext *s, \ obuf[j] = out; \ } \ i++; \ - j = len - 1 - i; \ + j = reverse ? len - 1 - i : i; \ o1 = i1 * b2 + i2 * b1 + ibuf[j] * b0 + o1 * a2 + o2 * a1; \ i1 = ibuf[j]; \ out = o1 * wet + i1 * dry; \ - if (need_clipping && out < min) { \ + if (disabled) { \ + obuf[j] = ibuf[j]; \ + } else if (need_clipping && out < min) { \ (*clippings)++; \ obuf[j] = min; \ } else if (need_clipping && out > max) { \ @@ -334,14 +257,16 @@ static void biquad_reverse_## name (BiquadsContext *s, \ } \ } \ if (i < len) { \ - j = len - 1 - i; \ + j = reverse ? len - 1 - i : i; \ o0 = ibuf[j] * b0 + i1 * b1 + i2 * b2 + o1 * a1 + o2 * a2; \ i2 = i1; \ i1 = ibuf[j]; \ o2 = o1; \ o1 = o0; \ out = o0 * wet + i1 * dry; \ - if (need_clipping && out < min) { \ + if (disabled) { \ + obuf[j] = ibuf[j]; \ + } else if (need_clipping && out < min) { \ (*clippings)++; \ obuf[j] = min; \ } else if (need_clipping && out > max) { \ @@ -356,6 +281,8 @@ static void biquad_reverse_## name (BiquadsContext *s, \ *out1 = o1; \ *out2 = o2; \ \ + if (!reverse) return; \ + \ for (i = 0; i < len; i++) \ dbuf[i] += obuf[i] * w[i]; \ for (i = 0; i < s->hop_size; i++) \ @@ -366,67 +293,25 @@ static void biquad_reverse_## name (BiquadsContext *s, \ s->hop_size * s->block_align); \ } -BIQUAD_FILTER_REVERSE(s16, int16_t, INT16_MIN, INT16_MAX, 1) -BIQUAD_FILTER_REVERSE(s32, int32_t, INT32_MIN, INT32_MAX, 1) -BIQUAD_FILTER_REVERSE(flt, float, -1., 1., 0) -BIQUAD_FILTER_REVERSE(dbl, double, -1., 1., 0) - -#define BIQUAD_DII_FILTER(name, type, min, max, need_clipping) \ -static void biquad_dii_## name (BiquadsContext *s, \ - const void *input, void *output, int len, \ - double *z1, double *z2, \ - double *unused1, double *unused2, \ - double b0, double b1, double b2, \ - double a1, double a2, int *clippings, \ - int disabled) \ -{ \ - const type *ibuf = input; \ - type *obuf = output; \ - double w1 = *z1; \ - double w2 = *z2; \ - double wet = s->mix; \ - double dry = 1. - wet; \ - double in, out, w0; \ - \ - a1 = -a1; \ - a2 = -a2; \ - \ - for (int i = 0; i < len; i++) { \ - in = ibuf[i]; \ - w0 = in + a1 * w1 + a2 * w2; \ - out = b0 * w0 + b1 * w1 + b2 * w2; \ - w2 = w1; \ - w1 = w0; \ - out = out * wet + in * dry; \ - if (disabled) { \ - obuf[i] = in; \ - } else if (need_clipping && out < min) { \ - (*clippings)++; \ - obuf[i] = min; \ - } else if (need_clipping && out > max) { \ - (*clippings)++; \ - obuf[i] = max; \ - } else { \ - obuf[i] = out; \ - } \ - } \ - *z1 = w1; \ - *z2 = w2; \ -} +BIQUAD_FILTER(s16, int16_t, INT16_MIN, INT16_MAX, 1, 0) +BIQUAD_FILTER(s32, int32_t, INT32_MIN, INT32_MAX, 1, 0) +BIQUAD_FILTER(flt, float, -1., 1., 0, 0) +BIQUAD_FILTER(dbl, double, -1., 1., 0, 0) -BIQUAD_DII_FILTER(s16, int16_t, INT16_MIN, INT16_MAX, 1) -BIQUAD_DII_FILTER(s32, int32_t, INT32_MIN, INT32_MAX, 1) -BIQUAD_DII_FILTER(flt, float, -1., 1., 0) -BIQUAD_DII_FILTER(dbl, double, -1., 1., 0) +BIQUAD_FILTER(reverse_s16, int16_t, INT16_MIN, INT16_MAX, 1, 1) +BIQUAD_FILTER(reverse_s32, int32_t, INT32_MIN, INT32_MAX, 1, 1) +BIQUAD_FILTER(reverse_flt, float, -1., 1., 0, 1) +BIQUAD_FILTER(reverse_dbl, double, -1., 1., 0, 1) -#define BIQUAD_REVERSE_DII_FILTER(name, type, min, max, need_clipping) \ -static void biquad_reverse_dii_## name (BiquadsContext *s, \ +#define BIQUAD_DII_FILTER(name, type, min, max, need_clipping, reverse) \ +static void biquad_## name (BiquadsContext *s, \ const void *input, void *output, void *dst, \ int len, \ double *z1, double *z2, \ double *unused1, double *unused2, \ double b0, double b1, double b2, \ - double a1, double a2, int *clippings) \ + double a1, double a2, int *clippings, \ + int disabled) \ { \ const double *w = s->window_func_lut; \ const type *ibuf = input; \ @@ -442,14 +327,16 @@ static void biquad_reverse_dii_## name (BiquadsContext *s, \ a2 = -a2; \ \ for (int i = 0; i < len; i++) { \ - int j = len - 1 - i; \ + int j = reverse ? len - 1 - i : i; \ in = ibuf[j]; \ w0 = in + a1 * w1 + a2 * w2; \ out = b0 * w0 + b1 * w1 + b2 * w2; \ w2 = w1; \ w1 = w0; \ out = out * wet + in * dry; \ - if (need_clipping && out < min) { \ + if (disabled) { \ + obuf[j] = in; \ + } else if (need_clipping && out < min) { \ (*clippings)++; \ obuf[j] = min; \ } else if (need_clipping && out > max) { \ @@ -462,6 +349,8 @@ static void biquad_reverse_dii_## name (BiquadsContext *s, \ *z1 = w1; \ *z2 = w2; \ \ + if (!reverse) return; \ + \ for (int i = 0; i < len; i++) \ dbuf[i] += obuf[i] * w[i]; \ for (int i = 0; i < s->hop_size; i++) \ @@ -472,66 +361,25 @@ static void biquad_reverse_dii_## name (BiquadsContext *s, \ s->hop_size * s->block_align); \ } -BIQUAD_REVERSE_DII_FILTER(s16, int16_t, INT16_MIN, INT16_MAX, 1) -BIQUAD_REVERSE_DII_FILTER(s32, int32_t, INT32_MIN, INT32_MAX, 1) -BIQUAD_REVERSE_DII_FILTER(flt, float, -1., 1., 0) -BIQUAD_REVERSE_DII_FILTER(dbl, double, -1., 1., 0) +BIQUAD_DII_FILTER(dii_s16, int16_t, INT16_MIN, INT16_MAX, 1, 0) +BIQUAD_DII_FILTER(dii_s32, int32_t, INT32_MIN, INT32_MAX, 1, 0) +BIQUAD_DII_FILTER(dii_flt, float, -1., 1., 0, 0) +BIQUAD_DII_FILTER(dii_dbl, double, -1., 1., 0, 0) -#define BIQUAD_TDII_FILTER(name, type, min, max, need_clipping) \ -static void biquad_tdii_## name (BiquadsContext *s, \ - const void *input, void *output, int len, \ - double *z1, double *z2, \ - double *unused1, double *unused2, \ - double b0, double b1, double b2, \ - double a1, double a2, int *clippings, \ - int disabled) \ -{ \ - const type *ibuf = input; \ - type *obuf = output; \ - double w1 = *z1; \ - double w2 = *z2; \ - double wet = s->mix; \ - double dry = 1. - wet; \ - double in, out; \ - \ - a1 = -a1; \ - a2 = -a2; \ - \ - for (int i = 0; i < len; i++) { \ - in = ibuf[i]; \ - out = b0 * in + w1; \ - w1 = b1 * in + w2 + a1 * out; \ - w2 = b2 * in + a2 * out; \ - out = out * wet + in * dry; \ - if (disabled) { \ - obuf[i] = in; \ - } else if (need_clipping && out < min) { \ - (*clippings)++; \ - obuf[i] = min; \ - } else if (need_clipping && out > max) { \ - (*clippings)++; \ - obuf[i] = max; \ - } else { \ - obuf[i] = out; \ - } \ - } \ - *z1 = w1; \ - *z2 = w2; \ -} - -BIQUAD_TDII_FILTER(s16, int16_t, INT16_MIN, INT16_MAX, 1) -BIQUAD_TDII_FILTER(s32, int32_t, INT32_MIN, INT32_MAX, 1) -BIQUAD_TDII_FILTER(flt, float, -1., 1., 0) -BIQUAD_TDII_FILTER(dbl, double, -1., 1., 0) +BIQUAD_DII_FILTER(reverse_dii_s16, int16_t, INT16_MIN, INT16_MAX, 1, 1) +BIQUAD_DII_FILTER(reverse_dii_s32, int32_t, INT32_MIN, INT32_MAX, 1, 1) +BIQUAD_DII_FILTER(reverse_dii_flt, float, -1., 1., 0, 1) +BIQUAD_DII_FILTER(reverse_dii_dbl, double, -1., 1., 0, 1) -#define BIQUAD_REVERSE_TDII_FILTER(name, type, min, max, need_clipping) \ -static void biquad_reverse_tdii_## name (BiquadsContext *s, \ +#define BIQUAD_TDII_FILTER(name, type, min, max, need_clipping, reverse) \ +static void biquad_## name (BiquadsContext *s, \ const void *input, void *output, void *dst, \ int len, \ double *z1, double *z2, \ double *unused1, double *unused2, \ double b0, double b1, double b2, \ - double a1, double a2, int *clippings) \ + double a1, double a2, int *clippings, \ + int disabled) \ { \ const double *w = s->window_func_lut; \ const type *ibuf = input; \ @@ -547,13 +395,15 @@ static void biquad_reverse_tdii_## name (BiquadsContext *s, \ a2 = -a2; \ \ for (int i = 0; i < len; i++) { \ - int j = len - 1 - i; \ + int j = reverse ? len - 1 - i : i; \ in = ibuf[j]; \ out = b0 * in + w1; \ w1 = b1 * in + w2 + a1 * out; \ w2 = b2 * in + a2 * out; \ out = out * wet + in * dry; \ - if (need_clipping && out < min) { \ + if (disabled) { \ + obuf[j] = in; \ + } else if (need_clipping && out < min) { \ (*clippings)++; \ obuf[j] = min; \ } else if (need_clipping && out > max) { \ @@ -566,6 +416,8 @@ static void biquad_reverse_tdii_## name (BiquadsContext *s, \ *z1 = w1; \ *z2 = w2; \ \ + if (!reverse) return; \ + \ for (int i = 0; i < len; i++) \ dbuf[i] += obuf[i] * w[i]; \ for (int i = 0; i < s->hop_size; i++) \ @@ -576,10 +428,15 @@ static void biquad_reverse_tdii_## name (BiquadsContext *s, \ s->hop_size * s->block_align); \ } -BIQUAD_REVERSE_TDII_FILTER(s16, int16_t, INT16_MIN, INT16_MAX, 1) -BIQUAD_REVERSE_TDII_FILTER(s32, int32_t, INT32_MIN, INT32_MAX, 1) -BIQUAD_REVERSE_TDII_FILTER(flt, float, -1., 1., 0) -BIQUAD_REVERSE_TDII_FILTER(dbl, double, -1., 1., 0) +BIQUAD_TDII_FILTER(tdii_s16, int16_t, INT16_MIN, INT16_MAX, 1, 0) +BIQUAD_TDII_FILTER(tdii_s32, int32_t, INT32_MIN, INT32_MAX, 1, 0) +BIQUAD_TDII_FILTER(tdii_flt, float, -1., 1., 0, 0) +BIQUAD_TDII_FILTER(tdii_dbl, double, -1., 1., 0, 0) + +BIQUAD_TDII_FILTER(reverse_tdii_s16, int16_t, INT16_MIN, INT16_MAX, 1, 1) +BIQUAD_TDII_FILTER(reverse_tdii_s32, int32_t, INT32_MIN, INT32_MAX, 1, 1) +BIQUAD_TDII_FILTER(reverse_tdii_flt, float, -1., 1., 0, 1) +BIQUAD_TDII_FILTER(reverse_tdii_dbl, double, -1., 1., 0, 1) static int config_filter(AVFilterLink *outlink, int reset) { @@ -875,7 +732,7 @@ static int reverse_filter_channel(AVFilterContext *ctx, void *arg, int jobnr, in continue; } - s->filter(s, buf->extended_data[ch], tmp_buf->extended_data[ch], buf->nb_samples, + s->filter(s, buf->extended_data[ch], tmp_buf->extended_data[ch], NULL, buf->nb_samples, &s->cache[ch].i1, &s->cache[ch].i2, &s->cache[ch].o1, &s->cache[ch].o2, s->b0, s->b1, s->b2, s->a1, s->a2, &s->cache[ch].clippings, ctx->is_disabled); s->reverse_filter(s, tmp_buf->extended_data[ch], out_buf->extended_data[ch], @@ -883,7 +740,7 @@ static int reverse_filter_channel(AVFilterContext *ctx, void *arg, int jobnr, in tmp_buf->nb_samples, &s->cache[ch].ri1, &s->cache[ch].ri2, &s->cache[ch].ro1, &s->cache[ch].ro2, s->b0, s->b1, s->b2, s->a1, s->a2, - &s->cache[ch].clippings); + &s->cache[ch].clippings, ctx->is_disabled); } return 0; @@ -908,7 +765,7 @@ static int filter_channel(AVFilterContext *ctx, void *arg, int jobnr, int nb_job continue; } - s->filter(s, buf->extended_data[ch], out_buf->extended_data[ch], buf->nb_samples, + s->filter(s, buf->extended_data[ch], out_buf->extended_data[ch], NULL, buf->nb_samples, &s->cache[ch].i1, &s->cache[ch].i2, &s->cache[ch].o1, &s->cache[ch].o2, s->b0, s->b1, s->b2, s->a1, s->a2, &s->cache[ch].clippings, ctx->is_disabled); } -- 2.17.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".