diff --git a/doc/filters.texi b/doc/filters.texi index 367614d2f8..dc8bb54994 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -2050,6 +2050,7 @@ Set transform type of IIR filter. @table @option @item di @item dii +@item tdi @item tdii @item latt @item svf @@ -3479,6 +3480,7 @@ Set transform type of IIR filter. @table @option @item di @item dii +@item tdi @item tdii @item latt @item svf @@ -3567,6 +3569,7 @@ Set transform type of IIR filter. @table @option @item di @item dii +@item tdi @item tdii @item latt @item svf @@ -3665,6 +3668,7 @@ Set transform type of IIR filter. @table @option @item di @item dii +@item tdi @item tdii @item latt @item svf @@ -3748,6 +3752,7 @@ Set transform type of IIR filter. @table @option @item di @item dii +@item tdi @item tdii @item latt @item svf @@ -4541,6 +4546,7 @@ Set transform type of IIR filter. @table @option @item di @item dii +@item tdi @item tdii @item latt @item svf @@ -5043,6 +5049,7 @@ Set transform type of IIR filter. @table @option @item di @item dii +@item tdi @item tdii @item latt @item svf @@ -5394,6 +5401,7 @@ Set transform type of IIR filter. @table @option @item di @item dii +@item tdi @item tdii @item latt @item svf @@ -6631,6 +6639,7 @@ Set transform type of IIR filter. @table @option @item di @item dii +@item tdi @item tdii @item latt @item svf diff --git a/libavfilter/af_biquads.c b/libavfilter/af_biquads.c index 54270701c9..8caf169d50 100644 --- a/libavfilter/af_biquads.c +++ b/libavfilter/af_biquads.c @@ -99,6 +99,7 @@ enum WidthType { enum TransformType { DI, DII, + TDI, TDII, LATT, SVF, @@ -321,6 +322,62 @@ 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) +#define BIQUAD_TDI_FILTER(name, type, min, max, need_clipping) \ +static void biquad_tdi_## name (BiquadsContext *s, \ + const void *input, void *output, int len, \ + double *z1, double *z2, \ + double *z3, double *z4, \ + double b0, double b1, double b2, \ + double a1, double a2, int *clippings, \ + int disabled) \ +{ \ + const type *ibuf = input; \ + type *obuf = output; \ + double s1 = *z1; \ + double s2 = *z2; \ + double s3 = *z3; \ + double s4 = *z4; \ + double wet = s->mix; \ + double dry = 1. - wet; \ + double in, out; \ + \ + a1 = -a1; \ + a2 = -a2; \ + \ + for (int i = 0; i < len; i++) { \ + double t1, t2, t3, t4; \ + in = ibuf[i] + s1; \ + t1 = in * a1 + s2; \ + t2 = in * a2; \ + t3 = in * b1 + s4; \ + t4 = in * b2; \ + out = b0 * in + s3; \ + out = out * wet + in * dry; \ + s1 = t1; s2 = t2; s3 = t3; s4 = t4; \ + 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 = s1; \ + *z2 = s2; \ + *z3 = s3; \ + *z4 = s4; \ +} + +BIQUAD_TDI_FILTER(s16, int16_t, INT16_MIN, INT16_MAX, 1) +BIQUAD_TDI_FILTER(s32, int32_t, INT32_MIN, INT32_MAX, 1) +BIQUAD_TDI_FILTER(flt, float, -1., 1., 0) +BIQUAD_TDI_FILTER(dbl, double, -1., 1., 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, \ @@ -760,6 +817,23 @@ static int config_filter(AVFilterLink *outlink, int reset) default: av_assert0(0); } break; + case TDI: + switch (inlink->format) { + case AV_SAMPLE_FMT_S16P: + s->filter = biquad_tdi_s16; + break; + case AV_SAMPLE_FMT_S32P: + s->filter = biquad_tdi_s32; + break; + case AV_SAMPLE_FMT_FLTP: + s->filter = biquad_tdi_flt; + break; + case AV_SAMPLE_FMT_DBLP: + s->filter = biquad_tdi_dbl; + break; + default: av_assert0(0); + } + break; case TDII: switch (inlink->format) { case AV_SAMPLE_FMT_S16P: @@ -1006,6 +1080,7 @@ static const AVOption equalizer_options[] = { {"a", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"}, {"di", "direct form I", 0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"}, {"dii", "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"}, + {"tdi", "transposed direct form I", 0, AV_OPT_TYPE_CONST, {.i64=TDI}, 0, 0, AF, "transform_type"}, {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"}, {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"}, {"svf", "state variable filter form", 0, AV_OPT_TYPE_CONST, {.i64=SVF}, 0, 0, AF, "transform_type"}, @@ -1048,6 +1123,7 @@ static const AVOption bass_lowshelf_options[] = { {"a", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"}, {"di", "direct form I", 0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"}, {"dii", "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"}, + {"tdi", "transposed direct form I", 0, AV_OPT_TYPE_CONST, {.i64=TDI}, 0, 0, AF, "transform_type"}, {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"}, {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"}, {"svf", "state variable filter form", 0, AV_OPT_TYPE_CONST, {.i64=SVF}, 0, 0, AF, "transform_type"}, @@ -1097,6 +1173,7 @@ static const AVOption treble_highshelf_options[] = { {"a", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"}, {"di", "direct form I", 0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"}, {"dii", "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"}, + {"tdi", "transposed direct form I", 0, AV_OPT_TYPE_CONST, {.i64=TDI}, 0, 0, AF, "transform_type"}, {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"}, {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"}, {"svf", "state variable filter form", 0, AV_OPT_TYPE_CONST, {.i64=SVF}, 0, 0, AF, "transform_type"}, @@ -1145,6 +1222,7 @@ static const AVOption bandpass_options[] = { {"a", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"}, {"di", "direct form I", 0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"}, {"dii", "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"}, + {"tdi", "transposed direct form I", 0, AV_OPT_TYPE_CONST, {.i64=TDI}, 0, 0, AF, "transform_type"}, {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"}, {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"}, {"svf", "state variable filter form", 0, AV_OPT_TYPE_CONST, {.i64=SVF}, 0, 0, AF, "transform_type"}, @@ -1183,6 +1261,7 @@ static const AVOption bandreject_options[] = { {"a", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"}, {"di", "direct form I", 0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"}, {"dii", "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"}, + {"tdi", "transposed direct form I", 0, AV_OPT_TYPE_CONST, {.i64=TDI}, 0, 0, AF, "transform_type"}, {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"}, {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"}, {"svf", "state variable filter form", 0, AV_OPT_TYPE_CONST, {.i64=SVF}, 0, 0, AF, "transform_type"}, @@ -1223,6 +1302,7 @@ static const AVOption lowpass_options[] = { {"a", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"}, {"di", "direct form I", 0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"}, {"dii", "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"}, + {"tdi", "transposed direct form I", 0, AV_OPT_TYPE_CONST, {.i64=TDI}, 0, 0, AF, "transform_type"}, {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"}, {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"}, {"svf", "state variable filter form", 0, AV_OPT_TYPE_CONST, {.i64=SVF}, 0, 0, AF, "transform_type"}, @@ -1263,6 +1343,7 @@ static const AVOption highpass_options[] = { {"a", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"}, {"di", "direct form I", 0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"}, {"dii", "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"}, + {"tdi", "transposed direct form I", 0, AV_OPT_TYPE_CONST, {.i64=TDI}, 0, 0, AF, "transform_type"}, {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"}, {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"}, {"svf", "state variable filter form", 0, AV_OPT_TYPE_CONST, {.i64=SVF}, 0, 0, AF, "transform_type"}, @@ -1303,6 +1384,7 @@ static const AVOption allpass_options[] = { {"a", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"}, {"di", "direct form I", 0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"}, {"dii", "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"}, + {"tdi", "transposed direct form I", 0, AV_OPT_TYPE_CONST, {.i64=TDI}, 0, 0, AF, "transform_type"}, {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"}, {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"}, {"svf", "state variable filter form", 0, AV_OPT_TYPE_CONST, {.i64=SVF}, 0, 0, AF, "transform_type"}, @@ -1336,6 +1418,7 @@ static const AVOption biquad_options[] = { {"a", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=0}, 0, NB_TTYPE-1, AF, "transform_type"}, {"di", "direct form I", 0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"}, {"dii", "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"}, + {"tdi", "transposed direct form I", 0, AV_OPT_TYPE_CONST, {.i64=TDI}, 0, 0, AF, "transform_type"}, {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"}, {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"}, {"svf", "state variable filter form", 0, AV_OPT_TYPE_CONST, {.i64=SVF}, 0, 0, AF, "transform_type"},