FFmpeg
af_surround.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 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 #include "libavutil/avassert.h"
23 #include "libavutil/mem.h"
24 #include "libavutil/opt.h"
25 #include "libavutil/tx.h"
26 #include "avfilter.h"
27 #include "audio.h"
28 #include "filters.h"
29 #include "internal.h"
30 #include "formats.h"
31 #include "window_func.h"
32 
36 };
37 
38 static const int ch_map[SC_NB] = {
48 };
49 
50 static const int sc_map[16] = {
60 };
61 
62 typedef struct AudioSurroundContext {
63  const AVClass *class;
64 
67 
68  float level_in;
69  float level_out;
70  float f_i[SC_NB];
71  float f_o[SC_NB];
72  int lfe_mode;
73  float smooth;
74  float angle;
75  float focus;
76  int win_size;
77  int win_func;
78  float win_gain;
79  float overlap;
80 
81  float all_x;
82  float all_y;
83 
84  float f_x[SC_NB];
85  float f_y[SC_NB];
86 
87  float *input_levels;
88  float *output_levels;
91  int lowcutf;
92  int highcutf;
93 
94  float lowcut;
95  float highcut;
96 
99 
110 
111  float *x_pos;
112  float *y_pos;
113  float *l_phase;
114  float *r_phase;
115  float *c_phase;
116  float *c_mag;
117  float *lfe_mag;
118  float *lfe_phase;
119  float *mag_total;
120 
122  int hop_size;
126 
128  void (*upmix)(AVFilterContext *ctx, int ch);
130  float c_re, float c_im,
131  float mag_totall, float mag_totalr,
132  float fl_phase, float fr_phase,
133  float bl_phase, float br_phase,
134  float sl_phase, float sr_phase,
135  float xl, float yl,
136  float xr, float yr,
137  int n);
139  float c_re, float c_im,
140  float lfe_re, float lfe_im,
141  float mag_totall, float mag_totalr,
142  float fl_phase, float fr_phase,
143  float bl_phase, float br_phase,
144  float sl_phase, float sr_phase,
145  float xl, float yl,
146  float xr, float yr,
147  int n);
149 
151 {
152  AudioSurroundContext *s = ctx->priv;
155  int ret;
156 
158  if (ret)
159  return ret;
161  if (ret)
162  return ret;
163 
164  layouts = NULL;
165  ret = ff_add_channel_layout(&layouts, &s->out_ch_layout);
166  if (ret)
167  return ret;
168 
169  ret = ff_channel_layouts_ref(layouts, &ctx->outputs[0]->incfg.channel_layouts);
170  if (ret)
171  return ret;
172 
173  layouts = NULL;
174  ret = ff_add_channel_layout(&layouts, &s->in_ch_layout);
175  if (ret)
176  return ret;
177 
178  ret = ff_channel_layouts_ref(layouts, &ctx->inputs[0]->outcfg.channel_layouts);
179  if (ret)
180  return ret;
181 
183 }
184 
186 {
187  AudioSurroundContext *s = ctx->priv;
188 
189  for (int ch = 0; ch < s->nb_in_channels && s->level_in >= 0.f; ch++)
190  s->input_levels[ch] = s->level_in;
191  s->level_in = -1.f;
192 
193  for (int n = 0; n < SC_NB; n++) {
194  const int ch = av_channel_layout_index_from_channel(&s->in_ch_layout, ch_map[n]);
195  if (ch >= 0)
196  s->input_levels[ch] = s->f_i[n];
197  }
198 }
199 
201 {
202  AudioSurroundContext *s = ctx->priv;
203 
204  for (int ch = 0; ch < s->nb_out_channels && s->level_out >= 0.f; ch++)
205  s->output_levels[ch] = s->level_out;
206  s->level_out = -1.f;
207 
208  for (int n = 0; n < SC_NB; n++) {
209  const int ch = av_channel_layout_index_from_channel(&s->out_ch_layout, ch_map[n]);
210  if (ch >= 0)
211  s->output_levels[ch] = s->f_o[n];
212  }
213 }
214 
216 {
217  AVFilterContext *ctx = inlink->dst;
218  AudioSurroundContext *s = ctx->priv;
219  int ret;
220 
221  s->rdft = av_calloc(inlink->ch_layout.nb_channels, sizeof(*s->rdft));
222  if (!s->rdft)
223  return AVERROR(ENOMEM);
224  s->nb_in_channels = inlink->ch_layout.nb_channels;
225 
226  for (int ch = 0; ch < inlink->ch_layout.nb_channels; ch++) {
227  float scale = 1.f;
228 
229  ret = av_tx_init(&s->rdft[ch], &s->tx_fn, AV_TX_FLOAT_RDFT,
230  0, s->win_size, &scale, 0);
231  if (ret < 0)
232  return ret;
233  }
234 
235  s->input_levels = av_malloc_array(s->nb_in_channels, sizeof(*s->input_levels));
236  if (!s->input_levels)
237  return AVERROR(ENOMEM);
238 
240 
241  s->window = ff_get_audio_buffer(inlink, s->win_size * 2);
242  if (!s->window)
243  return AVERROR(ENOMEM);
244 
245  s->input_in = ff_get_audio_buffer(inlink, s->win_size * 2);
246  if (!s->input_in)
247  return AVERROR(ENOMEM);
248 
249  s->input = ff_get_audio_buffer(inlink, s->win_size + 2);
250  if (!s->input)
251  return AVERROR(ENOMEM);
252 
253  s->lowcut = 1.f * s->lowcutf / (inlink->sample_rate * 0.5) * (s->win_size / 2);
254  s->highcut = 1.f * s->highcutf / (inlink->sample_rate * 0.5) * (s->win_size / 2);
255 
256  return 0;
257 }
258 
259 static int config_output(AVFilterLink *outlink)
260 {
261  AVFilterContext *ctx = outlink->src;
262  AudioSurroundContext *s = ctx->priv;
263  int ret;
264 
265  s->irdft = av_calloc(outlink->ch_layout.nb_channels, sizeof(*s->irdft));
266  if (!s->irdft)
267  return AVERROR(ENOMEM);
268  s->nb_out_channels = outlink->ch_layout.nb_channels;
269 
270  for (int ch = 0; ch < outlink->ch_layout.nb_channels; ch++) {
271  float iscale = 1.f;
272 
273  ret = av_tx_init(&s->irdft[ch], &s->itx_fn, AV_TX_FLOAT_RDFT,
274  1, s->win_size, &iscale, 0);
275  if (ret < 0)
276  return ret;
277  }
278 
279  s->output_levels = av_malloc_array(s->nb_out_channels, sizeof(*s->output_levels));
280  if (!s->output_levels)
281  return AVERROR(ENOMEM);
282 
284 
285  s->factors = ff_get_audio_buffer(outlink, s->win_size + 2);
286  s->sfactors = ff_get_audio_buffer(outlink, s->win_size + 2);
287  s->output_ph = ff_get_audio_buffer(outlink, s->win_size + 2);
288  s->output_mag = ff_get_audio_buffer(outlink, s->win_size + 2);
289  s->output_out = ff_get_audio_buffer(outlink, s->win_size + 2);
290  s->output = ff_get_audio_buffer(outlink, s->win_size + 2);
291  s->overlap_buffer = ff_get_audio_buffer(outlink, s->win_size * 2);
292  if (!s->overlap_buffer || !s->output || !s->output_out || !s->output_mag ||
293  !s->output_ph || !s->factors || !s->sfactors)
294  return AVERROR(ENOMEM);
295 
296  s->rdft_size = s->win_size / 2 + 1;
297 
298  s->x_pos = av_calloc(s->rdft_size, sizeof(*s->x_pos));
299  s->y_pos = av_calloc(s->rdft_size, sizeof(*s->y_pos));
300  s->l_phase = av_calloc(s->rdft_size, sizeof(*s->l_phase));
301  s->r_phase = av_calloc(s->rdft_size, sizeof(*s->r_phase));
302  s->c_mag = av_calloc(s->rdft_size, sizeof(*s->c_mag));
303  s->c_phase = av_calloc(s->rdft_size, sizeof(*s->c_phase));
304  s->mag_total = av_calloc(s->rdft_size, sizeof(*s->mag_total));
305  s->lfe_mag = av_calloc(s->rdft_size, sizeof(*s->lfe_mag));
306  s->lfe_phase = av_calloc(s->rdft_size, sizeof(*s->lfe_phase));
307  if (!s->x_pos || !s->y_pos || !s->l_phase || !s->r_phase || !s->lfe_phase ||
308  !s->c_phase || !s->mag_total || !s->lfe_mag || !s->c_mag)
309  return AVERROR(ENOMEM);
310 
311  return 0;
312 }
313 
314 static float sqrf(float x)
315 {
316  return x * x;
317 }
318 
319 static float r_distance(float a)
320 {
321  return fminf(sqrtf(1.f + sqrf(tanf(a))), sqrtf(1.f + sqrf(1.f / tanf(a))));
322 }
323 
324 #define MIN_MAG_SUM 0.00000001f
325 
326 static void angle_transform(float *x, float *y, float angle)
327 {
328  float reference, r, a;
329 
330  if (angle == 90.f)
331  return;
332 
333  reference = angle * M_PIf / 180.f;
334  r = hypotf(*x, *y);
335  a = atan2f(*x, *y);
336 
337  r /= r_distance(a);
338 
339  if (fabsf(a) <= M_PI_4f)
340  a *= reference / M_PI_2f;
341  else
342  a = M_PIf + (-2.f * M_PIf + reference) * (M_PIf - fabsf(a)) * FFDIFFSIGN(a, 0.f) / (3.f * M_PI_2f);
343 
344  r *= r_distance(a);
345 
346  *x = av_clipf(sinf(a) * r, -1.f, 1.f);
347  *y = av_clipf(cosf(a) * r, -1.f, 1.f);
348 }
349 
350 static void focus_transform(float *x, float *y, float focus)
351 {
352  float a, r, ra;
353 
354  if (focus == 0.f)
355  return;
356 
357  a = atan2f(*x, *y);
358  ra = r_distance(a);
359  r = av_clipf(hypotf(*x, *y) / ra, 0.f, 1.f);
360  r = focus > 0.f ? 1.f - powf(1.f - r, 1.f + focus * 20.f) : powf(r, 1.f - focus * 20.f);
361  r *= ra;
362  *x = av_clipf(sinf(a) * r, -1.f, 1.f);
363  *y = av_clipf(cosf(a) * r, -1.f, 1.f);
364 }
365 
366 static void stereo_position(float a, float p, float *x, float *y)
367 {
368  av_assert2(a >= -1.f && a <= 1.f);
369  av_assert2(p >= 0.f && p <= M_PIf);
370  *x = av_clipf(a+a*fmaxf(0.f, p*p-M_PI_2f), -1.f, 1.f);
371  *y = av_clipf(cosf(a*M_PI_2f+M_PIf)*cosf(M_PI_2f-p/M_PIf)*M_LN10f+1.f, -1.f, 1.f);
372 }
373 
374 static inline void get_lfe(int output_lfe, int n, float lowcut, float highcut,
375  float *lfe_mag, float c_mag, float *mag_total, int lfe_mode)
376 {
377  if (output_lfe && n < highcut) {
378  *lfe_mag = n < lowcut ? 1.f : .5f*(1.f+cosf(M_PIf*(lowcut-n)/(lowcut-highcut)));
379  *lfe_mag *= c_mag;
380  if (lfe_mode)
381  *mag_total -= *lfe_mag;
382  } else {
383  *lfe_mag = 0.f;
384  }
385 }
386 
387 #define TRANSFORM \
388  dst[2 * n ] = mag * cosf(ph); \
389  dst[2 * n + 1] = mag * sinf(ph);
390 
391 static void calculate_factors(AVFilterContext *ctx, int ch, int chan)
392 {
393  AudioSurroundContext *s = ctx->priv;
394  float *factor = (float *)s->factors->extended_data[ch];
395  const float f_x = s->f_x[sc_map[chan >= 0 ? chan : 0]];
396  const float f_y = s->f_y[sc_map[chan >= 0 ? chan : 0]];
397  const int rdft_size = s->rdft_size;
398  const float *x = s->x_pos;
399  const float *y = s->y_pos;
400 
401  switch (chan) {
403  for (int n = 0; n < rdft_size; n++)
404  factor[n] = powf(1.f - fabsf(x[n]), f_x) * powf((y[n] + 1.f) * .5f, f_y);
405  break;
406  case AV_CHAN_FRONT_LEFT:
407  for (int n = 0; n < rdft_size; n++)
408  factor[n] = powf(.5f * ( x[n] + 1.f), f_x) * powf((y[n] + 1.f) * .5f, f_y);
409  break;
410  case AV_CHAN_FRONT_RIGHT:
411  for (int n = 0; n < rdft_size; n++)
412  factor[n] = powf(.5f * (-x[n] + 1.f), f_x) * powf((y[n] + 1.f) * .5f, f_y);
413  break;
415  for (int n = 0; n < rdft_size; n++)
416  factor[n] = powf(1.f - fabsf(x[n]), f_x) * powf((1.f - fabsf(y[n])), f_y);
417  break;
418  case AV_CHAN_BACK_CENTER:
419  for (int n = 0; n < rdft_size; n++)
420  factor[n] = powf(1.f - fabsf(x[n]), f_x) * powf((1.f - y[n]) * .5f, f_y);
421  break;
422  case AV_CHAN_BACK_LEFT:
423  for (int n = 0; n < rdft_size; n++)
424  factor[n] = powf(.5f * ( x[n] + 1.f), f_x) * powf(1.f - ((y[n] + 1.f) * .5f), f_y);
425  break;
426  case AV_CHAN_BACK_RIGHT:
427  for (int n = 0; n < rdft_size; n++)
428  factor[n] = powf(.5f * (-x[n] + 1.f), f_x) * powf(1.f - ((y[n] + 1.f) * .5f), f_y);
429  break;
430  case AV_CHAN_SIDE_LEFT:
431  for (int n = 0; n < rdft_size; n++)
432  factor[n] = powf(.5f * ( x[n] + 1.f), f_x) * powf(1.f - fabsf(y[n]), f_y);
433  break;
434  case AV_CHAN_SIDE_RIGHT:
435  for (int n = 0; n < rdft_size; n++)
436  factor[n] = powf(.5f * (-x[n] + 1.f), f_x) * powf(1.f - fabsf(y[n]), f_y);
437  break;
438  default:
439  for (int n = 0; n < rdft_size; n++)
440  factor[n] = 1.f;
441  break;
442  }
443 }
444 
445 static void do_transform(AVFilterContext *ctx, int ch)
446 {
447  AudioSurroundContext *s = ctx->priv;
448  float *sfactor = (float *)s->sfactors->extended_data[ch];
449  float *factor = (float *)s->factors->extended_data[ch];
450  float *omag = (float *)s->output_mag->extended_data[ch];
451  float *oph = (float *)s->output_ph->extended_data[ch];
452  float *dst = (float *)s->output->extended_data[ch];
453  const int rdft_size = s->rdft_size;
454  const float smooth = s->smooth;
455 
456  if (smooth > 0.f) {
457  for (int n = 0; n < rdft_size; n++)
458  sfactor[n] = smooth * factor[n] + (1.f - smooth) * sfactor[n];
459 
460  factor = sfactor;
461  }
462 
463  for (int n = 0; n < rdft_size; n++)
464  omag[n] *= factor[n];
465 
466  for (int n = 0; n < rdft_size; n++) {
467  const float mag = omag[n];
468  const float ph = oph[n];
469 
470  TRANSFORM
471  }
472 }
473 
474 static void stereo_copy(AVFilterContext *ctx, int ch, int chan)
475 {
476  AudioSurroundContext *s = ctx->priv;
477  float *omag = (float *)s->output_mag->extended_data[ch];
478  float *oph = (float *)s->output_ph->extended_data[ch];
479  const float *mag_total = s->mag_total;
480  const int rdft_size = s->rdft_size;
481  const float *c_phase = s->c_phase;
482  const float *l_phase = s->l_phase;
483  const float *r_phase = s->r_phase;
484  const float *lfe_mag = s->lfe_mag;
485  const float *c_mag = s->c_mag;
486 
487  switch (chan) {
489  memcpy(omag, c_mag, rdft_size * sizeof(*omag));
490  break;
492  memcpy(omag, lfe_mag, rdft_size * sizeof(*omag));
493  break;
494  case AV_CHAN_FRONT_LEFT:
495  case AV_CHAN_FRONT_RIGHT:
496  case AV_CHAN_BACK_CENTER:
497  case AV_CHAN_BACK_LEFT:
498  case AV_CHAN_BACK_RIGHT:
499  case AV_CHAN_SIDE_LEFT:
500  case AV_CHAN_SIDE_RIGHT:
501  memcpy(omag, mag_total, rdft_size * sizeof(*omag));
502  break;
503  default:
504  break;
505  }
506 
507  switch (chan) {
510  case AV_CHAN_BACK_CENTER:
511  memcpy(oph, c_phase, rdft_size * sizeof(*oph));
512  break;
513  case AV_CHAN_FRONT_LEFT:
514  case AV_CHAN_BACK_LEFT:
515  case AV_CHAN_SIDE_LEFT:
516  memcpy(oph, l_phase, rdft_size * sizeof(*oph));
517  break;
518  case AV_CHAN_FRONT_RIGHT:
519  case AV_CHAN_BACK_RIGHT:
520  case AV_CHAN_SIDE_RIGHT:
521  memcpy(oph, r_phase, rdft_size * sizeof(*oph));
522  break;
523  default:
524  break;
525  }
526 }
527 
528 static void stereo_upmix(AVFilterContext *ctx, int ch)
529 {
530  AudioSurroundContext *s = ctx->priv;
531  const int chan = av_channel_layout_channel_from_index(&s->out_ch_layout, ch);
532 
533  calculate_factors(ctx, ch, chan);
534 
535  stereo_copy(ctx, ch, chan);
536 
537  do_transform(ctx, ch);
538 }
539 
540 static void l2_1_upmix(AVFilterContext *ctx, int ch)
541 {
542  AudioSurroundContext *s = ctx->priv;
543  const int chan = av_channel_layout_channel_from_index(&s->out_ch_layout, ch);
544  float *omag = (float *)s->output_mag->extended_data[ch];
545  float *oph = (float *)s->output_ph->extended_data[ch];
546  const float *mag_total = s->mag_total;
547  const float *lfe_phase = s->lfe_phase;
548  const int rdft_size = s->rdft_size;
549  const float *c_phase = s->c_phase;
550  const float *l_phase = s->l_phase;
551  const float *r_phase = s->r_phase;
552  const float *lfe_mag = s->lfe_mag;
553  const float *c_mag = s->c_mag;
554 
555  switch (chan) {
557  calculate_factors(ctx, ch, -1);
558  break;
559  default:
560  calculate_factors(ctx, ch, chan);
561  break;
562  }
563 
564  switch (chan) {
566  memcpy(omag, c_mag, rdft_size * sizeof(*omag));
567  break;
569  memcpy(omag, lfe_mag, rdft_size * sizeof(*omag));
570  break;
571  case AV_CHAN_FRONT_LEFT:
572  case AV_CHAN_FRONT_RIGHT:
573  case AV_CHAN_BACK_CENTER:
574  case AV_CHAN_BACK_LEFT:
575  case AV_CHAN_BACK_RIGHT:
576  case AV_CHAN_SIDE_LEFT:
577  case AV_CHAN_SIDE_RIGHT:
578  memcpy(omag, mag_total, rdft_size * sizeof(*omag));
579  break;
580  default:
581  break;
582  }
583 
584  switch (chan) {
586  memcpy(oph, lfe_phase, rdft_size * sizeof(*oph));
587  break;
589  case AV_CHAN_BACK_CENTER:
590  memcpy(oph, c_phase, rdft_size * sizeof(*oph));
591  break;
592  case AV_CHAN_FRONT_LEFT:
593  case AV_CHAN_BACK_LEFT:
594  case AV_CHAN_SIDE_LEFT:
595  memcpy(oph, l_phase, rdft_size * sizeof(*oph));
596  break;
597  case AV_CHAN_FRONT_RIGHT:
598  case AV_CHAN_BACK_RIGHT:
599  case AV_CHAN_SIDE_RIGHT:
600  memcpy(oph, r_phase, rdft_size * sizeof(*oph));
601  break;
602  default:
603  break;
604  }
605 
606  do_transform(ctx, ch);
607 }
608 
609 static void surround_upmix(AVFilterContext *ctx, int ch)
610 {
611  AudioSurroundContext *s = ctx->priv;
612  const int chan = av_channel_layout_channel_from_index(&s->out_ch_layout, ch);
613 
614  switch (chan) {
616  calculate_factors(ctx, ch, -1);
617  break;
618  default:
619  calculate_factors(ctx, ch, chan);
620  break;
621  }
622 
623  stereo_copy(ctx, ch, chan);
624 
625  do_transform(ctx, ch);
626 }
627 
629  float c_re, float c_im,
630  float mag_totall, float mag_totalr,
631  float fl_phase, float fr_phase,
632  float bl_phase, float br_phase,
633  float sl_phase, float sr_phase,
634  float xl, float yl,
635  float xr, float yr,
636  int n)
637 {
638  float fl_mag, fr_mag, ls_mag, rs_mag, lb_mag, rb_mag;
639  float *dstc, *dstl, *dstr, *dstls, *dstrs, *dstlb, *dstrb, *dstlfe;
640  float lfe_mag, c_phase, mag_total = (mag_totall + mag_totalr) * 0.5f;
641  AudioSurroundContext *s = ctx->priv;
642 
643  dstl = (float *)s->output->extended_data[0];
644  dstr = (float *)s->output->extended_data[1];
645  dstc = (float *)s->output->extended_data[2];
646  dstlfe = (float *)s->output->extended_data[3];
647  dstlb = (float *)s->output->extended_data[4];
648  dstrb = (float *)s->output->extended_data[5];
649  dstls = (float *)s->output->extended_data[6];
650  dstrs = (float *)s->output->extended_data[7];
651 
652  c_phase = atan2f(c_im, c_re);
653 
654  get_lfe(s->output_lfe, n, s->lowcut, s->highcut, &lfe_mag, hypotf(c_re, c_im), &mag_total, s->lfe_mode);
655 
656  fl_mag = powf(.5f * (xl + 1.f), s->f_x[SC_FL]) * powf((yl + 1.f) * .5f, s->f_y[SC_FL]) * mag_totall;
657  fr_mag = powf(.5f * (xr + 1.f), s->f_x[SC_FR]) * powf((yr + 1.f) * .5f, s->f_y[SC_FR]) * mag_totalr;
658  lb_mag = powf(.5f * (-xl + 1.f), s->f_x[SC_BL]) * powf((yl + 1.f) * .5f, s->f_y[SC_BL]) * mag_totall;
659  rb_mag = powf(.5f * (-xr + 1.f), s->f_x[SC_BR]) * powf((yr + 1.f) * .5f, s->f_y[SC_BR]) * mag_totalr;
660  ls_mag = powf(1.f - fabsf(xl), s->f_x[SC_SL]) * powf((yl + 1.f) * .5f, s->f_y[SC_SL]) * mag_totall;
661  rs_mag = powf(1.f - fabsf(xr), s->f_x[SC_SR]) * powf((yr + 1.f) * .5f, s->f_y[SC_SR]) * mag_totalr;
662 
663  dstl[2 * n ] = fl_mag * cosf(fl_phase);
664  dstl[2 * n + 1] = fl_mag * sinf(fl_phase);
665 
666  dstr[2 * n ] = fr_mag * cosf(fr_phase);
667  dstr[2 * n + 1] = fr_mag * sinf(fr_phase);
668 
669  dstc[2 * n ] = c_re;
670  dstc[2 * n + 1] = c_im;
671 
672  dstlfe[2 * n ] = lfe_mag * cosf(c_phase);
673  dstlfe[2 * n + 1] = lfe_mag * sinf(c_phase);
674 
675  dstlb[2 * n ] = lb_mag * cosf(bl_phase);
676  dstlb[2 * n + 1] = lb_mag * sinf(bl_phase);
677 
678  dstrb[2 * n ] = rb_mag * cosf(br_phase);
679  dstrb[2 * n + 1] = rb_mag * sinf(br_phase);
680 
681  dstls[2 * n ] = ls_mag * cosf(sl_phase);
682  dstls[2 * n + 1] = ls_mag * sinf(sl_phase);
683 
684  dstrs[2 * n ] = rs_mag * cosf(sr_phase);
685  dstrs[2 * n + 1] = rs_mag * sinf(sr_phase);
686 }
687 
689  float c_re, float c_im,
690  float lfe_re, float lfe_im,
691  float mag_totall, float mag_totalr,
692  float fl_phase, float fr_phase,
693  float bl_phase, float br_phase,
694  float sl_phase, float sr_phase,
695  float xl, float yl,
696  float xr, float yr,
697  int n)
698 {
699  float fl_mag, fr_mag, ls_mag, rs_mag, lb_mag, rb_mag;
700  float *dstc, *dstl, *dstr, *dstls, *dstrs, *dstlb, *dstrb, *dstlfe;
701  AudioSurroundContext *s = ctx->priv;
702 
703  dstl = (float *)s->output->extended_data[0];
704  dstr = (float *)s->output->extended_data[1];
705  dstc = (float *)s->output->extended_data[2];
706  dstlfe = (float *)s->output->extended_data[3];
707  dstlb = (float *)s->output->extended_data[4];
708  dstrb = (float *)s->output->extended_data[5];
709  dstls = (float *)s->output->extended_data[6];
710  dstrs = (float *)s->output->extended_data[7];
711 
712  fl_mag = powf(.5f * (xl + 1.f), s->f_x[SC_FL]) * powf((yl + 1.f) * .5f, s->f_y[SC_FL]) * mag_totall;
713  fr_mag = powf(.5f * (xr + 1.f), s->f_x[SC_FR]) * powf((yr + 1.f) * .5f, s->f_y[SC_FR]) * mag_totalr;
714  lb_mag = powf(.5f * (-xl + 1.f), s->f_x[SC_BL]) * powf((yl + 1.f) * .5f, s->f_y[SC_BL]) * mag_totall;
715  rb_mag = powf(.5f * (-xr + 1.f), s->f_x[SC_BR]) * powf((yr + 1.f) * .5f, s->f_y[SC_BR]) * mag_totalr;
716  ls_mag = powf(1.f - fabsf(xl), s->f_x[SC_SL]) * powf((yl + 1.f) * .5f, s->f_y[SC_SL]) * mag_totall;
717  rs_mag = powf(1.f - fabsf(xr), s->f_x[SC_SR]) * powf((yr + 1.f) * .5f, s->f_y[SC_SR]) * mag_totalr;
718 
719  dstl[2 * n ] = fl_mag * cosf(fl_phase);
720  dstl[2 * n + 1] = fl_mag * sinf(fl_phase);
721 
722  dstr[2 * n ] = fr_mag * cosf(fr_phase);
723  dstr[2 * n + 1] = fr_mag * sinf(fr_phase);
724 
725  dstc[2 * n ] = c_re;
726  dstc[2 * n + 1] = c_im;
727 
728  dstlfe[2 * n ] = lfe_re;
729  dstlfe[2 * n + 1] = lfe_im;
730 
731  dstlb[2 * n ] = lb_mag * cosf(bl_phase);
732  dstlb[2 * n + 1] = lb_mag * sinf(bl_phase);
733 
734  dstrb[2 * n ] = rb_mag * cosf(br_phase);
735  dstrb[2 * n + 1] = rb_mag * sinf(br_phase);
736 
737  dstls[2 * n ] = ls_mag * cosf(sl_phase);
738  dstls[2 * n + 1] = ls_mag * sinf(sl_phase);
739 
740  dstrs[2 * n ] = rs_mag * cosf(sr_phase);
741  dstrs[2 * n + 1] = rs_mag * sinf(sr_phase);
742 }
743 
745 {
746  AudioSurroundContext *s = ctx->priv;
747  const float *srcl = (const float *)s->input->extended_data[0];
748  const float *srcr = (const float *)s->input->extended_data[1];
749  const int output_lfe = s->output_lfe && s->create_lfe;
750  const int rdft_size = s->rdft_size;
751  const int lfe_mode = s->lfe_mode;
752  const float highcut = s->highcut;
753  const float lowcut = s->lowcut;
754  const float angle = s->angle;
755  const float focus = s->focus;
756  float *magtotal = s->mag_total;
757  float *lfemag = s->lfe_mag;
758  float *lphase = s->l_phase;
759  float *rphase = s->r_phase;
760  float *cphase = s->c_phase;
761  float *cmag = s->c_mag;
762  float *xpos = s->x_pos;
763  float *ypos = s->y_pos;
764 
765  for (int n = 0; n < rdft_size; n++) {
766  float l_re = srcl[2 * n], r_re = srcr[2 * n];
767  float l_im = srcl[2 * n + 1], r_im = srcr[2 * n + 1];
768  float c_phase = atan2f(l_im + r_im, l_re + r_re);
769  float l_mag = hypotf(l_re, l_im);
770  float r_mag = hypotf(r_re, r_im);
771  float mag_total = hypotf(l_mag, r_mag);
772  float l_phase = atan2f(l_im, l_re);
773  float r_phase = atan2f(r_im, r_re);
774  float phase_dif = fabsf(l_phase - r_phase);
775  float mag_sum = l_mag + r_mag;
776  float c_mag = mag_sum * 0.5f;
777  float mag_dif, x, y;
778 
779  mag_sum = mag_sum < MIN_MAG_SUM ? 1.f : mag_sum;
780  mag_dif = (l_mag - r_mag) / mag_sum;
781  if (phase_dif > M_PIf)
782  phase_dif = 2.f * M_PIf - phase_dif;
783 
784  stereo_position(mag_dif, phase_dif, &x, &y);
785  angle_transform(&x, &y, angle);
786  focus_transform(&x, &y, focus);
787  get_lfe(output_lfe, n, lowcut, highcut, &lfemag[n], c_mag, &mag_total, lfe_mode);
788 
789  xpos[n] = x;
790  ypos[n] = y;
791  lphase[n] = l_phase;
792  rphase[n] = r_phase;
793  cmag[n] = c_mag;
794  cphase[n] = c_phase;
795  magtotal[n] = mag_total;
796  }
797 }
798 
800 {
801  AudioSurroundContext *s = ctx->priv;
802  const float *srcl = (const float *)s->input->extended_data[0];
803  const float *srcr = (const float *)s->input->extended_data[1];
804  const float *srclfe = (const float *)s->input->extended_data[2];
805  const int rdft_size = s->rdft_size;
806  const float angle = s->angle;
807  const float focus = s->focus;
808  float *magtotal = s->mag_total;
809  float *lfephase = s->lfe_phase;
810  float *lfemag = s->lfe_mag;
811  float *lphase = s->l_phase;
812  float *rphase = s->r_phase;
813  float *cphase = s->c_phase;
814  float *cmag = s->c_mag;
815  float *xpos = s->x_pos;
816  float *ypos = s->y_pos;
817 
818  for (int n = 0; n < rdft_size; n++) {
819  float l_re = srcl[2 * n], r_re = srcr[2 * n];
820  float l_im = srcl[2 * n + 1], r_im = srcr[2 * n + 1];
821  float lfe_re = srclfe[2 * n], lfe_im = srclfe[2 * n + 1];
822  float c_phase = atan2f(l_im + r_im, l_re + r_re);
823  float l_mag = hypotf(l_re, l_im);
824  float r_mag = hypotf(r_re, r_im);
825  float lfe_mag = hypotf(lfe_re, lfe_im);
826  float lfe_phase = atan2f(lfe_im, lfe_re);
827  float mag_total = hypotf(l_mag, r_mag);
828  float l_phase = atan2f(l_im, l_re);
829  float r_phase = atan2f(r_im, r_re);
830  float phase_dif = fabsf(l_phase - r_phase);
831  float mag_sum = l_mag + r_mag;
832  float c_mag = mag_sum * 0.5f;
833  float mag_dif, x, y;
834 
835  mag_sum = mag_sum < MIN_MAG_SUM ? 1.f : mag_sum;
836  mag_dif = (l_mag - r_mag) / mag_sum;
837  if (phase_dif > M_PIf)
838  phase_dif = 2.f * M_PIf - phase_dif;
839 
840  stereo_position(mag_dif, phase_dif, &x, &y);
841  angle_transform(&x, &y, angle);
842  focus_transform(&x, &y, focus);
843 
844  xpos[n] = x;
845  ypos[n] = y;
846  lphase[n] = l_phase;
847  rphase[n] = r_phase;
848  cmag[n] = c_mag;
849  cphase[n] = c_phase;
850  lfemag[n] = lfe_mag;
851  lfephase[n] = lfe_phase;
852  magtotal[n] = mag_total;
853  }
854 }
855 
857 {
858  AudioSurroundContext *s = ctx->priv;
859  const float *srcl = (const float *)s->input->extended_data[0];
860  const float *srcr = (const float *)s->input->extended_data[1];
861  const float *srcc = (const float *)s->input->extended_data[2];
862  const int output_lfe = s->output_lfe && s->create_lfe;
863  const int rdft_size = s->rdft_size;
864  const int lfe_mode = s->lfe_mode;
865  const float highcut = s->highcut;
866  const float lowcut = s->lowcut;
867  const float angle = s->angle;
868  const float focus = s->focus;
869  float *magtotal = s->mag_total;
870  float *lfemag = s->lfe_mag;
871  float *lphase = s->l_phase;
872  float *rphase = s->r_phase;
873  float *cphase = s->c_phase;
874  float *cmag = s->c_mag;
875  float *xpos = s->x_pos;
876  float *ypos = s->y_pos;
877 
878  for (int n = 0; n < rdft_size; n++) {
879  float l_re = srcl[2 * n], r_re = srcr[2 * n];
880  float l_im = srcl[2 * n + 1], r_im = srcr[2 * n + 1];
881  float c_re = srcc[2 * n], c_im = srcc[2 * n + 1];
882  float c_phase = atan2f(c_im, c_re);
883  float c_mag = hypotf(c_re, c_im);
884  float l_mag = hypotf(l_re, l_im);
885  float r_mag = hypotf(r_re, r_im);
886  float mag_total = hypotf(l_mag, r_mag);
887  float l_phase = atan2f(l_im, l_re);
888  float r_phase = atan2f(r_im, r_re);
889  float phase_dif = fabsf(l_phase - r_phase);
890  float mag_sum = l_mag + r_mag;
891  float mag_dif, x, y;
892 
893  mag_sum = mag_sum < MIN_MAG_SUM ? 1.f : mag_sum;
894  mag_dif = (l_mag - r_mag) / mag_sum;
895  if (phase_dif > M_PIf)
896  phase_dif = 2.f * M_PIf - phase_dif;
897 
898  stereo_position(mag_dif, phase_dif, &x, &y);
899  angle_transform(&x, &y, angle);
900  focus_transform(&x, &y, focus);
901  get_lfe(output_lfe, n, lowcut, highcut, &lfemag[n], c_mag, &mag_total, lfe_mode);
902 
903  xpos[n] = x;
904  ypos[n] = y;
905  lphase[n] = l_phase;
906  rphase[n] = r_phase;
907  cmag[n] = c_mag;
908  cphase[n] = c_phase;
909  magtotal[n] = mag_total;
910  }
911 }
912 
914 {
915  AudioSurroundContext *s = ctx->priv;
916  const int rdft_size = s->rdft_size;
917  float *srcl, *srcr, *srcc, *srcsl, *srcsr;
918  int n;
919 
920  srcl = (float *)s->input->extended_data[0];
921  srcr = (float *)s->input->extended_data[1];
922  srcc = (float *)s->input->extended_data[2];
923  srcsl = (float *)s->input->extended_data[3];
924  srcsr = (float *)s->input->extended_data[4];
925 
926  for (n = 0; n < rdft_size; n++) {
927  float fl_re = srcl[2 * n], fr_re = srcr[2 * n];
928  float fl_im = srcl[2 * n + 1], fr_im = srcr[2 * n + 1];
929  float c_re = srcc[2 * n], c_im = srcc[2 * n + 1];
930  float sl_re = srcsl[2 * n], sl_im = srcsl[2 * n + 1];
931  float sr_re = srcsr[2 * n], sr_im = srcsr[2 * n + 1];
932  float fl_mag = hypotf(fl_re, fl_im);
933  float fr_mag = hypotf(fr_re, fr_im);
934  float fl_phase = atan2f(fl_im, fl_re);
935  float fr_phase = atan2f(fr_im, fr_re);
936  float sl_mag = hypotf(sl_re, sl_im);
937  float sr_mag = hypotf(sr_re, sr_im);
938  float sl_phase = atan2f(sl_im, sl_re);
939  float sr_phase = atan2f(sr_im, sr_re);
940  float phase_difl = fabsf(fl_phase - sl_phase);
941  float phase_difr = fabsf(fr_phase - sr_phase);
942  float magl_sum = fl_mag + sl_mag;
943  float magr_sum = fr_mag + sr_mag;
944  float mag_difl = magl_sum < MIN_MAG_SUM ? FFDIFFSIGN(fl_mag, sl_mag) : (fl_mag - sl_mag) / magl_sum;
945  float mag_difr = magr_sum < MIN_MAG_SUM ? FFDIFFSIGN(fr_mag, sr_mag) : (fr_mag - sr_mag) / magr_sum;
946  float mag_totall = hypotf(fl_mag, sl_mag);
947  float mag_totalr = hypotf(fr_mag, sr_mag);
948  float bl_phase = atan2f(fl_im + sl_im, fl_re + sl_re);
949  float br_phase = atan2f(fr_im + sr_im, fr_re + sr_re);
950  float xl, yl;
951  float xr, yr;
952 
953  if (phase_difl > M_PIf)
954  phase_difl = 2.f * M_PIf - phase_difl;
955 
956  if (phase_difr > M_PIf)
957  phase_difr = 2.f * M_PIf - phase_difr;
958 
959  stereo_position(mag_difl, phase_difl, &xl, &yl);
960  stereo_position(mag_difr, phase_difr, &xr, &yr);
961 
962  s->upmix_5_0(ctx, c_re, c_im,
963  mag_totall, mag_totalr,
964  fl_phase, fr_phase,
965  bl_phase, br_phase,
966  sl_phase, sr_phase,
967  xl, yl, xr, yr, n);
968  }
969 }
970 
972 {
973  AudioSurroundContext *s = ctx->priv;
974  const int rdft_size = s->rdft_size;
975  float *srcl, *srcr, *srcc, *srclfe, *srcsl, *srcsr;
976  int n;
977 
978  srcl = (float *)s->input->extended_data[0];
979  srcr = (float *)s->input->extended_data[1];
980  srcc = (float *)s->input->extended_data[2];
981  srclfe = (float *)s->input->extended_data[3];
982  srcsl = (float *)s->input->extended_data[4];
983  srcsr = (float *)s->input->extended_data[5];
984 
985  for (n = 0; n < rdft_size; n++) {
986  float fl_re = srcl[2 * n], fr_re = srcr[2 * n];
987  float fl_im = srcl[2 * n + 1], fr_im = srcr[2 * n + 1];
988  float c_re = srcc[2 * n], c_im = srcc[2 * n + 1];
989  float lfe_re = srclfe[2 * n], lfe_im = srclfe[2 * n + 1];
990  float sl_re = srcsl[2 * n], sl_im = srcsl[2 * n + 1];
991  float sr_re = srcsr[2 * n], sr_im = srcsr[2 * n + 1];
992  float fl_mag = hypotf(fl_re, fl_im);
993  float fr_mag = hypotf(fr_re, fr_im);
994  float fl_phase = atan2f(fl_im, fl_re);
995  float fr_phase = atan2f(fr_im, fr_re);
996  float sl_mag = hypotf(sl_re, sl_im);
997  float sr_mag = hypotf(sr_re, sr_im);
998  float sl_phase = atan2f(sl_im, sl_re);
999  float sr_phase = atan2f(sr_im, sr_re);
1000  float phase_difl = fabsf(fl_phase - sl_phase);
1001  float phase_difr = fabsf(fr_phase - sr_phase);
1002  float magl_sum = fl_mag + sl_mag;
1003  float magr_sum = fr_mag + sr_mag;
1004  float mag_difl = magl_sum < MIN_MAG_SUM ? FFDIFFSIGN(fl_mag, sl_mag) : (fl_mag - sl_mag) / magl_sum;
1005  float mag_difr = magr_sum < MIN_MAG_SUM ? FFDIFFSIGN(fr_mag, sr_mag) : (fr_mag - sr_mag) / magr_sum;
1006  float mag_totall = hypotf(fl_mag, sl_mag);
1007  float mag_totalr = hypotf(fr_mag, sr_mag);
1008  float bl_phase = atan2f(fl_im + sl_im, fl_re + sl_re);
1009  float br_phase = atan2f(fr_im + sr_im, fr_re + sr_re);
1010  float xl, yl;
1011  float xr, yr;
1012 
1013  if (phase_difl > M_PIf)
1014  phase_difl = 2.f * M_PIf - phase_difl;
1015 
1016  if (phase_difr > M_PIf)
1017  phase_difr = 2.f * M_PIf - phase_difr;
1018 
1019  stereo_position(mag_difl, phase_difl, &xl, &yl);
1020  stereo_position(mag_difr, phase_difr, &xr, &yr);
1021 
1022  s->upmix_5_1(ctx, c_re, c_im, lfe_re, lfe_im,
1023  mag_totall, mag_totalr,
1024  fl_phase, fr_phase,
1025  bl_phase, br_phase,
1026  sl_phase, sr_phase,
1027  xl, yl, xr, yr, n);
1028  }
1029 }
1030 
1032 {
1033  AudioSurroundContext *s = ctx->priv;
1034  const int rdft_size = s->rdft_size;
1035  float *srcl, *srcr, *srcc, *srclfe, *srcbl, *srcbr;
1036  int n;
1037 
1038  srcl = (float *)s->input->extended_data[0];
1039  srcr = (float *)s->input->extended_data[1];
1040  srcc = (float *)s->input->extended_data[2];
1041  srclfe = (float *)s->input->extended_data[3];
1042  srcbl = (float *)s->input->extended_data[4];
1043  srcbr = (float *)s->input->extended_data[5];
1044 
1045  for (n = 0; n < rdft_size; n++) {
1046  float fl_re = srcl[2 * n], fr_re = srcr[2 * n];
1047  float fl_im = srcl[2 * n + 1], fr_im = srcr[2 * n + 1];
1048  float c_re = srcc[2 * n], c_im = srcc[2 * n + 1];
1049  float lfe_re = srclfe[2 * n], lfe_im = srclfe[2 * n + 1];
1050  float bl_re = srcbl[2 * n], bl_im = srcbl[2 * n + 1];
1051  float br_re = srcbr[2 * n], br_im = srcbr[2 * n + 1];
1052  float fl_mag = hypotf(fl_re, fl_im);
1053  float fr_mag = hypotf(fr_re, fr_im);
1054  float fl_phase = atan2f(fl_im, fl_re);
1055  float fr_phase = atan2f(fr_im, fr_re);
1056  float bl_mag = hypotf(bl_re, bl_im);
1057  float br_mag = hypotf(br_re, br_im);
1058  float bl_phase = atan2f(bl_im, bl_re);
1059  float br_phase = atan2f(br_im, br_re);
1060  float phase_difl = fabsf(fl_phase - bl_phase);
1061  float phase_difr = fabsf(fr_phase - br_phase);
1062  float magl_sum = fl_mag + bl_mag;
1063  float magr_sum = fr_mag + br_mag;
1064  float mag_difl = magl_sum < MIN_MAG_SUM ? FFDIFFSIGN(fl_mag, bl_mag) : (fl_mag - bl_mag) / magl_sum;
1065  float mag_difr = magr_sum < MIN_MAG_SUM ? FFDIFFSIGN(fr_mag, br_mag) : (fr_mag - br_mag) / magr_sum;
1066  float mag_totall = hypotf(fl_mag, bl_mag);
1067  float mag_totalr = hypotf(fr_mag, br_mag);
1068  float sl_phase = atan2f(fl_im + bl_im, fl_re + bl_re);
1069  float sr_phase = atan2f(fr_im + br_im, fr_re + br_re);
1070  float xl, yl;
1071  float xr, yr;
1072 
1073  if (phase_difl > M_PIf)
1074  phase_difl = 2.f * M_PIf - phase_difl;
1075 
1076  if (phase_difr > M_PIf)
1077  phase_difr = 2.f * M_PIf - phase_difr;
1078 
1079  stereo_position(mag_difl, phase_difl, &xl, &yl);
1080  stereo_position(mag_difr, phase_difr, &xr, &yr);
1081 
1082  s->upmix_5_1(ctx, c_re, c_im, lfe_re, lfe_im,
1083  mag_totall, mag_totalr,
1084  fl_phase, fr_phase,
1085  bl_phase, br_phase,
1086  sl_phase, sr_phase,
1087  xl, yl, xr, yr, n);
1088  }
1089 }
1090 
1092 {
1093  AudioSurroundContext *s = ctx->priv;
1094 
1095  if (s->all_x >= 0.f)
1096  for (int n = 0; n < SC_NB; n++)
1097  s->f_x[n] = s->all_x;
1098  s->all_x = -1.f;
1099  if (s->all_y >= 0.f)
1100  for (int n = 0; n < SC_NB; n++)
1101  s->f_y[n] = s->all_y;
1102  s->all_y = -1.f;
1103 }
1104 
1106 {
1107  AudioSurroundContext *s = ctx->priv;
1108  int64_t in_channel_layout, out_channel_layout;
1109  char in_name[128], out_name[128];
1110  float overlap;
1111 
1112  if (s->lowcutf >= s->highcutf) {
1113  av_log(ctx, AV_LOG_ERROR, "Low cut-off '%d' should be less than high cut-off '%d'.\n",
1114  s->lowcutf, s->highcutf);
1115  return AVERROR(EINVAL);
1116  }
1117 
1118  in_channel_layout = s->in_ch_layout.order == AV_CHANNEL_ORDER_NATIVE ?
1119  s->in_ch_layout.u.mask : 0;
1120  out_channel_layout = s->out_ch_layout.order == AV_CHANNEL_ORDER_NATIVE ?
1121  s->out_ch_layout.u.mask : 0;
1122 
1123  s->create_lfe = av_channel_layout_index_from_channel(&s->out_ch_layout,
1124  AV_CHAN_LOW_FREQUENCY) >= 0;
1125 
1126  switch (in_channel_layout) {
1127  case AV_CH_LAYOUT_STEREO:
1128  s->filter = filter_stereo;
1129  s->upmix = stereo_upmix;
1130  break;
1131  case AV_CH_LAYOUT_2POINT1:
1132  s->filter = filter_2_1;
1133  s->upmix = l2_1_upmix;
1134  break;
1135  case AV_CH_LAYOUT_SURROUND:
1136  s->filter = filter_surround;
1137  s->upmix = surround_upmix;
1138  break;
1139  case AV_CH_LAYOUT_5POINT0:
1140  s->filter = filter_5_0_side;
1141  switch (out_channel_layout) {
1142  case AV_CH_LAYOUT_7POINT1:
1143  s->upmix_5_0 = upmix_7_1_5_0_side;
1144  break;
1145  default:
1146  goto fail;
1147  }
1148  break;
1149  case AV_CH_LAYOUT_5POINT1:
1150  s->filter = filter_5_1_side;
1151  switch (out_channel_layout) {
1152  case AV_CH_LAYOUT_7POINT1:
1153  s->upmix_5_1 = upmix_7_1_5_1;
1154  break;
1155  default:
1156  goto fail;
1157  }
1158  break;
1160  s->filter = filter_5_1_back;
1161  switch (out_channel_layout) {
1162  case AV_CH_LAYOUT_7POINT1:
1163  s->upmix_5_1 = upmix_7_1_5_1;
1164  break;
1165  default:
1166  goto fail;
1167  }
1168  break;
1169  default:
1170 fail:
1171  av_channel_layout_describe(&s->out_ch_layout, out_name, sizeof(out_name));
1172  av_channel_layout_describe(&s->in_ch_layout, in_name, sizeof(in_name));
1173  av_log(ctx, AV_LOG_ERROR, "Unsupported upmix: '%s' -> '%s'.\n",
1174  in_name, out_name);
1175  return AVERROR(EINVAL);
1176  }
1177 
1178  s->window_func_lut = av_calloc(s->win_size, sizeof(*s->window_func_lut));
1179  if (!s->window_func_lut)
1180  return AVERROR(ENOMEM);
1181 
1182  generate_window_func(s->window_func_lut, s->win_size, s->win_func, &overlap);
1183  if (s->overlap == 1)
1184  s->overlap = overlap;
1185 
1186  for (int i = 0; i < s->win_size; i++)
1187  s->window_func_lut[i] = sqrtf(s->window_func_lut[i] / s->win_size);
1188  s->hop_size = FFMAX(1, s->win_size * (1. - s->overlap));
1189 
1190  {
1191  float max = 0.f, *temp_lut = av_calloc(s->win_size, sizeof(*temp_lut));
1192  if (!temp_lut)
1193  return AVERROR(ENOMEM);
1194 
1195  for (int j = 0; j < s->win_size; j += s->hop_size) {
1196  for (int i = 0; i < s->win_size; i++)
1197  temp_lut[(i + j) % s->win_size] += s->window_func_lut[i];
1198  }
1199 
1200  for (int i = 0; i < s->win_size; i++)
1201  max = fmaxf(temp_lut[i], max);
1202  av_freep(&temp_lut);
1203 
1204  s->win_gain = 1.f / (max * sqrtf(s->win_size));
1205  }
1206 
1208 
1209  return 0;
1210 }
1211 
1212 static int fft_channel(AVFilterContext *ctx, AVFrame *in, int ch)
1213 {
1214  AudioSurroundContext *s = ctx->priv;
1215  float *src = (float *)s->input_in->extended_data[ch];
1216  float *win = (float *)s->window->extended_data[ch];
1217  const float *window_func_lut = s->window_func_lut;
1218  const int offset = s->win_size - s->hop_size;
1219  const float level_in = s->input_levels[ch];
1220  const int win_size = s->win_size;
1221 
1222  memmove(src, &src[s->hop_size], offset * sizeof(float));
1223  memcpy(&src[offset], in->extended_data[ch], in->nb_samples * sizeof(float));
1224  memset(&src[offset + in->nb_samples], 0, (s->hop_size - in->nb_samples) * sizeof(float));
1225 
1226  for (int n = 0; n < win_size; n++)
1227  win[n] = src[n] * window_func_lut[n] * level_in;
1228 
1229  s->tx_fn(s->rdft[ch], (float *)s->input->extended_data[ch], win, sizeof(float));
1230 
1231  return 0;
1232 }
1233 
1234 static int fft_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
1235 {
1236  AVFrame *in = arg;
1237  const int start = (in->ch_layout.nb_channels * jobnr) / nb_jobs;
1238  const int end = (in->ch_layout.nb_channels * (jobnr+1)) / nb_jobs;
1239 
1240  for (int ch = start; ch < end; ch++)
1241  fft_channel(ctx, in, ch);
1242 
1243  return 0;
1244 }
1245 
1247 {
1248  AudioSurroundContext *s = ctx->priv;
1249  const float level_out = s->output_levels[ch] * s->win_gain;
1250  const float *window_func_lut = s->window_func_lut;
1251  const int win_size = s->win_size;
1252  float *dst, *ptr;
1253 
1254  dst = (float *)s->output_out->extended_data[ch];
1255  ptr = (float *)s->overlap_buffer->extended_data[ch];
1256  s->itx_fn(s->irdft[ch], dst, (float *)s->output->extended_data[ch], sizeof(AVComplexFloat));
1257 
1258  memmove(s->overlap_buffer->extended_data[ch],
1259  s->overlap_buffer->extended_data[ch] + s->hop_size * sizeof(float),
1260  s->win_size * sizeof(float));
1261  memset(s->overlap_buffer->extended_data[ch] + s->win_size * sizeof(float),
1262  0, s->hop_size * sizeof(float));
1263 
1264  for (int n = 0; n < win_size; n++)
1265  ptr[n] += dst[n] * window_func_lut[n] * level_out;
1266 
1267  ptr = (float *)s->overlap_buffer->extended_data[ch];
1268  dst = (float *)out->extended_data[ch];
1269  memcpy(dst, ptr, s->hop_size * sizeof(float));
1270 
1271  return 0;
1272 }
1273 
1274 static int ifft_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
1275 {
1276  AudioSurroundContext *s = ctx->priv;
1277  AVFrame *out = arg;
1278  const int start = (out->ch_layout.nb_channels * jobnr) / nb_jobs;
1279  const int end = (out->ch_layout.nb_channels * (jobnr+1)) / nb_jobs;
1280 
1281  for (int ch = start; ch < end; ch++) {
1282  if (s->upmix)
1283  s->upmix(ctx, ch);
1284  ifft_channel(ctx, out, ch);
1285  }
1286 
1287  return 0;
1288 }
1289 
1291 {
1292  AVFilterContext *ctx = inlink->dst;
1293  AVFilterLink *outlink = ctx->outputs[0];
1294  AudioSurroundContext *s = ctx->priv;
1295  AVFrame *out;
1296 
1298  FFMIN(inlink->ch_layout.nb_channels,
1300 
1301  s->filter(ctx);
1302 
1303  out = ff_get_audio_buffer(outlink, s->hop_size);
1304  if (!out)
1305  return AVERROR(ENOMEM);
1306 
1308  FFMIN(outlink->ch_layout.nb_channels,
1310 
1311  av_frame_copy_props(out, in);
1312  out->nb_samples = in->nb_samples;
1313 
1314  av_frame_free(&in);
1315  return ff_filter_frame(outlink, out);
1316 }
1317 
1319 {
1320  AVFilterLink *inlink = ctx->inputs[0];
1321  AVFilterLink *outlink = ctx->outputs[0];
1322  AudioSurroundContext *s = ctx->priv;
1323  AVFrame *in = NULL;
1324  int ret = 0, status;
1325  int64_t pts;
1326 
1328 
1329  ret = ff_inlink_consume_samples(inlink, s->hop_size, s->hop_size, &in);
1330  if (ret < 0)
1331  return ret;
1332 
1333  if (ret > 0)
1334  ret = filter_frame(inlink, in);
1335  if (ret < 0)
1336  return ret;
1337 
1338  if (ff_inlink_queued_samples(inlink) >= s->hop_size) {
1339  ff_filter_set_ready(ctx, 10);
1340  return 0;
1341  }
1342 
1344  ff_outlink_set_status(outlink, status, pts);
1345  return 0;
1346  }
1347 
1348  FF_FILTER_FORWARD_WANTED(outlink, inlink);
1349 
1350  return FFERROR_NOT_READY;
1351 }
1352 
1354 {
1355  AudioSurroundContext *s = ctx->priv;
1356 
1357  av_frame_free(&s->factors);
1358  av_frame_free(&s->sfactors);
1359  av_frame_free(&s->window);
1360  av_frame_free(&s->input_in);
1361  av_frame_free(&s->input);
1362  av_frame_free(&s->output);
1363  av_frame_free(&s->output_ph);
1364  av_frame_free(&s->output_mag);
1365  av_frame_free(&s->output_out);
1366  av_frame_free(&s->overlap_buffer);
1367 
1368  for (int ch = 0; ch < s->nb_in_channels; ch++)
1369  av_tx_uninit(&s->rdft[ch]);
1370  for (int ch = 0; ch < s->nb_out_channels; ch++)
1371  av_tx_uninit(&s->irdft[ch]);
1372  av_freep(&s->input_levels);
1373  av_freep(&s->output_levels);
1374  av_freep(&s->rdft);
1375  av_freep(&s->irdft);
1376  av_freep(&s->window_func_lut);
1377 
1378  av_freep(&s->x_pos);
1379  av_freep(&s->y_pos);
1380  av_freep(&s->l_phase);
1381  av_freep(&s->r_phase);
1382  av_freep(&s->c_mag);
1383  av_freep(&s->c_phase);
1384  av_freep(&s->mag_total);
1385  av_freep(&s->lfe_mag);
1386  av_freep(&s->lfe_phase);
1387 }
1388 
1389 static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
1390  char *res, int res_len, int flags)
1391 {
1392  AudioSurroundContext *s = ctx->priv;
1393  int ret;
1394 
1395  ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags);
1396  if (ret < 0)
1397  return ret;
1398 
1399  s->hop_size = FFMAX(1, s->win_size * (1. - s->overlap));
1400 
1404 
1405  return 0;
1406 }
1407 
1408 #define OFFSET(x) offsetof(AudioSurroundContext, x)
1409 #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
1410 #define TFLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
1411 
1412 static const AVOption surround_options[] = {
1413  { "chl_out", "set output channel layout", OFFSET(out_ch_layout), AV_OPT_TYPE_CHLAYOUT, {.str="5.1"}, 0, 0, FLAGS },
1414  { "chl_in", "set input channel layout", OFFSET(in_ch_layout), AV_OPT_TYPE_CHLAYOUT, {.str="stereo"},0, 0, FLAGS },
1415  { "level_in", "set input level", OFFSET(level_in), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },
1416  { "level_out", "set output level", OFFSET(level_out), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },
1417  { "lfe", "output LFE", OFFSET(output_lfe), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, TFLAGS },
1418  { "lfe_low", "LFE low cut off", OFFSET(lowcutf), AV_OPT_TYPE_INT, {.i64=128}, 0, 256, FLAGS },
1419  { "lfe_high", "LFE high cut off", OFFSET(highcutf), AV_OPT_TYPE_INT, {.i64=256}, 0, 512, FLAGS },
1420  { "lfe_mode", "set LFE channel mode", OFFSET(lfe_mode), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, TFLAGS, .unit = "lfe_mode" },
1421  { "add", "just add LFE channel", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 1, TFLAGS, .unit = "lfe_mode" },
1422  { "sub", "subtract LFE channel with others", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 1, TFLAGS, .unit = "lfe_mode" },
1423  { "smooth", "set temporal smoothness strength", OFFSET(smooth), AV_OPT_TYPE_FLOAT, {.dbl=0}, 0, 1, TFLAGS },
1424  { "angle", "set soundfield transform angle", OFFSET(angle), AV_OPT_TYPE_FLOAT, {.dbl=90}, 0, 360, TFLAGS },
1425  { "focus", "set soundfield transform focus", OFFSET(focus), AV_OPT_TYPE_FLOAT, {.dbl=0}, -1, 1, TFLAGS },
1426  { "fc_in", "set front center channel input level", OFFSET(f_i[SC_FC]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },
1427  { "fc_out", "set front center channel output level", OFFSET(f_o[SC_FC]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },
1428  { "fl_in", "set front left channel input level", OFFSET(f_i[SC_FL]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },
1429  { "fl_out", "set front left channel output level", OFFSET(f_o[SC_FL]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },
1430  { "fr_in", "set front right channel input level", OFFSET(f_i[SC_FR]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },
1431  { "fr_out", "set front right channel output level", OFFSET(f_o[SC_FR]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },
1432  { "sl_in", "set side left channel input level", OFFSET(f_i[SC_SL]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },
1433  { "sl_out", "set side left channel output level", OFFSET(f_o[SC_SL]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },
1434  { "sr_in", "set side right channel input level", OFFSET(f_i[SC_SR]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },
1435  { "sr_out", "set side right channel output level", OFFSET(f_o[SC_SR]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },
1436  { "bl_in", "set back left channel input level", OFFSET(f_i[SC_BL]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },
1437  { "bl_out", "set back left channel output level", OFFSET(f_o[SC_BL]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },
1438  { "br_in", "set back right channel input level", OFFSET(f_i[SC_BR]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },
1439  { "br_out", "set back right channel output level", OFFSET(f_o[SC_BR]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },
1440  { "bc_in", "set back center channel input level", OFFSET(f_i[SC_BC]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },
1441  { "bc_out", "set back center channel output level", OFFSET(f_o[SC_BC]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },
1442  { "lfe_in", "set lfe channel input level", OFFSET(f_i[SC_LF]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },
1443  { "lfe_out", "set lfe channel output level", OFFSET(f_o[SC_LF]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },
1444  { "allx", "set all channel's x spread", OFFSET(all_x), AV_OPT_TYPE_FLOAT, {.dbl=-1}, -1, 15, TFLAGS },
1445  { "ally", "set all channel's y spread", OFFSET(all_y), AV_OPT_TYPE_FLOAT, {.dbl=-1}, -1, 15, TFLAGS },
1446  { "fcx", "set front center channel x spread", OFFSET(f_x[SC_FC]), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, .06, 15, TFLAGS },
1447  { "flx", "set front left channel x spread", OFFSET(f_x[SC_FL]), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, .06, 15, TFLAGS },
1448  { "frx", "set front right channel x spread", OFFSET(f_x[SC_FR]), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, .06, 15, TFLAGS },
1449  { "blx", "set back left channel x spread", OFFSET(f_x[SC_BL]), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, .06, 15, TFLAGS },
1450  { "brx", "set back right channel x spread", OFFSET(f_x[SC_BR]), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, .06, 15, TFLAGS },
1451  { "slx", "set side left channel x spread", OFFSET(f_x[SC_SL]), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, .06, 15, TFLAGS },
1452  { "srx", "set side right channel x spread", OFFSET(f_x[SC_SR]), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, .06, 15, TFLAGS },
1453  { "bcx", "set back center channel x spread", OFFSET(f_x[SC_BC]), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, .06, 15, TFLAGS },
1454  { "fcy", "set front center channel y spread", OFFSET(f_y[SC_FC]), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, .06, 15, TFLAGS },
1455  { "fly", "set front left channel y spread", OFFSET(f_y[SC_FL]), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, .06, 15, TFLAGS },
1456  { "fry", "set front right channel y spread", OFFSET(f_y[SC_FR]), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, .06, 15, TFLAGS },
1457  { "bly", "set back left channel y spread", OFFSET(f_y[SC_BL]), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, .06, 15, TFLAGS },
1458  { "bry", "set back right channel y spread", OFFSET(f_y[SC_BR]), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, .06, 15, TFLAGS },
1459  { "sly", "set side left channel y spread", OFFSET(f_y[SC_SL]), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, .06, 15, TFLAGS },
1460  { "sry", "set side right channel y spread", OFFSET(f_y[SC_SR]), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, .06, 15, TFLAGS },
1461  { "bcy", "set back center channel y spread", OFFSET(f_y[SC_BC]), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, .06, 15, TFLAGS },
1462  { "win_size", "set window size", OFFSET(win_size), AV_OPT_TYPE_INT, {.i64=4096},1024,65536,FLAGS },
1463  WIN_FUNC_OPTION("win_func", OFFSET(win_func), FLAGS, WFUNC_HANNING),
1464  { "overlap", "set window overlap", OFFSET(overlap), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, TFLAGS },
1465  { NULL }
1466 };
1467 
1468 AVFILTER_DEFINE_CLASS(surround);
1469 
1470 static const AVFilterPad inputs[] = {
1471  {
1472  .name = "default",
1473  .type = AVMEDIA_TYPE_AUDIO,
1474  .config_props = config_input,
1475  },
1476 };
1477 
1478 static const AVFilterPad outputs[] = {
1479  {
1480  .name = "default",
1481  .type = AVMEDIA_TYPE_AUDIO,
1482  .config_props = config_output,
1483  },
1484 };
1485 
1487  .name = "surround",
1488  .description = NULL_IF_CONFIG_SMALL("Apply audio surround upmix filter."),
1489  .priv_size = sizeof(AudioSurroundContext),
1490  .priv_class = &surround_class,
1491  .init = init,
1492  .uninit = uninit,
1493  .activate = activate,
1497  .flags = AVFILTER_FLAG_SLICE_THREADS,
1498  .process_command = process_command,
1499 };
allchannels_spread
static void allchannels_spread(AVFilterContext *ctx)
Definition: af_surround.c:1091
formats
formats
Definition: signature.h:48
M_LN10f
#define M_LN10f
Definition: mathematics.h:52
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:97
AudioSurroundContext::upmix_5_1
void(* upmix_5_1)(AVFilterContext *ctx, float c_re, float c_im, float lfe_re, float lfe_im, float mag_totall, float mag_totalr, float fl_phase, float fr_phase, float bl_phase, float br_phase, float sl_phase, float sr_phase, float xl, float yl, float xr, float yr, int n)
Definition: af_surround.c:138
upmix_7_1_5_1
static void upmix_7_1_5_1(AVFilterContext *ctx, float c_re, float c_im, float lfe_re, float lfe_im, float mag_totall, float mag_totalr, float fl_phase, float fr_phase, float bl_phase, float br_phase, float sl_phase, float sr_phase, float xl, float yl, float xr, float yr, int n)
Definition: af_surround.c:688
AV_SAMPLE_FMT_FLTP
@ AV_SAMPLE_FMT_FLTP
float, planar
Definition: samplefmt.h:66
sc_map
static const int sc_map[16]
Definition: af_surround.c:50
AVFilterChannelLayouts
A list of supported channel layouts.
Definition: formats.h:85
AudioSurroundContext::upmix
void(* upmix)(AVFilterContext *ctx, int ch)
Definition: af_surround.c:128
r
const char * r
Definition: vf_curves.c:127
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
AudioSurroundContext::highcutf
int highcutf
Definition: af_surround.c:92
opt.h
AudioSurroundContext
Definition: af_surround.c:62
ifft_channel
static int ifft_channel(AVFilterContext *ctx, AVFrame *out, int ch)
Definition: af_surround.c:1246
SC_BC
@ SC_BC
Definition: af_surround.c:34
out
FILE * out
Definition: movenc.c:55
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1015
ff_channel_layouts_ref
int ff_channel_layouts_ref(AVFilterChannelLayouts *f, AVFilterChannelLayouts **ref)
Add *ref as a new reference to f.
Definition: formats.c:674
layouts
enum MovChannelLayoutTag * layouts
Definition: mov_chan.c:337
FFERROR_NOT_READY
return FFERROR_NOT_READY
Definition: filter_design.txt:204
AudioSurroundContext::input
AVFrame * input
Definition: af_surround.c:103
AVTXContext
Definition: tx_priv.h:235
calculate_factors
static void calculate_factors(AVFilterContext *ctx, int ch, int chan)
Definition: af_surround.c:391
atan2f
#define atan2f(y, x)
Definition: libm.h:45
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
OFFSET
#define OFFSET(x)
Definition: af_surround.c:1408
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:160
fft_channel
static int fft_channel(AVFilterContext *ctx, AVFrame *in, int ch)
Definition: af_surround.c:1212
ph
static int FUNC() ph(CodedBitstreamContext *ctx, RWContext *rw, H266RawPH *current)
Definition: cbs_h266_syntax_template.c:3003
process_command
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
Definition: af_surround.c:1389
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:374
AudioSurroundContext::hop_size
int hop_size
Definition: af_surround.c:122
av_channel_layout_channel_from_index
enum AVChannel av_channel_layout_channel_from_index(const AVChannelLayout *channel_layout, unsigned int idx)
Get the channel with the given index in a channel layout.
Definition: channel_layout.c:665
set_output_levels
static void set_output_levels(AVFilterContext *ctx)
Definition: af_surround.c:200
SC_FC
@ SC_FC
Definition: af_surround.c:34
AudioSurroundContext::output_levels
float * output_levels
Definition: af_surround.c:88
AudioSurroundContext::nb_out_channels
int nb_out_channels
Definition: af_surround.c:98
AVOption
AVOption.
Definition: opt.h:346
focus_transform
static void focus_transform(float *x, float *y, float focus)
Definition: af_surround.c:350
FILTER_QUERY_FUNC
#define FILTER_QUERY_FUNC(func)
Definition: internal.h:159
AudioSurroundContext::input_in
AVFrame * input_in
Definition: af_surround.c:102
AudioSurroundContext::out_ch_layout
AVChannelLayout out_ch_layout
Definition: af_surround.c:65
ff_set_common_all_samplerates
int ff_set_common_all_samplerates(AVFilterContext *ctx)
Equivalent to ff_set_common_samplerates(ctx, ff_all_samplerates())
Definition: formats.c:822
AVComplexFloat
Definition: tx.h:27
WIN_FUNC_OPTION
#define WIN_FUNC_OPTION(win_func_opt_name, win_func_offset, flag, default_window_func)
Definition: window_func.h:37
max
#define max(a, b)
Definition: cuda_runtime.h:33
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:170
AudioSurroundContext::overlap
float overlap
Definition: af_surround.c:79
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:313
AudioSurroundContext::y_pos
float * y_pos
Definition: af_surround.c:112
SC_FL
@ SC_FL
Definition: af_surround.c:34
AudioSurroundContext::c_phase
float * c_phase
Definition: af_surround.c:115
FF_FILTER_FORWARD_STATUS_BACK
#define FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink)
Forward the status on an output link to an input link.
Definition: filters.h:199
AudioSurroundContext::output_mag
AVFrame * output_mag
Definition: af_surround.c:105
AudioSurroundContext::lfe_mode
int lfe_mode
Definition: af_surround.c:72
av_tx_init
av_cold int av_tx_init(AVTXContext **ctx, av_tx_fn *tx, enum AVTXType type, int inv, int len, const void *scale, uint64_t flags)
Initialize a transform context with the given configuration (i)MDCTs with an odd length are currently...
Definition: tx.c:903
ra
#define ra
Definition: regdef.h:57
AVFilterFormats
A list of supported formats for one end of a filter link.
Definition: formats.h:64
win
static float win(SuperEqualizerContext *s, float n, int N)
Definition: af_superequalizer.c:120
formats.h
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: af_surround.c:1353
AudioSurroundContext::output_lfe
int output_lfe
Definition: af_surround.c:89
AudioSurroundContext::output_ph
AVFrame * output_ph
Definition: af_surround.c:106
cosf
#define cosf(x)
Definition: libm.h:78
fail
#define fail()
Definition: checkasm.h:179
AudioSurroundContext::all_y
float all_y
Definition: af_surround.c:82
AudioSurroundContext::f_o
float f_o[SC_NB]
Definition: af_surround.c:71
SC_BL
@ SC_BL
Definition: af_surround.c:34
AudioSurroundContext::factors
AVFrame * factors
Definition: af_surround.c:100
AVFrame::ch_layout
AVChannelLayout ch_layout
Channel layout of the audio data.
Definition: frame.h:775
AudioSurroundContext::level_in
float level_in
Definition: af_surround.c:68
pts
static int64_t pts
Definition: transcode_aac.c:644
fabsf
static __device__ float fabsf(float a)
Definition: cuda_runtime.h:181
AV_CH_LAYOUT_STEREO
#define AV_CH_LAYOUT_STEREO
Definition: channel_layout.h:205
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:33
FFDIFFSIGN
#define FFDIFFSIGN(x, y)
Comparator.
Definition: macros.h:45
FLAGS
#define FLAGS
Definition: af_surround.c:1409
AudioSurroundContext::mag_total
float * mag_total
Definition: af_surround.c:119
avassert.h
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
av_cold
#define av_cold
Definition: attributes.h:90
ff_set_common_formats
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:868
av_tx_fn
void(* av_tx_fn)(AVTXContext *s, void *out, void *in, ptrdiff_t stride)
Function pointer to a function to perform the transform.
Definition: tx.h:151
filter_5_1_back
static void filter_5_1_back(AVFilterContext *ctx)
Definition: af_surround.c:1031
stereo_copy
static void stereo_copy(AVFilterContext *ctx, int ch, int chan)
Definition: af_surround.c:474
AudioSurroundContext::x_pos
float * x_pos
Definition: af_surround.c:111
av_channel_layout_describe
int av_channel_layout_describe(const AVChannelLayout *channel_layout, char *buf, size_t buf_size)
Get a human-readable string describing the channel layout properties.
Definition: channel_layout.c:645
ff_outlink_set_status
static void ff_outlink_set_status(AVFilterLink *link, int status, int64_t pts)
Set the status field of a link from the source filter.
Definition: filters.h:189
query_formats
static int query_formats(AVFilterContext *ctx)
Definition: af_surround.c:150
s
#define s(width, name)
Definition: cbs_vp9.c:198
ff_af_surround
const AVFilter ff_af_surround
Definition: af_surround.c:1486
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
SC_LF
@ SC_LF
Definition: af_surround.c:34
surround_options
static const AVOption surround_options[]
Definition: af_surround.c:1412
AudioSurroundContext::c_mag
float * c_mag
Definition: af_surround.c:116
outputs
static const AVFilterPad outputs[]
Definition: af_surround.c:1478
AudioSurroundContext::f_i
float f_i[SC_NB]
Definition: af_surround.c:70
fminf
float fminf(float, float)
AV_CHAN_SIDE_RIGHT
@ AV_CHAN_SIDE_RIGHT
Definition: channel_layout.h:60
filters.h
ctx
AVFormatContext * ctx
Definition: movenc.c:49
AudioSurroundContext::overlap_buffer
AVFrame * overlap_buffer
Definition: af_surround.c:108
AudioSurroundContext::output_out
AVFrame * output_out
Definition: af_surround.c:107
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: internal.h:182
M_PI_4f
#define M_PI_4f
Definition: mathematics.h:82
AudioSurroundContext::upmix_5_0
void(* upmix_5_0)(AVFilterContext *ctx, float c_re, float c_im, float mag_totall, float mag_totalr, float fl_phase, float fr_phase, float bl_phase, float br_phase, float sl_phase, float sr_phase, float xl, float yl, float xr, float yr, int n)
Definition: af_surround.c:129
AudioSurroundContext::focus
float focus
Definition: af_surround.c:75
arg
const char * arg
Definition: jacosubdec.c:67
if
if(ret)
Definition: filter_design.txt:179
AudioSurroundContext::lowcutf
int lowcutf
Definition: af_surround.c:91
AudioSurroundContext::level_out
float level_out
Definition: af_surround.c:69
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
SurroundChannel
SurroundChannel
Definition: af_surround.c:33
ff_inlink_consume_samples
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:1462
NULL
#define NULL
Definition: coverity.c:32
av_frame_copy_props
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:709
AudioSurroundContext::r_phase
float * r_phase
Definition: af_surround.c:114
stereo_upmix
static void stereo_upmix(AVFilterContext *ctx, int ch)
Definition: af_surround.c:528
filter_stereo
static void filter_stereo(AVFilterContext *ctx)
Definition: af_surround.c:744
AudioSurroundContext::irdft
AVTXContext ** irdft
Definition: af_surround.c:123
SC_BR
@ SC_BR
Definition: af_surround.c:34
AudioSurroundContext::filter
void(* filter)(AVFilterContext *ctx)
Definition: af_surround.c:127
ff_add_format
int ff_add_format(AVFilterFormats **avff, int64_t fmt)
Add fmt to the list of media formats contained in *avff.
Definition: formats.c:505
filter_5_0_side
static void filter_5_0_side(AVFilterContext *ctx)
Definition: af_surround.c:913
AV_CH_LAYOUT_5POINT1
#define AV_CH_LAYOUT_5POINT1
Definition: channel_layout.h:215
AudioSurroundContext::lowcut
float lowcut
Definition: af_surround.c:94
surround_upmix
static void surround_upmix(AVFilterContext *ctx, int ch)
Definition: af_surround.c:609
MIN_MAG_SUM
#define MIN_MAG_SUM
Definition: af_surround.c:324
sqrtf
static __device__ float sqrtf(float a)
Definition: cuda_runtime.h:184
generate_window_func
static void generate_window_func(float *lut, int N, int win_func, float *overlap)
Definition: window_func.h:63
WFUNC_HANNING
@ WFUNC_HANNING
Definition: window_func.h:29
AudioSurroundContext::input_levels
float * input_levels
Definition: af_surround.c:87
AudioSurroundContext::f_x
float f_x[SC_NB]
Definition: af_surround.c:84
sinf
#define sinf(x)
Definition: libm.h:419
AudioSurroundContext::nb_in_channels
int nb_in_channels
Definition: af_surround.c:97
av_clipf
av_clipf
Definition: af_crystalizer.c:121
AV_OPT_TYPE_CHLAYOUT
@ AV_OPT_TYPE_CHLAYOUT
Definition: opt.h:252
ff_add_channel_layout
int ff_add_channel_layout(AVFilterChannelLayouts **l, const AVChannelLayout *channel_layout)
Definition: formats.c:522
ff_inlink_acknowledge_status
int ff_inlink_acknowledge_status(AVFilterLink *link, int *rstatus, int64_t *rpts)
Test and acknowledge the change of status on the link.
Definition: avfilter.c:1389
l2_1_upmix
static void l2_1_upmix(AVFilterContext *ctx, int ch)
Definition: af_surround.c:540
AV_CHAN_FRONT_RIGHT
@ AV_CHAN_FRONT_RIGHT
Definition: channel_layout.h:51
AV_CHAN_FRONT_CENTER
@ AV_CHAN_FRONT_CENTER
Definition: channel_layout.h:52
ch_map
static const int ch_map[SC_NB]
Definition: af_surround.c:38
do_transform
static void do_transform(AVFilterContext *ctx, int ch)
Definition: af_surround.c:445
f
f
Definition: af_crystalizer.c:121
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:94
powf
#define powf(x, y)
Definition: libm.h:50
AVChannelLayout
An AVChannelLayout holds information about the channel layout of audio data.
Definition: channel_layout.h:303
for
for(k=2;k<=8;++k)
Definition: h264pred_template.c:425
fmaxf
float fmaxf(float, float)
AV_CHAN_LOW_FREQUENCY
@ AV_CHAN_LOW_FREQUENCY
Definition: channel_layout.h:53
activate
static int activate(AVFilterContext *ctx)
Definition: af_surround.c:1318
AV_CHAN_BACK_RIGHT
@ AV_CHAN_BACK_RIGHT
Definition: channel_layout.h:55
angle_transform
static void angle_transform(float *x, float *y, float angle)
Definition: af_surround.c:326
AV_CHAN_SIDE_LEFT
@ AV_CHAN_SIDE_LEFT
Definition: channel_layout.h:59
AudioSurroundContext::create_lfe
int create_lfe
Definition: af_surround.c:90
M_PI_2f
#define M_PI_2f
Definition: mathematics.h:76
ff_filter_process_command
int ff_filter_process_command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
Generic processing of user supplied commands that are set in the same way as the filter options.
Definition: avfilter.c:887
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: af_surround.c:1290
AV_CH_LAYOUT_5POINT1_BACK
#define AV_CH_LAYOUT_5POINT1_BACK
Definition: channel_layout.h:217
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
FF_FILTER_FORWARD_WANTED
FF_FILTER_FORWARD_WANTED(outlink, inlink)
AV_CHANNEL_ORDER_NATIVE
@ AV_CHANNEL_ORDER_NATIVE
The native channel order, i.e.
Definition: channel_layout.h:118
SC_FR
@ SC_FR
Definition: af_surround.c:34
av_tx_uninit
av_cold void av_tx_uninit(AVTXContext **ctx)
Frees a context and sets *ctx to NULL, does nothing when *ctx == NULL.
Definition: tx.c:295
config_output
static int config_output(AVFilterLink *outlink)
Definition: af_surround.c:259
internal.h
AV_OPT_TYPE_FLOAT
@ AV_OPT_TYPE_FLOAT
Definition: opt.h:238
AV_CH_LAYOUT_5POINT0
#define AV_CH_LAYOUT_5POINT0
Definition: channel_layout.h:214
get_lfe
static void get_lfe(int output_lfe, int n, float lowcut, float highcut, float *lfe_mag, float c_mag, float *mag_total, int lfe_mode)
Definition: af_surround.c:374
av_assert2
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:67
AVFrame::nb_samples
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:454
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(surround)
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
M_PIf
#define M_PIf
Definition: mathematics.h:70
AV_CH_LAYOUT_2POINT1
#define AV_CH_LAYOUT_2POINT1
Definition: channel_layout.h:206
r_distance
static float r_distance(float a)
Definition: af_surround.c:319
AVFrame::extended_data
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: frame.h:435
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:31
filter_5_1_side
static void filter_5_1_side(AVFilterContext *ctx)
Definition: af_surround.c:971
ff_filter_get_nb_threads
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition: avfilter.c:827
AV_CH_LAYOUT_7POINT1
#define AV_CH_LAYOUT_7POINT1
Definition: channel_layout.h:227
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
AudioSurroundContext::sfactors
AVFrame * sfactors
Definition: af_surround.c:101
SC_NB
@ SC_NB
Definition: af_surround.c:35
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:39
filter_surround
static void filter_surround(AVFilterContext *ctx)
Definition: af_surround.c:856
ff_inlink_queued_samples
int ff_inlink_queued_samples(AVFilterLink *link)
Definition: avfilter.c:1417
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
AudioSurroundContext::win_size
int win_size
Definition: af_surround.c:76
sqrf
static float sqrf(float x)
Definition: af_surround.c:314
AVFilter
Filter definition.
Definition: avfilter.h:166
AudioSurroundContext::output
AVFrame * output
Definition: af_surround.c:104
AudioSurroundContext::rdft_size
int rdft_size
Definition: af_surround.c:121
ret
ret
Definition: filter_design.txt:187
AudioSurroundContext::angle
float angle
Definition: af_surround.c:74
AV_CH_LAYOUT_SURROUND
#define AV_CH_LAYOUT_SURROUND
Definition: channel_layout.h:208
config_input
static int config_input(AVFilterLink *inlink)
Definition: af_surround.c:215
AV_CHAN_BACK_CENTER
@ AV_CHAN_BACK_CENTER
Definition: channel_layout.h:58
AudioSurroundContext::win_func
int win_func
Definition: af_surround.c:77
AV_TX_FLOAT_RDFT
@ AV_TX_FLOAT_RDFT
Real to complex and complex to real DFTs.
Definition: tx.h:90
window_func.h
AudioSurroundContext::window_func_lut
float * window_func_lut
Definition: af_surround.c:125
ifft_channels
static int ifft_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: af_surround.c:1274
AudioSurroundContext::win_gain
float win_gain
Definition: af_surround.c:78
AudioSurroundContext::tx_fn
av_tx_fn tx_fn
Definition: af_surround.c:124
status
ov_status_e status
Definition: dnn_backend_openvino.c:121
channel_layout.h
av_channel_layout_index_from_channel
int av_channel_layout_index_from_channel(const AVChannelLayout *channel_layout, enum AVChannel channel)
Get the index of a given channel in a channel layout.
Definition: channel_layout.c:705
upmix_7_1_5_0_side
static void upmix_7_1_5_0_side(AVFilterContext *ctx, float c_re, float c_im, float mag_totall, float mag_totalr, float fl_phase, float fr_phase, float bl_phase, float br_phase, float sl_phase, float sr_phase, float xl, float yl, float xr, float yr, int n)
Definition: af_surround.c:628
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:235
AudioSurroundContext::in_ch_layout
AVChannelLayout in_ch_layout
Definition: af_surround.c:66
avfilter.h
AV_CHAN_BACK_LEFT
@ AV_CHAN_BACK_LEFT
Definition: channel_layout.h:54
fft_channels
static int fft_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: af_surround.c:1234
AudioSurroundContext::window
AVFrame * window
Definition: af_surround.c:109
AVFilterContext
An instance of a filter.
Definition: avfilter.h:407
factor
static const int factor[16]
Definition: vf_pp7.c:79
TFLAGS
#define TFLAGS
Definition: af_surround.c:1410
AVFILTER_FLAG_SLICE_THREADS
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
Definition: avfilter.h:117
mem.h
audio.h
AudioSurroundContext::lfe_mag
float * lfe_mag
Definition: af_surround.c:117
AudioSurroundContext::highcut
float highcut
Definition: af_surround.c:95
scale
static void scale(int *out, const int *in, const int w, const int h, const int shift)
Definition: intra.c:291
smooth
static float smooth(DeshakeOpenCLContext *deshake_ctx, float *gauss_kernel, int length, float max_val, AVFifo *values)
Definition: vf_deshake_opencl.c:888
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:251
SC_SL
@ SC_SL
Definition: af_surround.c:34
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: internal.h:183
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
SC_SR
@ SC_SR
Definition: af_surround.c:34
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
AudioSurroundContext::lfe_phase
float * lfe_phase
Definition: af_surround.c:118
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:474
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
init
static av_cold int init(AVFilterContext *ctx)
Definition: af_surround.c:1105
AV_CHAN_FRONT_LEFT
@ AV_CHAN_FRONT_LEFT
Definition: channel_layout.h:50
AudioSurroundContext::itx_fn
av_tx_fn itx_fn
Definition: af_surround.c:124
AudioSurroundContext::rdft
AVTXContext ** rdft
Definition: af_surround.c:123
ff_filter_execute
static av_always_inline int ff_filter_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg, int *ret, int nb_jobs)
Definition: internal.h:134
AudioSurroundContext::l_phase
float * l_phase
Definition: af_surround.c:113
TRANSFORM
#define TRANSFORM
Definition: af_surround.c:387
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:244
stereo_position
static void stereo_position(float a, float p, float *x, float *y)
Definition: af_surround.c:366
filter_2_1
static void filter_2_1(AVFilterContext *ctx)
Definition: af_surround.c:799
AudioSurroundContext::all_x
float all_x
Definition: af_surround.c:81
ff_filter_set_ready
void ff_filter_set_ready(AVFilterContext *filter, unsigned priority)
Mark a filter ready and schedule it for activation.
Definition: avfilter.c:235
set_input_levels
static void set_input_levels(AVFilterContext *ctx)
Definition: af_surround.c:185
tx.h
inputs
static const AVFilterPad inputs[]
Definition: af_surround.c:1470
AudioSurroundContext::smooth
float smooth
Definition: af_surround.c:73
AudioSurroundContext::f_y
float f_y[SC_NB]
Definition: af_surround.c:85