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 @ 574a190e3c6896c6c4ed10d7f23649709a0c4347 Lines: 774 804 96.3 %
Date: 2025-06-27 02:59:36 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             : #ifdef OPT_SBA_ENC_V1_BE
     763      157500 :     Word16 total_guard = find_guarded_bits_fx( num_bands );
     764      157500 :     Word16 total_guard_2 = find_guarded_bits_fx( shl( frame_len, 1 ) );
     765      157500 :     Word16 tmp_q = sub( sub( *q_mixer_mat_fx, total_guard ), 32 ); // Q30 + hFbMixer->q_prior_mixer_fx - 31 - total_guard - 31
     766      157500 :     Word16 len = shl( frame_len, 1 );
     767             :     Word16 res_q, q_check;
     768             : #endif
     769      429399 :     FOR( ch = ( hFbMixer->fb_cfg->active_w_mixing == 0 ); ch < hFbMixer->fb_cfg->num_out_chans; ch++ )
     770             :     {
     771             :         /* Run a loop of 2 to calculate current frame's filterbank output and prev frame's output */
     772      815697 :         FOR( hist = 0; hist < 2; hist++ )
     773             :         {
     774      543798 :             set_zero_fx( pOut_fr_re_fx, frame_len );
     775      543798 :             set_zero_fx( pOut_fr_im_fx, frame_len );
     776      543798 :             q_pOut_fr_fx = 31;
     777      543798 :             move16();
     778     3332190 :             FOR( j = 0; j < hFbMixer->fb_cfg->num_in_chans; j++ )
     779             :             {
     780     2788392 :                 IF( in_out_mixer_map[ch][j] != 0 )
     781             :                 {
     782             : 
     783             : #ifdef OPT_SBA_ENC_V1_BE
     784      807144 :                     res_q = add( tmp_q, hFbMixer->q_ppFilterbank_inFR[j] );
     785      807144 :                     q_check = s_min( q_pOut_fr_fx, res_q );
     786      807144 :                     scale_sig32( pOut_fr_re_fx, frame_len, sub( q_check, q_pOut_fr_fx ) );
     787      807144 :                     scale_sig32( pOut_fr_im_fx, frame_len, sub( q_check, q_pOut_fr_fx ) );
     788             : #endif
     789             :                     Word32 filterbank_mixer_bins_re_fx[L_FRAME48k];
     790             :                     Word32 filterbank_mixer_bins_im_fx[L_FRAME48k];
     791      807144 :                     Word32 *pFb_inFR_re_fx = hFbMixer->ppFilterbank_inFR_re_fx[j]; // Q(hFbMixer->q_ppFilterbank_inFR_re_fx)
     792      807144 :                     Word32 *pFb_inFR_im_fx = hFbMixer->ppFilterbank_inFR_im_fx[j]; // Q(hFbMixer->q_ppFilterbank_inFR_im_fx)
     793             : 
     794      807144 :                     set_zero_fx( filterbank_mixer_bins_re_fx, frame_len );
     795      807144 :                     set_zero_fx( filterbank_mixer_bins_im_fx, frame_len );
     796             : 
     797             : #ifndef OPT_SBA_ENC_V1_BE
     798             :                     Word16 total_guard = find_guarded_bits_fx( num_bands );
     799             :                     move16();
     800             : #endif
     801    10353872 :                     FOR( i = 0; i < num_bands; i++ )
     802             :                     {
     803     9546728 :                         Word16 start_offset = pFb->fb_consts.pFilterbank_bins_start_offset[i];
     804     9546728 :                         move16();
     805     9546728 :                         Word16 num_bins = pFb->fb_consts.pFilterbank_bins_per_band[i];
     806     9546728 :                         move16();
     807     9546728 :                         Word32 mixer_const_fx = hFbMixer->prior_mixer_fx[ch][j][i]; // Q(hFbMixer->q_prior_mixer_fx)
     808     9546728 :                         move32();
     809     9546728 :                         pFilterbank_bin_to_band_re_fx = pFb->fb_consts.ppFilterbank_FRs_fx[0][i]; // Q30
     810     9546728 :                         pFilterbank_bin_to_band_im_fx = pFb->fb_consts.ppFilterbank_FRs_fx[1][i]; // Q30
     811             : 
     812  2942784180 :                         FOR( k = start_offset; k < num_bins + start_offset; k++ )
     813             :                         {
     814  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
     815  2933237452 :                             move32();
     816  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
     817  2933237452 :                             move32();
     818             :                             /*filterbank_mixer_bins_im_fx q 30 */
     819             :                             /*mixer_const_fx q  q_ppOut_pcm_fx */
     820  2933237452 :                             pFilterbank_bin_to_band_re_fx++;
     821  2933237452 :                             pFilterbank_bin_to_band_im_fx++;
     822             :                         }
     823     9546728 :                         hFbMixer->prior_mixer_fx[ch][j][i] = mixer_mat_fx[ch][j][i]; // Q(q_mixer_mat_fx)
     824     9546728 :                         move32();
     825             :                     }
     826             : #ifndef OPT_SBA_ENC_V1_BE
     827             :                     Word16 res_q = 0;
     828             :                     move16();
     829             : #endif
     830   622020584 :                     FOR( k = 0; k < frame_len; k++ )
     831             :                     {
     832             :                         Word32 temp_out_re_fx, temp_out_im_fx;
     833             : 
     834   621213440 :                         ivas_cmult_fix( filterbank_mixer_bins_re_fx[k], filterbank_mixer_bins_im_fx[k], pFb_inFR_re_fx[k],
     835   621213440 :                                         pFb_inFR_im_fx[k], &temp_out_re_fx, &temp_out_im_fx );
     836             : #ifndef OPT_SBA_ENC_V1_BE
     837             :                         res_q = sub( add( sub( sub( add( 30, *q_mixer_mat_fx ), 31 ), total_guard ), hFbMixer->q_ppFilterbank_inFR[j] ), 31 );
     838             : 
     839             :                         Word16 q_check = s_min( q_pOut_fr_fx, res_q );
     840             :                         IF( NE_16( q_check, q_pOut_fr_fx ) )
     841             :                         {
     842             :                             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
     843             :                             move32();
     844             :                             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
     845             :                             move32();
     846             :                         }
     847             : #endif
     848   621213440 :                         IF( NE_16( q_check, res_q ) )
     849             :                         {
     850   149251840 :                             temp_out_re_fx = L_shr( temp_out_re_fx, sub( res_q, q_check ) ); // res_q -> q_check
     851   149251840 :                             temp_out_im_fx = L_shr( temp_out_im_fx, sub( res_q, q_check ) ); // res_q -> q_check
     852             :                         }
     853             : #ifndef OPT_SBA_ENC_V1_BE
     854             :                         res_q = q_check;
     855             :                         move16();
     856             : #endif
     857             : 
     858   621213440 :                         pOut_fr_re_fx[k] = L_add_sat( pOut_fr_re_fx[k], temp_out_re_fx ); // res_q
     859   621213440 :                         move32();
     860   621213440 :                         pOut_fr_im_fx[k] = L_add_sat( pOut_fr_im_fx[k], temp_out_im_fx ); // res_q
     861   621213440 :                         move32();
     862             :                     }
     863             : #ifdef OPT_SBA_ENC_V1_BE
     864      807144 :                     q_pOut_fr_fx = q_check;
     865             : #else
     866             :                     q_pOut_fr_fx = res_q;
     867             :                     move16();
     868             : #endif
     869             :                 }
     870             :             }
     871             : #ifndef OPT_SBA_ENC_V1_BE
     872             :             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 ) ) );
     873             : #else
     874      543798 :             Word16 scale = sub( s_min( L_norm_arr( pOut_fr_re_fx, frame_len ), L_norm_arr( pOut_fr_im_fx, frame_len ) ), total_guard_2 );
     875             : #endif
     876      543798 :             scale_sig32( pOut_fr_re_fx, frame_len, scale );
     877      543798 :             scale_sig32( pOut_fr_im_fx, frame_len, scale );
     878      543798 :             ivas_imdft_fx( pOut_fr_re_fx, pOut_fr_im_fx, pMdft_out_fx[hist], frame_len );
     879      543798 :             q_pMdft_out_fx[hist] = add( q_pOut_fr_fx, scale );
     880      543798 :             move16();
     881             :         }
     882             : #ifdef OPT_SBA_ENC_V1_BE
     883      271899 :         scale_sig32( pMdft_out_fx[0], len, sub( s_min( q_pMdft_out_fx[0], q_pMdft_out_fx[1] ), q_pMdft_out_fx[0] ) );
     884      271899 :         scale_sig32( pMdft_out_fx[1], len, sub( s_min( q_pMdft_out_fx[0], q_pMdft_out_fx[1] ), q_pMdft_out_fx[1] ) );
     885             : #else
     886             :         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] ) );
     887             :         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] ) );
     888             : #endif
     889      271899 :         ivas_fb_mixer_cross_fading_fx( hFbMixer, ppOut_pcm_fx, pMdft_out_fx[0], pMdft_out_fx[1], ch, frame_len, frame_len );
     890      271899 :         q_ppOut_pcm_fx[ch] = s_min( q_pMdft_out_fx[0], q_pMdft_out_fx[1] );
     891      271899 :         move16();
     892             :     }
     893             : 
     894      157500 :     return;
     895             : }
     896             : 
     897             : /*-----------------------------------------------------------------------------------------*
     898             :  * Function ivas_fb_mixer_get_in_out_mapping()
     899             :  *
     900             :  *
     901             :  *-----------------------------------------------------------------------------------------*/
     902      157500 : void ivas_fb_mixer_get_in_out_mapping_fx(
     903             :     const IVAS_FB_CFG *fb_cfg,                                                      /* i  : FB config. handle  */
     904             :     Word16 in_out_mixer_map[IVAS_MAX_FB_MIXER_OUT_CH][IVAS_MAX_SPAR_FB_MIXER_IN_CH] /* i/o: mixing mapping     */
     905             : )
     906             : {
     907             :     Word16 i, j;
     908             : 
     909      157500 :     set_s( (Word16 *) in_out_mixer_map, 0, IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH );
     910             : 
     911      157500 :     IF( fb_cfg->active_w_mixing )
     912             :     {
     913       87782 :         FOR( i = 0; i < fb_cfg->num_out_chans; i++ )
     914             :         {
     915      219455 :             FOR( j = 0; j < fb_cfg->num_in_chans; j++ )
     916             :             {
     917      175564 :                 in_out_mixer_map[i][j] = 1;
     918      175564 :                 move16();
     919             :             }
     920             :         }
     921             :     }
     922             :     ELSE
     923             :     {
     924      113609 :         in_out_mixer_map[0][0] = 1; /* W depends on only W input*/
     925      113609 :         move16();
     926      341617 :         FOR( i = 1; i < fb_cfg->num_out_chans; i++ )
     927             :         {
     928      228008 :             in_out_mixer_map[i][0] = 1;
     929      228008 :             move16();
     930             :         }
     931             :     }
     932             : 
     933      157500 :     return;
     934             : }
     935             : 
     936             : /*-----------------------------------------------------------------------------------------*
     937             :  * Function ivas_calculate_abs_fr()
     938             :  *
     939             :  * Function to calculate number of active bands
     940             :  *-----------------------------------------------------------------------------------------*/
     941             : 
     942         564 : static Word16 ivas_calculate_abs_fr_fx(
     943             :     ivas_filterbank_t *pFb,
     944             :     const Word32 sampling_rate,
     945             :     const Word16 alloc_fb_resp,
     946             :     Word16 *index )
     947             : {
     948             :     Word16 frame_len;
     949             :     Word32 ppFilterbank_FRs_s_fx[L_FRAME48k];
     950         564 :     Word16 bands = pFb->filterbank_num_bands;
     951         564 :     move16();
     952         564 :     Word16 i, j, num_active_bands = 0;
     953         564 :     move16();
     954         564 :     Word16 idx_short_stride_bin_to_band = 0;
     955         564 :     move16();
     956             :     Word16 quo, tmp, exp_diff;
     957             : 
     958         564 :     Word32 temp = Mpy_32_32( sampling_rate, 42949673 /* FRAMES_PER_SEC in Q31 */ );
     959         564 :     frame_len = extract_l( temp );
     960             : 
     961        7174 :     FOR( i = 0; i < bands; i++ )
     962             :     {
     963        6610 :         const Word32 *long_mdft_ptr_re_fx = pFb->fb_consts.ppFilterbank_FRs_fx[0][i]; // Q30
     964        6610 :         const Word32 *long_mdft_ptr_im_fx = pFb->fb_consts.ppFilterbank_FRs_fx[1][i]; // Q30
     965             : 
     966        6610 :         Word16 start_offset = pFb->fb_consts.pFilterbank_bins_start_offset[i];
     967        6610 :         move16();
     968        6610 :         Word16 num_bins = pFb->fb_consts.pFilterbank_bins_per_band[i];
     969        6610 :         move16();
     970        6610 :         Word16 short_mdft_start_bin = -1;
     971        6610 :         move16();
     972             : 
     973             :         Word32 short_stride_pow_spec_fx[MDFT_FB_BANDS_240];
     974        6610 :         Word32 short_stride_nrg_fx = 0;
     975        6610 :         move16();
     976        6610 :         exp_diff = 0;
     977        6610 :         move16();
     978             : 
     979        6610 :         Word64 cldfb_nrg_fx = 0;
     980        6610 :         move64();
     981        6610 :         Word16 short_stride = pFb->fb_bin_to_band.short_stride;
     982        6610 :         move16();
     983             :         Word32 res_dec1, res_frac, res_dec2;
     984        6610 :         iDiv_and_mod_32( sampling_rate, FRAMES_PER_SEC, &res_dec1, &res_frac, 0 );
     985        6610 :         iDiv_and_mod_32( res_dec1, short_stride, &res_dec2, &res_frac, 0 );
     986        6610 :         const Word16 num_bins_per_short_stride_bin = extract_l( res_dec2 );
     987        6610 :         iDiv_and_mod_32( res_dec1, pFb->fb_bin_to_band.num_cldfb_bands, &res_dec2, &res_frac, 0 );
     988        6610 :         const Word16 num_bins_per_cldfb_band = extract_l( res_dec2 );
     989             : 
     990        6610 :         Word32 short_stride_max_per_spar_band_fx = 1;
     991        6610 :         move32();
     992             : 
     993             :         /*loop over all stored Filter Bank Response MDFT coefficients*/
     994             : 
     995        6610 :         set32_fx( short_stride_pow_spec_fx, 0, MDFT_FB_BANDS_240 );
     996             : 
     997     2006677 :         FOR( j = start_offset; j < num_bins + start_offset; j++ )
     998             :         {
     999             : 
    1000             :             Word32 sq_abs_fx;
    1001             : 
    1002             :             // Word32 real = L_shr( *long_mdft_ptr_re_fx, 3 ); // Q27
    1003     2000067 :             Word32 real = *long_mdft_ptr_re_fx; // Q30
    1004     2000067 :             move32();
    1005             :             // Word32 imag = L_shr( *long_mdft_ptr_im_fx, 3 ); // Q27
    1006     2000067 :             Word32 imag = *long_mdft_ptr_im_fx; // Q30
    1007     2000067 :             move32();
    1008     2000067 :             Word64 acc = W_mac_32_32( W_mult_32_32( real, real ), imag, imag ); // Q61
    1009     2000067 :             sq_abs_fx = W_extract_h( acc );                                     // Q28
    1010     2000067 :             long_mdft_ptr_re_fx++;
    1011     2000067 :             long_mdft_ptr_im_fx++;
    1012             : 
    1013             :             /* accumulate bin energies within a short stride bin */
    1014             : 
    1015     2000067 :             short_stride_nrg_fx = L_add( short_stride_nrg_fx, L_shr( sq_abs_fx, 6 ) ); // Q22
    1016     2000067 :             move32();
    1017             : 
    1018     2000067 :             IF( !( add( j, 1 ) % num_bins_per_short_stride_bin ) )
    1019             :             {
    1020             :                 /* new short stride bin */
    1021      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*/
    1022      498948 :                 move32();
    1023      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*/
    1024      498948 :                 short_stride_nrg_fx = 0;
    1025      498948 :                 move32();
    1026             :             }
    1027             : 
    1028             :             /* accumulate bin energies within a CLDFB band */
    1029     2000067 :             cldfb_nrg_fx = W_mac_32_32( cldfb_nrg_fx, sq_abs_fx, 1 ); // Q29
    1030             : 
    1031     2000067 :             IF( !( add( j, 1 ) % num_bins_per_cldfb_band ) )
    1032             :             {
    1033      123740 :                 Word16 exp = W_norm( cldfb_nrg_fx );
    1034      123740 :                 cldfb_nrg_fx = W_shl( cldfb_nrg_fx, exp );
    1035      123740 :                 exp = sub( 34, exp ); // 31 - (Q29 + exp -32)
    1036      123740 :                 temp = Sqrt32( W_extract_h( cldfb_nrg_fx ), &exp );
    1037      123740 :                 temp = L_shl( temp, sub( exp, Q9 ) );                                                         // Q22
    1038      123740 :                 pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[j / num_bins_per_cldfb_band][i] = temp; // Q22
    1039      123740 :                 move32();
    1040      123740 :                 cldfb_nrg_fx = 0;
    1041      123740 :                 move32();
    1042             :             }
    1043             :         }
    1044             : 
    1045        6610 :         quo = BASOP_Util_Divide3232_Scale( ONE_IN_Q30, short_stride_max_per_spar_band_fx, &exp_diff );
    1046             :         /* Q of quo = Q30 - Q22 + (15 - exp_diff) --> Q23 - exp_diff.
    1047             :         With Mult_32_16, Q23 - exp_diff - 15 --> Q8 - exp_diff */
    1048        6610 :         exp_diff = sub( Q8, exp_diff );
    1049             : 
    1050             :         /*loop over the short MDFT bins*/
    1051     1244850 :         FOR( j = 0; j < short_stride; j++ )
    1052             :         {
    1053     1238240 :             short_stride_pow_spec_fx[j] = L_shr( Mult_32_16( short_stride_pow_spec_fx[j], quo ), exp_diff ); // Q22
    1054     1238240 :             move32();
    1055     1238240 :             short_stride_pow_spec_fx[j] = L_max( L_sub( short_stride_pow_spec_fx[j], 1258291 ), 0 ); // 0.3f * ONE_IN_Q22
    1056     1238240 :             move32();
    1057     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
    1058     1238240 :             move32();
    1059             : 
    1060             : 
    1061     1238240 :             IF( short_stride_pow_spec_fx[j] > 0 )
    1062             :             {
    1063      111998 :                 assert( idx_short_stride_bin_to_band < 2 * MDFT_FB_BANDS_240 ); /* array size of p_short_stride_bin_to_band */
    1064      111998 :                 IF( EQ_16( short_mdft_start_bin, -1 ) )
    1065             :                 {
    1066        6610 :                     short_mdft_start_bin = j;
    1067        6610 :                     move16();
    1068        6610 :                     pFb->fb_bin_to_band.p_short_stride_start_bin_per_band[i] = j;
    1069        6610 :                     move16();
    1070             : 
    1071        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
    1072        6610 :                     index[i] = idx_short_stride_bin_to_band;
    1073        6610 :                     move16();
    1074             :                 }
    1075             : 
    1076      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
    1077      111998 :                 move32();
    1078      111998 :                 idx_short_stride_bin_to_band = add( idx_short_stride_bin_to_band, 1 );
    1079             : 
    1080      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 );
    1081      111998 :                 move16();
    1082             :             }
    1083             :         }
    1084             :     }
    1085             : 
    1086             :     /*loop over CLDFB bands*/
    1087       26624 :     FOR( j = 0; j < pFb->fb_bin_to_band.num_cldfb_bands; j++ )
    1088             :     {
    1089       26060 :         Word32 sum_over_spar_bands_fx = 0;
    1090       26060 :         move32();
    1091       26060 :         Word32 max_spar_band_contribution_fx = 0;
    1092       26060 :         move32();
    1093             : 
    1094       26060 :         Word16 spar_start = 0;
    1095       26060 :         move16();
    1096       26060 :         Word16 any_non_zero = 0;
    1097       26060 :         move16();
    1098             : 
    1099      335620 :         FOR( i = 0; i < bands; i++ )
    1100             :         {
    1101      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
    1102      309560 :             move32();
    1103             : 
    1104      309560 :             IF( pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[j][i] > max_spar_band_contribution_fx )
    1105             :             {
    1106       76715 :                 max_spar_band_contribution_fx = pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[j][i]; // Q22
    1107       76715 :                 move32();
    1108       76715 :                 pFb->fb_bin_to_band.p_cldfb_map_to_spar_band[j] = i;
    1109       76715 :                 move16();
    1110             :             }
    1111             :         }
    1112             : 
    1113       26060 :         sum_over_spar_bands_fx = L_max( sum_over_spar_bands_fx, EPSILON_FX ); // Q22
    1114       26060 :         move32();
    1115             : 
    1116       26060 :         exp_diff = 0;
    1117       26060 :         move16();
    1118       26060 :         tmp = BASOP_Util_Divide3232_Scale( ONE_IN_Q30, sum_over_spar_bands_fx, &exp_diff );
    1119             :         /* Q of quo = Q30 - Q22 + (15 - exp_diff) --> Q23 - exp_diff.
    1120             :         With Mult_32_16, Q23 - exp_diff - 15 --> Q8 - exp_diff */
    1121       26060 :         exp_diff = sub( Q8, exp_diff );
    1122             : 
    1123      335620 :         FOR( i = 0; i < bands; i++ )
    1124             :         {
    1125      309560 :             test();
    1126      309560 :             IF( pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[j][i] == 0 && !any_non_zero )
    1127             :             {
    1128      165303 :                 spar_start = add( spar_start, 1 );
    1129             :             }
    1130             :             ELSE
    1131             :             {
    1132      144257 :                 any_non_zero = 1;
    1133      144257 :                 move16();
    1134             :             }
    1135             : 
    1136      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 );
    1137      309560 :             move32();
    1138             :         }
    1139       26060 :         pFb->fb_bin_to_band.p_spar_start_bands[j] = spar_start;
    1140       26060 :         move16();
    1141             :     }
    1142             : 
    1143         564 :     set32_fx( ppFilterbank_FRs_s_fx, 0, frame_len );
    1144             : 
    1145             :     /*Commented logic is for calculating number of active bands, can be removed if not needed */
    1146        7174 :     FOR( i = 0; i < bands; i++ )
    1147             :     {
    1148        6610 :         const Word32 *pFilterbank_bin_to_band_re_fx = pFb->fb_consts.ppFilterbank_FRs_fx[0][i]; // Q30
    1149        6610 :         move32();
    1150        6610 :         const Word32 *pFilterbank_bin_to_band_im_fx = pFb->fb_consts.ppFilterbank_FRs_fx[1][i]; // Q30
    1151        6610 :         move32();
    1152             : 
    1153        6610 :         Word16 start_offset = pFb->fb_consts.pFilterbank_bins_start_offset[i];
    1154        6610 :         move16();
    1155        6610 :         Word16 num_bins = pFb->fb_consts.pFilterbank_bins_per_band[i];
    1156        6610 :         move16();
    1157        6610 :         Word16 idx = 0;
    1158        6610 :         move16();
    1159        6610 :         Word16 abs_active_bins = pFb->fb_bin_to_band.pFb_active_bins_per_band[i];
    1160        6610 :         move16();
    1161        6610 :         Word16 abs_start_offset = pFb->fb_bin_to_band.pFb_start_bin_per_band[i];
    1162        6610 :         move16();
    1163             : 
    1164     2006677 :         FOR( j = start_offset; j < num_bins + start_offset; j++ )
    1165             :         {
    1166     2000067 :             Word32 temp_fx = 0;
    1167     2000067 :             move32();
    1168             : 
    1169     2000067 :             exp_diff = 0;
    1170     2000067 :             move16();
    1171     2000067 :             Word32 real = L_shr( *pFilterbank_bin_to_band_re_fx, 3 ); // Q27
    1172     2000067 :             Word32 imag = L_shr( *pFilterbank_bin_to_band_im_fx, 3 ); // Q27
    1173             : 
    1174             :             Word32 real_sq, imag_sq;
    1175     2000067 :             real_sq = Mpy_32_32( real, real ); // Q27 + Q27 - 31 = Q23
    1176     2000067 :             imag_sq = Mpy_32_32( imag, imag ); // Q27 + Q27 - 31 = Q23
    1177             : 
    1178     2000067 :             temp_fx = L_add( L_shr( real_sq, 1 ), L_shr( imag_sq, 1 ) ); // Q22
    1179             : 
    1180     2000067 :             exp_diff = 9;
    1181     2000067 :             move16();
    1182     2000067 :             temp_fx = Sqrt32( temp_fx, &exp_diff );
    1183     2000067 :             temp_fx = L_shl( temp_fx, sub( exp_diff, Q9 ) ); // Q22
    1184             : 
    1185             : 
    1186     2000067 :             pFilterbank_bin_to_band_re_fx++;
    1187     2000067 :             pFilterbank_bin_to_band_im_fx++;
    1188             : 
    1189     2000067 :             temp_fx = L_sub( temp_fx, 1258291 ); // 0.3 in Q22
    1190     2000067 :             move32();
    1191             : 
    1192     2000067 :             if ( temp_fx < 0 )
    1193             :             {
    1194     1433594 :                 temp_fx = 0;
    1195     1433594 :                 move32();
    1196             :             }
    1197             : 
    1198     2000067 :             test();
    1199     2000067 :             test();
    1200     2000067 :             IF( LT_16( j, add( abs_active_bins, abs_start_offset ) ) && GE_16( j, abs_start_offset ) && NE_16( alloc_fb_resp, -1 ) )
    1201             :             {
    1202      294399 :                 pFb->fb_bin_to_band.pFb_bin_to_band_fx[i][idx] = temp_fx; // Q22
    1203      294399 :                 move32();
    1204      294399 :                 idx = add( idx, 1 );
    1205             :             }
    1206             : 
    1207             : 
    1208     2000067 :             ppFilterbank_FRs_s_fx[j] = L_add( ppFilterbank_FRs_s_fx[j], temp_fx ); // Q22
    1209     2000067 :             move32();
    1210             :         }
    1211             :     }
    1212             : 
    1213      417524 :     FOR( i = 0; i < frame_len; i++ )
    1214             :     {
    1215      416960 :         if ( ppFilterbank_FRs_s_fx[i] < 0 )
    1216             :         {
    1217           0 :             ppFilterbank_FRs_s_fx[i] = 419430; // 0.1 in Q22
    1218           0 :             move32();
    1219             :         }
    1220             :     }
    1221             : 
    1222         564 :     IF( NE_16( alloc_fb_resp, -1 ) )
    1223             :     {
    1224        3705 :         FOR( j = 0; j < bands; j++ )
    1225             :         {
    1226        3414 :             Word16 abs_active_bins = pFb->fb_bin_to_band.pFb_active_bins_per_band[j];
    1227        3414 :             Word16 abs_start_offset = pFb->fb_bin_to_band.pFb_start_bin_per_band[j];
    1228        3414 :             exp_diff = 0;
    1229             : 
    1230        3414 :             move16();
    1231        3414 :             move16();
    1232        3414 :             move16();
    1233             : 
    1234      297813 :             FOR( i = 0; i < abs_active_bins; i++ )
    1235             :             {
    1236      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 );
    1237      294399 :                 pFb->fb_bin_to_band.pFb_bin_to_band_fx[j][i] = L_shl( L_deposit_l( tmp ), add( Q7, exp_diff ) ); // Q22
    1238      294399 :                 move32();
    1239             :                 /*if(pFb->fb_bin_to_band.pFb_bin_to_band[j][i] > 0.5f)
    1240             :                 {
    1241             :                     num_active_bands = j + 1;
    1242             :                     break;
    1243             :                 }*/
    1244             :             }
    1245             :         }
    1246             :     }
    1247             : 
    1248         564 :     return num_active_bands;
    1249             : }
    1250             : 
    1251             : /*-----------------------------------------------------------------------------------------*
    1252             :  * Function ivas_get_active_bins()
    1253             :  *
    1254             :  *
    1255             :  *-----------------------------------------------------------------------------------------*/
    1256             : 
    1257        1128 : static void ivas_get_active_bins_fx(
    1258             :     const Word16 **pActive_bins,
    1259             :     const Word16 **pActive_bins_abs,
    1260             :     const Word16 **pStart_offset,
    1261             :     const Word16 **pStart_offset_abs,
    1262             :     const Word32 sampling_rate )
    1263             : {
    1264             :     Word16 sr_idx;
    1265             : 
    1266        1128 :     IF( EQ_32( sampling_rate, 32000 ) )
    1267             :     {
    1268         462 :         sr_idx = 1;
    1269         462 :         move16();
    1270             :     }
    1271         666 :     ELSE IF( EQ_32( sampling_rate, 16000 ) )
    1272             :     {
    1273         158 :         sr_idx = 2;
    1274         158 :         move16();
    1275             :     }
    1276             :     ELSE
    1277             :     {
    1278         508 :         sr_idx = 0;
    1279         508 :         move16();
    1280             :     }
    1281             : 
    1282        1128 :     *pActive_bins_abs = ivas_fb_abs_bins_per_band_12band_1ms[sr_idx];
    1283        1128 :     move16();
    1284        1128 :     *pActive_bins = ivas_fb_bins_per_band_12band_1ms[sr_idx];
    1285        1128 :     move16();
    1286        1128 :     *pStart_offset_abs = ivas_fb_abs_bins_start_offset_12band_1ms[sr_idx];
    1287        1128 :     move16();
    1288        1128 :     *pStart_offset = ivas_fb_bins_start_offset_12band_1ms[sr_idx];
    1289        1128 :     move16();
    1290             : 
    1291        1128 :     return;
    1292             : }
    1293             : 
    1294             : 
    1295             : /*-----------------------------------------------------------------------------------------*
    1296             :  * Function ivas_filterbank_setup()
    1297             :  *
    1298             :  * Filterbank setup, initialization
    1299             :  *-----------------------------------------------------------------------------------------*/
    1300             : 
    1301        1668 : static ivas_error ivas_filterbank_setup_fx(
    1302             :     IVAS_FB_MIXER_HANDLE hFbMixer,
    1303             :     const Word32 sampling_rate,
    1304             :     Word16 *index )
    1305             : {
    1306             :     Word16 i, j, exp, tmp;
    1307             :     const Word32 *pAll_fb_fr_fx[2];
    1308        1668 :     const Word16 *pAll_bins_start_offset = NULL;
    1309        1668 :     const Word16 *pAll_bins_per_band = NULL;
    1310        1668 :     const Word16 *pAll_bins_start_offset_abs = NULL;
    1311        1668 :     const Word16 *pAll_bins_per_band_abs = NULL;
    1312        1668 :     const Word16 *pAll_bins_per_band_48k = NULL;
    1313             :     ivas_error error;
    1314        1668 :     IVAS_FB_CFG *pCfg = hFbMixer->fb_cfg;
    1315             : 
    1316        1668 :     error = IVAS_ERR_OK;
    1317        1668 :     move32();
    1318             : 
    1319        1668 :     IF( pCfg->num_out_chans > 0 )
    1320             :     {
    1321         564 :         hFbMixer->pFb->filterbank_num_bands = ivas_get_num_bands( sampling_rate );
    1322         564 :         move16();
    1323             : 
    1324         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 );
    1325             : 
    1326         564 :         IF( EQ_16( pCfg->fb_latency, NS2SA_FX2( sampling_rate, DELAY_FB_1_NS ) ) )
    1327             :         {
    1328         564 :             pAll_fb_fr_fx[0] = ivas_fb_fr_12band_1ms_re_fx; // Q30
    1329         564 :             move32();
    1330         564 :             pAll_fb_fr_fx[1] = ivas_fb_fr_12band_1ms_im_fx; // Q30
    1331         564 :             move32();
    1332             : 
    1333         564 :             pAll_bins_per_band_48k = ivas_fb_bins_per_band_12band_1ms[0];
    1334         564 :             move16();
    1335             :         }
    1336             :         ELSE
    1337             :         {
    1338           0 :             return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Wrong FB in ivas_filterbank_setup()!" );
    1339             :         }
    1340             :     }
    1341             : 
    1342        1668 :     hFbMixer->cross_fade_end_offset = add( pCfg->fade_len, pCfg->pcm_offset );
    1343        1668 :     move16();
    1344        1668 :     hFbMixer->cross_fade_start_offset = sub( hFbMixer->cross_fade_end_offset, pCfg->fade_len );
    1345        1668 :     move16();
    1346        1668 :     hFbMixer->ana_window_offset = add( pCfg->fb_latency, pCfg->pcm_offset );
    1347        1668 :     move16();
    1348             : 
    1349        1668 :     IF( NE_32( ( error = ivas_fb_mixer_get_window_fx( pCfg->fb_latency, sampling_rate, &( hFbMixer->pAna_window_fx ) ) ), IVAS_ERR_OK ) )
    1350             :     {
    1351           0 :         return error;
    1352             :     }
    1353             : 
    1354        1668 :     IF( NE_32( ( error = ivas_fb_mixer_get_window_fx( pCfg->fade_len, sampling_rate, &( hFbMixer->pFilterbank_cross_fade_fx ) ) ), IVAS_ERR_OK ) )
    1355             :     {
    1356           0 :         return error;
    1357             :     }
    1358             : 
    1359        1668 :     IF( pCfg->num_out_chans > 0 )
    1360             :     {
    1361         564 :         ivas_filterbank_t *pFb = hFbMixer->pFb;
    1362         564 :         Word16 offset = 0;
    1363         564 :         move16();
    1364             : 
    1365         564 :         pFb->fb_consts.pFilterbank_bins_per_band = pAll_bins_per_band;
    1366         564 :         pFb->fb_consts.pFilterbank_bins_start_offset = pAll_bins_start_offset;
    1367         564 :         pFb->fb_bin_to_band.pFb_active_bins_per_band = pAll_bins_per_band_abs;
    1368         564 :         pFb->fb_bin_to_band.pFb_start_bin_per_band = pAll_bins_start_offset_abs;
    1369             : 
    1370             :         /* Initialization for short stride Parameter calculation and SPAR CLDFB reconstruction */
    1371         564 :         SWITCH( sampling_rate )
    1372             :         {
    1373         254 :             case 48000:
    1374         254 :                 pFb->fb_bin_to_band.num_cldfb_bands = 60; /* sampling_rate * 1.0f / 800.0f  */
    1375         254 :                 move16();
    1376         254 :                 BREAK;
    1377         231 :             case 32000:
    1378         231 :                 pFb->fb_bin_to_band.num_cldfb_bands = 40;
    1379         231 :                 move16();
    1380         231 :                 BREAK;
    1381          79 :             case 16000:
    1382          79 :                 pFb->fb_bin_to_band.num_cldfb_bands = 20;
    1383          79 :                 move16();
    1384          79 :                 BREAK;
    1385             :         }
    1386             : 
    1387             :         /*pFb->fb_bin_to_band.cldfb_stride = ( int16_t )( ( sampling_rate / FRAMES_PER_SEC ) / CLDFB_NO_COL_MAX );*/ /* equals num_cldfb_bands*/
    1388             :         // pFb->fb_bin_to_band.short_stride = extract_l( ( sampling_rate / FRAMES_PER_SEC ) / 4 );
    1389         564 :         tmp = BASOP_Util_Divide3232_Scale( sampling_rate, FRAMES_PER_SEC, &exp );
    1390         564 :         pFb->fb_bin_to_band.short_stride = shr( tmp, add( sub( 15, exp ), 2 ) );
    1391             : 
    1392         564 :         move16();
    1393             : 
    1394         564 :         set32_fx( pFb->fb_bin_to_band.p_short_stride_bin_to_band_fx, 0, 2 * MDFT_FB_BANDS_240 );
    1395             : 
    1396         564 :         set16_fx( pFb->fb_bin_to_band.p_cldfb_map_to_spar_band, 0, CLDFB_NO_CHANNELS_MAX );
    1397         564 :         set16_fx( pFb->fb_bin_to_band.p_spar_start_bands, 0, CLDFB_NO_CHANNELS_MAX );
    1398             : 
    1399       11844 :         FOR( j = 0; j < IVAS_MAX_NUM_FB_BANDS; j++ )
    1400             :         {
    1401       11280 :             pFb->fb_bin_to_band.p_short_stride_num_bins_per_band[j] = 0; /* aka num_active_bins per SPAR band */
    1402       11280 :             move16();
    1403       11280 :             pFb->fb_bin_to_band.p_short_stride_start_bin_per_band[j] = 0; /* first considered bin index per SPAR band */
    1404       11280 :             move16();
    1405             : 
    1406       11280 :             pFb->fb_bin_to_band.pp_short_stride_bin_to_band_fx[j] = NULL;
    1407             : 
    1408      688080 :             FOR( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ )
    1409             :             {
    1410             : 
    1411      676800 :                 pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[i][j] = 0;
    1412      676800 :                 move32();
    1413             :             }
    1414             :         }
    1415         564 :         IF( EQ_32( sampling_rate, 48000 ) )
    1416             :         {
    1417        3302 :             FOR( j = 0; j < pFb->filterbank_num_bands; j++ )
    1418             :             {
    1419             : 
    1420        3048 :                 pFb->fb_consts.ppFilterbank_FRs_fx[0][j] = &pAll_fb_fr_fx[0][offset]; // Q30
    1421        3048 :                 pFb->fb_consts.ppFilterbank_FRs_fx[1][j] = &pAll_fb_fr_fx[1][offset]; // Q30
    1422             : 
    1423        3048 :                 offset = add( offset, pFb->fb_consts.pFilterbank_bins_per_band[j] );
    1424             :             }
    1425             : 
    1426             :             /****************************************Calculate abs fr ***************************/
    1427             : 
    1428         254 :             ivas_calculate_abs_fr_fx( pFb, sampling_rate, pCfg->active_w_mixing, index );
    1429             :         }
    1430             :         ELSE
    1431             :         {
    1432             : 
    1433             :             Word32 *ppFilterbank_FRs_re_temp_fx[MAX_NUM_BANDS_DIFF_NON48K];
    1434             :             Word32 *ppFilterbank_FRs_im_temp_fx[MAX_NUM_BANDS_DIFF_NON48K];
    1435             :             Word16 active_bins_temp[MAX_NUM_BANDS_DIFF_NON48K];
    1436             :             Word16 start_offset_temp[MAX_NUM_BANDS_DIFF_NON48K];
    1437             :             Word16 num_diff_bands, start_diff_band_non48k;
    1438             : 
    1439         310 :             num_diff_bands = MAX_NUM_BANDS_DIFF_NON48K;
    1440         310 :             start_diff_band_non48k = sub( pFb->filterbank_num_bands, num_diff_bands );
    1441         310 :             move16();
    1442             : 
    1443         310 :             pFb->fb_consts.pFilterbank_bins_per_band = pAll_bins_per_band;
    1444         310 :             pFb->fb_consts.pFilterbank_bins_start_offset = pAll_bins_start_offset;
    1445             : 
    1446        3872 :             FOR( j = 0; j < pFb->filterbank_num_bands; j++ )
    1447             :             {
    1448        3562 :                 Word16 num_active_bins = pFb->fb_consts.pFilterbank_bins_per_band[j];
    1449        3562 :                 move16();
    1450             : 
    1451        3562 :                 IF( j < start_diff_band_non48k )
    1452             :                 {
    1453             : 
    1454        2632 :                     pFb->fb_consts.ppFilterbank_FRs_fx[0][j] = &pAll_fb_fr_fx[0][offset]; // Q30
    1455        2632 :                     pFb->fb_consts.ppFilterbank_FRs_fx[1][j] = &pAll_fb_fr_fx[1][offset]; // Q30
    1456             :                 }
    1457             :                 ELSE
    1458             :                 {
    1459         930 :                     Copy32( &pAll_fb_fr_fx[0][offset], pFb->fb_consts.ppFilterbank_FRs_non48k_fx[0][j], num_active_bins ); // Q30
    1460         930 :                     Copy32( &pAll_fb_fr_fx[1][offset], pFb->fb_consts.ppFilterbank_FRs_non48k_fx[1][j], num_active_bins ); // Q30
    1461             :                 }
    1462             : 
    1463        3562 :                 offset = add( offset, pAll_bins_per_band_48k[j] );
    1464             :             }
    1465             : 
    1466        1240 :             FOR( j = start_diff_band_non48k; j < pFb->filterbank_num_bands; j++ )
    1467             :             {
    1468             : 
    1469         930 :                 ppFilterbank_FRs_re_temp_fx[j - start_diff_band_non48k] = pFb->fb_consts.ppFilterbank_FRs_non48k_fx[0][j]; // Q30
    1470         930 :                 ppFilterbank_FRs_im_temp_fx[j - start_diff_band_non48k] = pFb->fb_consts.ppFilterbank_FRs_non48k_fx[1][j]; // Q30
    1471             : 
    1472         930 :                 active_bins_temp[j - start_diff_band_non48k] = pFb->fb_consts.pFilterbank_bins_per_band[j];
    1473         930 :                 start_offset_temp[j - start_diff_band_non48k] = pFb->fb_consts.pFilterbank_bins_start_offset[j];
    1474         930 :                 move16();
    1475         930 :                 move16();
    1476             :             }
    1477             : 
    1478         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,
    1479         310 :                                     active_bins_temp, start_offset_temp, num_diff_bands, pCfg->fb_latency, sampling_rate );
    1480             : 
    1481             : 
    1482        1240 :             FOR( j = start_diff_band_non48k; j < pFb->filterbank_num_bands; j++ )
    1483             :             {
    1484             : 
    1485         930 :                 pFb->fb_consts.ppFilterbank_FRs_fx[0][j] = (const Word32 *) pFb->fb_consts.ppFilterbank_FRs_non48k_fx[0][j]; // Q30
    1486         930 :                 pFb->fb_consts.ppFilterbank_FRs_fx[1][j] = (const Word32 *) pFb->fb_consts.ppFilterbank_FRs_non48k_fx[1][j]; // Q30
    1487             :             }
    1488             : 
    1489             :             /******************************************** Calculate abs fr ****************************************************/
    1490             : 
    1491         310 :             ivas_calculate_abs_fr_fx( pFb, sampling_rate, pCfg->active_w_mixing, index );
    1492             :         }
    1493             :     }
    1494             : 
    1495        1668 :     return error;
    1496             : }
    1497             : 
    1498             : /*-----------------------------------------------------------------------------------------*
    1499             :  * Function ivas_fb_mixer_get_window()
    1500             :  *
    1501             :  *
    1502             :  *-----------------------------------------------------------------------------------------*/
    1503             : 
    1504        3336 : static ivas_error ivas_fb_mixer_get_window_fx(
    1505             :     const Word16 fade_len,      /* i  : window fading length in samples    */
    1506             :     const Word32 sampling_rate, /* i  : sampling rate                      */
    1507             :     const Word16 **pWindow      /* o  : pointer to the window coefficents  */
    1508             : )
    1509             : {
    1510             :     ivas_error error;
    1511             : 
    1512        3336 :     error = IVAS_ERR_OK;
    1513        3336 :     move32();
    1514             : 
    1515        3336 :     IF( EQ_16( fade_len, NS2SA_FX2( sampling_rate, DELAY_FB_4_NS ) ) )
    1516             :     {
    1517        1192 :         SWITCH( sampling_rate )
    1518             :         {
    1519         882 :             case 48000:
    1520         882 :                 *pWindow = ivas_fb_cf_4ms_48k_fx;
    1521         882 :                 BREAK;
    1522         231 :             case 32000:
    1523         231 :                 *pWindow = ivas_fb_cf_4ms_32k_fx;
    1524         231 :                 BREAK;
    1525          79 :             case 16000:
    1526          79 :                 *pWindow = ivas_fb_cf_4ms_16k_fx;
    1527          79 :                 BREAK;
    1528           0 :             default:
    1529           0 :                 return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Unsupported Sampling frequency!" );
    1530             :         }
    1531             :     }
    1532        2144 :     ELSE IF( EQ_16( fade_len, NS2SA_FX2( sampling_rate, DELAY_FB_1_NS ) ) )
    1533             :     {
    1534        2144 :         SWITCH( sampling_rate )
    1535             :         {
    1536        1566 :             case 48000:
    1537        1566 :                 *pWindow = ivas_fb_cf_1ms_48k_fx;
    1538        1566 :                 BREAK;
    1539         499 :             case 32000:
    1540         499 :                 *pWindow = ivas_fb_cf_1ms_32k_fx;
    1541         499 :                 BREAK;
    1542          79 :             case 16000:
    1543          79 :                 *pWindow = ivas_fb_cf_1ms_16k_fx;
    1544          79 :                 BREAK;
    1545           0 :             default:
    1546           0 :                 return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Unsupported Sampling frequency!" );
    1547             :         }
    1548             :     }
    1549             :     ELSE
    1550             :     {
    1551           0 :         IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error: Incorrect FB window fade len (%f ms)\n", ( fade_len / 1000000.f ) );
    1552             :     }
    1553             : 
    1554        3336 :     return error;
    1555             : }
    1556             : 
    1557             : 
    1558         310 : static const Word32 *ivas_get_cheby_ramp_fx(
    1559             :     const Word16 delay )
    1560             : {
    1561         310 :     const Word32 *pCheby_fx = NULL;
    1562             : 
    1563         310 :     SWITCH( delay )
    1564             :     {
    1565         231 :         case IVAS_FB_1MS_32K_SAMP:
    1566         231 :             pCheby_fx = ivas_fb_resp_cheby_ramp_32del_fx;
    1567         231 :             BREAK;
    1568          79 :         case IVAS_FB_1MS_16K_SAMP:
    1569          79 :             pCheby_fx = ivas_fb_resp_cheby_ramp_16del_fx;
    1570          79 :             BREAK;
    1571           0 :         default:
    1572           0 :             assert( !"Unsupported cheby ramp length!" );
    1573             :     }
    1574             : 
    1575         310 :     return pCheby_fx;
    1576             : }
    1577             : 
    1578         310 : static void ivas_get_ld_fb_resp_fx(
    1579             :     Word32 **ppIdeal_FRs_re_fx, // i: Q30
    1580             :     Word32 **ppIdeal_FRs_im_fx, // i: Q30
    1581             :     Word32 **ppNew_FRs_re_fx,   // o: Q30
    1582             :     Word32 **ppNew_FRs_im_fx,   // o: Q30
    1583             :     const Word16 *pActive_bins,
    1584             :     const Word16 *pStart_offset,
    1585             :     const Word16 num_bands,
    1586             :     const Word16 delay,
    1587             :     const Word32 sampling_rate )
    1588             : {
    1589             :     Word16 b, s, frame_len;
    1590             :     const Word32 *pCheby_fx;
    1591         310 :     frame_len = 0;
    1592         310 :     move16();
    1593             :     /*common scratch buffers for computing impulse/frequency responses,
    1594             :     pre-ring, post-ring and circular shifted outputs to optimize stack*/
    1595             :     Word32 scratch1_fx[L_FRAME32k * 2];
    1596             :     Word32 scratch2_fx[L_FRAME32k * 2];
    1597             : 
    1598         310 :     set32_fx( scratch1_fx, 0, L_FRAME32k * 2 );
    1599         310 :     set32_fx( scratch2_fx, 0, L_FRAME32k * 2 );
    1600             : 
    1601         310 :     const Word32 *han_win_fx = NULL;
    1602             : 
    1603         310 :     SWITCH( sampling_rate )
    1604             :     {
    1605           0 :         case 48000:
    1606           0 :             frame_len = 960;
    1607           0 :             move16();
    1608           0 :             han_win_fx = ivas_han_win_48k_fx; // Q31
    1609           0 :             BREAK;
    1610         231 :         case 32000:
    1611         231 :             frame_len = 640;
    1612         231 :             move16();
    1613         231 :             han_win_fx = ivas_han_win_32k_fx; // Q31
    1614         231 :             BREAK;
    1615          79 :         case 16000:
    1616          79 :             frame_len = 320;
    1617          79 :             move16();
    1618          79 :             han_win_fx = ivas_han_win_16k_fx; // Q31
    1619          79 :             BREAK;
    1620             :     }
    1621             : 
    1622         310 :     pCheby_fx = ivas_get_cheby_ramp_fx( delay ); // Q31
    1623             : 
    1624         310 :     b = 0;
    1625         310 :     s = 0;
    1626         310 :     move16();
    1627         310 :     move16();
    1628             : 
    1629         310 :     assert( sampling_rate == 32000 || sampling_rate == 16000 );
    1630             : 
    1631        1240 :     FOR( b = 0; b < num_bands; b++ )
    1632             :     {
    1633             : 
    1634         930 :         set32_fx( scratch2_fx, 0, shl( frame_len, 1 ) );
    1635         930 :         Copy32( ppIdeal_FRs_re_fx[b], &scratch2_fx[pStart_offset[b]], pActive_bins[b] );             // Q30
    1636         930 :         Copy32( ppIdeal_FRs_im_fx[b], &scratch2_fx[frame_len + pStart_offset[b]], pActive_bins[b] ); // Q30
    1637             : 
    1638         930 :         Word16 guard_bits = sub( L_norm_arr( scratch2_fx, shl( L_FRAME32k, 1 ) ), find_guarded_bits_fx( shl( frame_len, 1 ) ) );
    1639         930 :         Scale_sig32( scratch2_fx, shl( L_FRAME32k, 1 ), guard_bits ); // Q30 + guard_bits
    1640             : 
    1641         930 :         ivas_imdft_fx( scratch2_fx, &scratch2_fx[frame_len], scratch1_fx, frame_len );
    1642             : 
    1643     1191330 :         FOR( Word16 x = 0; x < shl( L_FRAME32k, 1 ); x++ )
    1644             :         {
    1645     1190400 :             scratch2_fx[x] = L_shr( scratch2_fx[x], guard_bits ); // (Q30 + guard_bits) - guard_bits = Q30
    1646     1190400 :             scratch1_fx[x] = L_shr( scratch1_fx[x], guard_bits ); // (Q30 + guard_bits) - guard_bits = Q30
    1647             : 
    1648     1190400 :             move32();
    1649     1190400 :             move32();
    1650             :         }
    1651             : 
    1652             :         /*apply circular shift and hanning window*/
    1653             : 
    1654      520290 :         FOR( s = delay; s < frame_len + delay; s++ )
    1655             :         {
    1656             : 
    1657      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
    1658      519360 :             move32();
    1659             :         }
    1660             : 
    1661      494322 :         FOR( ; s < 2 * frame_len; s++ )
    1662             :         {
    1663             : 
    1664      493392 :             scratch2_fx[s - delay] = Mpy_32_32( scratch1_fx[s], han_win_fx[s - ( frame_len + delay )] ); // Q30
    1665      493392 :             move32();
    1666             :         }
    1667             : 
    1668       26898 :         FOR( s = 0; s < delay; s++ )
    1669             :         {
    1670             : 
    1671       25968 :             scratch2_fx[( ( ( frame_len * 2 ) - delay ) + s )] = L_negate( Mpy_32_32( scratch1_fx[s], han_win_fx[( frame_len - delay ) + s] ) ); // Q30
    1672       25968 :             move32();
    1673             :         }
    1674             : 
    1675             :         /*apply heavy/cheby ramp window and compute pre ring*/
    1676             : 
    1677       27828 :         FOR( s = 0; s < delay + 1; s++ )
    1678             :         {
    1679       26898 :             scratch1_fx[s] = Mpy_32_32( scratch2_fx[s], pCheby_fx[delay - s] ); // Q30
    1680       26898 :             move32();
    1681             :         }
    1682             : 
    1683      493392 :         FOR( ; s < frame_len; s++ )
    1684             :         {
    1685      492462 :             scratch1_fx[s] = 0;
    1686      492462 :             move32();
    1687             :         }
    1688             : 
    1689      494322 :         FOR( ; s < 2 * frame_len - delay; s++ )
    1690             :         {
    1691      493392 :             scratch1_fx[s] = scratch2_fx[s];
    1692      493392 :             move32();
    1693             :         }
    1694             : 
    1695       26898 :         FOR( ; s < 2 * frame_len; s++ )
    1696             :         {
    1697       25968 :             scratch1_fx[s] = Mpy_32_32( scratch2_fx[s], L_sub( ONE_IN_Q31, pCheby_fx[s - ( 2 * frame_len - delay )] ) ); // Q30
    1698       25968 :             move32();
    1699             :         }
    1700             : 
    1701             :         /*IR - pre ring + post ring*/
    1702     1038720 :         FOR( s = 1; s < 2 * frame_len; s++ )
    1703             :         {
    1704     1037790 :             scratch2_fx[s] = L_sub( L_sub( scratch2_fx[s] /*pre ring*/, scratch1_fx[s] /*post ring*/ ), scratch1_fx[frame_len * 2 - s] );
    1705     1037790 :             move32();
    1706             :         }
    1707             : 
    1708     1013682 :         FOR( s = 0; s < 2 * frame_len - delay; s++ )
    1709             :         {
    1710     1012752 :             scratch1_fx[s + delay] = scratch2_fx[s];
    1711     1012752 :             move32();
    1712             :         }
    1713             : 
    1714       26898 :         FOR( ; s < 2 * frame_len; s++ )
    1715             :         {
    1716       25968 :             scratch1_fx[( s - ( ( frame_len * 2 ) - delay ) )] = L_negate( scratch2_fx[s] );
    1717       25968 :             move32();
    1718             :         }
    1719             : 
    1720             :         /* apply final window*/
    1721         930 :         const Word32 *sine_till_delay = ivas_sine_delay_32_fx; // Q30
    1722         930 :         Word16 offset = 1;
    1723         930 :         Word16 delay_16 = 0;
    1724             : 
    1725         930 :         move16();
    1726         930 :         move16();
    1727             : 
    1728         930 :         if ( EQ_16( delay, IVAS_FB_1MS_16K_SAMP ) )
    1729             :         {
    1730         237 :             delay_16 = 1;
    1731         237 :             move16();
    1732             :         }
    1733             : 
    1734       26898 :         FOR( s = 0; s < delay; s++ )
    1735             :         {
    1736       25968 :             scratch1_fx[s] = Mpy_32_32( scratch1_fx[s], sine_till_delay[s + offset * delay_16] ); // Q30 + Q30 - 31 = Q29
    1737       25968 :             offset = add( offset, 1 );
    1738       25968 :             scratch1_fx[s] = L_shl( scratch1_fx[s], 1 ); // Q30
    1739             : 
    1740       25968 :             move32();
    1741       25968 :             move32();
    1742             :         }
    1743             : 
    1744         930 :         const Word32 *sine_till_frame_len = NULL;
    1745             : 
    1746         930 :         IF( EQ_16( delay, IVAS_FB_1MS_16K_SAMP ) )
    1747             :         {
    1748         237 :             sine_till_frame_len = ivas_sine_frame_len_640_del_16_fx; // Q30
    1749         237 :             move32();
    1750             :         }
    1751             :         ELSE
    1752             :         {
    1753         693 :             sine_till_frame_len = ivas_sine_frame_len_640_del_32_fx; // Q30
    1754         693 :             move32();
    1755             :         }
    1756         930 :         Word16 iterator = 0;
    1757         930 :         move16();
    1758      469284 :         FOR( s = 2 * delay; s < frame_len + 1; s++ )
    1759             :         {
    1760      468354 :             scratch1_fx[s] = Mpy_32_32( scratch1_fx[s], sine_till_frame_len[iterator] ); // Q30 + Q30 - 31 = Q29
    1761      468354 :             iterator = add( iterator, 1 );
    1762      468354 :             scratch1_fx[s] = L_shl( scratch1_fx[s], 1 ); // Q30
    1763             : 
    1764      468354 :             move32();
    1765      468354 :             move32();
    1766             :         }
    1767             : 
    1768      519360 :         FOR( ; s < 2 * frame_len; s++ )
    1769             :         {
    1770      518430 :             scratch1_fx[s] = 0;
    1771             : 
    1772      518430 :             move32();
    1773             :         }
    1774             : 
    1775             :         /*compute frequency response*/
    1776         930 :         ivas_mdft_fx( scratch1_fx, scratch2_fx, &scratch2_fx[frame_len], shl( frame_len, 1 ), frame_len );
    1777             : 
    1778         930 :         Copy32( &scratch2_fx[pStart_offset[b]], ppNew_FRs_re_fx[b], pActive_bins[b] );                 // Q30
    1779         930 :         Copy32( &scratch2_fx[( frame_len + pStart_offset[b] )], ppNew_FRs_im_fx[b], pActive_bins[b] ); // Q30
    1780             :     }
    1781             : 
    1782         310 :     return;
    1783             : }

Generated by: LCOV version 1.14