FFmpeg  4.0
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 "window_func.h"
30 
31 typedef struct AFFTFiltContext {
32  const AVClass *class;
33  char *real_str;
34  char *img_str;
35  int fft_bits;
36 
39  int nb_exprs;
44  int64_t pts;
45  int hop_size;
46  float overlap;
48  int start, end;
49  int win_func;
50  float win_scale;
53 
54 static const char *const var_names[] = { "sr", "b", "nb", "ch", "chs", "pts", NULL };
56 
57 #define OFFSET(x) offsetof(AFFTFiltContext, x)
58 #define A AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
59 
60 static const AVOption afftfilt_options[] = {
61  { "real", "set channels real expressions", OFFSET(real_str), AV_OPT_TYPE_STRING, {.str = "1" }, 0, 0, A },
62  { "imag", "set channels imaginary expressions", OFFSET(img_str), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, A },
63  { "win_size", "set window size", OFFSET(fft_bits), AV_OPT_TYPE_INT, {.i64=12}, 4, 17, A, "fft" },
64  { "w16", 0, 0, AV_OPT_TYPE_CONST, {.i64=4}, 0, 0, A, "fft" },
65  { "w32", 0, 0, AV_OPT_TYPE_CONST, {.i64=5}, 0, 0, A, "fft" },
66  { "w64", 0, 0, AV_OPT_TYPE_CONST, {.i64=6}, 0, 0, A, "fft" },
67  { "w128", 0, 0, AV_OPT_TYPE_CONST, {.i64=7}, 0, 0, A, "fft" },
68  { "w256", 0, 0, AV_OPT_TYPE_CONST, {.i64=8}, 0, 0, A, "fft" },
69  { "w512", 0, 0, AV_OPT_TYPE_CONST, {.i64=9}, 0, 0, A, "fft" },
70  { "w1024", 0, 0, AV_OPT_TYPE_CONST, {.i64=10}, 0, 0, A, "fft" },
71  { "w2048", 0, 0, AV_OPT_TYPE_CONST, {.i64=11}, 0, 0, A, "fft" },
72  { "w4096", 0, 0, AV_OPT_TYPE_CONST, {.i64=12}, 0, 0, A, "fft" },
73  { "w8192", 0, 0, AV_OPT_TYPE_CONST, {.i64=13}, 0, 0, A, "fft" },
74  { "w16384", 0, 0, AV_OPT_TYPE_CONST, {.i64=14}, 0, 0, A, "fft" },
75  { "w32768", 0, 0, AV_OPT_TYPE_CONST, {.i64=15}, 0, 0, A, "fft" },
76  { "w65536", 0, 0, AV_OPT_TYPE_CONST, {.i64=16}, 0, 0, A, "fft" },
77  { "w131072",0, 0, AV_OPT_TYPE_CONST, {.i64=17}, 0, 0, A, "fft" },
78  { "win_func", "set window function", OFFSET(win_func), AV_OPT_TYPE_INT, {.i64 = WFUNC_HANNING}, 0, NB_WFUNC-1, A, "win_func" },
79  { "rect", "Rectangular", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_RECT}, 0, 0, A, "win_func" },
80  { "bartlett", "Bartlett", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BARTLETT}, 0, 0, A, "win_func" },
81  { "hann", "Hann", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_HANNING}, 0, 0, A, "win_func" },
82  { "hanning", "Hanning", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_HANNING}, 0, 0, A, "win_func" },
83  { "hamming", "Hamming", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_HAMMING}, 0, 0, A, "win_func" },
84  { "sine", "Sine", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_SINE}, 0, 0, A, "win_func" },
85  { "overlap", "set window overlap", OFFSET(overlap), AV_OPT_TYPE_FLOAT, {.dbl=0.75}, 0, 1, A },
86  { NULL },
87 };
88 
89 AVFILTER_DEFINE_CLASS(afftfilt);
90 
91 static int config_input(AVFilterLink *inlink)
92 {
93  AVFilterContext *ctx = inlink->dst;
94  AFFTFiltContext *s = ctx->priv;
95  char *saveptr = NULL;
96  int ret = 0, ch, i;
97  float overlap;
98  char *args;
99  const char *last_expr = "1";
100 
101  s->fft = av_fft_init(s->fft_bits, 0);
102  s->ifft = av_fft_init(s->fft_bits, 1);
103  if (!s->fft || !s->ifft)
104  return AVERROR(ENOMEM);
105 
106  s->window_size = 1 << s->fft_bits;
107 
108  s->fft_data = av_calloc(inlink->channels, sizeof(*s->fft_data));
109  if (!s->fft_data)
110  return AVERROR(ENOMEM);
111 
112  for (ch = 0; ch < inlink->channels; ch++) {
113  s->fft_data[ch] = av_calloc(s->window_size, sizeof(**s->fft_data));
114  if (!s->fft_data[ch])
115  return AVERROR(ENOMEM);
116  }
117 
118  s->real = av_calloc(inlink->channels, sizeof(*s->real));
119  if (!s->real)
120  return AVERROR(ENOMEM);
121 
122  s->imag = av_calloc(inlink->channels, sizeof(*s->imag));
123  if (!s->imag)
124  return AVERROR(ENOMEM);
125 
126  args = av_strdup(s->real_str);
127  if (!args)
128  return AVERROR(ENOMEM);
129 
130  for (ch = 0; ch < inlink->channels; ch++) {
131  char *arg = av_strtok(ch == 0 ? args : NULL, "|", &saveptr);
132 
133  ret = av_expr_parse(&s->real[ch], arg ? arg : last_expr, var_names,
134  NULL, NULL, NULL, NULL, 0, ctx);
135  if (ret < 0)
136  break;
137  if (arg)
138  last_expr = arg;
139  s->nb_exprs++;
140  }
141 
142  av_free(args);
143 
144  args = av_strdup(s->img_str ? s->img_str : s->real_str);
145  if (!args)
146  return AVERROR(ENOMEM);
147 
148  for (ch = 0; ch < inlink->channels; ch++) {
149  char *arg = av_strtok(ch == 0 ? args : NULL, "|", &saveptr);
150 
151  ret = av_expr_parse(&s->imag[ch], arg ? arg : last_expr, var_names,
152  NULL, NULL, NULL, NULL, 0, ctx);
153  if (ret < 0)
154  break;
155  if (arg)
156  last_expr = arg;
157  }
158 
159  av_free(args);
160 
161  s->fifo = av_audio_fifo_alloc(inlink->format, inlink->channels, s->window_size);
162  if (!s->fifo)
163  return AVERROR(ENOMEM);
164 
166  sizeof(*s->window_func_lut));
167  if (!s->window_func_lut)
168  return AVERROR(ENOMEM);
170  if (s->overlap == 1)
171  s->overlap = overlap;
172 
173  for (s->win_scale = 0, i = 0; i < s->window_size; i++) {
174  s->win_scale += s->window_func_lut[i] * s->window_func_lut[i];
175  }
176 
177  s->hop_size = s->window_size * (1 - s->overlap);
178  if (s->hop_size <= 0)
179  return AVERROR(EINVAL);
180 
181  s->buffer = ff_get_audio_buffer(inlink, s->window_size * 2);
182  if (!s->buffer)
183  return AVERROR(ENOMEM);
184 
185  return ret;
186 }
187 
188 static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
189 {
190  AVFilterContext *ctx = inlink->dst;
191  AVFilterLink *outlink = ctx->outputs[0];
192  AFFTFiltContext *s = ctx->priv;
193  const int window_size = s->window_size;
194  const float f = 1. / s->win_scale;
195  double values[VAR_VARS_NB];
196  AVFrame *out, *in = NULL;
197  int ch, n, ret, i, j, k;
198  int start = s->start, end = s->end;
199 
200  ret = av_audio_fifo_write(s->fifo, (void **)frame->extended_data, frame->nb_samples);
201  av_frame_free(&frame);
202  if (ret < 0)
203  return ret;
204 
205  while (av_audio_fifo_size(s->fifo) >= window_size) {
206  if (!in) {
207  in = ff_get_audio_buffer(outlink, window_size);
208  if (!in)
209  return AVERROR(ENOMEM);
210  }
211 
212  ret = av_audio_fifo_peek(s->fifo, (void **)in->extended_data, window_size);
213  if (ret < 0)
214  break;
215 
216  for (ch = 0; ch < inlink->channels; ch++) {
217  const float *src = (float *)in->extended_data[ch];
218  FFTComplex *fft_data = s->fft_data[ch];
219 
220  for (n = 0; n < in->nb_samples; n++) {
221  fft_data[n].re = src[n] * s->window_func_lut[n];
222  fft_data[n].im = 0;
223  }
224 
225  for (; n < window_size; n++) {
226  fft_data[n].re = 0;
227  fft_data[n].im = 0;
228  }
229  }
230 
231  values[VAR_PTS] = s->pts;
232  values[VAR_SAMPLE_RATE] = inlink->sample_rate;
233  values[VAR_NBBINS] = window_size / 2;
234  values[VAR_CHANNELS] = inlink->channels;
235 
236  for (ch = 0; ch < inlink->channels; ch++) {
238  float *buf = (float *)s->buffer->extended_data[ch];
239  int x;
240 
241  values[VAR_CHANNEL] = ch;
242 
243  av_fft_permute(s->fft, fft_data);
244  av_fft_calc(s->fft, fft_data);
245 
246  for (n = 0; n < window_size / 2; n++) {
247  float fr, fi;
248 
249  values[VAR_BIN] = n;
250 
251  fr = av_expr_eval(s->real[ch], values, s);
252  fi = av_expr_eval(s->imag[ch], values, s);
253 
254  fft_data[n].re *= fr;
255  fft_data[n].im *= fi;
256  }
257 
258  for (n = window_size / 2 + 1, x = window_size / 2 - 1; n < window_size; n++, x--) {
259  fft_data[n].re = fft_data[x].re;
260  fft_data[n].im = -fft_data[x].im;
261  }
262 
263  av_fft_permute(s->ifft, fft_data);
264  av_fft_calc(s->ifft, fft_data);
265 
266  start = s->start;
267  end = s->end;
268  k = end;
269  for (i = 0, j = start; j < k && i < window_size; i++, j++) {
270  buf[j] += s->fft_data[ch][i].re * f;
271  }
272 
273  for (; i < window_size; i++, j++) {
274  buf[j] = s->fft_data[ch][i].re * f;
275  }
276 
277  start += s->hop_size;
278  end = j;
279  }
280 
281  s->start = start;
282  s->end = end;
283 
284  if (start >= window_size) {
285  float *dst, *buf;
286 
287  start -= window_size;
288  end -= window_size;
289 
290  s->start = start;
291  s->end = end;
292 
293  out = ff_get_audio_buffer(outlink, window_size);
294  if (!out) {
295  ret = AVERROR(ENOMEM);
296  break;
297  }
298 
299  out->pts = s->pts;
300  s->pts += window_size;
301 
302  for (ch = 0; ch < inlink->channels; ch++) {
303  dst = (float *)out->extended_data[ch];
304  buf = (float *)s->buffer->extended_data[ch];
305 
306  for (n = 0; n < window_size; n++) {
307  dst[n] = buf[n] * (1 - s->overlap);
308  }
309  memmove(buf, buf + window_size, window_size * 4);
310  }
311 
312  ret = ff_filter_frame(outlink, out);
313  if (ret < 0)
314  break;
315  }
316 
318  }
319 
320  av_frame_free(&in);
321  return ret < 0 ? ret : 0;
322 }
323 
325 {
328  static const enum AVSampleFormat sample_fmts[] = {
331  };
332  int ret;
333 
334  layouts = ff_all_channel_counts();
335  if (!layouts)
336  return AVERROR(ENOMEM);
337  ret = ff_set_common_channel_layouts(ctx, layouts);
338  if (ret < 0)
339  return ret;
340 
341  formats = ff_make_format_list(sample_fmts);
342  if (!formats)
343  return AVERROR(ENOMEM);
344  ret = ff_set_common_formats(ctx, formats);
345  if (ret < 0)
346  return ret;
347 
348  formats = ff_all_samplerates();
349  if (!formats)
350  return AVERROR(ENOMEM);
351  return ff_set_common_samplerates(ctx, formats);
352 }
353 
355 {
356  AFFTFiltContext *s = ctx->priv;
357  int i;
358 
359  av_fft_end(s->fft);
360  av_fft_end(s->ifft);
361 
362  for (i = 0; i < s->nb_exprs; i++) {
363  if (s->fft_data)
364  av_freep(&s->fft_data[i]);
365  }
366  av_freep(&s->fft_data);
367 
368  for (i = 0; i < s->nb_exprs; i++) {
369  av_expr_free(s->real[i]);
370  av_expr_free(s->imag[i]);
371  }
372 
373  av_freep(&s->real);
374  av_freep(&s->imag);
375  av_frame_free(&s->buffer);
377 
379 }
380 
381 static const AVFilterPad inputs[] = {
382  {
383  .name = "default",
384  .type = AVMEDIA_TYPE_AUDIO,
385  .config_props = config_input,
386  .filter_frame = filter_frame,
387  },
388  { NULL }
389 };
390 
391 static const AVFilterPad outputs[] = {
392  {
393  .name = "default",
394  .type = AVMEDIA_TYPE_AUDIO,
395  },
396  { NULL }
397 };
398 
400  .name = "afftfilt",
401  .description = NULL_IF_CONFIG_SMALL("Apply arbitrary expressions to samples in frequency domain."),
402  .priv_size = sizeof(AFFTFiltContext),
403  .priv_class = &afftfilt_class,
404  .inputs = inputs,
405  .outputs = outputs,
407  .uninit = uninit,
408 };
float, planar
Definition: samplefmt.h:69
#define NULL
Definition: coverity.c:32
int ff_set_common_channel_layouts(AVFilterContext *ctx, AVFilterChannelLayouts *layouts)
A helper for query_formats() which sets all links to the same list of channel layouts/sample rates...
Definition: formats.c:549
FFTContext * fft
Definition: af_afftfilt.c:37
const char * s
Definition: avisynth_c.h:768
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:218
AVOption.
Definition: opt.h:246
AVAudioFifo * fifo
Definition: af_afftfilt.c:43
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:41
static int config_input(AVFilterLink *inlink)
Definition: af_afftfilt.c:91
static const char *const var_names[]
Definition: af_afftfilt.c:54
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
#define OFFSET(x)
Definition: af_afftfilt.c:57
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:35
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
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:354
const char * name
Pad name.
Definition: internal.h:60
AVFilter ff_af_afftfilt
Definition: af_afftfilt.c:399
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:38
#define av_cold
Definition: attributes.h:82
AVOptions.
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:311
Definition: eval.c:157
#define A
Definition: af_afftfilt.c:58
static AVFrame * frame
A filter pad used for either input or output.
Definition: internal.h:54
AVS_FilterInfo ** fi
Definition: avisynth_c.h:731
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
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
Definition: fft.h:88
static int query_formats(AVFilterContext *ctx)
Definition: af_afftfilt.c:324
const char AVS_Value args
Definition: avisynth_c.h:780
AVFormatContext * ctx
Definition: movenc.c:48
int n
Definition: avisynth_c.h:684
static const AVFilterPad outputs[]
Definition: af_afftfilt.c:391
A list of supported channel layouts.
Definition: formats.h:85
static const AVFilterPad inputs[]
Definition: af_afftfilt.c:381
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:51
void * buf
Definition: avisynth_c.h:690
AVExpr ** imag
Definition: af_afftfilt.c:42
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:37
static const AVOption afftfilt_options[]
Definition: af_afftfilt.c:60
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:47
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
AVFILTER_DEFINE_CLASS(afftfilt)
#define av_free(p)
Audio FIFO Buffer.
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:265
static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
Definition: af_afftfilt.c:188
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:284
for(j=16;j >0;--j)
int ff_set_common_samplerates(AVFilterContext *ctx, AVFilterFormats *samplerates)
Definition: formats.c:556
simple arithmetic expression evaluator