LCOV - code coverage report
Current view: top level - lib_com - ivas_fb_mixer_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 780 810 96.3 %
Date: 2025-05-03 01:55:50 Functions: 18 18 100.0 %

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : #include <stdint.h>
      34             : #include <assert.h>
      35             : #include <math.h>
      36             : #include "options.h"
      37             : #include "prot_fx.h"
      38             : #include "rom_com.h"
      39             : #include "ivas_rom_com.h"
      40             : #include "wmc_auto.h"
      41             : #include "ivas_prot_fx.h"
      42             : #include "ivas_rom_com_fx.h"
      43             : 
      44             : 
      45             : /*------------------------------------------------------------------------------------------*
      46             :  * Static functions declarations
      47             :  *------------------------------------------------------------------------------------------*/
      48             : static void ivas_cmult_fix(
      49             :     Word32 in1_re,   // i: Qx
      50             :     Word32 in1_im,   // i: Qx
      51             :     Word32 in2_re,   // i: Qx
      52             :     Word32 in2_im,   // i: Qx
      53             :     Word32 *out1_re, // o: 2 * Qx - 31
      54             :     Word32 *out1_im  // o: 2 * Qx - 31
      55             : );
      56             : static void ivas_get_active_bins_fx( const Word16 **pActive_bins, const Word16 **pActive_bins_abs, const Word16 **pStart_offset, const Word16 **pStart_offset_ab, const Word32 sampling_rate );
      57             : static void ivas_get_ld_fb_resp_fx( Word32 **ppIdeal_FRs_re_fx, Word32 **ppIdeal_FRs_im_fx, Word32 **ppNew_FRs_re_fx, Word32 **ppNew_FRs_im_fx, const Word16 *pActive_bins, const Word16 *pStart_offset, const Word16 num_bands, const Word16 delay, const Word32 sampling_rate );
      58             : static ivas_error ivas_filterbank_setup_fx( IVAS_FB_MIXER_HANDLE hFbMixer, const Word32 sampling_rate, Word16 *index );
      59             : static ivas_error ivas_fb_mixer_get_window_fx( const Word16 fade_len, const Word32 sampling_rate, const Word16 **pWindow );
      60             : 
      61             : /*-----------------------------------------------------------------------------------------*
      62             :  * Function ivas_get_num_bands_from_bw_idx()
      63             :  *
      64             :  * Get number of bands from BW index
      65             :  *-----------------------------------------------------------------------------------------*/
      66             : 
      67             : /*! r: number of spectral bands */
      68      388777 : Word16 ivas_get_num_bands_from_bw_idx(
      69             :     const Word16 bwidth /* i  : audio bandwidth    */
      70             : )
      71             : {
      72             :     Word16 num_active_bands;
      73             : 
      74      388777 :     assert( bwidth > 0 ); /*NB BW is not supported*/
      75      388777 :     num_active_bands = ivas_num_active_bands[sub( bwidth, 1 )];
      76      388777 :     move16();
      77             : 
      78      388777 :     return num_active_bands;
      79             : }
      80             : 
      81             : 
      82             : /*-----------------------------------------------------------------------------------------*
      83             :  * Function ivas_get_num_bands()
      84             :  *
      85             :  * Get number of bands depending on the sampling rates
      86             :  *-----------------------------------------------------------------------------------------*/
      87             : 
      88        1128 : static Word16 ivas_get_num_bands(
      89             :     const Word32 sampling_rate )
      90             : {
      91        1128 :     Word16 bwidth = ivas_get_bw_idx_from_sample_rate_fx( sampling_rate );
      92        1128 :     Word16 num_active_bands = ivas_get_num_bands_from_bw_idx( bwidth );
      93             : 
      94        1128 :     return num_active_bands;
      95             : }
      96             : 
      97             : 
      98             : /*---------------------------------------------------------------------*
      99             :  * Function ivas_fb_set_cfg()
     100             :  *
     101             :  * Set default configs for FB mixer
     102             :  *---------------------------------------------------------------------*/
     103             : 
     104        4150 : ivas_error ivas_fb_set_cfg(
     105             :     IVAS_FB_CFG **pFb_cfg_out,    /* o  : FB config. handle                */
     106             :     const Word16 ivas_format,     /* i  : IVAS format                      */
     107             :     const Word16 num_in_chans,    /* i  : number of FB input channels      */
     108             :     const Word16 num_out_chans,   /* i  : number of FB output channels     */
     109             :     const Word16 active_w_mixing, /* i  : active_w_mixing flag             */
     110             :     const Word32 sampling_rate,   /* i  : sampling rate                    */
     111             :     const Word16 nchan_fb_in      /* i  : number of dirAC analysis channels*/
     112             : )
     113             : {
     114             :     IVAS_FB_CFG *pFb_cfg;
     115             : 
     116        4150 :     IF( ( pFb_cfg = (IVAS_FB_CFG *) malloc( sizeof( IVAS_FB_CFG ) ) ) == NULL )
     117             :     {
     118           0 :         return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FB mixer config" );
     119             :     }
     120             : 
     121        4150 :     pFb_cfg->num_in_chans = num_in_chans;
     122        4150 :     pFb_cfg->num_out_chans = num_out_chans;
     123        4150 :     pFb_cfg->nchan_fb_in = nchan_fb_in;
     124             : 
     125        4150 :     pFb_cfg->pcm_offset = 0; /* note: in SPAR decoder, this parameter is overwritten later */
     126        4150 :     pFb_cfg->active_w_mixing = active_w_mixing;
     127        4150 :     pFb_cfg->windowed_fr_offset = 0;
     128             : 
     129        4150 :     move16();
     130        4150 :     move16();
     131        4150 :     move16();
     132        4150 :     move16();
     133        4150 :     move16();
     134        4150 :     move16();
     135             : 
     136        4150 :     IF( EQ_16( ivas_format, ISM_FORMAT ) )
     137             :     {
     138         320 :         pFb_cfg->fb_latency = NS2SA_FX2( sampling_rate, DELAY_FB_4_NS );
     139         320 :         pFb_cfg->fade_len = NS2SA_FX2( sampling_rate, DELAY_FB_4_NS );
     140         320 :         pFb_cfg->prior_input_length = add( NS2SA_FX2( sampling_rate, DELAY_DIRAC_ENC_CMP_NS_PARAM_ISM ), NS2SA_FX2( sampling_rate, DIRAC_SLOT_ENC_NS ) );
     141             : 
     142         320 :         move16();
     143         320 :         move16();
     144         320 :         move16();
     145             :     }
     146        3830 :     ELSE IF( EQ_16( ivas_format, SBA_FORMAT ) )
     147             :     {
     148        3034 :         pFb_cfg->fb_latency = NS2SA_FX2( sampling_rate, DELAY_FB_1_NS );
     149             : 
     150        3034 :         pFb_cfg->fade_len = NS2SA_FX2( sampling_rate, DELAY_FB_4_NS );
     151        3034 :         pFb_cfg->prior_input_length = NS2SA_FX2( sampling_rate, FRAME_SIZE_NS );
     152        3034 :         Word16 tmp = shl( div_l( sampling_rate, FRAMES_PER_SEC ), 1 ); // Q0
     153        3034 :         tmp = mult0( tmp, 3 );                                         // Q0
     154        3034 :         tmp = shr( tmp, 2 );                                           // Q0
     155        3034 :         pFb_cfg->windowed_fr_offset = sub( tmp, NS2SA_FX2( sampling_rate, DELAY_DIRAC_SPAR_ENC_CMP_NS ) );
     156        3034 :         move16();
     157        3034 :         move16();
     158        3034 :         move16();
     159        3034 :         move16();
     160             :     }
     161         796 :     ELSE IF( EQ_16( ivas_format, MASA_FORMAT ) )
     162             :     {
     163         526 :         pFb_cfg->fb_latency = NS2SA_FX2( sampling_rate, DELAY_FB_1_NS );
     164         526 :         pFb_cfg->fade_len = NS2SA_FX2( sampling_rate, DELAY_FB_1_NS );
     165         526 :         pFb_cfg->prior_input_length = add( NS2SA_FX2( sampling_rate, DELAY_DIRAC_ENC_CMP_NS ), NS2SA_FX2( sampling_rate, DIRAC_SLOT_ENC_NS ) );
     166             : 
     167         526 :         move16();
     168         526 :         move16();
     169         526 :         move16();
     170             :     }
     171         270 :     ELSE IF( EQ_16( ivas_format, MC_FORMAT ) )
     172             :     {
     173         270 :         pFb_cfg->fb_latency = NS2SA_FX2( sampling_rate, DELAY_FB_1_NS );
     174         270 :         pFb_cfg->fade_len = NS2SA_FX2( sampling_rate, DELAY_FB_1_NS );
     175         270 :         pFb_cfg->prior_input_length = add( NS2SA_FX2( sampling_rate, DELAY_DIRAC_ENC_CMP_NS ), NS2SA_FX2( sampling_rate, PARAM_MC_SLOT_ENC_NS ) );
     176             : 
     177         270 :         move16();
     178         270 :         move16();
     179         270 :         move16();
     180             :     }
     181             : 
     182        4150 :     *pFb_cfg_out = pFb_cfg;
     183             : 
     184        4150 :     return IVAS_ERR_OK;
     185             : }
     186             : 
     187             : 
     188             : /*-------------------------------------------------------------------------
     189             :  * ivas_FB_mixer_open()
     190             :  *
     191             :  * Allocate and initialize FB mixer handle
     192             :  *------------------------------------------------------------------------*/
     193        4150 : ivas_error ivas_FB_mixer_open_fx(
     194             :     IVAS_FB_MIXER_HANDLE *hFbMixer_out, /* i/o: FB mixer handle           */
     195             :     const Word32 sampling_rate,         /* i  : sampling rate             */
     196             :     IVAS_FB_CFG *fb_cfg,                /* i  : FB config. handle         */
     197             :     const Word16 spar_reconfig_flag     /* i  : SPAR reconfiguration flag */
     198             : )
     199             : {
     200             :     IVAS_FB_MIXER_HANDLE hFbMixer;
     201             :     Word16 i, j, frame_len, num_bands;
     202             :     Word16 num_chs_alloc, exp;
     203             :     ivas_error error;
     204             : 
     205        4150 :     error = IVAS_ERR_OK;
     206        4150 :     move32();
     207             : 
     208        4150 :     frame_len = BASOP_Util_Divide3232_Scale( sampling_rate, FRAMES_PER_SEC, &exp );
     209        4150 :     frame_len = shr( frame_len, sub( 15, exp ) );
     210             : 
     211        4150 :     hFbMixer = *hFbMixer_out;
     212             : 
     213        4150 :     IF( !spar_reconfig_flag )
     214             :     {
     215        1668 :         IF( ( hFbMixer = (IVAS_FB_MIXER_HANDLE) malloc( sizeof( IVAS_FB_MIXER_DATA ) ) ) == NULL )
     216             :         {
     217           0 :             return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FB mixer encoder" );
     218             :         }
     219             : 
     220        1668 :         IF( fb_cfg->num_out_chans > 0 )
     221             :         {
     222         564 :             IF( ( hFbMixer->pFb = (ivas_filterbank_t *) malloc( sizeof( ivas_filterbank_t ) ) ) == NULL )
     223             :             {
     224           0 :                 return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FB mixer encoder" );
     225             :             }
     226             :         }
     227             :         ELSE
     228             :         {
     229        1104 :             hFbMixer->pFb = NULL;
     230             :         }
     231             :     }
     232             : 
     233        4150 :     IF( EQ_16( fb_cfg->active_w_mixing, -1 ) )
     234             :     {
     235        1476 :         num_chs_alloc = 0;
     236        1476 :         move16();
     237             :     }
     238        2674 :     ELSE IF( fb_cfg->active_w_mixing )
     239             :     {
     240         540 :         num_chs_alloc = s_max( fb_cfg->num_in_chans, fb_cfg->nchan_fb_in );
     241             :     }
     242             :     ELSE
     243             :     {
     244        2134 :         num_chs_alloc = 1; /* only W channel processed for predicting YZX */
     245        2134 :         move16();
     246             :     }
     247             : 
     248        8444 :     FOR( i = 0; i < num_chs_alloc; i++ )
     249             :     {
     250        4294 :         IF( fb_cfg->num_out_chans == 0 )
     251             :         {
     252        1104 :             hFbMixer->ppFilterbank_inFR_re_fx[i] = NULL;
     253        1104 :             hFbMixer->ppFilterbank_inFR_im_fx[i] = NULL;
     254             :         }
     255             :         ELSE
     256             :         {
     257        3190 :             j = fb_cfg->remix_order[i];
     258        3190 :             move16();
     259             : 
     260        3190 :             IF( ( hFbMixer->ppFilterbank_inFR_re_fx[j] = (Word32 *) malloc( sizeof( Word32 ) * frame_len ) ) == NULL )
     261             :             {
     262           0 :                 return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FB mixer encoder" );
     263             :             }
     264             : 
     265        3190 :             IF( ( hFbMixer->ppFilterbank_inFR_im_fx[j] = (Word32 *) malloc( sizeof( Word32 ) * frame_len ) ) == NULL )
     266             :             {
     267           0 :                 return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FB mixer encoder" );
     268             :             }
     269             :         }
     270             :     }
     271             : 
     272        4150 :     IF( EQ_16( fb_cfg->active_w_mixing, -1 ) )
     273             :     {
     274        1476 :         num_chs_alloc = 0;
     275        1476 :         move16();
     276             :     }
     277             :     ELSE
     278             :     {
     279        2674 :         num_chs_alloc = s_max( fb_cfg->num_in_chans, fb_cfg->nchan_fb_in );
     280             :     }
     281             : 
     282       17160 :     FOR( i = 0; i < num_chs_alloc; i++ )
     283             :     {
     284       13010 :         IF( ( hFbMixer->ppFilterbank_prior_input_fx[i] = (Word32 *) malloc( sizeof( Word32 ) * fb_cfg->prior_input_length ) ) == NULL )
     285             :         {
     286           0 :             return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FB mixer encoder" );
     287             :         }
     288       13010 :         set32_fx( hFbMixer->ppFilterbank_prior_input_fx[i], 0, fb_cfg->prior_input_length );
     289             :     }
     290             : 
     291        4150 :     test();
     292        4150 :     IF( ( NE_16( fb_cfg->active_w_mixing, -1 ) ) && ( fb_cfg->num_out_chans > 0 ) )
     293             :     {
     294             :         Word32 *pTemp_mem_fx;
     295        1570 :         IF( ( pTemp_mem_fx = (Word32 *) malloc( sizeof( Word32 ) * fb_cfg->num_out_chans * s_max( fb_cfg->num_in_chans, fb_cfg->nchan_fb_in ) * IVAS_MAX_NUM_BANDS ) ) == NULL )
     296             :         {
     297           0 :             return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FB mixer" );
     298             :         }
     299        5227 :         FOR( i = 0; i < fb_cfg->num_out_chans; i++ )
     300             :         {
     301       23177 :             FOR( j = 0; j < fb_cfg->num_in_chans; j++ )
     302             :             {
     303       19520 :                 hFbMixer->prior_mixer_fx[i][j] = pTemp_mem_fx;
     304       19520 :                 pTemp_mem_fx += IVAS_MAX_NUM_BANDS;
     305       19520 :                 set32_fx( hFbMixer->prior_mixer_fx[i][j], 0, IVAS_MAX_NUM_BANDS );
     306             :             }
     307             :         }
     308        1570 :         hFbMixer->q_prior_mixer_fx = Q31;
     309        1570 :         move16();
     310             :     }
     311             : 
     312        4150 :     IF( !spar_reconfig_flag )
     313             :     {
     314        1668 :         IF( fb_cfg->num_out_chans > 0 )
     315             :         {
     316             :             const Word16 *pActive_bins_per_band, *pActive_bins_per_band_abs, *pStart_offset, *pStart_offset_abs;
     317             : 
     318         564 :             num_bands = ivas_get_num_bands( sampling_rate );
     319             : 
     320         564 :             ivas_get_active_bins_fx( &pActive_bins_per_band, &pActive_bins_per_band_abs, &pStart_offset, &pStart_offset_abs, sampling_rate );
     321             : 
     322         564 :             IF( NE_16( fb_cfg->active_w_mixing, -1 ) )
     323             :             {
     324        3705 :                 FOR( i = 0; i < num_bands; i++ )
     325             :                 {
     326        3414 :                     IF( ( hFbMixer->pFb->fb_bin_to_band.pFb_bin_to_band_fx[i] = (Word32 *) malloc( sizeof( Word32 ) * pActive_bins_per_band_abs[i] ) ) == NULL )
     327             :                     {
     328           0 :                         return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FB mixer encoder fixed" );
     329             :                     }
     330             :                 }
     331             :             }
     332             : 
     333         564 :             IF( NE_32( sampling_rate, 48000 ) )
     334             :             {
     335             :                 Word16 num_diff_bands, start_diff_band_non48k;
     336             : 
     337         310 :                 num_diff_bands = MAX_NUM_BANDS_DIFF_NON48K;
     338         310 :                 move16();
     339         310 :                 start_diff_band_non48k = sub( num_bands, num_diff_bands );
     340             : 
     341         310 :                 hFbMixer->num_diff_bands = num_diff_bands;
     342         310 :                 move16();
     343             : 
     344        1240 :                 FOR( j = start_diff_band_non48k; j < num_bands; j++ )
     345             :                 {
     346         930 :                     IF( ( hFbMixer->pFb->fb_consts.ppFilterbank_FRs_non48k_fx[0][j] = (Word32 *) malloc( sizeof( Word32 ) * pActive_bins_per_band[j] ) ) == NULL )
     347             :                     {
     348           0 :                         return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FB mixer encoder" );
     349             :                     }
     350             : 
     351         930 :                     IF( ( hFbMixer->pFb->fb_consts.ppFilterbank_FRs_non48k_fx[1][j] = (Word32 *) malloc( sizeof( Word32 ) * pActive_bins_per_band[j] ) ) == NULL )
     352             :                     {
     353           0 :                         return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FB mixer encoder" );
     354             :                     }
     355             :                 }
     356             :             }
     357             :         }
     358             :         ELSE
     359             :         {
     360             :             /* ignore all the deeper filter bank stuff for now */
     361        1104 :             hFbMixer->num_diff_bands = 0;
     362        1104 :             move16();
     363             :         }
     364             :     }
     365             : 
     366        4150 :     hFbMixer->fb_cfg = fb_cfg;
     367        4150 :     set16_fx( hFbMixer->first_frame, 1, hFbMixer->fb_cfg->num_out_chans );
     368        4150 :     set16_fx( hFbMixer->first_frame + hFbMixer->fb_cfg->num_out_chans, 0, sub( IVAS_SPAR_MAX_CH, hFbMixer->fb_cfg->num_out_chans ) );
     369             : 
     370        4150 :     IF( !spar_reconfig_flag )
     371             :     {
     372             :         Word16 index[IVAS_MAX_NUM_FB_BANDS];
     373        1668 :         set16_fx( index, 0, IVAS_MAX_NUM_FB_BANDS );
     374        1668 :         IF( NE_32( ( error = ivas_filterbank_setup_fx( hFbMixer, sampling_rate, index ) ), IVAS_ERR_OK ) )
     375             :         {
     376           0 :             return error;
     377             :         }
     378             :     }
     379             : 
     380        4150 :     *hFbMixer_out = hFbMixer;
     381             : 
     382        4150 :     return error;
     383             : }
     384             : 
     385             : /*-------------------------------------------------------------------------
     386             :  * ivas_FB_mixer_close()
     387             :  *
     388             :  * Deallocate FB mixer handle
     389             :  *------------------------------------------------------------------------*/
     390             : 
     391        4150 : void ivas_FB_mixer_close_fx(
     392             :     IVAS_FB_MIXER_HANDLE *hFbMixer_in, /* i/o: FB mixer handle              */
     393             :     const Word32 sampling_rate,        /* i  : sampling rate in Hz          */
     394             :     const Word16 spar_reconfig_flag    /* i  : SPAR reconfiguration flag    */
     395             : )
     396             : {
     397             :     IVAS_FB_MIXER_HANDLE hFbMixer;
     398             :     IVAS_FB_CFG *fb_cfg;
     399             :     Word16 i, j, num_bands;
     400             :     Word16 num_chs_alloc;
     401             : 
     402        4150 :     hFbMixer = *hFbMixer_in;
     403        4150 :     fb_cfg = hFbMixer->fb_cfg;
     404             : 
     405        4150 :     IF( EQ_16( fb_cfg->active_w_mixing, -1 ) )
     406             :     {
     407        1476 :         num_chs_alloc = 0;
     408        1476 :         move16();
     409             :     }
     410        2674 :     ELSE IF( fb_cfg->active_w_mixing )
     411             :     {
     412         540 :         num_chs_alloc = s_max( fb_cfg->num_in_chans, fb_cfg->nchan_fb_in );
     413             :     }
     414             :     ELSE
     415             :     {
     416        2134 :         num_chs_alloc = 1; /* only W channel processed for predicting YZX */
     417        2134 :         move16();
     418             :     }
     419             : 
     420        4150 :     IF( hFbMixer != NULL )
     421             :     {
     422        8444 :         FOR( i = 0; i < num_chs_alloc; i++ )
     423             :         {
     424        4294 :             IF( fb_cfg->num_out_chans > 0 )
     425             :             {
     426        3190 :                 j = fb_cfg->remix_order[i];
     427        3190 :                 move16();
     428             : 
     429        3190 :                 free( hFbMixer->ppFilterbank_inFR_re_fx[j] );
     430        3190 :                 hFbMixer->ppFilterbank_inFR_re_fx[j] = NULL;
     431             : 
     432        3190 :                 free( hFbMixer->ppFilterbank_inFR_im_fx[j] );
     433        3190 :                 hFbMixer->ppFilterbank_inFR_im_fx[j] = NULL;
     434             :             }
     435             :         }
     436             : 
     437        4150 :         IF( EQ_16( fb_cfg->active_w_mixing, -1 ) )
     438             :         {
     439        1476 :             num_chs_alloc = 0;
     440        1476 :             move16();
     441             :         }
     442             :         ELSE
     443             :         {
     444        2674 :             num_chs_alloc = s_max( fb_cfg->num_in_chans, fb_cfg->nchan_fb_in );
     445             :         }
     446             : 
     447       17160 :         FOR( i = 0; i < num_chs_alloc; i++ )
     448             :         {
     449       13010 :             free( hFbMixer->ppFilterbank_prior_input_fx[i] );
     450       13010 :             hFbMixer->ppFilterbank_prior_input_fx[i] = NULL;
     451             :         }
     452             : 
     453        4150 :         test();
     454        4150 :         IF( NE_16( fb_cfg->active_w_mixing, -1 ) && ( fb_cfg->num_out_chans > 0 ) )
     455             :         {
     456        1570 :             free( hFbMixer->prior_mixer_fx[0][0] );
     457        1570 :             hFbMixer->prior_mixer_fx[0][0] = NULL;
     458             :         }
     459             : 
     460        4150 :         IF( !spar_reconfig_flag )
     461             :         {
     462        1668 :             IF( fb_cfg->num_out_chans > 0 )
     463             :             {
     464         564 :                 num_bands = hFbMixer->pFb->filterbank_num_bands;
     465         564 :                 move16();
     466             : 
     467         564 :                 IF( NE_16( fb_cfg->active_w_mixing, -1 ) )
     468             :                 {
     469        3705 :                     FOR( i = 0; i < num_bands; i++ )
     470             :                     {
     471        3414 :                         free( hFbMixer->pFb->fb_bin_to_band.pFb_bin_to_band_fx[i] );
     472        3414 :                         hFbMixer->pFb->fb_bin_to_band.pFb_bin_to_band_fx[i] = NULL;
     473             :                     }
     474             :                 }
     475             : 
     476         564 :                 IF( NE_32( sampling_rate, 48000 ) )
     477             :                 {
     478             :                     Word16 start_diff_band_non48k;
     479         310 :                     start_diff_band_non48k = sub( num_bands, hFbMixer->num_diff_bands );
     480             : 
     481        1240 :                     FOR( j = start_diff_band_non48k; j < num_bands; j++ )
     482             :                     {
     483         930 :                         free( hFbMixer->pFb->fb_consts.ppFilterbank_FRs_non48k_fx[0][j] );
     484         930 :                         hFbMixer->pFb->fb_consts.ppFilterbank_FRs_non48k_fx[0][j] = NULL;
     485             : 
     486         930 :                         free( hFbMixer->pFb->fb_consts.ppFilterbank_FRs_non48k_fx[1][j] );
     487         930 :                         hFbMixer->pFb->fb_consts.ppFilterbank_FRs_non48k_fx[1][j] = NULL;
     488             :                     }
     489             :                 }
     490             :             }
     491        1668 :             IF( hFbMixer->pFb != NULL )
     492             :             {
     493         564 :                 free( hFbMixer->pFb );
     494         564 :                 hFbMixer->pFb = NULL;
     495             :             }
     496             :         }
     497             : 
     498        4150 :         IF( hFbMixer->fb_cfg != NULL )
     499             :         {
     500        4150 :             free( hFbMixer->fb_cfg );
     501        4150 :             hFbMixer->fb_cfg = NULL;
     502             :         }
     503             : 
     504        4150 :         IF( !spar_reconfig_flag )
     505             :         {
     506        1668 :             free( hFbMixer );
     507        1668 :             hFbMixer = NULL;
     508             :         }
     509             :     }
     510             : 
     511        4150 :     return;
     512             : }
     513             : /*-----------------------------------------------------------------------------------------*
     514             :  * Function ivas_fb_mixer_pcm_ingest()
     515             :  *
     516             :  * PCM ingest block
     517             :  *-----------------------------------------------------------------------------------------*/
     518      157500 : void ivas_fb_mixer_pcm_ingest_fx(
     519             :     IVAS_FB_MIXER_HANDLE hFbMixer, /* i/o: FB mixer handle                          */
     520             :     Word32 *pcm_in[],              /* i  : input audio channels     Qq_data_fix[]   */
     521             :     Word32 **ppOut_pcm,            /* o  : output audio channels    Qq_ppOut_pcm[]  */
     522             :     const Word16 frame_len,        /* i  : frame length                             */
     523             :     const Word16 HOA_md_ind[IVAS_SPAR_MAX_CH],
     524             :     Word16 q_data_fix,
     525             :     Word16 *q_ppOut_pcm )
     526             : {
     527             :     Word16 i;
     528             :     Word16 num_chs_ingest;
     529      157500 :     IVAS_FB_CFG *fb_cfg = hFbMixer->fb_cfg;
     530             : 
     531      157500 :     IF( fb_cfg->active_w_mixing )
     532             :     {
     533       43891 :         num_chs_ingest = fb_cfg->num_in_chans;
     534       43891 :         move16();
     535             :     }
     536             :     ELSE
     537             :     {
     538      113609 :         num_chs_ingest = 1; /* forward Filterbank MDFT only on W */
     539      113609 :         move16();
     540             :     }
     541             : 
     542             : 
     543      889700 :     FOR( i = 0; i < fb_cfg->num_in_chans; i++ )
     544             :     {
     545      732200 :         Copy32( &hFbMixer->ppFilterbank_prior_input_fx[i][fb_cfg->prior_input_length - frame_len], ppOut_pcm[i], frame_len );
     546      732200 :         Copy32( pcm_in[HOA_md_ind[i]], &ppOut_pcm[i][frame_len], frame_len );
     547      732200 :         q_ppOut_pcm[i] = q_data_fix;
     548      732200 :         move16();
     549             :     }
     550             : 
     551      157500 :     Word16 guard_bits = find_guarded_bits_fx( shl( frame_len, 1 ) );
     552             : 
     553      446673 :     FOR( i = 0; i < num_chs_ingest; i++ )
     554             :     {
     555      289173 :         Word16 q_shift = sub( L_norm_arr( ppOut_pcm[fb_cfg->remix_order[i]], shl( frame_len, 1 ) ), guard_bits );
     556      289173 :         Scale_sig32( ppOut_pcm[fb_cfg->remix_order[i]], shl( frame_len, 1 ), q_shift ); // Qq_ppOut_pcm -> Qq_ppOut_pcm + q_shift
     557      289173 :         q_ppOut_pcm[fb_cfg->remix_order[i]] = add( q_ppOut_pcm[fb_cfg->remix_order[i]], q_shift );
     558      289173 :         move16();
     559             : 
     560      289173 :         ivas_mdft_fx( ppOut_pcm[fb_cfg->remix_order[i]], hFbMixer->ppFilterbank_inFR_re_fx[fb_cfg->remix_order[i]], hFbMixer->ppFilterbank_inFR_im_fx[fb_cfg->remix_order[i]], shl( frame_len, 1 ), frame_len );
     561      289173 :         q_shift = L_norm_arr( hFbMixer->ppFilterbank_inFR_re_fx[fb_cfg->remix_order[i]], frame_len );
     562      289173 :         q_shift = s_min( q_shift, L_norm_arr( hFbMixer->ppFilterbank_inFR_im_fx[fb_cfg->remix_order[i]], frame_len ) );
     563      289173 :         scale_sig32( hFbMixer->ppFilterbank_inFR_re_fx[fb_cfg->remix_order[i]], frame_len, q_shift );
     564      289173 :         scale_sig32( hFbMixer->ppFilterbank_inFR_im_fx[fb_cfg->remix_order[i]], frame_len, q_shift );
     565      289173 :         hFbMixer->q_ppFilterbank_inFR[fb_cfg->remix_order[i]] = add( q_shift, q_ppOut_pcm[fb_cfg->remix_order[i]] );
     566      289173 :         move16();
     567             :     }
     568             : 
     569      157500 :     return;
     570             : }
     571             : 
     572             : /*-----------------------------------------------------------------------------------------*
     573             :  * Function ivas_fb_mixer_update_prior_input()
     574             :  *
     575             :  *
     576             :  *-----------------------------------------------------------------------------------------*/
     577      884980 : void ivas_fb_mixer_update_prior_input_fx(
     578             :     IVAS_FB_MIXER_HANDLE hFbMixer, /* i/o: FB mixer handle              */
     579             :     Word32 *pcm_in_fx[],           /* i  : input audio channels         */
     580             :     const Word16 length,           /* i  : length of time slot          */
     581             :     const Word16 nchan_fb_in       /* i  : number of analysis channels  */
     582             : )
     583             : {
     584             :     Word16 i;
     585             : 
     586     5081380 :     FOR( i = 0; i < nchan_fb_in; i++ )
     587             :     {
     588     4196400 :         Copy32( &hFbMixer->ppFilterbank_prior_input_fx[i][length], hFbMixer->ppFilterbank_prior_input_fx[i], hFbMixer->fb_cfg->prior_input_length - length );
     589     4196400 :         Copy32( pcm_in_fx[i], &hFbMixer->ppFilterbank_prior_input_fx[i][hFbMixer->fb_cfg->prior_input_length - length], length );
     590             :     }
     591             : 
     592      884980 :     return;
     593             : }
     594             : 
     595             : 
     596             : /*-----------------------------------------------------------------------------------------*
     597             :  * Function ivas_fb_mixer_get_windowed_fr()
     598             :  *
     599             :  *
     600             :  *-----------------------------------------------------------------------------------------*/
     601             : 
     602      883395 : void ivas_fb_mixer_get_windowed_fr_fx(
     603             :     IVAS_FB_MIXER_HANDLE hFbMixer, /* i/o: FB mixer handle                    */
     604             :     Word32 *pcm_in_fx[],           // i: Qx
     605             :     Word32 *frame_f_real_fx[],
     606             :     Word32 *frame_f_imag_fx[],
     607             :     const Word16 length,      /* i  : number of new samples in time slot */
     608             :     const Word16 mdft_len,    /* i  : MDFT frame length                  */
     609             :     const Word16 nchan_fb_in, /* i  : number of analysis channels        */
     610             :     Word16 gb )
     611             : {
     612             :     Word16 ch_idx, j, offset, rev_offset;
     613             :     Word16 n_old_samples;
     614             :     Word16 n_new_samples;
     615             :     Word32 fr_in_block_fx[L_FRAME48k * 2];
     616             :     const Word16 *win_ptr_fx;
     617             : 
     618      883395 :     n_old_samples = s_min( ( sub( hFbMixer->fb_cfg->prior_input_length, hFbMixer->fb_cfg->windowed_fr_offset ) ), ( shl( mdft_len, 1 ) ) );
     619      883395 :     n_new_samples = s_max( 0, sub( shl( length, 1 ), n_old_samples ) );
     620      883395 :     offset = sub( sub( shl( mdft_len, 1 ), length ), hFbMixer->ana_window_offset );
     621      883395 :     rev_offset = sub( shl( mdft_len, 1 ), hFbMixer->ana_window_offset );
     622      883395 :     set32_fx( fr_in_block_fx, 0, offset );
     623             : 
     624     5069431 :     FOR( ch_idx = 0; ch_idx < nchan_fb_in; ch_idx++ )
     625             :     {
     626     4186036 :         Copy32( &hFbMixer->ppFilterbank_prior_input_fx[ch_idx][offset + hFbMixer->fb_cfg->windowed_fr_offset], &fr_in_block_fx[offset], sub( n_old_samples, offset ) ); // Qx
     627     4186036 :         Copy32( pcm_in_fx[ch_idx], &fr_in_block_fx[n_old_samples], n_new_samples );                                                                                     // Qx
     628             : 
     629     4186036 :         win_ptr_fx = hFbMixer->pAna_window_fx; /*Q15*/
     630             : 
     631   222847892 :         FOR( j = offset; j < sub( shl( mdft_len, 1 ), length ); j++ )
     632             :         {
     633   218661856 :             fr_in_block_fx[j] = Mpy_32_16_1( fr_in_block_fx[j], ( *( win_ptr_fx++ ) ) ); // Qx + 15 - 15 = Qx
     634   218661856 :             move32();
     635             :         }
     636             : 
     637   222847892 :         FOR( j = rev_offset; j < shl( mdft_len, 1 ); j++ )
     638             :         {
     639   218661856 :             fr_in_block_fx[j] = Mpy_32_16_1( fr_in_block_fx[j], ( *( --win_ptr_fx ) ) ); // Qx + 15 - 15 = Qx
     640   218661856 :             move32();
     641             :         }
     642             : 
     643  1638352916 :         FOR( Word16 i = 0; i < shl( mdft_len, 1 ); i++ )
     644             :         {
     645  1634166880 :             fr_in_block_fx[i] = L_shr( fr_in_block_fx[i], gb ); // Qx - gb
     646  1634166880 :             move32();
     647             :         }
     648             : 
     649     4186036 :         ivas_mdft_fx( fr_in_block_fx, frame_f_real_fx[ch_idx], frame_f_imag_fx[ch_idx], shl( mdft_len, 1 ), mdft_len );
     650             :     }
     651             : 
     652      883395 :     return;
     653             : }
     654             : 
     655             : /*-----------------------------------------------------------------------------------------*
     656             :  * Function ivas_fb_mixer_cross_fading()
     657             :  *
     658             :  * FB Mixer cross fading
     659             :  *-----------------------------------------------------------------------------------------*/
     660             : 
     661      271899 : void ivas_fb_mixer_cross_fading_fx(
     662             :     IVAS_FB_MIXER_HANDLE hFbMixer,
     663             :     Word32 **ppOut_pcm_fx,    // o: Qx
     664             :     Word32 *pMdft_out_old_fx, // i: Qx
     665             :     Word32 *pMdft_out_new_fx, // i: Qx
     666             :     const Word16 ch,
     667             :     const Word16 frame_len,
     668             :     const Word16 cf_offset )
     669             : {
     670             :     Word16 k, fade_start_offset, fade_end_offset;
     671             : 
     672      271899 :     IF( hFbMixer->first_frame[ch] == 0 )
     673             :     {
     674      269308 :         fade_start_offset = hFbMixer->cross_fade_start_offset;
     675      269308 :         fade_end_offset = hFbMixer->cross_fade_end_offset;
     676      269308 :         move16();
     677      269308 :         move16();
     678             : 
     679      269308 :         FOR( k = 0; k < fade_start_offset; k++ )
     680             :         {
     681           0 :             ppOut_pcm_fx[ch][k] = pMdft_out_old_fx[k + cf_offset]; // Qx
     682           0 :             move32();
     683             :         }
     684             : 
     685    42906108 :         FOR( k = fade_start_offset; k < fade_end_offset; k++ )
     686             :         {
     687    42636800 :             ppOut_pcm_fx[ch][k] = L_add( Mpy_32_16_1( pMdft_out_new_fx[k + cf_offset], hFbMixer->pFilterbank_cross_fade_fx[k - fade_start_offset] ), Mpy_32_16_1( pMdft_out_old_fx[k + cf_offset], sub( 32767, hFbMixer->pFilterbank_cross_fade_fx[k - fade_start_offset] ) ) ); // Qx + Q15 - 15 = Qx
     688    42636800 :             move32();
     689             :         }
     690             : 
     691   170816508 :         FOR( k = fade_end_offset; k < frame_len; k++ )
     692             :         {
     693   170547200 :             ppOut_pcm_fx[ch][k] = pMdft_out_new_fx[k + cf_offset]; // Qx
     694   170547200 :             move32();
     695             :         }
     696             :     }
     697             :     ELSE
     698             :     {
     699        2591 :         hFbMixer->first_frame[ch] = 0;
     700        2591 :         move32();
     701             : 
     702     2228831 :         FOR( k = 0; k < frame_len; k++ )
     703             :         {
     704     2226240 :             ppOut_pcm_fx[ch][k] = pMdft_out_new_fx[k + cf_offset]; // Qx
     705     2226240 :             move32();
     706             :         }
     707             :     }
     708             : 
     709      271899 :     return;
     710             : }
     711             : 
     712             : /*-----------------------------------------------------------------------------------------*
     713             :  * Function ivas_fb_mixer_process()
     714             :  *
     715             :  * Filter bank process
     716             :  *-----------------------------------------------------------------------------------------*/
     717   621213440 : void ivas_cmult_fix(
     718             :     Word32 in1_re,   // i: Qx
     719             :     Word32 in1_im,   // i: Qx
     720             :     Word32 in2_re,   // i: Qx
     721             :     Word32 in2_im,   // i: Qx
     722             :     Word32 *out1_re, // o: 2 * Qx - 31
     723             :     Word32 *out1_im  // o: 2 * Qx - 31
     724             : )
     725             : {
     726   621213440 :     *out1_re = L_sub_sat( Mpy_32_32( in1_re, in2_re ), Mpy_32_32( in1_im, in2_im ) );
     727   621213440 :     move32();
     728   621213440 :     *out1_im = L_add_sat( Mpy_32_32( in1_re, in2_im ), Mpy_32_32( in2_re, in1_im ) );
     729   621213440 :     move32();
     730   621213440 : }
     731             : 
     732      157500 : void ivas_fb_mixer_process_fx(
     733             :     IVAS_FB_MIXER_HANDLE hFbMixer,                                                  /* i/o: FB mixer handle                             */
     734             :     Word32 ***mixer_mat_fx,                                                         /* i  : mixer matrix                                */
     735             :     Word16 *q_mixer_mat_fx,                                                         /* i  : mixer matrix Q-factor                       */
     736             :     Word32 **ppOut_pcm_fx,                                                          /* o  : output audio channels                       */
     737             :     Word16 *q_ppOut_pcm_fx,                                                         /* o  : output audio channels Q-factor              */
     738             :     const Word16 frame_len,                                                         /* i  : frame length in samples                     */
     739             :     Word16 in_out_mixer_map[IVAS_MAX_FB_MIXER_OUT_CH][IVAS_MAX_SPAR_FB_MIXER_IN_CH] /* i/o: mixing mapping                              */
     740             : )
     741             : {
     742      157500 :     ivas_filterbank_t *pFb = hFbMixer->pFb;
     743      157500 :     Word16 num_bands = pFb->filterbank_num_bands;
     744      157500 :     move16();
     745             :     Word16 i, j, k, ch, hist;
     746             : 
     747             :     const Word32 *pFilterbank_bin_to_band_re_fx;
     748             :     const Word32 *pFilterbank_bin_to_band_im_fx;
     749             :     Word16 q_pMdft_out_fx[2];
     750             :     Word32 *pMdft_out_fx[2];
     751             :     Word32 *pOut_fr_re_fx, *pOut_fr_im_fx;
     752      157500 :     Word16 q_pOut_fr_fx = 31;
     753      157500 :     move16();
     754             :     Word32 Out_fr_re_fx[L_FRAME48k], Out_fr_im_fx[L_FRAME48k];
     755             :     Word32 Mdft_out_0_fx[L_FRAME48k * 2], Mdft_out_1_fx[L_FRAME48k * 2];
     756             : 
     757      157500 :     pOut_fr_re_fx = Out_fr_re_fx;
     758      157500 :     pOut_fr_im_fx = Out_fr_im_fx;
     759      157500 :     pMdft_out_fx[0] = Mdft_out_0_fx;
     760      157500 :     pMdft_out_fx[1] = Mdft_out_1_fx;
     761             : 
     762      429399 :     FOR( ch = ( hFbMixer->fb_cfg->active_w_mixing == 0 ); ch < hFbMixer->fb_cfg->num_out_chans; ch++ )
     763             :     {
     764             :         /* Run a loop of 2 to calculate current frame's filterbank output and prev frame's output */
     765      815697 :         FOR( hist = 0; hist < 2; hist++ )
     766             :         {
     767      543798 :             set_zero_fx( pOut_fr_re_fx, frame_len );
     768      543798 :             set_zero_fx( pOut_fr_im_fx, frame_len );
     769      543798 :             q_pOut_fr_fx = 31;
     770      543798 :             move16();
     771     3332190 :             FOR( j = 0; j < hFbMixer->fb_cfg->num_in_chans; j++ )
     772             :             {
     773     2788392 :                 IF( in_out_mixer_map[ch][j] != 0 )
     774             :                 {
     775             : 
     776             :                     Word32 filterbank_mixer_bins_re_fx[L_FRAME48k];
     777             :                     Word32 filterbank_mixer_bins_im_fx[L_FRAME48k];
     778      807144 :                     Word32 *pFb_inFR_re_fx = hFbMixer->ppFilterbank_inFR_re_fx[j]; // Q(hFbMixer->q_ppFilterbank_inFR_re_fx)
     779      807144 :                     Word32 *pFb_inFR_im_fx = hFbMixer->ppFilterbank_inFR_im_fx[j]; // Q(hFbMixer->q_ppFilterbank_inFR_im_fx)
     780             : 
     781      807144 :                     set_zero_fx( filterbank_mixer_bins_re_fx, frame_len );
     782      807144 :                     set_zero_fx( filterbank_mixer_bins_im_fx, frame_len );
     783             : 
     784      807144 :                     Word16 total_guard = find_guarded_bits_fx( num_bands );
     785      807144 :                     move16();
     786    10353872 :                     FOR( i = 0; i < num_bands; i++ )
     787             :                     {
     788     9546728 :                         Word16 start_offset = pFb->fb_consts.pFilterbank_bins_start_offset[i];
     789     9546728 :                         move16();
     790     9546728 :                         Word16 num_bins = pFb->fb_consts.pFilterbank_bins_per_band[i];
     791     9546728 :                         move16();
     792     9546728 :                         Word32 mixer_const_fx = hFbMixer->prior_mixer_fx[ch][j][i]; // Q(hFbMixer->q_prior_mixer_fx)
     793     9546728 :                         move32();
     794     9546728 :                         pFilterbank_bin_to_band_re_fx = pFb->fb_consts.ppFilterbank_FRs_fx[0][i]; // Q30
     795     9546728 :                         pFilterbank_bin_to_band_im_fx = pFb->fb_consts.ppFilterbank_FRs_fx[1][i]; // Q30
     796             : 
     797  2942784180 :                         FOR( k = start_offset; k < num_bins + start_offset; k++ )
     798             :                         {
     799  2933237452 :                             filterbank_mixer_bins_re_fx[k] = L_add_sat( filterbank_mixer_bins_re_fx[k], L_shr( Mpy_32_32( *pFilterbank_bin_to_band_re_fx, mixer_const_fx ), total_guard ) ); // Q30 + hFbMixer->q_prior_mixer_fx - 31 - total_guard
     800  2933237452 :                             move32();
     801  2933237452 :                             filterbank_mixer_bins_im_fx[k] = L_add_sat( filterbank_mixer_bins_im_fx[k], L_shr( Mpy_32_32( *pFilterbank_bin_to_band_im_fx, mixer_const_fx ), total_guard ) ); // Q30 + hFbMixer->q_prior_mixer_fx - 31 - total_guard
     802  2933237452 :                             move32();
     803             :                             /*filterbank_mixer_bins_im_fx q 30 */
     804             :                             /*mixer_const_fx q  q_ppOut_pcm_fx */
     805  2933237452 :                             pFilterbank_bin_to_band_re_fx++;
     806  2933237452 :                             pFilterbank_bin_to_band_im_fx++;
     807             :                         }
     808     9546728 :                         hFbMixer->prior_mixer_fx[ch][j][i] = mixer_mat_fx[ch][j][i]; // Q(q_mixer_mat_fx)
     809     9546728 :                         move32();
     810             :                     }
     811      807144 :                     Word16 res_q = 0;
     812      807144 :                     move16();
     813   622020584 :                     FOR( k = 0; k < frame_len; k++ )
     814             :                     {
     815             :                         Word32 temp_out_re_fx, temp_out_im_fx;
     816             : 
     817   621213440 :                         ivas_cmult_fix( filterbank_mixer_bins_re_fx[k], filterbank_mixer_bins_im_fx[k], pFb_inFR_re_fx[k],
     818   621213440 :                                         pFb_inFR_im_fx[k], &temp_out_re_fx, &temp_out_im_fx );
     819   621213440 :                         res_q = sub( add( sub( sub( add( 30, *q_mixer_mat_fx ), 31 ), total_guard ), hFbMixer->q_ppFilterbank_inFR[j] ), 31 );
     820   621213440 :                         Word16 q_check = s_min( q_pOut_fr_fx, res_q );
     821   621213440 :                         IF( NE_16( q_check, q_pOut_fr_fx ) )
     822             :                         {
     823   434008960 :                             pOut_fr_re_fx[k] = L_shr( pOut_fr_re_fx[k], sub( q_pOut_fr_fx, q_check ) ); // q_pOut_fr_fx -> q_check
     824   434008960 :                             move32();
     825   434008960 :                             pOut_fr_im_fx[k] = L_shr( pOut_fr_im_fx[k], sub( q_pOut_fr_fx, q_check ) ); // q_pOut_fr_fx -> q_check
     826   434008960 :                             move32();
     827             :                         }
     828   621213440 :                         IF( NE_16( q_check, res_q ) )
     829             :                         {
     830   149251840 :                             temp_out_re_fx = L_shr( temp_out_re_fx, sub( res_q, q_check ) ); // res_q -> q_check
     831   149251840 :                             temp_out_im_fx = L_shr( temp_out_im_fx, sub( res_q, q_check ) ); // res_q -> q_check
     832             :                         }
     833   621213440 :                         res_q = q_check;
     834   621213440 :                         move16();
     835   621213440 :                         pOut_fr_re_fx[k] = L_add_sat( pOut_fr_re_fx[k], temp_out_re_fx ); // res_q
     836   621213440 :                         move32();
     837   621213440 :                         pOut_fr_im_fx[k] = L_add_sat( pOut_fr_im_fx[k], temp_out_im_fx ); // res_q
     838   621213440 :                         move32();
     839             :                     }
     840      807144 :                     q_pOut_fr_fx = res_q;
     841      807144 :                     move16();
     842             :                 }
     843             :             }
     844      543798 :             Word16 scale = sub( s_min( L_norm_arr( pOut_fr_re_fx, frame_len ), L_norm_arr( pOut_fr_im_fx, frame_len ) ), find_guarded_bits_fx( shl( frame_len, 1 ) ) );
     845      543798 :             scale_sig32( pOut_fr_re_fx, frame_len, scale );
     846      543798 :             scale_sig32( pOut_fr_im_fx, frame_len, scale );
     847      543798 :             ivas_imdft_fx( pOut_fr_re_fx, pOut_fr_im_fx, pMdft_out_fx[hist], frame_len );
     848      543798 :             q_pMdft_out_fx[hist] = add( q_pOut_fr_fx, scale );
     849      543798 :             move16();
     850             :         }
     851      271899 :         scale_sig32( pMdft_out_fx[0], shl( frame_len, 1 ), sub( s_min( q_pMdft_out_fx[0], q_pMdft_out_fx[1] ), q_pMdft_out_fx[0] ) );
     852      271899 :         scale_sig32( pMdft_out_fx[1], shl( frame_len, 1 ), sub( s_min( q_pMdft_out_fx[0], q_pMdft_out_fx[1] ), q_pMdft_out_fx[1] ) );
     853      271899 :         ivas_fb_mixer_cross_fading_fx( hFbMixer, ppOut_pcm_fx, pMdft_out_fx[0], pMdft_out_fx[1], ch, frame_len, frame_len );
     854      271899 :         q_ppOut_pcm_fx[ch] = s_min( q_pMdft_out_fx[0], q_pMdft_out_fx[1] );
     855      271899 :         move16();
     856             :     }
     857             : 
     858      157500 :     return;
     859             : }
     860             : 
     861             : /*-----------------------------------------------------------------------------------------*
     862             :  * Function ivas_fb_mixer_get_in_out_mapping()
     863             :  *
     864             :  *
     865             :  *-----------------------------------------------------------------------------------------*/
     866      157500 : void ivas_fb_mixer_get_in_out_mapping_fx(
     867             :     const IVAS_FB_CFG *fb_cfg,                                                      /* i  : FB config. handle  */
     868             :     Word16 in_out_mixer_map[IVAS_MAX_FB_MIXER_OUT_CH][IVAS_MAX_SPAR_FB_MIXER_IN_CH] /* i/o: mixing mapping     */
     869             : )
     870             : {
     871             :     Word16 i, j;
     872             : 
     873      157500 :     set_s( (Word16 *) in_out_mixer_map, 0, IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH );
     874             : 
     875      157500 :     IF( fb_cfg->active_w_mixing )
     876             :     {
     877       87782 :         FOR( i = 0; i < fb_cfg->num_out_chans; i++ )
     878             :         {
     879      219455 :             FOR( j = 0; j < fb_cfg->num_in_chans; j++ )
     880             :             {
     881      175564 :                 in_out_mixer_map[i][j] = 1;
     882      175564 :                 move16();
     883             :             }
     884             :         }
     885             :     }
     886             :     ELSE
     887             :     {
     888      113609 :         in_out_mixer_map[0][0] = 1; /* W depends on only W input*/
     889      113609 :         move16();
     890      341617 :         FOR( i = 1; i < fb_cfg->num_out_chans; i++ )
     891             :         {
     892      228008 :             in_out_mixer_map[i][0] = 1;
     893      228008 :             move16();
     894             :         }
     895             :     }
     896             : 
     897      157500 :     return;
     898             : }
     899             : 
     900             : /*-----------------------------------------------------------------------------------------*
     901             :  * Function ivas_calculate_abs_fr()
     902             :  *
     903             :  * Function to calculate number of active bands
     904             :  *-----------------------------------------------------------------------------------------*/
     905             : 
     906         564 : static Word16 ivas_calculate_abs_fr_fx(
     907             :     ivas_filterbank_t *pFb,
     908             :     const Word32 sampling_rate,
     909             :     const Word16 alloc_fb_resp,
     910             :     Word16 *index )
     911             : {
     912             :     Word16 frame_len;
     913             :     Word32 ppFilterbank_FRs_s_fx[L_FRAME48k];
     914         564 :     Word16 bands = pFb->filterbank_num_bands;
     915         564 :     move16();
     916         564 :     Word16 i, j, num_active_bands = 0;
     917         564 :     move16();
     918         564 :     Word16 idx_short_stride_bin_to_band = 0;
     919         564 :     move16();
     920             :     Word16 quo, tmp, exp_diff;
     921             : 
     922         564 :     Word32 temp = Mpy_32_32( sampling_rate, 42949673 /* FRAMES_PER_SEC in Q31 */ );
     923         564 :     frame_len = extract_l( temp );
     924             : 
     925        7174 :     FOR( i = 0; i < bands; i++ )
     926             :     {
     927        6610 :         const Word32 *long_mdft_ptr_re_fx = pFb->fb_consts.ppFilterbank_FRs_fx[0][i]; // Q30
     928        6610 :         const Word32 *long_mdft_ptr_im_fx = pFb->fb_consts.ppFilterbank_FRs_fx[1][i]; // Q30
     929             : 
     930        6610 :         Word16 start_offset = pFb->fb_consts.pFilterbank_bins_start_offset[i];
     931        6610 :         move16();
     932        6610 :         Word16 num_bins = pFb->fb_consts.pFilterbank_bins_per_band[i];
     933        6610 :         move16();
     934        6610 :         Word16 short_mdft_start_bin = -1;
     935        6610 :         move16();
     936             : 
     937             :         Word32 short_stride_pow_spec_fx[MDFT_FB_BANDS_240];
     938        6610 :         Word32 short_stride_nrg_fx = 0;
     939        6610 :         move16();
     940        6610 :         exp_diff = 0;
     941        6610 :         move16();
     942             : 
     943        6610 :         Word64 cldfb_nrg_fx = 0;
     944        6610 :         move64();
     945        6610 :         Word16 short_stride = pFb->fb_bin_to_band.short_stride;
     946        6610 :         move16();
     947             :         Word32 res_dec1, res_frac, res_dec2;
     948        6610 :         iDiv_and_mod_32( sampling_rate, FRAMES_PER_SEC, &res_dec1, &res_frac, 0 );
     949        6610 :         iDiv_and_mod_32( res_dec1, short_stride, &res_dec2, &res_frac, 0 );
     950        6610 :         const Word16 num_bins_per_short_stride_bin = extract_l( res_dec2 );
     951        6610 :         iDiv_and_mod_32( res_dec1, pFb->fb_bin_to_band.num_cldfb_bands, &res_dec2, &res_frac, 0 );
     952        6610 :         const Word16 num_bins_per_cldfb_band = extract_l( res_dec2 );
     953             : 
     954        6610 :         Word32 short_stride_max_per_spar_band_fx = 1;
     955        6610 :         move32();
     956             : 
     957             :         /*loop over all stored Filter Bank Response MDFT coefficients*/
     958             : 
     959        6610 :         set32_fx( short_stride_pow_spec_fx, 0, MDFT_FB_BANDS_240 );
     960             : 
     961     2006677 :         FOR( j = start_offset; j < num_bins + start_offset; j++ )
     962             :         {
     963             : 
     964             :             Word32 sq_abs_fx;
     965             : 
     966             :             // Word32 real = L_shr( *long_mdft_ptr_re_fx, 3 ); // Q27
     967     2000067 :             Word32 real = *long_mdft_ptr_re_fx; // Q30
     968     2000067 :             move32();
     969             :             // Word32 imag = L_shr( *long_mdft_ptr_im_fx, 3 ); // Q27
     970     2000067 :             Word32 imag = *long_mdft_ptr_im_fx; // Q30
     971     2000067 :             move32();
     972     2000067 :             Word64 acc = W_mac_32_32( W_mult_32_32( real, real ), imag, imag ); // Q61
     973     2000067 :             sq_abs_fx = W_extract_h( acc );                                     // Q28
     974     2000067 :             long_mdft_ptr_re_fx++;
     975     2000067 :             long_mdft_ptr_im_fx++;
     976             : 
     977             :             /* accumulate bin energies within a short stride bin */
     978             : 
     979     2000067 :             short_stride_nrg_fx = L_add( short_stride_nrg_fx, L_shr( sq_abs_fx, 6 ) ); // Q22
     980     2000067 :             move32();
     981             : 
     982     2000067 :             IF( !( add( j, 1 ) % num_bins_per_short_stride_bin ) )
     983             :             {
     984             :                 /* new short stride bin */
     985      498948 :                 short_stride_pow_spec_fx[j / num_bins_per_short_stride_bin] = short_stride_nrg_fx; /* energy rather than magnitude works better for covariance weighting*/
     986      498948 :                 move32();
     987      498948 :                 short_stride_max_per_spar_band_fx = L_max( short_stride_nrg_fx, short_stride_max_per_spar_band_fx ); /*compute highest magnitude per band*/
     988      498948 :                 short_stride_nrg_fx = 0;
     989      498948 :                 move32();
     990             :             }
     991             : 
     992             :             /* accumulate bin energies within a CLDFB band */
     993     2000067 :             cldfb_nrg_fx = W_mac_32_32( cldfb_nrg_fx, sq_abs_fx, 1 ); // Q29
     994             : 
     995     2000067 :             IF( !( add( j, 1 ) % num_bins_per_cldfb_band ) )
     996             :             {
     997      123740 :                 Word16 exp = W_norm( cldfb_nrg_fx );
     998      123740 :                 cldfb_nrg_fx = W_shl( cldfb_nrg_fx, exp );
     999      123740 :                 exp = sub( 34, exp ); // 31 - (Q29 + exp -32)
    1000      123740 :                 temp = Sqrt32( W_extract_h( cldfb_nrg_fx ), &exp );
    1001      123740 :                 temp = L_shl( temp, sub( exp, Q9 ) );                                                         // Q22
    1002      123740 :                 pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[j / num_bins_per_cldfb_band][i] = temp; // Q22
    1003      123740 :                 move32();
    1004      123740 :                 cldfb_nrg_fx = 0;
    1005      123740 :                 move32();
    1006             :             }
    1007             :         }
    1008             : 
    1009        6610 :         quo = BASOP_Util_Divide3232_Scale( ONE_IN_Q30, short_stride_max_per_spar_band_fx, &exp_diff );
    1010             :         /* Q of quo = Q30 - Q22 + (15 - exp_diff) --> Q23 - exp_diff.
    1011             :         With Mult_32_16, Q23 - exp_diff - 15 --> Q8 - exp_diff */
    1012        6610 :         exp_diff = sub( Q8, exp_diff );
    1013             : 
    1014             :         /*loop over the short MDFT bins*/
    1015     1244850 :         FOR( j = 0; j < short_stride; j++ )
    1016             :         {
    1017     1238240 :             short_stride_pow_spec_fx[j] = L_shr( Mult_32_16( short_stride_pow_spec_fx[j], quo ), exp_diff ); // Q22
    1018     1238240 :             move32();
    1019     1238240 :             short_stride_pow_spec_fx[j] = L_max( L_sub( short_stride_pow_spec_fx[j], 1258291 ), 0 ); // 0.3f * ONE_IN_Q22
    1020     1238240 :             move32();
    1021     1238240 :             short_stride_pow_spec_fx[j] = L_shl( Mpy_32_32( short_stride_pow_spec_fx[j], 1533916891 /* 1/0.7 in Q30 */ ), 1 ); // Q22
    1022     1238240 :             move32();
    1023             : 
    1024             : 
    1025     1238240 :             IF( short_stride_pow_spec_fx[j] > 0 )
    1026             :             {
    1027      111998 :                 assert( idx_short_stride_bin_to_band < 2 * MDFT_FB_BANDS_240 ); /* array size of p_short_stride_bin_to_band */
    1028      111998 :                 IF( EQ_16( short_mdft_start_bin, -1 ) )
    1029             :                 {
    1030        6610 :                     short_mdft_start_bin = j;
    1031        6610 :                     move16();
    1032        6610 :                     pFb->fb_bin_to_band.p_short_stride_start_bin_per_band[i] = j;
    1033        6610 :                     move16();
    1034             : 
    1035        6610 :                     pFb->fb_bin_to_band.pp_short_stride_bin_to_band_fx[i] = &pFb->fb_bin_to_band.p_short_stride_bin_to_band_fx[idx_short_stride_bin_to_band]; // Q22
    1036        6610 :                     index[i] = idx_short_stride_bin_to_band;
    1037        6610 :                     move16();
    1038             :                 }
    1039             : 
    1040      111998 :                 pFb->fb_bin_to_band.p_short_stride_bin_to_band_fx[idx_short_stride_bin_to_band] = short_stride_pow_spec_fx[j]; // Q22
    1041      111998 :                 move32();
    1042      111998 :                 idx_short_stride_bin_to_band = add( idx_short_stride_bin_to_band, 1 );
    1043             : 
    1044      111998 :                 pFb->fb_bin_to_band.p_short_stride_num_bins_per_band[i] = add( pFb->fb_bin_to_band.p_short_stride_num_bins_per_band[i], 1 );
    1045      111998 :                 move16();
    1046             :             }
    1047             :         }
    1048             :     }
    1049             : 
    1050             :     /*loop over CLDFB bands*/
    1051       26624 :     FOR( j = 0; j < pFb->fb_bin_to_band.num_cldfb_bands; j++ )
    1052             :     {
    1053       26060 :         Word32 sum_over_spar_bands_fx = 0;
    1054       26060 :         move32();
    1055       26060 :         Word32 max_spar_band_contribution_fx = 0;
    1056       26060 :         move32();
    1057             : 
    1058       26060 :         Word16 spar_start = 0;
    1059       26060 :         move16();
    1060       26060 :         Word16 any_non_zero = 0;
    1061       26060 :         move16();
    1062             : 
    1063      335620 :         FOR( i = 0; i < bands; i++ )
    1064             :         {
    1065      309560 :             sum_over_spar_bands_fx = L_add( sum_over_spar_bands_fx, pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[j][i] ); // Q22
    1066      309560 :             move32();
    1067             : 
    1068      309560 :             IF( pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[j][i] > max_spar_band_contribution_fx )
    1069             :             {
    1070       76715 :                 max_spar_band_contribution_fx = pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[j][i]; // Q22
    1071       76715 :                 move32();
    1072       76715 :                 pFb->fb_bin_to_band.p_cldfb_map_to_spar_band[j] = i;
    1073       76715 :                 move16();
    1074             :             }
    1075             :         }
    1076             : 
    1077       26060 :         sum_over_spar_bands_fx = L_max( sum_over_spar_bands_fx, EPSILON_FX ); // Q22
    1078       26060 :         move32();
    1079             : 
    1080       26060 :         exp_diff = 0;
    1081       26060 :         move16();
    1082       26060 :         tmp = BASOP_Util_Divide3232_Scale( ONE_IN_Q30, sum_over_spar_bands_fx, &exp_diff );
    1083             :         /* Q of quo = Q30 - Q22 + (15 - exp_diff) --> Q23 - exp_diff.
    1084             :         With Mult_32_16, Q23 - exp_diff - 15 --> Q8 - exp_diff */
    1085       26060 :         exp_diff = sub( Q8, exp_diff );
    1086             : 
    1087      335620 :         FOR( i = 0; i < bands; i++ )
    1088             :         {
    1089      309560 :             test();
    1090      309560 :             IF( pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[j][i] == 0 && !any_non_zero )
    1091             :             {
    1092      165303 :                 spar_start = add( spar_start, 1 );
    1093             :             }
    1094             :             ELSE
    1095             :             {
    1096      144257 :                 any_non_zero = 1;
    1097      144257 :                 move16();
    1098             :             }
    1099             : 
    1100      309560 :             pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[j][i] = L_shr( Mult_32_16( pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[j][i], tmp ), exp_diff );
    1101      309560 :             move32();
    1102             :         }
    1103       26060 :         pFb->fb_bin_to_band.p_spar_start_bands[j] = spar_start;
    1104       26060 :         move16();
    1105             :     }
    1106             : 
    1107         564 :     set32_fx( ppFilterbank_FRs_s_fx, 0, frame_len );
    1108             : 
    1109             :     /*Commented logic is for calculating number of active bands, can be removed if not needed */
    1110        7174 :     FOR( i = 0; i < bands; i++ )
    1111             :     {
    1112        6610 :         const Word32 *pFilterbank_bin_to_band_re_fx = pFb->fb_consts.ppFilterbank_FRs_fx[0][i]; // Q30
    1113        6610 :         move32();
    1114        6610 :         const Word32 *pFilterbank_bin_to_band_im_fx = pFb->fb_consts.ppFilterbank_FRs_fx[1][i]; // Q30
    1115        6610 :         move32();
    1116             : 
    1117        6610 :         Word16 start_offset = pFb->fb_consts.pFilterbank_bins_start_offset[i];
    1118        6610 :         move16();
    1119        6610 :         Word16 num_bins = pFb->fb_consts.pFilterbank_bins_per_band[i];
    1120        6610 :         move16();
    1121        6610 :         Word16 idx = 0;
    1122        6610 :         move16();
    1123        6610 :         Word16 abs_active_bins = pFb->fb_bin_to_band.pFb_active_bins_per_band[i];
    1124        6610 :         move16();
    1125        6610 :         Word16 abs_start_offset = pFb->fb_bin_to_band.pFb_start_bin_per_band[i];
    1126        6610 :         move16();
    1127             : 
    1128     2006677 :         FOR( j = start_offset; j < num_bins + start_offset; j++ )
    1129             :         {
    1130     2000067 :             Word32 temp_fx = 0;
    1131     2000067 :             move32();
    1132             : 
    1133     2000067 :             exp_diff = 0;
    1134     2000067 :             move16();
    1135     2000067 :             Word32 real = L_shr( *pFilterbank_bin_to_band_re_fx, 3 ); // Q27
    1136     2000067 :             Word32 imag = L_shr( *pFilterbank_bin_to_band_im_fx, 3 ); // Q27
    1137             : 
    1138             :             Word32 real_sq, imag_sq;
    1139     2000067 :             real_sq = Mpy_32_32( real, real ); // Q27 + Q27 - 31 = Q23
    1140     2000067 :             imag_sq = Mpy_32_32( imag, imag ); // Q27 + Q27 - 31 = Q23
    1141             : 
    1142     2000067 :             temp_fx = L_add( L_shr( real_sq, 1 ), L_shr( imag_sq, 1 ) ); // Q22
    1143             : 
    1144     2000067 :             exp_diff = 9;
    1145     2000067 :             move16();
    1146     2000067 :             temp_fx = Sqrt32( temp_fx, &exp_diff );
    1147     2000067 :             temp_fx = L_shl( temp_fx, sub( exp_diff, Q9 ) ); // Q22
    1148             : 
    1149             : 
    1150     2000067 :             pFilterbank_bin_to_band_re_fx++;
    1151     2000067 :             pFilterbank_bin_to_band_im_fx++;
    1152             : 
    1153     2000067 :             temp_fx = L_sub( temp_fx, 1258291 ); // 0.3 in Q22
    1154     2000067 :             move32();
    1155             : 
    1156     2000067 :             if ( temp_fx < 0 )
    1157             :             {
    1158     1433594 :                 temp_fx = 0;
    1159     1433594 :                 move32();
    1160             :             }
    1161             : 
    1162     2000067 :             test();
    1163     2000067 :             test();
    1164     2000067 :             IF( LT_16( j, add( abs_active_bins, abs_start_offset ) ) && GE_16( j, abs_start_offset ) && NE_16( alloc_fb_resp, -1 ) )
    1165             :             {
    1166      294399 :                 pFb->fb_bin_to_band.pFb_bin_to_band_fx[i][idx] = temp_fx; // Q22
    1167      294399 :                 move32();
    1168      294399 :                 idx = add( idx, 1 );
    1169             :             }
    1170             : 
    1171             : 
    1172     2000067 :             ppFilterbank_FRs_s_fx[j] = L_add( ppFilterbank_FRs_s_fx[j], temp_fx ); // Q22
    1173     2000067 :             move32();
    1174             :         }
    1175             :     }
    1176             : 
    1177      417524 :     FOR( i = 0; i < frame_len; i++ )
    1178             :     {
    1179      416960 :         if ( ppFilterbank_FRs_s_fx[i] < 0 )
    1180             :         {
    1181           0 :             ppFilterbank_FRs_s_fx[i] = 419430; // 0.1 in Q22
    1182           0 :             move32();
    1183             :         }
    1184             :     }
    1185             : 
    1186         564 :     IF( NE_16( alloc_fb_resp, -1 ) )
    1187             :     {
    1188        3705 :         FOR( j = 0; j < bands; j++ )
    1189             :         {
    1190        3414 :             Word16 abs_active_bins = pFb->fb_bin_to_band.pFb_active_bins_per_band[j];
    1191        3414 :             Word16 abs_start_offset = pFb->fb_bin_to_band.pFb_start_bin_per_band[j];
    1192        3414 :             exp_diff = 0;
    1193             : 
    1194        3414 :             move16();
    1195        3414 :             move16();
    1196        3414 :             move16();
    1197             : 
    1198      297813 :             FOR( i = 0; i < abs_active_bins; i++ )
    1199             :             {
    1200      294399 :                 tmp = BASOP_Util_Divide3232_Scale( pFb->fb_bin_to_band.pFb_bin_to_band_fx[j][i], ppFilterbank_FRs_s_fx[i + abs_start_offset], &exp_diff );
    1201      294399 :                 pFb->fb_bin_to_band.pFb_bin_to_band_fx[j][i] = L_shl( L_deposit_l( tmp ), add( Q7, exp_diff ) ); // Q22
    1202      294399 :                 move32();
    1203             :                 /*if(pFb->fb_bin_to_band.pFb_bin_to_band[j][i] > 0.5f)
    1204             :                 {
    1205             :                     num_active_bands = j + 1;
    1206             :                     break;
    1207             :                 }*/
    1208             :             }
    1209             :         }
    1210             :     }
    1211             : 
    1212         564 :     return num_active_bands;
    1213             : }
    1214             : 
    1215             : /*-----------------------------------------------------------------------------------------*
    1216             :  * Function ivas_get_active_bins()
    1217             :  *
    1218             :  *
    1219             :  *-----------------------------------------------------------------------------------------*/
    1220             : 
    1221        1128 : static void ivas_get_active_bins_fx(
    1222             :     const Word16 **pActive_bins,
    1223             :     const Word16 **pActive_bins_abs,
    1224             :     const Word16 **pStart_offset,
    1225             :     const Word16 **pStart_offset_abs,
    1226             :     const Word32 sampling_rate )
    1227             : {
    1228             :     Word16 sr_idx;
    1229             : 
    1230        1128 :     IF( EQ_32( sampling_rate, 32000 ) )
    1231             :     {
    1232         462 :         sr_idx = 1;
    1233         462 :         move16();
    1234             :     }
    1235         666 :     ELSE IF( EQ_32( sampling_rate, 16000 ) )
    1236             :     {
    1237         158 :         sr_idx = 2;
    1238         158 :         move16();
    1239             :     }
    1240             :     ELSE
    1241             :     {
    1242         508 :         sr_idx = 0;
    1243         508 :         move16();
    1244             :     }
    1245             : 
    1246        1128 :     *pActive_bins_abs = ivas_fb_abs_bins_per_band_12band_1ms[sr_idx];
    1247        1128 :     move16();
    1248        1128 :     *pActive_bins = ivas_fb_bins_per_band_12band_1ms[sr_idx];
    1249        1128 :     move16();
    1250        1128 :     *pStart_offset_abs = ivas_fb_abs_bins_start_offset_12band_1ms[sr_idx];
    1251        1128 :     move16();
    1252        1128 :     *pStart_offset = ivas_fb_bins_start_offset_12band_1ms[sr_idx];
    1253        1128 :     move16();
    1254             : 
    1255        1128 :     return;
    1256             : }
    1257             : 
    1258             : 
    1259             : /*-----------------------------------------------------------------------------------------*
    1260             :  * Function ivas_filterbank_setup()
    1261             :  *
    1262             :  * Filterbank setup, initialization
    1263             :  *-----------------------------------------------------------------------------------------*/
    1264             : 
    1265        1668 : static ivas_error ivas_filterbank_setup_fx(
    1266             :     IVAS_FB_MIXER_HANDLE hFbMixer,
    1267             :     const Word32 sampling_rate,
    1268             :     Word16 *index )
    1269             : {
    1270             :     Word16 i, j, exp, tmp;
    1271             :     const Word32 *pAll_fb_fr_fx[2];
    1272        1668 :     const Word16 *pAll_bins_start_offset = NULL;
    1273        1668 :     const Word16 *pAll_bins_per_band = NULL;
    1274        1668 :     const Word16 *pAll_bins_start_offset_abs = NULL;
    1275        1668 :     const Word16 *pAll_bins_per_band_abs = NULL;
    1276        1668 :     const Word16 *pAll_bins_per_band_48k = NULL;
    1277             :     ivas_error error;
    1278        1668 :     IVAS_FB_CFG *pCfg = hFbMixer->fb_cfg;
    1279             : 
    1280        1668 :     error = IVAS_ERR_OK;
    1281        1668 :     move32();
    1282             : 
    1283        1668 :     IF( pCfg->num_out_chans > 0 )
    1284             :     {
    1285         564 :         hFbMixer->pFb->filterbank_num_bands = ivas_get_num_bands( sampling_rate );
    1286         564 :         move16();
    1287             : 
    1288         564 :         ivas_get_active_bins_fx( &pAll_bins_per_band, &pAll_bins_per_band_abs, &pAll_bins_start_offset, &pAll_bins_start_offset_abs, sampling_rate );
    1289             : 
    1290         564 :         IF( EQ_16( pCfg->fb_latency, NS2SA_FX2( sampling_rate, DELAY_FB_1_NS ) ) )
    1291             :         {
    1292         564 :             pAll_fb_fr_fx[0] = ivas_fb_fr_12band_1ms_re_fx; // Q30
    1293         564 :             move32();
    1294         564 :             pAll_fb_fr_fx[1] = ivas_fb_fr_12band_1ms_im_fx; // Q30
    1295         564 :             move32();
    1296             : 
    1297         564 :             pAll_bins_per_band_48k = ivas_fb_bins_per_band_12band_1ms[0];
    1298         564 :             move16();
    1299             :         }
    1300             :         ELSE
    1301             :         {
    1302           0 :             return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Wrong FB in ivas_filterbank_setup()!" );
    1303             :         }
    1304             :     }
    1305             : 
    1306        1668 :     hFbMixer->cross_fade_end_offset = add( pCfg->fade_len, pCfg->pcm_offset );
    1307        1668 :     move16();
    1308        1668 :     hFbMixer->cross_fade_start_offset = sub( hFbMixer->cross_fade_end_offset, pCfg->fade_len );
    1309        1668 :     move16();
    1310        1668 :     hFbMixer->ana_window_offset = add( pCfg->fb_latency, pCfg->pcm_offset );
    1311        1668 :     move16();
    1312             : 
    1313        1668 :     IF( NE_32( ( error = ivas_fb_mixer_get_window_fx( pCfg->fb_latency, sampling_rate, &( hFbMixer->pAna_window_fx ) ) ), IVAS_ERR_OK ) )
    1314             :     {
    1315           0 :         return error;
    1316             :     }
    1317             : 
    1318        1668 :     IF( NE_32( ( error = ivas_fb_mixer_get_window_fx( pCfg->fade_len, sampling_rate, &( hFbMixer->pFilterbank_cross_fade_fx ) ) ), IVAS_ERR_OK ) )
    1319             :     {
    1320           0 :         return error;
    1321             :     }
    1322             : 
    1323        1668 :     IF( pCfg->num_out_chans > 0 )
    1324             :     {
    1325         564 :         ivas_filterbank_t *pFb = hFbMixer->pFb;
    1326         564 :         Word16 offset = 0;
    1327         564 :         move16();
    1328             : 
    1329         564 :         pFb->fb_consts.pFilterbank_bins_per_band = pAll_bins_per_band;
    1330         564 :         pFb->fb_consts.pFilterbank_bins_start_offset = pAll_bins_start_offset;
    1331         564 :         pFb->fb_bin_to_band.pFb_active_bins_per_band = pAll_bins_per_band_abs;
    1332         564 :         pFb->fb_bin_to_band.pFb_start_bin_per_band = pAll_bins_start_offset_abs;
    1333             : 
    1334             :         /* Initialization for short stride Parameter calculation and SPAR CLDFB reconstruction */
    1335         564 :         SWITCH( sampling_rate )
    1336             :         {
    1337         254 :             case 48000:
    1338         254 :                 pFb->fb_bin_to_band.num_cldfb_bands = 60; /* sampling_rate * 1.0f / 800.0f  */
    1339         254 :                 move16();
    1340         254 :                 BREAK;
    1341         231 :             case 32000:
    1342         231 :                 pFb->fb_bin_to_band.num_cldfb_bands = 40;
    1343         231 :                 move16();
    1344         231 :                 BREAK;
    1345          79 :             case 16000:
    1346          79 :                 pFb->fb_bin_to_band.num_cldfb_bands = 20;
    1347          79 :                 move16();
    1348          79 :                 BREAK;
    1349             :         }
    1350             : 
    1351             :         /*pFb->fb_bin_to_band.cldfb_stride = ( int16_t )( ( sampling_rate / FRAMES_PER_SEC ) / CLDFB_NO_COL_MAX );*/ /* equals num_cldfb_bands*/
    1352             :         // pFb->fb_bin_to_band.short_stride = extract_l( ( sampling_rate / FRAMES_PER_SEC ) / 4 );
    1353         564 :         tmp = BASOP_Util_Divide3232_Scale( sampling_rate, FRAMES_PER_SEC, &exp );
    1354         564 :         pFb->fb_bin_to_band.short_stride = shr( tmp, add( sub( 15, exp ), 2 ) );
    1355             : 
    1356         564 :         move16();
    1357             : 
    1358         564 :         set32_fx( pFb->fb_bin_to_band.p_short_stride_bin_to_band_fx, 0, 2 * MDFT_FB_BANDS_240 );
    1359             : 
    1360         564 :         set16_fx( pFb->fb_bin_to_band.p_cldfb_map_to_spar_band, 0, CLDFB_NO_CHANNELS_MAX );
    1361         564 :         set16_fx( pFb->fb_bin_to_band.p_spar_start_bands, 0, CLDFB_NO_CHANNELS_MAX );
    1362             : 
    1363       11844 :         FOR( j = 0; j < IVAS_MAX_NUM_FB_BANDS; j++ )
    1364             :         {
    1365       11280 :             pFb->fb_bin_to_band.p_short_stride_num_bins_per_band[j] = 0; /* aka num_active_bins per SPAR band */
    1366       11280 :             move16();
    1367       11280 :             pFb->fb_bin_to_band.p_short_stride_start_bin_per_band[j] = 0; /* first considered bin index per SPAR band */
    1368       11280 :             move16();
    1369             : 
    1370       11280 :             pFb->fb_bin_to_band.pp_short_stride_bin_to_band_fx[j] = NULL;
    1371             : 
    1372      688080 :             FOR( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ )
    1373             :             {
    1374             : 
    1375      676800 :                 pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[i][j] = 0;
    1376      676800 :                 move32();
    1377             :             }
    1378             :         }
    1379         564 :         IF( EQ_32( sampling_rate, 48000 ) )
    1380             :         {
    1381        3302 :             FOR( j = 0; j < pFb->filterbank_num_bands; j++ )
    1382             :             {
    1383             : 
    1384        3048 :                 pFb->fb_consts.ppFilterbank_FRs_fx[0][j] = &pAll_fb_fr_fx[0][offset]; // Q30
    1385        3048 :                 pFb->fb_consts.ppFilterbank_FRs_fx[1][j] = &pAll_fb_fr_fx[1][offset]; // Q30
    1386             : 
    1387        3048 :                 offset = add( offset, pFb->fb_consts.pFilterbank_bins_per_band[j] );
    1388             :             }
    1389             : 
    1390             :             /****************************************Calculate abs fr ***************************/
    1391             : 
    1392         254 :             ivas_calculate_abs_fr_fx( pFb, sampling_rate, pCfg->active_w_mixing, index );
    1393             :         }
    1394             :         ELSE
    1395             :         {
    1396             : 
    1397             :             Word32 *ppFilterbank_FRs_re_temp_fx[MAX_NUM_BANDS_DIFF_NON48K];
    1398             :             Word32 *ppFilterbank_FRs_im_temp_fx[MAX_NUM_BANDS_DIFF_NON48K];
    1399             :             Word16 active_bins_temp[MAX_NUM_BANDS_DIFF_NON48K];
    1400             :             Word16 start_offset_temp[MAX_NUM_BANDS_DIFF_NON48K];
    1401             :             Word16 num_diff_bands, start_diff_band_non48k;
    1402             : 
    1403         310 :             num_diff_bands = MAX_NUM_BANDS_DIFF_NON48K;
    1404         310 :             start_diff_band_non48k = sub( pFb->filterbank_num_bands, num_diff_bands );
    1405         310 :             move16();
    1406             : 
    1407         310 :             pFb->fb_consts.pFilterbank_bins_per_band = pAll_bins_per_band;
    1408         310 :             pFb->fb_consts.pFilterbank_bins_start_offset = pAll_bins_start_offset;
    1409             : 
    1410        3872 :             FOR( j = 0; j < pFb->filterbank_num_bands; j++ )
    1411             :             {
    1412        3562 :                 Word16 num_active_bins = pFb->fb_consts.pFilterbank_bins_per_band[j];
    1413        3562 :                 move16();
    1414             : 
    1415        3562 :                 IF( j < start_diff_band_non48k )
    1416             :                 {
    1417             : 
    1418        2632 :                     pFb->fb_consts.ppFilterbank_FRs_fx[0][j] = &pAll_fb_fr_fx[0][offset]; // Q30
    1419        2632 :                     pFb->fb_consts.ppFilterbank_FRs_fx[1][j] = &pAll_fb_fr_fx[1][offset]; // Q30
    1420             :                 }
    1421             :                 ELSE
    1422             :                 {
    1423         930 :                     Copy32( &pAll_fb_fr_fx[0][offset], pFb->fb_consts.ppFilterbank_FRs_non48k_fx[0][j], num_active_bins ); // Q30
    1424         930 :                     Copy32( &pAll_fb_fr_fx[1][offset], pFb->fb_consts.ppFilterbank_FRs_non48k_fx[1][j], num_active_bins ); // Q30
    1425             :                 }
    1426             : 
    1427        3562 :                 offset = add( offset, pAll_bins_per_band_48k[j] );
    1428             :             }
    1429             : 
    1430        1240 :             FOR( j = start_diff_band_non48k; j < pFb->filterbank_num_bands; j++ )
    1431             :             {
    1432             : 
    1433         930 :                 ppFilterbank_FRs_re_temp_fx[j - start_diff_band_non48k] = pFb->fb_consts.ppFilterbank_FRs_non48k_fx[0][j]; // Q30
    1434         930 :                 ppFilterbank_FRs_im_temp_fx[j - start_diff_band_non48k] = pFb->fb_consts.ppFilterbank_FRs_non48k_fx[1][j]; // Q30
    1435             : 
    1436         930 :                 active_bins_temp[j - start_diff_band_non48k] = pFb->fb_consts.pFilterbank_bins_per_band[j];
    1437         930 :                 start_offset_temp[j - start_diff_band_non48k] = pFb->fb_consts.pFilterbank_bins_start_offset[j];
    1438         930 :                 move16();
    1439         930 :                 move16();
    1440             :             }
    1441             : 
    1442         310 :             ivas_get_ld_fb_resp_fx( ppFilterbank_FRs_re_temp_fx, ppFilterbank_FRs_im_temp_fx, ppFilterbank_FRs_re_temp_fx, ppFilterbank_FRs_im_temp_fx,
    1443         310 :                                     active_bins_temp, start_offset_temp, num_diff_bands, pCfg->fb_latency, sampling_rate );
    1444             : 
    1445             : 
    1446        1240 :             FOR( j = start_diff_band_non48k; j < pFb->filterbank_num_bands; j++ )
    1447             :             {
    1448             : 
    1449         930 :                 pFb->fb_consts.ppFilterbank_FRs_fx[0][j] = (const Word32 *) pFb->fb_consts.ppFilterbank_FRs_non48k_fx[0][j]; // Q30
    1450         930 :                 pFb->fb_consts.ppFilterbank_FRs_fx[1][j] = (const Word32 *) pFb->fb_consts.ppFilterbank_FRs_non48k_fx[1][j]; // Q30
    1451             :             }
    1452             : 
    1453             :             /******************************************** Calculate abs fr ****************************************************/
    1454             : 
    1455         310 :             ivas_calculate_abs_fr_fx( pFb, sampling_rate, pCfg->active_w_mixing, index );
    1456             :         }
    1457             :     }
    1458             : 
    1459        1668 :     return error;
    1460             : }
    1461             : 
    1462             : /*-----------------------------------------------------------------------------------------*
    1463             :  * Function ivas_fb_mixer_get_window()
    1464             :  *
    1465             :  *
    1466             :  *-----------------------------------------------------------------------------------------*/
    1467             : 
    1468        3336 : static ivas_error ivas_fb_mixer_get_window_fx(
    1469             :     const Word16 fade_len,      /* i  : window fading length in samples    */
    1470             :     const Word32 sampling_rate, /* i  : sampling rate                      */
    1471             :     const Word16 **pWindow      /* o  : pointer to the window coefficents  */
    1472             : )
    1473             : {
    1474             :     ivas_error error;
    1475             : 
    1476        3336 :     error = IVAS_ERR_OK;
    1477        3336 :     move32();
    1478             : 
    1479        3336 :     IF( EQ_16( fade_len, NS2SA_FX2( sampling_rate, DELAY_FB_4_NS ) ) )
    1480             :     {
    1481        1192 :         SWITCH( sampling_rate )
    1482             :         {
    1483         882 :             case 48000:
    1484         882 :                 *pWindow = ivas_fb_cf_4ms_48k_fx;
    1485         882 :                 BREAK;
    1486         231 :             case 32000:
    1487         231 :                 *pWindow = ivas_fb_cf_4ms_32k_fx;
    1488         231 :                 BREAK;
    1489          79 :             case 16000:
    1490          79 :                 *pWindow = ivas_fb_cf_4ms_16k_fx;
    1491          79 :                 BREAK;
    1492           0 :             default:
    1493           0 :                 return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Unsupported Sampling frequency!" );
    1494             :         }
    1495             :     }
    1496        2144 :     ELSE IF( EQ_16( fade_len, NS2SA_FX2( sampling_rate, DELAY_FB_1_NS ) ) )
    1497             :     {
    1498        2144 :         SWITCH( sampling_rate )
    1499             :         {
    1500        1566 :             case 48000:
    1501        1566 :                 *pWindow = ivas_fb_cf_1ms_48k_fx;
    1502        1566 :                 BREAK;
    1503         499 :             case 32000:
    1504         499 :                 *pWindow = ivas_fb_cf_1ms_32k_fx;
    1505         499 :                 BREAK;
    1506          79 :             case 16000:
    1507          79 :                 *pWindow = ivas_fb_cf_1ms_16k_fx;
    1508          79 :                 BREAK;
    1509           0 :             default:
    1510           0 :                 return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Unsupported Sampling frequency!" );
    1511             :         }
    1512             :     }
    1513             :     ELSE
    1514             :     {
    1515           0 :         IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error: Incorrect FB window fade len (%f ms)\n", ( fade_len / 1000000.f ) );
    1516             :     }
    1517             : 
    1518        3336 :     return error;
    1519             : }
    1520             : 
    1521             : 
    1522         310 : static const Word32 *ivas_get_cheby_ramp_fx(
    1523             :     const Word16 delay )
    1524             : {
    1525         310 :     const Word32 *pCheby_fx = NULL;
    1526             : 
    1527         310 :     SWITCH( delay )
    1528             :     {
    1529         231 :         case IVAS_FB_1MS_32K_SAMP:
    1530         231 :             pCheby_fx = ivas_fb_resp_cheby_ramp_32del_fx;
    1531         231 :             BREAK;
    1532          79 :         case IVAS_FB_1MS_16K_SAMP:
    1533          79 :             pCheby_fx = ivas_fb_resp_cheby_ramp_16del_fx;
    1534          79 :             BREAK;
    1535           0 :         default:
    1536           0 :             assert( !"Unsupported cheby ramp length!" );
    1537             :     }
    1538             : 
    1539         310 :     return pCheby_fx;
    1540             : }
    1541             : 
    1542         310 : static void ivas_get_ld_fb_resp_fx(
    1543             :     Word32 **ppIdeal_FRs_re_fx, // i: Q30
    1544             :     Word32 **ppIdeal_FRs_im_fx, // i: Q30
    1545             :     Word32 **ppNew_FRs_re_fx,   // o: Q30
    1546             :     Word32 **ppNew_FRs_im_fx,   // o: Q30
    1547             :     const Word16 *pActive_bins,
    1548             :     const Word16 *pStart_offset,
    1549             :     const Word16 num_bands,
    1550             :     const Word16 delay,
    1551             :     const Word32 sampling_rate )
    1552             : {
    1553             :     Word16 b, s, frame_len;
    1554             :     const Word32 *pCheby_fx;
    1555         310 :     frame_len = 0;
    1556         310 :     move16();
    1557             :     /*common scratch buffers for computing impulse/frequency responses,
    1558             :     pre-ring, post-ring and circular shifted outputs to optimize stack*/
    1559             :     Word32 scratch1_fx[L_FRAME32k * 2];
    1560             :     Word32 scratch2_fx[L_FRAME32k * 2];
    1561             : 
    1562         310 :     set32_fx( scratch1_fx, 0, L_FRAME32k * 2 );
    1563         310 :     set32_fx( scratch2_fx, 0, L_FRAME32k * 2 );
    1564             : 
    1565         310 :     const Word32 *han_win_fx = NULL;
    1566             : 
    1567         310 :     SWITCH( sampling_rate )
    1568             :     {
    1569           0 :         case 48000:
    1570           0 :             frame_len = 960;
    1571           0 :             move16();
    1572           0 :             han_win_fx = ivas_han_win_48k_fx; // Q31
    1573           0 :             BREAK;
    1574         231 :         case 32000:
    1575         231 :             frame_len = 640;
    1576         231 :             move16();
    1577         231 :             han_win_fx = ivas_han_win_32k_fx; // Q31
    1578         231 :             BREAK;
    1579          79 :         case 16000:
    1580          79 :             frame_len = 320;
    1581          79 :             move16();
    1582          79 :             han_win_fx = ivas_han_win_16k_fx; // Q31
    1583          79 :             BREAK;
    1584             :     }
    1585             : 
    1586         310 :     pCheby_fx = ivas_get_cheby_ramp_fx( delay ); // Q31
    1587             : 
    1588         310 :     b = 0;
    1589         310 :     s = 0;
    1590         310 :     move16();
    1591         310 :     move16();
    1592             : 
    1593         310 :     assert( sampling_rate == 32000 || sampling_rate == 16000 );
    1594             : 
    1595        1240 :     FOR( b = 0; b < num_bands; b++ )
    1596             :     {
    1597             : 
    1598         930 :         set32_fx( scratch2_fx, 0, shl( frame_len, 1 ) );
    1599         930 :         Copy32( ppIdeal_FRs_re_fx[b], &scratch2_fx[pStart_offset[b]], pActive_bins[b] );             // Q30
    1600         930 :         Copy32( ppIdeal_FRs_im_fx[b], &scratch2_fx[frame_len + pStart_offset[b]], pActive_bins[b] ); // Q30
    1601             : 
    1602         930 :         Word16 guard_bits = sub( L_norm_arr( scratch2_fx, shl( L_FRAME32k, 1 ) ), find_guarded_bits_fx( shl( frame_len, 1 ) ) );
    1603         930 :         Scale_sig32( scratch2_fx, shl( L_FRAME32k, 1 ), guard_bits ); // Q30 + guard_bits
    1604             : 
    1605         930 :         ivas_imdft_fx( scratch2_fx, &scratch2_fx[frame_len], scratch1_fx, frame_len );
    1606             : 
    1607     1191330 :         FOR( Word16 x = 0; x < shl( L_FRAME32k, 1 ); x++ )
    1608             :         {
    1609     1190400 :             scratch2_fx[x] = L_shr( scratch2_fx[x], guard_bits ); // (Q30 + guard_bits) - guard_bits = Q30
    1610     1190400 :             scratch1_fx[x] = L_shr( scratch1_fx[x], guard_bits ); // (Q30 + guard_bits) - guard_bits = Q30
    1611             : 
    1612     1190400 :             move32();
    1613     1190400 :             move32();
    1614             :         }
    1615             : 
    1616             :         /*apply circular shift and hanning window*/
    1617             : 
    1618      520290 :         FOR( s = delay; s < frame_len + delay; s++ )
    1619             :         {
    1620             : 
    1621      519360 :             scratch2_fx[s - delay] = Mpy_32_32( scratch1_fx[s], L_sub( ONE_IN_Q31, han_win_fx[s - delay] ) ); // Q(30 + 31 - 31) == Q30
    1622      519360 :             move32();
    1623             :         }
    1624             : 
    1625      494322 :         FOR( ; s < 2 * frame_len; s++ )
    1626             :         {
    1627             : 
    1628      493392 :             scratch2_fx[s - delay] = Mpy_32_32( scratch1_fx[s], han_win_fx[s - ( frame_len + delay )] ); // Q30
    1629      493392 :             move32();
    1630             :         }
    1631             : 
    1632       26898 :         FOR( s = 0; s < delay; s++ )
    1633             :         {
    1634             : 
    1635       25968 :             scratch2_fx[( ( ( frame_len * 2 ) - delay ) + s )] = L_negate( Mpy_32_32( scratch1_fx[s], han_win_fx[( frame_len - delay ) + s] ) ); // Q30
    1636       25968 :             move32();
    1637             :         }
    1638             : 
    1639             :         /*apply heavy/cheby ramp window and compute pre ring*/
    1640             : 
    1641       27828 :         FOR( s = 0; s < delay + 1; s++ )
    1642             :         {
    1643       26898 :             scratch1_fx[s] = Mpy_32_32( scratch2_fx[s], pCheby_fx[delay - s] ); // Q30
    1644       26898 :             move32();
    1645             :         }
    1646             : 
    1647      493392 :         FOR( ; s < frame_len; s++ )
    1648             :         {
    1649      492462 :             scratch1_fx[s] = 0;
    1650      492462 :             move32();
    1651             :         }
    1652             : 
    1653      494322 :         FOR( ; s < 2 * frame_len - delay; s++ )
    1654             :         {
    1655      493392 :             scratch1_fx[s] = scratch2_fx[s];
    1656      493392 :             move32();
    1657             :         }
    1658             : 
    1659       26898 :         FOR( ; s < 2 * frame_len; s++ )
    1660             :         {
    1661       25968 :             scratch1_fx[s] = Mpy_32_32( scratch2_fx[s], L_sub( ONE_IN_Q31, pCheby_fx[s - ( 2 * frame_len - delay )] ) ); // Q30
    1662       25968 :             move32();
    1663             :         }
    1664             : 
    1665             :         /*IR - pre ring + post ring*/
    1666     1038720 :         FOR( s = 1; s < 2 * frame_len; s++ )
    1667             :         {
    1668     1037790 :             scratch2_fx[s] = L_sub( L_sub( scratch2_fx[s] /*pre ring*/, scratch1_fx[s] /*post ring*/ ), scratch1_fx[frame_len * 2 - s] );
    1669     1037790 :             move32();
    1670             :         }
    1671             : 
    1672     1013682 :         FOR( s = 0; s < 2 * frame_len - delay; s++ )
    1673             :         {
    1674     1012752 :             scratch1_fx[s + delay] = scratch2_fx[s];
    1675     1012752 :             move32();
    1676             :         }
    1677             : 
    1678       26898 :         FOR( ; s < 2 * frame_len; s++ )
    1679             :         {
    1680       25968 :             scratch1_fx[( s - ( ( frame_len * 2 ) - delay ) )] = L_negate( scratch2_fx[s] );
    1681       25968 :             move32();
    1682             :         }
    1683             : 
    1684             :         /* apply final window*/
    1685         930 :         const Word32 *sine_till_delay = ivas_sine_delay_32_fx; // Q30
    1686         930 :         Word16 offset = 1;
    1687         930 :         Word16 delay_16 = 0;
    1688             : 
    1689         930 :         move16();
    1690         930 :         move16();
    1691             : 
    1692         930 :         if ( EQ_16( delay, IVAS_FB_1MS_16K_SAMP ) )
    1693             :         {
    1694         237 :             delay_16 = 1;
    1695         237 :             move16();
    1696             :         }
    1697             : 
    1698       26898 :         FOR( s = 0; s < delay; s++ )
    1699             :         {
    1700       25968 :             scratch1_fx[s] = Mpy_32_32( scratch1_fx[s], sine_till_delay[s + offset * delay_16] ); // Q30 + Q30 - 31 = Q29
    1701       25968 :             offset = add( offset, 1 );
    1702       25968 :             scratch1_fx[s] = L_shl( scratch1_fx[s], 1 ); // Q30
    1703             : 
    1704       25968 :             move32();
    1705       25968 :             move32();
    1706             :         }
    1707             : 
    1708         930 :         const Word32 *sine_till_frame_len = NULL;
    1709             : 
    1710         930 :         IF( EQ_16( delay, IVAS_FB_1MS_16K_SAMP ) )
    1711             :         {
    1712         237 :             sine_till_frame_len = ivas_sine_frame_len_640_del_16_fx; // Q30
    1713         237 :             move32();
    1714             :         }
    1715             :         ELSE
    1716             :         {
    1717         693 :             sine_till_frame_len = ivas_sine_frame_len_640_del_32_fx; // Q30
    1718         693 :             move32();
    1719             :         }
    1720         930 :         Word16 iterator = 0;
    1721         930 :         move16();
    1722      469284 :         FOR( s = 2 * delay; s < frame_len + 1; s++ )
    1723             :         {
    1724      468354 :             scratch1_fx[s] = Mpy_32_32( scratch1_fx[s], sine_till_frame_len[iterator] ); // Q30 + Q30 - 31 = Q29
    1725      468354 :             iterator = add( iterator, 1 );
    1726      468354 :             scratch1_fx[s] = L_shl( scratch1_fx[s], 1 ); // Q30
    1727             : 
    1728      468354 :             move32();
    1729      468354 :             move32();
    1730             :         }
    1731             : 
    1732      519360 :         FOR( ; s < 2 * frame_len; s++ )
    1733             :         {
    1734      518430 :             scratch1_fx[s] = 0;
    1735             : 
    1736      518430 :             move32();
    1737             :         }
    1738             : 
    1739             :         /*compute frequency response*/
    1740         930 :         ivas_mdft_fx( scratch1_fx, scratch2_fx, &scratch2_fx[frame_len], shl( frame_len, 1 ), frame_len );
    1741             : 
    1742         930 :         Copy32( &scratch2_fx[pStart_offset[b]], ppNew_FRs_re_fx[b], pActive_bins[b] );                 // Q30
    1743         930 :         Copy32( &scratch2_fx[( frame_len + pStart_offset[b] )], ppNew_FRs_im_fx[b], pActive_bins[b] ); // Q30
    1744             :     }
    1745             : 
    1746         310 :     return;
    1747             : }

Generated by: LCOV version 1.14