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