FFmpeg  4.0
vaf_spectrumsynth.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
7  * modify it under the terms of the GNU Lesser General Public
8  * License 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 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 /**
22  * @file
23  * SpectrumSynth filter
24  * @todo support float pixel format
25  */
26 
27 #include "libavcodec/avfft.h"
28 #include "libavutil/avassert.h"
30 #include "libavutil/ffmath.h"
31 #include "libavutil/opt.h"
32 #include "libavutil/parseutils.h"
33 #include "avfilter.h"
34 #include "formats.h"
35 #include "audio.h"
36 #include "video.h"
37 #include "internal.h"
38 #include "window_func.h"
39 
43 
44 typedef struct SpectrumSynthContext {
45  const AVClass *class;
47  int channels;
48  int scale;
49  int sliding;
50  int win_func;
51  float overlap;
53 
55  FFTContext *fft; ///< Fast Fourier Transform context
56  int fft_bits; ///< number of bits (FFT window size = 1<<fft_bits)
57  FFTComplex **fft_data; ///< bins holder for each (displayed) channels
58  int win_size;
59  int size;
60  int nb_freq;
61  int hop_size;
62  int start, end;
63  int xpos;
64  int xend;
65  int64_t pts;
66  float factor;
68  float *window_func_lut; ///< Window function LUT
70 
71 #define OFFSET(x) offsetof(SpectrumSynthContext, x)
72 #define A AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_AUDIO_PARAM
73 #define V AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
74 
75 static const AVOption spectrumsynth_options[] = {
76  { "sample_rate", "set sample rate", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = 44100}, 15, INT_MAX, A },
77  { "channels", "set channels", OFFSET(channels), AV_OPT_TYPE_INT, {.i64 = 1}, 1, 8, A },
78  { "scale", "set input amplitude scale", OFFSET(scale), AV_OPT_TYPE_INT, {.i64 = LOG}, 0, NB_SCALES-1, V, "scale" },
79  { "lin", "linear", 0, AV_OPT_TYPE_CONST, {.i64=LINEAR}, 0, 0, V, "scale" },
80  { "log", "logarithmic", 0, AV_OPT_TYPE_CONST, {.i64=LOG}, 0, 0, V, "scale" },
81  { "slide", "set input sliding mode", OFFSET(sliding), AV_OPT_TYPE_INT, {.i64 = FULLFRAME}, 0, NB_SLIDES-1, V, "slide" },
82  { "replace", "consume old columns with new", 0, AV_OPT_TYPE_CONST, {.i64=REPLACE}, 0, 0, V, "slide" },
83  { "scroll", "consume only most right column", 0, AV_OPT_TYPE_CONST, {.i64=SCROLL}, 0, 0, V, "slide" },
84  { "fullframe", "consume full frames", 0, AV_OPT_TYPE_CONST, {.i64=FULLFRAME}, 0, 0, V, "slide" },
85  { "rscroll", "consume only most left column", 0, AV_OPT_TYPE_CONST, {.i64=RSCROLL}, 0, 0, V, "slide" },
86  { "win_func", "set window function", OFFSET(win_func), AV_OPT_TYPE_INT, {.i64 = 0}, 0, NB_WFUNC-1, A, "win_func" },
87  { "rect", "Rectangular", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_RECT}, 0, 0, A, "win_func" },
88  { "bartlett", "Bartlett", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BARTLETT}, 0, 0, A, "win_func" },
89  { "hann", "Hann", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_HANNING}, 0, 0, A, "win_func" },
90  { "hanning", "Hanning", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_HANNING}, 0, 0, A, "win_func" },
91  { "hamming", "Hamming", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_HAMMING}, 0, 0, A, "win_func" },
92  { "sine", "Sine", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_SINE}, 0, 0, A, "win_func" },
93  { "overlap", "set window overlap", OFFSET(overlap), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 1, A },
94  { "orientation", "set orientation", OFFSET(orientation), AV_OPT_TYPE_INT, {.i64=VERTICAL}, 0, NB_ORIENTATIONS-1, V, "orientation" },
95  { "vertical", NULL, 0, AV_OPT_TYPE_CONST, {.i64=VERTICAL}, 0, 0, V, "orientation" },
96  { "horizontal", NULL, 0, AV_OPT_TYPE_CONST, {.i64=HORIZONTAL}, 0, 0, V, "orientation" },
97  { NULL }
98 };
99 
100 AVFILTER_DEFINE_CLASS(spectrumsynth);
101 
103 {
104  SpectrumSynthContext *s = ctx->priv;
107  AVFilterLink *magnitude = ctx->inputs[0];
108  AVFilterLink *phase = ctx->inputs[1];
109  AVFilterLink *outlink = ctx->outputs[0];
111  static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY16,
114  int ret, sample_rates[] = { 48000, -1 };
115 
116  formats = ff_make_format_list(sample_fmts);
117  if ((ret = ff_formats_ref (formats, &outlink->in_formats )) < 0 ||
118  (ret = ff_add_channel_layout (&layout, FF_COUNT2LAYOUT(s->channels))) < 0 ||
119  (ret = ff_channel_layouts_ref (layout , &outlink->in_channel_layouts)) < 0)
120  return ret;
121 
122  sample_rates[0] = s->sample_rate;
123  formats = ff_make_format_list(sample_rates);
124  if (!formats)
125  return AVERROR(ENOMEM);
126  if ((ret = ff_formats_ref(formats, &outlink->in_samplerates)) < 0)
127  return ret;
128 
129  formats = ff_make_format_list(pix_fmts);
130  if (!formats)
131  return AVERROR(ENOMEM);
132  if ((ret = ff_formats_ref(formats, &magnitude->out_formats)) < 0)
133  return ret;
134 
135  formats = ff_make_format_list(pix_fmts);
136  if (!formats)
137  return AVERROR(ENOMEM);
138  if ((ret = ff_formats_ref(formats, &phase->out_formats)) < 0)
139  return ret;
140 
141  return 0;
142 }
143 
144 static int config_output(AVFilterLink *outlink)
145 {
146  AVFilterContext *ctx = outlink->src;
147  SpectrumSynthContext *s = ctx->priv;
148  int width = ctx->inputs[0]->w;
149  int height = ctx->inputs[0]->h;
150  AVRational time_base = ctx->inputs[0]->time_base;
151  AVRational frame_rate = ctx->inputs[0]->frame_rate;
152  int i, ch, fft_bits;
153  float factor, overlap;
154 
155  outlink->sample_rate = s->sample_rate;
156  outlink->time_base = (AVRational){1, s->sample_rate};
157 
158  if (width != ctx->inputs[1]->w ||
159  height != ctx->inputs[1]->h) {
160  av_log(ctx, AV_LOG_ERROR,
161  "Magnitude and Phase sizes differ (%dx%d vs %dx%d).\n",
162  width, height,
163  ctx->inputs[1]->w, ctx->inputs[1]->h);
164  return AVERROR_INVALIDDATA;
165  } else if (av_cmp_q(time_base, ctx->inputs[1]->time_base) != 0) {
166  av_log(ctx, AV_LOG_ERROR,
167  "Magnitude and Phase time bases differ (%d/%d vs %d/%d).\n",
168  time_base.num, time_base.den,
169  ctx->inputs[1]->time_base.num,
170  ctx->inputs[1]->time_base.den);
171  return AVERROR_INVALIDDATA;
172  } else if (av_cmp_q(frame_rate, ctx->inputs[1]->frame_rate) != 0) {
173  av_log(ctx, AV_LOG_ERROR,
174  "Magnitude and Phase framerates differ (%d/%d vs %d/%d).\n",
175  frame_rate.num, frame_rate.den,
176  ctx->inputs[1]->frame_rate.num,
177  ctx->inputs[1]->frame_rate.den);
178  return AVERROR_INVALIDDATA;
179  }
180 
181  s->size = s->orientation == VERTICAL ? height / s->channels : width / s->channels;
182  s->xend = s->orientation == VERTICAL ? width : height;
183 
184  for (fft_bits = 1; 1 << fft_bits < 2 * s->size; fft_bits++);
185 
186  s->win_size = 1 << fft_bits;
187  s->nb_freq = 1 << (fft_bits - 1);
188 
189  s->fft = av_fft_init(fft_bits, 1);
190  if (!s->fft) {
191  av_log(ctx, AV_LOG_ERROR, "Unable to create FFT context. "
192  "The window size might be too high.\n");
193  return AVERROR(EINVAL);
194  }
195  s->fft_data = av_calloc(s->channels, sizeof(*s->fft_data));
196  if (!s->fft_data)
197  return AVERROR(ENOMEM);
198  for (ch = 0; ch < s->channels; ch++) {
199  s->fft_data[ch] = av_calloc(s->win_size, sizeof(**s->fft_data));
200  if (!s->fft_data[ch])
201  return AVERROR(ENOMEM);
202  }
203 
204  s->buffer = ff_get_audio_buffer(outlink, s->win_size * 2);
205  if (!s->buffer)
206  return AVERROR(ENOMEM);
207 
208  /* pre-calc windowing function */
210  sizeof(*s->window_func_lut));
211  if (!s->window_func_lut)
212  return AVERROR(ENOMEM);
214  if (s->overlap == 1)
215  s->overlap = overlap;
216  s->hop_size = (1 - s->overlap) * s->win_size;
217  for (factor = 0, i = 0; i < s->win_size; i++) {
218  factor += s->window_func_lut[i] * s->window_func_lut[i];
219  }
220  s->factor = (factor / s->win_size) / FFMAX(1 / (1 - s->overlap) - 1, 1);
221 
222  return 0;
223 }
224 
225 static int request_frame(AVFilterLink *outlink)
226 {
227  AVFilterContext *ctx = outlink->src;
228  SpectrumSynthContext *s = ctx->priv;
229  int ret;
230 
231  if (!s->magnitude) {
232  ret = ff_request_frame(ctx->inputs[0]);
233  if (ret < 0)
234  return ret;
235  }
236  if (!s->phase) {
237  ret = ff_request_frame(ctx->inputs[1]);
238  if (ret < 0)
239  return ret;
240  }
241  return 0;
242 }
243 
245  int x, int y, int f, int ch)
246 {
247  const int m_linesize = s->magnitude->linesize[0];
248  const int p_linesize = s->phase->linesize[0];
249  const uint16_t *m = (uint16_t *)(s->magnitude->data[0] + y * m_linesize);
250  const uint16_t *p = (uint16_t *)(s->phase->data[0] + y * p_linesize);
251  float magnitude, phase;
252 
253  switch (s->scale) {
254  case LINEAR:
255  magnitude = m[x] / (double)UINT16_MAX;
256  break;
257  case LOG:
258  magnitude = ff_exp10(((m[x] / (double)UINT16_MAX) - 1.) * 6.);
259  break;
260  default:
261  av_assert0(0);
262  }
263  phase = ((p[x] / (double)UINT16_MAX) * 2. - 1.) * M_PI;
264 
265  s->fft_data[ch][f].re = magnitude * cos(phase);
266  s->fft_data[ch][f].im = magnitude * sin(phase);
267 }
268 
270  int x, int y, int f, int ch)
271 {
272  const int m_linesize = s->magnitude->linesize[0];
273  const int p_linesize = s->phase->linesize[0];
274  const uint8_t *m = (uint8_t *)(s->magnitude->data[0] + y * m_linesize);
275  const uint8_t *p = (uint8_t *)(s->phase->data[0] + y * p_linesize);
276  float magnitude, phase;
277 
278  switch (s->scale) {
279  case LINEAR:
280  magnitude = m[x] / (double)UINT8_MAX;
281  break;
282  case LOG:
283  magnitude = ff_exp10(((m[x] / (double)UINT8_MAX) - 1.) * 6.);
284  break;
285  default:
286  av_assert0(0);
287  }
288  phase = ((p[x] / (double)UINT8_MAX) * 2. - 1.) * M_PI;
289 
290  s->fft_data[ch][f].re = magnitude * cos(phase);
291  s->fft_data[ch][f].im = magnitude * sin(phase);
292 }
293 
294 static void read_fft_data(AVFilterContext *ctx, int x, int h, int ch)
295 {
296  SpectrumSynthContext *s = ctx->priv;
297  AVFilterLink *inlink = ctx->inputs[0];
298  int start = h * (s->channels - ch) - 1;
299  int end = h * (s->channels - ch - 1);
300  int y, f;
301 
302  switch (s->orientation) {
303  case VERTICAL:
304  switch (inlink->format) {
306  case AV_PIX_FMT_GRAY16:
307  for (y = start, f = 0; y >= end; y--, f++) {
308  read16_fft_bin(s, x, y, f, ch);
309  }
310  break;
311  case AV_PIX_FMT_YUVJ444P:
312  case AV_PIX_FMT_YUV444P:
313  case AV_PIX_FMT_GRAY8:
314  for (y = start, f = 0; y >= end; y--, f++) {
315  read8_fft_bin(s, x, y, f, ch);
316  }
317  break;
318  }
319  break;
320  case HORIZONTAL:
321  switch (inlink->format) {
323  case AV_PIX_FMT_GRAY16:
324  for (y = end, f = 0; y <= start; y++, f++) {
325  read16_fft_bin(s, y, x, f, ch);
326  }
327  break;
328  case AV_PIX_FMT_YUVJ444P:
329  case AV_PIX_FMT_YUV444P:
330  case AV_PIX_FMT_GRAY8:
331  for (y = end, f = 0; y <= start; y++, f++) {
332  read8_fft_bin(s, y, x, f, ch);
333  }
334  break;
335  }
336  break;
337  }
338 }
339 
340 static void synth_window(AVFilterContext *ctx, int x)
341 {
342  SpectrumSynthContext *s = ctx->priv;
343  const int h = s->size;
344  int nb = s->win_size;
345  int y, f, ch;
346 
347  for (ch = 0; ch < s->channels; ch++) {
348  read_fft_data(ctx, x, h, ch);
349 
350  for (y = h; y <= s->nb_freq; y++) {
351  s->fft_data[ch][y].re = 0;
352  s->fft_data[ch][y].im = 0;
353  }
354 
355  for (y = s->nb_freq + 1, f = s->nb_freq - 1; y < nb; y++, f--) {
356  s->fft_data[ch][y].re = s->fft_data[ch][f].re;
357  s->fft_data[ch][y].im = -s->fft_data[ch][f].im;
358  }
359 
360  av_fft_permute(s->fft, s->fft_data[ch]);
361  av_fft_calc(s->fft, s->fft_data[ch]);
362  }
363 }
364 
365 static int try_push_frame(AVFilterContext *ctx, int x)
366 {
367  SpectrumSynthContext *s = ctx->priv;
368  AVFilterLink *outlink = ctx->outputs[0];
369  const float factor = s->factor;
370  int ch, n, i, ret;
371  int start, end;
372  AVFrame *out;
373 
374  synth_window(ctx, x);
375 
376  for (ch = 0; ch < s->channels; ch++) {
377  float *buf = (float *)s->buffer->extended_data[ch];
378  int j, k;
379 
380  start = s->start;
381  end = s->end;
382  k = end;
383  for (i = 0, j = start; j < k && i < s->win_size; i++, j++) {
384  buf[j] += s->fft_data[ch][i].re;
385  }
386 
387  for (; i < s->win_size; i++, j++) {
388  buf[j] = s->fft_data[ch][i].re;
389  }
390 
391  start += s->hop_size;
392  end = j;
393 
394  if (start >= s->win_size) {
395  start -= s->win_size;
396  end -= s->win_size;
397 
398  if (ch == s->channels - 1) {
399  float *dst;
400  int c;
401 
402  out = ff_get_audio_buffer(outlink, s->win_size);
403  if (!out) {
405  av_frame_free(&s->phase);
406  return AVERROR(ENOMEM);
407  }
408 
409  out->pts = s->pts;
410  s->pts += s->win_size;
411  for (c = 0; c < s->channels; c++) {
412  dst = (float *)out->extended_data[c];
413  buf = (float *)s->buffer->extended_data[c];
414 
415  for (n = 0; n < s->win_size; n++) {
416  dst[n] = buf[n] * factor;
417  }
418  memmove(buf, buf + s->win_size, s->win_size * 4);
419  }
420 
421  ret = ff_filter_frame(outlink, out);
422  if (ret < 0)
423  return ret;
424  }
425  }
426  }
427 
428  s->start = start;
429  s->end = end;
430 
431  return 0;
432 }
433 
435 {
436  SpectrumSynthContext *s = ctx->priv;
437  int ret, x;
438 
439  if (!(s->magnitude && s->phase))
440  return 0;
441 
442  switch (s->sliding) {
443  case REPLACE:
444  ret = try_push_frame(ctx, s->xpos);
445  s->xpos++;
446  if (s->xpos >= s->xend)
447  s->xpos = 0;
448  break;
449  case SCROLL:
450  s->xpos = s->xend - 1;
451  ret = try_push_frame(ctx, s->xpos);
452  break;
453  case RSCROLL:
454  s->xpos = 0;
455  ret = try_push_frame(ctx, s->xpos);
456  break;
457  case FULLFRAME:
458  for (x = 0; x < s->xend; x++) {
459  ret = try_push_frame(ctx, x);
460  if (ret < 0)
461  break;
462  }
463  break;
464  default:
465  av_assert0(0);
466  }
467 
469  av_frame_free(&s->phase);
470  return ret;
471 }
472 
474 {
475  AVFilterContext *ctx = inlink->dst;
476  SpectrumSynthContext *s = ctx->priv;
477 
478  s->magnitude = magnitude;
479  return try_push_frames(ctx);
480 }
481 
483 {
484  AVFilterContext *ctx = inlink->dst;
485  SpectrumSynthContext *s = ctx->priv;
486 
487  s->phase = phase;
488  return try_push_frames(ctx);
489 }
490 
492 {
493  SpectrumSynthContext *s = ctx->priv;
494  int i;
495 
497  av_frame_free(&s->phase);
498  av_frame_free(&s->buffer);
499  av_fft_end(s->fft);
500  if (s->fft_data) {
501  for (i = 0; i < s->channels; i++)
502  av_freep(&s->fft_data[i]);
503  }
504  av_freep(&s->fft_data);
506 }
507 
509  {
510  .name = "magnitude",
511  .type = AVMEDIA_TYPE_VIDEO,
512  .filter_frame = filter_frame_magnitude,
513  .needs_fifo = 1,
514  },
515  {
516  .name = "phase",
517  .type = AVMEDIA_TYPE_VIDEO,
518  .filter_frame = filter_frame_phase,
519  .needs_fifo = 1,
520  },
521  { NULL }
522 };
523 
525  {
526  .name = "default",
527  .type = AVMEDIA_TYPE_AUDIO,
528  .config_props = config_output,
529  .request_frame = request_frame,
530  },
531  { NULL }
532 };
533 
535  .name = "spectrumsynth",
536  .description = NULL_IF_CONFIG_SMALL("Convert input spectrum videos to audio output."),
537  .uninit = uninit,
538  .query_formats = query_formats,
539  .priv_size = sizeof(SpectrumSynthContext),
540  .inputs = spectrumsynth_inputs,
541  .outputs = spectrumsynth_outputs,
542  .priv_class = &spectrumsynth_class,
543 };
float, planar
Definition: samplefmt.h:69
#define NULL
Definition: coverity.c:32
const char * s
Definition: avisynth_c.h:768
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h: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
av_cold void av_fft_end(FFTContext *s)
Definition: avfft.c:48
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:67
Main libavfilter public API header.
AVFILTER_DEFINE_CLASS(spectrumsynth)
channels
Definition: aptx.c:30
int num
Numerator.
Definition: rational.h:59
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
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
static const AVOption spectrumsynth_options[]
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
const char * name
Pad name.
Definition: internal.h:60
AVFilterLink ** inputs
array of pointers to input links
Definition: avfilter.h:346
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
int ff_channel_layouts_ref(AVFilterChannelLayouts *f, AVFilterChannelLayouts **ref)
Add *ref as a new reference to f.
Definition: formats.c:435
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1080
float * window_func_lut
Window function LUT.
FFTComplex ** fft_data
bins holder for each (displayed) channels
uint8_t
#define av_cold
Definition: attributes.h:82
AVOptions.
static int query_formats(AVFilterContext *ctx)
static const AVFilterPad spectrumsynth_outputs[]
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:311
static int try_push_frames(AVFilterContext *ctx)
static void read16_fft_bin(SpectrumSynthContext *s, int x, int y, int f, int ch)
#define height
#define AV_PIX_FMT_YUV444P16
Definition: pixfmt.h:381
#define av_log(a,...)
SlideMode
A filter pad used for either input or output.
Definition: internal.h:54
static av_always_inline double ff_exp10(double x)
Compute 10^x for floating point values.
Definition: ffmath.h:42
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
static void read8_fft_bin(SpectrumSynthContext *s, int x, int y, int f, int ch)
int ff_add_channel_layout(AVFilterChannelLayouts **l, uint64_t channel_layout)
Definition: formats.c:343
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
static const AVFilterPad spectrumsynth_inputs[]
uint16_t width
Definition: gdv.c:47
simple assert() macros that are a bit more flexible than ISO C assert().
#define V
static void read_fft_data(AVFilterContext *ctx, int x, int h, int ch)
FFTContext * av_fft_init(int nbits, int inverse)
Set up a complex FFT.
Definition: avfft.c:28
#define FFMAX(a, b)
Definition: common.h:94
Definition: fft.h:88
FFTContext * fft
Fast Fourier Transform context.
audio channel layout utility functions
#define AV_PIX_FMT_GRAY16
Definition: pixfmt.h:352
int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
Add *ref as a new reference to formats.
Definition: formats.c:440
AVFormatContext * ctx
Definition: movenc.c:48
static int filter_frame_magnitude(AVFilterLink *inlink, AVFrame *magnitude)
int n
Definition: avisynth_c.h:684
MagnitudeScale
static const AVFilterPad inputs[]
Definition: af_acontrast.c:193
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
A list of supported channel layouts.
Definition: formats.h:85
static av_cold void uninit(AVFilterContext *ctx)
Orientation
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:249
FFT functions.
#define A
void * buf
Definition: avisynth_c.h:690
Describe the class of an AVClass context structure.
Definition: log.h:67
Filter definition.
Definition: avfilter.h:144
Rational number (pair of numerator and denominator).
Definition: rational.h:58
int fft_bits
number of bits (FFT window size = 1<<fft_bits)
const char * name
Filter name.
Definition: avfilter.h:148
misc parsing utilities
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:350
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:266
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:232
static int av_cmp_q(AVRational a, AVRational b)
Compare two rationals.
Definition: rational.h:89
static int request_frame(AVFilterLink *outlink)
internal math functions header
Y , 8bpp.
Definition: pixfmt.h:70
sample_rates
FFTSample im
Definition: avfft.h:38
static double c[64]
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
Definition: pixfmt.h:76
int den
Denominator.
Definition: rational.h:60
static int try_push_frame(AVFilterContext *ctx, int x)
AVFilter ff_vaf_spectrumsynth
A list of supported formats for one end of a filter link.
Definition: formats.h:64
uint64_t layout
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)
#define FF_COUNT2LAYOUT(c)
Encode a channel count as a channel layout.
Definition: formats.h:102
#define M_PI
Definition: mathematics.h:52
static int filter_frame_phase(AVFilterLink *inlink, AVFrame *phase)
int ff_request_frame(AVFilterLink *link)
Request an input frame from the filter at the other end of the link.
Definition: avfilter.c:407
formats
Definition: signature.h:48
internal API functions
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: frame.h:265
static int config_output(AVFilterLink *outlink)
static void synth_window(AVFilterContext *ctx, int x)
void av_fft_calc(FFTContext *s, FFTComplex *z)
Do a complex FFT with the parameters defined in av_fft_init().
Definition: avfft.c:43
AVPixelFormat
Pixel format.
Definition: pixfmt.h:60
for(j=16;j >0;--j)
#define OFFSET(x)