Go to the documentation of this file.
111 #define IIR_CH(name, type, min, max, need_clipping) \
112 static int iir_ch_## name(AVFilterContext *ctx, void *arg, int ch, int nb_jobs) \
114 AudioIIRContext *s = ctx->priv; \
115 const double ig = s->dry_gain; \
116 const double og = s->wet_gain; \
117 const double mix = s->mix; \
118 ThreadData *td = arg; \
119 AVFrame *in = td->in, *out = td->out; \
120 const type *src = (const type *)in->extended_data[ch]; \
121 double *oc = (double *)s->iir[ch].cache[0]; \
122 double *ic = (double *)s->iir[ch].cache[1]; \
123 const int nb_a = s->iir[ch].nb_ab[0]; \
124 const int nb_b = s->iir[ch].nb_ab[1]; \
125 const double *a = s->iir[ch].ab[0]; \
126 const double *b = s->iir[ch].ab[1]; \
127 const double g = s->iir[ch].g; \
128 int *clippings = &s->iir[ch].clippings; \
129 type *dst = (type *)out->extended_data[ch]; \
132 for (n = 0; n < in->nb_samples; n++) { \
133 double sample = 0.; \
136 memmove(&ic[1], &ic[0], (nb_b - 1) * sizeof(*ic)); \
137 memmove(&oc[1], &oc[0], (nb_a - 1) * sizeof(*oc)); \
138 ic[0] = src[n] * ig; \
139 for (x = 0; x < nb_b; x++) \
140 sample += b[x] * ic[x]; \
142 for (x = 1; x < nb_a; x++) \
143 sample -= a[x] * oc[x]; \
147 sample = sample * mix + ic[0] * (1. - mix); \
148 if (need_clipping && sample < min) { \
151 } else if (need_clipping && sample > max) { \
162 IIR_CH(s16p, int16_t, INT16_MIN, INT16_MAX, 1)
164 IIR_CH(fltp,
float, -1., 1., 0)
165 IIR_CH(dblp,
double, -1., 1., 0)
167 #define SERIAL_IIR_CH(name, type, min, max, need_clipping) \
168 static int iir_ch_serial_## name(AVFilterContext *ctx, void *arg, \
169 int ch, int nb_jobs) \
171 AudioIIRContext *s = ctx->priv; \
172 const double ig = s->dry_gain; \
173 const double og = s->wet_gain; \
174 const double mix = s->mix; \
175 const double imix = 1. - mix; \
176 ThreadData *td = arg; \
177 AVFrame *in = td->in, *out = td->out; \
178 const type *src = (const type *)in->extended_data[ch]; \
179 type *dst = (type *)out->extended_data[ch]; \
180 IIRChannel *iir = &s->iir[ch]; \
181 const double g = iir->g; \
182 int *clippings = &iir->clippings; \
183 int nb_biquads = (FFMAX(iir->nb_ab[0], iir->nb_ab[1]) + 1) / 2; \
186 for (i = nb_biquads - 1; i >= 0; i--) { \
187 const double a1 = -iir->biquads[i].a[1]; \
188 const double a2 = -iir->biquads[i].a[2]; \
189 const double b0 = iir->biquads[i].b[0]; \
190 const double b1 = iir->biquads[i].b[1]; \
191 const double b2 = iir->biquads[i].b[2]; \
192 double w1 = iir->biquads[i].w1; \
193 double w2 = iir->biquads[i].w2; \
195 for (n = 0; n < in->nb_samples; n++) { \
196 double i0 = ig * (i ? dst[n] : src[n]); \
197 double o0 = i0 * b0 + w1; \
199 w1 = b1 * i0 + w2 + a1 * o0; \
200 w2 = b2 * i0 + a2 * o0; \
203 o0 = o0 * mix + imix * i0; \
204 if (need_clipping && o0 < min) { \
207 } else if (need_clipping && o0 > max) { \
214 iir->biquads[i].w1 = w1; \
215 iir->biquads[i].w2 = w2; \
226 #define PARALLEL_IIR_CH(name, type, min, max, need_clipping) \
227 static int iir_ch_parallel_## name(AVFilterContext *ctx, void *arg, \
228 int ch, int nb_jobs) \
230 AudioIIRContext *s = ctx->priv; \
231 const double ig = s->dry_gain; \
232 const double og = s->wet_gain; \
233 const double mix = s->mix; \
234 const double imix = 1. - mix; \
235 ThreadData *td = arg; \
236 AVFrame *in = td->in, *out = td->out; \
237 const type *src = (const type *)in->extended_data[ch]; \
238 type *dst = (type *)out->extended_data[ch]; \
239 IIRChannel *iir = &s->iir[ch]; \
240 const double g = iir->g; \
241 const double fir = iir->fir; \
242 int *clippings = &iir->clippings; \
243 int nb_biquads = (FFMAX(iir->nb_ab[0], iir->nb_ab[1]) + 1) / 2; \
246 for (i = 0; i < nb_biquads; i++) { \
247 const double a1 = -iir->biquads[i].a[1]; \
248 const double a2 = -iir->biquads[i].a[2]; \
249 const double b1 = iir->biquads[i].b[1]; \
250 const double b2 = iir->biquads[i].b[2]; \
251 double w1 = iir->biquads[i].w1; \
252 double w2 = iir->biquads[i].w2; \
254 for (n = 0; n < in->nb_samples; n++) { \
255 double i0 = ig * src[n]; \
258 w1 = b1 * i0 + w2 + a1 * o0; \
259 w2 = b2 * i0 + a2 * o0; \
263 if (need_clipping && o0 < min) { \
266 } else if (need_clipping && o0 > max) { \
273 iir->biquads[i].w1 = w1; \
274 iir->biquads[i].w2 = w2; \
277 for (n = 0; n < in->nb_samples; n++) { \
278 dst[n] += fir * src[n]; \
279 dst[n] = dst[n] * mix + imix * src[n]; \
290 #define LATTICE_IIR_CH(name, type, min, max, need_clipping) \
291 static int iir_ch_lattice_## name(AVFilterContext *ctx, void *arg, \
292 int ch, int nb_jobs) \
294 AudioIIRContext *s = ctx->priv; \
295 const double ig = s->dry_gain; \
296 const double og = s->wet_gain; \
297 const double mix = s->mix; \
298 ThreadData *td = arg; \
299 AVFrame *in = td->in, *out = td->out; \
300 const type *src = (const type *)in->extended_data[ch]; \
301 double n0, n1, p0, *x = (double *)s->iir[ch].cache[0]; \
302 const int nb_stages = s->iir[ch].nb_ab[1]; \
303 const double *v = s->iir[ch].ab[0]; \
304 const double *k = s->iir[ch].ab[1]; \
305 const double g = s->iir[ch].g; \
306 int *clippings = &s->iir[ch].clippings; \
307 type *dst = (type *)out->extended_data[ch]; \
310 for (n = 0; n < in->nb_samples; n++) { \
311 const double in = src[n] * ig; \
315 for (int i = nb_stages - 1; i >= 0; i--) { \
316 n0 = n1 - k[i] * x[i]; \
317 p0 = n0 * k[i] + x[i]; \
318 out += p0 * v[i+1]; \
324 memmove(&x[1], &x[0], nb_stages * sizeof(*x)); \
327 out = out * mix + in * (1. - mix); \
328 if (need_clipping && out < min) { \
331 } else if (need_clipping && out > max) { \
355 for (p = item_str; *p && *p !=
'|'; p++) {
364 char *p, *
arg, *old_str, *prev_arg =
NULL, *saveptr =
NULL;
370 for (
i = 0;
i < nb_items;
i++) {
396 char *p, *
arg, *old_str, *saveptr =
NULL;
402 for (
i = 0;
i < nb_items;
i++) {
421 char *p, *
arg, *old_str, *saveptr =
NULL;
427 for (
i = 0;
i < nb_items;
i++) {
444 static const char *
const format[] = {
"%lf",
"%lf %lfi",
"%lf %lfr",
"%lf %lfd",
"%lf %lfi" };
449 char *p, *
arg, *old_str, *prev_arg =
NULL, *saveptr =
NULL;
471 if (!iir->
ab[ab] || !iir->
cache[ab]) {
493 static void cmul(
double re,
double im,
double re2,
double im2,
double *
RE,
double *
IM)
495 *
RE = re * re2 - im * im2;
496 *
IM = re * im2 + re2 * im;
503 for (
int i = 1;
i <= n;
i++) {
504 for (
int j = n -
i; j < n; j++) {
507 cmul(coefs[2 * (j + 1)], coefs[2 * (j + 1) + 1],
508 pz[2 * (
i - 1)], pz[2 * (
i - 1) + 1], &re, &im);
511 coefs[2 * j + 1] -= im;
515 for (
int i = 0;
i < n + 1;
i++) {
516 if (
fabs(coefs[2 *
i + 1]) > FLT_EPSILON) {
517 av_log(
ctx,
AV_LOG_ERROR,
"coefs: %f of z^%d is not real; poles/zeros are not complex conjugates.\n",
518 coefs[2 *
i + 1],
i);
535 for (
int i = 0;
i < iir->
nb_ab[1];
i++) {
536 sum_den += iir->
ab[1][
i];
539 if (sum_den > 1e-6) {
540 double factor, sum_num = 0.;
542 for (
int i = 0;
i < iir->
nb_ab[0];
i++) {
543 sum_num += iir->
ab[0][
i];
546 factor = sum_num / sum_den;
548 for (
int i = 0;
i < iir->
nb_ab[1];
i++) {
557 int ch,
i, j,
ret = 0;
565 if (!topc || !botc) {
580 for (j = 0,
i = iir->
nb_ab[1];
i >= 0; j++,
i--) {
581 iir->
ab[1][j] = topc[2 *
i];
585 for (j = 0,
i = iir->
nb_ab[0];
i >= 0; j++,
i--) {
586 iir->
ab[0][j] = botc[2 *
i];
610 int current_biquad = 0;
616 while (nb_biquads--) {
617 Pair outmost_pole = { -1, -1 };
618 Pair nearest_zero = { -1, -1 };
619 double zeros[4] = { 0 };
620 double poles[4] = { 0 };
623 double min_distance = DBL_MAX;
628 for (
i = 0;
i < iir->
nb_ab[0];
i++) {
633 mag =
hypot(iir->
ab[0][2 *
i], iir->
ab[0][2 *
i + 1]);
641 for (
i = 0;
i < iir->
nb_ab[0];
i++) {
645 if (iir->
ab[0][2 *
i ] == iir->
ab[0][2 * outmost_pole.
a ] &&
646 iir->
ab[0][2 *
i + 1] == -iir->
ab[0][2 * outmost_pole.
a + 1]) {
654 if (outmost_pole.
a < 0 || outmost_pole.
b < 0)
657 for (
i = 0;
i < iir->
nb_ab[1];
i++) {
663 iir->
ab[0][2 * outmost_pole.
a + 1] - iir->
ab[1][2 *
i + 1]);
671 for (
i = 0;
i < iir->
nb_ab[1];
i++) {
675 if (iir->
ab[1][2 *
i ] == iir->
ab[1][2 * nearest_zero.
a ] &&
676 iir->
ab[1][2 *
i + 1] == -iir->
ab[1][2 * nearest_zero.
a + 1]) {
684 if (nearest_zero.
a < 0 || nearest_zero.
b < 0)
687 poles[0] = iir->
ab[0][2 * outmost_pole.
a ];
688 poles[1] = iir->
ab[0][2 * outmost_pole.
a + 1];
690 zeros[0] = iir->
ab[1][2 * nearest_zero.
a ];
691 zeros[1] = iir->
ab[1][2 * nearest_zero.
a + 1];
693 if (nearest_zero.
a == nearest_zero.
b && outmost_pole.
a == outmost_pole.
b) {
700 poles[2] = iir->
ab[0][2 * outmost_pole.
b ];
701 poles[3] = iir->
ab[0][2 * outmost_pole.
b + 1];
703 zeros[2] = iir->
ab[1][2 * nearest_zero.
b ];
704 zeros[3] = iir->
ab[1][2 * nearest_zero.
b + 1];
715 iir->
ab[0][2 * outmost_pole.
a] = iir->
ab[0][2 * outmost_pole.
a + 1] =
NAN;
716 iir->
ab[0][2 * outmost_pole.
b] = iir->
ab[0][2 * outmost_pole.
b + 1] =
NAN;
717 iir->
ab[1][2 * nearest_zero.
a] = iir->
ab[1][2 * nearest_zero.
a + 1] =
NAN;
718 iir->
ab[1][2 * nearest_zero.
b] = iir->
ab[1][2 * nearest_zero.
b + 1] =
NAN;
720 iir->
biquads[current_biquad].
a[0] = 1.;
721 iir->
biquads[current_biquad].
a[1] =
a[2] /
a[4];
722 iir->
biquads[current_biquad].
a[2] =
a[0] /
a[4];
723 iir->
biquads[current_biquad].
b[0] =
b[4] /
a[4];
724 iir->
biquads[current_biquad].
b[1] =
b[2] /
a[4];
725 iir->
biquads[current_biquad].
b[2] =
b[0] /
a[4];
730 iir->
biquads[current_biquad].
b[2]) > 1e-6) {
733 iir->
biquads[current_biquad].
a[2]) /
734 (iir->
biquads[current_biquad].
b[0] +
745 iir->
biquads[current_biquad].
b[0] *= (current_biquad ? 1.0 : iir->
g);
746 iir->
biquads[current_biquad].
b[1] *= (current_biquad ? 1.0 : iir->
g);
747 iir->
biquads[current_biquad].
b[2] *= (current_biquad ? 1.0 : iir->
g);
765 double b0,
double b1,
double b2,
766 double a1,
double a2)
768 double w1 = 0., w2 = 0.;
773 for (
int n = 0; n < length; n++) {
774 double out, in = x[n];
776 y[n] =
out = in *
b0 + w1;
782 static void solve(
double *
matrix,
double *vector,
int n,
double *y,
double *x,
double *lu)
786 for (
int i = 0;
i < n;
i++) {
787 for (
int j =
i; j < n; j++) {
789 for (
int k = 0; k <
i; k++)
790 sum += lu[
i * n + k] * lu[k * n + j];
791 lu[
i * n + j] =
matrix[j * n +
i] - sum;
793 for (
int j =
i + 1; j < n; j++) {
795 for (
int k = 0; k <
i; k++)
796 sum += lu[j * n + k] * lu[k * n +
i];
797 lu[j * n +
i] = (1. / lu[
i * n +
i]) * (
matrix[
i * n + j] - sum);
801 for (
int i = 0;
i < n;
i++) {
803 for (
int k = 0; k <
i; k++)
804 sum += lu[
i * n + k] * y[k];
805 y[
i] = vector[
i] - sum;
808 for (
int i = n - 1;
i >= 0;
i--) {
810 for (
int k =
i + 1; k < n; k++)
811 sum += lu[
i * n + k] * x[k];
812 x[
i] = (1 / lu[
i * n +
i]) * (y[
i] - sum);
820 for (
int ch = 0; ch <
channels; ch++) {
823 int length = nb_biquads * 2 + 1;
824 double *impulse =
av_calloc(length,
sizeof(*impulse));
825 double *y =
av_calloc(length,
sizeof(*y));
826 double *resp =
av_calloc(length,
sizeof(*resp));
827 double *
M =
av_calloc((length - 1) * nb_biquads, 2 * 2 *
sizeof(*
M));
830 if (!impulse || !y || !resp || !
M) {
837 W =
M + (length - 1) * 2 * nb_biquads;
841 for (
int n = 0; n < nb_biquads; n++) {
849 for (
int n = 0; n < nb_biquads; n++) {
855 memcpy(
M + n * 2 * (length - 1), resp,
sizeof(*resp) * (length - 1));
856 memcpy(
M + n * 2 * (length - 1) + length, resp,
sizeof(*resp) * (length - 2));
857 memset(resp, 0, length *
sizeof(*resp));
860 solve(
M, &y[1], length - 1, &impulse[1], resp,
W);
864 for (
int n = 0; n < nb_biquads; n++) {
868 biquad->b[1] = resp[n * 2 + 0];
869 biquad->b[2] = resp[n * 2 + 1];
890 for (n = 0; n < iir->
nb_ab[0]; n++) {
891 double r = iir->
ab[0][2*n];
892 double angle = iir->
ab[0][2*n+1];
894 iir->
ab[0][2*n] =
r * cos(angle);
895 iir->
ab[0][2*n+1] =
r * sin(angle);
898 for (n = 0; n < iir->
nb_ab[1]; n++) {
899 double r = iir->
ab[1][2*n];
900 double angle = iir->
ab[1][2*n+1];
902 iir->
ab[1][2*n] =
r * cos(angle);
903 iir->
ab[1][2*n+1] =
r * sin(angle);
917 for (n = 0; n < iir->
nb_ab[0]; n++) {
918 double sr = iir->
ab[0][2*n];
919 double si = iir->
ab[0][2*n+1];
921 iir->
ab[0][2*n] =
exp(sr) * cos(si);
922 iir->
ab[0][2*n+1] =
exp(sr) * sin(si);
925 for (n = 0; n < iir->
nb_ab[1]; n++) {
926 double sr = iir->
ab[1][2*n];
927 double si = iir->
ab[1][2*n+1];
929 iir->
ab[1][2*n] =
exp(sr) * cos(si);
930 iir->
ab[1][2*n+1] =
exp(sr) * sin(si);
946 for (
int i = 0;
i <=
N;
i++) {
952 ((k & 1) ? -1. : 1.);
955 z +=
a[
i] * pow(2.,
i) * acc;
971 if (!temp0 || !temp1)
974 memcpy(temp0, iir->
ab[0], iir->
nb_ab[0] *
sizeof(*temp0));
975 memcpy(temp1, iir->
ab[1], iir->
nb_ab[1] *
sizeof(*temp1));
977 for (
int n = 0; n < iir->
nb_ab[0]; n++)
980 for (
int n = 0; n < iir->
nb_ab[1]; n++)
998 for (n = 0; n < iir->
nb_ab[0]; n++) {
999 double r = iir->
ab[0][2*n];
1000 double angle =
M_PI*iir->
ab[0][2*n+1]/180.;
1002 iir->
ab[0][2*n] =
r * cos(angle);
1003 iir->
ab[0][2*n+1] =
r * sin(angle);
1006 for (n = 0; n < iir->
nb_ab[1]; n++) {
1007 double r = iir->
ab[1][2*n];
1008 double angle =
M_PI*iir->
ab[1][2*n+1]/180.;
1010 iir->
ab[1][2*n] =
r * cos(angle);
1011 iir->
ab[1][2*n+1] =
r * sin(angle);
1021 for (ch = 0; ch <
channels; ch++) {
1024 for (
int n = 0; n < iir->
nb_ab[0]; n++) {
1025 double pr =
hypot(iir->
ab[0][2*n], iir->
ab[0][2*n+1]);
1037 const uint8_t *font;
1043 for (
i = 0; txt[
i];
i++) {
1046 uint8_t *p = pic->
data[0] + y * pic->
linesize[0] + (x +
i * 8) * 4;
1047 for (char_y = 0; char_y < font_height; char_y++) {
1049 if (font[txt[
i] * font_height + char_y] &
mask)
1060 int dx =
FFABS(x1-x0);
1061 int dy =
FFABS(y1-y0), sy = y0 < y1 ? 1 : -1;
1062 int err = (dx>dy ? dx : -dy) / 2, e2;
1067 if (x0 == x1 && y0 == y1)
1084 static double distance(
double x0,
double x1,
double y0,
double y1)
1086 return hypot(x0 - x1, y0 - y1);
1090 const double *
b,
const double *
a,
1091 int nb_b,
int nb_a,
double *magnitude,
double *phase)
1093 double realz, realp;
1094 double imagz, imagp;
1099 realz = 0., realp = 0.;
1100 imagz = 0., imagp = 0.;
1101 for (
int x = 0; x < nb_a; x++) {
1102 realz += cos(-x *
w) *
a[x];
1103 imagz += sin(-x *
w) *
a[x];
1106 for (
int x = 0; x < nb_b; x++) {
1107 realp += cos(-x *
w) *
b[x];
1108 imagp += sin(-x *
w) *
b[x];
1111 div = realp * realp + imagp * imagp;
1112 real = (realz * realp + imagz * imagp) / div;
1113 imag = (imagz * realp - imagp * realz) / div;
1115 *magnitude =
hypot(real, imag);
1116 *phase = atan2(imag, real);
1118 double p = 1., z = 1.;
1121 for (
int x = 0; x < nb_a; x++) {
1123 acc += atan2(sin(
w) -
a[2 * x + 1], cos(
w) -
a[2 * x]);
1126 for (
int x = 0; x < nb_b; x++) {
1128 acc -= atan2(sin(
w) -
b[2 * x + 1], cos(
w) -
b[2 * x]);
1139 double *mag, *phase, *
temp, *delay,
min = DBL_MAX,
max = -DBL_MAX;
1140 double min_delay = DBL_MAX, max_delay = -DBL_MAX, min_phase, max_phase;
1141 int prev_ymag = -1, prev_yphase = -1, prev_ydelay = -1;
1145 memset(
out->data[0], 0,
s->h *
out->linesize[0]);
1151 if (!mag || !phase || !delay || !
temp)
1154 ch =
av_clip(
s->ir_channel, 0,
s->channels - 1);
1155 for (
i = 0;
i <
s->w;
i++) {
1156 const double *
b =
s->iir[ch].ab[0];
1157 const double *
a =
s->iir[ch].ab[1];
1158 const int nb_b =
s->iir[ch].nb_ab[0];
1159 const int nb_a =
s->iir[ch].nb_ab[1];
1160 double w =
i *
M_PI / (
s->w - 1);
1165 mag[
i] =
s->iir[ch].g * m;
1172 for (
i = 0;
i <
s->w - 1;
i++) {
1173 double d = phase[
i] - phase[
i + 1];
1177 min_phase = phase[0];
1178 max_phase = phase[0];
1179 for (
i = 1;
i <
s->w;
i++) {
1182 min_phase =
fmin(min_phase, phase[
i]);
1183 max_phase =
fmax(max_phase, phase[
i]);
1186 for (
i = 0;
i <
s->w - 1;
i++) {
1187 double div =
s->w / (
double)sample_rate;
1189 delay[
i + 1] = -(phase[
i] - phase[
i + 1]) / div;
1190 min_delay =
fmin(min_delay, delay[
i + 1]);
1191 max_delay =
fmax(max_delay, delay[
i + 1]);
1193 delay[0] = delay[1];
1195 for (
i = 0;
i <
s->w;
i++) {
1196 int ymag = mag[
i] /
max * (
s->h - 1);
1197 int ydelay = (delay[
i] - min_delay) / (max_delay - min_delay) * (
s->h - 1);
1198 int yphase = (phase[
i] - min_phase) / (max_phase - min_phase) * (
s->h - 1);
1200 ymag =
s->h - 1 -
av_clip(ymag, 0,
s->h - 1);
1201 yphase =
s->h - 1 -
av_clip(yphase, 0,
s->h - 1);
1202 ydelay =
s->h - 1 -
av_clip(ydelay, 0,
s->h - 1);
1206 if (prev_yphase < 0)
1207 prev_yphase = yphase;
1208 if (prev_ydelay < 0)
1209 prev_ydelay = ydelay;
1216 prev_yphase = yphase;
1217 prev_ydelay = ydelay;
1220 if (
s->w > 400 &&
s->h > 100) {
1221 drawtext(
out, 2, 2,
"Max Magnitude:", 0xDDDDDDDD);
1225 drawtext(
out, 2, 12,
"Min Magnitude:", 0xDDDDDDDD);
1230 snprintf(text,
sizeof(text),
"%.2f", max_phase);
1234 snprintf(text,
sizeof(text),
"%.2f", min_phase);
1238 snprintf(text,
sizeof(text),
"%.2f", max_delay);
1242 snprintf(text,
sizeof(text),
"%.2f", min_delay);
1260 s->channels =
inlink->ch_layout.nb_channels;
1277 if (
s->format == -1) {
1280 }
else if (
s->format == 2) {
1282 }
else if (
s->format == 3) {
1284 }
else if (
s->format == 4) {
1287 if (
s->format > 0) {
1301 av_log(
ctx,
AV_LOG_WARNING,
"transfer function coefficients format is not recommended for too high number of zeros/poles.\n");
1303 if (
s->format > 0 &&
s->process == 0) {
1309 }
else if (
s->format == -2 &&
s->process > 0) {
1312 }
else if (
s->format <= 0 &&
s->process == 1) {
1315 }
else if (
s->format <= 0 &&
s->process == 2) {
1318 }
else if (
s->format > 0 &&
s->process == 1) {
1322 }
else if (
s->format > 0 &&
s->process == 2) {
1323 if (
s->precision > 1)
1333 for (ch = 0;
s->format == -2 && ch <
inlink->ch_layout.nb_channels; ch++) {
1337 av_log(
ctx,
AV_LOG_ERROR,
"Number of ladder coefficients must be one more than number of reflection coefficients.\n");
1342 for (ch = 0;
s->format == 0 && ch <
inlink->ch_layout.nb_channels; ch++) {
1345 for (
i = 1;
i < iir->
nb_ab[0];
i++) {
1346 iir->
ab[0][
i] /= iir->
ab[0][0];
1349 iir->
ab[0][0] = 1.0;
1350 for (
i = 0;
i < iir->
nb_ab[1];
i++) {
1351 iir->
ab[1][
i] *= iir->
g;
1357 switch (
inlink->format) {
1358 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;
1359 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;
1360 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;
1361 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;
1364 if (
s->format == -2) {
1365 switch (
inlink->format) {
1401 if (
s->iir[ch].clippings > 0)
1403 ch,
s->iir[ch].clippings);
1404 s->iir[ch].clippings = 0;
1415 if (new_pts > old_pts) {
1418 s->video->pts = new_pts;
1452 if (!
s->a_str || !
s->b_str || !
s->g_str) {
1457 switch (
s->precision) {
1477 .
name =
"filter_response",
1496 for (ch = 0; ch <
s->channels; ch++) {
1518 #define OFFSET(x) offsetof(AudioIIRContext, x)
1519 #define AF AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
1520 #define VF AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
1523 {
"zeros",
"set B/numerator/zeros/reflection coefficients",
OFFSET(b_str),
AV_OPT_TYPE_STRING, {.str=
"1+0i 1-0i"}, 0, 0,
AF },
1533 {
"ll",
"lattice-ladder function", 0,
AV_OPT_TYPE_CONST, {.i64=-2}, 0, 0,
AF, .unit =
"format" },
1534 {
"sf",
"analog transfer function", 0,
AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0,
AF, .unit =
"format" },
1535 {
"tf",
"digital transfer function", 0,
AV_OPT_TYPE_CONST, {.i64=0}, 0, 0,
AF, .unit =
"format" },
1536 {
"zp",
"Z-plane zeros/poles", 0,
AV_OPT_TYPE_CONST, {.i64=1}, 0, 0,
AF, .unit =
"format" },
1537 {
"pr",
"Z-plane zeros/poles (polar radians)", 0,
AV_OPT_TYPE_CONST, {.i64=2}, 0, 0,
AF, .unit =
"format" },
1538 {
"pd",
"Z-plane zeros/poles (polar degrees)", 0,
AV_OPT_TYPE_CONST, {.i64=3}, 0, 0,
AF, .unit =
"format" },
1539 {
"sp",
"S-plane zeros/poles", 0,
AV_OPT_TYPE_CONST, {.i64=4}, 0, 0,
AF, .unit =
"format" },
1545 {
"precision",
"set filtering precision",
OFFSET(precision),
AV_OPT_TYPE_INT, {.i64=0}, 0, 3,
AF, .unit =
"precision" },
1547 {
"dbl",
"double-precision floating-point", 0,
AV_OPT_TYPE_CONST, {.i64=0}, 0, 0,
AF, .unit =
"precision" },
1548 {
"flt",
"single-precision floating-point", 0,
AV_OPT_TYPE_CONST, {.i64=1}, 0, 0,
AF, .unit =
"precision" },
1549 {
"i32",
"32-bit integers", 0,
AV_OPT_TYPE_CONST, {.i64=2}, 0, 0,
AF, .unit =
"precision" },
1550 {
"i16",
"16-bit integers", 0,
AV_OPT_TYPE_CONST, {.i64=3}, 0, 0,
AF, .unit =
"precision" },
1555 {
"channel",
"set IR channel to display frequency response",
OFFSET(ir_channel),
AV_OPT_TYPE_INT, {.i64=0}, 0, 1024,
VF },
1565 .description =
NULL_IF_CONFIG_SMALL(
"Apply Infinite Impulse Response filter with supplied coefficients."),
1567 .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
Underlying C type is 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.
#define FILTER_INPUTS(array)
static int read_channels(AVFilterContext *ctx, int channels, uint8_t *item_str, int ab)
This structure describes decoded (raw) audio or video data.
static int query_formats(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out)
#define IIR_CH(name, type, min, max, need_clipping)
@ 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.
Link properties exposed to filter code, but not external callers.
static double b1(void *priv, double x, double y)
static double a2(void *priv, double x, double y)
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)
@ AV_OPT_TYPE_DOUBLE
Underlying C type is double.
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
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 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
Underlying C type is two consecutive integers.
static void normalize_coeffs(AVFilterContext *ctx, int ch)
static av_cold int init(AVFilterContext *ctx)
static FilterLink * ff_filter_link(AVFilterLink *link)
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.
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
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
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.
#define FILTER_QUERY_FUNC2(func)
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
int ff_filter_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg, int *ret, int nb_jobs)
static void draw_response(AVFilterContext *ctx, AVFrame *out, int sample_rate)
@ AV_OPT_TYPE_INT
Underlying C type is int.
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]
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
#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)
static double a1(void *priv, double x, double y)
AVRational frame_rate
Frame rate of the stream on the link, or 1/0 if unknown or variable.
const AVFilter ff_af_aiir
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
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)