FFmpeg  4.2.3
af_afftfilt.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 Paul B Mahol
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU Lesser General Public License as published
8  * by the Free Software Foundation; either version 2.1 of the License,
9  * 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/audio_fifo.h"
22 #include "libavutil/avstring.h"
23 #include "libavfilter/internal.h"
24 #include "libavutil/common.h"
25 #include "libavutil/opt.h"
26 #include "libavcodec/avfft.h"
27 #include "libavutil/eval.h"
28 #include "audio.h"
29 #include "filters.h"
30 #include "window_func.h"
31 
32 typedef struct AFFTFiltContext {
33  const AVClass *class;
34  char *real_str;
35  char *img_str;
36  int fft_size;
37  int fft_bits;
38 
42  int nb_exprs;
47  int64_t pts;
48  int hop_size;
49  float overlap;
51  int eof;
52  int win_func;
55 
56 static const char *const var_names[] = { "sr", "b", "nb", "ch", "chs", "pts", "re", "im", NULL };
58 
59 #define OFFSET(x) offsetof(AFFTFiltContext, x)
60 #define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
61 
62 static const AVOption afftfilt_options[] = {
63  { "real", "set channels real expressions", OFFSET(real_str), AV_OPT_TYPE_STRING, {.str = "re" }, 0, 0, A },
64  { "imag", "set channels imaginary expressions", OFFSET(img_str), AV_OPT_TYPE_STRING, {.str = "im" }, 0, 0, A },
65  { "win_size", "set window size", OFFSET(fft_size), AV_OPT_TYPE_INT, {.i64=4096}, 16, 131072, A },
66  { "win_func", "set window function", OFFSET(win_func), AV_OPT_TYPE_INT, {.i64 = WFUNC_HANNING}, 0, NB_WFUNC-1, A, "win_func" },
67  { "rect", "Rectangular", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_RECT}, 0, 0, A, "win_func" },
68  { "bartlett", "Bartlett", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BARTLETT}, 0, 0, A, "win_func" },
69  { "hann", "Hann", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_HANNING}, 0, 0, A, "win_func" },
70  { "hanning", "Hanning", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_HANNING}, 0, 0, A, "win_func" },
71  { "hamming", "Hamming", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_HAMMING}, 0, 0, A, "win_func" },
72  { "blackman", "Blackman", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BLACKMAN}, 0, 0, A, "win_func" },
73  { "welch", "Welch", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_WELCH}, 0, 0, A, "win_func" },
74  { "flattop", "Flat-top", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_FLATTOP}, 0, 0, A, "win_func" },
75  { "bharris", "Blackman-Harris", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BHARRIS}, 0, 0, A, "win_func" },
76  { "bnuttall", "Blackman-Nuttall", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BNUTTALL}, 0, 0, A, "win_func" },
77  { "bhann", "Bartlett-Hann", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BHANN}, 0, 0, A, "win_func" },
78  { "sine", "Sine", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_SINE}, 0, 0, A, "win_func" },
79  { "nuttall", "Nuttall", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_NUTTALL}, 0, 0, A, "win_func" },
80  { "lanczos", "Lanczos", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_LANCZOS}, 0, 0, A, "win_func" },
81  { "gauss", "Gauss", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_GAUSS}, 0, 0, A, "win_func" },
82  { "tukey", "Tukey", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_TUKEY}, 0, 0, A, "win_func" },
83  { "dolph", "Dolph-Chebyshev", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_DOLPH}, 0, 0, A, "win_func" },
84  { "cauchy", "Cauchy", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_CAUCHY}, 0, 0, A, "win_func" },
85  { "parzen", "Parzen", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_PARZEN}, 0, 0, A, "win_func" },
86  { "poisson", "Poisson", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_POISSON}, 0, 0, A, "win_func" },
87  { "bohman", "Bohman", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BOHMAN}, 0, 0, A, "win_func" },
88  { "overlap", "set window overlap", OFFSET(overlap), AV_OPT_TYPE_FLOAT, {.dbl=0.75}, 0, 1, A },
89  { NULL },
90 };
91 
92 AVFILTER_DEFINE_CLASS(afftfilt);
93 
94 static inline double getreal(void *priv, double x, double ch)
95 {
96  AFFTFiltContext *s = priv;
97  int ich, ix;
98 
99  ich = av_clip(ch, 0, s->nb_exprs - 1);
100  ix = av_clip(x, 0, s->window_size / 2);
101 
102  return s->fft_data[ich][ix].re;
103 }
104 
105 static inline double getimag(void *priv, double x, double ch)
106 {
107  AFFTFiltContext *s = priv;
108  int ich, ix;
109 
110  ich = av_clip(ch, 0, s->nb_exprs - 1);
111  ix = av_clip(x, 0, s->window_size / 2);
112 
113  return s->fft_data[ich][ix].im;
114 }
115 
116 static double realf(void *priv, double x, double ch) { return getreal(priv, x, ch); }
117 static double imagf(void *priv, double x, double ch) { return getimag(priv, x, ch); }
118 
119 static const char *const func2_names[] = { "real", "imag", NULL };
120 double (*func2[])(void *, double, double) = { realf, imagf, NULL };
121 
122 static int config_input(AVFilterLink *inlink)
123 {
124  AVFilterContext *ctx = inlink->dst;
125  AFFTFiltContext *s = ctx->priv;
126  char *saveptr = NULL;
127  int ret = 0, ch;
128  float overlap;
129  char *args;
130  const char *last_expr = "1";
131 
132  s->pts = AV_NOPTS_VALUE;
133  s->fft_bits = av_log2(s->fft_size);
134  s->fft = av_fft_init(s->fft_bits, 0);
135  s->ifft = av_fft_init(s->fft_bits, 1);
136  if (!s->fft || !s->ifft)
137  return AVERROR(ENOMEM);
138 
139  s->window_size = 1 << s->fft_bits;
140 
141  s->fft_data = av_calloc(inlink->channels, sizeof(*s->fft_data));
142  if (!s->fft_data)
143  return AVERROR(ENOMEM);
144 
145  s->fft_temp = av_calloc(inlink->channels, sizeof(*s->fft_temp));
146  if (!s->fft_temp)
147  return AVERROR(ENOMEM);
148 
149  for (ch = 0; ch < inlink->channels; ch++) {
150  s->fft_data[ch] = av_calloc(s->window_size, sizeof(**s->fft_data));
151  if (!s->fft_data[ch])
152  return AVERROR(ENOMEM);
153  }
154 
155  for (ch = 0; ch < inlink->channels; ch++) {
156  s->fft_temp[ch] = av_calloc(s->window_size, sizeof(**s->fft_temp));
157  if (!s->fft_temp[ch])
158  return AVERROR(ENOMEM);
159  }
160 
161  s->real = av_calloc(inlink->channels, sizeof(*s->real));
162  if (!s->real)
163  return AVERROR(ENOMEM);
164 
165  s->imag = av_calloc(inlink->channels, sizeof(*s->imag));
166  if (!s->imag)
167  return AVERROR(ENOMEM);
168 
169  args = av_strdup(s->real_str);
170  if (!args)
171  return AVERROR(ENOMEM);
172 
173  for (ch = 0; ch < inlink->channels; ch++) {
174  char *arg = av_strtok(ch == 0 ? args : NULL, "|", &saveptr);
175 
176  ret = av_expr_parse(&s->real[ch], arg ? arg : last_expr, var_names,
177  NULL, NULL, func2_names, func2, 0, ctx);
178  if (ret < 0)
179  break;
180  if (arg)
181  last_expr = arg;
182  s->nb_exprs++;
183  }
184 
185  av_free(args);
186 
187  args = av_strdup(s->img_str ? s->img_str : s->real_str);
188  if (!args)
189  return AVERROR(ENOMEM);
190 
191  for (ch = 0; ch < inlink->channels; ch++) {
192  char *arg = av_strtok(ch == 0 ? args : NULL, "|", &saveptr);
193 
194  ret = av_expr_parse(&s->imag[ch], arg ? arg : last_expr, var_names,
195  NULL, NULL, func2_names, func2, 0, ctx);
196  if (ret < 0)
197  break;
198  if (arg)
199  last_expr = arg;
200  }
201 
202  av_free(args);
203 
204  s->fifo = av_audio_fifo_alloc(inlink->format, inlink->channels, s->window_size);
205  if (!s->fifo)
206  return AVERROR(ENOMEM);
207 
209  sizeof(*s->window_func_lut));
210  if (!s->window_func_lut)
211  return AVERROR(ENOMEM);
213  if (s->overlap == 1)
214  s->overlap = overlap;
215 
216  s->hop_size = s->window_size * (1 - s->overlap);
217  if (s->hop_size <= 0)
218  return AVERROR(EINVAL);
219 
220  s->buffer = ff_get_audio_buffer(inlink, s->window_size * 2);
221  if (!s->buffer)
222  return AVERROR(ENOMEM);
223 
224  return ret;
225 }
226 
227 static int filter_frame(AVFilterLink *inlink)
228 {
229  AVFilterContext *ctx = inlink->dst;
230  AVFilterLink *outlink = ctx->outputs[0];
231  AFFTFiltContext *s = ctx->priv;
232  const int window_size = s->window_size;
233  const float f = 1. / (s->window_size / 2);
234  double values[VAR_VARS_NB];
235  AVFrame *out, *in = NULL;
236  int ch, n, ret, i;
237 
238  if (!in) {
239  in = ff_get_audio_buffer(outlink, window_size);
240  if (!in)
241  return AVERROR(ENOMEM);
242  }
243 
244  ret = av_audio_fifo_peek(s->fifo, (void **)in->extended_data, window_size);
245  if (ret < 0)
246  goto fail;
247 
248  for (ch = 0; ch < inlink->channels; ch++) {
249  const float *src = (float *)in->extended_data[ch];
250  FFTComplex *fft_data = s->fft_data[ch];
251 
252  for (n = 0; n < in->nb_samples; n++) {
253  fft_data[n].re = src[n] * s->window_func_lut[n];
254  fft_data[n].im = 0;
255  }
256 
257  for (; n < window_size; n++) {
258  fft_data[n].re = 0;
259  fft_data[n].im = 0;
260  }
261  }
262 
263  values[VAR_PTS] = s->pts;
264  values[VAR_SAMPLE_RATE] = inlink->sample_rate;
265  values[VAR_NBBINS] = window_size / 2;
266  values[VAR_CHANNELS] = inlink->channels;
267 
268  for (ch = 0; ch < inlink->channels; ch++) {
270 
271  av_fft_permute(s->fft, fft_data);
272  av_fft_calc(s->fft, fft_data);
273  }
274 
275  for (ch = 0; ch < inlink->channels; ch++) {
278  float *buf = (float *)s->buffer->extended_data[ch];
279  int x;
280  values[VAR_CHANNEL] = ch;
281 
282  for (n = 0; n <= window_size / 2; n++) {
283  float fr, fi;
284 
285  values[VAR_BIN] = n;
286  values[VAR_REAL] = fft_data[n].re;
287  values[VAR_IMAG] = fft_data[n].im;
288 
289  fr = av_expr_eval(s->real[ch], values, s);
290  fi = av_expr_eval(s->imag[ch], values, s);
291 
292  fft_temp[n].re = fr;
293  fft_temp[n].im = fi;
294  }
295 
296  for (n = window_size / 2 + 1, x = window_size / 2 - 1; n < window_size; n++, x--) {
297  fft_temp[n].re = fft_temp[x].re;
298  fft_temp[n].im = -fft_temp[x].im;
299  }
300 
301  av_fft_permute(s->ifft, fft_temp);
302  av_fft_calc(s->ifft, fft_temp);
303 
304  for (i = 0; i < window_size; i++) {
305  buf[i] += s->fft_temp[ch][i].re * f;
306  }
307  }
308 
309  out = ff_get_audio_buffer(outlink, s->hop_size);
310  if (!out) {
311  ret = AVERROR(ENOMEM);
312  goto fail;
313  }
314 
315  out->pts = s->pts;
316  s->pts += s->hop_size;
317 
318  for (ch = 0; ch < inlink->channels; ch++) {
319  float *dst = (float *)out->extended_data[ch];
320  float *buf = (float *)s->buffer->extended_data[ch];
321 
322  for (n = 0; n < s->hop_size; n++)
323  dst[n] = buf[n] * (1.f - s->overlap);
324  memmove(buf, buf + s->hop_size, window_size * 4);
325  }
326 
327  ret = ff_filter_frame(outlink, out);
328  if (ret < 0)
329  goto fail;
330 
332 
333 fail:
334  av_frame_free(&in);
335  return ret < 0 ? ret : 0;
336 }
337 
339 {
340  AVFilterLink *inlink = ctx->inputs[0];
341  AVFilterLink *outlink = ctx->outputs[0];
342  AFFTFiltContext *s = ctx->priv;
343  AVFrame *in = NULL;
344  int ret = 0, status;
345  int64_t pts;
346 
347  FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink);
348 
349  if (!s->eof && av_audio_fifo_size(s->fifo) < s->window_size) {
350  ret = ff_inlink_consume_frame(inlink, &in);
351  if (ret < 0)
352  return ret;
353 
354  if (ret > 0) {
355  ret = av_audio_fifo_write(s->fifo, (void **)in->extended_data,
356  in->nb_samples);
357  if (ret >= 0 && s->pts == AV_NOPTS_VALUE)
358  s->pts = in->pts;
359 
360  av_frame_free(&in);
361  if (ret < 0)
362  return ret;
363  }
364  }
365 
366  if ((av_audio_fifo_size(s->fifo) >= s->window_size) ||
367  (av_audio_fifo_size(s->fifo) > 0 && s->eof)) {
368  ret = filter_frame(inlink);
369  if (av_audio_fifo_size(s->fifo) >= s->window_size)
370  ff_filter_set_ready(ctx, 100);
371  return ret;
372  }
373 
374  if (!s->eof && ff_inlink_acknowledge_status(inlink, &status, &pts)) {
375  if (status == AVERROR_EOF) {
376  s->eof = 1;
377  if (av_audio_fifo_size(s->fifo) >= 0) {
378  ff_filter_set_ready(ctx, 100);
379  return 0;
380  }
381  }
382  }
383 
384  if (s->eof && av_audio_fifo_size(s->fifo) <= 0) {
385  ff_outlink_set_status(outlink, AVERROR_EOF, s->pts);
386  return 0;
387  }
388 
389  if (!s->eof)
390  FF_FILTER_FORWARD_WANTED(outlink, inlink);
391 
392  return FFERROR_NOT_READY;
393 }
394 
396 {
399  static const enum AVSampleFormat sample_fmts[] = {
402  };
403  int ret;
404 
405  layouts = ff_all_channel_counts();
406  if (!layouts)
407  return AVERROR(ENOMEM);
408  ret = ff_set_common_channel_layouts(ctx, layouts);
409  if (ret < 0)
410  return ret;
411 
412  formats = ff_make_format_list(sample_fmts);
413  if (!formats)
414  return AVERROR(ENOMEM);
415  ret = ff_set_common_formats(ctx, formats);
416  if (ret < 0)
417  return ret;
418 
419  formats = ff_all_samplerates();
420  if (!formats)
421  return AVERROR(ENOMEM);
422  return ff_set_common_samplerates(ctx, formats);
423 }
424 
426 {
427  AFFTFiltContext *s = ctx->priv;
428  int i;
429 
430  av_fft_end(s->fft);
431  av_fft_end(s->ifft);
432 
433  for (i = 0; i < s->nb_exprs; i++) {
434  if (s->fft_data)
435  av_freep(&s->fft_data[i]);
436  if (s->fft_temp)
437  av_freep(&s->fft_temp[i]);
438  }
439  av_freep(&s->fft_data);
440  av_freep(&s->fft_temp);
441 
442  for (i = 0; i < s->nb_exprs; i++) {
443  av_expr_free(s->real[i]);
444  av_expr_free(s->imag[i]);
445  }
446 
447  av_freep(&s->real);
448  av_freep(&s->imag);
449  av_frame_free(&s->buffer);
451 
453 }
454 
455 static const AVFilterPad inputs[] = {
456  {
457  .name = "default",
458  .type = AVMEDIA_TYPE_AUDIO,
459  .config_props = config_input,
460  },
461  { NULL }
462 };
463 
464 static const AVFilterPad outputs[] = {
465  {
466  .name = "default",
467  .type = AVMEDIA_TYPE_AUDIO,
468  },
469  { NULL }
470 };
471 
473  .name = "afftfilt",
474  .description = NULL_IF_CONFIG_SMALL("Apply arbitrary expressions to samples in frequency domain."),
475  .priv_size = sizeof(AFFTFiltContext),
476  .priv_class = &afftfilt_class,
477  .inputs = inputs,
478  .outputs = outputs,
479  .activate = activate,
481  .uninit = uninit,
482 };
float, planar
Definition: samplefmt.h:69
int ff_inlink_consume_frame(AVFilterLink *link, AVFrame **rframe)
Take a frame from the link&#39;s FIFO and update the link&#39;s stats.
Definition: avfilter.c:1481
#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
FFTContext * fft
Definition: af_afftfilt.c:39
AVAudioFifo * av_audio_fifo_alloc(enum AVSampleFormat sample_fmt, int channels, int nb_samples)
Allocate an AVAudioFifo.
Definition: audio_fifo.c:59
#define av_realloc_f(p, o, n)
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
AVOption.
Definition: opt.h:246
AVAudioFifo * fifo
Definition: af_afftfilt.c:46
av_cold void av_fft_end(FFTContext *s)
Definition: avfft.c:48
void av_audio_fifo_free(AVAudioFifo *af)
Free an AVAudioFifo.
Definition: audio_fifo.c:45
AVExpr ** real
Definition: af_afftfilt.c:44
static int config_input(AVFilterLink *inlink)
Definition: af_afftfilt.c:122
static const char *const var_names[]
Definition: af_afftfilt.c:56
uint8_t pi<< 24) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_U8,(uint64_t)((*(const uint8_t *) pi - 0x80U))<< 56) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16,(*(const int16_t *) pi >>8)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S16,(uint64_t)(*(const int16_t *) pi)<< 48) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32,(*(const int32_t *) pi >>24)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S32,(uint64_t)(*(const int32_t *) pi)<< 32) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S64,(*(const int64_t *) pi >>56)+0x80) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S64, *(const int64_t *) pi *(1.0f/(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S64, *(const int64_t *) pi *(1.0/(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_FLT, llrintf(*(const float *) pi *(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_DBL, llrint(*(const double *) pi *(INT64_C(1)<< 63))) #define FMT_PAIR_FUNC(out, in) static conv_func_type *const fmt_pair_to_conv_functions[AV_SAMPLE_FMT_NB *AV_SAMPLE_FMT_NB]={ FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S64), };static void cpy1(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, len);} static void cpy2(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, 2 *len);} static void cpy4(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, 4 *len);} static void cpy8(uint8_t **dst, const uint8_t **src, int len){ memcpy(*dst, *src, 8 *len);} AudioConvert *swri_audio_convert_alloc(enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, const int *ch_map, int flags) { AudioConvert *ctx;conv_func_type *f=fmt_pair_to_conv_functions[av_get_packed_sample_fmt(out_fmt)+AV_SAMPLE_FMT_NB *av_get_packed_sample_fmt(in_fmt)];if(!f) return NULL;ctx=av_mallocz(sizeof(*ctx));if(!ctx) return NULL;if(channels==1){ in_fmt=av_get_planar_sample_fmt(in_fmt);out_fmt=av_get_planar_sample_fmt(out_fmt);} ctx->channels=channels;ctx->conv_f=f;ctx->ch_map=ch_map;if(in_fmt==AV_SAMPLE_FMT_U8||in_fmt==AV_SAMPLE_FMT_U8P) memset(ctx->silence, 0x80, sizeof(ctx->silence));if(out_fmt==in_fmt &&!ch_map) { switch(av_get_bytes_per_sample(in_fmt)){ case 1:ctx->simd_f=cpy1;break;case 2:ctx->simd_f=cpy2;break;case 4:ctx->simd_f=cpy4;break;case 8:ctx->simd_f=cpy8;break;} } if(HAVE_X86ASM &&HAVE_MMX) swri_audio_convert_init_x86(ctx, out_fmt, in_fmt, channels);if(ARCH_ARM) swri_audio_convert_init_arm(ctx, out_fmt, in_fmt, channels);if(ARCH_AARCH64) swri_audio_convert_init_aarch64(ctx, out_fmt, in_fmt, channels);return ctx;} void swri_audio_convert_free(AudioConvert **ctx) { av_freep(ctx);} int swri_audio_convert(AudioConvert *ctx, AudioData *out, AudioData *in, int len) { int ch;int off=0;const int os=(out->planar ? 1 :out->ch_count) *out->bps;unsigned misaligned=0;av_assert0(ctx->channels==out->ch_count);if(ctx->in_simd_align_mask) { int planes=in->planar ? in->ch_count :1;unsigned m=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) in->ch[ch];misaligned|=m &ctx->in_simd_align_mask;} if(ctx->out_simd_align_mask) { int planes=out->planar ? out->ch_count :1;unsigned m=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) out->ch[ch];misaligned|=m &ctx->out_simd_align_mask;} if(ctx->simd_f &&!ctx->ch_map &&!misaligned){ off=len &~15;av_assert1(off >=0);av_assert1(off<=len);av_assert2(ctx->channels==SWR_CH_MAX||!in->ch[ctx->channels]);if(off >0){ if(out->planar==in->planar){ int planes=out->planar ? out->ch_count :1;for(ch=0;ch< planes;ch++){ ctx->simd_f(out-> ch ch
Definition: audioconvert.c:56
static double realf(void *priv, double x, double ch)
Definition: af_afftfilt.c:116
#define FFERROR_NOT_READY
Filters implementation helper functions.
Definition: filters.h:34
#define OFFSET(x)
Definition: af_afftfilt.c:59
FFTSample re
Definition: avfft.h:38
void av_fft_permute(FFTContext *s, FFTComplex *z)
Do the permutation needed BEFORE calling ff_fft_calc().
Definition: avfft.c:38
static void generate_window_func(float *lut, int N, int win_func, float *overlap)
Definition: window_func.h:36
int av_expr_parse(AVExpr **expr, const char *s, const char *const *const_names, const char *const *func1_names, double(*const *funcs1)(void *, double), const char *const *func2_names, double(*const *funcs2)(void *, double, double), int log_offset, void *log_ctx)
Parse an expression.
Definition: eval.c:679
#define src
Definition: vp8dsp.c:254
static int filter_frame(AVFilterLink *inlink)
Definition: af_afftfilt.c:227
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:189
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
Definition: mem.c:244
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:283
static av_cold void uninit(AVFilterContext *ctx)
Definition: af_afftfilt.c:425
const char * name
Pad name.
Definition: internal.h:60
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:346
AVFilter ff_af_afftfilt
Definition: af_afftfilt.c:472
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1080
FFTComplex ** fft_data
Definition: af_afftfilt.c:40
#define av_cold
Definition: attributes.h:82
AVOptions.
#define f(width, name)
Definition: cbs_vp9.c:255
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:388
Definition: eval.c:157
FFTComplex ** fft_temp
Definition: af_afftfilt.c:41
#define A
Definition: af_afftfilt.c:60
#define AVERROR_EOF
End of file.
Definition: error.h:55
#define FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink)
Forward the status on an output link to an input link.
Definition: filters.h:199
A filter pad used for either input or output.
Definition: internal.h:54
int ff_inlink_acknowledge_status(AVFilterLink *link, int *rstatus, int64_t *rpts)
Test and acknowledge the change of status on the link.
Definition: avfilter.c:1436
static double imagf(void *priv, double x, double ch)
Definition: af_afftfilt.c:117
AVS_FilterInfo ** fi
Definition: avisynth_c.h:807
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
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
AVFrame * ff_get_audio_buffer(AVFilterLink *link, int nb_samples)
Request an audio samples buffer with a specific set of permissions.
Definition: audio.c:86
#define AVERROR(e)
Definition: error.h:43
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:202
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
void * priv
private data for use by the filter
Definition: avfilter.h:353
const char * arg
Definition: jacosubdec.c:66
FFTContext * av_fft_init(int nbits, int inverse)
Set up a complex FFT.
Definition: avfft.c:28
#define fail()
Definition: checkasm.h:120
Context for an Audio FIFO Buffer.
Definition: audio_fifo.c:34
int av_audio_fifo_size(AVAudioFifo *af)
Get the current number of samples in the AVAudioFifo available for reading.
Definition: audio_fifo.c:228
#define FF_FILTER_FORWARD_WANTED(outlink, inlink)
Forward the frame_wanted_out flag from an output link to an input link.
Definition: filters.h:254
Definition: fft.h:88
static int query_formats(AVFilterContext *ctx)
Definition: af_afftfilt.c:395
const char AVS_Value args
Definition: avisynth_c.h:872
AVFormatContext * ctx
Definition: movenc.c:48
#define s(width, name)
Definition: cbs_vp9.c:257
int n
Definition: avisynth_c.h:760
static const AVFilterPad outputs[]
Definition: af_afftfilt.c:464
#define av_log2
Definition: intmath.h:83
A list of supported channel layouts.
Definition: formats.h:85
static double getreal(void *priv, double x, double ch)
Definition: af_afftfilt.c:94
static const AVFilterPad inputs[]
Definition: af_afftfilt.c:455
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:251
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:334
FFT functions.
float * window_func_lut
Definition: af_afftfilt.c:53
double(* func2[])(void *, double, double)
Definition: af_afftfilt.c:120
void * buf
Definition: avisynth_c.h:766
AVExpr ** imag
Definition: af_afftfilt.c:45
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) #define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac) { } void ff_audio_convert_free(AudioConvert **ac) { if(! *ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);} AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map) { AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method !=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2) { ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc) { av_free(ac);return NULL;} return ac;} in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar) { ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar ? ac->channels :1;} else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;} int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in) { int use_generic=1;int len=in->nb_samples;int p;if(ac->dc) { av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (dithered)\", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
Describe the class of an AVClass context structure.
Definition: log.h:67
Filter definition.
Definition: avfilter.h:144
FFTContext * ifft
Definition: af_afftfilt.c:39
static const AVOption afftfilt_options[]
Definition: af_afftfilt.c:62
const char * name
Filter name.
Definition: avfilter.h:148
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:350
enum MovChannelLayoutTag * layouts
Definition: mov_chan.c:434
AVFilterFormats * ff_all_samplerates(void)
Definition: formats.c:395
AVFrame * buffer
Definition: af_afftfilt.c:50
int av_audio_fifo_write(AVAudioFifo *af, void **data, int nb_samples)
Write data to an AVAudioFifo.
Definition: audio_fifo.c:112
int av_audio_fifo_drain(AVAudioFifo *af, int nb_samples)
Drain data from an AVAudioFifo.
Definition: audio_fifo.c:201
char * av_strtok(char *s, const char *delim, char **saveptr)
Split the string into several tokens which can be accessed by successive calls to av_strtok()...
Definition: avstring.c:184
FFTSample im
Definition: avfft.h:38
common internal and external API header
void ff_filter_set_ready(AVFilterContext *filter, unsigned priority)
Mark a filter ready and schedule it for activation.
Definition: avfilter.c:193
AVFILTER_DEFINE_CLASS(afftfilt)
static const char *const func2_names[]
Definition: af_afftfilt.c:119
static double getimag(void *priv, double x, double ch)
Definition: af_afftfilt.c:105
#define av_free(p)
Audio FIFO Buffer.
static int activate(AVFilterContext *ctx)
Definition: af_afftfilt.c:338
double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
Evaluate a previously parsed expression.
Definition: eval.c:734
A list of supported formats for one end of a filter link.
Definition: formats.h:64
int av_audio_fifo_peek(AVAudioFifo *af, void **data, int nb_samples)
Peek data from an AVAudioFifo.
Definition: audio_fifo.c:138
An instance of a filter.
Definition: avfilter.h:338
static enum AVSampleFormat sample_fmts[]
Definition: adpcmenc.c:701
FILE * out
Definition: movenc.c:54
#define av_freep(p)
formats
Definition: signature.h:48
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:342
void av_fft_calc(FFTContext *s, FFTComplex *z)
Do a complex FFT with the parameters defined in av_fft_init().
Definition: avfft.c:43
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:361
for(j=16;j >0;--j)
int ff_set_common_samplerates(AVFilterContext *ctx, AVFilterFormats *samplerates)
Definition: formats.c:556
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
simple arithmetic expression evaluator