FFmpeg  4.4
af_sofalizer.c
Go to the documentation of this file.
1 /*****************************************************************************
2  * sofalizer.c : SOFAlizer filter for virtual binaural acoustics
3  *****************************************************************************
4  * Copyright (C) 2013-2015 Andreas Fuchs, Wolfgang Hrauda,
5  * Acoustics Research Institute (ARI), Vienna, Austria
6  *
7  * Authors: Andreas Fuchs <andi.fuchs.mail@gmail.com>
8  * Wolfgang Hrauda <wolfgang.hrauda@gmx.at>
9  *
10  * SOFAlizer project coordinator at ARI, main developer of SOFA:
11  * Piotr Majdak <piotr@majdak.at>
12  *
13  * This program is free software; you can redistribute it and/or modify it
14  * under the terms of the GNU Lesser General Public License as published by
15  * the Free Software Foundation; either version 2.1 of the License, or
16  * (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU Lesser General Public License for more details.
22  *
23  * You should have received a copy of the GNU Lesser General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
26  *****************************************************************************/
27 
28 #include <math.h>
29 #include <mysofa.h>
30 
31 #include "libavcodec/avfft.h"
32 #include "libavutil/avstring.h"
34 #include "libavutil/float_dsp.h"
35 #include "libavutil/intmath.h"
36 #include "libavutil/opt.h"
37 #include "avfilter.h"
38 #include "filters.h"
39 #include "internal.h"
40 #include "audio.h"
41 
42 #define TIME_DOMAIN 0
43 #define FREQUENCY_DOMAIN 1
44 
45 typedef struct MySofa { /* contains data of one SOFA file */
46  struct MYSOFA_HRTF *hrtf;
47  struct MYSOFA_LOOKUP *lookup;
48  struct MYSOFA_NEIGHBORHOOD *neighborhood;
49  int ir_samples; /* length of one impulse response (IR) */
50  int n_samples; /* ir_samples to next power of 2 */
51  float *lir, *rir; /* IRs (time-domain) */
52  float *fir;
53  int max_delay;
54 } MySofa;
55 
56 typedef struct VirtualSpeaker {
58  float azim;
59  float elev;
61 
62 typedef struct SOFAlizerContext {
63  const AVClass *class;
64 
65  char *filename; /* name of SOFA file */
66  MySofa sofa; /* contains data of the SOFA file */
67 
68  int sample_rate; /* sample rate from SOFA file */
69  float *speaker_azim; /* azimuth of the virtual loudspeakers */
70  float *speaker_elev; /* elevation of the virtual loudspeakers */
71  char *speakers_pos; /* custom positions of the virtual loudspeakers */
72  float lfe_gain; /* initial gain for the LFE channel */
73  float gain_lfe; /* gain applied to LFE channel */
74  int lfe_channel; /* LFE channel position in channel layout */
75 
76  int n_conv; /* number of channels to convolute */
77 
78  /* buffer variables (for convolution) */
79  float *ringbuffer[2]; /* buffers input samples, length of one buffer: */
80  /* no. input ch. (incl. LFE) x buffer_length */
81  int write[2]; /* current write position to ringbuffer */
82  int buffer_length; /* is: longest IR plus max. delay in all SOFA files */
83  /* then choose next power of 2 */
84  int n_fft; /* number of samples in one FFT block */
86 
87  /* netCDF variables */
88  int *delay[2]; /* broadband delay for each channel/IR to be convolved */
89 
90  float *data_ir[2]; /* IRs for all channels to be convolved */
91  /* (this excludes the LFE) */
92  float *temp_src[2];
93  FFTComplex *temp_fft[2]; /* Array to hold FFT values */
94  FFTComplex *temp_afft[2]; /* Array to accumulate FFT values prior to IFFT */
95 
96  /* control variables */
97  float gain; /* filter gain (in dB) */
98  float rotation; /* rotation of virtual loudspeakers (in degrees) */
99  float elevation; /* elevation of virtual loudspeakers (in deg.) */
100  float radius; /* distance virtual loudspeakers to listener (in metres) */
101  int type; /* processing type */
102  int framesize; /* size of buffer */
103  int normalize; /* should all IRs be normalized upon import ? */
104  int interpolate; /* should wanted IRs be interpolated from neighbors ? */
105  int minphase; /* should all IRs be minphased upon import ? */
106  float anglestep; /* neighbor search angle step, in agles */
107  float radstep; /* neighbor search radius step, in meters */
108 
110 
111  FFTContext *fft[2], *ifft[2];
113 
116 
117 static int close_sofa(struct MySofa *sofa)
118 {
119  if (sofa->neighborhood)
120  mysofa_neighborhood_free(sofa->neighborhood);
121  sofa->neighborhood = NULL;
122  if (sofa->lookup)
123  mysofa_lookup_free(sofa->lookup);
124  sofa->lookup = NULL;
125  if (sofa->hrtf)
126  mysofa_free(sofa->hrtf);
127  sofa->hrtf = NULL;
128  av_freep(&sofa->fir);
129 
130  return 0;
131 }
132 
133 static int preload_sofa(AVFilterContext *ctx, char *filename, int *samplingrate)
134 {
135  struct SOFAlizerContext *s = ctx->priv;
136  struct MYSOFA_HRTF *mysofa;
137  char *license;
138  int ret;
139 
140  mysofa = mysofa_load(filename, &ret);
141  s->sofa.hrtf = mysofa;
142  if (ret || !mysofa) {
143  av_log(ctx, AV_LOG_ERROR, "Can't find SOFA-file '%s'\n", filename);
144  return AVERROR(EINVAL);
145  }
146 
147  ret = mysofa_check(mysofa);
148  if (ret != MYSOFA_OK) {
149  av_log(ctx, AV_LOG_ERROR, "Selected SOFA file is invalid. Please select valid SOFA file.\n");
150  return ret;
151  }
152 
153  if (s->normalize)
154  mysofa_loudness(s->sofa.hrtf);
155 
156  if (s->minphase)
157  mysofa_minphase(s->sofa.hrtf, 0.01f);
158 
159  mysofa_tocartesian(s->sofa.hrtf);
160 
161  s->sofa.lookup = mysofa_lookup_init(s->sofa.hrtf);
162  if (s->sofa.lookup == NULL)
163  return AVERROR(EINVAL);
164 
165  if (s->interpolate)
166  s->sofa.neighborhood = mysofa_neighborhood_init_withstepdefine(s->sofa.hrtf,
167  s->sofa.lookup,
168  s->anglestep,
169  s->radstep);
170 
171  s->sofa.fir = av_calloc(s->sofa.hrtf->N * s->sofa.hrtf->R, sizeof(*s->sofa.fir));
172  if (!s->sofa.fir)
173  return AVERROR(ENOMEM);
174 
175  if (mysofa->DataSamplingRate.elements != 1)
176  return AVERROR(EINVAL);
177  av_log(ctx, AV_LOG_DEBUG, "Original IR length: %d.\n", mysofa->N);
178  *samplingrate = mysofa->DataSamplingRate.values[0];
179  license = mysofa_getAttribute(mysofa->attributes, (char *)"License");
180  if (license)
181  av_log(ctx, AV_LOG_INFO, "SOFA license: %s\n", license);
182 
183  return 0;
184 }
185 
186 static int parse_channel_name(AVFilterContext *ctx, char **arg, int *rchannel)
187 {
188  int len, i, channel_id = 0;
189  int64_t layout, layout0;
190  char buf[8] = {0};
191 
192  /* try to parse a channel name, e.g. "FL" */
193  if (av_sscanf(*arg, "%7[A-Z]%n", buf, &len)) {
194  layout0 = layout = av_get_channel_layout(buf);
195  /* channel_id <- first set bit in layout */
196  for (i = 32; i > 0; i >>= 1) {
197  if (layout >= 1LL << i) {
198  channel_id += i;
199  layout >>= i;
200  }
201  }
202  /* reject layouts that are not a single channel */
203  if (channel_id >= 64 || layout0 != 1LL << channel_id) {
204  av_log(ctx, AV_LOG_WARNING, "Failed to parse \'%s\' as channel name.\n", buf);
205  return AVERROR(EINVAL);
206  }
207  *rchannel = channel_id;
208  *arg += len;
209  return 0;
210  } else if (av_sscanf(*arg, "%d%n", &channel_id, &len) == 1) {
211  if (channel_id < 0 || channel_id >= 64) {
212  av_log(ctx, AV_LOG_WARNING, "Failed to parse \'%d\' as channel number.\n", channel_id);
213  return AVERROR(EINVAL);
214  }
215  *rchannel = channel_id;
216  *arg += len;
217  return 0;
218  }
219  return AVERROR(EINVAL);
220 }
221 
222 static void parse_speaker_pos(AVFilterContext *ctx, int64_t in_channel_layout)
223 {
224  SOFAlizerContext *s = ctx->priv;
225  char *arg, *tokenizer, *p, *args = av_strdup(s->speakers_pos);
226 
227  if (!args)
228  return;
229  p = args;
230 
231  while ((arg = av_strtok(p, "|", &tokenizer))) {
232  float azim, elev;
233  int out_ch_id;
234 
235  p = NULL;
236  if (parse_channel_name(ctx, &arg, &out_ch_id)) {
237  continue;
238  }
239  if (av_sscanf(arg, "%f %f", &azim, &elev) == 2) {
240  s->vspkrpos[out_ch_id].set = 1;
241  s->vspkrpos[out_ch_id].azim = azim;
242  s->vspkrpos[out_ch_id].elev = elev;
243  } else if (av_sscanf(arg, "%f", &azim) == 1) {
244  s->vspkrpos[out_ch_id].set = 1;
245  s->vspkrpos[out_ch_id].azim = azim;
246  s->vspkrpos[out_ch_id].elev = 0;
247  }
248  }
249 
250  av_free(args);
251 }
252 
254  float *speaker_azim, float *speaker_elev)
255 {
256  struct SOFAlizerContext *s = ctx->priv;
257  uint64_t channels_layout = ctx->inputs[0]->channel_layout;
258  float azim[64] = { 0 };
259  float elev[64] = { 0 };
260  int m, ch, n_conv = ctx->inputs[0]->channels; /* get no. input channels */
261 
262  if (n_conv < 0 || n_conv > 64)
263  return AVERROR(EINVAL);
264 
265  s->lfe_channel = -1;
266 
267  if (s->speakers_pos)
268  parse_speaker_pos(ctx, channels_layout);
269 
270  /* set speaker positions according to input channel configuration: */
271  for (m = 0, ch = 0; ch < n_conv && m < 64; m++) {
272  uint64_t mask = channels_layout & (1ULL << m);
273 
274  switch (mask) {
275  case AV_CH_FRONT_LEFT: azim[ch] = 30; break;
276  case AV_CH_FRONT_RIGHT: azim[ch] = 330; break;
277  case AV_CH_FRONT_CENTER: azim[ch] = 0; break;
278  case AV_CH_LOW_FREQUENCY:
279  case AV_CH_LOW_FREQUENCY_2: s->lfe_channel = ch; break;
280  case AV_CH_BACK_LEFT: azim[ch] = 150; break;
281  case AV_CH_BACK_RIGHT: azim[ch] = 210; break;
282  case AV_CH_BACK_CENTER: azim[ch] = 180; break;
283  case AV_CH_SIDE_LEFT: azim[ch] = 90; break;
284  case AV_CH_SIDE_RIGHT: azim[ch] = 270; break;
285  case AV_CH_FRONT_LEFT_OF_CENTER: azim[ch] = 15; break;
286  case AV_CH_FRONT_RIGHT_OF_CENTER: azim[ch] = 345; break;
287  case AV_CH_TOP_CENTER: azim[ch] = 0;
288  elev[ch] = 90; break;
289  case AV_CH_TOP_FRONT_LEFT: azim[ch] = 30;
290  elev[ch] = 45; break;
291  case AV_CH_TOP_FRONT_CENTER: azim[ch] = 0;
292  elev[ch] = 45; break;
293  case AV_CH_TOP_FRONT_RIGHT: azim[ch] = 330;
294  elev[ch] = 45; break;
295  case AV_CH_TOP_BACK_LEFT: azim[ch] = 150;
296  elev[ch] = 45; break;
297  case AV_CH_TOP_BACK_RIGHT: azim[ch] = 210;
298  elev[ch] = 45; break;
299  case AV_CH_TOP_BACK_CENTER: azim[ch] = 180;
300  elev[ch] = 45; break;
301  case AV_CH_WIDE_LEFT: azim[ch] = 90; break;
302  case AV_CH_WIDE_RIGHT: azim[ch] = 270; break;
303  case AV_CH_SURROUND_DIRECT_LEFT: azim[ch] = 90; break;
304  case AV_CH_SURROUND_DIRECT_RIGHT: azim[ch] = 270; break;
305  case AV_CH_STEREO_LEFT: azim[ch] = 90; break;
306  case AV_CH_STEREO_RIGHT: azim[ch] = 270; break;
307  case 0: break;
308  default:
309  return AVERROR(EINVAL);
310  }
311 
312  if (s->vspkrpos[m].set) {
313  azim[ch] = s->vspkrpos[m].azim;
314  elev[ch] = s->vspkrpos[m].elev;
315  }
316 
317  if (mask)
318  ch++;
319  }
320 
321  memcpy(speaker_azim, azim, n_conv * sizeof(float));
322  memcpy(speaker_elev, elev, n_conv * sizeof(float));
323 
324  return 0;
325 
326 }
327 
328 typedef struct ThreadData {
329  AVFrame *in, *out;
330  int *write;
331  int **delay;
332  float **ir;
333  int *n_clippings;
334  float **ringbuffer;
335  float **temp_src;
338 } ThreadData;
339 
340 static int sofalizer_convolute(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
341 {
342  SOFAlizerContext *s = ctx->priv;
343  ThreadData *td = arg;
344  AVFrame *in = td->in, *out = td->out;
345  int offset = jobnr;
346  int *write = &td->write[jobnr];
347  const int *const delay = td->delay[jobnr];
348  const float *const ir = td->ir[jobnr];
349  int *n_clippings = &td->n_clippings[jobnr];
350  float *ringbuffer = td->ringbuffer[jobnr];
351  float *temp_src = td->temp_src[jobnr];
352  const int ir_samples = s->sofa.ir_samples; /* length of one IR */
353  const int n_samples = s->sofa.n_samples;
354  const int planar = in->format == AV_SAMPLE_FMT_FLTP;
355  const int mult = 1 + !planar;
356  const float *src = (const float *)in->extended_data[0]; /* get pointer to audio input buffer */
357  float *dst = (float *)out->extended_data[jobnr * planar]; /* get pointer to audio output buffer */
358  const int in_channels = s->n_conv; /* number of input channels */
359  /* ring buffer length is: longest IR plus max. delay -> next power of 2 */
360  const int buffer_length = s->buffer_length;
361  /* -1 for AND instead of MODULO (applied to powers of 2): */
362  const uint32_t modulo = (uint32_t)buffer_length - 1;
363  float *buffer[64]; /* holds ringbuffer for each input channel */
364  int wr = *write;
365  int read;
366  int i, l;
367 
368  if (!planar)
369  dst += offset;
370 
371  for (l = 0; l < in_channels; l++) {
372  /* get starting address of ringbuffer for each input channel */
373  buffer[l] = ringbuffer + l * buffer_length;
374  }
375 
376  for (i = 0; i < in->nb_samples; i++) {
377  const float *temp_ir = ir; /* using same set of IRs for each sample */
378 
379  dst[0] = 0;
380  if (planar) {
381  for (l = 0; l < in_channels; l++) {
382  const float *srcp = (const float *)in->extended_data[l];
383 
384  /* write current input sample to ringbuffer (for each channel) */
385  buffer[l][wr] = srcp[i];
386  }
387  } else {
388  for (l = 0; l < in_channels; l++) {
389  /* write current input sample to ringbuffer (for each channel) */
390  buffer[l][wr] = src[l];
391  }
392  }
393 
394  /* loop goes through all channels to be convolved */
395  for (l = 0; l < in_channels; l++) {
396  const float *const bptr = buffer[l];
397 
398  if (l == s->lfe_channel) {
399  /* LFE is an input channel but requires no convolution */
400  /* apply gain to LFE signal and add to output buffer */
401  dst[0] += *(buffer[s->lfe_channel] + wr) * s->gain_lfe;
402  temp_ir += n_samples;
403  continue;
404  }
405 
406  /* current read position in ringbuffer: input sample write position
407  * - delay for l-th ch. + diff. betw. IR length and buffer length
408  * (mod buffer length) */
409  read = (wr - delay[l] - (ir_samples - 1) + buffer_length) & modulo;
410 
411  if (read + ir_samples < buffer_length) {
412  memmove(temp_src, bptr + read, ir_samples * sizeof(*temp_src));
413  } else {
414  int len = FFMIN(n_samples - (read % ir_samples), buffer_length - read);
415 
416  memmove(temp_src, bptr + read, len * sizeof(*temp_src));
417  memmove(temp_src + len, bptr, (n_samples - len) * sizeof(*temp_src));
418  }
419 
420  /* multiply signal and IR, and add up the results */
421  dst[0] += s->fdsp->scalarproduct_float(temp_ir, temp_src, FFALIGN(ir_samples, 32));
422  temp_ir += n_samples;
423  }
424 
425  /* clippings counter */
426  if (fabsf(dst[0]) > 1)
427  n_clippings[0]++;
428 
429  /* move output buffer pointer by +2 to get to next sample of processed channel: */
430  dst += mult;
431  src += in_channels;
432  wr = (wr + 1) & modulo; /* update ringbuffer write position */
433  }
434 
435  *write = wr; /* remember write position in ringbuffer for next call */
436 
437  return 0;
438 }
439 
440 static int sofalizer_fast_convolute(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
441 {
442  SOFAlizerContext *s = ctx->priv;
443  ThreadData *td = arg;
444  AVFrame *in = td->in, *out = td->out;
445  int offset = jobnr;
446  int *write = &td->write[jobnr];
447  FFTComplex *hrtf = s->data_hrtf[jobnr]; /* get pointers to current HRTF data */
448  int *n_clippings = &td->n_clippings[jobnr];
449  float *ringbuffer = td->ringbuffer[jobnr];
450  const int ir_samples = s->sofa.ir_samples; /* length of one IR */
451  const int planar = in->format == AV_SAMPLE_FMT_FLTP;
452  const int mult = 1 + !planar;
453  float *dst = (float *)out->extended_data[jobnr * planar]; /* get pointer to audio output buffer */
454  const int in_channels = s->n_conv; /* number of input channels */
455  /* ring buffer length is: longest IR plus max. delay -> next power of 2 */
456  const int buffer_length = s->buffer_length;
457  /* -1 for AND instead of MODULO (applied to powers of 2): */
458  const uint32_t modulo = (uint32_t)buffer_length - 1;
459  FFTComplex *fft_in = s->temp_fft[jobnr]; /* temporary array for FFT input/output data */
460  FFTComplex *fft_acc = s->temp_afft[jobnr];
461  FFTContext *ifft = s->ifft[jobnr];
462  FFTContext *fft = s->fft[jobnr];
463  const int n_conv = s->n_conv;
464  const int n_fft = s->n_fft;
465  const float fft_scale = 1.0f / s->n_fft;
466  FFTComplex *hrtf_offset;
467  int wr = *write;
468  int n_read;
469  int i, j;
470 
471  if (!planar)
472  dst += offset;
473 
474  /* find minimum between number of samples and output buffer length:
475  * (important, if one IR is longer than the output buffer) */
476  n_read = FFMIN(ir_samples, in->nb_samples);
477  for (j = 0; j < n_read; j++) {
478  /* initialize output buf with saved signal from overflow buf */
479  dst[mult * j] = ringbuffer[wr];
480  ringbuffer[wr] = 0.0f; /* re-set read samples to zero */
481  /* update ringbuffer read/write position */
482  wr = (wr + 1) & modulo;
483  }
484 
485  /* initialize rest of output buffer with 0 */
486  for (j = n_read; j < in->nb_samples; j++) {
487  dst[mult * j] = 0;
488  }
489 
490  /* fill FFT accumulation with 0 */
491  memset(fft_acc, 0, sizeof(FFTComplex) * n_fft);
492 
493  for (i = 0; i < n_conv; i++) {
494  const float *src = (const float *)in->extended_data[i * planar]; /* get pointer to audio input buffer */
495 
496  if (i == s->lfe_channel) { /* LFE */
497  if (in->format == AV_SAMPLE_FMT_FLT) {
498  for (j = 0; j < in->nb_samples; j++) {
499  /* apply gain to LFE signal and add to output buffer */
500  dst[2 * j] += src[i + j * in_channels] * s->gain_lfe;
501  }
502  } else {
503  for (j = 0; j < in->nb_samples; j++) {
504  /* apply gain to LFE signal and add to output buffer */
505  dst[j] += src[j] * s->gain_lfe;
506  }
507  }
508  continue;
509  }
510 
511  /* outer loop: go through all input channels to be convolved */
512  offset = i * n_fft; /* no. samples already processed */
513  hrtf_offset = hrtf + offset;
514 
515  /* fill FFT input with 0 (we want to zero-pad) */
516  memset(fft_in, 0, sizeof(FFTComplex) * n_fft);
517 
518  if (in->format == AV_SAMPLE_FMT_FLT) {
519  for (j = 0; j < in->nb_samples; j++) {
520  /* prepare input for FFT */
521  /* write all samples of current input channel to FFT input array */
522  fft_in[j].re = src[j * in_channels + i];
523  }
524  } else {
525  for (j = 0; j < in->nb_samples; j++) {
526  /* prepare input for FFT */
527  /* write all samples of current input channel to FFT input array */
528  fft_in[j].re = src[j];
529  }
530  }
531 
532  /* transform input signal of current channel to frequency domain */
533  av_fft_permute(fft, fft_in);
534  av_fft_calc(fft, fft_in);
535  for (j = 0; j < n_fft; j++) {
536  const FFTComplex *hcomplex = hrtf_offset + j;
537  const float re = fft_in[j].re;
538  const float im = fft_in[j].im;
539 
540  /* complex multiplication of input signal and HRTFs */
541  /* output channel (real): */
542  fft_acc[j].re += re * hcomplex->re - im * hcomplex->im;
543  /* output channel (imag): */
544  fft_acc[j].im += re * hcomplex->im + im * hcomplex->re;
545  }
546  }
547 
548  /* transform output signal of current channel back to time domain */
549  av_fft_permute(ifft, fft_acc);
550  av_fft_calc(ifft, fft_acc);
551 
552  for (j = 0; j < in->nb_samples; j++) {
553  /* write output signal of current channel to output buffer */
554  dst[mult * j] += fft_acc[j].re * fft_scale;
555  }
556 
557  for (j = 0; j < ir_samples - 1; j++) { /* overflow length is IR length - 1 */
558  /* write the rest of output signal to overflow buffer */
559  int write_pos = (wr + j) & modulo;
560 
561  *(ringbuffer + write_pos) += fft_acc[in->nb_samples + j].re * fft_scale;
562  }
563 
564  /* go through all samples of current output buffer: count clippings */
565  for (i = 0; i < out->nb_samples; i++) {
566  /* clippings counter */
567  if (fabsf(dst[i * mult]) > 1) { /* if current output sample > 1 */
568  n_clippings[0]++;
569  }
570  }
571 
572  /* remember read/write position in ringbuffer for next call */
573  *write = wr;
574 
575  return 0;
576 }
577 
578 static int filter_frame(AVFilterLink *inlink, AVFrame *in)
579 {
580  AVFilterContext *ctx = inlink->dst;
581  SOFAlizerContext *s = ctx->priv;
582  AVFilterLink *outlink = ctx->outputs[0];
583  int n_clippings[2] = { 0 };
584  ThreadData td;
585  AVFrame *out;
586 
587  out = ff_get_audio_buffer(outlink, in->nb_samples);
588  if (!out) {
589  av_frame_free(&in);
590  return AVERROR(ENOMEM);
591  }
593 
594  td.in = in; td.out = out; td.write = s->write;
595  td.delay = s->delay; td.ir = s->data_ir; td.n_clippings = n_clippings;
596  td.ringbuffer = s->ringbuffer; td.temp_src = s->temp_src;
597  td.temp_fft = s->temp_fft;
598  td.temp_afft = s->temp_afft;
599 
600  if (s->type == TIME_DOMAIN) {
601  ctx->internal->execute(ctx, sofalizer_convolute, &td, NULL, 2);
602  } else if (s->type == FREQUENCY_DOMAIN) {
603  ctx->internal->execute(ctx, sofalizer_fast_convolute, &td, NULL, 2);
604  }
605  emms_c();
606 
607  /* display error message if clipping occurred */
608  if (n_clippings[0] + n_clippings[1] > 0) {
609  av_log(ctx, AV_LOG_WARNING, "%d of %d samples clipped. Please reduce gain.\n",
610  n_clippings[0] + n_clippings[1], out->nb_samples * 2);
611  }
612 
613  av_frame_free(&in);
614  return ff_filter_frame(outlink, out);
615 }
616 
618 {
619  AVFilterLink *inlink = ctx->inputs[0];
620  AVFilterLink *outlink = ctx->outputs[0];
621  SOFAlizerContext *s = ctx->priv;
622  AVFrame *in;
623  int ret;
624 
625  FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink);
626 
627  if (s->nb_samples)
628  ret = ff_inlink_consume_samples(inlink, s->nb_samples, s->nb_samples, &in);
629  else
630  ret = ff_inlink_consume_frame(inlink, &in);
631  if (ret < 0)
632  return ret;
633  if (ret > 0)
634  return filter_frame(inlink, in);
635 
636  FF_FILTER_FORWARD_STATUS(inlink, outlink);
637  FF_FILTER_FORWARD_WANTED(outlink, inlink);
638 
639  return FFERROR_NOT_READY;
640 }
641 
643 {
644  struct SOFAlizerContext *s = ctx->priv;
647  int ret, sample_rates[] = { 48000, -1 };
648  static const enum AVSampleFormat sample_fmts[] = {
651  };
652 
654  if (!formats)
655  return AVERROR(ENOMEM);
657  if (ret)
658  return ret;
659 
661  if (!layouts)
662  return AVERROR(ENOMEM);
663 
664  ret = ff_channel_layouts_ref(layouts, &ctx->inputs[0]->outcfg.channel_layouts);
665  if (ret)
666  return ret;
667 
668  layouts = NULL;
670  if (ret)
671  return ret;
672 
673  ret = ff_channel_layouts_ref(layouts, &ctx->outputs[0]->incfg.channel_layouts);
674  if (ret)
675  return ret;
676 
677  sample_rates[0] = s->sample_rate;
679  if (!formats)
680  return AVERROR(ENOMEM);
682 }
683 
684 static int getfilter_float(AVFilterContext *ctx, float x, float y, float z,
685  float *left, float *right,
686  float *delay_left, float *delay_right)
687 {
688  struct SOFAlizerContext *s = ctx->priv;
689  float c[3], delays[2];
690  float *fl, *fr;
691  int nearest;
692  int *neighbors;
693  float *res;
694 
695  c[0] = x, c[1] = y, c[2] = z;
696  nearest = mysofa_lookup(s->sofa.lookup, c);
697  if (nearest < 0)
698  return AVERROR(EINVAL);
699 
700  if (s->interpolate) {
701  neighbors = mysofa_neighborhood(s->sofa.neighborhood, nearest);
702  res = mysofa_interpolate(s->sofa.hrtf, c,
703  nearest, neighbors,
704  s->sofa.fir, delays);
705  } else {
706  if (s->sofa.hrtf->DataDelay.elements > s->sofa.hrtf->R) {
707  delays[0] = s->sofa.hrtf->DataDelay.values[nearest * s->sofa.hrtf->R];
708  delays[1] = s->sofa.hrtf->DataDelay.values[nearest * s->sofa.hrtf->R + 1];
709  } else {
710  delays[0] = s->sofa.hrtf->DataDelay.values[0];
711  delays[1] = s->sofa.hrtf->DataDelay.values[1];
712  }
713  res = s->sofa.hrtf->DataIR.values + nearest * s->sofa.hrtf->N * s->sofa.hrtf->R;
714  }
715 
716  *delay_left = delays[0];
717  *delay_right = delays[1];
718 
719  fl = res;
720  fr = res + s->sofa.hrtf->N;
721 
722  memcpy(left, fl, sizeof(float) * s->sofa.hrtf->N);
723  memcpy(right, fr, sizeof(float) * s->sofa.hrtf->N);
724 
725  return 0;
726 }
727 
728 static int load_data(AVFilterContext *ctx, int azim, int elev, float radius, int sample_rate)
729 {
730  struct SOFAlizerContext *s = ctx->priv;
731  int n_samples;
732  int ir_samples;
733  int n_conv = s->n_conv; /* no. channels to convolve */
734  int n_fft;
735  float delay_l; /* broadband delay for each IR */
736  float delay_r;
737  int nb_input_channels = ctx->inputs[0]->channels; /* no. input channels */
738  float gain_lin = expf((s->gain - 3 * nb_input_channels) / 20 * M_LN10); /* gain - 3dB/channel */
739  FFTComplex *data_hrtf_l = NULL;
740  FFTComplex *data_hrtf_r = NULL;
741  FFTComplex *fft_in_l = NULL;
742  FFTComplex *fft_in_r = NULL;
743  float *data_ir_l = NULL;
744  float *data_ir_r = NULL;
745  int offset = 0; /* used for faster pointer arithmetics in for-loop */
746  int i, j, azim_orig = azim, elev_orig = elev;
747  int ret = 0;
748  int n_current;
749  int n_max = 0;
750 
751  av_log(ctx, AV_LOG_DEBUG, "IR length: %d.\n", s->sofa.hrtf->N);
752  s->sofa.ir_samples = s->sofa.hrtf->N;
753  s->sofa.n_samples = 1 << (32 - ff_clz(s->sofa.ir_samples));
754 
755  n_samples = s->sofa.n_samples;
756  ir_samples = s->sofa.ir_samples;
757 
758  if (s->type == TIME_DOMAIN) {
759  s->data_ir[0] = av_calloc(n_samples, sizeof(float) * s->n_conv);
760  s->data_ir[1] = av_calloc(n_samples, sizeof(float) * s->n_conv);
761 
762  if (!s->data_ir[0] || !s->data_ir[1]) {
763  ret = AVERROR(ENOMEM);
764  goto fail;
765  }
766  }
767 
768  s->delay[0] = av_calloc(s->n_conv, sizeof(int));
769  s->delay[1] = av_calloc(s->n_conv, sizeof(int));
770 
771  if (!s->delay[0] || !s->delay[1]) {
772  ret = AVERROR(ENOMEM);
773  goto fail;
774  }
775 
776  /* get temporary IR for L and R channel */
777  data_ir_l = av_calloc(n_conv * n_samples, sizeof(*data_ir_l));
778  data_ir_r = av_calloc(n_conv * n_samples, sizeof(*data_ir_r));
779  if (!data_ir_r || !data_ir_l) {
780  ret = AVERROR(ENOMEM);
781  goto fail;
782  }
783 
784  if (s->type == TIME_DOMAIN) {
785  s->temp_src[0] = av_calloc(n_samples, sizeof(float));
786  s->temp_src[1] = av_calloc(n_samples, sizeof(float));
787  if (!s->temp_src[0] || !s->temp_src[1]) {
788  ret = AVERROR(ENOMEM);
789  goto fail;
790  }
791  }
792 
793  s->speaker_azim = av_calloc(s->n_conv, sizeof(*s->speaker_azim));
794  s->speaker_elev = av_calloc(s->n_conv, sizeof(*s->speaker_elev));
795  if (!s->speaker_azim || !s->speaker_elev) {
796  ret = AVERROR(ENOMEM);
797  goto fail;
798  }
799 
800  /* get speaker positions */
801  if ((ret = get_speaker_pos(ctx, s->speaker_azim, s->speaker_elev)) < 0) {
802  av_log(ctx, AV_LOG_ERROR, "Couldn't get speaker positions. Input channel configuration not supported.\n");
803  goto fail;
804  }
805 
806  for (i = 0; i < s->n_conv; i++) {
807  float coordinates[3];
808 
809  /* load and store IRs and corresponding delays */
810  azim = (int)(s->speaker_azim[i] + azim_orig) % 360;
811  elev = (int)(s->speaker_elev[i] + elev_orig) % 90;
812 
813  coordinates[0] = azim;
814  coordinates[1] = elev;
815  coordinates[2] = radius;
816 
817  mysofa_s2c(coordinates);
818 
819  /* get id of IR closest to desired position */
820  ret = getfilter_float(ctx, coordinates[0], coordinates[1], coordinates[2],
821  data_ir_l + n_samples * i,
822  data_ir_r + n_samples * i,
823  &delay_l, &delay_r);
824  if (ret < 0)
825  goto fail;
826 
827  s->delay[0][i] = delay_l * sample_rate;
828  s->delay[1][i] = delay_r * sample_rate;
829 
830  s->sofa.max_delay = FFMAX3(s->sofa.max_delay, s->delay[0][i], s->delay[1][i]);
831  }
832 
833  /* get size of ringbuffer (longest IR plus max. delay) */
834  /* then choose next power of 2 for performance optimization */
835  n_current = n_samples + s->sofa.max_delay;
836  /* length of longest IR plus max. delay */
837  n_max = FFMAX(n_max, n_current);
838 
839  /* buffer length is longest IR plus max. delay -> next power of 2
840  (32 - count leading zeros gives required exponent) */
841  s->buffer_length = 1 << (32 - ff_clz(n_max));
842  s->n_fft = n_fft = 1 << (32 - ff_clz(n_max + s->framesize));
843 
844  if (s->type == FREQUENCY_DOMAIN) {
845  av_fft_end(s->fft[0]);
846  av_fft_end(s->fft[1]);
847  s->fft[0] = av_fft_init(av_log2(s->n_fft), 0);
848  s->fft[1] = av_fft_init(av_log2(s->n_fft), 0);
849  av_fft_end(s->ifft[0]);
850  av_fft_end(s->ifft[1]);
851  s->ifft[0] = av_fft_init(av_log2(s->n_fft), 1);
852  s->ifft[1] = av_fft_init(av_log2(s->n_fft), 1);
853 
854  if (!s->fft[0] || !s->fft[1] || !s->ifft[0] || !s->ifft[1]) {
855  av_log(ctx, AV_LOG_ERROR, "Unable to create FFT contexts of size %d.\n", s->n_fft);
856  ret = AVERROR(ENOMEM);
857  goto fail;
858  }
859  }
860 
861  if (s->type == TIME_DOMAIN) {
862  s->ringbuffer[0] = av_calloc(s->buffer_length, sizeof(float) * nb_input_channels);
863  s->ringbuffer[1] = av_calloc(s->buffer_length, sizeof(float) * nb_input_channels);
864  } else if (s->type == FREQUENCY_DOMAIN) {
865  /* get temporary HRTF memory for L and R channel */
866  data_hrtf_l = av_malloc_array(n_fft, sizeof(*data_hrtf_l) * n_conv);
867  data_hrtf_r = av_malloc_array(n_fft, sizeof(*data_hrtf_r) * n_conv);
868  if (!data_hrtf_r || !data_hrtf_l) {
869  ret = AVERROR(ENOMEM);
870  goto fail;
871  }
872 
873  s->ringbuffer[0] = av_calloc(s->buffer_length, sizeof(float));
874  s->ringbuffer[1] = av_calloc(s->buffer_length, sizeof(float));
875  s->temp_fft[0] = av_malloc_array(s->n_fft, sizeof(FFTComplex));
876  s->temp_fft[1] = av_malloc_array(s->n_fft, sizeof(FFTComplex));
877  s->temp_afft[0] = av_malloc_array(s->n_fft, sizeof(FFTComplex));
878  s->temp_afft[1] = av_malloc_array(s->n_fft, sizeof(FFTComplex));
879  if (!s->temp_fft[0] || !s->temp_fft[1] ||
880  !s->temp_afft[0] || !s->temp_afft[1]) {
881  ret = AVERROR(ENOMEM);
882  goto fail;
883  }
884  }
885 
886  if (!s->ringbuffer[0] || !s->ringbuffer[1]) {
887  ret = AVERROR(ENOMEM);
888  goto fail;
889  }
890 
891  if (s->type == FREQUENCY_DOMAIN) {
892  fft_in_l = av_calloc(n_fft, sizeof(*fft_in_l));
893  fft_in_r = av_calloc(n_fft, sizeof(*fft_in_r));
894  if (!fft_in_l || !fft_in_r) {
895  ret = AVERROR(ENOMEM);
896  goto fail;
897  }
898  }
899 
900  for (i = 0; i < s->n_conv; i++) {
901  float *lir, *rir;
902 
903  offset = i * n_samples; /* no. samples already written */
904 
905  lir = data_ir_l + offset;
906  rir = data_ir_r + offset;
907 
908  if (s->type == TIME_DOMAIN) {
909  for (j = 0; j < ir_samples; j++) {
910  /* load reversed IRs of the specified source position
911  * sample-by-sample for left and right ear; and apply gain */
912  s->data_ir[0][offset + j] = lir[ir_samples - 1 - j] * gain_lin;
913  s->data_ir[1][offset + j] = rir[ir_samples - 1 - j] * gain_lin;
914  }
915  } else if (s->type == FREQUENCY_DOMAIN) {
916  memset(fft_in_l, 0, n_fft * sizeof(*fft_in_l));
917  memset(fft_in_r, 0, n_fft * sizeof(*fft_in_r));
918 
919  offset = i * n_fft; /* no. samples already written */
920  for (j = 0; j < ir_samples; j++) {
921  /* load non-reversed IRs of the specified source position
922  * sample-by-sample and apply gain,
923  * L channel is loaded to real part, R channel to imag part,
924  * IRs are shifted by L and R delay */
925  fft_in_l[s->delay[0][i] + j].re = lir[j] * gain_lin;
926  fft_in_r[s->delay[1][i] + j].re = rir[j] * gain_lin;
927  }
928 
929  /* actually transform to frequency domain (IRs -> HRTFs) */
930  av_fft_permute(s->fft[0], fft_in_l);
931  av_fft_calc(s->fft[0], fft_in_l);
932  memcpy(data_hrtf_l + offset, fft_in_l, n_fft * sizeof(*fft_in_l));
933  av_fft_permute(s->fft[0], fft_in_r);
934  av_fft_calc(s->fft[0], fft_in_r);
935  memcpy(data_hrtf_r + offset, fft_in_r, n_fft * sizeof(*fft_in_r));
936  }
937  }
938 
939  if (s->type == FREQUENCY_DOMAIN) {
940  s->data_hrtf[0] = av_malloc_array(n_fft * s->n_conv, sizeof(FFTComplex));
941  s->data_hrtf[1] = av_malloc_array(n_fft * s->n_conv, sizeof(FFTComplex));
942  if (!s->data_hrtf[0] || !s->data_hrtf[1]) {
943  ret = AVERROR(ENOMEM);
944  goto fail;
945  }
946 
947  memcpy(s->data_hrtf[0], data_hrtf_l, /* copy HRTF data to */
948  sizeof(FFTComplex) * n_conv * n_fft); /* filter struct */
949  memcpy(s->data_hrtf[1], data_hrtf_r,
950  sizeof(FFTComplex) * n_conv * n_fft);
951  }
952 
953 fail:
954  av_freep(&data_hrtf_l); /* free temporary HRTF memory */
955  av_freep(&data_hrtf_r);
956 
957  av_freep(&data_ir_l); /* free temprary IR memory */
958  av_freep(&data_ir_r);
959 
960  av_freep(&fft_in_l); /* free temporary FFT memory */
961  av_freep(&fft_in_r);
962 
963  return ret;
964 }
965 
967 {
968  SOFAlizerContext *s = ctx->priv;
969  int ret;
970 
971  if (!s->filename) {
972  av_log(ctx, AV_LOG_ERROR, "Valid SOFA filename must be set.\n");
973  return AVERROR(EINVAL);
974  }
975 
976  /* preload SOFA file, */
977  ret = preload_sofa(ctx, s->filename, &s->sample_rate);
978  if (ret) {
979  /* file loading error */
980  av_log(ctx, AV_LOG_ERROR, "Error while loading SOFA file: '%s'\n", s->filename);
981  } else { /* no file loading error, resampling not required */
982  av_log(ctx, AV_LOG_DEBUG, "File '%s' loaded.\n", s->filename);
983  }
984 
985  if (ret) {
986  av_log(ctx, AV_LOG_ERROR, "No valid SOFA file could be loaded. Please specify valid SOFA file.\n");
987  return ret;
988  }
989 
990  s->fdsp = avpriv_float_dsp_alloc(0);
991  if (!s->fdsp)
992  return AVERROR(ENOMEM);
993 
994  return 0;
995 }
996 
997 static int config_input(AVFilterLink *inlink)
998 {
999  AVFilterContext *ctx = inlink->dst;
1000  SOFAlizerContext *s = ctx->priv;
1001  int ret;
1002 
1003  if (s->type == FREQUENCY_DOMAIN)
1004  s->nb_samples = s->framesize;
1005 
1006  /* gain -3 dB per channel */
1007  s->gain_lfe = expf((s->gain - 3 * inlink->channels + s->lfe_gain) / 20 * M_LN10);
1008 
1009  s->n_conv = inlink->channels;
1010 
1011  /* load IRs to data_ir[0] and data_ir[1] for required directions */
1012  if ((ret = load_data(ctx, s->rotation, s->elevation, s->radius, inlink->sample_rate)) < 0)
1013  return ret;
1014 
1015  av_log(ctx, AV_LOG_DEBUG, "Samplerate: %d Channels to convolute: %d, Length of ringbuffer: %d x %d\n",
1016  inlink->sample_rate, s->n_conv, inlink->channels, s->buffer_length);
1017 
1018  return 0;
1019 }
1020 
1022 {
1023  SOFAlizerContext *s = ctx->priv;
1024 
1025  close_sofa(&s->sofa);
1026  av_fft_end(s->ifft[0]);
1027  av_fft_end(s->ifft[1]);
1028  av_fft_end(s->fft[0]);
1029  av_fft_end(s->fft[1]);
1030  s->ifft[0] = NULL;
1031  s->ifft[1] = NULL;
1032  s->fft[0] = NULL;
1033  s->fft[1] = NULL;
1034  av_freep(&s->delay[0]);
1035  av_freep(&s->delay[1]);
1036  av_freep(&s->data_ir[0]);
1037  av_freep(&s->data_ir[1]);
1038  av_freep(&s->ringbuffer[0]);
1039  av_freep(&s->ringbuffer[1]);
1040  av_freep(&s->speaker_azim);
1041  av_freep(&s->speaker_elev);
1042  av_freep(&s->temp_src[0]);
1043  av_freep(&s->temp_src[1]);
1044  av_freep(&s->temp_afft[0]);
1045  av_freep(&s->temp_afft[1]);
1046  av_freep(&s->temp_fft[0]);
1047  av_freep(&s->temp_fft[1]);
1048  av_freep(&s->data_hrtf[0]);
1049  av_freep(&s->data_hrtf[1]);
1050  av_freep(&s->fdsp);
1051 }
1052 
1053 #define OFFSET(x) offsetof(SOFAlizerContext, x)
1054 #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
1055 
1056 static const AVOption sofalizer_options[] = {
1057  { "sofa", "sofa filename", OFFSET(filename), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
1058  { "gain", "set gain in dB", OFFSET(gain), AV_OPT_TYPE_FLOAT, {.dbl=0}, -20, 40, .flags = FLAGS },
1059  { "rotation", "set rotation" , OFFSET(rotation), AV_OPT_TYPE_FLOAT, {.dbl=0}, -360, 360, .flags = FLAGS },
1060  { "elevation", "set elevation", OFFSET(elevation), AV_OPT_TYPE_FLOAT, {.dbl=0}, -90, 90, .flags = FLAGS },
1061  { "radius", "set radius", OFFSET(radius), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 5, .flags = FLAGS },
1062  { "type", "set processing", OFFSET(type), AV_OPT_TYPE_INT, {.i64=1}, 0, 1, .flags = FLAGS, "type" },
1063  { "time", "time domain", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, .flags = FLAGS, "type" },
1064  { "freq", "frequency domain", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, .flags = FLAGS, "type" },
1065  { "speakers", "set speaker custom positions", OFFSET(speakers_pos), AV_OPT_TYPE_STRING, {.str=0}, 0, 0, .flags = FLAGS },
1066  { "lfegain", "set lfe gain", OFFSET(lfe_gain), AV_OPT_TYPE_FLOAT, {.dbl=0}, -20,40, .flags = FLAGS },
1067  { "framesize", "set frame size", OFFSET(framesize), AV_OPT_TYPE_INT, {.i64=1024},1024,96000, .flags = FLAGS },
1068  { "normalize", "normalize IRs", OFFSET(normalize), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, .flags = FLAGS },
1069  { "interpolate","interpolate IRs from neighbors", OFFSET(interpolate),AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, .flags = FLAGS },
1070  { "minphase", "minphase IRs", OFFSET(minphase), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, .flags = FLAGS },
1071  { "anglestep", "set neighbor search angle step", OFFSET(anglestep), AV_OPT_TYPE_FLOAT, {.dbl=.5}, 0.01, 10, .flags = FLAGS },
1072  { "radstep", "set neighbor search radius step", OFFSET(radstep), AV_OPT_TYPE_FLOAT, {.dbl=.01}, 0.01, 1, .flags = FLAGS },
1073  { NULL }
1074 };
1075 
1077 
1078 static const AVFilterPad inputs[] = {
1079  {
1080  .name = "default",
1081  .type = AVMEDIA_TYPE_AUDIO,
1082  .config_props = config_input,
1083  },
1084  { NULL }
1085 };
1086 
1087 static const AVFilterPad outputs[] = {
1088  {
1089  .name = "default",
1090  .type = AVMEDIA_TYPE_AUDIO,
1091  },
1092  { NULL }
1093 };
1094 
1096  .name = "sofalizer",
1097  .description = NULL_IF_CONFIG_SMALL("SOFAlizer (Spatially Oriented Format for Acoustics)."),
1098  .priv_size = sizeof(SOFAlizerContext),
1099  .priv_class = &sofalizer_class,
1100  .init = init,
1101  .activate = activate,
1102  .uninit = uninit,
1104  .inputs = inputs,
1105  .outputs = outputs,
1107 };
static enum AVSampleFormat sample_fmts[]
Definition: adpcmenc.c:925
static int preload_sofa(AVFilterContext *ctx, char *filename, int *samplingrate)
Definition: af_sofalizer.c:133
static int close_sofa(struct MySofa *sofa)
Definition: af_sofalizer.c:117
static int load_data(AVFilterContext *ctx, int azim, int elev, float radius, int sample_rate)
Definition: af_sofalizer.c:728
static int query_formats(AVFilterContext *ctx)
Definition: af_sofalizer.c:642
static int config_input(AVFilterLink *inlink)
Definition: af_sofalizer.c:997
static int sofalizer_convolute(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: af_sofalizer.c:340
AVFilter ff_af_sofalizer
#define FLAGS
#define TIME_DOMAIN
Definition: af_sofalizer.c:42
static const AVFilterPad inputs[]
static const AVOption sofalizer_options[]
static const AVFilterPad outputs[]
static void parse_speaker_pos(AVFilterContext *ctx, int64_t in_channel_layout)
Definition: af_sofalizer.c:222
static int get_speaker_pos(AVFilterContext *ctx, float *speaker_azim, float *speaker_elev)
Definition: af_sofalizer.c:253
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: af_sofalizer.c:578
static int activate(AVFilterContext *ctx)
Definition: af_sofalizer.c:617
static av_cold int init(AVFilterContext *ctx)
Definition: af_sofalizer.c:966
static av_cold void uninit(AVFilterContext *ctx)
static int getfilter_float(AVFilterContext *ctx, float x, float y, float z, float *left, float *right, float *delay_left, float *delay_right)
Definition: af_sofalizer.c:684
#define FREQUENCY_DOMAIN
Definition: af_sofalizer.c:43
#define OFFSET(x)
AVFILTER_DEFINE_CLASS(sofalizer)
static int sofalizer_fast_convolute(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: af_sofalizer.c:440
static int parse_channel_name(AVFilterContext *ctx, char **arg, int *rchannel)
Definition: af_sofalizer.c:186
#define av_cold
Definition: attributes.h:88
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
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) #define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac) { } void ff_audio_convert_free(AudioConvert **ac) { if(! *ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);} AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map) { AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method !=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2) { ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc) { av_free(ac);return NULL;} return ac;} in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar) { ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar ? ac->channels :1;} else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;} int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in) { int use_generic=1;int len=in->nb_samples;int p;if(ac->dc) { av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
uint8_t
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_S32, int32_t, AV_SAMPLE_FMT_S16, *(const int16_t *) pi *(1<< 16)) 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/(UINT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S64, *(const int64_t *) pi *(1.0/(UINT64_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 *(UINT64_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 *(UINT64_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,(const uint8_t **) in->ch+ch, off *(out-> planar
Definition: audioconvert.c:56
FFT functions.
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1094
int ff_inlink_consume_samples(AVFilterLink *link, unsigned min, unsigned max, AVFrame **rframe)
Take samples from the link's FIFO and update the link's stats.
Definition: avfilter.c:1511
int ff_inlink_consume_frame(AVFilterLink *link, AVFrame **rframe)
Take a frame from the link's FIFO and update the link's stats.
Definition: avfilter.c:1492
Main libavfilter public API header.
#define flags(name, subs,...)
Definition: cbs_av1.c:561
#define s(width, name)
Definition: cbs_vp9.c:257
uint64_t layout
audio channel layout utility functions
#define fail()
Definition: checkasm.h:133
#define FFMAX3(a, b, c)
Definition: common.h:104
#define FFMIN(a, b)
Definition: common.h:105
#define FFMAX(a, b)
Definition: common.h:103
#define NULL
Definition: coverity.c:32
static __device__ float fabsf(float a)
Definition: cuda_runtime.h:181
sample_rates
int
sample_rate
float im
Definition: fft.c:82
float re
Definition: fft.c:82
#define FF_FILTER_FORWARD_WANTED(outlink, inlink)
Forward the frame_wanted_out flag from an output link to an input link.
Definition: filters.h:254
#define FF_FILTER_FORWARD_STATUS(inlink, outlink)
Acknowledge the status on an input link and forward it to an output link.
Definition: filters.h:226
#define FFERROR_NOT_READY
Filters implementation helper functions.
Definition: filters.h:34
#define FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink)
Forward the status on an output link to an input link.
Definition: filters.h:199
int ff_add_channel_layout(AVFilterChannelLayouts **l, uint64_t channel_layout)
Definition: formats.c:338
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:587
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:286
AVFilterChannelLayouts * ff_all_channel_layouts(void)
Construct an empty AVFilterChannelLayouts/AVFilterFormats struct – representing any channel layout (w...
Definition: formats.c:427
int ff_set_common_samplerates(AVFilterContext *ctx, AVFilterFormats *samplerates)
Definition: formats.c:575
int ff_channel_layouts_ref(AVFilterChannelLayouts *f, AVFilterChannelLayouts **ref)
Add *ref as a new reference to f.
Definition: formats.c:461
@ AV_OPT_TYPE_CONST
Definition: opt.h:234
@ AV_OPT_TYPE_INT
Definition: opt.h:225
@ AV_OPT_TYPE_FLOAT
Definition: opt.h:228
@ AV_OPT_TYPE_BOOL
Definition: opt.h:242
@ AV_OPT_TYPE_STRING
Definition: opt.h:229
uint64_t av_get_channel_layout(const char *name)
Return a channel layout id that matches name, or 0 if no match is found.
#define AV_CH_LAYOUT_STEREO
#define AV_CH_SIDE_LEFT
#define AV_CH_SURROUND_DIRECT_RIGHT
#define AV_CH_WIDE_LEFT
#define AV_CH_WIDE_RIGHT
#define AV_CH_TOP_FRONT_LEFT
#define AV_CH_FRONT_RIGHT
#define AV_CH_TOP_BACK_CENTER
#define AV_CH_FRONT_RIGHT_OF_CENTER
#define AV_CH_BACK_CENTER
#define AV_CH_TOP_FRONT_CENTER
#define AV_CH_FRONT_LEFT_OF_CENTER
#define AV_CH_LOW_FREQUENCY_2
#define AV_CH_BACK_RIGHT
#define AV_CH_FRONT_CENTER
#define AV_CH_TOP_BACK_RIGHT
#define AV_CH_TOP_CENTER
#define AV_CH_SIDE_RIGHT
#define AV_CH_BACK_LEFT
#define AV_CH_TOP_BACK_LEFT
#define AV_CH_LOW_FREQUENCY
#define AV_CH_STEREO_RIGHT
See AV_CH_STEREO_LEFT.
#define AV_CH_TOP_FRONT_RIGHT
#define AV_CH_STEREO_LEFT
Stereo downmix.
#define AV_CH_FRONT_LEFT
#define AV_CH_SURROUND_DIRECT_LEFT
void av_fft_permute(FFTContext *s, FFTComplex *z)
Do the permutation needed BEFORE calling ff_fft_calc().
Definition: avfft.c:38
void av_fft_calc(FFTContext *s, FFTComplex *z)
Do a complex FFT with the parameters defined in av_fft_init().
Definition: avfft.c:43
FFTContext * av_fft_init(int nbits, int inverse)
Set up a complex FFT.
Definition: avfft.c:28
av_cold void av_fft_end(FFTContext *s)
Definition: avfft.c:48
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
Definition: avfilter.h:117
#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:203
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:658
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:215
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:200
#define AV_LOG_INFO
Standard information.
Definition: log.h:205
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
#define ff_clz
Definition: intmath.h:142
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:253
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
Definition: mem.c:245
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
@ AV_SAMPLE_FMT_FLTP
float, planar
Definition: samplefmt.h:69
@ AV_SAMPLE_FMT_FLT
float
Definition: samplefmt.h:63
@ AV_SAMPLE_FMT_NONE
Definition: samplefmt.h:59
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:186
int av_sscanf(const char *string, const char *format,...)
See libc sscanf manual for more information.
Definition: avsscanf.c:962
cl_device_type type
int i
Definition: input.c:407
#define av_log2
Definition: intmath.h:83
static int16_t mult(Float11 *f1, Float11 *f2)
Definition: g726.c:55
const char * arg
Definition: jacosubdec.c:66
av_cold AVFloatDSPContext * avpriv_float_dsp_alloc(int bit_exact)
Allocate a float DSP context.
Definition: float_dsp.c:135
common internal API header
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
#define emms_c()
Definition: internal.h:54
#define expf(x)
Definition: libm.h:283
static const uint16_t mask[17]
Definition: lzw.c:38
#define FFALIGN(x, a)
Definition: macros.h:48
#define M_LN10
Definition: mathematics.h:43
enum MovChannelLayoutTag * layouts
Definition: mov_chan.c:434
AVOptions.
#define td
Definition: regdef.h:70
static char buffer[20]
Definition: seek.c:32
formats
Definition: signature.h:48
Describe the class of an AVClass context structure.
Definition: log.h:67
A list of supported channel layouts.
Definition: formats.h:86
An instance of a filter.
Definition: avfilter.h:341
A list of supported formats for one end of a filter link.
Definition: formats.h:65
A filter pad used for either input or output.
Definition: internal.h:54
const char * name
Pad name.
Definition: internal.h:60
Filter definition.
Definition: avfilter.h:145
const char * name
Filter name.
Definition: avfilter.h:149
AVFormatInternal * internal
An opaque field for libavformat internal usage.
Definition: avformat.h:1699
This structure describes decoded (raw) audio or video data.
Definition: frame.h:318
AVOption.
Definition: opt.h:248
FFTSample re
Definition: avfft.h:38
FFTSample im
Definition: avfft.h:38
Definition: fft.h:83
int n_samples
Definition: af_sofalizer.c:50
float * lir
Definition: af_sofalizer.c:51
struct MYSOFA_NEIGHBORHOOD * neighborhood
Definition: af_sofalizer.c:48
int max_delay
Definition: af_sofalizer.c:53
struct MYSOFA_HRTF * hrtf
Definition: af_sofalizer.c:46
int ir_samples
Definition: af_sofalizer.c:49
struct MYSOFA_LOOKUP * lookup
Definition: af_sofalizer.c:47
float * rir
Definition: af_sofalizer.c:51
float * fir
Definition: af_sofalizer.c:52
float * ringbuffer[2]
Definition: af_sofalizer.c:79
FFTComplex * temp_afft[2]
Definition: af_sofalizer.c:94
float * temp_src[2]
Definition: af_sofalizer.c:92
float * speaker_elev
Definition: af_sofalizer.c:70
FFTContext * ifft[2]
Definition: af_sofalizer.c:111
FFTContext * fft[2]
Definition: af_sofalizer.c:111
VirtualSpeaker vspkrpos[64]
Definition: af_sofalizer.c:109
float * speaker_azim
Definition: af_sofalizer.c:69
FFTComplex * temp_fft[2]
Definition: af_sofalizer.c:93
float * data_ir[2]
Definition: af_sofalizer.c:90
FFTComplex * data_hrtf[2]
Definition: af_sofalizer.c:112
AVFloatDSPContext * fdsp
Definition: af_sofalizer.c:114
Used for passing data between threads.
Definition: dsddec.c:67
FFTComplex ** temp_fft
Definition: af_headphone.c:133
int * n_clippings
Definition: af_headphone.c:130
int ** delay
Definition: af_sofalizer.c:331
AVFrame * out
Definition: af_adeclick.c:502
float ** ir
Definition: af_headphone.c:129
AVFrame * in
Definition: af_adenorm.c:223
float ** temp_src
Definition: af_headphone.c:132
FFTComplex ** temp_afft
Definition: af_headphone.c:134
float ** ringbuffer
Definition: af_headphone.c:131
#define av_free(p)
#define av_malloc_array(a, b)
#define av_freep(p)
#define av_log(a,...)
#define src
Definition: vp8dsp.c:255
FILE * out
Definition: movenc.c:54
AVFormatContext * ctx
Definition: movenc.c:48
static void interpolate(float *out, float v1, float v2, int size)
Definition: twinvq.c:84
if(ret< 0)
Definition: vf_mcdeint.c:282
static const uint8_t offset[127][2]
Definition: vf_spp.c:107
int len
static double c[64]