LCOV - code coverage report
Current view: top level - lib_com - ivas_fb_mixer_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main -- dec/rend @ 6c320724ac154bae0b720af82641e0df71ffdfc7 Lines: 533 805 66.2 %
Date: 2025-07-01 04:22:09 Functions: 11 18 61.1 %

          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         546 : Word16 ivas_get_num_bands_from_bw_idx(
      69             :     const Word16 bwidth /* i  : audio bandwidth    */
      70             : )
      71             : {
      72             :     Word16 num_active_bands;
      73             : 
      74         546 :     assert( bwidth > 0 ); /*NB BW is not supported*/
      75         546 :     num_active_bands = ivas_num_active_bands[sub( bwidth, 1 )];
      76         546 :     move16();
      77             : 
      78         546 :     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         546 : static Word16 ivas_get_num_bands(
      89             :     const Word32 sampling_rate )
      90             : {
      91         546 :     Word16 bwidth = ivas_get_bw_idx_from_sample_rate_fx( sampling_rate );
      92         546 :     Word16 num_active_bands = ivas_get_num_bands_from_bw_idx( bwidth );
      93             : 
      94         546 :     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        1476 : 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        1476 :     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        1476 :     pFb_cfg->num_in_chans = num_in_chans;
     122        1476 :     pFb_cfg->num_out_chans = num_out_chans;
     123        1476 :     pFb_cfg->nchan_fb_in = nchan_fb_in;
     124             : 
     125        1476 :     pFb_cfg->pcm_offset = 0; /* note: in SPAR decoder, this parameter is overwritten later */
     126        1476 :     pFb_cfg->active_w_mixing = active_w_mixing;
     127        1476 :     pFb_cfg->windowed_fr_offset = 0;
     128             : 
     129        1476 :     move16();
     130        1476 :     move16();
     131        1476 :     move16();
     132        1476 :     move16();
     133        1476 :     move16();
     134        1476 :     move16();
     135             : 
     136        1476 :     IF( EQ_16( ivas_format, ISM_FORMAT ) )
     137             :     {
     138           0 :         pFb_cfg->fb_latency = NS2SA_FX2( sampling_rate, DELAY_FB_4_NS );
     139           0 :         pFb_cfg->fade_len = NS2SA_FX2( sampling_rate, DELAY_FB_4_NS );
     140           0 :         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           0 :         move16();
     143           0 :         move16();
     144           0 :         move16();
     145             :     }
     146        1476 :     ELSE IF( EQ_16( ivas_format, SBA_FORMAT ) )
     147             :     {
     148        1476 :         pFb_cfg->fb_latency = NS2SA_FX2( sampling_rate, DELAY_FB_1_NS );
     149             : 
     150        1476 :         pFb_cfg->fade_len = NS2SA_FX2( sampling_rate, DELAY_FB_4_NS );
     151        1476 :         pFb_cfg->prior_input_length = NS2SA_FX2( sampling_rate, FRAME_SIZE_NS );
     152        1476 :         Word16 tmp = shl( div_l( sampling_rate, FRAMES_PER_SEC ), 1 ); // Q0
     153        1476 :         tmp = mult0( tmp, 3 );                                         // Q0
     154        1476 :         tmp = shr( tmp, 2 );                                           // Q0
     155        1476 :         pFb_cfg->windowed_fr_offset = sub( tmp, NS2SA_FX2( sampling_rate, DELAY_DIRAC_SPAR_ENC_CMP_NS ) );
     156        1476 :         move16();
     157        1476 :         move16();
     158        1476 :         move16();
     159        1476 :         move16();
     160             :     }
     161           0 :     ELSE IF( EQ_16( ivas_format, MASA_FORMAT ) )
     162             :     {
     163           0 :         pFb_cfg->fb_latency = NS2SA_FX2( sampling_rate, DELAY_FB_1_NS );
     164           0 :         pFb_cfg->fade_len = NS2SA_FX2( sampling_rate, DELAY_FB_1_NS );
     165           0 :         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           0 :         move16();
     168           0 :         move16();
     169           0 :         move16();
     170             :     }
     171           0 :     ELSE IF( EQ_16( ivas_format, MC_FORMAT ) )
     172             :     {
     173           0 :         pFb_cfg->fb_latency = NS2SA_FX2( sampling_rate, DELAY_FB_1_NS );
     174           0 :         pFb_cfg->fade_len = NS2SA_FX2( sampling_rate, DELAY_FB_1_NS );
     175           0 :         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           0 :         move16();
     178           0 :         move16();
     179           0 :         move16();
     180             :     }
     181             : 
     182        1476 :     *pFb_cfg_out = pFb_cfg;
     183             : 
     184        1476 :     return IVAS_ERR_OK;
     185             : }
     186             : 
     187             : 
     188             : /*-------------------------------------------------------------------------
     189             :  * ivas_FB_mixer_open()
     190             :  *
     191             :  * Allocate and initialize FB mixer handle
     192             :  *------------------------------------------------------------------------*/
     193        1476 : 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        1476 :     error = IVAS_ERR_OK;
     206        1476 :     move32();
     207             : 
     208        1476 :     frame_len = BASOP_Util_Divide3232_Scale( sampling_rate, FRAMES_PER_SEC, &exp );
     209        1476 :     frame_len = shr( frame_len, sub( 15, exp ) );
     210             : 
     211        1476 :     hFbMixer = *hFbMixer_out;
     212             : 
     213        1476 :     IF( !spar_reconfig_flag )
     214             :     {
     215         273 :         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         273 :         IF( fb_cfg->num_out_chans > 0 )
     221             :         {
     222         273 :             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           0 :             hFbMixer->pFb = NULL;
     230             :         }
     231             :     }
     232             : 
     233        1476 :     IF( EQ_16( fb_cfg->active_w_mixing, -1 ) )
     234             :     {
     235        1476 :         num_chs_alloc = 0;
     236        1476 :         move16();
     237             :     }
     238           0 :     ELSE IF( fb_cfg->active_w_mixing )
     239             :     {
     240           0 :         num_chs_alloc = s_max( fb_cfg->num_in_chans, fb_cfg->nchan_fb_in );
     241             :     }
     242             :     ELSE
     243             :     {
     244           0 :         num_chs_alloc = 1; /* only W channel processed for predicting YZX */
     245           0 :         move16();
     246             :     }
     247             : 
     248        1476 :     FOR( i = 0; i < num_chs_alloc; i++ )
     249             :     {
     250           0 :         IF( fb_cfg->num_out_chans == 0 )
     251             :         {
     252           0 :             hFbMixer->ppFilterbank_inFR_re_fx[i] = NULL;
     253           0 :             hFbMixer->ppFilterbank_inFR_im_fx[i] = NULL;
     254             :         }
     255             :         ELSE
     256             :         {
     257           0 :             j = fb_cfg->remix_order[i];
     258           0 :             move16();
     259             : 
     260           0 :             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           0 :             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        1476 :     IF( EQ_16( fb_cfg->active_w_mixing, -1 ) )
     273             :     {
     274        1476 :         num_chs_alloc = 0;
     275        1476 :         move16();
     276             :     }
     277             :     ELSE
     278             :     {
     279           0 :         num_chs_alloc = s_max( fb_cfg->num_in_chans, fb_cfg->nchan_fb_in );
     280             :     }
     281             : 
     282        1476 :     FOR( i = 0; i < num_chs_alloc; i++ )
     283             :     {
     284           0 :         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           0 :         set32_fx( hFbMixer->ppFilterbank_prior_input_fx[i], 0, fb_cfg->prior_input_length );
     289             :     }
     290             : 
     291        1476 :     test();
     292        1476 :     IF( ( NE_16( fb_cfg->active_w_mixing, -1 ) ) && ( fb_cfg->num_out_chans > 0 ) )
     293             :     {
     294             :         Word32 *pTemp_mem_fx;
     295           0 :         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           0 :         FOR( i = 0; i < fb_cfg->num_out_chans; i++ )
     300             :         {
     301           0 :             FOR( j = 0; j < fb_cfg->num_in_chans; j++ )
     302             :             {
     303           0 :                 hFbMixer->prior_mixer_fx[i][j] = pTemp_mem_fx;
     304           0 :                 pTemp_mem_fx += IVAS_MAX_NUM_BANDS;
     305           0 :                 set32_fx( hFbMixer->prior_mixer_fx[i][j], 0, IVAS_MAX_NUM_BANDS );
     306             :             }
     307             :         }
     308           0 :         hFbMixer->q_prior_mixer_fx = Q31;
     309           0 :         move16();
     310             :     }
     311             : 
     312        1476 :     IF( !spar_reconfig_flag )
     313             :     {
     314         273 :         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         273 :             num_bands = ivas_get_num_bands( sampling_rate );
     319             : 
     320         273 :             ivas_get_active_bins_fx( &pActive_bins_per_band, &pActive_bins_per_band_abs, &pStart_offset, &pStart_offset_abs, sampling_rate );
     321             : 
     322         273 :             IF( NE_16( fb_cfg->active_w_mixing, -1 ) )
     323             :             {
     324           0 :                 FOR( i = 0; i < num_bands; i++ )
     325             :                 {
     326           0 :                     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         273 :             IF( NE_32( sampling_rate, 48000 ) )
     334             :             {
     335             :                 Word16 num_diff_bands, start_diff_band_non48k;
     336             : 
     337         154 :                 num_diff_bands = MAX_NUM_BANDS_DIFF_NON48K;
     338         154 :                 move16();
     339         154 :                 start_diff_band_non48k = sub( num_bands, num_diff_bands );
     340             : 
     341         154 :                 hFbMixer->num_diff_bands = num_diff_bands;
     342         154 :                 move16();
     343             : 
     344         616 :                 FOR( j = start_diff_band_non48k; j < num_bands; j++ )
     345             :                 {
     346         462 :                     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         462 :                     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           0 :             hFbMixer->num_diff_bands = 0;
     362           0 :             move16();
     363             :         }
     364             :     }
     365             : 
     366        1476 :     hFbMixer->fb_cfg = fb_cfg;
     367        1476 :     set16_fx( hFbMixer->first_frame, 1, hFbMixer->fb_cfg->num_out_chans );
     368        1476 :     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        1476 :     IF( !spar_reconfig_flag )
     371             :     {
     372             :         Word16 index[IVAS_MAX_NUM_FB_BANDS];
     373         273 :         set16_fx( index, 0, IVAS_MAX_NUM_FB_BANDS );
     374         273 :         IF( NE_32( ( error = ivas_filterbank_setup_fx( hFbMixer, sampling_rate, index ) ), IVAS_ERR_OK ) )
     375             :         {
     376           0 :             return error;
     377             :         }
     378             :     }
     379             : 
     380        1476 :     *hFbMixer_out = hFbMixer;
     381             : 
     382        1476 :     return error;
     383             : }
     384             : 
     385             : /*-------------------------------------------------------------------------
     386             :  * ivas_FB_mixer_close()
     387             :  *
     388             :  * Deallocate FB mixer handle
     389             :  *------------------------------------------------------------------------*/
     390             : 
     391        1476 : 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        1476 :     hFbMixer = *hFbMixer_in;
     403        1476 :     fb_cfg = hFbMixer->fb_cfg;
     404             : 
     405        1476 :     IF( EQ_16( fb_cfg->active_w_mixing, -1 ) )
     406             :     {
     407        1476 :         num_chs_alloc = 0;
     408        1476 :         move16();
     409             :     }
     410           0 :     ELSE IF( fb_cfg->active_w_mixing )
     411             :     {
     412           0 :         num_chs_alloc = s_max( fb_cfg->num_in_chans, fb_cfg->nchan_fb_in );
     413             :     }
     414             :     ELSE
     415             :     {
     416           0 :         num_chs_alloc = 1; /* only W channel processed for predicting YZX */
     417           0 :         move16();
     418             :     }
     419             : 
     420        1476 :     IF( hFbMixer != NULL )
     421             :     {
     422        1476 :         FOR( i = 0; i < num_chs_alloc; i++ )
     423             :         {
     424           0 :             IF( fb_cfg->num_out_chans > 0 )
     425             :             {
     426           0 :                 j = fb_cfg->remix_order[i];
     427           0 :                 move16();
     428             : 
     429           0 :                 free( hFbMixer->ppFilterbank_inFR_re_fx[j] );
     430           0 :                 hFbMixer->ppFilterbank_inFR_re_fx[j] = NULL;
     431             : 
     432           0 :                 free( hFbMixer->ppFilterbank_inFR_im_fx[j] );
     433           0 :                 hFbMixer->ppFilterbank_inFR_im_fx[j] = NULL;
     434             :             }
     435             :         }
     436             : 
     437        1476 :         IF( EQ_16( fb_cfg->active_w_mixing, -1 ) )
     438             :         {
     439        1476 :             num_chs_alloc = 0;
     440        1476 :             move16();
     441             :         }
     442             :         ELSE
     443             :         {
     444           0 :             num_chs_alloc = s_max( fb_cfg->num_in_chans, fb_cfg->nchan_fb_in );
     445             :         }
     446             : 
     447        1476 :         FOR( i = 0; i < num_chs_alloc; i++ )
     448             :         {
     449           0 :             free( hFbMixer->ppFilterbank_prior_input_fx[i] );
     450           0 :             hFbMixer->ppFilterbank_prior_input_fx[i] = NULL;
     451             :         }
     452             : 
     453        1476 :         test();
     454        1476 :         IF( NE_16( fb_cfg->active_w_mixing, -1 ) && ( fb_cfg->num_out_chans > 0 ) )
     455             :         {
     456           0 :             free( hFbMixer->prior_mixer_fx[0][0] );
     457           0 :             hFbMixer->prior_mixer_fx[0][0] = NULL;
     458             :         }
     459             : 
     460        1476 :         IF( !spar_reconfig_flag )
     461             :         {
     462         273 :             IF( fb_cfg->num_out_chans > 0 )
     463             :             {
     464         273 :                 num_bands = hFbMixer->pFb->filterbank_num_bands;
     465         273 :                 move16();
     466             : 
     467         273 :                 IF( NE_16( fb_cfg->active_w_mixing, -1 ) )
     468             :                 {
     469           0 :                     FOR( i = 0; i < num_bands; i++ )
     470             :                     {
     471           0 :                         free( hFbMixer->pFb->fb_bin_to_band.pFb_bin_to_band_fx[i] );
     472           0 :                         hFbMixer->pFb->fb_bin_to_band.pFb_bin_to_band_fx[i] = NULL;
     473             :                     }
     474             :                 }
     475             : 
     476         273 :                 IF( NE_32( sampling_rate, 48000 ) )
     477             :                 {
     478             :                     Word16 start_diff_band_non48k;
     479         154 :                     start_diff_band_non48k = sub( num_bands, hFbMixer->num_diff_bands );
     480             : 
     481         616 :                     FOR( j = start_diff_band_non48k; j < num_bands; j++ )
     482             :                     {
     483         462 :                         free( hFbMixer->pFb->fb_consts.ppFilterbank_FRs_non48k_fx[0][j] );
     484         462 :                         hFbMixer->pFb->fb_consts.ppFilterbank_FRs_non48k_fx[0][j] = NULL;
     485             : 
     486         462 :                         free( hFbMixer->pFb->fb_consts.ppFilterbank_FRs_non48k_fx[1][j] );
     487         462 :                         hFbMixer->pFb->fb_consts.ppFilterbank_FRs_non48k_fx[1][j] = NULL;
     488             :                     }
     489             :                 }
     490             :             }
     491         273 :             IF( hFbMixer->pFb != NULL )
     492             :             {
     493         273 :                 free( hFbMixer->pFb );
     494         273 :                 hFbMixer->pFb = NULL;
     495             :             }
     496             :         }
     497             : 
     498        1476 :         IF( hFbMixer->fb_cfg != NULL )
     499             :         {
     500        1476 :             free( hFbMixer->fb_cfg );
     501        1476 :             hFbMixer->fb_cfg = NULL;
     502             :         }
     503             : 
     504        1476 :         IF( !spar_reconfig_flag )
     505             :         {
     506         273 :             free( hFbMixer );
     507         273 :             hFbMixer = NULL;
     508             :         }
     509             :     }
     510             : 
     511        1476 :     return;
     512             : }
     513             : /*-----------------------------------------------------------------------------------------*
     514             :  * Function ivas_fb_mixer_pcm_ingest()
     515             :  *
     516             :  * PCM ingest block
     517             :  *-----------------------------------------------------------------------------------------*/
     518           0 : 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           0 :     IVAS_FB_CFG *fb_cfg = hFbMixer->fb_cfg;
     530             : 
     531           0 :     IF( fb_cfg->active_w_mixing )
     532             :     {
     533           0 :         num_chs_ingest = fb_cfg->num_in_chans;
     534           0 :         move16();
     535             :     }
     536             :     ELSE
     537             :     {
     538           0 :         num_chs_ingest = 1; /* forward Filterbank MDFT only on W */
     539           0 :         move16();
     540             :     }
     541             : 
     542             : 
     543           0 :     FOR( i = 0; i < fb_cfg->num_in_chans; i++ )
     544             :     {
     545           0 :         Copy32( &hFbMixer->ppFilterbank_prior_input_fx[i][fb_cfg->prior_input_length - frame_len], ppOut_pcm[i], frame_len );
     546           0 :         Copy32( pcm_in[HOA_md_ind[i]], &ppOut_pcm[i][frame_len], frame_len );
     547           0 :         q_ppOut_pcm[i] = q_data_fix;
     548           0 :         move16();
     549             :     }
     550             : 
     551           0 :     Word16 guard_bits = find_guarded_bits_fx( shl( frame_len, 1 ) );
     552             : 
     553           0 :     FOR( i = 0; i < num_chs_ingest; i++ )
     554             :     {
     555           0 :         Word16 q_shift = sub( L_norm_arr( ppOut_pcm[fb_cfg->remix_order[i]], shl( frame_len, 1 ) ), guard_bits );
     556           0 :         Scale_sig32( ppOut_pcm[fb_cfg->remix_order[i]], shl( frame_len, 1 ), q_shift ); // Qq_ppOut_pcm -> Qq_ppOut_pcm + q_shift
     557           0 :         q_ppOut_pcm[fb_cfg->remix_order[i]] = add( q_ppOut_pcm[fb_cfg->remix_order[i]], q_shift );
     558           0 :         move16();
     559             : 
     560           0 :         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           0 :         q_shift = L_norm_arr( hFbMixer->ppFilterbank_inFR_re_fx[fb_cfg->remix_order[i]], frame_len );
     562           0 :         q_shift = s_min( q_shift, L_norm_arr( hFbMixer->ppFilterbank_inFR_im_fx[fb_cfg->remix_order[i]], frame_len ) );
     563           0 :         scale_sig32( hFbMixer->ppFilterbank_inFR_re_fx[fb_cfg->remix_order[i]], frame_len, q_shift );
     564           0 :         scale_sig32( hFbMixer->ppFilterbank_inFR_im_fx[fb_cfg->remix_order[i]], frame_len, q_shift );
     565           0 :         hFbMixer->q_ppFilterbank_inFR[fb_cfg->remix_order[i]] = add( q_shift, q_ppOut_pcm[fb_cfg->remix_order[i]] );
     566           0 :         move16();
     567             :     }
     568             : 
     569           0 :     return;
     570             : }
     571             : 
     572             : /*-----------------------------------------------------------------------------------------*
     573             :  * Function ivas_fb_mixer_update_prior_input()
     574             :  *
     575             :  *
     576             :  *-----------------------------------------------------------------------------------------*/
     577           0 : 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           0 :     FOR( i = 0; i < nchan_fb_in; i++ )
     587             :     {
     588           0 :         Copy32( &hFbMixer->ppFilterbank_prior_input_fx[i][length], hFbMixer->ppFilterbank_prior_input_fx[i], hFbMixer->fb_cfg->prior_input_length - length );
     589           0 :         Copy32( pcm_in_fx[i], &hFbMixer->ppFilterbank_prior_input_fx[i][hFbMixer->fb_cfg->prior_input_length - length], length );
     590             :     }
     591             : 
     592           0 :     return;
     593             : }
     594             : 
     595             : 
     596             : /*-----------------------------------------------------------------------------------------*
     597             :  * Function ivas_fb_mixer_get_windowed_fr()
     598             :  *
     599             :  *
     600             :  *-----------------------------------------------------------------------------------------*/
     601             : 
     602           0 : 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             : #ifdef OPT_MCT_ENC_V1_BE
     618           0 :     Word16 two_mdft_len = shl( mdft_len, 1 );
     619           0 :     Word16 tmp = sub( shl( mdft_len, 1 ), length );
     620           0 :     Word16 gb_neg = negate( gb );
     621             : 
     622           0 :     n_old_samples = s_min( ( sub( hFbMixer->fb_cfg->prior_input_length, hFbMixer->fb_cfg->windowed_fr_offset ) ), two_mdft_len );
     623           0 :     offset = sub( tmp, hFbMixer->ana_window_offset );
     624           0 :     rev_offset = sub( two_mdft_len, hFbMixer->ana_window_offset );
     625             : #else
     626             :     n_old_samples = s_min( ( sub( hFbMixer->fb_cfg->prior_input_length, hFbMixer->fb_cfg->windowed_fr_offset ) ), ( shl( mdft_len, 1 ) ) );
     627             :     offset = sub( sub( shl( mdft_len, 1 ), length ), hFbMixer->ana_window_offset );
     628             :     rev_offset = sub( shl( mdft_len, 1 ), hFbMixer->ana_window_offset );
     629             : #endif
     630           0 :     set32_fx( fr_in_block_fx, 0, offset );
     631           0 :     n_new_samples = s_max( 0, sub( shl( length, 1 ), n_old_samples ) );
     632           0 :     FOR( ch_idx = 0; ch_idx < nchan_fb_in; ch_idx++ )
     633             :     {
     634           0 :         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
     635           0 :         Copy32( pcm_in_fx[ch_idx], &fr_in_block_fx[n_old_samples], n_new_samples );                                                                                     // Qx
     636             : 
     637           0 :         win_ptr_fx = hFbMixer->pAna_window_fx; /*Q15*/
     638             : 
     639             : #ifdef OPT_MCT_ENC_V1_BE
     640           0 :         FOR( j = offset; j < tmp; j++ )
     641             : #else
     642             :         FOR( j = offset; j < sub( shl( mdft_len, 1 ), length ); j++ )
     643             : #endif
     644             :         {
     645           0 :             fr_in_block_fx[j] = Mpy_32_16_1( fr_in_block_fx[j], ( *( win_ptr_fx++ ) ) ); // Qx + 15 - 15 = Qx
     646           0 :             move32();
     647             :         }
     648             : 
     649             : #ifdef OPT_MCT_ENC_V1_BE
     650           0 :         FOR( j = rev_offset; j < two_mdft_len; j++ )
     651             : #else
     652             :         FOR( j = rev_offset; j < shl( mdft_len, 1 ); j++ )
     653             : #endif
     654             :         {
     655           0 :             fr_in_block_fx[j] = Mpy_32_16_1( fr_in_block_fx[j], ( *( --win_ptr_fx ) ) ); // Qx + 15 - 15 = Qx
     656           0 :             move32();
     657             :         }
     658             : 
     659             : #ifdef OPT_MCT_ENC_V1_BE
     660           0 :         scale_sig32( fr_in_block_fx, two_mdft_len, gb_neg );
     661             : #else
     662             :         FOR( Word16 i = 0; i < shl( mdft_len, 1 ); i++ )
     663             :         {
     664             :             fr_in_block_fx[i] = L_shr( fr_in_block_fx[i], gb ); // Qx - gb
     665             :             move32();
     666             :         }
     667             : #endif
     668             : 
     669             : #ifdef OPT_MCT_ENC_V1_BE
     670           0 :         ivas_mdft_fx( fr_in_block_fx, frame_f_real_fx[ch_idx], frame_f_imag_fx[ch_idx], two_mdft_len, mdft_len );
     671             : #else
     672             :         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 );
     673             : #endif
     674             :     }
     675             : 
     676           0 :     return;
     677             : }
     678             : 
     679             : /*-----------------------------------------------------------------------------------------*
     680             :  * Function ivas_fb_mixer_cross_fading()
     681             :  *
     682             :  * FB Mixer cross fading
     683             :  *-----------------------------------------------------------------------------------------*/
     684             : 
     685           0 : void ivas_fb_mixer_cross_fading_fx(
     686             :     IVAS_FB_MIXER_HANDLE hFbMixer,
     687             :     Word32 **ppOut_pcm_fx,    // o: Qx
     688             :     Word32 *pMdft_out_old_fx, // i: Qx
     689             :     Word32 *pMdft_out_new_fx, // i: Qx
     690             :     const Word16 ch,
     691             :     const Word16 frame_len,
     692             :     const Word16 cf_offset )
     693             : {
     694             :     Word16 k, fade_start_offset, fade_end_offset;
     695             : 
     696           0 :     IF( hFbMixer->first_frame[ch] == 0 )
     697             :     {
     698           0 :         fade_start_offset = hFbMixer->cross_fade_start_offset;
     699           0 :         fade_end_offset = hFbMixer->cross_fade_end_offset;
     700           0 :         move16();
     701           0 :         move16();
     702             : 
     703           0 :         FOR( k = 0; k < fade_start_offset; k++ )
     704             :         {
     705           0 :             ppOut_pcm_fx[ch][k] = pMdft_out_old_fx[k + cf_offset]; // Qx
     706           0 :             move32();
     707             :         }
     708             : 
     709           0 :         FOR( k = fade_start_offset; k < fade_end_offset; k++ )
     710             :         {
     711           0 :             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
     712           0 :             move32();
     713             :         }
     714             : 
     715           0 :         FOR( k = fade_end_offset; k < frame_len; k++ )
     716             :         {
     717           0 :             ppOut_pcm_fx[ch][k] = pMdft_out_new_fx[k + cf_offset]; // Qx
     718           0 :             move32();
     719             :         }
     720             :     }
     721             :     ELSE
     722             :     {
     723           0 :         hFbMixer->first_frame[ch] = 0;
     724           0 :         move32();
     725             : 
     726           0 :         FOR( k = 0; k < frame_len; k++ )
     727             :         {
     728           0 :             ppOut_pcm_fx[ch][k] = pMdft_out_new_fx[k + cf_offset]; // Qx
     729           0 :             move32();
     730             :         }
     731             :     }
     732             : 
     733           0 :     return;
     734             : }
     735             : 
     736             : /*-----------------------------------------------------------------------------------------*
     737             :  * Function ivas_fb_mixer_process()
     738             :  *
     739             :  * Filter bank process
     740             :  *-----------------------------------------------------------------------------------------*/
     741           0 : void ivas_cmult_fix(
     742             :     Word32 in1_re,   // i: Qx
     743             :     Word32 in1_im,   // i: Qx
     744             :     Word32 in2_re,   // i: Qx
     745             :     Word32 in2_im,   // i: Qx
     746             :     Word32 *out1_re, // o: 2 * Qx - 31
     747             :     Word32 *out1_im  // o: 2 * Qx - 31
     748             : )
     749             : {
     750           0 :     *out1_re = L_sub_sat( Mpy_32_32( in1_re, in2_re ), Mpy_32_32( in1_im, in2_im ) );
     751           0 :     move32();
     752           0 :     *out1_im = L_add_sat( Mpy_32_32( in1_re, in2_im ), Mpy_32_32( in2_re, in1_im ) );
     753           0 :     move32();
     754           0 : }
     755             : 
     756           0 : void ivas_fb_mixer_process_fx(
     757             :     IVAS_FB_MIXER_HANDLE hFbMixer,                                                  /* i/o: FB mixer handle                             */
     758             :     Word32 ***mixer_mat_fx,                                                         /* i  : mixer matrix                                */
     759             :     Word16 *q_mixer_mat_fx,                                                         /* i  : mixer matrix Q-factor                       */
     760             :     Word32 **ppOut_pcm_fx,                                                          /* o  : output audio channels                       */
     761             :     Word16 *q_ppOut_pcm_fx,                                                         /* o  : output audio channels Q-factor              */
     762             :     const Word16 frame_len,                                                         /* i  : frame length in samples                     */
     763             :     Word16 in_out_mixer_map[IVAS_MAX_FB_MIXER_OUT_CH][IVAS_MAX_SPAR_FB_MIXER_IN_CH] /* i/o: mixing mapping                              */
     764             : )
     765             : {
     766           0 :     ivas_filterbank_t *pFb = hFbMixer->pFb;
     767           0 :     Word16 num_bands = pFb->filterbank_num_bands;
     768           0 :     move16();
     769             :     Word16 i, j, k, ch, hist;
     770             : 
     771             :     const Word32 *pFilterbank_bin_to_band_re_fx;
     772             :     const Word32 *pFilterbank_bin_to_band_im_fx;
     773             :     Word16 q_pMdft_out_fx[2];
     774             :     Word32 *pMdft_out_fx[2];
     775             :     Word32 *pOut_fr_re_fx, *pOut_fr_im_fx;
     776           0 :     Word16 q_pOut_fr_fx = 31;
     777           0 :     move16();
     778             :     Word32 Out_fr_re_fx[L_FRAME48k], Out_fr_im_fx[L_FRAME48k];
     779             :     Word32 Mdft_out_0_fx[L_FRAME48k * 2], Mdft_out_1_fx[L_FRAME48k * 2];
     780             : 
     781           0 :     pOut_fr_re_fx = Out_fr_re_fx;
     782           0 :     pOut_fr_im_fx = Out_fr_im_fx;
     783           0 :     pMdft_out_fx[0] = Mdft_out_0_fx;
     784           0 :     pMdft_out_fx[1] = Mdft_out_1_fx;
     785             : 
     786             : #ifdef OPT_SBA_ENC_V1_BE
     787           0 :     Word16 total_guard = find_guarded_bits_fx( num_bands );
     788           0 :     Word16 total_guard_2 = find_guarded_bits_fx( shl( frame_len, 1 ) );
     789           0 :     Word16 tmp_q = sub( sub( *q_mixer_mat_fx, total_guard ), 32 ); // Q30 + hFbMixer->q_prior_mixer_fx - 31 - total_guard - 31
     790           0 :     Word16 len = shl( frame_len, 1 );
     791             :     Word16 res_q, q_check;
     792             : #endif
     793           0 :     FOR( ch = ( hFbMixer->fb_cfg->active_w_mixing == 0 ); ch < hFbMixer->fb_cfg->num_out_chans; ch++ )
     794             :     {
     795             :         /* Run a loop of 2 to calculate current frame's filterbank output and prev frame's output */
     796           0 :         FOR( hist = 0; hist < 2; hist++ )
     797             :         {
     798           0 :             set_zero_fx( pOut_fr_re_fx, frame_len );
     799           0 :             set_zero_fx( pOut_fr_im_fx, frame_len );
     800           0 :             q_pOut_fr_fx = 31;
     801           0 :             move16();
     802           0 :             FOR( j = 0; j < hFbMixer->fb_cfg->num_in_chans; j++ )
     803             :             {
     804           0 :                 IF( in_out_mixer_map[ch][j] != 0 )
     805             :                 {
     806             : 
     807             : #ifdef OPT_SBA_ENC_V1_BE
     808           0 :                     res_q = add( tmp_q, hFbMixer->q_ppFilterbank_inFR[j] );
     809           0 :                     q_check = s_min( q_pOut_fr_fx, res_q );
     810           0 :                     scale_sig32( pOut_fr_re_fx, frame_len, sub( q_check, q_pOut_fr_fx ) );
     811           0 :                     scale_sig32( pOut_fr_im_fx, frame_len, sub( q_check, q_pOut_fr_fx ) );
     812             : #endif
     813             :                     Word32 filterbank_mixer_bins_re_fx[L_FRAME48k];
     814             :                     Word32 filterbank_mixer_bins_im_fx[L_FRAME48k];
     815           0 :                     Word32 *pFb_inFR_re_fx = hFbMixer->ppFilterbank_inFR_re_fx[j]; // Q(hFbMixer->q_ppFilterbank_inFR_re_fx)
     816           0 :                     Word32 *pFb_inFR_im_fx = hFbMixer->ppFilterbank_inFR_im_fx[j]; // Q(hFbMixer->q_ppFilterbank_inFR_im_fx)
     817             : 
     818           0 :                     set_zero_fx( filterbank_mixer_bins_re_fx, frame_len );
     819           0 :                     set_zero_fx( filterbank_mixer_bins_im_fx, frame_len );
     820             : 
     821             : #ifndef OPT_SBA_ENC_V1_BE
     822             :                     Word16 total_guard = find_guarded_bits_fx( num_bands );
     823             :                     move16();
     824             : #endif
     825           0 :                     FOR( i = 0; i < num_bands; i++ )
     826             :                     {
     827           0 :                         Word16 start_offset = pFb->fb_consts.pFilterbank_bins_start_offset[i];
     828           0 :                         move16();
     829           0 :                         Word16 num_bins = pFb->fb_consts.pFilterbank_bins_per_band[i];
     830           0 :                         move16();
     831           0 :                         Word32 mixer_const_fx = hFbMixer->prior_mixer_fx[ch][j][i]; // Q(hFbMixer->q_prior_mixer_fx)
     832           0 :                         move32();
     833           0 :                         pFilterbank_bin_to_band_re_fx = pFb->fb_consts.ppFilterbank_FRs_fx[0][i]; // Q30
     834           0 :                         pFilterbank_bin_to_band_im_fx = pFb->fb_consts.ppFilterbank_FRs_fx[1][i]; // Q30
     835             : 
     836           0 :                         FOR( k = start_offset; k < num_bins + start_offset; k++ )
     837             :                         {
     838           0 :                             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
     839           0 :                             move32();
     840           0 :                             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
     841           0 :                             move32();
     842             :                             /*filterbank_mixer_bins_im_fx q 30 */
     843             :                             /*mixer_const_fx q  q_ppOut_pcm_fx */
     844           0 :                             pFilterbank_bin_to_band_re_fx++;
     845           0 :                             pFilterbank_bin_to_band_im_fx++;
     846             :                         }
     847           0 :                         hFbMixer->prior_mixer_fx[ch][j][i] = mixer_mat_fx[ch][j][i]; // Q(q_mixer_mat_fx)
     848           0 :                         move32();
     849             :                     }
     850             : #ifndef OPT_SBA_ENC_V1_BE
     851             :                     Word16 res_q = 0;
     852             :                     move16();
     853             : #endif
     854           0 :                     FOR( k = 0; k < frame_len; k++ )
     855             :                     {
     856             :                         Word32 temp_out_re_fx, temp_out_im_fx;
     857             : 
     858           0 :                         ivas_cmult_fix( filterbank_mixer_bins_re_fx[k], filterbank_mixer_bins_im_fx[k], pFb_inFR_re_fx[k],
     859           0 :                                         pFb_inFR_im_fx[k], &temp_out_re_fx, &temp_out_im_fx );
     860             : #ifndef OPT_SBA_ENC_V1_BE
     861             :                         res_q = sub( add( sub( sub( add( 30, *q_mixer_mat_fx ), 31 ), total_guard ), hFbMixer->q_ppFilterbank_inFR[j] ), 31 );
     862             : 
     863             :                         Word16 q_check = s_min( q_pOut_fr_fx, res_q );
     864             :                         IF( NE_16( q_check, q_pOut_fr_fx ) )
     865             :                         {
     866             :                             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
     867             :                             move32();
     868             :                             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
     869             :                             move32();
     870             :                         }
     871             : #endif
     872           0 :                         IF( NE_16( q_check, res_q ) )
     873             :                         {
     874           0 :                             temp_out_re_fx = L_shr( temp_out_re_fx, sub( res_q, q_check ) ); // res_q -> q_check
     875           0 :                             temp_out_im_fx = L_shr( temp_out_im_fx, sub( res_q, q_check ) ); // res_q -> q_check
     876             :                         }
     877             : #ifndef OPT_SBA_ENC_V1_BE
     878             :                         res_q = q_check;
     879             :                         move16();
     880             : #endif
     881             : 
     882           0 :                         pOut_fr_re_fx[k] = L_add_sat( pOut_fr_re_fx[k], temp_out_re_fx ); // res_q
     883           0 :                         move32();
     884           0 :                         pOut_fr_im_fx[k] = L_add_sat( pOut_fr_im_fx[k], temp_out_im_fx ); // res_q
     885           0 :                         move32();
     886             :                     }
     887             : #ifdef OPT_SBA_ENC_V1_BE
     888           0 :                     q_pOut_fr_fx = q_check;
     889             : #else
     890             :                     q_pOut_fr_fx = res_q;
     891             :                     move16();
     892             : #endif
     893             :                 }
     894             :             }
     895             : #ifndef OPT_SBA_ENC_V1_BE
     896             :             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 ) ) );
     897             : #else
     898           0 :             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 );
     899             : #endif
     900           0 :             scale_sig32( pOut_fr_re_fx, frame_len, scale );
     901           0 :             scale_sig32( pOut_fr_im_fx, frame_len, scale );
     902           0 :             ivas_imdft_fx( pOut_fr_re_fx, pOut_fr_im_fx, pMdft_out_fx[hist], frame_len );
     903           0 :             q_pMdft_out_fx[hist] = add( q_pOut_fr_fx, scale );
     904           0 :             move16();
     905             :         }
     906             : #ifdef OPT_SBA_ENC_V1_BE
     907           0 :         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] ) );
     908           0 :         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] ) );
     909             : #else
     910             :         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] ) );
     911             :         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] ) );
     912             : #endif
     913           0 :         ivas_fb_mixer_cross_fading_fx( hFbMixer, ppOut_pcm_fx, pMdft_out_fx[0], pMdft_out_fx[1], ch, frame_len, frame_len );
     914           0 :         q_ppOut_pcm_fx[ch] = s_min( q_pMdft_out_fx[0], q_pMdft_out_fx[1] );
     915           0 :         move16();
     916             :     }
     917             : 
     918           0 :     return;
     919             : }
     920             : 
     921             : /*-----------------------------------------------------------------------------------------*
     922             :  * Function ivas_fb_mixer_get_in_out_mapping()
     923             :  *
     924             :  *
     925             :  *-----------------------------------------------------------------------------------------*/
     926           0 : void ivas_fb_mixer_get_in_out_mapping_fx(
     927             :     const IVAS_FB_CFG *fb_cfg,                                                      /* i  : FB config. handle  */
     928             :     Word16 in_out_mixer_map[IVAS_MAX_FB_MIXER_OUT_CH][IVAS_MAX_SPAR_FB_MIXER_IN_CH] /* i/o: mixing mapping     */
     929             : )
     930             : {
     931             :     Word16 i, j;
     932             : 
     933           0 :     set_s( (Word16 *) in_out_mixer_map, 0, IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_SPAR_FB_MIXER_IN_CH );
     934             : 
     935           0 :     IF( fb_cfg->active_w_mixing )
     936             :     {
     937           0 :         FOR( i = 0; i < fb_cfg->num_out_chans; i++ )
     938             :         {
     939           0 :             FOR( j = 0; j < fb_cfg->num_in_chans; j++ )
     940             :             {
     941           0 :                 in_out_mixer_map[i][j] = 1;
     942           0 :                 move16();
     943             :             }
     944             :         }
     945             :     }
     946             :     ELSE
     947             :     {
     948           0 :         in_out_mixer_map[0][0] = 1; /* W depends on only W input*/
     949           0 :         move16();
     950           0 :         FOR( i = 1; i < fb_cfg->num_out_chans; i++ )
     951             :         {
     952           0 :             in_out_mixer_map[i][0] = 1;
     953           0 :             move16();
     954             :         }
     955             :     }
     956             : 
     957           0 :     return;
     958             : }
     959             : 
     960             : /*-----------------------------------------------------------------------------------------*
     961             :  * Function ivas_calculate_abs_fr()
     962             :  *
     963             :  * Function to calculate number of active bands
     964             :  *-----------------------------------------------------------------------------------------*/
     965             : 
     966         273 : static Word16 ivas_calculate_abs_fr_fx(
     967             :     ivas_filterbank_t *pFb,
     968             :     const Word32 sampling_rate,
     969             :     const Word16 alloc_fb_resp,
     970             :     Word16 *index )
     971             : {
     972             :     Word16 frame_len;
     973             :     Word32 ppFilterbank_FRs_s_fx[L_FRAME48k];
     974         273 :     Word16 bands = pFb->filterbank_num_bands;
     975         273 :     move16();
     976         273 :     Word16 i, j, num_active_bands = 0;
     977         273 :     move16();
     978         273 :     Word16 idx_short_stride_bin_to_band = 0;
     979         273 :     move16();
     980             :     Word16 quo, tmp, exp_diff;
     981             : 
     982         273 :     Word32 temp = Mpy_32_32( sampling_rate, 42949673 /* FRAMES_PER_SEC in Q31 */ );
     983         273 :     frame_len = extract_l( temp );
     984             : 
     985        3469 :     FOR( i = 0; i < bands; i++ )
     986             :     {
     987        3196 :         const Word32 *long_mdft_ptr_re_fx = pFb->fb_consts.ppFilterbank_FRs_fx[0][i]; // Q30
     988        3196 :         const Word32 *long_mdft_ptr_im_fx = pFb->fb_consts.ppFilterbank_FRs_fx[1][i]; // Q30
     989             : 
     990        3196 :         Word16 start_offset = pFb->fb_consts.pFilterbank_bins_start_offset[i];
     991        3196 :         move16();
     992        3196 :         Word16 num_bins = pFb->fb_consts.pFilterbank_bins_per_band[i];
     993        3196 :         move16();
     994        3196 :         Word16 short_mdft_start_bin = -1;
     995        3196 :         move16();
     996             : 
     997             :         Word32 short_stride_pow_spec_fx[MDFT_FB_BANDS_240];
     998        3196 :         Word32 short_stride_nrg_fx = 0;
     999        3196 :         move16();
    1000        3196 :         exp_diff = 0;
    1001        3196 :         move16();
    1002             : 
    1003        3196 :         Word64 cldfb_nrg_fx = 0;
    1004        3196 :         move64();
    1005        3196 :         Word16 short_stride = pFb->fb_bin_to_band.short_stride;
    1006        3196 :         move16();
    1007             :         Word32 res_dec1, res_frac, res_dec2;
    1008        3196 :         iDiv_and_mod_32( sampling_rate, FRAMES_PER_SEC, &res_dec1, &res_frac, 0 );
    1009        3196 :         iDiv_and_mod_32( res_dec1, short_stride, &res_dec2, &res_frac, 0 );
    1010        3196 :         const Word16 num_bins_per_short_stride_bin = extract_l( res_dec2 );
    1011        3196 :         iDiv_and_mod_32( res_dec1, pFb->fb_bin_to_band.num_cldfb_bands, &res_dec2, &res_frac, 0 );
    1012        3196 :         const Word16 num_bins_per_cldfb_band = extract_l( res_dec2 );
    1013             : 
    1014        3196 :         Word32 short_stride_max_per_spar_band_fx = 1;
    1015        3196 :         move32();
    1016             : 
    1017             :         /*loop over all stored Filter Bank Response MDFT coefficients*/
    1018             : 
    1019        3196 :         set32_fx( short_stride_pow_spec_fx, 0, MDFT_FB_BANDS_240 );
    1020             : 
    1021      966952 :         FOR( j = start_offset; j < num_bins + start_offset; j++ )
    1022             :         {
    1023             : 
    1024             :             Word32 sq_abs_fx;
    1025             : 
    1026             :             // Word32 real = L_shr( *long_mdft_ptr_re_fx, 3 ); // Q27
    1027      963756 :             Word32 real = *long_mdft_ptr_re_fx; // Q30
    1028      963756 :             move32();
    1029             :             // Word32 imag = L_shr( *long_mdft_ptr_im_fx, 3 ); // Q27
    1030      963756 :             Word32 imag = *long_mdft_ptr_im_fx; // Q30
    1031      963756 :             move32();
    1032      963756 :             Word64 acc = W_mac_32_32( W_mult_32_32( real, real ), imag, imag ); // Q61
    1033      963756 :             sq_abs_fx = W_extract_h( acc );                                     // Q28
    1034      963756 :             long_mdft_ptr_re_fx++;
    1035      963756 :             long_mdft_ptr_im_fx++;
    1036             : 
    1037             :             /* accumulate bin energies within a short stride bin */
    1038             : 
    1039      963756 :             short_stride_nrg_fx = L_add( short_stride_nrg_fx, L_shr( sq_abs_fx, 6 ) ); // Q22
    1040      963756 :             move32();
    1041             : 
    1042      963756 :             IF( !( add( j, 1 ) % num_bins_per_short_stride_bin ) )
    1043             :             {
    1044             :                 /* new short stride bin */
    1045      240423 :                 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*/
    1046      240423 :                 move32();
    1047      240423 :                 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*/
    1048      240423 :                 short_stride_nrg_fx = 0;
    1049      240423 :                 move32();
    1050             :             }
    1051             : 
    1052             :             /* accumulate bin energies within a CLDFB band */
    1053      963756 :             cldfb_nrg_fx = W_mac_32_32( cldfb_nrg_fx, sq_abs_fx, 1 ); // Q29
    1054             : 
    1055      963756 :             IF( !( add( j, 1 ) % num_bins_per_cldfb_band ) )
    1056             :             {
    1057       59627 :                 Word16 exp = W_norm( cldfb_nrg_fx );
    1058       59627 :                 cldfb_nrg_fx = W_shl( cldfb_nrg_fx, exp );
    1059       59627 :                 exp = sub( 34, exp ); // 31 - (Q29 + exp -32)
    1060       59627 :                 temp = Sqrt32( W_extract_h( cldfb_nrg_fx ), &exp );
    1061       59627 :                 temp = L_shl( temp, sub( exp, Q9 ) );                                                         // Q22
    1062       59627 :                 pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[j / num_bins_per_cldfb_band][i] = temp; // Q22
    1063       59627 :                 move32();
    1064       59627 :                 cldfb_nrg_fx = 0;
    1065       59627 :                 move32();
    1066             :             }
    1067             :         }
    1068             : 
    1069        3196 :         quo = BASOP_Util_Divide3232_Scale( ONE_IN_Q30, short_stride_max_per_spar_band_fx, &exp_diff );
    1070             :         /* Q of quo = Q30 - Q22 + (15 - exp_diff) --> Q23 - exp_diff.
    1071             :         With Mult_32_16, Q23 - exp_diff - 15 --> Q8 - exp_diff */
    1072        3196 :         exp_diff = sub( Q8, exp_diff );
    1073             : 
    1074             :         /*loop over the short MDFT bins*/
    1075      596796 :         FOR( j = 0; j < short_stride; j++ )
    1076             :         {
    1077      593600 :             short_stride_pow_spec_fx[j] = L_shr( Mult_32_16( short_stride_pow_spec_fx[j], quo ), exp_diff ); // Q22
    1078      593600 :             move32();
    1079      593600 :             short_stride_pow_spec_fx[j] = L_max( L_sub( short_stride_pow_spec_fx[j], 1258291 ), 0 ); // 0.3f * ONE_IN_Q22
    1080      593600 :             move32();
    1081      593600 :             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
    1082      593600 :             move32();
    1083             : 
    1084             : 
    1085      593600 :             IF( short_stride_pow_spec_fx[j] > 0 )
    1086             :             {
    1087       53792 :                 assert( idx_short_stride_bin_to_band < 2 * MDFT_FB_BANDS_240 ); /* array size of p_short_stride_bin_to_band */
    1088       53792 :                 IF( EQ_16( short_mdft_start_bin, -1 ) )
    1089             :                 {
    1090        3196 :                     short_mdft_start_bin = j;
    1091        3196 :                     move16();
    1092        3196 :                     pFb->fb_bin_to_band.p_short_stride_start_bin_per_band[i] = j;
    1093        3196 :                     move16();
    1094             : 
    1095        3196 :                     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
    1096        3196 :                     index[i] = idx_short_stride_bin_to_band;
    1097        3196 :                     move16();
    1098             :                 }
    1099             : 
    1100       53792 :                 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
    1101       53792 :                 move32();
    1102       53792 :                 idx_short_stride_bin_to_band = add( idx_short_stride_bin_to_band, 1 );
    1103             : 
    1104       53792 :                 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 );
    1105       53792 :                 move16();
    1106             :             }
    1107             :         }
    1108             :     }
    1109             : 
    1110             :     /*loop over CLDFB bands*/
    1111       12773 :     FOR( j = 0; j < pFb->fb_bin_to_band.num_cldfb_bands; j++ )
    1112             :     {
    1113       12500 :         Word32 sum_over_spar_bands_fx = 0;
    1114       12500 :         move32();
    1115       12500 :         Word32 max_spar_band_contribution_fx = 0;
    1116       12500 :         move32();
    1117             : 
    1118       12500 :         Word16 spar_start = 0;
    1119       12500 :         move16();
    1120       12500 :         Word16 any_non_zero = 0;
    1121       12500 :         move16();
    1122             : 
    1123      160900 :         FOR( i = 0; i < bands; i++ )
    1124             :         {
    1125      148400 :             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
    1126      148400 :             move32();
    1127             : 
    1128      148400 :             IF( pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[j][i] > max_spar_band_contribution_fx )
    1129             :             {
    1130       36923 :                 max_spar_band_contribution_fx = pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[j][i]; // Q22
    1131       36923 :                 move32();
    1132       36923 :                 pFb->fb_bin_to_band.p_cldfb_map_to_spar_band[j] = i;
    1133       36923 :                 move16();
    1134             :             }
    1135             :         }
    1136             : 
    1137       12500 :         sum_over_spar_bands_fx = L_max( sum_over_spar_bands_fx, EPSILON_FX ); // Q22
    1138       12500 :         move32();
    1139             : 
    1140       12500 :         exp_diff = 0;
    1141       12500 :         move16();
    1142       12500 :         tmp = BASOP_Util_Divide3232_Scale( ONE_IN_Q30, sum_over_spar_bands_fx, &exp_diff );
    1143             :         /* Q of quo = Q30 - Q22 + (15 - exp_diff) --> Q23 - exp_diff.
    1144             :         With Mult_32_16, Q23 - exp_diff - 15 --> Q8 - exp_diff */
    1145       12500 :         exp_diff = sub( Q8, exp_diff );
    1146             : 
    1147      160900 :         FOR( i = 0; i < bands; i++ )
    1148             :         {
    1149      148400 :             test();
    1150      148400 :             IF( pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[j][i] == 0 && !any_non_zero )
    1151             :             {
    1152       78900 :                 spar_start = add( spar_start, 1 );
    1153             :             }
    1154             :             ELSE
    1155             :             {
    1156       69500 :                 any_non_zero = 1;
    1157       69500 :                 move16();
    1158             :             }
    1159             : 
    1160      148400 :             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 );
    1161      148400 :             move32();
    1162             :         }
    1163       12500 :         pFb->fb_bin_to_band.p_spar_start_bands[j] = spar_start;
    1164       12500 :         move16();
    1165             :     }
    1166             : 
    1167         273 :     set32_fx( ppFilterbank_FRs_s_fx, 0, frame_len );
    1168             : 
    1169             :     /*Commented logic is for calculating number of active bands, can be removed if not needed */
    1170        3469 :     FOR( i = 0; i < bands; i++ )
    1171             :     {
    1172        3196 :         const Word32 *pFilterbank_bin_to_band_re_fx = pFb->fb_consts.ppFilterbank_FRs_fx[0][i]; // Q30
    1173        3196 :         move32();
    1174        3196 :         const Word32 *pFilterbank_bin_to_band_im_fx = pFb->fb_consts.ppFilterbank_FRs_fx[1][i]; // Q30
    1175        3196 :         move32();
    1176             : 
    1177        3196 :         Word16 start_offset = pFb->fb_consts.pFilterbank_bins_start_offset[i];
    1178        3196 :         move16();
    1179        3196 :         Word16 num_bins = pFb->fb_consts.pFilterbank_bins_per_band[i];
    1180        3196 :         move16();
    1181        3196 :         Word16 idx = 0;
    1182        3196 :         move16();
    1183        3196 :         Word16 abs_active_bins = pFb->fb_bin_to_band.pFb_active_bins_per_band[i];
    1184        3196 :         move16();
    1185        3196 :         Word16 abs_start_offset = pFb->fb_bin_to_band.pFb_start_bin_per_band[i];
    1186        3196 :         move16();
    1187             : 
    1188      966952 :         FOR( j = start_offset; j < num_bins + start_offset; j++ )
    1189             :         {
    1190      963756 :             Word32 temp_fx = 0;
    1191      963756 :             move32();
    1192             : 
    1193      963756 :             exp_diff = 0;
    1194      963756 :             move16();
    1195      963756 :             Word32 real = L_shr( *pFilterbank_bin_to_band_re_fx, 3 ); // Q27
    1196      963756 :             Word32 imag = L_shr( *pFilterbank_bin_to_band_im_fx, 3 ); // Q27
    1197             : 
    1198             :             Word32 real_sq, imag_sq;
    1199      963756 :             real_sq = Mpy_32_32( real, real ); // Q27 + Q27 - 31 = Q23
    1200      963756 :             imag_sq = Mpy_32_32( imag, imag ); // Q27 + Q27 - 31 = Q23
    1201             : 
    1202      963756 :             temp_fx = L_add( L_shr( real_sq, 1 ), L_shr( imag_sq, 1 ) ); // Q22
    1203             : 
    1204      963756 :             exp_diff = 9;
    1205      963756 :             move16();
    1206      963756 :             temp_fx = Sqrt32( temp_fx, &exp_diff );
    1207      963756 :             temp_fx = L_shl( temp_fx, sub( exp_diff, Q9 ) ); // Q22
    1208             : 
    1209             : 
    1210      963756 :             pFilterbank_bin_to_band_re_fx++;
    1211      963756 :             pFilterbank_bin_to_band_im_fx++;
    1212             : 
    1213      963756 :             temp_fx = L_sub( temp_fx, 1258291 ); // 0.3 in Q22
    1214      963756 :             move32();
    1215             : 
    1216      963756 :             if ( temp_fx < 0 )
    1217             :             {
    1218      691682 :                 temp_fx = 0;
    1219      691682 :                 move32();
    1220             :             }
    1221             : 
    1222      963756 :             test();
    1223      963756 :             test();
    1224      963756 :             IF( LT_16( j, add( abs_active_bins, abs_start_offset ) ) && GE_16( j, abs_start_offset ) && NE_16( alloc_fb_resp, -1 ) )
    1225             :             {
    1226           0 :                 pFb->fb_bin_to_band.pFb_bin_to_band_fx[i][idx] = temp_fx; // Q22
    1227           0 :                 move32();
    1228           0 :                 idx = add( idx, 1 );
    1229             :             }
    1230             : 
    1231             : 
    1232      963756 :             ppFilterbank_FRs_s_fx[j] = L_add( ppFilterbank_FRs_s_fx[j], temp_fx ); // Q22
    1233      963756 :             move32();
    1234             :         }
    1235             :     }
    1236             : 
    1237      200273 :     FOR( i = 0; i < frame_len; i++ )
    1238             :     {
    1239      200000 :         if ( ppFilterbank_FRs_s_fx[i] < 0 )
    1240             :         {
    1241           0 :             ppFilterbank_FRs_s_fx[i] = 419430; // 0.1 in Q22
    1242           0 :             move32();
    1243             :         }
    1244             :     }
    1245             : 
    1246         273 :     IF( NE_16( alloc_fb_resp, -1 ) )
    1247             :     {
    1248           0 :         FOR( j = 0; j < bands; j++ )
    1249             :         {
    1250           0 :             Word16 abs_active_bins = pFb->fb_bin_to_band.pFb_active_bins_per_band[j];
    1251           0 :             Word16 abs_start_offset = pFb->fb_bin_to_band.pFb_start_bin_per_band[j];
    1252           0 :             exp_diff = 0;
    1253             : 
    1254           0 :             move16();
    1255           0 :             move16();
    1256           0 :             move16();
    1257             : 
    1258           0 :             FOR( i = 0; i < abs_active_bins; i++ )
    1259             :             {
    1260           0 :                 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 );
    1261           0 :                 pFb->fb_bin_to_band.pFb_bin_to_band_fx[j][i] = L_shl( L_deposit_l( tmp ), add( Q7, exp_diff ) ); // Q22
    1262           0 :                 move32();
    1263             :                 /*if(pFb->fb_bin_to_band.pFb_bin_to_band[j][i] > 0.5f)
    1264             :                 {
    1265             :                     num_active_bands = j + 1;
    1266             :                     break;
    1267             :                 }*/
    1268             :             }
    1269             :         }
    1270             :     }
    1271             : 
    1272         273 :     return num_active_bands;
    1273             : }
    1274             : 
    1275             : /*-----------------------------------------------------------------------------------------*
    1276             :  * Function ivas_get_active_bins()
    1277             :  *
    1278             :  *
    1279             :  *-----------------------------------------------------------------------------------------*/
    1280             : 
    1281         546 : static void ivas_get_active_bins_fx(
    1282             :     const Word16 **pActive_bins,
    1283             :     const Word16 **pActive_bins_abs,
    1284             :     const Word16 **pStart_offset,
    1285             :     const Word16 **pStart_offset_abs,
    1286             :     const Word32 sampling_rate )
    1287             : {
    1288             :     Word16 sr_idx;
    1289             : 
    1290         546 :     IF( EQ_32( sampling_rate, 32000 ) )
    1291             :     {
    1292         228 :         sr_idx = 1;
    1293         228 :         move16();
    1294             :     }
    1295         318 :     ELSE IF( EQ_32( sampling_rate, 16000 ) )
    1296             :     {
    1297          80 :         sr_idx = 2;
    1298          80 :         move16();
    1299             :     }
    1300             :     ELSE
    1301             :     {
    1302         238 :         sr_idx = 0;
    1303         238 :         move16();
    1304             :     }
    1305             : 
    1306         546 :     *pActive_bins_abs = ivas_fb_abs_bins_per_band_12band_1ms[sr_idx];
    1307         546 :     move16();
    1308         546 :     *pActive_bins = ivas_fb_bins_per_band_12band_1ms[sr_idx];
    1309         546 :     move16();
    1310         546 :     *pStart_offset_abs = ivas_fb_abs_bins_start_offset_12band_1ms[sr_idx];
    1311         546 :     move16();
    1312         546 :     *pStart_offset = ivas_fb_bins_start_offset_12band_1ms[sr_idx];
    1313         546 :     move16();
    1314             : 
    1315         546 :     return;
    1316             : }
    1317             : 
    1318             : 
    1319             : /*-----------------------------------------------------------------------------------------*
    1320             :  * Function ivas_filterbank_setup()
    1321             :  *
    1322             :  * Filterbank setup, initialization
    1323             :  *-----------------------------------------------------------------------------------------*/
    1324             : 
    1325         273 : static ivas_error ivas_filterbank_setup_fx(
    1326             :     IVAS_FB_MIXER_HANDLE hFbMixer,
    1327             :     const Word32 sampling_rate,
    1328             :     Word16 *index )
    1329             : {
    1330             :     Word16 i, j, exp, tmp;
    1331             :     const Word32 *pAll_fb_fr_fx[2];
    1332         273 :     const Word16 *pAll_bins_start_offset = NULL;
    1333         273 :     const Word16 *pAll_bins_per_band = NULL;
    1334         273 :     const Word16 *pAll_bins_start_offset_abs = NULL;
    1335         273 :     const Word16 *pAll_bins_per_band_abs = NULL;
    1336         273 :     const Word16 *pAll_bins_per_band_48k = NULL;
    1337             :     ivas_error error;
    1338         273 :     IVAS_FB_CFG *pCfg = hFbMixer->fb_cfg;
    1339             : 
    1340         273 :     error = IVAS_ERR_OK;
    1341         273 :     move32();
    1342             : 
    1343         273 :     IF( pCfg->num_out_chans > 0 )
    1344             :     {
    1345         273 :         hFbMixer->pFb->filterbank_num_bands = ivas_get_num_bands( sampling_rate );
    1346         273 :         move16();
    1347             : 
    1348         273 :         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 );
    1349             : 
    1350         273 :         IF( EQ_16( pCfg->fb_latency, NS2SA_FX2( sampling_rate, DELAY_FB_1_NS ) ) )
    1351             :         {
    1352         273 :             pAll_fb_fr_fx[0] = ivas_fb_fr_12band_1ms_re_fx; // Q30
    1353         273 :             move32();
    1354         273 :             pAll_fb_fr_fx[1] = ivas_fb_fr_12band_1ms_im_fx; // Q30
    1355         273 :             move32();
    1356             : 
    1357         273 :             pAll_bins_per_band_48k = ivas_fb_bins_per_band_12band_1ms[0];
    1358         273 :             move16();
    1359             :         }
    1360             :         ELSE
    1361             :         {
    1362           0 :             return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Wrong FB in ivas_filterbank_setup()!" );
    1363             :         }
    1364             :     }
    1365             : 
    1366         273 :     hFbMixer->cross_fade_end_offset = add( pCfg->fade_len, pCfg->pcm_offset );
    1367         273 :     move16();
    1368         273 :     hFbMixer->cross_fade_start_offset = sub( hFbMixer->cross_fade_end_offset, pCfg->fade_len );
    1369         273 :     move16();
    1370         273 :     hFbMixer->ana_window_offset = add( pCfg->fb_latency, pCfg->pcm_offset );
    1371         273 :     move16();
    1372             : 
    1373         273 :     IF( NE_32( ( error = ivas_fb_mixer_get_window_fx( pCfg->fb_latency, sampling_rate, &( hFbMixer->pAna_window_fx ) ) ), IVAS_ERR_OK ) )
    1374             :     {
    1375           0 :         return error;
    1376             :     }
    1377             : 
    1378         273 :     IF( NE_32( ( error = ivas_fb_mixer_get_window_fx( pCfg->fade_len, sampling_rate, &( hFbMixer->pFilterbank_cross_fade_fx ) ) ), IVAS_ERR_OK ) )
    1379             :     {
    1380           0 :         return error;
    1381             :     }
    1382             : 
    1383         273 :     IF( pCfg->num_out_chans > 0 )
    1384             :     {
    1385         273 :         ivas_filterbank_t *pFb = hFbMixer->pFb;
    1386         273 :         Word16 offset = 0;
    1387         273 :         move16();
    1388             : 
    1389         273 :         pFb->fb_consts.pFilterbank_bins_per_band = pAll_bins_per_band;
    1390         273 :         pFb->fb_consts.pFilterbank_bins_start_offset = pAll_bins_start_offset;
    1391         273 :         pFb->fb_bin_to_band.pFb_active_bins_per_band = pAll_bins_per_band_abs;
    1392         273 :         pFb->fb_bin_to_band.pFb_start_bin_per_band = pAll_bins_start_offset_abs;
    1393             : 
    1394             :         /* Initialization for short stride Parameter calculation and SPAR CLDFB reconstruction */
    1395         273 :         SWITCH( sampling_rate )
    1396             :         {
    1397         119 :             case 48000:
    1398         119 :                 pFb->fb_bin_to_band.num_cldfb_bands = 60; /* sampling_rate * 1.0f / 800.0f  */
    1399         119 :                 move16();
    1400         119 :                 BREAK;
    1401         114 :             case 32000:
    1402         114 :                 pFb->fb_bin_to_band.num_cldfb_bands = 40;
    1403         114 :                 move16();
    1404         114 :                 BREAK;
    1405          40 :             case 16000:
    1406          40 :                 pFb->fb_bin_to_band.num_cldfb_bands = 20;
    1407          40 :                 move16();
    1408          40 :                 BREAK;
    1409             :         }
    1410             : 
    1411             :         /*pFb->fb_bin_to_band.cldfb_stride = ( int16_t )( ( sampling_rate / FRAMES_PER_SEC ) / CLDFB_NO_COL_MAX );*/ /* equals num_cldfb_bands*/
    1412             :         // pFb->fb_bin_to_band.short_stride = extract_l( ( sampling_rate / FRAMES_PER_SEC ) / 4 );
    1413         273 :         tmp = BASOP_Util_Divide3232_Scale( sampling_rate, FRAMES_PER_SEC, &exp );
    1414         273 :         pFb->fb_bin_to_band.short_stride = shr( tmp, add( sub( 15, exp ), 2 ) );
    1415             : 
    1416         273 :         move16();
    1417             : 
    1418         273 :         set32_fx( pFb->fb_bin_to_band.p_short_stride_bin_to_band_fx, 0, 2 * MDFT_FB_BANDS_240 );
    1419             : 
    1420         273 :         set16_fx( pFb->fb_bin_to_band.p_cldfb_map_to_spar_band, 0, CLDFB_NO_CHANNELS_MAX );
    1421         273 :         set16_fx( pFb->fb_bin_to_band.p_spar_start_bands, 0, CLDFB_NO_CHANNELS_MAX );
    1422             : 
    1423        5733 :         FOR( j = 0; j < IVAS_MAX_NUM_FB_BANDS; j++ )
    1424             :         {
    1425        5460 :             pFb->fb_bin_to_band.p_short_stride_num_bins_per_band[j] = 0; /* aka num_active_bins per SPAR band */
    1426        5460 :             move16();
    1427        5460 :             pFb->fb_bin_to_band.p_short_stride_start_bin_per_band[j] = 0; /* first considered bin index per SPAR band */
    1428        5460 :             move16();
    1429             : 
    1430        5460 :             pFb->fb_bin_to_band.pp_short_stride_bin_to_band_fx[j] = NULL;
    1431             : 
    1432      333060 :             FOR( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ )
    1433             :             {
    1434             : 
    1435      327600 :                 pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band_fx[i][j] = 0;
    1436      327600 :                 move32();
    1437             :             }
    1438             :         }
    1439         273 :         IF( EQ_32( sampling_rate, 48000 ) )
    1440             :         {
    1441        1547 :             FOR( j = 0; j < pFb->filterbank_num_bands; j++ )
    1442             :             {
    1443             : 
    1444        1428 :                 pFb->fb_consts.ppFilterbank_FRs_fx[0][j] = &pAll_fb_fr_fx[0][offset]; // Q30
    1445        1428 :                 pFb->fb_consts.ppFilterbank_FRs_fx[1][j] = &pAll_fb_fr_fx[1][offset]; // Q30
    1446             : 
    1447        1428 :                 offset = add( offset, pFb->fb_consts.pFilterbank_bins_per_band[j] );
    1448             :             }
    1449             : 
    1450             :             /****************************************Calculate abs fr ***************************/
    1451             : 
    1452         119 :             ivas_calculate_abs_fr_fx( pFb, sampling_rate, pCfg->active_w_mixing, index );
    1453             :         }
    1454             :         ELSE
    1455             :         {
    1456             : 
    1457             :             Word32 *ppFilterbank_FRs_re_temp_fx[MAX_NUM_BANDS_DIFF_NON48K];
    1458             :             Word32 *ppFilterbank_FRs_im_temp_fx[MAX_NUM_BANDS_DIFF_NON48K];
    1459             :             Word16 active_bins_temp[MAX_NUM_BANDS_DIFF_NON48K];
    1460             :             Word16 start_offset_temp[MAX_NUM_BANDS_DIFF_NON48K];
    1461             :             Word16 num_diff_bands, start_diff_band_non48k;
    1462             : 
    1463         154 :             num_diff_bands = MAX_NUM_BANDS_DIFF_NON48K;
    1464         154 :             start_diff_band_non48k = sub( pFb->filterbank_num_bands, num_diff_bands );
    1465         154 :             move16();
    1466             : 
    1467         154 :             pFb->fb_consts.pFilterbank_bins_per_band = pAll_bins_per_band;
    1468         154 :             pFb->fb_consts.pFilterbank_bins_start_offset = pAll_bins_start_offset;
    1469             : 
    1470        1922 :             FOR( j = 0; j < pFb->filterbank_num_bands; j++ )
    1471             :             {
    1472        1768 :                 Word16 num_active_bins = pFb->fb_consts.pFilterbank_bins_per_band[j];
    1473        1768 :                 move16();
    1474             : 
    1475        1768 :                 IF( j < start_diff_band_non48k )
    1476             :                 {
    1477             : 
    1478        1306 :                     pFb->fb_consts.ppFilterbank_FRs_fx[0][j] = &pAll_fb_fr_fx[0][offset]; // Q30
    1479        1306 :                     pFb->fb_consts.ppFilterbank_FRs_fx[1][j] = &pAll_fb_fr_fx[1][offset]; // Q30
    1480             :                 }
    1481             :                 ELSE
    1482             :                 {
    1483         462 :                     Copy32( &pAll_fb_fr_fx[0][offset], pFb->fb_consts.ppFilterbank_FRs_non48k_fx[0][j], num_active_bins ); // Q30
    1484         462 :                     Copy32( &pAll_fb_fr_fx[1][offset], pFb->fb_consts.ppFilterbank_FRs_non48k_fx[1][j], num_active_bins ); // Q30
    1485             :                 }
    1486             : 
    1487        1768 :                 offset = add( offset, pAll_bins_per_band_48k[j] );
    1488             :             }
    1489             : 
    1490         616 :             FOR( j = start_diff_band_non48k; j < pFb->filterbank_num_bands; j++ )
    1491             :             {
    1492             : 
    1493         462 :                 ppFilterbank_FRs_re_temp_fx[j - start_diff_band_non48k] = pFb->fb_consts.ppFilterbank_FRs_non48k_fx[0][j]; // Q30
    1494         462 :                 ppFilterbank_FRs_im_temp_fx[j - start_diff_band_non48k] = pFb->fb_consts.ppFilterbank_FRs_non48k_fx[1][j]; // Q30
    1495             : 
    1496         462 :                 active_bins_temp[j - start_diff_band_non48k] = pFb->fb_consts.pFilterbank_bins_per_band[j];
    1497         462 :                 start_offset_temp[j - start_diff_band_non48k] = pFb->fb_consts.pFilterbank_bins_start_offset[j];
    1498         462 :                 move16();
    1499         462 :                 move16();
    1500             :             }
    1501             : 
    1502         154 :             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,
    1503         154 :                                     active_bins_temp, start_offset_temp, num_diff_bands, pCfg->fb_latency, sampling_rate );
    1504             : 
    1505             : 
    1506         616 :             FOR( j = start_diff_band_non48k; j < pFb->filterbank_num_bands; j++ )
    1507             :             {
    1508             : 
    1509         462 :                 pFb->fb_consts.ppFilterbank_FRs_fx[0][j] = (const Word32 *) pFb->fb_consts.ppFilterbank_FRs_non48k_fx[0][j]; // Q30
    1510         462 :                 pFb->fb_consts.ppFilterbank_FRs_fx[1][j] = (const Word32 *) pFb->fb_consts.ppFilterbank_FRs_non48k_fx[1][j]; // Q30
    1511             :             }
    1512             : 
    1513             :             /******************************************** Calculate abs fr ****************************************************/
    1514             : 
    1515         154 :             ivas_calculate_abs_fr_fx( pFb, sampling_rate, pCfg->active_w_mixing, index );
    1516             :         }
    1517             :     }
    1518             : 
    1519         273 :     return error;
    1520             : }
    1521             : 
    1522             : /*-----------------------------------------------------------------------------------------*
    1523             :  * Function ivas_fb_mixer_get_window()
    1524             :  *
    1525             :  *
    1526             :  *-----------------------------------------------------------------------------------------*/
    1527             : 
    1528         546 : static ivas_error ivas_fb_mixer_get_window_fx(
    1529             :     const Word16 fade_len,      /* i  : window fading length in samples    */
    1530             :     const Word32 sampling_rate, /* i  : sampling rate                      */
    1531             :     const Word16 **pWindow      /* o  : pointer to the window coefficents  */
    1532             : )
    1533             : {
    1534             :     ivas_error error;
    1535             : 
    1536         546 :     error = IVAS_ERR_OK;
    1537         546 :     move32();
    1538             : 
    1539         546 :     IF( EQ_16( fade_len, NS2SA_FX2( sampling_rate, DELAY_FB_4_NS ) ) )
    1540             :     {
    1541         273 :         SWITCH( sampling_rate )
    1542             :         {
    1543         119 :             case 48000:
    1544         119 :                 *pWindow = ivas_fb_cf_4ms_48k_fx;
    1545         119 :                 BREAK;
    1546         114 :             case 32000:
    1547         114 :                 *pWindow = ivas_fb_cf_4ms_32k_fx;
    1548         114 :                 BREAK;
    1549          40 :             case 16000:
    1550          40 :                 *pWindow = ivas_fb_cf_4ms_16k_fx;
    1551          40 :                 BREAK;
    1552           0 :             default:
    1553           0 :                 return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Unsupported Sampling frequency!" );
    1554             :         }
    1555             :     }
    1556         273 :     ELSE IF( EQ_16( fade_len, NS2SA_FX2( sampling_rate, DELAY_FB_1_NS ) ) )
    1557             :     {
    1558         273 :         SWITCH( sampling_rate )
    1559             :         {
    1560         119 :             case 48000:
    1561         119 :                 *pWindow = ivas_fb_cf_1ms_48k_fx;
    1562         119 :                 BREAK;
    1563         114 :             case 32000:
    1564         114 :                 *pWindow = ivas_fb_cf_1ms_32k_fx;
    1565         114 :                 BREAK;
    1566          40 :             case 16000:
    1567          40 :                 *pWindow = ivas_fb_cf_1ms_16k_fx;
    1568          40 :                 BREAK;
    1569           0 :             default:
    1570           0 :                 return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Unsupported Sampling frequency!" );
    1571             :         }
    1572             :     }
    1573             :     ELSE
    1574             :     {
    1575           0 :         IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error: Incorrect FB window fade len (%f ms)\n", ( fade_len / 1000000.f ) );
    1576             :     }
    1577             : 
    1578         546 :     return error;
    1579             : }
    1580             : 
    1581             : 
    1582         154 : static const Word32 *ivas_get_cheby_ramp_fx(
    1583             :     const Word16 delay )
    1584             : {
    1585         154 :     const Word32 *pCheby_fx = NULL;
    1586             : 
    1587         154 :     SWITCH( delay )
    1588             :     {
    1589         114 :         case IVAS_FB_1MS_32K_SAMP:
    1590         114 :             pCheby_fx = ivas_fb_resp_cheby_ramp_32del_fx;
    1591         114 :             BREAK;
    1592          40 :         case IVAS_FB_1MS_16K_SAMP:
    1593          40 :             pCheby_fx = ivas_fb_resp_cheby_ramp_16del_fx;
    1594          40 :             BREAK;
    1595           0 :         default:
    1596           0 :             assert( !"Unsupported cheby ramp length!" );
    1597             :     }
    1598             : 
    1599         154 :     return pCheby_fx;
    1600             : }
    1601             : 
    1602         154 : static void ivas_get_ld_fb_resp_fx(
    1603             :     Word32 **ppIdeal_FRs_re_fx, // i: Q30
    1604             :     Word32 **ppIdeal_FRs_im_fx, // i: Q30
    1605             :     Word32 **ppNew_FRs_re_fx,   // o: Q30
    1606             :     Word32 **ppNew_FRs_im_fx,   // o: Q30
    1607             :     const Word16 *pActive_bins,
    1608             :     const Word16 *pStart_offset,
    1609             :     const Word16 num_bands,
    1610             :     const Word16 delay,
    1611             :     const Word32 sampling_rate )
    1612             : {
    1613             :     Word16 b, s, frame_len;
    1614             :     const Word32 *pCheby_fx;
    1615         154 :     frame_len = 0;
    1616         154 :     move16();
    1617             :     /*common scratch buffers for computing impulse/frequency responses,
    1618             :     pre-ring, post-ring and circular shifted outputs to optimize stack*/
    1619             :     Word32 scratch1_fx[L_FRAME32k * 2];
    1620             :     Word32 scratch2_fx[L_FRAME32k * 2];
    1621             : 
    1622         154 :     set32_fx( scratch1_fx, 0, L_FRAME32k * 2 );
    1623         154 :     set32_fx( scratch2_fx, 0, L_FRAME32k * 2 );
    1624             : 
    1625         154 :     const Word32 *han_win_fx = NULL;
    1626             : 
    1627         154 :     SWITCH( sampling_rate )
    1628             :     {
    1629           0 :         case 48000:
    1630           0 :             frame_len = 960;
    1631           0 :             move16();
    1632           0 :             han_win_fx = ivas_han_win_48k_fx; // Q31
    1633           0 :             BREAK;
    1634         114 :         case 32000:
    1635         114 :             frame_len = 640;
    1636         114 :             move16();
    1637         114 :             han_win_fx = ivas_han_win_32k_fx; // Q31
    1638         114 :             BREAK;
    1639          40 :         case 16000:
    1640          40 :             frame_len = 320;
    1641          40 :             move16();
    1642          40 :             han_win_fx = ivas_han_win_16k_fx; // Q31
    1643          40 :             BREAK;
    1644             :     }
    1645             : 
    1646         154 :     pCheby_fx = ivas_get_cheby_ramp_fx( delay ); // Q31
    1647             : 
    1648         154 :     b = 0;
    1649         154 :     s = 0;
    1650         154 :     move16();
    1651         154 :     move16();
    1652             : 
    1653         154 :     assert( sampling_rate == 32000 || sampling_rate == 16000 );
    1654             : 
    1655         616 :     FOR( b = 0; b < num_bands; b++ )
    1656             :     {
    1657             : 
    1658         462 :         set32_fx( scratch2_fx, 0, shl( frame_len, 1 ) );
    1659         462 :         Copy32( ppIdeal_FRs_re_fx[b], &scratch2_fx[pStart_offset[b]], pActive_bins[b] );             // Q30
    1660         462 :         Copy32( ppIdeal_FRs_im_fx[b], &scratch2_fx[frame_len + pStart_offset[b]], pActive_bins[b] ); // Q30
    1661             : 
    1662         462 :         Word16 guard_bits = sub( L_norm_arr( scratch2_fx, shl( L_FRAME32k, 1 ) ), find_guarded_bits_fx( shl( frame_len, 1 ) ) );
    1663         462 :         Scale_sig32( scratch2_fx, shl( L_FRAME32k, 1 ), guard_bits ); // Q30 + guard_bits
    1664             : 
    1665         462 :         ivas_imdft_fx( scratch2_fx, &scratch2_fx[frame_len], scratch1_fx, frame_len );
    1666             : 
    1667      591822 :         FOR( Word16 x = 0; x < shl( L_FRAME32k, 1 ); x++ )
    1668             :         {
    1669      591360 :             scratch2_fx[x] = L_shr( scratch2_fx[x], guard_bits ); // (Q30 + guard_bits) - guard_bits = Q30
    1670      591360 :             scratch1_fx[x] = L_shr( scratch1_fx[x], guard_bits ); // (Q30 + guard_bits) - guard_bits = Q30
    1671             : 
    1672      591360 :             move32();
    1673      591360 :             move32();
    1674             :         }
    1675             : 
    1676             :         /*apply circular shift and hanning window*/
    1677             : 
    1678      257742 :         FOR( s = delay; s < frame_len + delay; s++ )
    1679             :         {
    1680             : 
    1681      257280 :             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
    1682      257280 :             move32();
    1683             :         }
    1684             : 
    1685      244878 :         FOR( ; s < 2 * frame_len; s++ )
    1686             :         {
    1687             : 
    1688      244416 :             scratch2_fx[s - delay] = Mpy_32_32( scratch1_fx[s], han_win_fx[s - ( frame_len + delay )] ); // Q30
    1689      244416 :             move32();
    1690             :         }
    1691             : 
    1692       13326 :         FOR( s = 0; s < delay; s++ )
    1693             :         {
    1694             : 
    1695       12864 :             scratch2_fx[( ( ( frame_len * 2 ) - delay ) + s )] = L_negate( Mpy_32_32( scratch1_fx[s], han_win_fx[( frame_len - delay ) + s] ) ); // Q30
    1696       12864 :             move32();
    1697             :         }
    1698             : 
    1699             :         /*apply heavy/cheby ramp window and compute pre ring*/
    1700             : 
    1701       13788 :         FOR( s = 0; s < delay + 1; s++ )
    1702             :         {
    1703       13326 :             scratch1_fx[s] = Mpy_32_32( scratch2_fx[s], pCheby_fx[delay - s] ); // Q30
    1704       13326 :             move32();
    1705             :         }
    1706             : 
    1707      244416 :         FOR( ; s < frame_len; s++ )
    1708             :         {
    1709      243954 :             scratch1_fx[s] = 0;
    1710      243954 :             move32();
    1711             :         }
    1712             : 
    1713      244878 :         FOR( ; s < 2 * frame_len - delay; s++ )
    1714             :         {
    1715      244416 :             scratch1_fx[s] = scratch2_fx[s];
    1716      244416 :             move32();
    1717             :         }
    1718             : 
    1719       13326 :         FOR( ; s < 2 * frame_len; s++ )
    1720             :         {
    1721       12864 :             scratch1_fx[s] = Mpy_32_32( scratch2_fx[s], L_sub( ONE_IN_Q31, pCheby_fx[s - ( 2 * frame_len - delay )] ) ); // Q30
    1722       12864 :             move32();
    1723             :         }
    1724             : 
    1725             :         /*IR - pre ring + post ring*/
    1726      514560 :         FOR( s = 1; s < 2 * frame_len; s++ )
    1727             :         {
    1728      514098 :             scratch2_fx[s] = L_sub( L_sub( scratch2_fx[s] /*pre ring*/, scratch1_fx[s] /*post ring*/ ), scratch1_fx[frame_len * 2 - s] );
    1729      514098 :             move32();
    1730             :         }
    1731             : 
    1732      502158 :         FOR( s = 0; s < 2 * frame_len - delay; s++ )
    1733             :         {
    1734      501696 :             scratch1_fx[s + delay] = scratch2_fx[s];
    1735      501696 :             move32();
    1736             :         }
    1737             : 
    1738       13326 :         FOR( ; s < 2 * frame_len; s++ )
    1739             :         {
    1740       12864 :             scratch1_fx[( s - ( ( frame_len * 2 ) - delay ) )] = L_negate( scratch2_fx[s] );
    1741       12864 :             move32();
    1742             :         }
    1743             : 
    1744             :         /* apply final window*/
    1745         462 :         const Word32 *sine_till_delay = ivas_sine_delay_32_fx; // Q30
    1746         462 :         Word16 offset = 1;
    1747         462 :         Word16 delay_16 = 0;
    1748             : 
    1749         462 :         move16();
    1750         462 :         move16();
    1751             : 
    1752         462 :         if ( EQ_16( delay, IVAS_FB_1MS_16K_SAMP ) )
    1753             :         {
    1754         120 :             delay_16 = 1;
    1755         120 :             move16();
    1756             :         }
    1757             : 
    1758       13326 :         FOR( s = 0; s < delay; s++ )
    1759             :         {
    1760       12864 :             scratch1_fx[s] = Mpy_32_32( scratch1_fx[s], sine_till_delay[s + offset * delay_16] ); // Q30 + Q30 - 31 = Q29
    1761       12864 :             offset = add( offset, 1 );
    1762       12864 :             scratch1_fx[s] = L_shl( scratch1_fx[s], 1 ); // Q30
    1763             : 
    1764       12864 :             move32();
    1765       12864 :             move32();
    1766             :         }
    1767             : 
    1768         462 :         const Word32 *sine_till_frame_len = NULL;
    1769             : 
    1770         462 :         IF( EQ_16( delay, IVAS_FB_1MS_16K_SAMP ) )
    1771             :         {
    1772         120 :             sine_till_frame_len = ivas_sine_frame_len_640_del_16_fx; // Q30
    1773         120 :             move32();
    1774             :         }
    1775             :         ELSE
    1776             :         {
    1777         342 :             sine_till_frame_len = ivas_sine_frame_len_640_del_32_fx; // Q30
    1778         342 :             move32();
    1779             :         }
    1780         462 :         Word16 iterator = 0;
    1781         462 :         move16();
    1782      232476 :         FOR( s = 2 * delay; s < frame_len + 1; s++ )
    1783             :         {
    1784      232014 :             scratch1_fx[s] = Mpy_32_32( scratch1_fx[s], sine_till_frame_len[iterator] ); // Q30 + Q30 - 31 = Q29
    1785      232014 :             iterator = add( iterator, 1 );
    1786      232014 :             scratch1_fx[s] = L_shl( scratch1_fx[s], 1 ); // Q30
    1787             : 
    1788      232014 :             move32();
    1789      232014 :             move32();
    1790             :         }
    1791             : 
    1792      257280 :         FOR( ; s < 2 * frame_len; s++ )
    1793             :         {
    1794      256818 :             scratch1_fx[s] = 0;
    1795             : 
    1796      256818 :             move32();
    1797             :         }
    1798             : 
    1799             :         /*compute frequency response*/
    1800         462 :         ivas_mdft_fx( scratch1_fx, scratch2_fx, &scratch2_fx[frame_len], shl( frame_len, 1 ), frame_len );
    1801             : 
    1802         462 :         Copy32( &scratch2_fx[pStart_offset[b]], ppNew_FRs_re_fx[b], pActive_bins[b] );                 // Q30
    1803         462 :         Copy32( &scratch2_fx[( frame_len + pStart_offset[b] )], ppNew_FRs_im_fx[b], pActive_bins[b] ); // Q30
    1804             :     }
    1805             : 
    1806         154 :     return;
    1807             : }

Generated by: LCOV version 1.14