LCOV - code coverage report
Current view: top level - lib_dec - ivas_stereo_td_dec_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main @ da9cc8ead0679b4682d329fdff98cf1616159273 Lines: 220 318 69.2 %
Date: 2025-10-13 22:24:20 Functions: 5 5 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 "options.h"
      35             : #include <math.h>
      36             : #include "cnst.h"
      37             : #include "rom_com.h"
      38             : #include "prot_fx.h"
      39             : #include "ivas_rom_com.h"
      40             : #include "ivas_cnst.h"
      41             : #include "wmc_auto.h"
      42             : #include "ivas_prot_fx.h"
      43             : 
      44             : /*-------------------------------------------------------------------*
      45             :  * stereo_td_init_dec()
      46             :  *
      47             :  * Initialize TD stereo decoder
      48             :  *-------------------------------------------------------------------*/
      49             : 
      50          60 : void stereo_td_init_dec_fx(
      51             :     STEREO_TD_DEC_DATA_HANDLE hStereoTD, /* i/o: TD stereo decoder handle      */
      52             :     const Word16 last_element_mode       /* i  : last element mode           Q0*/
      53             : )
      54             : {
      55          60 :     hStereoTD->tdm_SM_flag = 0;
      56          60 :     move16();
      57          60 :     hStereoTD->tdm_last_SM_flag = 0;
      58          60 :     move16();
      59          60 :     hStereoTD->tdm_last_ratio_idx = LRTD_STEREO_MID_IS_PRIM; /* Q0 */
      60          60 :     move16();
      61          60 :     hStereoTD->tdm_prev_last_SM_flag = 0;
      62          60 :     move16();
      63          60 :     hStereoTD->tdm_LRTD_flag = 0;
      64          60 :     move16();
      65             :     // hStereoTD->prevSP_ratio = 0.5f;
      66          60 :     hStereoTD->prevSP_ratio_fx = ONE_IN_Q14; //.5    /* Q15 */
      67          60 :     move16();
      68             :     // hStereoTD->SP_ratio_LT = 0.0f;
      69          60 :     hStereoTD->SP_ratio_LT_fx = 0;
      70          60 :     move32();
      71             :     // hStereoTD->c_LR_LT = 0.5f;
      72          60 :     hStereoTD->c_LR_LT_fx = ONE_IN_Q30; //.5 /* Q31 */
      73          60 :     move32();
      74             : 
      75          60 :     hStereoTD->flag_skip_DMX = 0;
      76          60 :     move16();
      77             : 
      78          60 :     IF( EQ_16( last_element_mode, IVAS_CPE_MDCT ) )
      79             :     {
      80           8 :         hStereoTD->tdm_last_ratio_idx = LRTD_STEREO_LEFT_IS_PRIM; /* Q0 */
      81           8 :         move16();
      82           8 :         hStereoTD->tdm_LRTD_flag = 1; /* Q0 */
      83           8 :         move16();
      84             :     }
      85             : 
      86          60 :     set32_fx( hStereoTD->TCX_old_syn_Overl_fx, 0, L_FRAME16k / 2 );
      87             : 
      88          60 :     return;
      89             : }
      90             : 
      91             : /*-------------------------------------------------------------------*
      92             :  * tdm_configure_dec()
      93             :  *
      94             :  * Configure TD stereo decoder
      95             :  *-------------------------------------------------------------------*/
      96             : 
      97             : static Word32 power_table[32 + 1] = {
      98             :     53687092, 60237908, 67588048, 75835024, 85088304, 95470648, 107119832, 120190432,
      99             :     134855872, 151310800, 169773488, 190488992, 213732176, 239811440, 269072832, 301904704,
     100             :     338742656, 380075520, 426451744, 478486688, 536870912, 602379200, 675880448, 758350272,
     101             :     850883136, 954706496, 1071198464, 1201904384, 1348558720, 1513107968, 1697734912, 1904890240,
     102             :     2137321728
     103             : }; // Q29
     104             : 
     105        3739 : void tdm_configure_dec_fx(
     106             :     const Word16 ivas_format,     /* i  : IVAS format                     Q0*/
     107             :     const Word16 ism_mode,        /* i  : ISM mode in combined format     Q0*/
     108             :     CPE_DEC_HANDLE hCPE,          /* i/o: CPE decoder structure             */
     109             :     Word16 *tdm_ratio_idx,        /* o  : ratio index                     Q0*/
     110             :     const Word16 nb_bits_metadata /* i  : number of metadata bits         Q0*/
     111             : )
     112             : {
     113             :     STEREO_TD_DEC_DATA_HANDLE hStereoTD;
     114             :     Decoder_State **sts;
     115             :     Word16 tdm_tmp_SM_LRTD_flag;
     116             :     Word16 mod_ct, core, bits_offset;
     117             :     Word16 idx_LRTD_pri_side, tdm_inst_ratio_idx;
     118             :     Word32 element_brate_adapt;
     119             :     Word16 bstr_last_pos, temp;
     120             : 
     121        3739 :     hStereoTD = hCPE->hStereoTD;
     122        3739 :     sts = hCPE->hCoreCoder;
     123             : 
     124        3739 :     element_brate_adapt = L_add( hCPE->element_brate, hCPE->brate_surplus ); /* Q0 */
     125             : 
     126        3739 :     IF( hCPE->brate_surplus < 0 )
     127             :     {
     128           0 :         temp = extract_l( L_negate( Mpy_32_32( L_abs( hCPE->brate_surplus ), ONE_BY_FRAMES_PER_SEC_Q31 ) ) ); /* Q0 */
     129             :     }
     130             :     ELSE
     131             :     {
     132        3739 :         temp = extract_l( Mpy_32_32( hCPE->brate_surplus, ONE_BY_FRAMES_PER_SEC_Q31 ) ); /* Q0 */
     133             :     }
     134        3739 :     bstr_last_pos = add( sub( div_l( hCPE->element_brate, FRAMES_PER_SEC / 2 ), nb_bits_metadata ), temp ); /* Q0 */
     135             : 
     136             :     /*----------------------------------------------------------------*
     137             :      * Decode CoreCoder signaling
     138             :      *----------------------------------------------------------------*/
     139             : 
     140             :     /* temporarily decode PCh signaling */
     141        3739 :     bits_offset = sts[0]->next_bit_pos; /* Q0 */
     142        3739 :     move16();
     143        3739 :     core = get_indice_st( sts[0], hCPE->element_brate, bits_offset, 1 ); /* Q0 */
     144        3739 :     bits_offset = add( bits_offset, 1 );                                 /* Q0 */
     145             : 
     146        3739 :     IF( core == ACELP_CORE && LT_32( hCPE->element_brate, IVAS_24k4 ) )
     147             :     {
     148         575 :         mod_ct = get_indice_st( sts[0], hCPE->element_brate, bits_offset, 3 ); /* Q0 */
     149             :         /* Only transition mode is important to decoder, otherwise mod_ct is set to AUDIO only to easy debugging IF needed */
     150         575 :         if ( NE_16( mod_ct, TRANSITION ) )
     151             :         {
     152         552 :             mod_ct = AUDIO; /* Q0 */
     153         552 :             move16();
     154             :         }
     155             :     }
     156             :     ELSE /* core != ACELP_CORE */
     157             :     {
     158        3164 :         mod_ct = AUDIO; /* coder_type == VOICED || coder_type == GENERIC */ /* Q0 */
     159        3164 :         move16();
     160             :     }
     161             : 
     162             :     /* Get few parameters needed to decode the bitrate allocated to each channel */
     163             :     /* Get the coder_type of the secondary channel (last parameter on 2 bits) */
     164        3739 :     sts[1]->coder_type = get_indice_st( sts[0], element_brate_adapt, sub( bstr_last_pos, TDM_SECONDARY_SIGNALLING ), TDM_SECONDARY_SIGNALLING ); /* Q0 */
     165        3739 :     move16();
     166             : 
     167             :     /* Get the LRTD config flag:  1 = LRTD configuration, favor closer bitrate per channel;
     168             :                                   0 = Pri/Sec configuration, bitrates linked wrt. the mono */
     169        3739 :     tdm_tmp_SM_LRTD_flag = s_and( sts[1]->coder_type, 0x1 ); /* Q0 */
     170        3739 :     sts[1]->coder_type = shr( sts[1]->coder_type, 1 );       /* Q0 */
     171        3739 :     move16();
     172        3739 :     hStereoTD->tdm_Pitch_reuse_flag = 0;
     173        3739 :     move16();
     174             : 
     175        3739 :     IF( EQ_16( sts[1]->coder_type, 2 ) )
     176             :     {
     177        3609 :         sts[1]->coder_type = GENERIC; /* Q0 */
     178        3609 :         move16();
     179             :     }
     180         130 :     ELSE IF( EQ_16( sts[1]->coder_type, 3 ) )
     181             :     {
     182          35 :         sts[1]->coder_type = AUDIO; /* Q0 */
     183          35 :         move16();
     184             : 
     185          35 :         IF( LE_32( hCPE->element_brate, IVAS_24k4 ) )
     186             :         {
     187          35 :             hStereoTD->tdm_Pitch_reuse_flag = 1; /* Q0 */
     188          35 :             move16();
     189          35 :             sts[1]->coder_type = GENERIC; /* Q0 */
     190          35 :             move16();
     191             :         }
     192             :     }
     193             : 
     194             :     /*----------------------------------------------------------------*
     195             :      * Decode TDM parameters
     196             :      *----------------------------------------------------------------*/
     197             : 
     198             :     /* Get the correlation ratio */
     199        3739 :     *tdm_ratio_idx = get_indice_st( sts[0], element_brate_adapt, ( sub( bstr_last_pos, ( TDM_SECONDARY_SIGNALLING + TDM_RATIO_BITS ) ) ), TDM_RATIO_BITS ); /* Q0 */
     200        3739 :     move16();
     201             : 
     202        3739 :     hStereoTD->tdm_use_IAWB_Ave_lpc = 0;
     203        3739 :     move16();
     204        3739 :     IF( sts[1]->coder_type == INACTIVE )
     205             :     {
     206             :         /* Get the flag on the LPC reusage type (primary channel of ave LPC */
     207           0 :         hStereoTD->tdm_use_IAWB_Ave_lpc = get_indice_st( sts[0], element_brate_adapt, sub( bstr_last_pos, TDM_SECONDARY_SIGNALLING + TDM_RATIO_BITS + TDM_LP_REUSE_BITS ), TDM_LP_REUSE_BITS ); /* Q0 */
     208           0 :         move16();
     209           0 :         hStereoTD->tdm_lp_reuse_flag = 1; /* Q0 */
     210           0 :         move16();
     211             :     }
     212             :     ELSE
     213             :     {
     214             :         /* Get the flag on the LPC reusage */
     215        3739 :         hStereoTD->tdm_lp_reuse_flag = get_indice_st( sts[0], element_brate_adapt, sub( bstr_last_pos, TDM_SECONDARY_SIGNALLING + TDM_RATIO_BITS + TDM_LP_REUSE_BITS ), TDM_LP_REUSE_BITS ); /* Q0 */
     216        3739 :         move16();
     217             :     }
     218             : 
     219        3739 :     sts[0]->tdm_LRTD_flag = hStereoTD->tdm_LRTD_flag; /* the flag was already read in function stereo_memory_dec()        Q0*/
     220        3739 :     move16();
     221        3739 :     sts[1]->tdm_LRTD_flag = hStereoTD->tdm_LRTD_flag; /* Q0 */
     222        3739 :     move16();
     223             : 
     224        3739 :     tdm_inst_ratio_idx = *tdm_ratio_idx; /* Q0 */
     225        3739 :     move16();
     226             : 
     227             :     /* update past tdm_SM_flag */
     228        3739 :     hStereoTD->tdm_prev_last_SM_flag = hStereoTD->tdm_last_SM_flag; /* Q0 */
     229        3739 :     move16();
     230        3739 :     hStereoTD->tdm_last_SM_flag = hStereoTD->tdm_SM_flag; /* Q0 */
     231        3739 :     move16();
     232             : 
     233        3739 :     idx_LRTD_pri_side = -1; /* Q0 */
     234        3739 :     move16();
     235        3739 :     IF( EQ_16( hStereoTD->tdm_LRTD_flag, 1 ) )
     236             :     {
     237        3618 :         idx_LRTD_pri_side = tdm_tmp_SM_LRTD_flag; /* Q0 */
     238        3618 :         move16();
     239        3618 :         hStereoTD->tdm_SM_flag = 0;
     240        3618 :         move16();
     241        3618 :         IF( tdm_inst_ratio_idx == TDM_NQ )
     242             :         {
     243         100 :             hStereoTD->flag_skip_DMX = 1; /* Q0 */
     244         100 :             move16();
     245             :         }
     246             :         ELSE
     247             :         {
     248        3518 :             hStereoTD->flag_skip_DMX = 0;
     249        3518 :             move16();
     250             :         }
     251             :         /* Set primary channel */
     252        3618 :         *tdm_ratio_idx = LRTD_STEREO_RIGHT_IS_PRIM; /* Q0 */
     253        3618 :         move16();
     254        3618 :         if ( EQ_16( idx_LRTD_pri_side, 1 ) )
     255             :         {
     256        3350 :             *tdm_ratio_idx = LRTD_STEREO_LEFT_IS_PRIM; /* Q0 */
     257        3350 :             move16();
     258             :         }
     259             :     }
     260             :     ELSE
     261             :     {
     262         121 :         hStereoTD->tdm_SM_flag = tdm_tmp_SM_LRTD_flag; /* Q0 */
     263         121 :         move16();
     264         121 :         if ( EQ_16( hCPE->nchan_out, 1 ) )
     265             :         {
     266             :             /* in case of mono output, use exclusively the YX upmixing scheme in order to deal with NOOP signals */
     267          26 :             hStereoTD->tdm_SM_flag = 0;
     268          26 :             move16();
     269             :         }
     270             :     }
     271             : 
     272        3739 :     test();
     273        3739 :     test();
     274        3739 :     IF( sts[1]->coder_type == INACTIVE && ( GE_16( *tdm_ratio_idx, 29 ) || LE_16( *tdm_ratio_idx, 1 ) ) )
     275             :     {
     276           0 :         hStereoTD->tdm_lp_reuse_flag = hStereoTD->tdm_use_IAWB_Ave_lpc; /* Q0 */
     277           0 :         move16();
     278           0 :         hStereoTD->tdm_use_IAWB_Ave_lpc = 0;
     279           0 :         move16();
     280             :     }
     281             : 
     282             :     /*sts[1]->tdm_inst_ratio_idx = sts[0]->tdm_inst_ratio_idx;*/
     283             : 
     284        3739 :     test();
     285        3739 :     IF( EQ_16( hCPE->nchan_out, 1 ) && hCPE->hStereoDftDmx != NULL )
     286        1317 :     {
     287             :         /* in mono DMX, only targetGain is needed */
     288        1317 :         Word16 tmpS = 20;
     289        1317 :         move16();
     290        1317 :         IF( hStereoTD->tdm_LRTD_flag == 0 )
     291             :         {
     292          26 :             tmpS = get_indice_st( sts[0], element_brate_adapt, add( sub( bstr_last_pos, TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS ), STEREO_BITS_TCA_CHAN + STEREO_BITS_TCA_CORRSTATS ), STEREO_BITS_TCA_GD );
     293             :         }
     294        1317 :         hCPE->hStereoDftDmx->targetGain_fx = power_table[tmpS]; /* Q29 */
     295        1317 :         move32();
     296             :     }
     297             :     ELSE
     298             :     {
     299        2422 :         IF( hStereoTD->tdm_LRTD_flag == 0 )
     300             :         {
     301          95 :             hCPE->hStereoTCA->refChanIndx = get_indice_st( sts[0], element_brate_adapt, sub( bstr_last_pos, TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS ), STEREO_BITS_TCA_CHAN ); /* Q0 */
     302          95 :             move16();
     303          95 :             hCPE->hStereoTCA->indx_ica_NCShift = get_indice_st( sts[0], element_brate_adapt, add( sub( bstr_last_pos, TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS ), STEREO_BITS_TCA_CHAN ), STEREO_BITS_TCA_CORRSTATS ); /* Q0 */
     304          95 :             move16();
     305          95 :             hCPE->hStereoTCA->indx_ica_gD = get_indice_st( sts[0], element_brate_adapt, add( sub( bstr_last_pos, TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS ), STEREO_BITS_TCA_CHAN + STEREO_BITS_TCA_CORRSTATS ), STEREO_BITS_TCA_GD ); /* Q0 */
     306          95 :             move16();
     307             :         }
     308             :         ELSE
     309             :         {
     310        2327 :             hCPE->hStereoTCA->refChanIndx = L_CH_INDX; /* Q0 */
     311        2327 :             move16();
     312        2327 :             hCPE->hStereoTCA->indx_ica_NCShift = 0; /* Q0 */
     313        2327 :             move16();
     314        2327 :             hCPE->hStereoTCA->indx_ica_gD = 20; /* Q0 */
     315        2327 :             move16();
     316             :         }
     317        2422 :         hCPE->hStereoTCA->targetGain_fx = power_table[hCPE->hStereoTCA->indx_ica_gD]; /* Q29 */
     318        2422 :         move32();
     319             :     }
     320             :     /* set the BW of the secondary channel */
     321        3739 :     IF( hStereoTD->tdm_LRTD_flag && GE_16( sts[1]->bits_frame_channel, IVAS_16k4 / FRAMES_PER_SEC ) )
     322             :     {
     323             :         /* set BW of the secondary channel in LRTD stereo mode as the BW of the primary channel at higher bitrates */
     324        3618 :         sts[1]->bwidth = sts[0]->bwidth; /* Q0 */
     325        3618 :         move16();
     326             :     }
     327             :     ELSE
     328             :     {
     329             :         /* limit BW of the secondary channel in LRTD mode to WB for low bitrates */
     330         121 :         sts[1]->bwidth = WB; /* Q0 */
     331         121 :         move16();
     332             :     }
     333             : 
     334             :     /*----------------------------------------------------------------*
     335             :      * bitbudget distribution between channels (taking into account also metadata bitbudget)
     336             :      *----------------------------------------------------------------*/
     337             : 
     338        3739 :     tdm_bit_alloc( ivas_format, ism_mode, L_add( L_sub( hCPE->element_brate, L_mult0( nb_bits_metadata, FRAMES_PER_SEC ) ), hCPE->brate_surplus ),
     339        3739 :                    hStereoTD->tdm_lp_reuse_flag, &( sts[0]->total_brate ), &( sts[1]->total_brate ),
     340        3739 :                    &hStereoTD->tdm_low_rate_mode, sts[1]->coder_type, *tdm_ratio_idx, hStereoTD->tdm_Pitch_reuse_flag,
     341        3739 :                    sts[0]->bwidth, sts[1]->bwidth, sts[0]->flag_ACELP16k, hStereoTD->tdm_LRTD_flag, mod_ct, tdm_inst_ratio_idx );
     342             : 
     343        3739 :     return;
     344             : }
     345             : 
     346       16984 : void tdm_upmix_plain_fx(
     347             :     Word32 Left_fx[],                 /* o  : left channel            Qx*/
     348             :     Word32 Right_fx[],                /* o  : right channel           Qx*/
     349             :     const Word32 PCh_2_L_fx[],        /* i  : primary channel         Qx*/
     350             :     const Word32 SCh_2_R_fx[],        /* i  : secondary channel       Qx*/
     351             :     const Word32 LR_ratio_fx,         /* i  : mixing ratio            Q31*/
     352             :     const Word32 inv_den_LR_ratio_fx, /* i  : inverse mixing ration   Q30*/
     353             :     const Word16 start_index,         /* i  : start index             Q0*/
     354             :     const Word16 end_index,           /* i  : end index               Q0*/
     355             :     const Word16 plus_minus_flag      /* i  : plus/minus flag         Q0*/
     356             : )
     357             : {
     358             :     Word16 i;
     359             : 
     360       16984 :     IF( EQ_16( plus_minus_flag, 1 ) )
     361             :     {
     362     4879004 :         FOR( i = start_index; i < end_index; i++ )
     363             :         {
     364     4862020 :             Word32 temp_left = Madd_32_32( SCh_2_R_fx[i], L_sub( PCh_2_L_fx[i], SCh_2_R_fx[i] ), LR_ratio_fx ); /* Qx */
     365     4862020 :             Left_fx[i] = W_shl_sat_l( W_mult0_32_32( temp_left, inv_den_LR_ratio_fx ), -30 );                   /* Qx */
     366     4862020 :             move32();
     367     4862020 :             Word32 temp_right = Msub_32_32( PCh_2_L_fx[i], L_add( PCh_2_L_fx[i], SCh_2_R_fx[i] ), LR_ratio_fx ); /* Qx */
     368     4862020 :             Right_fx[i] = W_shl_sat_l( W_mult0_32_32( temp_right, inv_den_LR_ratio_fx ), -30 );                  /* Qx */
     369     4862020 :             move32();
     370             :         }
     371             :     }
     372             :     ELSE
     373             :     {
     374           0 :         Word32 inv_den_LR_ratio_fx_neg = L_negate( inv_den_LR_ratio_fx );
     375           0 :         FOR( i = start_index; i < end_index; i++ )
     376             :         {
     377           0 :             Word32 temp_left = Msub_32_32( SCh_2_R_fx[i], L_add( PCh_2_L_fx[i], SCh_2_R_fx[i] ), LR_ratio_fx ); /* Qx */
     378           0 :             Left_fx[i] = W_shl_sat_l( W_mult0_32_32( temp_left, inv_den_LR_ratio_fx_neg ), -30 );               /* Qx */
     379           0 :             move32();
     380           0 :             Word32 temp_right = Msub_32_32( PCh_2_L_fx[i], L_sub( PCh_2_L_fx[i], SCh_2_R_fx[i] ), LR_ratio_fx ); /* Qx */
     381           0 :             Right_fx[i] = W_shl_sat_l( W_mult0_32_32( temp_right, inv_den_LR_ratio_fx_neg ), -30 );              /* Qx */
     382           0 :             move32();
     383             :         }
     384             :     }
     385             : 
     386       16984 :     return;
     387             : }
     388             : 
     389             : /*-------------------------------------------------------------------*
     390             :  * Function tdm_downmix_fade()
     391             :  *
     392             :  * downmix Left+Right to Primary+Secondary channel with fade in/out
     393             :  *-------------------------------------------------------------------*/
     394             : 
     395             : 
     396             : // Q31
     397             : Word32 inv_time[960 + 1] = {
     398             :     0, 2147483647, 1073741824, 715827904, 536870912, 429496736, 357913952, 306783392,
     399             :     268435456, 238609296, 214748368, 195225792, 178956976, 165191056, 153391696, 143165584,
     400             :     134217728, 126322568, 119304648, 113025456, 107374184, 102261128, 97612896, 93368856,
     401             :     89478488, 85899344, 82595528, 79536432, 76695848, 74051160, 71582792, 69273664,
     402             :     67108864, 65075264, 63161284, 61356676, 59652324, 58040100, 56512728, 55063684,
     403             :     53687092, 52377648, 51130564, 49941480, 48806448, 47721860, 46684428, 45691140,
     404             :     44739244, 43826196, 42949672, 42107524, 41297764, 40518560, 39768216, 39045156,
     405             :     38347924, 37675152, 37025580, 36398028, 35791396, 35204648, 34636832, 34087044,
     406             :     33554432, 33038210, 32537632, 32051994, 31580642, 31122952, 30678338, 30246248,
     407             :     29826162, 29417584, 29020050, 28633116, 28256364, 27889398, 27531842, 27183338,
     408             :     26843546, 26512144, 26188824, 25873296, 25565282, 25264514, 24970740, 24683720,
     409             :     24403224, 24129030, 23860930, 23598722, 23342214, 23091222, 22845570, 22605092,
     410             :     22369622, 22139006, 21913098, 21691754, 21474836, 21262214, 21053762, 20849356,
     411             :     20648882, 20452226, 20259280, 20069940, 19884108, 19701684, 19522578, 19346700,
     412             :     19173962, 19004280, 18837576, 18673770, 18512790, 18354562, 18199014, 18046082,
     413             :     17895698, 17747798, 17602324, 17459216, 17318416, 17179870, 17043522, 16909320,
     414             :     16777216, 16647160, 16519105, 16393005, 16268816, 16146494, 16025997, 15907286,
     415             :     15790321, 15675063, 15561476, 15449523, 15339169, 15230380, 15123124, 15017368,
     416             :     14913081, 14810232, 14708792, 14608732, 14510025, 14412642, 14316558, 14221746,
     417             :     14128182, 14035841, 13944699, 13854733, 13765921, 13678240, 13591669, 13506186,
     418             :     13421773, 13338408, 13256072, 13174746, 13094412, 13015052, 12936648, 12859184,
     419             :     12782641, 12707004, 12632257, 12558384, 12485370, 12413200, 12341860, 12271335,
     420             :     12201612, 12132676, 12064515, 11997115, 11930465, 11864551, 11799361, 11734883,
     421             :     11671107, 11608020, 11545611, 11483870, 11422785, 11362347, 11302546, 11243370,
     422             :     11184811, 11126858, 11069503, 11012737, 10956549, 10900932, 10845877, 10791375,
     423             :     10737418, 10683998, 10631107, 10578737, 10526881, 10475530, 10424678, 10374317,
     424             :     10324441, 10275041, 10226113, 10177648, 10129640, 10082083, 10034970, 9988296,
     425             :     9942054, 9896238, 9850842, 9805861, 9761289, 9717121, 9673350, 9629972,
     426             :     9586981, 9544372, 9502140, 9460280, 9418788, 9377658, 9336885, 9296466,
     427             :     9256395, 9216668, 9177281, 9138228, 9099507, 9061112, 9023041, 8985287,
     428             :     8947849, 8910721, 8873899, 8837381, 8801162, 8765239, 8729608, 8694266,
     429             :     8659208, 8624432, 8589935, 8555712, 8521761, 8488078, 8454660, 8421505,
     430             :     8388608, 8355967, 8323580, 8291442, 8259552, 8227906, 8196502, 8165337,
     431             :     8134408, 8103712, 8073247, 8043010, 8012998, 7983210, 7953643, 7924294,
     432             :     7895160, 7866240, 7837531, 7809031, 7780738, 7752648, 7724761, 7697074,
     433             :     7669584, 7642290, 7615190, 7588281, 7561562, 7535030, 7508684, 7482521,
     434             :     7456540, 7430739, 7405116, 7379669, 7354396, 7329295, 7304366, 7279605,
     435             :     7255012, 7230584, 7206321, 7182219, 7158279, 7134497, 7110873, 7087405,
     436             :     7064091, 7040930, 7017920, 6995060, 6972349, 6949785, 6927366, 6905092,
     437             :     6882960, 6860970, 6839120, 6817408, 6795834, 6774396, 6753093, 6731923,
     438             :     6710886, 6689980, 6669204, 6648556, 6628036, 6607642, 6587373, 6567228,
     439             :     6547206, 6527306, 6507526, 6487866, 6468324, 6448900, 6429592, 6410399,
     440             :     6391320, 6372355, 6353502, 6334760, 6316128, 6297606, 6279192, 6260885,
     441             :     6242685, 6224590, 6206600, 6188713, 6170930, 6153248, 6135667, 6118187,
     442             :     6100806, 6083523, 6066338, 6049249, 6032257, 6015360, 5998557, 5981848,
     443             :     5965232, 5948708, 5932275, 5915933, 5899680, 5883517, 5867441, 5851454,
     444             :     5835553, 5819739, 5804010, 5788365, 5772805, 5757329, 5741935, 5726623,
     445             :     5711392, 5696243, 5681173, 5666184, 5651273, 5636440, 5621685, 5607007,
     446             :     5592405, 5577879, 5563429, 5549053, 5534751, 5520523, 5506368, 5492285,
     447             :     5478274, 5464335, 5450466, 5436667, 5422938, 5409278, 5395687, 5382164,
     448             :     5368709, 5355321, 5341999, 5328743, 5315553, 5302429, 5289368, 5276372,
     449             :     5263440, 5250571, 5237765, 5225021, 5212339, 5199718, 5187158, 5174659,
     450             :     5162220, 5149841, 5137520, 5125259, 5113056, 5100911, 5088824, 5076793,
     451             :     5064820, 5052902, 5041041, 5029235, 5017485, 5005789, 4994148, 4982560,
     452             :     4971027, 4959546, 4948119, 4936744, 4925421, 4914150, 4902930, 4891762,
     453             :     4880644, 4869577, 4858560, 4847593, 4836675, 4825806, 4814986, 4804214,
     454             :     4793490, 4782814, 4772186, 4761604, 4751070, 4740582, 4730140, 4719744,
     455             :     4709394, 4699089, 4688829, 4678613, 4668442, 4658316, 4648233, 4638193,
     456             :     4628197, 4618244, 4608334, 4598466, 4588640, 4578856, 4569114, 4559413,
     457             :     4549753, 4540134, 4530556, 4521018, 4511520, 4502062, 4492643, 4483264,
     458             :     4473924, 4464623, 4455360, 4446136, 4436949, 4427801, 4418690, 4409617,
     459             :     4400581, 4391582, 4382619, 4373694, 4364804, 4355950, 4347133, 4338351,
     460             :     4329604, 4320892, 4312216, 4303574, 4294967, 4286394, 4277856, 4269351,
     461             :     4260880, 4252443, 4244039, 4235668, 4227330, 4219025, 4210752, 4202512,
     462             :     4194304, 4186128, 4177983, 4169871, 4161790, 4153740, 4145721, 4137733,
     463             :     4129776, 4121849, 4113953, 4106087, 4098251, 4090445, 4082668, 4074921,
     464             :     4067204, 4059515, 4051856, 4044225, 4036623, 4029050, 4021505, 4013988,
     465             :     4006499, 3999038, 3991605, 3984199, 3976821, 3969470, 3962147, 3954850,
     466             :     3947580, 3940337, 3933120, 3925930, 3918765, 3911627, 3904515, 3897429,
     467             :     3890369, 3883334, 3876324, 3869340, 3862380, 3855446, 3848537, 3841652,
     468             :     3834792, 3827956, 3821145, 3814358, 3807595, 3800856, 3794140, 3787449,
     469             :     3780781, 3774136, 3767515, 3760917, 3754342, 3747790, 3741260, 3734754,
     470             :     3728270, 3721808, 3715369, 3708952, 3702558, 3696185, 3689834, 3683505,
     471             :     3677198, 3670912, 3664647, 3658404, 3652183, 3645982, 3639802, 3633644,
     472             :     3627506, 3621389, 3615292, 3609216, 3603160, 3597125, 3591109, 3585114,
     473             :     3579139, 3573184, 3567248, 3561332, 3555436, 3549559, 3543702, 3537864,
     474             :     3532045, 3526245, 3520465, 3514703, 3508960, 3503236, 3497530, 3491843,
     475             :     3486174, 3480524, 3474892, 3469279, 3463683, 3458105, 3452546, 3447004,
     476             :     3441480, 3435973, 3430485, 3425013, 3419560, 3414123, 3408704, 3403302,
     477             :     3397917, 3392549, 3387198, 3381864, 3376546, 3371246, 3365961, 3360694,
     478             :     3355443, 3350208, 3344990, 3339788, 3334602, 3329432, 3324278, 3319140,
     479             :     3314018, 3308911, 3303821, 3298746, 3293686, 3288642, 3283614, 3278601,
     480             :     3273603, 3268620, 3263653, 3258700, 3253763, 3248840, 3243933, 3239040,
     481             :     3234162, 3229298, 3224450, 3219615, 3214796, 3209990, 3205199, 3200422,
     482             :     3195660, 3190911, 3186177, 3181457, 3176751, 3172058, 3167380, 3162715,
     483             :     3158064, 3153426, 3148803, 3144192, 3139596, 3135012, 3130442, 3125886,
     484             :     3121342, 3116812, 3112295, 3107791, 3103300, 3098822, 3094356, 3089904,
     485             :     3085465, 3081038, 3076624, 3072222, 3067833, 3063457, 3059093, 3054742,
     486             :     3050403, 3046076, 3041761, 3037459, 3033169, 3028891, 3024624, 3020370,
     487             :     3016128, 3011898, 3007680, 3003473, 2999278, 2995095, 2990924, 2986764,
     488             :     2982616, 2978479, 2974354, 2970240, 2966137, 2962046, 2957966, 2953897,
     489             :     2949840, 2945793, 2941758, 2937734, 2933720, 2929718, 2925727, 2921746,
     490             :     2917776, 2913817, 2909869, 2905931, 2902005, 2898088, 2894182, 2890287,
     491             :     2886402, 2882528, 2878664, 2874810, 2870967, 2867134, 2863311, 2859498,
     492             :     2855696, 2851904, 2848121, 2844349, 2840586, 2836834, 2833092, 2829359,
     493             :     2825636, 2821923, 2818220, 2814526, 2810842, 2807168, 2803503, 2799848,
     494             :     2796202, 2792566, 2788939, 2785322, 2781714, 2778116, 2774526, 2770946,
     495             :     2767375, 2763814, 2760261, 2756718, 2753184, 2749659, 2746142, 2742635,
     496             :     2739137, 2735648, 2732167, 2728695, 2725233, 2721779, 2718333, 2714897,
     497             :     2711469, 2708050, 2704639, 2701237, 2697843, 2694458, 2691082, 2687714,
     498             :     2684354, 2681003, 2677660, 2674325, 2670999, 2667681, 2664371, 2661070,
     499             :     2657776, 2654491, 2651214, 2647945, 2644684, 2641431, 2638186, 2634949,
     500             :     2631720, 2628499, 2625285, 2622080, 2618882, 2615692, 2612510, 2609336,
     501             :     2606169, 2603010, 2599859, 2596715, 2593579, 2590450, 2587329, 2584216,
     502             :     2581110, 2578011, 2574920, 2571836, 2568760, 2565691, 2562629, 2559575,
     503             :     2556528, 2553488, 2550455, 2547430, 2544412, 2541400, 2538396, 2535399,
     504             :     2532410, 2529427, 2526451, 2523482, 2520520, 2517565, 2514617, 2511676,
     505             :     2508742, 2505815, 2502894, 2499981, 2497074, 2494173, 2491280, 2488393,
     506             :     2485513, 2482640, 2479773, 2476913, 2474059, 2471212, 2468372, 2465538,
     507             :     2462710, 2459889, 2457075, 2454267, 2451465, 2448670, 2445881, 2443098,
     508             :     2440322, 2437552, 2434788, 2432031, 2429280, 2426535, 2423796, 2421063,
     509             :     2418337, 2415617, 2412903, 2410195, 2407493, 2404797, 2402107, 2399423,
     510             :     2396745, 2394073, 2391407, 2388747, 2386093, 2383444, 2380802, 2378165,
     511             :     2375535, 2372910, 2370291, 2367677, 2365070, 2362468, 2359872, 2357281,
     512             :     2354697, 2352118, 2349544, 2346976, 2344414, 2341857, 2339306, 2336761,
     513             :     2334221, 2331687, 2329158, 2326634, 2324116, 2321604, 2319096, 2316595,
     514             :     2314098, 2311607, 2309122, 2306642, 2304167, 2301697, 2299233, 2296774,
     515             :     2294320, 2291871, 2289428, 2286990, 2284557, 2282129, 2279706, 2277289,
     516             :     2274876, 2272469, 2270067, 2267670, 2265278, 2262891, 2260509, 2258132,
     517             :     2255760, 2253393, 2251031, 2248674, 2246321, 2243974, 2241632, 2239294,
     518             :     2236962
     519             : };
     520         119 : static void tdm_upmix_fade_fx(
     521             :     Word32 Left_fx[],                     /* o  : left channel                Qx*/
     522             :     Word32 Right_fx[],                    /* o  : right channel                           Qx*/
     523             :     const Word32 PCh_2_L_fx[],            /* i  : primary channel             Qx*/
     524             :     const Word32 SCh_2_R_fx[],            /* i  : secondary channel           Qx*/
     525             :     const Word32 LR_ratio_mem_fx,         /* i  : last mixing ratio           Q31*/
     526             :     const Word32 inv_den_LR_ratio_mem_fx, /* i  : last inverse mixing ration  Q31*/
     527             :     const Word32 LR_ratio_fx,             /* i  : mixing ratio                Q31*/
     528             :     const Word32 inv_den_LR_ratio_fx,     /* i  : inverse mixing ration       Q31*/
     529             :     const Word16 start_index,             /* i  : start index                 Q0*/
     530             :     const Word16 end_index,               /* i  : end index                   Q0*/
     531             :     const Word16 fading_type              /* i  : fading type                 Q0*/
     532             : )
     533             : {
     534             :     Word16 i;
     535             :     Word32 step_fx, step2_fx, fade_in_fx, fade_out_fx;
     536             : 
     537         119 :     step_fx = inv_time[end_index - start_index];
     538         119 :     fade_out_fx = ONE_IN_Q31; /* Q31 */
     539         119 :     move32();
     540         119 :     fade_in_fx = 0;
     541         119 :     move32();
     542             : 
     543         119 :     fade_out_fx = Mpy_32_32( fade_out_fx, inv_den_LR_ratio_mem_fx ); /* Q31 */
     544         119 :     fade_in_fx = Mpy_32_32( fade_in_fx, inv_den_LR_ratio_fx );       /* Q31 */
     545         119 :     step2_fx = Mpy_32_32( step_fx, inv_den_LR_ratio_fx );            /* Q31 */
     546         119 :     step_fx = Mpy_32_32( step_fx, inv_den_LR_ratio_mem_fx );         /* Q31 */
     547             : 
     548         119 :     IF( fading_type == 0 ) /* Switching from YX scheme to SM scheme */
     549             :     {
     550           0 :         FOR( i = start_index; i < end_index; i++ )
     551             :         {
     552           0 :             Word32 temp_left1 = Mpy_32_32( L_add( Mpy_32_32( L_sub( PCh_2_L_fx[i], SCh_2_R_fx[i] ), LR_ratio_mem_fx ), SCh_2_R_fx[i] ), fade_out_fx ); /* Qx */
     553           0 :             Word32 temp_left2 = Mpy_32_32( L_sub( Mpy_32_32( L_add( PCh_2_L_fx[i], SCh_2_R_fx[i] ), LR_ratio_fx ), SCh_2_R_fx[i] ), fade_in_fx );      /* Qx */
     554           0 :             Left_fx[i] = L_shl_sat( L_add( temp_left1, temp_left2 ), 1 );                                                                              /* Qx + 1 */
     555           0 :             move32();
     556           0 :             Word32 temp_right1 = Mpy_32_32( L_add( Mpy_32_32( L_add( PCh_2_L_fx[i], SCh_2_R_fx[i] ), L_negate( LR_ratio_mem_fx ) ), PCh_2_L_fx[i] ), fade_out_fx ); /* Qx */
     557           0 :             Word32 temp_right2 = Mpy_32_32( L_sub( Mpy_32_32( L_sub( PCh_2_L_fx[i], SCh_2_R_fx[i] ), LR_ratio_fx ), PCh_2_L_fx[i] ), fade_in_fx );                  /* Qx */
     558           0 :             Right_fx[i] = L_shl_sat( L_add( temp_right1, temp_right2 ), 1 );                                                                                        /* Qx + 1 */
     559           0 :             move32();
     560             : 
     561           0 :             fade_in_fx = L_add( fade_in_fx, step2_fx );  /* Q31 */
     562           0 :             fade_out_fx = L_sub( fade_out_fx, step_fx ); /* Q31 */
     563             :         }
     564             :     }
     565         119 :     ELSE IF( EQ_16( fading_type, 1 ) ) /* SM scheme */
     566             :     {
     567           0 :         FOR( i = start_index; i < end_index; i++ )
     568             :         {
     569           0 :             Word32 temp_left1 = Mpy_32_32( L_sub( Mpy_32_32( L_add( PCh_2_L_fx[i], SCh_2_R_fx[i] ), LR_ratio_mem_fx ), SCh_2_R_fx[i] ), fade_out_fx ); /* Qx */
     570           0 :             Word32 temp_left2 = Mpy_32_32( L_sub( Mpy_32_32( L_add( PCh_2_L_fx[i], SCh_2_R_fx[i] ), LR_ratio_fx ), SCh_2_R_fx[i] ), fade_in_fx );      /* Qx */
     571           0 :             Left_fx[i] = L_shl_sat( L_add( temp_left1, temp_left2 ), 1 );                                                                              /* Qx + 1 */
     572           0 :             move32();
     573             : 
     574           0 :             Word32 temp_right1 = Mpy_32_32( L_sub( Mpy_32_32( L_sub( PCh_2_L_fx[i], SCh_2_R_fx[i] ), LR_ratio_mem_fx ), PCh_2_L_fx[i] ), fade_out_fx ); /* Qx */
     575           0 :             Word32 temp_right2 = Mpy_32_32( L_sub( Mpy_32_32( L_sub( PCh_2_L_fx[i], SCh_2_R_fx[i] ), LR_ratio_fx ), PCh_2_L_fx[i] ), fade_in_fx );      /* Qx */
     576           0 :             Right_fx[i] = L_shl_sat( L_add( temp_right1, temp_right2 ), 1 );                                                                            /* Qx + 1 */
     577           0 :             move32();
     578             : 
     579           0 :             fade_in_fx = L_add( fade_in_fx, step2_fx );  /* Q31 */
     580           0 :             fade_out_fx = L_sub( fade_out_fx, step_fx ); /* Q31 */
     581             :         }
     582             :     }
     583         119 :     ELSE IF( EQ_16( fading_type, 2 ) ) /* Switching from SM scheme to YX scheme */
     584             :     {
     585           0 :         FOR( i = start_index; i < end_index; i++ )
     586             :         {
     587           0 :             Word32 temp_left1 = Mpy_32_32( L_sub( Mpy_32_32( L_add( PCh_2_L_fx[i], SCh_2_R_fx[i] ), LR_ratio_mem_fx ), SCh_2_R_fx[i] ), fade_out_fx ); /* Qx */
     588           0 :             Word32 temp_left2 = Mpy_32_32( L_add( Mpy_32_32( L_sub( PCh_2_L_fx[i], SCh_2_R_fx[i] ), LR_ratio_fx ), SCh_2_R_fx[i] ), fade_in_fx );      /* Qx */
     589           0 :             Left_fx[i] = L_shl_sat( L_add( temp_left1, temp_left2 ), 1 );                                                                              /* Qx + 1 */
     590           0 :             move32();
     591             : 
     592           0 :             Word32 temp_right1 = Mpy_32_32( L_sub( Mpy_32_32( L_sub( PCh_2_L_fx[i], SCh_2_R_fx[i] ), LR_ratio_mem_fx ), PCh_2_L_fx[i] ), fade_out_fx );        /* Qx */
     593           0 :             Word32 temp_right2 = Mpy_32_32( L_add( Mpy_32_32( L_add( PCh_2_L_fx[i], SCh_2_R_fx[i] ), L_negate( LR_ratio_fx ) ), PCh_2_L_fx[i] ), fade_in_fx ); /* Qx */
     594           0 :             Right_fx[i] = L_shl_sat( L_add( temp_right1, temp_right2 ), 1 );                                                                                   /* Qx + 1 */
     595           0 :             move32();
     596             : 
     597           0 :             fade_in_fx = L_add( fade_in_fx, step2_fx );  /* Q31 */
     598           0 :             fade_out_fx = L_sub( fade_out_fx, step_fx ); /* Q31 */
     599             :         }
     600             :     }
     601         119 :     ELSE IF( EQ_16( fading_type, 3 ) ) /* YX scheme */
     602             :     {
     603       18999 :         FOR( i = start_index; i < end_index; i++ )
     604             :         {
     605       18880 :             Word32 temp_left1 = Mpy_32_32( L_add( Mpy_32_32( L_sub( PCh_2_L_fx[i], SCh_2_R_fx[i] ), LR_ratio_mem_fx ), SCh_2_R_fx[i] ), fade_out_fx ); /* Qx */
     606       18880 :             Word32 temp_left2 = Mpy_32_32( L_add( Mpy_32_32( L_sub( PCh_2_L_fx[i], SCh_2_R_fx[i] ), LR_ratio_fx ), SCh_2_R_fx[i] ), fade_in_fx );      /* Qx */
     607       18880 :             Left_fx[i] = L_shl_sat( L_add( temp_left1, temp_left2 ), 1 );                                                                              /* Qx + 1 */
     608       18880 :             move32();
     609             : 
     610       18880 :             Word32 temp_right1 = Mpy_32_32( L_add( Mpy_32_32( L_add( PCh_2_L_fx[i], SCh_2_R_fx[i] ), L_negate( LR_ratio_mem_fx ) ), PCh_2_L_fx[i] ), fade_out_fx ); /* Qx */
     611       18880 :             Word32 temp_right2 = Mpy_32_32( L_add( Mpy_32_32( L_add( PCh_2_L_fx[i], SCh_2_R_fx[i] ), L_negate( LR_ratio_fx ) ), PCh_2_L_fx[i] ), fade_in_fx );      /* Qx */
     612       18880 :             Right_fx[i] = L_shl_sat( L_add( temp_right1, temp_right2 ), 1 );                                                                                        /* Qx + 1 */
     613       18880 :             move32();
     614             : 
     615       18880 :             fade_in_fx = L_add( fade_in_fx, step2_fx );  /* Q31 */
     616       18880 :             fade_out_fx = L_sub( fade_out_fx, step_fx ); /* Q31 */
     617             :         }
     618             :     }
     619             : 
     620         119 :     return;
     621             : }
     622             : /*-------------------------------------------------------------------*
     623             :  * stereo_tdm_combine()
     624             :  *
     625             :  * Combine Primary and Secondary channels into L and R channels
     626             :  *-------------------------------------------------------------------*/
     627             : 
     628        7469 : void stereo_tdm_combine_fx(
     629             :     CPE_DEC_HANDLE hCPE,       /* i/o: CPE decoder structure                       */
     630             :     Word32 *PCh_2_L_fx,        /* i/o: Primary channel -> output as left channel                                     Qx*/
     631             :     Word32 *SCh_2_R_fx,        /* i/o: Secondary channel -> output as right channel                                  Qx*/
     632             :     const Word16 output_frame, /* i  : Number of samples                                                                                        Q0*/
     633             :     const Word16 flag_HB,      /* i  : flag to distinguish between core (0) and HB (1) synthesis        Q0*/
     634             :     const Word16 tdm_ratio_idx /* i  : TDM ratio index                                                                                          Q0*/
     635             : )
     636             : {
     637             :     Word16 i;
     638             :     Word32 output_Fs;
     639             :     Word32 LR_ratio_fx, LR_ratio_mem_fx;
     640             :     Word32 Left_fx[L_FRAME48k], Right_fx[L_FRAME48k];
     641             :     Word16 upmixing_delay;
     642             :     Word16 stereo_tdm_coder_type;
     643             :     Word16 tdm_n_OVA;
     644        7469 :     Word16 tdm_last_ratio_idx = hCPE->hStereoTD->tdm_last_ratio_idx;
     645        7469 :     move16();
     646             : 
     647        7469 :     output_Fs = hCPE->hCoreCoder[0]->output_Fs; /* Q0 */
     648        7469 :     move32();
     649        7469 :     tdm_n_OVA = NS2SA_FX2( output_Fs, TDM_L_NOVA_NS ); /* Q0 */
     650        7469 :     move16();
     651             : 
     652        7469 :     IF( flag_HB )
     653             :     {
     654           0 :         upmixing_delay = NS2SA_FX2( output_Fs, ACELP_LOOK_NS + DELAY_BWE_TOTAL_NS ); /* Q0 */
     655           0 :         move16();
     656             :     }
     657             :     ELSE
     658             :     {
     659        7469 :         upmixing_delay = NS2SA_FX2( output_Fs, ACELP_LOOK_NS + DELAY_CLDFB_NS ); /* Q0 */
     660        7469 :         move16();
     661             :     }
     662             : 
     663        7469 :     LR_ratio_fx = tdm_ratio_tabl_fx[tdm_ratio_idx]; /* Q31 */
     664        7469 :     move32();
     665        7469 :     LR_ratio_mem_fx = tdm_ratio_tabl_fx[tdm_last_ratio_idx]; /* Q31 */
     666        7469 :     move32();
     667             : 
     668        7469 :     IF( hCPE->hStereoTD->flag_skip_DMX )
     669             :     {
     670         200 :         stereo_tdm_coder_type = 10; /* no DMX */
     671         200 :         move16();
     672         200 :         Copy32( PCh_2_L_fx, Left_fx, output_frame );  /* Qx */
     673         200 :         Copy32( SCh_2_R_fx, Right_fx, output_frame ); /* Qx */
     674             :     }
     675        7269 :     ELSE IF( EQ_16( hCPE->hStereoTD->tdm_last_SM_flag, 1 ) )
     676             :     {
     677           0 :         IF( hCPE->hStereoTD->tdm_prev_last_SM_flag == 0 )
     678             :         {
     679           0 :             stereo_tdm_coder_type = 0; /* mode 1 : Switching from YX scheme to SM scheme*/
     680           0 :             move16();
     681             :         }
     682             :         ELSE
     683             :         {
     684           0 :             stereo_tdm_coder_type = 1; /* mode 2 : SM scheme    Q0*/
     685           0 :             move16();
     686             :         }
     687             :     }
     688             :     ELSE
     689             :     {
     690        7269 :         IF( EQ_16( hCPE->hStereoTD->tdm_prev_last_SM_flag, 1 ) )
     691             :         {
     692           0 :             stereo_tdm_coder_type = 2; /* mode 3 : Switching from SM scheme to YX scheme*/
     693           0 :             move16();
     694             :         }
     695             :         ELSE
     696             :         {
     697        7269 :             stereo_tdm_coder_type = 3; /* mode 4 : YX scheme*/
     698        7269 :             move16();
     699             :         }
     700             :     }
     701             : 
     702        7469 :     SWITCH( stereo_tdm_coder_type )
     703             :     {
     704           0 :         case ( 0 ):
     705             :         {
     706             :             /* Do the upmixing of the first upmixing_delay samples with the old coefficient and formular for YX scheme */
     707           0 :             tdm_upmix_plain_fx( Left_fx, Right_fx, PCh_2_L_fx, SCh_2_R_fx, LR_ratio_mem_fx, tdm_den_ratio_tabl_fx[tdm_last_ratio_idx], 0, upmixing_delay, 1 );
     708             : 
     709             :             /* Switching from YX scheme to SM scheme */
     710           0 :             tdm_upmix_fade_fx( Left_fx, Right_fx, PCh_2_L_fx, SCh_2_R_fx, LR_ratio_mem_fx, tdm_den_ratio_tabl_fx[tdm_last_ratio_idx], LR_ratio_fx, tdm_den_ratio_tabl_fx[tdm_ratio_idx], upmixing_delay, add( upmixing_delay, tdm_n_OVA ), 0 );
     711             : 
     712             :             /* Do the upmixing of the other samples with the new coefficient and formular for SM scheme */
     713           0 :             tdm_upmix_plain_fx( Left_fx, Right_fx, PCh_2_L_fx, SCh_2_R_fx, LR_ratio_fx, tdm_den_ratio_tabl_fx[tdm_ratio_idx], add( upmixing_delay, tdm_n_OVA ), output_frame, 0 );
     714             :         }
     715           0 :             BREAK;
     716           0 :         case ( 1 ):
     717             :         {
     718             :             /* Do the upmixing of the first upmixing_delay samples with the old coefficient and formular for SM scheme */
     719           0 :             tdm_upmix_plain_fx( Left_fx, Right_fx, PCh_2_L_fx, SCh_2_R_fx, LR_ratio_mem_fx, tdm_den_ratio_tabl_fx[tdm_last_ratio_idx], 0, upmixing_delay, 0 );
     720             : 
     721             :             /* Do the upmixing of the other samples with the new coefficient and formular for SM scheme */
     722           0 :             IF( EQ_32( LR_ratio_fx, LR_ratio_mem_fx ) )
     723             :             {
     724           0 :                 tdm_upmix_plain_fx( Left_fx, Right_fx, PCh_2_L_fx, SCh_2_R_fx, LR_ratio_mem_fx, tdm_den_ratio_tabl_fx[tdm_last_ratio_idx], upmixing_delay, output_frame, 0 );
     725             :             }
     726             :             ELSE
     727             :             {
     728           0 :                 tdm_upmix_fade_fx( Left_fx, Right_fx, PCh_2_L_fx, SCh_2_R_fx, LR_ratio_mem_fx, tdm_den_ratio_tabl_fx[tdm_last_ratio_idx], LR_ratio_fx, tdm_den_ratio_tabl_fx[tdm_ratio_idx], upmixing_delay, add( upmixing_delay, tdm_n_OVA ), 1 );
     729           0 :                 tdm_upmix_plain_fx( Left_fx, Right_fx, PCh_2_L_fx, SCh_2_R_fx, LR_ratio_fx, tdm_den_ratio_tabl_fx[tdm_ratio_idx], upmixing_delay + tdm_n_OVA, output_frame, 0 );
     730             :             }
     731             :         }
     732           0 :             BREAK;
     733           0 :         case ( 2 ):
     734             :         {
     735             :             /* Do the upmixing of the first upmixing_delay samples with the old coefficient and formular for SM scheme */
     736           0 :             tdm_upmix_plain_fx( Left_fx, Right_fx, PCh_2_L_fx, SCh_2_R_fx, LR_ratio_mem_fx, tdm_den_ratio_tabl_fx[tdm_last_ratio_idx], 0, upmixing_delay, 0 );
     737             : 
     738             :             /* Switching from SM scheme to YX scheme */
     739           0 :             tdm_upmix_fade_fx( Left_fx, Right_fx, PCh_2_L_fx, SCh_2_R_fx, LR_ratio_mem_fx, tdm_den_ratio_tabl_fx[tdm_last_ratio_idx], LR_ratio_fx, tdm_den_ratio_tabl_fx[tdm_ratio_idx], upmixing_delay, add( upmixing_delay, tdm_n_OVA ), 2 );
     740             : 
     741             :             /* Do the upmixing of the other samples with the new coefficient and formular for YX scheme */
     742           0 :             tdm_upmix_plain_fx( Left_fx, Right_fx, PCh_2_L_fx, SCh_2_R_fx, LR_ratio_fx, tdm_den_ratio_tabl_fx[tdm_ratio_idx], upmixing_delay + tdm_n_OVA, output_frame, 1 );
     743             :         }
     744           0 :             BREAK;
     745        7269 :         case ( 3 ):
     746             :         {
     747             :             /* Do the upmixing of the first upmixing_delay samples with the old coefficient and formular for YX scheme */
     748        7269 :             tdm_upmix_plain_fx( Left_fx, Right_fx, PCh_2_L_fx, SCh_2_R_fx, LR_ratio_mem_fx, tdm_den_ratio_tabl_fx[tdm_last_ratio_idx], 0, upmixing_delay, 1 );
     749             : 
     750             :             /* Do the upmixing of the other samples with the new coefficient and formular for YX scheme */
     751        7269 :             IF( EQ_32( LR_ratio_fx, LR_ratio_mem_fx ) )
     752             :             {
     753        7150 :                 tdm_upmix_plain_fx( Left_fx, Right_fx, PCh_2_L_fx, SCh_2_R_fx, LR_ratio_mem_fx, tdm_den_ratio_tabl_fx[tdm_last_ratio_idx], upmixing_delay, output_frame, 1 );
     754             :             }
     755             :             ELSE
     756             :             {
     757         119 :                 tdm_upmix_fade_fx( Left_fx, Right_fx, PCh_2_L_fx, SCh_2_R_fx, LR_ratio_mem_fx, tdm_den_ratio_tabl_fx[tdm_last_ratio_idx], LR_ratio_fx, tdm_den_ratio_tabl_fx[tdm_ratio_idx], upmixing_delay, add( upmixing_delay, tdm_n_OVA ), 3 );
     758         119 :                 tdm_upmix_plain_fx( Left_fx, Right_fx, PCh_2_L_fx, SCh_2_R_fx, LR_ratio_fx, tdm_den_ratio_tabl_fx[tdm_ratio_idx], upmixing_delay + tdm_n_OVA, output_frame, 1 );
     759             :             }
     760             :         }
     761        7269 :             BREAK;
     762         200 :         default:
     763         200 :             BREAK;
     764             :     }
     765     4794669 :     FOR( i = 0; i < output_frame; i++ )
     766             :     {
     767     4787200 :         PCh_2_L_fx[i] = Left_fx[i]; /* Qx */
     768     4787200 :         move32();
     769     4787200 :         SCh_2_R_fx[i] = Right_fx[i]; /* Qx */
     770     4787200 :         move32();
     771             :     }
     772             : 
     773             :     /* DFT -> TD stereo switching: equalize signal energies */
     774        7469 :     IF( NE_16( hCPE->last_element_mode, IVAS_CPE_TD ) )
     775             :     {
     776             :         Word32 incr_fx, fac_fx;
     777             : 
     778         120 :         IF( hCPE->hStereoDftDmx != NULL )
     779             :         {
     780          46 :             fac_fx = ONE_IN_Q29; /* Q29 */
     781          46 :             move32();
     782             :         }
     783             :         ELSE
     784             :         {
     785          74 :             fac_fx = hCPE->hStereoTCA->targetGain_fx; /* Q29 */
     786          74 :             move32();
     787             :         }
     788             : 
     789             : 
     790         120 :         IF( LT_32( fac_fx, ONE_IN_Q29 ) )
     791             :         {
     792           0 :             Word32 step = 0;
     793           0 :             move32();
     794           0 :             SWITCH( output_Fs )
     795             :             {
     796           0 :                 case ( 16000 ):
     797           0 :                     step = 15339168; /* Q31 */
     798           0 :                     move32();
     799           0 :                     BREAK;
     800           0 :                 case ( 32000 ):
     801           0 :                     step = 7669584; /* Q31 */
     802           0 :                     move32();
     803           0 :                     BREAK;
     804           0 :                 case ( 48000 ):
     805           0 :                     step = 5113056; /* Q31 */
     806           0 :                     move32();
     807           0 :                     BREAK;
     808           0 :                 default:
     809           0 :                     assert( 0 );
     810             :                     BREAK;
     811             :             }
     812           0 :             incr_fx = Mpy_32_32( L_sub( ONE_IN_Q29, fac_fx ), step ); /* Q29 */
     813             : 
     814           0 :             FOR( i = 0; i < NS2SA_FX2( output_Fs, ACELP_LOOK_NS ); i++ )
     815             :             {
     816           0 :                 PCh_2_L_fx[i] = L_shl_sat( Mpy_32_32( PCh_2_L_fx[i], fac_fx ), 2 ); /* Qx */
     817           0 :                 move32();
     818             : 
     819           0 :                 fac_fx = L_add( incr_fx, fac_fx ); /* Q29 */
     820             :             }
     821             :         }
     822             :     }
     823        7469 :     return;
     824             : }

Generated by: LCOV version 1.14