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 overlap;
78 
79  float all_x;
80  float all_y;
81 
82  float f_x[SC_NB];
83  float f_y[SC_NB];
84 
85  float *input_levels;
86  float *output_levels;
89  int lowcutf;
90  int highcutf;
91 
92  float lowcut;
93  float highcut;
94 
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_PI / 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_4)
340  a *= reference / M_PI_2;
341  else
342  a = M_PI + (-2.f * M_PI + reference) * (M_PI - fabsf(a)) * FFDIFFSIGN(a, 0.f) / (3.f * M_PI_2);
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_PI);
370  *x = av_clipf(a+a*fmaxf(0.f, p*p-M_PI_2), -1.f, 1.f);
371  *y = av_clipf(cosf(a*M_PI_2+M_PI)*cosf(M_PI_2-p/M_PI)*M_LN10+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_PI*(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 - fabs(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.5;
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 lfe_mode = s->lfe_mode;
751  const float highcut = s->highcut;
752  const float lowcut = s->lowcut;
753  const float angle = s->angle;
754  const float focus = s->focus;
755  float *magtotal = s->mag_total;
756  float *lfemag = s->lfe_mag;
757  float *lphase = s->l_phase;
758  float *rphase = s->r_phase;
759  float *cphase = s->c_phase;
760  float *cmag = s->c_mag;
761  float *xpos = s->x_pos;
762  float *ypos = s->y_pos;
763 
764  for (int n = 0; n < s->rdft_size; n++) {
765  float l_re = srcl[2 * n], r_re = srcr[2 * n];
766  float l_im = srcl[2 * n + 1], r_im = srcr[2 * n + 1];
767  float c_phase = atan2f(l_im + r_im, l_re + r_re);
768  float l_mag = hypotf(l_re, l_im);
769  float r_mag = hypotf(r_re, r_im);
770  float mag_total = hypotf(l_mag, r_mag);
771  float l_phase = atan2f(l_im, l_re);
772  float r_phase = atan2f(r_im, r_re);
773  float phase_dif = fabsf(l_phase - r_phase);
774  float mag_sum = l_mag + r_mag;
775  float c_mag = mag_sum * 0.5f;
776  float mag_dif, x, y;
777 
778  mag_sum = mag_sum < MIN_MAG_SUM ? 1.f : mag_sum;
779  mag_dif = (l_mag - r_mag) / mag_sum;
780  if (phase_dif > M_PI)
781  phase_dif = 2.f * M_PI - phase_dif;
782 
783  stereo_position(mag_dif, phase_dif, &x, &y);
784  angle_transform(&x, &y, angle);
785  focus_transform(&x, &y, focus);
786  get_lfe(output_lfe, n, lowcut, highcut, &lfemag[n], c_mag, &mag_total, lfe_mode);
787 
788  xpos[n] = x;
789  ypos[n] = y;
790  lphase[n] = l_phase;
791  rphase[n] = r_phase;
792  cmag[n] = c_mag;
793  cphase[n] = c_phase;
794  magtotal[n] = mag_total;
795  }
796 }
797 
799 {
800  AudioSurroundContext *s = ctx->priv;
801  const float *srcl = (const float *)s->input->extended_data[0];
802  const float *srcr = (const float *)s->input->extended_data[1];
803  const float *srclfe = (const float *)s->input->extended_data[2];
804  const float angle = s->angle;
805  const float focus = s->focus;
806  float *magtotal = s->mag_total;
807  float *lfephase = s->lfe_phase;
808  float *lfemag = s->lfe_mag;
809  float *lphase = s->l_phase;
810  float *rphase = s->r_phase;
811  float *cphase = s->c_phase;
812  float *cmag = s->c_mag;
813  float *xpos = s->x_pos;
814  float *ypos = s->y_pos;
815 
816  for (int n = 0; n < s->rdft_size; n++) {
817  float l_re = srcl[2 * n], r_re = srcr[2 * n];
818  float l_im = srcl[2 * n + 1], r_im = srcr[2 * n + 1];
819  float lfe_re = srclfe[2 * n], lfe_im = srclfe[2 * n + 1];
820  float c_phase = atan2f(l_im + r_im, l_re + r_re);
821  float l_mag = hypotf(l_re, l_im);
822  float r_mag = hypotf(r_re, r_im);
823  float lfe_mag = hypotf(lfe_re, lfe_im);
824  float lfe_phase = atan2f(lfe_im, lfe_re);
825  float mag_total = hypotf(l_mag, r_mag);
826  float l_phase = atan2f(l_im, l_re);
827  float r_phase = atan2f(r_im, r_re);
828  float phase_dif = fabsf(l_phase - r_phase);
829  float mag_sum = l_mag + r_mag;
830  float c_mag = mag_sum * 0.5f;
831  float mag_dif, x, y;
832 
833  mag_sum = mag_sum < MIN_MAG_SUM ? 1.f : mag_sum;
834  mag_dif = (l_mag - r_mag) / mag_sum;
835  if (phase_dif > M_PI)
836  phase_dif = 2.f * M_PI - phase_dif;
837 
838  stereo_position(mag_dif, phase_dif, &x, &y);
839  angle_transform(&x, &y, angle);
840  focus_transform(&x, &y, focus);
841 
842  xpos[n] = x;
843  ypos[n] = y;
844  lphase[n] = l_phase;
845  rphase[n] = r_phase;
846  cmag[n] = c_mag;
847  cphase[n] = c_phase;
848  lfemag[n] = lfe_mag;
849  lfephase[n] = lfe_phase;
850  magtotal[n] = mag_total;
851  }
852 }
853 
855 {
856  AudioSurroundContext *s = ctx->priv;
857  const float *srcl = (const float *)s->input->extended_data[0];
858  const float *srcr = (const float *)s->input->extended_data[1];
859  const float *srcc = (const float *)s->input->extended_data[2];
860  const int output_lfe = s->output_lfe && s->create_lfe;
861  const int lfe_mode = s->lfe_mode;
862  const float highcut = s->highcut;
863  const float lowcut = s->lowcut;
864  const float angle = s->angle;
865  const float focus = s->focus;
866  float *magtotal = s->mag_total;
867  float *lfemag = s->lfe_mag;
868  float *lphase = s->l_phase;
869  float *rphase = s->r_phase;
870  float *cphase = s->c_phase;
871  float *cmag = s->c_mag;
872  float *xpos = s->x_pos;
873  float *ypos = s->y_pos;
874 
875  for (int n = 0; n < s->rdft_size; n++) {
876  float l_re = srcl[2 * n], r_re = srcr[2 * n];
877  float l_im = srcl[2 * n + 1], r_im = srcr[2 * n + 1];
878  float c_re = srcc[2 * n], c_im = srcc[2 * n + 1];
879  float c_phase = atan2f(c_im, c_re);
880  float c_mag = hypotf(c_re, c_im);
881  float l_mag = hypotf(l_re, l_im);
882  float r_mag = hypotf(r_re, r_im);
883  float mag_total = hypotf(l_mag, r_mag);
884  float l_phase = atan2f(l_im, l_re);
885  float r_phase = atan2f(r_im, r_re);
886  float phase_dif = fabsf(l_phase - r_phase);
887  float mag_sum = l_mag + r_mag;
888  float mag_dif, x, y;
889 
890  mag_sum = mag_sum < MIN_MAG_SUM ? 1.f : mag_sum;
891  mag_dif = (l_mag - r_mag) / mag_sum;
892  if (phase_dif > M_PI)
893  phase_dif = 2.f * M_PI - phase_dif;
894 
895  stereo_position(mag_dif, phase_dif, &x, &y);
896  angle_transform(&x, &y, angle);
897  focus_transform(&x, &y, focus);
898  get_lfe(output_lfe, n, lowcut, highcut, &lfemag[n], c_mag, &mag_total, lfe_mode);
899 
900  xpos[n] = x;
901  ypos[n] = y;
902  lphase[n] = l_phase;
903  rphase[n] = r_phase;
904  cmag[n] = c_mag;
905  cphase[n] = c_phase;
906  magtotal[n] = mag_total;
907  }
908 }
909 
911 {
912  AudioSurroundContext *s = ctx->priv;
913  float *srcl, *srcr, *srcc, *srcsl, *srcsr;
914  int n;
915 
916  srcl = (float *)s->input->extended_data[0];
917  srcr = (float *)s->input->extended_data[1];
918  srcc = (float *)s->input->extended_data[2];
919  srcsl = (float *)s->input->extended_data[3];
920  srcsr = (float *)s->input->extended_data[4];
921 
922  for (n = 0; n < s->rdft_size; n++) {
923  float fl_re = srcl[2 * n], fr_re = srcr[2 * n];
924  float fl_im = srcl[2 * n + 1], fr_im = srcr[2 * n + 1];
925  float c_re = srcc[2 * n], c_im = srcc[2 * n + 1];
926  float sl_re = srcsl[2 * n], sl_im = srcsl[2 * n + 1];
927  float sr_re = srcsr[2 * n], sr_im = srcsr[2 * n + 1];
928  float fl_mag = hypotf(fl_re, fl_im);
929  float fr_mag = hypotf(fr_re, fr_im);
930  float fl_phase = atan2f(fl_im, fl_re);
931  float fr_phase = atan2f(fr_im, fr_re);
932  float sl_mag = hypotf(sl_re, sl_im);
933  float sr_mag = hypotf(sr_re, sr_im);
934  float sl_phase = atan2f(sl_im, sl_re);
935  float sr_phase = atan2f(sr_im, sr_re);
936  float phase_difl = fabsf(fl_phase - sl_phase);
937  float phase_difr = fabsf(fr_phase - sr_phase);
938  float magl_sum = fl_mag + sl_mag;
939  float magr_sum = fr_mag + sr_mag;
940  float mag_difl = magl_sum < MIN_MAG_SUM ? FFDIFFSIGN(fl_mag, sl_mag) : (fl_mag - sl_mag) / magl_sum;
941  float mag_difr = magr_sum < MIN_MAG_SUM ? FFDIFFSIGN(fr_mag, sr_mag) : (fr_mag - sr_mag) / magr_sum;
942  float mag_totall = hypotf(fl_mag, sl_mag);
943  float mag_totalr = hypotf(fr_mag, sr_mag);
944  float bl_phase = atan2f(fl_im + sl_im, fl_re + sl_re);
945  float br_phase = atan2f(fr_im + sr_im, fr_re + sr_re);
946  float xl, yl;
947  float xr, yr;
948 
949  if (phase_difl > M_PI)
950  phase_difl = 2.f * M_PI - phase_difl;
951 
952  if (phase_difr > M_PI)
953  phase_difr = 2.f * M_PI - phase_difr;
954 
955  stereo_position(mag_difl, phase_difl, &xl, &yl);
956  stereo_position(mag_difr, phase_difr, &xr, &yr);
957 
958  s->upmix_5_0(ctx, c_re, c_im,
959  mag_totall, mag_totalr,
960  fl_phase, fr_phase,
961  bl_phase, br_phase,
962  sl_phase, sr_phase,
963  xl, yl, xr, yr, n);
964  }
965 }
966 
968 {
969  AudioSurroundContext *s = ctx->priv;
970  float *srcl, *srcr, *srcc, *srclfe, *srcsl, *srcsr;
971  int n;
972 
973  srcl = (float *)s->input->extended_data[0];
974  srcr = (float *)s->input->extended_data[1];
975  srcc = (float *)s->input->extended_data[2];
976  srclfe = (float *)s->input->extended_data[3];
977  srcsl = (float *)s->input->extended_data[4];
978  srcsr = (float *)s->input->extended_data[5];
979 
980  for (n = 0; n < s->rdft_size; n++) {
981  float fl_re = srcl[2 * n], fr_re = srcr[2 * n];
982  float fl_im = srcl[2 * n + 1], fr_im = srcr[2 * n + 1];
983  float c_re = srcc[2 * n], c_im = srcc[2 * n + 1];
984  float lfe_re = srclfe[2 * n], lfe_im = srclfe[2 * n + 1];
985  float sl_re = srcsl[2 * n], sl_im = srcsl[2 * n + 1];
986  float sr_re = srcsr[2 * n], sr_im = srcsr[2 * n + 1];
987  float fl_mag = hypotf(fl_re, fl_im);
988  float fr_mag = hypotf(fr_re, fr_im);
989  float fl_phase = atan2f(fl_im, fl_re);
990  float fr_phase = atan2f(fr_im, fr_re);
991  float sl_mag = hypotf(sl_re, sl_im);
992  float sr_mag = hypotf(sr_re, sr_im);
993  float sl_phase = atan2f(sl_im, sl_re);
994  float sr_phase = atan2f(sr_im, sr_re);
995  float phase_difl = fabsf(fl_phase - sl_phase);
996  float phase_difr = fabsf(fr_phase - sr_phase);
997  float magl_sum = fl_mag + sl_mag;
998  float magr_sum = fr_mag + sr_mag;
999  float mag_difl = magl_sum < MIN_MAG_SUM ? FFDIFFSIGN(fl_mag, sl_mag) : (fl_mag - sl_mag) / magl_sum;
1000  float mag_difr = magr_sum < MIN_MAG_SUM ? FFDIFFSIGN(fr_mag, sr_mag) : (fr_mag - sr_mag) / magr_sum;
1001  float mag_totall = hypotf(fl_mag, sl_mag);
1002  float mag_totalr = hypotf(fr_mag, sr_mag);
1003  float bl_phase = atan2f(fl_im + sl_im, fl_re + sl_re);
1004  float br_phase = atan2f(fr_im + sr_im, fr_re + sr_re);
1005  float xl, yl;
1006  float xr, yr;
1007 
1008  if (phase_difl > M_PI)
1009  phase_difl = 2.f * M_PI - phase_difl;
1010 
1011  if (phase_difr > M_PI)
1012  phase_difr = 2.f * M_PI - phase_difr;
1013 
1014  stereo_position(mag_difl, phase_difl, &xl, &yl);
1015  stereo_position(mag_difr, phase_difr, &xr, &yr);
1016 
1017  s->upmix_5_1(ctx, c_re, c_im, lfe_re, lfe_im,
1018  mag_totall, mag_totalr,
1019  fl_phase, fr_phase,
1020  bl_phase, br_phase,
1021  sl_phase, sr_phase,
1022  xl, yl, xr, yr, n);
1023  }
1024 }
1025 
1027 {
1028  AudioSurroundContext *s = ctx->priv;
1029  float *srcl, *srcr, *srcc, *srclfe, *srcbl, *srcbr;
1030  int n;
1031 
1032  srcl = (float *)s->input->extended_data[0];
1033  srcr = (float *)s->input->extended_data[1];
1034  srcc = (float *)s->input->extended_data[2];
1035  srclfe = (float *)s->input->extended_data[3];
1036  srcbl = (float *)s->input->extended_data[4];
1037  srcbr = (float *)s->input->extended_data[5];
1038 
1039  for (n = 0; n < s->rdft_size; n++) {
1040  float fl_re = srcl[2 * n], fr_re = srcr[2 * n];
1041  float fl_im = srcl[2 * n + 1], fr_im = srcr[2 * n + 1];
1042  float c_re = srcc[2 * n], c_im = srcc[2 * n + 1];
1043  float lfe_re = srclfe[2 * n], lfe_im = srclfe[2 * n + 1];
1044  float bl_re = srcbl[2 * n], bl_im = srcbl[2 * n + 1];
1045  float br_re = srcbr[2 * n], br_im = srcbr[2 * n + 1];
1046  float fl_mag = hypotf(fl_re, fl_im);
1047  float fr_mag = hypotf(fr_re, fr_im);
1048  float fl_phase = atan2f(fl_im, fl_re);
1049  float fr_phase = atan2f(fr_im, fr_re);
1050  float bl_mag = hypotf(bl_re, bl_im);
1051  float br_mag = hypotf(br_re, br_im);
1052  float bl_phase = atan2f(bl_im, bl_re);
1053  float br_phase = atan2f(br_im, br_re);
1054  float phase_difl = fabsf(fl_phase - bl_phase);
1055  float phase_difr = fabsf(fr_phase - br_phase);
1056  float magl_sum = fl_mag + bl_mag;
1057  float magr_sum = fr_mag + br_mag;
1058  float mag_difl = magl_sum < MIN_MAG_SUM ? FFDIFFSIGN(fl_mag, bl_mag) : (fl_mag - bl_mag) / magl_sum;
1059  float mag_difr = magr_sum < MIN_MAG_SUM ? FFDIFFSIGN(fr_mag, br_mag) : (fr_mag - br_mag) / magr_sum;
1060  float mag_totall = hypotf(fl_mag, bl_mag);
1061  float mag_totalr = hypotf(fr_mag, br_mag);
1062  float sl_phase = atan2f(fl_im + bl_im, fl_re + bl_re);
1063  float sr_phase = atan2f(fr_im + br_im, fr_re + br_re);
1064  float xl, yl;
1065  float xr, yr;
1066 
1067  if (phase_difl > M_PI)
1068  phase_difl = 2.f * M_PI - phase_difl;
1069 
1070  if (phase_difr > M_PI)
1071  phase_difr = 2.f * M_PI - phase_difr;
1072 
1073  stereo_position(mag_difl, phase_difl, &xl, &yl);
1074  stereo_position(mag_difr, phase_difr, &xr, &yr);
1075 
1076  s->upmix_5_1(ctx, c_re, c_im, lfe_re, lfe_im,
1077  mag_totall, mag_totalr,
1078  fl_phase, fr_phase,
1079  bl_phase, br_phase,
1080  sl_phase, sr_phase,
1081  xl, yl, xr, yr, n);
1082  }
1083 }
1084 
1086 {
1087  AudioSurroundContext *s = ctx->priv;
1088 
1089  if (s->all_x >= 0.f)
1090  for (int n = 0; n < SC_NB; n++)
1091  s->f_x[n] = s->all_x;
1092  s->all_x = -1.f;
1093  if (s->all_y >= 0.f)
1094  for (int n = 0; n < SC_NB; n++)
1095  s->f_y[n] = s->all_y;
1096  s->all_y = -1.f;
1097 }
1098 
1100 {
1101  AudioSurroundContext *s = ctx->priv;
1102  int64_t in_channel_layout, out_channel_layout;
1103  float overlap;
1104  int ret;
1105 
1106  if ((ret = av_channel_layout_from_string(&s->out_ch_layout, s->out_channel_layout_str)) < 0) {
1107  av_log(ctx, AV_LOG_ERROR, "Error parsing output channel layout '%s'.\n",
1108  s->out_channel_layout_str);
1109  return ret;
1110  }
1111 
1112  if ((ret = av_channel_layout_from_string(&s->in_ch_layout, s->in_channel_layout_str)) < 0) {
1113  av_log(ctx, AV_LOG_ERROR, "Error parsing input channel layout '%s'.\n",
1114  s->in_channel_layout_str);
1115  return AVERROR(EINVAL);
1116  }
1117 
1118  if (s->lowcutf >= s->highcutf) {
1119  av_log(ctx, AV_LOG_ERROR, "Low cut-off '%d' should be less than high cut-off '%d'.\n",
1120  s->lowcutf, s->highcutf);
1121  return AVERROR(EINVAL);
1122  }
1123 
1124  in_channel_layout = s->in_ch_layout.order == AV_CHANNEL_ORDER_NATIVE ?
1125  s->in_ch_layout.u.mask : 0;
1126  out_channel_layout = s->out_ch_layout.order == AV_CHANNEL_ORDER_NATIVE ?
1127  s->out_ch_layout.u.mask : 0;
1128 
1129  s->create_lfe = av_channel_layout_index_from_channel(&s->out_ch_layout,
1130  AV_CHAN_LOW_FREQUENCY) >= 0;
1131 
1132  switch (in_channel_layout) {
1133  case AV_CH_LAYOUT_STEREO:
1134  s->filter = filter_stereo;
1135  s->upmix = stereo_upmix;
1136  break;
1137  case AV_CH_LAYOUT_2POINT1:
1138  s->filter = filter_2_1;
1139  s->upmix = l2_1_upmix;
1140  break;
1141  case AV_CH_LAYOUT_SURROUND:
1142  s->filter = filter_surround;
1143  s->upmix = surround_upmix;
1144  break;
1145  case AV_CH_LAYOUT_5POINT0:
1146  s->filter = filter_5_0_side;
1147  switch (out_channel_layout) {
1148  case AV_CH_LAYOUT_7POINT1:
1149  s->upmix_5_0 = upmix_7_1_5_0_side;
1150  break;
1151  default:
1152  goto fail;
1153  }
1154  break;
1155  case AV_CH_LAYOUT_5POINT1:
1156  s->filter = filter_5_1_side;
1157  switch (out_channel_layout) {
1158  case AV_CH_LAYOUT_7POINT1:
1159  s->upmix_5_1 = upmix_7_1_5_1;
1160  break;
1161  default:
1162  goto fail;
1163  }
1164  break;
1166  s->filter = filter_5_1_back;
1167  switch (out_channel_layout) {
1168  case AV_CH_LAYOUT_7POINT1:
1169  s->upmix_5_1 = upmix_7_1_5_1;
1170  break;
1171  default:
1172  goto fail;
1173  }
1174  break;
1175  default:
1176 fail:
1177  av_log(ctx, AV_LOG_ERROR, "Unsupported upmix: '%s' -> '%s'.\n",
1178  s->in_channel_layout_str, s->out_channel_layout_str);
1179  return AVERROR(EINVAL);
1180  }
1181 
1182  s->window_func_lut = av_calloc(s->win_size, sizeof(*s->window_func_lut));
1183  if (!s->window_func_lut)
1184  return AVERROR(ENOMEM);
1185 
1186  generate_window_func(s->window_func_lut, s->win_size, s->win_func, &overlap);
1187  if (s->overlap == 1)
1188  s->overlap = overlap;
1189 
1190  for (int i = 0; i < s->win_size; i++)
1191  s->window_func_lut[i] = sqrtf(s->window_func_lut[i] / s->win_size);
1192  s->hop_size = FFMAX(1, s->win_size * (1. - s->overlap));
1193 
1195 
1196  return 0;
1197 }
1198 
1199 static int fft_channel(AVFilterContext *ctx, AVFrame *in, int ch)
1200 {
1201  AudioSurroundContext *s = ctx->priv;
1202  float *src = (float *)s->input_in->extended_data[ch];
1203  float *win = (float *)s->window->extended_data[ch];
1204  const int offset = s->win_size - s->hop_size;
1205  const float level_in = s->input_levels[ch];
1206 
1207  memmove(src, &src[s->hop_size], offset * sizeof(float));
1208  memcpy(&src[offset], in->extended_data[ch], in->nb_samples * sizeof(float));
1209  memset(&src[offset + in->nb_samples], 0, (s->hop_size - in->nb_samples) * sizeof(float));
1210 
1211  for (int n = 0; n < s->win_size; n++)
1212  win[n] = src[n] * s->window_func_lut[n] * level_in;
1213 
1214  s->tx_fn(s->rdft[ch], (float *)s->input->extended_data[ch], win, sizeof(float));
1215 
1216  return 0;
1217 }
1218 
1219 static int fft_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
1220 {
1221  AVFrame *in = arg;
1222  const int start = (in->ch_layout.nb_channels * jobnr) / nb_jobs;
1223  const int end = (in->ch_layout.nb_channels * (jobnr+1)) / nb_jobs;
1224 
1225  for (int ch = start; ch < end; ch++)
1226  fft_channel(ctx, in, ch);
1227 
1228  return 0;
1229 }
1230 
1232 {
1233  AudioSurroundContext *s = ctx->priv;
1234  const float level_out = s->output_levels[ch];
1235  float *dst, *ptr;
1236 
1237  dst = (float *)s->output_out->extended_data[ch];
1238  ptr = (float *)s->overlap_buffer->extended_data[ch];
1239  s->itx_fn(s->irdft[ch], dst, (float *)s->output->extended_data[ch], sizeof(AVComplexFloat));
1240 
1241  memmove(s->overlap_buffer->extended_data[ch],
1242  s->overlap_buffer->extended_data[ch] + s->hop_size * sizeof(float),
1243  s->win_size * sizeof(float));
1244  memset(s->overlap_buffer->extended_data[ch] + s->win_size * sizeof(float),
1245  0, s->hop_size * sizeof(float));
1246 
1247  for (int n = 0; n < s->win_size; n++)
1248  ptr[n] += dst[n] * s->window_func_lut[n] * level_out;
1249 
1250  ptr = (float *)s->overlap_buffer->extended_data[ch];
1251  dst = (float *)out->extended_data[ch];
1252  memcpy(dst, ptr, s->hop_size * sizeof(float));
1253 
1254  return 0;
1255 }
1256 
1257 static int ifft_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
1258 {
1259  AudioSurroundContext *s = ctx->priv;
1260  AVFrame *out = arg;
1261  const int start = (out->ch_layout.nb_channels * jobnr) / nb_jobs;
1262  const int end = (out->ch_layout.nb_channels * (jobnr+1)) / nb_jobs;
1263 
1264  for (int ch = start; ch < end; ch++) {
1265  if (s->upmix)
1266  s->upmix(ctx, ch);
1267  ifft_channel(ctx, out, ch);
1268  }
1269 
1270  return 0;
1271 }
1272 
1274 {
1275  AVFilterContext *ctx = inlink->dst;
1276  AVFilterLink *outlink = ctx->outputs[0];
1277  AudioSurroundContext *s = ctx->priv;
1278  AVFrame *out;
1279 
1281  FFMIN(inlink->ch_layout.nb_channels,
1283 
1284  s->filter(ctx);
1285 
1286  out = ff_get_audio_buffer(outlink, s->hop_size);
1287  if (!out)
1288  return AVERROR(ENOMEM);
1289 
1291  FFMIN(outlink->ch_layout.nb_channels,
1293 
1294  av_frame_copy_props(out, in);
1295  out->nb_samples = in->nb_samples;
1296 
1297  av_frame_free(&in);
1298  return ff_filter_frame(outlink, out);
1299 }
1300 
1302 {
1303  AVFilterLink *inlink = ctx->inputs[0];
1304  AVFilterLink *outlink = ctx->outputs[0];
1305  AudioSurroundContext *s = ctx->priv;
1306  AVFrame *in = NULL;
1307  int ret = 0, status;
1308  int64_t pts;
1309 
1311 
1312  ret = ff_inlink_consume_samples(inlink, s->hop_size, s->hop_size, &in);
1313  if (ret < 0)
1314  return ret;
1315 
1316  if (ret > 0)
1317  ret = filter_frame(inlink, in);
1318  if (ret < 0)
1319  return ret;
1320 
1321  if (ff_inlink_queued_samples(inlink) >= s->hop_size) {
1322  ff_filter_set_ready(ctx, 10);
1323  return 0;
1324  }
1325 
1327  ff_outlink_set_status(outlink, status, pts);
1328  return 0;
1329  }
1330 
1331  FF_FILTER_FORWARD_WANTED(outlink, inlink);
1332 
1333  return FFERROR_NOT_READY;
1334 }
1335 
1337 {
1338  AudioSurroundContext *s = ctx->priv;
1339 
1340  av_frame_free(&s->factors);
1341  av_frame_free(&s->sfactors);
1342  av_frame_free(&s->window);
1343  av_frame_free(&s->input_in);
1344  av_frame_free(&s->input);
1345  av_frame_free(&s->output);
1346  av_frame_free(&s->output_ph);
1347  av_frame_free(&s->output_mag);
1348  av_frame_free(&s->output_out);
1349  av_frame_free(&s->overlap_buffer);
1350 
1351  for (int ch = 0; ch < s->nb_in_channels; ch++)
1352  av_tx_uninit(&s->rdft[ch]);
1353  for (int ch = 0; ch < s->nb_out_channels; ch++)
1354  av_tx_uninit(&s->irdft[ch]);
1355  av_freep(&s->input_levels);
1356  av_freep(&s->output_levels);
1357  av_freep(&s->rdft);
1358  av_freep(&s->irdft);
1359  av_freep(&s->window_func_lut);
1360 
1361  av_freep(&s->x_pos);
1362  av_freep(&s->y_pos);
1363  av_freep(&s->l_phase);
1364  av_freep(&s->r_phase);
1365  av_freep(&s->c_mag);
1366  av_freep(&s->c_phase);
1367  av_freep(&s->mag_total);
1368  av_freep(&s->lfe_mag);
1369  av_freep(&s->lfe_phase);
1370 }
1371 
1372 static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
1373  char *res, int res_len, int flags)
1374 {
1375  AudioSurroundContext *s = ctx->priv;
1376  int ret;
1377 
1378  ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags);
1379  if (ret < 0)
1380  return ret;
1381 
1382  s->hop_size = FFMAX(1, s->win_size * (1. - s->overlap));
1383 
1387 
1388  return 0;
1389 }
1390 
1391 #define OFFSET(x) offsetof(AudioSurroundContext, x)
1392 #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
1393 #define TFLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
1394 
1395 static const AVOption surround_options[] = {
1396  { "chl_out", "set output channel layout", OFFSET(out_channel_layout_str), AV_OPT_TYPE_STRING, {.str="5.1"}, 0, 0, FLAGS },
1397  { "chl_in", "set input channel layout", OFFSET(in_channel_layout_str), AV_OPT_TYPE_STRING, {.str="stereo"},0, 0, FLAGS },
1398  { "level_in", "set input level", OFFSET(level_in), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },
1399  { "level_out", "set output level", OFFSET(level_out), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },
1400  { "lfe", "output LFE", OFFSET(output_lfe), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, TFLAGS },
1401  { "lfe_low", "LFE low cut off", OFFSET(lowcutf), AV_OPT_TYPE_INT, {.i64=128}, 0, 256, FLAGS },
1402  { "lfe_high", "LFE high cut off", OFFSET(highcutf), AV_OPT_TYPE_INT, {.i64=256}, 0, 512, FLAGS },
1403  { "lfe_mode", "set LFE channel mode", OFFSET(lfe_mode), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, TFLAGS, "lfe_mode" },
1404  { "add", "just add LFE channel", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 1, TFLAGS, "lfe_mode" },
1405  { "sub", "substract LFE channel with others", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 1, TFLAGS, "lfe_mode" },
1406  { "smooth", "set temporal smoothness strength", OFFSET(smooth), AV_OPT_TYPE_FLOAT, {.dbl=0}, 0, 1, TFLAGS },
1407  { "angle", "set soundfield transform angle", OFFSET(angle), AV_OPT_TYPE_FLOAT, {.dbl=90}, 0, 360, TFLAGS },
1408  { "focus", "set soundfield transform focus", OFFSET(focus), AV_OPT_TYPE_FLOAT, {.dbl=0}, -1, 1, TFLAGS },
1409  { "fc_in", "set front center channel input level", OFFSET(f_i[SC_FC]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },
1410  { "fc_out", "set front center channel output level", OFFSET(f_o[SC_FC]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },
1411  { "fl_in", "set front left channel input level", OFFSET(f_i[SC_FL]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },
1412  { "fl_out", "set front left channel output level", OFFSET(f_o[SC_FL]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },
1413  { "fr_in", "set front right channel input level", OFFSET(f_i[SC_FR]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },
1414  { "fr_out", "set front right channel output level", OFFSET(f_o[SC_FR]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },
1415  { "sl_in", "set side left channel input level", OFFSET(f_i[SC_SL]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },
1416  { "sl_out", "set side left channel output level", OFFSET(f_o[SC_SL]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },
1417  { "sr_in", "set side right channel input level", OFFSET(f_i[SC_SR]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },
1418  { "sr_out", "set side right channel output level", OFFSET(f_o[SC_SR]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },
1419  { "bl_in", "set back left channel input level", OFFSET(f_i[SC_BL]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },
1420  { "bl_out", "set back left channel output level", OFFSET(f_o[SC_BL]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },
1421  { "br_in", "set back right channel input level", OFFSET(f_i[SC_BR]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },
1422  { "br_out", "set back right channel output level", OFFSET(f_o[SC_BR]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },
1423  { "bc_in", "set back center channel input level", OFFSET(f_i[SC_BC]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },
1424  { "bc_out", "set back center channel output level", OFFSET(f_o[SC_BC]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },
1425  { "lfe_in", "set lfe channel input level", OFFSET(f_i[SC_LF]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },
1426  { "lfe_out", "set lfe channel output level", OFFSET(f_o[SC_LF]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, TFLAGS },
1427  { "allx", "set all channel's x spread", OFFSET(all_x), AV_OPT_TYPE_FLOAT, {.dbl=-1}, -1, 15, TFLAGS },
1428  { "ally", "set all channel's y spread", OFFSET(all_y), AV_OPT_TYPE_FLOAT, {.dbl=-1}, -1, 15, TFLAGS },
1429  { "fcx", "set front center channel x spread", OFFSET(f_x[SC_FC]), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, .06, 15, TFLAGS },
1430  { "flx", "set front left channel x spread", OFFSET(f_x[SC_FL]), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, .06, 15, TFLAGS },
1431  { "frx", "set front right channel x spread", OFFSET(f_x[SC_FR]), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, .06, 15, TFLAGS },
1432  { "blx", "set back left channel x spread", OFFSET(f_x[SC_BL]), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, .06, 15, TFLAGS },
1433  { "brx", "set back right channel x spread", OFFSET(f_x[SC_BR]), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, .06, 15, TFLAGS },
1434  { "slx", "set side left channel x spread", OFFSET(f_x[SC_SL]), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, .06, 15, TFLAGS },
1435  { "srx", "set side right channel x spread", OFFSET(f_x[SC_SR]), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, .06, 15, TFLAGS },
1436  { "bcx", "set back center channel x spread", OFFSET(f_x[SC_BC]), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, .06, 15, TFLAGS },
1437  { "fcy", "set front center channel y spread", OFFSET(f_y[SC_FC]), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, .06, 15, TFLAGS },
1438  { "fly", "set front left channel y spread", OFFSET(f_y[SC_FL]), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, .06, 15, TFLAGS },
1439  { "fry", "set front right channel y spread", OFFSET(f_y[SC_FR]), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, .06, 15, TFLAGS },
1440  { "bly", "set back left channel y spread", OFFSET(f_y[SC_BL]), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, .06, 15, TFLAGS },
1441  { "bry", "set back right channel y spread", OFFSET(f_y[SC_BR]), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, .06, 15, TFLAGS },
1442  { "sly", "set side left channel y spread", OFFSET(f_y[SC_SL]), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, .06, 15, TFLAGS },
1443  { "sry", "set side right channel y spread", OFFSET(f_y[SC_SR]), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, .06, 15, TFLAGS },
1444  { "bcy", "set back center channel y spread", OFFSET(f_y[SC_BC]), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, .06, 15, TFLAGS },
1445  { "win_size", "set window size", OFFSET(win_size), AV_OPT_TYPE_INT, {.i64=4096},1024,65536,FLAGS },
1446  WIN_FUNC_OPTION("win_func", OFFSET(win_func), FLAGS, WFUNC_HANNING),
1447  { "overlap", "set window overlap", OFFSET(overlap), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, TFLAGS },
1448  { NULL }
1449 };
1450 
1451 AVFILTER_DEFINE_CLASS(surround);
1452 
1453 static const AVFilterPad inputs[] = {
1454  {
1455  .name = "default",
1456  .type = AVMEDIA_TYPE_AUDIO,
1457  .config_props = config_input,
1458  },
1459 };
1460 
1461 static const AVFilterPad outputs[] = {
1462  {
1463  .name = "default",
1464  .type = AVMEDIA_TYPE_AUDIO,
1465  .config_props = config_output,
1466  },
1467 };
1468 
1470  .name = "surround",
1471  .description = NULL_IF_CONFIG_SMALL("Apply audio surround upmix filter."),
1472  .priv_size = sizeof(AudioSurroundContext),
1473  .priv_class = &surround_class,
1474  .init = init,
1475  .uninit = uninit,
1476  .activate = activate,
1480  .flags = AVFILTER_FLAG_SLICE_THREADS,
1481  .process_command = process_command,
1482 };
allchannels_spread
static void allchannels_spread(AVFilterContext *ctx)
Definition: af_surround.c:1085
formats
formats
Definition: signature.h:48
ff_get_audio_buffer
AVFrame * ff_get_audio_buffer(AVFilterLink *link, int nb_samples)
Request an audio samples buffer with a specific set of permissions.
Definition: audio.c:100
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:49
AVFilterChannelLayouts
A list of supported channel layouts.
Definition: formats.h:85
status
they must not be accessed directly The fifo field contains the frames that are queued in the input for processing by the filter The status_in and status_out fields contains the queued status(EOF or error) of the link
AudioSurroundContext::upmix
void(* upmix)(AVFilterContext *ctx, int ch)
Definition: af_surround.c:128
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:90
opt.h
AudioSurroundContext
Definition: af_surround.c:61
ifft_channel
static int ifft_channel(AVFilterContext *ctx, AVFrame *out, int ch)
Definition: af_surround.c:1231
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:969
ff_channel_layouts_ref
int ff_channel_layouts_ref(AVFilterChannelLayouts *f, AVFilterChannelLayouts **ref)
Add *ref as a new reference to f.
Definition: formats.c:591
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:103
AVTXContext
Definition: tx_priv.h:228
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:1391
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:99
fft_channel
static int fft_channel(AVFilterContext *ctx, AVFrame *in, int ch)
Definition: af_surround.c:1199
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:1372
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:330
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:796
set_output_levels
static void set_output_levels(AVFilterContext *ctx)
Definition: af_surround.c:200
SC_FC
@ SC_FC
Definition: af_surround.c:33
AudioSurroundContext::output_levels
float * output_levels
Definition: af_surround.c:86
M_PI_2
#define M_PI_2
Definition: mathematics.h:55
AudioSurroundContext::nb_out_channels
int nb_out_channels
Definition: af_surround.c:98
AVOption
AVOption.
Definition: opt.h:251
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:171
AudioSurroundContext::input_in
AVFrame * input_in
Definition: af_surround.c:102
AudioSurroundContext::out_ch_layout
AVChannelLayout out_ch_layout
Definition: af_surround.c:95
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:739
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
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:165
AudioSurroundContext::overlap
float overlap
Definition: af_surround.c:77
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:311
AudioSurroundContext::y_pos
float * y_pos
Definition: af_surround.c:112
SC_FL
@ SC_FL
Definition: af_surround.c:33
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: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:883
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:1336
AudioSurroundContext::output_lfe
int output_lfe
Definition: af_surround.c:87
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:134
AudioSurroundContext::all_y
float all_y
Definition: af_surround.c:80
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:100
AVFrame::ch_layout
AVChannelLayout ch_layout
Channel layout of the audio data.
Definition: frame.h:723
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:653
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:49
FFDIFFSIGN
#define FFDIFFSIGN(x, y)
Comparator.
Definition: macros.h:45
FLAGS
#define FLAGS
Definition: af_surround.c:1392
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:749
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:127
filter_5_1_back
static void filter_5_1_back(AVFilterContext *ctx)
Definition: af_surround.c:1026
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
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:256
ff_af_surround
const AVFilter ff_af_surround
Definition: af_surround.c:1469
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:1395
AudioSurroundContext::c_mag
float * c_mag
Definition: af_surround.c:116
outputs
static const AVFilterPad outputs[]
Definition: af_surround.c:1461
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:108
AudioSurroundContext::output_out
AVFrame * output_out
Definition: af_surround.c:107
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: internal.h:194
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: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:89
AudioSurroundContext::level_out
float level_out
Definition: af_surround.c:68
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
fabs
static __device__ float fabs(float a)
Definition: cuda_runtime.h:182
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:1383
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:594
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:33
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:449
filter_5_0_side
static void filter_5_0_side(AVFilterContext *ctx)
Definition: af_surround.c:910
AV_CH_LAYOUT_5POINT1
#define AV_CH_LAYOUT_5POINT1
Definition: channel_layout.h:221
AudioSurroundContext::lowcut
float lowcut
Definition: af_surround.c:92
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:76
WFUNC_HANNING
@ WFUNC_HANNING
Definition: window_func.h:29
AudioSurroundContext::input_levels
float * input_levels
Definition: af_surround.c:85
AudioSurroundContext::f_x
float f_x[SC_NB]
Definition: af_surround.c:82
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:122
ff_add_channel_layout
int ff_add_channel_layout(AVFilterChannelLayouts **l, const AVChannelLayout *channel_layout)
Definition: formats.c:466
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:1318
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:37
do_transform
static void do_transform(AVFilterContext *ctx, int ch)
Definition: af_surround.c:445
f
f
Definition: af_crystalizer.c:122
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:115
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:301
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:1301
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:88
AudioSurroundContext::in_channel_layout_str
char * in_channel_layout_str
Definition: af_surround.c:65
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:842
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:1273
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
M_PI
#define M_PI
Definition: mathematics.h:52
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:259
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:374
av_assert2
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:64
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:404
AVFrame::nb_samples
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:410
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(surround)
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
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:319
AVFrame::extended_data
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: frame.h:391
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:967
ff_filter_get_nb_threads
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition: avfilter.c:777
AV_CH_LAYOUT_7POINT1
#define AV_CH_LAYOUT_7POINT1
Definition: channel_layout.h:232
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:34
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:55
filter_surround
static void filter_surround(AVFilterContext *ctx)
Definition: af_surround.c:854
ff_inlink_queued_samples
int ff_inlink_queued_samples(AVFilterLink *link)
Definition: avfilter.c:1343
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:314
AVFilter
Filter definition.
Definition: avfilter.h:161
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: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:215
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:125
ifft_channels
static int ifft_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: af_surround.c:1257
AudioSurroundContext::tx_fn
av_tx_fn tx_fn
Definition: af_surround.c:124
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:836
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:225
AudioSurroundContext::in_ch_layout
AVChannelLayout in_ch_layout
Definition: af_surround.c:96
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:1219
AudioSurroundContext::window
AVFrame * window
Definition: af_surround.c:109
AVFilterContext
An instance of a filter.
Definition: avfilter.h:392
factor
static const int factor[16]
Definition: vf_pp7.c:76
TFLAGS
#define TFLAGS
Definition: af_surround.c:1393
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
M_LN10
#define M_LN10
Definition: mathematics.h:43
AudioSurroundContext::lfe_mag
float * lfe_mag
Definition: af_surround.c:117
AudioSurroundContext::highcut
float highcut
Definition: af_surround.c:93
smooth
static float smooth(DeshakeOpenCLContext *deshake_ctx, float *gauss_kernel, int length, float max_val, AVFifo *values)
Definition: vf_deshake_opencl.c:889
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:195
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:118
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:561
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
init
static av_cold int init(AVFilterContext *ctx)
Definition: af_surround.c:1099
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
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:229
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:146
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:234
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:798
AudioSurroundContext::all_x
float all_x
Definition: af_surround.c:79
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:204
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:1453
AudioSurroundContext::smooth
float smooth
Definition: af_surround.c:72
AudioSurroundContext::f_y
float f_y[SC_NB]
Definition: af_surround.c:83