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);
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 enum AVSampleFormat sample_fmts[]
#define LATTICE_IIR_CH(name, type, min, max, need_clipping)
#define PARALLEL_IIR_CH(name, type, min, max, need_clipping)
static void check_stability(AVFilterContext *ctx, int channels)
static void drawtext(AVFrame *pic, int x, int y, const char *txt, uint32_t color)
static int read_zp_coefficients(AVFilterContext *ctx, char *item_str, int nb_items, double *dst, const char *format)
static void convert_sf2tf(AVFilterContext *ctx, int channels)
static int config_video(AVFilterLink *outlink)
static int read_tf_coefficients(AVFilterContext *ctx, char *item_str, int nb_items, double *dst)
static double distance(double x0, double x1, double y0, double y1)
static void draw_response(AVFilterContext *ctx, AVFrame *out, int sample_rate)
static void convert_pr2zp(AVFilterContext *ctx, int channels)
static void convert_pd2zp(AVFilterContext *ctx, int channels)
static const AVOption aiir_options[]
static int expand(AVFilterContext *ctx, double *pz, int n, double *coefs)
static int decompose_zp2biquads(AVFilterContext *ctx, int channels)
static int query_formats(AVFilterContext *ctx)
static void draw_line(AVFrame *out, int x0, int y0, int x1, int y1, uint32_t color)
static double fact(double i)
#define IIR_CH(name, type, min, max, need_clipping)
static int read_channels(AVFilterContext *ctx, int channels, uint8_t *item_str, int ab)
static void normalize_coeffs(AVFilterContext *ctx, int ch)
static const AVFilterPad inputs[]
static int read_gains(AVFilterContext *ctx, char *item_str, int nb_items)
static const char *const format[]
#define SERIAL_IIR_CH(name, type, min, max, need_clipping)
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
static void convert_sp2zp(AVFilterContext *ctx, int channels)
AVFILTER_DEFINE_CLASS(aiir)
static int convert_serial2parallel(AVFilterContext *ctx, int channels)
static int convert_zp2tf(AVFilterContext *ctx, int channels)
static void biquad_process(double *x, double *y, int length, double b0, double b1, double b2, double a1, double a2)
static void count_coefficients(char *item_str, int *nb_items)
static double coef_sf2zf(double *a, int N, int n)
static av_cold int init(AVFilterContext *ctx)
static av_cold void uninit(AVFilterContext *ctx)
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)
static int config_output(AVFilterLink *outlink)
static void solve(double *matrix, double *vector, int n, double *y, double *x, double *lu)
AVFrame * ff_get_audio_buffer(AVFilterLink *link, int nb_samples)
Request an audio samples buffer with a specific set of permissions.
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
simple assert() macros that are a bit more flexible than ISO C assert().
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Main libavfilter public API header.
#define flags(name, subs,...)
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
static __device__ float ceil(float a)
static __device__ float fabs(float a)
double fmin(double, double)
double fmax(double, double)
channel
Use these values when setting the channel map with ebur128_set_channel().
@ AV_OPT_TYPE_IMAGE_SIZE
offset must point to two consecutive integers
@ AV_OPT_TYPE_VIDEO_RATE
offset must point to AVRational
#define AVFILTER_FLAG_DYNAMIC_OUTPUTS
The number of the filter outputs is not determined just by AVFilter.outputs.
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
int av_frame_is_writable(AVFrame *frame)
Check if the frame data is writable.
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
#define AV_LOG_WARNING
Something somehow does not look correct.
#define AV_LOG_VERBOSE
Detailed information.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
char * av_strdup(const char *s)
Duplicate a string.
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
AVSampleFormat
Audio sample formats.
@ AV_SAMPLE_FMT_FLTP
float, planar
@ AV_SAMPLE_FMT_S16P
signed 16 bits, planar
@ AV_SAMPLE_FMT_S32P
signed 32 bits, planar
@ AV_SAMPLE_FMT_DBLP
double, planar
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().
int av_sscanf(const char *string, const char *format,...)
See libc sscanf manual for more information.
static int mix(int c0, int c1)
static int ff_insert_outpad(AVFilterContext *f, unsigned index, AVFilterPad *p)
Insert a new output pad for the filter.
common internal API header
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
static enum AVPixelFormat pix_fmts[]
static av_const double hypot(double x, double y)
static const uint16_t mask[17]
enum MovChannelLayoutTag * layouts
AVPixelFormat
Pixel format.
@ AV_PIX_FMT_RGB0
packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined
Describe the class of an AVClass context structure.
A list of supported channel layouts.
A link between two filters.
AVFilterFormatsConfig incfg
Lists of supported formats / etc.
int w
agreed upon image width
int h
agreed upon image height
int channels
Number of channels.
AVFilterContext * src
source filter
AVRational time_base
Define the time base used by the PTS of the frames/samples which will pass through this link.
int sample_rate
samples per second
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,...
AVFilterContext * dst
dest filter
int format
agreed upon media format
A filter pad used for either input or output.
const char * name
Pad name.
const char * name
Filter name.
AVFormatInternal * internal
An opaque field for libavformat internal usage.
This structure describes decoded (raw) audio or video data.
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Rational number (pair of numerator and denominator).
int(* iir_channel)(AVFilterContext *ctx, void *arg, int ch, int nb_jobs)
enum AVSampleFormat sample_format
Used for passing data between threads.
#define av_malloc_array(a, b)
static void process(NormalizeContext *s, AVFrame *in, AVFrame *out)
static const int factor[16]
static double b1(void *priv, double x, double y)
static double b2(void *priv, double x, double y)
static double b0(void *priv, double x, double y)
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
const uint8_t avpriv_cga_font[2048]
CGA/EGA/VGA ROM font data.