LCOV - code coverage report
Current view: top level - lib_dec - ivas_stereo_cng_dec.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 394 410 96.1 %
Date: 2025-05-23 08:37:30 Functions: 9 9 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 "prot.h"
      38             : #include "ivas_prot.h"
      39             : #include "ivas_cnst.h"
      40             : #include "ivas_rom_com.h"
      41             : #ifdef DEBUGGING
      42             : #include "debug.h"
      43             : #endif
      44             : #include "wmc_auto.h"
      45             : 
      46             : /*-------------------------------------------------------------------
      47             :  * Local constants
      48             :  *-------------------------------------------------------------------*/
      49             : 
      50             : #define A_GFILT           0.8f /* LP-filter coefficient for coherence and sidegain */
      51             : #define SKIP_XFADE_FRAMES 2
      52             : 
      53             : /* DTX/CNG */
      54             : #define MAX_K                      50.0f
      55             : #define STEREO_TD_PS_CORR_FILT     0.8f
      56             : #define MAX_XFADE                  50.0f
      57             : #define CM_INIT                    50
      58             : #define CORR_INIT                  8
      59             : #define SID_INIT                   6
      60             : #define STEREO_CNA_LR_CORR_LT_FILT 0.95f /* long-term averaging factor for L/R correlation estimation in stereo CNA */
      61             : #define STEREO_CNA_ILD_LT_FILT     0.9f  /* long-term averaging factor for ILD estimation in stereo CNA */
      62             : #define STEREO_CNA_SOFT_VAD_UP     0.7f  /* long-term averaging factor for upward soft VAD update in stereo CNA */
      63             : #define STEREO_CNA_SOFT_VAD_DN     0.95f /* long-term averaging factor for downward soft VAD update in stereo CNA */
      64             : 
      65             : 
      66             : /*-------------------------------------------------------------------
      67             :  * stereo_dft_dec_sid_coh()
      68             :  *
      69             :  * Decode coherence vector
      70             :  *-------------------------------------------------------------------*/
      71             : 
      72        4065 : void stereo_dft_dec_sid_coh(
      73             :     Decoder_State *st,    /* i/o: decoder state structure     */
      74             :     const int16_t nbands, /* i  : number of DFT stereo bands  */
      75             :     float *coh,           /* i/o: coherence                   */
      76             :     int16_t *nb_bits      /* i/o: number of bits read         */
      77             : )
      78             : {
      79             :     int16_t nr_of_sid_stereo_bits;
      80             :     int16_t i;
      81             :     float alpha;
      82             :     int16_t alpha_index;
      83             :     int16_t alpha_step;
      84             :     float pred;
      85             :     float pred_err;
      86             :     int16_t coh_pred_index;
      87             :     int16_t res_index;
      88             :     float cohBandq[STEREO_DFT_BAND_MAX];
      89             :     const float *pptr;
      90             :     int16_t bits_tmp;
      91             :     int16_t b;
      92             : 
      93        4065 :     nr_of_sid_stereo_bits = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS;
      94             : 
      95             :     /* If the coherence is not encoded due to lack of bits set alpha to zero which leads to that the coherence */
      96             :     /* from the previous frame is used. */
      97        4065 :     if ( ( nr_of_sid_stereo_bits - *nb_bits - STEREO_DFT_N_COH_ALPHA_BITS - STEREO_DFT_PRED_NBITS ) > 0 )
      98             :     {
      99             :         /* Read coherence from bitstream  */
     100        4065 :         coh_pred_index = get_next_indice( st, STEREO_DFT_PRED_NBITS ); /* Read predictor index */
     101        4065 :         ( *nb_bits ) += STEREO_DFT_PRED_NBITS;
     102             : 
     103        4065 :         alpha_index = get_next_indice( st, STEREO_DFT_N_COH_ALPHA_BITS ); /* Read alpha index */
     104        4065 :         ( *nb_bits ) += STEREO_DFT_N_COH_ALPHA_BITS;
     105             : 
     106        4065 :         alpha_step = 0;
     107       20325 :         for ( i = 0; i < STEREO_DFT_N_COH_ALPHA_STEPS - 1; i++ )
     108             :         {
     109       16260 :             if ( nr_of_sid_stereo_bits - *nb_bits > dft_cng_coh_alpha_start[i] )
     110             :             {
     111       16260 :                 alpha_step = i + 1;
     112             :             }
     113             :         }
     114        4065 :         alpha = dft_cng_alpha_bits[alpha_step][alpha_index];
     115             :     }
     116             :     else
     117             :     {
     118           0 :         alpha = 0;
     119           0 :         coh_pred_index = 0;
     120           0 :         for ( i = *nb_bits; i < nr_of_sid_stereo_bits; i++ )
     121             :         {
     122           0 :             get_next_indice( st, 1 );
     123           0 :             ( *nb_bits )++;
     124             :         }
     125             :     }
     126             : 
     127        4065 :     pptr = dft_cng_coh_pred[coh_pred_index];
     128        4065 :     pred = 0.4f;
     129             : 
     130       27549 :     for ( b = 0; b < nbands; b++ )
     131             :     {
     132             :         /* Intra-frame prediction */
     133             : 
     134       79929 :         for ( i = 0; i < b; i++ )
     135             :         {
     136       56445 :             pred += ( *pptr++ ) * cohBandq[i];
     137             :         }
     138             :         /* Weighted intra/inter-frame prediction */
     139       23484 :         pred = alpha * pred + ( 1 - alpha ) * coh[b];
     140             : 
     141             :         /* Read residual index from bitstream */
     142       23484 :         if ( *nb_bits < nr_of_sid_stereo_bits ) /* If the bit limit is reached, res_index = 0 is assumed for remaining indices */
     143             :         {
     144       23484 :             bits_tmp = read_GR0( &st->bit_stream[st->next_bit_pos], &res_index, 1 );
     145       23484 :             *nb_bits += bits_tmp;
     146       23484 :             st->next_bit_pos += bits_tmp;
     147             :         }
     148             :         else
     149             :         {
     150           0 :             res_index = 0;
     151             :         }
     152             : 
     153             :         /* Reconstruct */
     154       23484 :         res_index = dft_cng_coh_u2i[res_index];
     155       23484 :         pred_err = usdequant( res_index, -0.4f, 0.1f );
     156       23484 :         cohBandq[b] = pred + pred_err; /* Store for intra-frame prediction */
     157       23484 :         if ( cohBandq[b] > 1 )
     158             :         {
     159           0 :             cohBandq[b] = 1;
     160             :         }
     161       23484 :         else if ( cohBandq[b] < 0 )
     162             :         {
     163         429 :             cohBandq[b] = 0;
     164             :         }
     165       23484 :         coh[b] = cohBandq[b]; /* Update memory for next frame */
     166       23484 :         pred = 0;
     167             :     }
     168             : 
     169             :     /* Remove padding bits */
     170       72258 :     for ( i = *nb_bits; i < nr_of_sid_stereo_bits; i++ )
     171             :     {
     172       68193 :         get_next_indice( st, 1 );
     173       68193 :         ( *nb_bits )++;
     174             :     }
     175             : 
     176             : 
     177        4065 :     return;
     178             : }
     179             : 
     180             : 
     181             : /*-------------------------------------------------------------------
     182             :  * stereo_dft_generate_comfort_noise()
     183             :  *
     184             :  * Generate the comfort noise based on the target noise level for the CLDFB part
     185             :  *-------------------------------------------------------------------*/
     186             : 
     187       32610 : static void stereo_dft_generate_comfort_noise(
     188             :     STEREO_DFT_DEC_DATA_HANDLE hStereoDft,       /* i/o: DFT Stereo decoder handle                  */
     189             :     STEREO_CNG_DEC_HANDLE hStereoCng,            /* i/o: Stereo CNG data structure                  */
     190             :     const int16_t last_element_mode,             /* i  : last element mode                          */
     191             :     Decoder_State *st,                           /* i/o: Core coder decoder state                   */
     192             :     float DFT[CPE_CHANNELS][STEREO_DFT_BUF_MAX], /* i/o: DFT buffers                                */
     193             :     Decoder_State *st1,                          /* i/o: Core coder decoder state secondary channel */
     194             :     const float targetGain,                      /* i  : ICA target gain                            */
     195             :     const int16_t chan,                          /* i  : channel number                             */
     196             :     const int16_t output_frame                   /* i  : output frame size                          */
     197             : )
     198             : {
     199             :     int16_t i, j, k;
     200             :     float *ptr_level, *ptr_shb, *ptr_r, *ptr_i;
     201             :     HANDLE_FD_CNG_COM hFdCngCom;
     202             :     int16_t numSlots;
     203             :     float scale;
     204             :     float lp_noise;
     205             :     float tmp, enr;
     206             :     float shb_shape[L_FRAME16k];
     207             :     float *ptr0, *ptr1, *ptr2;
     208             :     float dmpf[M + 2], Atmp[M + 2];
     209             :     float cngNoiseLevel_upd[L_FRAME16k], cngNoiseLevel_hist[L_FRAME16k - 2];
     210             :     float *ptr_tmp, *ptr_cng;
     211             :     float E0, E1;
     212             :     int16_t b;
     213             :     float *pSideGain;
     214             :     float gamma;
     215             :     float c;
     216             :     float scaleMS;
     217             :     float scaleAvg;
     218             :     float LR_ratio;
     219             :     float factor;
     220             :     float alpha, ftmp;
     221             :     float trigo_dec[STEREO_DFT32MS_N_16k / 2 + 1];
     222             :     const float *pTrigo;
     223             :     int16_t trigo_step;
     224             : 
     225       32610 :     hFdCngCom = st->hFdCngDec->hFdCngCom;
     226             : 
     227       32610 :     push_wmops( "DFT_CNG" );
     228             : 
     229       32610 :     set_f( dmpf, 0.0f, M + 2 );
     230       32610 :     set_f( Atmp, 0.0f, M + 2 );
     231             : 
     232       32610 :     set_zero( DFT[chan], STEREO_DFT_BUF_MAX );
     233             : 
     234       32610 :     enr = 0; /* Eliminates compiler warning. They are always set before they are used */
     235       32610 :     E0 = 0.0f;
     236       32610 :     E1 = 0.0f;
     237       32610 :     lp_noise = 0;
     238             : 
     239       32610 :     if ( chan == 0 )
     240             :     {
     241       16305 :         pSideGain = hStereoDft->side_gain + STEREO_DFT_NBDIV * STEREO_DFT_BAND_MAX;
     242      111231 :         for ( b = 0; b < hStereoDft->nbands; b++ )
     243             :         {
     244       94926 :             if ( hStereoCng->xfade_frame_counter == 0 )
     245             :             {
     246        1938 :                 hStereoDft->g_state[b] = *pSideGain++;
     247             :             }
     248             :             else
     249             :             {
     250       92988 :                 hStereoDft->g_state[b] = ( 1 - A_GFILT ) * *pSideGain++ + A_GFILT * hStereoDft->g_state[b];
     251             :             }
     252             : 
     253       94926 :             if ( hStereoCng->first_SID )
     254             :             {
     255         258 :                 if ( hStereoCng->first_SID_after_TD )
     256             :                 {
     257           0 :                     hStereoCng->cm[b] = hStereoCng->c_LR_LT * hStereoCng->c_LR_LT;
     258             :                 }
     259             :                 else
     260             :                 {
     261         258 :                     hStereoCng->cm[b] = hStereoCng->coh[b];
     262             :                 }
     263             :             }
     264       94668 :             else if ( hStereoCng->nr_dft_frames < CM_INIT && hStereoCng->nr_sid_frames < SID_INIT )
     265             :             {
     266           0 :                 if ( hStereoCng->nr_corr_frames > CORR_INIT )
     267             :                 {
     268           0 :                     hStereoCng->cm[b] = hStereoCng->c_LR_LT * hStereoCng->c_LR_LT;
     269             :                 }
     270             :                 else
     271             :                 {
     272           0 :                     hStereoCng->cm[b] = ( 1 - A_GFILT ) * hStereoCng->coh[b] + A_GFILT * hStereoCng->cm[b];
     273             :                 }
     274             :             }
     275             :             else
     276             :             {
     277       94668 :                 hStereoCng->cm[b] = ( 1 - A_GFILT ) * hStereoCng->coh[b] + A_GFILT * hStereoCng->cm[b];
     278             :             }
     279             :         }
     280             : 
     281       16305 :         if ( hStereoCng->first_SID_after_TD )
     282             :         {
     283          42 :             scaleAvg = 0;
     284         279 :             for ( b = 0; b < hStereoDft->nbands; b++ )
     285             :             {
     286         237 :                 if ( hStereoCng->cm[b] < 0.9f )
     287             :                 {
     288         237 :                     gamma = hStereoCng->cm[b];
     289         237 :                     gamma = gamma / ( 1 - gamma );
     290         237 :                     gamma = sqrtf( gamma + 1 - hStereoDft->g_state[b] * hStereoDft->g_state[b] ) - sqrtf( gamma );
     291             :                 }
     292             :                 else
     293             :                 {
     294           0 :                     gamma = 0;
     295             :                 }
     296             : 
     297         237 :                 LR_ratio = tdm_ratio_tabl[hStereoCng->last_tdm_idx];
     298         237 :                 c = ( ( 1 + hStereoDft->g_state[b] ) * ( 1 + hStereoDft->g_state[b] ) + gamma * gamma ) / ( ( 1 - hStereoDft->g_state[b] ) * ( 1 - hStereoDft->g_state[b] ) + gamma * gamma );
     299         237 :                 scaleMS = ( 1 + c + 2 * sqrtf( c * hStereoCng->cm[b] ) ) / ( 4 * ( c * LR_ratio * LR_ratio + ( 1 - LR_ratio ) * ( 1 - LR_ratio ) * targetGain * targetGain + 2 * LR_ratio * ( 1 - LR_ratio ) * targetGain * sqrtf( c * hStereoCng->cm[b] ) ) );
     300         237 :                 scaleMS = sqrtf( scaleMS );
     301         237 :                 scaleAvg += scaleMS;
     302             :             }
     303          42 :             scaleAvg = scaleAvg / hStereoDft->nbands;
     304             : 
     305          42 :             hStereoDft->scale = scaleAvg;
     306             :         }
     307             :     }
     308             : 
     309       32610 :     if ( st->cng_type == LP_CNG )
     310             :     {
     311        7440 :         set_f( cngNoiseLevel_upd, 0.0f, st->L_frame );
     312             : 
     313             :         /* Deemphasis */
     314        7440 :         dmpf[0] = 1.0f;
     315        7440 :         dmpf[1] = -st->preemph_fac;
     316        7440 :         mvr2r( st->Aq_cng, Atmp, M + 1 );
     317        7440 :         conv( Atmp, dmpf, cngNoiseLevel_upd, M + 2 );
     318             : 
     319        7440 :         if ( st->L_frame == L_FRAME )
     320             :         {
     321        2142 :             pTrigo = hStereoDft->dft_trigo_12k8;
     322        2142 :             trigo_step = STEREO_DFT_TRIGO_SRATE_12k8_STEP * STEREO_DFT_TRIGO_DEC_STEP;
     323             :         }
     324             :         else
     325             :         {
     326        5298 :             pTrigo = hStereoDft->dft_trigo_16k;
     327        5298 :             trigo_step = STEREO_DFT_TRIGO_SRATE_16k_STEP * STEREO_DFT_TRIGO_DEC_STEP;
     328             :         }
     329             : 
     330      568368 :         for ( i = 0; i < st->L_frame / 4; i++ )
     331             :         {
     332      560928 :             trigo_dec[i] = pTrigo[i * trigo_step];
     333      560928 :             trigo_dec[st->L_frame / 2 - i] = pTrigo[i * trigo_step];
     334             :         }
     335        7440 :         trigo_dec[st->L_frame / 4] = pTrigo[st->L_frame / 4 * trigo_step];
     336             : 
     337        7440 :         rfft( cngNoiseLevel_upd, trigo_dec, st->L_frame, -1 );
     338             : 
     339             :         /* Compute 1/|A| */
     340        7440 :         ptr0 = cngNoiseLevel_upd;
     341        7440 :         ptr1 = ptr0 + 2;
     342        7440 :         ptr2 = ptr1 + 1;
     343        7440 :         assert( st->lp_ener > 0.0f );
     344        7440 :         factor = 2.0f * sqrtf( st->lp_ener / st->L_frame * 0.5f ); /* fixed factor  in the loop below */
     345     1121856 :         for ( i = 0; i < st->L_frame / 2 - 1; i++ )
     346             :         {
     347     1114416 :             ftmp = *ptr1 * *ptr1 + *ptr2 * *ptr2;
     348     1114416 :             assert( ftmp > 0.0f );
     349     1114416 :             *ptr0++ = factor * inv_sqrt( ftmp );
     350     1114416 :             ptr1 += 2;
     351     1114416 :             ptr2 += 2;
     352             :         }
     353             : 
     354        7440 :         if ( min( output_frame, L_FRAME32k ) - hFdCngCom->stopFFTbin > 0 )
     355             :         {
     356             :             /* Transform shb LP spectrum */
     357        6378 :             set_f( shb_shape, 0.0f, L_FRAME16k );
     358        6378 :             mvr2r( st->hTdCngDec->shb_lpcCNG, shb_shape, LPC_SHB_ORDER + 1 );
     359             : 
     360        6378 :             if ( st->L_frame != L_FRAME16k )
     361             :             {
     362        2142 :                 pTrigo = hStereoDft->dft_trigo_16k;
     363        2142 :                 trigo_step = STEREO_DFT_TRIGO_SRATE_16k_STEP * STEREO_DFT_TRIGO_DEC_STEP;
     364             : 
     365      173502 :                 for ( i = 0; i < L_FRAME16k / 4; i++ )
     366             :                 {
     367      171360 :                     trigo_dec[i] = pTrigo[i * trigo_step];
     368      171360 :                     trigo_dec[L_FRAME16k / 2 - i] = pTrigo[i * trigo_step];
     369             :                 }
     370        2142 :                 trigo_dec[L_FRAME16k / 4] = pTrigo[L_FRAME16k / 4 * trigo_step];
     371             :             }
     372             : 
     373        6378 :             rfft( shb_shape, trigo_dec, L_FRAME16k, -1 );
     374             : 
     375             :             /* Compute 1/|A| */
     376        6378 :             enr = shb_shape[0] * shb_shape[0] + shb_shape[1] * shb_shape[1];
     377        6378 :             ptr0 = shb_shape;
     378        6378 :             ptr1 = ptr0 + 2;
     379        6378 :             ptr2 = ptr1 + 1;
     380             : 
     381     1020480 :             for ( i = 0; i < L_FRAME16k / 2 - 1; i++ )
     382             :             {
     383     1014102 :                 ftmp = ( *ptr1 * *ptr1 + *ptr2 * *ptr2 );
     384     1014102 :                 assert( ftmp > 0.0f );
     385     1014102 :                 ftmp = 1.0f / ftmp;
     386             :                 /* in float:
     387             :                      both a = "div"=(1/(x^2+y^2) and sqrt(a)  is used and summed up in the same loop.
     388             : 
     389             :                   in BASOP:
     390             :                     sum up  using inv_sqrt( *ptr1 * *ptr1 + *ptr2 * *ptr2 ), in this loop
     391             :                     and then sum up  enr = sum( *ptr0 * *ptr0 ),  in a subsequent MAC loop  */
     392     1014102 :                 enr += ftmp;
     393     1014102 :                 *ptr0++ = sqrtf( ftmp );
     394     1014102 :                 ptr1 += 2;
     395     1014102 :                 ptr2 += 2;
     396             :             }
     397             :         }
     398             : 
     399             :         /* Update CNG noise level from MS noise estimation */
     400        7440 :         mvr2r( st->hFdCngDec->bandNoiseShape, cngNoiseLevel_hist, hFdCngCom->stopFFTbin - hFdCngCom->startBand );
     401        7440 :         ptr_cng = cngNoiseLevel_hist;
     402     1121856 :         for ( i = 0; i < ( st->last_L_frame - hFdCngCom->startBand ) / 2; i++ )
     403             :         {
     404     1114416 :             tmp = *( cngNoiseLevel_hist + i * 2 );
     405     1114416 :             tmp += *( cngNoiseLevel_hist + i * 2 + 1 );
     406     1114416 :             *ptr_cng++ = tmp * 0.5f;
     407             :         }
     408             : 
     409        7440 :         if ( last_element_mode == IVAS_CPE_TD && chan == 0 && hStereoCng->xfade_frame_counter == 0 && !( hFdCngCom->msFrCnt_init_counter < hFdCngCom->msFrCnt_init_thresh ) )
     410             :         {
     411          21 :             ptr_cng = cngNoiseLevel_hist + hFdCngCom->startBand;
     412          21 :             ptr_tmp = cngNoiseLevel_upd + hFdCngCom->startBand;
     413        3360 :             for ( i = 0; i < ( st->last_L_frame - hFdCngCom->startBand ) / 2; i++ )
     414             :             {
     415        3339 :                 E0 += *ptr_cng++;
     416        3339 :                 E1 += ( *ptr_tmp ) * ( *ptr_tmp );
     417        3339 :                 ptr_tmp++;
     418             :             }
     419             : 
     420          21 :             tmp = sqrtf( E0 / E1 );
     421          21 :             if ( tmp < 1 )
     422             :             {
     423          21 :                 hStereoCng->xfade_length = (int16_t) ( -MAX_XFADE * tmp + MAX_XFADE );
     424             :             }
     425             :             else
     426             :             {
     427           0 :                 hStereoCng->xfade_length = (int16_t) ( -MAX_XFADE * ( 1 / tmp ) + MAX_XFADE );
     428             :             }
     429             :         }
     430             : 
     431        7440 :         if ( hStereoCng->xfade_frame_counter < hStereoCng->xfade_length )
     432             :         {
     433         222 :             ptr_cng = cngNoiseLevel_hist + hFdCngCom->startBand;
     434         222 :             ptr_tmp = cngNoiseLevel_upd + hFdCngCom->startBand;
     435       35520 :             for ( i = 0; i < ( st->last_L_frame - hFdCngCom->startBand ) / 2; i++ )
     436             :             {
     437       35298 :                 tmp = hStereoCng->xfade_frame_counter / (float) hStereoCng->xfade_length;
     438       35298 :                 *ptr_tmp = tmp * *ptr_tmp + ( 1 - tmp ) * sqrtf( *ptr_cng++ ) * hStereoDft->scale;
     439       35298 :                 ptr_tmp++;
     440             :             }
     441             :         }
     442             : 
     443       22320 :         for ( k = 0; k < STEREO_DFT_NBDIV; k++ )
     444             :         {
     445             :             /* low band */
     446       14880 :             ptr_level = cngNoiseLevel_upd;
     447       14880 :             ptr_r = DFT[chan] + hFdCngCom->startBand + k * STEREO_DFT32MS_N_MAX;
     448       14880 :             ptr_i = ptr_r + 1;
     449       14880 :             scale = output_frame * 0.5f;
     450             : 
     451     2243712 :             for ( i = 0; i < ( hFdCngCom->stopFFTbin - hFdCngCom->startBand ) / 2; i++ )
     452             :             {
     453             :                 /* Real part in FFT bins */
     454     2228832 :                 rand_gauss( ptr_r, &st->hTdCngDec->cng_seed );
     455     2228832 :                 tmp = scale * *ptr_level;
     456     2228832 :                 ( *ptr_r ) *= tmp;
     457     2228832 :                 ptr_r += 2;
     458             :                 /* Imaginary part in FFT bins */
     459     2228832 :                 rand_gauss( ptr_i, &st->hTdCngDec->cng_seed );
     460     2228832 :                 ( *ptr_i ) *= tmp;
     461     2228832 :                 ptr_i += 2;
     462     2228832 :                 ptr_level++;
     463             :             }
     464             : 
     465       14880 :             if ( min( output_frame, L_FRAME32k ) - hFdCngCom->stopFFTbin > 0 )
     466             :             {
     467             : 
     468             :                 /* high band generation, flipped spectrum */
     469       12756 :                 assert( enr != 0.0f );
     470       12756 :                 scale = sqrtf( powf( 10, 0.1f * st->hTdCngDec->shb_cng_gain ) / enr );
     471       12756 :                 ptr_shb = shb_shape + L_FRAME16k / 2 - 1;
     472             :                 /* Averaging for Nyquist frequency */
     473       12756 :                 *ptr_shb = 0.5f * ( cngNoiseLevel_upd[( hFdCngCom->stopFFTbin - hFdCngCom->startBand ) / 2 - 1] / scale + *( ptr_shb - 1 ) );
     474             : 
     475       12756 :                 ptr_r = DFT[chan] + hFdCngCom->stopFFTbin + k * STEREO_DFT32MS_N_MAX;
     476       12756 :                 ptr_i = ptr_r + 1;
     477             : 
     478     1554804 :                 for ( i = 0; i < ( min( output_frame, hFdCngCom->regularStopBand * 16 ) - hFdCngCom->stopFFTbin ) / 2; i++ )
     479             :                 {
     480             :                     /* Real part in FFT bins */
     481     1542048 :                     rand_gauss( ptr_r, &st->hTdCngDec->cng_seed );
     482     1542048 :                     ( *ptr_r ) *= *ptr_shb;
     483     1542048 :                     ptr_r += 2;
     484             :                     /* Imaginary part in FFT bins */
     485     1542048 :                     rand_gauss( ptr_i, &st->hTdCngDec->cng_seed );
     486     1542048 :                     ( *ptr_i ) *= *ptr_shb;
     487     1542048 :                     ptr_i += 2;
     488     1542048 :                     ptr_shb--;
     489             :                 }
     490             : 
     491             :                 /* rescale */
     492       12756 :                 scale *= output_frame * 0.5f;
     493       12756 :                 ptr_r = DFT[chan] + hFdCngCom->stopFFTbin + k * STEREO_DFT32MS_N_MAX;
     494       12756 :                 ptr_i = ptr_r + 1;
     495     1554804 :                 for ( i = 0; i < ( min( output_frame, hFdCngCom->regularStopBand * 16 ) - hFdCngCom->stopFFTbin ) / 2; i++ )
     496             :                 {
     497     1542048 :                     ( *ptr_r ) *= scale;
     498     1542048 :                     ( *ptr_i ) *= scale;
     499     1542048 :                     ptr_r += 2;
     500     1542048 :                     ptr_i += 2;
     501             :                 }
     502             :             }
     503             :         }
     504             : 
     505             :         /* Expand cngNoiseLevel from 0-159 to 0-318, compute noise level */
     506        7440 :         lp_noise = 0.0f;
     507        7440 :         ptr_level = hFdCngCom->cngNoiseLevel + hFdCngCom->stopFFTbin - hFdCngCom->startBand - 1;
     508        7440 :         ptr_tmp = cngNoiseLevel_upd + ( hFdCngCom->stopFFTbin - hFdCngCom->startBand ) / 2 - 1;
     509     1121856 :         for ( i = 0; i < ( hFdCngCom->stopFFTbin - hFdCngCom->startBand ) / 2; i++ )
     510             :         {
     511     1114416 :             *ptr_level-- = *ptr_tmp * *ptr_tmp;
     512     1114416 :             ptr_tmp--;
     513     1114416 :             *ptr_level = *( ptr_level + 1 );
     514     1114416 :             lp_noise += 2 * *ptr_level--;
     515             :         }
     516             :     }
     517             :     else
     518             :     {
     519             :         /* FD-CNG */
     520       25170 :         if ( !( hFdCngCom->msFrCnt_init_counter < hFdCngCom->msFrCnt_init_thresh ) )
     521             :         {
     522       25170 :             if ( hStereoCng->xfade_frame_counter <= MAX_K && hStereoCng->last_act_element_mode == IVAS_CPE_TD && chan == 0 )
     523             :             {
     524             :                 /* Fade MS -> SID/MS */
     525         168 :                 j = 0;
     526        3360 :                 for ( k = 0; k < ( hFdCngCom->nFFTpart - 2 ); k++ )
     527             :                 {
     528        3192 :                     factor = ( hFdCngCom->sidNoiseEstLp[k] + DELTA ) / ( st->hFdCngDec->partNoiseShape[k] + DELTA );
     529        3192 :                     factor = min( hStereoDft->scale + ( 1 / MAX_K ) * ( factor - hStereoDft->scale ) * hStereoCng->xfade_frame_counter, factor );
     530       38640 :                     for ( ; j <= hFdCngCom->part[k]; j++ )
     531             :                     {
     532       35448 :                         hFdCngCom->cngNoiseLevel[j] = st->hFdCngDec->bandNoiseShape[j] * factor;
     533             :                     }
     534             :                 }
     535             :             }
     536             :         }
     537       25170 :         scale = output_frame * 0.5f;
     538       25170 :         numSlots = hFdCngCom->numSlots / 2;
     539       75510 :         for ( k = 0; k < STEREO_DFT_NBDIV; k++ )
     540             :         {
     541       50340 :             ptr_level = hFdCngCom->cngNoiseLevel;
     542       50340 :             ptr_r = DFT[chan] + hFdCngCom->startBand + k * STEREO_DFT32MS_N_MAX;
     543       50340 :             ptr_i = ptr_r + 1;
     544     7247616 :             for ( i = 0; i < ( hFdCngCom->stopFFTbin - hFdCngCom->startBand ) / 2; i++ )
     545             :             {
     546             :                 /* Real part in FFT bins */
     547     7197276 :                 tmp = *ptr_level++;
     548     7197276 :                 tmp += *ptr_level++;
     549     7197276 :                 tmp = tmp * 0.5f;
     550     7197276 :                 rand_gauss( ptr_r, &st->hTdCngDec->cng_seed );
     551     7197276 :                 tmp = sqrtf( tmp ) * scale;
     552     7197276 :                 ( *ptr_r ) *= tmp;
     553     7197276 :                 ptr_r += 2;
     554             :                 /* Imaginary part in FFT bins */
     555     7197276 :                 rand_gauss( ptr_i, &st->hTdCngDec->cng_seed );
     556     7197276 :                 ( *ptr_i ) *= tmp;
     557     7197276 :                 ptr_i += 2;
     558             :             }
     559       50340 :             ptr_level = hFdCngCom->cngNoiseLevel + hFdCngCom->stopFFTbin - hFdCngCom->startBand;
     560       50340 :             ptr_r = DFT[chan] + hFdCngCom->stopFFTbin + k * STEREO_DFT32MS_N_MAX;
     561       50340 :             ptr_i = ptr_r + 1;
     562      739068 :             for ( j = hFdCngCom->numCoreBands; j < hFdCngCom->regularStopBand; j++ )
     563             :             {
     564     6198552 :                 for ( i = 0; i < numSlots; i++ )
     565             :                 {
     566             :                     /* Real part in FFT bins */
     567     5509824 :                     rand_gauss( ptr_r, &st->hTdCngDec->cng_seed );
     568     5509824 :                     tmp = sqrtf( *ptr_level ) * scale;
     569     5509824 :                     ( *ptr_r ) *= tmp;
     570     5509824 :                     ptr_r += 2;
     571             :                     /* Imaginary part in FFT bins */
     572     5509824 :                     rand_gauss( ptr_i, &st->hTdCngDec->cng_seed );
     573     5509824 :                     ( *ptr_i ) *= tmp;
     574     5509824 :                     ptr_i += 2;
     575             :                 }
     576      688728 :                 ptr_level++;
     577             :             }
     578             :         }
     579             : 
     580             :         /* Compute noise level */
     581       25170 :         lp_noise = 0.0f;
     582       25170 :         ptr_level = hFdCngCom->cngNoiseLevel;
     583     7222446 :         for ( i = 0; i < hFdCngCom->stopFFTbin - hFdCngCom->startBand; i++ )
     584             :         {
     585     7197276 :             lp_noise += *ptr_level++;
     586             :         }
     587             :     }
     588             : 
     589       32610 :     if ( hStereoCng->last_act_element_mode == IVAS_CPE_TD && chan > 0 )
     590             :     {
     591         279 :         st1->lp_noise = 0.9f * st1->lp_noise + 0.1f * 10.f * log10f( lp_noise + DELTA );
     592             :     }
     593       32331 :     else if ( chan == 0 )
     594             :     {
     595       16305 :         st->hFdCngDec->lp_noise = 0.9f * st->hFdCngDec->lp_noise + 0.1f * 10.f * log10f( lp_noise + DELTA );
     596       16305 :         st->lp_noise = st->hFdCngDec->lp_noise;
     597       16305 :         st->hFdCngDec->hFdCngCom->flag_noisy_speech = ( st->hFdCngDec->lp_speech - st->hFdCngDec->lp_noise ) < 28.f;
     598       16305 :         st->hFdCngDec->hFdCngCom->likelihood_noisy_speech = 0.99f * st->hFdCngDec->hFdCngCom->likelihood_noisy_speech + 0.01f * st->hFdCngDec->hFdCngCom->flag_noisy_speech;
     599             :     }
     600             : 
     601       32610 :     if ( chan == 0 && st->core_brate <= SID_2k40 )
     602             :     {
     603             :         /* update smoothed periodogram used by stereo CNA in SID and NO_DATA frames from cngNoiseLevel */
     604     4729359 :         for ( i = hFdCngCom->startBand; i < hFdCngCom->stopFFTbin; i++ )
     605             :         {
     606     4713054 :             ftmp = hFdCngCom->cngNoiseLevel[i - hFdCngCom->startBand];
     607             : 
     608     4713054 :             if ( !st->hFdCngDec->first_cna_noise_updated )
     609             :             {
     610             :                 /* very first update */
     611        7818 :                 alpha = 0.0f;
     612             :             }
     613             :             else
     614             :             {
     615     4705236 :                 alpha = 0.95f;
     616     4705236 :                 if ( st->hFdCngDec->smoothed_psd[i] > 0.0f && ftmp > 2.5f * st->hFdCngDec->smoothed_psd[i] )
     617             :                 {
     618             :                     /* prevent abrupt upward update steps */
     619       54501 :                     ftmp = 2.5f * st->hFdCngDec->smoothed_psd[i];
     620             :                 }
     621     4650735 :                 else if ( ftmp < st->hFdCngDec->smoothed_psd[i] )
     622             :                 {
     623             :                     /* faster downward updates */
     624     1472073 :                     alpha = 0.7f;
     625             :                 }
     626             :             }
     627             : 
     628             :             /* smoothing */
     629     4713054 :             st->hFdCngDec->smoothed_psd[i] = alpha * st->hFdCngDec->smoothed_psd[i] + ( 1 - alpha ) * ftmp;
     630             :         }
     631             : 
     632             :         /* update msNoiseEst in SID and NO_DATA frames */
     633       16305 :         bandcombinepow( &st->hFdCngDec->smoothed_psd[hFdCngCom->startBand], hFdCngCom->stopFFTbin - hFdCngCom->startBand, st->hFdCngDec->part_shaping, st->hFdCngDec->nFFTpart_shaping, st->hFdCngDec->psize_inv_shaping, st->hFdCngDec->msNoiseEst );
     634             : 
     635       16305 :         st->hFdCngDec->first_cna_noise_updated = 1;
     636       16305 :         mvr2r( st->hFdCngDec->msNoiseEst, st->hFdCngDec->msPeriodog_ST, st->hFdCngDec->nFFTpart_shaping );
     637       16305 :         st->hFdCngDec->ms_last_inactive_bwidth = st->bwidth;
     638             :     }
     639             : 
     640       32610 :     pop_wmops();
     641       32610 :     return;
     642             : }
     643             : 
     644             : 
     645             : /*-------------------------------------------------------------------
     646             :  * stereo_dtf_cng()
     647             :  *
     648             :  * DFT stereo CNG
     649             :  *-------------------------------------------------------------------*/
     650             : 
     651      127719 : void stereo_dtf_cng(
     652             :     CPE_DEC_HANDLE hCPE,                         /* i/o: CPE decoder structure    */
     653             :     const int32_t ivas_total_brate,              /* i  : IVAS total bitrate       */
     654             :     float DFT[CPE_CHANNELS][STEREO_DFT_BUF_MAX], /* i/o: DFT buffers              */
     655             :     const int16_t output_frame                   /* i  : output frame size        */
     656             : )
     657             : {
     658             :     Decoder_State **sts;
     659             :     int16_t n;
     660             : 
     661      127719 :     sts = hCPE->hCoreCoder;
     662             : 
     663      127719 :     if ( hCPE->hStereoCng != NULL )
     664             :     {
     665      127719 :         if ( hCPE->hStereoCng->nr_dft_frames < CM_INIT )
     666             :         {
     667       18384 :             hCPE->hStereoCng->nr_dft_frames++;
     668             :         }
     669             : 
     670      127719 :         if ( ivas_total_brate <= IVAS_SID_5k2 )
     671             :         {
     672       16305 :             if ( hCPE->hStereoCng->nr_sid_frames < SID_INIT && ivas_total_brate == IVAS_SID_5k2 )
     673             :             {
     674         270 :                 hCPE->hStereoCng->nr_sid_frames++;
     675             :             }
     676             : 
     677       48915 :             for ( n = 0; n < CPE_CHANNELS; n++ )
     678             :             {
     679       32610 :                 stereo_dft_generate_comfort_noise( hCPE->hStereoDft, hCPE->hStereoCng, hCPE->last_element_mode, sts[0], DFT, sts[1], hCPE->hStereoTCA->targetGain, n, output_frame );
     680             :             }
     681             :         }
     682             :     }
     683             : 
     684      127719 :     return;
     685             : }
     686             : 
     687             : 
     688             : /*-------------------------------------------------------------------
     689             :  * stereo_cng_dec_update()
     690             :  *
     691             :  * Update counters used for TD->DFT-CNG cross fade and stereo SID parameters
     692             :  *-------------------------------------------------------------------*/
     693             : 
     694      190398 : void stereo_cng_dec_update(
     695             :     CPE_DEC_HANDLE hCPE,           /* i/o: CPE decoder structure    */
     696             :     const int32_t ivas_total_brate /* i  : IVAS total bitrate       */
     697             : )
     698             : {
     699      190398 :     if ( hCPE->hCoreCoder[0]->core_brate > SID_2k40 )
     700             :     {
     701      159594 :         hCPE->hStereoCng->last_act_element_mode = hCPE->element_mode;
     702      159594 :         if ( hCPE->hStereoCng->active_frame_counter > SKIP_XFADE_FRAMES )
     703             :         {
     704      150633 :             hCPE->hStereoCng->xfade_frame_counter = 0;
     705      150633 :             hCPE->hStereoCng->xfade_length = 0;
     706             :         }
     707      159594 :         if ( hCPE->hStereoCng->active_frame_counter < MAX_FRAME_COUNTER )
     708             :         {
     709      103866 :             hCPE->hStereoCng->active_frame_counter++;
     710             :         }
     711             :     }
     712             :     else
     713             :     {
     714       30804 :         hCPE->hStereoCng->active_frame_counter = 0;
     715       30804 :         if ( hCPE->hStereoCng->xfade_frame_counter < MAX_FRAME_COUNTER )
     716             :         {
     717       30804 :             hCPE->hStereoCng->xfade_frame_counter++;
     718             :         }
     719             :     }
     720             : 
     721      190398 :     if ( hCPE->element_mode == IVAS_CPE_DFT )
     722             :     {
     723      179058 :         if ( ivas_total_brate == IVAS_SID_5k2 || ivas_total_brate == FRAME_NO_DATA )
     724             :         {
     725       30804 :             hCPE->hStereoCng->prev_sid_nodata = 1;
     726             :         }
     727             :         else
     728             :         {
     729      148254 :             hCPE->hStereoCng->prev_sid_nodata = 0;
     730             :         }
     731             :     }
     732             : 
     733      190398 :     hCPE->hCoreCoder[0]->hFdCngDec->hFdCngCom->active_frame_counter = hCPE->hStereoCng->active_frame_counter;
     734             : 
     735      190398 :     return;
     736             : }
     737             : 
     738             : 
     739             : /*-------------------------------------------------------------------*
     740             :  * Function stereo_cng_compute_PScorr()
     741             :  *
     742             :  * CNA for TD stereo, compute PS correlation
     743             :  *-------------------------------------------------------------------*/
     744             : 
     745       11340 : void stereo_cng_compute_PScorr(
     746             :     float *output[CPE_CHANNELS], /* i  : Output signal     */
     747             :     float *c_PS_LT,              /* i/o: Correlation       */
     748             :     const int16_t L_frame_0,     /* i  : L_frame channel 0 */
     749             :     const int16_t L_frame_1      /* i  : L_frame channel 1 */
     750             : )
     751             : {
     752             :     int16_t i;
     753             :     float enrP, enrS, dotPS;
     754             :     float c_PS;
     755             :     float outputResamp[L_FRAME16k];
     756             :     float *outputPptr, *outputSptr;
     757             : 
     758       11340 :     enrP = 0.0f;
     759       11340 :     enrS = 0.0f;
     760       11340 :     dotPS = 0.0f;
     761             : 
     762       11340 :     if ( L_frame_0 > L_frame_1 )
     763             :     {
     764        6294 :         outputPptr = output[0];
     765        6294 :         lerp( output[1], outputResamp, L_frame_0, L_frame_1 );
     766        6294 :         outputSptr = outputResamp;
     767             :     }
     768        5046 :     else if ( L_frame_1 > L_frame_0 )
     769             :     {
     770           0 :         outputSptr = output[1];
     771           0 :         lerp( output[0], outputResamp, L_frame_1, L_frame_0 );
     772           0 :         outputPptr = outputResamp;
     773             :     }
     774             :     else
     775             :     {
     776        5046 :         outputPptr = output[0];
     777        5046 :         outputSptr = output[1];
     778             :     }
     779             : 
     780     3317196 :     for ( i = 0; i < L_frame_0; i++ )
     781             :     {
     782     3305856 :         enrP += *outputPptr * *outputPptr;
     783     3305856 :         enrS += *outputSptr * *outputSptr;
     784     3305856 :         dotPS += *outputPptr++ * *outputSptr++;
     785             :     }
     786             : 
     787       11340 :     c_PS = ( dotPS + EPSILON ) * inv_sqrt( enrP * enrS + EPSILON );
     788             : 
     789       11340 :     *c_PS_LT = STEREO_TD_PS_CORR_FILT * *c_PS_LT + ( 1 - STEREO_TD_PS_CORR_FILT ) * c_PS;
     790             : 
     791       11340 :     return;
     792             : }
     793             : 
     794             : 
     795             : /*-------------------------------------------------------------------*
     796             :  * Function stereo_cng_compute_LRcorr()
     797             :  *
     798             :  * CNA for TD stereo, compute LR correlation
     799             :  *-------------------------------------------------------------------*/
     800             : 
     801       11340 : static void stereo_cng_compute_LRcorr(
     802             :     CPE_DEC_HANDLE hCPE,         /* i/o: CPE handle                           */
     803             :     float *output[CPE_CHANNELS], /* i  : Output signal                        */
     804             :     const int16_t output_frame,  /* i  : Output frame length                  */
     805             :     const int16_t tdm_ratio_idx  /* i  : TDM ratio index                      */
     806             : )
     807             : {
     808             :     int16_t i;
     809             :     float c_LR, c, tmp, sc;
     810             :     float enrL, enrR, dotLR;
     811             :     float beta;
     812             : 
     813       11340 :     beta = tdm_ratio_tabl[tdm_ratio_idx];
     814             : 
     815       11340 :     enrL = 0.0f;
     816       11340 :     enrR = 0.0f;
     817       11340 :     dotLR = 0.0f;
     818     7294860 :     for ( i = 0; i < output_frame; i++ )
     819             :     {
     820     7283520 :         enrL += output[0][i] * output[0][i];
     821     7283520 :         enrR += output[1][i] * output[1][i];
     822     7283520 :         dotLR += output[0][i] * output[1][i];
     823             :     }
     824             : 
     825       11340 :     c_LR = fabsf( dotLR + EPSILON ) * inv_sqrt( enrL * enrR + EPSILON );
     826       11340 :     c = ( enrL + DELTA ) / ( enrR + DELTA );
     827       11340 :     hCPE->hStereoTD->c_LR_LT = STEREO_TD_PS_CORR_FILT * hCPE->hStereoTD->c_LR_LT + ( 1 - STEREO_TD_PS_CORR_FILT ) * c_LR;
     828       11340 :     hCPE->hStereoCng->c_LR_LT = hCPE->hStereoTD->c_LR_LT;
     829             : 
     830       11340 :     tmp = 2 * beta * ( 1 - beta ) * sqrtf( c ) * hCPE->hStereoTD->c_LR_LT;
     831       11340 :     sc = ( ( 1 - beta ) * ( 1 - beta ) * c + beta * beta - tmp + DELTA ) / ( beta * beta * c + ( 1 - beta ) * ( 1 - beta ) + tmp + DELTA );
     832       11340 :     sc = min( sc, 4.0f );
     833       11340 :     hCPE->hStereoTD->SP_ratio_LT = 0.9f * hCPE->hStereoTD->SP_ratio_LT + ( 1 - 0.9f ) * sqrtf( sc );
     834             : 
     835       11340 :     if ( hCPE->hStereoCng->nr_corr_frames < CM_INIT )
     836             :     {
     837        5331 :         hCPE->hStereoCng->nr_corr_frames++;
     838             :     }
     839             : 
     840       11340 :     hCPE->hStereoCng->nr_dft_frames = 0;
     841             : 
     842       11340 :     return;
     843             : }
     844             : 
     845             : 
     846             : /*-------------------------------------------------------------------*
     847             :  * FindEmEs()
     848             :  *
     849             :  * Find the energie ratio between the mono and the side
     850             :  *-------------------------------------------------------------------*/
     851             : 
     852      123033 : static void FindEmEs(
     853             :     const float *ch1,  /* i  : Left channel          */
     854             :     const float *ch2,  /* i  : right channel         */
     855             :     const int16_t len, /* i  : length                */
     856             :     float *lt_es_em    /* i/o: LT energy ratio       */
     857             : )
     858             : {
     859             :     int16_t i;
     860             :     float mono_i, ener, es_em;
     861             :     float side_i, ener_side;
     862             : 
     863      123033 :     ener = 1e-6f;
     864      123033 :     ener_side = 1e-6f;
     865             : 
     866    79642713 :     for ( i = 0; i < len; i++ )
     867             :     {
     868    79519680 :         mono_i = ( ch1[i] + ch2[i] ) / 2.0f;
     869    79519680 :         ener += mono_i * mono_i;
     870    79519680 :         side_i = ( ch1[i] - ch2[i] ) / 2.0f;
     871    79519680 :         ener_side += side_i * side_i;
     872             :     }
     873             : 
     874             :     /**es_em = 10 * ( log10( sqrt( ener_side / len ) ) - log10( sqrt( ener / len ) ) ); */
     875      123033 :     es_em = 5 * ( logf( sqrtf( ener_side / ener ) ) / logf( 10 ) );
     876             : 
     877             :     /* long-term estimate */
     878      123033 :     *lt_es_em = 0.4f * *lt_es_em + 0.6f * es_em;
     879             : 
     880      123033 :     return;
     881             : }
     882             : 
     883             : 
     884             : /*-------------------------------------------------------------------*
     885             :  * Function stereo_cna_update_params()
     886             :  *
     887             :  * compute LR correlation and update long-term parameters for stereo CNA
     888             :  *-------------------------------------------------------------------*/
     889             : 
     890      450150 : void stereo_cna_update_params(
     891             :     CPE_DEC_HANDLE hCPE,         /* i/o: CPE decoder structure       */
     892             :     float *output[CPE_CHANNELS], /* i  : Output signal               */
     893             :     const int16_t output_frame,  /* i  : Output frame length         */
     894             :     const int16_t tdm_ratio_idx  /* i  : TDM ratio index             */
     895             : )
     896             : {
     897             :     int16_t i;
     898             :     float c, c_LR, c_ILD, enrL, enrR, dotLR;
     899             :     Decoder_State **sts;
     900             :     HANDLE_FD_CNG_DEC hFdCngDec;
     901             : 
     902      450150 :     sts = hCPE->hCoreCoder;
     903             : 
     904      450150 :     hFdCngDec = sts[0]->hFdCngDec;
     905             : 
     906      450150 :     if ( hCPE->element_mode == IVAS_CPE_DFT )
     907             :     {
     908      179058 :         if ( hCPE->nchan_out > 1 )
     909             :         {
     910      111693 :             FindEmEs( output[0], output[1], output_frame, &hCPE->lt_es_em );
     911             :         }
     912             :         else
     913             :         {
     914       67365 :             hCPE->lt_es_em = 0.0f;
     915             :         }
     916             :     }
     917      271092 :     else if ( hCPE->element_mode == IVAS_CPE_TD )
     918             :     {
     919       11340 :         FindEmEs( output[0], output[1], output_frame, &hCPE->lt_es_em );
     920             : 
     921       11340 :         hCPE->hStereoCng->first_SID_after_TD = 1;
     922       11340 :         stereo_cng_compute_LRcorr( hCPE, output, output_frame, tdm_ratio_idx );
     923             :     }
     924             :     else
     925             :     {
     926      259752 :         hFdCngDec->first_cna_noise_updated = 0;
     927             : 
     928      259752 :         return;
     929             :     }
     930             : 
     931      190398 :     enrL = 0.0f;
     932      190398 :     enrR = 0.0f;
     933      190398 :     dotLR = 0.0f;
     934      190398 :     if ( hCPE->element_mode == IVAS_CPE_TD || ( hCPE->element_mode == IVAS_CPE_DFT && sts[0]->core_brate > SID_2k40 && sts[0]->VAD == 0 ) )
     935             :     {
     936       20685 :         if ( hCPE->nchan_out == 1 )
     937             :         {
     938        8553 :             c_LR = 1;
     939        8553 :             c_ILD = 0;
     940             :         }
     941             :         else
     942             :         {
     943     8331492 :             for ( i = 0; i < output_frame; i++ )
     944             :             {
     945     8319360 :                 enrL += output[0][i] * output[0][i];
     946     8319360 :                 enrR += output[1][i] * output[1][i];
     947     8319360 :                 dotLR += output[0][i] * output[1][i];
     948             :             }
     949             : 
     950             :             /* estimate L/R correlation factor and ILD in time domain */
     951       12132 :             c_LR = fabsf( dotLR + EPSILON ) * inv_sqrt( enrL * enrR + EPSILON );
     952       12132 :             c = ( enrL + DELTA ) / ( enrR + DELTA );
     953       12132 :             c_ILD = ( c - 1 ) / ( c + 1 );
     954             :         }
     955             : 
     956             :         /* update of long-term ILD and LR correlation factors for stereo CNA */
     957       20685 :         if ( !hFdCngDec->first_cna_noise_updated )
     958             :         {
     959        8301 :             hFdCngDec->cna_LR_LT = c_LR;
     960        8301 :             hFdCngDec->cna_ILD_LT = c_ILD;
     961             :         }
     962             :         else
     963             :         {
     964       12384 :             hFdCngDec->cna_LR_LT = STEREO_CNA_LR_CORR_LT_FILT * hFdCngDec->cna_LR_LT + ( 1 - STEREO_CNA_LR_CORR_LT_FILT ) * c_LR;
     965       12384 :             hFdCngDec->cna_ILD_LT = STEREO_CNA_ILD_LT_FILT * hFdCngDec->cna_ILD_LT + ( 1 - STEREO_CNA_ILD_LT_FILT ) * c_ILD;
     966             :         }
     967             : 
     968       20685 :         set_f( hFdCngDec->cna_g_state, hFdCngDec->cna_ILD_LT, hFdCngDec->cna_nbands );
     969       20685 :         set_f( hFdCngDec->cna_cm, hFdCngDec->cna_LR_LT, hFdCngDec->cna_nbands );
     970             :     }
     971             : 
     972             :     /* Soft VAD for stereo CNA */
     973      190398 :     if ( hCPE->element_mode == IVAS_CPE_TD || hCPE->element_mode == IVAS_CPE_DFT )
     974             :     {
     975      190398 :         if ( !hFdCngDec->first_cna_noise_updated )
     976             :         {
     977       98190 :             hFdCngDec->cna_act_fact = 0.0f;
     978             :         }
     979             :         else
     980             :         {
     981       92208 :             if ( hCPE->element_mode == IVAS_CPE_TD )
     982             :             {
     983             :                 /* quickly decrease in TD stereo mode */
     984        4860 :                 hFdCngDec->cna_act_fact *= 0.7f;
     985             :             }
     986       87348 :             else if ( sts[0]->VAD > hFdCngDec->cna_act_fact )
     987             :             {
     988             :                 /* quickly increase during active frames in DFT stereo mode */
     989       49086 :                 hFdCngDec->cna_act_fact = 0.7f * hFdCngDec->cna_act_fact + 0.3f * sts[0]->VAD;
     990             :             }
     991             :             else
     992             :             {
     993             :                 /* slowly decrease during inactive frames in DFT stereo mode */
     994       38262 :                 hFdCngDec->cna_act_fact = 0.95f * hFdCngDec->cna_act_fact + 0.05f * sts[0]->VAD;
     995             :             }
     996             :         }
     997             :     }
     998             : 
     999      190398 :     return;
    1000             : }
    1001             : 
    1002             : 
    1003             : /*-------------------------------------------------------------------
    1004             :  * stereo_cng_init_dec()
    1005             :  *
    1006             :  * Initialized stereo CNG
    1007             :  *-------------------------------------------------------------------*/
    1008             : 
    1009        2469 : void stereo_cng_init_dec(
    1010             :     STEREO_CNG_DEC_HANDLE hStereoCng, /* i/o: stereo CNG decoder structure                               */
    1011             :     const int16_t *frameSize          /* i  : pointer to frameSize of channel 0 to be used for channel 1 */
    1012             : )
    1013             : {
    1014        2469 :     hStereoCng->prev_sid_nodata = 0;
    1015        2469 :     set_f( hStereoCng->coh, 0.5f, STEREO_DFT_BAND_MAX + 1 );
    1016        2469 :     set_zero( hStereoCng->cm, STEREO_DFT_BAND_MAX );
    1017        2469 :     hStereoCng->first_SID = 1;
    1018        2469 :     hStereoCng->first_SID_after_TD = 0;
    1019        2469 :     hStereoCng->active_frame_counter = 0;
    1020        2469 :     hStereoCng->xfade_frame_counter = 0;
    1021        2469 :     hStereoCng->xfade_length = 0;
    1022        2469 :     hStereoCng->nr_dft_frames = 0;
    1023        2469 :     hStereoCng->nr_corr_frames = 0;
    1024        2469 :     hStereoCng->nr_sid_frames = 0;
    1025        2469 :     set_f( hStereoCng->olapBufferSynth22, 0.0f, FFTLEN );
    1026        2469 :     hStereoCng->flag_cna_fade = 0;
    1027        2469 :     set_zero( hStereoCng->maskingNoiseS, L_FRAME16k );
    1028        2469 :     hStereoCng->enableSecCNA = 0;
    1029        2469 :     hStereoCng->c_PS_LT = 0.5f;
    1030        2469 :     hStereoCng->frameSize = frameSize;
    1031        2469 :     hStereoCng->last_act_element_mode = IVAS_CPE_DFT;
    1032             : 
    1033        2469 :     return;
    1034             : }

Generated by: LCOV version 1.14