2 * Copyright (c) 2017 Paul B Mahol
4 * This file is part of FFmpeg.
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.
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.
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
21 #include "libavutil/audio_fifo.h"
22 #include "libavutil/channel_layout.h"
23 #include "libavutil/opt.h"
24 #include "libavcodec/avfft.h"
30 #include "window_func.h"
32 typedef struct AudioSurroundContext {
35 char *out_channel_layout_str;
36 char *in_channel_layout_str;
93 uint64_t out_channel_layout;
94 uint64_t in_channel_layout;
100 AVFrame *overlap_buffer;
105 RDFTContext **rdft, **irdft;
106 float *window_func_lut;
111 void (*filter)(AVFilterContext *ctx);
112 void (*upmix_stereo)(AVFilterContext *ctx,
119 void (*upmix_2_1)(AVFilterContext *ctx,
128 void (*upmix_3_0)(AVFilterContext *ctx,
136 void (*upmix_5_0)(AVFilterContext *ctx,
137 float c_re, float c_im,
138 float mag_totall, float mag_totalr,
139 float fl_phase, float fr_phase,
140 float bl_phase, float br_phase,
141 float sl_phase, float sr_phase,
145 void (*upmix_5_1)(AVFilterContext *ctx,
146 float c_re, float c_im,
147 float lfe_re, float lfe_im,
148 float mag_totall, float mag_totalr,
149 float fl_phase, float fr_phase,
150 float bl_phase, float br_phase,
151 float sl_phase, float sr_phase,
155 } AudioSurroundContext;
157 static int query_formats(AVFilterContext *ctx)
159 AudioSurroundContext *s = ctx->priv;
160 AVFilterFormats *formats = NULL;
161 AVFilterChannelLayouts *layouts = NULL;
164 ret = ff_add_format(&formats, AV_SAMPLE_FMT_FLTP);
167 ret = ff_set_common_formats(ctx, formats);
172 ret = ff_add_channel_layout(&layouts, s->out_channel_layout);
176 ret = ff_channel_layouts_ref(layouts, &ctx->outputs[0]->in_channel_layouts);
181 ret = ff_add_channel_layout(&layouts, s->in_channel_layout);
185 ret = ff_channel_layouts_ref(layouts, &ctx->inputs[0]->out_channel_layouts);
189 formats = ff_all_samplerates();
191 return AVERROR(ENOMEM);
192 return ff_set_common_samplerates(ctx, formats);
195 static int config_input(AVFilterLink *inlink)
197 AVFilterContext *ctx = inlink->dst;
198 AudioSurroundContext *s = ctx->priv;
201 s->rdft = av_calloc(inlink->channels, sizeof(*s->rdft));
203 return AVERROR(ENOMEM);
205 for (ch = 0; ch < inlink->channels; ch++) {
206 s->rdft[ch] = av_rdft_init(ff_log2(s->buf_size), DFT_R2C);
208 return AVERROR(ENOMEM);
210 s->nb_in_channels = inlink->channels;
211 s->input_levels = av_malloc_array(s->nb_in_channels, sizeof(*s->input_levels));
212 if (!s->input_levels)
213 return AVERROR(ENOMEM);
214 for (ch = 0; ch < s->nb_in_channels; ch++)
215 s->input_levels[ch] = s->level_in;
216 ch = av_get_channel_layout_channel_index(inlink->channel_layout, AV_CH_FRONT_CENTER);
218 s->input_levels[ch] *= s->fc_in;
219 ch = av_get_channel_layout_channel_index(inlink->channel_layout, AV_CH_FRONT_LEFT);
221 s->input_levels[ch] *= s->fl_in;
222 ch = av_get_channel_layout_channel_index(inlink->channel_layout, AV_CH_FRONT_RIGHT);
224 s->input_levels[ch] *= s->fr_in;
225 ch = av_get_channel_layout_channel_index(inlink->channel_layout, AV_CH_SIDE_LEFT);
227 s->input_levels[ch] *= s->sl_in;
228 ch = av_get_channel_layout_channel_index(inlink->channel_layout, AV_CH_SIDE_RIGHT);
230 s->input_levels[ch] *= s->sr_in;
231 ch = av_get_channel_layout_channel_index(inlink->channel_layout, AV_CH_BACK_LEFT);
233 s->input_levels[ch] *= s->bl_in;
234 ch = av_get_channel_layout_channel_index(inlink->channel_layout, AV_CH_BACK_RIGHT);
236 s->input_levels[ch] *= s->br_in;
237 ch = av_get_channel_layout_channel_index(inlink->channel_layout, AV_CH_BACK_CENTER);
239 s->input_levels[ch] *= s->bc_in;
240 ch = av_get_channel_layout_channel_index(inlink->channel_layout, AV_CH_LOW_FREQUENCY);
242 s->input_levels[ch] *= s->lfe_in;
244 s->input = ff_get_audio_buffer(inlink, s->buf_size * 2);
246 return AVERROR(ENOMEM);
248 s->fifo = av_audio_fifo_alloc(inlink->format, inlink->channels, s->buf_size);
250 return AVERROR(ENOMEM);
252 s->lowcut = 1.f * s->lowcutf / (inlink->sample_rate * 0.5) * (s->buf_size / 2);
253 s->highcut = 1.f * s->highcutf / (inlink->sample_rate * 0.5) * (s->buf_size / 2);
258 static int config_output(AVFilterLink *outlink)
260 AVFilterContext *ctx = outlink->src;
261 AudioSurroundContext *s = ctx->priv;
264 s->irdft = av_calloc(outlink->channels, sizeof(*s->irdft));
266 return AVERROR(ENOMEM);
268 for (ch = 0; ch < outlink->channels; ch++) {
269 s->irdft[ch] = av_rdft_init(ff_log2(s->buf_size), IDFT_C2R);
271 return AVERROR(ENOMEM);
273 s->nb_out_channels = outlink->channels;
274 s->output_levels = av_malloc_array(s->nb_out_channels, sizeof(*s->output_levels));
275 if (!s->output_levels)
276 return AVERROR(ENOMEM);
277 for (ch = 0; ch < s->nb_out_channels; ch++)
278 s->output_levels[ch] = s->level_out;
279 ch = av_get_channel_layout_channel_index(outlink->channel_layout, AV_CH_FRONT_CENTER);
281 s->output_levels[ch] *= s->fc_out;
282 ch = av_get_channel_layout_channel_index(outlink->channel_layout, AV_CH_FRONT_LEFT);
284 s->output_levels[ch] *= s->fl_out;
285 ch = av_get_channel_layout_channel_index(outlink->channel_layout, AV_CH_FRONT_RIGHT);
287 s->output_levels[ch] *= s->fr_out;
288 ch = av_get_channel_layout_channel_index(outlink->channel_layout, AV_CH_SIDE_LEFT);
290 s->output_levels[ch] *= s->sl_out;
291 ch = av_get_channel_layout_channel_index(outlink->channel_layout, AV_CH_SIDE_RIGHT);
293 s->output_levels[ch] *= s->sr_out;
294 ch = av_get_channel_layout_channel_index(outlink->channel_layout, AV_CH_BACK_LEFT);
296 s->output_levels[ch] *= s->bl_out;
297 ch = av_get_channel_layout_channel_index(outlink->channel_layout, AV_CH_BACK_RIGHT);
299 s->output_levels[ch] *= s->br_out;
300 ch = av_get_channel_layout_channel_index(outlink->channel_layout, AV_CH_BACK_CENTER);
302 s->output_levels[ch] *= s->bc_out;
303 ch = av_get_channel_layout_channel_index(outlink->channel_layout, AV_CH_LOW_FREQUENCY);
305 s->output_levels[ch] *= s->lfe_out;
307 s->output = ff_get_audio_buffer(outlink, s->buf_size * 2);
308 s->overlap_buffer = ff_get_audio_buffer(outlink, s->buf_size * 2);
309 if (!s->overlap_buffer || !s->output)
310 return AVERROR(ENOMEM);
315 static void stereo_position(float a, float p, float *x, float *y)
317 *x = av_clipf(a+FFMAX(0, sinf(p-M_PI_2))*FFDIFFSIGN(a,0), -1, 1);
318 *y = av_clipf(cosf(a*M_PI_2+M_PI)*cosf(M_PI_2-p/M_PI)*M_LN10+1, -1, 1);
321 static inline void get_lfe(int output_lfe, int n, float lowcut, float highcut,
322 float *lfe_mag, float *mag_total, int lfe_mode)
324 if (output_lfe && n < highcut) {
325 *lfe_mag = n < lowcut ? 1.f : .5f*(1.f+cosf(M_PI*(lowcut-n)/(lowcut-highcut)));
326 *lfe_mag *= *mag_total;
328 *mag_total -= *lfe_mag;
334 static void upmix_1_0(AVFilterContext *ctx,
342 AudioSurroundContext *s = ctx->priv;
345 dst = (float *)s->output->extended_data[0];
347 mag = powf(1.f - fabsf(x), s->fc_x) * powf((y + 1.f) * .5f, s->fc_y) * mag_total;
349 dst[2 * n ] = mag * cosf(c_phase);
350 dst[2 * n + 1] = mag * sinf(c_phase);
353 static void upmix_stereo(AVFilterContext *ctx,
361 AudioSurroundContext *s = ctx->priv;
362 float l_mag, r_mag, *dstl, *dstr;
364 dstl = (float *)s->output->extended_data[0];
365 dstr = (float *)s->output->extended_data[1];
367 l_mag = powf(.5f * ( x + 1.f), s->fl_x) * powf((y + 1.f) * .5f, s->fl_y) * mag_total;
368 r_mag = powf(.5f * (-x + 1.f), s->fr_x) * powf((y + 1.f) * .5f, s->fr_y) * mag_total;
370 dstl[2 * n ] = l_mag * cosf(l_phase);
371 dstl[2 * n + 1] = l_mag * sinf(l_phase);
373 dstr[2 * n ] = r_mag * cosf(r_phase);
374 dstr[2 * n + 1] = r_mag * sinf(r_phase);
377 static void upmix_2_1(AVFilterContext *ctx,
385 AudioSurroundContext *s = ctx->priv;
386 float lfe_mag, l_mag, r_mag, *dstl, *dstr, *dstlfe;
388 dstl = (float *)s->output->extended_data[0];
389 dstr = (float *)s->output->extended_data[1];
390 dstlfe = (float *)s->output->extended_data[2];
392 get_lfe(s->output_lfe, n, s->lowcut, s->highcut, &lfe_mag, &mag_total, s->lfe_mode);
394 l_mag = powf(.5f * ( x + 1.f), s->fl_x) * powf((y + 1.f) * .5f, s->fl_y) * mag_total;
395 r_mag = powf(.5f * (-x + 1.f), s->fr_x) * powf((y + 1.f) * .5f, s->fr_y) * mag_total;
397 dstl[2 * n ] = l_mag * cosf(l_phase);
398 dstl[2 * n + 1] = l_mag * sinf(l_phase);
400 dstr[2 * n ] = r_mag * cosf(r_phase);
401 dstr[2 * n + 1] = r_mag * sinf(r_phase);
403 dstlfe[2 * n ] = lfe_mag * cosf(c_phase);
404 dstlfe[2 * n + 1] = lfe_mag * sinf(c_phase);
407 static void upmix_3_0(AVFilterContext *ctx,
415 AudioSurroundContext *s = ctx->priv;
416 float l_mag, r_mag, c_mag, *dstc, *dstl, *dstr;
418 dstl = (float *)s->output->extended_data[0];
419 dstr = (float *)s->output->extended_data[1];
420 dstc = (float *)s->output->extended_data[2];
422 c_mag = powf(1.f - fabsf(x), s->fc_x) * powf((y + 1.f) * .5f, s->fc_y) * mag_total;
423 l_mag = powf(.5f * ( x + 1.f), s->fl_x) * powf((y + 1.f) * .5f, s->fl_y) * mag_total;
424 r_mag = powf(.5f * (-x + 1.f), s->fr_x) * powf((y + 1.f) * .5f, s->fr_y) * mag_total;
426 dstl[2 * n ] = l_mag * cosf(l_phase);
427 dstl[2 * n + 1] = l_mag * sinf(l_phase);
429 dstr[2 * n ] = r_mag * cosf(r_phase);
430 dstr[2 * n + 1] = r_mag * sinf(r_phase);
432 dstc[2 * n ] = c_mag * cosf(c_phase);
433 dstc[2 * n + 1] = c_mag * sinf(c_phase);
436 static void upmix_3_1(AVFilterContext *ctx,
444 AudioSurroundContext *s = ctx->priv;
445 float lfe_mag, l_mag, r_mag, c_mag, *dstc, *dstl, *dstr, *dstlfe;
447 dstl = (float *)s->output->extended_data[0];
448 dstr = (float *)s->output->extended_data[1];
449 dstc = (float *)s->output->extended_data[2];
450 dstlfe = (float *)s->output->extended_data[3];
452 get_lfe(s->output_lfe, n, s->lowcut, s->highcut, &lfe_mag, &mag_total, s->lfe_mode);
454 c_mag = powf(1.f - fabsf(x), s->fc_x) * powf((y + 1.f) * .5f, s->fc_y) * mag_total;
455 l_mag = powf(.5f * ( x + 1.f), s->fl_x) * powf((y + 1.f) * .5f, s->fl_y) * mag_total;
456 r_mag = powf(.5f * (-x + 1.f), s->fr_x) * powf((y + 1.f) * .5f, s->fr_y) * mag_total;
458 dstl[2 * n ] = l_mag * cosf(l_phase);
459 dstl[2 * n + 1] = l_mag * sinf(l_phase);
461 dstr[2 * n ] = r_mag * cosf(r_phase);
462 dstr[2 * n + 1] = r_mag * sinf(r_phase);
464 dstc[2 * n ] = c_mag * cosf(c_phase);
465 dstc[2 * n + 1] = c_mag * sinf(c_phase);
467 dstlfe[2 * n ] = lfe_mag * cosf(c_phase);
468 dstlfe[2 * n + 1] = lfe_mag * sinf(c_phase);
471 static void upmix_3_1_surround(AVFilterContext *ctx,
480 AudioSurroundContext *s = ctx->priv;
481 float lfe_mag, l_mag, r_mag, *dstc, *dstl, *dstr, *dstlfe;
483 dstl = (float *)s->output->extended_data[0];
484 dstr = (float *)s->output->extended_data[1];
485 dstc = (float *)s->output->extended_data[2];
486 dstlfe = (float *)s->output->extended_data[3];
488 get_lfe(s->output_lfe, n, s->lowcut, s->highcut, &lfe_mag, &c_mag, s->lfe_mode);
490 l_mag = powf(.5f * ( x + 1.f), s->fl_x) * powf((y + 1.f) * .5f, s->fl_y) * mag_total;
491 r_mag = powf(.5f * (-x + 1.f), s->fr_x) * powf((y + 1.f) * .5f, s->fr_y) * mag_total;
493 dstl[2 * n ] = l_mag * cosf(l_phase);
494 dstl[2 * n + 1] = l_mag * sinf(l_phase);
496 dstr[2 * n ] = r_mag * cosf(r_phase);
497 dstr[2 * n + 1] = r_mag * sinf(r_phase);
499 dstc[2 * n ] = c_mag * cosf(c_phase);
500 dstc[2 * n + 1] = c_mag * sinf(c_phase);
502 dstlfe[2 * n ] = lfe_mag * cosf(c_phase);
503 dstlfe[2 * n + 1] = lfe_mag * sinf(c_phase);
506 static void upmix_4_0(AVFilterContext *ctx,
514 AudioSurroundContext *s = ctx->priv;
515 float b_mag, l_mag, r_mag, c_mag, *dstc, *dstl, *dstr, *dstb;
517 dstl = (float *)s->output->extended_data[0];
518 dstr = (float *)s->output->extended_data[1];
519 dstc = (float *)s->output->extended_data[2];
520 dstb = (float *)s->output->extended_data[3];
522 c_mag = powf(1.f - fabsf(x), s->fc_x) * powf((y + 1.f) * .5f, s->fc_y) * mag_total;
523 b_mag = powf(1.f - fabsf(x), s->bc_x) * powf((1.f - y) * .5f, s->bc_y) * mag_total;
524 l_mag = powf(.5f * ( x + 1.f), s->fl_x) * powf((y + 1.f) * .5f, s->fl_y) * mag_total;
525 r_mag = powf(.5f * (-x + 1.f), s->fr_x) * powf((y + 1.f) * .5f, s->fr_y) * mag_total;
527 dstl[2 * n ] = l_mag * cosf(l_phase);
528 dstl[2 * n + 1] = l_mag * sinf(l_phase);
530 dstr[2 * n ] = r_mag * cosf(r_phase);
531 dstr[2 * n + 1] = r_mag * sinf(r_phase);
533 dstc[2 * n ] = c_mag * cosf(c_phase);
534 dstc[2 * n + 1] = c_mag * sinf(c_phase);
536 dstb[2 * n ] = b_mag * cosf(c_phase);
537 dstb[2 * n + 1] = b_mag * sinf(c_phase);
540 static void upmix_4_1(AVFilterContext *ctx,
548 AudioSurroundContext *s = ctx->priv;
549 float lfe_mag, b_mag, l_mag, r_mag, c_mag, *dstc, *dstl, *dstr, *dstb, *dstlfe;
551 dstl = (float *)s->output->extended_data[0];
552 dstr = (float *)s->output->extended_data[1];
553 dstc = (float *)s->output->extended_data[2];
554 dstlfe = (float *)s->output->extended_data[3];
555 dstb = (float *)s->output->extended_data[4];
557 get_lfe(s->output_lfe, n, s->lowcut, s->highcut, &lfe_mag, &mag_total, s->lfe_mode);
559 dstlfe[2 * n ] = lfe_mag * cosf(c_phase);
560 dstlfe[2 * n + 1] = lfe_mag * sinf(c_phase);
562 c_mag = powf(1.f - fabsf(x), s->fc_x) * powf((y + 1.f) * .5f, s->fc_y) * mag_total;
563 b_mag = powf(1.f - fabsf(x), s->bc_x) * powf((1.f - y) * .5f, s->bc_y) * mag_total;
564 l_mag = powf(.5f * ( x + 1.f), s->fl_x) * powf((y + 1.f) * .5f, s->fl_y) * mag_total;
565 r_mag = powf(.5f * (-x + 1.f), s->fr_x) * powf((y + 1.f) * .5f, s->fr_y) * mag_total;
567 dstl[2 * n ] = l_mag * cosf(l_phase);
568 dstl[2 * n + 1] = l_mag * sinf(l_phase);
570 dstr[2 * n ] = r_mag * cosf(r_phase);
571 dstr[2 * n + 1] = r_mag * sinf(r_phase);
573 dstc[2 * n ] = c_mag * cosf(c_phase);
574 dstc[2 * n + 1] = c_mag * sinf(c_phase);
576 dstb[2 * n ] = b_mag * cosf(c_phase);
577 dstb[2 * n + 1] = b_mag * sinf(c_phase);
580 static void upmix_5_0_back(AVFilterContext *ctx,
588 AudioSurroundContext *s = ctx->priv;
589 float l_mag, r_mag, ls_mag, rs_mag, c_mag, *dstc, *dstl, *dstr, *dstls, *dstrs;
591 dstl = (float *)s->output->extended_data[0];
592 dstr = (float *)s->output->extended_data[1];
593 dstc = (float *)s->output->extended_data[2];
594 dstls = (float *)s->output->extended_data[3];
595 dstrs = (float *)s->output->extended_data[4];
597 c_mag = powf(1.f - fabsf(x), s->fc_x) * powf((y + 1.f) * .5f, s->fc_y) * mag_total;
598 l_mag = powf(.5f * ( x + 1.f), s->fl_x) * powf((y + 1.f) * .5f, s->fl_y) * mag_total;
599 r_mag = powf(.5f * (-x + 1.f), s->fr_x) * powf((y + 1.f) * .5f, s->fr_y) * mag_total;
600 ls_mag = powf(.5f * ( x + 1.f), s->bl_x) * powf(1.f - ((y + 1.f) * .5f), s->bl_y) * mag_total;
601 rs_mag = powf(.5f * (-x + 1.f), s->br_x) * powf(1.f - ((y + 1.f) * .5f), s->br_y) * mag_total;
603 dstl[2 * n ] = l_mag * cosf(l_phase);
604 dstl[2 * n + 1] = l_mag * sinf(l_phase);
606 dstr[2 * n ] = r_mag * cosf(r_phase);
607 dstr[2 * n + 1] = r_mag * sinf(r_phase);
609 dstc[2 * n ] = c_mag * cosf(c_phase);
610 dstc[2 * n + 1] = c_mag * sinf(c_phase);
612 dstls[2 * n ] = ls_mag * cosf(l_phase);
613 dstls[2 * n + 1] = ls_mag * sinf(l_phase);
615 dstrs[2 * n ] = rs_mag * cosf(r_phase);
616 dstrs[2 * n + 1] = rs_mag * sinf(r_phase);
619 static void upmix_5_1_back(AVFilterContext *ctx,
627 AudioSurroundContext *s = ctx->priv;
628 float lfe_mag, l_mag, r_mag, ls_mag, rs_mag, c_mag, *dstc, *dstl, *dstr, *dstls, *dstrs, *dstlfe;
630 dstl = (float *)s->output->extended_data[0];
631 dstr = (float *)s->output->extended_data[1];
632 dstc = (float *)s->output->extended_data[2];
633 dstlfe = (float *)s->output->extended_data[3];
634 dstls = (float *)s->output->extended_data[4];
635 dstrs = (float *)s->output->extended_data[5];
637 get_lfe(s->output_lfe, n, s->lowcut, s->highcut, &lfe_mag, &mag_total, s->lfe_mode);
639 c_mag = powf(1.f - fabsf(x), s->fc_x) * powf((y + 1.f) * .5f, s->fc_y) * mag_total;
640 l_mag = powf(.5f * ( x + 1.f), s->fl_x) * powf((y + 1.f) * .5f, s->fl_y) * mag_total;
641 r_mag = powf(.5f * (-x + 1.f), s->fr_x) * powf((y + 1.f) * .5f, s->fr_y) * mag_total;
642 ls_mag = powf(.5f * ( x + 1.f), s->bl_x) * powf(1.f - ((y + 1.f) * .5f), s->bl_y) * mag_total;
643 rs_mag = powf(.5f * (-x + 1.f), s->br_x) * powf(1.f - ((y + 1.f) * .5f), s->br_y) * mag_total;
645 dstl[2 * n ] = l_mag * cosf(l_phase);
646 dstl[2 * n + 1] = l_mag * sinf(l_phase);
648 dstr[2 * n ] = r_mag * cosf(r_phase);
649 dstr[2 * n + 1] = r_mag * sinf(r_phase);
651 dstc[2 * n ] = c_mag * cosf(c_phase);
652 dstc[2 * n + 1] = c_mag * sinf(c_phase);
654 dstlfe[2 * n ] = lfe_mag * cosf(c_phase);
655 dstlfe[2 * n + 1] = lfe_mag * sinf(c_phase);
657 dstls[2 * n ] = ls_mag * cosf(l_phase);
658 dstls[2 * n + 1] = ls_mag * sinf(l_phase);
660 dstrs[2 * n ] = rs_mag * cosf(r_phase);
661 dstrs[2 * n + 1] = rs_mag * sinf(r_phase);
664 static void upmix_6_0(AVFilterContext *ctx,
672 AudioSurroundContext *s = ctx->priv;
673 float l_mag, r_mag, ls_mag, rs_mag, c_mag, b_mag, *dstc, *dstb, *dstl, *dstr, *dstls, *dstrs;
675 dstl = (float *)s->output->extended_data[0];
676 dstr = (float *)s->output->extended_data[1];
677 dstc = (float *)s->output->extended_data[2];
678 dstb = (float *)s->output->extended_data[3];
679 dstls = (float *)s->output->extended_data[4];
680 dstrs = (float *)s->output->extended_data[5];
682 c_mag = powf(1.f - fabsf(x), s->fc_x) * powf((y + 1.f) * .5f, s->fc_y) * mag_total;
683 b_mag = powf(1.f - fabsf(x), s->bc_x) * powf((1.f - y) * .5f, s->bc_y) * mag_total;
684 l_mag = powf(.5f * ( x + 1.f), s->fl_x) * powf((y + 1.f) * .5f, s->fl_y) * mag_total;
685 r_mag = powf(.5f * (-x + 1.f), s->fr_x) * powf((y + 1.f) * .5f, s->fr_y) * mag_total;
686 ls_mag = powf(.5f * ( x + 1.f), s->bl_x) * powf(1.f - ((y + 1.f) * .5f), s->bl_y) * mag_total;
687 rs_mag = powf(.5f * (-x + 1.f), s->br_x) * powf(1.f - ((y + 1.f) * .5f), s->br_y) * mag_total;
689 dstl[2 * n ] = l_mag * cosf(l_phase);
690 dstl[2 * n + 1] = l_mag * sinf(l_phase);
692 dstr[2 * n ] = r_mag * cosf(r_phase);
693 dstr[2 * n + 1] = r_mag * sinf(r_phase);
695 dstc[2 * n ] = c_mag * cosf(c_phase);
696 dstc[2 * n + 1] = c_mag * sinf(c_phase);
698 dstls[2 * n ] = ls_mag * cosf(l_phase);
699 dstls[2 * n + 1] = ls_mag * sinf(l_phase);
701 dstrs[2 * n ] = rs_mag * cosf(r_phase);
702 dstrs[2 * n + 1] = rs_mag * sinf(r_phase);
704 dstb[2 * n ] = b_mag * cosf(c_phase);
705 dstb[2 * n + 1] = b_mag * sinf(c_phase);
708 static void upmix_6_1(AVFilterContext *ctx,
716 AudioSurroundContext *s = ctx->priv;
717 float lfe_mag, l_mag, r_mag, ls_mag, rs_mag, c_mag, b_mag, *dstc, *dstb, *dstl, *dstr, *dstls, *dstrs, *dstlfe;
719 dstl = (float *)s->output->extended_data[0];
720 dstr = (float *)s->output->extended_data[1];
721 dstc = (float *)s->output->extended_data[2];
722 dstlfe = (float *)s->output->extended_data[3];
723 dstb = (float *)s->output->extended_data[4];
724 dstls = (float *)s->output->extended_data[5];
725 dstrs = (float *)s->output->extended_data[6];
727 get_lfe(s->output_lfe, n, s->lowcut, s->highcut, &lfe_mag, &mag_total, s->lfe_mode);
729 c_mag = powf(1.f - fabsf(x), s->fc_x) * powf((y + 1.f) * .5f, s->fc_y) * mag_total;
730 b_mag = powf(1.f - fabsf(x), s->bc_x) * powf((1.f - y) * .5f, s->bc_y) * mag_total;
731 l_mag = powf(.5f * ( x + 1.f), s->fl_x) * powf((y + 1.f) * .5f, s->fl_y) * mag_total;
732 r_mag = powf(.5f * (-x + 1.f), s->fr_x) * powf((y + 1.f) * .5f, s->fr_y) * mag_total;
733 ls_mag = powf(.5f * ( x + 1.f), s->bl_x) * powf(1.f - ((y + 1.f) * .5f), s->bl_y) * mag_total;
734 rs_mag = powf(.5f * (-x + 1.f), s->br_x) * powf(1.f - ((y + 1.f) * .5f), s->br_y) * mag_total;
736 dstl[2 * n ] = l_mag * cosf(l_phase);
737 dstl[2 * n + 1] = l_mag * sinf(l_phase);
739 dstr[2 * n ] = r_mag * cosf(r_phase);
740 dstr[2 * n + 1] = r_mag * sinf(r_phase);
742 dstc[2 * n ] = c_mag * cosf(c_phase);
743 dstc[2 * n + 1] = c_mag * sinf(c_phase);
745 dstlfe[2 * n ] = lfe_mag * cosf(c_phase);
746 dstlfe[2 * n + 1] = lfe_mag * sinf(c_phase);
748 dstls[2 * n ] = ls_mag * cosf(l_phase);
749 dstls[2 * n + 1] = ls_mag * sinf(l_phase);
751 dstrs[2 * n ] = rs_mag * cosf(r_phase);
752 dstrs[2 * n + 1] = rs_mag * sinf(r_phase);
754 dstb[2 * n ] = b_mag * cosf(c_phase);
755 dstb[2 * n + 1] = b_mag * sinf(c_phase);
758 static void upmix_5_1_back_surround(AVFilterContext *ctx,
767 AudioSurroundContext *s = ctx->priv;
768 float lfe_mag, l_mag, r_mag, *dstc, *dstl, *dstr, *dstlfe;
769 float ls_mag, rs_mag, *dstls, *dstrs;
771 dstl = (float *)s->output->extended_data[0];
772 dstr = (float *)s->output->extended_data[1];
773 dstc = (float *)s->output->extended_data[2];
774 dstlfe = (float *)s->output->extended_data[3];
775 dstls = (float *)s->output->extended_data[4];
776 dstrs = (float *)s->output->extended_data[5];
778 get_lfe(s->output_lfe, n, s->lowcut, s->highcut, &lfe_mag, &c_mag, s->lfe_mode);
780 l_mag = powf(.5f * ( x + 1.f), s->fl_x) * powf((y + 1.f) * .5f, s->fl_y) * mag_total;
781 r_mag = powf(.5f * (-x + 1.f), s->fr_x) * powf((y + 1.f) * .5f, s->fr_y) * mag_total;
782 ls_mag = powf(.5f * ( x + 1.f), s->bl_x) * powf(1.f - ((y + 1.f) * .5f), s->bl_y) * mag_total;
783 rs_mag = powf(.5f * (-x + 1.f), s->br_x) * powf(1.f - ((y + 1.f) * .5f), s->br_y) * mag_total;
785 dstl[2 * n ] = l_mag * cosf(l_phase);
786 dstl[2 * n + 1] = l_mag * sinf(l_phase);
788 dstr[2 * n ] = r_mag * cosf(r_phase);
789 dstr[2 * n + 1] = r_mag * sinf(r_phase);
791 dstc[2 * n ] = c_mag * cosf(c_phase);
792 dstc[2 * n + 1] = c_mag * sinf(c_phase);
794 dstlfe[2 * n ] = lfe_mag * cosf(c_phase);
795 dstlfe[2 * n + 1] = lfe_mag * sinf(c_phase);
797 dstls[2 * n ] = ls_mag * cosf(l_phase);
798 dstls[2 * n + 1] = ls_mag * sinf(l_phase);
800 dstrs[2 * n ] = rs_mag * cosf(r_phase);
801 dstrs[2 * n + 1] = rs_mag * sinf(r_phase);
804 static void upmix_5_1_back_2_1(AVFilterContext *ctx,
814 AudioSurroundContext *s = ctx->priv;
815 float c_mag, l_mag, r_mag, *dstc, *dstl, *dstr, *dstlfe;
816 float ls_mag, rs_mag, *dstls, *dstrs;
818 dstl = (float *)s->output->extended_data[0];
819 dstr = (float *)s->output->extended_data[1];
820 dstc = (float *)s->output->extended_data[2];
821 dstlfe = (float *)s->output->extended_data[3];
822 dstls = (float *)s->output->extended_data[4];
823 dstrs = (float *)s->output->extended_data[5];
825 c_mag = powf(1.f - fabsf(x), s->fc_x) * powf((y + 1.f) * .5f, s->fc_y) * mag_total;
826 l_mag = powf(.5f * ( x + 1.f), s->fl_x) * powf((y + 1.f) * .5f, s->fl_y) * mag_total;
827 r_mag = powf(.5f * (-x + 1.f), s->fr_x) * powf((y + 1.f) * .5f, s->fr_y) * mag_total;
828 ls_mag = powf(.5f * ( x + 1.f), s->bl_x) * powf(1.f - ((y + 1.f) * .5f), s->bl_y) * mag_total;
829 rs_mag = powf(.5f * (-x + 1.f), s->br_x) * powf(1.f - ((y + 1.f) * .5f), s->br_y) * mag_total;
831 dstl[2 * n ] = l_mag * cosf(l_phase);
832 dstl[2 * n + 1] = l_mag * sinf(l_phase);
834 dstr[2 * n ] = r_mag * cosf(r_phase);
835 dstr[2 * n + 1] = r_mag * sinf(r_phase);
837 dstc[2 * n ] = c_mag * cosf(c_phase);
838 dstc[2 * n + 1] = c_mag * sinf(c_phase);
840 dstlfe[2 * n ] = lfe_re;
841 dstlfe[2 * n + 1] = lfe_im;
843 dstls[2 * n ] = ls_mag * cosf(l_phase);
844 dstls[2 * n + 1] = ls_mag * sinf(l_phase);
846 dstrs[2 * n ] = rs_mag * cosf(r_phase);
847 dstrs[2 * n + 1] = rs_mag * sinf(r_phase);
850 static void upmix_7_0(AVFilterContext *ctx,
858 float l_mag, r_mag, ls_mag, rs_mag, c_mag, lb_mag, rb_mag;
859 float *dstc, *dstl, *dstr, *dstls, *dstrs, *dstlb, *dstrb;
860 AudioSurroundContext *s = ctx->priv;
862 dstl = (float *)s->output->extended_data[0];
863 dstr = (float *)s->output->extended_data[1];
864 dstc = (float *)s->output->extended_data[2];
865 dstlb = (float *)s->output->extended_data[3];
866 dstrb = (float *)s->output->extended_data[4];
867 dstls = (float *)s->output->extended_data[5];
868 dstrs = (float *)s->output->extended_data[6];
870 c_mag = powf(1.f - fabsf(x), s->fc_x) * powf((y + 1.f) * .5f, s->fc_y) * mag_total;
871 l_mag = powf(.5f * ( x + 1.f), s->fl_x) * powf((y + 1.f) * .5f, s->fl_y) * mag_total;
872 r_mag = powf(.5f * (-x + 1.f), s->fr_x) * powf((y + 1.f) * .5f, s->fr_y) * mag_total;
873 lb_mag = powf(.5f * ( x + 1.f), s->bl_x) * powf(1.f - ((y + 1.f) * .5f), s->bl_y) * mag_total;
874 rb_mag = powf(.5f * (-x + 1.f), s->br_x) * powf(1.f - ((y + 1.f) * .5f), s->br_y) * mag_total;
875 ls_mag = powf(.5f * ( x + 1.f), s->sl_x) * powf(1.f - fabsf(y), s->sl_y) * mag_total;
876 rs_mag = powf(.5f * (-x + 1.f), s->sr_x) * powf(1.f - fabsf(y), s->sr_y) * mag_total;
878 dstl[2 * n ] = l_mag * cosf(l_phase);
879 dstl[2 * n + 1] = l_mag * sinf(l_phase);
881 dstr[2 * n ] = r_mag * cosf(r_phase);
882 dstr[2 * n + 1] = r_mag * sinf(r_phase);
884 dstc[2 * n ] = c_mag * cosf(c_phase);
885 dstc[2 * n + 1] = c_mag * sinf(c_phase);
887 dstlb[2 * n ] = lb_mag * cosf(l_phase);
888 dstlb[2 * n + 1] = lb_mag * sinf(l_phase);
890 dstrb[2 * n ] = rb_mag * cosf(r_phase);
891 dstrb[2 * n + 1] = rb_mag * sinf(r_phase);
893 dstls[2 * n ] = ls_mag * cosf(l_phase);
894 dstls[2 * n + 1] = ls_mag * sinf(l_phase);
896 dstrs[2 * n ] = rs_mag * cosf(r_phase);
897 dstrs[2 * n + 1] = rs_mag * sinf(r_phase);
900 static void upmix_7_1(AVFilterContext *ctx,
908 float lfe_mag, l_mag, r_mag, ls_mag, rs_mag, c_mag, lb_mag, rb_mag;
909 float *dstc, *dstl, *dstr, *dstls, *dstrs, *dstlb, *dstrb, *dstlfe;
910 AudioSurroundContext *s = ctx->priv;
912 dstl = (float *)s->output->extended_data[0];
913 dstr = (float *)s->output->extended_data[1];
914 dstc = (float *)s->output->extended_data[2];
915 dstlfe = (float *)s->output->extended_data[3];
916 dstlb = (float *)s->output->extended_data[4];
917 dstrb = (float *)s->output->extended_data[5];
918 dstls = (float *)s->output->extended_data[6];
919 dstrs = (float *)s->output->extended_data[7];
921 get_lfe(s->output_lfe, n, s->lowcut, s->highcut, &lfe_mag, &mag_total, s->lfe_mode);
923 c_mag = powf(1.f - fabsf(x), s->fc_x) * powf((y + 1.f) * .5f, s->fc_y) * mag_total;
924 l_mag = powf(.5f * ( x + 1.f), s->fl_x) * powf((y + 1.f) * .5f, s->fl_y) * mag_total;
925 r_mag = powf(.5f * (-x + 1.f), s->fr_x) * powf((y + 1.f) * .5f, s->fr_y) * mag_total;
926 lb_mag = powf(.5f * ( x + 1.f), s->bl_x) * powf(1.f - ((y + 1.f) * .5f), s->bl_y) * mag_total;
927 rb_mag = powf(.5f * (-x + 1.f), s->br_x) * powf(1.f - ((y + 1.f) * .5f), s->br_y) * mag_total;
928 ls_mag = powf(.5f * ( x + 1.f), s->sl_x) * powf(1.f - fabsf(y), s->sl_y) * mag_total;
929 rs_mag = powf(.5f * (-x + 1.f), s->sr_x) * powf(1.f - fabsf(y), s->sr_y) * mag_total;
931 dstl[2 * n ] = l_mag * cosf(l_phase);
932 dstl[2 * n + 1] = l_mag * sinf(l_phase);
934 dstr[2 * n ] = r_mag * cosf(r_phase);
935 dstr[2 * n + 1] = r_mag * sinf(r_phase);
937 dstc[2 * n ] = c_mag * cosf(c_phase);
938 dstc[2 * n + 1] = c_mag * sinf(c_phase);
940 dstlfe[2 * n ] = lfe_mag * cosf(c_phase);
941 dstlfe[2 * n + 1] = lfe_mag * sinf(c_phase);
943 dstlb[2 * n ] = lb_mag * cosf(l_phase);
944 dstlb[2 * n + 1] = lb_mag * sinf(l_phase);
946 dstrb[2 * n ] = rb_mag * cosf(r_phase);
947 dstrb[2 * n + 1] = rb_mag * sinf(r_phase);
949 dstls[2 * n ] = ls_mag * cosf(l_phase);
950 dstls[2 * n + 1] = ls_mag * sinf(l_phase);
952 dstrs[2 * n ] = rs_mag * cosf(r_phase);
953 dstrs[2 * n + 1] = rs_mag * sinf(r_phase);
956 static void upmix_7_1_5_0_side(AVFilterContext *ctx,
957 float c_re, float c_im,
958 float mag_totall, float mag_totalr,
959 float fl_phase, float fr_phase,
960 float bl_phase, float br_phase,
961 float sl_phase, float sr_phase,
966 float fl_mag, fr_mag, ls_mag, rs_mag, lb_mag, rb_mag;
967 float *dstc, *dstl, *dstr, *dstls, *dstrs, *dstlb, *dstrb, *dstlfe;
968 float lfe_mag, c_phase, mag_total = (mag_totall + mag_totalr) * 0.5;
969 AudioSurroundContext *s = ctx->priv;
971 dstl = (float *)s->output->extended_data[0];
972 dstr = (float *)s->output->extended_data[1];
973 dstc = (float *)s->output->extended_data[2];
974 dstlfe = (float *)s->output->extended_data[3];
975 dstlb = (float *)s->output->extended_data[4];
976 dstrb = (float *)s->output->extended_data[5];
977 dstls = (float *)s->output->extended_data[6];
978 dstrs = (float *)s->output->extended_data[7];
980 c_phase = atan2f(c_im, c_re);
982 get_lfe(s->output_lfe, n, s->lowcut, s->highcut, &lfe_mag, &mag_total, s->lfe_mode);
984 fl_mag = powf(.5f * (xl + 1.f), s->fl_x) * powf((yl + 1.f) * .5f, s->fl_y) * mag_totall;
985 fr_mag = powf(.5f * (xr + 1.f), s->fr_x) * powf((yr + 1.f) * .5f, s->fr_y) * mag_totalr;
986 lb_mag = powf(.5f * (-xl + 1.f), s->bl_x) * powf((yl + 1.f) * .5f, s->bl_y) * mag_totall;
987 rb_mag = powf(.5f * (-xr + 1.f), s->br_x) * powf((yr + 1.f) * .5f, s->br_y) * mag_totalr;
988 ls_mag = powf(1.f - fabsf(xl), s->sl_x) * powf((yl + 1.f) * .5f, s->sl_y) * mag_totall;
989 rs_mag = powf(1.f - fabsf(xr), s->sr_x) * powf((yr + 1.f) * .5f, s->sr_y) * mag_totalr;
991 dstl[2 * n ] = fl_mag * cosf(fl_phase);
992 dstl[2 * n + 1] = fl_mag * sinf(fl_phase);
994 dstr[2 * n ] = fr_mag * cosf(fr_phase);
995 dstr[2 * n + 1] = fr_mag * sinf(fr_phase);
998 dstc[2 * n + 1] = c_im;
1000 dstlfe[2 * n ] = lfe_mag * cosf(c_phase);
1001 dstlfe[2 * n + 1] = lfe_mag * sinf(c_phase);
1003 dstlb[2 * n ] = lb_mag * cosf(bl_phase);
1004 dstlb[2 * n + 1] = lb_mag * sinf(bl_phase);
1006 dstrb[2 * n ] = rb_mag * cosf(br_phase);
1007 dstrb[2 * n + 1] = rb_mag * sinf(br_phase);
1009 dstls[2 * n ] = ls_mag * cosf(sl_phase);
1010 dstls[2 * n + 1] = ls_mag * sinf(sl_phase);
1012 dstrs[2 * n ] = rs_mag * cosf(sr_phase);
1013 dstrs[2 * n + 1] = rs_mag * sinf(sr_phase);
1016 static void upmix_7_1_5_1(AVFilterContext *ctx,
1017 float c_re, float c_im,
1018 float lfe_re, float lfe_im,
1019 float mag_totall, float mag_totalr,
1020 float fl_phase, float fr_phase,
1021 float bl_phase, float br_phase,
1022 float sl_phase, float sr_phase,
1027 float fl_mag, fr_mag, ls_mag, rs_mag, lb_mag, rb_mag;
1028 float *dstc, *dstl, *dstr, *dstls, *dstrs, *dstlb, *dstrb, *dstlfe;
1029 AudioSurroundContext *s = ctx->priv;
1031 dstl = (float *)s->output->extended_data[0];
1032 dstr = (float *)s->output->extended_data[1];
1033 dstc = (float *)s->output->extended_data[2];
1034 dstlfe = (float *)s->output->extended_data[3];
1035 dstlb = (float *)s->output->extended_data[4];
1036 dstrb = (float *)s->output->extended_data[5];
1037 dstls = (float *)s->output->extended_data[6];
1038 dstrs = (float *)s->output->extended_data[7];
1040 fl_mag = powf(.5f * (xl + 1.f), s->fl_x) * powf((yl + 1.f) * .5f, s->fl_y) * mag_totall;
1041 fr_mag = powf(.5f * (xr + 1.f), s->fr_x) * powf((yr + 1.f) * .5f, s->fr_y) * mag_totalr;
1042 lb_mag = powf(.5f * (-xl + 1.f), s->bl_x) * powf((yl + 1.f) * .5f, s->bl_y) * mag_totall;
1043 rb_mag = powf(.5f * (-xr + 1.f), s->br_x) * powf((yr + 1.f) * .5f, s->br_y) * mag_totalr;
1044 ls_mag = powf(1.f - fabsf(xl), s->sl_x) * powf((yl + 1.f) * .5f, s->sl_y) * mag_totall;
1045 rs_mag = powf(1.f - fabsf(xr), s->sl_x) * powf((yr + 1.f) * .5f, s->sr_y) * mag_totalr;
1047 dstl[2 * n ] = fl_mag * cosf(fl_phase);
1048 dstl[2 * n + 1] = fl_mag * sinf(fl_phase);
1050 dstr[2 * n ] = fr_mag * cosf(fr_phase);
1051 dstr[2 * n + 1] = fr_mag * sinf(fr_phase);
1053 dstc[2 * n ] = c_re;
1054 dstc[2 * n + 1] = c_im;
1056 dstlfe[2 * n ] = lfe_re;
1057 dstlfe[2 * n + 1] = lfe_im;
1059 dstlb[2 * n ] = lb_mag * cosf(bl_phase);
1060 dstlb[2 * n + 1] = lb_mag * sinf(bl_phase);
1062 dstrb[2 * n ] = rb_mag * cosf(br_phase);
1063 dstrb[2 * n + 1] = rb_mag * sinf(br_phase);
1065 dstls[2 * n ] = ls_mag * cosf(sl_phase);
1066 dstls[2 * n + 1] = ls_mag * sinf(sl_phase);
1068 dstrs[2 * n ] = rs_mag * cosf(sr_phase);
1069 dstrs[2 * n + 1] = rs_mag * sinf(sr_phase);
1072 static void filter_stereo(AVFilterContext *ctx)
1074 AudioSurroundContext *s = ctx->priv;
1078 srcl = (float *)s->input->extended_data[0];
1079 srcr = (float *)s->input->extended_data[1];
1081 for (n = 0; n < s->buf_size; n++) {
1082 float l_re = srcl[2 * n], r_re = srcr[2 * n];
1083 float l_im = srcl[2 * n + 1], r_im = srcr[2 * n + 1];
1084 float c_phase = atan2f(l_im + r_im, l_re + r_re);
1085 float l_mag = hypotf(l_re, l_im);
1086 float r_mag = hypotf(r_re, r_im);
1087 float l_phase = atan2f(l_im, l_re);
1088 float r_phase = atan2f(r_im, r_re);
1089 float phase_dif = fabsf(l_phase - r_phase);
1090 float mag_sum = l_mag + r_mag;
1091 float mag_dif = mag_sum < 0.000001 ? 0.f : (l_mag - r_mag) / mag_sum;
1092 float mag_total = hypotf(l_mag, r_mag);
1095 if (phase_dif > M_PI)
1096 phase_dif = 2 * M_PI - phase_dif;
1098 stereo_position(mag_dif, phase_dif, &x, &y);
1100 s->upmix_stereo(ctx, l_phase, r_phase, c_phase, mag_total, x, y, n);
1104 static void filter_surround(AVFilterContext *ctx)
1106 AudioSurroundContext *s = ctx->priv;
1107 float *srcl, *srcr, *srcc;
1110 srcl = (float *)s->input->extended_data[0];
1111 srcr = (float *)s->input->extended_data[1];
1112 srcc = (float *)s->input->extended_data[2];
1114 for (n = 0; n < s->buf_size; n++) {
1115 float l_re = srcl[2 * n], r_re = srcr[2 * n];
1116 float l_im = srcl[2 * n + 1], r_im = srcr[2 * n + 1];
1117 float c_re = srcc[2 * n], c_im = srcc[2 * n + 1];
1118 float c_mag = hypotf(c_re, c_im);
1119 float c_phase = atan2f(c_im, c_re);
1120 float l_mag = hypotf(l_re, l_im);
1121 float r_mag = hypotf(r_re, r_im);
1122 float l_phase = atan2f(l_im, l_re);
1123 float r_phase = atan2f(r_im, r_re);
1124 float phase_dif = fabsf(l_phase - r_phase);
1125 float mag_sum = l_mag + r_mag;
1126 float mag_dif = mag_sum < 0.000001 ? 0.f : (l_mag - r_mag) / mag_sum;
1127 float mag_total = hypotf(l_mag, r_mag);
1130 if (phase_dif > M_PI)
1131 phase_dif = 2 * M_PI - phase_dif;
1133 stereo_position(mag_dif, phase_dif, &x, &y);
1135 s->upmix_3_0(ctx, l_phase, r_phase, c_phase, c_mag, mag_total, x, y, n);
1139 static void filter_2_1(AVFilterContext *ctx)
1141 AudioSurroundContext *s = ctx->priv;
1142 float *srcl, *srcr, *srclfe;
1145 srcl = (float *)s->input->extended_data[0];
1146 srcr = (float *)s->input->extended_data[1];
1147 srclfe = (float *)s->input->extended_data[2];
1149 for (n = 0; n < s->buf_size; n++) {
1150 float l_re = srcl[2 * n], r_re = srcr[2 * n];
1151 float l_im = srcl[2 * n + 1], r_im = srcr[2 * n + 1];
1152 float lfe_re = srclfe[2 * n], lfe_im = srclfe[2 * n + 1];
1153 float c_phase = atan2f(l_im + r_im, l_re + r_re);
1154 float l_mag = hypotf(l_re, l_im);
1155 float r_mag = hypotf(r_re, r_im);
1156 float l_phase = atan2f(l_im, l_re);
1157 float r_phase = atan2f(r_im, r_re);
1158 float phase_dif = fabsf(l_phase - r_phase);
1159 float mag_sum = l_mag + r_mag;
1160 float mag_dif = mag_sum < 0.000001 ? 0.f : (l_mag - r_mag) / mag_sum;
1161 float mag_total = hypotf(l_mag, r_mag);
1164 if (phase_dif > M_PI)
1165 phase_dif = 2 * M_PI - phase_dif;
1167 stereo_position(mag_dif, phase_dif, &x, &y);
1169 s->upmix_2_1(ctx, l_phase, r_phase, c_phase, mag_total, lfe_re, lfe_im, x, y, n);
1173 static void filter_5_0_side(AVFilterContext *ctx)
1175 AudioSurroundContext *s = ctx->priv;
1176 float *srcl, *srcr, *srcc, *srcsl, *srcsr;
1179 srcl = (float *)s->input->extended_data[0];
1180 srcr = (float *)s->input->extended_data[1];
1181 srcc = (float *)s->input->extended_data[2];
1182 srcsl = (float *)s->input->extended_data[3];
1183 srcsr = (float *)s->input->extended_data[4];
1185 for (n = 0; n < s->buf_size; n++) {
1186 float fl_re = srcl[2 * n], fr_re = srcr[2 * n];
1187 float fl_im = srcl[2 * n + 1], fr_im = srcr[2 * n + 1];
1188 float c_re = srcc[2 * n], c_im = srcc[2 * n + 1];
1189 float sl_re = srcsl[2 * n], sl_im = srcsl[2 * n + 1];
1190 float sr_re = srcsr[2 * n], sr_im = srcsr[2 * n + 1];
1191 float fl_mag = hypotf(fl_re, fl_im);
1192 float fr_mag = hypotf(fr_re, fr_im);
1193 float fl_phase = atan2f(fl_im, fl_re);
1194 float fr_phase = atan2f(fr_im, fr_re);
1195 float sl_mag = hypotf(sl_re, sl_im);
1196 float sr_mag = hypotf(sr_re, sr_im);
1197 float sl_phase = atan2f(sl_im, sl_re);
1198 float sr_phase = atan2f(sr_im, sr_re);
1199 float phase_difl = fabsf(fl_phase - sl_phase);
1200 float phase_difr = fabsf(fr_phase - sr_phase);
1201 float magl_sum = fl_mag + sl_mag;
1202 float magr_sum = fr_mag + sr_mag;
1203 float mag_difl = magl_sum < 0.000001 ? 0.f : (fl_mag - sl_mag) / magl_sum;
1204 float mag_difr = magr_sum < 0.000001 ? 0.f : (fr_mag - sr_mag) / magr_sum;
1205 float mag_totall = hypotf(fl_mag, sl_mag);
1206 float mag_totalr = hypotf(fr_mag, sr_mag);
1207 float bl_phase = atan2f(fl_im + sl_im, fl_re + sl_re);
1208 float br_phase = atan2f(fr_im + sr_im, fr_re + sr_re);
1212 if (phase_difl > M_PI)
1213 phase_difl = 2 * M_PI - phase_difl;
1215 if (phase_difr > M_PI)
1216 phase_difr = 2 * M_PI - phase_difr;
1218 stereo_position(mag_difl, phase_difl, &xl, &yl);
1219 stereo_position(mag_difr, phase_difr, &xr, &yr);
1221 s->upmix_5_0(ctx, c_re, c_im,
1222 mag_totall, mag_totalr,
1230 static void filter_5_1_side(AVFilterContext *ctx)
1232 AudioSurroundContext *s = ctx->priv;
1233 float *srcl, *srcr, *srcc, *srclfe, *srcsl, *srcsr;
1236 srcl = (float *)s->input->extended_data[0];
1237 srcr = (float *)s->input->extended_data[1];
1238 srcc = (float *)s->input->extended_data[2];
1239 srclfe = (float *)s->input->extended_data[3];
1240 srcsl = (float *)s->input->extended_data[4];
1241 srcsr = (float *)s->input->extended_data[5];
1243 for (n = 0; n < s->buf_size; n++) {
1244 float fl_re = srcl[2 * n], fr_re = srcr[2 * n];
1245 float fl_im = srcl[2 * n + 1], fr_im = srcr[2 * n + 1];
1246 float c_re = srcc[2 * n], c_im = srcc[2 * n + 1];
1247 float lfe_re = srclfe[2 * n], lfe_im = srclfe[2 * n + 1];
1248 float sl_re = srcsl[2 * n], sl_im = srcsl[2 * n + 1];
1249 float sr_re = srcsr[2 * n], sr_im = srcsr[2 * n + 1];
1250 float fl_mag = hypotf(fl_re, fl_im);
1251 float fr_mag = hypotf(fr_re, fr_im);
1252 float fl_phase = atan2f(fl_im, fl_re);
1253 float fr_phase = atan2f(fr_im, fr_re);
1254 float sl_mag = hypotf(sl_re, sl_im);
1255 float sr_mag = hypotf(sr_re, sr_im);
1256 float sl_phase = atan2f(sl_im, sl_re);
1257 float sr_phase = atan2f(sr_im, sr_re);
1258 float phase_difl = fabsf(fl_phase - sl_phase);
1259 float phase_difr = fabsf(fr_phase - sr_phase);
1260 float magl_sum = fl_mag + sl_mag;
1261 float magr_sum = fr_mag + sr_mag;
1262 float mag_difl = magl_sum < 0.000001 ? 0.f : (fl_mag - sl_mag) / magl_sum;
1263 float mag_difr = magr_sum < 0.000001 ? 0.f : (fr_mag - sr_mag) / magr_sum;
1264 float mag_totall = hypotf(fl_mag, sl_mag);
1265 float mag_totalr = hypotf(fr_mag, sr_mag);
1266 float bl_phase = atan2f(fl_im + sl_im, fl_re + sl_re);
1267 float br_phase = atan2f(fr_im + sr_im, fr_re + sr_re);
1271 if (phase_difl > M_PI)
1272 phase_difl = 2 * M_PI - phase_difl;
1274 if (phase_difr > M_PI)
1275 phase_difr = 2 * M_PI - phase_difr;
1277 stereo_position(mag_difl, phase_difl, &xl, &yl);
1278 stereo_position(mag_difr, phase_difr, &xr, &yr);
1280 s->upmix_5_1(ctx, c_re, c_im, lfe_re, lfe_im,
1281 mag_totall, mag_totalr,
1289 static void filter_5_1_back(AVFilterContext *ctx)
1291 AudioSurroundContext *s = ctx->priv;
1292 float *srcl, *srcr, *srcc, *srclfe, *srcbl, *srcbr;
1295 srcl = (float *)s->input->extended_data[0];
1296 srcr = (float *)s->input->extended_data[1];
1297 srcc = (float *)s->input->extended_data[2];
1298 srclfe = (float *)s->input->extended_data[3];
1299 srcbl = (float *)s->input->extended_data[4];
1300 srcbr = (float *)s->input->extended_data[5];
1302 for (n = 0; n < s->buf_size; n++) {
1303 float fl_re = srcl[2 * n], fr_re = srcr[2 * n];
1304 float fl_im = srcl[2 * n + 1], fr_im = srcr[2 * n + 1];
1305 float c_re = srcc[2 * n], c_im = srcc[2 * n + 1];
1306 float lfe_re = srclfe[2 * n], lfe_im = srclfe[2 * n + 1];
1307 float bl_re = srcbl[2 * n], bl_im = srcbl[2 * n + 1];
1308 float br_re = srcbr[2 * n], br_im = srcbr[2 * n + 1];
1309 float fl_mag = hypotf(fl_re, fl_im);
1310 float fr_mag = hypotf(fr_re, fr_im);
1311 float fl_phase = atan2f(fl_im, fl_re);
1312 float fr_phase = atan2f(fr_im, fr_re);
1313 float bl_mag = hypotf(bl_re, bl_im);
1314 float br_mag = hypotf(br_re, br_im);
1315 float bl_phase = atan2f(bl_im, bl_re);
1316 float br_phase = atan2f(br_im, br_re);
1317 float phase_difl = fabsf(fl_phase - bl_phase);
1318 float phase_difr = fabsf(fr_phase - br_phase);
1319 float magl_sum = fl_mag + bl_mag;
1320 float magr_sum = fr_mag + br_mag;
1321 float mag_difl = magl_sum < 0.000001 ? 0.f : (fl_mag - bl_mag) / magl_sum;
1322 float mag_difr = magr_sum < 0.000001 ? 0.f : (fr_mag - br_mag) / magr_sum;
1323 float mag_totall = hypotf(fl_mag, bl_mag);
1324 float mag_totalr = hypotf(fr_mag, br_mag);
1325 float sl_phase = atan2f(fl_im + bl_im, fl_re + bl_re);
1326 float sr_phase = atan2f(fr_im + br_im, fr_re + br_re);
1330 if (phase_difl > M_PI)
1331 phase_difl = 2 * M_PI - phase_difl;
1333 if (phase_difr > M_PI)
1334 phase_difr = 2 * M_PI - phase_difr;
1336 stereo_position(mag_difl, phase_difl, &xl, &yl);
1337 stereo_position(mag_difr, phase_difr, &xr, &yr);
1339 s->upmix_5_1(ctx, c_re, c_im, lfe_re, lfe_im,
1340 mag_totall, mag_totalr,
1348 static int init(AVFilterContext *ctx)
1350 AudioSurroundContext *s = ctx->priv;
1354 if (!(s->out_channel_layout = av_get_channel_layout(s->out_channel_layout_str))) {
1355 av_log(ctx, AV_LOG_ERROR, "Error parsing output channel layout '%s'.\n",
1356 s->out_channel_layout_str);
1357 return AVERROR(EINVAL);
1360 if (!(s->in_channel_layout = av_get_channel_layout(s->in_channel_layout_str))) {
1361 av_log(ctx, AV_LOG_ERROR, "Error parsing input channel layout '%s'.\n",
1362 s->in_channel_layout_str);
1363 return AVERROR(EINVAL);
1366 if (s->lowcutf >= s->highcutf) {
1367 av_log(ctx, AV_LOG_ERROR, "Low cut-off '%d' should be less than high cut-off '%d'.\n",
1368 s->lowcutf, s->highcutf);
1369 return AVERROR(EINVAL);
1372 switch (s->in_channel_layout) {
1373 case AV_CH_LAYOUT_STEREO:
1374 s->filter = filter_stereo;
1375 switch (s->out_channel_layout) {
1376 case AV_CH_LAYOUT_MONO:
1377 s->upmix_stereo = upmix_1_0;
1379 case AV_CH_LAYOUT_STEREO:
1380 s->upmix_stereo = upmix_stereo;
1382 case AV_CH_LAYOUT_2POINT1:
1383 s->upmix_stereo = upmix_2_1;
1385 case AV_CH_LAYOUT_SURROUND:
1386 s->upmix_stereo = upmix_3_0;
1388 case AV_CH_LAYOUT_3POINT1:
1389 s->upmix_stereo = upmix_3_1;
1391 case AV_CH_LAYOUT_4POINT0:
1392 s->upmix_stereo = upmix_4_0;
1394 case AV_CH_LAYOUT_4POINT1:
1395 s->upmix_stereo = upmix_4_1;
1397 case AV_CH_LAYOUT_5POINT0_BACK:
1398 s->upmix_stereo = upmix_5_0_back;
1400 case AV_CH_LAYOUT_5POINT1_BACK:
1401 s->upmix_stereo = upmix_5_1_back;
1403 case AV_CH_LAYOUT_6POINT0:
1404 s->upmix_stereo = upmix_6_0;
1406 case AV_CH_LAYOUT_6POINT1:
1407 s->upmix_stereo = upmix_6_1;
1409 case AV_CH_LAYOUT_7POINT0:
1410 s->upmix_stereo = upmix_7_0;
1412 case AV_CH_LAYOUT_7POINT1:
1413 s->upmix_stereo = upmix_7_1;
1419 case AV_CH_LAYOUT_2POINT1:
1420 s->filter = filter_2_1;
1421 switch (s->out_channel_layout) {
1422 case AV_CH_LAYOUT_5POINT1_BACK:
1423 s->upmix_2_1 = upmix_5_1_back_2_1;
1429 case AV_CH_LAYOUT_SURROUND:
1430 s->filter = filter_surround;
1431 switch (s->out_channel_layout) {
1432 case AV_CH_LAYOUT_3POINT1:
1433 s->upmix_3_0 = upmix_3_1_surround;
1435 case AV_CH_LAYOUT_5POINT1_BACK:
1436 s->upmix_3_0 = upmix_5_1_back_surround;
1442 case AV_CH_LAYOUT_5POINT0:
1443 s->filter = filter_5_0_side;
1444 switch (s->out_channel_layout) {
1445 case AV_CH_LAYOUT_7POINT1:
1446 s->upmix_5_0 = upmix_7_1_5_0_side;
1452 case AV_CH_LAYOUT_5POINT1:
1453 s->filter = filter_5_1_side;
1454 switch (s->out_channel_layout) {
1455 case AV_CH_LAYOUT_7POINT1:
1456 s->upmix_5_1 = upmix_7_1_5_1;
1462 case AV_CH_LAYOUT_5POINT1_BACK:
1463 s->filter = filter_5_1_back;
1464 switch (s->out_channel_layout) {
1465 case AV_CH_LAYOUT_7POINT1:
1466 s->upmix_5_1 = upmix_7_1_5_1;
1474 av_log(ctx, AV_LOG_ERROR, "Unsupported upmix: '%s' -> '%s'.\n",
1475 s->in_channel_layout_str, s->out_channel_layout_str);
1476 return AVERROR(EINVAL);
1479 s->buf_size = 1 << av_log2(s->win_size);
1480 s->pts = AV_NOPTS_VALUE;
1482 s->window_func_lut = av_calloc(s->buf_size, sizeof(*s->window_func_lut));
1483 if (!s->window_func_lut)
1484 return AVERROR(ENOMEM);
1486 generate_window_func(s->window_func_lut, s->buf_size, s->win_func, &overlap);
1487 if (s->overlap == 1)
1488 s->overlap = overlap;
1490 for (i = 0; i < s->buf_size; i++)
1491 s->window_func_lut[i] = sqrtf(s->window_func_lut[i] / s->buf_size);
1492 s->hop_size = s->buf_size * (1. - s->overlap);
1493 if (s->hop_size <= 0)
1494 return AVERROR(EINVAL);
1496 if (s->all_x >= 0.f)
1497 s->fc_x = s->fl_x = s->fr_x = s->bc_x = s->sl_x = s->sr_x = s->bl_x = s->br_x = s->all_x;
1498 if (s->all_y >= 0.f)
1499 s->fc_y = s->fl_y = s->fr_y = s->bc_y = s->sl_y = s->sr_y = s->bl_y = s->br_y = s->all_y;
1504 static int fft_channel(AVFilterContext *ctx, void *arg, int ch, int nb_jobs)
1506 AudioSurroundContext *s = ctx->priv;
1507 const float level_in = s->input_levels[ch];
1511 memset(s->input->extended_data[ch] + s->buf_size * sizeof(float), 0, s->buf_size * sizeof(float));
1513 dst = (float *)s->input->extended_data[ch];
1514 for (n = 0; n < s->buf_size; n++) {
1515 dst[n] *= s->window_func_lut[n] * level_in;
1518 av_rdft_calc(s->rdft[ch], (float *)s->input->extended_data[ch]);
1523 static int ifft_channel(AVFilterContext *ctx, void *arg, int ch, int nb_jobs)
1525 AudioSurroundContext *s = ctx->priv;
1526 const float level_out = s->output_levels[ch];
1531 av_rdft_calc(s->irdft[ch], (float *)s->output->extended_data[ch]);
1533 dst = (float *)s->output->extended_data[ch];
1534 ptr = (float *)s->overlap_buffer->extended_data[ch];
1536 memmove(s->overlap_buffer->extended_data[ch],
1537 s->overlap_buffer->extended_data[ch] + s->hop_size * sizeof(float),
1538 s->buf_size * sizeof(float));
1539 memset(s->overlap_buffer->extended_data[ch] + s->buf_size * sizeof(float),
1540 0, s->hop_size * sizeof(float));
1542 for (n = 0; n < s->buf_size; n++) {
1543 ptr[n] += dst[n] * s->window_func_lut[n] * level_out;
1546 ptr = (float *)s->overlap_buffer->extended_data[ch];
1547 dst = (float *)out->extended_data[ch];
1548 memcpy(dst, ptr, s->hop_size * sizeof(float));
1553 static int filter_frame(AVFilterLink *inlink)
1555 AVFilterContext *ctx = inlink->dst;
1556 AVFilterLink *outlink = ctx->outputs[0];
1557 AudioSurroundContext *s = ctx->priv;
1561 ret = av_audio_fifo_peek(s->fifo, (void **)s->input->extended_data, s->buf_size);
1565 ctx->internal->execute(ctx, fft_channel, NULL, NULL, inlink->channels);
1569 out = ff_get_audio_buffer(outlink, s->hop_size);
1571 return AVERROR(ENOMEM);
1573 ctx->internal->execute(ctx, ifft_channel, out, NULL, outlink->channels);
1576 if (s->pts != AV_NOPTS_VALUE)
1577 s->pts += av_rescale_q(out->nb_samples, (AVRational){1, outlink->sample_rate}, outlink->time_base);
1578 av_audio_fifo_drain(s->fifo, FFMIN(av_audio_fifo_size(s->fifo), s->hop_size));
1580 return ff_filter_frame(outlink, out);
1583 static int activate(AVFilterContext *ctx)
1585 AVFilterLink *inlink = ctx->inputs[0];
1586 AVFilterLink *outlink = ctx->outputs[0];
1587 AudioSurroundContext *s = ctx->priv;
1589 int ret = 0, status;
1592 FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink);
1594 if (!s->eof && av_audio_fifo_size(s->fifo) < s->buf_size) {
1595 ret = ff_inlink_consume_frame(inlink, &in);
1600 ret = av_audio_fifo_write(s->fifo, (void **)in->extended_data,
1602 if (ret >= 0 && s->pts == AV_NOPTS_VALUE)
1611 if ((av_audio_fifo_size(s->fifo) >= s->buf_size) ||
1612 (av_audio_fifo_size(s->fifo) > 0 && s->eof)) {
1613 ret = filter_frame(inlink);
1614 if (av_audio_fifo_size(s->fifo) >= s->buf_size)
1615 ff_filter_set_ready(ctx, 100);
1619 if (!s->eof && ff_inlink_acknowledge_status(inlink, &status, &pts)) {
1620 if (status == AVERROR_EOF) {
1622 if (av_audio_fifo_size(s->fifo) >= 0) {
1623 ff_filter_set_ready(ctx, 100);
1629 if (s->eof && av_audio_fifo_size(s->fifo) <= 0) {
1630 ff_outlink_set_status(outlink, AVERROR_EOF, s->pts);
1635 FF_FILTER_FORWARD_WANTED(outlink, inlink);
1637 return FFERROR_NOT_READY;
1640 static av_cold void uninit(AVFilterContext *ctx)
1642 AudioSurroundContext *s = ctx->priv;
1645 av_frame_free(&s->input);
1646 av_frame_free(&s->output);
1647 av_frame_free(&s->overlap_buffer);
1649 for (ch = 0; ch < s->nb_in_channels; ch++) {
1650 av_rdft_end(s->rdft[ch]);
1652 for (ch = 0; ch < s->nb_out_channels; ch++) {
1653 av_rdft_end(s->irdft[ch]);
1655 av_freep(&s->input_levels);
1656 av_freep(&s->output_levels);
1658 av_freep(&s->irdft);
1659 av_audio_fifo_free(s->fifo);
1660 av_freep(&s->window_func_lut);
1663 #define OFFSET(x) offsetof(AudioSurroundContext, x)
1664 #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
1666 static const AVOption surround_options[] = {
1667 { "chl_out", "set output channel layout", OFFSET(out_channel_layout_str), AV_OPT_TYPE_STRING, {.str="5.1"}, 0, 0, FLAGS },
1668 { "chl_in", "set input channel layout", OFFSET(in_channel_layout_str), AV_OPT_TYPE_STRING, {.str="stereo"},0, 0, FLAGS },
1669 { "level_in", "set input level", OFFSET(level_in), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, FLAGS },
1670 { "level_out", "set output level", OFFSET(level_out), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, FLAGS },
1671 { "lfe", "output LFE", OFFSET(output_lfe), AV_OPT_TYPE_BOOL, {.i64=1}, 0, 1, FLAGS },
1672 { "lfe_low", "LFE low cut off", OFFSET(lowcutf), AV_OPT_TYPE_INT, {.i64=128}, 0, 256, FLAGS },
1673 { "lfe_high", "LFE high cut off", OFFSET(highcutf), AV_OPT_TYPE_INT, {.i64=256}, 0, 512, FLAGS },
1674 { "lfe_mode", "set LFE channel mode", OFFSET(lfe_mode), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "lfe_mode" },
1675 { "add", "just add LFE channel", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 1, FLAGS, "lfe_mode" },
1676 { "sub", "substract LFE channel with others", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 1, FLAGS, "lfe_mode" },
1677 { "fc_in", "set front center channel input level", OFFSET(fc_in), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, FLAGS },
1678 { "fc_out", "set front center channel output level", OFFSET(fc_out), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, FLAGS },
1679 { "fl_in", "set front left channel input level", OFFSET(fl_in), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, FLAGS },
1680 { "fl_out", "set front left channel output level", OFFSET(fl_out), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, FLAGS },
1681 { "fr_in", "set front right channel input level", OFFSET(fr_in), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, FLAGS },
1682 { "fr_out", "set front right channel output level", OFFSET(fr_out), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, FLAGS },
1683 { "sl_in", "set side left channel input level", OFFSET(sl_in), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, FLAGS },
1684 { "sl_out", "set side left channel output level", OFFSET(sl_out), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, FLAGS },
1685 { "sr_in", "set side right channel input level", OFFSET(sr_in), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, FLAGS },
1686 { "sr_out", "set side right channel output level", OFFSET(sr_out), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, FLAGS },
1687 { "bl_in", "set back left channel input level", OFFSET(bl_in), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, FLAGS },
1688 { "bl_out", "set back left channel output level", OFFSET(bl_out), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, FLAGS },
1689 { "br_in", "set back right channel input level", OFFSET(br_in), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, FLAGS },
1690 { "br_out", "set back right channel output level", OFFSET(br_out), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, FLAGS },
1691 { "bc_in", "set back center channel input level", OFFSET(bc_in), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, FLAGS },
1692 { "bc_out", "set back center channel output level", OFFSET(bc_out), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, FLAGS },
1693 { "lfe_in", "set lfe channel input level", OFFSET(lfe_in), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, FLAGS },
1694 { "lfe_out", "set lfe channel output level", OFFSET(lfe_out), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 10, FLAGS },
1695 { "allx", "set all channel's x spread", OFFSET(all_x), AV_OPT_TYPE_FLOAT, {.dbl=-1}, -1, 15, FLAGS },
1696 { "ally", "set all channel's y spread", OFFSET(all_y), AV_OPT_TYPE_FLOAT, {.dbl=-1}, -1, 15, FLAGS },
1697 { "fcx", "set front center channel x spread", OFFSET(fc_x), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 15, FLAGS },
1698 { "flx", "set front left channel x spread", OFFSET(fl_x), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 15, FLAGS },
1699 { "frx", "set front right channel x spread", OFFSET(fr_x), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 15, FLAGS },
1700 { "blx", "set back left channel x spread", OFFSET(bl_x), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 15, FLAGS },
1701 { "brx", "set back right channel x spread", OFFSET(br_x), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 15, FLAGS },
1702 { "slx", "set side left channel x spread", OFFSET(sl_x), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 15, FLAGS },
1703 { "srx", "set side right channel x spread", OFFSET(sr_x), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 15, FLAGS },
1704 { "bcx", "set back center channel x spread", OFFSET(bc_x), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 15, FLAGS },
1705 { "fcy", "set front center channel y spread", OFFSET(fc_y), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 15, FLAGS },
1706 { "fly", "set front left channel y spread", OFFSET(fl_y), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 15, FLAGS },
1707 { "fry", "set front right channel y spread", OFFSET(fr_y), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 15, FLAGS },
1708 { "bly", "set back left channel y spread", OFFSET(bl_y), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 15, FLAGS },
1709 { "bry", "set back right channel y spread", OFFSET(br_y), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 15, FLAGS },
1710 { "sly", "set side left channel y spread", OFFSET(sl_y), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 15, FLAGS },
1711 { "sry", "set side right channel y spread", OFFSET(sr_y), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 15, FLAGS },
1712 { "bcy", "set back center channel y spread", OFFSET(bc_y), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 15, FLAGS },
1713 { "win_size", "set window size", OFFSET(win_size), AV_OPT_TYPE_INT, {.i64 = 4096}, 1024, 65536, FLAGS },
1714 { "win_func", "set window function", OFFSET(win_func), AV_OPT_TYPE_INT, {.i64 = WFUNC_HANNING}, 0, NB_WFUNC-1, FLAGS, "win_func" },
1715 { "rect", "Rectangular", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_RECT}, 0, 0, FLAGS, "win_func" },
1716 { "bartlett", "Bartlett", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BARTLETT}, 0, 0, FLAGS, "win_func" },
1717 { "hann", "Hann", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_HANNING}, 0, 0, FLAGS, "win_func" },
1718 { "hanning", "Hanning", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_HANNING}, 0, 0, FLAGS, "win_func" },
1719 { "hamming", "Hamming", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_HAMMING}, 0, 0, FLAGS, "win_func" },
1720 { "blackman", "Blackman", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BLACKMAN}, 0, 0, FLAGS, "win_func" },
1721 { "welch", "Welch", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_WELCH}, 0, 0, FLAGS, "win_func" },
1722 { "flattop", "Flat-top", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_FLATTOP}, 0, 0, FLAGS, "win_func" },
1723 { "bharris", "Blackman-Harris", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BHARRIS}, 0, 0, FLAGS, "win_func" },
1724 { "bnuttall", "Blackman-Nuttall", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BNUTTALL}, 0, 0, FLAGS, "win_func" },
1725 { "bhann", "Bartlett-Hann", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BHANN}, 0, 0, FLAGS, "win_func" },
1726 { "sine", "Sine", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_SINE}, 0, 0, FLAGS, "win_func" },
1727 { "nuttall", "Nuttall", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_NUTTALL}, 0, 0, FLAGS, "win_func" },
1728 { "lanczos", "Lanczos", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_LANCZOS}, 0, 0, FLAGS, "win_func" },
1729 { "gauss", "Gauss", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_GAUSS}, 0, 0, FLAGS, "win_func" },
1730 { "tukey", "Tukey", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_TUKEY}, 0, 0, FLAGS, "win_func" },
1731 { "dolph", "Dolph-Chebyshev", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_DOLPH}, 0, 0, FLAGS, "win_func" },
1732 { "cauchy", "Cauchy", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_CAUCHY}, 0, 0, FLAGS, "win_func" },
1733 { "parzen", "Parzen", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_PARZEN}, 0, 0, FLAGS, "win_func" },
1734 { "poisson", "Poisson", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_POISSON}, 0, 0, FLAGS, "win_func" },
1735 { "bohman", "Bohman", 0, AV_OPT_TYPE_CONST, {.i64=WFUNC_BOHMAN}, 0, 0, FLAGS, "win_func" },
1736 { "overlap", "set window overlap", OFFSET(overlap), AV_OPT_TYPE_FLOAT, {.dbl=0.5}, 0, 1, FLAGS },
1740 AVFILTER_DEFINE_CLASS(surround);
1742 static const AVFilterPad inputs[] = {
1745 .type = AVMEDIA_TYPE_AUDIO,
1746 .config_props = config_input,
1751 static const AVFilterPad outputs[] = {
1754 .type = AVMEDIA_TYPE_AUDIO,
1755 .config_props = config_output,
1760 AVFilter ff_af_surround = {
1762 .description = NULL_IF_CONFIG_SMALL("Apply audio surround upmix filter."),
1763 .query_formats = query_formats,
1764 .priv_size = sizeof(AudioSurroundContext),
1765 .priv_class = &surround_class,
1768 .activate = activate,
1771 .flags = AVFILTER_FLAG_SLICE_THREADS,