Go to the documentation of this file.
123 #define IIR_CH(name, type, min, max, need_clipping) \
124 static int iir_ch_## name(AVFilterContext *ctx, void *arg, int ch, int nb_jobs) \
126 AudioIIRContext *s = ctx->priv; \
127 const double ig = s->dry_gain; \
128 const double og = s->wet_gain; \
129 const double mix = s->mix; \
130 ThreadData *td = arg; \
131 AVFrame *in = td->in, *out = td->out; \
132 const type *src = (const type *)in->extended_data[ch]; \
133 double *oc = (double *)s->iir[ch].cache[0]; \
134 double *ic = (double *)s->iir[ch].cache[1]; \
135 const int nb_a = s->iir[ch].nb_ab[0]; \
136 const int nb_b = s->iir[ch].nb_ab[1]; \
137 const double *a = s->iir[ch].ab[0]; \
138 const double *b = s->iir[ch].ab[1]; \
139 const double g = s->iir[ch].g; \
140 int *clippings = &s->iir[ch].clippings; \
141 type *dst = (type *)out->extended_data[ch]; \
144 for (n = 0; n < in->nb_samples; n++) { \
145 double sample = 0.; \
148 memmove(&ic[1], &ic[0], (nb_b - 1) * sizeof(*ic)); \
149 memmove(&oc[1], &oc[0], (nb_a - 1) * sizeof(*oc)); \
150 ic[0] = src[n] * ig; \
151 for (x = 0; x < nb_b; x++) \
152 sample += b[x] * ic[x]; \
154 for (x = 1; x < nb_a; x++) \
155 sample -= a[x] * oc[x]; \
159 sample = sample * mix + ic[0] * (1. - mix); \
160 if (need_clipping && sample < min) { \
163 } else if (need_clipping && sample > max) { \
174 IIR_CH(s16p, int16_t, INT16_MIN, INT16_MAX, 1)
176 IIR_CH(fltp,
float, -1., 1., 0)
177 IIR_CH(dblp,
double, -1., 1., 0)
179 #define SERIAL_IIR_CH(name, type, min, max, need_clipping) \
180 static int iir_ch_serial_## name(AVFilterContext *ctx, void *arg, \
181 int ch, int nb_jobs) \
183 AudioIIRContext *s = ctx->priv; \
184 const double ig = s->dry_gain; \
185 const double og = s->wet_gain; \
186 const double mix = s->mix; \
187 const double imix = 1. - mix; \
188 ThreadData *td = arg; \
189 AVFrame *in = td->in, *out = td->out; \
190 const type *src = (const type *)in->extended_data[ch]; \
191 type *dst = (type *)out->extended_data[ch]; \
192 IIRChannel *iir = &s->iir[ch]; \
193 const double g = iir->g; \
194 int *clippings = &iir->clippings; \
195 int nb_biquads = (FFMAX(iir->nb_ab[0], iir->nb_ab[1]) + 1) / 2; \
198 for (i = nb_biquads - 1; i >= 0; i--) { \
199 const double a1 = -iir->biquads[i].a[1]; \
200 const double a2 = -iir->biquads[i].a[2]; \
201 const double b0 = iir->biquads[i].b[0]; \
202 const double b1 = iir->biquads[i].b[1]; \
203 const double b2 = iir->biquads[i].b[2]; \
204 double w1 = iir->biquads[i].w1; \
205 double w2 = iir->biquads[i].w2; \
207 for (n = 0; n < in->nb_samples; n++) { \
208 double i0 = ig * (i ? dst[n] : src[n]); \
209 double o0 = i0 * b0 + w1; \
211 w1 = b1 * i0 + w2 + a1 * o0; \
212 w2 = b2 * i0 + a2 * o0; \
215 o0 = o0 * mix + imix * i0; \
216 if (need_clipping && o0 < min) { \
219 } else if (need_clipping && o0 > max) { \
226 iir->biquads[i].w1 = w1; \
227 iir->biquads[i].w2 = w2; \
238 #define PARALLEL_IIR_CH(name, type, min, max, need_clipping) \
239 static int iir_ch_parallel_## name(AVFilterContext *ctx, void *arg, \
240 int ch, int nb_jobs) \
242 AudioIIRContext *s = ctx->priv; \
243 const double ig = s->dry_gain; \
244 const double og = s->wet_gain; \
245 const double mix = s->mix; \
246 const double imix = 1. - mix; \
247 ThreadData *td = arg; \
248 AVFrame *in = td->in, *out = td->out; \
249 const type *src = (const type *)in->extended_data[ch]; \
250 type *dst = (type *)out->extended_data[ch]; \
251 IIRChannel *iir = &s->iir[ch]; \
252 const double g = iir->g; \
253 const double fir = iir->fir; \
254 int *clippings = &iir->clippings; \
255 int nb_biquads = (FFMAX(iir->nb_ab[0], iir->nb_ab[1]) + 1) / 2; \
258 for (i = 0; i < nb_biquads; i++) { \
259 const double a1 = -iir->biquads[i].a[1]; \
260 const double a2 = -iir->biquads[i].a[2]; \
261 const double b1 = iir->biquads[i].b[1]; \
262 const double b2 = iir->biquads[i].b[2]; \
263 double w1 = iir->biquads[i].w1; \
264 double w2 = iir->biquads[i].w2; \
266 for (n = 0; n < in->nb_samples; n++) { \
267 double i0 = ig * src[n]; \
270 w1 = b1 * i0 + w2 + a1 * o0; \
271 w2 = b2 * i0 + a2 * o0; \
275 if (need_clipping && o0 < min) { \
278 } else if (need_clipping && o0 > max) { \
285 iir->biquads[i].w1 = w1; \
286 iir->biquads[i].w2 = w2; \
289 for (n = 0; n < in->nb_samples; n++) { \
290 dst[n] += fir * src[n]; \
291 dst[n] = dst[n] * mix + imix * src[n]; \
302 #define LATTICE_IIR_CH(name, type, min, max, need_clipping) \
303 static int iir_ch_lattice_## name(AVFilterContext *ctx, void *arg, \
304 int ch, int nb_jobs) \
306 AudioIIRContext *s = ctx->priv; \
307 const double ig = s->dry_gain; \
308 const double og = s->wet_gain; \
309 const double mix = s->mix; \
310 ThreadData *td = arg; \
311 AVFrame *in = td->in, *out = td->out; \
312 const type *src = (const type *)in->extended_data[ch]; \
313 double n0, n1, p0, *x = (double *)s->iir[ch].cache[0]; \
314 const int nb_stages = s->iir[ch].nb_ab[1]; \
315 const double *v = s->iir[ch].ab[0]; \
316 const double *k = s->iir[ch].ab[1]; \
317 const double g = s->iir[ch].g; \
318 int *clippings = &s->iir[ch].clippings; \
319 type *dst = (type *)out->extended_data[ch]; \
322 for (n = 0; n < in->nb_samples; n++) { \
323 const double in = src[n] * ig; \
327 for (int i = nb_stages - 1; i >= 0; i--) { \
328 n0 = n1 - k[i] * x[i]; \
329 p0 = n0 * k[i] + x[i]; \
330 out += p0 * v[i+1]; \
336 memmove(&x[1], &x[0], nb_stages * sizeof(*x)); \
339 out = out * mix + in * (1. - mix); \
340 if (need_clipping && out < min) { \
343 } else if (need_clipping && out > max) { \
367 for (p = item_str; *p && *p !=
'|'; p++) {
376 char *p, *
arg, *old_str, *prev_arg =
NULL, *saveptr =
NULL;
382 for (
i = 0;
i < nb_items;
i++) {
408 char *p, *
arg, *old_str, *saveptr =
NULL;
414 for (
i = 0;
i < nb_items;
i++) {
433 char *p, *
arg, *old_str, *saveptr =
NULL;
439 for (
i = 0;
i < nb_items;
i++) {
456 static const char *
const format[] = {
"%lf",
"%lf %lfi",
"%lf %lfr",
"%lf %lfd",
"%lf %lfi" };
461 char *p, *
arg, *old_str, *prev_arg =
NULL, *saveptr =
NULL;
483 if (!iir->
ab[ab] || !iir->
cache[ab]) {
505 static void cmul(
double re,
double im,
double re2,
double im2,
double *
RE,
double *
IM)
507 *
RE =
re * re2 -
im * im2;
508 *
IM =
re * im2 + re2 *
im;
515 for (
int i = 1;
i <= n;
i++) {
516 for (
int j = n -
i; j < n; j++) {
519 cmul(coefs[2 * (j + 1)], coefs[2 * (j + 1) + 1],
520 pz[2 * (
i - 1)], pz[2 * (
i - 1) + 1], &
re, &
im);
523 coefs[2 * j + 1] -=
im;
527 for (
int i = 0;
i < n + 1;
i++) {
528 if (
fabs(coefs[2 *
i + 1]) > FLT_EPSILON) {
529 av_log(
ctx,
AV_LOG_ERROR,
"coefs: %f of z^%d is not real; poles/zeros are not complex conjugates.\n",
530 coefs[2 *
i + 1],
i);
547 for (
int i = 0;
i < iir->
nb_ab[1];
i++) {
548 sum_den += iir->
ab[1][
i];
551 if (sum_den > 1e-6) {
552 double factor, sum_num = 0.;
554 for (
int i = 0;
i < iir->
nb_ab[0];
i++) {
555 sum_num += iir->
ab[0][
i];
558 factor = sum_num / sum_den;
560 for (
int i = 0;
i < iir->
nb_ab[1];
i++) {
569 int ch,
i, j,
ret = 0;
577 if (!topc || !botc) {
592 for (j = 0,
i = iir->
nb_ab[1];
i >= 0; j++,
i--) {
593 iir->
ab[1][j] = topc[2 *
i];
597 for (j = 0,
i = iir->
nb_ab[0];
i >= 0; j++,
i--) {
598 iir->
ab[0][j] = botc[2 *
i];
622 int current_biquad = 0;
628 while (nb_biquads--) {
629 Pair outmost_pole = { -1, -1 };
630 Pair nearest_zero = { -1, -1 };
631 double zeros[4] = { 0 };
632 double poles[4] = { 0 };
635 double min_distance = DBL_MAX;
640 for (
i = 0;
i < iir->
nb_ab[0];
i++) {
645 mag =
hypot(iir->
ab[0][2 *
i], iir->
ab[0][2 *
i + 1]);
653 for (
i = 0;
i < iir->
nb_ab[0];
i++) {
657 if (iir->
ab[0][2 *
i ] == iir->
ab[0][2 * outmost_pole.
a ] &&
658 iir->
ab[0][2 *
i + 1] == -iir->
ab[0][2 * outmost_pole.
a + 1]) {
666 if (outmost_pole.
a < 0 || outmost_pole.
b < 0)
669 for (
i = 0;
i < iir->
nb_ab[1];
i++) {
675 iir->
ab[0][2 * outmost_pole.
a + 1] - iir->
ab[1][2 *
i + 1]);
683 for (
i = 0;
i < iir->
nb_ab[1];
i++) {
687 if (iir->
ab[1][2 *
i ] == iir->
ab[1][2 * nearest_zero.
a ] &&
688 iir->
ab[1][2 *
i + 1] == -iir->
ab[1][2 * nearest_zero.
a + 1]) {
696 if (nearest_zero.
a < 0 || nearest_zero.
b < 0)
699 poles[0] = iir->
ab[0][2 * outmost_pole.
a ];
700 poles[1] = iir->
ab[0][2 * outmost_pole.
a + 1];
702 zeros[0] = iir->
ab[1][2 * nearest_zero.
a ];
703 zeros[1] = iir->
ab[1][2 * nearest_zero.
a + 1];
705 if (nearest_zero.
a == nearest_zero.
b && outmost_pole.
a == outmost_pole.
b) {
712 poles[2] = iir->
ab[0][2 * outmost_pole.
b ];
713 poles[3] = iir->
ab[0][2 * outmost_pole.
b + 1];
715 zeros[2] = iir->
ab[1][2 * nearest_zero.
b ];
716 zeros[3] = iir->
ab[1][2 * nearest_zero.
b + 1];
727 iir->
ab[0][2 * outmost_pole.
a] = iir->
ab[0][2 * outmost_pole.
a + 1] =
NAN;
728 iir->
ab[0][2 * outmost_pole.
b] = iir->
ab[0][2 * outmost_pole.
b + 1] =
NAN;
729 iir->
ab[1][2 * nearest_zero.
a] = iir->
ab[1][2 * nearest_zero.
a + 1] =
NAN;
730 iir->
ab[1][2 * nearest_zero.
b] = iir->
ab[1][2 * nearest_zero.
b + 1] =
NAN;
732 iir->
biquads[current_biquad].
a[0] = 1.;
733 iir->
biquads[current_biquad].
a[1] =
a[2] /
a[4];
734 iir->
biquads[current_biquad].
a[2] =
a[0] /
a[4];
735 iir->
biquads[current_biquad].
b[0] =
b[4] /
a[4];
736 iir->
biquads[current_biquad].
b[1] =
b[2] /
a[4];
737 iir->
biquads[current_biquad].
b[2] =
b[0] /
a[4];
742 iir->
biquads[current_biquad].
b[2]) > 1e-6) {
745 iir->
biquads[current_biquad].
a[2]) /
746 (iir->
biquads[current_biquad].
b[0] +
757 iir->
biquads[current_biquad].
b[0] *= (current_biquad ? 1.0 : iir->
g);
758 iir->
biquads[current_biquad].
b[1] *= (current_biquad ? 1.0 : iir->
g);
759 iir->
biquads[current_biquad].
b[2] *= (current_biquad ? 1.0 : iir->
g);
777 double b0,
double b1,
double b2,
778 double a1,
double a2)
780 double w1 = 0., w2 = 0.;
785 for (
int n = 0; n < length; n++) {
786 double out,
in = x[n];
794 static void solve(
double *matrix,
double *vector,
int n,
double *y,
double *x,
double *lu)
798 for (
int i = 0;
i < n;
i++) {
799 for (
int j =
i; j < n; j++) {
801 for (
int k = 0; k <
i; k++)
802 sum += lu[
i * n + k] * lu[k * n + j];
803 lu[
i * n + j] = matrix[j * n +
i] - sum;
805 for (
int j =
i + 1; j < n; j++) {
807 for (
int k = 0; k <
i; k++)
808 sum += lu[j * n + k] * lu[k * n +
i];
809 lu[j * n +
i] = (1. / lu[
i * n +
i]) * (matrix[
i * n + j] - sum);
813 for (
int i = 0;
i < n;
i++) {
815 for (
int k = 0; k <
i; k++)
816 sum += lu[
i * n + k] * y[k];
817 y[
i] = vector[
i] - sum;
820 for (
int i = n - 1;
i >= 0;
i--) {
822 for (
int k =
i + 1; k < n; k++)
823 sum += lu[
i * n + k] * x[k];
824 x[
i] = (1 / lu[
i * n +
i]) * (y[
i] - sum);
833 for (
int ch = 0; ch <
channels; ch++) {
836 int length = nb_biquads * 2 + 1;
837 double *impulse =
av_calloc(length,
sizeof(*impulse));
838 double *y =
av_calloc(length,
sizeof(*y));
839 double *resp =
av_calloc(length,
sizeof(*resp));
840 double *
M =
av_calloc((length - 1) * 2 * nb_biquads,
sizeof(*
M));
841 double *
W =
av_calloc((length - 1) * 2 * nb_biquads,
sizeof(*
W));
843 if (!impulse || !y || !resp || !
M) {
854 for (
int n = 0; n < nb_biquads; n++) {
862 for (
int n = 0; n < nb_biquads; n++) {
868 memcpy(
M + n * 2 * (length - 1), resp,
sizeof(*resp) * (length - 1));
869 memcpy(
M + n * 2 * (length - 1) + length, resp,
sizeof(*resp) * (length - 2));
870 memset(resp, 0, length *
sizeof(*resp));
873 solve(
M, &y[1], length - 1, &impulse[1], resp,
W);
877 for (
int n = 0; n < nb_biquads; n++) {
881 biquad->b[1] = resp[n * 2 + 0];
882 biquad->b[2] = resp[n * 2 + 1];
907 for (n = 0; n < iir->
nb_ab[0]; n++) {
908 double r = iir->
ab[0][2*n];
909 double angle = iir->
ab[0][2*n+1];
911 iir->
ab[0][2*n] =
r * cos(angle);
912 iir->
ab[0][2*n+1] =
r * sin(angle);
915 for (n = 0; n < iir->
nb_ab[1]; n++) {
916 double r = iir->
ab[1][2*n];
917 double angle = iir->
ab[1][2*n+1];
919 iir->
ab[1][2*n] =
r * cos(angle);
920 iir->
ab[1][2*n+1] =
r * sin(angle);
934 for (n = 0; n < iir->
nb_ab[0]; n++) {
935 double sr = iir->
ab[0][2*n];
936 double si = iir->
ab[0][2*n+1];
938 iir->
ab[0][2*n] =
exp(sr) * cos(si);
939 iir->
ab[0][2*n+1] =
exp(sr) * sin(si);
942 for (n = 0; n < iir->
nb_ab[1]; n++) {
943 double sr = iir->
ab[1][2*n];
944 double si = iir->
ab[1][2*n+1];
946 iir->
ab[1][2*n] =
exp(sr) * cos(si);
947 iir->
ab[1][2*n+1] =
exp(sr) * sin(si);
963 for (
int i = 0;
i <=
N;
i++) {
969 ((k & 1) ? -1. : 1.);
972 z +=
a[
i] * pow(2.,
i) *
acc;
988 if (!temp0 || !temp1)
991 memcpy(temp0, iir->
ab[0], iir->
nb_ab[0] *
sizeof(*temp0));
992 memcpy(temp1, iir->
ab[1], iir->
nb_ab[1] *
sizeof(*temp1));
994 for (
int n = 0; n < iir->
nb_ab[0]; n++)
997 for (
int n = 0; n < iir->
nb_ab[1]; n++)
1011 for (ch = 0; ch <
channels; ch++) {
1015 for (n = 0; n < iir->
nb_ab[0]; n++) {
1016 double r = iir->
ab[0][2*n];
1017 double angle =
M_PI*iir->
ab[0][2*n+1]/180.;
1019 iir->
ab[0][2*n] =
r * cos(angle);
1020 iir->
ab[0][2*n+1] =
r * sin(angle);
1023 for (n = 0; n < iir->
nb_ab[1]; n++) {
1024 double r = iir->
ab[1][2*n];
1025 double angle =
M_PI*iir->
ab[1][2*n+1]/180.;
1027 iir->
ab[1][2*n] =
r * cos(angle);
1028 iir->
ab[1][2*n+1] =
r * sin(angle);
1038 for (ch = 0; ch <
channels; ch++) {
1041 for (
int n = 0; n < iir->
nb_ab[0]; n++) {
1042 double pr =
hypot(iir->
ab[0][2*n], iir->
ab[0][2*n+1]);
1060 for (
i = 0; txt[
i];
i++) {
1064 for (char_y = 0; char_y < font_height; char_y++) {
1066 if (font[txt[
i] * font_height + char_y] &
mask)
1077 int dx =
FFABS(x1-x0);
1078 int dy =
FFABS(y1-y0), sy = y0 < y1 ? 1 : -1;
1079 int err = (dx>dy ? dx : -dy) / 2, e2;
1084 if (x0 == x1 && y0 == y1)
1101 static double distance(
double x0,
double x1,
double y0,
double y1)
1103 return hypot(x0 - x1, y0 - y1);
1107 const double *
b,
const double *
a,
1108 int nb_b,
int nb_a,
double *magnitude,
double *phase)
1110 double realz, realp;
1111 double imagz, imagp;
1116 realz = 0., realp = 0.;
1117 imagz = 0., imagp = 0.;
1118 for (
int x = 0; x < nb_a; x++) {
1119 realz += cos(-x *
w) *
a[x];
1120 imagz += sin(-x *
w) *
a[x];
1123 for (
int x = 0; x < nb_b; x++) {
1124 realp += cos(-x *
w) *
b[x];
1125 imagp += sin(-x *
w) *
b[x];
1128 div = realp * realp + imagp * imagp;
1129 real = (realz * realp + imagz * imagp) / div;
1130 imag = (imagz * realp - imagp * realz) / div;
1132 *magnitude =
hypot(real, imag);
1133 *phase = atan2(imag, real);
1135 double p = 1., z = 1.;
1138 for (
int x = 0; x < nb_a; x++) {
1140 acc += atan2(sin(
w) -
a[2 * x + 1], cos(
w) -
a[2 * x]);
1143 for (
int x = 0; x < nb_b; x++) {
1145 acc -= atan2(sin(
w) -
b[2 * x + 1], cos(
w) -
b[2 * x]);
1156 double *mag, *phase, *
temp, *delay,
min = DBL_MAX,
max = -DBL_MAX;
1157 double min_delay = DBL_MAX, max_delay = -DBL_MAX, min_phase, max_phase;
1158 int prev_ymag = -1, prev_yphase = -1, prev_ydelay = -1;
1162 memset(
out->data[0], 0,
s->h *
out->linesize[0]);
1168 if (!mag || !phase || !delay || !
temp)
1171 ch =
av_clip(
s->ir_channel, 0,
s->channels - 1);
1172 for (
i = 0;
i <
s->w;
i++) {
1173 const double *
b =
s->iir[ch].ab[0];
1174 const double *
a =
s->iir[ch].ab[1];
1175 const int nb_b =
s->iir[ch].nb_ab[0];
1176 const int nb_a =
s->iir[ch].nb_ab[1];
1177 double w =
i *
M_PI / (
s->w - 1);
1182 mag[
i] =
s->iir[ch].g * m;
1189 for (
i = 0;
i <
s->w - 1;
i++) {
1190 double d = phase[
i] - phase[
i + 1];
1194 min_phase = phase[0];
1195 max_phase = phase[0];
1196 for (
i = 1;
i <
s->w;
i++) {
1199 min_phase =
fmin(min_phase, phase[
i]);
1200 max_phase =
fmax(max_phase, phase[
i]);
1203 for (
i = 0;
i <
s->w - 1;
i++) {
1206 delay[
i + 1] = -(phase[
i] - phase[
i + 1]) / div;
1207 min_delay =
fmin(min_delay, delay[
i + 1]);
1208 max_delay =
fmax(max_delay, delay[
i + 1]);
1210 delay[0] = delay[1];
1212 for (
i = 0;
i <
s->w;
i++) {
1213 int ymag = mag[
i] /
max * (
s->h - 1);
1214 int ydelay = (delay[
i] - min_delay) / (max_delay - min_delay) * (
s->h - 1);
1215 int yphase = (phase[
i] - min_phase) / (max_phase - min_phase) * (
s->h - 1);
1217 ymag =
s->h - 1 -
av_clip(ymag, 0,
s->h - 1);
1218 yphase =
s->h - 1 -
av_clip(yphase, 0,
s->h - 1);
1219 ydelay =
s->h - 1 -
av_clip(ydelay, 0,
s->h - 1);
1223 if (prev_yphase < 0)
1224 prev_yphase = yphase;
1225 if (prev_ydelay < 0)
1226 prev_ydelay = ydelay;
1233 prev_yphase = yphase;
1234 prev_ydelay = ydelay;
1237 if (
s->w > 400 &&
s->h > 100) {
1238 drawtext(
out, 2, 2,
"Max Magnitude:", 0xDDDDDDDD);
1242 drawtext(
out, 2, 12,
"Min Magnitude:", 0xDDDDDDDD);
1247 snprintf(text,
sizeof(text),
"%.2f", max_phase);
1251 snprintf(text,
sizeof(text),
"%.2f", min_phase);
1255 snprintf(text,
sizeof(text),
"%.2f", max_delay);
1259 snprintf(text,
sizeof(text),
"%.2f", min_delay);
1277 s->channels =
inlink->channels;
1294 if (
s->format == -1) {
1297 }
else if (
s->format == 2) {
1299 }
else if (
s->format == 3) {
1301 }
else if (
s->format == 4) {
1304 if (
s->format > 0) {
1318 av_log(
ctx,
AV_LOG_WARNING,
"transfer function coefficients format is not recommended for too high number of zeros/poles.\n");
1320 if (
s->format > 0 &&
s->process == 0) {
1326 }
else if (
s->format == -2 &&
s->process > 0) {
1329 }
else if (
s->format <= 0 &&
s->process == 1) {
1332 }
else if (
s->format <= 0 &&
s->process == 2) {
1335 }
else if (
s->format > 0 &&
s->process == 1) {
1339 }
else if (
s->format > 0 &&
s->process == 2) {
1340 if (
s->precision > 1)
1350 for (ch = 0;
s->format == -2 && ch <
inlink->channels; ch++) {
1354 av_log(
ctx,
AV_LOG_ERROR,
"Number of ladder coefficients must be one more than number of reflection coefficients.\n");
1359 for (ch = 0;
s->format == 0 && ch <
inlink->channels; ch++) {
1362 for (
i = 1;
i < iir->
nb_ab[0];
i++) {
1363 iir->
ab[0][
i] /= iir->
ab[0][0];
1366 iir->
ab[0][0] = 1.0;
1367 for (
i = 0;
i < iir->
nb_ab[1];
i++) {
1368 iir->
ab[1][
i] *= iir->
g;
1374 switch (
inlink->format) {
1375 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;
1376 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;
1377 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;
1378 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;
1381 if (
s->format == -2) {
1382 switch (
inlink->format) {
1417 for (ch = 0; ch < outlink->
channels; ch++) {
1418 if (
s->iir[ch].clippings > 0)
1420 ch,
s->iir[ch].clippings);
1421 s->iir[ch].clippings = 0;
1429 int64_t old_pts =
s->video->pts;
1432 if (new_pts > old_pts) {
1435 s->video->pts = new_pts;
1468 if (!
s->a_str || !
s->b_str || !
s->g_str) {
1473 switch (
s->precision) {
1493 .
name =
"filter_response",
1512 for (ch = 0; ch <
s->channels; ch++) {
1535 #define OFFSET(x) offsetof(AudioIIRContext, x)
1536 #define AF AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
1537 #define VF AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
1540 {
"zeros",
"set B/numerator/zeros/reflection coefficients",
OFFSET(b_str),
AV_OPT_TYPE_STRING, {.str=
"1+0i 1-0i"}, 0, 0,
AF },
1551 {
"sf",
"analog transfer function", 0,
AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0,
AF,
"format" },
1552 {
"tf",
"digital transfer function", 0,
AV_OPT_TYPE_CONST, {.i64=0}, 0, 0,
AF,
"format" },
1554 {
"pr",
"Z-plane zeros/poles (polar radians)", 0,
AV_OPT_TYPE_CONST, {.i64=2}, 0, 0,
AF,
"format" },
1555 {
"pd",
"Z-plane zeros/poles (polar degrees)", 0,
AV_OPT_TYPE_CONST, {.i64=3}, 0, 0,
AF,
"format" },
1562 {
"precision",
"set filtering precision",
OFFSET(precision),
AV_OPT_TYPE_INT, {.i64=0}, 0, 3,
AF,
"precision" },
1564 {
"dbl",
"double-precision floating-point", 0,
AV_OPT_TYPE_CONST, {.i64=0}, 0, 0,
AF,
"precision" },
1565 {
"flt",
"single-precision floating-point", 0,
AV_OPT_TYPE_CONST, {.i64=1}, 0, 0,
AF,
"precision" },
1572 {
"channel",
"set IR channel to display frequency response",
OFFSET(ir_channel),
AV_OPT_TYPE_INT, {.i64=0}, 0, 1024,
VF },
1582 .description =
NULL_IF_CONFIG_SMALL(
"Apply Infinite Impulse Response filter with supplied coefficients."),
1584 .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
A list of supported channel layouts.
#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[]
enum MovChannelLayoutTag * layouts
@ 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)
@ 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)
AVFormatInternal * internal
An opaque field for libavformat internal usage.
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 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
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) #define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac) { } void ff_audio_convert_free(AudioConvert **ac) { if(! *ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);} AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map) { AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method !=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2) { ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc) { av_free(ac);return NULL;} return ac;} in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar) { ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar ? ac->channels :1;} else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;} int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in) { int use_generic=1;int len=in->nb_samples;int p;if(ac->dc) { av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
enum AVSampleFormat sample_format
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.
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)
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
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 int ff_insert_outpad(AVFilterContext *f, unsigned index, AVFilterPad *p)
Insert a new output pad for the filter.
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)
const uint8_t avpriv_cga_font[2048]
#define flags(name, subs,...)
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
static double b0(void *priv, double x, double y)
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)