Go to the documentation of this file.
114 #define IIR_CH(name, type, min, max, need_clipping) \
115 static int iir_ch_## name(AVFilterContext *ctx, void *arg, int ch, int nb_jobs) \
117 AudioIIRContext *s = ctx->priv; \
118 const double ig = s->dry_gain; \
119 const double og = s->wet_gain; \
120 const double mix = s->mix; \
121 ThreadData *td = arg; \
122 AVFrame *in = td->in, *out = td->out; \
123 const type *src = (const type *)in->extended_data[ch]; \
124 double *oc = (double *)s->iir[ch].cache[0]; \
125 double *ic = (double *)s->iir[ch].cache[1]; \
126 const int nb_a = s->iir[ch].nb_ab[0]; \
127 const int nb_b = s->iir[ch].nb_ab[1]; \
128 const double *a = s->iir[ch].ab[0]; \
129 const double *b = s->iir[ch].ab[1]; \
130 const double g = s->iir[ch].g; \
131 int *clippings = &s->iir[ch].clippings; \
132 type *dst = (type *)out->extended_data[ch]; \
135 for (n = 0; n < in->nb_samples; n++) { \
136 double sample = 0.; \
139 memmove(&ic[1], &ic[0], (nb_b - 1) * sizeof(*ic)); \
140 memmove(&oc[1], &oc[0], (nb_a - 1) * sizeof(*oc)); \
141 ic[0] = src[n] * ig; \
142 for (x = 0; x < nb_b; x++) \
143 sample += b[x] * ic[x]; \
145 for (x = 1; x < nb_a; x++) \
146 sample -= a[x] * oc[x]; \
150 sample = sample * mix + ic[0] * (1. - mix); \
151 if (need_clipping && sample < min) { \
154 } else if (need_clipping && sample > max) { \
165 IIR_CH(s16p, int16_t, INT16_MIN, INT16_MAX, 1)
167 IIR_CH(fltp,
float, -1., 1., 0)
168 IIR_CH(dblp,
double, -1., 1., 0)
170 #define SERIAL_IIR_CH(name, type, min, max, need_clipping) \
171 static int iir_ch_serial_## name(AVFilterContext *ctx, void *arg, \
172 int ch, int nb_jobs) \
174 AudioIIRContext *s = ctx->priv; \
175 const double ig = s->dry_gain; \
176 const double og = s->wet_gain; \
177 const double mix = s->mix; \
178 const double imix = 1. - mix; \
179 ThreadData *td = arg; \
180 AVFrame *in = td->in, *out = td->out; \
181 const type *src = (const type *)in->extended_data[ch]; \
182 type *dst = (type *)out->extended_data[ch]; \
183 IIRChannel *iir = &s->iir[ch]; \
184 const double g = iir->g; \
185 int *clippings = &iir->clippings; \
186 int nb_biquads = (FFMAX(iir->nb_ab[0], iir->nb_ab[1]) + 1) / 2; \
189 for (i = nb_biquads - 1; i >= 0; i--) { \
190 const double a1 = -iir->biquads[i].a[1]; \
191 const double a2 = -iir->biquads[i].a[2]; \
192 const double b0 = iir->biquads[i].b[0]; \
193 const double b1 = iir->biquads[i].b[1]; \
194 const double b2 = iir->biquads[i].b[2]; \
195 double w1 = iir->biquads[i].w1; \
196 double w2 = iir->biquads[i].w2; \
198 for (n = 0; n < in->nb_samples; n++) { \
199 double i0 = ig * (i ? dst[n] : src[n]); \
200 double o0 = i0 * b0 + w1; \
202 w1 = b1 * i0 + w2 + a1 * o0; \
203 w2 = b2 * i0 + a2 * o0; \
206 o0 = o0 * mix + imix * i0; \
207 if (need_clipping && o0 < min) { \
210 } else if (need_clipping && o0 > max) { \
217 iir->biquads[i].w1 = w1; \
218 iir->biquads[i].w2 = w2; \
229 #define PARALLEL_IIR_CH(name, type, min, max, need_clipping) \
230 static int iir_ch_parallel_## name(AVFilterContext *ctx, void *arg, \
231 int ch, int nb_jobs) \
233 AudioIIRContext *s = ctx->priv; \
234 const double ig = s->dry_gain; \
235 const double og = s->wet_gain; \
236 const double mix = s->mix; \
237 const double imix = 1. - mix; \
238 ThreadData *td = arg; \
239 AVFrame *in = td->in, *out = td->out; \
240 const type *src = (const type *)in->extended_data[ch]; \
241 type *dst = (type *)out->extended_data[ch]; \
242 IIRChannel *iir = &s->iir[ch]; \
243 const double g = iir->g; \
244 const double fir = iir->fir; \
245 int *clippings = &iir->clippings; \
246 int nb_biquads = (FFMAX(iir->nb_ab[0], iir->nb_ab[1]) + 1) / 2; \
249 for (i = 0; i < nb_biquads; i++) { \
250 const double a1 = -iir->biquads[i].a[1]; \
251 const double a2 = -iir->biquads[i].a[2]; \
252 const double b1 = iir->biquads[i].b[1]; \
253 const double b2 = iir->biquads[i].b[2]; \
254 double w1 = iir->biquads[i].w1; \
255 double w2 = iir->biquads[i].w2; \
257 for (n = 0; n < in->nb_samples; n++) { \
258 double i0 = ig * src[n]; \
261 w1 = b1 * i0 + w2 + a1 * o0; \
262 w2 = b2 * i0 + a2 * o0; \
266 if (need_clipping && o0 < min) { \
269 } else if (need_clipping && o0 > max) { \
276 iir->biquads[i].w1 = w1; \
277 iir->biquads[i].w2 = w2; \
280 for (n = 0; n < in->nb_samples; n++) { \
281 dst[n] += fir * src[n]; \
282 dst[n] = dst[n] * mix + imix * src[n]; \
293 #define LATTICE_IIR_CH(name, type, min, max, need_clipping) \
294 static int iir_ch_lattice_## name(AVFilterContext *ctx, void *arg, \
295 int ch, int nb_jobs) \
297 AudioIIRContext *s = ctx->priv; \
298 const double ig = s->dry_gain; \
299 const double og = s->wet_gain; \
300 const double mix = s->mix; \
301 ThreadData *td = arg; \
302 AVFrame *in = td->in, *out = td->out; \
303 const type *src = (const type *)in->extended_data[ch]; \
304 double n0, n1, p0, *x = (double *)s->iir[ch].cache[0]; \
305 const int nb_stages = s->iir[ch].nb_ab[1]; \
306 const double *v = s->iir[ch].ab[0]; \
307 const double *k = s->iir[ch].ab[1]; \
308 const double g = s->iir[ch].g; \
309 int *clippings = &s->iir[ch].clippings; \
310 type *dst = (type *)out->extended_data[ch]; \
313 for (n = 0; n < in->nb_samples; n++) { \
314 const double in = src[n] * ig; \
318 for (int i = nb_stages - 1; i >= 0; i--) { \
319 n0 = n1 - k[i] * x[i]; \
320 p0 = n0 * k[i] + x[i]; \
321 out += p0 * v[i+1]; \
327 memmove(&x[1], &x[0], nb_stages * sizeof(*x)); \
330 out = out * mix + in * (1. - mix); \
331 if (need_clipping && out < min) { \
334 } else if (need_clipping && out > max) { \
358 for (p = item_str; *p && *p !=
'|'; p++) {
367 char *p, *
arg, *old_str, *prev_arg =
NULL, *saveptr =
NULL;
373 for (
i = 0;
i < nb_items;
i++) {
399 char *p, *
arg, *old_str, *saveptr =
NULL;
405 for (
i = 0;
i < nb_items;
i++) {
424 char *p, *
arg, *old_str, *saveptr =
NULL;
430 for (
i = 0;
i < nb_items;
i++) {
447 static const char *
const format[] = {
"%lf",
"%lf %lfi",
"%lf %lfr",
"%lf %lfd",
"%lf %lfi" };
452 char *p, *
arg, *old_str, *prev_arg =
NULL, *saveptr =
NULL;
474 if (!iir->
ab[ab] || !iir->
cache[ab]) {
496 static void cmul(
double re,
double im,
double re2,
double im2,
double *
RE,
double *
IM)
498 *
RE = re * re2 - im * im2;
499 *
IM = re * im2 + re2 * im;
506 for (
int i = 1;
i <= n;
i++) {
507 for (
int j = n -
i; j < n; j++) {
510 cmul(coefs[2 * (j + 1)], coefs[2 * (j + 1) + 1],
511 pz[2 * (
i - 1)], pz[2 * (
i - 1) + 1], &re, &im);
514 coefs[2 * j + 1] -= im;
518 for (
int i = 0;
i < n + 1;
i++) {
519 if (
fabs(coefs[2 *
i + 1]) > FLT_EPSILON) {
520 av_log(
ctx,
AV_LOG_ERROR,
"coefs: %f of z^%d is not real; poles/zeros are not complex conjugates.\n",
521 coefs[2 *
i + 1],
i);
538 for (
int i = 0;
i < iir->
nb_ab[1];
i++) {
539 sum_den += iir->
ab[1][
i];
542 if (sum_den > 1e-6) {
543 double factor, sum_num = 0.;
545 for (
int i = 0;
i < iir->
nb_ab[0];
i++) {
546 sum_num += iir->
ab[0][
i];
549 factor = sum_num / sum_den;
551 for (
int i = 0;
i < iir->
nb_ab[1];
i++) {
560 int ch,
i, j,
ret = 0;
568 if (!topc || !botc) {
583 for (j = 0,
i = iir->
nb_ab[1];
i >= 0; j++,
i--) {
584 iir->
ab[1][j] = topc[2 *
i];
588 for (j = 0,
i = iir->
nb_ab[0];
i >= 0; j++,
i--) {
589 iir->
ab[0][j] = botc[2 *
i];
613 int current_biquad = 0;
619 while (nb_biquads--) {
620 Pair outmost_pole = { -1, -1 };
621 Pair nearest_zero = { -1, -1 };
622 double zeros[4] = { 0 };
623 double poles[4] = { 0 };
626 double min_distance = DBL_MAX;
631 for (
i = 0;
i < iir->
nb_ab[0];
i++) {
636 mag =
hypot(iir->
ab[0][2 *
i], iir->
ab[0][2 *
i + 1]);
644 for (
i = 0;
i < iir->
nb_ab[0];
i++) {
648 if (iir->
ab[0][2 *
i ] == iir->
ab[0][2 * outmost_pole.
a ] &&
649 iir->
ab[0][2 *
i + 1] == -iir->
ab[0][2 * outmost_pole.
a + 1]) {
657 if (outmost_pole.
a < 0 || outmost_pole.
b < 0)
660 for (
i = 0;
i < iir->
nb_ab[1];
i++) {
666 iir->
ab[0][2 * outmost_pole.
a + 1] - iir->
ab[1][2 *
i + 1]);
674 for (
i = 0;
i < iir->
nb_ab[1];
i++) {
678 if (iir->
ab[1][2 *
i ] == iir->
ab[1][2 * nearest_zero.
a ] &&
679 iir->
ab[1][2 *
i + 1] == -iir->
ab[1][2 * nearest_zero.
a + 1]) {
687 if (nearest_zero.
a < 0 || nearest_zero.
b < 0)
690 poles[0] = iir->
ab[0][2 * outmost_pole.
a ];
691 poles[1] = iir->
ab[0][2 * outmost_pole.
a + 1];
693 zeros[0] = iir->
ab[1][2 * nearest_zero.
a ];
694 zeros[1] = iir->
ab[1][2 * nearest_zero.
a + 1];
696 if (nearest_zero.
a == nearest_zero.
b && outmost_pole.
a == outmost_pole.
b) {
703 poles[2] = iir->
ab[0][2 * outmost_pole.
b ];
704 poles[3] = iir->
ab[0][2 * outmost_pole.
b + 1];
706 zeros[2] = iir->
ab[1][2 * nearest_zero.
b ];
707 zeros[3] = iir->
ab[1][2 * nearest_zero.
b + 1];
718 iir->
ab[0][2 * outmost_pole.
a] = iir->
ab[0][2 * outmost_pole.
a + 1] =
NAN;
719 iir->
ab[0][2 * outmost_pole.
b] = iir->
ab[0][2 * outmost_pole.
b + 1] =
NAN;
720 iir->
ab[1][2 * nearest_zero.
a] = iir->
ab[1][2 * nearest_zero.
a + 1] =
NAN;
721 iir->
ab[1][2 * nearest_zero.
b] = iir->
ab[1][2 * nearest_zero.
b + 1] =
NAN;
723 iir->
biquads[current_biquad].
a[0] = 1.;
724 iir->
biquads[current_biquad].
a[1] =
a[2] /
a[4];
725 iir->
biquads[current_biquad].
a[2] =
a[0] /
a[4];
726 iir->
biquads[current_biquad].
b[0] =
b[4] /
a[4];
727 iir->
biquads[current_biquad].
b[1] =
b[2] /
a[4];
728 iir->
biquads[current_biquad].
b[2] =
b[0] /
a[4];
733 iir->
biquads[current_biquad].
b[2]) > 1e-6) {
736 iir->
biquads[current_biquad].
a[2]) /
737 (iir->
biquads[current_biquad].
b[0] +
748 iir->
biquads[current_biquad].
b[0] *= (current_biquad ? 1.0 : iir->
g);
749 iir->
biquads[current_biquad].
b[1] *= (current_biquad ? 1.0 : iir->
g);
750 iir->
biquads[current_biquad].
b[2] *= (current_biquad ? 1.0 : iir->
g);
768 double b0,
double b1,
double b2,
769 double a1,
double a2)
771 double w1 = 0., w2 = 0.;
776 for (
int n = 0; n < length; n++) {
777 double out, in = x[n];
779 y[n] =
out = in *
b0 + w1;
785 static void solve(
double *
matrix,
double *vector,
int n,
double *y,
double *x,
double *lu)
789 for (
int i = 0;
i < n;
i++) {
790 for (
int j =
i; j < n; j++) {
792 for (
int k = 0; k <
i; k++)
793 sum += lu[
i * n + k] * lu[k * n + j];
794 lu[
i * n + j] =
matrix[j * n +
i] - sum;
796 for (
int j =
i + 1; j < n; j++) {
798 for (
int k = 0; k <
i; k++)
799 sum += lu[j * n + k] * lu[k * n +
i];
800 lu[j * n +
i] = (1. / lu[
i * n +
i]) * (
matrix[
i * n + j] - sum);
804 for (
int i = 0;
i < n;
i++) {
806 for (
int k = 0; k <
i; k++)
807 sum += lu[
i * n + k] * y[k];
808 y[
i] = vector[
i] - sum;
811 for (
int i = n - 1;
i >= 0;
i--) {
813 for (
int k =
i + 1; k < n; k++)
814 sum += lu[
i * n + k] * x[k];
815 x[
i] = (1 / lu[
i * n +
i]) * (y[
i] - sum);
824 for (
int ch = 0; ch <
channels; ch++) {
827 int length = nb_biquads * 2 + 1;
828 double *impulse =
av_calloc(length,
sizeof(*impulse));
829 double *y =
av_calloc(length,
sizeof(*y));
830 double *resp =
av_calloc(length,
sizeof(*resp));
831 double *
M =
av_calloc((length - 1) * 2 * nb_biquads,
sizeof(*
M));
832 double *
W =
av_calloc((length - 1) * 2 * nb_biquads,
sizeof(*
W));
834 if (!impulse || !y || !resp || !
M) {
845 for (
int n = 0; n < nb_biquads; n++) {
853 for (
int n = 0; n < nb_biquads; n++) {
859 memcpy(
M + n * 2 * (length - 1), resp,
sizeof(*resp) * (length - 1));
860 memcpy(
M + n * 2 * (length - 1) + length, resp,
sizeof(*resp) * (length - 2));
861 memset(resp, 0, length *
sizeof(*resp));
864 solve(
M, &y[1], length - 1, &impulse[1], resp,
W);
868 for (
int n = 0; n < nb_biquads; n++) {
872 biquad->b[1] = resp[n * 2 + 0];
873 biquad->b[2] = resp[n * 2 + 1];
898 for (n = 0; n < iir->
nb_ab[0]; n++) {
899 double r = iir->
ab[0][2*n];
900 double angle = iir->
ab[0][2*n+1];
902 iir->
ab[0][2*n] =
r * cos(angle);
903 iir->
ab[0][2*n+1] =
r * sin(angle);
906 for (n = 0; n < iir->
nb_ab[1]; n++) {
907 double r = iir->
ab[1][2*n];
908 double angle = iir->
ab[1][2*n+1];
910 iir->
ab[1][2*n] =
r * cos(angle);
911 iir->
ab[1][2*n+1] =
r * sin(angle);
925 for (n = 0; n < iir->
nb_ab[0]; n++) {
926 double sr = iir->
ab[0][2*n];
927 double si = iir->
ab[0][2*n+1];
929 iir->
ab[0][2*n] =
exp(sr) * cos(si);
930 iir->
ab[0][2*n+1] =
exp(sr) * sin(si);
933 for (n = 0; n < iir->
nb_ab[1]; n++) {
934 double sr = iir->
ab[1][2*n];
935 double si = iir->
ab[1][2*n+1];
937 iir->
ab[1][2*n] =
exp(sr) * cos(si);
938 iir->
ab[1][2*n+1] =
exp(sr) * sin(si);
954 for (
int i = 0;
i <=
N;
i++) {
960 ((k & 1) ? -1. : 1.);
963 z +=
a[
i] * pow(2.,
i) *
acc;
979 if (!temp0 || !temp1)
982 memcpy(temp0, iir->
ab[0], iir->
nb_ab[0] *
sizeof(*temp0));
983 memcpy(temp1, iir->
ab[1], iir->
nb_ab[1] *
sizeof(*temp1));
985 for (
int n = 0; n < iir->
nb_ab[0]; n++)
988 for (
int n = 0; n < iir->
nb_ab[1]; n++)
1002 for (ch = 0; ch <
channels; ch++) {
1006 for (n = 0; n < iir->
nb_ab[0]; n++) {
1007 double r = iir->
ab[0][2*n];
1008 double angle =
M_PI*iir->
ab[0][2*n+1]/180.;
1010 iir->
ab[0][2*n] =
r * cos(angle);
1011 iir->
ab[0][2*n+1] =
r * sin(angle);
1014 for (n = 0; n < iir->
nb_ab[1]; n++) {
1015 double r = iir->
ab[1][2*n];
1016 double angle =
M_PI*iir->
ab[1][2*n+1]/180.;
1018 iir->
ab[1][2*n] =
r * cos(angle);
1019 iir->
ab[1][2*n+1] =
r * sin(angle);
1029 for (ch = 0; ch <
channels; ch++) {
1032 for (
int n = 0; n < iir->
nb_ab[0]; n++) {
1033 double pr =
hypot(iir->
ab[0][2*n], iir->
ab[0][2*n+1]);
1045 const uint8_t *font;
1051 for (
i = 0; txt[
i];
i++) {
1054 uint8_t *p = pic->
data[0] + y * pic->
linesize[0] + (x +
i * 8) * 4;
1055 for (char_y = 0; char_y < font_height; char_y++) {
1057 if (font[txt[
i] * font_height + char_y] &
mask)
1068 int dx =
FFABS(x1-x0);
1069 int dy =
FFABS(y1-y0), sy = y0 < y1 ? 1 : -1;
1070 int err = (dx>dy ? dx : -dy) / 2, e2;
1075 if (x0 == x1 && y0 == y1)
1092 static double distance(
double x0,
double x1,
double y0,
double y1)
1094 return hypot(x0 - x1, y0 - y1);
1098 const double *
b,
const double *
a,
1099 int nb_b,
int nb_a,
double *magnitude,
double *phase)
1101 double realz, realp;
1102 double imagz, imagp;
1107 realz = 0., realp = 0.;
1108 imagz = 0., imagp = 0.;
1109 for (
int x = 0; x < nb_a; x++) {
1110 realz += cos(-x *
w) *
a[x];
1111 imagz += sin(-x *
w) *
a[x];
1114 for (
int x = 0; x < nb_b; x++) {
1115 realp += cos(-x *
w) *
b[x];
1116 imagp += sin(-x *
w) *
b[x];
1119 div = realp * realp + imagp * imagp;
1120 real = (realz * realp + imagz * imagp) / div;
1121 imag = (imagz * realp - imagp * realz) / div;
1123 *magnitude =
hypot(real, imag);
1124 *phase = atan2(imag, real);
1126 double p = 1., z = 1.;
1129 for (
int x = 0; x < nb_a; x++) {
1131 acc += atan2(sin(
w) -
a[2 * x + 1], cos(
w) -
a[2 * x]);
1134 for (
int x = 0; x < nb_b; x++) {
1136 acc -= atan2(sin(
w) -
b[2 * x + 1], cos(
w) -
b[2 * x]);
1147 double *mag, *phase, *
temp, *delay,
min = DBL_MAX,
max = -DBL_MAX;
1148 double min_delay = DBL_MAX, max_delay = -DBL_MAX, min_phase, max_phase;
1149 int prev_ymag = -1, prev_yphase = -1, prev_ydelay = -1;
1153 memset(
out->data[0], 0,
s->h *
out->linesize[0]);
1159 if (!mag || !phase || !delay || !
temp)
1162 ch =
av_clip(
s->ir_channel, 0,
s->channels - 1);
1163 for (
i = 0;
i <
s->w;
i++) {
1164 const double *
b =
s->iir[ch].ab[0];
1165 const double *
a =
s->iir[ch].ab[1];
1166 const int nb_b =
s->iir[ch].nb_ab[0];
1167 const int nb_a =
s->iir[ch].nb_ab[1];
1168 double w =
i *
M_PI / (
s->w - 1);
1173 mag[
i] =
s->iir[ch].g * m;
1180 for (
i = 0;
i <
s->w - 1;
i++) {
1181 double d = phase[
i] - phase[
i + 1];
1185 min_phase = phase[0];
1186 max_phase = phase[0];
1187 for (
i = 1;
i <
s->w;
i++) {
1190 min_phase =
fmin(min_phase, phase[
i]);
1191 max_phase =
fmax(max_phase, phase[
i]);
1194 for (
i = 0;
i <
s->w - 1;
i++) {
1197 delay[
i + 1] = -(phase[
i] - phase[
i + 1]) / div;
1198 min_delay =
fmin(min_delay, delay[
i + 1]);
1199 max_delay =
fmax(max_delay, delay[
i + 1]);
1201 delay[0] = delay[1];
1203 for (
i = 0;
i <
s->w;
i++) {
1204 int ymag = mag[
i] /
max * (
s->h - 1);
1205 int ydelay = (delay[
i] - min_delay) / (max_delay - min_delay) * (
s->h - 1);
1206 int yphase = (phase[
i] - min_phase) / (max_phase - min_phase) * (
s->h - 1);
1208 ymag =
s->h - 1 -
av_clip(ymag, 0,
s->h - 1);
1209 yphase =
s->h - 1 -
av_clip(yphase, 0,
s->h - 1);
1210 ydelay =
s->h - 1 -
av_clip(ydelay, 0,
s->h - 1);
1214 if (prev_yphase < 0)
1215 prev_yphase = yphase;
1216 if (prev_ydelay < 0)
1217 prev_ydelay = ydelay;
1224 prev_yphase = yphase;
1225 prev_ydelay = ydelay;
1228 if (
s->w > 400 &&
s->h > 100) {
1229 drawtext(
out, 2, 2,
"Max Magnitude:", 0xDDDDDDDD);
1233 drawtext(
out, 2, 12,
"Min Magnitude:", 0xDDDDDDDD);
1238 snprintf(text,
sizeof(text),
"%.2f", max_phase);
1242 snprintf(text,
sizeof(text),
"%.2f", min_phase);
1246 snprintf(text,
sizeof(text),
"%.2f", max_delay);
1250 snprintf(text,
sizeof(text),
"%.2f", min_delay);
1268 s->channels =
inlink->ch_layout.nb_channels;
1285 if (
s->format == -1) {
1288 }
else if (
s->format == 2) {
1290 }
else if (
s->format == 3) {
1292 }
else if (
s->format == 4) {
1295 if (
s->format > 0) {
1309 av_log(
ctx,
AV_LOG_WARNING,
"transfer function coefficients format is not recommended for too high number of zeros/poles.\n");
1311 if (
s->format > 0 &&
s->process == 0) {
1317 }
else if (
s->format == -2 &&
s->process > 0) {
1320 }
else if (
s->format <= 0 &&
s->process == 1) {
1323 }
else if (
s->format <= 0 &&
s->process == 2) {
1326 }
else if (
s->format > 0 &&
s->process == 1) {
1330 }
else if (
s->format > 0 &&
s->process == 2) {
1331 if (
s->precision > 1)
1341 for (ch = 0;
s->format == -2 && ch <
inlink->ch_layout.nb_channels; ch++) {
1345 av_log(
ctx,
AV_LOG_ERROR,
"Number of ladder coefficients must be one more than number of reflection coefficients.\n");
1350 for (ch = 0;
s->format == 0 && ch <
inlink->ch_layout.nb_channels; ch++) {
1353 for (
i = 1;
i < iir->
nb_ab[0];
i++) {
1354 iir->
ab[0][
i] /= iir->
ab[0][0];
1357 iir->
ab[0][0] = 1.0;
1358 for (
i = 0;
i < iir->
nb_ab[1];
i++) {
1359 iir->
ab[1][
i] *= iir->
g;
1365 switch (
inlink->format) {
1366 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;
1367 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;
1368 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;
1369 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;
1372 if (
s->format == -2) {
1373 switch (
inlink->format) {
1409 if (
s->iir[ch].clippings > 0)
1411 ch,
s->iir[ch].clippings);
1412 s->iir[ch].clippings = 0;
1420 int64_t old_pts =
s->video->pts;
1423 if (new_pts > old_pts) {
1426 s->video->pts = new_pts;
1459 if (!
s->a_str || !
s->b_str || !
s->g_str) {
1464 switch (
s->precision) {
1484 .
name =
"filter_response",
1503 for (ch = 0; ch <
s->channels; ch++) {
1525 #define OFFSET(x) offsetof(AudioIIRContext, x)
1526 #define AF AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
1527 #define VF AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
1530 {
"zeros",
"set B/numerator/zeros/reflection coefficients",
OFFSET(b_str),
AV_OPT_TYPE_STRING, {.str=
"1+0i 1-0i"}, 0, 0,
AF },
1541 {
"sf",
"analog transfer function", 0,
AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0,
AF,
"format" },
1542 {
"tf",
"digital transfer function", 0,
AV_OPT_TYPE_CONST, {.i64=0}, 0, 0,
AF,
"format" },
1544 {
"pr",
"Z-plane zeros/poles (polar radians)", 0,
AV_OPT_TYPE_CONST, {.i64=2}, 0, 0,
AF,
"format" },
1545 {
"pd",
"Z-plane zeros/poles (polar degrees)", 0,
AV_OPT_TYPE_CONST, {.i64=3}, 0, 0,
AF,
"format" },
1552 {
"precision",
"set filtering precision",
OFFSET(precision),
AV_OPT_TYPE_INT, {.i64=0}, 0, 3,
AF,
"precision" },
1554 {
"dbl",
"double-precision floating-point", 0,
AV_OPT_TYPE_CONST, {.i64=0}, 0, 0,
AF,
"precision" },
1555 {
"flt",
"single-precision floating-point", 0,
AV_OPT_TYPE_CONST, {.i64=1}, 0, 0,
AF,
"precision" },
1562 {
"channel",
"set IR channel to display frequency response",
OFFSET(ir_channel),
AV_OPT_TYPE_INT, {.i64=0}, 0, 1024,
VF },
1572 .description =
NULL_IF_CONFIG_SMALL(
"Apply Infinite Impulse Response filter with supplied coefficients."),
1574 .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)
int nb_channels
Number of channels in this layout.
A link between two filters.
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)
AVChannelLayout ch_layout
channel layout of current buffer (see libavutil/channel_layout.h)
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)