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