FFmpeg
asrc_afirsrc.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 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 License
8  * 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
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with FFmpeg; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include "libavutil/cpu.h"
23 #include "libavutil/ffmath.h"
24 #include "libavutil/eval.h"
25 #include "libavutil/mem.h"
26 #include "libavutil/opt.h"
27 #include "libavutil/tx.h"
28 #include "audio.h"
29 #include "avfilter.h"
30 #include "filters.h"
31 #include "formats.h"
32 #include "window_func.h"
33 
34 typedef struct AudioFIRSourceContext {
35  const AVClass *class;
36 
39  char *phase_str;
40  int nb_taps;
43  int win_func;
44  int preset;
45  int interp;
46  int phaset;
47 
49  float *freq;
50  float *magnitude;
51  float *phase;
52  int freq_size;
55  int nb_freq;
57  int nb_phase;
58 
59  float *taps;
60  float *win;
62 
66 
67 #define OFFSET(x) offsetof(AudioFIRSourceContext, x)
68 #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
69 
70 static const AVOption afirsrc_options[] = {
71  { "taps", "set number of taps", OFFSET(nb_taps), AV_OPT_TYPE_INT, {.i64=1025}, 9, UINT16_MAX, FLAGS },
72  { "t", "set number of taps", OFFSET(nb_taps), AV_OPT_TYPE_INT, {.i64=1025}, 9, UINT16_MAX, FLAGS },
73  { "frequency", "set frequency points", OFFSET(freq_points_str), AV_OPT_TYPE_STRING, {.str="0 1"}, 0, 0, FLAGS },
74  { "f", "set frequency points", OFFSET(freq_points_str), AV_OPT_TYPE_STRING, {.str="0 1"}, 0, 0, FLAGS },
75  { "magnitude", "set magnitude values", OFFSET(magnitude_str), AV_OPT_TYPE_STRING, {.str="1 1"}, 0, 0, FLAGS },
76  { "m", "set magnitude values", OFFSET(magnitude_str), AV_OPT_TYPE_STRING, {.str="1 1"}, 0, 0, FLAGS },
77  { "phase", "set phase values", OFFSET(phase_str), AV_OPT_TYPE_STRING, {.str="0 0"}, 0, 0, FLAGS },
78  { "p", "set phase values", OFFSET(phase_str), AV_OPT_TYPE_STRING, {.str="0 0"}, 0, 0, FLAGS },
79  { "sample_rate", "set sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64=44100}, 1, INT_MAX, FLAGS },
80  { "r", "set sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64=44100}, 1, INT_MAX, FLAGS },
81  { "nb_samples", "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64 = 1024}, 1, INT_MAX, FLAGS },
82  { "n", "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64 = 1024}, 1, INT_MAX, FLAGS },
83  WIN_FUNC_OPTION("win_func", OFFSET(win_func), FLAGS, WFUNC_BLACKMAN),
84  WIN_FUNC_OPTION("w", OFFSET(win_func), FLAGS, WFUNC_BLACKMAN),
85  {NULL}
86 };
87 
88 AVFILTER_DEFINE_CLASS(afirsrc);
89 
91 {
92  AudioFIRSourceContext *s = ctx->priv;
93 
94  if (!(s->nb_taps & 1)) {
95  av_log(s, AV_LOG_WARNING, "Number of taps %d must be odd length.\n", s->nb_taps);
96  s->nb_taps |= 1;
97  }
98 
99  return 0;
100 }
101 
103 {
104  AudioFIRSourceContext *s = ctx->priv;
105 
106  av_freep(&s->win);
107  av_freep(&s->taps);
108  av_freep(&s->freq);
109  av_freep(&s->magnitude);
110  av_freep(&s->phase);
111  av_freep(&s->complexf);
112  av_tx_uninit(&s->tx_ctx);
113  av_tx_uninit(&s->itx_ctx);
114 }
115 
117  AVFilterFormatsConfig **cfg_in,
118  AVFilterFormatsConfig **cfg_out)
119 {
120  const AudioFIRSourceContext *s = ctx->priv;
121  static const AVChannelLayout chlayouts[] = { AV_CHANNEL_LAYOUT_MONO, { 0 } };
122  int sample_rates[] = { s->sample_rate, -1 };
123  static const enum AVSampleFormat sample_fmts[] = {
126  };
127  int ret = ff_set_common_formats_from_list2(ctx, cfg_in, cfg_out, sample_fmts);
128  if (ret < 0)
129  return ret;
130 
131  ret = ff_set_common_channel_layouts_from_list2(ctx, cfg_in, cfg_out, chlayouts);
132  if (ret < 0)
133  return ret;
134 
135  return ff_set_common_samplerates_from_list2(ctx, cfg_in, cfg_out, sample_rates);
136 }
137 
138 static int parse_string(char *str, float **items, int *nb_items, int *items_size)
139 {
140  float *new_items;
141  char *tail;
142 
143  new_items = av_fast_realloc(NULL, items_size, sizeof(float));
144  if (!new_items)
145  return AVERROR(ENOMEM);
146  *items = new_items;
147 
148  tail = str;
149  if (!tail)
150  return AVERROR(EINVAL);
151 
152  do {
153  (*items)[(*nb_items)++] = av_strtod(tail, &tail);
154  new_items = av_fast_realloc(*items, items_size, (*nb_items + 2) * sizeof(float));
155  if (!new_items)
156  return AVERROR(ENOMEM);
157  *items = new_items;
158  if (tail && *tail)
159  tail++;
160  } while (tail && *tail);
161 
162  return 0;
163 }
164 
165 static void lininterp(AVComplexFloat *complexf,
166  const float *freq,
167  const float *magnitude,
168  const float *phase,
169  int m, int minterp)
170 {
171  for (int i = 0; i < minterp; i++) {
172  for (int j = 1; j < m; j++) {
173  const float x = i / (float)minterp;
174 
175  if (x <= freq[j]) {
176  const float mg = (x - freq[j-1]) / (freq[j] - freq[j-1]) * (magnitude[j] - magnitude[j-1]) + magnitude[j-1];
177  const float ph = (x - freq[j-1]) / (freq[j] - freq[j-1]) * (phase[j] - phase[j-1]) + phase[j-1];
178 
179  complexf[i].re = mg * cosf(ph);
180  complexf[i].im = mg * sinf(ph);
181  break;
182  }
183  }
184  }
185 }
186 
187 static av_cold int config_output(AVFilterLink *outlink)
188 {
189  AVFilterContext *ctx = outlink->src;
190  AudioFIRSourceContext *s = ctx->priv;
191  float overlap, scale = 1.f, compensation;
192  int fft_size, middle, ret;
193 
194  s->nb_freq = s->nb_magnitude = s->nb_phase = 0;
195 
196  ret = parse_string(s->freq_points_str, &s->freq, &s->nb_freq, &s->freq_size);
197  if (ret < 0)
198  return ret;
199 
200  ret = parse_string(s->magnitude_str, &s->magnitude, &s->nb_magnitude, &s->magnitude_size);
201  if (ret < 0)
202  return ret;
203 
204  ret = parse_string(s->phase_str, &s->phase, &s->nb_phase, &s->phase_size);
205  if (ret < 0)
206  return ret;
207 
208  if (s->nb_freq != s->nb_magnitude && s->nb_freq != s->nb_phase && s->nb_freq >= 2) {
209  av_log(ctx, AV_LOG_ERROR, "Number of frequencies, magnitudes and phases must be same and >= 2.\n");
210  return AVERROR(EINVAL);
211  }
212 
213  for (int i = 0; i < s->nb_freq; i++) {
214  if (i == 0 && s->freq[i] != 0.f) {
215  av_log(ctx, AV_LOG_ERROR, "First frequency must be 0.\n");
216  return AVERROR(EINVAL);
217  }
218 
219  if (i == s->nb_freq - 1 && s->freq[i] != 1.f) {
220  av_log(ctx, AV_LOG_ERROR, "Last frequency must be 1.\n");
221  return AVERROR(EINVAL);
222  }
223 
224  if (i && s->freq[i] < s->freq[i-1]) {
225  av_log(ctx, AV_LOG_ERROR, "Frequencies must be in increasing order.\n");
226  return AVERROR(EINVAL);
227  }
228  }
229 
230  fft_size = 1 << (av_log2(s->nb_taps) + 1);
231  s->complexf = av_calloc(fft_size * 2, sizeof(*s->complexf));
232  if (!s->complexf)
233  return AVERROR(ENOMEM);
234 
235  ret = av_tx_init(&s->tx_ctx, &s->tx_fn, AV_TX_FLOAT_FFT, 1, fft_size, &scale, 0);
236  if (ret < 0)
237  return ret;
238 
239  s->taps = av_calloc(s->nb_taps, sizeof(*s->taps));
240  if (!s->taps)
241  return AVERROR(ENOMEM);
242 
243  s->win = av_calloc(s->nb_taps, sizeof(*s->win));
244  if (!s->win)
245  return AVERROR(ENOMEM);
246 
247  generate_window_func(s->win, s->nb_taps, s->win_func, &overlap);
248 
249  lininterp(s->complexf, s->freq, s->magnitude, s->phase, s->nb_freq, fft_size / 2);
250 
251  s->tx_fn(s->tx_ctx, s->complexf + fft_size, s->complexf, sizeof(*s->complexf));
252 
253  compensation = 2.f / fft_size;
254  middle = s->nb_taps / 2;
255 
256  for (int i = 0; i <= middle; i++) {
257  s->taps[ i] = s->complexf[fft_size + middle - i].re * compensation * s->win[i];
258  s->taps[middle + i] = s->complexf[fft_size + i].re * compensation * s->win[middle + i];
259  }
260 
261  s->pts = 0;
262 
263  return 0;
264 }
265 
267 {
268  AVFilterLink *outlink = ctx->outputs[0];
269  AudioFIRSourceContext *s = ctx->priv;
270  AVFrame *frame;
271  int nb_samples;
272 
273  if (!ff_outlink_frame_wanted(outlink))
274  return FFERROR_NOT_READY;
275 
276  nb_samples = FFMIN(s->nb_samples, s->nb_taps - s->pts);
277  if (nb_samples <= 0) {
278  ff_outlink_set_status(outlink, AVERROR_EOF, s->pts);
279  return 0;
280  }
281 
282  if (!(frame = ff_get_audio_buffer(outlink, nb_samples)))
283  return AVERROR(ENOMEM);
284 
285  memcpy(frame->data[0], s->taps + s->pts, nb_samples * sizeof(float));
286 
287  frame->pts = s->pts;
288  s->pts += nb_samples;
289  return ff_filter_frame(outlink, frame);
290 }
291 
292 static const AVFilterPad afirsrc_outputs[] = {
293  {
294  .name = "default",
295  .type = AVMEDIA_TYPE_AUDIO,
296  .config_props = config_output,
297  },
298 };
299 
301  .name = "afirsrc",
302  .description = NULL_IF_CONFIG_SMALL("Generate a FIR coefficients audio stream."),
303  .init = init,
304  .uninit = uninit,
305  .activate = activate,
306  .priv_size = sizeof(AudioFIRSourceContext),
307  .inputs = NULL,
310  .priv_class = &afirsrc_class,
311 };
312 
313 #define DEFAULT_BANDS "25 40 63 100 160 250 400 630 1000 1600 2500 4000 6300 10000 16000 24000"
314 
315 typedef struct EqPreset {
316  char name[16];
317  float gains[16];
318 } EqPreset;
319 
320 static const EqPreset eq_presets[] = {
321  { "flat", { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
322  { "acoustic", { 5.0, 4.5, 4.0, 3.5, 1.5, 1.0, 1.5, 1.5, 2.0, 3.0, 3.5, 4.0, 3.7, 3.0, 3.0 } },
323  { "bass", { 10.0, 8.8, 8.5, 6.5, 2.5, 1.5, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
324  { "beats", { -5.5, -5.0, -4.5, -4.2, -3.5, -3.0, -1.9, 0, 0, 0, 0, 0, 0, 0, 0 } },
325  { "classic", { -0.3, 0.3, -3.5, -9.0, -1.0, 0.0, 1.8, 2.1, 0.0, 0.0, 0.0, 4.4, 9.0, 9.0, 9.0 } },
326  { "clear", { 3.5, 5.5, 6.5, 9.5, 8.0, 6.5, 3.5, 2.5, 1.3, 5.0, 7.0, 9.0, 10.0, 11.0, 9.0 } },
327  { "deep bass", { 12.0, 8.0, 0.0, -6.7, -12.0, -9.0, -3.5, -3.5, -6.1, 0.0, -3.0, -5.0, 0.0, 1.2, 3.0 } },
328  { "dubstep", { 12.0, 10.0, 0.5, -1.0, -3.0, -5.0, -5.0, -4.8, -4.5, -2.5, -1.0, 0.0, -2.5, -2.5, 0.0 } },
329  { "electronic", { 4.0, 4.0, 3.5, 1.0, 0.0, -0.5, -2.0, 0.0, 2.0, 0.0, 0.0, 1.0, 3.0, 4.0, 4.5 } },
330  { "hardstyle", { 6.1, 7.0, 12.0, 6.1, -5.0, -12.0, -2.5, 3.0, 6.5, 0.0, -2.2, -4.5, -6.1, -9.2, -10.0 } },
331  { "hip-hop", { 4.5, 4.3, 4.0, 2.5, 1.5, 3.0, -1.0, -1.5, -1.5, 1.5, 0.0, -1.0, 0.0, 1.5, 3.0 } },
332  { "jazz", { 0.0, 0.0, 0.0, 2.0, 4.0, 5.9, -5.9, -4.5, -2.5, 2.5, 1.0, -0.8, -0.8, -0.8, -0.8 } },
333  { "metal", { 10.5, 10.5, 7.5, 0.0, 2.0, 5.5, 0.0, 0.0, 0.0, 6.1, 0.0, 0.0, 6.1, 10.0, 12.0 } },
334  { "movie", { 3.0, 3.0, 6.1, 8.5, 9.0, 7.0, 6.1, 6.1, 5.0, 8.0, 3.5, 3.5, 8.0, 10.0, 8.0 } },
335  { "pop", { 0.0, 0.0, 0.0, 0.0, 0.0, 1.3, 2.0, 2.5, 5.0, -1.5, -2.0, -3.0, -3.0, -3.0, -3.0 } },
336  { "r&b", { 3.0, 3.0, 7.0, 6.1, 4.5, 1.5, -1.5, -2.0, -1.5, 2.0, 2.5, 3.0, 3.5, 3.8, 4.0 } },
337  { "rock", { 0.0, 0.0, 0.0, 3.0, 3.0, -10.0, -4.0, -1.0, 0.8, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0 } },
338  { "vocal booster", { -1.5, -2.0, -3.0, -3.0, -0.5, 1.5, 3.5, 3.5, 3.5, 3.0, 2.0, 1.5, 0.0, 0.0, -1.5 } },
339 };
340 
341 static const AVOption afireqsrc_options[] = {
342  { "preset","set equalizer preset", OFFSET(preset), AV_OPT_TYPE_INT, {.i64=0}, -1, FF_ARRAY_ELEMS(eq_presets)-1, FLAGS, .unit = "preset" },
343  { "p", "set equalizer preset", OFFSET(preset), AV_OPT_TYPE_INT, {.i64=0}, -1, FF_ARRAY_ELEMS(eq_presets)-1, FLAGS, .unit = "preset" },
344  { "custom", NULL, 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, FLAGS, .unit = "preset" },
345  { eq_presets[ 0].name, NULL, 0, AV_OPT_TYPE_CONST, {.i64= 0}, 0, 0, FLAGS, .unit = "preset" },
346  { eq_presets[ 1].name, NULL, 0, AV_OPT_TYPE_CONST, {.i64= 1}, 0, 0, FLAGS, .unit = "preset" },
347  { eq_presets[ 2].name, NULL, 0, AV_OPT_TYPE_CONST, {.i64= 2}, 0, 0, FLAGS, .unit = "preset" },
348  { eq_presets[ 3].name, NULL, 0, AV_OPT_TYPE_CONST, {.i64= 3}, 0, 0, FLAGS, .unit = "preset" },
349  { eq_presets[ 4].name, NULL, 0, AV_OPT_TYPE_CONST, {.i64= 4}, 0, 0, FLAGS, .unit = "preset" },
350  { eq_presets[ 5].name, NULL, 0, AV_OPT_TYPE_CONST, {.i64= 5}, 0, 0, FLAGS, .unit = "preset" },
351  { eq_presets[ 6].name, NULL, 0, AV_OPT_TYPE_CONST, {.i64= 6}, 0, 0, FLAGS, .unit = "preset" },
352  { eq_presets[ 7].name, NULL, 0, AV_OPT_TYPE_CONST, {.i64= 7}, 0, 0, FLAGS, .unit = "preset" },
353  { eq_presets[ 8].name, NULL, 0, AV_OPT_TYPE_CONST, {.i64= 8}, 0, 0, FLAGS, .unit = "preset" },
354  { eq_presets[ 9].name, NULL, 0, AV_OPT_TYPE_CONST, {.i64= 9}, 0, 0, FLAGS, .unit = "preset" },
355  { eq_presets[10].name, NULL, 0, AV_OPT_TYPE_CONST, {.i64=10}, 0, 0, FLAGS, .unit = "preset" },
356  { eq_presets[11].name, NULL, 0, AV_OPT_TYPE_CONST, {.i64=11}, 0, 0, FLAGS, .unit = "preset" },
357  { eq_presets[12].name, NULL, 0, AV_OPT_TYPE_CONST, {.i64=12}, 0, 0, FLAGS, .unit = "preset" },
358  { eq_presets[13].name, NULL, 0, AV_OPT_TYPE_CONST, {.i64=13}, 0, 0, FLAGS, .unit = "preset" },
359  { eq_presets[14].name, NULL, 0, AV_OPT_TYPE_CONST, {.i64=14}, 0, 0, FLAGS, .unit = "preset" },
360  { eq_presets[15].name, NULL, 0, AV_OPT_TYPE_CONST, {.i64=15}, 0, 0, FLAGS, .unit = "preset" },
361  { eq_presets[16].name, NULL, 0, AV_OPT_TYPE_CONST, {.i64=16}, 0, 0, FLAGS, .unit = "preset" },
362  { eq_presets[17].name, NULL, 0, AV_OPT_TYPE_CONST, {.i64=17}, 0, 0, FLAGS, .unit = "preset" },
363  { "gains", "set gain values per band", OFFSET(magnitude_str), AV_OPT_TYPE_STRING, {.str="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"}, 0, 0, FLAGS },
364  { "g", "set gain values per band", OFFSET(magnitude_str), AV_OPT_TYPE_STRING, {.str="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"}, 0, 0, FLAGS },
365  { "bands", "set central frequency values per band", OFFSET(freq_points_str), AV_OPT_TYPE_STRING, {.str=DEFAULT_BANDS}, 0, 0, FLAGS },
366  { "b", "set central frequency values per band", OFFSET(freq_points_str), AV_OPT_TYPE_STRING, {.str=DEFAULT_BANDS}, 0, 0, FLAGS },
367  { "taps", "set number of taps", OFFSET(nb_taps), AV_OPT_TYPE_INT, {.i64=4096}, 16, UINT16_MAX, FLAGS },
368  { "t", "set number of taps", OFFSET(nb_taps), AV_OPT_TYPE_INT, {.i64=4096}, 16, UINT16_MAX, FLAGS },
369  { "sample_rate", "set sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64=44100}, 1, INT_MAX, FLAGS },
370  { "r", "set sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64=44100}, 1, INT_MAX, FLAGS },
371  { "nb_samples", "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64 = 1024}, 1, INT_MAX, FLAGS },
372  { "n", "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64 = 1024}, 1, INT_MAX, FLAGS },
373  { "interp","set the interpolation", OFFSET(interp), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, .unit = "interp" },
374  { "i", "set the interpolation", OFFSET(interp), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, .unit = "interp" },
375  { "linear", NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, .unit = "interp" },
376  { "cubic", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, .unit = "interp" },
377  { "phase","set the phase", OFFSET(phaset), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS, .unit = "phase" },
378  { "h", "set the phase", OFFSET(phaset), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS, .unit = "phase" },
379  { "linear", "linear phase", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, .unit = "phase" },
380  { "min", "minimum phase", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, .unit = "phase" },
381  {NULL}
382 };
383 
384 AVFILTER_DEFINE_CLASS(afireqsrc);
385 
386 static void eq_interp(AVComplexFloat *complexf,
387  const float *freq,
388  const float *magnitude,
389  int m, int interp, int minterp,
390  const float factor)
391 {
392  for (int i = 0; i < minterp; i++) {
393  for (int j = 0; j < m; j++) {
394  const float x = factor * i;
395 
396  if (x <= freq[j+1]) {
397  float g;
398 
399  if (interp == 0) {
400  const float d = freq[j+1] - freq[j];
401  const float d0 = x - freq[j];
402  const float d1 = freq[j+1] - x;
403  const float g0 = magnitude[j];
404  const float g1 = magnitude[j+1];
405 
406  if (d0 && d1) {
407  g = (d0 * g1 + d1 * g0) / d;
408  } else if (d0) {
409  g = g1;
410  } else {
411  g = g0;
412  }
413  } else {
414  if (x <= freq[j]) {
415  g = magnitude[j];
416  } else {
417  float x1, x2, x3;
418  float a, b, c, d;
419  float m0, m1, m2, msum;
420  const float unit = freq[j+1] - freq[j];
421 
422  m0 = j != 0 ? unit * (magnitude[j] - magnitude[j-1]) / (freq[j] - freq[j-1]) : 0;
423  m1 = magnitude[j+1] - magnitude[j];
424  m2 = j != minterp - 1 ? unit * (magnitude[j+2] - magnitude[j+1]) / (freq[j+2] - freq[j+1]) : 0;
425 
426  msum = fabsf(m0) + fabsf(m1);
427  m0 = msum > 0.f ? (fabsf(m0) * m1 + fabsf(m1) * m0) / msum : 0.f;
428  msum = fabsf(m1) + fabsf(m2);
429  m1 = msum > 0.f ? (fabsf(m1) * m2 + fabsf(m2) * m1) / msum : 0.f;
430 
431  d = magnitude[j];
432  c = m0;
433  b = 3.f * magnitude[j+1] - m1 - 2.f * c - 3.f * d;
434  a = magnitude[j+1] - b - c - d;
435 
436  x1 = (x - freq[j]) / unit;
437  x2 = x1 * x1;
438  x3 = x2 * x1;
439 
440  g = a * x3 + b * x2 + c * x1 + d;
441  }
442  }
443 
444  complexf[i].re = g;
445  complexf[i].im = 0;
446  complexf[minterp * 2 - i - 1].re = g;
447  complexf[minterp * 2 - i - 1].im = 0;
448 
449  break;
450  }
451  }
452  }
453 }
454 
456 {
457  AVFilterContext *ctx = outlink->src;
458  AudioFIRSourceContext *s = ctx->priv;
459  int fft_size, middle, asize, ret;
460  float scale, factor;
461 
462  s->nb_freq = s->nb_magnitude = 0;
463  if (s->preset < 0) {
464  ret = parse_string(s->freq_points_str, &s->freq, &s->nb_freq, &s->freq_size);
465  if (ret < 0)
466  return ret;
467 
468  ret = parse_string(s->magnitude_str, &s->magnitude, &s->nb_magnitude, &s->magnitude_size);
469  if (ret < 0)
470  return ret;
471  } else {
472  char *freq_str;
473 
474  s->nb_magnitude = FF_ARRAY_ELEMS(eq_presets[s->preset].gains);
475 
476  freq_str = av_strdup(DEFAULT_BANDS);
477  if (!freq_str)
478  return AVERROR(ENOMEM);
479 
480  ret = parse_string(freq_str, &s->freq, &s->nb_freq, &s->freq_size);
481  av_free(freq_str);
482  if (ret < 0)
483  return ret;
484 
485  s->magnitude = av_calloc(s->nb_magnitude + 1, sizeof(*s->magnitude));
486  if (!s->magnitude)
487  return AVERROR(ENOMEM);
488  memcpy(s->magnitude, eq_presets[s->preset].gains, sizeof(*s->magnitude) * s->nb_magnitude);
489  }
490 
491  if (s->nb_freq != s->nb_magnitude || s->nb_freq < 2) {
492  av_log(ctx, AV_LOG_ERROR, "Number of bands and gains must be same and >= 2.\n");
493  return AVERROR(EINVAL);
494  }
495 
496  s->freq[s->nb_freq] = outlink->sample_rate * 0.5f;
497  s->magnitude[s->nb_freq] = s->magnitude[s->nb_freq-1];
498 
499  fft_size = s->nb_taps * 2;
500  factor = FFMIN(outlink->sample_rate * 0.5f, s->freq[s->nb_freq - 1]) / (float)fft_size;
501  asize = FFALIGN(fft_size, av_cpu_max_align());
502  s->complexf = av_calloc(asize * 2, sizeof(*s->complexf));
503  if (!s->complexf)
504  return AVERROR(ENOMEM);
505 
506  scale = 1.f;
507  ret = av_tx_init(&s->itx_ctx, &s->itx_fn, AV_TX_FLOAT_FFT, 1, fft_size, &scale, 0);
508  if (ret < 0)
509  return ret;
510 
511  s->taps = av_calloc(s->nb_taps, sizeof(*s->taps));
512  if (!s->taps)
513  return AVERROR(ENOMEM);
514 
515  eq_interp(s->complexf, s->freq, s->magnitude, s->nb_freq, s->interp, s->nb_taps, factor);
516 
517  for (int i = 0; i < fft_size; i++)
518  s->complexf[i].re = ff_exp10f(s->complexf[i].re / 20.f);
519 
520  if (s->phaset) {
521  const float threshold = powf(10.f, -100.f / 20.f);
522  const float logt = logf(threshold);
523 
524  scale = 1.f;
525  ret = av_tx_init(&s->tx_ctx, &s->tx_fn, AV_TX_FLOAT_FFT, 0, fft_size, &scale, 0);
526  if (ret < 0)
527  return ret;
528 
529  for (int i = 0; i < fft_size; i++)
530  s->complexf[i].re = s->complexf[i].re < threshold ? logt : logf(s->complexf[i].re);
531 
532  s->itx_fn(s->itx_ctx, s->complexf + asize, s->complexf, sizeof(float));
533  for (int i = 0; i < fft_size; i++) {
534  s->complexf[i + asize].re /= fft_size;
535  s->complexf[i + asize].im /= fft_size;
536  }
537 
538  for (int i = 1; i < s->nb_taps; i++) {
539  s->complexf[asize + i].re += s->complexf[asize + fft_size - i].re;
540  s->complexf[asize + i].im -= s->complexf[asize + fft_size - i].im;
541  s->complexf[asize + fft_size - i].re = 0.f;
542  s->complexf[asize + fft_size - i].im = 0.f;
543  }
544  s->complexf[asize + s->nb_taps - 1].im *= -1.f;
545 
546  s->tx_fn(s->tx_ctx, s->complexf, s->complexf + asize, sizeof(float));
547 
548  for (int i = 0; i < fft_size; i++) {
549  float eR = expf(s->complexf[i].re);
550 
551  s->complexf[i].re = eR * cosf(s->complexf[i].im);
552  s->complexf[i].im = eR * sinf(s->complexf[i].im);
553  }
554 
555  s->itx_fn(s->itx_ctx, s->complexf + asize, s->complexf, sizeof(float));
556 
557  for (int i = 0; i < s->nb_taps; i++)
558  s->taps[i] = s->complexf[i + asize].re / fft_size;
559  } else {
560  s->itx_fn(s->itx_ctx, s->complexf + asize, s->complexf, sizeof(float));
561 
562  middle = s->nb_taps / 2;
563  for (int i = 0; i < middle; i++) {
564  s->taps[middle - i] = s->complexf[i + asize].re / fft_size;
565  s->taps[middle + i] = s->complexf[i + asize].re / fft_size;
566  }
567  }
568 
569  s->pts = 0;
570 
571  return 0;
572 }
573 
574 static const AVFilterPad afireqsrc_outputs[] = {
575  {
576  .name = "default",
577  .type = AVMEDIA_TYPE_AUDIO,
578  .config_props = config_eq_output,
579  },
580 };
581 
583  .name = "afireqsrc",
584  .description = NULL_IF_CONFIG_SMALL("Generate a FIR equalizer coefficients audio stream."),
585  .uninit = uninit,
586  .activate = activate,
587  .priv_size = sizeof(AudioFIRSourceContext),
588  .inputs = NULL,
591  .priv_class = &afireqsrc_class,
592 };
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:98
AudioFIRSourceContext::phase_str
char * phase_str
Definition: asrc_afirsrc.c:39
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:215
lininterp
static void lininterp(AVComplexFloat *complexf, const float *freq, const float *magnitude, const float *phase, int m, int minterp)
Definition: asrc_afirsrc.c:165
AudioFIRSourceContext::nb_samples
int nb_samples
Definition: asrc_afirsrc.c:42
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
afirsrc_options
static const AVOption afirsrc_options[]
Definition: asrc_afirsrc.c:70
AudioFIRSourceContext
Definition: asrc_afirsrc.c:34
DEFAULT_BANDS
#define DEFAULT_BANDS
Definition: asrc_afirsrc.c:313
afireqsrc_options
static const AVOption afireqsrc_options[]
Definition: asrc_afirsrc.c:341
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1062
sample_fmts
static enum AVSampleFormat sample_fmts[]
Definition: adpcmenc.c:948
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
FFERROR_NOT_READY
return FFERROR_NOT_READY
Definition: filter_design.txt:204
AudioFIRSourceContext::freq_points_str
char * freq_points_str
Definition: asrc_afirsrc.c:37
AVTXContext
Definition: tx_priv.h:235
int64_t
long long int64_t
Definition: coverity.c:34
eq_interp
static void eq_interp(AVComplexFloat *complexf, const float *freq, const float *magnitude, int m, int interp, int minterp, const float factor)
Definition: asrc_afirsrc.c:386
activate
static int activate(AVFilterContext *ctx)
Definition: asrc_afirsrc.c:266
ph
static int FUNC() ph(CodedBitstreamContext *ctx, RWContext *rw, H266RawPH *current)
Definition: cbs_h266_syntax_template.c:3042
sample_rates
static const int sample_rates[]
Definition: dcaenc.h:34
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:389
eq_presets
static const EqPreset eq_presets[]
Definition: asrc_afirsrc.c:320
AudioFIRSourceContext::nb_freq
int nb_freq
Definition: asrc_afirsrc.c:55
AVOption
AVOption.
Definition: opt.h:429
b
#define b
Definition: input.c:41
AudioFIRSourceContext::phase
float * phase
Definition: asrc_afirsrc.c:51
expf
#define expf(x)
Definition: libm.h:283
ff_set_common_channel_layouts_from_list2
int ff_set_common_channel_layouts_from_list2(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out, const AVChannelLayout *fmts)
Definition: formats.c:920
AVComplexFloat
Definition: tx.h:27
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: asrc_afirsrc.c:102
WIN_FUNC_OPTION
#define WIN_FUNC_OPTION(win_func_opt_name, win_func_offset, flag, default_window_func)
Definition: window_func.h:37
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:205
ff_asrc_afirsrc
const AVFilter ff_asrc_afirsrc
Definition: asrc_afirsrc.c:300
av_tx_init
av_cold int av_tx_init(AVTXContext **ctx, av_tx_fn *tx, enum AVTXType type, int inv, int len, const void *scale, uint64_t flags)
Initialize a transform context with the given configuration (i)MDCTs with an odd length are currently...
Definition: tx.c:903
AudioFIRSourceContext::complexf
AVComplexFloat * complexf
Definition: asrc_afirsrc.c:48
formats.h
WFUNC_BLACKMAN
@ WFUNC_BLACKMAN
Definition: af_firequalizer.c:39
AVComplexFloat::im
float im
Definition: tx.h:28
AudioFIRSourceContext::nb_taps
int nb_taps
Definition: asrc_afirsrc.c:40
ff_asrc_afireqsrc
const AVFilter ff_asrc_afireqsrc
Definition: asrc_afirsrc.c:582
cosf
#define cosf(x)
Definition: libm.h:78
interp
interp
Definition: vf_curves.c:62
OFFSET
#define OFFSET(x)
Definition: asrc_afirsrc.c:67
config_eq_output
static av_cold int config_eq_output(AVFilterLink *outlink)
Definition: asrc_afirsrc.c:455
fabsf
static __device__ float fabsf(float a)
Definition: cuda_runtime.h:181
afireqsrc_outputs
static const AVFilterPad afireqsrc_outputs[]
Definition: asrc_afirsrc.c:574
AVFilterPad
A filter pad used for either input or output.
Definition: filters.h:38
preset
preset
Definition: vf_curves.c:47
AudioFIRSourceContext::magnitude
float * magnitude
Definition: asrc_afirsrc.c:50
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:209
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
av_cold
#define av_cold
Definition: attributes.h:90
av_tx_fn
void(* av_tx_fn)(AVTXContext *s, void *out, void *in, ptrdiff_t stride)
Function pointer to a function to perform the transform.
Definition: tx.h:151
float
float
Definition: af_crystalizer.c:122
ff_outlink_set_status
static void ff_outlink_set_status(AVFilterLink *link, int status, int64_t pts)
Set the status field of a link from the source filter.
Definition: filters.h:424
av_fast_realloc
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given buffer if it is not large enough, otherwise do nothing.
Definition: mem.c:497
s
#define s(width, name)
Definition: cbs_vp9.c:198
parse_string
static int parse_string(char *str, float **items, int *nb_items, int *items_size)
Definition: asrc_afirsrc.c:138
g
const char * g
Definition: vf_curves.c:128
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
filters.h
AV_TX_FLOAT_FFT
@ AV_TX_FLOAT_FFT
Standard complex to complex FFT with sample data type of AVComplexFloat, AVComplexDouble or AVComplex...
Definition: tx.h:47
ff_set_common_samplerates_from_list2
int ff_set_common_samplerates_from_list2(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out, const int *samplerates)
Definition: formats.c:944
ctx
AVFormatContext * ctx
Definition: movenc.c:49
mg
#define mg
Definition: vf_colormatrix.c:104
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: filters.h:263
AudioFIRSourceContext::nb_phase
int nb_phase
Definition: asrc_afirsrc.c:57
AudioFIRSourceContext::interp
int interp
Definition: asrc_afirsrc.c:45
AudioFIRSourceContext::win_func
int win_func
Definition: asrc_afirsrc.c:43
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:75
NULL
#define NULL
Definition: coverity.c:32
AudioFIRSourceContext::nb_magnitude
int nb_magnitude
Definition: asrc_afirsrc.c:56
av_cpu_max_align
size_t av_cpu_max_align(void)
Get the maximum data alignment that may be required by FFmpeg.
Definition: cpu.c:276
generate_window_func
static void generate_window_func(float *lut, int N, int win_func, float *overlap)
Definition: window_func.h:63
sinf
#define sinf(x)
Definition: libm.h:419
AudioFIRSourceContext::itx_ctx
AVTXContext * itx_ctx
Definition: asrc_afirsrc.c:63
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
EqPreset::gains
float gains[16]
Definition: asrc_afirsrc.c:317
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
AVFilterFormatsConfig
Lists of formats / etc.
Definition: avfilter.h:111
eval.h
f
f
Definition: af_crystalizer.c:122
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:94
powf
#define powf(x, y)
Definition: libm.h:50
AudioFIRSourceContext::itx_fn
av_tx_fn itx_fn
Definition: asrc_afirsrc.c:64
AVChannelLayout
An AVChannelLayout holds information about the channel layout of audio data.
Definition: channel_layout.h:317
cpu.h
AV_SAMPLE_FMT_NONE
@ AV_SAMPLE_FMT_NONE
Definition: samplefmt.h:56
AVComplexFloat::re
float re
Definition: tx.h:28
AudioFIRSourceContext::sample_rate
int sample_rate
Definition: asrc_afirsrc.c:41
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(afirsrc)
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
AudioFIRSourceContext::magnitude_str
char * magnitude_str
Definition: asrc_afirsrc.c:38
AudioFIRSourceContext::pts
int64_t pts
Definition: asrc_afirsrc.c:61
EqPreset
Definition: asrc_afirsrc.c:315
av_tx_uninit
av_cold void av_tx_uninit(AVTXContext **ctx)
Frees a context and sets *ctx to NULL, does nothing when *ctx == NULL.
Definition: tx.c:295
AudioFIRSourceContext::preset
int preset
Definition: asrc_afirsrc.c:44
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
AudioFIRSourceContext::freq_size
int freq_size
Definition: asrc_afirsrc.c:52
AVSampleFormat
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:55
FILTER_QUERY_FUNC2
#define FILTER_QUERY_FUNC2(func)
Definition: filters.h:239
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
AVFilterPad::name
const char * name
Pad name.
Definition: filters.h:44
EqPreset::name
char name[16]
Definition: asrc_afirsrc.c:316
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
AVFilter
Filter definition.
Definition: avfilter.h:201
AudioFIRSourceContext::win
float * win
Definition: asrc_afirsrc.c:60
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
av_strtod
double av_strtod(const char *numstr, char **tail)
Parse the string in numstr and return its value as a double.
Definition: eval.c:107
AudioFIRSourceContext::tx_fn
av_tx_fn tx_fn
Definition: asrc_afirsrc.c:64
window_func.h
query_formats
static av_cold int query_formats(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out)
Definition: asrc_afirsrc.c:116
ff_set_common_formats_from_list2
int ff_set_common_formats_from_list2(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out, const int *fmts)
Definition: formats.c:1016
channel_layout.h
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:259
avfilter.h
AudioFIRSourceContext::taps
float * taps
Definition: asrc_afirsrc.c:59
AudioFIRSourceContext::magnitude_size
int magnitude_size
Definition: asrc_afirsrc.c:53
ffmath.h
AVFilterContext
An instance of a filter.
Definition: avfilter.h:457
factor
static const int factor[16]
Definition: vf_pp7.c:80
av_strdup
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:272
mem.h
audio.h
AV_CHANNEL_LAYOUT_MONO
#define AV_CHANNEL_LAYOUT_MONO
Definition: channel_layout.h:392
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
scale
static void scale(int *out, const int *in, const int w, const int h, const int shift)
Definition: intra.c:291
AudioFIRSourceContext::tx_ctx
AVTXContext * tx_ctx
Definition: asrc_afirsrc.c:63
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
FLAGS
#define FLAGS
Definition: asrc_afirsrc.c:68
ff_exp10f
static av_always_inline float ff_exp10f(float x)
Definition: ffmath.h:47
AudioFIRSourceContext::phase_size
int phase_size
Definition: asrc_afirsrc.c:54
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
ff_outlink_frame_wanted
the definition of that something depends on the semantic of the filter The callback must examine the status of the filter s links and proceed accordingly The status of output links is stored in the status_in and status_out fields and tested by the ff_outlink_frame_wanted() function. If this function returns true
AudioFIRSourceContext::phaset
int phaset
Definition: asrc_afirsrc.c:46
init
static av_cold int init(AVFilterContext *ctx)
Definition: asrc_afirsrc.c:90
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
Definition: opt.h:276
afirsrc_outputs
static const AVFilterPad afirsrc_outputs[]
Definition: asrc_afirsrc.c:292
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition: opt.h:299
av_log2
int av_log2(unsigned v)
Definition: intmath.c:26
AV_SAMPLE_FMT_FLT
@ AV_SAMPLE_FMT_FLT
float
Definition: samplefmt.h:60
config_output
static av_cold int config_output(AVFilterLink *outlink)
Definition: asrc_afirsrc.c:187
tx.h
AudioFIRSourceContext::freq
float * freq
Definition: asrc_afirsrc.c:49