FFmpeg  4.3.6
af_aiir.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018 Paul B Mahol
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include <float.h>
22 
23 #include "libavutil/avassert.h"
24 #include "libavutil/avstring.h"
25 #include "libavutil/intreadwrite.h"
26 #include "libavutil/opt.h"
28 #include "audio.h"
29 #include "avfilter.h"
30 #include "internal.h"
31 
32 typedef struct ThreadData {
33  AVFrame *in, *out;
34 } ThreadData;
35 
36 typedef struct Pair {
37  int a, b;
38 } Pair;
39 
40 typedef struct BiquadContext {
41  double a[3];
42  double b[3];
43  double i1, i2;
44  double o1, o2;
46 
47 typedef struct IIRChannel {
48  int nb_ab[2];
49  double *ab[2];
50  double g;
51  double *cache[2];
53  int clippings;
54 } IIRChannel;
55 
56 typedef struct AudioIIRContext {
57  const AVClass *class;
58  char *a_str, *b_str, *g_str;
59  double dry_gain, wet_gain;
60  double mix;
61  int normalize;
62  int format;
63  int process;
64  int precision;
65  int response;
66  int w, h;
69 
71 
73  int channels;
74  enum AVSampleFormat sample_format;
75 
76  int (*iir_channel)(AVFilterContext *ctx, void *arg, int ch, int nb_jobs);
78 
80 {
81  AudioIIRContext *s = ctx->priv;
84  enum AVSampleFormat sample_fmts[] = {
87  };
88  static const enum AVPixelFormat pix_fmts[] = {
91  };
92  int ret;
93 
94  if (s->response) {
95  AVFilterLink *videolink = ctx->outputs[1];
96 
97  formats = ff_make_format_list(pix_fmts);
98  if ((ret = ff_formats_ref(formats, &videolink->in_formats)) < 0)
99  return ret;
100  }
101 
102  layouts = ff_all_channel_counts();
103  if (!layouts)
104  return AVERROR(ENOMEM);
105  ret = ff_set_common_channel_layouts(ctx, layouts);
106  if (ret < 0)
107  return ret;
108 
109  sample_fmts[0] = s->sample_format;
110  formats = ff_make_format_list(sample_fmts);
111  if (!formats)
112  return AVERROR(ENOMEM);
113  ret = ff_set_common_formats(ctx, formats);
114  if (ret < 0)
115  return ret;
116 
117  formats = ff_all_samplerates();
118  if (!formats)
119  return AVERROR(ENOMEM);
120  return ff_set_common_samplerates(ctx, formats);
121 }
122 
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) \
125 { \
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]; \
142  int n; \
143  \
144  for (n = 0; n < in->nb_samples; n++) { \
145  double sample = 0.; \
146  int x; \
147  \
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]; \
153  \
154  for (x = 1; x < nb_a; x++) \
155  sample -= a[x] * oc[x]; \
156  \
157  oc[0] = sample; \
158  sample *= og * g; \
159  sample = sample * mix + ic[0] * (1. - mix); \
160  if (need_clipping && sample < min) { \
161  (*clippings)++; \
162  dst[n] = min; \
163  } else if (need_clipping && sample > max) { \
164  (*clippings)++; \
165  dst[n] = max; \
166  } else { \
167  dst[n] = sample; \
168  } \
169  } \
170  \
171  return 0; \
172 }
173 
174 IIR_CH(s16p, int16_t, INT16_MIN, INT16_MAX, 1)
175 IIR_CH(s32p, int32_t, INT32_MIN, INT32_MAX, 1)
176 IIR_CH(fltp, float, -1., 1., 0)
177 IIR_CH(dblp, double, -1., 1., 0)
178 
179 #define SERIAL_IIR_CH(name, type, min, max, need_clipping) \
180 static int iir_ch_serial_## name(AVFilterContext *ctx, void *arg, int ch, int nb_jobs) \
181 { \
182  AudioIIRContext *s = ctx->priv; \
183  const double ig = s->dry_gain; \
184  const double og = s->wet_gain; \
185  const double mix = s->mix; \
186  ThreadData *td = arg; \
187  AVFrame *in = td->in, *out = td->out; \
188  const type *src = (const type *)in->extended_data[ch]; \
189  type *dst = (type *)out->extended_data[ch]; \
190  IIRChannel *iir = &s->iir[ch]; \
191  const double g = iir->g; \
192  int *clippings = &iir->clippings; \
193  int nb_biquads = (FFMAX(iir->nb_ab[0], iir->nb_ab[1]) + 1) / 2; \
194  int n, i; \
195  \
196  for (i = 0; i < nb_biquads; i++) { \
197  const double a1 = -iir->biquads[i].a[1]; \
198  const double a2 = -iir->biquads[i].a[2]; \
199  const double b0 = iir->biquads[i].b[0]; \
200  const double b1 = iir->biquads[i].b[1]; \
201  const double b2 = iir->biquads[i].b[2]; \
202  double i1 = iir->biquads[i].i1; \
203  double i2 = iir->biquads[i].i2; \
204  double o1 = iir->biquads[i].o1; \
205  double o2 = iir->biquads[i].o2; \
206  \
207  for (n = 0; n < in->nb_samples; n++) { \
208  double sample = ig * (i ? dst[n] : src[n]); \
209  double o0 = sample * b0 + i1 * b1 + i2 * b2 + o1 * a1 + o2 * a2; \
210  \
211  i2 = i1; \
212  i1 = src[n]; \
213  o2 = o1; \
214  o1 = o0; \
215  o0 *= og * g; \
216  \
217  o0 = o0 * mix + (1. - mix) * sample; \
218  if (need_clipping && o0 < min) { \
219  (*clippings)++; \
220  dst[n] = min; \
221  } else if (need_clipping && o0 > max) { \
222  (*clippings)++; \
223  dst[n] = max; \
224  } else { \
225  dst[n] = o0; \
226  } \
227  } \
228  iir->biquads[i].i1 = i1; \
229  iir->biquads[i].i2 = i2; \
230  iir->biquads[i].o1 = o1; \
231  iir->biquads[i].o2 = o2; \
232  } \
233  \
234  return 0; \
235 }
236 
237 SERIAL_IIR_CH(s16p, int16_t, INT16_MIN, INT16_MAX, 1)
238 SERIAL_IIR_CH(s32p, int32_t, INT32_MIN, INT32_MAX, 1)
239 SERIAL_IIR_CH(fltp, float, -1., 1., 0)
240 SERIAL_IIR_CH(dblp, double, -1., 1., 0)
241 
242 static void count_coefficients(char *item_str, int *nb_items)
243 {
244  char *p;
245 
246  if (!item_str)
247  return;
248 
249  *nb_items = 1;
250  for (p = item_str; *p && *p != '|'; p++) {
251  if (*p == ' ')
252  (*nb_items)++;
253  }
254 }
255 
256 static int read_gains(AVFilterContext *ctx, char *item_str, int nb_items)
257 {
258  AudioIIRContext *s = ctx->priv;
259  char *p, *arg, *old_str, *prev_arg = NULL, *saveptr = NULL;
260  int i;
261 
262  p = old_str = av_strdup(item_str);
263  if (!p)
264  return AVERROR(ENOMEM);
265  for (i = 0; i < nb_items; i++) {
266  if (!(arg = av_strtok(p, "|", &saveptr)))
267  arg = prev_arg;
268 
269  if (!arg) {
270  av_freep(&old_str);
271  return AVERROR(EINVAL);
272  }
273 
274  p = NULL;
275  if (sscanf(arg, "%lf", &s->iir[i].g) != 1) {
276  av_log(ctx, AV_LOG_ERROR, "Invalid gains supplied: %s\n", arg);
277  av_freep(&old_str);
278  return AVERROR(EINVAL);
279  }
280 
281  prev_arg = arg;
282  }
283 
284  av_freep(&old_str);
285 
286  return 0;
287 }
288 
289 static int read_tf_coefficients(AVFilterContext *ctx, char *item_str, int nb_items, double *dst)
290 {
291  char *p, *arg, *old_str, *saveptr = NULL;
292  int i;
293 
294  p = old_str = av_strdup(item_str);
295  if (!p)
296  return AVERROR(ENOMEM);
297  for (i = 0; i < nb_items; i++) {
298  if (!(arg = av_strtok(p, " ", &saveptr)))
299  break;
300 
301  p = NULL;
302  if (sscanf(arg, "%lf", &dst[i]) != 1) {
303  av_log(ctx, AV_LOG_ERROR, "Invalid coefficients supplied: %s\n", arg);
304  av_freep(&old_str);
305  return AVERROR(EINVAL);
306  }
307  }
308 
309  av_freep(&old_str);
310 
311  return 0;
312 }
313 
314 static int read_zp_coefficients(AVFilterContext *ctx, char *item_str, int nb_items, double *dst, const char *format)
315 {
316  char *p, *arg, *old_str, *saveptr = NULL;
317  int i;
318 
319  p = old_str = av_strdup(item_str);
320  if (!p)
321  return AVERROR(ENOMEM);
322  for (i = 0; i < nb_items; i++) {
323  if (!(arg = av_strtok(p, " ", &saveptr)))
324  break;
325 
326  p = NULL;
327  if (sscanf(arg, format, &dst[i*2], &dst[i*2+1]) != 2) {
328  av_log(ctx, AV_LOG_ERROR, "Invalid coefficients supplied: %s\n", arg);
329  av_freep(&old_str);
330  return AVERROR(EINVAL);
331  }
332  }
333 
334  av_freep(&old_str);
335 
336  return 0;
337 }
338 
339 static const char *format[] = { "%lf", "%lf %lfi", "%lf %lfr", "%lf %lfd", "%lf %lfi" };
340 
341 static int read_channels(AVFilterContext *ctx, int channels, uint8_t *item_str, int ab)
342 {
343  AudioIIRContext *s = ctx->priv;
344  char *p, *arg, *old_str, *prev_arg = NULL, *saveptr = NULL;
345  int i, ret;
346 
347  p = old_str = av_strdup(item_str);
348  if (!p)
349  return AVERROR(ENOMEM);
350  for (i = 0; i < channels; i++) {
351  IIRChannel *iir = &s->iir[i];
352 
353  if (!(arg = av_strtok(p, "|", &saveptr)))
354  arg = prev_arg;
355 
356  if (!arg) {
357  av_freep(&old_str);
358  return AVERROR(EINVAL);
359  }
360 
361  count_coefficients(arg, &iir->nb_ab[ab]);
362 
363  p = NULL;
364  iir->cache[ab] = av_calloc(iir->nb_ab[ab] + 1, sizeof(double));
365  iir->ab[ab] = av_calloc(iir->nb_ab[ab] * (!!s->format + 1), sizeof(double));
366  if (!iir->ab[ab] || !iir->cache[ab]) {
367  av_freep(&old_str);
368  return AVERROR(ENOMEM);
369  }
370 
371  if (s->format) {
372  ret = read_zp_coefficients(ctx, arg, iir->nb_ab[ab], iir->ab[ab], format[s->format]);
373  } else {
374  ret = read_tf_coefficients(ctx, arg, iir->nb_ab[ab], iir->ab[ab]);
375  }
376  if (ret < 0) {
377  av_freep(&old_str);
378  return ret;
379  }
380  prev_arg = arg;
381  }
382 
383  av_freep(&old_str);
384 
385  return 0;
386 }
387 
388 static void cmul(double re, double im, double re2, double im2, double *RE, double *IM)
389 {
390  *RE = re * re2 - im * im2;
391  *IM = re * im2 + re2 * im;
392 }
393 
394 static int expand(AVFilterContext *ctx, double *pz, int n, double *coefs)
395 {
396  coefs[2 * n] = 1.0;
397 
398  for (int i = 1; i <= n; i++) {
399  for (int j = n - i; j < n; j++) {
400  double re, im;
401 
402  cmul(coefs[2 * (j + 1)], coefs[2 * (j + 1) + 1],
403  pz[2 * (i - 1)], pz[2 * (i - 1) + 1], &re, &im);
404 
405  coefs[2 * j] -= re;
406  coefs[2 * j + 1] -= im;
407  }
408  }
409 
410  for (int i = 0; i < n + 1; i++) {
411  if (fabs(coefs[2 * i + 1]) > FLT_EPSILON) {
412  av_log(ctx, AV_LOG_ERROR, "coefs: %f of z^%d is not real; poles/zeros are not complex conjugates.\n",
413  coefs[2 * i + 1], i);
414  return AVERROR(EINVAL);
415  }
416  }
417 
418  return 0;
419 }
420 
421 static void normalize_coeffs(AVFilterContext *ctx, int ch)
422 {
423  AudioIIRContext *s = ctx->priv;
424  IIRChannel *iir = &s->iir[ch];
425  double sum_den = 0.;
426 
427  if (!s->normalize)
428  return;
429 
430  for (int i = 0; i < iir->nb_ab[1]; i++) {
431  sum_den += iir->ab[1][i];
432  }
433 
434  if (sum_den > 1e-6) {
435  double factor, sum_num = 0.;
436 
437  for (int i = 0; i < iir->nb_ab[0]; i++) {
438  sum_num += iir->ab[0][i];
439  }
440 
441  factor = sum_num / sum_den;
442 
443  for (int i = 0; i < iir->nb_ab[1]; i++) {
444  iir->ab[1][i] *= factor;
445  }
446  }
447 }
448 
450 {
451  AudioIIRContext *s = ctx->priv;
452  int ch, i, j, ret = 0;
453 
454  for (ch = 0; ch < channels; ch++) {
455  IIRChannel *iir = &s->iir[ch];
456  double *topc, *botc;
457 
458  topc = av_calloc((iir->nb_ab[1] + 1) * 2, sizeof(*topc));
459  botc = av_calloc((iir->nb_ab[0] + 1) * 2, sizeof(*botc));
460  if (!topc || !botc) {
461  ret = AVERROR(ENOMEM);
462  goto fail;
463  }
464 
465  ret = expand(ctx, iir->ab[0], iir->nb_ab[0], botc);
466  if (ret < 0) {
467  goto fail;
468  }
469 
470  ret = expand(ctx, iir->ab[1], iir->nb_ab[1], topc);
471  if (ret < 0) {
472  goto fail;
473  }
474 
475  for (j = 0, i = iir->nb_ab[1]; i >= 0; j++, i--) {
476  iir->ab[1][j] = topc[2 * i];
477  }
478  iir->nb_ab[1]++;
479 
480  for (j = 0, i = iir->nb_ab[0]; i >= 0; j++, i--) {
481  iir->ab[0][j] = botc[2 * i];
482  }
483  iir->nb_ab[0]++;
484 
485  normalize_coeffs(ctx, ch);
486 
487 fail:
488  av_free(topc);
489  av_free(botc);
490  if (ret < 0)
491  break;
492  }
493 
494  return ret;
495 }
496 
498 {
499  AudioIIRContext *s = ctx->priv;
500  int ch, ret;
501 
502  for (ch = 0; ch < channels; ch++) {
503  IIRChannel *iir = &s->iir[ch];
504  int nb_biquads = (FFMAX(iir->nb_ab[0], iir->nb_ab[1]) + 1) / 2;
505  int current_biquad = 0;
506 
507  iir->biquads = av_calloc(nb_biquads, sizeof(BiquadContext));
508  if (!iir->biquads)
509  return AVERROR(ENOMEM);
510 
511  while (nb_biquads--) {
512  Pair outmost_pole = { -1, -1 };
513  Pair nearest_zero = { -1, -1 };
514  double zeros[4] = { 0 };
515  double poles[4] = { 0 };
516  double b[6] = { 0 };
517  double a[6] = { 0 };
518  double min_distance = DBL_MAX;
519  double max_mag = 0;
520  double factor;
521  int i;
522 
523  for (i = 0; i < iir->nb_ab[0]; i++) {
524  double mag;
525 
526  if (isnan(iir->ab[0][2 * i]) || isnan(iir->ab[0][2 * i + 1]))
527  continue;
528  mag = hypot(iir->ab[0][2 * i], iir->ab[0][2 * i + 1]);
529 
530  if (mag > max_mag) {
531  max_mag = mag;
532  outmost_pole.a = i;
533  }
534  }
535 
536  for (i = 0; i < iir->nb_ab[0]; i++) {
537  if (isnan(iir->ab[0][2 * i]) || isnan(iir->ab[0][2 * i + 1]))
538  continue;
539 
540  if (iir->ab[0][2 * i ] == iir->ab[0][2 * outmost_pole.a ] &&
541  iir->ab[0][2 * i + 1] == -iir->ab[0][2 * outmost_pole.a + 1]) {
542  outmost_pole.b = i;
543  break;
544  }
545  }
546 
547  av_log(ctx, AV_LOG_VERBOSE, "outmost_pole is %d.%d\n", outmost_pole.a, outmost_pole.b);
548 
549  if (outmost_pole.a < 0 || outmost_pole.b < 0)
550  return AVERROR(EINVAL);
551 
552  for (i = 0; i < iir->nb_ab[1]; i++) {
553  double distance;
554 
555  if (isnan(iir->ab[1][2 * i]) || isnan(iir->ab[1][2 * i + 1]))
556  continue;
557  distance = hypot(iir->ab[0][2 * outmost_pole.a ] - iir->ab[1][2 * i ],
558  iir->ab[0][2 * outmost_pole.a + 1] - iir->ab[1][2 * i + 1]);
559 
560  if (distance < min_distance) {
561  min_distance = distance;
562  nearest_zero.a = i;
563  }
564  }
565 
566  for (i = 0; i < iir->nb_ab[1]; i++) {
567  if (isnan(iir->ab[1][2 * i]) || isnan(iir->ab[1][2 * i + 1]))
568  continue;
569 
570  if (iir->ab[1][2 * i ] == iir->ab[1][2 * nearest_zero.a ] &&
571  iir->ab[1][2 * i + 1] == -iir->ab[1][2 * nearest_zero.a + 1]) {
572  nearest_zero.b = i;
573  break;
574  }
575  }
576 
577  av_log(ctx, AV_LOG_VERBOSE, "nearest_zero is %d.%d\n", nearest_zero.a, nearest_zero.b);
578 
579  if (nearest_zero.a < 0 || nearest_zero.b < 0)
580  return AVERROR(EINVAL);
581 
582  poles[0] = iir->ab[0][2 * outmost_pole.a ];
583  poles[1] = iir->ab[0][2 * outmost_pole.a + 1];
584 
585  zeros[0] = iir->ab[1][2 * nearest_zero.a ];
586  zeros[1] = iir->ab[1][2 * nearest_zero.a + 1];
587 
588  if (nearest_zero.a == nearest_zero.b && outmost_pole.a == outmost_pole.b) {
589  zeros[2] = 0;
590  zeros[3] = 0;
591 
592  poles[2] = 0;
593  poles[3] = 0;
594  } else {
595  poles[2] = iir->ab[0][2 * outmost_pole.b ];
596  poles[3] = iir->ab[0][2 * outmost_pole.b + 1];
597 
598  zeros[2] = iir->ab[1][2 * nearest_zero.b ];
599  zeros[3] = iir->ab[1][2 * nearest_zero.b + 1];
600  }
601 
602  ret = expand(ctx, zeros, 2, b);
603  if (ret < 0)
604  return ret;
605 
606  ret = expand(ctx, poles, 2, a);
607  if (ret < 0)
608  return ret;
609 
610  iir->ab[0][2 * outmost_pole.a] = iir->ab[0][2 * outmost_pole.a + 1] = NAN;
611  iir->ab[0][2 * outmost_pole.b] = iir->ab[0][2 * outmost_pole.b + 1] = NAN;
612  iir->ab[1][2 * nearest_zero.a] = iir->ab[1][2 * nearest_zero.a + 1] = NAN;
613  iir->ab[1][2 * nearest_zero.b] = iir->ab[1][2 * nearest_zero.b + 1] = NAN;
614 
615  iir->biquads[current_biquad].a[0] = 1.;
616  iir->biquads[current_biquad].a[1] = a[2] / a[4];
617  iir->biquads[current_biquad].a[2] = a[0] / a[4];
618  iir->biquads[current_biquad].b[0] = b[4] / a[4];
619  iir->biquads[current_biquad].b[1] = b[2] / a[4];
620  iir->biquads[current_biquad].b[2] = b[0] / a[4];
621 
622  if (s->normalize &&
623  fabs(iir->biquads[current_biquad].b[0] +
624  iir->biquads[current_biquad].b[1] +
625  iir->biquads[current_biquad].b[2]) > 1e-6) {
626  factor = (iir->biquads[current_biquad].a[0] +
627  iir->biquads[current_biquad].a[1] +
628  iir->biquads[current_biquad].a[2]) /
629  (iir->biquads[current_biquad].b[0] +
630  iir->biquads[current_biquad].b[1] +
631  iir->biquads[current_biquad].b[2]);
632 
633  av_log(ctx, AV_LOG_VERBOSE, "factor=%f\n", factor);
634 
635  iir->biquads[current_biquad].b[0] *= factor;
636  iir->biquads[current_biquad].b[1] *= factor;
637  iir->biquads[current_biquad].b[2] *= factor;
638  }
639 
640  iir->biquads[current_biquad].b[0] *= (current_biquad ? 1.0 : iir->g);
641  iir->biquads[current_biquad].b[1] *= (current_biquad ? 1.0 : iir->g);
642  iir->biquads[current_biquad].b[2] *= (current_biquad ? 1.0 : iir->g);
643 
644  av_log(ctx, AV_LOG_VERBOSE, "a=%f %f %f:b=%f %f %f\n",
645  iir->biquads[current_biquad].a[0],
646  iir->biquads[current_biquad].a[1],
647  iir->biquads[current_biquad].a[2],
648  iir->biquads[current_biquad].b[0],
649  iir->biquads[current_biquad].b[1],
650  iir->biquads[current_biquad].b[2]);
651 
652  current_biquad++;
653  }
654  }
655 
656  return 0;
657 }
658 
660 {
661  AudioIIRContext *s = ctx->priv;
662  int ch;
663 
664  for (ch = 0; ch < channels; ch++) {
665  IIRChannel *iir = &s->iir[ch];
666  int n;
667 
668  for (n = 0; n < iir->nb_ab[0]; n++) {
669  double r = iir->ab[0][2*n];
670  double angle = iir->ab[0][2*n+1];
671 
672  iir->ab[0][2*n] = r * cos(angle);
673  iir->ab[0][2*n+1] = r * sin(angle);
674  }
675 
676  for (n = 0; n < iir->nb_ab[1]; n++) {
677  double r = iir->ab[1][2*n];
678  double angle = iir->ab[1][2*n+1];
679 
680  iir->ab[1][2*n] = r * cos(angle);
681  iir->ab[1][2*n+1] = r * sin(angle);
682  }
683  }
684 }
685 
687 {
688  AudioIIRContext *s = ctx->priv;
689  int ch;
690 
691  for (ch = 0; ch < channels; ch++) {
692  IIRChannel *iir = &s->iir[ch];
693  int n;
694 
695  for (n = 0; n < iir->nb_ab[0]; n++) {
696  double sr = iir->ab[0][2*n];
697  double si = iir->ab[0][2*n+1];
698  double snr = 1. + sr;
699  double sdr = 1. - sr;
700  double div = sdr * sdr + si * si;
701 
702  iir->ab[0][2*n] = (snr * sdr - si * si) / div;
703  iir->ab[0][2*n+1] = (sdr * si + snr * si) / div;
704  }
705 
706  for (n = 0; n < iir->nb_ab[1]; n++) {
707  double sr = iir->ab[1][2*n];
708  double si = iir->ab[1][2*n+1];
709  double snr = 1. + sr;
710  double sdr = 1. - sr;
711  double div = sdr * sdr + si * si;
712 
713  iir->ab[1][2*n] = (snr * sdr - si * si) / div;
714  iir->ab[1][2*n+1] = (sdr * si + snr * si) / div;
715  }
716  }
717 }
718 
720 {
721  AudioIIRContext *s = ctx->priv;
722  int ch;
723 
724  for (ch = 0; ch < channels; ch++) {
725  IIRChannel *iir = &s->iir[ch];
726  int n;
727 
728  for (n = 0; n < iir->nb_ab[0]; n++) {
729  double r = iir->ab[0][2*n];
730  double angle = M_PI*iir->ab[0][2*n+1]/180.;
731 
732  iir->ab[0][2*n] = r * cos(angle);
733  iir->ab[0][2*n+1] = r * sin(angle);
734  }
735 
736  for (n = 0; n < iir->nb_ab[1]; n++) {
737  double r = iir->ab[1][2*n];
738  double angle = M_PI*iir->ab[1][2*n+1]/180.;
739 
740  iir->ab[1][2*n] = r * cos(angle);
741  iir->ab[1][2*n+1] = r * sin(angle);
742  }
743  }
744 }
745 
747 {
748  AudioIIRContext *s = ctx->priv;
749  int ch;
750 
751  for (ch = 0; ch < channels; ch++) {
752  IIRChannel *iir = &s->iir[ch];
753 
754  for (int n = 0; n < iir->nb_ab[0]; n++) {
755  double pr = hypot(iir->ab[0][2*n], iir->ab[0][2*n+1]);
756 
757  if (pr >= 1.) {
758  av_log(ctx, AV_LOG_WARNING, "pole %d at channel %d is unstable\n", n, ch);
759  break;
760  }
761  }
762  }
763 }
764 
765 static void drawtext(AVFrame *pic, int x, int y, const char *txt, uint32_t color)
766 {
767  const uint8_t *font;
768  int font_height;
769  int i;
770 
771  font = avpriv_cga_font, font_height = 8;
772 
773  for (i = 0; txt[i]; i++) {
774  int char_y, mask;
775 
776  uint8_t *p = pic->data[0] + y * pic->linesize[0] + (x + i * 8) * 4;
777  for (char_y = 0; char_y < font_height; char_y++) {
778  for (mask = 0x80; mask; mask >>= 1) {
779  if (font[txt[i] * font_height + char_y] & mask)
780  AV_WL32(p, color);
781  p += 4;
782  }
783  p += pic->linesize[0] - 8 * 4;
784  }
785  }
786 }
787 
788 static void draw_line(AVFrame *out, int x0, int y0, int x1, int y1, uint32_t color)
789 {
790  int dx = FFABS(x1-x0);
791  int dy = FFABS(y1-y0), sy = y0 < y1 ? 1 : -1;
792  int err = (dx>dy ? dx : -dy) / 2, e2;
793 
794  for (;;) {
795  AV_WL32(out->data[0] + y0 * out->linesize[0] + x0 * 4, color);
796 
797  if (x0 == x1 && y0 == y1)
798  break;
799 
800  e2 = err;
801 
802  if (e2 >-dx) {
803  err -= dy;
804  x0--;
805  }
806 
807  if (e2 < dy) {
808  err += dx;
809  y0 += sy;
810  }
811  }
812 }
813 
814 static double distance(double x0, double x1, double y0, double y1)
815 {
816  return hypot(x0 - x1, y0 - y1);
817 }
818 
819 static void get_response(int channel, int format, double w,
820  const double *b, const double *a,
821  int nb_b, int nb_a, double *magnitude, double *phase)
822 {
823  double realz, realp;
824  double imagz, imagp;
825  double real, imag;
826  double div;
827 
828  if (format == 0) {
829  realz = 0., realp = 0.;
830  imagz = 0., imagp = 0.;
831  for (int x = 0; x < nb_a; x++) {
832  realz += cos(-x * w) * a[x];
833  imagz += sin(-x * w) * a[x];
834  }
835 
836  for (int x = 0; x < nb_b; x++) {
837  realp += cos(-x * w) * b[x];
838  imagp += sin(-x * w) * b[x];
839  }
840 
841  div = realp * realp + imagp * imagp;
842  real = (realz * realp + imagz * imagp) / div;
843  imag = (imagz * realp - imagp * realz) / div;
844 
845  *magnitude = hypot(real, imag);
846  *phase = atan2(imag, real);
847  } else {
848  double p = 1., z = 1.;
849  double acc = 0.;
850 
851  for (int x = 0; x < nb_a; x++) {
852  z *= distance(cos(w), a[2 * x], sin(w), a[2 * x + 1]);
853  acc += atan2(sin(w) - a[2 * x + 1], cos(w) - a[2 * x]);
854  }
855 
856  for (int x = 0; x < nb_b; x++) {
857  p *= distance(cos(w), b[2 * x], sin(w), b[2 * x + 1]);
858  acc -= atan2(sin(w) - b[2 * x + 1], cos(w) - b[2 * x]);
859  }
860 
861  *magnitude = z / p;
862  *phase = acc;
863  }
864 }
865 
867 {
868  AudioIIRContext *s = ctx->priv;
869  double *mag, *phase, *temp, *delay, min = DBL_MAX, max = -DBL_MAX;
870  double min_delay = DBL_MAX, max_delay = -DBL_MAX, min_phase, max_phase;
871  int prev_ymag = -1, prev_yphase = -1, prev_ydelay = -1;
872  char text[32];
873  int ch, i;
874 
875  memset(out->data[0], 0, s->h * out->linesize[0]);
876 
877  phase = av_malloc_array(s->w, sizeof(*phase));
878  temp = av_malloc_array(s->w, sizeof(*temp));
879  mag = av_malloc_array(s->w, sizeof(*mag));
880  delay = av_malloc_array(s->w, sizeof(*delay));
881  if (!mag || !phase || !delay || !temp)
882  goto end;
883 
884  ch = av_clip(s->ir_channel, 0, s->channels - 1);
885  for (i = 0; i < s->w; i++) {
886  const double *b = s->iir[ch].ab[0];
887  const double *a = s->iir[ch].ab[1];
888  const int nb_b = s->iir[ch].nb_ab[0];
889  const int nb_a = s->iir[ch].nb_ab[1];
890  double w = i * M_PI / (s->w - 1);
891  double m, p;
892 
893  get_response(ch, s->format, w, b, a, nb_b, nb_a, &m, &p);
894 
895  mag[i] = s->iir[ch].g * m;
896  phase[i] = p;
897  min = fmin(min, mag[i]);
898  max = fmax(max, mag[i]);
899  }
900 
901  temp[0] = 0.;
902  for (i = 0; i < s->w - 1; i++) {
903  double d = phase[i] - phase[i + 1];
904  temp[i + 1] = ceil(fabs(d) / (2. * M_PI)) * 2. * M_PI * ((d > M_PI) - (d < -M_PI));
905  }
906 
907  min_phase = phase[0];
908  max_phase = phase[0];
909  for (i = 1; i < s->w; i++) {
910  temp[i] += temp[i - 1];
911  phase[i] += temp[i];
912  min_phase = fmin(min_phase, phase[i]);
913  max_phase = fmax(max_phase, phase[i]);
914  }
915 
916  for (i = 0; i < s->w - 1; i++) {
917  double div = s->w / (double)sample_rate;
918 
919  delay[i + 1] = -(phase[i] - phase[i + 1]) / div;
920  min_delay = fmin(min_delay, delay[i + 1]);
921  max_delay = fmax(max_delay, delay[i + 1]);
922  }
923  delay[0] = delay[1];
924 
925  for (i = 0; i < s->w; i++) {
926  int ymag = mag[i] / max * (s->h - 1);
927  int ydelay = (delay[i] - min_delay) / (max_delay - min_delay) * (s->h - 1);
928  int yphase = (phase[i] - min_phase) / (max_phase - min_phase) * (s->h - 1);
929 
930  ymag = s->h - 1 - av_clip(ymag, 0, s->h - 1);
931  yphase = s->h - 1 - av_clip(yphase, 0, s->h - 1);
932  ydelay = s->h - 1 - av_clip(ydelay, 0, s->h - 1);
933 
934  if (prev_ymag < 0)
935  prev_ymag = ymag;
936  if (prev_yphase < 0)
937  prev_yphase = yphase;
938  if (prev_ydelay < 0)
939  prev_ydelay = ydelay;
940 
941  draw_line(out, i, ymag, FFMAX(i - 1, 0), prev_ymag, 0xFFFF00FF);
942  draw_line(out, i, yphase, FFMAX(i - 1, 0), prev_yphase, 0xFF00FF00);
943  draw_line(out, i, ydelay, FFMAX(i - 1, 0), prev_ydelay, 0xFF00FFFF);
944 
945  prev_ymag = ymag;
946  prev_yphase = yphase;
947  prev_ydelay = ydelay;
948  }
949 
950  if (s->w > 400 && s->h > 100) {
951  drawtext(out, 2, 2, "Max Magnitude:", 0xDDDDDDDD);
952  snprintf(text, sizeof(text), "%.2f", max);
953  drawtext(out, 15 * 8 + 2, 2, text, 0xDDDDDDDD);
954 
955  drawtext(out, 2, 12, "Min Magnitude:", 0xDDDDDDDD);
956  snprintf(text, sizeof(text), "%.2f", min);
957  drawtext(out, 15 * 8 + 2, 12, text, 0xDDDDDDDD);
958 
959  drawtext(out, 2, 22, "Max Phase:", 0xDDDDDDDD);
960  snprintf(text, sizeof(text), "%.2f", max_phase);
961  drawtext(out, 15 * 8 + 2, 22, text, 0xDDDDDDDD);
962 
963  drawtext(out, 2, 32, "Min Phase:", 0xDDDDDDDD);
964  snprintf(text, sizeof(text), "%.2f", min_phase);
965  drawtext(out, 15 * 8 + 2, 32, text, 0xDDDDDDDD);
966 
967  drawtext(out, 2, 42, "Max Delay:", 0xDDDDDDDD);
968  snprintf(text, sizeof(text), "%.2f", max_delay);
969  drawtext(out, 11 * 8 + 2, 42, text, 0xDDDDDDDD);
970 
971  drawtext(out, 2, 52, "Min Delay:", 0xDDDDDDDD);
972  snprintf(text, sizeof(text), "%.2f", min_delay);
973  drawtext(out, 11 * 8 + 2, 52, text, 0xDDDDDDDD);
974  }
975 
976 end:
977  av_free(delay);
978  av_free(temp);
979  av_free(phase);
980  av_free(mag);
981 }
982 
983 static int config_output(AVFilterLink *outlink)
984 {
985  AVFilterContext *ctx = outlink->src;
986  AudioIIRContext *s = ctx->priv;
987  AVFilterLink *inlink = ctx->inputs[0];
988  int ch, ret, i;
989 
990  s->channels = inlink->channels;
991  s->iir = av_calloc(s->channels, sizeof(*s->iir));
992  if (!s->iir)
993  return AVERROR(ENOMEM);
994 
995  ret = read_gains(ctx, s->g_str, inlink->channels);
996  if (ret < 0)
997  return ret;
998 
999  ret = read_channels(ctx, inlink->channels, s->a_str, 0);
1000  if (ret < 0)
1001  return ret;
1002 
1003  ret = read_channels(ctx, inlink->channels, s->b_str, 1);
1004  if (ret < 0)
1005  return ret;
1006 
1007  if (s->format == 2) {
1008  convert_pr2zp(ctx, inlink->channels);
1009  } else if (s->format == 3) {
1010  convert_pd2zp(ctx, inlink->channels);
1011  } else if (s->format == 4) {
1012  convert_sp2zp(ctx, inlink->channels);
1013  }
1014  if (s->format > 0) {
1015  check_stability(ctx, inlink->channels);
1016  }
1017 
1018  av_frame_free(&s->video);
1019  if (s->response) {
1020  s->video = ff_get_video_buffer(ctx->outputs[1], s->w, s->h);
1021  if (!s->video)
1022  return AVERROR(ENOMEM);
1023 
1024  draw_response(ctx, s->video, inlink->sample_rate);
1025  }
1026 
1027  if (s->format == 0)
1028  av_log(ctx, AV_LOG_WARNING, "tf coefficients format is not recommended for too high number of zeros/poles.\n");
1029 
1030  if (s->format > 0 && s->process == 0) {
1031  av_log(ctx, AV_LOG_WARNING, "Direct processsing is not recommended for zp coefficients format.\n");
1032 
1033  ret = convert_zp2tf(ctx, inlink->channels);
1034  if (ret < 0)
1035  return ret;
1036  } else if (s->format == 0 && s->process == 1) {
1037  av_log(ctx, AV_LOG_ERROR, "Serial cascading is not implemented for transfer function.\n");
1038  return AVERROR_PATCHWELCOME;
1039  } else if (s->format > 0 && s->process == 1) {
1040  if (inlink->format == AV_SAMPLE_FMT_S16P)
1041  av_log(ctx, AV_LOG_WARNING, "Serial cascading is not recommended for i16 precision.\n");
1042 
1043  ret = decompose_zp2biquads(ctx, inlink->channels);
1044  if (ret < 0)
1045  return ret;
1046  }
1047 
1048  for (ch = 0; s->format == 0 && ch < inlink->channels; ch++) {
1049  IIRChannel *iir = &s->iir[ch];
1050 
1051  for (i = 1; i < iir->nb_ab[0]; i++) {
1052  iir->ab[0][i] /= iir->ab[0][0];
1053  }
1054 
1055  iir->ab[0][0] = 1.0;
1056  for (i = 0; i < iir->nb_ab[1]; i++) {
1057  iir->ab[1][i] *= iir->g;
1058  }
1059 
1060  normalize_coeffs(ctx, ch);
1061  }
1062 
1063  switch (inlink->format) {
1064  case AV_SAMPLE_FMT_DBLP: s->iir_channel = s->process == 1 ? iir_ch_serial_dblp : iir_ch_dblp; break;
1065  case AV_SAMPLE_FMT_FLTP: s->iir_channel = s->process == 1 ? iir_ch_serial_fltp : iir_ch_fltp; break;
1066  case AV_SAMPLE_FMT_S32P: s->iir_channel = s->process == 1 ? iir_ch_serial_s32p : iir_ch_s32p; break;
1067  case AV_SAMPLE_FMT_S16P: s->iir_channel = s->process == 1 ? iir_ch_serial_s16p : iir_ch_s16p; break;
1068  }
1069 
1070  return 0;
1071 }
1072 
1074 {
1075  AVFilterContext *ctx = inlink->dst;
1076  AudioIIRContext *s = ctx->priv;
1077  AVFilterLink *outlink = ctx->outputs[0];
1078  ThreadData td;
1079  AVFrame *out;
1080  int ch, ret;
1081 
1082  if (av_frame_is_writable(in)) {
1083  out = in;
1084  } else {
1085  out = ff_get_audio_buffer(outlink, in->nb_samples);
1086  if (!out) {
1087  av_frame_free(&in);
1088  return AVERROR(ENOMEM);
1089  }
1090  av_frame_copy_props(out, in);
1091  }
1092 
1093  td.in = in;
1094  td.out = out;
1095  ctx->internal->execute(ctx, s->iir_channel, &td, NULL, outlink->channels);
1096 
1097  for (ch = 0; ch < outlink->channels; ch++) {
1098  if (s->iir[ch].clippings > 0)
1099  av_log(ctx, AV_LOG_WARNING, "Channel %d clipping %d times. Please reduce gain.\n",
1100  ch, s->iir[ch].clippings);
1101  s->iir[ch].clippings = 0;
1102  }
1103 
1104  if (in != out)
1105  av_frame_free(&in);
1106 
1107  if (s->response) {
1108  AVFilterLink *outlink = ctx->outputs[1];
1109  int64_t old_pts = s->video->pts;
1110  int64_t new_pts = av_rescale_q(out->pts, ctx->inputs[0]->time_base, outlink->time_base);
1111 
1112  if (new_pts > old_pts) {
1113  AVFrame *clone;
1114 
1115  s->video->pts = new_pts;
1116  clone = av_frame_clone(s->video);
1117  if (!clone)
1118  return AVERROR(ENOMEM);
1119  ret = ff_filter_frame(outlink, clone);
1120  if (ret < 0)
1121  return ret;
1122  }
1123  }
1124 
1125  return ff_filter_frame(outlink, out);
1126 }
1127 
1128 static int config_video(AVFilterLink *outlink)
1129 {
1130  AVFilterContext *ctx = outlink->src;
1131  AudioIIRContext *s = ctx->priv;
1132 
1133  outlink->sample_aspect_ratio = (AVRational){1,1};
1134  outlink->w = s->w;
1135  outlink->h = s->h;
1136  outlink->frame_rate = s->rate;
1137  outlink->time_base = av_inv_q(outlink->frame_rate);
1138 
1139  return 0;
1140 }
1141 
1143 {
1144  AudioIIRContext *s = ctx->priv;
1145  AVFilterPad pad, vpad;
1146  int ret;
1147 
1148  if (!s->a_str || !s->b_str || !s->g_str) {
1149  av_log(ctx, AV_LOG_ERROR, "Valid coefficients are mandatory.\n");
1150  return AVERROR(EINVAL);
1151  }
1152 
1153  switch (s->precision) {
1154  case 0: s->sample_format = AV_SAMPLE_FMT_DBLP; break;
1155  case 1: s->sample_format = AV_SAMPLE_FMT_FLTP; break;
1156  case 2: s->sample_format = AV_SAMPLE_FMT_S32P; break;
1157  case 3: s->sample_format = AV_SAMPLE_FMT_S16P; break;
1158  default: return AVERROR_BUG;
1159  }
1160 
1161  pad = (AVFilterPad){
1162  .name = "default",
1163  .type = AVMEDIA_TYPE_AUDIO,
1164  .config_props = config_output,
1165  };
1166 
1167  ret = ff_insert_outpad(ctx, 0, &pad);
1168  if (ret < 0)
1169  return ret;
1170 
1171  if (s->response) {
1172  vpad = (AVFilterPad){
1173  .name = "filter_response",
1174  .type = AVMEDIA_TYPE_VIDEO,
1175  .config_props = config_video,
1176  };
1177 
1178  ret = ff_insert_outpad(ctx, 1, &vpad);
1179  if (ret < 0)
1180  return ret;
1181  }
1182 
1183  return 0;
1184 }
1185 
1187 {
1188  AudioIIRContext *s = ctx->priv;
1189  int ch;
1190 
1191  if (s->iir) {
1192  for (ch = 0; ch < s->channels; ch++) {
1193  IIRChannel *iir = &s->iir[ch];
1194  av_freep(&iir->ab[0]);
1195  av_freep(&iir->ab[1]);
1196  av_freep(&iir->cache[0]);
1197  av_freep(&iir->cache[1]);
1198  av_freep(&iir->biquads);
1199  }
1200  }
1201  av_freep(&s->iir);
1202 
1203  av_frame_free(&s->video);
1204 }
1205 
1206 static const AVFilterPad inputs[] = {
1207  {
1208  .name = "default",
1209  .type = AVMEDIA_TYPE_AUDIO,
1210  .filter_frame = filter_frame,
1211  },
1212  { NULL }
1213 };
1214 
1215 #define OFFSET(x) offsetof(AudioIIRContext, x)
1216 #define AF AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
1217 #define VF AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
1218 
1219 static const AVOption aiir_options[] = {
1220  { "zeros", "set B/numerator/zeros coefficients", OFFSET(b_str), AV_OPT_TYPE_STRING, {.str="1+0i 1-0i"}, 0, 0, AF },
1221  { "z", "set B/numerator/zeros coefficients", OFFSET(b_str), AV_OPT_TYPE_STRING, {.str="1+0i 1-0i"}, 0, 0, AF },
1222  { "poles", "set A/denominator/poles coefficients", OFFSET(a_str),AV_OPT_TYPE_STRING, {.str="1+0i 1-0i"}, 0, 0, AF },
1223  { "p", "set A/denominator/poles coefficients", OFFSET(a_str), AV_OPT_TYPE_STRING, {.str="1+0i 1-0i"}, 0, 0, AF },
1224  { "gains", "set channels gains", OFFSET(g_str), AV_OPT_TYPE_STRING, {.str="1|1"}, 0, 0, AF },
1225  { "k", "set channels gains", OFFSET(g_str), AV_OPT_TYPE_STRING, {.str="1|1"}, 0, 0, AF },
1226  { "dry", "set dry gain", OFFSET(dry_gain), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, AF },
1227  { "wet", "set wet gain", OFFSET(wet_gain), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, AF },
1228  { "format", "set coefficients format", OFFSET(format), AV_OPT_TYPE_INT, {.i64=1}, 0, 4, AF, "format" },
1229  { "f", "set coefficients format", OFFSET(format), AV_OPT_TYPE_INT, {.i64=1}, 0, 4, AF, "format" },
1230  { "tf", "digital transfer function", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "format" },
1231  { "zp", "Z-plane zeros/poles", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "format" },
1232  { "pr", "Z-plane zeros/poles (polar radians)", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, AF, "format" },
1233  { "pd", "Z-plane zeros/poles (polar degrees)", 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, AF, "format" },
1234  { "sp", "S-plane zeros/poles", 0, AV_OPT_TYPE_CONST, {.i64=4}, 0, 0, AF, "format" },
1235  { "process", "set kind of processing", OFFSET(process), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, AF, "process" },
1236  { "r", "set kind of processing", OFFSET(process), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, AF, "process" },
1237  { "d", "direct", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "process" },
1238  { "s", "serial cascading", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "process" },
1239  { "precision", "set filtering precision", OFFSET(precision),AV_OPT_TYPE_INT, {.i64=0}, 0, 3, AF, "precision" },
1240  { "e", "set precision", OFFSET(precision),AV_OPT_TYPE_INT, {.i64=0}, 0, 3, AF, "precision" },
1241  { "dbl", "double-precision floating-point", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, "precision" },
1242  { "flt", "single-precision floating-point", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, "precision" },
1243  { "i32", "32-bit integers", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, AF, "precision" },
1244  { "i16", "16-bit integers", 0, AV_OPT_TYPE_CONST, {.i64=3}, 0, 0, AF, "precision" },
1245  { "normalize", "normalize coefficients", OFFSET(normalize),AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, AF },
1246  { "n", "normalize coefficients", OFFSET(normalize),AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, AF },
1247  { "mix", "set mix", OFFSET(mix), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 1, AF },
1248  { "response", "show IR frequency response", OFFSET(response), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, VF },
1249  { "channel", "set IR channel to display frequency response", OFFSET(ir_channel), AV_OPT_TYPE_INT, {.i64=0}, 0, 1024, VF },
1250  { "size", "set video size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "hd720"}, 0, 0, VF },
1251  { "rate", "set video rate", OFFSET(rate), AV_OPT_TYPE_VIDEO_RATE, {.str = "25"}, 0, INT32_MAX, VF },
1252  { NULL },
1253 };
1254 
1255 AVFILTER_DEFINE_CLASS(aiir);
1256 
1258  .name = "aiir",
1259  .description = NULL_IF_CONFIG_SMALL("Apply Infinite Impulse Response filter with supplied coefficients."),
1260  .priv_size = sizeof(AudioIIRContext),
1261  .priv_class = &aiir_class,
1262  .init = init,
1263  .uninit = uninit,
1265  .inputs = inputs,
1268 };
float, planar
Definition: samplefmt.h:69
static double distance(double x0, double x1, double y0, double y1)
Definition: af_aiir.c:814
#define NULL
Definition: coverity.c:32
int ff_set_common_channel_layouts(AVFilterContext *ctx, AVFilterChannelLayouts *layouts)
A helper for query_formats() which sets all links to the same list of channel layouts/sample rates...
Definition: formats.c:586
char * a_str
Definition: af_aiir.c:58
AVFrame * out
Definition: af_adeclick.c:494
static void cmul(double re, double im, double re2, double im2, double *RE, double *IM)
Definition: af_aiir.c:388
static const char * format[]
Definition: af_aiir.c:339
This structure describes decoded (raw) audio or video data.
Definition: frame.h:300
enum AVSampleFormat sample_format
Definition: af_aiir.c:74
AVOption.
Definition: opt.h:246
BiquadContext * biquads
Definition: af_aiir.c:52
float re
Definition: fft.c:82
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
Main libavfilter public API header.
else temp
Definition: vf_mcdeint.c:256
int acc
Definition: yuv2rgb.c:555
static int config_video(AVFilterLink *outlink)
Definition: af_aiir.c:1128
#define IM(x, ch)
static void convert_pd2zp(AVFilterContext *ctx, int channels)
Definition: af_aiir.c:719
static void drawtext(AVFrame *pic, int x, int y, const char *txt, uint32_t color)
Definition: af_aiir.c:765
int clippings
Definition: af_aiir.c:53
static int decompose_zp2biquads(AVFilterContext *ctx, int channels)
Definition: af_aiir.c:497
double, planar
Definition: samplefmt.h:70
#define SERIAL_IIR_CH(name, type, min, max, need_clipping)
Definition: af_aiir.c:179
static void count_coefficients(char *item_str, int *nb_items)
Definition: af_aiir.c:242
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:104
static int config_output(AVFilterLink *outlink)
Definition: af_aiir.c:983
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
Definition: mem.c:245
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:300
static void convert_sp2zp(AVFilterContext *ctx, int channels)
Definition: af_aiir.c:686
const char * name
Pad name.
Definition: internal.h:60
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:346
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1075
uint8_t
#define av_cold
Definition: attributes.h:88
packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined
Definition: pixfmt.h:238
AVOptions.
int ** delay
Definition: af_headphone.c:162
double * cache[2]
Definition: af_aiir.c:51
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:92
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:393
AVFilter ff_af_aiir
Definition: af_aiir.c:1257
static av_cold int init(AVFilterContext *ctx)
Definition: af_aiir.c:1142
static void normalize_coeffs(AVFilterContext *ctx, int ch)
Definition: af_aiir.c:421
AVFrame * dst
Definition: vf_blend.c:56
#define IIR_CH(name, type, min, max, need_clipping)
Definition: af_aiir.c:123
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:192
static int read_tf_coefficients(AVFilterContext *ctx, char *item_str, int nb_items, double *dst)
Definition: af_aiir.c:289
#define AVFILTER_FLAG_DYNAMIC_OUTPUTS
The number of the filter outputs is not determined just by AVFilter.outputs.
Definition: avfilter.h:111
static int query_formats(AVFilterContext *ctx)
Definition: af_aiir.c:79
channels
Definition: aptx.h:33
#define av_log(a,...)
A filter pad used for either input or output.
Definition: internal.h:54
static int expand(AVFilterContext *ctx, double *pz, int n, double *coefs)
Definition: af_aiir.c:394
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
A helper for query_formats() which sets all links to the same list of formats.
Definition: formats.c:605
#define td
Definition: regdef.h:70
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)
Definition: af_aiir.c:819
const uint8_t avpriv_cga_font[2048]
Definition: xga_font_data.c:29
AVFrame * ff_get_audio_buffer(AVFilterLink *link, int nb_samples)
Request an audio samples buffer with a specific set of permissions.
Definition: audio.c:86
static int read_channels(AVFilterContext *ctx, int channels, uint8_t *item_str, int ab)
Definition: af_aiir.c:341
#define AVERROR(e)
Definition: error.h:43
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:203
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:188
const char * r
Definition: vf_curves.c:114
void * priv
private data for use by the filter
Definition: avfilter.h:353
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
Definition: avfilter.h:116
const char * arg
Definition: jacosubdec.c:66
simple assert() macros that are a bit more flexible than ISO C assert().
#define AF
Definition: af_aiir.c:1216
#define FFMAX(a, b)
Definition: common.h:94
char * g_str
Definition: af_aiir.c:58
#define fail()
Definition: checkasm.h:123
double g
Definition: af_aiir.c:50
static av_const double hypot(double x, double y)
Definition: libm.h:366
#define NAN
Definition: mathematics.h:64
static int convert_zp2tf(AVFilterContext *ctx, int channels)
Definition: af_aiir.c:449
signed 32 bits, planar
Definition: samplefmt.h:68
char * b_str
Definition: af_aiir.c:58
int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
Add *ref as a new reference to formats.
Definition: formats.c:484
double a[3]
Definition: af_aiir.c:41
AVFrame * m
int32_t
AVFormatContext * ctx
Definition: movenc.c:48
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:72
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
Definition: frame.c:541
A list of supported channel layouts.
Definition: formats.h:85
#define VF
Definition: af_aiir.c:1217
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:62
static int mix(int c0, int c1)
Definition: 4xm.c:714
sample_rate
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:253
double wet_gain
Definition: af_aiir.c:59
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
int av_frame_is_writable(AVFrame *frame)
Check if the frame data is writable.
Definition: frame.c:595
Used for passing data between threads.
Definition: dsddec.c:67
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:331
double fmax(double, double)
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:50
Describe the class of an AVClass context structure.
Definition: log.h:67
static int read_gains(AVFilterContext *ctx, char *item_str, int nb_items)
Definition: af_aiir.c:256
Filter definition.
Definition: avfilter.h:144
AVFrame * mask
static void convert_pr2zp(AVFilterContext *ctx, int channels)
Definition: af_aiir.c:659
Rational number (pair of numerator and denominator).
Definition: rational.h:58
#define isnan(x)
Definition: libm.h:340
AVFrame * b
float im
Definition: fft.c:82
int a
Definition: af_aiir.c:37
offset must point to AVRational
Definition: opt.h:236
int b
Definition: af_aiir.c:37
double mix
Definition: af_aiir.c:60
static const int factor[16]
Definition: vf_pp7.c:75
const char * name
Filter name.
Definition: avfilter.h:148
static int read_zp_coefficients(AVFilterContext *ctx, char *item_str, int nb_items, double *dst, const char *format)
Definition: af_aiir.c:314
#define snprintf
Definition: snprintf.h:34
static av_cold void uninit(AVFilterContext *ctx)
Definition: af_aiir.c:1186
offset must point to two consecutive integers
Definition: opt.h:233
static const AVFilterPad inputs[]
Definition: af_aiir.c:1206
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:350
enum MovChannelLayoutTag * layouts
Definition: mov_chan.c:434
AVFrame * min
Definition: vf_threshold.c:74
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:275
AVFilterFormats * ff_all_samplerates(void)
Definition: formats.c:439
#define flags(name, subs,...)
Definition: cbs_av1.c:565
AVFilterInternal * internal
An opaque struct for libavfilter internal use.
Definition: avfilter.h:378
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:314
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()...
Definition: avstring.c:184
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
Definition: rational.h:159
int(* iir_channel)(AVFilterContext *ctx, void *arg, int ch, int nb_jobs)
Definition: af_aiir.c:76
static void draw_line(AVFrame *out, int x0, int y0, int x1, int y1, uint32_t color)
Definition: af_aiir.c:788
IIRChannel * iir
Definition: af_aiir.c:72
int
#define OFFSET(x)
Definition: af_aiir.c:1215
static void check_stability(AVFilterContext *ctx, int channels)
Definition: af_aiir.c:746
AVFrame * video
Definition: af_aiir.c:70
channel
Use these values when setting the channel map with ebur128_set_channel().
Definition: ebur128.h:39
double fmin(double, double)
avfilter_execute_func * execute
Definition: internal.h:144
double * ab[2]
Definition: af_aiir.c:49
AVRational rate
Definition: af_aiir.c:68
#define av_free(p)
double b[3]
Definition: af_aiir.c:42
A list of supported formats for one end of a filter link.
Definition: formats.h:64
#define RE(x, ch)
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: af_aiir.c:1073
An instance of a filter.
Definition: avfilter.h:338
static enum AVSampleFormat sample_fmts[]
Definition: adpcmenc.c:731
AVFILTER_DEFINE_CLASS(aiir)
#define av_freep(p)
const void ** s
signed 16 bits, planar
Definition: samplefmt.h:67
#define M_PI
Definition: mathematics.h:52
#define av_malloc_array(a, b)
int nb_ab[2]
Definition: af_aiir.c:48
AVFrame * in
Definition: af_afftdn.c:1083
formats
Definition: signature.h:48
AVFilterLink * inlink
Definition: vf_blend.c:57
internal API functions
static void draw_response(AVFilterContext *ctx, AVFrame *out, int sample_rate)
Definition: af_aiir.c:866
AVFilterChannelLayouts * ff_all_channel_counts(void)
Construct an AVFilterChannelLayouts coding for any channel layout, with known or unknown disposition...
Definition: formats.c:454
static int ff_insert_outpad(AVFilterContext *f, unsigned index, AVFilterPad *p)
Insert a new output pad for the filter.
Definition: internal.h:274
AVFrame * a
static void process(NormalizeContext *s, AVFrame *in, AVFrame *out)
Definition: vf_normalize.c:156
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:366
Definition: af_aiir.c:36
int ff_set_common_samplerates(AVFilterContext *ctx, AVFilterFormats *samplerates)
Definition: formats.c:593
int ir_channel
Definition: af_aiir.c:67
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:659
static const AVOption aiir_options[]
Definition: af_aiir.c:1219
CGA/EGA/VGA ROM font data.
AVFrame * max
Definition: vf_threshold.c:75
#define AV_WL32(p, v)
Definition: intreadwrite.h:426