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

Generated by: LCOV version 1.14