Go to the documentation of this file.
112 #define IIR_CH(name, type, min, max, need_clipping) \
113 static int iir_ch_## name(AVFilterContext *ctx, void *arg, int ch, int nb_jobs) \
115 AudioIIRContext *s = ctx->priv; \
116 const double ig = s->dry_gain; \
117 const double og = s->wet_gain; \
118 const double mix = s->mix; \
119 ThreadData *td = arg; \
120 AVFrame *in = td->in, *out = td->out; \
121 const type *src = (const type *)in->extended_data[ch]; \
122 double *oc = (double *)s->iir[ch].cache[0]; \
123 double *ic = (double *)s->iir[ch].cache[1]; \
124 const int nb_a = s->iir[ch].nb_ab[0]; \
125 const int nb_b = s->iir[ch].nb_ab[1]; \
126 const double *a = s->iir[ch].ab[0]; \
127 const double *b = s->iir[ch].ab[1]; \
128 const double g = s->iir[ch].g; \
129 int *clippings = &s->iir[ch].clippings; \
130 type *dst = (type *)out->extended_data[ch]; \
133 for (n = 0; n < in->nb_samples; n++) { \
134 double sample = 0.; \
137 memmove(&ic[1], &ic[0], (nb_b - 1) * sizeof(*ic)); \
138 memmove(&oc[1], &oc[0], (nb_a - 1) * sizeof(*oc)); \
139 ic[0] = src[n] * ig; \
140 for (x = 0; x < nb_b; x++) \
141 sample += b[x] * ic[x]; \
143 for (x = 1; x < nb_a; x++) \
144 sample -= a[x] * oc[x]; \
148 sample = sample * mix + ic[0] * (1. - mix); \
149 if (need_clipping && sample < min) { \
152 } else if (need_clipping && sample > max) { \
163 IIR_CH(s16p, int16_t, INT16_MIN, INT16_MAX, 1)
165 IIR_CH(fltp,
float, -1., 1., 0)
166 IIR_CH(dblp,
double, -1., 1., 0)
168 #define SERIAL_IIR_CH(name, type, min, max, need_clipping) \
169 static int iir_ch_serial_## name(AVFilterContext *ctx, void *arg, \
170 int ch, int nb_jobs) \
172 AudioIIRContext *s = ctx->priv; \
173 const double ig = s->dry_gain; \
174 const double og = s->wet_gain; \
175 const double mix = s->mix; \
176 const double imix = 1. - mix; \
177 ThreadData *td = arg; \
178 AVFrame *in = td->in, *out = td->out; \
179 const type *src = (const type *)in->extended_data[ch]; \
180 type *dst = (type *)out->extended_data[ch]; \
181 IIRChannel *iir = &s->iir[ch]; \
182 const double g = iir->g; \
183 int *clippings = &iir->clippings; \
184 int nb_biquads = (FFMAX(iir->nb_ab[0], iir->nb_ab[1]) + 1) / 2; \
187 for (i = nb_biquads - 1; i >= 0; i--) { \
188 const double a1 = -iir->biquads[i].a[1]; \
189 const double a2 = -iir->biquads[i].a[2]; \
190 const double b0 = iir->biquads[i].b[0]; \
191 const double b1 = iir->biquads[i].b[1]; \
192 const double b2 = iir->biquads[i].b[2]; \
193 double w1 = iir->biquads[i].w1; \
194 double w2 = iir->biquads[i].w2; \
196 for (n = 0; n < in->nb_samples; n++) { \
197 double i0 = ig * (i ? dst[n] : src[n]); \
198 double o0 = i0 * b0 + w1; \
200 w1 = b1 * i0 + w2 + a1 * o0; \
201 w2 = b2 * i0 + a2 * o0; \
204 o0 = o0 * mix + imix * i0; \
205 if (need_clipping && o0 < min) { \
208 } else if (need_clipping && o0 > max) { \
215 iir->biquads[i].w1 = w1; \
216 iir->biquads[i].w2 = w2; \
227 #define PARALLEL_IIR_CH(name, type, min, max, need_clipping) \
228 static int iir_ch_parallel_## name(AVFilterContext *ctx, void *arg, \
229 int ch, int nb_jobs) \
231 AudioIIRContext *s = ctx->priv; \
232 const double ig = s->dry_gain; \
233 const double og = s->wet_gain; \
234 const double mix = s->mix; \
235 const double imix = 1. - mix; \
236 ThreadData *td = arg; \
237 AVFrame *in = td->in, *out = td->out; \
238 const type *src = (const type *)in->extended_data[ch]; \
239 type *dst = (type *)out->extended_data[ch]; \
240 IIRChannel *iir = &s->iir[ch]; \
241 const double g = iir->g; \
242 const double fir = iir->fir; \
243 int *clippings = &iir->clippings; \
244 int nb_biquads = (FFMAX(iir->nb_ab[0], iir->nb_ab[1]) + 1) / 2; \
247 for (i = 0; i < nb_biquads; i++) { \
248 const double a1 = -iir->biquads[i].a[1]; \
249 const double a2 = -iir->biquads[i].a[2]; \
250 const double b1 = iir->biquads[i].b[1]; \
251 const double b2 = iir->biquads[i].b[2]; \
252 double w1 = iir->biquads[i].w1; \
253 double w2 = iir->biquads[i].w2; \
255 for (n = 0; n < in->nb_samples; n++) { \
256 double i0 = ig * src[n]; \
259 w1 = b1 * i0 + w2 + a1 * o0; \
260 w2 = b2 * i0 + a2 * o0; \
264 if (need_clipping && o0 < min) { \
267 } else if (need_clipping && o0 > max) { \
274 iir->biquads[i].w1 = w1; \
275 iir->biquads[i].w2 = w2; \
278 for (n = 0; n < in->nb_samples; n++) { \
279 dst[n] += fir * src[n]; \
280 dst[n] = dst[n] * mix + imix * src[n]; \
291 #define LATTICE_IIR_CH(name, type, min, max, need_clipping) \
292 static int iir_ch_lattice_## name(AVFilterContext *ctx, void *arg, \
293 int ch, int nb_jobs) \
295 AudioIIRContext *s = ctx->priv; \
296 const double ig = s->dry_gain; \
297 const double og = s->wet_gain; \
298 const double mix = s->mix; \
299 ThreadData *td = arg; \
300 AVFrame *in = td->in, *out = td->out; \
301 const type *src = (const type *)in->extended_data[ch]; \
302 double n0, n1, p0, *x = (double *)s->iir[ch].cache[0]; \
303 const int nb_stages = s->iir[ch].nb_ab[1]; \
304 const double *v = s->iir[ch].ab[0]; \
305 const double *k = s->iir[ch].ab[1]; \
306 const double g = s->iir[ch].g; \
307 int *clippings = &s->iir[ch].clippings; \
308 type *dst = (type *)out->extended_data[ch]; \
311 for (n = 0; n < in->nb_samples; n++) { \
312 const double in = src[n] * ig; \
316 for (int i = nb_stages - 1; i >= 0; i--) { \
317 n0 = n1 - k[i] * x[i]; \
318 p0 = n0 * k[i] + x[i]; \
319 out += p0 * v[i+1]; \
325 memmove(&x[1], &x[0], nb_stages * sizeof(*x)); \
328 out = out * mix + in * (1. - mix); \
329 if (need_clipping && out < min) { \
332 } else if (need_clipping && out > max) { \
356 for (p = item_str; *p && *p !=
'|'; p++) {
365 char *p, *
arg, *old_str, *prev_arg =
NULL, *saveptr =
NULL;
371 for (
i = 0;
i < nb_items;
i++) {
397 char *p, *
arg, *old_str, *saveptr =
NULL;
403 for (
i = 0;
i < nb_items;
i++) {
422 char *p, *
arg, *old_str, *saveptr =
NULL;
428 for (
i = 0;
i < nb_items;
i++) {
445 static const char *
const format[] = {
"%lf",
"%lf %lfi",
"%lf %lfr",
"%lf %lfd",
"%lf %lfi" };
450 char *p, *
arg, *old_str, *prev_arg =
NULL, *saveptr =
NULL;
472 if (!iir->
ab[ab] || !iir->
cache[ab]) {
494 static void cmul(
double re,
double im,
double re2,
double im2,
double *
RE,
double *
IM)
496 *
RE =
re * re2 -
im * im2;
497 *
IM =
re * im2 + re2 *
im;
504 for (
int i = 1;
i <= n;
i++) {
505 for (
int j = n -
i; j < n; j++) {
508 cmul(coefs[2 * (j + 1)], coefs[2 * (j + 1) + 1],
509 pz[2 * (
i - 1)], pz[2 * (
i - 1) + 1], &
re, &
im);
512 coefs[2 * j + 1] -=
im;
516 for (
int i = 0;
i < n + 1;
i++) {
517 if (
fabs(coefs[2 *
i + 1]) > FLT_EPSILON) {
518 av_log(
ctx,
AV_LOG_ERROR,
"coefs: %f of z^%d is not real; poles/zeros are not complex conjugates.\n",
519 coefs[2 *
i + 1],
i);
536 for (
int i = 0;
i < iir->
nb_ab[1];
i++) {
537 sum_den += iir->
ab[1][
i];
540 if (sum_den > 1e-6) {
541 double factor, sum_num = 0.;
543 for (
int i = 0;
i < iir->
nb_ab[0];
i++) {
544 sum_num += iir->
ab[0][
i];
547 factor = sum_num / sum_den;
549 for (
int i = 0;
i < iir->
nb_ab[1];
i++) {
558 int ch,
i, j,
ret = 0;
566 if (!topc || !botc) {
581 for (j = 0,
i = iir->
nb_ab[1];
i >= 0; j++,
i--) {
582 iir->
ab[1][j] = topc[2 *
i];
586 for (j = 0,
i = iir->
nb_ab[0];
i >= 0; j++,
i--) {
587 iir->
ab[0][j] = botc[2 *
i];
611 int current_biquad = 0;
617 while (nb_biquads--) {
618 Pair outmost_pole = { -1, -1 };
619 Pair nearest_zero = { -1, -1 };
620 double zeros[4] = { 0 };
621 double poles[4] = { 0 };
624 double min_distance = DBL_MAX;
629 for (
i = 0;
i < iir->
nb_ab[0];
i++) {
634 mag =
hypot(iir->
ab[0][2 *
i], iir->
ab[0][2 *
i + 1]);
642 for (
i = 0;
i < iir->
nb_ab[0];
i++) {
646 if (iir->
ab[0][2 *
i ] == iir->
ab[0][2 * outmost_pole.
a ] &&
647 iir->
ab[0][2 *
i + 1] == -iir->
ab[0][2 * outmost_pole.
a + 1]) {
655 if (outmost_pole.
a < 0 || outmost_pole.
b < 0)
658 for (
i = 0;
i < iir->
nb_ab[1];
i++) {
664 iir->
ab[0][2 * outmost_pole.
a + 1] - iir->
ab[1][2 *
i + 1]);
672 for (
i = 0;
i < iir->
nb_ab[1];
i++) {
676 if (iir->
ab[1][2 *
i ] == iir->
ab[1][2 * nearest_zero.
a ] &&
677 iir->
ab[1][2 *
i + 1] == -iir->
ab[1][2 * nearest_zero.
a + 1]) {
685 if (nearest_zero.
a < 0 || nearest_zero.
b < 0)
688 poles[0] = iir->
ab[0][2 * outmost_pole.
a ];
689 poles[1] = iir->
ab[0][2 * outmost_pole.
a + 1];
691 zeros[0] = iir->
ab[1][2 * nearest_zero.
a ];
692 zeros[1] = iir->
ab[1][2 * nearest_zero.
a + 1];
694 if (nearest_zero.
a == nearest_zero.
b && outmost_pole.
a == outmost_pole.
b) {
701 poles[2] = iir->
ab[0][2 * outmost_pole.
b ];
702 poles[3] = iir->
ab[0][2 * outmost_pole.
b + 1];
704 zeros[2] = iir->
ab[1][2 * nearest_zero.
b ];
705 zeros[3] = iir->
ab[1][2 * nearest_zero.
b + 1];
716 iir->
ab[0][2 * outmost_pole.
a] = iir->
ab[0][2 * outmost_pole.
a + 1] =
NAN;
717 iir->
ab[0][2 * outmost_pole.
b] = iir->
ab[0][2 * outmost_pole.
b + 1] =
NAN;
718 iir->
ab[1][2 * nearest_zero.
a] = iir->
ab[1][2 * nearest_zero.
a + 1] =
NAN;
719 iir->
ab[1][2 * nearest_zero.
b] = iir->
ab[1][2 * nearest_zero.
b + 1] =
NAN;
721 iir->
biquads[current_biquad].
a[0] = 1.;
722 iir->
biquads[current_biquad].
a[1] =
a[2] /
a[4];
723 iir->
biquads[current_biquad].
a[2] =
a[0] /
a[4];
724 iir->
biquads[current_biquad].
b[0] =
b[4] /
a[4];
725 iir->
biquads[current_biquad].
b[1] =
b[2] /
a[4];
726 iir->
biquads[current_biquad].
b[2] =
b[0] /
a[4];
731 iir->
biquads[current_biquad].
b[2]) > 1e-6) {
734 iir->
biquads[current_biquad].
a[2]) /
735 (iir->
biquads[current_biquad].
b[0] +
746 iir->
biquads[current_biquad].
b[0] *= (current_biquad ? 1.0 : iir->
g);
747 iir->
biquads[current_biquad].
b[1] *= (current_biquad ? 1.0 : iir->
g);
748 iir->
biquads[current_biquad].
b[2] *= (current_biquad ? 1.0 : iir->
g);
766 double b0,
double b1,
double b2,
767 double a1,
double a2)
769 double w1 = 0., w2 = 0.;
774 for (
int n = 0; n < length; n++) {
775 double out, in = x[n];
777 y[n] =
out = in *
b0 + w1;
783 static void solve(
double *matrix,
double *vector,
int n,
double *y,
double *x,
double *lu)
787 for (
int i = 0;
i < n;
i++) {
788 for (
int j =
i; j < n; j++) {
790 for (
int k = 0; k <
i; k++)
791 sum += lu[
i * n + k] * lu[k * n + j];
792 lu[
i * n + j] = matrix[j * n +
i] - sum;
794 for (
int j =
i + 1; j < n; j++) {
796 for (
int k = 0; k <
i; k++)
797 sum += lu[j * n + k] * lu[k * n +
i];
798 lu[j * n +
i] = (1. / lu[
i * n +
i]) * (matrix[
i * n + j] - sum);
802 for (
int i = 0;
i < n;
i++) {
804 for (
int k = 0; k <
i; k++)
805 sum += lu[
i * n + k] * y[k];
806 y[
i] = vector[
i] - sum;
809 for (
int i = n - 1;
i >= 0;
i--) {
811 for (
int k =
i + 1; k < n; k++)
812 sum += lu[
i * n + k] * x[k];
813 x[
i] = (1 / lu[
i * n +
i]) * (y[
i] - sum);
822 for (
int ch = 0; ch <
channels; ch++) {
825 int length = nb_biquads * 2 + 1;
826 double *impulse =
av_calloc(length,
sizeof(*impulse));
827 double *y =
av_calloc(length,
sizeof(*y));
828 double *resp =
av_calloc(length,
sizeof(*resp));
829 double *
M =
av_calloc((length - 1) * 2 * nb_biquads,
sizeof(*
M));
830 double *
W =
av_calloc((length - 1) * 2 * nb_biquads,
sizeof(*
W));
832 if (!impulse || !y || !resp || !
M) {
843 for (
int n = 0; n < nb_biquads; n++) {
851 for (
int n = 0; n < nb_biquads; n++) {
857 memcpy(
M + n * 2 * (length - 1), resp,
sizeof(*resp) * (length - 1));
858 memcpy(
M + n * 2 * (length - 1) + length, resp,
sizeof(*resp) * (length - 2));
859 memset(resp, 0, length *
sizeof(*resp));
862 solve(
M, &y[1], length - 1, &impulse[1], resp,
W);
866 for (
int n = 0; n < nb_biquads; n++) {
870 biquad->b[1] = resp[n * 2 + 0];
871 biquad->b[2] = resp[n * 2 + 1];
896 for (n = 0; n < iir->
nb_ab[0]; n++) {
897 double r = iir->
ab[0][2*n];
898 double angle = iir->
ab[0][2*n+1];
900 iir->
ab[0][2*n] =
r * cos(angle);
901 iir->
ab[0][2*n+1] =
r * sin(angle);
904 for (n = 0; n < iir->
nb_ab[1]; n++) {
905 double r = iir->
ab[1][2*n];
906 double angle = iir->
ab[1][2*n+1];
908 iir->
ab[1][2*n] =
r * cos(angle);
909 iir->
ab[1][2*n+1] =
r * sin(angle);
923 for (n = 0; n < iir->
nb_ab[0]; n++) {
924 double sr = iir->
ab[0][2*n];
925 double si = iir->
ab[0][2*n+1];
927 iir->
ab[0][2*n] =
exp(sr) * cos(si);
928 iir->
ab[0][2*n+1] =
exp(sr) * sin(si);
931 for (n = 0; n < iir->
nb_ab[1]; n++) {
932 double sr = iir->
ab[1][2*n];
933 double si = iir->
ab[1][2*n+1];
935 iir->
ab[1][2*n] =
exp(sr) * cos(si);
936 iir->
ab[1][2*n+1] =
exp(sr) * sin(si);
952 for (
int i = 0;
i <=
N;
i++) {
958 ((k & 1) ? -1. : 1.);
961 z +=
a[
i] * pow(2.,
i) *
acc;
977 if (!temp0 || !temp1)
980 memcpy(temp0, iir->
ab[0], iir->
nb_ab[0] *
sizeof(*temp0));
981 memcpy(temp1, iir->
ab[1], iir->
nb_ab[1] *
sizeof(*temp1));
983 for (
int n = 0; n < iir->
nb_ab[0]; n++)
986 for (
int n = 0; n < iir->
nb_ab[1]; n++)
1000 for (ch = 0; ch <
channels; ch++) {
1004 for (n = 0; n < iir->
nb_ab[0]; n++) {
1005 double r = iir->
ab[0][2*n];
1006 double angle =
M_PI*iir->
ab[0][2*n+1]/180.;
1008 iir->
ab[0][2*n] =
r * cos(angle);
1009 iir->
ab[0][2*n+1] =
r * sin(angle);
1012 for (n = 0; n < iir->
nb_ab[1]; n++) {
1013 double r = iir->
ab[1][2*n];
1014 double angle =
M_PI*iir->
ab[1][2*n+1]/180.;
1016 iir->
ab[1][2*n] =
r * cos(angle);
1017 iir->
ab[1][2*n+1] =
r * sin(angle);
1027 for (ch = 0; ch <
channels; ch++) {
1030 for (
int n = 0; n < iir->
nb_ab[0]; n++) {
1031 double pr =
hypot(iir->
ab[0][2*n], iir->
ab[0][2*n+1]);
1043 const uint8_t *font;
1049 for (
i = 0; txt[
i];
i++) {
1052 uint8_t *p = pic->
data[0] + y * pic->
linesize[0] + (x +
i * 8) * 4;
1053 for (char_y = 0; char_y < font_height; char_y++) {
1055 if (font[txt[
i] * font_height + char_y] &
mask)
1066 int dx =
FFABS(x1-x0);
1067 int dy =
FFABS(y1-y0), sy = y0 < y1 ? 1 : -1;
1068 int err = (dx>dy ? dx : -dy) / 2, e2;
1073 if (x0 == x1 && y0 == y1)
1090 static double distance(
double x0,
double x1,
double y0,
double y1)
1092 return hypot(x0 - x1, y0 - y1);
1096 const double *
b,
const double *
a,
1097 int nb_b,
int nb_a,
double *magnitude,
double *phase)
1099 double realz, realp;
1100 double imagz, imagp;
1105 realz = 0., realp = 0.;
1106 imagz = 0., imagp = 0.;
1107 for (
int x = 0; x < nb_a; x++) {
1108 realz += cos(-x *
w) *
a[x];
1109 imagz += sin(-x *
w) *
a[x];
1112 for (
int x = 0; x < nb_b; x++) {
1113 realp += cos(-x *
w) *
b[x];
1114 imagp += sin(-x *
w) *
b[x];
1117 div = realp * realp + imagp * imagp;
1118 real = (realz * realp + imagz * imagp) / div;
1119 imag = (imagz * realp - imagp * realz) / div;
1121 *magnitude =
hypot(real, imag);
1122 *phase = atan2(imag, real);
1124 double p = 1., z = 1.;
1127 for (
int x = 0; x < nb_a; x++) {
1129 acc += atan2(sin(
w) -
a[2 * x + 1], cos(
w) -
a[2 * x]);
1132 for (
int x = 0; x < nb_b; x++) {
1134 acc -= atan2(sin(
w) -
b[2 * x + 1], cos(
w) -
b[2 * x]);
1145 double *mag, *phase, *
temp, *delay,
min = DBL_MAX,
max = -DBL_MAX;
1146 double min_delay = DBL_MAX, max_delay = -DBL_MAX, min_phase, max_phase;
1147 int prev_ymag = -1, prev_yphase = -1, prev_ydelay = -1;
1151 memset(
out->data[0], 0,
s->h *
out->linesize[0]);
1157 if (!mag || !phase || !delay || !
temp)
1160 ch =
av_clip(
s->ir_channel, 0,
s->channels - 1);
1161 for (
i = 0;
i <
s->w;
i++) {
1162 const double *
b =
s->iir[ch].ab[0];
1163 const double *
a =
s->iir[ch].ab[1];
1164 const int nb_b =
s->iir[ch].nb_ab[0];
1165 const int nb_a =
s->iir[ch].nb_ab[1];
1166 double w =
i *
M_PI / (
s->w - 1);
1171 mag[
i] =
s->iir[ch].g * m;
1178 for (
i = 0;
i <
s->w - 1;
i++) {
1179 double d = phase[
i] - phase[
i + 1];
1183 min_phase = phase[0];
1184 max_phase = phase[0];
1185 for (
i = 1;
i <
s->w;
i++) {
1188 min_phase =
fmin(min_phase, phase[
i]);
1189 max_phase =
fmax(max_phase, phase[
i]);
1192 for (
i = 0;
i <
s->w - 1;
i++) {
1195 delay[
i + 1] = -(phase[
i] - phase[
i + 1]) / div;
1196 min_delay =
fmin(min_delay, delay[
i + 1]);
1197 max_delay =
fmax(max_delay, delay[
i + 1]);
1199 delay[0] = delay[1];
1201 for (
i = 0;
i <
s->w;
i++) {
1202 int ymag = mag[
i] /
max * (
s->h - 1);
1203 int ydelay = (delay[
i] - min_delay) / (max_delay - min_delay) * (
s->h - 1);
1204 int yphase = (phase[
i] - min_phase) / (max_phase - min_phase) * (
s->h - 1);
1206 ymag =
s->h - 1 -
av_clip(ymag, 0,
s->h - 1);
1207 yphase =
s->h - 1 -
av_clip(yphase, 0,
s->h - 1);
1208 ydelay =
s->h - 1 -
av_clip(ydelay, 0,
s->h - 1);
1212 if (prev_yphase < 0)
1213 prev_yphase = yphase;
1214 if (prev_ydelay < 0)
1215 prev_ydelay = ydelay;
1222 prev_yphase = yphase;
1223 prev_ydelay = ydelay;
1226 if (
s->w > 400 &&
s->h > 100) {
1227 drawtext(
out, 2, 2,
"Max Magnitude:", 0xDDDDDDDD);
1231 drawtext(
out, 2, 12,
"Min Magnitude:", 0xDDDDDDDD);
1236 snprintf(text,
sizeof(text),
"%.2f", max_phase);
1240 snprintf(text,
sizeof(text),
"%.2f", min_phase);
1244 snprintf(text,
sizeof(text),
"%.2f", max_delay);
1248 snprintf(text,
sizeof(text),
"%.2f", min_delay);
1266 s->channels =
inlink->channels;
1283 if (
s->format == -1) {
1286 }
else if (
s->format == 2) {
1288 }
else if (
s->format == 3) {
1290 }
else if (
s->format == 4) {
1293 if (
s->format > 0) {
1307 av_log(
ctx,
AV_LOG_WARNING,
"transfer function coefficients format is not recommended for too high number of zeros/poles.\n");
1309 if (
s->format > 0 &&
s->process == 0) {
1315 }
else if (
s->format == -2 &&
s->process > 0) {
1318 }
else if (
s->format <= 0 &&
s->process == 1) {
1321 }
else if (
s->format <= 0 &&
s->process == 2) {
1324 }
else if (
s->format > 0 &&
s->process == 1) {
1328 }
else if (
s->format > 0 &&
s->process == 2) {
1329 if (
s->precision > 1)
1339 for (ch = 0;
s->format == -2 && ch <
inlink->channels; ch++) {
1343 av_log(
ctx,
AV_LOG_ERROR,
"Number of ladder coefficients must be one more than number of reflection coefficients.\n");
1348 for (ch = 0;
s->format == 0 && ch <
inlink->channels; ch++) {
1351 for (
i = 1;
i < iir->
nb_ab[0];
i++) {
1352 iir->
ab[0][
i] /= iir->
ab[0][0];
1355 iir->
ab[0][0] = 1.0;
1356 for (
i = 0;
i < iir->
nb_ab[1];
i++) {
1357 iir->
ab[1][
i] *= iir->
g;
1363 switch (
inlink->format) {
1364 case AV_SAMPLE_FMT_DBLP:
s->iir_channel =
s->process == 2 ? iir_ch_parallel_dblp :
s->process == 1 ? iir_ch_serial_dblp : iir_ch_dblp;
break;
1365 case AV_SAMPLE_FMT_FLTP:
s->iir_channel =
s->process == 2 ? iir_ch_parallel_fltp :
s->process == 1 ? iir_ch_serial_fltp : iir_ch_fltp;
break;
1366 case AV_SAMPLE_FMT_S32P:
s->iir_channel =
s->process == 2 ? iir_ch_parallel_s32p :
s->process == 1 ? iir_ch_serial_s32p : iir_ch_s32p;
break;
1367 case AV_SAMPLE_FMT_S16P:
s->iir_channel =
s->process == 2 ? iir_ch_parallel_s16p :
s->process == 1 ? iir_ch_serial_s16p : iir_ch_s16p;
break;
1370 if (
s->format == -2) {
1371 switch (
inlink->format) {
1406 for (ch = 0; ch < outlink->
channels; ch++) {
1407 if (
s->iir[ch].clippings > 0)
1409 ch,
s->iir[ch].clippings);
1410 s->iir[ch].clippings = 0;
1418 int64_t old_pts =
s->video->pts;
1421 if (new_pts > old_pts) {
1424 s->video->pts = new_pts;
1457 if (!
s->a_str || !
s->b_str || !
s->g_str) {
1462 switch (
s->precision) {
1482 .
name =
"filter_response",
1501 for (ch = 0; ch <
s->channels; ch++) {
1523 #define OFFSET(x) offsetof(AudioIIRContext, x)
1524 #define AF AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
1525 #define VF AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
1528 {
"zeros",
"set B/numerator/zeros/reflection coefficients",
OFFSET(b_str),
AV_OPT_TYPE_STRING, {.str=
"1+0i 1-0i"}, 0, 0,
AF },
1539 {
"sf",
"analog transfer function", 0,
AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0,
AF,
"format" },
1540 {
"tf",
"digital transfer function", 0,
AV_OPT_TYPE_CONST, {.i64=0}, 0, 0,
AF,
"format" },
1542 {
"pr",
"Z-plane zeros/poles (polar radians)", 0,
AV_OPT_TYPE_CONST, {.i64=2}, 0, 0,
AF,
"format" },
1543 {
"pd",
"Z-plane zeros/poles (polar degrees)", 0,
AV_OPT_TYPE_CONST, {.i64=3}, 0, 0,
AF,
"format" },
1550 {
"precision",
"set filtering precision",
OFFSET(precision),
AV_OPT_TYPE_INT, {.i64=0}, 0, 3,
AF,
"precision" },
1552 {
"dbl",
"double-precision floating-point", 0,
AV_OPT_TYPE_CONST, {.i64=0}, 0, 0,
AF,
"precision" },
1553 {
"flt",
"single-precision floating-point", 0,
AV_OPT_TYPE_CONST, {.i64=1}, 0, 0,
AF,
"precision" },
1560 {
"channel",
"set IR channel to display frequency response",
OFFSET(ir_channel),
AV_OPT_TYPE_INT, {.i64=0}, 0, 1024,
VF },
1570 .description =
NULL_IF_CONFIG_SMALL(
"Apply Infinite Impulse Response filter with supplied coefficients."),
1572 .priv_class = &aiir_class,
static double coef_sf2zf(double *a, int N, int n)
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
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 AV_LOG_WARNING
Something somehow does not look correct.
static void process(NormalizeContext *s, AVFrame *in, AVFrame *out)
AVPixelFormat
Pixel format.
static int mix(int c0, int c1)
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
AVFILTER_DEFINE_CLASS(aiir)
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
static enum AVSampleFormat sample_fmts[]
@ AV_OPT_TYPE_VIDEO_RATE
offset must point to AVRational
static const AVFilterPad inputs[]
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
static const AVOption aiir_options[]
static int convert_serial2parallel(AVFilterContext *ctx, int channels)
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
static int read_channels(AVFilterContext *ctx, int channels, uint8_t *item_str, int ab)
This structure describes decoded (raw) audio or video data.
#define IIR_CH(name, type, min, max, need_clipping)
#define FILTER_QUERY_FUNC(func)
@ AV_SAMPLE_FMT_S32P
signed 32 bits, planar
static int read_tf_coefficients(AVFilterContext *ctx, char *item_str, int nb_items, double *dst)
int(* iir_channel)(AVFilterContext *ctx, void *arg, int ch, int nb_jobs)
static void check_stability(AVFilterContext *ctx, int channels)
#define AV_LOG_VERBOSE
Detailed information.
static int config_output(AVFilterLink *outlink)
static void solve(double *matrix, double *vector, int n, double *y, double *x, double *lu)
const char * name
Filter name.
static int config_video(AVFilterLink *outlink)
A link between two filters.
int channels
Number of channels.
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
static double b1(void *priv, double x, double y)
static int query_formats(AVFilterContext *ctx)
A filter pad used for either input or output.
static __device__ float ceil(float a)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
static int convert_zp2tf(AVFilterContext *ctx, int channels)
static const uint16_t mask[17]
char * av_strtok(char *s, const char *delim, char **saveptr)
Split the string into several tokens which can be accessed by successive calls to av_strtok().
AVRational sample_aspect_ratio
agreed upon sample aspect ratio
AVRational frame_rate
Frame rate of the stream on the link, or 1/0 if unknown or variable; if left to 0/0,...
static enum AVPixelFormat pix_fmts[]
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
#define FILTER_INPUTS(array)
#define SERIAL_IIR_CH(name, type, min, max, need_clipping)
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
int av_sscanf(const char *string, const char *format,...)
See libc sscanf manual for more information.
Describe the class of an AVClass context structure.
static __device__ float fabs(float a)
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Rational number (pair of numerator and denominator).
@ AV_OPT_TYPE_IMAGE_SIZE
offset must point to two consecutive integers
static void normalize_coeffs(AVFilterContext *ctx, int ch)
static av_cold int init(AVFilterContext *ctx)
static void convert_sp2zp(AVFilterContext *ctx, int channels)
#define AVFILTER_FLAG_DYNAMIC_OUTPUTS
The number of the filter outputs is not determined just by AVFilter.outputs.
static const char *const format[]
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
static void draw_line(AVFrame *out, int x0, int y0, int x1, int y1, uint32_t color)
double fmin(double, double)
static av_const double hypot(double x, double y)
int av_frame_is_writable(AVFrame *frame)
Check if the frame data is writable.
static int read_zp_coefficients(AVFilterContext *ctx, char *item_str, int nb_items, double *dst, const char *format)
AVFilterContext * src
source filter
AVFilterFormatsConfig incfg
Lists of supported formats / etc.
static double b2(void *priv, double x, double y)
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
@ AV_PIX_FMT_RGB0
packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined
static double fact(double i)
@ AV_SAMPLE_FMT_S16P
signed 16 bits, planar
int nb_samples
number of audio samples (per channel) described by this frame
enum AVSampleFormat sample_format
#define i(width, name, range_min, range_max)
int w
agreed upon image width
#define av_malloc_array(a, b)
AVSampleFormat
Audio sample formats.
Used for passing data between threads.
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
static void convert_sf2tf(AVFilterContext *ctx, int channels)
const char * name
Pad name.
void * av_calloc(size_t nmemb, size_t size)
static void get_response(int channel, int format, double w, const double *b, const double *a, int nb_b, int nb_a, double *magnitude, double *phase)
static void cmul(double re, double im, double re2, double im2, double *RE, double *IM)
#define PARALLEL_IIR_CH(name, type, min, max, need_clipping)
double fmax(double, double)
static void convert_pr2zp(AVFilterContext *ctx, int channels)
int h
agreed upon image height
static void draw_response(AVFilterContext *ctx, AVFrame *out, int sample_rate)
static double distance(double x0, double x1, double y0, double y1)
@ AV_SAMPLE_FMT_DBLP
double, planar
AVRational time_base
Define the time base used by the PTS of the frames/samples which will pass through this link.
static int decompose_zp2biquads(AVFilterContext *ctx, int channels)
static const int factor[16]
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
char * av_strdup(const char *s)
Duplicate a string.
#define LATTICE_IIR_CH(name, type, min, max, need_clipping)
static void count_coefficients(char *item_str, int *nb_items)
static void biquad_process(double *x, double *y, int length, double b0, double b1, double b2, double a1, double a2)
static int expand(AVFilterContext *ctx, double *pz, int n, double *coefs)
int ff_append_outpad(AVFilterContext *f, AVFilterPad *p)
const uint8_t avpriv_cga_font[2048]
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
static double b0(void *priv, double x, double y)
const AVFilter ff_af_aiir
static av_always_inline int ff_filter_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg, int *ret, int nb_jobs)
static av_cold void uninit(AVFilterContext *ctx)
static int read_gains(AVFilterContext *ctx, char *item_str, int nb_items)
static void convert_pd2zp(AVFilterContext *ctx, int channels)
static void drawtext(AVFrame *pic, int x, int y, const char *txt, uint32_t color)