FFmpeg
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 
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;
124  if (!formats)
125  return AVERROR(ENOMEM);
126  if ((ret = ff_formats_ref(formats, &outlink->in_samplerates)) < 0)
127  return ret;
128 
130  if (!formats)
131  return AVERROR(ENOMEM);
132  if ((ret = ff_formats_ref(formats, &magnitude->out_formats)) < 0)
133  return ret;
134 
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) {
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) {
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) {
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 */
209  s->window_func_lut = av_realloc_f(s->window_func_lut, s->win_size,
210  sizeof(*s->window_func_lut));
211  if (!s->window_func_lut)
212  return AVERROR(ENOMEM);
213  generate_window_func(s->window_func_lut, s->win_size, s->win_func, &overlap);
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) {
404  av_frame_free(&s->magnitude);
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 
468  av_frame_free(&s->magnitude);
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 
496  av_frame_free(&s->magnitude);
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);
505  av_freep(&s->window_func_lut);
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),
542  .priv_class = &spectrumsynth_class,
543 };
formats
formats
Definition: signature.h:48
av_fft_end
av_cold void av_fft_end(FFTContext *s)
Definition: avfft.c:48
ff_get_audio_buffer
AVFrame * ff_get_audio_buffer(AVFilterLink *link, int nb_samples)
Request an audio samples buffer with a specific set of permissions.
Definition: audio.c:86
AV_SAMPLE_FMT_FLTP
@ AV_SAMPLE_FMT_FLTP
float, planar
Definition: samplefmt.h:69
AVFilterChannelLayouts
A list of supported channel layouts.
Definition: formats.h:85
try_push_frames
static int try_push_frames(AVFilterContext *ctx)
Definition: vaf_spectrumsynth.c:434
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
ff_exp10
static av_always_inline double ff_exp10(double x)
Compute 10^x for floating point values.
Definition: ffmath.h:42
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
ff_make_format_list
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:283
out
FILE * out
Definition: movenc.c:54
n
int n
Definition: avisynth_c.h:760
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1080
sample_fmts
static enum AVSampleFormat sample_fmts[]
Definition: adpcmenc.c:686
ff_channel_layouts_ref
int ff_channel_layouts_ref(AVFilterChannelLayouts *f, AVFilterChannelLayouts **ref)
Add *ref as a new reference to f.
Definition: formats.c:435
SpectrumSynthContext::size
int size
Definition: vaf_spectrumsynth.c:59
SpectrumSynthContext::scale
int scale
Definition: vaf_spectrumsynth.c:48
ch
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 &&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);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
inlink
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is inlink
Definition: filter_design.txt:212
SCROLL
@ SCROLL
Definition: vaf_spectrumsynth.c:41
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:202
end
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
MagnitudeScale
MagnitudeScale
Definition: vaf_spectrumsynth.c:40
AVOption
AVOption.
Definition: opt.h:246
ff_request_frame
int ff_request_frame(AVFilterLink *link)
Request an input frame from the filter at the other end of the link.
Definition: avfilter.c:407
av_fft_permute
void av_fft_permute(FFTContext *s, FFTComplex *z)
Do the permutation needed BEFORE calling ff_fft_calc().
Definition: avfft.c:38
request_frame
static int request_frame(AVFilterLink *outlink)
Definition: vaf_spectrumsynth.c:225
channels
channels
Definition: aptx.c:30
SpectrumSynthContext
Definition: vaf_spectrumsynth.c:44
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:148
video.h
SpectrumSynthContext::buffer
AVFrame * buffer
Definition: vaf_spectrumsynth.c:67
sample_rate
sample_rate
Definition: ffmpeg_filter.c:191
filter_frame_phase
static int filter_frame_phase(AVFilterLink *inlink, AVFrame *phase)
Definition: vaf_spectrumsynth.c:482
AVFilterFormats
A list of supported formats for one end of a filter link.
Definition: formats.h:64
formats.h
config_output
static int config_output(AVFilterLink *outlink)
Definition: vaf_spectrumsynth.c:144
start
void INT64 start
Definition: avisynth_c.h:767
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(spectrumsynth)
SpectrumSynthContext::end
int end
Definition: vaf_spectrumsynth.c:62
AV_PIX_FMT_GRAY16
#define AV_PIX_FMT_GRAY16
Definition: pixfmt.h:371
SpectrumSynthContext::start
int start
Definition: vaf_spectrumsynth.c:62
SpectrumSynthContext::sliding
int sliding
Definition: vaf_spectrumsynth.c:49
AVRational::num
int num
Numerator.
Definition: rational.h:59
SpectrumSynthContext::window_func_lut
float * window_func_lut
Window function LUT.
Definition: vaf_spectrumsynth.c:68
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:54
SpectrumSynthContext::magnitude
AVFrame * magnitude
Definition: vaf_spectrumsynth.c:54
SpectrumSynthContext::sample_rate
int sample_rate
Definition: vaf_spectrumsynth.c:46
avassert.h
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
buf
void * buf
Definition: avisynth_c.h:766
av_cold
#define av_cold
Definition: attributes.h:84
ff_add_channel_layout
int ff_add_channel_layout(AVFilterChannelLayouts **l, uint64_t channel_layout)
Definition: formats.c:343
width
#define width
s
#define s(width, name)
Definition: cbs_vp9.c:257
SpectrumSynthContext::fft_bits
int fft_bits
number of bits (FFT window size = 1<<fft_bits)
Definition: vaf_spectrumsynth.c:56
AV_PIX_FMT_YUV444P16
#define AV_PIX_FMT_YUV444P16
Definition: pixfmt.h:400
Orientation
Orientation
Definition: avf_showspectrum.c:52
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
ff_formats_ref
int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
Add *ref as a new reference to formats.
Definition: formats.c:440
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
NB_SLIDES
@ NB_SLIDES
Definition: vaf_spectrumsynth.c:41
outputs
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
pix_fmts
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:275
WFUNC_RECT
@ WFUNC_RECT
Definition: window_func.h:28
ctx
AVFormatContext * ctx
Definition: movenc.c:48
synth_window
static void synth_window(AVFilterContext *ctx, int x)
Definition: vaf_spectrumsynth.c:340
A
#define A
Definition: vaf_spectrumsynth.c:72
f
#define f(width, name)
Definition: cbs_vp9.c:255
AV_PIX_FMT_YUVJ444P
@ AV_PIX_FMT_YUVJ444P
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
Definition: pixfmt.h:80
OFFSET
#define OFFSET(x)
Definition: vaf_spectrumsynth.c:71
av_realloc_f
#define av_realloc_f(p, o, n)
Definition: tableprint_vlc.h:33
ff_vaf_spectrumsynth
AVFilter ff_vaf_spectrumsynth
Definition: vaf_spectrumsynth.c:534
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:67
NULL
#define NULL
Definition: coverity.c:32
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
WFUNC_HAMMING
@ WFUNC_HAMMING
Definition: af_firequalizer.c:35
parseutils.h
generate_window_func
static void generate_window_func(float *lut, int N, int win_func, float *overlap)
Definition: window_func.h:36
avfft.h
WFUNC_HANNING
@ WFUNC_HANNING
Definition: window_func.h:28
WFUNC_BARTLETT
@ WFUNC_BARTLETT
Definition: window_func.h:29
inputs
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several inputs
Definition: filter_design.txt:243
AV_PIX_FMT_GRAY8
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:74
try_push_frame
static int try_push_frame(AVFilterContext *ctx, int x)
Definition: vaf_spectrumsynth.c:365
spectrumsynth_outputs
static const AVFilterPad spectrumsynth_outputs[]
Definition: vaf_spectrumsynth.c:524
SpectrumSynthContext::xend
int xend
Definition: vaf_spectrumsynth.c:64
VERTICAL
@ VERTICAL
Definition: vaf_spectrumsynth.c:42
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
SpectrumSynthContext::phase
AVFrame * phase
Definition: vaf_spectrumsynth.c:54
for
for(j=16;j >0;--j)
Definition: h264pred_template.c:469
SpectrumSynthContext::xpos
int xpos
Definition: vaf_spectrumsynth.c:63
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:188
spectrumsynth_inputs
static const AVFilterPad spectrumsynth_inputs[]
Definition: vaf_spectrumsynth.c:508
FFMAX
#define FFMAX(a, b)
Definition: common.h:94
read_fft_data
static void read_fft_data(AVFilterContext *ctx, int x, int h, int ch)
Definition: vaf_spectrumsynth.c:294
AV_SAMPLE_FMT_NONE
@ AV_SAMPLE_FMT_NONE
Definition: samplefmt.h:59
SpectrumSynthContext::fft_data
FFTComplex ** fft_data
bins holder for each (displayed) channels
Definition: vaf_spectrumsynth.c:57
SpectrumSynthContext::factor
float factor
Definition: vaf_spectrumsynth.c:66
SpectrumSynthContext::hop_size
int hop_size
Definition: vaf_spectrumsynth.c:61
height
#define height
SpectrumSynthContext::orientation
int orientation
Definition: vaf_spectrumsynth.c:52
NB_ORIENTATIONS
@ NB_ORIENTATIONS
Definition: vaf_spectrumsynth.c:42
read16_fft_bin
static void read16_fft_bin(SpectrumSynthContext *s, int x, int y, int f, int ch)
Definition: vaf_spectrumsynth.c:244
SpectrumSynthContext::win_func
int win_func
Definition: vaf_spectrumsynth.c:50
M_PI
#define M_PI
Definition: mathematics.h:52
sample_rates
sample_rates
Definition: ffmpeg_filter.c:191
internal.h
AV_OPT_TYPE_FLOAT
@ AV_OPT_TYPE_FLOAT
Definition: opt.h:226
layout
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel layout
Definition: filter_design.txt:18
FFTContext
Definition: fft.h:88
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
HORIZONTAL
@ HORIZONTAL
Definition: vaf_spectrumsynth.c:42
SpectrumSynthContext::channels
int channels
Definition: vaf_spectrumsynth.c:47
AVSampleFormat
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
SpectrumSynthContext::nb_freq
int nb_freq
Definition: vaf_spectrumsynth.c:60
filter_frame_magnitude
static int filter_frame_magnitude(AVFilterLink *inlink, AVFrame *magnitude)
Definition: vaf_spectrumsynth.c:473
SpectrumSynthContext::overlap
float overlap
Definition: vaf_spectrumsynth.c:51
uint8_t
uint8_t
Definition: audio_convert.c:194
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:60
av_cmp_q
static int av_cmp_q(AVRational a, AVRational b)
Compare two rationals.
Definition: rational.h:89
AVFilter
Filter definition.
Definition: avfilter.h:144
ret
ret
Definition: filter_design.txt:187
FF_COUNT2LAYOUT
#define FF_COUNT2LAYOUT(c)
Encode a channel count as a channel layout.
Definition: formats.h:102
av_fft_init
FFTContext * av_fft_init(int nbits, int inverse)
Set up a complex FFT.
Definition: avfft.c:28
window_func.h
FULLFRAME
@ FULLFRAME
Definition: vaf_spectrumsynth.c:41
NB_WFUNC
@ NB_WFUNC
Definition: af_firequalizer.c:43
query_formats
static int query_formats(AVFilterContext *ctx)
Definition: vaf_spectrumsynth.c:102
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
Definition: mem.c:244
channel_layout.h
WFUNC_SINE
@ WFUNC_SINE
Definition: window_func.h:30
spectrumsynth_options
static const AVOption spectrumsynth_options[]
Definition: vaf_spectrumsynth.c:75
AVRational::den
int den
Denominator.
Definition: rational.h:60
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
read8_fft_bin
static void read8_fft_bin(SpectrumSynthContext *s, int x, int y, int f, int ch)
Definition: vaf_spectrumsynth.c:269
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:223
avfilter.h
ffmath.h
AV_PIX_FMT_YUV444P
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:71
SpectrumSynthContext::fft
FFTContext * fft
Fast Fourier Transform context.
Definition: vaf_spectrumsynth.c:55
AVFilterContext
An instance of a filter.
Definition: avfilter.h:338
factor
static const int factor[16]
Definition: vf_pp7.c:75
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
audio.h
V
#define V
Definition: vaf_spectrumsynth.c:73
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
LOG
@ LOG
Definition: vaf_spectrumsynth.c:40
SpectrumSynthContext::win_size
int win_size
Definition: vaf_spectrumsynth.c:58
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
h
h
Definition: vp9dsp_template.c:2038
LINEAR
@ LINEAR
Definition: vaf_spectrumsynth.c:40
REPLACE
@ REPLACE
Definition: vaf_spectrumsynth.c:41
RSCROLL
@ RSCROLL
Definition: vaf_spectrumsynth.c:41
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:232
av_fft_calc
void av_fft_calc(FFTContext *s, FFTComplex *z)
Do a complex FFT with the parameters defined in av_fft_init().
Definition: avfft.c:43
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: vaf_spectrumsynth.c:491
NB_SCALES
@ NB_SCALES
Definition: vaf_spectrumsynth.c:40
SpectrumSynthContext::pts
int64_t pts
Definition: vaf_spectrumsynth.c:65
SlideMode
SlideMode
Definition: avf_ahistogram.c:33
FFTComplex
Definition: avfft.h:37