LCOV - code coverage report
Current view: top level - lib_dec - ivas_stereo_td_dec.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 173 192 90.1 %
Date: 2025-05-23 08:37:30 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.h"
      39             : #include "ivas_prot.h"
      40             : #include "ivas_rom_com.h"
      41             : #include "ivas_cnst.h"
      42             : #ifdef DEBUGGING
      43             : #include "debug.h"
      44             : #endif
      45             : #include "wmc_auto.h"
      46             : 
      47             : /*-------------------------------------------------------------------*
      48             :  * stereo_td_init_dec()
      49             :  *
      50             :  * Initialize TD stereo decoder
      51             :  *-------------------------------------------------------------------*/
      52             : 
      53         177 : void stereo_td_init_dec(
      54             :     STEREO_TD_DEC_DATA_HANDLE hStereoTD, /* i/o: TD stereo decoder handle    */
      55             :     const int16_t last_element_mode      /* i  : last element mode           */
      56             : )
      57             : {
      58         177 :     hStereoTD->tdm_SM_flag = 0;
      59         177 :     hStereoTD->tdm_last_SM_flag = 0;
      60         177 :     hStereoTD->tdm_last_ratio_idx = LRTD_STEREO_MID_IS_PRIM;
      61         177 :     hStereoTD->tdm_prev_last_SM_flag = 0;
      62         177 :     hStereoTD->tdm_LRTD_flag = 0;
      63         177 :     hStereoTD->prevSP_ratio = 0.5f;
      64         177 :     hStereoTD->SP_ratio_LT = 0.0f;
      65         177 :     hStereoTD->c_LR_LT = 0.5f;
      66             : 
      67         177 :     hStereoTD->flag_skip_DMX = 0;
      68             : 
      69         177 :     if ( last_element_mode == IVAS_CPE_MDCT )
      70             :     {
      71          24 :         hStereoTD->tdm_last_ratio_idx = LRTD_STEREO_LEFT_IS_PRIM;
      72          24 :         hStereoTD->tdm_LRTD_flag = 1;
      73             :     }
      74             : 
      75         177 :     set_f( hStereoTD->TCX_old_syn_Overl, 0.0f, L_FRAME16k / 2 );
      76             : 
      77         177 :     return;
      78             : }
      79             : 
      80             : 
      81             : /*-------------------------------------------------------------------*
      82             :  * tdm_configure_dec()
      83             :  *
      84             :  * Configure TD stereo decoder
      85             :  *-------------------------------------------------------------------*/
      86             : 
      87       10956 : void tdm_configure_dec(
      88             :     const int16_t ivas_format,     /* i  : IVAS format                     */
      89             :     const int16_t ism_mode,        /* i  : ISM mode in combined format     */
      90             :     CPE_DEC_HANDLE hCPE,           /* i/o: CPE decoder structure           */
      91             :     int16_t *tdm_ratio_idx,        /* o  : ratio index                     */
      92             :     const int16_t nb_bits_metadata /* i  : number of metadata bits         */
      93             : )
      94             : {
      95             :     STEREO_TD_DEC_DATA_HANDLE hStereoTD;
      96             :     Decoder_State **sts;
      97             :     int16_t tdm_tmp_SM_LRTD_flag;
      98             :     int16_t mod_ct, core, bits_offset;
      99             :     int16_t idx_LRTD_pri_side, tdm_inst_ratio_idx;
     100             :     int32_t element_brate_adapt;
     101             :     int16_t bstr_last_pos;
     102             : 
     103       10956 :     hStereoTD = hCPE->hStereoTD;
     104       10956 :     sts = hCPE->hCoreCoder;
     105             : 
     106       10956 :     element_brate_adapt = hCPE->element_brate + hCPE->brate_surplus;
     107       10956 :     bstr_last_pos = (int16_t) ( hCPE->element_brate / FRAMES_PER_SEC ) - nb_bits_metadata + (int16_t) ( hCPE->brate_surplus / FRAMES_PER_SEC );
     108             : 
     109             :     /*----------------------------------------------------------------*
     110             :      * Decode CoreCoder signaling
     111             :      *----------------------------------------------------------------*/
     112             : 
     113             :     /* temporarily decode PCh signaling */
     114       10956 :     bits_offset = sts[0]->next_bit_pos;
     115       10956 :     core = get_indice_st( sts[0], hCPE->element_brate, bits_offset, 1 );
     116       10956 :     bits_offset += 1;
     117             : 
     118       10956 :     if ( core == ACELP_CORE && hCPE->element_brate < IVAS_24k4 )
     119             :     {
     120        1632 :         mod_ct = get_indice_st( sts[0], hCPE->element_brate, bits_offset, 3 );
     121             :         /* Only transition mode is important to decoder, otherwise mod_ct is set to AUDIO only to easy debugging if needed */
     122        1632 :         if ( mod_ct != TRANSITION )
     123             :         {
     124        1563 :             mod_ct = AUDIO;
     125             :         }
     126             :     }
     127             :     else /* core != ACELP_CORE */
     128             :     {
     129        9324 :         mod_ct = AUDIO; /* coder_type == VOICED || coder_type == GENERIC */
     130             :     }
     131             : 
     132             :     /* Get few parameters needed to decode the bitrate allocated to each channel */
     133             :     /* Get the coder_type of the secondary channel (last parameter on 2 bits) */
     134       10956 :     sts[1]->coder_type = get_indice_st( sts[0], element_brate_adapt, bstr_last_pos - TDM_SECONDARY_SIGNALLING, TDM_SECONDARY_SIGNALLING );
     135             : 
     136             :     /* Get the LRTD config flag:  1 = LRTD configuration, favor closer bitrate per channel;
     137             :                                   0 = Pri/Sec configuration, bitrates linked wrt. the mono */
     138       10956 :     tdm_tmp_SM_LRTD_flag = sts[1]->coder_type & 0x1;
     139       10956 :     sts[1]->coder_type >>= 1;
     140       10956 :     hStereoTD->tdm_Pitch_reuse_flag = 0;
     141             : 
     142       10956 :     if ( sts[1]->coder_type == 2 )
     143             :     {
     144       10572 :         sts[1]->coder_type = GENERIC;
     145             :     }
     146         384 :     else if ( sts[1]->coder_type == 3 )
     147             :     {
     148          99 :         sts[1]->coder_type = AUDIO;
     149             : 
     150          99 :         if ( hCPE->element_brate <= IVAS_24k4 )
     151             :         {
     152          99 :             hStereoTD->tdm_Pitch_reuse_flag = 1;
     153          99 :             sts[1]->coder_type = GENERIC;
     154             :         }
     155             :     }
     156             : 
     157             :     /*----------------------------------------------------------------*
     158             :      * Decode TDM parameters
     159             :      *----------------------------------------------------------------*/
     160             : 
     161             :     /* Get the correlation ratio */
     162       10956 :     *tdm_ratio_idx = get_indice_st( sts[0], element_brate_adapt, (int16_t) ( bstr_last_pos - TDM_SECONDARY_SIGNALLING - TDM_RATIO_BITS ), TDM_RATIO_BITS );
     163             : 
     164       10956 :     hStereoTD->tdm_use_IAWB_Ave_lpc = 0;
     165       10956 :     if ( sts[1]->coder_type == INACTIVE )
     166             :     {
     167             :         /* Get the flag on the LPC reusage type (primary channel of ave LPC */
     168           0 :         hStereoTD->tdm_use_IAWB_Ave_lpc = get_indice_st( sts[0], element_brate_adapt, bstr_last_pos - TDM_SECONDARY_SIGNALLING - TDM_RATIO_BITS - TDM_LP_REUSE_BITS, TDM_LP_REUSE_BITS );
     169           0 :         hStereoTD->tdm_lp_reuse_flag = 1;
     170             :     }
     171             :     else
     172             :     {
     173             :         /* Get the flag on the LPC reusage */
     174       10956 :         hStereoTD->tdm_lp_reuse_flag = get_indice_st( sts[0], element_brate_adapt, bstr_last_pos - TDM_SECONDARY_SIGNALLING - TDM_RATIO_BITS - TDM_LP_REUSE_BITS, TDM_LP_REUSE_BITS );
     175             :     }
     176             : 
     177       10956 :     sts[0]->tdm_LRTD_flag = hStereoTD->tdm_LRTD_flag; /* the flag was already read in function stereo_memory_dec() */
     178       10956 :     sts[1]->tdm_LRTD_flag = hStereoTD->tdm_LRTD_flag;
     179             : 
     180       10956 :     tdm_inst_ratio_idx = *tdm_ratio_idx;
     181             : 
     182             :     /* update past tdm_SM_flag */
     183       10956 :     hStereoTD->tdm_prev_last_SM_flag = hStereoTD->tdm_last_SM_flag;
     184       10956 :     hStereoTD->tdm_last_SM_flag = hStereoTD->tdm_SM_flag;
     185             : 
     186       10956 :     idx_LRTD_pri_side = -1;
     187       10956 :     if ( hStereoTD->tdm_LRTD_flag == 1 )
     188             :     {
     189       10602 :         idx_LRTD_pri_side = tdm_tmp_SM_LRTD_flag;
     190       10602 :         hStereoTD->tdm_SM_flag = 0;
     191       10602 :         if ( tdm_inst_ratio_idx == TDM_NQ )
     192             :         {
     193         300 :             hStereoTD->flag_skip_DMX = 1;
     194             :         }
     195             :         else
     196             :         {
     197       10302 :             hStereoTD->flag_skip_DMX = 0;
     198             :         }
     199             :         /* Set primary channel */
     200       10602 :         *tdm_ratio_idx = LRTD_STEREO_RIGHT_IS_PRIM;
     201       10602 :         if ( idx_LRTD_pri_side == 1 )
     202             :         {
     203        9825 :             *tdm_ratio_idx = LRTD_STEREO_LEFT_IS_PRIM;
     204             :         }
     205             :     }
     206             :     else
     207             :     {
     208         354 :         hStereoTD->tdm_SM_flag = tdm_tmp_SM_LRTD_flag;
     209         354 :         if ( hCPE->nchan_out == 1 )
     210             :         {
     211             :             /* in case of mono output, use exclusively the YX upmixing scheme in order to deal with NOOP signals */
     212          75 :             hStereoTD->tdm_SM_flag = 0;
     213             :         }
     214             :     }
     215             : 
     216       10956 :     if ( sts[1]->coder_type == INACTIVE && ( *tdm_ratio_idx >= 29 || *tdm_ratio_idx <= 1 ) )
     217             :     {
     218           0 :         hStereoTD->tdm_lp_reuse_flag = hStereoTD->tdm_use_IAWB_Ave_lpc;
     219           0 :         hStereoTD->tdm_use_IAWB_Ave_lpc = 0;
     220             :     }
     221             : 
     222             :     /*sts[1]->tdm_inst_ratio_idx = sts[0]->tdm_inst_ratio_idx;*/
     223             : 
     224       10956 :     if ( hCPE->nchan_out == 1 && hCPE->hStereoDftDmx != NULL )
     225        3864 :     {
     226             :         /* in mono DMX, only targetGain is needed */
     227        3864 :         int16_t tmpS = 20;
     228        3864 :         if ( hStereoTD->tdm_LRTD_flag == 0 )
     229             :         {
     230          75 :             tmpS = get_indice_st( sts[0], element_brate_adapt, bstr_last_pos - TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS + STEREO_BITS_TCA_CHAN + STEREO_BITS_TCA_CORRSTATS, STEREO_BITS_TCA_GD );
     231             :         }
     232        3864 :         hCPE->hStereoDftDmx->targetGain = usdequant( tmpS, STEREO_TCA_GDMIN, STEREO_TCA_GDSTEP );
     233        3864 :         hCPE->hStereoDftDmx->targetGain = powf( 10, hCPE->hStereoDftDmx->targetGain );
     234             :     }
     235             :     else
     236             :     {
     237        7092 :         if ( hStereoTD->tdm_LRTD_flag == 0 )
     238             :         {
     239         279 :             hCPE->hStereoTCA->refChanIndx = get_indice_st( sts[0], element_brate_adapt, bstr_last_pos - TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS, STEREO_BITS_TCA_CHAN );
     240         279 :             hCPE->hStereoTCA->indx_ica_NCShift = get_indice_st( sts[0], element_brate_adapt, bstr_last_pos - TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS + STEREO_BITS_TCA_CHAN, STEREO_BITS_TCA_CORRSTATS );
     241         279 :             hCPE->hStereoTCA->indx_ica_gD = get_indice_st( sts[0], element_brate_adapt, bstr_last_pos - TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS + STEREO_BITS_TCA_CHAN + STEREO_BITS_TCA_CORRSTATS, STEREO_BITS_TCA_GD );
     242             :         }
     243             :         else
     244             :         {
     245        6813 :             hCPE->hStereoTCA->refChanIndx = L_CH_INDX;
     246        6813 :             hCPE->hStereoTCA->indx_ica_NCShift = 0;
     247        6813 :             hCPE->hStereoTCA->indx_ica_gD = 20;
     248             :         }
     249        7092 :         hCPE->hStereoTCA->targetGain = usdequant( hCPE->hStereoTCA->indx_ica_gD, STEREO_TCA_GDMIN, STEREO_TCA_GDSTEP );
     250        7092 :         hCPE->hStereoTCA->targetGain = powf( 10, hCPE->hStereoTCA->targetGain );
     251             :     }
     252             : 
     253             : #ifdef DEBUG_MODE_TD
     254             :     dbgwrite( tdm_ratio_idx, 2, 1, 320, "res/tdm_ratio_idx.dec" );
     255             :     dbgwrite( &tdm_inst_ratio_idx, 2, 1, 320, "res/tdm_inst_ratio_idx.dec" );
     256             :     dbgwrite( &hStereoTD->tdm_lp_reuse_flag, 2, 1, 320, "res/tdm_lp_reuse_flag.dec" );
     257             : #endif
     258             : 
     259             :     /* set the BW of the secondary channel */
     260       10956 :     if ( hStereoTD->tdm_LRTD_flag && sts[1]->bits_frame_channel >= IVAS_16k4 / FRAMES_PER_SEC )
     261             :     {
     262             :         /* set BW of the secondary channel in LRTD stereo mode as the BW of the primary channel at higher bitrates */
     263       10602 :         sts[1]->bwidth = sts[0]->bwidth;
     264             :     }
     265             :     else
     266             :     {
     267             :         /* limit BW of the secondary channel in LRTD mode to WB for low bitrates */
     268         354 :         sts[1]->bwidth = WB;
     269             :     }
     270             : 
     271             :     /*----------------------------------------------------------------*
     272             :      * bitbudget distribution between channels (taking into account also metadata bitbudget)
     273             :      *----------------------------------------------------------------*/
     274             : 
     275       10956 :     tdm_bit_alloc( ivas_format, ism_mode, hCPE->element_brate - nb_bits_metadata * FRAMES_PER_SEC + hCPE->brate_surplus,
     276       10956 :                    hStereoTD->tdm_lp_reuse_flag, &( sts[0]->total_brate ), &( sts[1]->total_brate ),
     277       10956 :                    &hStereoTD->tdm_low_rate_mode, sts[1]->coder_type, *tdm_ratio_idx, hStereoTD->tdm_Pitch_reuse_flag,
     278       10956 :                    sts[0]->bwidth, sts[1]->bwidth, sts[0]->flag_ACELP16k, hStereoTD->tdm_LRTD_flag, mod_ct, tdm_inst_ratio_idx );
     279             : 
     280       10956 :     return;
     281             : }
     282             : 
     283             : 
     284             : /*-------------------------------------------------------------------*
     285             :  * Function tdm_downmix_plain()
     286             :  *
     287             :  * downmix Left+Right to Primary+Secondary channel
     288             :  *-------------------------------------------------------------------*/
     289             : 
     290       50691 : void tdm_upmix_plain(
     291             :     float Left[],                 /* o  : left channel            */
     292             :     float Right[],                /* o  : right channel           */
     293             :     const float PCh_2_L[],        /* i  : primary channel         */
     294             :     const float SCh_2_R[],        /* i  : secondary channel       */
     295             :     const float LR_ratio,         /* i  : mixing ratio            */
     296             :     const float inv_den_LR_ratio, /* i  : inverse mixing ration   */
     297             :     const int16_t start_index,    /* i  : start index             */
     298             :     const int16_t end_index,      /* i  : end index               */
     299             :     const int16_t plus_minus_flag /* i  : plus/minus flag         */
     300             : )
     301             : {
     302             :     int16_t i;
     303             : 
     304       50691 :     if ( plus_minus_flag == 1 )
     305             :     {
     306    14584152 :         for ( i = start_index; i < end_index; i++ )
     307             :         {
     308    14533530 :             Left[i] = ( LR_ratio * ( PCh_2_L[i] - SCh_2_R[i] ) + SCh_2_R[i] ) * inv_den_LR_ratio;
     309    14533530 :             Right[i] = ( -LR_ratio * ( PCh_2_L[i] + SCh_2_R[i] ) + PCh_2_L[i] ) * inv_den_LR_ratio;
     310             :         }
     311             :     }
     312             :     else
     313             :     {
     314       21189 :         for ( i = start_index; i < end_index; i++ )
     315             :         {
     316       21120 :             Left[i] = ( LR_ratio * ( PCh_2_L[i] + SCh_2_R[i] ) - SCh_2_R[i] ) * inv_den_LR_ratio;
     317       21120 :             Right[i] = ( LR_ratio * ( PCh_2_L[i] - SCh_2_R[i] ) - PCh_2_L[i] ) * inv_den_LR_ratio;
     318             :         }
     319             :     }
     320             : 
     321       50691 :     return;
     322             : }
     323             : 
     324             : 
     325             : /*-------------------------------------------------------------------*
     326             :  * Function tdm_downmix_fade()
     327             :  *
     328             :  * downmix Left+Right to Primary+Secondary channel with fade in/out
     329             :  *-------------------------------------------------------------------*/
     330             : 
     331         336 : static void tdm_upmix_fade(
     332             :     float Left[],                     /* o  : left channel                */
     333             :     float Right[],                    /* o  : right channel               */
     334             :     const float PCh_2_L[],            /* i  : primary channel             */
     335             :     const float SCh_2_R[],            /* i  : secondary channel           */
     336             :     const float LR_ratio_mem,         /* i  : last mixing ratio           */
     337             :     const float inv_den_LR_ratio_mem, /* i  : last inverse mixing ration  */
     338             :     const float LR_ratio,             /* i  : mixing ratio                */
     339             :     const float inv_den_LR_ratio,     /* i  : inverse mixing ration       */
     340             :     const int16_t start_index,        /* i  : start index                 */
     341             :     const int16_t end_index,          /* i  : end index                   */
     342             :     const int16_t fading_type         /* i  : fading type                 */
     343             : )
     344             : {
     345             :     int16_t i;
     346             :     float step, step2, fade_in, fade_out;
     347             : 
     348         336 :     step = 1.0f / (float) ( end_index - start_index );
     349         336 :     fade_out = 1.0f;
     350         336 :     fade_in = 0.0f;
     351             : 
     352         336 :     fade_out *= inv_den_LR_ratio_mem;
     353         336 :     fade_in *= inv_den_LR_ratio;
     354         336 :     step2 = step * inv_den_LR_ratio;
     355         336 :     step *= inv_den_LR_ratio_mem;
     356             : 
     357         336 :     if ( fading_type == 0 ) /* Switching from YX scheme to SM scheme */
     358             :     {
     359         483 :         for ( i = start_index; i < end_index; i++ )
     360             :         {
     361         480 :             Left[i] = ( LR_ratio_mem * ( PCh_2_L[i] - SCh_2_R[i] ) + SCh_2_R[i] ) * fade_out + ( LR_ratio * ( PCh_2_L[i] + SCh_2_R[i] ) - SCh_2_R[i] ) * fade_in;
     362         480 :             Right[i] = ( -LR_ratio_mem * ( PCh_2_L[i] + SCh_2_R[i] ) + PCh_2_L[i] ) * fade_out + ( LR_ratio * ( PCh_2_L[i] - SCh_2_R[i] ) - PCh_2_L[i] ) * fade_in;
     363         480 :             fade_in += step2;
     364         480 :             fade_out -= step;
     365             :         }
     366             :     }
     367         333 :     else if ( fading_type == 1 ) /* SM scheme */
     368             :     {
     369         483 :         for ( i = start_index; i < end_index; i++ )
     370             :         {
     371         480 :             Left[i] = ( LR_ratio_mem * ( PCh_2_L[i] + SCh_2_R[i] ) - SCh_2_R[i] ) * fade_out + ( LR_ratio * ( PCh_2_L[i] + SCh_2_R[i] ) - SCh_2_R[i] ) * fade_in;
     372         480 :             Right[i] = ( LR_ratio_mem * ( PCh_2_L[i] - SCh_2_R[i] ) - PCh_2_L[i] ) * fade_out + ( LR_ratio * ( PCh_2_L[i] - SCh_2_R[i] ) - PCh_2_L[i] ) * fade_in;
     373         480 :             fade_in += step2;
     374         480 :             fade_out -= step;
     375             :         }
     376             :     }
     377         330 :     else if ( fading_type == 2 ) /* Switching from SM scheme to YX scheme */
     378             :     {
     379           0 :         for ( i = start_index; i < end_index; i++ )
     380             :         {
     381           0 :             Left[i] = ( LR_ratio_mem * ( PCh_2_L[i] + SCh_2_R[i] ) - SCh_2_R[i] ) * fade_out + ( LR_ratio * ( PCh_2_L[i] - SCh_2_R[i] ) + SCh_2_R[i] ) * fade_in;
     382           0 :             Right[i] = ( LR_ratio_mem * ( PCh_2_L[i] - SCh_2_R[i] ) - PCh_2_L[i] ) * fade_out + ( -LR_ratio * ( PCh_2_L[i] + SCh_2_R[i] ) + PCh_2_L[i] ) * fade_in;
     383           0 :             fade_in += step2;
     384           0 :             fade_out -= step;
     385             :         }
     386             :     }
     387         330 :     else if ( fading_type == 3 ) /* YX scheme */
     388             :     {
     389       51930 :         for ( i = start_index; i < end_index; i++ )
     390             :         {
     391       51600 :             Left[i] = ( LR_ratio_mem * ( PCh_2_L[i] - SCh_2_R[i] ) + SCh_2_R[i] ) * fade_out + ( LR_ratio * ( PCh_2_L[i] - SCh_2_R[i] ) + SCh_2_R[i] ) * fade_in;
     392       51600 :             Right[i] = ( -LR_ratio_mem * ( PCh_2_L[i] + SCh_2_R[i] ) + PCh_2_L[i] ) * fade_out + ( -LR_ratio * ( PCh_2_L[i] + SCh_2_R[i] ) + PCh_2_L[i] ) * fade_in;
     393       51600 :             fade_in += step2;
     394       51600 :             fade_out -= step;
     395             :         }
     396             :     }
     397             : 
     398         336 :     return;
     399             : }
     400             : 
     401             : 
     402             : /*-------------------------------------------------------------------*
     403             :  * stereo_tdm_combine()
     404             :  *
     405             :  * Combine Primary and Secondary channels into L and R channels
     406             :  *-------------------------------------------------------------------*/
     407             : 
     408       22305 : void stereo_tdm_combine(
     409             :     CPE_DEC_HANDLE hCPE,        /* i/o: CPE decoder structure                       */
     410             :     float *PCh_2_L,             /* i/o: Primary channel -> output as left channel   */
     411             :     float *SCh_2_R,             /* i/o: Secondary channel -> output as right channel*/
     412             :     const int16_t output_frame, /* i  : Number of samples                           */
     413             :     const int16_t flag_HB,      /* i  : flag to distinguish between core (0) and HB (1) synthesis */
     414             :     const int16_t tdm_ratio_idx /* i  : TDM ratio index                             */
     415             : )
     416             : {
     417             :     int16_t i;
     418             :     int32_t output_Fs;
     419             :     float LR_ratio, LR_ratio_mem;
     420             :     float Left[L_FRAME48k], Right[L_FRAME48k];
     421             :     int16_t upmixing_delay;
     422             :     int16_t stereo_tdm_coder_type;
     423             :     int16_t tdm_n_OVA;
     424       22305 :     int16_t tdm_last_ratio_idx = hCPE->hStereoTD->tdm_last_ratio_idx;
     425             : 
     426       22305 :     output_Fs = hCPE->hCoreCoder[0]->output_Fs;
     427       22305 :     tdm_n_OVA = NS2SA( output_Fs, TDM_L_NOVA_NS );
     428             : 
     429       22305 :     if ( flag_HB )
     430             :     {
     431       10965 :         upmixing_delay = NS2SA( output_Fs, ACELP_LOOK_NS + DELAY_BWE_TOTAL_NS );
     432             :     }
     433             :     else
     434             :     {
     435       11340 :         upmixing_delay = NS2SA( output_Fs, ACELP_LOOK_NS + DELAY_CLDFB_NS );
     436             :     }
     437             : 
     438       22305 :     LR_ratio = tdm_ratio_tabl[tdm_ratio_idx];
     439       22305 :     LR_ratio_mem = tdm_ratio_tabl[tdm_last_ratio_idx];
     440             : 
     441       22305 :     if ( hCPE->hStereoTD->flag_skip_DMX )
     442             :     {
     443         600 :         stereo_tdm_coder_type = 10; /* no DMX */
     444         600 :         mvr2r( PCh_2_L, Left, output_frame );
     445         600 :         mvr2r( SCh_2_R, Right, output_frame );
     446             :     }
     447       21705 :     else if ( hCPE->hStereoTD->tdm_last_SM_flag == 1 )
     448             :     {
     449          36 :         if ( hCPE->hStereoTD->tdm_prev_last_SM_flag == 0 )
     450             :         {
     451           3 :             stereo_tdm_coder_type = 0; /* mode 1 : Switching from YX scheme to SM scheme*/
     452             :         }
     453             :         else
     454             :         {
     455          33 :             stereo_tdm_coder_type = 1; /* mode 2 : SM scheme*/
     456             :         }
     457             :     }
     458             :     else
     459             :     {
     460       21669 :         if ( hCPE->hStereoTD->tdm_prev_last_SM_flag == 1 )
     461             :         {
     462           0 :             stereo_tdm_coder_type = 2; /* mode 3 : Switching from SM scheme to YX scheme*/
     463             :         }
     464             :         else
     465             :         {
     466       21669 :             stereo_tdm_coder_type = 3; /* mode 4 : YX scheme*/
     467             :         }
     468             :     }
     469             : 
     470       22305 :     switch ( stereo_tdm_coder_type )
     471             :     {
     472           3 :         case ( 0 ):
     473             :         {
     474             :             /* Do the upmixing of the first upmixing_delay samples with the old coefficient and formular for YX scheme */
     475           3 :             tdm_upmix_plain( Left, Right, PCh_2_L, SCh_2_R, LR_ratio_mem, tdm_den_ratio_tabl[tdm_last_ratio_idx], 0, upmixing_delay, 1 );
     476             : 
     477             :             /* Switching from YX scheme to SM scheme */
     478           3 :             tdm_upmix_fade( Left, Right, PCh_2_L, SCh_2_R, LR_ratio_mem, tdm_den_ratio_tabl[tdm_last_ratio_idx], LR_ratio, tdm_den_ratio_tabl[tdm_ratio_idx], upmixing_delay, upmixing_delay + tdm_n_OVA, 0 );
     479             : 
     480             :             /* Do the upmixing of the other samples with the new coefficient and formular for SM scheme */
     481           3 :             tdm_upmix_plain( Left, Right, PCh_2_L, SCh_2_R, LR_ratio, tdm_den_ratio_tabl[tdm_ratio_idx], upmixing_delay + tdm_n_OVA, output_frame, 0 );
     482             :         }
     483           3 :         break;
     484          33 :         case ( 1 ):
     485             :         {
     486             :             /* Do the upmixing of the first upmixing_delay samples with the old coefficient and formular for SM scheme */
     487          33 :             tdm_upmix_plain( Left, Right, PCh_2_L, SCh_2_R, LR_ratio_mem, tdm_den_ratio_tabl[tdm_last_ratio_idx], 0, upmixing_delay, 0 );
     488             : 
     489             :             /* Do the upmixing of the other samples with the new coefficient and formular for SM scheme */
     490          33 :             if ( LR_ratio == LR_ratio_mem )
     491             :             {
     492          30 :                 tdm_upmix_plain( Left, Right, PCh_2_L, SCh_2_R, LR_ratio_mem, tdm_den_ratio_tabl[tdm_last_ratio_idx], upmixing_delay, output_frame, 0 );
     493             :             }
     494             :             else
     495             :             {
     496           3 :                 tdm_upmix_fade( Left, Right, PCh_2_L, SCh_2_R, LR_ratio_mem, tdm_den_ratio_tabl[tdm_last_ratio_idx], LR_ratio, tdm_den_ratio_tabl[tdm_ratio_idx], upmixing_delay, upmixing_delay + tdm_n_OVA, 1 );
     497           3 :                 tdm_upmix_plain( Left, Right, PCh_2_L, SCh_2_R, LR_ratio, tdm_den_ratio_tabl[tdm_ratio_idx], upmixing_delay + tdm_n_OVA, output_frame, 0 );
     498             :             }
     499             :         }
     500          33 :         break;
     501           0 :         case ( 2 ):
     502             :         {
     503             :             /* Do the upmixing of the first upmixing_delay samples with the old coefficient and formular for SM scheme */
     504           0 :             tdm_upmix_plain( Left, Right, PCh_2_L, SCh_2_R, LR_ratio_mem, tdm_den_ratio_tabl[tdm_last_ratio_idx], 0, upmixing_delay, 0 );
     505             : 
     506             :             /* Switching from SM scheme to YX scheme */
     507           0 :             tdm_upmix_fade( Left, Right, PCh_2_L, SCh_2_R, LR_ratio_mem, tdm_den_ratio_tabl[tdm_last_ratio_idx], LR_ratio, tdm_den_ratio_tabl[tdm_ratio_idx], upmixing_delay, upmixing_delay + tdm_n_OVA, 2 );
     508             : 
     509             :             /* Do the upmixing of the other samples with the new coefficient and formular for YX scheme */
     510           0 :             tdm_upmix_plain( Left, Right, PCh_2_L, SCh_2_R, LR_ratio, tdm_den_ratio_tabl[tdm_ratio_idx], upmixing_delay + tdm_n_OVA, output_frame, 1 );
     511             :         }
     512           0 :         break;
     513       21669 :         case ( 3 ):
     514             :         {
     515             :             /* Do the upmixing of the first upmixing_delay samples with the old coefficient and formular for YX scheme */
     516       21669 :             tdm_upmix_plain( Left, Right, PCh_2_L, SCh_2_R, LR_ratio_mem, tdm_den_ratio_tabl[tdm_last_ratio_idx], 0, upmixing_delay, 1 );
     517             : 
     518             :             /* Do the upmixing of the other samples with the new coefficient and formular for YX scheme */
     519       21669 :             if ( LR_ratio == LR_ratio_mem )
     520             :             {
     521       21339 :                 tdm_upmix_plain( Left, Right, PCh_2_L, SCh_2_R, LR_ratio_mem, tdm_den_ratio_tabl[tdm_last_ratio_idx], upmixing_delay, output_frame, 1 );
     522             :             }
     523             :             else
     524             :             {
     525         330 :                 tdm_upmix_fade( Left, Right, PCh_2_L, SCh_2_R, LR_ratio_mem, tdm_den_ratio_tabl[tdm_last_ratio_idx], LR_ratio, tdm_den_ratio_tabl[tdm_ratio_idx], upmixing_delay, upmixing_delay + tdm_n_OVA, 3 );
     526         330 :                 tdm_upmix_plain( Left, Right, PCh_2_L, SCh_2_R, LR_ratio, tdm_den_ratio_tabl[tdm_ratio_idx], upmixing_delay + tdm_n_OVA, output_frame, 1 );
     527             :             }
     528             :         }
     529       21669 :         break;
     530         600 :         default:
     531         600 :             break;
     532             :     }
     533             : 
     534    14351265 :     for ( i = 0; i < output_frame; i++ )
     535             :     {
     536    14328960 :         PCh_2_L[i] = Left[i];
     537    14328960 :         SCh_2_R[i] = Right[i];
     538             :     }
     539             : 
     540             :     /* DFT -> TD stereo switching: equalize signal energies */
     541       22305 :     if ( hCPE->last_element_mode != IVAS_CPE_TD )
     542             :     {
     543             :         float incr, fac;
     544             : 
     545         354 :         if ( hCPE->hStereoDftDmx != NULL )
     546             :         {
     547         132 :             fac = 1.0f;
     548             :         }
     549             :         else
     550             :         {
     551         222 :             fac = hCPE->hStereoTCA->targetGain;
     552             :         }
     553             : 
     554         354 :         if ( fac < 1.0f )
     555             :         {
     556           0 :             incr = ( 1.0f - fac ) / NS2SA( output_Fs, ACELP_LOOK_NS );
     557             : 
     558           0 :             for ( i = 0; i < NS2SA( output_Fs, ACELP_LOOK_NS ); i++ )
     559             :             {
     560           0 :                 PCh_2_L[i] *= fac;
     561           0 :                 fac += incr;
     562             :             }
     563             :         }
     564             :     }
     565             : 
     566       22305 :     return;
     567             : }

Generated by: LCOV version 1.14