FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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 #define NB_GAIN_ENTRY_MAX 4096
47 typedef struct {
48  double freq;
49  double gain;
50 } GainEntry;
51 
52 typedef struct {
53  int buf_idx;
55 } OverlapIndex;
56 
57 typedef struct {
58  const AVClass *class;
59 
64  int rdft_len;
65 
66  float *analysis_buf;
68  float *kernel_buf;
69  float *conv_buf;
71  int fir_len;
73  int64_t next_pts;
75  int remaining;
76 
77  char *gain_cmd;
79  const char *gain;
80  const char *gain_entry;
81  double delay;
82  double accuracy;
83  int wfunc;
84  int fixed;
85  int multi;
87 
90  GainEntry gain_entry_tbl[NB_GAIN_ENTRY_MAX];
92 
93 #define OFFSET(x) offsetof(FIREqualizerContext, x)
94 #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
95 
96 static const AVOption firequalizer_options[] = {
97  { "gain", "set gain curve", OFFSET(gain), AV_OPT_TYPE_STRING, { .str = "gain_interpolate(f)" }, 0, 0, FLAGS },
98  { "gain_entry", "set gain entry", OFFSET(gain_entry), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, FLAGS },
99  { "delay", "set delay", OFFSET(delay), AV_OPT_TYPE_DOUBLE, { .dbl = 0.01 }, 0.0, 1e10, FLAGS },
100  { "accuracy", "set accuracy", OFFSET(accuracy), AV_OPT_TYPE_DOUBLE, { .dbl = 5.0 }, 0.0, 1e10, FLAGS },
101  { "wfunc", "set window function", OFFSET(wfunc), AV_OPT_TYPE_INT, { .i64 = WFUNC_HANN }, WFUNC_MIN, WFUNC_MAX, FLAGS, "wfunc" },
102  { "rectangular", "rectangular window", 0, AV_OPT_TYPE_CONST, { .i64 = WFUNC_RECTANGULAR }, 0, 0, FLAGS, "wfunc" },
103  { "hann", "hann window", 0, AV_OPT_TYPE_CONST, { .i64 = WFUNC_HANN }, 0, 0, FLAGS, "wfunc" },
104  { "hamming", "hamming window", 0, AV_OPT_TYPE_CONST, { .i64 = WFUNC_HAMMING }, 0, 0, FLAGS, "wfunc" },
105  { "blackman", "blackman window", 0, AV_OPT_TYPE_CONST, { .i64 = WFUNC_BLACKMAN }, 0, 0, FLAGS, "wfunc" },
106  { "nuttall3", "3-term nuttall window", 0, AV_OPT_TYPE_CONST, { .i64 = WFUNC_NUTTALL3 }, 0, 0, FLAGS, "wfunc" },
107  { "mnuttall3", "minimum 3-term nuttall window", 0, AV_OPT_TYPE_CONST, { .i64 = WFUNC_MNUTTALL3 }, 0, 0, FLAGS, "wfunc" },
108  { "nuttall", "nuttall window", 0, AV_OPT_TYPE_CONST, { .i64 = WFUNC_NUTTALL }, 0, 0, FLAGS, "wfunc" },
109  { "bnuttall", "blackman-nuttall window", 0, AV_OPT_TYPE_CONST, { .i64 = WFUNC_BNUTTALL }, 0, 0, FLAGS, "wfunc" },
110  { "bharris", "blackman-harris window", 0, AV_OPT_TYPE_CONST, { .i64 = WFUNC_BHARRIS }, 0, 0, FLAGS, "wfunc" },
111  { "fixed", "set fixed frame samples", OFFSET(fixed), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS },
112  { "multi", "set multi channels mode", OFFSET(multi), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS },
113  { "zero_phase", "set zero phase mode", OFFSET(zero_phase), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS },
114  { NULL }
115 };
116 
117 AVFILTER_DEFINE_CLASS(firequalizer);
118 
120 {
122  av_rdft_end(s->rdft);
123  av_rdft_end(s->irdft);
124  s->analysis_irdft = s->rdft = s->irdft = NULL;
125 
126  av_freep(&s->analysis_buf);
128  av_freep(&s->kernel_buf);
129  av_freep(&s->conv_buf);
130  av_freep(&s->conv_idx);
131 }
132 
134 {
135  FIREqualizerContext *s = ctx->priv;
136 
137  common_uninit(s);
138  av_freep(&s->gain_cmd);
140 }
141 
143 {
146  static const enum AVSampleFormat sample_fmts[] = {
149  };
150  int ret;
151 
152  layouts = ff_all_channel_counts();
153  if (!layouts)
154  return AVERROR(ENOMEM);
155  ret = ff_set_common_channel_layouts(ctx, layouts);
156  if (ret < 0)
157  return ret;
158 
159  formats = ff_make_format_list(sample_fmts);
160  if (!formats)
161  return AVERROR(ENOMEM);
162  ret = ff_set_common_formats(ctx, formats);
163  if (ret < 0)
164  return ret;
165 
166  formats = ff_all_samplerates();
167  if (!formats)
168  return AVERROR(ENOMEM);
169  return ff_set_common_samplerates(ctx, formats);
170 }
171 
172 static void fast_convolute(FIREqualizerContext *s, const float *kernel_buf, float *conv_buf,
173  OverlapIndex *idx, float *data, int nsamples)
174 {
175  if (nsamples <= s->nsamples_max) {
176  float *buf = conv_buf + idx->buf_idx * s->rdft_len;
177  float *obuf = conv_buf + !idx->buf_idx * s->rdft_len + idx->overlap_idx;
178  int k;
179 
180  memcpy(buf, data, nsamples * sizeof(*data));
181  memset(buf + nsamples, 0, (s->rdft_len - nsamples) * sizeof(*data));
182  av_rdft_calc(s->rdft, buf);
183 
184  buf[0] *= kernel_buf[0];
185  buf[1] *= kernel_buf[1];
186  for (k = 2; k < s->rdft_len; k += 2) {
187  float re, im;
188  re = buf[k] * kernel_buf[k] - buf[k+1] * kernel_buf[k+1];
189  im = buf[k] * kernel_buf[k+1] + buf[k+1] * kernel_buf[k];
190  buf[k] = re;
191  buf[k+1] = im;
192  }
193 
194  av_rdft_calc(s->irdft, buf);
195  for (k = 0; k < s->rdft_len - idx->overlap_idx; k++)
196  buf[k] += obuf[k];
197  memcpy(data, buf, nsamples * sizeof(*data));
198  idx->buf_idx = !idx->buf_idx;
199  idx->overlap_idx = nsamples;
200  } else {
201  while (nsamples > s->nsamples_max * 2) {
202  fast_convolute(s, kernel_buf, conv_buf, idx, data, s->nsamples_max);
203  data += s->nsamples_max;
204  nsamples -= s->nsamples_max;
205  }
206  fast_convolute(s, kernel_buf, conv_buf, idx, data, nsamples/2);
207  fast_convolute(s, kernel_buf, conv_buf, idx, data + nsamples/2, nsamples - nsamples/2);
208  }
209 }
210 
211 static double entry_func(void *p, double freq, double gain)
212 {
213  AVFilterContext *ctx = p;
214  FIREqualizerContext *s = ctx->priv;
215 
216  if (s->nb_gain_entry >= NB_GAIN_ENTRY_MAX) {
217  av_log(ctx, AV_LOG_ERROR, "entry table overflow.\n");
218  s->gain_entry_err = AVERROR(EINVAL);
219  return 0;
220  }
221 
222  if (isnan(freq)) {
223  av_log(ctx, AV_LOG_ERROR, "nan frequency (%g, %g).\n", freq, gain);
224  s->gain_entry_err = AVERROR(EINVAL);
225  return 0;
226  }
227 
228  if (s->nb_gain_entry > 0 && freq <= s->gain_entry_tbl[s->nb_gain_entry - 1].freq) {
229  av_log(ctx, AV_LOG_ERROR, "unsorted frequency (%g, %g).\n", freq, gain);
230  s->gain_entry_err = AVERROR(EINVAL);
231  return 0;
232  }
233 
234  s->gain_entry_tbl[s->nb_gain_entry].freq = freq;
235  s->gain_entry_tbl[s->nb_gain_entry].gain = gain;
236  s->nb_gain_entry++;
237  return 0;
238 }
239 
240 static int gain_entry_compare(const void *key, const void *memb)
241 {
242  const double *freq = key;
243  const GainEntry *entry = memb;
244 
245  if (*freq < entry[0].freq)
246  return -1;
247  if (*freq > entry[1].freq)
248  return 1;
249  return 0;
250 }
251 
252 static double gain_interpolate_func(void *p, double freq)
253 {
254  AVFilterContext *ctx = p;
255  FIREqualizerContext *s = ctx->priv;
256  GainEntry *res;
257  double d0, d1, d;
258 
259  if (isnan(freq))
260  return freq;
261 
262  if (!s->nb_gain_entry)
263  return 0;
264 
265  if (freq <= s->gain_entry_tbl[0].freq)
266  return s->gain_entry_tbl[0].gain;
267 
268  if (freq >= s->gain_entry_tbl[s->nb_gain_entry-1].freq)
269  return s->gain_entry_tbl[s->nb_gain_entry-1].gain;
270 
271  res = bsearch(&freq, &s->gain_entry_tbl, s->nb_gain_entry - 1, sizeof(*res), gain_entry_compare);
272  av_assert0(res);
273 
274  d = res[1].freq - res[0].freq;
275  d0 = freq - res[0].freq;
276  d1 = res[1].freq - freq;
277 
278  if (d0 && d1)
279  return (d0 * res[1].gain + d1 * res[0].gain) / d;
280 
281  if (d0)
282  return res[1].gain;
283 
284  return res[0].gain;
285 }
286 
287 static const char *const var_names[] = {
288  "f",
289  "sr",
290  "ch",
291  "chid",
292  "chs",
293  "chlayout",
294  NULL
295 };
296 
297 enum VarOffset {
305 };
306 
307 static int generate_kernel(AVFilterContext *ctx, const char *gain, const char *gain_entry)
308 {
309  FIREqualizerContext *s = ctx->priv;
310  AVFilterLink *inlink = ctx->inputs[0];
311  const char *gain_entry_func_names[] = { "entry", NULL };
312  const char *gain_func_names[] = { "gain_interpolate", NULL };
313  double (*gain_entry_funcs[])(void *, double, double) = { entry_func, NULL };
314  double (*gain_funcs[])(void *, double) = { gain_interpolate_func, NULL };
315  double vars[VAR_NB];
316  AVExpr *gain_expr;
317  int ret, k, center, ch;
318 
319  s->nb_gain_entry = 0;
320  s->gain_entry_err = 0;
321  if (gain_entry) {
322  double result = 0.0;
323  ret = av_expr_parse_and_eval(&result, gain_entry, NULL, NULL, NULL, NULL,
324  gain_entry_func_names, gain_entry_funcs, ctx, 0, ctx);
325  if (ret < 0)
326  return ret;
327  if (s->gain_entry_err < 0)
328  return s->gain_entry_err;
329  }
330 
331  av_log(ctx, AV_LOG_DEBUG, "nb_gain_entry = %d.\n", s->nb_gain_entry);
332 
333  ret = av_expr_parse(&gain_expr, gain, var_names,
334  gain_func_names, gain_funcs, NULL, NULL, 0, ctx);
335  if (ret < 0)
336  return ret;
337 
338  vars[VAR_CHS] = inlink->channels;
339  vars[VAR_CHLAYOUT] = inlink->channel_layout;
340  vars[VAR_SR] = inlink->sample_rate;
341  for (ch = 0; ch < inlink->channels; ch++) {
342  vars[VAR_CH] = ch;
344  vars[VAR_F] = 0.0;
345  s->analysis_buf[0] = pow(10.0, 0.05 * av_expr_eval(gain_expr, vars, ctx));
346  vars[VAR_F] = 0.5 * inlink->sample_rate;
347  s->analysis_buf[1] = pow(10.0, 0.05 * av_expr_eval(gain_expr, vars, ctx));
348 
349  for (k = 1; k < s->analysis_rdft_len/2; k++) {
350  vars[VAR_F] = k * ((double)inlink->sample_rate /(double)s->analysis_rdft_len);
351  s->analysis_buf[2*k] = pow(10.0, 0.05 * av_expr_eval(gain_expr, vars, ctx));
352  s->analysis_buf[2*k+1] = 0.0;
353  }
354 
356  center = s->fir_len / 2;
357 
358  for (k = 0; k <= center; k++) {
359  double u = k * (M_PI/center);
360  double win;
361  switch (s->wfunc) {
362  case WFUNC_RECTANGULAR:
363  win = 1.0;
364  break;
365  case WFUNC_HANN:
366  win = 0.5 + 0.5 * cos(u);
367  break;
368  case WFUNC_HAMMING:
369  win = 0.53836 + 0.46164 * cos(u);
370  break;
371  case WFUNC_BLACKMAN:
372  win = 0.48 + 0.5 * cos(u) + 0.02 * cos(2*u);
373  break;
374  case WFUNC_NUTTALL3:
375  win = 0.40897 + 0.5 * cos(u) + 0.09103 * cos(2*u);
376  break;
377  case WFUNC_MNUTTALL3:
378  win = 0.4243801 + 0.4973406 * cos(u) + 0.0782793 * cos(2*u);
379  break;
380  case WFUNC_NUTTALL:
381  win = 0.355768 + 0.487396 * cos(u) + 0.144232 * cos(2*u) + 0.012604 * cos(3*u);
382  break;
383  case WFUNC_BNUTTALL:
384  win = 0.3635819 + 0.4891775 * cos(u) + 0.1365995 * cos(2*u) + 0.0106411 * cos(3*u);
385  break;
386  case WFUNC_BHARRIS:
387  win = 0.35875 + 0.48829 * cos(u) + 0.14128 * cos(2*u) + 0.01168 * cos(3*u);
388  break;
389  default:
390  av_assert0(0);
391  }
392  s->analysis_buf[k] *= (2.0/s->analysis_rdft_len) * (2.0/s->rdft_len) * win;
393  }
394 
395  for (k = 0; k < center - k; k++) {
396  float tmp = s->analysis_buf[k];
397  s->analysis_buf[k] = s->analysis_buf[center - k];
398  s->analysis_buf[center - k] = tmp;
399  }
400 
401  for (k = 1; k <= center; k++)
402  s->analysis_buf[center + k] = s->analysis_buf[center - k];
403 
404  memset(s->analysis_buf + s->fir_len, 0, (s->rdft_len - s->fir_len) * sizeof(*s->analysis_buf));
406 
407  for (k = 0; k < s->rdft_len; k++) {
408  if (isnan(s->analysis_buf[k]) || isinf(s->analysis_buf[k])) {
409  av_log(ctx, AV_LOG_ERROR, "filter kernel contains nan or infinity.\n");
410  av_expr_free(gain_expr);
411  return AVERROR(EINVAL);
412  }
413  }
414 
415  memcpy(s->kernel_tmp_buf + ch * s->rdft_len, s->analysis_buf, s->rdft_len * sizeof(*s->analysis_buf));
416  if (!s->multi)
417  break;
418  }
419 
420  memcpy(s->kernel_buf, s->kernel_tmp_buf, (s->multi ? inlink->channels : 1) * s->rdft_len * sizeof(*s->kernel_buf));
421  av_expr_free(gain_expr);
422  return 0;
423 }
424 
425 static int config_input(AVFilterLink *inlink)
426 {
427  AVFilterContext *ctx = inlink->dst;
428  FIREqualizerContext *s = ctx->priv;
429  int rdft_bits;
430 
431  common_uninit(s);
432 
433  s->next_pts = 0;
434  s->frame_nsamples_max = 0;
435 
436  s->fir_len = FFMAX(2 * (int)(inlink->sample_rate * s->delay) + 1, 3);
437  s->remaining = s->fir_len - 1;
438 
439  for (rdft_bits = RDFT_BITS_MIN; rdft_bits <= RDFT_BITS_MAX; rdft_bits++) {
440  s->rdft_len = 1 << rdft_bits;
441  s->nsamples_max = s->rdft_len - s->fir_len + 1;
442  if (s->nsamples_max * 2 >= s->fir_len)
443  break;
444  }
445 
446  if (rdft_bits > RDFT_BITS_MAX) {
447  av_log(ctx, AV_LOG_ERROR, "too large delay, please decrease it.\n");
448  return AVERROR(EINVAL);
449  }
450 
451  if (!(s->rdft = av_rdft_init(rdft_bits, DFT_R2C)) || !(s->irdft = av_rdft_init(rdft_bits, IDFT_C2R)))
452  return AVERROR(ENOMEM);
453 
454  for ( ; rdft_bits <= RDFT_BITS_MAX; rdft_bits++) {
455  s->analysis_rdft_len = 1 << rdft_bits;
456  if (inlink->sample_rate <= s->accuracy * s->analysis_rdft_len)
457  break;
458  }
459 
460  if (rdft_bits > RDFT_BITS_MAX) {
461  av_log(ctx, AV_LOG_ERROR, "too small accuracy, please increase it.\n");
462  return AVERROR(EINVAL);
463  }
464 
465  if (!(s->analysis_irdft = av_rdft_init(rdft_bits, IDFT_C2R)))
466  return AVERROR(ENOMEM);
467 
469  s->kernel_tmp_buf = av_malloc_array(s->rdft_len * (s->multi ? inlink->channels : 1), sizeof(*s->kernel_tmp_buf));
470  s->kernel_buf = av_malloc_array(s->rdft_len * (s->multi ? inlink->channels : 1), sizeof(*s->kernel_buf));
471  s->conv_buf = av_calloc(2 * s->rdft_len * inlink->channels, sizeof(*s->conv_buf));
472  s->conv_idx = av_calloc(inlink->channels, sizeof(*s->conv_idx));
473  if (!s->analysis_buf || !s->kernel_tmp_buf || !s->kernel_buf || !s->conv_buf || !s->conv_idx)
474  return AVERROR(ENOMEM);
475 
476  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",
477  inlink->sample_rate, inlink->channels, s->analysis_rdft_len, s->rdft_len, s->fir_len, s->nsamples_max);
478 
479  if (s->fixed)
480  inlink->min_samples = inlink->max_samples = inlink->partial_buf_size = s->nsamples_max;
481 
482  return generate_kernel(ctx, s->gain_cmd ? s->gain_cmd : s->gain,
484 }
485 
486 static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
487 {
488  AVFilterContext *ctx = inlink->dst;
489  FIREqualizerContext *s = ctx->priv;
490  int ch;
491 
492  for (ch = 0; ch < inlink->channels; ch++) {
493  fast_convolute(s, s->kernel_buf + (s->multi ? ch * s->rdft_len : 0),
494  s->conv_buf + 2 * ch * s->rdft_len, s->conv_idx + ch,
495  (float *) frame->extended_data[ch], frame->nb_samples);
496  }
497 
499  if (frame->pts != AV_NOPTS_VALUE) {
500  s->next_pts = frame->pts + av_rescale_q(frame->nb_samples, av_make_q(1, inlink->sample_rate), inlink->time_base);
501  if (s->zero_phase)
502  frame->pts -= av_rescale_q(s->fir_len/2, av_make_q(1, inlink->sample_rate), inlink->time_base);
503  }
505  return ff_filter_frame(ctx->outputs[0], frame);
506 }
507 
508 static int request_frame(AVFilterLink *outlink)
509 {
510  AVFilterContext *ctx = outlink->src;
511  FIREqualizerContext *s= ctx->priv;
512  int ret;
513 
514  ret = ff_request_frame(ctx->inputs[0]);
515  if (ret == AVERROR_EOF && s->remaining > 0 && s->frame_nsamples_max > 0) {
517 
518  if (!frame)
519  return AVERROR(ENOMEM);
520 
521  av_samples_set_silence(frame->extended_data, 0, frame->nb_samples, outlink->channels, frame->format);
522  frame->pts = s->next_pts;
523  s->remaining -= frame->nb_samples;
524  ret = filter_frame(ctx->inputs[0], frame);
525  }
526 
527  return ret;
528 }
529 
530 static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
531  char *res, int res_len, int flags)
532 {
533  FIREqualizerContext *s = ctx->priv;
534  int ret = AVERROR(ENOSYS);
535 
536  if (!strcmp(cmd, "gain")) {
537  char *gain_cmd;
538 
539  gain_cmd = av_strdup(args);
540  if (!gain_cmd)
541  return AVERROR(ENOMEM);
542 
543  ret = generate_kernel(ctx, gain_cmd, s->gain_entry_cmd ? s->gain_entry_cmd : s->gain_entry);
544  if (ret >= 0) {
545  av_freep(&s->gain_cmd);
546  s->gain_cmd = gain_cmd;
547  } else {
548  av_freep(&gain_cmd);
549  }
550  } else if (!strcmp(cmd, "gain_entry")) {
551  char *gain_entry_cmd;
552 
553  gain_entry_cmd = av_strdup(args);
554  if (!gain_entry_cmd)
555  return AVERROR(ENOMEM);
556 
557  ret = generate_kernel(ctx, s->gain_cmd ? s->gain_cmd : s->gain, gain_entry_cmd);
558  if (ret >= 0) {
560  s->gain_entry_cmd = gain_entry_cmd;
561  } else {
562  av_freep(&gain_entry_cmd);
563  }
564  }
565 
566  return ret;
567 }
568 
570  {
571  .name = "default",
572  .config_props = config_input,
573  .filter_frame = filter_frame,
574  .type = AVMEDIA_TYPE_AUDIO,
575  .needs_writable = 1,
576  },
577  { NULL }
578 };
579 
581  {
582  .name = "default",
583  .request_frame = request_frame,
584  .type = AVMEDIA_TYPE_AUDIO,
585  },
586  { NULL }
587 };
588 
590  .name = "firequalizer",
591  .description = NULL_IF_CONFIG_SMALL("Finite Impulse Response Equalizer."),
592  .uninit = uninit,
593  .query_formats = query_formats,
594  .process_command = process_command,
595  .priv_size = sizeof(FIREqualizerContext),
596  .inputs = firequalizer_inputs,
597  .outputs = firequalizer_outputs,
598  .priv_class = &firequalizer_class,
599 };
float, planar
Definition: samplefmt.h:69
#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:549
const char * s
Definition: avisynth_c.h:631
#define isinf(x)
Definition: libm.h:317
This structure describes decoded (raw) audio or video data.
Definition: frame.h:184
AVOption.
Definition: opt.h:245
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:101
float re
Definition: fft.c:73
RDFTContext * rdft
static void common_uninit(FIREqualizerContext *s)
Main libavfilter public API header.
static double gain_interpolate_func(void *p, double freq)
static enum AVSampleFormat formats[]
Definition: avresample.c:163
static int request_frame(AVFilterLink *outlink)
static int config_input(AVFilterLink *inlink)
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:658
static AVRational av_make_q(int num, int den)
Create a rational.
Definition: rational.h:53
#define NB_GAIN_ENTRY_MAX
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:283
#define RDFT_BITS_MIN
static const AVFilterPad firequalizer_outputs[]
const char * name
Pad name.
Definition: internal.h:59
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:313
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
VarOffset
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1180
RDFTContext * irdft
#define av_cold
Definition: attributes.h:82
AVOptions.
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:268
#define RDFT_BITS_MAX
Definition: eval.c:149
static AVFrame * frame
static const char *const var_names[]
#define AVERROR_EOF
End of file.
Definition: error.h:55
#define av_log(a,...)
A filter pad used for either input or output.
Definition: internal.h:53
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
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:723
#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:568
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:235
static void fast_convolute(FIREqualizerContext *s, const float *kernel_buf, float *conv_buf, OverlapIndex *idx, float *data, int nsamples)
AVFrame * ff_get_audio_buffer(AVFilterLink *link, int nb_samples)
Request an audio samples buffer with a specific set of permissions.
Definition: audio.c:65
#define AVERROR(e)
Definition: error.h:43
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:176
AVFILTER_DEFINE_CLASS(firequalizer)
void * priv
private data for use by the filter
Definition: avfilter.h:320
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
simple assert() macros that are a bit more flexible than ISO C assert().
Definition: avfft.h:73
#define FFMAX(a, b)
Definition: common.h:94
RDFTContext * analysis_irdft
static av_cold void uninit(AVFilterContext *ctx)
static const AVOption firequalizer_options[]
void av_rdft_calc(RDFTContext *s, FFTSample *data)
static const AVFilterPad firequalizer_inputs[]
WindowFunc
#define FFMIN(a, b)
Definition: common.h:96
AVFormatContext * ctx
Definition: movenc.c:48
#define FLAGS
const char * gain_entry
Definition: avfft.h:72
void av_rdft_end(RDFTContext *s)
RDFTContext * av_rdft_init(int nbits, enum RDFTransformType trans)
Set up a real FFT.
static const AVFilterPad outputs[]
Definition: af_afftfilt.c:386
OverlapIndex * conv_idx
A list of supported channel layouts.
Definition: formats.h:85
static double entry_func(void *p, double freq, double gain)
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
Definition: frame.h:248
static const uint8_t vars[2][12]
Definition: camellia.c:179
static const AVFilterPad inputs[]
Definition: af_afftfilt.c:376
#define OFFSET(x)
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
Definition: eval.c:318
char * av_strdup(const char *s)
Duplicate the string s.
Definition: mem.c:267
AVFilter ff_af_firequalizer
FFT functions.
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
void * buf
Definition: avisynth_c.h:553
Describe the class of an AVClass context structure.
Definition: log.h:67
Filter definition.
Definition: avfilter.h:142
#define isnan(x)
Definition: libm.h:340
float im
Definition: fft.c:73
GainEntry gain_entry_tbl[NB_GAIN_ENTRY_MAX]
const char * name
Filter name.
Definition: avfilter.h:146
#define u(width,...)
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:317
enum MovChannelLayoutTag * layouts
Definition: mov_chan.c:434
AVFilterFormats * ff_all_samplerates(void)
Definition: formats.c:395
void * av_calloc(size_t nmemb, size_t size)
Allocate a block of nmemb * size bytes with alignment suitable for all memory accesses (including vec...
Definition: mem.c:260
static int flags
Definition: cpu.c:47
uint64_t av_channel_layout_extract_channel(uint64_t channel_layout, int index)
Get the channel with the given index in channel_layout.
static int query_formats(AVFilterContext *ctx)
static int generate_kernel(AVFilterContext *ctx, const char *gain, const char *gain_entry)
double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
Evaluate a previously parsed expression.
Definition: eval.c:713
static uint8_t tmp[8]
Definition: des.c:38
A list of supported formats for one end of a filter link.
Definition: formats.h:64
static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
An instance of a filter.
Definition: avfilter.h:305
static enum AVSampleFormat sample_fmts[]
Definition: adpcmenc.c:701
#define av_freep(p)
#define M_PI
Definition: mathematics.h:46
#define av_malloc_array(a, b)
static int gain_entry_compare(const void *key, const void *memb)
int ff_request_frame(AVFilterLink *link)
Request an input frame from the filter at the other end of the link.
Definition: avfilter.c:369
internal API functions
AVFilterChannelLayouts * ff_all_channel_counts(void)
Construct an AVFilterChannelLayouts coding for any channel layout, with known or unknown disposition...
Definition: formats.c:410
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: frame.h:231
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:241
int ff_set_common_samplerates(AVFilterContext *ctx, AVFilterFormats *samplerates)
Definition: formats.c:556
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:240
simple arithmetic expression evaluator