LCOV - code coverage report
Current view: top level - libavfilter - af_surround.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 825 0.0 %
Date: 2017-12-16 21:16:39 Functions: 0 32 0.0 %

          Line data    Source code
       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/audio_fifo.h"
      22             : #include "libavutil/channel_layout.h"
      23             : #include "libavutil/opt.h"
      24             : #include "libavcodec/avfft.h"
      25             : #include "avfilter.h"
      26             : #include "audio.h"
      27             : #include "formats.h"
      28             : 
      29             : typedef struct AudioSurroundContext {
      30             :     const AVClass *class;
      31             : 
      32             :     char *out_channel_layout_str;
      33             :     char *in_channel_layout_str;
      34             : 
      35             :     float level_in;
      36             :     float level_out;
      37             :     float fc_in;
      38             :     float fc_out;
      39             :     float lfe_in;
      40             :     float lfe_out;
      41             : 
      42             :     float *input_levels;
      43             :     float *output_levels;
      44             :     int output_lfe;
      45             :     int lowcutf;
      46             :     int highcutf;
      47             : 
      48             :     float lowcut;
      49             :     float highcut;
      50             : 
      51             :     uint64_t out_channel_layout;
      52             :     uint64_t in_channel_layout;
      53             :     int nb_in_channels;
      54             :     int nb_out_channels;
      55             : 
      56             :     AVFrame *input;
      57             :     AVFrame *output;
      58             :     AVFrame *overlap_buffer;
      59             : 
      60             :     int buf_size;
      61             :     int hop_size;
      62             :     AVAudioFifo *fifo;
      63             :     RDFTContext **rdft, **irdft;
      64             :     float *window_func_lut;
      65             : 
      66             :     int64_t pts;
      67             : 
      68             :     void (*filter)(AVFilterContext *ctx);
      69             :     void (*upmix_stereo)(AVFilterContext *ctx,
      70             :                          float l_phase,
      71             :                          float r_phase,
      72             :                          float c_phase,
      73             :                          float mag_total,
      74             :                          float x, float y,
      75             :                          int n);
      76             :     void (*upmix_2_1)(AVFilterContext *ctx,
      77             :                       float l_phase,
      78             :                       float r_phase,
      79             :                       float c_phase,
      80             :                       float mag_total,
      81             :                       float lfe_im,
      82             :                       float lfe_re,
      83             :                       float x, float y,
      84             :                       int n);
      85             :     void (*upmix_3_0)(AVFilterContext *ctx,
      86             :                       float l_phase,
      87             :                       float r_phase,
      88             :                       float c_mag,
      89             :                       float c_phase,
      90             :                       float mag_total,
      91             :                       float x, float y,
      92             :                       int n);
      93             :     void (*upmix_5_0)(AVFilterContext *ctx,
      94             :                       float c_re, float c_im,
      95             :                       float mag_totall, float mag_totalr,
      96             :                       float fl_phase, float fr_phase,
      97             :                       float bl_phase, float br_phase,
      98             :                       float sl_phase, float sr_phase,
      99             :                       float xl, float yl,
     100             :                       float xr, float yr,
     101             :                       int n);
     102             :     void (*upmix_5_1)(AVFilterContext *ctx,
     103             :                       float c_re, float c_im,
     104             :                       float lfe_re, float lfe_im,
     105             :                       float mag_totall, float mag_totalr,
     106             :                       float fl_phase, float fr_phase,
     107             :                       float bl_phase, float br_phase,
     108             :                       float sl_phase, float sr_phase,
     109             :                       float xl, float yl,
     110             :                       float xr, float yr,
     111             :                       int n);
     112             : } AudioSurroundContext;
     113             : 
     114           0 : static int query_formats(AVFilterContext *ctx)
     115             : {
     116           0 :     AudioSurroundContext *s = ctx->priv;
     117           0 :     AVFilterFormats *formats = NULL;
     118           0 :     AVFilterChannelLayouts *layouts = NULL;
     119             :     int ret;
     120             : 
     121           0 :     ret = ff_add_format(&formats, AV_SAMPLE_FMT_FLTP);
     122           0 :     if (ret)
     123           0 :         return ret;
     124           0 :     ret = ff_set_common_formats(ctx, formats);
     125           0 :     if (ret)
     126           0 :         return ret;
     127             : 
     128           0 :     layouts = NULL;
     129           0 :     ret = ff_add_channel_layout(&layouts, s->out_channel_layout);
     130           0 :     if (ret)
     131           0 :         return ret;
     132             : 
     133           0 :     ret = ff_channel_layouts_ref(layouts, &ctx->outputs[0]->in_channel_layouts);
     134           0 :     if (ret)
     135           0 :         return ret;
     136             : 
     137           0 :     layouts = NULL;
     138           0 :     ret = ff_add_channel_layout(&layouts, s->in_channel_layout);
     139           0 :     if (ret)
     140           0 :         return ret;
     141             : 
     142           0 :     ret = ff_channel_layouts_ref(layouts, &ctx->inputs[0]->out_channel_layouts);
     143           0 :     if (ret)
     144           0 :         return ret;
     145             : 
     146           0 :     formats = ff_all_samplerates();
     147           0 :     if (!formats)
     148           0 :         return AVERROR(ENOMEM);
     149           0 :     return ff_set_common_samplerates(ctx, formats);
     150             : }
     151             : 
     152           0 : static int config_input(AVFilterLink *inlink)
     153             : {
     154           0 :     AVFilterContext *ctx = inlink->dst;
     155           0 :     AudioSurroundContext *s = ctx->priv;
     156             :     int ch;
     157             : 
     158           0 :     s->rdft = av_calloc(inlink->channels, sizeof(*s->rdft));
     159           0 :     if (!s->rdft)
     160           0 :         return AVERROR(ENOMEM);
     161             : 
     162           0 :     for (ch = 0; ch < inlink->channels; ch++) {
     163           0 :         s->rdft[ch]  = av_rdft_init(ff_log2(s->buf_size), DFT_R2C);
     164           0 :         if (!s->rdft[ch])
     165           0 :             return AVERROR(ENOMEM);
     166             :     }
     167           0 :     s->nb_in_channels = inlink->channels;
     168           0 :     s->input_levels = av_malloc_array(s->nb_in_channels, sizeof(*s->input_levels));
     169           0 :     if (!s->input_levels)
     170           0 :         return AVERROR(ENOMEM);
     171           0 :     for (ch = 0;  ch < s->nb_in_channels; ch++)
     172           0 :         s->input_levels[ch] = s->level_in;
     173           0 :     ch = av_get_channel_layout_channel_index(inlink->channel_layout, AV_CH_FRONT_CENTER);
     174           0 :     if (ch >= 0)
     175           0 :         s->input_levels[ch] *= s->fc_in;
     176           0 :     ch = av_get_channel_layout_channel_index(inlink->channel_layout, AV_CH_LOW_FREQUENCY);
     177           0 :     if (ch >= 0)
     178           0 :         s->input_levels[ch] *= s->lfe_in;
     179             : 
     180           0 :     s->input = ff_get_audio_buffer(inlink, s->buf_size * 2);
     181           0 :     if (!s->input)
     182           0 :         return AVERROR(ENOMEM);
     183             : 
     184           0 :     s->fifo = av_audio_fifo_alloc(inlink->format, inlink->channels, s->buf_size);
     185           0 :     if (!s->fifo)
     186           0 :         return AVERROR(ENOMEM);
     187             : 
     188           0 :     s->lowcut = 1.f * s->lowcutf / (inlink->sample_rate * 0.5) * (s->buf_size / 2);
     189           0 :     s->highcut = 1.f * s->highcutf / (inlink->sample_rate * 0.5) * (s->buf_size / 2);
     190             : 
     191           0 :     return 0;
     192             : }
     193             : 
     194           0 : static int config_output(AVFilterLink *outlink)
     195             : {
     196           0 :     AVFilterContext *ctx = outlink->src;
     197           0 :     AudioSurroundContext *s = ctx->priv;
     198             :     int ch;
     199             : 
     200           0 :     s->irdft = av_calloc(outlink->channels, sizeof(*s->irdft));
     201           0 :     if (!s->irdft)
     202           0 :         return AVERROR(ENOMEM);
     203             : 
     204           0 :     for (ch = 0; ch < outlink->channels; ch++) {
     205           0 :         s->irdft[ch] = av_rdft_init(ff_log2(s->buf_size), IDFT_C2R);
     206           0 :         if (!s->irdft[ch])
     207           0 :             return AVERROR(ENOMEM);
     208             :     }
     209           0 :     s->nb_out_channels = outlink->channels;
     210           0 :     s->output_levels = av_malloc_array(s->nb_out_channels, sizeof(*s->output_levels));
     211           0 :     if (!s->output_levels)
     212           0 :         return AVERROR(ENOMEM);
     213           0 :     for (ch = 0;  ch < s->nb_out_channels; ch++)
     214           0 :         s->output_levels[ch] = s->level_out;
     215           0 :     ch = av_get_channel_layout_channel_index(outlink->channel_layout, AV_CH_FRONT_CENTER);
     216           0 :     if (ch >= 0)
     217           0 :         s->output_levels[ch] *= s->fc_out;
     218           0 :     ch = av_get_channel_layout_channel_index(outlink->channel_layout, AV_CH_LOW_FREQUENCY);
     219           0 :     if (ch >= 0)
     220           0 :         s->output_levels[ch] *= s->lfe_out;
     221             : 
     222           0 :     s->output = ff_get_audio_buffer(outlink, s->buf_size * 2);
     223           0 :     s->overlap_buffer = ff_get_audio_buffer(outlink, s->buf_size * 2);
     224           0 :     if (!s->overlap_buffer || !s->output)
     225           0 :         return AVERROR(ENOMEM);
     226             : 
     227           0 :     return 0;
     228             : }
     229             : 
     230           0 : static void stereo_position(float a, float p, float *x, float *y)
     231             : {
     232           0 :       *x = av_clipf(a+FFMAX(0, sinf(p-M_PI_2))*FFDIFFSIGN(a,0), -1, 1);
     233           0 :       *y = av_clipf(cosf(a*M_PI_2+M_PI)*cosf(M_PI_2-p/M_PI)*M_LN10+1, -1, 1);
     234           0 : }
     235             : 
     236           0 : static inline void get_lfe(int output_lfe, int n, float lowcut, float highcut,
     237             :                            float *lfe_mag, float *mag_total)
     238             : {
     239           0 :     if (output_lfe && n < highcut) {
     240           0 :         *lfe_mag    = n < lowcut ? 1.f : .5f*(1.f+cosf(M_PI*(lowcut-n)/(lowcut-highcut)));
     241           0 :         *lfe_mag   *= *mag_total;
     242           0 :         *mag_total -= *lfe_mag;
     243             :     } else {
     244           0 :         *lfe_mag = 0.f;
     245             :     }
     246           0 : }
     247             : 
     248           0 : static void upmix_1_0(AVFilterContext *ctx,
     249             :                       float l_phase,
     250             :                       float r_phase,
     251             :                       float c_phase,
     252             :                       float mag_total,
     253             :                       float x, float y,
     254             :                       int n)
     255             : {
     256           0 :     AudioSurroundContext *s = ctx->priv;
     257             :     float mag, *dst;
     258             : 
     259           0 :     dst = (float *)s->output->extended_data[0];
     260             : 
     261           0 :     mag = sqrtf(1.f - fabsf(x)) * ((y + 1.f) * .5f) * mag_total;
     262             : 
     263           0 :     dst[2 * n    ] = mag * cosf(c_phase);
     264           0 :     dst[2 * n + 1] = mag * sinf(c_phase);
     265           0 : }
     266             : 
     267           0 : static void upmix_stereo(AVFilterContext *ctx,
     268             :                          float l_phase,
     269             :                          float r_phase,
     270             :                          float c_phase,
     271             :                          float mag_total,
     272             :                          float x, float y,
     273             :                          int n)
     274             : {
     275           0 :     AudioSurroundContext *s = ctx->priv;
     276             :     float l_mag, r_mag, *dstl, *dstr;
     277             : 
     278           0 :     dstl = (float *)s->output->extended_data[0];
     279           0 :     dstr = (float *)s->output->extended_data[1];
     280             : 
     281           0 :     l_mag = sqrtf(.5f * ( x + 1.f)) * ((y + 1.f) * .5f) * mag_total;
     282           0 :     r_mag = sqrtf(.5f * (-x + 1.f)) * ((y + 1.f) * .5f) * mag_total;
     283             : 
     284           0 :     dstl[2 * n    ] = l_mag * cosf(l_phase);
     285           0 :     dstl[2 * n + 1] = l_mag * sinf(l_phase);
     286             : 
     287           0 :     dstr[2 * n    ] = r_mag * cosf(r_phase);
     288           0 :     dstr[2 * n + 1] = r_mag * sinf(r_phase);
     289           0 : }
     290             : 
     291           0 : static void upmix_2_1(AVFilterContext *ctx,
     292             :                       float l_phase,
     293             :                       float r_phase,
     294             :                       float c_phase,
     295             :                       float mag_total,
     296             :                       float x, float y,
     297             :                       int n)
     298             : {
     299           0 :     AudioSurroundContext *s = ctx->priv;
     300             :     float lfe_mag, l_mag, r_mag, *dstl, *dstr, *dstlfe;
     301             : 
     302           0 :     dstl = (float *)s->output->extended_data[0];
     303           0 :     dstr = (float *)s->output->extended_data[1];
     304           0 :     dstlfe = (float *)s->output->extended_data[2];
     305             : 
     306           0 :     get_lfe(s->output_lfe, n, s->lowcut, s->highcut, &lfe_mag, &mag_total);
     307             : 
     308           0 :     l_mag = sqrtf(.5f * ( x + 1.f)) * ((y + 1.f) * .5f) * mag_total;
     309           0 :     r_mag = sqrtf(.5f * (-x + 1.f)) * ((y + 1.f) * .5f) * mag_total;
     310             : 
     311           0 :     dstl[2 * n    ] = l_mag * cosf(l_phase);
     312           0 :     dstl[2 * n + 1] = l_mag * sinf(l_phase);
     313             : 
     314           0 :     dstr[2 * n    ] = r_mag * cosf(r_phase);
     315           0 :     dstr[2 * n + 1] = r_mag * sinf(r_phase);
     316             : 
     317           0 :     dstlfe[2 * n    ] = lfe_mag * cosf(c_phase);
     318           0 :     dstlfe[2 * n + 1] = lfe_mag * sinf(c_phase);
     319           0 : }
     320             : 
     321           0 : static void upmix_3_0(AVFilterContext *ctx,
     322             :                       float l_phase,
     323             :                       float r_phase,
     324             :                       float c_phase,
     325             :                       float mag_total,
     326             :                       float x, float y,
     327             :                       int n)
     328             : {
     329           0 :     AudioSurroundContext *s = ctx->priv;
     330             :     float l_mag, r_mag, c_mag, *dstc, *dstl, *dstr;
     331             : 
     332           0 :     dstl = (float *)s->output->extended_data[0];
     333           0 :     dstr = (float *)s->output->extended_data[1];
     334           0 :     dstc = (float *)s->output->extended_data[2];
     335             : 
     336           0 :     c_mag = sqrtf(1.f - fabsf(x))   * ((y + 1.f) * .5f) * mag_total;
     337           0 :     l_mag = sqrtf(.5f * ( x + 1.f)) * ((y + 1.f) * .5f) * mag_total;
     338           0 :     r_mag = sqrtf(.5f * (-x + 1.f)) * ((y + 1.f) * .5f) * mag_total;
     339             : 
     340           0 :     dstl[2 * n    ] = l_mag * cosf(l_phase);
     341           0 :     dstl[2 * n + 1] = l_mag * sinf(l_phase);
     342             : 
     343           0 :     dstr[2 * n    ] = r_mag * cosf(r_phase);
     344           0 :     dstr[2 * n + 1] = r_mag * sinf(r_phase);
     345             : 
     346           0 :     dstc[2 * n    ] = c_mag * cosf(c_phase);
     347           0 :     dstc[2 * n + 1] = c_mag * sinf(c_phase);
     348           0 : }
     349             : 
     350           0 : static void upmix_3_1(AVFilterContext *ctx,
     351             :                       float l_phase,
     352             :                       float r_phase,
     353             :                       float c_phase,
     354             :                       float mag_total,
     355             :                       float x, float y,
     356             :                       int n)
     357             : {
     358           0 :     AudioSurroundContext *s = ctx->priv;
     359             :     float lfe_mag, l_mag, r_mag, c_mag, *dstc, *dstl, *dstr, *dstlfe;
     360             : 
     361           0 :     dstl = (float *)s->output->extended_data[0];
     362           0 :     dstr = (float *)s->output->extended_data[1];
     363           0 :     dstc = (float *)s->output->extended_data[2];
     364           0 :     dstlfe = (float *)s->output->extended_data[3];
     365             : 
     366           0 :     get_lfe(s->output_lfe, n, s->lowcut, s->highcut, &lfe_mag, &mag_total);
     367             : 
     368           0 :     c_mag = sqrtf(1.f - fabsf(x))   * ((y + 1.f) * .5f) * mag_total;
     369           0 :     l_mag = sqrtf(.5f * ( x + 1.f)) * ((y + 1.f) * .5f) * mag_total;
     370           0 :     r_mag = sqrtf(.5f * (-x + 1.f)) * ((y + 1.f) * .5f) * mag_total;
     371             : 
     372           0 :     dstl[2 * n    ] = l_mag * cosf(l_phase);
     373           0 :     dstl[2 * n + 1] = l_mag * sinf(l_phase);
     374             : 
     375           0 :     dstr[2 * n    ] = r_mag * cosf(r_phase);
     376           0 :     dstr[2 * n + 1] = r_mag * sinf(r_phase);
     377             : 
     378           0 :     dstc[2 * n    ] = c_mag * cosf(c_phase);
     379           0 :     dstc[2 * n + 1] = c_mag * sinf(c_phase);
     380             : 
     381           0 :     dstlfe[2 * n    ] = lfe_mag * cosf(c_phase);
     382           0 :     dstlfe[2 * n + 1] = lfe_mag * sinf(c_phase);
     383           0 : }
     384             : 
     385           0 : static void upmix_3_1_surround(AVFilterContext *ctx,
     386             :                                float l_phase,
     387             :                                float r_phase,
     388             :                                float c_phase,
     389             :                                float c_mag,
     390             :                                float mag_total,
     391             :                                float x, float y,
     392             :                                int n)
     393             : {
     394           0 :     AudioSurroundContext *s = ctx->priv;
     395             :     float lfe_mag, l_mag, r_mag, *dstc, *dstl, *dstr, *dstlfe;
     396             : 
     397           0 :     dstl = (float *)s->output->extended_data[0];
     398           0 :     dstr = (float *)s->output->extended_data[1];
     399           0 :     dstc = (float *)s->output->extended_data[2];
     400           0 :     dstlfe = (float *)s->output->extended_data[3];
     401             : 
     402           0 :     get_lfe(s->output_lfe, n, s->lowcut, s->highcut, &lfe_mag, &c_mag);
     403             : 
     404           0 :     l_mag = sqrtf(.5f * ( x + 1.f)) * ((y + 1.f) * .5f) * mag_total;
     405           0 :     r_mag = sqrtf(.5f * (-x + 1.f)) * ((y + 1.f) * .5f) * mag_total;
     406             : 
     407           0 :     dstl[2 * n    ] = l_mag * cosf(l_phase);
     408           0 :     dstl[2 * n + 1] = l_mag * sinf(l_phase);
     409             : 
     410           0 :     dstr[2 * n    ] = r_mag * cosf(r_phase);
     411           0 :     dstr[2 * n + 1] = r_mag * sinf(r_phase);
     412             : 
     413           0 :     dstc[2 * n    ] = c_mag * cosf(c_phase);
     414           0 :     dstc[2 * n + 1] = c_mag * sinf(c_phase);
     415             : 
     416           0 :     dstlfe[2 * n    ] = lfe_mag * cosf(c_phase);
     417           0 :     dstlfe[2 * n + 1] = lfe_mag * sinf(c_phase);
     418           0 : }
     419             : 
     420           0 : static void upmix_4_0(AVFilterContext *ctx,
     421             :                       float l_phase,
     422             :                       float r_phase,
     423             :                       float c_phase,
     424             :                       float mag_total,
     425             :                       float x, float y,
     426             :                       int n)
     427             : {
     428             :     float b_mag, l_mag, r_mag, c_mag, *dstc, *dstl, *dstr, *dstb;
     429           0 :     AudioSurroundContext *s = ctx->priv;
     430             : 
     431           0 :     dstl = (float *)s->output->extended_data[0];
     432           0 :     dstr = (float *)s->output->extended_data[1];
     433           0 :     dstc = (float *)s->output->extended_data[2];
     434           0 :     dstb = (float *)s->output->extended_data[3];
     435             : 
     436           0 :     c_mag = sqrtf(1.f - fabsf(x))   * ((y + 1.f) * .5f) * mag_total;
     437           0 :     b_mag = sqrtf(1.f - fabsf(x))   * ((1.f - y) * .5f) * mag_total;
     438           0 :     l_mag = sqrtf(.5f * ( x + 1.f)) * ((y + 1.f) * .5f) * mag_total;
     439           0 :     r_mag = sqrtf(.5f * (-x + 1.f)) * ((y + 1.f) * .5f) * mag_total;
     440             : 
     441           0 :     dstl[2 * n    ] = l_mag * cosf(l_phase);
     442           0 :     dstl[2 * n + 1] = l_mag * sinf(l_phase);
     443             : 
     444           0 :     dstr[2 * n    ] = r_mag * cosf(r_phase);
     445           0 :     dstr[2 * n + 1] = r_mag * sinf(r_phase);
     446             : 
     447           0 :     dstc[2 * n    ] = c_mag * cosf(c_phase);
     448           0 :     dstc[2 * n + 1] = c_mag * sinf(c_phase);
     449             : 
     450           0 :     dstb[2 * n    ] = b_mag * cosf(c_phase);
     451           0 :     dstb[2 * n + 1] = b_mag * sinf(c_phase);
     452           0 : }
     453             : 
     454           0 : static void upmix_4_1(AVFilterContext *ctx,
     455             :                       float l_phase,
     456             :                       float r_phase,
     457             :                       float c_phase,
     458             :                       float mag_total,
     459             :                       float x, float y,
     460             :                       int n)
     461             : {
     462             :     float lfe_mag, b_mag, l_mag, r_mag, c_mag, *dstc, *dstl, *dstr, *dstb, *dstlfe;
     463           0 :     AudioSurroundContext *s = ctx->priv;
     464             : 
     465           0 :     dstl = (float *)s->output->extended_data[0];
     466           0 :     dstr = (float *)s->output->extended_data[1];
     467           0 :     dstc = (float *)s->output->extended_data[2];
     468           0 :     dstlfe = (float *)s->output->extended_data[3];
     469           0 :     dstb = (float *)s->output->extended_data[4];
     470             : 
     471           0 :     get_lfe(s->output_lfe, n, s->lowcut, s->highcut, &lfe_mag, &mag_total);
     472             : 
     473           0 :     dstlfe[2 * n    ] = lfe_mag * cosf(c_phase);
     474           0 :     dstlfe[2 * n + 1] = lfe_mag * sinf(c_phase);
     475             : 
     476           0 :     c_mag = sqrtf(1.f - fabsf(x))   * ((y + 1.f) * .5f) * mag_total;
     477           0 :     b_mag = sqrtf(1.f - fabsf(x))   * ((1.f - y) * .5f) * mag_total;
     478           0 :     l_mag = sqrtf(.5f * ( x + 1.f)) * ((y + 1.f) * .5f) * mag_total;
     479           0 :     r_mag = sqrtf(.5f * (-x + 1.f)) * ((y + 1.f) * .5f) * mag_total;
     480             : 
     481           0 :     dstl[2 * n    ] = l_mag * cosf(l_phase);
     482           0 :     dstl[2 * n + 1] = l_mag * sinf(l_phase);
     483             : 
     484           0 :     dstr[2 * n    ] = r_mag * cosf(r_phase);
     485           0 :     dstr[2 * n + 1] = r_mag * sinf(r_phase);
     486             : 
     487           0 :     dstc[2 * n    ] = c_mag * cosf(c_phase);
     488           0 :     dstc[2 * n + 1] = c_mag * sinf(c_phase);
     489             : 
     490           0 :     dstb[2 * n    ] = b_mag * cosf(c_phase);
     491           0 :     dstb[2 * n + 1] = b_mag * sinf(c_phase);
     492           0 : }
     493             : 
     494           0 : static void upmix_5_0_back(AVFilterContext *ctx,
     495             :                            float l_phase,
     496             :                            float r_phase,
     497             :                            float c_phase,
     498             :                            float mag_total,
     499             :                            float x, float y,
     500             :                            int n)
     501             : {
     502             :     float l_mag, r_mag, ls_mag, rs_mag, c_mag, *dstc, *dstl, *dstr, *dstls, *dstrs;
     503           0 :     AudioSurroundContext *s = ctx->priv;
     504             : 
     505           0 :     dstl  = (float *)s->output->extended_data[0];
     506           0 :     dstr  = (float *)s->output->extended_data[1];
     507           0 :     dstc  = (float *)s->output->extended_data[2];
     508           0 :     dstls = (float *)s->output->extended_data[3];
     509           0 :     dstrs = (float *)s->output->extended_data[4];
     510             : 
     511           0 :     c_mag  = sqrtf(1.f - fabsf(x))   * ((y + 1.f) * .5f) * mag_total;
     512           0 :     l_mag  = sqrtf(.5f * ( x + 1.f)) * ((y + 1.f) * .5f) * mag_total;
     513           0 :     r_mag  = sqrtf(.5f * (-x + 1.f)) * ((y + 1.f) * .5f) * mag_total;
     514           0 :     ls_mag = sqrtf(.5f * ( x + 1.f)) * (1.f - ((y + 1.f) * .5f)) * mag_total;
     515           0 :     rs_mag = sqrtf(.5f * (-x + 1.f)) * (1.f - ((y + 1.f) * .5f)) * mag_total;
     516             : 
     517           0 :     dstl[2 * n    ] = l_mag * cosf(l_phase);
     518           0 :     dstl[2 * n + 1] = l_mag * sinf(l_phase);
     519             : 
     520           0 :     dstr[2 * n    ] = r_mag * cosf(r_phase);
     521           0 :     dstr[2 * n + 1] = r_mag * sinf(r_phase);
     522             : 
     523           0 :     dstc[2 * n    ] = c_mag * cosf(c_phase);
     524           0 :     dstc[2 * n + 1] = c_mag * sinf(c_phase);
     525             : 
     526           0 :     dstls[2 * n    ] = ls_mag * cosf(l_phase);
     527           0 :     dstls[2 * n + 1] = ls_mag * sinf(l_phase);
     528             : 
     529           0 :     dstrs[2 * n    ] = rs_mag * cosf(r_phase);
     530           0 :     dstrs[2 * n + 1] = rs_mag * sinf(r_phase);
     531           0 : }
     532             : 
     533           0 : static void upmix_5_1_back(AVFilterContext *ctx,
     534             :                            float l_phase,
     535             :                            float r_phase,
     536             :                            float c_phase,
     537             :                            float mag_total,
     538             :                            float x, float y,
     539             :                            int n)
     540             : {
     541             :     float lfe_mag, l_mag, r_mag, ls_mag, rs_mag, c_mag, *dstc, *dstl, *dstr, *dstls, *dstrs, *dstlfe;
     542           0 :     AudioSurroundContext *s = ctx->priv;
     543             : 
     544           0 :     dstl  = (float *)s->output->extended_data[0];
     545           0 :     dstr  = (float *)s->output->extended_data[1];
     546           0 :     dstc  = (float *)s->output->extended_data[2];
     547           0 :     dstlfe = (float *)s->output->extended_data[3];
     548           0 :     dstls = (float *)s->output->extended_data[4];
     549           0 :     dstrs = (float *)s->output->extended_data[5];
     550             : 
     551           0 :     get_lfe(s->output_lfe, n, s->lowcut, s->highcut, &lfe_mag, &mag_total);
     552             : 
     553           0 :     c_mag  = sqrtf(1.f - fabsf(x))   * ((y + 1.f) * .5f) * mag_total;
     554           0 :     l_mag  = sqrtf(.5f * ( x + 1.f)) * ((y + 1.f) * .5f) * mag_total;
     555           0 :     r_mag  = sqrtf(.5f * (-x + 1.f)) * ((y + 1.f) * .5f) * mag_total;
     556           0 :     ls_mag = sqrtf(.5f * ( x + 1.f)) * (1.f - ((y + 1.f) * .5f)) * mag_total;
     557           0 :     rs_mag = sqrtf(.5f * (-x + 1.f)) * (1.f - ((y + 1.f) * .5f)) * mag_total;
     558             : 
     559           0 :     dstl[2 * n    ] = l_mag * cosf(l_phase);
     560           0 :     dstl[2 * n + 1] = l_mag * sinf(l_phase);
     561             : 
     562           0 :     dstr[2 * n    ] = r_mag * cosf(r_phase);
     563           0 :     dstr[2 * n + 1] = r_mag * sinf(r_phase);
     564             : 
     565           0 :     dstc[2 * n    ] = c_mag * cosf(c_phase);
     566           0 :     dstc[2 * n + 1] = c_mag * sinf(c_phase);
     567             : 
     568           0 :     dstlfe[2 * n    ] = lfe_mag * cosf(c_phase);
     569           0 :     dstlfe[2 * n + 1] = lfe_mag * sinf(c_phase);
     570             : 
     571           0 :     dstls[2 * n    ] = ls_mag * cosf(l_phase);
     572           0 :     dstls[2 * n + 1] = ls_mag * sinf(l_phase);
     573             : 
     574           0 :     dstrs[2 * n    ] = rs_mag * cosf(r_phase);
     575           0 :     dstrs[2 * n + 1] = rs_mag * sinf(r_phase);
     576           0 : }
     577             : 
     578           0 : static void upmix_5_1_back_surround(AVFilterContext *ctx,
     579             :                                     float l_phase,
     580             :                                     float r_phase,
     581             :                                     float c_phase,
     582             :                                     float c_mag,
     583             :                                     float mag_total,
     584             :                                     float x, float y,
     585             :                                     int n)
     586             : {
     587           0 :     AudioSurroundContext *s = ctx->priv;
     588             :     float lfe_mag, l_mag, r_mag, *dstc, *dstl, *dstr, *dstlfe;
     589             :     float ls_mag, rs_mag, *dstls, *dstrs;
     590             : 
     591           0 :     dstl = (float *)s->output->extended_data[0];
     592           0 :     dstr = (float *)s->output->extended_data[1];
     593           0 :     dstc = (float *)s->output->extended_data[2];
     594           0 :     dstlfe = (float *)s->output->extended_data[3];
     595           0 :     dstls = (float *)s->output->extended_data[4];
     596           0 :     dstrs = (float *)s->output->extended_data[5];
     597             : 
     598           0 :     get_lfe(s->output_lfe, n, s->lowcut, s->highcut, &lfe_mag, &c_mag);
     599             : 
     600           0 :     l_mag = sqrtf(.5f * ( x + 1.f)) * ((y + 1.f) * .5f) * mag_total;
     601           0 :     r_mag = sqrtf(.5f * (-x + 1.f)) * ((y + 1.f) * .5f) * mag_total;
     602           0 :     ls_mag = sqrtf(.5f * ( x + 1.f)) * (1.f - ((y + 1.f) * .5f)) * mag_total;
     603           0 :     rs_mag = sqrtf(.5f * (-x + 1.f)) * (1.f - ((y + 1.f) * .5f)) * mag_total;
     604             : 
     605           0 :     dstl[2 * n    ] = l_mag * cosf(l_phase);
     606           0 :     dstl[2 * n + 1] = l_mag * sinf(l_phase);
     607             : 
     608           0 :     dstr[2 * n    ] = r_mag * cosf(r_phase);
     609           0 :     dstr[2 * n + 1] = r_mag * sinf(r_phase);
     610             : 
     611           0 :     dstc[2 * n    ] = c_mag * cosf(c_phase);
     612           0 :     dstc[2 * n + 1] = c_mag * sinf(c_phase);
     613             : 
     614           0 :     dstlfe[2 * n    ] = lfe_mag * cosf(c_phase);
     615           0 :     dstlfe[2 * n + 1] = lfe_mag * sinf(c_phase);
     616             : 
     617           0 :     dstls[2 * n    ] = ls_mag * cosf(l_phase);
     618           0 :     dstls[2 * n + 1] = ls_mag * sinf(l_phase);
     619             : 
     620           0 :     dstrs[2 * n    ] = rs_mag * cosf(r_phase);
     621           0 :     dstrs[2 * n + 1] = rs_mag * sinf(r_phase);
     622           0 : }
     623             : 
     624           0 : static void upmix_5_1_back_2_1(AVFilterContext *ctx,
     625             :                                float l_phase,
     626             :                                float r_phase,
     627             :                                float c_phase,
     628             :                                float mag_total,
     629             :                                float lfe_re,
     630             :                                float lfe_im,
     631             :                                float x, float y,
     632             :                                int n)
     633             : {
     634           0 :     AudioSurroundContext *s = ctx->priv;
     635             :     float c_mag, l_mag, r_mag, *dstc, *dstl, *dstr, *dstlfe;
     636             :     float ls_mag, rs_mag, *dstls, *dstrs;
     637             : 
     638           0 :     dstl = (float *)s->output->extended_data[0];
     639           0 :     dstr = (float *)s->output->extended_data[1];
     640           0 :     dstc = (float *)s->output->extended_data[2];
     641           0 :     dstlfe = (float *)s->output->extended_data[3];
     642           0 :     dstls = (float *)s->output->extended_data[4];
     643           0 :     dstrs = (float *)s->output->extended_data[5];
     644             : 
     645           0 :     c_mag  = sqrtf(1.f - fabsf(x))   * ((y + 1.f) * .5f) * mag_total;
     646           0 :     l_mag  = sqrtf(.5f * ( x + 1.f)) * ((y + 1.f) * .5f) * mag_total;
     647           0 :     r_mag  = sqrtf(.5f * (-x + 1.f)) * ((y + 1.f) * .5f) * mag_total;
     648           0 :     ls_mag = sqrtf(.5f * ( x + 1.f)) * (1.f - ((y + 1.f) * .5f)) * mag_total;
     649           0 :     rs_mag = sqrtf(.5f * (-x + 1.f)) * (1.f - ((y + 1.f) * .5f)) * mag_total;
     650             : 
     651           0 :     dstl[2 * n    ] = l_mag * cosf(l_phase);
     652           0 :     dstl[2 * n + 1] = l_mag * sinf(l_phase);
     653             : 
     654           0 :     dstr[2 * n    ] = r_mag * cosf(r_phase);
     655           0 :     dstr[2 * n + 1] = r_mag * sinf(r_phase);
     656             : 
     657           0 :     dstc[2 * n    ] = c_mag * cosf(c_phase);
     658           0 :     dstc[2 * n + 1] = c_mag * sinf(c_phase);
     659             : 
     660           0 :     dstlfe[2 * n    ] = lfe_re;
     661           0 :     dstlfe[2 * n + 1] = lfe_im;
     662             : 
     663           0 :     dstls[2 * n    ] = ls_mag * cosf(l_phase);
     664           0 :     dstls[2 * n + 1] = ls_mag * sinf(l_phase);
     665             : 
     666           0 :     dstrs[2 * n    ] = rs_mag * cosf(r_phase);
     667           0 :     dstrs[2 * n + 1] = rs_mag * sinf(r_phase);
     668           0 : }
     669             : 
     670           0 : static void upmix_7_0(AVFilterContext *ctx,
     671             :                       float l_phase,
     672             :                       float r_phase,
     673             :                       float c_phase,
     674             :                       float mag_total,
     675             :                       float x, float y,
     676             :                       int n)
     677             : {
     678             :     float l_mag, r_mag, ls_mag, rs_mag, c_mag, lb_mag, rb_mag;
     679             :     float *dstc, *dstl, *dstr, *dstls, *dstrs, *dstlb, *dstrb;
     680           0 :     AudioSurroundContext *s = ctx->priv;
     681             : 
     682           0 :     dstl  = (float *)s->output->extended_data[0];
     683           0 :     dstr  = (float *)s->output->extended_data[1];
     684           0 :     dstc  = (float *)s->output->extended_data[2];
     685           0 :     dstlb = (float *)s->output->extended_data[3];
     686           0 :     dstrb = (float *)s->output->extended_data[4];
     687           0 :     dstls = (float *)s->output->extended_data[5];
     688           0 :     dstrs = (float *)s->output->extended_data[6];
     689             : 
     690           0 :     c_mag  = sqrtf(1.f - fabsf(x))   * ((y + 1.f) * .5f) * mag_total;
     691           0 :     l_mag  = sqrtf(.5f * ( x + 1.f)) * ((y + 1.f) * .5f) * mag_total;
     692           0 :     r_mag  = sqrtf(.5f * (-x + 1.f)) * ((y + 1.f) * .5f) * mag_total;
     693           0 :     lb_mag = sqrtf(.5f * ( x + 1.f)) * (1.f - ((y + 1.f) * .5f)) * mag_total;
     694           0 :     rb_mag = sqrtf(.5f * (-x + 1.f)) * (1.f - ((y + 1.f) * .5f)) * mag_total;
     695           0 :     ls_mag = sqrtf(.5f * ( x + 1.f)) * (1.f - fabsf(y)) * mag_total;
     696           0 :     rs_mag = sqrtf(.5f * (-x + 1.f)) * (1.f - fabsf(y)) * mag_total;
     697             : 
     698           0 :     dstl[2 * n    ] = l_mag * cosf(l_phase);
     699           0 :     dstl[2 * n + 1] = l_mag * sinf(l_phase);
     700             : 
     701           0 :     dstr[2 * n    ] = r_mag * cosf(r_phase);
     702           0 :     dstr[2 * n + 1] = r_mag * sinf(r_phase);
     703             : 
     704           0 :     dstc[2 * n    ] = c_mag * cosf(c_phase);
     705           0 :     dstc[2 * n + 1] = c_mag * sinf(c_phase);
     706             : 
     707           0 :     dstlb[2 * n    ] = lb_mag * cosf(l_phase);
     708           0 :     dstlb[2 * n + 1] = lb_mag * sinf(l_phase);
     709             : 
     710           0 :     dstrb[2 * n    ] = rb_mag * cosf(r_phase);
     711           0 :     dstrb[2 * n + 1] = rb_mag * sinf(r_phase);
     712             : 
     713           0 :     dstls[2 * n    ] = ls_mag * cosf(l_phase);
     714           0 :     dstls[2 * n + 1] = ls_mag * sinf(l_phase);
     715             : 
     716           0 :     dstrs[2 * n    ] = rs_mag * cosf(r_phase);
     717           0 :     dstrs[2 * n + 1] = rs_mag * sinf(r_phase);
     718           0 : }
     719             : 
     720           0 : static void upmix_7_1(AVFilterContext *ctx,
     721             :                       float l_phase,
     722             :                       float r_phase,
     723             :                       float c_phase,
     724             :                       float mag_total,
     725             :                       float x, float y,
     726             :                       int n)
     727             : {
     728             :     float lfe_mag, l_mag, r_mag, ls_mag, rs_mag, c_mag, lb_mag, rb_mag;
     729             :     float *dstc, *dstl, *dstr, *dstls, *dstrs, *dstlb, *dstrb, *dstlfe;
     730           0 :     AudioSurroundContext *s = ctx->priv;
     731             : 
     732           0 :     dstl  = (float *)s->output->extended_data[0];
     733           0 :     dstr  = (float *)s->output->extended_data[1];
     734           0 :     dstc  = (float *)s->output->extended_data[2];
     735           0 :     dstlfe = (float *)s->output->extended_data[3];
     736           0 :     dstlb = (float *)s->output->extended_data[4];
     737           0 :     dstrb = (float *)s->output->extended_data[5];
     738           0 :     dstls = (float *)s->output->extended_data[6];
     739           0 :     dstrs = (float *)s->output->extended_data[7];
     740             : 
     741           0 :     get_lfe(s->output_lfe, n, s->lowcut, s->highcut, &lfe_mag, &mag_total);
     742             : 
     743           0 :     c_mag  = sqrtf(1.f - fabsf(x))   * ((y + 1.f) * .5f) * mag_total;
     744           0 :     l_mag  = sqrtf(.5f * ( x + 1.f)) * ((y + 1.f) * .5f) * mag_total;
     745           0 :     r_mag  = sqrtf(.5f * (-x + 1.f)) * ((y + 1.f) * .5f) * mag_total;
     746           0 :     lb_mag = sqrtf(.5f * ( x + 1.f)) * (1.f - ((y + 1.f) * .5f)) * mag_total;
     747           0 :     rb_mag = sqrtf(.5f * (-x + 1.f)) * (1.f - ((y + 1.f) * .5f)) * mag_total;
     748           0 :     ls_mag = sqrtf(.5f * ( x + 1.f)) * (1.f - fabsf(y)) * mag_total;
     749           0 :     rs_mag = sqrtf(.5f * (-x + 1.f)) * (1.f - fabsf(y)) * mag_total;
     750             : 
     751           0 :     dstl[2 * n    ] = l_mag * cosf(l_phase);
     752           0 :     dstl[2 * n + 1] = l_mag * sinf(l_phase);
     753             : 
     754           0 :     dstr[2 * n    ] = r_mag * cosf(r_phase);
     755           0 :     dstr[2 * n + 1] = r_mag * sinf(r_phase);
     756             : 
     757           0 :     dstc[2 * n    ] = c_mag * cosf(c_phase);
     758           0 :     dstc[2 * n + 1] = c_mag * sinf(c_phase);
     759             : 
     760           0 :     dstlfe[2 * n    ] = lfe_mag * cosf(c_phase);
     761           0 :     dstlfe[2 * n + 1] = lfe_mag * sinf(c_phase);
     762             : 
     763           0 :     dstlb[2 * n    ] = lb_mag * cosf(l_phase);
     764           0 :     dstlb[2 * n + 1] = lb_mag * sinf(l_phase);
     765             : 
     766           0 :     dstrb[2 * n    ] = rb_mag * cosf(r_phase);
     767           0 :     dstrb[2 * n + 1] = rb_mag * sinf(r_phase);
     768             : 
     769           0 :     dstls[2 * n    ] = ls_mag * cosf(l_phase);
     770           0 :     dstls[2 * n + 1] = ls_mag * sinf(l_phase);
     771             : 
     772           0 :     dstrs[2 * n    ] = rs_mag * cosf(r_phase);
     773           0 :     dstrs[2 * n + 1] = rs_mag * sinf(r_phase);
     774           0 : }
     775             : 
     776           0 : static void upmix_7_1_5_0_side(AVFilterContext *ctx,
     777             :                                float c_re, float c_im,
     778             :                                float mag_totall, float mag_totalr,
     779             :                                float fl_phase, float fr_phase,
     780             :                                float bl_phase, float br_phase,
     781             :                                float sl_phase, float sr_phase,
     782             :                                float xl, float yl,
     783             :                                float xr, float yr,
     784             :                                int n)
     785             : {
     786             :     float fl_mag, fr_mag, ls_mag, rs_mag, lb_mag, rb_mag;
     787             :     float *dstc, *dstl, *dstr, *dstls, *dstrs, *dstlb, *dstrb, *dstlfe;
     788           0 :     float lfe_mag, c_phase, mag_total = (mag_totall + mag_totalr) * 0.5;
     789           0 :     AudioSurroundContext *s = ctx->priv;
     790             : 
     791           0 :     dstl  = (float *)s->output->extended_data[0];
     792           0 :     dstr  = (float *)s->output->extended_data[1];
     793           0 :     dstc  = (float *)s->output->extended_data[2];
     794           0 :     dstlfe = (float *)s->output->extended_data[3];
     795           0 :     dstlb = (float *)s->output->extended_data[4];
     796           0 :     dstrb = (float *)s->output->extended_data[5];
     797           0 :     dstls = (float *)s->output->extended_data[6];
     798           0 :     dstrs = (float *)s->output->extended_data[7];
     799             : 
     800           0 :     c_phase = atan2f(c_im, c_re);
     801             : 
     802           0 :     get_lfe(s->output_lfe, n, s->lowcut, s->highcut, &lfe_mag, &mag_total);
     803             : 
     804           0 :     fl_mag = sqrtf(.5f * (xl + 1.f)) * ((yl + 1.f) * .5f) * mag_totall;
     805           0 :     fr_mag = sqrtf(.5f * (xr + 1.f)) * ((yr + 1.f) * .5f) * mag_totalr;
     806           0 :     lb_mag = sqrtf(.5f * (-xl + 1.f)) * ((yl + 1.f) * .5f) * mag_totall;
     807           0 :     rb_mag = sqrtf(.5f * (-xr + 1.f)) * ((yr + 1.f) * .5f) * mag_totalr;
     808           0 :     ls_mag = sqrtf(1.f - fabsf(xl)) * ((yl + 1.f) * .5f) * mag_totall;
     809           0 :     rs_mag = sqrtf(1.f - fabsf(xr)) * ((yr + 1.f) * .5f) * mag_totalr;
     810             : 
     811           0 :     dstl[2 * n    ] = fl_mag * cosf(fl_phase);
     812           0 :     dstl[2 * n + 1] = fl_mag * sinf(fl_phase);
     813             : 
     814           0 :     dstr[2 * n    ] = fr_mag * cosf(fr_phase);
     815           0 :     dstr[2 * n + 1] = fr_mag * sinf(fr_phase);
     816             : 
     817           0 :     dstc[2 * n    ] = c_re;
     818           0 :     dstc[2 * n + 1] = c_im;
     819             : 
     820           0 :     dstlfe[2 * n    ] = lfe_mag * cosf(c_phase);
     821           0 :     dstlfe[2 * n + 1] = lfe_mag * sinf(c_phase);
     822             : 
     823           0 :     dstlb[2 * n    ] = lb_mag * cosf(bl_phase);
     824           0 :     dstlb[2 * n + 1] = lb_mag * sinf(bl_phase);
     825             : 
     826           0 :     dstrb[2 * n    ] = rb_mag * cosf(br_phase);
     827           0 :     dstrb[2 * n + 1] = rb_mag * sinf(br_phase);
     828             : 
     829           0 :     dstls[2 * n    ] = ls_mag * cosf(sl_phase);
     830           0 :     dstls[2 * n + 1] = ls_mag * sinf(sl_phase);
     831             : 
     832           0 :     dstrs[2 * n    ] = rs_mag * cosf(sr_phase);
     833           0 :     dstrs[2 * n + 1] = rs_mag * sinf(sr_phase);
     834           0 : }
     835             : 
     836           0 : static void upmix_7_1_5_1(AVFilterContext *ctx,
     837             :                           float c_re, float c_im,
     838             :                           float lfe_re, float lfe_im,
     839             :                           float mag_totall, float mag_totalr,
     840             :                           float fl_phase, float fr_phase,
     841             :                           float bl_phase, float br_phase,
     842             :                           float sl_phase, float sr_phase,
     843             :                           float xl, float yl,
     844             :                           float xr, float yr,
     845             :                           int n)
     846             : {
     847             :     float fl_mag, fr_mag, ls_mag, rs_mag, lb_mag, rb_mag;
     848             :     float *dstc, *dstl, *dstr, *dstls, *dstrs, *dstlb, *dstrb, *dstlfe;
     849           0 :     AudioSurroundContext *s = ctx->priv;
     850             : 
     851           0 :     dstl  = (float *)s->output->extended_data[0];
     852           0 :     dstr  = (float *)s->output->extended_data[1];
     853           0 :     dstc  = (float *)s->output->extended_data[2];
     854           0 :     dstlfe = (float *)s->output->extended_data[3];
     855           0 :     dstlb = (float *)s->output->extended_data[4];
     856           0 :     dstrb = (float *)s->output->extended_data[5];
     857           0 :     dstls = (float *)s->output->extended_data[6];
     858           0 :     dstrs = (float *)s->output->extended_data[7];
     859             : 
     860           0 :     fl_mag = sqrtf(.5f * (xl + 1.f)) * ((yl + 1.f) * .5f) * mag_totall;
     861           0 :     fr_mag = sqrtf(.5f * (xr + 1.f)) * ((yr + 1.f) * .5f) * mag_totalr;
     862           0 :     lb_mag = sqrtf(.5f * (-xl + 1.f)) * ((yl + 1.f) * .5f) * mag_totall;
     863           0 :     rb_mag = sqrtf(.5f * (-xr + 1.f)) * ((yr + 1.f) * .5f) * mag_totalr;
     864           0 :     ls_mag = sqrtf(1.f - fabsf(xl)) * ((yl + 1.f) * .5f) * mag_totall;
     865           0 :     rs_mag = sqrtf(1.f - fabsf(xr)) * ((yr + 1.f) * .5f) * mag_totalr;
     866             : 
     867           0 :     dstl[2 * n    ] = fl_mag * cosf(fl_phase);
     868           0 :     dstl[2 * n + 1] = fl_mag * sinf(fl_phase);
     869             : 
     870           0 :     dstr[2 * n    ] = fr_mag * cosf(fr_phase);
     871           0 :     dstr[2 * n + 1] = fr_mag * sinf(fr_phase);
     872             : 
     873           0 :     dstc[2 * n    ] = c_re;
     874           0 :     dstc[2 * n + 1] = c_im;
     875             : 
     876           0 :     dstlfe[2 * n    ] = lfe_re;
     877           0 :     dstlfe[2 * n + 1] = lfe_im;
     878             : 
     879           0 :     dstlb[2 * n    ] = lb_mag * cosf(bl_phase);
     880           0 :     dstlb[2 * n + 1] = lb_mag * sinf(bl_phase);
     881             : 
     882           0 :     dstrb[2 * n    ] = rb_mag * cosf(br_phase);
     883           0 :     dstrb[2 * n + 1] = rb_mag * sinf(br_phase);
     884             : 
     885           0 :     dstls[2 * n    ] = ls_mag * cosf(sl_phase);
     886           0 :     dstls[2 * n + 1] = ls_mag * sinf(sl_phase);
     887             : 
     888           0 :     dstrs[2 * n    ] = rs_mag * cosf(sr_phase);
     889           0 :     dstrs[2 * n + 1] = rs_mag * sinf(sr_phase);
     890           0 : }
     891             : 
     892           0 : static void filter_stereo(AVFilterContext *ctx)
     893             : {
     894           0 :     AudioSurroundContext *s = ctx->priv;
     895             :     float *srcl, *srcr;
     896             :     int n;
     897             : 
     898           0 :     srcl = (float *)s->input->extended_data[0];
     899           0 :     srcr = (float *)s->input->extended_data[1];
     900             : 
     901           0 :     for (n = 0; n < s->buf_size; n++) {
     902           0 :         float l_re = srcl[2 * n], r_re = srcr[2 * n];
     903           0 :         float l_im = srcl[2 * n + 1], r_im = srcr[2 * n + 1];
     904           0 :         float c_phase = atan2f(l_im + r_im, l_re + r_re);
     905           0 :         float l_mag = hypotf(l_re, l_im);
     906           0 :         float r_mag = hypotf(r_re, r_im);
     907           0 :         float l_phase = atan2f(l_im, l_re);
     908           0 :         float r_phase = atan2f(r_im, r_re);
     909           0 :         float phase_dif = fabsf(l_phase - r_phase);
     910           0 :         float mag_dif = (l_mag - r_mag) / (l_mag + r_mag);
     911           0 :         float mag_total = hypotf(l_mag, r_mag);
     912             :         float x, y;
     913             : 
     914           0 :         if (phase_dif > M_PI)
     915           0 :             phase_dif = 2 * M_PI - phase_dif;
     916             : 
     917           0 :         stereo_position(mag_dif, phase_dif, &x, &y);
     918             : 
     919           0 :         s->upmix_stereo(ctx, l_phase, r_phase, c_phase, mag_total, x, y, n);
     920             :     }
     921           0 : }
     922             : 
     923           0 : static void filter_surround(AVFilterContext *ctx)
     924             : {
     925           0 :     AudioSurroundContext *s = ctx->priv;
     926             :     float *srcl, *srcr, *srcc;
     927             :     int n;
     928             : 
     929           0 :     srcl = (float *)s->input->extended_data[0];
     930           0 :     srcr = (float *)s->input->extended_data[1];
     931           0 :     srcc = (float *)s->input->extended_data[2];
     932             : 
     933           0 :     for (n = 0; n < s->buf_size; n++) {
     934           0 :         float l_re = srcl[2 * n], r_re = srcr[2 * n];
     935           0 :         float l_im = srcl[2 * n + 1], r_im = srcr[2 * n + 1];
     936           0 :         float c_re = srcc[2 * n], c_im = srcc[2 * n + 1];
     937           0 :         float c_mag = hypotf(c_re, c_im);
     938           0 :         float c_phase = atan2f(c_im, c_re);
     939           0 :         float l_mag = hypotf(l_re, l_im);
     940           0 :         float r_mag = hypotf(r_re, r_im);
     941           0 :         float l_phase = atan2f(l_im, l_re);
     942           0 :         float r_phase = atan2f(r_im, r_re);
     943           0 :         float phase_dif = fabsf(l_phase - r_phase);
     944           0 :         float mag_dif = (l_mag - r_mag) / (l_mag + r_mag);
     945           0 :         float mag_total = hypotf(l_mag, r_mag);
     946             :         float x, y;
     947             : 
     948           0 :         if (phase_dif > M_PI)
     949           0 :             phase_dif = 2 * M_PI - phase_dif;
     950             : 
     951           0 :         stereo_position(mag_dif, phase_dif, &x, &y);
     952             : 
     953           0 :         s->upmix_3_0(ctx, l_phase, r_phase, c_phase, c_mag, mag_total, x, y, n);
     954             :     }
     955           0 : }
     956             : 
     957           0 : static void filter_2_1(AVFilterContext *ctx)
     958             : {
     959           0 :     AudioSurroundContext *s = ctx->priv;
     960             :     float *srcl, *srcr, *srclfe;
     961             :     int n;
     962             : 
     963           0 :     srcl = (float *)s->input->extended_data[0];
     964           0 :     srcr = (float *)s->input->extended_data[1];
     965           0 :     srclfe = (float *)s->input->extended_data[2];
     966             : 
     967           0 :     for (n = 0; n < s->buf_size; n++) {
     968           0 :         float l_re = srcl[2 * n], r_re = srcr[2 * n];
     969           0 :         float l_im = srcl[2 * n + 1], r_im = srcr[2 * n + 1];
     970           0 :         float lfe_re = srclfe[2 * n], lfe_im = srclfe[2 * n + 1];
     971           0 :         float c_phase = atan2f(l_im + r_im, l_re + r_re);
     972           0 :         float l_mag = hypotf(l_re, l_im);
     973           0 :         float r_mag = hypotf(r_re, r_im);
     974           0 :         float l_phase = atan2f(l_im, l_re);
     975           0 :         float r_phase = atan2f(r_im, r_re);
     976           0 :         float phase_dif = fabsf(l_phase - r_phase);
     977           0 :         float mag_dif = (l_mag - r_mag) / (l_mag + r_mag);
     978           0 :         float mag_total = hypotf(l_mag, r_mag);
     979             :         float x, y;
     980             : 
     981           0 :         if (phase_dif > M_PI)
     982           0 :             phase_dif = 2 * M_PI - phase_dif;
     983             : 
     984           0 :         stereo_position(mag_dif, phase_dif, &x, &y);
     985             : 
     986           0 :         s->upmix_2_1(ctx, l_phase, r_phase, c_phase, mag_total, lfe_re, lfe_im, x, y, n);
     987             :     }
     988           0 : }
     989             : 
     990           0 : static void filter_5_0_side(AVFilterContext *ctx)
     991             : {
     992           0 :     AudioSurroundContext *s = ctx->priv;
     993             :     float *srcl, *srcr, *srcc, *srcsl, *srcsr;
     994             :     int n;
     995             : 
     996           0 :     srcl = (float *)s->input->extended_data[0];
     997           0 :     srcr = (float *)s->input->extended_data[1];
     998           0 :     srcc = (float *)s->input->extended_data[2];
     999           0 :     srcsl = (float *)s->input->extended_data[3];
    1000           0 :     srcsr = (float *)s->input->extended_data[4];
    1001             : 
    1002           0 :     for (n = 0; n < s->buf_size; n++) {
    1003           0 :         float fl_re = srcl[2 * n], fr_re = srcr[2 * n];
    1004           0 :         float fl_im = srcl[2 * n + 1], fr_im = srcr[2 * n + 1];
    1005           0 :         float c_re = srcc[2 * n], c_im = srcc[2 * n + 1];
    1006           0 :         float sl_re = srcsl[2 * n], sl_im = srcsl[2 * n + 1];
    1007           0 :         float sr_re = srcsr[2 * n], sr_im = srcsr[2 * n + 1];
    1008           0 :         float fl_mag = hypotf(fl_re, fl_im);
    1009           0 :         float fr_mag = hypotf(fr_re, fr_im);
    1010           0 :         float fl_phase = atan2f(fl_im, fl_re);
    1011           0 :         float fr_phase = atan2f(fr_im, fr_re);
    1012           0 :         float sl_mag = hypotf(sl_re, sl_im);
    1013           0 :         float sr_mag = hypotf(sr_re, sr_im);
    1014           0 :         float sl_phase = atan2f(sl_im, sl_re);
    1015           0 :         float sr_phase = atan2f(sr_im, sr_re);
    1016           0 :         float phase_difl = fabsf(fl_phase - sl_phase);
    1017           0 :         float phase_difr = fabsf(fr_phase - sr_phase);
    1018           0 :         float mag_difl = (fl_mag - sl_mag) / (fl_mag + sl_mag);
    1019           0 :         float mag_difr = (fr_mag - sr_mag) / (fr_mag + sr_mag);
    1020           0 :         float mag_totall = hypotf(fl_mag, sl_mag);
    1021           0 :         float mag_totalr = hypotf(fr_mag, sr_mag);
    1022           0 :         float bl_phase = atan2f(fl_im + sl_im, fl_re + sl_re);
    1023           0 :         float br_phase = atan2f(fr_im + sr_im, fr_re + sr_re);
    1024             :         float xl, yl;
    1025             :         float xr, yr;
    1026             : 
    1027           0 :         if (phase_difl > M_PI)
    1028           0 :             phase_difl = 2 * M_PI - phase_difl;
    1029             : 
    1030           0 :         if (phase_difr > M_PI)
    1031           0 :             phase_difr = 2 * M_PI - phase_difr;
    1032             : 
    1033           0 :         stereo_position(mag_difl, phase_difl, &xl, &yl);
    1034           0 :         stereo_position(mag_difr, phase_difr, &xr, &yr);
    1035             : 
    1036           0 :         s->upmix_5_0(ctx, c_re, c_im,
    1037             :                      mag_totall, mag_totalr,
    1038             :                      fl_phase, fr_phase,
    1039             :                      bl_phase, br_phase,
    1040             :                      sl_phase, sr_phase,
    1041             :                      xl, yl, xr, yr, n);
    1042             :     }
    1043           0 : }
    1044             : 
    1045           0 : static void filter_5_1_side(AVFilterContext *ctx)
    1046             : {
    1047           0 :     AudioSurroundContext *s = ctx->priv;
    1048             :     float *srcl, *srcr, *srcc, *srclfe, *srcsl, *srcsr;
    1049             :     int n;
    1050             : 
    1051           0 :     srcl = (float *)s->input->extended_data[0];
    1052           0 :     srcr = (float *)s->input->extended_data[1];
    1053           0 :     srcc = (float *)s->input->extended_data[2];
    1054           0 :     srclfe = (float *)s->input->extended_data[3];
    1055           0 :     srcsl = (float *)s->input->extended_data[4];
    1056           0 :     srcsr = (float *)s->input->extended_data[5];
    1057             : 
    1058           0 :     for (n = 0; n < s->buf_size; n++) {
    1059           0 :         float fl_re = srcl[2 * n], fr_re = srcr[2 * n];
    1060           0 :         float fl_im = srcl[2 * n + 1], fr_im = srcr[2 * n + 1];
    1061           0 :         float c_re = srcc[2 * n], c_im = srcc[2 * n + 1];
    1062           0 :         float lfe_re = srclfe[2 * n], lfe_im = srclfe[2 * n + 1];
    1063           0 :         float sl_re = srcsl[2 * n], sl_im = srcsl[2 * n + 1];
    1064           0 :         float sr_re = srcsr[2 * n], sr_im = srcsr[2 * n + 1];
    1065           0 :         float fl_mag = hypotf(fl_re, fl_im);
    1066           0 :         float fr_mag = hypotf(fr_re, fr_im);
    1067           0 :         float fl_phase = atan2f(fl_im, fl_re);
    1068           0 :         float fr_phase = atan2f(fr_im, fr_re);
    1069           0 :         float sl_mag = hypotf(sl_re, sl_im);
    1070           0 :         float sr_mag = hypotf(sr_re, sr_im);
    1071           0 :         float sl_phase = atan2f(sl_im, sl_re);
    1072           0 :         float sr_phase = atan2f(sr_im, sr_re);
    1073           0 :         float phase_difl = fabsf(fl_phase - sl_phase);
    1074           0 :         float phase_difr = fabsf(fr_phase - sr_phase);
    1075           0 :         float mag_difl = (fl_mag - sl_mag) / (fl_mag + sl_mag);
    1076           0 :         float mag_difr = (fr_mag - sr_mag) / (fr_mag + sr_mag);
    1077           0 :         float mag_totall = hypotf(fl_mag, sl_mag);
    1078           0 :         float mag_totalr = hypotf(fr_mag, sr_mag);
    1079           0 :         float bl_phase = atan2f(fl_im + sl_im, fl_re + sl_re);
    1080           0 :         float br_phase = atan2f(fr_im + sr_im, fr_re + sr_re);
    1081             :         float xl, yl;
    1082             :         float xr, yr;
    1083             : 
    1084           0 :         if (phase_difl > M_PI)
    1085           0 :             phase_difl = 2 * M_PI - phase_difl;
    1086             : 
    1087           0 :         if (phase_difr > M_PI)
    1088           0 :             phase_difr = 2 * M_PI - phase_difr;
    1089             : 
    1090           0 :         stereo_position(mag_difl, phase_difl, &xl, &yl);
    1091           0 :         stereo_position(mag_difr, phase_difr, &xr, &yr);
    1092             : 
    1093           0 :         s->upmix_5_1(ctx, c_re, c_im, lfe_re, lfe_im,
    1094             :                      mag_totall, mag_totalr,
    1095             :                      fl_phase, fr_phase,
    1096             :                      bl_phase, br_phase,
    1097             :                      sl_phase, sr_phase,
    1098             :                      xl, yl, xr, yr, n);
    1099             :     }
    1100           0 : }
    1101             : 
    1102           0 : static void filter_5_1_back(AVFilterContext *ctx)
    1103             : {
    1104           0 :     AudioSurroundContext *s = ctx->priv;
    1105             :     float *srcl, *srcr, *srcc, *srclfe, *srcbl, *srcbr;
    1106             :     int n;
    1107             : 
    1108           0 :     srcl = (float *)s->input->extended_data[0];
    1109           0 :     srcr = (float *)s->input->extended_data[1];
    1110           0 :     srcc = (float *)s->input->extended_data[2];
    1111           0 :     srclfe = (float *)s->input->extended_data[3];
    1112           0 :     srcbl = (float *)s->input->extended_data[4];
    1113           0 :     srcbr = (float *)s->input->extended_data[5];
    1114             : 
    1115           0 :     for (n = 0; n < s->buf_size; n++) {
    1116           0 :         float fl_re = srcl[2 * n], fr_re = srcr[2 * n];
    1117           0 :         float fl_im = srcl[2 * n + 1], fr_im = srcr[2 * n + 1];
    1118           0 :         float c_re = srcc[2 * n], c_im = srcc[2 * n + 1];
    1119           0 :         float lfe_re = srclfe[2 * n], lfe_im = srclfe[2 * n + 1];
    1120           0 :         float bl_re = srcbl[2 * n], bl_im = srcbl[2 * n + 1];
    1121           0 :         float br_re = srcbr[2 * n], br_im = srcbr[2 * n + 1];
    1122           0 :         float fl_mag = hypotf(fl_re, fl_im);
    1123           0 :         float fr_mag = hypotf(fr_re, fr_im);
    1124           0 :         float fl_phase = atan2f(fl_im, fl_re);
    1125           0 :         float fr_phase = atan2f(fr_im, fr_re);
    1126           0 :         float bl_mag = hypotf(bl_re, bl_im);
    1127           0 :         float br_mag = hypotf(br_re, br_im);
    1128           0 :         float bl_phase = atan2f(bl_im, bl_re);
    1129           0 :         float br_phase = atan2f(br_im, br_re);
    1130           0 :         float phase_difl = fabsf(fl_phase - bl_phase);
    1131           0 :         float phase_difr = fabsf(fr_phase - br_phase);
    1132           0 :         float mag_difl = (fl_mag - bl_mag) / (fl_mag + bl_mag);
    1133           0 :         float mag_difr = (fr_mag - br_mag) / (fr_mag + br_mag);
    1134           0 :         float mag_totall = hypotf(fl_mag, bl_mag);
    1135           0 :         float mag_totalr = hypotf(fr_mag, br_mag);
    1136           0 :         float sl_phase = atan2f(fl_im + bl_im, fl_re + bl_re);
    1137           0 :         float sr_phase = atan2f(fr_im + br_im, fr_re + br_re);
    1138             :         float xl, yl;
    1139             :         float xr, yr;
    1140             : 
    1141           0 :         if (phase_difl > M_PI)
    1142           0 :             phase_difl = 2 * M_PI - phase_difl;
    1143             : 
    1144           0 :         if (phase_difr > M_PI)
    1145           0 :             phase_difr = 2 * M_PI - phase_difr;
    1146             : 
    1147           0 :         stereo_position(mag_difl, phase_difl, &xl, &yl);
    1148           0 :         stereo_position(mag_difr, phase_difr, &xr, &yr);
    1149             : 
    1150           0 :         s->upmix_5_1(ctx, c_re, c_im, lfe_re, lfe_im,
    1151             :                      mag_totall, mag_totalr,
    1152             :                      fl_phase, fr_phase,
    1153             :                      bl_phase, br_phase,
    1154             :                      sl_phase, sr_phase,
    1155             :                      xl, yl, xr, yr, n);
    1156             :     }
    1157           0 : }
    1158             : 
    1159           0 : static int init(AVFilterContext *ctx)
    1160             : {
    1161           0 :     AudioSurroundContext *s = ctx->priv;
    1162             :     float overlap;
    1163             :     int i;
    1164             : 
    1165           0 :     if (!(s->out_channel_layout = av_get_channel_layout(s->out_channel_layout_str))) {
    1166           0 :         av_log(ctx, AV_LOG_ERROR, "Error parsing output channel layout '%s'.\n",
    1167             :                s->out_channel_layout_str);
    1168           0 :         return AVERROR(EINVAL);
    1169             :     }
    1170             : 
    1171           0 :     if (!(s->in_channel_layout = av_get_channel_layout(s->in_channel_layout_str))) {
    1172           0 :         av_log(ctx, AV_LOG_ERROR, "Error parsing input channel layout '%s'.\n",
    1173             :                s->in_channel_layout_str);
    1174           0 :         return AVERROR(EINVAL);
    1175             :     }
    1176             : 
    1177           0 :     if (s->lowcutf >= s->highcutf) {
    1178           0 :         av_log(ctx, AV_LOG_ERROR, "Low cut-off '%d' should be less than high cut-off '%d'.\n",
    1179             :                s->lowcutf, s->highcutf);
    1180           0 :         return AVERROR(EINVAL);
    1181             :     }
    1182             : 
    1183           0 :     switch (s->in_channel_layout) {
    1184           0 :     case AV_CH_LAYOUT_STEREO:
    1185           0 :         s->filter = filter_stereo;
    1186           0 :         switch (s->out_channel_layout) {
    1187           0 :         case AV_CH_LAYOUT_MONO:
    1188           0 :             s->upmix_stereo = upmix_1_0;
    1189           0 :             break;
    1190           0 :         case AV_CH_LAYOUT_STEREO:
    1191           0 :             s->upmix_stereo = upmix_stereo;
    1192           0 :             break;
    1193           0 :         case AV_CH_LAYOUT_2POINT1:
    1194           0 :             s->upmix_stereo = upmix_2_1;
    1195           0 :             break;
    1196           0 :         case AV_CH_LAYOUT_SURROUND:
    1197           0 :             s->upmix_stereo = upmix_3_0;
    1198           0 :             break;
    1199           0 :         case AV_CH_LAYOUT_3POINT1:
    1200           0 :             s->upmix_stereo = upmix_3_1;
    1201           0 :             break;
    1202           0 :         case AV_CH_LAYOUT_4POINT0:
    1203           0 :             s->upmix_stereo = upmix_4_0;
    1204           0 :             break;
    1205           0 :         case AV_CH_LAYOUT_4POINT1:
    1206           0 :             s->upmix_stereo = upmix_4_1;
    1207           0 :             break;
    1208           0 :         case AV_CH_LAYOUT_5POINT0_BACK:
    1209           0 :             s->upmix_stereo = upmix_5_0_back;
    1210           0 :             break;
    1211           0 :         case AV_CH_LAYOUT_5POINT1_BACK:
    1212           0 :             s->upmix_stereo = upmix_5_1_back;
    1213           0 :             break;
    1214           0 :         case AV_CH_LAYOUT_7POINT0:
    1215           0 :             s->upmix_stereo = upmix_7_0;
    1216           0 :             break;
    1217           0 :         case AV_CH_LAYOUT_7POINT1:
    1218           0 :             s->upmix_stereo = upmix_7_1;
    1219           0 :             break;
    1220           0 :         default:
    1221           0 :             goto fail;
    1222             :         }
    1223           0 :         break;
    1224           0 :     case AV_CH_LAYOUT_2POINT1:
    1225           0 :         s->filter = filter_2_1;
    1226           0 :         switch (s->out_channel_layout) {
    1227           0 :         case AV_CH_LAYOUT_5POINT1_BACK:
    1228           0 :             s->upmix_2_1 = upmix_5_1_back_2_1;
    1229           0 :             break;
    1230           0 :         default:
    1231           0 :             goto fail;
    1232             :         }
    1233           0 :         break;
    1234           0 :     case AV_CH_LAYOUT_SURROUND:
    1235           0 :         s->filter = filter_surround;
    1236           0 :         switch (s->out_channel_layout) {
    1237           0 :         case AV_CH_LAYOUT_3POINT1:
    1238           0 :             s->upmix_3_0 = upmix_3_1_surround;
    1239           0 :             break;
    1240           0 :         case AV_CH_LAYOUT_5POINT1_BACK:
    1241           0 :             s->upmix_3_0 = upmix_5_1_back_surround;
    1242           0 :             break;
    1243           0 :         default:
    1244           0 :             goto fail;
    1245             :         }
    1246           0 :         break;
    1247           0 :     case AV_CH_LAYOUT_5POINT0:
    1248           0 :         s->filter = filter_5_0_side;
    1249           0 :         switch (s->out_channel_layout) {
    1250           0 :         case AV_CH_LAYOUT_7POINT1:
    1251           0 :             s->upmix_5_0 = upmix_7_1_5_0_side;
    1252           0 :             break;
    1253           0 :         default:
    1254           0 :             goto fail;
    1255             :         }
    1256           0 :         break;
    1257           0 :     case AV_CH_LAYOUT_5POINT1:
    1258           0 :         s->filter = filter_5_1_side;
    1259           0 :         switch (s->out_channel_layout) {
    1260           0 :         case AV_CH_LAYOUT_7POINT1:
    1261           0 :             s->upmix_5_1 = upmix_7_1_5_1;
    1262           0 :             break;
    1263           0 :         default:
    1264           0 :             goto fail;
    1265             :         }
    1266           0 :         break;
    1267           0 :     case AV_CH_LAYOUT_5POINT1_BACK:
    1268           0 :         s->filter = filter_5_1_back;
    1269           0 :         switch (s->out_channel_layout) {
    1270           0 :         case AV_CH_LAYOUT_7POINT1:
    1271           0 :             s->upmix_5_1 = upmix_7_1_5_1;
    1272           0 :             break;
    1273           0 :         default:
    1274           0 :             goto fail;
    1275             :         }
    1276           0 :         break;
    1277             :     default:
    1278           0 : fail:
    1279           0 :         av_log(ctx, AV_LOG_ERROR, "Unsupported upmix: '%s' -> '%s'.\n",
    1280             :                s->in_channel_layout_str, s->out_channel_layout_str);
    1281           0 :         return AVERROR(EINVAL);
    1282             :     }
    1283             : 
    1284           0 :     s->buf_size = 4096;
    1285           0 :     s->pts = AV_NOPTS_VALUE;
    1286             : 
    1287           0 :     s->window_func_lut = av_calloc(s->buf_size, sizeof(*s->window_func_lut));
    1288           0 :     if (!s->window_func_lut)
    1289           0 :         return AVERROR(ENOMEM);
    1290             : 
    1291           0 :     for (i = 0; i < s->buf_size; i++)
    1292           0 :         s->window_func_lut[i] = sqrtf(0.5 * (1 - cosf(2 * M_PI * i / s->buf_size)) / s->buf_size);
    1293           0 :     overlap = .5;
    1294           0 :     s->hop_size = s->buf_size * (1. - overlap);
    1295             : 
    1296           0 :     return 0;
    1297             : }
    1298             : 
    1299           0 : static int fft_channel(AVFilterContext *ctx, void *arg, int ch, int nb_jobs)
    1300             : {
    1301           0 :     AudioSurroundContext *s = ctx->priv;
    1302           0 :     const float level_in = s->input_levels[ch];
    1303             :     float *dst;
    1304             :     int n;
    1305             : 
    1306           0 :     memset(s->input->extended_data[ch] + s->buf_size * sizeof(float), 0, s->buf_size * sizeof(float));
    1307             : 
    1308           0 :     dst = (float *)s->input->extended_data[ch];
    1309           0 :     for (n = 0; n < s->buf_size; n++) {
    1310           0 :         dst[n] *= s->window_func_lut[n] * level_in;
    1311             :     }
    1312             : 
    1313           0 :     av_rdft_calc(s->rdft[ch], (float *)s->input->extended_data[ch]);
    1314             : 
    1315           0 :     return 0;
    1316             : }
    1317             : 
    1318           0 : static int ifft_channel(AVFilterContext *ctx, void *arg, int ch, int nb_jobs)
    1319             : {
    1320           0 :     AudioSurroundContext *s = ctx->priv;
    1321           0 :     const float level_out = s->output_levels[ch];
    1322           0 :     AVFrame *out = arg;
    1323             :     float *dst, *ptr;
    1324             :     int n;
    1325             : 
    1326           0 :     av_rdft_calc(s->irdft[ch], (float *)s->output->extended_data[ch]);
    1327             : 
    1328           0 :     dst = (float *)s->output->extended_data[ch];
    1329           0 :     ptr = (float *)s->overlap_buffer->extended_data[ch];
    1330             : 
    1331           0 :     memmove(s->overlap_buffer->extended_data[ch],
    1332           0 :             s->overlap_buffer->extended_data[ch] + s->hop_size * sizeof(float),
    1333           0 :             s->buf_size * sizeof(float));
    1334           0 :     memset(s->overlap_buffer->extended_data[ch] + s->buf_size * sizeof(float),
    1335           0 :            0, s->hop_size * sizeof(float));
    1336             : 
    1337           0 :     for (n = 0; n < s->buf_size; n++) {
    1338           0 :         ptr[n] += dst[n] * s->window_func_lut[n] * level_out;
    1339             :     }
    1340             : 
    1341           0 :     ptr = (float *)s->overlap_buffer->extended_data[ch];
    1342           0 :     dst = (float *)out->extended_data[ch];
    1343           0 :     memcpy(dst, ptr, s->hop_size * sizeof(float));
    1344             : 
    1345           0 :     return 0;
    1346             : }
    1347             : 
    1348           0 : static int filter_frame(AVFilterLink *inlink, AVFrame *in)
    1349             : {
    1350           0 :     AVFilterContext *ctx = inlink->dst;
    1351           0 :     AVFilterLink *outlink = ctx->outputs[0];
    1352           0 :     AudioSurroundContext *s = ctx->priv;
    1353             :     int ret;
    1354             : 
    1355           0 :     ret = av_audio_fifo_write(s->fifo, (void **)in->extended_data,
    1356           0 :                               in->nb_samples);
    1357           0 :     if (ret >= 0 && s->pts == AV_NOPTS_VALUE)
    1358           0 :         s->pts = in->pts;
    1359             : 
    1360           0 :     av_frame_free(&in);
    1361           0 :     if (ret < 0)
    1362           0 :         return ret;
    1363             : 
    1364           0 :     while (av_audio_fifo_size(s->fifo) >= s->buf_size) {
    1365             :         AVFrame *out;
    1366             : 
    1367           0 :         ret = av_audio_fifo_peek(s->fifo, (void **)s->input->extended_data, s->buf_size);
    1368           0 :         if (ret < 0)
    1369           0 :             return ret;
    1370             : 
    1371           0 :         ctx->internal->execute(ctx, fft_channel, NULL, NULL, inlink->channels);
    1372             : 
    1373           0 :         s->filter(ctx);
    1374             : 
    1375           0 :         out = ff_get_audio_buffer(outlink, s->hop_size);
    1376           0 :         if (!out)
    1377           0 :             return AVERROR(ENOMEM);
    1378             : 
    1379           0 :         ctx->internal->execute(ctx, ifft_channel, out, NULL, outlink->channels);
    1380             : 
    1381           0 :         out->pts = s->pts;
    1382           0 :         if (s->pts != AV_NOPTS_VALUE)
    1383           0 :             s->pts += av_rescale_q(out->nb_samples, (AVRational){1, outlink->sample_rate}, outlink->time_base);
    1384           0 :         av_audio_fifo_drain(s->fifo, s->hop_size);
    1385           0 :         ret = ff_filter_frame(outlink, out);
    1386           0 :         if (ret < 0)
    1387           0 :             return ret;
    1388             :     }
    1389             : 
    1390           0 :     return 0;
    1391             : }
    1392             : 
    1393           0 : static av_cold void uninit(AVFilterContext *ctx)
    1394             : {
    1395           0 :     AudioSurroundContext *s = ctx->priv;
    1396             :     int ch;
    1397             : 
    1398           0 :     av_frame_free(&s->input);
    1399           0 :     av_frame_free(&s->output);
    1400           0 :     av_frame_free(&s->overlap_buffer);
    1401             : 
    1402           0 :     for (ch = 0; ch < s->nb_in_channels; ch++) {
    1403           0 :         av_rdft_end(s->rdft[ch]);
    1404             :     }
    1405           0 :     for (ch = 0; ch < s->nb_out_channels; ch++) {
    1406           0 :         av_rdft_end(s->irdft[ch]);
    1407             :     }
    1408           0 :     av_freep(&s->input_levels);
    1409           0 :     av_freep(&s->output_levels);
    1410           0 :     av_freep(&s->rdft);
    1411           0 :     av_freep(&s->irdft);
    1412           0 :     av_audio_fifo_free(s->fifo);
    1413           0 :     av_freep(&s->window_func_lut);
    1414           0 : }
    1415             : 
    1416             : #define OFFSET(x) offsetof(AudioSurroundContext, x)
    1417             : #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
    1418             : 
    1419             : static const AVOption surround_options[] = {
    1420             :     { "chl_out",   "set output channel layout", OFFSET(out_channel_layout_str), AV_OPT_TYPE_STRING, {.str="5.1"}, 0,   0, FLAGS },
    1421             :     { "chl_in",    "set input channel layout",  OFFSET(in_channel_layout_str),  AV_OPT_TYPE_STRING, {.str="stereo"},0, 0, FLAGS },
    1422             :     { "level_in",  "set input level",           OFFSET(level_in),               AV_OPT_TYPE_FLOAT,  {.dbl=1},     0,  10, FLAGS },
    1423             :     { "level_out", "set output level",          OFFSET(level_out),              AV_OPT_TYPE_FLOAT,  {.dbl=1},     0,  10, FLAGS },
    1424             :     { "lfe",       "output LFE",                OFFSET(output_lfe),             AV_OPT_TYPE_BOOL,   {.i64=1},     0,   1, FLAGS },
    1425             :     { "lfe_low",   "LFE low cut off",           OFFSET(lowcutf),                AV_OPT_TYPE_INT,    {.i64=128},   0, 256, FLAGS },
    1426             :     { "lfe_high",  "LFE high cut off",          OFFSET(highcutf),               AV_OPT_TYPE_INT,    {.i64=256},   0, 512, FLAGS },
    1427             :     { "fc_in",     "set front center channel input level",  OFFSET(fc_in),      AV_OPT_TYPE_FLOAT,  {.dbl=1},     0,  10, FLAGS },
    1428             :     { "fc_out",    "set front center channel output level", OFFSET(fc_out),     AV_OPT_TYPE_FLOAT,  {.dbl=1},     0,  10, FLAGS },
    1429             :     { "lfe_in",    "set lfe channel input level",  OFFSET(lfe_in),              AV_OPT_TYPE_FLOAT,  {.dbl=1},     0,  10, FLAGS },
    1430             :     { "lfe_out",   "set lfe channel output level", OFFSET(lfe_out),             AV_OPT_TYPE_FLOAT,  {.dbl=1},     0,  10, FLAGS },
    1431             :     { NULL }
    1432             : };
    1433             : 
    1434             : AVFILTER_DEFINE_CLASS(surround);
    1435             : 
    1436             : static const AVFilterPad inputs[] = {
    1437             :     {
    1438             :         .name         = "default",
    1439             :         .type         = AVMEDIA_TYPE_AUDIO,
    1440             :         .filter_frame = filter_frame,
    1441             :         .config_props = config_input,
    1442             :     },
    1443             :     { NULL }
    1444             : };
    1445             : 
    1446             : static const AVFilterPad outputs[] = {
    1447             :     {
    1448             :         .name         = "default",
    1449             :         .type         = AVMEDIA_TYPE_AUDIO,
    1450             :         .config_props = config_output,
    1451             :     },
    1452             :     { NULL }
    1453             : };
    1454             : 
    1455             : AVFilter ff_af_surround = {
    1456             :     .name           = "surround",
    1457             :     .description    = NULL_IF_CONFIG_SMALL("Apply audio surround upmix filter."),
    1458             :     .query_formats  = query_formats,
    1459             :     .priv_size      = sizeof(AudioSurroundContext),
    1460             :     .priv_class     = &surround_class,
    1461             :     .init           = init,
    1462             :     .uninit         = uninit,
    1463             :     .inputs         = inputs,
    1464             :     .outputs        = outputs,
    1465             :     .flags          = AVFILTER_FLAG_SLICE_THREADS,
    1466             : };

Generated by: LCOV version 1.13