Go to the documentation of this file.
115 #define IIR_CH(name, type, min, max, need_clipping) \
116 static int iir_ch_## name(AVFilterContext *ctx, void *arg, int ch, int nb_jobs) \
118 AudioIIRContext *s = ctx->priv; \
119 const double ig = s->dry_gain; \
120 const double og = s->wet_gain; \
121 const double mix = s->mix; \
122 ThreadData *td = arg; \
123 AVFrame *in = td->in, *out = td->out; \
124 const type *src = (const type *)in->extended_data[ch]; \
125 double *oc = (double *)s->iir[ch].cache[0]; \
126 double *ic = (double *)s->iir[ch].cache[1]; \
127 const int nb_a = s->iir[ch].nb_ab[0]; \
128 const int nb_b = s->iir[ch].nb_ab[1]; \
129 const double *a = s->iir[ch].ab[0]; \
130 const double *b = s->iir[ch].ab[1]; \
131 const double g = s->iir[ch].g; \
132 int *clippings = &s->iir[ch].clippings; \
133 type *dst = (type *)out->extended_data[ch]; \
136 for (n = 0; n < in->nb_samples; n++) { \
137 double sample = 0.; \
140 memmove(&ic[1], &ic[0], (nb_b - 1) * sizeof(*ic)); \
141 memmove(&oc[1], &oc[0], (nb_a - 1) * sizeof(*oc)); \
142 ic[0] = src[n] * ig; \
143 for (x = 0; x < nb_b; x++) \
144 sample += b[x] * ic[x]; \
146 for (x = 1; x < nb_a; x++) \
147 sample -= a[x] * oc[x]; \
151 sample = sample * mix + ic[0] * (1. - mix); \
152 if (need_clipping && sample < min) { \
155 } else if (need_clipping && sample > max) { \
166 IIR_CH(s16p, int16_t, INT16_MIN, INT16_MAX, 1)
168 IIR_CH(fltp,
float, -1., 1., 0)
169 IIR_CH(dblp,
double, -1., 1., 0)
171 #define SERIAL_IIR_CH(name, type, min, max, need_clipping) \
172 static int iir_ch_serial_## name(AVFilterContext *ctx, void *arg, \
173 int ch, int nb_jobs) \
175 AudioIIRContext *s = ctx->priv; \
176 const double ig = s->dry_gain; \
177 const double og = s->wet_gain; \
178 const double mix = s->mix; \
179 const double imix = 1. - mix; \
180 ThreadData *td = arg; \
181 AVFrame *in = td->in, *out = td->out; \
182 const type *src = (const type *)in->extended_data[ch]; \
183 type *dst = (type *)out->extended_data[ch]; \
184 IIRChannel *iir = &s->iir[ch]; \
185 const double g = iir->g; \
186 int *clippings = &iir->clippings; \
187 int nb_biquads = (FFMAX(iir->nb_ab[0], iir->nb_ab[1]) + 1) / 2; \
190 for (i = nb_biquads - 1; i >= 0; i--) { \
191 const double a1 = -iir->biquads[i].a[1]; \
192 const double a2 = -iir->biquads[i].a[2]; \
193 const double b0 = iir->biquads[i].b[0]; \
194 const double b1 = iir->biquads[i].b[1]; \
195 const double b2 = iir->biquads[i].b[2]; \
196 double w1 = iir->biquads[i].w1; \
197 double w2 = iir->biquads[i].w2; \
199 for (n = 0; n < in->nb_samples; n++) { \
200 double i0 = ig * (i ? dst[n] : src[n]); \
201 double o0 = i0 * b0 + w1; \
203 w1 = b1 * i0 + w2 + a1 * o0; \
204 w2 = b2 * i0 + a2 * o0; \
207 o0 = o0 * mix + imix * i0; \
208 if (need_clipping && o0 < min) { \
211 } else if (need_clipping && o0 > max) { \
218 iir->biquads[i].w1 = w1; \
219 iir->biquads[i].w2 = w2; \
230 #define PARALLEL_IIR_CH(name, type, min, max, need_clipping) \
231 static int iir_ch_parallel_## name(AVFilterContext *ctx, void *arg, \
232 int ch, int nb_jobs) \
234 AudioIIRContext *s = ctx->priv; \
235 const double ig = s->dry_gain; \
236 const double og = s->wet_gain; \
237 const double mix = s->mix; \
238 const double imix = 1. - mix; \
239 ThreadData *td = arg; \
240 AVFrame *in = td->in, *out = td->out; \
241 const type *src = (const type *)in->extended_data[ch]; \
242 type *dst = (type *)out->extended_data[ch]; \
243 IIRChannel *iir = &s->iir[ch]; \
244 const double g = iir->g; \
245 const double fir = iir->fir; \
246 int *clippings = &iir->clippings; \
247 int nb_biquads = (FFMAX(iir->nb_ab[0], iir->nb_ab[1]) + 1) / 2; \
250 for (i = 0; i < nb_biquads; i++) { \
251 const double a1 = -iir->biquads[i].a[1]; \
252 const double a2 = -iir->biquads[i].a[2]; \
253 const double b1 = iir->biquads[i].b[1]; \
254 const double b2 = iir->biquads[i].b[2]; \
255 double w1 = iir->biquads[i].w1; \
256 double w2 = iir->biquads[i].w2; \
258 for (n = 0; n < in->nb_samples; n++) { \
259 double i0 = ig * src[n]; \
262 w1 = b1 * i0 + w2 + a1 * o0; \
263 w2 = b2 * i0 + a2 * o0; \
267 if (need_clipping && o0 < min) { \
270 } else if (need_clipping && o0 > max) { \
277 iir->biquads[i].w1 = w1; \
278 iir->biquads[i].w2 = w2; \
281 for (n = 0; n < in->nb_samples; n++) { \
282 dst[n] += fir * src[n]; \
283 dst[n] = dst[n] * mix + imix * src[n]; \
294 #define LATTICE_IIR_CH(name, type, min, max, need_clipping) \
295 static int iir_ch_lattice_## name(AVFilterContext *ctx, void *arg, \
296 int ch, int nb_jobs) \
298 AudioIIRContext *s = ctx->priv; \
299 const double ig = s->dry_gain; \
300 const double og = s->wet_gain; \
301 const double mix = s->mix; \
302 ThreadData *td = arg; \
303 AVFrame *in = td->in, *out = td->out; \
304 const type *src = (const type *)in->extended_data[ch]; \
305 double n0, n1, p0, *x = (double *)s->iir[ch].cache[0]; \
306 const int nb_stages = s->iir[ch].nb_ab[1]; \
307 const double *v = s->iir[ch].ab[0]; \
308 const double *k = s->iir[ch].ab[1]; \
309 const double g = s->iir[ch].g; \
310 int *clippings = &s->iir[ch].clippings; \
311 type *dst = (type *)out->extended_data[ch]; \
314 for (n = 0; n < in->nb_samples; n++) { \
315 const double in = src[n] * ig; \
319 for (int i = nb_stages - 1; i >= 0; i--) { \
320 n0 = n1 - k[i] * x[i]; \
321 p0 = n0 * k[i] + x[i]; \
322 out += p0 * v[i+1]; \
328 memmove(&x[1], &x[0], nb_stages * sizeof(*x)); \
331 out = out * mix + in * (1. - mix); \
332 if (need_clipping && out < min) { \
335 } else if (need_clipping && out > max) { \
359 for (p = item_str; *p && *p !=
'|'; p++) {
368 char *p, *
arg, *old_str, *prev_arg =
NULL, *saveptr =
NULL;
374 for (
i = 0;
i < nb_items;
i++) {
400 char *p, *
arg, *old_str, *saveptr =
NULL;
406 for (
i = 0;
i < nb_items;
i++) {
425 char *p, *
arg, *old_str, *saveptr =
NULL;
431 for (
i = 0;
i < nb_items;
i++) {
448 static const char *
const format[] = {
"%lf",
"%lf %lfi",
"%lf %lfr",
"%lf %lfd",
"%lf %lfi" };
453 char *p, *
arg, *old_str, *prev_arg =
NULL, *saveptr =
NULL;
475 if (!iir->
ab[ab] || !iir->
cache[ab]) {
497 static void cmul(
double re,
double im,
double re2,
double im2,
double *
RE,
double *
IM)
499 *
RE = re * re2 - im * im2;
500 *
IM = re * im2 + re2 * im;
507 for (
int i = 1;
i <= n;
i++) {
508 for (
int j = n -
i; j < n; j++) {
511 cmul(coefs[2 * (j + 1)], coefs[2 * (j + 1) + 1],
512 pz[2 * (
i - 1)], pz[2 * (
i - 1) + 1], &re, &im);
515 coefs[2 * j + 1] -= im;
519 for (
int i = 0;
i < n + 1;
i++) {
520 if (
fabs(coefs[2 *
i + 1]) > FLT_EPSILON) {
521 av_log(
ctx,
AV_LOG_ERROR,
"coefs: %f of z^%d is not real; poles/zeros are not complex conjugates.\n",
522 coefs[2 *
i + 1],
i);
539 for (
int i = 0;
i < iir->
nb_ab[1];
i++) {
540 sum_den += iir->
ab[1][
i];
543 if (sum_den > 1e-6) {
544 double factor, sum_num = 0.;
546 for (
int i = 0;
i < iir->
nb_ab[0];
i++) {
547 sum_num += iir->
ab[0][
i];
550 factor = sum_num / sum_den;
552 for (
int i = 0;
i < iir->
nb_ab[1];
i++) {
561 int ch,
i, j,
ret = 0;
569 if (!topc || !botc) {
584 for (j = 0,
i = iir->
nb_ab[1];
i >= 0; j++,
i--) {
585 iir->
ab[1][j] = topc[2 *
i];
589 for (j = 0,
i = iir->
nb_ab[0];
i >= 0; j++,
i--) {
590 iir->
ab[0][j] = botc[2 *
i];
614 int current_biquad = 0;
620 while (nb_biquads--) {
621 Pair outmost_pole = { -1, -1 };
622 Pair nearest_zero = { -1, -1 };
623 double zeros[4] = { 0 };
624 double poles[4] = { 0 };
627 double min_distance = DBL_MAX;
632 for (
i = 0;
i < iir->
nb_ab[0];
i++) {
637 mag =
hypot(iir->
ab[0][2 *
i], iir->
ab[0][2 *
i + 1]);
645 for (
i = 0;
i < iir->
nb_ab[0];
i++) {
649 if (iir->
ab[0][2 *
i ] == iir->
ab[0][2 * outmost_pole.
a ] &&
650 iir->
ab[0][2 *
i + 1] == -iir->
ab[0][2 * outmost_pole.
a + 1]) {
658 if (outmost_pole.
a < 0 || outmost_pole.
b < 0)
661 for (
i = 0;
i < iir->
nb_ab[1];
i++) {
667 iir->
ab[0][2 * outmost_pole.
a + 1] - iir->
ab[1][2 *
i + 1]);
675 for (
i = 0;
i < iir->
nb_ab[1];
i++) {
679 if (iir->
ab[1][2 *
i ] == iir->
ab[1][2 * nearest_zero.
a ] &&
680 iir->
ab[1][2 *
i + 1] == -iir->
ab[1][2 * nearest_zero.
a + 1]) {
688 if (nearest_zero.
a < 0 || nearest_zero.
b < 0)
691 poles[0] = iir->
ab[0][2 * outmost_pole.
a ];
692 poles[1] = iir->
ab[0][2 * outmost_pole.
a + 1];
694 zeros[0] = iir->
ab[1][2 * nearest_zero.
a ];
695 zeros[1] = iir->
ab[1][2 * nearest_zero.
a + 1];
697 if (nearest_zero.
a == nearest_zero.
b && outmost_pole.
a == outmost_pole.
b) {
704 poles[2] = iir->
ab[0][2 * outmost_pole.
b ];
705 poles[3] = iir->
ab[0][2 * outmost_pole.
b + 1];
707 zeros[2] = iir->
ab[1][2 * nearest_zero.
b ];
708 zeros[3] = iir->
ab[1][2 * nearest_zero.
b + 1];
719 iir->
ab[0][2 * outmost_pole.
a] = iir->
ab[0][2 * outmost_pole.
a + 1] =
NAN;
720 iir->
ab[0][2 * outmost_pole.
b] = iir->
ab[0][2 * outmost_pole.
b + 1] =
NAN;
721 iir->
ab[1][2 * nearest_zero.
a] = iir->
ab[1][2 * nearest_zero.
a + 1] =
NAN;
722 iir->
ab[1][2 * nearest_zero.
b] = iir->
ab[1][2 * nearest_zero.
b + 1] =
NAN;
724 iir->
biquads[current_biquad].
a[0] = 1.;
725 iir->
biquads[current_biquad].
a[1] =
a[2] /
a[4];
726 iir->
biquads[current_biquad].
a[2] =
a[0] /
a[4];
727 iir->
biquads[current_biquad].
b[0] =
b[4] /
a[4];
728 iir->
biquads[current_biquad].
b[1] =
b[2] /
a[4];
729 iir->
biquads[current_biquad].
b[2] =
b[0] /
a[4];
734 iir->
biquads[current_biquad].
b[2]) > 1e-6) {
737 iir->
biquads[current_biquad].
a[2]) /
738 (iir->
biquads[current_biquad].
b[0] +
749 iir->
biquads[current_biquad].
b[0] *= (current_biquad ? 1.0 : iir->
g);
750 iir->
biquads[current_biquad].
b[1] *= (current_biquad ? 1.0 : iir->
g);
751 iir->
biquads[current_biquad].
b[2] *= (current_biquad ? 1.0 : iir->
g);
769 double b0,
double b1,
double b2,
770 double a1,
double a2)
772 double w1 = 0., w2 = 0.;
777 for (
int n = 0; n < length; n++) {
778 double out, in = x[n];
780 y[n] =
out = in *
b0 + w1;
786 static void solve(
double *
matrix,
double *vector,
int n,
double *y,
double *x,
double *lu)
790 for (
int i = 0;
i < n;
i++) {
791 for (
int j =
i; j < n; j++) {
793 for (
int k = 0; k <
i; k++)
794 sum += lu[
i * n + k] * lu[k * n + j];
795 lu[
i * n + j] =
matrix[j * n +
i] - sum;
797 for (
int j =
i + 1; j < n; j++) {
799 for (
int k = 0; k <
i; k++)
800 sum += lu[j * n + k] * lu[k * n +
i];
801 lu[j * n +
i] = (1. / lu[
i * n +
i]) * (
matrix[
i * n + j] - sum);
805 for (
int i = 0;
i < n;
i++) {
807 for (
int k = 0; k <
i; k++)
808 sum += lu[
i * n + k] * y[k];
809 y[
i] = vector[
i] - sum;
812 for (
int i = n - 1;
i >= 0;
i--) {
814 for (
int k =
i + 1; k < n; k++)
815 sum += lu[
i * n + k] * x[k];
816 x[
i] = (1 / lu[
i * n +
i]) * (y[
i] - sum);
825 for (
int ch = 0; ch <
channels; ch++) {
828 int length = nb_biquads * 2 + 1;
829 double *impulse =
av_calloc(length,
sizeof(*impulse));
830 double *y =
av_calloc(length,
sizeof(*y));
831 double *resp =
av_calloc(length,
sizeof(*resp));
832 double *
M =
av_calloc((length - 1) * 2 * nb_biquads,
sizeof(*
M));
833 double *
W =
av_calloc((length - 1) * 2 * nb_biquads,
sizeof(*
W));
835 if (!impulse || !y || !resp || !
M) {
846 for (
int n = 0; n < nb_biquads; n++) {
854 for (
int n = 0; n < nb_biquads; n++) {
860 memcpy(
M + n * 2 * (length - 1), resp,
sizeof(*resp) * (length - 1));
861 memcpy(
M + n * 2 * (length - 1) + length, resp,
sizeof(*resp) * (length - 2));
862 memset(resp, 0, length *
sizeof(*resp));
865 solve(
M, &y[1], length - 1, &impulse[1], resp,
W);
869 for (
int n = 0; n < nb_biquads; n++) {
873 biquad->b[1] = resp[n * 2 + 0];
874 biquad->b[2] = resp[n * 2 + 1];
899 for (n = 0; n < iir->
nb_ab[0]; n++) {
900 double r = iir->
ab[0][2*n];
901 double angle = iir->
ab[0][2*n+1];
903 iir->
ab[0][2*n] =
r * cos(angle);
904 iir->
ab[0][2*n+1] =
r * sin(angle);
907 for (n = 0; n < iir->
nb_ab[1]; n++) {
908 double r = iir->
ab[1][2*n];
909 double angle = iir->
ab[1][2*n+1];
911 iir->
ab[1][2*n] =
r * cos(angle);
912 iir->
ab[1][2*n+1] =
r * sin(angle);
926 for (n = 0; n < iir->
nb_ab[0]; n++) {
927 double sr = iir->
ab[0][2*n];
928 double si = iir->
ab[0][2*n+1];
930 iir->
ab[0][2*n] =
exp(sr) * cos(si);
931 iir->
ab[0][2*n+1] =
exp(sr) * sin(si);
934 for (n = 0; n < iir->
nb_ab[1]; n++) {
935 double sr = iir->
ab[1][2*n];
936 double si = iir->
ab[1][2*n+1];
938 iir->
ab[1][2*n] =
exp(sr) * cos(si);
939 iir->
ab[1][2*n+1] =
exp(sr) * sin(si);
955 for (
int i = 0;
i <=
N;
i++) {
961 ((k & 1) ? -1. : 1.);
964 z +=
a[
i] * pow(2.,
i) *
acc;
980 if (!temp0 || !temp1)
983 memcpy(temp0, iir->
ab[0], iir->
nb_ab[0] *
sizeof(*temp0));
984 memcpy(temp1, iir->
ab[1], iir->
nb_ab[1] *
sizeof(*temp1));
986 for (
int n = 0; n < iir->
nb_ab[0]; n++)
989 for (
int n = 0; n < iir->
nb_ab[1]; n++)
1003 for (ch = 0; ch <
channels; ch++) {
1007 for (n = 0; n < iir->
nb_ab[0]; n++) {
1008 double r = iir->
ab[0][2*n];
1009 double angle =
M_PI*iir->
ab[0][2*n+1]/180.;
1011 iir->
ab[0][2*n] =
r * cos(angle);
1012 iir->
ab[0][2*n+1] =
r * sin(angle);
1015 for (n = 0; n < iir->
nb_ab[1]; n++) {
1016 double r = iir->
ab[1][2*n];
1017 double angle =
M_PI*iir->
ab[1][2*n+1]/180.;
1019 iir->
ab[1][2*n] =
r * cos(angle);
1020 iir->
ab[1][2*n+1] =
r * sin(angle);
1030 for (ch = 0; ch <
channels; ch++) {
1033 for (
int n = 0; n < iir->
nb_ab[0]; n++) {
1034 double pr =
hypot(iir->
ab[0][2*n], iir->
ab[0][2*n+1]);
1046 const uint8_t *font;
1052 for (
i = 0; txt[
i];
i++) {
1055 uint8_t *p = pic->
data[0] + y * pic->
linesize[0] + (x +
i * 8) * 4;
1056 for (char_y = 0; char_y < font_height; char_y++) {
1058 if (font[txt[
i] * font_height + char_y] &
mask)
1069 int dx =
FFABS(x1-x0);
1070 int dy =
FFABS(y1-y0), sy = y0 < y1 ? 1 : -1;
1071 int err = (dx>dy ? dx : -dy) / 2, e2;
1076 if (x0 == x1 && y0 == y1)
1093 static double distance(
double x0,
double x1,
double y0,
double y1)
1095 return hypot(x0 - x1, y0 - y1);
1099 const double *
b,
const double *
a,
1100 int nb_b,
int nb_a,
double *magnitude,
double *phase)
1102 double realz, realp;
1103 double imagz, imagp;
1108 realz = 0., realp = 0.;
1109 imagz = 0., imagp = 0.;
1110 for (
int x = 0; x < nb_a; x++) {
1111 realz += cos(-x *
w) *
a[x];
1112 imagz += sin(-x *
w) *
a[x];
1115 for (
int x = 0; x < nb_b; x++) {
1116 realp += cos(-x *
w) *
b[x];
1117 imagp += sin(-x *
w) *
b[x];
1120 div = realp * realp + imagp * imagp;
1121 real = (realz * realp + imagz * imagp) / div;
1122 imag = (imagz * realp - imagp * realz) / div;
1124 *magnitude =
hypot(real, imag);
1125 *phase = atan2(imag, real);
1127 double p = 1., z = 1.;
1130 for (
int x = 0; x < nb_a; x++) {
1132 acc += atan2(sin(
w) -
a[2 * x + 1], cos(
w) -
a[2 * x]);
1135 for (
int x = 0; x < nb_b; x++) {
1137 acc -= atan2(sin(
w) -
b[2 * x + 1], cos(
w) -
b[2 * x]);
1148 double *mag, *phase, *
temp, *delay,
min = DBL_MAX,
max = -DBL_MAX;
1149 double min_delay = DBL_MAX, max_delay = -DBL_MAX, min_phase, max_phase;
1150 int prev_ymag = -1, prev_yphase = -1, prev_ydelay = -1;
1154 memset(
out->data[0], 0,
s->h *
out->linesize[0]);
1160 if (!mag || !phase || !delay || !
temp)
1163 ch =
av_clip(
s->ir_channel, 0,
s->channels - 1);
1164 for (
i = 0;
i <
s->w;
i++) {
1165 const double *
b =
s->iir[ch].ab[0];
1166 const double *
a =
s->iir[ch].ab[1];
1167 const int nb_b =
s->iir[ch].nb_ab[0];
1168 const int nb_a =
s->iir[ch].nb_ab[1];
1169 double w =
i *
M_PI / (
s->w - 1);
1174 mag[
i] =
s->iir[ch].g * m;
1181 for (
i = 0;
i <
s->w - 1;
i++) {
1182 double d = phase[
i] - phase[
i + 1];
1186 min_phase = phase[0];
1187 max_phase = phase[0];
1188 for (
i = 1;
i <
s->w;
i++) {
1191 min_phase =
fmin(min_phase, phase[
i]);
1192 max_phase =
fmax(max_phase, phase[
i]);
1195 for (
i = 0;
i <
s->w - 1;
i++) {
1198 delay[
i + 1] = -(phase[
i] - phase[
i + 1]) / div;
1199 min_delay =
fmin(min_delay, delay[
i + 1]);
1200 max_delay =
fmax(max_delay, delay[
i + 1]);
1202 delay[0] = delay[1];
1204 for (
i = 0;
i <
s->w;
i++) {
1205 int ymag = mag[
i] /
max * (
s->h - 1);
1206 int ydelay = (delay[
i] - min_delay) / (max_delay - min_delay) * (
s->h - 1);
1207 int yphase = (phase[
i] - min_phase) / (max_phase - min_phase) * (
s->h - 1);
1209 ymag =
s->h - 1 -
av_clip(ymag, 0,
s->h - 1);
1210 yphase =
s->h - 1 -
av_clip(yphase, 0,
s->h - 1);
1211 ydelay =
s->h - 1 -
av_clip(ydelay, 0,
s->h - 1);
1215 if (prev_yphase < 0)
1216 prev_yphase = yphase;
1217 if (prev_ydelay < 0)
1218 prev_ydelay = ydelay;
1225 prev_yphase = yphase;
1226 prev_ydelay = ydelay;
1229 if (
s->w > 400 &&
s->h > 100) {
1230 drawtext(
out, 2, 2,
"Max Magnitude:", 0xDDDDDDDD);
1234 drawtext(
out, 2, 12,
"Min Magnitude:", 0xDDDDDDDD);
1239 snprintf(text,
sizeof(text),
"%.2f", max_phase);
1243 snprintf(text,
sizeof(text),
"%.2f", min_phase);
1247 snprintf(text,
sizeof(text),
"%.2f", max_delay);
1251 snprintf(text,
sizeof(text),
"%.2f", min_delay);
1269 s->channels =
inlink->ch_layout.nb_channels;
1286 if (
s->format == -1) {
1289 }
else if (
s->format == 2) {
1291 }
else if (
s->format == 3) {
1293 }
else if (
s->format == 4) {
1296 if (
s->format > 0) {
1310 av_log(
ctx,
AV_LOG_WARNING,
"transfer function coefficients format is not recommended for too high number of zeros/poles.\n");
1312 if (
s->format > 0 &&
s->process == 0) {
1318 }
else if (
s->format == -2 &&
s->process > 0) {
1321 }
else if (
s->format <= 0 &&
s->process == 1) {
1324 }
else if (
s->format <= 0 &&
s->process == 2) {
1327 }
else if (
s->format > 0 &&
s->process == 1) {
1331 }
else if (
s->format > 0 &&
s->process == 2) {
1332 if (
s->precision > 1)
1342 for (ch = 0;
s->format == -2 && ch <
inlink->ch_layout.nb_channels; ch++) {
1346 av_log(
ctx,
AV_LOG_ERROR,
"Number of ladder coefficients must be one more than number of reflection coefficients.\n");
1351 for (ch = 0;
s->format == 0 && ch <
inlink->ch_layout.nb_channels; ch++) {
1354 for (
i = 1;
i < iir->
nb_ab[0];
i++) {
1355 iir->
ab[0][
i] /= iir->
ab[0][0];
1358 iir->
ab[0][0] = 1.0;
1359 for (
i = 0;
i < iir->
nb_ab[1];
i++) {
1360 iir->
ab[1][
i] *= iir->
g;
1366 switch (
inlink->format) {
1367 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;
1368 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;
1369 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;
1370 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;
1373 if (
s->format == -2) {
1374 switch (
inlink->format) {
1410 if (
s->iir[ch].clippings > 0)
1412 ch,
s->iir[ch].clippings);
1413 s->iir[ch].clippings = 0;
1421 int64_t old_pts =
s->video->pts;
1424 if (new_pts > old_pts) {
1427 s->video->pts = new_pts;
1460 if (!
s->a_str || !
s->b_str || !
s->g_str) {
1465 switch (
s->precision) {
1485 .
name =
"filter_response",
1504 for (ch = 0; ch <
s->channels; ch++) {
1526 #define OFFSET(x) offsetof(AudioIIRContext, x)
1527 #define AF AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
1528 #define VF AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
1531 {
"zeros",
"set B/numerator/zeros/reflection coefficients",
OFFSET(b_str),
AV_OPT_TYPE_STRING, {.str=
"1+0i 1-0i"}, 0, 0,
AF },
1541 {
"ll",
"lattice-ladder function", 0,
AV_OPT_TYPE_CONST, {.i64=-2}, 0, 0,
AF, .unit =
"format" },
1542 {
"sf",
"analog transfer function", 0,
AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0,
AF, .unit =
"format" },
1543 {
"tf",
"digital transfer function", 0,
AV_OPT_TYPE_CONST, {.i64=0}, 0, 0,
AF, .unit =
"format" },
1544 {
"zp",
"Z-plane zeros/poles", 0,
AV_OPT_TYPE_CONST, {.i64=1}, 0, 0,
AF, .unit =
"format" },
1545 {
"pr",
"Z-plane zeros/poles (polar radians)", 0,
AV_OPT_TYPE_CONST, {.i64=2}, 0, 0,
AF, .unit =
"format" },
1546 {
"pd",
"Z-plane zeros/poles (polar degrees)", 0,
AV_OPT_TYPE_CONST, {.i64=3}, 0, 0,
AF, .unit =
"format" },
1547 {
"sp",
"S-plane zeros/poles", 0,
AV_OPT_TYPE_CONST, {.i64=4}, 0, 0,
AF, .unit =
"format" },
1553 {
"precision",
"set filtering precision",
OFFSET(precision),
AV_OPT_TYPE_INT, {.i64=0}, 0, 3,
AF, .unit =
"precision" },
1555 {
"dbl",
"double-precision floating-point", 0,
AV_OPT_TYPE_CONST, {.i64=0}, 0, 0,
AF, .unit =
"precision" },
1556 {
"flt",
"single-precision floating-point", 0,
AV_OPT_TYPE_CONST, {.i64=1}, 0, 0,
AF, .unit =
"precision" },
1557 {
"i32",
"32-bit integers", 0,
AV_OPT_TYPE_CONST, {.i64=2}, 0, 0,
AF, .unit =
"precision" },
1558 {
"i16",
"16-bit integers", 0,
AV_OPT_TYPE_CONST, {.i64=3}, 0, 0,
AF, .unit =
"precision" },
1563 {
"channel",
"set IR channel to display frequency response",
OFFSET(ir_channel),
AV_OPT_TYPE_INT, {.i64=0}, 0, 1024,
VF },
1573 .description =
NULL_IF_CONFIG_SMALL(
"Apply Infinite Impulse Response filter with supplied coefficients."),
1575 .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)