Go to the documentation of this file.
65 #include "config_components.h"
157 double *i1,
double *i2,
double *o1,
double *o2,
158 double b0,
double b1,
double b2,
double a0,
double a1,
double a2,
int *clippings,
181 switch (
s->precision) {
195 sample_fmts_list = auto_sample_fmts;
205 #define BIQUAD_FILTER(name, type, min, max, need_clipping) \
206 static void biquad_## name (BiquadsContext *s, \
207 const void *input, void *output, int len, \
208 double *in1, double *in2, \
209 double *out1, double *out2, \
210 double b0, double b1, double b2, \
211 double a0, double a1, double a2, int *clippings, \
214 const type *ibuf = input; \
215 type *obuf = output; \
220 double wet = s->mix; \
221 double dry = 1. - wet; \
227 for (i = 0; i+1 < len; i++) { \
228 o2 = i2 * b2 + i1 * b1 + ibuf[i] * b0 + o2 * a2 + o1 * a1; \
230 out = o2 * wet + i2 * dry; \
233 } else if (need_clipping && out < min) { \
236 } else if (need_clipping && out > max) { \
243 o1 = i1 * b2 + i2 * b1 + ibuf[i] * b0 + o1 * a2 + o2 * a1; \
245 out = o1 * wet + i1 * dry; \
248 } else if (need_clipping && out < min) { \
251 } else if (need_clipping && out > max) { \
259 double o0 = ibuf[i] * b0 + i1 * b1 + i2 * b2 + o1 * a1 + o2 * a2; \
264 out = o0 * wet + i1 * dry; \
267 } else if (need_clipping && out < min) { \
270 } else if (need_clipping && out > max) { \
288 #define BIQUAD_DII_FILTER(name, type, min, max, need_clipping) \
289 static void biquad_dii_## name (BiquadsContext *s, \
290 const void *input, void *output, int len, \
291 double *z1, double *z2, \
292 double *unused1, double *unused2, \
293 double b0, double b1, double b2, \
294 double a0, double a1, double a2, int *clippings, \
297 const type *ibuf = input; \
298 type *obuf = output; \
301 double wet = s->mix; \
302 double dry = 1. - wet; \
303 double in, out, w0; \
308 for (int i = 0; i < len; i++) { \
310 w0 = in + a1 * w1 + a2 * w2; \
311 out = b0 * w0 + b1 * w1 + b2 * w2; \
314 out = out * wet + in * dry; \
317 } else if (need_clipping && out < min) { \
320 } else if (need_clipping && out > max) { \
336 #define BIQUAD_TDI_FILTER(name, type, min, max, need_clipping) \
337 static void biquad_tdi_## name (BiquadsContext *s, \
338 const void *input, void *output, int len, \
339 double *z1, double *z2, \
340 double *z3, double *z4, \
341 double b0, double b1, double b2, \
342 double a0, double a1, double a2, int *clippings, \
345 const type *ibuf = input; \
346 type *obuf = output; \
351 double wet = s->mix; \
352 double dry = 1. - wet; \
358 for (int i = 0; i < len; i++) { \
359 double t1, t2, t3, t4; \
365 out = b0 * in + s3; \
366 out = out * wet + in * dry; \
367 s1 = t1; s2 = t2; s3 = t3; s4 = t4; \
370 } else if (need_clipping && out < min) { \
373 } else if (need_clipping && out > max) { \
392 #define BIQUAD_TDII_FILTER(name, type, min, max, need_clipping) \
393 static void biquad_tdii_## name (BiquadsContext *s, \
394 const void *input, void *output, int len, \
395 double *z1, double *z2, \
396 double *unused1, double *unused2, \
397 double b0, double b1, double b2, \
398 double a0, double a1, double a2, int *clippings, \
401 const type *ibuf = input; \
402 type *obuf = output; \
405 double wet = s->mix; \
406 double dry = 1. - wet; \
412 for (int i = 0; i < len; i++) { \
414 out = b0 * in + w1; \
415 w1 = b1 * in + w2 + a1 * out; \
416 w2 = b2 * in + a2 * out; \
417 out = out * wet + in * dry; \
420 } else if (need_clipping && out < min) { \
423 } else if (need_clipping && out > max) { \
439 #define BIQUAD_LATT_FILTER(name, type, min, max, need_clipping) \
440 static void biquad_latt_## name (BiquadsContext *s, \
441 const void *input, void *output, int len, \
442 double *z1, double *z2, \
443 double *unused1, double *unused2, \
444 double v0, double v1, double v2, \
445 double unused, double k0, double k1, \
449 const type *ibuf = input; \
450 type *obuf = output; \
453 double wet = s->mix; \
454 double dry = 1. - wet; \
458 for (int i = 0; i < len; i++) { \
473 out = out * wet + in * dry; \
476 } else if (need_clipping && out < min) { \
479 } else if (need_clipping && out > max) { \
495 #define BIQUAD_SVF_FILTER(name, type, min, max, need_clipping) \
496 static void biquad_svf_## name (BiquadsContext *s, \
497 const void *input, void *output, int len, \
498 double *y0, double *y1, \
499 double *unused1, double *unused2, \
500 double b0, double b1, double b2, \
501 double a0, double a1, double a2, int *clippings, \
504 const type *ibuf = input; \
505 type *obuf = output; \
508 double wet = s->mix; \
509 double dry = 1. - wet; \
513 for (int i = 0; i < len; i++) { \
515 out = b2 * in + s0; \
516 t0 = b0 * in + a1 * s0 + s1; \
517 t1 = b1 * in + a2 * s0; \
521 out = out * wet + in * dry; \
524 } else if (need_clipping && out < min) { \
527 } else if (need_clipping && out > max) { \
543 #define BIQUAD_ZDF_FILTER(name, type, min, max, need_clipping) \
544 static void biquad_zdf_## name (BiquadsContext *s, \
545 const void *input, void *output, int len, \
546 double *y0, double *y1, \
547 double *unused1, double *unused2, \
548 double m0, double m1, double m2, \
549 double a0, double a1, double a2, int *clippings, \
552 const type *ibuf = input; \
553 type *obuf = output; \
556 double wet = s->mix; \
557 double dry = 1. - wet; \
560 for (int i = 0; i < len; i++) { \
561 const double in = ibuf[i]; \
562 const double v0 = in; \
563 const double v3 = v0 - b1; \
564 const double v1 = a0 * b0 + a1 * v3; \
565 const double v2 = b1 + a1 * b0 + a2 * v3; \
570 out = m0 * v0 + m1 * v1 + m2 * v2; \
571 out = out * wet + in * dry; \
574 } else if (need_clipping && out < min) { \
577 } else if (need_clipping && out > max) { \
595 double k0, k1,
v0, v1, v2;
598 k0 =
s->a1 / (1. + k1);
600 v1 =
s->b1 - v2 *
s->a1;
601 v0 =
s->b0 - v1 * k0 - v2 * k1;
617 b[0] =
s->b1 -
s->a1 *
s->b0;
618 b[1] =
s->b2 -
s->a2 *
s->b0;
650 ret = 1. / (2. * sinh(log(2.) / 2. *
width * w0 / sin(w0)));
653 ret = 1. / sqrt((
A + 1. /
A) * (1. /
width - 1.) + 2.);
670 switch (
s->filter_type) {
683 a[0] = 1. / (1. +
g * (
g + k));
687 m[1] = k * (
A *
A - 1.);
695 a[0] = 1. / (1. +
g * (
g + k));
706 a[0] = 1. / (1. +
g * (
g + k));
710 m[1] = k * (
A - 1.) /
A;
711 m[2] = (
A *
A - 1.) /
A;
718 a[0] = 1. / (1. +
g * (
g + k));
722 m[1] = k * (1. -
A) *
A;
728 a[0] = 1. / (1. +
g * (
g + k));
732 m[1] =
s->csg ? 1. : k;
738 a[0] = 1. / (1. +
g * (
g + k));
748 a[0] = 1. / (1. +
g * (
g + k));
758 a[0] = 1. / (1. +
g * (
g + k));
768 a[0] = 1. / (1. +
g * (
g + k));
794 double w0 = 2 *
M_PI *
s->frequency /
inlink->sample_rate;
795 double K = tan(w0 / 2.);
798 s->bypass = (((w0 >
M_PI || w0 <= 0.) && reset) || (
s->width <= 0.)) && (
s->filter_type !=
biquad);
804 if ((w0 >
M_PI || w0 <= 0.) && (
s->filter_type !=
biquad))
807 switch (
s->width_type) {
812 alpha = sin(w0) / (2 *
s->frequency /
s->width);
815 alpha = sin(w0) / (2 *
s->frequency / (
s->width * 1000));
818 alpha = sin(w0) * sinh(log(2.) / 2 *
s->width * w0 / sin(w0));
821 alpha = sin(w0) / (2 *
s->width);
824 alpha = sin(w0) / 2 * sqrt((
A + 1 /
A) * (1 /
s->width - 1) + 2);
832 switch (
s->filter_type) {
843 s->a1 = -2 * cos(w0);
846 s->b1 = -2 * cos(w0);
850 beta = sqrt((
A *
A + 1) - (
A - 1) * (
A - 1));
855 double ro = -sin(w0 / 2. - M_PI_4) / sin(w0 / 2. + M_PI_4);
856 double n = (
A + 1) / (
A - 1);
857 double alpha1 =
A == 1. ? 0. : n -
FFSIGN(n) * sqrt(n * n - 1);
858 double beta0 = ((1 +
A) + (1 -
A) * alpha1) * 0.5;
859 double beta1 = ((1 -
A) + (1 +
A) * alpha1) * 0.5;
861 s->a0 = 1 + ro * alpha1;
862 s->a1 = -ro - alpha1;
864 s->b0 = beta0 + ro * beta1;
865 s->b1 = -beta1 - ro * beta0;
868 s->a0 = (
A + 1) + (
A - 1) * cos(w0) + beta *
alpha;
869 s->a1 = -2 * ((
A - 1) + (
A + 1) * cos(w0));
870 s->a2 = (
A + 1) + (
A - 1) * cos(w0) - beta *
alpha;
871 s->b0 =
A * ((
A + 1) - (
A - 1) * cos(w0) + beta *
alpha);
872 s->b1 = 2 *
A * ((
A - 1) - (
A + 1) * cos(w0));
873 s->b2 =
A * ((
A + 1) - (
A - 1) * cos(w0) - beta *
alpha);
877 beta = sqrt((
A *
A + 1) - (
A - 1) * (
A - 1));
881 double ro = sin(w0 / 2. - M_PI_4) / sin(w0 / 2. + M_PI_4);
882 double n = (
A + 1) / (
A - 1);
883 double alpha1 =
A == 1. ? 0. : n -
FFSIGN(n) * sqrt(n * n - 1);
884 double beta0 = ((1 +
A) + (1 -
A) * alpha1) * 0.5;
885 double beta1 = ((1 -
A) + (1 +
A) * alpha1) * 0.5;
887 s->a0 = 1 + ro * alpha1;
890 s->b0 = beta0 + ro * beta1;
891 s->b1 = beta1 + ro * beta0;
894 s->a0 = (
A + 1) - (
A - 1) * cos(w0) + beta *
alpha;
895 s->a1 = 2 * ((
A - 1) - (
A + 1) * cos(w0));
896 s->a2 = (
A + 1) - (
A - 1) * cos(w0) - beta *
alpha;
897 s->b0 =
A * ((
A + 1) + (
A - 1) * cos(w0) + beta *
alpha);
898 s->b1 =-2 *
A * ((
A - 1) + (
A + 1) * cos(w0));
899 s->b2 =
A * ((
A + 1) + (
A - 1) * cos(w0) - beta *
alpha);
905 s->a1 = -2 * cos(w0);
909 s->b2 = -sin(w0) / 2;
912 s->a1 = -2 * cos(w0);
921 s->a1 = -2 * cos(w0);
924 s->b1 = -2 * cos(w0);
937 s->a1 = -2 * cos(w0);
939 s->b0 = (1 - cos(w0)) / 2;
941 s->b2 = (1 - cos(w0)) / 2;
949 s->b0 = (1 -
s->a1) / 2;
954 s->a1 = -2 * cos(w0);
956 s->b0 = (1 + cos(w0)) / 2;
957 s->b1 = -(1 + cos(w0));
958 s->b2 = (1 + cos(w0)) / 2;
965 s->a1 = -(1. -
K) / (1. +
K);
973 s->a1 = -2 * cos(w0);
976 s->b1 = -2 * cos(w0);
994 if (
s->normalize &&
fabs(
s->b0 +
s->b1 +
s->b2) > 1e-6) {
995 double factor = (
s->a0 +
s->a1 +
s->a2) / (
s->b0 +
s->b1 +
s->b2);
1002 switch (
s->filter_type) {
1016 if (reset &&
s->block_samples > 0) {
1017 for (
int i = 0;
i < 3;
i++) {
1022 s->block[
i]->ch_layout.nb_channels,
s->block[
i]->format);
1026 switch (
s->transform_type) {
1028 switch (
inlink->format) {
1030 s->filter = biquad_s16;
1033 s->filter = biquad_s32;
1036 s->filter = biquad_flt;
1039 s->filter = biquad_dbl;
1045 switch (
inlink->format) {
1047 s->filter = biquad_dii_s16;
1050 s->filter = biquad_dii_s32;
1053 s->filter = biquad_dii_flt;
1056 s->filter = biquad_dii_dbl;
1062 switch (
inlink->format) {
1064 s->filter = biquad_tdi_s16;
1067 s->filter = biquad_tdi_s32;
1070 s->filter = biquad_tdi_flt;
1073 s->filter = biquad_tdi_dbl;
1079 switch (
inlink->format) {
1081 s->filter = biquad_tdii_s16;
1084 s->filter = biquad_tdii_s32;
1087 s->filter = biquad_tdii_flt;
1090 s->filter = biquad_tdii_dbl;
1096 switch (
inlink->format) {
1098 s->filter = biquad_latt_s16;
1101 s->filter = biquad_latt_s32;
1104 s->filter = biquad_latt_flt;
1107 s->filter = biquad_latt_dbl;
1113 switch (
inlink->format) {
1115 s->filter = biquad_svf_s16;
1118 s->filter = biquad_svf_s32;
1121 s->filter = biquad_svf_flt;
1124 s->filter = biquad_svf_dbl;
1130 switch (
inlink->format) {
1132 s->filter = biquad_zdf_s16;
1135 s->filter = biquad_zdf_s32;
1138 s->filter = biquad_zdf_flt;
1141 s->filter = biquad_zdf_dbl;
1152 if (
s->transform_type ==
LATT)
1154 else if (
s->transform_type ==
SVF)
1156 else if (
s->transform_type ==
ZDF)
1173 int oo,
int io,
int nb_samples)
1175 switch (
out->format) {
1178 int16_t *dst = ((int16_t *)
out->extended_data[p]) + oo;
1179 for (
int i = 0, j = nb_samples - 1;
i < nb_samples;
i++, j--)
1186 for (
int i = 0, j = nb_samples - 1;
i < nb_samples;
i++, j--)
1192 float *dst = ((
float *)
out->extended_data[p]) + oo;
1193 for (
int i = 0, j = nb_samples - 1;
i < nb_samples;
i++, j--)
1199 double *dst = ((
double *)
out->extended_data[p]) + oo;
1200 for (
int i = 0, j = nb_samples - 1;
i < nb_samples;
i++, j--)
1218 for (ch = start; ch < end; ch++) {
1228 if (!
s->block_samples) {
1230 &
s->cache[ch].i1, &
s->cache[ch].i2, &
s->cache[ch].o1, &
s->cache[ch].o2,
1231 s->b0,
s->b1,
s->b2,
s->a0,
s->a1,
s->a2, &
s->cache[ch].clippings,
ctx->is_disabled);
1232 }
else if (
td->eof) {
1233 memcpy(out_buf->
extended_data[ch],
s->block[1]->extended_data[ch] +
s->block_align *
s->block_samples,
1234 s->nb_samples *
s->block_align);
1236 memcpy(
s->block[0]->extended_data[ch] +
s->block_align *
s->block_samples, buf->
extended_data[ch],
1238 memset(
s->block[0]->extended_data[ch] +
s->block_align * (
s->block_samples + buf->
nb_samples),
1239 0, (
s->block_samples - buf->
nb_samples) *
s->block_align);
1240 s->filter(
s,
s->block[0]->extended_data[ch],
s->block[1]->extended_data[ch],
s->block_samples,
1241 &
s->cache[ch].i1, &
s->cache[ch].i2, &
s->cache[ch].o1, &
s->cache[ch].o2,
1242 s->b0,
s->b1,
s->b2,
s->a0,
s->a1,
s->a2, &
s->cache[ch].clippings,
ctx->is_disabled);
1243 s->cache[ch].ri1 =
s->cache[ch].i1;
1244 s->cache[ch].ri2 =
s->cache[ch].i2;
1245 s->cache[ch].ro1 =
s->cache[ch].o1;
1246 s->cache[ch].ro2 =
s->cache[ch].o2;
1247 s->filter(
s,
s->block[0]->extended_data[ch] +
s->block_samples *
s->block_align,
1248 s->block[1]->extended_data[ch] +
s->block_samples *
s->block_align,
1250 &
s->cache[ch].ri1, &
s->cache[ch].ri2, &
s->cache[ch].ro1, &
s->cache[ch].ro2,
1251 s->b0,
s->b1,
s->b2,
s->a0,
s->a1,
s->a2, &
s->cache[ch].clippings,
ctx->is_disabled);
1253 s->cache[ch].ri1 = 0.;
1254 s->cache[ch].ri2 = 0.;
1255 s->cache[ch].ro1 = 0.;
1256 s->cache[ch].ro2 = 0.;
1257 s->filter(
s,
s->block[2]->extended_data[ch],
s->block[2]->extended_data[ch], 2 *
s->block_samples,
1258 &
s->cache[ch].ri1, &
s->cache[ch].ri2, &
s->cache[ch].ro1, &
s->cache[ch].ro2,
1259 s->b0,
s->b1,
s->b2,
s->a0,
s->a1,
s->a2, &
s->cache[ch].clippings,
ctx->is_disabled);
1261 memcpy(out_buf->
extended_data[ch],
s->block[1]->extended_data[ch],
1262 s->block_samples *
s->block_align);
1263 memmove(
s->block[0]->extended_data[ch],
s->block[0]->extended_data[ch] +
s->block_align *
s->block_samples,
1264 s->block_samples *
s->block_align);
1278 int ch,
ret, drop = 0;
1288 if (strcmp(
s->ch_layout_str,
"all"))
1312 if (
s->cache[ch].clippings > 0)
1314 ch,
s->cache[ch].clippings);
1315 s->cache[ch].clippings = 0;
1318 if (
s->block_samples > 0) {
1322 out_buf->
pts =
s->pts;
1325 s->nb_samples = nb_samples;
1352 if (
s->block_samples > 0) {
1368 if (
s->block_samples > 0) {
1387 char *res,
int res_len,
int flags)
1403 for (
int i = 0;
i < 3;
i++)
1424 #define OFFSET(x) offsetof(BiquadsContext, x)
1425 #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
1426 #define AF AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
1428 #define DEFINE_BIQUAD_FILTER_2(name_, description_, priv_class_) \
1429 static av_cold int name_##_init(AVFilterContext *ctx) \
1431 BiquadsContext *s = ctx->priv; \
1432 s->filter_type = name_; \
1433 s->pts = AV_NOPTS_VALUE; \
1437 const AVFilter ff_af_##name_ = { \
1439 .description = NULL_IF_CONFIG_SMALL(description_), \
1440 .priv_class = &priv_class_##_class, \
1441 .priv_size = sizeof(BiquadsContext), \
1442 .init = name_##_init, \
1443 .activate = activate, \
1445 FILTER_INPUTS(inputs), \
1446 FILTER_OUTPUTS(outputs), \
1447 FILTER_QUERY_FUNC(query_formats), \
1448 .process_command = process_command, \
1449 .flags = AVFILTER_FLAG_SLICE_THREADS | AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL, \
1452 #define DEFINE_BIQUAD_FILTER(name, description) \
1453 AVFILTER_DEFINE_CLASS(name); \
1454 DEFINE_BIQUAD_FILTER_2(name, description, name)
1456 #define WIDTH_OPTION(x) \
1457 {"width", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=x}, 0, 99999, FLAGS}, \
1458 {"w", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=x}, 0, 99999, FLAGS}
1460 #define WIDTH_TYPE_OPTION(x) \
1461 {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=x}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"}, \
1462 {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=x}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"}, \
1463 {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"}, \
1464 {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"}, \
1465 {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"}, \
1466 {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"}, \
1467 {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"}
1469 #define MIX_CHANNELS_NORMALIZE_OPTION(x, y, z) \
1470 {"mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=x}, 0, 1, FLAGS}, \
1471 {"m", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=x}, 0, 1, FLAGS}, \
1472 {"channels", "set channels to filter", OFFSET(ch_layout_str), AV_OPT_TYPE_STRING, {.str=y}, 0, 0, FLAGS}, \
1473 {"c", "set channels to filter", OFFSET(ch_layout_str), AV_OPT_TYPE_STRING, {.str=y}, 0, 0, FLAGS}, \
1474 {"normalize", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=z}, 0, 1, FLAGS}, \
1475 {"n", "normalize coefficients", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=z}, 0, 1, FLAGS}
1477 #define TRANSFORM_OPTION(x) \
1478 {"transform", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=x}, 0, NB_TTYPE-1, AF, "transform_type"}, \
1479 {"a", "set transform type", OFFSET(transform_type), AV_OPT_TYPE_INT, {.i64=x}, 0, NB_TTYPE-1, AF, "transform_type"}, \
1480 {"di", "direct form I", 0, AV_OPT_TYPE_CONST, {.i64=DI}, 0, 0, AF, "transform_type"}, \
1481 {"dii", "direct form II", 0, AV_OPT_TYPE_CONST, {.i64=DII}, 0, 0, AF, "transform_type"}, \
1482 {"tdi", "transposed direct form I", 0, AV_OPT_TYPE_CONST, {.i64=TDI}, 0, 0, AF, "transform_type"}, \
1483 {"tdii", "transposed direct form II", 0, AV_OPT_TYPE_CONST, {.i64=TDII}, 0, 0, AF, "transform_type"}, \
1484 {"latt", "lattice-ladder form", 0, AV_OPT_TYPE_CONST, {.i64=LATT}, 0, 0, AF, "transform_type"}, \
1485 {"svf", "state variable filter form", 0, AV_OPT_TYPE_CONST, {.i64=SVF}, 0, 0, AF, "transform_type"}, \
1486 {"zdf", "zero-delay filter form", 0, AV_OPT_TYPE_CONST, {.i64=ZDF}, 0, 0, AF, "transform_type"}
1488 #define PRECISION_OPTION(x) \
1489 {"precision", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=x}, -1, 3, AF, "precision"}, \
1490 {"r", "set filtering precision", OFFSET(precision), AV_OPT_TYPE_INT, {.i64=x}, -1, 3, AF, "precision"}, \
1491 {"auto", "automatic", 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, AF, "precision"}, \
1492 {"s16", "signed 16-bit", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "precision"}, \
1493 {"s32", "signed 32-bit", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "precision"}, \
1494 {"f32", "floating-point single", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, AF, "precision"}, \
1495 {"f64", "floating-point double", 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, AF, "precision"}
1497 #define BLOCKSIZE_OPTION(x) \
1498 {"blocksize", "set the block size", OFFSET(block_samples), AV_OPT_TYPE_INT, {.i64=x}, 0, 32768, AF}, \
1499 {"b", "set the block size", OFFSET(block_samples), AV_OPT_TYPE_INT, {.i64=x}, 0, 32768, AF}
1501 #if CONFIG_EQUALIZER_FILTER
1502 static const AVOption equalizer_options[] = {
1518 #if CONFIG_BASS_FILTER || CONFIG_LOWSHELF_FILTER
1519 static const AVOption bass_lowshelf_options[] = {
1536 #if CONFIG_BASS_FILTER
1540 #if CONFIG_LOWSHELF_FILTER
1544 #if CONFIG_TREBLE_FILTER || CONFIG_HIGHSHELF_FILTER || CONFIG_TILTSHELF_FILTER
1545 static const AVOption treble_highshelf_options[] = {
1562 treble_highshelf_options);
1564 #if CONFIG_TREBLE_FILTER
1568 #if CONFIG_HIGHSHELF_FILTER
1572 #if CONFIG_TILTSHELF_FILTER
1577 #if CONFIG_BANDPASS_FILTER
1578 static const AVOption bandpass_options[] = {
1593 #if CONFIG_BANDREJECT_FILTER
1594 static const AVOption bandreject_options[] = {
1608 #if CONFIG_LOWPASS_FILTER
1609 static const AVOption lowpass_options[] = {
1625 #if CONFIG_HIGHPASS_FILTER
1626 static const AVOption highpass_options[] = {
1642 #if CONFIG_ALLPASS_FILTER
1643 static const AVOption allpass_options[] = {
1658 #if CONFIG_BIQUAD_FILTER
1659 static const AVOption biquad_options[] = {
#define BLOCKSIZE_OPTION(x)
AVFrame * ff_get_audio_buffer(AVFilterLink *link, int nb_samples)
Request an audio samples buffer with a specific set of permissions.
@ AV_SAMPLE_FMT_FLTP
float, planar
#define BIQUAD_ZDF_FILTER(name, type, min, max, need_clipping)
#define AV_LOG_WARNING
Something somehow does not look correct.
they must not be accessed directly The fifo field contains the frames that are queued in the input for processing by the filter The status_in and status_out fields contains the queued status(EOF or error) of the link
static av_always_inline double ff_exp10(double x)
Compute 10^x for floating point values.
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
static enum AVSampleFormat sample_fmts[]
#define DEFINE_BIQUAD_FILTER(name, description)
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is inlink
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
static void reverse_samples(AVFrame *out, AVFrame *in, int p, int oo, int io, int nb_samples)
This structure describes decoded (raw) audio or video data.
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
enum AVChannel av_channel_layout_channel_from_index(const AVChannelLayout *channel_layout, unsigned int idx)
Get the channel with the given index in a channel layout.
@ AV_SAMPLE_FMT_S32P
signed 32 bits, planar
#define AV_LOG_VERBOSE
Detailed information.
#define AVFILTER_DEFINE_CLASS_EXT(name, desc, options)
int nb_channels
Number of channels in this layout.
A link between two filters.
#define FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink)
Forward the status on an output link to an input link.
int ff_inlink_consume_frame(AVFilterLink *link, AVFrame **rframe)
Take a frame from the link's FIFO and update the link's stats.
static void convert_dir2latt(BiquadsContext *s)
static const AVFilterPad outputs[]
AVChannelLayout ch_layout
Channel layout of the audio data.
AVChannelLayout ch_layout
A filter pad used for either input or output.
static int activate(AVFilterContext *ctx)
static void convert_dir2zdf(BiquadsContext *s, int sample_rate)
static void ff_outlink_set_status(AVFilterLink *link, int status, int64_t pts)
Set the status field of a link from the source filter.
static void convert_dir2svf(BiquadsContext *s)
#define av_assert0(cond)
assert() equivalent, that is always enabled.
#define av_realloc_f(p, o, n)
Describe the class of an AVClass context structure.
static __device__ float fabs(float a)
int ff_inlink_consume_samples(AVFilterLink *link, unsigned min, unsigned max, AVFrame **rframe)
Take samples from the link's FIFO and update the link's stats.
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
static int filter_frame(AVFilterLink *inlink, AVFrame *buf, int eof)
#define MIX_CHANNELS_NORMALIZE_OPTION(x, y, z)
int ff_inlink_acknowledge_status(AVFilterLink *link, int *rstatus, int64_t *rpts)
Test and acknowledge the change of status on the link.
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
static int filter_channel(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
An AVChannelLayout holds information about the channel layout of audio data.
#define BIQUAD_TDI_FILTER(name, type, min, max, need_clipping)
#define AV_NOPTS_VALUE
Undefined timestamp value.
int av_frame_is_writable(AVFrame *frame)
Check if the frame data is writable.
AVFilterContext * src
source filter
int ff_filter_process_command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
Generic processing of user supplied commands that are set in the same way as the filter options.
static int config_output(AVFilterLink *outlink)
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
FF_FILTER_FORWARD_WANTED(outlink, inlink)
#define BIQUAD_LATT_FILTER(name, type, min, max, need_clipping)
@ AV_SAMPLE_FMT_S16P
signed 16 bits, planar
static const AVFilterPad inputs[]
int av_channel_layout_from_string(AVChannelLayout *channel_layout, const char *str)
Initialize a channel layout from a given string description.
int nb_samples
number of audio samples (per channel) described by this frame
#define i(width, name, range_min, range_max)
int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt)
Return number of bytes per sample.
uint8_t ** extended_data
pointers to the data planes/channels.
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
#define BIQUAD_DII_FILTER(name, type, min, max, need_clipping)
AVSampleFormat
Audio sample formats.
Used for passing data between threads.
static int config_filter(AVFilterLink *outlink, int reset)
const char * name
Pad name.
int ff_inlink_queued_samples(AVFilterLink *link)
int av_samples_set_silence(uint8_t **audio_data, int offset, int nb_samples, int nb_channels, enum AVSampleFormat sample_fmt)
Fill an audio buffer with silence.
#define PRECISION_OPTION(x)
#define TRANSFORM_OPTION(x)
#define BIQUAD_FILTER(name, type, min, max, need_clipping)
void(* filter)(struct BiquadsContext *s, const void *ibuf, void *obuf, int len, double *i1, double *i2, double *o1, double *o2, double b0, double b1, double b2, double a0, double a1, double a2, int *clippings, int disabled)
enum FilterType filter_type
int av_channel_layout_index_from_channel(const AVChannelLayout *channel_layout, enum AVChannel channel)
Get the index of a given channel in a channel layout.
void av_channel_layout_uninit(AVChannelLayout *channel_layout)
Free any allocated data in the channel layout and reset the channel count to 0.
static int query_formats(AVFilterContext *ctx)
@ AV_SAMPLE_FMT_DBLP
double, planar
#define DEFINE_BIQUAD_FILTER_2(name_, description_, priv_class_)
#define WIDTH_TYPE_OPTION(x)
static av_cold void uninit(AVFilterContext *ctx)
static const int factor[16]
int av_channel_layout_copy(AVChannelLayout *dst, const AVChannelLayout *src)
Make a copy of a channel layout.
#define BIQUAD_SVF_FILTER(name, type, min, max, need_clipping)
AVChannelLayout ch_layout
channel layout of current buffer (see libavutil/channel_layout.h)
static const int16_t alpha[]
#define BIQUAD_TDII_FILTER(name, type, min, max, need_clipping)
static double convert_width2qfactor(double width, double frequency, double gain, double sample_rate, int width_type)
#define flags(name, subs,...)
static av_always_inline int ff_filter_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg, int *ret, int nb_jobs)
void ff_filter_set_ready(AVFilterContext *filter, unsigned priority)
Mark a filter ready and schedule it for activation.