LCOV - code coverage report
Current view: top level - lib_enc - ivas_stereo_mdct_stereo_enc_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ e95243e9e67ddeb69dddf129509de1b3d95b402e Lines: 580 598 97.0 %
Date: 2025-09-14 03:13:15 Functions: 17 17 100.0 %

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : #include <assert.h>
      34             : #include <stdint.h>
      35             : #include "options.h"
      36             : #include <math.h>
      37             : #include "ivas_cnst.h"
      38             : #include "ivas_prot_fx.h"
      39             : #include "prot_fx.h"
      40             : #include "prot_fx_enc.h"
      41             : #include "ivas_rom_com.h"
      42             : #include "ivas_rom_com_fx.h"
      43             : #include "ivas_rom_enc.h"
      44             : #include "wmc_auto.h"
      45             : #include "stat_enc.h"
      46             : 
      47             : 
      48             : /*-------------------------------------------------------------------*
      49             :  * Local constants
      50             :  *-------------------------------------------------------------------*/
      51             : 
      52             : #define OFFSET_BITS_TCX20 126
      53             : #define OFFSET_BITS_TCX10 222
      54             : 
      55             : 
      56             : /*-------------------------------------------------------------------*
      57             :  * Local function prototypes
      58             :  *-------------------------------------------------------------------*/
      59             : 
      60             : static void convertToBwMS_fx( const Word16 startLine, const Word16 stopLine, Word32 x0[], Word32 x1[], const Word32 norm_fac );
      61             : 
      62             : void convertToMS_fx( const Word16 L_frame, Word32 x0_fx[], Word32 x1_fx[], const Word32 norm_fac );
      63             : 
      64             : static Word16 GetChannelEnergyRatio_fx( Encoder_State **st, const Word16 iFirstSubframe, const Word16 iLastSubframe, const UWord8 ratioInRmsDomain );
      65             : 
      66             : static void MsStereoDecision_fx( STEREO_MDCT_BAND_PARAMETERS *sfbParam, Word32 *specL_fx, Word32 *specR_fx, Word32 *specM_fx, Word32 *specS_fx, Word16 q_spec, Word16 *mdct_stereo_mode, Word16 *msMask, const Word16 nBitsAvailable );
      67             : 
      68             : 
      69             : /*-------------------------------------------------------------------*
      70             :  * dft_ana_init()
      71             :  *
      72             :  * Initialization function for dft analysis handle within
      73             :  * MDCT-stereo
      74             :  *-------------------------------------------------------------------*/
      75             : 
      76         151 : static void dft_ana_init_fx(
      77             :     DFT_ANA_HANDLE hDft_ana, /*i  : DFT analysis handle         */
      78             :     const Word32 input_Fs    /*i  : Input sampling frequency    Q0*/
      79             : )
      80             : {
      81         151 :     hDft_ana->N = extract_l( Mpy_32_16_1( input_Fs, 656 /* STEREO_DFT_HOP_MAX_ENC / 48000 in Q15 */ ) );
      82         151 :     move16();
      83         151 :     hDft_ana->NFFT = extract_l( Mpy_32_16_1( input_Fs, 1311 /* STEREO_DFT_N_MAX_ENC / 48000 in Q15 */ ) );
      84         151 :     move16();
      85         151 :     hDft_ana->dft_ovl = extract_l( Mpy_32_16_1( input_Fs, 287 /* STEREO_DFT_OVL_MAX / 48000 in Q15 */ ) );
      86         151 :     move16();
      87         151 :     hDft_ana->dft_zp = extract_l( Mpy_32_16_1( input_Fs, 185 /* STEREO_DFT_ZP_MAX_ENC / 48000 in Q15 */ ) );
      88         151 :     move16();
      89             : 
      90         151 :     hDft_ana->dft_trigo_32k_fx = dft_trigo_32k_fx; /* Q15 */
      91             : 
      92         151 :     IF( EQ_32( input_Fs, 16000 ) )
      93             :     {
      94           5 :         hDft_ana->dft_trigo_fx = dft_trigo_32k_fx; /* Q15 */
      95           5 :         hDft_ana->dft_trigo_step = STEREO_DFT_TRIGO_SRATE_16k_STEP;
      96           5 :         move16();
      97           5 :         hDft_ana->win_ana_fx = win_ana_16k_fx; /* Q15 */
      98             :     }
      99         146 :     ELSE IF( EQ_32( input_Fs, 32000 ) )
     100             :     {
     101          59 :         hDft_ana->dft_trigo_fx = dft_trigo_32k_fx; /* Q15 */
     102          59 :         hDft_ana->dft_trigo_step = STEREO_DFT_TRIGO_SRATE_32k_STEP;
     103          59 :         move16();
     104          59 :         hDft_ana->win_ana_fx = win_ana_32k_fx; /* Q15 */
     105             :     }
     106             :     ELSE
     107             :     {
     108          87 :         assert( input_Fs == 48000 );
     109          87 :         hDft_ana->dft_trigo_fx = dft_trigo_48k_fx; /* Q15 */
     110          87 :         hDft_ana->dft_trigo_step = STEREO_DFT_TRIGO_SRATE_48k_STEP;
     111          87 :         move16();
     112          87 :         hDft_ana->win_ana_fx = win_ana_48k_fx; /* Q15 */
     113             :     }
     114             : 
     115         151 :     return;
     116             : }
     117             : 
     118             : 
     119             : /*-------------------------------------------------------------------*
     120             :  * write_itd_data()
     121             :  *
     122             :  * Bitstream writing of ITDs
     123             :  *-------------------------------------------------------------------*/
     124             : 
     125       11750 : static void write_itd_data_fx(
     126             :     ITD_DATA_HANDLE hItd, /* i  : ITD data handle     */
     127             :     BSTR_ENC_HANDLE hBstr /* i/o: bitstream handle    */
     128             : )
     129             : {
     130             :     Word16 k_offset;
     131             :     Word16 itd;
     132             : 
     133       11750 :     k_offset = 1;
     134       11750 :     move16();
     135             : 
     136       11750 :     push_next_indice( hBstr, ( hItd->itd_fx[k_offset] != 0 ), STEREO_DFT_ITD_MODE_NBITS );
     137             : 
     138       11750 :     IF( hItd->itd_fx[k_offset] != 0 )
     139             :     {
     140        3549 :         itd = hItd->itd_index[k_offset]; /* Q0 */
     141        3549 :         IF( GT_16( itd, 255 ) )
     142             :         {
     143        2391 :             itd = sub( itd, 256 );
     144             : 
     145        2391 :             IF( LT_16( itd, 20 ) )
     146             :             {
     147        1620 :                 push_next_indice( hBstr, 1, 1 ); /* use Huffman*/
     148        1620 :                 push_next_indice( hBstr, 1, 1 ); /* negative */
     149        1620 :                 push_next_indice( hBstr, dft_code_itd[itd], dft_len_itd[itd] );
     150             :             }
     151             :             ELSE
     152             :             {
     153         771 :                 push_next_indice( hBstr, 0, 1 ); /* don't use Huffman */
     154         771 :                 push_next_indice( hBstr, 1, 1 ); /* negative */
     155         771 :                 push_next_indice( hBstr, itd, STEREO_DFT_ITD_NBITS - 1 );
     156             :             }
     157             :         }
     158             :         ELSE
     159             :         {
     160        1158 :             IF( LT_16( itd, 20 ) )
     161             :             {
     162         886 :                 push_next_indice( hBstr, 1, 1 ); /* use Huffman*/
     163         886 :                 push_next_indice( hBstr, 0, 1 ); /* positive */
     164         886 :                 push_next_indice( hBstr, dft_code_itd[itd], dft_len_itd[itd] );
     165             :             }
     166             :             ELSE
     167             :             {
     168             :                 /* don't use Huffman and positive*/
     169         272 :                 push_next_indice( hBstr, itd, STEREO_DFT_ITD_NBITS + 1 );
     170             :             }
     171             :         }
     172             :     }
     173       11750 :     return;
     174             : }
     175             : 
     176             : /*-------------------------------------------------------------------*
     177             :  * stereo_coder_tcx()
     178             :  *
     179             :  *
     180             :  *-------------------------------------------------------------------*/
     181             : 
     182      139819 : void stereo_coder_tcx_fx(
     183             :     STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: Stereo MDCT encoder structure   */
     184             :     Encoder_State **sts,                     /* i/o: encoder state structure         */
     185             :     Word16 ms_mask[NB_DIV][MAX_SFB],         /* i  : bandwise MS mask                Q0*/
     186             :     Word32 *mdst_spectrum_fx[CPE_CHANNELS][NB_DIV],
     187             :     /* i/o: MDST spectrum                   */ // Q( q_spec ) (same as spectrum buffer in hTcxEnc)
     188             :     Word32 *inv_spectrum_fx[CPE_CHANNELS][NB_DIV],
     189             :     /* i/o: inverse spectrum                */ // Q( q_spec ) (same as spectrum buffer in hTcxEnc)
     190             :     Word32 *inv_mdst_spectrum_fx[CPE_CHANNELS][NB_DIV],
     191             :     /* i/o: inverse MDST spectrum           */ // Q( q_spec ) (same as spectrum buffer in hTcxEnc)
     192             :     const Word16 mct_on,                       /* i  : flag mct block (1) or stereo (0)  Q0*/
     193             :     Word16 exp_spec,
     194             :     Word16 exp_mdct_spec )
     195             : {
     196      139819 :     STEREO_MDCT_BAND_PARAMETERS *sfbConf = NULL;
     197             :     Word32 nrgRatio_fx[CPE_CHANNELS];
     198             :     Word16 nrgRatio_e[CPE_CHANNELS];
     199             :     Word16 nonQNrgRatio_fx[CPE_CHANNELS]; // Q15
     200             :     Word16 k;
     201             :     Word16 nSubframes, L_frameTCX;
     202             :     Word16 nAvailBitsMS[NB_DIV];
     203             :     Word16 tmp, e_tmp;
     204      139819 :     push_wmops( "stereo_coder_tcx" );
     205             : 
     206             : 
     207      139819 :     set16_fx( nAvailBitsMS, 0, NB_DIV );
     208             : 
     209      139819 :     nSubframes = ( sts[0]->core == TCX_20_CORE && sts[1]->core == TCX_20_CORE ) ? 1 : NB_DIV;
     210      139819 :     L_frameTCX = idiv1616( sts[0]->hTcxEnc->L_frameTCX, nSubframes );
     211             : 
     212      139819 :     set16_fx( &ms_mask[0][0], 0, MAX_SFB );
     213      139819 :     set16_fx( &ms_mask[1][0], 0, MAX_SFB );
     214             : 
     215      139819 :     IF( !mct_on )
     216             :     {
     217       42785 :         IF( EQ_16( sts[0]->core, sts[1]->core ) )
     218             :         {
     219       86188 :             FOR( k = 0; k < nSubframes; k++ )
     220             :             {
     221       43667 :                 nonQNrgRatio_fx[k] = GetChannelEnergyRatio_fx( sts, k, k, 1 ); // Q15
     222       43667 :                 move16();
     223             : 
     224       43667 :                 hStereoMdct->global_ild[k] = s_max( 1, s_min( SMDCT_ILD_RANGE - 1, round_fx( L_mult( SMDCT_ILD_RANGE, nonQNrgRatio_fx[k] ) ) ) );
     225       43667 :                 move16();
     226       43667 :                 nrgRatio_fx[k] = L_deposit_h( BASOP_Util_Divide1616_Scale( sub( SMDCT_ILD_RANGE, hStereoMdct->global_ild[k] ), hStereoMdct->global_ild[k], &nrgRatio_e[k] ) ); /* Q31-nrgRatio_e[k] */
     227       43667 :                 move32();
     228             :                 /*nonQNrgRatio[k] = max( 0.5f / SMDCT_ILD_RANGE, min( ( SMDCT_ILD_RANGE - 0.5f ) / SMDCT_ILD_RANGE, nonQNrgRatio[k] ) );
     229             :                 nonQNrgRatio[k] = 1.0f / nonQNrgRatio[k] - 1.0f;*/
     230             :                 // Not getting used further
     231             :             }
     232             :         }
     233             :         ELSE
     234             :         {
     235         264 :             nonQNrgRatio_fx[0] = nonQNrgRatio_fx[1] = GetChannelEnergyRatio_fx( sts, 0, nSubframes - 1, 1 ); /* Q15 */
     236         264 :             move16();
     237         264 :             hStereoMdct->global_ild[0] = s_max( 1, s_min( SMDCT_ILD_RANGE - 1, round_fx( L_mult( SMDCT_ILD_RANGE, nonQNrgRatio_fx[0] ) ) ) );
     238         264 :             move16();
     239         264 :             nrgRatio_fx[0] = nrgRatio_fx[1] = L_deposit_h( BASOP_Util_Divide1616_Scale( sub( SMDCT_ILD_RANGE, hStereoMdct->global_ild[0] ), hStereoMdct->global_ild[0], &nrgRatio_e[0] ) ); /* nrgRatio = nrg[1]/nrg[0] (Q31-nrgRatio_e[0])*/
     240         264 :             move32();
     241         264 :             nrgRatio_e[1] = nrgRatio_e[0];
     242         264 :             move16();
     243             :             /*nonQNrgRatio[0] = nonQNrgRatio[1] = max( 0.5f / SMDCT_ILD_RANGE, min( ( SMDCT_ILD_RANGE - 0.5f ) / SMDCT_ILD_RANGE, nonQNrgRatio[0] ) );
     244             :             nonQNrgRatio[0] = nonQNrgRatio[1] = 1.0f / nonQNrgRatio[0] - 1.0f;*/
     245             :             // Not getting used further
     246             :         }
     247             : 
     248       86980 :         FOR( k = 0; k < nSubframes; k++ )
     249             :         {
     250       44195 :             IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( nrgRatio_fx[k], nrgRatio_e[k], ONE_IN_Q27, 4 ), 1 ) && LT_16( k, ( EQ_16( sts[1]->core, TCX_20_CORE ) ? 1 : NB_DIV ) ) )
     251             :             {
     252       21443 :                 L_frameTCX = add( sts[1]->hTcxEnc->L_frameTCX, ( ( sts[1]->last_core == 0 ) ? shr( sts[1]->hTcxEnc->L_frameTCX, 2 ) : 0 ) ); /* Q0 */
     253       21443 :                 L_frameTCX = idiv1616( L_frameTCX, ( sts[1]->core == TCX_20_CORE ) ? 1 : NB_DIV );                                           /* Q0 */
     254             : 
     255       21443 :                 e_tmp = nrgRatio_e[k];
     256       21443 :                 tmp = Inv16( extract_h( nrgRatio_fx[k] ), &e_tmp ); /* Q15-e_tmp */
     257       21443 :                 tmp = shl( tmp, e_tmp );                            /* Q15 */
     258             : 
     259       21443 :                 v_multc_fixed_16( sts[1]->hTcxEnc->spectrum_fx[k], tmp, sts[1]->hTcxEnc->spectrum_fx[k], L_frameTCX ); /* exp: exp_spec */
     260       21443 :                 v_multc_fixed_16( mdst_spectrum_fx[1][k], tmp, mdst_spectrum_fx[1][k], L_frameTCX );                   /* exp: exp_mdct_spec */
     261             :             }
     262       22752 :             ELSE IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( nrgRatio_fx[k], nrgRatio_e[k], ONE_IN_Q27, 4 ), -1 ) && LT_16( k, EQ_16( sts[0]->core, TCX_20_CORE ) ? 1 : NB_DIV ) )
     263             :             {
     264        9564 :                 L_frameTCX = add( sts[0]->hTcxEnc->L_frameTCX, EQ_16( sts[0]->last_core, 0 ) ? shr( sts[0]->hTcxEnc->L_frameTCX, 2 ) : 0 ); /* Q0 */
     265        9564 :                 L_frameTCX = idiv1616( L_frameTCX, ( sts[0]->core == TCX_20_CORE ) ? 1 : NB_DIV );                                          /* Q0 */
     266             : 
     267             :                 /* This operation is resulting in some high MLDs in fixed point. */
     268        9564 :                 v_multc_fixed_16( sts[0]->hTcxEnc->spectrum_fx[k], extract_l( L_shr( nrgRatio_fx[k], 16 - nrgRatio_e[k] ) ), sts[0]->hTcxEnc->spectrum_fx[k], L_frameTCX ); /* exp: exp_spec */
     269        9564 :                 v_multc_fixed_16( mdst_spectrum_fx[0][k], extract_l( L_shr( nrgRatio_fx[k], 16 - nrgRatio_e[k] ) ), mdst_spectrum_fx[0][k], L_frameTCX );                   /* exp: exp_mdct_spec */
     270             :             }
     271             :         }
     272             :     }
     273             : 
     274             : #ifdef DEBUG_FORCE_MDCT_STEREO_MODE
     275             :     IF( hStereoMdct->fDualMono ||
     276             :         ( NE_16( sts[0]->hTcxEnc->transform_type[0], sts[1]->hTcxEnc->transform_type[0] ) ) || NE_16( sts[0]->hTcxEnc->transform_type[1], sts[1]->hTcxEnc->transform_type[1] ) || ( NE_16( sts[0]->last_core, sts[1]->last_core ) && ( EQ_16( sts[0]->last_core, ACELP_CORE ) || EQ_16( sts[1]->last_core, ACELP_CORE ) ) ) || EQ_16( sts[0]->last_core, ACELP_CORE ) || EQ_16( sts[1]->last_core, ACELP_CORE ) )
     277             : #else
     278      139819 :     IF( ( NE_16( sts[0]->hTcxEnc->transform_type[0], sts[1]->hTcxEnc->transform_type[0] ) ) || NE_16( sts[0]->hTcxEnc->transform_type[1], sts[1]->hTcxEnc->transform_type[1] ) || ( NE_16( sts[0]->last_core, sts[1]->last_core ) && ( EQ_16( sts[0]->last_core, ACELP_CORE ) || EQ_16( sts[1]->last_core, ACELP_CORE ) ) ) || EQ_16( sts[0]->last_core, ACELP_CORE ) || EQ_16( sts[1]->last_core, ACELP_CORE ) )
     279             : #endif
     280             :     {
     281         931 :         hStereoMdct->mdct_stereo_mode[0] = SMDCT_DUAL_MONO;
     282         931 :         move16();
     283         931 :         hStereoMdct->mdct_stereo_mode[1] = SMDCT_DUAL_MONO;
     284         931 :         move16();
     285             : 
     286             : 
     287         931 :         IF( sts[0]->igf )
     288             :         {
     289         659 :             hStereoMdct->IGFStereoMode[0] = SMDCT_DUAL_MONO;
     290         659 :             move16();
     291         659 :             hStereoMdct->IGFStereoMode[1] = SMDCT_DUAL_MONO;
     292         659 :             move16();
     293             :         }
     294         931 :         hStereoMdct->sw_uncorr = 1;
     295         931 :         move16();
     296             : 
     297         931 :         pop_wmops();
     298         931 :         return;
     299             :     }
     300             : #ifdef DEBUG_FORCE_MDCT_STEREO_MODE
     301             :     else if ( hStereoMdct->fMSstereo )
     302             :     {
     303             :         hStereoMdct->mdct_stereo_mode[0] = SMDCT_MS_FULL;
     304             :         hStereoMdct->mdct_stereo_mode[1] = SMDCT_MS_FULL;
     305             : 
     306             :         if ( sts[0]->igf )
     307             :         {
     308             :             hStereoMdct->IGFStereoMode[0] = SMDCT_MS_FULL;
     309             :             hStereoMdct->IGFStereoMode[1] = SMDCT_MS_FULL;
     310             :         }
     311             :         for ( k = 0; k < nSubframes; k++ )
     312             :         {
     313             :             convertToMS_fx( L_frameTCX, sts[0]->hTcxEnc->spectrum_fx[k], sts[1]->hTcxEnc->spectrum_fx[k], SQRT2_OVER_2_FIXED );
     314             : 
     315             :             /* Make sure that the MDST is processed in the correct way also */
     316             :             set_s( &ms_mask[k][0], 1, MAX_SFB );
     317             :         }
     318             : 
     319             :         pop_wmops();
     320             :         return;
     321             :     }
     322             : #endif
     323             :     ELSE /* decide based on signal */
     324             :     {
     325      280939 :         FOR( k = 0; k < nSubframes; k++ )
     326             :         {
     327      142051 :             IF( EQ_16( sts[0]->core, TCX_20_CORE ) )
     328             :             {
     329      135725 :                 sfbConf = &hStereoMdct->stbParamsTCX20;
     330             :             }
     331             :             ELSE
     332             :             {
     333        6326 :                 sfbConf = &hStereoMdct->stbParamsTCX10;
     334             :             }
     335      142051 :             IF( EQ_16( sts[0]->last_core, ACELP_CORE ) )
     336             :             {
     337           0 :                 sfbConf = &hStereoMdct->stbParamsTCX20afterACELP;
     338             :             }
     339             : 
     340      142051 :             IF( LT_32( sts[0]->element_brate, IVAS_80k ) && EQ_16( sts[0]->core, sts[1]->core ) && !mct_on ) /* band-wise HF ILD alignment to increase channel compaction */
     341             :             {
     342       25293 :                 Word16 sfb = 1;
     343       25293 :                 move16();
     344             : 
     345       25293 :                 test();
     346      417805 :                 WHILE( LT_16( sfb, sfbConf->nBandsStereoCore ) && LT_16( sub( sfbConf->sfbOffset[sfb + 1], sfbConf->sfbOffset[sfb] ), 12 ) )
     347             :                 {
     348      392512 :                     test();
     349      392512 :                     sfb = add( sfb, 1 ); /* find start offset */
     350             :                 }
     351             : 
     352      420649 :                 FOR( sfb--; sfb < sfbConf->nBandsStereoCore; sfb++ ) /* start one SFB early for the fade-in */
     353             :                 {
     354      395356 :                     const Word16 startLine = sfbConf->sfbOffset[sfb]; /* Q0 */
     355      395356 :                     move16();
     356      395356 :                     const Word16 endLine = sfbConf->sfbOffset[sfb + 1]; /* Q0 */
     357      395356 :                     move16();
     358      395356 :                     const Word16 sfbWidth = sub( endLine, startLine );
     359             : 
     360      395356 :                     nrgRatio_e[0] = nrgRatio_e[1] = exp_spec;
     361      395356 :                     move16();
     362      395356 :                     move16();
     363             : 
     364      395356 :                     nrgRatio_fx[0] = sum2_32_fx( &sts[0]->hTcxEnc->spectrum_fx[k][startLine], sfbWidth, &nrgRatio_e[0] ); /* Q31-nrgRatio_e[0] */
     365      395356 :                     move32();
     366      395356 :                     nrgRatio_fx[1] = sum2_32_fx( &sts[1]->hTcxEnc->spectrum_fx[k][startLine], sfbWidth, &nrgRatio_e[1] ); /* Q31-nrgRatio_e[1] */
     367      395356 :                     move32();
     368             : 
     369      395356 :                     test();
     370      395356 :                     IF( !sts[0]->hTcxEnc->fUseTns[k] && !sts[1]->hTcxEnc->fUseTns[k] ) /* no TNS in either ch */
     371             :                     {
     372             :                         Word32 tmp_fx;
     373             :                         Word16 tmp_e;
     374      331885 :                         tmp_e = exp_mdct_spec;
     375      331885 :                         move16();
     376      331885 :                         tmp_fx = sum2_32_fx( &mdst_spectrum_fx[0][k][startLine], sfbWidth, &tmp_e );                               /* Q31-tmp_e */
     377      331885 :                         nrgRatio_fx[0] = BASOP_Util_Add_Mant32Exp( nrgRatio_fx[0], nrgRatio_e[0], tmp_fx, tmp_e, &nrgRatio_e[0] ); /* Q31-nrgRatio_e[0] */
     378      331885 :                         tmp_e = exp_mdct_spec;
     379      331885 :                         move16();
     380      331885 :                         tmp_fx = sum2_32_fx( &mdst_spectrum_fx[1][k][startLine], sfbWidth, &tmp_e );                               /* Q31-tmp_e */
     381      331885 :                         nrgRatio_fx[1] = BASOP_Util_Add_Mant32Exp( nrgRatio_fx[1], nrgRatio_e[1], tmp_fx, tmp_e, &nrgRatio_e[1] ); /* Q31-nrgRatio_e[1] */
     382             :                     }
     383      395356 :                     IF( ( nrgRatio_fx[0] > 0 ) && ( nrgRatio_fx[1] > 0 ) && BASOP_Util_Cmp_Mant32Exp( nrgRatio_fx[0], nrgRatio_e[0], nrgRatio_fx[1], nrgRatio_e[1] ) )
     384             :                     {
     385             :                         Word16 fTemp_e, tmp_e;
     386      395026 :                         Word32 fTemp_fx = BASOP_Util_Add_Mant32Exp( nrgRatio_fx[0], nrgRatio_e[0], nrgRatio_fx[1], nrgRatio_e[1], &fTemp_e ); /* Q31-fTemp_e */
     387      395026 :                         fTemp_e = sub( fTemp_e, 1 );
     388      395026 :                         nrgRatio_fx[0] = BASOP_Util_Divide3232_Scale_newton( fTemp_fx, nrgRatio_fx[0], &tmp_e ); /* Q31 - tmp_e - fTemp_e + nrgRatio_e[0] */
     389      395026 :                         move32();
     390      395026 :                         nrgRatio_e[0] = add( tmp_e, sub( fTemp_e, nrgRatio_e[0] ) );
     391      395026 :                         move16();
     392      395026 :                         nrgRatio_fx[0] = Sqrt32( nrgRatio_fx[0], &nrgRatio_e[0] ); /* Q31-nrgRatio_e[0] */
     393      395026 :                         move32();
     394             : 
     395      395026 :                         nrgRatio_fx[1] = BASOP_Util_Divide3232_Scale_newton( fTemp_fx, nrgRatio_fx[1], &tmp_e ); /* Q31 - tmp_e - fTemp_e + nrgRatio_e[1] */
     396      395026 :                         move32();
     397      395026 :                         nrgRatio_e[1] = add( tmp_e, sub( fTemp_e, nrgRatio_e[1] ) );
     398      395026 :                         move16();
     399      395026 :                         nrgRatio_fx[1] = Sqrt32( nrgRatio_fx[1], &nrgRatio_e[1] ); /* Q31-nrgRatio_e[1] */
     400      395026 :                         move32();
     401             : 
     402      395026 :                         nrgRatio_fx[0] = L_max( ONE_IN_Q27, L_shl_sat( nrgRatio_fx[0], sub( nrgRatio_e[0], 2 ) ) ); // max( 0.25f, min( 4.f, nrgRatio[0] ) );
     403      395026 :                         move32();
     404      395026 :                         nrgRatio_fx[1] = L_max( ONE_IN_Q27, L_shl_sat( nrgRatio_fx[1], sub( nrgRatio_e[1], 2 ) ) ); // Q29
     405      395026 :                         move32();
     406      395026 :                         nrgRatio_e[0] = Q2;
     407      395026 :                         move16();
     408      395026 :                         nrgRatio_e[1] = Q2;
     409      395026 :                         move16();
     410             : 
     411      395026 :                         IF( ( LT_16( sfbWidth, 12 ) && LT_16( add( sfb, 1 ), sfbConf->nBandsStereoCore ) ) || GT_32( sts[0]->element_brate, IVAS_48k ) ) /* attenuate ILD alignment in the first SFB or at 64k */
     412             :                         {
     413      208803 :                             nrgRatio_fx[0] = BASOP_Util_fPow( nrgRatio_fx[0], nrgRatio_e[0], ONE_IN_Q29, 0, &nrgRatio_e[0] ); /* Q31-nrgRatio_e[0] */
     414      208803 :                             move32();
     415      208803 :                             nrgRatio_fx[1] = BASOP_Util_fPow( nrgRatio_fx[1], nrgRatio_e[1], ONE_IN_Q29, 0, &nrgRatio_e[1] ); /* Q31-nrgRatio_e[1] */
     416      208803 :                             move32();
     417             :                         }
     418             :                         ELSE
     419             :                         {
     420      186223 :                             nrgRatio_fx[0] = Sqrt32( nrgRatio_fx[0], &nrgRatio_e[0] ); /* Q31-nrgRatio_e[0] */
     421      186223 :                             move32();
     422      186223 :                             nrgRatio_fx[1] = Sqrt32( nrgRatio_fx[1], &nrgRatio_e[1] ); /* Q31-nrgRatio_e[1] */
     423      186223 :                             move32();
     424             :                         }
     425             : 
     426      395026 :                         nrgRatio_fx[0] = L_shl( nrgRatio_fx[0], sub( nrgRatio_e[0], 1 ) ); // Q30
     427      395026 :                         move32();
     428      395026 :                         nrgRatio_fx[1] = L_shl( nrgRatio_fx[1], sub( nrgRatio_e[1], 1 ) ); // Q30
     429      395026 :                         move32();
     430             : 
     431             : 
     432      395026 :                         v_multc_fixed( &sts[0]->hTcxEnc->spectrum_fx[k][startLine], nrgRatio_fx[0], &sts[0]->hTcxEnc->spectrum_fx[k][startLine], sfbWidth ); /* exp: exp_spec+1 */
     433      395026 :                         v_multc_fixed( &mdst_spectrum_fx[0][k][startLine], nrgRatio_fx[0], &mdst_spectrum_fx[0][k][startLine], sfbWidth );                   /* exp: exp_mdct_spec+1 */
     434      395026 :                         scale_sig32( &sts[0]->hTcxEnc->spectrum_fx[k][startLine], sfbWidth, Q1 );                                                            // exp: exp_spec
     435      395026 :                         scale_sig32( &mdst_spectrum_fx[0][k][startLine], sfbWidth, Q1 );                                                                     // exp: exp_mdct_spec
     436             : 
     437      395026 :                         v_multc_fixed( &sts[1]->hTcxEnc->spectrum_fx[k][startLine], nrgRatio_fx[1], &sts[1]->hTcxEnc->spectrum_fx[k][startLine], sfbWidth ); /* exp: exp_spec+1 */
     438      395026 :                         v_multc_fixed( &mdst_spectrum_fx[1][k][startLine], nrgRatio_fx[1], &mdst_spectrum_fx[1][k][startLine], sfbWidth );                   /* exp: exp_mdct_spec+1 */
     439      395026 :                         scale_sig32( &sts[1]->hTcxEnc->spectrum_fx[k][startLine], sfbWidth, Q1 );                                                            // exp: exp_spec
     440      395026 :                         scale_sig32( &mdst_spectrum_fx[1][k][startLine], sfbWidth, Q1 );                                                                     // exp: exp_mdct_spec
     441             :                     }
     442             :                 }
     443             :             }
     444             : 
     445             :             /* set mask to zero */
     446      142051 :             set16_fx( &ms_mask[k][0], 0, MAX_SFB );
     447      142051 :             IF( mct_on )
     448             :             {
     449       99057 :                 nAvailBitsMS[k] = shl( sts[0]->bits_frame_channel, 1 ); /* Q0 */
     450       99057 :                 move16();
     451             :             }
     452             :             ELSE
     453             :             {
     454       42994 :                 nAvailBitsMS[k] = sts[0]->bits_frame_nominal; /* Q0 */
     455       42994 :                 move16();
     456             :             }
     457             : 
     458      142051 :             nAvailBitsMS[k] = sub( nAvailBitsMS[k], add( sts[0]->side_bits_frame_channel, sts[1]->side_bits_frame_channel ) ); /* Q0 */
     459      142051 :             move16();
     460             : 
     461      142051 :             IF( EQ_16( nSubframes, 2 ) )
     462             :             {
     463        6326 :                 nAvailBitsMS[k] = sub( nAvailBitsMS[k], OFFSET_BITS_TCX10 ); /* Q0 */
     464        6326 :                 move16();
     465             :             }
     466             :             ELSE
     467             :             {
     468      135725 :                 nAvailBitsMS[k] = sub( nAvailBitsMS[k], OFFSET_BITS_TCX20 ); /* Q0 */
     469      135725 :                 move16();
     470             :             }
     471             : 
     472      142051 :             nAvailBitsMS[k] = idiv1616( nAvailBitsMS[k], nSubframes ); /* Q0 */
     473      142051 :             move16();
     474             : 
     475      142051 :             test();
     476      142051 :             IF( mct_on && LE_16( nAvailBitsMS[k], 0 ) ) /*Force M/S when bit-budget is low for MCT*/
     477             :             {
     478           0 :                 hStereoMdct->mdct_stereo_mode[k] = 1;
     479           0 :                 move16();
     480           0 :                 hStereoMdct->IGFStereoMode[k] = 1;
     481           0 :                 move16();
     482           0 :                 set16_fx( ms_mask[k], 1, sfbConf->sfbCnt );
     483             :             }
     484             :             ELSE
     485             :             {
     486      142051 :                 MsStereoDecision_fx( sfbConf, sts[0]->hTcxEnc->spectrum_fx[k], sts[1]->hTcxEnc->spectrum_fx[k], inv_spectrum_fx[0][k], inv_spectrum_fx[1][k], sub( Q31, exp_spec ), &hStereoMdct->mdct_stereo_mode[k], &ms_mask[k][0], nAvailBitsMS[k] );
     487             : 
     488      142051 :                 IF( sts[0]->igf )
     489             :                 {
     490       92740 :                     IGFEncStereoEncoder_fx( sfbConf, sts[0]->hIGFEnc, sts[0]->hTcxEnc->spectrum_fx[k], sts[1]->hTcxEnc->spectrum_fx[k], sub( Q31, exp_spec ), &ms_mask[k][0],
     491       92740 :                                             &hStereoMdct->IGFStereoMode[k], hStereoMdct->mdct_stereo_mode[k], (Word16) EQ_16( sts[0]->core, TCX_20_CORE ), (Word16) EQ_16( sts[0]->last_core, ACELP_CORE ) );
     492             :                 }
     493             :                 ELSE
     494             :                 {
     495       49311 :                     hStereoMdct->IGFStereoMode[k] = hStereoMdct->mdct_stereo_mode[k];
     496       49311 :                     move16();
     497             :                 }
     498             :             }
     499             : 
     500      142051 :             IF( NE_16( hStereoMdct->mdct_stereo_mode[k], SMDCT_DUAL_MONO ) || NE_16( hStereoMdct->IGFStereoMode[k], SMDCT_DUAL_MONO ) )
     501             :             {
     502             : 
     503      134652 :                 ms_inv_mask_processing_fx( hStereoMdct, sts, ms_mask, k, sts[0]->hTcxEnc->spectrum_fx[k], sts[1]->hTcxEnc->spectrum_fx[k], inv_spectrum_fx[0][k], inv_spectrum_fx[1][k], sfbConf->sfbCnt );
     504             : 
     505      134652 :                 ms_processing_fx( hStereoMdct, sts, ms_mask, k, sts[0]->hTcxEnc->spectrum_fx[k], sts[1]->hTcxEnc->spectrum_fx[k], sfbConf->sfbCnt );
     506             : 
     507      134652 :                 IF( !sts[0]->hTcxEnc->fUseTns[k] && !sts[1]->hTcxEnc->fUseTns[k] )
     508             :                 {
     509      111833 :                     sts[0]->hTcxEnc->tns_ms_flag[k] = 1;
     510      111833 :                     move16();
     511      111833 :                     sts[1]->hTcxEnc->tns_ms_flag[k] = 1;
     512      111833 :                     move16();
     513      111833 :                     ms_inv_mask_processing_fx( hStereoMdct, sts, ms_mask, k, mdst_spectrum_fx[0][k], mdst_spectrum_fx[1][k], inv_mdst_spectrum_fx[0][k], inv_mdst_spectrum_fx[1][k], -1 );
     514             : 
     515      111833 :                     ms_processing_fx( hStereoMdct, sts, ms_mask, k, mdst_spectrum_fx[0][k], mdst_spectrum_fx[1][k], sfbConf->sfbCnt );
     516             :                 }
     517             :             }
     518             :         } /* for k */
     519             :     }
     520             :     /*  for bitrate switching determine correlation depending on m/s decision */
     521             :     {
     522             :         Word16 ms_bands[2];
     523             :         Word16 sw_uncorr[2], sw_uncorr_mean;
     524      280939 :         FOR( k = 0; k < nSubframes; k++ )
     525             :         {
     526      142051 :             sfbConf = EQ_16( sts[0]->core, TCX_20_CORE ) ? &hStereoMdct->stbParamsTCX20 : &hStereoMdct->stbParamsTCX10;
     527      142051 :             ms_bands[k] = sum_s( ms_mask[k], sfbConf->nBandsStereoCore ); /* Q0 */
     528      142051 :             move16();
     529      142051 :             sw_uncorr[k] = sub( 32767 /*Q15*/, div_s( ms_bands[k], sfbConf->nBandsStereoCore ) ); /* Q15 */
     530      142051 :             move16();
     531             :         }
     532      138888 :         IF( EQ_16( sts[0]->core, TCX_20_CORE ) )
     533             :         {
     534      135725 :             sw_uncorr_mean = sw_uncorr[0]; /* Q15 */
     535      135725 :             move16();
     536             :         }
     537             :         ELSE
     538             :         {
     539        3163 :             sw_uncorr_mean = add( shr( sw_uncorr[0], 1 ), shr( sw_uncorr[1], 1 ) ); /* Q15 */
     540             :         }
     541      138888 :         hStereoMdct->sw_uncorr = extract_l( GT_16( sw_uncorr_mean, 19661 /*0.6 in Q15*/ ) );
     542      138888 :         move16();
     543             :     }
     544             : 
     545      138888 :     pop_wmops();
     546      138888 :     return;
     547             : }
     548             : 
     549             : /*-------------------------------------------------------------------*
     550             :  * ms_processing()
     551             :  *
     552             :  *
     553             :  *-------------------------------------------------------------------*/
     554             : 
     555      246485 : void ms_processing_fx(
     556             :     STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: Stereo MDCT encoder structure   */
     557             :     Encoder_State **sts,                     /* i/o: Encoder state structure         */
     558             :     Word16 ms_mask[NB_DIV][MAX_SFB],         /* i  : bandwise MS mask                Q0*/
     559             :     const Word16 iSubframe,                  /* i  : subframe number                 Q0*/
     560             :     Word32 x_0_fx[],
     561             :     /* i/o: spectrum 1                      */ // Q( q_x )
     562             :     Word32 x_1_fx[],
     563             :     /* i/o: spectrum 1                      */ // Q( q_x )
     564             :     Word16 maxSfb                              /* i  : number of stereo frequency bands Q0*/
     565             : )
     566             : {
     567             :     Word16 sfb;
     568             :     STEREO_MDCT_BAND_PARAMETERS *sfbConf;
     569             : 
     570      246485 :     sfbConf = EQ_16( sts[0]->core, TCX_20_CORE ) ? &hStereoMdct->stbParamsTCX20 : &hStereoMdct->stbParamsTCX10;
     571             : 
     572      246485 :     IF( sts[0]->last_core == ACELP_CORE )
     573             :     {
     574           0 :         assert( EQ_16( sts[1]->last_core, ACELP_CORE ) );
     575           0 :         sfbConf = &hStereoMdct->stbParamsTCX20afterACELP;
     576             :     }
     577             : 
     578      246485 :     if ( EQ_16( maxSfb, -1 ) )
     579             :     {
     580           0 :         maxSfb = sfbConf->sfbCnt; /* Q0 */
     581           0 :         move16();
     582             :     }
     583             : 
     584    10841495 :     FOR( sfb = 0; sfb < maxSfb; sfb++ )
     585             :     {
     586    10595010 :         IF( NE_16( ms_mask[iSubframe][sfb], 0 ) )
     587             :         {
     588     8698441 :             convertToBwMS_fx( sfbConf->sfbOffset[sfb], sfbConf->sfbOffset[sfb + 1], x_0_fx, x_1_fx, SQRT2_OVER_2_FIXED );
     589             :         }
     590             :     }
     591             : 
     592      246485 :     return;
     593             : }
     594             : 
     595             : /*-------------------------------------------------------------------*
     596             :  * ms_inv_mask_processing()
     597             :  *
     598             :  *
     599             :  *-------------------------------------------------------------------*/
     600             : 
     601      246485 : void ms_inv_mask_processing_fx(
     602             :     STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: Stereo MDCT encoder structure   */
     603             :     Encoder_State **sts,                     /* i/o: Encoder state structure         */
     604             :     Word16 ms_mask[NB_DIV][MAX_SFB],         /* i  : bandwise MS mask                Q0*/
     605             :     const Word16 iSubframe,                  /* i  : subframe number                 Q0*/
     606             :     const Word32 x_0_fx[],
     607             :     /* i  : spectrum 1                      */ // Q( q_x )
     608             :     const Word32 x_1_fx[],
     609             :     /* i  : spectrum 2                      */ // Q( q_x )
     610             :     Word32 x_inv_0_fx[],
     611             :     /* o  : inverse spectrum 1              */ // Q( q_x )
     612             :     Word32 x_inv_1_fx[],
     613             :     /* o  : inverse spectrum 2              */ // Q( q_x )
     614             :     Word16 maxSfb                              /* i  : number of stereo frequency bands Q0*/
     615             : )
     616             : {
     617             :     Word16 sfb;
     618             :     STEREO_MDCT_BAND_PARAMETERS *sfbConf;
     619             :     Word16 nSubframes, L_subframeTCX;
     620             : 
     621      246485 :     nSubframes = ( sts[0]->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV;
     622      246485 :     L_subframeTCX = idiv1616( sts[0]->hTcxEnc->L_frameTCX, nSubframes ); /* Q0 */
     623      246485 :     sfbConf = ( sts[0]->core == TCX_20_CORE ) ? &hStereoMdct->stbParamsTCX20 : &hStereoMdct->stbParamsTCX10;
     624             : 
     625      246485 :     IF( EQ_16( sts[0]->last_core, ACELP_CORE ) )
     626             :     {
     627           0 :         assert( EQ_16( sts[1]->last_core, ACELP_CORE ) );
     628           0 :         sfbConf = &hStereoMdct->stbParamsTCX20afterACELP;
     629             :     }
     630             : 
     631      246485 :     IF( EQ_16( maxSfb, -1 ) )
     632             :     {
     633      111833 :         maxSfb = sfbConf->sfbCnt; /* Q0 */
     634      111833 :         move16();
     635             :     }
     636             : 
     637    10841495 :     FOR( sfb = 0; sfb < maxSfb; sfb++ )
     638             :     {
     639    10595010 :         Copy32( &x_0_fx[sfbConf->sfbOffset[sfb]], &x_inv_0_fx[sfbConf->sfbOffset[sfb]], sfbConf->sfbOffset[sfb + 1] - sfbConf->sfbOffset[sfb] ); /* q_x */
     640    10595010 :         Copy32( &x_1_fx[sfbConf->sfbOffset[sfb]], &x_inv_1_fx[sfbConf->sfbOffset[sfb]], sfbConf->sfbOffset[sfb + 1] - sfbConf->sfbOffset[sfb] ); /* q_x */
     641             : 
     642    10595010 :         IF( EQ_16( ms_mask[iSubframe][sfb], 0 ) )
     643             :         {
     644     1896569 :             convertToBwMS_fx( sfbConf->sfbOffset[sfb], sfbConf->sfbOffset[sfb + 1], x_inv_0_fx, x_inv_1_fx, SQRT2_OVER_2_FIXED );
     645             :         }
     646             :     }
     647             : 
     648             :     /* set rest of inverse spectrum to zero */
     649      246485 :     IF( GT_16( L_subframeTCX, sfbConf->sfbOffset[maxSfb] ) )
     650             :     {
     651      146728 :         set_zero_fx( &x_inv_0_fx[sfbConf->sfbOffset[maxSfb]], sub( L_subframeTCX, sfbConf->sfbOffset[maxSfb] ) );
     652      146728 :         set_zero_fx( &x_inv_1_fx[sfbConf->sfbOffset[maxSfb]], sub( L_subframeTCX, sfbConf->sfbOffset[maxSfb] ) );
     653             :     }
     654             : 
     655      246485 :     return;
     656             : }
     657             : 
     658             : 
     659             : /*-------------------------------------------------------------------*
     660             :  * write_stereo_to_bitstream()
     661             :  *
     662             :  *
     663             :  *-------------------------------------------------------------------*/
     664             : 
     665      134951 : Word16 write_stereo_to_bitstream_fx(
     666             :     STEREO_MDCT_ENC_DATA_HANDLE hStereoMdct, /* i/o: Stereo MDCT encoder structure    */
     667             :     Encoder_State **sts,                     /* i/o: Encoder state structure          */
     668             :     Word16 ms_mask[NB_DIV][MAX_SFB],         /* i  : bandwise MS mask                 Q0*/
     669             :     const Word16 mct_on,                     /* i  : flag mct block (1) or stereo (0) Q0*/
     670             :     BSTR_ENC_HANDLE hBstr                    /* i/o: bitstream handle                 */
     671             : )
     672             : {
     673             :     Word16 i, k, nSubframes;
     674             :     UWord16 mdct_stereo_mode, stereo_mode_bits;
     675             :     STEREO_MDCT_BAND_PARAMETERS *sfbConf;
     676      134951 :     Word16 start_bits = hBstr->nb_bits_tot;
     677      134951 :     move16();
     678             : 
     679      134951 :     if ( !mct_on )
     680             :     {
     681       42785 :         assert( ( EQ_16( sts[0]->hTcxEnc->transform_type[0], sts[1]->hTcxEnc->transform_type[0] ) && EQ_16( sts[0]->hTcxEnc->transform_type[1], sts[1]->hTcxEnc->transform_type[1] ) ) || ( EQ_16( hStereoMdct->mdct_stereo_mode[0], SMDCT_DUAL_MONO ) && EQ_16( hStereoMdct->mdct_stereo_mode[1], SMDCT_DUAL_MONO ) ) );
     682             :     }
     683             : 
     684      134951 :     nSubframes = ( EQ_16( sts[0]->core, TCX_10_CORE ) || NE_16( sts[0]->core, sts[1]->core ) ) ? NB_DIV : 1;
     685      134951 :     move16();
     686      134951 :     sfbConf = EQ_16( sts[0]->core, TCX_20_CORE ) ? &hStereoMdct->stbParamsTCX20 : &hStereoMdct->stbParamsTCX10;
     687      134951 :     move16();
     688             : 
     689      134951 :     IF( EQ_16( sts[0]->last_core, ACELP_CORE ) )
     690             :     {
     691         651 :         assert( EQ_16( sts[1]->ini_frame, 0 ) || EQ_16( sts[1]->last_core, ACELP_CORE ) );
     692         651 :         sfbConf = &hStereoMdct->stbParamsTCX20afterACELP;
     693             :     }
     694             : 
     695      134951 :     IF( hStereoMdct->hItd != NULL )
     696             :     {
     697       11750 :         write_itd_data_fx( hStereoMdct->hItd, hBstr );
     698             :     }
     699             : 
     700      273320 :     FOR( k = 0; k < nSubframes; k++ )
     701             :     {
     702      138369 :         mdct_stereo_mode = 0;
     703      138369 :         move16();
     704      138369 :         stereo_mode_bits = 1;
     705      138369 :         move16();
     706             : 
     707      138369 :         SWITCH( hStereoMdct->mdct_stereo_mode[k] )
     708             :         {
     709        3788 :             case SMDCT_DUAL_MONO:
     710        3788 :                 mdct_stereo_mode = 0;
     711        3788 :                 move16();
     712        3788 :                 stereo_mode_bits = 1;
     713        3788 :                 move16();
     714        3788 :                 BREAK;
     715       83549 :             case SMDCT_MS_FULL:
     716       83549 :                 mdct_stereo_mode = 2;
     717       83549 :                 move16();
     718       83549 :                 stereo_mode_bits = 2;
     719       83549 :                 move16();
     720       83549 :                 BREAK;
     721       51032 :             case SMDCT_BW_MS:
     722       51032 :                 mdct_stereo_mode = 3;
     723       51032 :                 move16();
     724       51032 :                 stereo_mode_bits = 2;
     725       51032 :                 move16();
     726       51032 :                 BREAK;
     727           0 :             default:
     728           0 :                 assert( !"Not supported MDCT stereo mode\n" );
     729             :         }
     730             : 
     731      138369 :         push_next_indice( hBstr, mdct_stereo_mode, stereo_mode_bits );
     732             : 
     733      138369 :         IF( !mct_on )
     734             :         {
     735       44195 :             IF( EQ_16( sts[0]->core, sts[1]->core ) || ( k == 0 ) )
     736             :             {
     737       43931 :                 push_next_indice( hBstr, hStereoMdct->global_ild[k], SMDCT_GLOBAL_ILD_BITS );
     738             :             }
     739             :         }
     740             : 
     741      138369 :         IF( EQ_16( hStereoMdct->mdct_stereo_mode[k], SMDCT_BW_MS ) )
     742             :         {
     743     2117442 :             FOR( i = 0; i < sfbConf->nBandsStereoCore; i++ )
     744             :             {
     745     2066410 :                 push_next_indice( hBstr, ms_mask[k][i] ? 1 : 0, 1 );
     746             :             }
     747             :         }
     748             : 
     749      138369 :         IF( sts[0]->igf )
     750             :         {
     751       92107 :             mdct_stereo_mode = 0;
     752       92107 :             move16();
     753       92107 :             stereo_mode_bits = 1;
     754       92107 :             move16();
     755       92107 :             SWITCH( hStereoMdct->IGFStereoMode[k] )
     756             :             {
     757       37337 :                 case SMDCT_DUAL_MONO:
     758       37337 :                     mdct_stereo_mode = 0;
     759       37337 :                     move16();
     760       37337 :                     stereo_mode_bits = 1;
     761       37337 :                     move16();
     762       37337 :                     BREAK;
     763       40413 :                 case SMDCT_MS_FULL:
     764       40413 :                     mdct_stereo_mode = 2;
     765       40413 :                     move16();
     766       40413 :                     stereo_mode_bits = 2;
     767       40413 :                     move16();
     768       40413 :                     BREAK;
     769       14357 :                 case SMDCT_BW_MS:
     770       14357 :                     mdct_stereo_mode = 3;
     771       14357 :                     move16();
     772       14357 :                     stereo_mode_bits = 2;
     773       14357 :                     move16();
     774       14357 :                     BREAK;
     775           0 :                 default:
     776           0 :                     assert( !"Not supported MDCT stereo mode\n" );
     777             :             }
     778             : 
     779       92107 :             push_next_indice( hBstr, mdct_stereo_mode, stereo_mode_bits );
     780             : 
     781             : 
     782       92107 :             IF( EQ_16( hStereoMdct->IGFStereoMode[k], SMDCT_BW_MS ) )
     783             :             {
     784       90936 :                 FOR( i = sfbConf->nBandsStereoCore; i < sfbConf->sfbCnt; i++ )
     785             :                 {
     786       76579 :                     push_next_indice( hBstr, ms_mask[k][i] ? 1 : 0, 1 );
     787             :                 }
     788             :             }
     789             :         }
     790             :     }
     791             : 
     792      134951 :     return sub( hBstr->nb_bits_tot, start_bits );
     793             : }
     794             : 
     795             : /*-------------------------------------------------------------------*
     796             :  * Band-wise M/S stereo processing
     797             :  *
     798             :  *
     799             :  *-------------------------------------------------------------------*/
     800             : 
     801    10689090 : static void convertToBwMS_fx(
     802             :     const Word16 startLine, /* i  : start line of sfb               Q0*/
     803             :     const Word16 stopLine,  /* i  : stop line of sfb                Q0*/
     804             :     Word32 x0[],
     805             :     /* i/o: mid/left channel coefficients   */ /* Q_x */
     806             :     Word32 x1[],
     807             :     /* i/o: side/right channel coefficients */                       /* Q_x */
     808             :     const Word32 norm_fac /* i  : normalization factor            */ /* Q31 */
     809             : )
     810             : {
     811             :     Word16 j;
     812             :     Word32 tmpValue_fx;
     813             : 
     814   198213652 :     FOR( j = startLine; j < stopLine; j++ )
     815             :     {
     816   187524562 :         tmpValue_fx = x0[j]; /*Q_x*/
     817   187524562 :         move32();
     818   187524562 :         x0[j] = Mpy_32_32( L_add( x0[j], x1[j] ), norm_fac ); /* Q_x */
     819   187524562 :         move32();
     820   187524562 :         x1[j] = Mpy_32_32( L_sub( tmpValue_fx, x1[j] ), norm_fac ); /* Q_x */
     821   187524562 :         move32();
     822             :     }
     823             : 
     824    10689090 :     return;
     825             : }
     826             : 
     827             : /*-------------------------------------------------------------------*
     828             :  * convertToMS()
     829             :  *
     830             :  *
     831             :  *-------------------------------------------------------------------*/
     832             : 
     833       94080 : void convertToMS_fx(
     834             :     const Word16 L_frame, /* i  : frame length                    Q0*/
     835             :     Word32 x0[],          /* i/o: mid/left channel coefficients   Q(q_x)*/
     836             :     Word32 x1[],          /* i/o: side/right channel coefficients Q(q_x)*/
     837             :     const Word32 norm_fac /* i  : normalization factor            Q31*/
     838             : )
     839             : {
     840       94080 :     convertToBwMS_fx( 0, L_frame, x0, x1, norm_fac );
     841             : 
     842       94080 :     return;
     843             : }
     844             : 
     845             : /*-------------------------------------------------------------------*
     846             :  * SQ_gain_estimate_stereo()
     847             :  *
     848             :  *
     849             :  *-------------------------------------------------------------------*/
     850             : 
     851             : /*! r: SQ gain */
     852      142051 : static Word32 SQ_gain_estimate_stereo_fx( // e_res
     853             :     const Word32 xL_fx[],                 /* i  : L vector to quantize        Q31-e_xL*/
     854             :     const Word16 e_xL,
     855             :     const Word32 xR_fx[], /* i  : R vector to quantize        Q31-e_xR*/
     856             :     const Word16 e_xR,
     857             :     const Word16 nbitsSQ, /* i  : number of bits targeted     Q0*/
     858             :     const Word16 lg,      /* i  : vector size (2048 max)      Q0*/
     859             :     Word16 *e_res )
     860             : {
     861             :     Word16 i, q, iter, e_ener, e_xL_2, e_xR_2, s;
     862             :     Word32 ener_fx, tmp_32, target_fx, fac_fx, offset_fx;
     863             :     Word32 en_fx[N_MAX / 2]; // Q25
     864             :     Word16 lg2, lg_4, lg2_4;
     865             :     Word64 W_tmp, _0_01;
     866             : 
     867      142051 :     lg_4 = shr( lg, 2 );    /* Q0 */
     868      142051 :     lg2_4 = shl( lg_4, 1 ); /* Q0 */
     869      142051 :     lg2 = shl( lg2_4, 2 );  /* Q0 */
     870      142051 :     i = 0;
     871      142051 :     move16();
     872      142051 :     e_xL_2 = shl( e_xL, 1 );
     873      142051 :     e_xR_2 = shl( e_xR, 1 );
     874      142051 :     _0_01 = W_shr( 21474836 /* 0.01 in Q31 */, sub( e_xL_2, 32 ) ); // 0.01 in 2*(Q of specL/R) + 1
     875             : 
     876      142051 :     set32_fx( en_fx, 335544 /* 0.01 in Q25 */, ( N_MAX / 2 ) );
     877             : 
     878             :     /* energy of quadruples with 9dB offset */
     879             :     /* ignore that we may take no all lines into account, max. 3 lines at the upper end of the spectrum can be missed (if lg is not a multiple of 4, happens also in SQGain()*/
     880             : 
     881    20311967 :     FOR( q = 0; q < lg_4; q++ )
     882             :     {
     883    20169916 :         W_tmp = W_mac_32_32( _0_01, xL_fx[i], xL_fx[i] );         // 2 * e_xL
     884    20169916 :         W_tmp = W_mac_32_32( W_tmp, xL_fx[i + 1], xL_fx[i + 1] ); // 2 * e_xL
     885    20169916 :         W_tmp = W_mac_32_32( W_tmp, xL_fx[i + 2], xL_fx[i + 2] ); // 2 * e_xL
     886    20169916 :         W_tmp = W_mac_32_32( W_tmp, xL_fx[i + 3], xL_fx[i + 3] ); // 2 * e_xL
     887             : 
     888    20169916 :         s = W_norm( W_tmp );
     889    20169916 :         ener_fx = W_extract_h( W_shl( W_tmp, s ) );
     890    20169916 :         e_ener = sub( e_xL_2, s );
     891             : 
     892    20169916 :         en_fx[q] = BASOP_Util_Log2( ener_fx ); /* saves a MAC */
     893    20169916 :         move32();
     894    20169916 :         en_fx[q] = Mpy_32_16_1( L_add( L_shl( e_ener, Q25 ), en_fx[q] ), 9864 /* log10(2) in Q15 */ ); // Q(25)
     895    20169916 :         move32();
     896    20169916 :         i += 4;
     897             :     }
     898      142051 :     i = 0;
     899      142051 :     move16();
     900    20311967 :     FOR( ; q < lg2_4; q++ )
     901             :     {
     902    20169916 :         W_tmp = W_mac_32_32( _0_01, xR_fx[i], xR_fx[i] );         // 2 * e_xR
     903    20169916 :         W_tmp = W_mac_32_32( W_tmp, xR_fx[i + 1], xR_fx[i + 1] ); // 2 * e_xR
     904    20169916 :         W_tmp = W_mac_32_32( W_tmp, xR_fx[i + 2], xR_fx[i + 2] ); // 2 * e_xR
     905    20169916 :         W_tmp = W_mac_32_32( W_tmp, xR_fx[i + 3], xR_fx[i + 3] ); // 2 * e_xR
     906             : 
     907    20169916 :         s = W_norm( W_tmp );
     908    20169916 :         ener_fx = W_extract_h( W_shl( W_tmp, s ) );
     909    20169916 :         e_ener = sub( e_xR_2, s );
     910             : 
     911    20169916 :         en_fx[q] = BASOP_Util_Log2( ener_fx ); /* saves a MAC */
     912    20169916 :         move32();
     913    20169916 :         en_fx[q] = Mpy_32_16_1( L_add( L_shl( e_ener, Q25 ), en_fx[q] ), 9864 /* log10(2) in Q15 */ ); // Q(25)
     914    20169916 :         move32();
     915    20169916 :         i += 4;
     916             :     }
     917             : 
     918             :     /* SQ scale: 4 bits / 6 dB per quadruple */
     919      142051 :     target_fx = L_mult( 19660 /* 0.15 in Q17 */, sub( nbitsSQ, shr( lg2, 4 ) ) ); // Q(18)
     920      142051 :     fac_fx = 429496729;                                                           /* 12.8 in Q25 */
     921      142051 :     move32();
     922      142051 :     offset_fx = fac_fx; /* Q25 */
     923      142051 :     move32();
     924             : 
     925      142051 :     Word64 target_64_fx = W_shl( target_fx, 7 ); // Q25
     926             :     /* find offset (0 to 128 dB with step of 0.125dB) */
     927     1562561 :     FOR( iter = 0; iter < 10; iter++ )
     928             :     {
     929     1420510 :         fac_fx = L_shr( fac_fx, 1 );            /* Q25 */
     930     1420510 :         offset_fx = L_sub( offset_fx, fac_fx ); /* Q25 */
     931     1420510 :         W_tmp = 0;
     932     1420510 :         move64();
     933             : 
     934   366372737 :         FOR( i = 0; i < lg2_4; i++ )
     935             :         {
     936   365534700 :             tmp_32 = L_sub( en_fx[i], offset_fx ); /* Q25 */
     937             : 
     938             :             /* avoid SV with 1 bin of amp < 0.5f */
     939   365534700 :             if ( GT_32( tmp_32, 10066329 /*0.3 Q25*/ ) )
     940             :             {
     941   202080105 :                 W_tmp = W_add( W_tmp, tmp_32 ); /* Q25 */
     942             :             }
     943             :             /* if ener is above target -> break and increase offset */
     944   365534700 :             IF( GT_64( W_tmp, target_64_fx ) )
     945             :             {
     946      582473 :                 offset_fx = L_add( offset_fx, fac_fx ); /* Q25 */
     947      582473 :                 BREAK;
     948             :             }
     949             :         }
     950             :     }
     951             : 
     952             :     /* return gain */
     953      142051 :     tmp_32 = L_add( 12539858, Mpy_32_16_1( offset_fx, 13606 ) ); // Q23
     954             : 
     955      142051 :     return BASOP_util_Pow2( tmp_32, Q8, e_res ); /* Q31-e_res */
     956             : }
     957             : 
     958             : /*-------------------------------------------------------------------*
     959             :  * QuantSpecEstimateBits()
     960             :  *
     961             :  *
     962             :  *-------------------------------------------------------------------*/
     963             : 
     964      568204 : static Word16 QuantSpecEstimateBits_fx(
     965             :     Word32 *spec_fx, /* Q15-spec_e */
     966             :     Word16 spec_e,
     967             :     Word16 G_fx, /* Q15-G_e */
     968             :     Word16 G_e,
     969             :     const Word16 length,         /* Q0 */
     970             :     const Word16 nBitsAvailable, /* Q0 */
     971             :     Word16 sqQ[] /* Q0 */ )
     972             : {
     973             :     Word16 stop, sqBits, nEncoded;
     974             :     Word16 lastnz;
     975             : 
     976      568204 :     tcx_scalar_quantization_ivas_fx( spec_fx, spec_e, sqQ, length, G_fx, G_e, 16384 /*Q15*/, NULL, 1 );
     977             : 
     978      568204 :     stop = 0;
     979      568204 :     move16();
     980             : 
     981      568204 :     sqBits = RCcontextMapping_encode2_estimate_no_mem_s17_LCS_fx( sqQ, length, &lastnz, &nEncoded, nBitsAvailable, &stop, 0, NULL ); /*Q0*/
     982             : 
     983      568204 :     if ( stop != 0 )
     984             :     {
     985       79531 :         sqBits = stop;
     986       79531 :         move16();
     987             :     }
     988             : 
     989      568204 :     return sqBits;
     990             : }
     991             : 
     992             : /*-------------------------------------------------------------------*
     993             :  * context_update()
     994             :  *
     995             :  *
     996             :  *-------------------------------------------------------------------*/
     997             : 
     998    11299330 : static void context_update_fx(
     999             :     HANDLE_RC_CONTEXT_MEM ctxSrc,
    1000             :     HANDLE_RC_CONTEXT_MEM ctxTarget,
    1001             :     const Word16 endLine /*Q0*/ )
    1002             : {
    1003             :     Word16 last_nz;
    1004             : 
    1005             :     /* check if last_nz of target is smaller than endLine, save and update */
    1006    11299330 :     last_nz = s_max( ctxTarget->lastnz, endLine ); /* Q0 */
    1007             : 
    1008    11299330 :     mvc2c( (UWord8 *) ctxSrc, (UWord8 *) ctxTarget, sizeof( RC_CONTEXT_MEM ) );
    1009    11299330 :     ctxTarget->lastnz = last_nz;
    1010    11299330 :     move16();
    1011             : 
    1012    11299330 :     return;
    1013             : }
    1014             : 
    1015             : /*-------------------------------------------------------------------*
    1016             :  * GetChannelEnergyRatio()
    1017             :  *
    1018             :  *
    1019             :  *-------------------------------------------------------------------*/
    1020             : 
    1021      127714 : static Word16 GetChannelEnergyRatio_fx( // Q15
    1022             :     Encoder_State **sts,                /* i/o: Encoder state structure */
    1023             :     const Word16 iFirstSubframe,
    1024             :     const Word16 iLastSubframe,
    1025             :     const UWord8 ratioInRmsDomain /* Q0 */ )
    1026             : {
    1027             :     Word16 ch, n, i;
    1028             :     Word32 nrg_fx[2];
    1029             :     Word16 nrg_e[2];
    1030             : 
    1031             :     /* Calculate energies per channel */
    1032      383142 :     FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
    1033             :     {
    1034      255428 :         const Encoder_State *st = sts[ch];
    1035             : 
    1036      255428 :         Word16 nSubframes = NB_DIV;
    1037      255428 :         move16();
    1038             : 
    1039      255428 :         if ( EQ_16( st->hTcxEnc->tcxMode, TCX_20 ) )
    1040             :         {
    1041      246420 :             nSubframes = 1;
    1042      246420 :             move16();
    1043             :         }
    1044             : 
    1045      255428 :         Word16 L_subframeTCX = shr( st->hTcxEnc->L_frameTCX, sub( nSubframes, 1 ) ); /* Q0 */
    1046             : 
    1047      255428 :         if ( st->last_core == ACELP_CORE )
    1048             :         {
    1049        2604 :             L_subframeTCX = add( L_subframeTCX, shr( L_subframeTCX, 2 ) ); /* Q0 */
    1050             :         }
    1051      255428 :         assert( iFirstSubframe >= 0 && ( iFirstSubframe <= iLastSubframe ) );
    1052             : 
    1053      255428 :         nrg_fx[ch] = 0;
    1054      255428 :         move32();
    1055      255428 :         nrg_e[ch] = 0;
    1056      255428 :         move16();
    1057             : 
    1058      515280 :         FOR( n = iFirstSubframe; n <= s_min( nSubframes - 1, iLastSubframe ); n++ )
    1059             :         {
    1060   196510092 :             FOR( i = 0; i < L_subframeTCX; i++ )
    1061             :             {
    1062   196250240 :                 nrg_fx[ch] = BASOP_Util_Add_Mant32Exp( nrg_fx[ch], nrg_e[ch], Mpy_32_32( st->hTcxEnc->spectrum_fx[n][i], st->hTcxEnc->spectrum_fx[n][i] ), shl( st->hTcxEnc->spectrum_e[n], 1 ), &nrg_e[ch] ); /* Q31-nrg_e */
    1063   196250240 :                 move32();
    1064             :             }
    1065             :         }
    1066      255428 :         IF( ratioInRmsDomain && nrg_fx[ch] )
    1067             :         {
    1068      246431 :             nrg_fx[ch] = Sqrt32( nrg_fx[ch], &nrg_e[ch] ); /* Q31-nrg_e */
    1069      246431 :             move32();
    1070             :         }
    1071             :     }
    1072             : 
    1073      127714 :     IF( L_add_sat( nrg_fx[0], nrg_fx[1] ) )
    1074             :     {
    1075      127693 :         nrg_fx[1] = BASOP_Util_Add_Mant32Exp( nrg_fx[0], nrg_e[0], nrg_fx[1], nrg_e[1], &nrg_e[1] ); /* Q31-nrg_e[1] */
    1076      127693 :         move32();
    1077             : 
    1078      127693 :         IF( NE_16( nrg_e[1], nrg_e[0] ) )
    1079             :         {
    1080       89664 :             nrg_fx[0] = L_shr( nrg_fx[0], sub( nrg_e[1], nrg_e[0] ) ); /* Q31-nrg_e[1] */
    1081       89664 :             move32();
    1082             :         }
    1083      127693 :         return divide3232( nrg_fx[0], nrg_fx[1] ); /* Q15 */
    1084             :     }
    1085             : 
    1086          21 :     return MIN_16;
    1087             : }
    1088             : 
    1089             : /*-------------------------------------------------------------------*
    1090             :  * FindSplitRatio()
    1091             :  *
    1092             :  *
    1093             :  *-------------------------------------------------------------------*/
    1094             : 
    1095       83783 : void FindSplitRatio_fx(
    1096             :     CPE_ENC_HANDLE hCPE, /* i/o: CPE encoder structure       */
    1097             :     Encoder_State **sts  /* i/o: Encoder state structure     */
    1098             : )
    1099             : {
    1100       83783 :     const UWord8 highRateMdctStereo = ( LT_32( sts[0]->element_brate, IVAS_80k ) && EQ_16( sts[0]->core, sts[1]->core ) && EQ_16( sts[0]->element_mode, IVAS_CPE_MDCT ) && sts[0]->hTcxEnc->enc_ste_pre_corr_past ? 0 : 1 );
    1101       83783 :     move16();
    1102             :     Word16 ratio_fx;
    1103             : 
    1104             :     /* Calculate split ratio and quantize it */
    1105       83783 :     hCPE->hStereoMdct->split_ratio = SMDCT_EQUAL_RATIO_RANGE; /* Equal bits to both channels */
    1106       83783 :     move16();
    1107             : 
    1108       83783 :     ratio_fx = GetChannelEnergyRatio_fx( sts, 0, 1, highRateMdctStereo ); // Q15
    1109             : 
    1110       83783 :     IF( ratio_fx >= 0 )
    1111             :     {
    1112       83762 :         hCPE->hStereoMdct->split_ratio = round_fx( L_mult( SMDCT_BITRATE_RATIO_RANGE, ratio_fx ) ); /* Q0 */
    1113       83762 :         move16();
    1114             :         /* Tuning to get closer to the optimal split ratio */
    1115       83762 :         IF( LT_32( L_mult0( 9, ratio_fx ), 8 * ONE_IN_Q15 ) && GT_16( hCPE->hStereoMdct->split_ratio, SMDCT_EQUAL_RATIO_RANGE + ( SMDCT_BITRATE_RATIO_RANGE >> 4 ) ) )
    1116             :         {
    1117       64698 :             hCPE->hStereoMdct->split_ratio = sub( hCPE->hStereoMdct->split_ratio, SMDCT_BITRATE_RATIO_RANGE >> 3 ); /* Q0 */
    1118       64698 :             move16();
    1119             :         }
    1120       83762 :         IF( GT_32( L_mult0( 9, ratio_fx ), 1 * ONE_IN_Q15 ) && LT_16( hCPE->hStereoMdct->split_ratio, SMDCT_EQUAL_RATIO_RANGE - ( SMDCT_BITRATE_RATIO_RANGE >> 4 ) ) )
    1121             :         {
    1122        1139 :             hCPE->hStereoMdct->split_ratio = add( hCPE->hStereoMdct->split_ratio, SMDCT_BITRATE_RATIO_RANGE >> 3 ); /* Q0 */
    1123        1139 :             move16();
    1124             :         }
    1125             : 
    1126       83762 :         hCPE->hStereoMdct->split_ratio = s_min( SMDCT_BITRATE_RATIO_RANGE - 1, s_max( 1, hCPE->hStereoMdct->split_ratio ) ); /* Q0 */
    1127       83762 :         move16();
    1128             :     }
    1129             : 
    1130       83783 :     return;
    1131             : }
    1132             : 
    1133             : /*-------------------------------------------------------------------*
    1134             :  * MsStereoDecision()
    1135             :  *
    1136             :  *
    1137             :  *-------------------------------------------------------------------*/
    1138             : 
    1139      142051 : static void MsStereoDecision_fx(
    1140             :     STEREO_MDCT_BAND_PARAMETERS *sfbParam,
    1141             :     Word32 *specL_fx, /* Q( q_spec ) */
    1142             :     Word32 *specR_fx, /* Q( q_spec ) */
    1143             :     Word32 *specM_fx,
    1144             :     /* scratch buffer for M, use buffer for inverse MS mask spectrum */ /* Q( q_spec ) */
    1145             :     Word32 *specS_fx,
    1146             :     /* scratch buffer for M, use buffer for inverse MS mask spectrum */ /* Q( q_spec ) */
    1147             :     Word16 q_spec,
    1148             :     Word16 *mdct_stereo_mode, /* output Q0*/
    1149             :     Word16 *msMask,           /* output Q0*/
    1150             :     const Word16 nBitsAvailable /*Q0*/ )
    1151             : {
    1152      142051 :     Word16 length = sfbParam->sfbOffset[sfbParam->nBandsStereoCore]; /* Q0 */
    1153             : 
    1154             :     Word16 bitsL, bitsR, bitsM, bitsS;
    1155             :     Word16 bitsBW, bitsLR, bitsMS;
    1156             :     Word16 sfb, i;
    1157             :     Word16 nMSOn; /* Number of MS active bands */
    1158             :     Word16 quantSpecL[N_MAX];
    1159             :     Word16 quantSpecR[N_MAX];
    1160             :     Word16 quantSpecM[N_MAX];
    1161             :     Word16 quantSpecS[N_MAX];
    1162             :     RC_CONTEXT_MEM ctxMem[4];
    1163             :     HANDLE_RC_CONTEXT_MEM ctxL, ctxR, ctxM, ctxS;
    1164             : 
    1165      142051 :     set16_fx( quantSpecL, 0, N_MAX );
    1166      142051 :     set16_fx( quantSpecR, 0, N_MAX );
    1167      142051 :     set16_fx( quantSpecM, 0, N_MAX );
    1168      142051 :     set16_fx( quantSpecS, 0, N_MAX );
    1169             : 
    1170      142051 :     assert( GT_16( nBitsAvailable, 0 ) );
    1171             : 
    1172      142051 :     ctxL = &ctxMem[0];
    1173      142051 :     ctxR = &ctxMem[1];
    1174      142051 :     ctxM = &ctxMem[2];
    1175      142051 :     ctxS = &ctxMem[3];
    1176             :     Word16 specL_e, specR_e, specM_e, specS_e, G_fx, G_e;
    1177             :     Word16 e_GLR;
    1178             :     Word32 GLR_fx;
    1179             : 
    1180      142051 :     specL_e = sub( Q31, q_spec );
    1181      142051 :     specR_e = sub( Q31, q_spec );
    1182      142051 :     specM_e = sub( Q31, q_spec );
    1183      142051 :     specS_e = sub( Q31, q_spec );
    1184             : 
    1185      142051 :     GLR_fx = SQ_gain_estimate_stereo_fx( specL_fx, specL_e, specR_fx, specR_e, nBitsAvailable, length, &e_GLR ); /* Q31-e_GLR */
    1186             : 
    1187    80821715 :     FOR( i = 0; i < length; i++ )
    1188             :     {
    1189    80679664 :         specM_fx[i] = Mpy_32_32( L_add( specL_fx[i], specR_fx[i] ), SQRT2_OVER_2_FIXED ); // Q( q_spec )
    1190    80679664 :         move32();
    1191    80679664 :         specS_fx[i] = Mpy_32_32( L_sub( specL_fx[i], specR_fx[i] ), SQRT2_OVER_2_FIXED ); // Q( q_spec )
    1192    80679664 :         move32();
    1193             :     }
    1194             : 
    1195      142051 :     G_fx = extract_h( GLR_fx ); /* seems to be favourable to underestimate a bit Q15-e_GLR*/
    1196      142051 :     G_e = sub( e_GLR, 1 );
    1197             : 
    1198             :     /* do the full spectrum estimates already here, as side effect we get the quantized spectra... */
    1199      142051 :     bitsLR = add( QuantSpecEstimateBits_fx( specL_fx, specL_e, G_fx, G_e, length, nBitsAvailable, quantSpecL ), QuantSpecEstimateBits_fx( specR_fx, specR_e, G_fx, G_e, length, nBitsAvailable, quantSpecR ) ); /* Q0 */
    1200      142051 :     bitsMS = add( QuantSpecEstimateBits_fx( specM_fx, specM_e, G_fx, G_e, length, nBitsAvailable, quantSpecM ), QuantSpecEstimateBits_fx( specS_fx, specS_e, G_fx, G_e, length, nBitsAvailable, quantSpecS ) ); /* Q0 */
    1201             : 
    1202             :     /* clean-up MS scratch buffers */
    1203      142051 :     set32_fx( specM_fx, 0, length );
    1204      142051 :     set32_fx( specS_fx, 0, length );
    1205             : 
    1206      142051 :     nMSOn = 0;
    1207      142051 :     move16();
    1208      142051 :     bitsBW = 0;
    1209      142051 :     move16();
    1210             : 
    1211      142051 :     RCcontextMapping_encode2_estimate_bandWise_start_fx( quantSpecL, length, nBitsAvailable, ctxL );
    1212      142051 :     RCcontextMapping_encode2_estimate_bandWise_start_fx( quantSpecR, length, nBitsAvailable, ctxR );
    1213             : 
    1214      142051 :     bitsBW = add( bitsBW, RCcontextMapping_encode2_estimate_bandWise_start_fx( quantSpecM, length, nBitsAvailable, ctxM ) ); /* Q0 */
    1215      142051 :     bitsBW = add( bitsBW, RCcontextMapping_encode2_estimate_bandWise_start_fx( quantSpecS, length, nBitsAvailable, ctxS ) ); /* Q0 */
    1216             : 
    1217             :     /*find_max_lastnz(ctxL,ctxR,ctxM,ctxS);*/
    1218             : 
    1219     5791716 :     FOR( sfb = 0; sfb < sfbParam->nBandsStereoCore; sfb++ )
    1220             :     {
    1221     5649665 :         const Word16 startline = sfbParam->sfbOffset[sfb];
    1222     5649665 :         move16();
    1223     5649665 :         const Word16 endline = sfbParam->sfbOffset[sfb + 1];
    1224     5649665 :         move16();
    1225             : 
    1226     5649665 :         bitsL = RCcontextMapping_encode2_estimate_bandWise_fx( quantSpecL, startline, endline, ctxL );
    1227     5649665 :         bitsR = RCcontextMapping_encode2_estimate_bandWise_fx( quantSpecR, startline, endline, ctxR );
    1228     5649665 :         bitsM = RCcontextMapping_encode2_estimate_bandWise_fx( quantSpecM, startline, endline, ctxM );
    1229     5649665 :         bitsS = RCcontextMapping_encode2_estimate_bandWise_fx( quantSpecS, startline, endline, ctxS );
    1230             : 
    1231     5649665 :         IF( LE_16( add( bitsM, bitsS ), add( bitsL, bitsR ) ) )
    1232             :         {
    1233     4241882 :             msMask[sfb] = 1;
    1234     4241882 :             move16();
    1235     4241882 :             nMSOn = add( nMSOn, 1 );
    1236     4241882 :             context_update_fx( ctxM, ctxL, endline );
    1237     4241882 :             context_update_fx( ctxS, ctxR, endline );
    1238     4241882 :             bitsBW = add( bitsBW, add( bitsM, bitsS ) ); /* Q0 */
    1239             :         }
    1240             :         ELSE
    1241             :         {
    1242     1407783 :             msMask[sfb] = 0;
    1243     1407783 :             move16();
    1244             : 
    1245     1407783 :             context_update_fx( ctxL, ctxM, endline );
    1246     1407783 :             context_update_fx( ctxR, ctxS, endline );
    1247     1407783 :             bitsBW = add( bitsBW, add( bitsL, bitsR ) ); /* Q0 */
    1248             :         }
    1249             :     }
    1250             : 
    1251      142051 :     bitsBW = add( bitsBW, sfbParam->nBandsStereoCore ); /* Signaling bits Q0*/
    1252             : 
    1253      142051 :     IF( LT_16( bitsLR, bitsBW ) )
    1254             :     {
    1255        8666 :         nMSOn = 0;
    1256        8666 :         move16();
    1257        8666 :         set16_fx( msMask, 0, sfbParam->sfbCnt );
    1258        8666 :         bitsBW = bitsLR;
    1259        8666 :         move16();
    1260             :     }
    1261             : 
    1262      142051 :     IF( LT_16( bitsMS, bitsBW ) )
    1263             :     {
    1264       83549 :         nMSOn = sfbParam->nBandsStereoCore;
    1265       83549 :         move16();
    1266       83549 :         set16_fx( msMask, 1, sfbParam->sfbCnt );
    1267             :     }
    1268             : 
    1269      142051 :     *mdct_stereo_mode = SMDCT_BW_MS;
    1270      142051 :     move16();
    1271      142051 :     IF( EQ_16( nMSOn, sfbParam->nBandsStereoCore ) )
    1272             :     {
    1273       83549 :         *mdct_stereo_mode = SMDCT_MS_FULL;
    1274       83549 :         move16();
    1275             :     }
    1276       58502 :     ELSE IF( nMSOn == 0 )
    1277             :     {
    1278        7470 :         *mdct_stereo_mode = SMDCT_DUAL_MONO;
    1279        7470 :         move16();
    1280             :     }
    1281             : 
    1282      142051 :     return;
    1283             : }
    1284             : 
    1285             : 
    1286             : /*-----------------------------------------------------------------------*
    1287             :  * initMdctStereoEncData()
    1288             :  *
    1289             :  * initialize encoder mdct stereo structure
    1290             :  *-----------------------------------------------------------------------*/
    1291             : 
    1292       76307 : void initMdctStereoEncData_fx(
    1293             :     STEREO_MDCT_ENC_DATA *hStereoMdct, /* i/o: mdct stereo parameters structure   */
    1294             :     const IVAS_FORMAT ivas_format,     /* i  : IVAS format                        */
    1295             :     const Word16 element_mode,         /* i  : element mode                       Q0*/
    1296             :     const Word32 element_brate,        /* i  : element bitrate                    Q0*/
    1297             :     const Word16 bwidth,               /* i  : bandwidth                          Q0*/
    1298             :     const Word16 igf,                  /* i  : flag indicating IGF activity       Q0*/
    1299             :     const H_IGF_GRID hIgfGrid,         /* i  : IGF grid setup                     */
    1300             :     const Word16 mem_init              /* i  : initialize memory after malloc     Q0*/
    1301             : )
    1302             : {
    1303             :     Word16 tcx_coded_lines;
    1304             : 
    1305       76307 :     tcx_coded_lines = getNumTcxCodedLines( bwidth ); /* Q0 */
    1306             : 
    1307             :     /*initialize mdct stereo mode*/
    1308       76307 :     set16_fx( hStereoMdct->mdct_stereo_mode, -1, 2 );
    1309             : 
    1310             :     /*Initialize sfb parameteres for TCX20 */
    1311       76307 :     stereo_mdct_init_bands_fx( tcx_coded_lines, TCX_20_CORE, element_brate, igf, igf ? &hIgfGrid[IGF_GRID_LB_NORM] : NULL, &hStereoMdct->stbParamsTCX20.sfbOffset[0], &hStereoMdct->stbParamsTCX20.sfbCnt );
    1312             : 
    1313             :     /*Initialize sfb parameteres for TCX10 */
    1314       76307 :     stereo_mdct_init_bands_fx( tcx_coded_lines, TCX_10_CORE, element_brate, igf, igf ? &hIgfGrid[IGF_GRID_LB_SHORT] : NULL,
    1315             :                                &hStereoMdct->stbParamsTCX10.sfbOffset[0], &hStereoMdct->stbParamsTCX10.sfbCnt );
    1316             : 
    1317             :     /*Initialize sfb parameteres for transitions */
    1318       76307 :     stereo_mdct_init_bands_fx( tcx_coded_lines, -1, element_brate, igf, igf ? &hIgfGrid[IGF_GRID_LB_TRAN] : NULL,
    1319             :                                &hStereoMdct->stbParamsTCX20afterACELP.sfbOffset[0], &hStereoMdct->stbParamsTCX20afterACELP.sfbCnt );
    1320             : 
    1321       76307 :     set16_fx( hStereoMdct->IGFStereoMode, -1, 2 );
    1322             : 
    1323       76307 :     hStereoMdct->split_ratio = SMDCT_EQUAL_RATIO_RANGE; /* Q0 */
    1324       76307 :     move16();
    1325       76307 :     set16_fx( hStereoMdct->global_ild, SMDCT_ILD_RANGE >> 1, 2 );
    1326             : 
    1327       76307 :     IF( mem_init )
    1328             :     {
    1329        3550 :         hStereoMdct->hItd = NULL;
    1330        3550 :         hStereoMdct->hDft_ana = NULL;
    1331             :     }
    1332             : 
    1333       76307 :     test();
    1334       76307 :     test();
    1335       76307 :     IF( !( EQ_16( element_mode, IVAS_CPE_MDCT ) && LE_32( element_brate, MAX_MDCT_ITD_BRATE ) && EQ_32( ivas_format, STEREO_FORMAT ) ) )
    1336             :     {
    1337       25747 :         IF( hStereoMdct->hDft_ana != NULL )
    1338             :         {
    1339          25 :             free( hStereoMdct->hDft_ana );
    1340          25 :             hStereoMdct->hDft_ana = NULL;
    1341             :         }
    1342             : 
    1343       25747 :         IF( hStereoMdct->hItd != NULL )
    1344             :         {
    1345          25 :             free( hStereoMdct->hItd );
    1346          25 :             hStereoMdct->hItd = NULL;
    1347             :         }
    1348             :     }
    1349             : 
    1350       76307 :     return;
    1351             : }
    1352             : 
    1353             : 
    1354             : /*-----------------------------------------------------------------------*
    1355             :  * initMdctItdHandling()
    1356             :  *
    1357             :  * initialize encoder mdct ITD handling structures
    1358             :  *-----------------------------------------------------------------------*/
    1359             : 
    1360         151 : ivas_error initMdctItdHandling_fx(
    1361             :     STEREO_MDCT_ENC_DATA *hStereoMdct, /* i/o: mdct stereo parameters structure */
    1362             :     const Word32 input_Fs              /* i  : input sampling rate              Q0*/
    1363             : )
    1364             : {
    1365         151 :     test();
    1366         151 :     test();
    1367         151 :     IF( hStereoMdct->hItd == NULL )
    1368             :     {
    1369          67 :         IF( ( hStereoMdct->hItd = (ITD_DATA_HANDLE) malloc( sizeof( ITD_DATA ) ) ) == NULL )
    1370             :         {
    1371           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for ITD data\n" ) );
    1372             :         }
    1373             :     }
    1374             : 
    1375         151 :     test();
    1376         151 :     test();
    1377         151 :     IF( hStereoMdct->hDft_ana == NULL )
    1378             :     {
    1379          67 :         IF( ( hStereoMdct->hDft_ana = (DFT_ANA_HANDLE) malloc( sizeof( DFT_ANA ) ) ) == NULL )
    1380             :         {
    1381           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for ITD data\n" ) );
    1382             :         }
    1383             :     }
    1384             : 
    1385             :     /*Initialize ITD parameters*/
    1386         151 :     stereo_enc_itd_init_fx( hStereoMdct->hItd );
    1387             : 
    1388             :     /*Initialize DFT analysis parameters*/
    1389         151 :     dft_ana_init_fx( hStereoMdct->hDft_ana, input_Fs );
    1390             : 
    1391         151 :     return IVAS_ERR_OK;
    1392             : }
    1393             : 
    1394             : /*-------------------------------------------------------------------------
    1395             :  * stereo_mdct_enc_destroy()
    1396             :  *
    1397             :  * destroy MDCT stereo handle
    1398             :  *-------------------------------------------------------------------------*/
    1399             : 
    1400        1123 : void stereo_mdct_enc_destroy_fx(
    1401             :     STEREO_MDCT_ENC_DATA_HANDLE *hStereoMdct /* i/o: encoder MDCT stereo handle */
    1402             : )
    1403             : {
    1404        1123 :     IF( ( *hStereoMdct )->hDft_ana != NULL )
    1405             :     {
    1406          42 :         free( ( *hStereoMdct )->hDft_ana );
    1407          42 :         ( *hStereoMdct )->hDft_ana = NULL;
    1408             :     }
    1409             : 
    1410        1123 :     IF( ( *hStereoMdct )->hItd != NULL )
    1411             :     {
    1412          42 :         free( ( *hStereoMdct )->hItd );
    1413          42 :         ( *hStereoMdct )->hItd = NULL;
    1414             :     }
    1415             : 
    1416        1123 :     free( *hStereoMdct );
    1417        1123 :     *hStereoMdct = NULL;
    1418             : 
    1419        1123 :     return;
    1420             : }

Generated by: LCOV version 1.14