FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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  av_audio_fifo_write(s->fifo, (void **)frame->extended_data, frame->nb_samples);
201  av_frame_free(&frame);
202 
203  while (av_audio_fifo_size(s->fifo) >= window_size) {
204  if (!in) {
205  in = ff_get_audio_buffer(outlink, window_size);
206  if (!in)
207  return AVERROR(ENOMEM);
208  }
209 
210  ret = av_audio_fifo_peek(s->fifo, (void **)in->extended_data, window_size);
211  if (ret < 0)
212  break;
213 
214  for (ch = 0; ch < inlink->channels; ch++) {
215  const float *src = (float *)in->extended_data[ch];
216  FFTComplex *fft_data = s->fft_data[ch];
217 
218  for (n = 0; n < in->nb_samples; n++) {
219  fft_data[n].re = src[n] * s->window_func_lut[n];
220  fft_data[n].im = 0;
221  }
222 
223  for (; n < window_size; n++) {
224  fft_data[n].re = 0;
225  fft_data[n].im = 0;
226  }
227  }
228 
229  values[VAR_PTS] = s->pts;
230  values[VAR_SAMPLE_RATE] = inlink->sample_rate;
231  values[VAR_NBBINS] = window_size / 2;
232  values[VAR_CHANNELS] = inlink->channels;
233 
234  for (ch = 0; ch < inlink->channels; ch++) {
235  FFTComplex *fft_data = s->fft_data[ch];
236  float *buf = (float *)s->buffer->extended_data[ch];
237  int x;
238 
239  values[VAR_CHANNEL] = ch;
240 
241  av_fft_permute(s->fft, fft_data);
242  av_fft_calc(s->fft, fft_data);
243 
244  for (n = 0; n < window_size / 2; n++) {
245  float fr, fi;
246 
247  values[VAR_BIN] = n;
248 
249  fr = av_expr_eval(s->real[ch], values, s);
250  fi = av_expr_eval(s->imag[ch], values, s);
251 
252  fft_data[n].re *= fr;
253  fft_data[n].im *= fi;
254  }
255 
256  for (n = window_size / 2 + 1, x = window_size / 2 - 1; n < window_size; n++, x--) {
257  fft_data[n].re = fft_data[x].re;
258  fft_data[n].im = -fft_data[x].im;
259  }
260 
261  av_fft_permute(s->ifft, fft_data);
262  av_fft_calc(s->ifft, fft_data);
263 
264  start = s->start;
265  end = s->end;
266  k = end;
267  for (i = 0, j = start; j < k && i < window_size; i++, j++) {
268  buf[j] += s->fft_data[ch][i].re * f;
269  }
270 
271  for (; i < window_size; i++, j++) {
272  buf[j] = s->fft_data[ch][i].re * f;
273  }
274 
275  start += s->hop_size;
276  end = j;
277  }
278 
279  s->start = start;
280  s->end = end;
281 
282  if (start >= window_size) {
283  float *dst, *buf;
284 
285  start -= window_size;
286  end -= window_size;
287 
288  s->start = start;
289  s->end = end;
290 
291  out = ff_get_audio_buffer(outlink, window_size);
292  if (!out) {
293  ret = AVERROR(ENOMEM);
294  break;
295  }
296 
297  out->pts = s->pts;
298  s->pts += window_size;
299 
300  for (ch = 0; ch < inlink->channels; ch++) {
301  dst = (float *)out->extended_data[ch];
302  buf = (float *)s->buffer->extended_data[ch];
303 
304  for (n = 0; n < window_size; n++) {
305  dst[n] = buf[n] * (1 - s->overlap);
306  }
307  memmove(buf, buf + window_size, window_size * 4);
308  }
309 
310  ret = ff_filter_frame(outlink, out);
311  if (ret < 0)
312  break;
313  }
314 
316  }
317 
318  av_frame_free(&in);
319  return ret;
320 }
321 
323 {
326  static const enum AVSampleFormat sample_fmts[] = {
329  };
330  int ret;
331 
332  layouts = ff_all_channel_counts();
333  if (!layouts)
334  return AVERROR(ENOMEM);
335  ret = ff_set_common_channel_layouts(ctx, layouts);
336  if (ret < 0)
337  return ret;
338 
339  formats = ff_make_format_list(sample_fmts);
340  if (!formats)
341  return AVERROR(ENOMEM);
342  ret = ff_set_common_formats(ctx, formats);
343  if (ret < 0)
344  return ret;
345 
346  formats = ff_all_samplerates();
347  if (!formats)
348  return AVERROR(ENOMEM);
349  return ff_set_common_samplerates(ctx, formats);
350 }
351 
353 {
354  AFFTFiltContext *s = ctx->priv;
355  int i;
356 
357  av_fft_end(s->fft);
358  av_fft_end(s->ifft);
359 
360  for (i = 0; i < s->nb_exprs; i++) {
361  if (s->fft_data)
362  av_freep(&s->fft_data[i]);
363  }
364  av_freep(&s->fft_data);
365 
366  for (i = 0; i < s->nb_exprs; i++) {
367  av_expr_free(s->real[i]);
368  av_expr_free(s->imag[i]);
369  }
370 
371  av_freep(&s->real);
372  av_freep(&s->imag);
373  av_frame_free(&s->buffer);
375 
377 }
378 
379 static const AVFilterPad inputs[] = {
380  {
381  .name = "default",
382  .type = AVMEDIA_TYPE_AUDIO,
383  .config_props = config_input,
384  .filter_frame = filter_frame,
385  },
386  { NULL }
387 };
388 
389 static const AVFilterPad outputs[] = {
390  {
391  .name = "default",
392  .type = AVMEDIA_TYPE_AUDIO,
393  },
394  { NULL }
395 };
396 
398  .name = "afftfilt",
399  .description = NULL_IF_CONFIG_SMALL("Apply arbitrary expressions to samples in frequency domain."),
400  .priv_size = sizeof(AFFTFiltContext),
401  .priv_class = &afftfilt_class,
402  .inputs = inputs,
403  .outputs = outputs,
405  .uninit = uninit,
406 };
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:201
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
#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:672
#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:230
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:352
const char * name
Pad name.
Definition: internal.h:60
AVFilter ff_af_afftfilt
Definition: af_afftfilt.c:397
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1151
FFTComplex ** fft_data
Definition: af_afftfilt.c:38
#define av_cold
Definition: attributes.h:82
AVOptions.
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
uint8_t pi<< 24) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_U8,(uint64_t)((*(constuint8_t *) pi-0x80U))<< 56) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8,(*(constuint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8,(*(constuint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16,(*(constint16_t *) pi >>8)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S16,(uint64_t)(*(constint16_t *) pi)<< 48) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16,*(constint16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16,*(constint16_t *) pi *(1.0/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32,(*(constint32_t *) pi >>24)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S32,(uint64_t)(*(constint32_t *) pi)<< 32) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32,*(constint32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32,*(constint32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S64,(*(constint64_t *) pi >>56)+0x80) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S64,*(constint64_t *) pi *(1.0f/(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S64,*(constint64_t *) pi *(1.0/(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, av_clip_uint8(lrintf(*(constfloat *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, av_clip_int16(lrintf(*(constfloat *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(constfloat *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_FLT, llrintf(*(constfloat *) pi *(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, av_clip_uint8(lrint(*(constdouble *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, av_clip_int16(lrint(*(constdouble *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(constdouble *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_DBL, llrint(*(constdouble *) pi *(INT64_C(1)<< 63)))#defineFMT_PAIR_FUNC(out, in) staticconv_func_type *constfmt_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),};staticvoidcpy1(uint8_t **dst, constuint8_t **src, intlen){memcpy(*dst,*src, len);}staticvoidcpy2(uint8_t **dst, constuint8_t **src, intlen){memcpy(*dst,*src, 2 *len);}staticvoidcpy4(uint8_t **dst, constuint8_t **src, intlen){memcpy(*dst,*src, 4 *len);}staticvoidcpy8(uint8_t **dst, constuint8_t **src, intlen){memcpy(*dst,*src, 8 *len);}AudioConvert *swri_audio_convert_alloc(enumAVSampleFormatout_fmt, enumAVSampleFormatin_fmt, intchannels, constint *ch_map, intflags){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) returnNULL;ctx=av_mallocz(sizeof(*ctx));if(!ctx) returnNULL;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)){case1:ctx->simd_f=cpy1;break;case2:ctx->simd_f=cpy2;break;case4:ctx->simd_f=cpy4;break;case8:ctx->simd_f=cpy8;break;}}if(HAVE_X86ASM &&1) 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);returnctx;}voidswri_audio_convert_free(AudioConvert **ctx){av_freep(ctx);}intswri_audio_convert(AudioConvert *ctx, AudioData *out, AudioData *in, intlen){intch;intoff=0;constintos=(out->planar?1:out->ch_count)*out->bps;unsignedmisaligned=0;av_assert0(ctx->channels==out->ch_count);if(ctx->in_simd_align_mask){intplanes=in->planar?in->ch_count:1;unsignedm=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){intplanes=out->planar?out->ch_count:1;unsignedm=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){intplanes=out->planar?out->ch_count:1;for(ch=0;ch< planes;ch++){ctx->simd_f(out-> ch ch
Definition: audioconvert.c:56
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:294
Definition: eval.c:150
#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:163
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:179
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:322
AVS_Value args
Definition: avisynth_c.h:699
AVFormatContext * ctx
Definition: movenc.c:48
int n
Definition: avisynth_c.h:684
static const AVFilterPad outputs[]
Definition: af_afftfilt.c:389
A list of supported channel layouts.
Definition: formats.h:85
static const AVFilterPad inputs[]
Definition: af_afftfilt.c:379
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:237
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:327
FFT functions.
float * window_func_lut
Definition: af_afftfilt.c:51
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(constint16_t *) pi >>8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(constint32_t *) pi >>24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(constfloat *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(constfloat *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(constfloat *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(constdouble *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(constdouble *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(constdouble *) pi *(1U<< 31))))#defineSET_CONV_FUNC_GROUP(ofmt, ifmt) staticvoidset_generic_function(AudioConvert *ac){}voidff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enumAVSampleFormatout_fmt, enumAVSampleFormatin_fmt, intchannels, intsample_rate, intapply_map){AudioConvert *ac;intin_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) returnNULL;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);returnNULL;}returnac;}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;}elseif(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;elseac->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);returnac;}intff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){intuse_generic=1;intlen=in->nb_samples;intp;if(ac->dc){av_log(ac->avr, AV_LOG_TRACE,"%dsamples-audio_convert:%sto%s(dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));returnff_convert_dither(ac-> in
void * buf
Definition: avisynth_c.h:690
AVExpr ** imag
Definition: af_afftfilt.c:42
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:727
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)
void INT64 start
Definition: avisynth_c.h:690
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:248
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:267
for(j=16;j >0;--j)
int ff_set_common_samplerates(AVFilterContext *ctx, AVFilterFormats *samplerates)
Definition: formats.c:556
simple arithmetic expression evaluator