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