FFmpeg
af_firequalizer.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 Muhammad Faiz <mfcc64@gmail.com>
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 "libavutil/opt.h"
22 #include "libavutil/eval.h"
23 #include "libavutil/avassert.h"
24 #include "libavcodec/avfft.h"
25 #include "avfilter.h"
26 #include "internal.h"
27 #include "audio.h"
28 
29 #define RDFT_BITS_MIN 4
30 #define RDFT_BITS_MAX 16
31 
32 enum WindowFunc {
44 };
45 
46 enum Scale {
52 };
53 
54 #define NB_GAIN_ENTRY_MAX 4096
55 typedef struct GainEntry {
56  double freq;
57  double gain;
58 } GainEntry;
59 
60 typedef struct OverlapIndex {
61  int buf_idx;
63 } OverlapIndex;
64 
65 typedef struct FIREqualizerContext {
66  const AVClass *class;
67 
76  int rdft_len;
78 
79  float *analysis_buf;
80  float *dump_buf;
82  float *kernel_buf;
83  float *cepstrum_buf;
84  float *conv_buf;
86  int fir_len;
88  int64_t next_pts;
90  int remaining;
91 
92  char *gain_cmd;
94  const char *gain;
95  const char *gain_entry;
96  double delay;
97  double accuracy;
98  int wfunc;
99  int fixed;
100  int multi;
102  int scale;
103  char *dumpfile;
105  int fft2;
107 
112 
113 #define OFFSET(x) offsetof(FIREqualizerContext, x)
114 #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
115 
116 static const AVOption firequalizer_options[] = {
117  { "gain", "set gain curve", OFFSET(gain), AV_OPT_TYPE_STRING, { .str = "gain_interpolate(f)" }, 0, 0, FLAGS },
118  { "gain_entry", "set gain entry", OFFSET(gain_entry), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, FLAGS },
119  { "delay", "set delay", OFFSET(delay), AV_OPT_TYPE_DOUBLE, { .dbl = 0.01 }, 0.0, 1e10, FLAGS },
120  { "accuracy", "set accuracy", OFFSET(accuracy), AV_OPT_TYPE_DOUBLE, { .dbl = 5.0 }, 0.0, 1e10, FLAGS },
121  { "wfunc", "set window function", OFFSET(wfunc), AV_OPT_TYPE_INT, { .i64 = WFUNC_HANN }, 0, NB_WFUNC-1, FLAGS, "wfunc" },
122  { "rectangular", "rectangular window", 0, AV_OPT_TYPE_CONST, { .i64 = WFUNC_RECTANGULAR }, 0, 0, FLAGS, "wfunc" },
123  { "hann", "hann window", 0, AV_OPT_TYPE_CONST, { .i64 = WFUNC_HANN }, 0, 0, FLAGS, "wfunc" },
124  { "hamming", "hamming window", 0, AV_OPT_TYPE_CONST, { .i64 = WFUNC_HAMMING }, 0, 0, FLAGS, "wfunc" },
125  { "blackman", "blackman window", 0, AV_OPT_TYPE_CONST, { .i64 = WFUNC_BLACKMAN }, 0, 0, FLAGS, "wfunc" },
126  { "nuttall3", "3-term nuttall window", 0, AV_OPT_TYPE_CONST, { .i64 = WFUNC_NUTTALL3 }, 0, 0, FLAGS, "wfunc" },
127  { "mnuttall3", "minimum 3-term nuttall window", 0, AV_OPT_TYPE_CONST, { .i64 = WFUNC_MNUTTALL3 }, 0, 0, FLAGS, "wfunc" },
128  { "nuttall", "nuttall window", 0, AV_OPT_TYPE_CONST, { .i64 = WFUNC_NUTTALL }, 0, 0, FLAGS, "wfunc" },
129  { "bnuttall", "blackman-nuttall window", 0, AV_OPT_TYPE_CONST, { .i64 = WFUNC_BNUTTALL }, 0, 0, FLAGS, "wfunc" },
130  { "bharris", "blackman-harris window", 0, AV_OPT_TYPE_CONST, { .i64 = WFUNC_BHARRIS }, 0, 0, FLAGS, "wfunc" },
131  { "tukey", "tukey window", 0, AV_OPT_TYPE_CONST, { .i64 = WFUNC_TUKEY }, 0, 0, FLAGS, "wfunc" },
132  { "fixed", "set fixed frame samples", OFFSET(fixed), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS },
133  { "multi", "set multi channels mode", OFFSET(multi), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS },
134  { "zero_phase", "set zero phase mode", OFFSET(zero_phase), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS },
135  { "scale", "set gain scale", OFFSET(scale), AV_OPT_TYPE_INT, { .i64 = SCALE_LINLOG }, 0, NB_SCALE-1, FLAGS, "scale" },
136  { "linlin", "linear-freq linear-gain", 0, AV_OPT_TYPE_CONST, { .i64 = SCALE_LINLIN }, 0, 0, FLAGS, "scale" },
137  { "linlog", "linear-freq logarithmic-gain", 0, AV_OPT_TYPE_CONST, { .i64 = SCALE_LINLOG }, 0, 0, FLAGS, "scale" },
138  { "loglin", "logarithmic-freq linear-gain", 0, AV_OPT_TYPE_CONST, { .i64 = SCALE_LOGLIN }, 0, 0, FLAGS, "scale" },
139  { "loglog", "logarithmic-freq logarithmic-gain", 0, AV_OPT_TYPE_CONST, { .i64 = SCALE_LOGLOG }, 0, 0, FLAGS, "scale" },
140  { "dumpfile", "set dump file", OFFSET(dumpfile), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, FLAGS },
141  { "dumpscale", "set dump scale", OFFSET(dumpscale), AV_OPT_TYPE_INT, { .i64 = SCALE_LINLOG }, 0, NB_SCALE-1, FLAGS, "scale" },
142  { "fft2", "set 2-channels fft", OFFSET(fft2), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS },
143  { "min_phase", "set minimum phase mode", OFFSET(min_phase), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS },
144  { NULL }
145 };
146 
147 AVFILTER_DEFINE_CLASS(firequalizer);
148 
150 {
151  av_rdft_end(s->analysis_rdft);
152  av_rdft_end(s->analysis_irdft);
153  av_rdft_end(s->rdft);
154  av_rdft_end(s->irdft);
155  av_fft_end(s->fft_ctx);
156  av_rdft_end(s->cepstrum_rdft);
157  av_rdft_end(s->cepstrum_irdft);
158  s->analysis_rdft = s->analysis_irdft = s->rdft = s->irdft = NULL;
159  s->fft_ctx = NULL;
160  s->cepstrum_rdft = NULL;
161  s->cepstrum_irdft = NULL;
162 
163  av_freep(&s->analysis_buf);
164  av_freep(&s->dump_buf);
165  av_freep(&s->kernel_tmp_buf);
166  av_freep(&s->kernel_buf);
167  av_freep(&s->cepstrum_buf);
168  av_freep(&s->conv_buf);
169  av_freep(&s->conv_idx);
170 }
171 
173 {
174  FIREqualizerContext *s = ctx->priv;
175 
176  common_uninit(s);
177  av_freep(&s->gain_cmd);
178  av_freep(&s->gain_entry_cmd);
179 }
180 
182 {
185  static const enum AVSampleFormat sample_fmts[] = {
188  };
189  int ret;
190 
192  if (!layouts)
193  return AVERROR(ENOMEM);
195  if (ret < 0)
196  return ret;
197 
199  if (!formats)
200  return AVERROR(ENOMEM);
202  if (ret < 0)
203  return ret;
204 
206  if (!formats)
207  return AVERROR(ENOMEM);
209 }
210 
211 static void fast_convolute(FIREqualizerContext *av_restrict s, const float *av_restrict kernel_buf, float *av_restrict conv_buf,
212  OverlapIndex *av_restrict idx, float *av_restrict data, int nsamples)
213 {
214  if (nsamples <= s->nsamples_max) {
215  float *buf = conv_buf + idx->buf_idx * s->rdft_len;
216  float *obuf = conv_buf + !idx->buf_idx * s->rdft_len + idx->overlap_idx;
217  int center = s->fir_len/2;
218  int k;
219 
220  memset(buf, 0, center * sizeof(*data));
221  memcpy(buf + center, data, nsamples * sizeof(*data));
222  memset(buf + center + nsamples, 0, (s->rdft_len - nsamples - center) * sizeof(*data));
223  av_rdft_calc(s->rdft, buf);
224 
225  buf[0] *= kernel_buf[0];
226  buf[1] *= kernel_buf[s->rdft_len/2];
227  for (k = 1; k < s->rdft_len/2; k++) {
228  buf[2*k] *= kernel_buf[k];
229  buf[2*k+1] *= kernel_buf[k];
230  }
231 
232  av_rdft_calc(s->irdft, buf);
233  for (k = 0; k < s->rdft_len - idx->overlap_idx; k++)
234  buf[k] += obuf[k];
235  memcpy(data, buf, nsamples * sizeof(*data));
236  idx->buf_idx = !idx->buf_idx;
237  idx->overlap_idx = nsamples;
238  } else {
239  while (nsamples > s->nsamples_max * 2) {
240  fast_convolute(s, kernel_buf, conv_buf, idx, data, s->nsamples_max);
241  data += s->nsamples_max;
242  nsamples -= s->nsamples_max;
243  }
244  fast_convolute(s, kernel_buf, conv_buf, idx, data, nsamples/2);
245  fast_convolute(s, kernel_buf, conv_buf, idx, data + nsamples/2, nsamples - nsamples/2);
246  }
247 }
248 
249 static void fast_convolute_nonlinear(FIREqualizerContext *av_restrict s, const float *av_restrict kernel_buf,
250  float *av_restrict conv_buf, OverlapIndex *av_restrict idx,
251  float *av_restrict data, int nsamples)
252 {
253  if (nsamples <= s->nsamples_max) {
254  float *buf = conv_buf + idx->buf_idx * s->rdft_len;
255  float *obuf = conv_buf + !idx->buf_idx * s->rdft_len + idx->overlap_idx;
256  int k;
257 
258  memcpy(buf, data, nsamples * sizeof(*data));
259  memset(buf + nsamples, 0, (s->rdft_len - nsamples) * sizeof(*data));
260  av_rdft_calc(s->rdft, buf);
261 
262  buf[0] *= kernel_buf[0];
263  buf[1] *= kernel_buf[1];
264  for (k = 2; k < s->rdft_len; k += 2) {
265  float re, im;
266  re = buf[k] * kernel_buf[k] - buf[k+1] * kernel_buf[k+1];
267  im = buf[k] * kernel_buf[k+1] + buf[k+1] * kernel_buf[k];
268  buf[k] = re;
269  buf[k+1] = im;
270  }
271 
272  av_rdft_calc(s->irdft, buf);
273  for (k = 0; k < s->rdft_len - idx->overlap_idx; k++)
274  buf[k] += obuf[k];
275  memcpy(data, buf, nsamples * sizeof(*data));
276  idx->buf_idx = !idx->buf_idx;
277  idx->overlap_idx = nsamples;
278  } else {
279  while (nsamples > s->nsamples_max * 2) {
280  fast_convolute_nonlinear(s, kernel_buf, conv_buf, idx, data, s->nsamples_max);
281  data += s->nsamples_max;
282  nsamples -= s->nsamples_max;
283  }
284  fast_convolute_nonlinear(s, kernel_buf, conv_buf, idx, data, nsamples/2);
285  fast_convolute_nonlinear(s, kernel_buf, conv_buf, idx, data + nsamples/2, nsamples - nsamples/2);
286  }
287 }
288 
289 static void fast_convolute2(FIREqualizerContext *av_restrict s, const float *av_restrict kernel_buf, FFTComplex *av_restrict conv_buf,
290  OverlapIndex *av_restrict idx, float *av_restrict data0, float *av_restrict data1, int nsamples)
291 {
292  if (nsamples <= s->nsamples_max) {
293  FFTComplex *buf = conv_buf + idx->buf_idx * s->rdft_len;
294  FFTComplex *obuf = conv_buf + !idx->buf_idx * s->rdft_len + idx->overlap_idx;
295  int center = s->fir_len/2;
296  int k;
297  float tmp;
298 
299  memset(buf, 0, center * sizeof(*buf));
300  for (k = 0; k < nsamples; k++) {
301  buf[center+k].re = data0[k];
302  buf[center+k].im = data1[k];
303  }
304  memset(buf + center + nsamples, 0, (s->rdft_len - nsamples - center) * sizeof(*buf));
305  av_fft_permute(s->fft_ctx, buf);
306  av_fft_calc(s->fft_ctx, buf);
307 
308  /* swap re <-> im, do backward fft using forward fft_ctx */
309  /* normalize with 0.5f */
310  tmp = buf[0].re;
311  buf[0].re = 0.5f * kernel_buf[0] * buf[0].im;
312  buf[0].im = 0.5f * kernel_buf[0] * tmp;
313  for (k = 1; k < s->rdft_len/2; k++) {
314  int m = s->rdft_len - k;
315  tmp = buf[k].re;
316  buf[k].re = 0.5f * kernel_buf[k] * buf[k].im;
317  buf[k].im = 0.5f * kernel_buf[k] * tmp;
318  tmp = buf[m].re;
319  buf[m].re = 0.5f * kernel_buf[k] * buf[m].im;
320  buf[m].im = 0.5f * kernel_buf[k] * tmp;
321  }
322  tmp = buf[k].re;
323  buf[k].re = 0.5f * kernel_buf[k] * buf[k].im;
324  buf[k].im = 0.5f * kernel_buf[k] * tmp;
325 
326  av_fft_permute(s->fft_ctx, buf);
327  av_fft_calc(s->fft_ctx, buf);
328 
329  for (k = 0; k < s->rdft_len - idx->overlap_idx; k++) {
330  buf[k].re += obuf[k].re;
331  buf[k].im += obuf[k].im;
332  }
333 
334  /* swapped re <-> im */
335  for (k = 0; k < nsamples; k++) {
336  data0[k] = buf[k].im;
337  data1[k] = buf[k].re;
338  }
339  idx->buf_idx = !idx->buf_idx;
340  idx->overlap_idx = nsamples;
341  } else {
342  while (nsamples > s->nsamples_max * 2) {
343  fast_convolute2(s, kernel_buf, conv_buf, idx, data0, data1, s->nsamples_max);
344  data0 += s->nsamples_max;
345  data1 += s->nsamples_max;
346  nsamples -= s->nsamples_max;
347  }
348  fast_convolute2(s, kernel_buf, conv_buf, idx, data0, data1, nsamples/2);
349  fast_convolute2(s, kernel_buf, conv_buf, idx, data0 + nsamples/2, data1 + nsamples/2, nsamples - nsamples/2);
350  }
351 }
352 
353 static void dump_fir(AVFilterContext *ctx, FILE *fp, int ch)
354 {
355  FIREqualizerContext *s = ctx->priv;
356  int rate = ctx->inputs[0]->sample_rate;
357  int xlog = s->dumpscale == SCALE_LOGLIN || s->dumpscale == SCALE_LOGLOG;
358  int ylog = s->dumpscale == SCALE_LINLOG || s->dumpscale == SCALE_LOGLOG;
359  int x;
360  int center = s->fir_len / 2;
361  double delay = s->zero_phase ? 0.0 : (double) center / rate;
362  double vx, ya, yb;
363 
364  if (!s->min_phase) {
365  s->analysis_buf[0] *= s->rdft_len/2;
366  for (x = 1; x <= center; x++) {
367  s->analysis_buf[x] *= s->rdft_len/2;
368  s->analysis_buf[s->analysis_rdft_len - x] *= s->rdft_len/2;
369  }
370  } else {
371  for (x = 0; x < s->fir_len; x++)
372  s->analysis_buf[x] *= s->rdft_len/2;
373  }
374 
375  if (ch)
376  fprintf(fp, "\n\n");
377 
378  fprintf(fp, "# time[%d] (time amplitude)\n", ch);
379 
380  if (!s->min_phase) {
381  for (x = center; x > 0; x--)
382  fprintf(fp, "%15.10f %15.10f\n", delay - (double) x / rate, (double) s->analysis_buf[s->analysis_rdft_len - x]);
383 
384  for (x = 0; x <= center; x++)
385  fprintf(fp, "%15.10f %15.10f\n", delay + (double)x / rate , (double) s->analysis_buf[x]);
386  } else {
387  for (x = 0; x < s->fir_len; x++)
388  fprintf(fp, "%15.10f %15.10f\n", (double)x / rate, (double) s->analysis_buf[x]);
389  }
390 
391  av_rdft_calc(s->analysis_rdft, s->analysis_buf);
392 
393  fprintf(fp, "\n\n# freq[%d] (frequency desired_gain actual_gain)\n", ch);
394 
395  for (x = 0; x <= s->analysis_rdft_len/2; x++) {
396  int i = (x == s->analysis_rdft_len/2) ? 1 : 2 * x;
397  vx = (double)x * rate / s->analysis_rdft_len;
398  if (xlog)
399  vx = log2(0.05*vx);
400  ya = s->dump_buf[i];
401  yb = s->min_phase && (i > 1) ? hypotf(s->analysis_buf[i], s->analysis_buf[i+1]) : s->analysis_buf[i];
402  if (s->min_phase)
403  yb = fabs(yb);
404  if (ylog) {
405  ya = 20.0 * log10(fabs(ya));
406  yb = 20.0 * log10(fabs(yb));
407  }
408  fprintf(fp, "%17.10f %17.10f %17.10f\n", vx, ya, yb);
409  }
410 }
411 
412 static double entry_func(void *p, double freq, double gain)
413 {
414  AVFilterContext *ctx = p;
415  FIREqualizerContext *s = ctx->priv;
416 
417  if (s->nb_gain_entry >= NB_GAIN_ENTRY_MAX) {
418  av_log(ctx, AV_LOG_ERROR, "entry table overflow.\n");
419  s->gain_entry_err = AVERROR(EINVAL);
420  return 0;
421  }
422 
423  if (isnan(freq)) {
424  av_log(ctx, AV_LOG_ERROR, "nan frequency (%g, %g).\n", freq, gain);
425  s->gain_entry_err = AVERROR(EINVAL);
426  return 0;
427  }
428 
429  if (s->nb_gain_entry > 0 && freq <= s->gain_entry_tbl[s->nb_gain_entry - 1].freq) {
430  av_log(ctx, AV_LOG_ERROR, "unsorted frequency (%g, %g).\n", freq, gain);
431  s->gain_entry_err = AVERROR(EINVAL);
432  return 0;
433  }
434 
435  s->gain_entry_tbl[s->nb_gain_entry].freq = freq;
436  s->gain_entry_tbl[s->nb_gain_entry].gain = gain;
437  s->nb_gain_entry++;
438  return 0;
439 }
440 
441 static int gain_entry_compare(const void *key, const void *memb)
442 {
443  const double *freq = key;
444  const GainEntry *entry = memb;
445 
446  if (*freq < entry[0].freq)
447  return -1;
448  if (*freq > entry[1].freq)
449  return 1;
450  return 0;
451 }
452 
453 static double gain_interpolate_func(void *p, double freq)
454 {
455  AVFilterContext *ctx = p;
456  FIREqualizerContext *s = ctx->priv;
457  GainEntry *res;
458  double d0, d1, d;
459 
460  if (isnan(freq))
461  return freq;
462 
463  if (!s->nb_gain_entry)
464  return 0;
465 
466  if (freq <= s->gain_entry_tbl[0].freq)
467  return s->gain_entry_tbl[0].gain;
468 
469  if (freq >= s->gain_entry_tbl[s->nb_gain_entry-1].freq)
470  return s->gain_entry_tbl[s->nb_gain_entry-1].gain;
471 
472  res = bsearch(&freq, &s->gain_entry_tbl, s->nb_gain_entry - 1, sizeof(*res), gain_entry_compare);
473  av_assert0(res);
474 
475  d = res[1].freq - res[0].freq;
476  d0 = freq - res[0].freq;
477  d1 = res[1].freq - freq;
478 
479  if (d0 && d1)
480  return (d0 * res[1].gain + d1 * res[0].gain) / d;
481 
482  if (d0)
483  return res[1].gain;
484 
485  return res[0].gain;
486 }
487 
488 static double cubic_interpolate_func(void *p, double freq)
489 {
490  AVFilterContext *ctx = p;
491  FIREqualizerContext *s = ctx->priv;
492  GainEntry *res;
493  double x, x2, x3;
494  double a, b, c, d;
495  double m0, m1, m2, msum, unit;
496 
497  if (!s->nb_gain_entry)
498  return 0;
499 
500  if (freq <= s->gain_entry_tbl[0].freq)
501  return s->gain_entry_tbl[0].gain;
502 
503  if (freq >= s->gain_entry_tbl[s->nb_gain_entry-1].freq)
504  return s->gain_entry_tbl[s->nb_gain_entry-1].gain;
505 
506  res = bsearch(&freq, &s->gain_entry_tbl, s->nb_gain_entry - 1, sizeof(*res), gain_entry_compare);
507  av_assert0(res);
508 
509  unit = res[1].freq - res[0].freq;
510  m0 = res != s->gain_entry_tbl ?
511  unit * (res[0].gain - res[-1].gain) / (res[0].freq - res[-1].freq) : 0;
512  m1 = res[1].gain - res[0].gain;
513  m2 = res != s->gain_entry_tbl + s->nb_gain_entry - 2 ?
514  unit * (res[2].gain - res[1].gain) / (res[2].freq - res[1].freq) : 0;
515 
516  msum = fabs(m0) + fabs(m1);
517  m0 = msum > 0 ? (fabs(m0) * m1 + fabs(m1) * m0) / msum : 0;
518  msum = fabs(m1) + fabs(m2);
519  m1 = msum > 0 ? (fabs(m1) * m2 + fabs(m2) * m1) / msum : 0;
520 
521  d = res[0].gain;
522  c = m0;
523  b = 3 * res[1].gain - m1 - 2 * c - 3 * d;
524  a = res[1].gain - b - c - d;
525 
526  x = (freq - res[0].freq) / unit;
527  x2 = x * x;
528  x3 = x2 * x;
529 
530  return a * x3 + b * x2 + c * x + d;
531 }
532 
533 static const char *const var_names[] = {
534  "f",
535  "sr",
536  "ch",
537  "chid",
538  "chs",
539  "chlayout",
540  NULL
541 };
542 
543 enum VarOffset {
551 };
552 
553 static void generate_min_phase_kernel(FIREqualizerContext *s, float *rdft_buf)
554 {
555  int k, cepstrum_len = s->cepstrum_len, rdft_len = s->rdft_len;
556  double norm = 2.0 / cepstrum_len;
557  double minval = 1e-7 / rdft_len;
558 
559  memset(s->cepstrum_buf, 0, cepstrum_len * sizeof(*s->cepstrum_buf));
560  memcpy(s->cepstrum_buf, rdft_buf, rdft_len/2 * sizeof(*rdft_buf));
561  memcpy(s->cepstrum_buf + cepstrum_len - rdft_len/2, rdft_buf + rdft_len/2, rdft_len/2 * sizeof(*rdft_buf));
562 
563  av_rdft_calc(s->cepstrum_rdft, s->cepstrum_buf);
564 
565  s->cepstrum_buf[0] = log(FFMAX(s->cepstrum_buf[0], minval));
566  s->cepstrum_buf[1] = log(FFMAX(s->cepstrum_buf[1], minval));
567 
568  for (k = 2; k < cepstrum_len; k += 2) {
569  s->cepstrum_buf[k] = log(FFMAX(s->cepstrum_buf[k], minval));
570  s->cepstrum_buf[k+1] = 0;
571  }
572 
573  av_rdft_calc(s->cepstrum_irdft, s->cepstrum_buf);
574 
575  memset(s->cepstrum_buf + cepstrum_len/2 + 1, 0, (cepstrum_len/2 - 1) * sizeof(*s->cepstrum_buf));
576  for (k = 1; k < cepstrum_len/2; k++)
577  s->cepstrum_buf[k] *= 2;
578 
579  av_rdft_calc(s->cepstrum_rdft, s->cepstrum_buf);
580 
581  s->cepstrum_buf[0] = exp(s->cepstrum_buf[0] * norm) * norm;
582  s->cepstrum_buf[1] = exp(s->cepstrum_buf[1] * norm) * norm;
583  for (k = 2; k < cepstrum_len; k += 2) {
584  double mag = exp(s->cepstrum_buf[k] * norm) * norm;
585  double ph = s->cepstrum_buf[k+1] * norm;
586  s->cepstrum_buf[k] = mag * cos(ph);
587  s->cepstrum_buf[k+1] = mag * sin(ph);
588  }
589 
590  av_rdft_calc(s->cepstrum_irdft, s->cepstrum_buf);
591  memset(rdft_buf, 0, s->rdft_len * sizeof(*rdft_buf));
592  memcpy(rdft_buf, s->cepstrum_buf, s->fir_len * sizeof(*rdft_buf));
593 
594  if (s->dumpfile) {
595  memset(s->analysis_buf, 0, s->analysis_rdft_len * sizeof(*s->analysis_buf));
596  memcpy(s->analysis_buf, s->cepstrum_buf, s->fir_len * sizeof(*s->analysis_buf));
597  }
598 
599 }
600 
601 static int generate_kernel(AVFilterContext *ctx, const char *gain, const char *gain_entry)
602 {
603  FIREqualizerContext *s = ctx->priv;
604  AVFilterLink *inlink = ctx->inputs[0];
605  const char *gain_entry_func_names[] = { "entry", NULL };
606  const char *gain_func_names[] = { "gain_interpolate", "cubic_interpolate", NULL };
607  double (*gain_entry_funcs[])(void *, double, double) = { entry_func, NULL };
608  double (*gain_funcs[])(void *, double) = { gain_interpolate_func, cubic_interpolate_func, NULL };
609  double vars[VAR_NB];
610  AVExpr *gain_expr;
611  int ret, k, center, ch;
612  int xlog = s->scale == SCALE_LOGLIN || s->scale == SCALE_LOGLOG;
613  int ylog = s->scale == SCALE_LINLOG || s->scale == SCALE_LOGLOG;
614  FILE *dump_fp = NULL;
615 
616  s->nb_gain_entry = 0;
617  s->gain_entry_err = 0;
618  if (gain_entry) {
619  double result = 0.0;
620  ret = av_expr_parse_and_eval(&result, gain_entry, NULL, NULL, NULL, NULL,
621  gain_entry_func_names, gain_entry_funcs, ctx, 0, ctx);
622  if (ret < 0)
623  return ret;
624  if (s->gain_entry_err < 0)
625  return s->gain_entry_err;
626  }
627 
628  av_log(ctx, AV_LOG_DEBUG, "nb_gain_entry = %d.\n", s->nb_gain_entry);
629 
630  ret = av_expr_parse(&gain_expr, gain, var_names,
631  gain_func_names, gain_funcs, NULL, NULL, 0, ctx);
632  if (ret < 0)
633  return ret;
634 
635  if (s->dumpfile && (!s->dump_buf || !s->analysis_rdft || !(dump_fp = fopen(s->dumpfile, "w"))))
636  av_log(ctx, AV_LOG_WARNING, "dumping failed.\n");
637 
638  vars[VAR_CHS] = inlink->channels;
639  vars[VAR_CHLAYOUT] = inlink->channel_layout;
640  vars[VAR_SR] = inlink->sample_rate;
641  for (ch = 0; ch < inlink->channels; ch++) {
642  float *rdft_buf = s->kernel_tmp_buf + ch * s->rdft_len;
643  double result;
644  vars[VAR_CH] = ch;
646  vars[VAR_F] = 0.0;
647  if (xlog)
648  vars[VAR_F] = log2(0.05 * vars[VAR_F]);
649  result = av_expr_eval(gain_expr, vars, ctx);
650  s->analysis_buf[0] = ylog ? pow(10.0, 0.05 * result) : result;
651 
652  vars[VAR_F] = 0.5 * inlink->sample_rate;
653  if (xlog)
654  vars[VAR_F] = log2(0.05 * vars[VAR_F]);
655  result = av_expr_eval(gain_expr, vars, ctx);
656  s->analysis_buf[1] = ylog ? pow(10.0, 0.05 * result) : result;
657 
658  for (k = 1; k < s->analysis_rdft_len/2; k++) {
659  vars[VAR_F] = k * ((double)inlink->sample_rate /(double)s->analysis_rdft_len);
660  if (xlog)
661  vars[VAR_F] = log2(0.05 * vars[VAR_F]);
662  result = av_expr_eval(gain_expr, vars, ctx);
663  s->analysis_buf[2*k] = ylog ? pow(10.0, 0.05 * result) : s->min_phase ? fabs(result) : result;
664  s->analysis_buf[2*k+1] = 0.0;
665  }
666 
667  if (s->dump_buf)
668  memcpy(s->dump_buf, s->analysis_buf, s->analysis_rdft_len * sizeof(*s->analysis_buf));
669 
670  av_rdft_calc(s->analysis_irdft, s->analysis_buf);
671  center = s->fir_len / 2;
672 
673  for (k = 0; k <= center; k++) {
674  double u = k * (M_PI/center);
675  double win;
676  switch (s->wfunc) {
677  case WFUNC_RECTANGULAR:
678  win = 1.0;
679  break;
680  case WFUNC_HANN:
681  win = 0.5 + 0.5 * cos(u);
682  break;
683  case WFUNC_HAMMING:
684  win = 0.53836 + 0.46164 * cos(u);
685  break;
686  case WFUNC_BLACKMAN:
687  win = 0.42 + 0.5 * cos(u) + 0.08 * cos(2*u);
688  break;
689  case WFUNC_NUTTALL3:
690  win = 0.40897 + 0.5 * cos(u) + 0.09103 * cos(2*u);
691  break;
692  case WFUNC_MNUTTALL3:
693  win = 0.4243801 + 0.4973406 * cos(u) + 0.0782793 * cos(2*u);
694  break;
695  case WFUNC_NUTTALL:
696  win = 0.355768 + 0.487396 * cos(u) + 0.144232 * cos(2*u) + 0.012604 * cos(3*u);
697  break;
698  case WFUNC_BNUTTALL:
699  win = 0.3635819 + 0.4891775 * cos(u) + 0.1365995 * cos(2*u) + 0.0106411 * cos(3*u);
700  break;
701  case WFUNC_BHARRIS:
702  win = 0.35875 + 0.48829 * cos(u) + 0.14128 * cos(2*u) + 0.01168 * cos(3*u);
703  break;
704  case WFUNC_TUKEY:
705  win = (u <= 0.5 * M_PI) ? 1.0 : (0.5 + 0.5 * cos(2*u - M_PI));
706  break;
707  default:
708  av_assert0(0);
709  }
710  s->analysis_buf[k] *= (2.0/s->analysis_rdft_len) * (2.0/s->rdft_len) * win;
711  if (k)
712  s->analysis_buf[s->analysis_rdft_len - k] = s->analysis_buf[k];
713  }
714 
715  memset(s->analysis_buf + center + 1, 0, (s->analysis_rdft_len - s->fir_len) * sizeof(*s->analysis_buf));
716  memcpy(rdft_buf, s->analysis_buf, s->rdft_len/2 * sizeof(*s->analysis_buf));
717  memcpy(rdft_buf + s->rdft_len/2, s->analysis_buf + s->analysis_rdft_len - s->rdft_len/2, s->rdft_len/2 * sizeof(*s->analysis_buf));
718  if (s->min_phase)
719  generate_min_phase_kernel(s, rdft_buf);
720  av_rdft_calc(s->rdft, rdft_buf);
721 
722  for (k = 0; k < s->rdft_len; k++) {
723  if (isnan(rdft_buf[k]) || isinf(rdft_buf[k])) {
724  av_log(ctx, AV_LOG_ERROR, "filter kernel contains nan or infinity.\n");
725  av_expr_free(gain_expr);
726  if (dump_fp)
727  fclose(dump_fp);
728  return AVERROR(EINVAL);
729  }
730  }
731 
732  if (!s->min_phase) {
733  rdft_buf[s->rdft_len-1] = rdft_buf[1];
734  for (k = 0; k < s->rdft_len/2; k++)
735  rdft_buf[k] = rdft_buf[2*k];
736  rdft_buf[s->rdft_len/2] = rdft_buf[s->rdft_len-1];
737  }
738 
739  if (dump_fp)
740  dump_fir(ctx, dump_fp, ch);
741 
742  if (!s->multi)
743  break;
744  }
745 
746  memcpy(s->kernel_buf, s->kernel_tmp_buf, (s->multi ? inlink->channels : 1) * s->rdft_len * sizeof(*s->kernel_buf));
747  av_expr_free(gain_expr);
748  if (dump_fp)
749  fclose(dump_fp);
750  return 0;
751 }
752 
753 #define SELECT_GAIN(s) (s->gain_cmd ? s->gain_cmd : s->gain)
754 #define SELECT_GAIN_ENTRY(s) (s->gain_entry_cmd ? s->gain_entry_cmd : s->gain_entry)
755 
757 {
758  AVFilterContext *ctx = inlink->dst;
759  FIREqualizerContext *s = ctx->priv;
760  int rdft_bits;
761 
762  common_uninit(s);
763 
764  s->next_pts = 0;
765  s->frame_nsamples_max = 0;
766 
767  s->fir_len = FFMAX(2 * (int)(inlink->sample_rate * s->delay) + 1, 3);
768  s->remaining = s->fir_len - 1;
769 
770  for (rdft_bits = RDFT_BITS_MIN; rdft_bits <= RDFT_BITS_MAX; rdft_bits++) {
771  s->rdft_len = 1 << rdft_bits;
772  s->nsamples_max = s->rdft_len - s->fir_len + 1;
773  if (s->nsamples_max * 2 >= s->fir_len)
774  break;
775  }
776 
777  if (rdft_bits > RDFT_BITS_MAX) {
778  av_log(ctx, AV_LOG_ERROR, "too large delay, please decrease it.\n");
779  return AVERROR(EINVAL);
780  }
781 
782  if (!(s->rdft = av_rdft_init(rdft_bits, DFT_R2C)) || !(s->irdft = av_rdft_init(rdft_bits, IDFT_C2R)))
783  return AVERROR(ENOMEM);
784 
785  if (s->fft2 && !s->multi && inlink->channels > 1 && !(s->fft_ctx = av_fft_init(rdft_bits, 0)))
786  return AVERROR(ENOMEM);
787 
788  if (s->min_phase) {
789  int cepstrum_bits = rdft_bits + 2;
790  if (cepstrum_bits > RDFT_BITS_MAX) {
791  av_log(ctx, AV_LOG_ERROR, "too large delay, please decrease it.\n");
792  return AVERROR(EINVAL);
793  }
794 
795  cepstrum_bits = FFMIN(RDFT_BITS_MAX, cepstrum_bits + 1);
796  s->cepstrum_rdft = av_rdft_init(cepstrum_bits, DFT_R2C);
797  s->cepstrum_irdft = av_rdft_init(cepstrum_bits, IDFT_C2R);
798  if (!s->cepstrum_rdft || !s->cepstrum_irdft)
799  return AVERROR(ENOMEM);
800 
801  s->cepstrum_len = 1 << cepstrum_bits;
802  s->cepstrum_buf = av_malloc_array(s->cepstrum_len, sizeof(*s->cepstrum_buf));
803  if (!s->cepstrum_buf)
804  return AVERROR(ENOMEM);
805  }
806 
807  for ( ; rdft_bits <= RDFT_BITS_MAX; rdft_bits++) {
808  s->analysis_rdft_len = 1 << rdft_bits;
809  if (inlink->sample_rate <= s->accuracy * s->analysis_rdft_len)
810  break;
811  }
812 
813  if (rdft_bits > RDFT_BITS_MAX) {
814  av_log(ctx, AV_LOG_ERROR, "too small accuracy, please increase it.\n");
815  return AVERROR(EINVAL);
816  }
817 
818  if (!(s->analysis_irdft = av_rdft_init(rdft_bits, IDFT_C2R)))
819  return AVERROR(ENOMEM);
820 
821  if (s->dumpfile) {
822  s->analysis_rdft = av_rdft_init(rdft_bits, DFT_R2C);
823  s->dump_buf = av_malloc_array(s->analysis_rdft_len, sizeof(*s->dump_buf));
824  }
825 
826  s->analysis_buf = av_malloc_array(s->analysis_rdft_len, sizeof(*s->analysis_buf));
827  s->kernel_tmp_buf = av_malloc_array(s->rdft_len * (s->multi ? inlink->channels : 1), sizeof(*s->kernel_tmp_buf));
828  s->kernel_buf = av_malloc_array(s->rdft_len * (s->multi ? inlink->channels : 1), sizeof(*s->kernel_buf));
829  s->conv_buf = av_calloc(2 * s->rdft_len * inlink->channels, sizeof(*s->conv_buf));
830  s->conv_idx = av_calloc(inlink->channels, sizeof(*s->conv_idx));
831  if (!s->analysis_buf || !s->kernel_tmp_buf || !s->kernel_buf || !s->conv_buf || !s->conv_idx)
832  return AVERROR(ENOMEM);
833 
834  av_log(ctx, AV_LOG_DEBUG, "sample_rate = %d, channels = %d, analysis_rdft_len = %d, rdft_len = %d, fir_len = %d, nsamples_max = %d.\n",
835  inlink->sample_rate, inlink->channels, s->analysis_rdft_len, s->rdft_len, s->fir_len, s->nsamples_max);
836 
837  if (s->fixed)
838  inlink->min_samples = inlink->max_samples = inlink->partial_buf_size = s->nsamples_max;
839 
841 }
842 
844 {
845  AVFilterContext *ctx = inlink->dst;
846  FIREqualizerContext *s = ctx->priv;
847  int ch;
848 
849  if (!s->min_phase) {
850  for (ch = 0; ch + 1 < inlink->channels && s->fft_ctx; ch += 2) {
851  fast_convolute2(s, s->kernel_buf, (FFTComplex *)(s->conv_buf + 2 * ch * s->rdft_len),
852  s->conv_idx + ch, (float *) frame->extended_data[ch],
853  (float *) frame->extended_data[ch+1], frame->nb_samples);
854  }
855 
856  for ( ; ch < inlink->channels; ch++) {
857  fast_convolute(s, s->kernel_buf + (s->multi ? ch * s->rdft_len : 0),
858  s->conv_buf + 2 * ch * s->rdft_len, s->conv_idx + ch,
859  (float *) frame->extended_data[ch], frame->nb_samples);
860  }
861  } else {
862  for (ch = 0; ch < inlink->channels; ch++) {
863  fast_convolute_nonlinear(s, s->kernel_buf + (s->multi ? ch * s->rdft_len : 0),
864  s->conv_buf + 2 * ch * s->rdft_len, s->conv_idx + ch,
865  (float *) frame->extended_data[ch], frame->nb_samples);
866  }
867  }
868 
869  s->next_pts = AV_NOPTS_VALUE;
870  if (frame->pts != AV_NOPTS_VALUE) {
871  s->next_pts = frame->pts + av_rescale_q(frame->nb_samples, av_make_q(1, inlink->sample_rate), inlink->time_base);
872  if (s->zero_phase && !s->min_phase)
873  frame->pts -= av_rescale_q(s->fir_len/2, av_make_q(1, inlink->sample_rate), inlink->time_base);
874  }
875  s->frame_nsamples_max = FFMAX(s->frame_nsamples_max, frame->nb_samples);
876  return ff_filter_frame(ctx->outputs[0], frame);
877 }
878 
879 static int request_frame(AVFilterLink *outlink)
880 {
881  AVFilterContext *ctx = outlink->src;
882  FIREqualizerContext *s= ctx->priv;
883  int ret;
884 
885  ret = ff_request_frame(ctx->inputs[0]);
886  if (ret == AVERROR_EOF && s->remaining > 0 && s->frame_nsamples_max > 0) {
887  AVFrame *frame = ff_get_audio_buffer(outlink, FFMIN(s->remaining, s->frame_nsamples_max));
888 
889  if (!frame)
890  return AVERROR(ENOMEM);
891 
892  av_samples_set_silence(frame->extended_data, 0, frame->nb_samples, outlink->channels, frame->format);
893  frame->pts = s->next_pts;
894  s->remaining -= frame->nb_samples;
895  ret = filter_frame(ctx->inputs[0], frame);
896  }
897 
898  return ret;
899 }
900 
901 static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
902  char *res, int res_len, int flags)
903 {
904  FIREqualizerContext *s = ctx->priv;
905  int ret = AVERROR(ENOSYS);
906 
907  if (!strcmp(cmd, "gain")) {
908  char *gain_cmd;
909 
910  if (SELECT_GAIN(s) && !strcmp(SELECT_GAIN(s), args)) {
911  av_log(ctx, AV_LOG_DEBUG, "equal gain, do not rebuild.\n");
912  return 0;
913  }
914 
915  gain_cmd = av_strdup(args);
916  if (!gain_cmd)
917  return AVERROR(ENOMEM);
918 
919  ret = generate_kernel(ctx, gain_cmd, SELECT_GAIN_ENTRY(s));
920  if (ret >= 0) {
921  av_freep(&s->gain_cmd);
922  s->gain_cmd = gain_cmd;
923  } else {
924  av_freep(&gain_cmd);
925  }
926  } else if (!strcmp(cmd, "gain_entry")) {
927  char *gain_entry_cmd;
928 
929  if (SELECT_GAIN_ENTRY(s) && !strcmp(SELECT_GAIN_ENTRY(s), args)) {
930  av_log(ctx, AV_LOG_DEBUG, "equal gain_entry, do not rebuild.\n");
931  return 0;
932  }
933 
934  gain_entry_cmd = av_strdup(args);
935  if (!gain_entry_cmd)
936  return AVERROR(ENOMEM);
937 
938  ret = generate_kernel(ctx, SELECT_GAIN(s), gain_entry_cmd);
939  if (ret >= 0) {
940  av_freep(&s->gain_entry_cmd);
941  s->gain_entry_cmd = gain_entry_cmd;
942  } else {
943  av_freep(&gain_entry_cmd);
944  }
945  }
946 
947  return ret;
948 }
949 
951  {
952  .name = "default",
953  .config_props = config_input,
954  .filter_frame = filter_frame,
955  .type = AVMEDIA_TYPE_AUDIO,
956  .needs_writable = 1,
957  },
958  { NULL }
959 };
960 
962  {
963  .name = "default",
964  .request_frame = request_frame,
965  .type = AVMEDIA_TYPE_AUDIO,
966  },
967  { NULL }
968 };
969 
971  .name = "firequalizer",
972  .description = NULL_IF_CONFIG_SMALL("Finite Impulse Response Equalizer."),
973  .uninit = uninit,
974  .query_formats = query_formats,
975  .process_command = process_command,
976  .priv_size = sizeof(FIREqualizerContext),
979  .priv_class = &firequalizer_class,
980 };
FIREqualizerContext::cepstrum_len
int cepstrum_len
Definition: af_firequalizer.c:77
formats
formats
Definition: signature.h:48
av_fft_end
av_cold void av_fft_end(FFTContext *s)
Definition: avfft.c:48
ff_get_audio_buffer
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
AV_SAMPLE_FMT_FLTP
@ AV_SAMPLE_FMT_FLTP
float, planar
Definition: samplefmt.h:69
GainEntry::freq
double freq
Definition: af_firequalizer.c:56
FIREqualizerContext::gain_cmd
char * gain_cmd
Definition: af_firequalizer.c:92
AVFilterChannelLayouts
A list of supported channel layouts.
Definition: formats.h:85
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
AVERROR
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
opt.h
generate_kernel
static int generate_kernel(AVFilterContext *ctx, const char *gain, const char *gain_entry)
Definition: af_firequalizer.c:601
ff_make_format_list
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:283
u
#define u(width, name, range_min, range_max)
Definition: cbs_h2645.c:252
ff_set_common_channel_layouts
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:549
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1080
sample_fmts
static enum AVSampleFormat sample_fmts[]
Definition: adpcmenc.c:686
layouts
enum MovChannelLayoutTag * layouts
Definition: mov_chan.c:434
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:55
ch
uint8_t pi<< 24) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_U8,(uint64_t)((*(const uint8_t *) pi - 0x80U))<< 56) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16,(*(const int16_t *) pi >>8)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S16,(uint64_t)(*(const int16_t *) pi)<< 48) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32,(*(const int32_t *) pi >>24)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S32,(uint64_t)(*(const int32_t *) pi)<< 32) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S64,(*(const int64_t *) pi >>56)+0x80) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S64, *(const int64_t *) pi *(1.0f/(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S64, *(const int64_t *) pi *(1.0/(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_FLT, llrintf(*(const float *) pi *(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_DBL, llrint(*(const double *) pi *(INT64_C(1)<< 63))) #define FMT_PAIR_FUNC(out, in) static conv_func_type *const fmt_pair_to_conv_functions[AV_SAMPLE_FMT_NB *AV_SAMPLE_FMT_NB]={ FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S64), };static void cpy1(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, len);} static void cpy2(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, 2 *len);} static void cpy4(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, 4 *len);} static void cpy8(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, 8 *len);} AudioConvert *swri_audio_convert_alloc(enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, const int *ch_map, int flags) { AudioConvert *ctx;conv_func_type *f=fmt_pair_to_conv_functions[av_get_packed_sample_fmt(out_fmt)+AV_SAMPLE_FMT_NB *av_get_packed_sample_fmt(in_fmt)];if(!f) return NULL;ctx=av_mallocz(sizeof(*ctx));if(!ctx) return NULL;if(channels==1){ in_fmt=av_get_planar_sample_fmt(in_fmt);out_fmt=av_get_planar_sample_fmt(out_fmt);} ctx->channels=channels;ctx->conv_f=f;ctx->ch_map=ch_map;if(in_fmt==AV_SAMPLE_FMT_U8||in_fmt==AV_SAMPLE_FMT_U8P) memset(ctx->silence, 0x80, sizeof(ctx->silence));if(out_fmt==in_fmt &&!ch_map) { switch(av_get_bytes_per_sample(in_fmt)){ case 1:ctx->simd_f=cpy1;break;case 2:ctx->simd_f=cpy2;break;case 4:ctx->simd_f=cpy4;break;case 8:ctx->simd_f=cpy8;break;} } if(HAVE_X86ASM &&1) swri_audio_convert_init_x86(ctx, out_fmt, in_fmt, channels);if(ARCH_ARM) swri_audio_convert_init_arm(ctx, out_fmt, in_fmt, channels);if(ARCH_AARCH64) swri_audio_convert_init_aarch64(ctx, out_fmt, in_fmt, channels);return ctx;} void swri_audio_convert_free(AudioConvert **ctx) { av_freep(ctx);} int swri_audio_convert(AudioConvert *ctx, AudioData *out, AudioData *in, int len) { int ch;int off=0;const int os=(out->planar ? 1 :out->ch_count) *out->bps;unsigned misaligned=0;av_assert0(ctx->channels==out->ch_count);if(ctx->in_simd_align_mask) { int planes=in->planar ? in->ch_count :1;unsigned m=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) in->ch[ch];misaligned|=m &ctx->in_simd_align_mask;} if(ctx->out_simd_align_mask) { int planes=out->planar ? out->ch_count :1;unsigned m=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) out->ch[ch];misaligned|=m &ctx->out_simd_align_mask;} if(ctx->simd_f &&!ctx->ch_map &&!misaligned){ off=len &~15;av_assert1(off >=0);av_assert1(off<=len);av_assert2(ctx->channels==SWR_CH_MAX||!in->ch[ctx->channels]);if(off >0){ if(out->planar==in->planar){ int planes=out->planar ? out->ch_count :1;for(ch=0;ch< planes;ch++){ ctx->simd_f(out-> ch ch
Definition: audioconvert.c:56
inlink
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
Definition: filter_design.txt:212
gain_interpolate_func
static double gain_interpolate_func(void *p, double freq)
Definition: af_firequalizer.c:453
FIREqualizerContext::analysis_irdft
RDFTContext * analysis_irdft
Definition: af_firequalizer.c:69
ff_all_channel_counts
AVFilterChannelLayouts * ff_all_channel_counts(void)
Construct an AVFilterChannelLayouts coding for any channel layout, with known or unknown disposition.
Definition: formats.c:410
im
float im
Definition: fft.c:82
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:26
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
Definition: af_firequalizer.c:843
AVOption
AVOption.
Definition: opt.h:246
b
#define b
Definition: input.c:41
FIREqualizerContext::frame_nsamples_max
int frame_nsamples_max
Definition: af_firequalizer.c:89
data
const char data[16]
Definition: mxf.c:91
OverlapIndex::buf_idx
int buf_idx
Definition: af_firequalizer.c:61
ff_request_frame
int ff_request_frame(AVFilterLink *link)
Request an input frame from the filter at the other end of the link.
Definition: avfilter.c:407
av_fft_permute
void av_fft_permute(FFTContext *s, FFTComplex *z)
Do the permutation needed BEFORE calling ff_fft_calc().
Definition: avfft.c:38
FIREqualizerContext::rdft_len
int rdft_len
Definition: af_firequalizer.c:76
VarOffset
VarOffset
Definition: af_firequalizer.c:543
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:148
query_formats
static int query_formats(AVFilterContext *ctx)
Definition: af_firequalizer.c:181
SCALE_LOGLOG
@ SCALE_LOGLOG
Definition: af_firequalizer.c:50
FIREqualizerContext::wfunc
int wfunc
Definition: af_firequalizer.c:98
FIREqualizerContext::cepstrum_irdft
RDFTContext * cepstrum_irdft
Definition: af_firequalizer.c:74
SELECT_GAIN_ENTRY
#define SELECT_GAIN_ENTRY(s)
Definition: af_firequalizer.c:754
FIREqualizerContext::nb_gain_entry
int nb_gain_entry
Definition: af_firequalizer.c:108
AVFilterFormats
A list of supported formats for one end of a filter link.
Definition: formats.h:64
FIREqualizerContext
Definition: af_firequalizer.c:65
WFUNC_RECTANGULAR
@ WFUNC_RECTANGULAR
Definition: af_firequalizer.c:33
win
static float win(SuperEqualizerContext *s, float n, int N)
Definition: af_superequalizer.c:119
av_expr_parse
int av_expr_parse(AVExpr **expr, const char *s, const char *const *const_names, const char *const *func1_names, double(*const *funcs1)(void *, double), const char *const *func2_names, double(*const *funcs2)(void *, double, double), int log_offset, void *log_ctx)
Parse an expression.
Definition: eval.c:679
NB_GAIN_ENTRY_MAX
#define NB_GAIN_ENTRY_MAX
Definition: af_firequalizer.c:54
VAR_CHLAYOUT
@ VAR_CHLAYOUT
Definition: af_firequalizer.c:549
WFUNC_BLACKMAN
@ WFUNC_BLACKMAN
Definition: af_firequalizer.c:36
generate_min_phase_kernel
static void generate_min_phase_kernel(FIREqualizerContext *s, float *rdft_buf)
Definition: af_firequalizer.c:553
firequalizer_outputs
static const AVFilterPad firequalizer_outputs[]
Definition: af_firequalizer.c:961
firequalizer_inputs
static const AVFilterPad firequalizer_inputs[]
Definition: af_firequalizer.c:950
WindowFunc
WindowFunc
Definition: af_firequalizer.c:32
VAR_SR
@ VAR_SR
Definition: af_firequalizer.c:545
GainEntry::gain
double gain
Definition: af_firequalizer.c:57
RDFT_BITS_MAX
#define RDFT_BITS_MAX
Definition: af_firequalizer.c:30
request_frame
static int request_frame(AVFilterLink *outlink)
Definition: af_firequalizer.c:879
IDFT_C2R
@ IDFT_C2R
Definition: avfft.h:73
FIREqualizerContext::conv_idx
OverlapIndex * conv_idx
Definition: af_firequalizer.c:85
cubic_interpolate_func
static double cubic_interpolate_func(void *p, double freq)
Definition: af_firequalizer.c:488
av_expr_free
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
Definition: eval.c:334
ff_af_firequalizer
AVFilter ff_af_firequalizer
Definition: af_firequalizer.c:970
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:54
SELECT_GAIN
#define SELECT_GAIN(s)
Definition: af_firequalizer.c:753
avassert.h
FIREqualizerContext::scale
int scale
Definition: af_firequalizer.c:102
VAR_CHID
@ VAR_CHID
Definition: af_firequalizer.c:547
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
buf
void * buf
Definition: avisynth_c.h:766
av_cold
#define av_cold
Definition: attributes.h:84
ff_set_common_formats
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:568
WFUNC_NUTTALL
@ WFUNC_NUTTALL
Definition: af_firequalizer.c:39
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: af_firequalizer.c:172
s
#define s(width, name)
Definition: cbs_vp9.c:257
AV_OPT_TYPE_DOUBLE
@ AV_OPT_TYPE_DOUBLE
Definition: opt.h:225
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
WFUNC_NUTTALL3
@ WFUNC_NUTTALL3
Definition: af_firequalizer.c:37
outputs
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
FIREqualizerContext::min_phase
int min_phase
Definition: af_firequalizer.c:106
ctx
AVFormatContext * ctx
Definition: movenc.c:48
av_expr_eval
double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
Evaluate a previously parsed expression.
Definition: eval.c:734
WFUNC_BHARRIS
@ WFUNC_BHARRIS
Definition: af_firequalizer.c:41
OverlapIndex::overlap_idx
int overlap_idx
Definition: af_firequalizer.c:62
av_rescale_q
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
AVExpr
Definition: eval.c:157
key
const char * key
Definition: hwcontext_opencl.c:168
av_rdft_calc
void av_rdft_calc(RDFTContext *s, FFTSample *data)
if
if(ret)
Definition: filter_design.txt:179
SCALE_LINLIN
@ SCALE_LINLIN
Definition: af_firequalizer.c:47
FIREqualizerContext::analysis_rdft_len
int analysis_rdft_len
Definition: af_firequalizer.c:75
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:67
result
and forward the result(frame or status change) to the corresponding input. If nothing is possible
NULL
#define NULL
Definition: coverity.c:32
FIREqualizerContext::gain_entry_err
int gain_entry_err
Definition: af_firequalizer.c:109
vars
static const uint8_t vars[2][12]
Definition: camellia.c:179
FLAGS
#define FLAGS
Definition: af_firequalizer.c:114
WFUNC_HAMMING
@ WFUNC_HAMMING
Definition: af_firequalizer.c:35
isnan
#define isnan(x)
Definition: libm.h:340
FIREqualizerContext::fft_ctx
FFTContext * fft_ctx
Definition: af_firequalizer.c:72
GainEntry
Definition: af_firequalizer.c:55
FIREqualizerContext::zero_phase
int zero_phase
Definition: af_firequalizer.c:101
entry_func
static double entry_func(void *p, double freq, double gain)
Definition: af_firequalizer.c:412
FIREqualizerContext::gain
const char * gain
Definition: af_firequalizer.c:94
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(firequalizer)
isinf
#define isinf(x)
Definition: libm.h:317
DFT_R2C
@ DFT_R2C
Definition: avfft.h:72
avfft.h
inputs
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several inputs
Definition: filter_design.txt:243
OFFSET
#define OFFSET(x)
Definition: af_firequalizer.c:113
fp
#define fp
Definition: regdef.h:44
exp
int8_t exp
Definition: eval.c:72
var_names
static const char *const var_names[]
Definition: af_firequalizer.c:533
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
VAR_CHS
@ VAR_CHS
Definition: af_firequalizer.c:548
FIREqualizerContext::gain_entry_cmd
char * gain_entry_cmd
Definition: af_firequalizer.c:93
eval.h
RDFT_BITS_MIN
#define RDFT_BITS_MIN
Definition: af_firequalizer.c:29
av_rdft_init
RDFTContext * av_rdft_init(int nbits, enum RDFTransformType trans)
Set up a real FFT.
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:188
av_expr_parse_and_eval
int av_expr_parse_and_eval(double *d, const char *s, const char *const *const_names, const double *const_values, const char *const *func1_names, double(*const *funcs1)(void *, double), const char *const *func2_names, double(*const *funcs2)(void *, double, double), void *opaque, int log_offset, void *log_ctx)
Parse and evaluate an expression.
Definition: eval.c:744
FIREqualizerContext::analysis_buf
float * analysis_buf
Definition: af_firequalizer.c:79
fast_convolute2
static void fast_convolute2(FIREqualizerContext *av_restrict s, const float *av_restrict kernel_buf, FFTComplex *av_restrict conv_buf, OverlapIndex *av_restrict idx, float *av_restrict data0, float *av_restrict data1, int nsamples)
Definition: af_firequalizer.c:289
FFMAX
#define FFMAX(a, b)
Definition: common.h:94
AV_SAMPLE_FMT_NONE
@ AV_SAMPLE_FMT_NONE
Definition: samplefmt.h:59
av_make_q
static AVRational av_make_q(int num, int den)
Create an AVRational.
Definition: rational.h:71
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
WFUNC_TUKEY
@ WFUNC_TUKEY
Definition: af_firequalizer.c:42
FIREqualizerContext::fir_len
int fir_len
Definition: af_firequalizer.c:86
FFTComplex::im
FFTSample im
Definition: avfft.h:38
FFTComplex::re
FFTSample re
Definition: avfft.h:38
firequalizer_options
static const AVOption firequalizer_options[]
Definition: af_firequalizer.c:116
VAR_NB
@ VAR_NB
Definition: af_firequalizer.c:550
FFMIN
#define FFMIN(a, b)
Definition: common.h:96
a
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
Definition: undefined.txt:41
FIREqualizerContext::kernel_tmp_buf
float * kernel_tmp_buf
Definition: af_firequalizer.c:81
FIREqualizerContext::cepstrum_rdft
RDFTContext * cepstrum_rdft
Definition: af_firequalizer.c:73
M_PI
#define M_PI
Definition: mathematics.h:52
internal.h
FIREqualizerContext::cepstrum_buf
float * cepstrum_buf
Definition: af_firequalizer.c:83
FIREqualizerContext::remaining
int remaining
Definition: af_firequalizer.c:90
VAR_CH
@ VAR_CH
Definition: af_firequalizer.c:546
WFUNC_HANN
@ WFUNC_HANN
Definition: af_firequalizer.c:34
FFTContext
Definition: fft.h:88
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
av_channel_layout_extract_channel
uint64_t av_channel_layout_extract_channel(uint64_t channel_layout, int index)
Get the channel with the given index in channel_layout.
Definition: channel_layout.c:265
FIREqualizerContext::conv_buf
float * conv_buf
Definition: af_firequalizer.c:84
SCALE_LINLOG
@ SCALE_LINLOG
Definition: af_firequalizer.c:48
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:32
RDFTContext
Definition: rdft.h:28
FIREqualizerContext::dump_buf
float * dump_buf
Definition: af_firequalizer.c:80
AVSampleFormat
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
args
const char AVS_Value args
Definition: avisynth_c.h:873
FIREqualizerContext::gain_entry_tbl
GainEntry gain_entry_tbl[NB_GAIN_ENTRY_MAX]
Definition: af_firequalizer.c:110
Scale
Scale
Definition: af_firequalizer.c:46
VAR_F
@ VAR_F
Definition: af_firequalizer.c:544
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:60
process_command
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
Definition: af_firequalizer.c:901
fast_convolute
static void fast_convolute(FIREqualizerContext *av_restrict s, const float *av_restrict kernel_buf, float *av_restrict conv_buf, OverlapIndex *av_restrict idx, float *av_restrict data, int nsamples)
Definition: af_firequalizer.c:211
FIREqualizerContext::kernel_buf
float * kernel_buf
Definition: af_firequalizer.c:82
log2
#define log2(x)
Definition: libm.h:404
av_samples_set_silence
int av_samples_set_silence(uint8_t **audio_data, int offset, int nb_samples, int nb_channels, enum AVSampleFormat sample_fmt)
Fill an audio buffer with silence.
Definition: samplefmt.c:237
FIREqualizerContext::next_pts
int64_t next_pts
Definition: af_firequalizer.c:88
AVFilter
Filter definition.
Definition: avfilter.h:144
ret
ret
Definition: filter_design.txt:187
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:264
SCALE_LOGLIN
@ SCALE_LOGLIN
Definition: af_firequalizer.c:49
FIREqualizerContext::accuracy
double accuracy
Definition: af_firequalizer.c:97
av_fft_init
FFTContext * av_fft_init(int nbits, int inverse)
Set up a complex FFT.
Definition: avfft.c:28
NB_WFUNC
@ NB_WFUNC
Definition: af_firequalizer.c:43
ff_all_samplerates
AVFilterFormats * ff_all_samplerates(void)
Definition: formats.c:395
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
Definition: mem.c:244
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:223
avfilter.h
FIREqualizerContext::fixed
int fixed
Definition: af_firequalizer.c:99
FIREqualizerContext::dumpscale
int dumpscale
Definition: af_firequalizer.c:104
FIREqualizerContext::nsamples_max
int nsamples_max
Definition: af_firequalizer.c:87
AVFilterContext
An instance of a filter.
Definition: avfilter.h:338
FIREqualizerContext::rdft
RDFTContext * rdft
Definition: af_firequalizer.c:70
common_uninit
static void common_uninit(FIREqualizerContext *s)
Definition: af_firequalizer.c:149
av_strdup
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:251
WFUNC_BNUTTALL
@ WFUNC_BNUTTALL
Definition: af_firequalizer.c:40
audio.h
fast_convolute_nonlinear
static void fast_convolute_nonlinear(FIREqualizerContext *av_restrict s, const float *av_restrict kernel_buf, float *av_restrict conv_buf, OverlapIndex *av_restrict idx, float *av_restrict data, int nsamples)
Definition: af_firequalizer.c:249
gain_entry_compare
static int gain_entry_compare(const void *key, const void *memb)
Definition: af_firequalizer.c:441
FIREqualizerContext::gain_entry
const char * gain_entry
Definition: af_firequalizer.c:95
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:240
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
FIREqualizerContext::analysis_rdft
RDFTContext * analysis_rdft
Definition: af_firequalizer.c:68
fixed
#define fixed(width, name, value)
Definition: cbs_av1.c:570
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:565
av_rdft_end
void av_rdft_end(RDFTContext *s)
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
FIREqualizerContext::fft2
int fft2
Definition: af_firequalizer.c:105
ff_set_common_samplerates
int ff_set_common_samplerates(AVFilterContext *ctx, AVFilterFormats *samplerates)
Definition: formats.c:556
NB_SCALE
@ NB_SCALE
Definition: af_firequalizer.c:51
config_input
static int config_input(AVFilterLink *inlink)
Definition: af_firequalizer.c:756
OverlapIndex
Definition: af_firequalizer.c:60
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:227
FIREqualizerContext::delay
double delay
Definition: af_firequalizer.c:96
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:232
av_fft_calc
void av_fft_calc(FFTContext *s, FFTComplex *z)
Do a complex FFT with the parameters defined in av_fft_init().
Definition: avfft.c:43
dump_fir
static void dump_fir(AVFilterContext *ctx, FILE *fp, int ch)
Definition: af_firequalizer.c:353
FFTComplex
Definition: avfft.h:37
re
float re
Definition: fft.c:82
FIREqualizerContext::irdft
RDFTContext * irdft
Definition: af_firequalizer.c:71
FIREqualizerContext::multi
int multi
Definition: af_firequalizer.c:100
WFUNC_MNUTTALL3
@ WFUNC_MNUTTALL3
Definition: af_firequalizer.c:38
FIREqualizerContext::dumpfile
char * dumpfile
Definition: af_firequalizer.c:103