LCOV - code coverage report
Current view: top level - lib_enc - ivas_stereo_td_enc_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 574a190e3c6896c6c4ed10d7f23649709a0c4347 Lines: 444 526 84.4 %
Date: 2025-06-27 02:59:36 Functions: 8 8 100.0 %

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : #include <stdint.h>
      34             : #include <math.h>
      35             : #include "options.h"
      36             : #include "cnst.h"
      37             : #include "rom_com.h"
      38             : #include "prot_fx.h"
      39             : #include "ivas_rom_com.h"
      40             : #include "wmc_auto.h"
      41             : #ifdef DEBUGGING
      42             : #include "debug.h"
      43             : #endif
      44             : #include "prot_fx_enc.h"
      45             : #include "ivas_prot_fx.h"
      46             : #include "ivas_rom_com_fx.h"
      47             : 
      48             : 
      49             : /*-------------------------------------------------------------------*
      50             :  * stereo_td_init_enc()
      51             :  *
      52             :  * Initialize TD stereo encoder
      53             :  *-------------------------------------------------------------------*/
      54          60 : void stereo_td_init_enc_fx(
      55             :     STEREO_TD_ENC_DATA_HANDLE hStereoTD, /* i/o: TD stereo encoder handle    */
      56             :     const Word16 last_element_mode       /* i  : last element mode           */
      57             : )
      58             : {
      59          60 :     hStereoTD->tdm_lt_corr_RM_fx = 167772; // Q24
      60          60 :     move32();
      61          60 :     hStereoTD->tdm_lt_corr_LM_fx = 167772; // Q24
      62          60 :     move32();
      63          60 :     hStereoTD->tdm_last_ratio_fx = 1073741824; // Q31
      64          60 :     move32();
      65          60 :     hStereoTD->tdm_last_ratio_idx = LRTD_STEREO_MID_IS_PRIM;
      66          60 :     move16();
      67          60 :     hStereoTD->tdm_lt_rms_L_fx = 2621440; // Q16
      68          60 :     move32();
      69          60 :     hStereoTD->tdm_lt_rms_R_fx = 2621440; // Q16
      70          60 :     move32();
      71          60 :     hStereoTD->tdm_last_diff_lt_corr_fx = 0;
      72          60 :     move32();
      73          60 :     hStereoTD->q_tdm_last_diff_lt_corr = Q31;
      74          60 :     move16();
      75          60 :     hStereoTD->tdm_last_ener_lt_R_fx = 0;
      76          60 :     move32();
      77          60 :     hStereoTD->tdm_last_ener_lt_L_fx = 0;
      78          60 :     move32();
      79             : 
      80          60 :     hStereoTD->tdm_ratio_transition_mov_flag = 0;
      81          60 :     move16();
      82          60 :     hStereoTD->tdm_ratio_transition_cnt = 0;
      83          60 :     move16();
      84          60 :     hStereoTD->tdm_noop_mov_flag = 0;
      85          60 :     move16();
      86          60 :     hStereoTD->tdm_noop_cnt = 0;
      87          60 :     move16();
      88          60 :     hStereoTD->tdm_last_SM_flag = 0;
      89          60 :     move16();
      90             : 
      91          60 :     hStereoTD->tdm_last_ratio_idx = LRTD_STEREO_MID_IS_PRIM;
      92          60 :     move16();
      93          60 :     hStereoTD->tdm_prev_stable_idx = LRTD_STEREO_MID_IS_PRIM;
      94          60 :     move16();
      95          60 :     hStereoTD->tdm_prev_desired_idx = LRTD_STEREO_MID_IS_PRIM;
      96          60 :     move16();
      97          60 :     hStereoTD->tdm_FD2LRTD_SW_cnt = 0;
      98          60 :     move16();
      99          60 :     hStereoTD->tdm_LT_es_em_fx = 209715; // Q21
     100          60 :     move32();
     101          60 :     hStereoTD->tdm_hyst_cnt = 0;
     102          60 :     move16();
     103             :     /* NOOP parameters */
     104          60 :     hStereoTD->tdm_lt_corr_RM_SM_fx = 167772 /*0.01f Q24*/;
     105          60 :     move32();
     106          60 :     hStereoTD->tdm_lt_corr_LM_SM_fx = 167772 /*0.01f Q24*/;
     107          60 :     hStereoTD->tdm_last_ratio_SM_fx = 1073741824; // Q31
     108          60 :     move32();
     109          60 :     hStereoTD->tdm_last_ratio_idx_SM = 0;
     110          60 :     move16();
     111          60 :     hStereoTD->q_tdm_last_diff_lt_corr_SM = Q31;
     112          60 :     move16();
     113          60 :     hStereoTD->tdm_lt_rms_L_SM_fx = 2621440; // Q16
     114          60 :     move32();
     115          60 :     hStereoTD->tdm_lt_rms_R_SM_fx = 2621440; // Q16
     116          60 :     move32();
     117          60 :     hStereoTD->tdm_last_diff_lt_corr_SM_fx = 0;
     118          60 :     move32();
     119          60 :     hStereoTD->q_tdm_last_diff_lt_corr_SM = Q31;
     120          60 :     move16();
     121          60 :     hStereoTD->tdm_last_ener_lt_R_SM_fx = 0;
     122          60 :     move32();
     123          60 :     hStereoTD->tdm_last_ener_lt_L_SM_fx = 0;
     124          60 :     move32();
     125          60 :     hStereoTD->tdm_noop_mov_flag = 0;
     126          60 :     move16();
     127          60 :     hStereoTD->tdm_NOOP_cnt = 0;
     128          60 :     move16();
     129          60 :     hStereoTD->tdm_last_SM_flag_noop = 0;
     130          60 :     move16();
     131          60 :     hStereoTD->tdm_last_ratio_idx_SM = LRTD_STEREO_MID_IS_PRIM;
     132          60 :     move16();
     133          60 :     hStereoTD->tdm_prev_stable_idx_SM = LRTD_STEREO_MID_IS_PRIM;
     134          60 :     move16();
     135          60 :     hStereoTD->tdm_prev_desired_idx_SM = LRTD_STEREO_MID_IS_PRIM;
     136          60 :     move16();
     137          60 :     hStereoTD->tdm_LT_es_em_SM_fx = 209715; // Q21
     138          60 :     move32();
     139          60 :     hStereoTD->tdm_hyst_cnt_SM = 0;
     140          60 :     move16();
     141          60 :     hStereoTD->tdm_noop_cnt = 0;
     142          60 :     move16();
     143          60 :     hStereoTD->tdm_SM_flag = 0;
     144          60 :     move16();
     145          60 :     hStereoTD->tdm_SM_last_clas[0] = VOICED_CLAS;
     146          60 :     move16();
     147          60 :     hStereoTD->tdm_SM_last_clas[1] = VOICED_CLAS;
     148          60 :     move16();
     149          60 :     hStereoTD->tdm_SM_last2_clas[0] = VOICED_CLAS;
     150          60 :     move16();
     151          60 :     hStereoTD->tdm_SM_last2_clas[1] = VOICED_CLAS;
     152          60 :     move16();
     153          60 :     hStereoTD->tdm_SM_modi_flag = 0;
     154          60 :     move16();
     155          60 :     hStereoTD->tdm_SM_reset_flag = 0;
     156          60 :     move16();
     157          60 :     hStereoTD->prev_fr_LRTD_TD_dec = 0;
     158          60 :     move16();
     159          60 :     hStereoTD->tdm_LRTD_flag = 0;
     160          60 :     move16();
     161          60 :     hStereoTD->tdm_inst_ratio_idx = LRTD_STEREO_RIGHT_IS_PRIM;
     162          60 :     move16();
     163          60 :     hStereoTD->tdm_last_inst_ratio_idx = LRTD_STEREO_MID_IS_PRIM;
     164          60 :     move16();
     165          60 :     hStereoTD->tdm_last_LRTD_frame_cnt = 0;
     166          60 :     move16();
     167          60 :     hStereoTD->tdm_vad_hangover_cnt = 0;
     168          60 :     move16();
     169          60 :     hStereoTD->tdm_ini_frame_cnt = 0;
     170          60 :     move16();
     171          60 :     hStereoTD->tdm_last_LRTD_PriCh_cnt = 0;
     172          60 :     move16();
     173             : 
     174          60 :     hStereoTD->flag_skip_DMX = 0;
     175          60 :     move16();
     176          60 :     IF( EQ_16( last_element_mode, IVAS_CPE_MDCT ) )
     177             :     {
     178           8 :         hStereoTD->flag_skip_DMX = 1;
     179           8 :         move16();
     180           8 :         hStereoTD->prev_fr_LRTD_TD_dec = 1;
     181           8 :         move16();
     182           8 :         hStereoTD->tdm_last_ratio_fx = MAX_32; // Q31
     183           8 :         move32();
     184           8 :         hStereoTD->tdm_last_ratio_idx = LRTD_STEREO_LEFT_IS_PRIM;
     185           8 :         move16();
     186           8 :         hStereoTD->tdm_prev_stable_idx = LRTD_STEREO_LEFT_IS_PRIM;
     187           8 :         move16();
     188           8 :         hStereoTD->tdm_prev_desired_idx = LRTD_STEREO_LEFT_IS_PRIM;
     189           8 :         move16();
     190             :     }
     191             : 
     192          60 :     hStereoTD->tdm_hBstr_tmp.ind_list = hStereoTD->tdm_ind_list_tmp;
     193          60 :     hStereoTD->tdm_hBstr_tmp.ivas_ind_list_zero = (Indice **) ( &hStereoTD->tdm_hBstr_tmp.ind_list );
     194          60 :     hStereoTD->max_ind_tdm_tmp = MAX_IND_TDM_TMP;
     195          60 :     move32();
     196          60 :     hStereoTD->tdm_hBstr_tmp.ivas_max_num_indices = &hStereoTD->max_ind_tdm_tmp;
     197          60 :     hStereoTD->tdm_hBstr_tmp.st_ivas = NULL;
     198          60 :     reset_indices_enc_fx( &hStereoTD->tdm_hBstr_tmp, MAX_IND_TDM_TMP );
     199             : 
     200          60 :     return;
     201             : }
     202             : 
     203             : /*-------------------------------------------------------------------*
     204             :  * stereo_set_tdm()
     205             :  *
     206             :  * Set TD stereo encoder parameters
     207             :  *-------------------------------------------------------------------*/
     208             : 
     209      410255 : ivas_error stereo_set_tdm_fx(
     210             :     CPE_ENC_HANDLE hCPE,      /* i  : CPE encoder structure           */
     211             :     const Word16 input_frame, /* i  : input frame length per channel  */
     212             :     Word16 input_q )
     213             : {
     214             :     Encoder_State **sts;
     215      410255 :     sts = hCPE->hCoreCoder;
     216             :     ivas_error error;
     217             : 
     218      410255 :     error = IVAS_ERR_OK;
     219             : 
     220             :     /* initialize TD stereo parameters */
     221      410255 :     IF( hCPE->hStereoTD != NULL )
     222             :     {
     223        3811 :         hCPE->hStereoTD->tdm_lp_reuse_flag = 0;
     224        3811 :         move16();
     225        3811 :         hCPE->hStereoTD->tdm_low_rate_mode = 0;
     226        3811 :         move16();
     227        3811 :         hCPE->hStereoTD->tdm_Pitch_reuse_flag = 0;
     228        3811 :         move16();
     229             : 
     230        3811 :         IF( EQ_16( hCPE->hStereoClassif->lrtd_mode, 1 ) )
     231             :         {
     232             :             /* initialize this flag when uncorrelated L&R channels have been detected in the previous frame */
     233        3811 :             test();
     234        3811 :             test();
     235        3811 :             IF( EQ_16( hCPE->hStereoTD->prev_fr_LRTD_TD_dec, 1 ) || NE_16( hCPE->last_element_mode, IVAS_CPE_TD ) || LT_16( hCPE->hStereoTD->tdm_FD2LRTD_SW_cnt, 5 ) )
     236             :             {
     237        3690 :                 hCPE->hStereoTD->tdm_LRTD_flag = 1;
     238        3690 :                 move16();
     239             :             }
     240             :             ELSE
     241             :             {
     242         121 :                 hCPE->hStereoTD->tdm_LRTD_flag = 0;
     243         121 :                 move16();
     244             :             }
     245             :         }
     246             :         ELSE
     247             :         {
     248           0 :             hCPE->hStereoTD->tdm_LRTD_flag = hCPE->hStereoTD->prev_fr_LRTD_TD_dec;
     249           0 :             move16();
     250             :         }
     251             : 
     252             : #ifdef DEBUG_MODE_INFO
     253             :         dbgwrite( &hCPE->hStereoTD->tdm_LRTD_flag, 2, 1, (int16_t) ( hCPE->hCoreCoder[0]->input_Fs / FRAMES_PER_SEC ), "res/tdm_LRTD_flag" );
     254             : #endif
     255             : 
     256             : 
     257             :         /* normal TD / LRTD switching */
     258        3811 :         IF( EQ_16( hCPE->hStereoTD->tdm_LRTD_flag, 0 ) )
     259             :         {
     260             :             Encoder_State *st;
     261         121 :             st = hCPE->hCoreCoder[1];
     262             : 
     263             :             /* deallocate CLDFB ana for secondary channel */
     264         121 :             IF( st->cldfbAnaEnc != NULL )
     265             :             {
     266          33 :                 deleteCldfb_ivas_fx( &st->cldfbAnaEnc );
     267             :             }
     268             : 
     269             :             /* deallocate BWEs for secondary channel */
     270         121 :             IF( st->hBWE_TD != NULL )
     271             :             {
     272          33 :                 IF( st->hBWE_TD != NULL )
     273             :                 {
     274          33 :                     free( st->hBWE_TD );
     275          33 :                     st->hBWE_TD = NULL;
     276             :                 }
     277             : 
     278          33 :                 deleteCldfb_ivas_fx( &st->cldfbSynTd );
     279             : 
     280          33 :                 IF( st->hBWE_FD != NULL )
     281             :                 {
     282          33 :                     free( st->hBWE_FD );
     283          33 :                     st->hBWE_FD = NULL;
     284             :                 }
     285             :             }
     286             : 
     287             :             /* allocate ICBWE structure */
     288         121 :             IF( hCPE->hStereoICBWE == NULL )
     289             :             {
     290          33 :                 IF( ( hCPE->hStereoICBWE = (STEREO_ICBWE_ENC_HANDLE) malloc( sizeof( STEREO_ICBWE_ENC_DATA ) ) ) == NULL )
     291             :                 {
     292           0 :                     return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Stereo ICBWE \n" ) );
     293             :                 }
     294          33 :                 stereo_icBWE_init_enc_fx( hCPE->hStereoICBWE );
     295             :             }
     296             :         }
     297             :         ELSE /* tdm_LRTD_flag == 1 */
     298             :         {
     299             :             Encoder_State *st;
     300        3690 :             st = hCPE->hCoreCoder[1];
     301             : 
     302             :             /* deallocate ICBWE structure */
     303        3690 :             IF( hCPE->hStereoICBWE != NULL )
     304             :             {
     305          52 :                 free( hCPE->hStereoICBWE );
     306          52 :                 hCPE->hStereoICBWE = NULL;
     307             :             }
     308             : 
     309             :             /* allocate CLDFB ana for secondary channel */
     310        3690 :             IF( st->cldfbAnaEnc == NULL )
     311             :             {
     312          60 :                 IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, ENC ) ), IVAS_ERR_OK ) )
     313             :                 {
     314           0 :                     return error;
     315             :                 }
     316             :             }
     317             : 
     318             :             /* allocate BWEs for secondary channel */
     319        3690 :             IF( st->hBWE_TD == NULL )
     320             :             {
     321          60 :                 IF( ( st->hBWE_TD = (TD_BWE_ENC_HANDLE) malloc( sizeof( TD_BWE_ENC_DATA ) ) ) == NULL )
     322             :                 {
     323           0 :                     return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD BWE\n" ) );
     324             :                 }
     325          60 :                 IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, ENC ) ), IVAS_ERR_OK ) )
     326             :                 {
     327           0 :                     return error;
     328             :                 }
     329             : 
     330          60 :                 InitSWBencBuffer_ivas_fx( st );
     331          60 :                 ResetSHBbuffer_Enc_fx( st );
     332             : 
     333          60 :                 IF( ( st->hBWE_FD = (FD_BWE_ENC_HANDLE) malloc( sizeof( FD_BWE_ENC_DATA ) ) ) == NULL )
     334             :                 {
     335           0 :                     return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FD BWE\n" ) );
     336             :                 }
     337             : 
     338          60 :                 fd_bwe_enc_init_fx( st->hBWE_FD );
     339          60 :                 st->Q_old_wtda = 0;
     340          60 :                 move16();
     341             :             }
     342             :         }
     343             : 
     344        3811 :         IF( hCPE->hStereoClassif->lrtd_mode == 0 )
     345             :         {
     346           0 :             hCPE->hStereoTD->tdm_FD2LRTD_SW_cnt = 0;
     347           0 :             move16();
     348             :         }
     349        3811 :         hCPE->hStereoTD->tdm_FD2LRTD_SW_cnt = s_min( 100, hCPE->hStereoTD->tdm_FD2LRTD_SW_cnt + 1 );
     350        3811 :         move16();
     351        3811 :         stereo_tdm_prep_dwnmx_fx( hCPE, sts[1]->input32_fx, input_frame, input_q );
     352             :     }
     353             :     ELSE
     354             :     {
     355             : #ifdef DEBUG_MODE_INFO
     356             :         {
     357             :             int16_t tmp = -2;
     358             :             dbgwrite( &tmp, 2, 1, (int16_t) ( hCPE->hCoreCoder[0]->input_Fs / FRAMES_PER_SEC ), "res/tdm_LRTD_flag" );
     359             :         }
     360             : #endif
     361      406444 :         hCPE->hCoreCoder[0]->tdm_LRTD_flag = 0;
     362      406444 :         move16();
     363      406444 :         hCPE->hCoreCoder[1]->tdm_LRTD_flag = 0;
     364      406444 :         move16();
     365             :     }
     366             : 
     367      410255 :     return error;
     368             : }
     369             : /*-------------------------------------------------------------------*
     370             :  * tdm_configure_enc()
     371             :  *
     372             :  * Configure TD stereo encoder
     373             :  *-------------------------------------------------------------------*/
     374        3811 : void tdm_configure_enc_fx(
     375             :     const Word16 ivas_format,                /* i  : IVAS format                       */
     376             :     const Word16 ism_mode,                   /* i  : ISM mode in combined format       */
     377             :     CPE_ENC_HANDLE hCPE,                     /* i  : CPE encoder structure             */
     378             :     const Word16 Etot_last_fx[CPE_CHANNELS], /* i/o: Energy of last frame           Q8*/
     379             :     const Word16 tdm_SM_or_LRTD_Pri,         /* i  : channel combination scheme flag in TD stereo OR LRTD primary channel */
     380             :     const Word16 tdm_ratio_idx,              /* i  : ratio index                       */
     381             :     const Word16 tdm_ratio_idx_SM,           /* i  : ratio index in SM mode            */
     382             :     const Word16 attack_flag,                /* i  : Primary channel attack flag       */
     383             :     const Word16 nb_bits_metadata            /* i  : number of metadata bits           */
     384             : )
     385             : {
     386             :     Word16 tdm_ratio_bit_alloc_idx, mod_ct;
     387             :     STEREO_TD_ENC_DATA_HANDLE hStereoTD;
     388             :     Encoder_State **sts;
     389             :     Word16 loc_coder_tyape_raw0;
     390        3811 :     hStereoTD = hCPE->hStereoTD;
     391        3811 :     sts = hCPE->hCoreCoder;
     392        3811 :     loc_coder_tyape_raw0 = sts[0]->coder_type_raw;
     393        3811 :     move16();
     394             : 
     395             :     /*----------------------------------------------------------------*
     396             :      * Overwrite certain decisions depending on the input
     397             :      *----------------------------------------------------------------*/
     398             : 
     399        3811 :     hStereoTD->tdm_use_IAWB_Ave_lpc = 0; /* Flag initialisation */
     400        3811 :     move16();
     401        3811 :     sts[0]->hSpMusClas->tdm_lt_Etot_fx = add( mult( 3277 /*0.1f in Q15*/, Etot_last_fx[0] ), mult( 29491 /* 0.9f*/, sts[0]->hSpMusClas->tdm_lt_Etot_fx ) );
     402        3811 :     move16();
     403        3811 :     sts[1]->hSpMusClas->tdm_lt_Etot_fx = add( mult( 3277 /*0.1f in Q15*/, Etot_last_fx[1] ), mult( 29491 /* 0.9f*/, sts[1]->hSpMusClas->tdm_lt_Etot_fx ) );
     404        3811 :     move16();
     405             : 
     406        3811 :     test();
     407        3811 :     test();
     408        3811 :     test();
     409        3811 :     test();
     410        3811 :     test();
     411        3811 :     test();
     412        3811 :     test();
     413        3811 :     test();
     414        3811 :     test();
     415        3811 :     test();
     416        3811 :     test();
     417        3811 :     test();
     418        3811 :     test();
     419        3811 :     test();
     420        3811 :     test();
     421        3811 :     test();
     422        3811 :     test();
     423        3811 :     test();
     424        3811 :     test();
     425        3811 :     test();
     426        3811 :     test();
     427        3811 :     test();
     428        3811 :     test();
     429        3811 :     test();
     430        3811 :     test();
     431        3811 :     IF( hCPE->hStereoClassif->lrtd_mode == 0 && ( ( sts[1]->hSpMusClas->tdm_lt_Etot_fx < 0 && hCPE->hCoreCoder[1]->vad_flag == 0 ) /* very clean signal */
     432             :                                                   || ( hCPE->hCoreCoder[1]->vad_flag == 0 || ( LT_16( Etot_last_fx[1], 7680 /*30.0f*/ ) && GT_16( sub( sts[0]->hSpMusClas->tdm_lt_Etot_fx, sts[1]->hSpMusClas->tdm_lt_Etot_fx ), 6656 /*26.0f*/ ) ) ) ) )
     433             :     {
     434           0 :         sts[1]->coder_type = INACTIVE;
     435           0 :         move16();
     436             : 
     437           0 :         test();
     438           0 :         if ( hStereoTD->tdm_lp_reuse_flag == 0 && hCPE->hCoreCoder[0]->vad_flag != 0 )
     439             :         {
     440           0 :             hStereoTD->tdm_use_IAWB_Ave_lpc = 1;
     441           0 :             move16();
     442             :         }
     443           0 :         hStereoTD->tdm_lp_reuse_flag = 1;
     444           0 :         move16();
     445             :     }
     446        3811 :     ELSE IF( ( ( hCPE->hCoreCoder[1]->vad_flag == 0 ) || ( hCPE->hCoreCoder[0]->vad_flag == 0 && LT_16( Etot_last_fx[1], 7680 /*30.0f*/ ) && GT_16( sub( sts[0]->hSpMusClas->tdm_lt_Etot_fx, sts[1]->hSpMusClas->tdm_lt_Etot_fx ), 6656 /*26.0f*/ ) ) ) && ( EQ_16( hCPE->hStereoClassif->lrtd_mode, 1 ) ) /* && NO_DTX */ ) /* boths channels are inactive but not DTX used*/
     447             :     {
     448           0 :         sts[1]->coder_type = INACTIVE;
     449           0 :         move16();
     450           0 :         IF( GT_16( tdm_ratio_idx, 1 ) && LT_16( tdm_ratio_idx, 29 ) )
     451             :         {
     452           0 :             if ( hStereoTD->tdm_lp_reuse_flag == 0 && hCPE->hCoreCoder[0]->vad_flag != 0 )
     453             :             {
     454           0 :                 hStereoTD->tdm_use_IAWB_Ave_lpc = 1;
     455           0 :                 move16();
     456             :             }
     457           0 :             hStereoTD->tdm_lp_reuse_flag = 1;
     458           0 :             move16();
     459             :         }
     460             :     }
     461        3811 :     ELSE IF( !( sts[1]->sp_aud_decision0 ) && sts[1]->tc_cnt <= 0 && ( EQ_16( sts[1]->coder_type_raw, UNVOICED ) || ( EQ_16( hStereoTD->tdm_LRTD_flag, 1 ) && hStereoTD->tdm_lp_reuse_flag == 0 && ( hCPE->hCoreCoder[1]->vad_flag == 0 || ( LT_16( Etot_last_fx[1], 7680 /*30.0f*/ ) && GT_16( sub( sts[0]->hSpMusClas->tdm_lt_Etot_fx, sts[1]->hSpMusClas->tdm_lt_Etot_fx ), 6656 /*26.0f*/ ) ) ) ) ) )
     462             :     {
     463         326 :         sts[1]->coder_type = UNVOICED;
     464         326 :         move16();
     465         326 :         if ( EQ_16( hStereoTD->tdm_LRTD_flag, 1 ) )
     466             :         {
     467         256 :             hStereoTD->tdm_lp_reuse_flag = 0;
     468         256 :             move16();
     469             :         }
     470             :     }
     471        3485 :     ELSE IF( ( LT_16( sts[1]->coder_type, AUDIO ) && NE_16( sts[1]->coder_type, UNVOICED ) ) || /* TC and VC are not supported in secondary channel */
     472             :              ( ( EQ_16( sts[1]->coder_type, AUDIO ) && LE_32( hCPE->element_brate, IVAS_24k4 ) ) || ( EQ_16( sts[0]->sp_aud_decision1, 1 ) && GE_32( hCPE->element_brate, IVAS_16k4 ) ) || ( EQ_16( sts[1]->sp_aud_decision0, 1 ) && GT_32( hCPE->element_brate, IVAS_13k2 ) ) ) )
     473             :     {
     474        3485 :         sts[1]->coder_type = GENERIC;
     475        3485 :         move16();
     476             :     }
     477           0 :     ELSE IF( EQ_16( sts[1]->coder_type, GENERIC ) && EQ_16( sts[1]->coder_type_raw, UNVOICED ) )
     478             :     {
     479           0 :         hStereoTD->tdm_lp_reuse_flag = 0;
     480           0 :         move16();
     481             :     }
     482             : 
     483        3811 :     test();
     484        3811 :     IF( GT_32( hCPE->element_brate, IVAS_24k4 ) && EQ_16( hCPE->hStereoClassif->lrtd_mode, 1 ) )
     485             :     {
     486        2074 :         if ( EQ_16( sts[1]->coder_type, UNVOICED ) )
     487             :         {
     488         198 :             sts[1]->coder_type = GENERIC;
     489         198 :             move16();
     490             :         }
     491             : 
     492        2074 :         IF( EQ_16( sts[0]->coder_type, UNVOICED ) )
     493             :         {
     494         171 :             sts[0]->coder_type = GENERIC;
     495         171 :             move16();
     496         171 :             loc_coder_tyape_raw0 = GENERIC;
     497         171 :             move16();
     498             :         }
     499             :     }
     500        3811 :     test();
     501        3811 :     test();
     502        3811 :     IF( GE_32( hCPE->element_brate, IVAS_24k4 ) && hCPE->hStereoClassif->lrtd_mode == 0 && EQ_16( sts[0]->coder_type, UNVOICED ) )
     503             :     {
     504           0 :         sts[0]->coder_type = GENERIC;
     505           0 :         move16();
     506           0 :         loc_coder_tyape_raw0 = GENERIC;
     507           0 :         move16();
     508             :     }
     509             : 
     510        3811 :     if ( NE_16( sts[1]->coder_type, GENERIC ) )
     511             :     {
     512         128 :         hStereoTD->tdm_Pitch_reuse_flag = 0;
     513         128 :         move16();
     514             :     }
     515             : 
     516        3811 :     IF( attack_flag != 0 )
     517             :     {
     518          77 :         if ( sts[1]->coder_type != INACTIVE )
     519             :         {
     520          77 :             hStereoTD->tdm_lp_reuse_flag = 0; /* Do not allow the LP filter reusing on TC or attack in the primary channel */
     521          77 :             move16();
     522             :         }
     523             :     }
     524        3811 :     test();
     525        3811 :     IF( tdm_SM_or_LRTD_Pri && hStereoTD->tdm_LRTD_flag == 0 )
     526             :     {
     527           0 :         tdm_ratio_bit_alloc_idx = tdm_ratio_idx_SM;
     528           0 :         move16();
     529             :     }
     530             :     ELSE
     531             :     {
     532        3811 :         tdm_ratio_bit_alloc_idx = tdm_ratio_idx;
     533        3811 :         move16();
     534             :     }
     535        3811 :     test();
     536        3811 :     test();
     537        3811 :     test();
     538        3811 :     test();
     539        3811 :     if ( ( EQ_16( hCPE->hStereoClassif->lrtd_mode, 1 ) && GE_16( sts[1]->coder_type, UNVOICED ) && GT_16( abs_s( sub( hStereoTD->tdm_last_ratio_idx, tdm_ratio_bit_alloc_idx ) ), 15 ) ) /* channel inversion in lrtd */
     540        3776 :          || ( LT_16( hStereoTD->tdm_FD2LRTD_SW_cnt, 4 ) && LT_16( hStereoTD->tdm_last_LRTD_frame_cnt, 4 ) ) )
     541             :     {
     542         213 :         sts[1]->coder_type = GENERIC;
     543         213 :         move16();
     544             :     }
     545             : 
     546        3811 :     IF( LT_32( L_sub( L_add( hCPE->element_brate, hCPE->brate_surplus ), L_mult0( nb_bits_metadata, FRAMES_PER_SEC ) ), 12000 ) )
     547             :     {
     548           0 :         if ( EQ_16( sts[1]->coder_type, UNVOICED ) )
     549             :         {
     550           0 :             sts[1]->coder_type = GENERIC;
     551           0 :             move16();
     552             :         }
     553           0 :         hStereoTD->tdm_lp_reuse_flag = 1;
     554           0 :         move16();
     555             : 
     556           0 :         if ( LT_32( L_sub( L_add( hCPE->element_brate, hCPE->brate_surplus ), L_mult0( nb_bits_metadata, FRAMES_PER_SEC ) ), 11000 ) )
     557             :         {
     558           0 :             sts[1]->coder_type = INACTIVE;
     559           0 :             move16();
     560             :         }
     561             :     }
     562             : 
     563        3811 :     IF( LT_32( L_sub( L_add( hCPE->element_brate, hCPE->brate_surplus ), L_mult0( nb_bits_metadata, FRAMES_PER_SEC ) ), 14700 ) )
     564             :     {
     565           0 :         if ( EQ_16( sts[0]->coder_type, TRANSITION ) )
     566             :         {
     567           0 :             sts[0]->coder_type = GENERIC;
     568           0 :             move16();
     569             :         }
     570             :     }
     571             : 
     572        3811 :     mod_ct = AUDIO;
     573        3811 :     move16();
     574        3811 :     IF( LT_32( hCPE->element_brate, IVAS_24k4 ) )
     575             :     {
     576         581 :         test();
     577         581 :         test();
     578         581 :         test();
     579         581 :         test();
     580         581 :         test();
     581         581 :         test();
     582         581 :         test();
     583         581 :         test();
     584         581 :         test();
     585             :         /* In TD stereo, the TRANSITION mode has a specific bit allocation. All other formats share the same bit allocation. For these other formats, `mod_ct` is set to AUDIO to aid in debugging, though it does not have any functional impact. */
     586        1162 :         if ( !( sts[0]->localVAD == 0 && EQ_16( sts[0]->coder_type, TRANSITION ) ) &&
     587        1141 :              ( EQ_16( sts[0]->coder_type, TRANSITION ) ||
     588        1120 :                ( ( ( GE_16( sts[0]->last_L_frame, L_FRAME16k ) && sts[0]->flag_ACELP16k == 0 ) ||
     589        1116 :                    ( EQ_16( sts[0]->last_L_frame, L_FRAME ) && EQ_16( sts[0]->flag_ACELP16k, 1 ) ) ) &&
     590           4 :                  ( sts[0]->last_core_brate != FRAME_NO_DATA ) &&
     591           4 :                  NE_32( sts[0]->last_core_brate, SID_2k40 ) &&
     592           2 :                  NE_16( sts[0]->coder_type_raw, VOICED ) ) ) )
     593             :         {
     594          23 :             mod_ct = TRANSITION;
     595          23 :             move16();
     596             :         }
     597             :     }
     598             : 
     599             : 
     600             :     /* Correction of tdm_inst_ratio_idx in case of TC in the seecondary channel */
     601        3811 :     test();
     602        3811 :     test();
     603        3811 :     IF( hStereoTD->flag_skip_DMX == 0 && EQ_16( hStereoTD->tdm_LRTD_flag, 1 ) && GT_16( sts[1]->tc_cnt, 1 ) /*&& abs(hStereoTD->tdm_inst_ratio_idx-LRTD_STEREO_MID_IS_PRIM) > 5*/ )
     604             :     {
     605         143 :         IF( tdm_SM_or_LRTD_Pri == 0 ) /* Primary is right */
     606             :         {
     607           0 :             hStereoTD->tdm_inst_ratio_idx = add( hStereoTD->tdm_inst_ratio_idx, LRTD_STEREO_QUARTER_RANGE );
     608           0 :             move16();
     609             :         }
     610         143 :         ELSE IF( EQ_16( tdm_SM_or_LRTD_Pri, 1 ) ) /* Primary is left */
     611             :         {
     612         143 :             hStereoTD->tdm_inst_ratio_idx = sub( hStereoTD->tdm_inst_ratio_idx, LRTD_STEREO_QUARTER_RANGE );
     613         143 :             move16();
     614             :         }
     615         143 :         hStereoTD->tdm_inst_ratio_idx = check_bounds_s_fx( hStereoTD->tdm_inst_ratio_idx, 8, 22 );
     616         143 :         move16();
     617             :     }
     618             : 
     619             :     /*----------------------------------------------------------------*
     620             :      * bitbudget distribution between channels (taking into account also metadata bitbudget)
     621             :      *----------------------------------------------------------------*/
     622             : 
     623        3811 :     tdm_bit_alloc( ivas_format, ism_mode, L_sub( L_add( hCPE->element_brate, hCPE->brate_surplus ), L_mult0( nb_bits_metadata, FRAMES_PER_SEC ) ),
     624        3811 :                    hStereoTD->tdm_lp_reuse_flag, &( sts[0]->total_brate ), &( sts[1]->total_brate ),
     625        3811 :                    &( hStereoTD->tdm_low_rate_mode ), sts[1]->coder_type, tdm_ratio_bit_alloc_idx, hStereoTD->tdm_Pitch_reuse_flag,
     626        3811 :                    sts[0]->bwidth, sts[1]->bwidth, sts[0]->flag_ACELP16k, hStereoTD->tdm_LRTD_flag, mod_ct, hStereoTD->tdm_inst_ratio_idx );
     627        3811 :     test();
     628        3811 :     if ( sts[0]->GSC_IVAS_mode > 0 && LE_32( sts[0]->total_brate, STEREO_GSC_BIT_RATE_ALLOC ) )
     629             :     {
     630           1 :         sts[0]->GSC_IVAS_mode = 0;
     631           1 :         move16();
     632             :     }
     633        3811 :     test();
     634        3811 :     test();
     635        3811 :     if ( sts[1]->GSC_IVAS_mode > 0 && ( LE_32( sts[1]->total_brate, STEREO_GSC_BIT_RATE_ALLOC ) || EQ_16( hStereoTD->tdm_low_rate_mode, 1 ) ) )
     636             :     {
     637           0 :         sts[1]->GSC_IVAS_mode = 0;
     638           0 :         move16();
     639             :     }
     640        3811 :     test();
     641        3811 :     IF( EQ_16( sts[0]->coder_type, GENERIC ) && EQ_16( loc_coder_tyape_raw0, UNVOICED ) )
     642             :     {
     643           0 :         if ( LT_32( sts[0]->total_brate, MAX_UNVOICED_BRATE ) )
     644             :         {
     645           0 :             sts[0]->coder_type = UNVOICED;
     646           0 :             move16();
     647             :         }
     648             :     }
     649             : 
     650             :     /*----------------------------------------------------------------*
     651             :      * Bitstream writing
     652             :      *----------------------------------------------------------------*/
     653             : 
     654             :     /* transmit the ratio index */
     655        3811 :     test();
     656        3811 :     IF( tdm_SM_or_LRTD_Pri && hStereoTD->tdm_LRTD_flag == 0 )
     657             :     {
     658           0 :         push_indice( &hStereoTD->tdm_hBstr_tmp, IND_STEREO_TD_ALPHA, tdm_ratio_idx_SM, TDM_RATIO_BITS );
     659             :     }
     660             :     ELSE
     661             :     {
     662        3811 :         IF( EQ_16( hStereoTD->tdm_LRTD_flag, 1 ) )
     663             :         {
     664        3690 :             push_indice( &hStereoTD->tdm_hBstr_tmp, IND_STEREO_TD_ALPHA, hStereoTD->tdm_inst_ratio_idx, TDM_RATIO_BITS );
     665             :         }
     666             :         ELSE
     667             :         {
     668         121 :             push_indice( &hStereoTD->tdm_hBstr_tmp, IND_STEREO_TD_ALPHA, tdm_ratio_idx, TDM_RATIO_BITS );
     669             :         }
     670             :     }
     671             : 
     672             :     /* LPC reuse flag */
     673        3811 :     test();
     674        3811 :     test();
     675        3811 :     IF( sts[1]->coder_type == INACTIVE && LT_16( tdm_ratio_idx, 29 ) && GT_16( tdm_ratio_idx, 1 ) )
     676             :     {
     677             :         /* normal TD, tdm_lp_reuse_flag always on, tdm_use_IAWB_Ave_lpc varies tdm_ratio_idx<29 && tdm_ratio_idx> 1*/
     678           0 :         push_indice( &hStereoTD->tdm_hBstr_tmp, IND_STEREO_LPC_REUSE, hStereoTD->tdm_use_IAWB_Ave_lpc, TDM_LP_REUSE_BITS );
     679             :     }
     680             :     ELSE
     681             :     {
     682        3811 :         push_indice( &hStereoTD->tdm_hBstr_tmp, IND_STEREO_LPC_REUSE, hStereoTD->tdm_lp_reuse_flag, TDM_LP_REUSE_BITS );
     683             :     }
     684             : 
     685             :     /* LRTD flag */
     686        3811 :     push_indice( &hStereoTD->tdm_hBstr_tmp, IND_STEREO_LRTD_FLAG, hStereoTD->tdm_LRTD_flag, TDM_LR_CONTENT_BITS );
     687             : 
     688             :     /* Stereo ICA parameters */
     689        3811 :     IF( hStereoTD->tdm_LRTD_flag == 0 )
     690             :     {
     691         121 :         push_indice( &hStereoTD->tdm_hBstr_tmp, IND_STEREO_REFCHAN, hCPE->hStereoTCA->refChanIndx, STEREO_BITS_TCA_CHAN );
     692         121 :         push_indice( &hStereoTD->tdm_hBstr_tmp, IND_STEREO_CORRSTATS, hCPE->hStereoTCA->indx_ica_NCShift, STEREO_BITS_TCA_CORRSTATS );
     693         121 :         push_indice( &hStereoTD->tdm_hBstr_tmp, IND_STEREO_GD, hCPE->hStereoTCA->indx_ica_gD, STEREO_BITS_TCA_GD );
     694             :     }
     695             : 
     696             : 
     697             :     /*----------------------------------------------------------------*
     698             :      * Updates
     699             :      *----------------------------------------------------------------*/
     700             : 
     701        3811 :     hStereoTD->tdm_last_ratio_idx = tdm_ratio_idx;
     702        3811 :     move16();
     703        3811 :     hStereoTD->tdm_last_ratio_idx_SM = tdm_ratio_idx_SM;
     704        3811 :     move16();
     705        3811 :     hStereoTD->tdm_last_SM_flag = tdm_SM_or_LRTD_Pri;
     706        3811 :     move16();
     707             : 
     708        3811 :     if ( EQ_16( hStereoTD->tdm_LRTD_flag, 1 ) )
     709             :     {
     710        3690 :         hStereoTD->tdm_last_SM_flag = 0;
     711        3690 :         move16();
     712             :     }
     713             : 
     714        3811 :     hStereoTD->tdm_last_inst_ratio_idx = hStereoTD->tdm_inst_ratio_idx;
     715        3811 :     move16();
     716             : 
     717        3811 :     return;
     718             : }
     719             : 
     720             : /*-------------------------------------------------------------------*
     721             :  * signaling_enc_secondary()
     722             :  *
     723             :  * Signalling of the secondary channel
     724             :  *-------------------------------------------------------------------*/
     725             : 
     726        3811 : ivas_error signaling_enc_secondary_fx(
     727             :     Encoder_State *st,                /* i/o: Encoder structure               */
     728             :     const Word16 tdm_SM_or_LRTD_Pri,  /* i  : channel combination scheme flag OR LRTD primary channel */
     729             :     const Word16 tdm_Pitch_reuse_flag /* i  : primary channel pitch reuse flag*/
     730             : )
     731             : {
     732             :     Word16 ind;
     733        3811 :     BSTR_ENC_HANDLE hBstr = st->hBstr;
     734             :     ivas_error error;
     735             : 
     736        3811 :     error = IVAS_ERR_OK;
     737        3811 :     move32();
     738             : 
     739             :     /* The secondary channel band-witdh is always the same as the primary channel bandwidth */
     740             : 
     741        3811 :     ind = st->coder_type;
     742        3811 :     move16();
     743        3811 :     IF( EQ_16( tdm_Pitch_reuse_flag, 1 ) ) /* possible only for bitrate <= 24400 */
     744             :     {
     745          35 :         ind = 3;
     746          35 :         move16();
     747             :     }
     748        3776 :     ELSE IF( EQ_16( st->coder_type, GENERIC ) )
     749             :     {
     750        3681 :         ind = 2;
     751        3681 :         move16();
     752             :     }
     753          95 :     ELSE IF( EQ_16( st->coder_type, AUDIO ) )
     754             :     {
     755           0 :         ind = sub( ind, 2 );
     756             :     }
     757             : 
     758        3811 :     ind = shl( ind, 1 );
     759        3811 :     ind = add( ind, tdm_SM_or_LRTD_Pri ); /* addition of the channel combination scheme flag value or the LRTD primary channel*/
     760        3811 :     push_indice( hBstr, IND_STEREO_2ND_CODER_T, ind, TDM_SECONDARY_SIGNALLING );
     761             : 
     762             :     /* write extension layer flag to distinguish between TBE (0) and BWE (1) */
     763        3811 :     IF( st->extl_brate > 0 )
     764             :     {
     765        2894 :         test();
     766        2894 :         test();
     767        2894 :         test();
     768        2894 :         test();
     769        2894 :         IF( EQ_16( st->extl, WB_TBE ) || EQ_16( st->extl, SWB_TBE ) || EQ_16( st->extl, FB_TBE ) )
     770             :         {
     771        2894 :             push_indice( hBstr, IND_BWE_FLAG, 0, 1 );
     772             :         }
     773           0 :         ELSE IF( EQ_16( st->extl, WB_BWE ) || EQ_16( st->extl, SWB_BWE ) || EQ_16( st->extl, FB_BWE ) )
     774             :         {
     775           0 :             push_indice( hBstr, IND_BWE_FLAG, 1, 1 );
     776             :         }
     777             :     }
     778             : 
     779        3811 :     return error;
     780             : }
     781             : 
     782             : /*-------------------------------------------------------------------*
     783             :  * Function tdm_downmix_plain()
     784             :  *
     785             :  * downmix Left+Right to Primary+Secondary channel
     786             :  *-------------------------------------------------------------------*/
     787             : 
     788        3711 : static void tdm_downmix_plain_ivas_fx(
     789             :     Word16 FR_Y_fx[],            /*Qx*/
     790             :     Word16 LR_X_fx[],            /*Qx*/
     791             :     const Word16 Left_in_fx[],   /*Qx*/
     792             :     const Word16 Right_in_fx[],  /*Qx*/
     793             :     const Word32 ratio_L_fx,     /* Q31 */
     794             :     const Word32 One_m_Ratio_fx, /* Q31 */
     795             :     const Word16 start_index,    /* i  : start index             */
     796             :     const Word16 end_index       /* i  : end index               */
     797             : )
     798             : {
     799             :     Word16 i;
     800             : 
     801     2424351 :     FOR( i = start_index; i < end_index; i++ )
     802             :     {
     803     2420640 :         FR_Y_fx[i] = add( mult( Right_in_fx[i], extract_h( One_m_Ratio_fx ) ), mult( Left_in_fx[i], extract_h( ratio_L_fx ) ) );
     804     2420640 :         LR_X_fx[i] = sub( mult( Left_in_fx[i], extract_h( One_m_Ratio_fx ) ), mult( Right_in_fx[i], extract_h( ratio_L_fx ) ) );
     805     2420640 :         move16();
     806     2420640 :         move16();
     807             :     }
     808             : 
     809        3711 :     return;
     810             : }
     811             : 
     812             : /*-------------------------------------------------------------------*
     813             :  * Function tdm_downmix_fade()
     814             :  *
     815             :  * downmix Left+Right to Primary+Secondary channel with fade in/out
     816             :  *-------------------------------------------------------------------*/
     817          86 : static void tdm_downmix_fade_ivas_fx(
     818             :     Word16 FR_Y_fx[],               /* o  : primary channel       Qx  */
     819             :     Word16 LR_X_fx[],               /* o  : secondary channel     Qx  */
     820             :     const Word16 Left_in_fx[],      /* i  : Left channel          Qx  */
     821             :     const Word16 Right_in_fx[],     /* i  : Right channel         Qx  */
     822             :     const Word32 ratio_L_fx,        /* i  : mixing ratio          Q31 */
     823             :     const Word32 One_m_Ratio_fx,    /* i  : 1 - mixing ratio      Q31 */
     824             :     const Word32 OldRatio_L_fx,     /* i  : old mixing ratio      Q31 */
     825             :     const Word32 One_m_OldRatio_fx, /* i  : 1 - old mixing ratio  Q31 */
     826             :     const Word16 start_index,       /* i  : start index               */
     827             :     const Word16 end_index          /* i  : end index                 */
     828             : )
     829             : {
     830             :     Word16 i;
     831             :     Word16 step_fx, fade_in_fx, fade_out_fx, scale;
     832             : 
     833          86 :     step_fx = BASOP_Util_Divide1616_Scale( 1, sub( end_index, start_index ), &scale );
     834          86 :     step_fx = shl( step_fx, scale ); // Q15
     835          86 :     fade_out_fx = 32767;
     836          86 :     fade_in_fx = 0;
     837          86 :     move16();
     838          86 :     move16();
     839             : 
     840             :     Word16 tmp1, tmp2, tmp3, tmp4;
     841          86 :     tmp1 = extract_h( One_m_OldRatio_fx );
     842          86 :     tmp2 = extract_h( OldRatio_L_fx );
     843          86 :     tmp3 = extract_h( One_m_Ratio_fx );
     844          86 :     tmp4 = extract_h( ratio_L_fx );
     845             : 
     846       13686 :     FOR( i = start_index; i < end_index; i++ )
     847             :     {
     848       13600 :         FR_Y_fx[i] = extract_h( L_add( Mpy_32_16_1( L_mac( L_mult( Right_in_fx[i], tmp1 ), Left_in_fx[i], tmp2 ), fade_out_fx ),
     849       13600 :                                        Mpy_32_16_1( L_mac( L_mult( Right_in_fx[i], tmp3 ), Left_in_fx[i], tmp4 ), fade_in_fx ) ) ); // Qx
     850       13600 :         LR_X_fx[i] = extract_h( L_add( Mpy_32_16_1( L_msu( L_mult( Left_in_fx[i], tmp1 ), Right_in_fx[i], tmp2 ), fade_out_fx ),
     851       13600 :                                        Mpy_32_16_1( L_msu( L_mult( Left_in_fx[i], tmp3 ), Right_in_fx[i], tmp4 ),
     852             :                                                     fade_in_fx ) ) ); // Qx
     853       13600 :         move16();
     854       13600 :         move16();
     855             : 
     856             : 
     857       13600 :         fade_in_fx = add( fade_in_fx, step_fx );
     858       13600 :         fade_out_fx = sub( fade_out_fx, step_fx );
     859             :     }
     860             : 
     861          86 :     return;
     862             : }
     863             : 
     864             : 
     865             : /*-------------------------------------------------------------------*
     866             :  * Function stereo_tdm_downmix()
     867             :  *
     868             :  * Compute the TD stereo downmix signal based on the ratio index
     869             :  *-------------------------------------------------------------------*/
     870        3811 : void stereo_tdm_downmix_ivas_fx(
     871             :     STEREO_TD_ENC_DATA_HANDLE hStereoTD, /* i  : TD stereo IVAS encoder structure    */
     872             :     Word16 *Left_in_fx,                  /* Qx */
     873             :     Word16 *Right_in_fx,                 /* Qx */
     874             :     const Word16 input_frame,            /* i  : Number of samples                   */
     875             :     const Word16 tdm_ratio_idx,          /* i  : TDM ratio index                     */
     876             :     const Word16 tdm_SM_flag,            /* i  : channel combination scheme flag     */
     877             :     const Word16 tdm_ratio_idx_SM        /* i  : TDM ratio index for SM mode         */
     878             : )
     879             : {
     880             :     Word16 FR_Y_fx[L_FRAME48k], LR_X_fx[L_FRAME48k];
     881             :     Word16 i, tdm_n_OVA;
     882             :     Word16 stereo_tdm_coder_type;
     883             : 
     884        3811 :     tdm_n_OVA = NS2SA_FX2( L_mult0( input_frame, FRAMES_PER_SEC ), TDM_L_NOVA_NS );
     885        3811 :     move16();
     886             : 
     887        3811 :     IF( hStereoTD->flag_skip_DMX )
     888             :     {
     889         100 :         stereo_tdm_coder_type = 10; /* no DMX */
     890         100 :         move16();
     891             : 
     892         100 :         Copy( Left_in_fx, FR_Y_fx, input_frame );
     893         100 :         Copy( Right_in_fx, LR_X_fx, input_frame );
     894             :     }
     895        3711 :     ELSE IF( EQ_16( tdm_SM_flag, 1 ) )
     896             :     {
     897           0 :         IF( hStereoTD->tdm_last_SM_flag == 0 )
     898             :         {
     899           0 :             stereo_tdm_coder_type = 0; /* mode 1 : Switching from YX scheme to SM scheme*/
     900           0 :             move16();
     901             :         }
     902             :         ELSE
     903             :         {
     904           0 :             stereo_tdm_coder_type = 1; /* mode 2 : SM scheme*/
     905           0 :             move16();
     906             :         }
     907             :     }
     908             :     ELSE
     909             :     {
     910        3711 :         IF( EQ_16( hStereoTD->tdm_last_SM_flag, 1 ) )
     911             :         {
     912           0 :             stereo_tdm_coder_type = 2; /* mode 3 : Switching from SM scheme to YX scheme*/
     913           0 :             move16();
     914             :         }
     915             :         ELSE
     916             :         {
     917        3711 :             stereo_tdm_coder_type = 3; /* mode 4 : YX scheme*/
     918        3711 :             move16();
     919             :         }
     920             :     }
     921             : 
     922        3811 :     SWITCH( stereo_tdm_coder_type )
     923             :     {
     924           0 :         case ( 0 ):
     925             :         {
     926             :             /* Switching from YX scheme to SM scheme */
     927           0 :             tdm_downmix_fade_ivas_fx( FR_Y_fx, LR_X_fx, Left_in_fx, Right_in_fx, tdm_ratio_tabl_fx[tdm_ratio_idx_SM], L_sub( tdm_ratio_tabl_fx[tdm_ratio_idx_SM], 2147483647 ), hStereoTD->tdm_last_ratio_fx, L_sub( 2147483647, hStereoTD->tdm_last_ratio_fx ), 0, tdm_n_OVA ); // 1.0 in Q31 -> 2147483647
     928             : 
     929             :             /* Create new mixture of using the ratio computed above and formular for SM scheme */
     930           0 :             tdm_downmix_plain_ivas_fx( FR_Y_fx, LR_X_fx, Left_in_fx, Right_in_fx, tdm_ratio_tabl_fx[tdm_ratio_idx_SM], L_sub( tdm_ratio_tabl_fx[tdm_ratio_idx_SM], 2147483647 ), tdm_n_OVA, input_frame ); // 1.0 in Q31 -> 2147483647
     931             :         }
     932           0 :             BREAK;
     933           0 :         case ( 1 ):
     934             :         {
     935             :             /* Create new mixture of using the ratio computed above and formular for SM scheme */
     936           0 :             IF( EQ_32( tdm_ratio_tabl_fx[tdm_ratio_idx_SM], hStereoTD->tdm_last_ratio_SM_fx ) )
     937             :             {
     938           0 :                 tdm_downmix_plain_ivas_fx( FR_Y_fx, LR_X_fx, Left_in_fx, Right_in_fx, tdm_ratio_tabl_fx[tdm_ratio_idx_SM], L_sub( (Word32) tdm_ratio_tabl_fx[tdm_ratio_idx_SM], 2147483647 ), 0, input_frame ); // 1.0 in Q31 -> 2147483647
     939             :             }
     940             :             ELSE
     941             :             {
     942           0 :                 tdm_downmix_fade_ivas_fx( FR_Y_fx, LR_X_fx, Left_in_fx, Right_in_fx, tdm_ratio_tabl_fx[tdm_ratio_idx_SM], L_sub( tdm_ratio_tabl_fx[tdm_ratio_idx_SM], 2147483647 ), hStereoTD->tdm_last_ratio_SM_fx, L_sub( hStereoTD->tdm_last_ratio_SM_fx, 2147483647 ), 0, tdm_n_OVA ); // 1.0 in Q31 -> 2147483647
     943             : 
     944           0 :                 tdm_downmix_plain_ivas_fx( FR_Y_fx, LR_X_fx, Left_in_fx, Right_in_fx, tdm_ratio_tabl_fx[tdm_ratio_idx_SM], L_sub( tdm_ratio_tabl_fx[tdm_ratio_idx_SM], 2147483647 ), tdm_n_OVA, input_frame ); // 1.0 in Q31 -> 2147483647
     945             :             }
     946             :         }
     947           0 :             BREAK;
     948           0 :         case ( 2 ):
     949             :         {
     950             :             /* Switching from SM scheme to YX scheme */
     951           0 :             tdm_downmix_fade_ivas_fx( FR_Y_fx, LR_X_fx, Left_in_fx, Right_in_fx, tdm_ratio_tabl_fx[tdm_ratio_idx], L_sub( 2147483647, tdm_ratio_tabl_fx[tdm_ratio_idx] ), hStereoTD->tdm_last_ratio_SM_fx, L_sub( hStereoTD->tdm_last_ratio_SM_fx, 2147483647 ), 0, tdm_n_OVA ); // 1.0 in Q31 -> 2147483647
     952             : 
     953             :             /* Create new mixture of using the ratio computed above and formular for YX scheme */
     954           0 :             tdm_downmix_plain_ivas_fx( FR_Y_fx, LR_X_fx, Left_in_fx, Right_in_fx, tdm_ratio_tabl_fx[tdm_ratio_idx], L_sub( 2147483647, tdm_ratio_tabl_fx[tdm_ratio_idx] ), tdm_n_OVA, input_frame ); // 1.0 in Q31 -> 2147483647
     955             :         }
     956           0 :             BREAK;
     957        3711 :         case ( 3 ):
     958             :         {
     959             :             /* Create new mixture of using the ratio computed above and formular for YX scheme */
     960        3711 :             IF( EQ_32( tdm_ratio_tabl_fx[tdm_ratio_idx],
     961             :                        hStereoTD->tdm_last_ratio_fx ) )
     962             :             {
     963        3625 :                 tdm_downmix_plain_ivas_fx( FR_Y_fx, LR_X_fx, Left_in_fx, Right_in_fx, tdm_ratio_tabl_fx[tdm_ratio_idx], L_sub( 2147483647, tdm_ratio_tabl_fx[tdm_ratio_idx] ), 0, input_frame ); // 1.0 in Q31 -> 2147483647
     964             :             }
     965             :             ELSE
     966             :             {
     967          86 :                 tdm_downmix_fade_ivas_fx( FR_Y_fx, LR_X_fx, Left_in_fx, Right_in_fx, tdm_ratio_tabl_fx[tdm_ratio_idx], L_sub( 2147483647, tdm_ratio_tabl_fx[tdm_ratio_idx] ), hStereoTD->tdm_last_ratio_fx, L_sub( 2147483647, hStereoTD->tdm_last_ratio_fx ), 0, tdm_n_OVA ); // 1.0 in Q31 -> 2147483647
     968             : 
     969          86 :                 tdm_downmix_plain_ivas_fx( FR_Y_fx, LR_X_fx, Left_in_fx, Right_in_fx, tdm_ratio_tabl_fx[tdm_ratio_idx], L_sub( 2147483647, tdm_ratio_tabl_fx[tdm_ratio_idx] ), tdm_n_OVA, input_frame ); // 1.0 in Q31 -> 2147483647
     970             :             }
     971             :         }
     972        3711 :             BREAK;
     973         100 :         default:
     974         100 :             BREAK;
     975             :     }
     976             : 
     977     2527651 :     FOR( i = 0; i < input_frame; i++ )
     978             :     {
     979     2523840 :         Left_in_fx[i] = FR_Y_fx[i];  // Qx
     980     2523840 :         Right_in_fx[i] = LR_X_fx[i]; // Qx
     981     2523840 :         move16();
     982     2523840 :         move16();
     983             :     }
     984             : 
     985        3811 :     hStereoTD->tdm_last_ratio_fx = tdm_ratio_tabl_fx[tdm_ratio_idx];       // Q31
     986        3811 :     hStereoTD->tdm_last_ratio_SM_fx = tdm_ratio_tabl_fx[tdm_ratio_idx_SM]; // Q31
     987        3811 :     move32();
     988        3811 :     move32();
     989             : 
     990        3811 :     return;
     991             : }
     992             : 
     993             : /*-------------------------------------------------------------------*
     994             :  * Function stereo_tdm_prep_dwnmx()
     995             :  *
     996             :  * Reactivate downmixing after bitrate switching from MDCT to lower rate
     997             :  *-------------------------------------------------------------------*/
     998             : 
     999        3811 : void stereo_tdm_prep_dwnmx_fx(
    1000             :     CPE_ENC_HANDLE hCPE,      /* i  : CPE encoder structure             */
    1001             :     const Word32 *input1,     /* i  : right channel input               */
    1002             :     const Word16 input_frame, /* i  : frame lenght                      */
    1003             :     const Word16 input_q      /* i  : frame lenght                      */
    1004             : )
    1005             : {
    1006             :     Word32 mener;
    1007             :     Word16 i, sw_pos, enr_len;
    1008             :     Encoder_State **sts;
    1009             :     Word16 mener_e;
    1010        3811 :     sts = hCPE->hCoreCoder;
    1011             : 
    1012        3811 :     i = idiv1616( input_frame, L_FRAME16k );
    1013             : 
    1014        3811 :     sw_pos = i_mult( 22, i );
    1015        3811 :     enr_len = i_mult( 6, i );
    1016        3811 :     IF( EQ_16( hCPE->element_mode, IVAS_CPE_TD ) )
    1017             :     {
    1018        3811 :         IF( EQ_16( hCPE->hStereoTD->flag_skip_DMX, 1 ) ) /* hStereoTD is defined only if element mode == TD */
    1019             :         {
    1020         100 :             IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_TD ) )
    1021             :             {
    1022             :                 Word16 tmp_e;
    1023          92 :                 mener_e = sub( 31, input_q );
    1024          92 :                 mener = L_add( sum2_32_fx( input1 + sub( input_frame, sw_pos ), enr_len, &mener_e ), EPSILON_FX );
    1025          92 :                 mener = BASOP_Util_Divide3232_Scale( mener, (Word32) enr_len, &tmp_e );
    1026          92 :                 mener_e = add( mener_e, sub( tmp_e, 15 ) );
    1027          92 :                 mener = Sqrt32( mener, &mener_e );
    1028          92 :                 test();
    1029          92 :                 test();
    1030          92 :                 IF( ( BASOP_Util_Cmp_Mant32Exp( mener, mener_e, 10, Q31 ) < 0 ) && ( sts[1]->vad_flag == 0 || EQ_16( sts[1]->coder_type_raw, UNVOICED ) ) )
    1031             :                 {
    1032           0 :                     hCPE->hStereoTD->flag_skip_DMX = 0; /* Can start using the TD downmix whenever the right channel is sufficiently low energy to limit switching artefacts */
    1033           0 :                     move16();
    1034             :                 }
    1035             :             }
    1036           8 :             ELSE IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_DFT ) || EQ_32( hCPE->last_element_brate, IVAS_13k2 ) ) /* Just security check, should not happened */
    1037             :             {
    1038           0 :                 hCPE->hStereoTD->flag_skip_DMX = 0;
    1039           0 :                 move16();
    1040             :             }
    1041         100 :             test();
    1042             :         }
    1043             :     }
    1044             : 
    1045        3811 :     return;
    1046             : }

Generated by: LCOV version 1.14