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  .p.name = "afirsrc",
302  .p.description = NULL_IF_CONFIG_SMALL("Generate a FIR coefficients audio stream."),
303  .p.priv_class = &afirsrc_class,
304  .init = init,
305  .uninit = uninit,
306  .activate = activate,
307  .priv_size = sizeof(AudioFIRSourceContext),
310 };
311 
312 #define DEFAULT_BANDS "25 40 63 100 160 250 400 630 1000 1600 2500 4000 6300 10000 16000 24000"
313 
314 typedef struct EqPreset {
315  char name[16];
316  float gains[16];
317 } EqPreset;
318 
319 static const EqPreset eq_presets[] = {
320  { "flat", { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
321  { "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 } },
322  { "bass", { 10.0, 8.8, 8.5, 6.5, 2.5, 1.5, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
323  { "beats", { -5.5, -5.0, -4.5, -4.2, -3.5, -3.0, -1.9, 0, 0, 0, 0, 0, 0, 0, 0 } },
324  { "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 } },
325  { "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 } },
326  { "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 } },
327  { "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 } },
328  { "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 } },
329  { "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 } },
330  { "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 } },
331  { "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 } },
332  { "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 } },
333  { "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 } },
334  { "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 } },
335  { "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 } },
336  { "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 } },
337  { "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 } },
338 };
339 
340 static const AVOption afireqsrc_options[] = {
341  { "preset","set equalizer preset", OFFSET(preset), AV_OPT_TYPE_INT, {.i64=0}, -1, FF_ARRAY_ELEMS(eq_presets)-1, FLAGS, .unit = "preset" },
342  { "p", "set equalizer preset", OFFSET(preset), AV_OPT_TYPE_INT, {.i64=0}, -1, FF_ARRAY_ELEMS(eq_presets)-1, FLAGS, .unit = "preset" },
343  { "custom", NULL, 0, AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0, FLAGS, .unit = "preset" },
344  { eq_presets[ 0].name, NULL, 0, AV_OPT_TYPE_CONST, {.i64= 0}, 0, 0, FLAGS, .unit = "preset" },
345  { eq_presets[ 1].name, NULL, 0, AV_OPT_TYPE_CONST, {.i64= 1}, 0, 0, FLAGS, .unit = "preset" },
346  { eq_presets[ 2].name, NULL, 0, AV_OPT_TYPE_CONST, {.i64= 2}, 0, 0, FLAGS, .unit = "preset" },
347  { eq_presets[ 3].name, NULL, 0, AV_OPT_TYPE_CONST, {.i64= 3}, 0, 0, FLAGS, .unit = "preset" },
348  { eq_presets[ 4].name, NULL, 0, AV_OPT_TYPE_CONST, {.i64= 4}, 0, 0, FLAGS, .unit = "preset" },
349  { eq_presets[ 5].name, NULL, 0, AV_OPT_TYPE_CONST, {.i64= 5}, 0, 0, FLAGS, .unit = "preset" },
350  { eq_presets[ 6].name, NULL, 0, AV_OPT_TYPE_CONST, {.i64= 6}, 0, 0, FLAGS, .unit = "preset" },
351  { eq_presets[ 7].name, NULL, 0, AV_OPT_TYPE_CONST, {.i64= 7}, 0, 0, FLAGS, .unit = "preset" },
352  { eq_presets[ 8].name, NULL, 0, AV_OPT_TYPE_CONST, {.i64= 8}, 0, 0, FLAGS, .unit = "preset" },
353  { eq_presets[ 9].name, NULL, 0, AV_OPT_TYPE_CONST, {.i64= 9}, 0, 0, FLAGS, .unit = "preset" },
354  { eq_presets[10].name, NULL, 0, AV_OPT_TYPE_CONST, {.i64=10}, 0, 0, FLAGS, .unit = "preset" },
355  { eq_presets[11].name, NULL, 0, AV_OPT_TYPE_CONST, {.i64=11}, 0, 0, FLAGS, .unit = "preset" },
356  { eq_presets[12].name, NULL, 0, AV_OPT_TYPE_CONST, {.i64=12}, 0, 0, FLAGS, .unit = "preset" },
357  { eq_presets[13].name, NULL, 0, AV_OPT_TYPE_CONST, {.i64=13}, 0, 0, FLAGS, .unit = "preset" },
358  { eq_presets[14].name, NULL, 0, AV_OPT_TYPE_CONST, {.i64=14}, 0, 0, FLAGS, .unit = "preset" },
359  { eq_presets[15].name, NULL, 0, AV_OPT_TYPE_CONST, {.i64=15}, 0, 0, FLAGS, .unit = "preset" },
360  { eq_presets[16].name, NULL, 0, AV_OPT_TYPE_CONST, {.i64=16}, 0, 0, FLAGS, .unit = "preset" },
361  { eq_presets[17].name, NULL, 0, AV_OPT_TYPE_CONST, {.i64=17}, 0, 0, FLAGS, .unit = "preset" },
362  { "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 },
363  { "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 },
364  { "bands", "set central frequency values per band", OFFSET(freq_points_str), AV_OPT_TYPE_STRING, {.str=DEFAULT_BANDS}, 0, 0, FLAGS },
365  { "b", "set central frequency values per band", OFFSET(freq_points_str), AV_OPT_TYPE_STRING, {.str=DEFAULT_BANDS}, 0, 0, FLAGS },
366  { "taps", "set number of taps", OFFSET(nb_taps), AV_OPT_TYPE_INT, {.i64=4096}, 16, UINT16_MAX, FLAGS },
367  { "t", "set number of taps", OFFSET(nb_taps), AV_OPT_TYPE_INT, {.i64=4096}, 16, UINT16_MAX, FLAGS },
368  { "sample_rate", "set sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64=44100}, 1, INT_MAX, FLAGS },
369  { "r", "set sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64=44100}, 1, INT_MAX, FLAGS },
370  { "nb_samples", "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64 = 1024}, 1, INT_MAX, FLAGS },
371  { "n", "set the number of samples per requested frame", OFFSET(nb_samples), AV_OPT_TYPE_INT, {.i64 = 1024}, 1, INT_MAX, FLAGS },
372  { "interp","set the interpolation", OFFSET(interp), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, .unit = "interp" },
373  { "i", "set the interpolation", OFFSET(interp), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, .unit = "interp" },
374  { "linear", NULL, 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, .unit = "interp" },
375  { "cubic", NULL, 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, .unit = "interp" },
376  { "phase","set the phase", OFFSET(phaset), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS, .unit = "phase" },
377  { "h", "set the phase", OFFSET(phaset), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, FLAGS, .unit = "phase" },
378  { "linear", "linear phase", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, .unit = "phase" },
379  { "min", "minimum phase", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, .unit = "phase" },
380  {NULL}
381 };
382 
383 AVFILTER_DEFINE_CLASS(afireqsrc);
384 
385 static void eq_interp(AVComplexFloat *complexf,
386  const float *freq,
387  const float *magnitude,
388  int m, int interp, int minterp,
389  const float factor)
390 {
391  for (int i = 0; i < minterp; i++) {
392  for (int j = 0; j < m; j++) {
393  const float x = factor * i;
394 
395  if (x <= freq[j+1]) {
396  float g;
397 
398  if (interp == 0) {
399  const float d = freq[j+1] - freq[j];
400  const float d0 = x - freq[j];
401  const float d1 = freq[j+1] - x;
402  const float g0 = magnitude[j];
403  const float g1 = magnitude[j+1];
404 
405  if (d0 && d1) {
406  g = (d0 * g1 + d1 * g0) / d;
407  } else if (d0) {
408  g = g1;
409  } else {
410  g = g0;
411  }
412  } else {
413  if (x <= freq[j]) {
414  g = magnitude[j];
415  } else {
416  float x1, x2, x3;
417  float a, b, c, d;
418  float m0, m1, m2, msum;
419  const float unit = freq[j+1] - freq[j];
420 
421  m0 = j != 0 ? unit * (magnitude[j] - magnitude[j-1]) / (freq[j] - freq[j-1]) : 0;
422  m1 = magnitude[j+1] - magnitude[j];
423  m2 = j != minterp - 1 ? unit * (magnitude[j+2] - magnitude[j+1]) / (freq[j+2] - freq[j+1]) : 0;
424 
425  msum = fabsf(m0) + fabsf(m1);
426  m0 = msum > 0.f ? (fabsf(m0) * m1 + fabsf(m1) * m0) / msum : 0.f;
427  msum = fabsf(m1) + fabsf(m2);
428  m1 = msum > 0.f ? (fabsf(m1) * m2 + fabsf(m2) * m1) / msum : 0.f;
429 
430  d = magnitude[j];
431  c = m0;
432  b = 3.f * magnitude[j+1] - m1 - 2.f * c - 3.f * d;
433  a = magnitude[j+1] - b - c - d;
434 
435  x1 = (x - freq[j]) / unit;
436  x2 = x1 * x1;
437  x3 = x2 * x1;
438 
439  g = a * x3 + b * x2 + c * x1 + d;
440  }
441  }
442 
443  complexf[i].re = g;
444  complexf[i].im = 0;
445  complexf[minterp * 2 - i - 1].re = g;
446  complexf[minterp * 2 - i - 1].im = 0;
447 
448  break;
449  }
450  }
451  }
452 }
453 
455 {
456  AVFilterContext *ctx = outlink->src;
457  AudioFIRSourceContext *s = ctx->priv;
458  int fft_size, middle, asize, ret;
459  float scale, factor;
460 
461  s->nb_freq = s->nb_magnitude = 0;
462  if (s->preset < 0) {
463  ret = parse_string(s->freq_points_str, &s->freq, &s->nb_freq, &s->freq_size);
464  if (ret < 0)
465  return ret;
466 
467  ret = parse_string(s->magnitude_str, &s->magnitude, &s->nb_magnitude, &s->magnitude_size);
468  if (ret < 0)
469  return ret;
470  } else {
471  char *freq_str;
472 
473  s->nb_magnitude = FF_ARRAY_ELEMS(eq_presets[s->preset].gains);
474 
475  freq_str = av_strdup(DEFAULT_BANDS);
476  if (!freq_str)
477  return AVERROR(ENOMEM);
478 
479  ret = parse_string(freq_str, &s->freq, &s->nb_freq, &s->freq_size);
480  av_free(freq_str);
481  if (ret < 0)
482  return ret;
483 
484  s->magnitude = av_calloc(s->nb_magnitude + 1, sizeof(*s->magnitude));
485  if (!s->magnitude)
486  return AVERROR(ENOMEM);
487  memcpy(s->magnitude, eq_presets[s->preset].gains, sizeof(*s->magnitude) * s->nb_magnitude);
488  }
489 
490  if (s->nb_freq != s->nb_magnitude || s->nb_freq < 2) {
491  av_log(ctx, AV_LOG_ERROR, "Number of bands and gains must be same and >= 2.\n");
492  return AVERROR(EINVAL);
493  }
494 
495  s->freq[s->nb_freq] = outlink->sample_rate * 0.5f;
496  s->magnitude[s->nb_freq] = s->magnitude[s->nb_freq-1];
497 
498  fft_size = s->nb_taps * 2;
499  factor = FFMIN(outlink->sample_rate * 0.5f, s->freq[s->nb_freq - 1]) / (float)fft_size;
500  asize = FFALIGN(fft_size, av_cpu_max_align());
501  s->complexf = av_calloc(asize * 2, sizeof(*s->complexf));
502  if (!s->complexf)
503  return AVERROR(ENOMEM);
504 
505  scale = 1.f;
506  ret = av_tx_init(&s->itx_ctx, &s->itx_fn, AV_TX_FLOAT_FFT, 1, fft_size, &scale, 0);
507  if (ret < 0)
508  return ret;
509 
510  s->taps = av_calloc(s->nb_taps, sizeof(*s->taps));
511  if (!s->taps)
512  return AVERROR(ENOMEM);
513 
514  eq_interp(s->complexf, s->freq, s->magnitude, s->nb_freq, s->interp, s->nb_taps, factor);
515 
516  for (int i = 0; i < fft_size; i++)
517  s->complexf[i].re = ff_exp10f(s->complexf[i].re / 20.f);
518 
519  if (s->phaset) {
520  const float threshold = powf(10.f, -100.f / 20.f);
521  const float logt = logf(threshold);
522 
523  scale = 1.f;
524  ret = av_tx_init(&s->tx_ctx, &s->tx_fn, AV_TX_FLOAT_FFT, 0, fft_size, &scale, 0);
525  if (ret < 0)
526  return ret;
527 
528  for (int i = 0; i < fft_size; i++)
529  s->complexf[i].re = s->complexf[i].re < threshold ? logt : logf(s->complexf[i].re);
530 
531  s->itx_fn(s->itx_ctx, s->complexf + asize, s->complexf, sizeof(float));
532  for (int i = 0; i < fft_size; i++) {
533  s->complexf[i + asize].re /= fft_size;
534  s->complexf[i + asize].im /= fft_size;
535  }
536 
537  for (int i = 1; i < s->nb_taps; i++) {
538  s->complexf[asize + i].re += s->complexf[asize + fft_size - i].re;
539  s->complexf[asize + i].im -= s->complexf[asize + fft_size - i].im;
540  s->complexf[asize + fft_size - i].re = 0.f;
541  s->complexf[asize + fft_size - i].im = 0.f;
542  }
543  s->complexf[asize + s->nb_taps - 1].im *= -1.f;
544 
545  s->tx_fn(s->tx_ctx, s->complexf, s->complexf + asize, sizeof(float));
546 
547  for (int i = 0; i < fft_size; i++) {
548  float eR = expf(s->complexf[i].re);
549 
550  s->complexf[i].re = eR * cosf(s->complexf[i].im);
551  s->complexf[i].im = eR * sinf(s->complexf[i].im);
552  }
553 
554  s->itx_fn(s->itx_ctx, s->complexf + asize, s->complexf, sizeof(float));
555 
556  for (int i = 0; i < s->nb_taps; i++)
557  s->taps[i] = s->complexf[i + asize].re / fft_size;
558  } else {
559  s->itx_fn(s->itx_ctx, s->complexf + asize, s->complexf, sizeof(float));
560 
561  middle = s->nb_taps / 2;
562  for (int i = 0; i < middle; i++) {
563  s->taps[middle - i] = s->complexf[i + asize].re / fft_size;
564  s->taps[middle + i] = s->complexf[i + asize].re / fft_size;
565  }
566  }
567 
568  s->pts = 0;
569 
570  return 0;
571 }
572 
573 static const AVFilterPad afireqsrc_outputs[] = {
574  {
575  .name = "default",
576  .type = AVMEDIA_TYPE_AUDIO,
577  .config_props = config_eq_output,
578  },
579 };
580 
582  .p.name = "afireqsrc",
583  .p.description = NULL_IF_CONFIG_SMALL("Generate a FIR equalizer coefficients audio stream."),
584  .p.priv_class = &afireqsrc_class,
585  .uninit = uninit,
586  .activate = activate,
587  .priv_size = sizeof(AudioFIRSourceContext),
590 };
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:312
afireqsrc_options
static const AVOption afireqsrc_options[]
Definition: asrc_afirsrc.c:340
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:385
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:3043
sample_rates
static const int sample_rates[]
Definition: dcaenc.h:34
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:403
eq_presets
static const EqPreset eq_presets[]
Definition: asrc_afirsrc.c:319
ff_asrc_afireqsrc
const FFFilter ff_asrc_afireqsrc
Definition: asrc_afirsrc.c:581
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:203
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
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:454
fabsf
static __device__ float fabsf(float a)
Definition: cuda_runtime.h:181
afireqsrc_outputs
static const AVFilterPad afireqsrc_outputs[]
Definition: asrc_afirsrc.c:573
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
FFFilter
Definition: filters.h:265
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:627
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:280
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
EqPreset::gains
float gains[16]
Definition: asrc_afirsrc.c:316
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:109
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:319
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:314
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
ff_asrc_afirsrc
const FFFilter ff_asrc_afirsrc
Definition: asrc_afirsrc.c:300
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:315
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
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:257
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
FFFilter::p
AVFilter p
The public AVFilter.
Definition: filters.h:269
mem.h
audio.h
AV_CHANNEL_LAYOUT_MONO
#define AV_CHANNEL_LAYOUT_MONO
Definition: channel_layout.h:394
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