LCOV - code coverage report
Current view: top level - lib_enc - cng_enc.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 399 442 90.3 %
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             : /*====================================================================================
      34             :     EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0
      35             :   ====================================================================================*/
      36             : 
      37             : #include <stdint.h>
      38             : #include "options.h"
      39             : #ifdef DEBUGGING
      40             : #include "debug.h"
      41             : #endif
      42             : #include <math.h>
      43             : #include "cnst.h"
      44             : #include "rom_enc.h"
      45             : #include "rom_com.h"
      46             : #include "prot.h"
      47             : #include "wmc_auto.h"
      48             : 
      49             : /*---------------------------------------------------------------------*
      50             :  * Local constants
      51             :  *---------------------------------------------------------------------*/
      52             : 
      53             : #define MAX_DELTA_CNG      1
      54             : #define ENER_MID_DEAD_ZONE 0.01 /* dead-zone width around mid points between quantization levels */
      55             : 
      56             : /*---------------------------------------------------------------------*
      57             :  * Local function prototypes
      58             :  *---------------------------------------------------------------------*/
      59             : 
      60             : static int16_t shb_DTX( Encoder_State *st, const float *shb_speech, const float *syn_12k8_16k );
      61             : 
      62             : static void shb_CNG_encod( Encoder_State *st, const int16_t update );
      63             : 
      64             : 
      65             : /*---------------------------------------------------------------------*
      66             :  * CNG_enc()
      67             :  *
      68             :  * Confort noise generation for the coder
      69             :  *---------------------------------------------------------------------*/
      70             : 
      71        2395 : void CNG_enc(
      72             :     Encoder_State *st,      /* i/o: State structure                                 */
      73             :     float Aq[],             /* o  : LP coefficients                                 */
      74             :     const float *speech,    /* i  : pointer to current frame input speech buffer    */
      75             :     float enr,              /* i  : residual energy from Levinson-Durbin            */
      76             :     const float *lsp_mid,   /* i  : mid frame LSPs                                  */
      77             :     float *lsp_new,         /* i/o: current frame ISPs                              */
      78             :     float *lsf_new,         /* i/o: current frame ISFs                              */
      79             :     int16_t *allow_cn_step, /* o  : allow CN step                                   */
      80             :     float *q_env,
      81             :     int16_t *sid_bw )
      82             : {
      83             :     int16_t enr_index, i;
      84             :     float step, res[L_FRAME16k];
      85             :     int16_t maxl, num_bits;
      86             :     int16_t j, k, ptr;
      87             :     int16_t m1;
      88             :     float weights;
      89             :     float sp_enr;
      90        2395 :     int16_t m = 0;
      91             :     float tmp[HO_HIST_SIZE * M];
      92             :     int16_t ll, s_ptr;
      93        2395 :     float att = 1.0f;
      94             :     float lsf_tmp[M];
      95             :     float C[M];
      96             :     float max_val[2];
      97             :     int16_t max_idx[2];
      98             :     float ftmp;
      99             :     float lsp_tmp[M];
     100             :     float dev;
     101             :     float max_dev;
     102             :     float dist;
     103        2395 :     int16_t max_idx1[2] = { 0, 0 };
     104             :     float fft_io[L_FRAME16k];
     105             :     float *ptR, *ptI;
     106        2395 :     float enr1 = 0;
     107             :     float env[NUM_ENV_CNG];
     108             :     float min1;
     109             :     int16_t min1_idx;
     110             :     float d;
     111             :     float res1[L_FRAME16k];
     112             :     float tmp_env[HO_HIST_SIZE * NUM_ENV_CNG];
     113        2395 :     int16_t force_cn_step = 0;
     114             : 
     115             :     float st_lp_sp_enr;
     116             : 
     117             :     float lp_ener_thr_scale;
     118             : 
     119        2395 :     BSTR_ENC_HANDLE hBstr = st->hBstr;
     120        2395 :     TD_CNG_ENC_HANDLE hTdCngEnc = st->hTdCngEnc;
     121        2395 :     DTX_ENC_HANDLE hDtxEnc = st->hDtxEnc;
     122             : 
     123        2395 :     st_lp_sp_enr = hTdCngEnc->lp_sp_enr;
     124             : 
     125        2395 :     lp_ener_thr_scale = 4.0f;
     126        2395 :     if ( st->element_mode != EVS_MONO )
     127             :     {
     128        2395 :         lp_ener_thr_scale = 3.5f;
     129             :     }
     130             : 
     131             :     /* calculate input energy */
     132        2395 :     sp_enr = (float) log10( sum2_f( speech, st->L_frame ) / st->L_frame + 0.1f ) / (float) log10( 2.0f );
     133             : 
     134        2395 :     if ( sp_enr < 0.0f )
     135             :     {
     136         156 :         sp_enr = 0.0f;
     137             :     }
     138             : 
     139        2395 :     if ( hDtxEnc->first_CNG == 0 || hTdCngEnc->old_enr_index < 0 )
     140             :     {
     141          28 :         hTdCngEnc->lp_sp_enr = sp_enr;
     142             :     }
     143             :     else
     144             :     {
     145        2367 :         if ( st->last_core_brate > SID_2k40 && ( st->last_core == HQ_CORE || st->hTdCngEnc->burst_ho_cnt > 0 ) && hTdCngEnc->lp_sp_enr < 6.0f && ( sp_enr - hTdCngEnc->lp_sp_enr ) > 4.0f && sp_enr > 6.0f )
     146             :         {
     147           0 :             hTdCngEnc->lp_sp_enr = sp_enr;
     148           0 :             force_cn_step = 1;
     149             :         }
     150             :         else
     151             :         {
     152        2367 :             hTdCngEnc->lp_sp_enr = 0.1f * sp_enr + 0.9f * hTdCngEnc->lp_sp_enr;
     153             :         }
     154             :     }
     155             : 
     156             :     /* update the pointer to circular buffer of old LSP vectors */
     157        2395 :     if ( ++( hTdCngEnc->cng_hist_ptr ) == DTX_HIST_SIZE )
     158             :     {
     159           0 :         hTdCngEnc->cng_hist_ptr = 0;
     160             :     }
     161             : 
     162             :     /* update the circular buffer of old LSP vectors with the new LSP vector */
     163        2395 :     mvr2r( lsp_new, &( hTdCngEnc->cng_lsp_hist[( hTdCngEnc->cng_hist_ptr ) * M] ), M );
     164             : 
     165             :     /*-----------------------------------------------------------------*
     166             :      * Find CNG spectral envelope
     167             :      * Find LSP median
     168             :      *-----------------------------------------------------------------*/
     169             : 
     170        2395 :     if ( ( st->core_brate == SID_2k40 || st->core_brate == SID_1k75 ) && hDtxEnc->cng_cnt >= ( hDtxEnc->cng_hist_size - 1 ) )
     171             :     {
     172         232 :         set_f( max_val, 0.0f, 2 );
     173         232 :         set_s( max_idx, 0, 2 );
     174             : 
     175        2088 :         for ( i = 0; i < hDtxEnc->cng_hist_size; i++ )
     176             :         {
     177        1856 :             if ( st->L_frame == L_FRAME )
     178             :             {
     179         672 :                 lsp2lsf( &hTdCngEnc->cng_lsp_hist[i * M], lsf_tmp, M, INT_FS_12k8 );
     180         672 :                 ftmp = 6400.0f / ( M + 1 );
     181         672 :                 C[i] = ( 6400.0f - lsf_tmp[M - 1] - ftmp ) * ( 6400.0f - lsf_tmp[M - 1] - ftmp );
     182             :             }
     183             :             else
     184             :             {
     185        1184 :                 lsp2lsf( &hTdCngEnc->cng_lsp_hist[i * M], lsf_tmp, M, INT_FS_16k );
     186        1184 :                 ftmp = 8000.0f / ( M + 1 );
     187        1184 :                 C[i] = ( 8000.0f - lsf_tmp[M - 1] - ftmp ) * ( 8000.0f - lsf_tmp[M - 1] - ftmp );
     188             :             }
     189             : 
     190        1856 :             C[i] += ( lsf_tmp[0] - ftmp ) * ( lsf_tmp[0] - ftmp );
     191             : 
     192       29696 :             for ( j = 0; j < M - 1; j++ )
     193             :             {
     194       27840 :                 C[i] += ( lsf_tmp[j + 1] - lsf_tmp[j] - ftmp ) * ( lsf_tmp[j + 1] - lsf_tmp[j] - ftmp );
     195             :             }
     196             : 
     197        1856 :             C[i] *= 0.0588235f; /* 1/M+1 */
     198             : 
     199        1856 :             if ( C[i] > max_val[0] )
     200             :             {
     201         615 :                 max_val[1] = max_val[0];
     202         615 :                 max_idx[1] = max_idx[0];
     203         615 :                 max_val[0] = C[i];
     204         615 :                 max_idx[0] = i;
     205             :             }
     206        1241 :             else if ( C[i] > max_val[1] )
     207             :             {
     208         387 :                 max_val[1] = C[i];
     209         387 :                 max_idx[1] = i;
     210             :             }
     211             :         }
     212             : 
     213        3944 :         for ( i = 0; i < M; i++ )
     214             :         {
     215        3712 :             lsp_new[i] = 0.0f;
     216       33408 :             for ( j = 0; j < hDtxEnc->cng_hist_size; j++ )
     217             :             {
     218       29696 :                 lsp_new[i] += hTdCngEnc->cng_lsp_hist[j * M + i];
     219             :             }
     220             : 
     221        3712 :             lsp_new[i] -= ( hTdCngEnc->cng_lsp_hist[max_idx[0] * M + i] + hTdCngEnc->cng_lsp_hist[max_idx[1] * M + i] );
     222        3712 :             lsp_new[i] /= (float) ( hDtxEnc->cng_hist_size - 2 );
     223             :         }
     224         232 :         max_idx1[0] = max_idx[0];
     225         232 :         max_idx1[1] = max_idx[1];
     226             :     }
     227             : 
     228             :     /*-----------------------------------------------------------------*
     229             :      * Quantize CNG spectral envelope (only in SID frame)
     230             :      * Quantize the LSF vector
     231             :      *-----------------------------------------------------------------*/
     232             : 
     233             : 
     234        5333 :     *allow_cn_step = ( ( hDtxEnc->cng_cnt == 0 ) &&
     235         543 :                        ( hTdCngEnc->lp_sp_enr > 6.0f ) &&
     236         543 :                        ( ( st_lp_sp_enr + 4.0f ) < sp_enr ) &&
     237          28 :                        ( hDtxEnc->first_CNG != 0 ) &&
     238           0 :                        ( hTdCngEnc->old_enr_index >= 0 ) &&
     239        2938 :                        ( st->last_core_brate > SID_2k40 ) ) ||
     240             :                      force_cn_step;
     241             : 
     242             :     /* Initialize the CNG spectral envelope in case of the very first CNG frame */
     243        2395 :     if ( hDtxEnc->first_CNG == 0 )
     244             :     {
     245          28 :         mvr2r( st->lsp_old, hDtxEnc->lspCNG, M );
     246             : 
     247             :         /* Average the CNG spectral envelope in case of the very first CNG frame */
     248          28 :         if ( st->element_mode != EVS_MONO )
     249             :         {
     250         476 :             for ( i = 0; i < M; i++ )
     251             :             {
     252         448 :                 lsp_new[i] = 0.5f * ( lsp_mid[i] + lsp_new[i] );
     253             :             }
     254             :         }
     255             :     }
     256             : 
     257        2395 :     if ( st->core_brate == SID_2k40 || st->core_brate == SID_1k75 )
     258             :     {
     259             :         /* LSF quantization */
     260         433 :         if ( st->Opt_AMR_WB )
     261             :         {
     262           0 :             isf_enc_amr_wb( st, lsf_new, lsp_new, 0 );
     263             :         }
     264             :         else
     265             :         {
     266         433 :             lsf_enc( st, lsf_new, lsp_new, 0, 0, 0, 0, NULL );
     267             :         }
     268             : 
     269             :         /* Reset CNG history if CNG frame length is changed */
     270         433 :         if ( st->bwidth == WB && hDtxEnc->first_CNG && st->L_frame != hDtxEnc->last_CNG_L_frame )
     271             :         {
     272           4 :             hTdCngEnc->ho_hist_size = 0;
     273             :         }
     274             :     }
     275             :     else
     276             :     {
     277             :         /* Use old LSP vector */
     278        1962 :         mvr2r( st->lsp_old, lsp_new, M );
     279        1962 :         mvr2r( st->lsf_old, lsf_new, M );
     280             :     }
     281             : 
     282             : 
     283             :     /*---------------------------------------------------------------------*
     284             :      * CNG spectral envelope update
     285             :      * Find A(z) coefficients
     286             :      *---------------------------------------------------------------------*/
     287             : 
     288        2395 :     if ( st->last_core_brate == FRAME_NO_DATA || st->last_core_brate == SID_1k75 || st->last_core_brate == SID_2k40 )
     289             :     {
     290             :         /* Reset hangover counter if not first SID period */
     291        2194 :         if ( st->core_brate > FRAME_NO_DATA )
     292             :         {
     293         232 :             hTdCngEnc->num_ho = 0;
     294             :         }
     295             :         /* Update LSPs if last SID energy not outlier or insufficient number of hangover frames */
     296        2194 :         if ( hTdCngEnc->num_ho < 3 || hTdCngEnc->Enew < 1.5f * hTdCngEnc->lp_ener )
     297             :         {
     298       36856 :             for ( i = 0; i < M; i++ )
     299             :             {
     300             :                 /* AR low-pass filter  */
     301       34688 :                 hDtxEnc->lspCNG[i] = CNG_ISF_FACT * hDtxEnc->lspCNG[i] + ( 1 - CNG_ISF_FACT ) * lsp_new[i];
     302             :             }
     303             :         }
     304             :     }
     305             :     else
     306             :     {
     307             :         /* Update CNG_mode if allowed */
     308         201 :         if ( st->element_mode == EVS_MONO && ( st->Opt_AMR_WB || st->bwidth == WB ) && ( !hDtxEnc->first_CNG || hTdCngEnc->act_cnt2 >= MIN_ACT_CNG_UPD ) )
     309             :         {
     310           0 :             if ( hDtxEnc->last_active_brate > ACELP_16k40 )
     311             :             {
     312           0 :                 hDtxEnc->CNG_mode = -1;
     313             :             }
     314             :             else
     315             :             {
     316           0 :                 hDtxEnc->CNG_mode = get_cng_mode( hDtxEnc->last_active_brate );
     317             :             }
     318             :         }
     319             : 
     320             :         /* If first SID after active burst update LSF history from circ buffer */
     321         201 :         hTdCngEnc->burst_ho_cnt = min( hTdCngEnc->burst_ho_cnt, hTdCngEnc->ho_circ_size );
     322         201 :         hTdCngEnc->act_cnt = 0;
     323         201 :         s_ptr = hTdCngEnc->ho_circ_ptr - hTdCngEnc->burst_ho_cnt + 1;
     324         201 :         if ( s_ptr < 0 )
     325             :         {
     326          32 :             s_ptr += hTdCngEnc->ho_circ_size;
     327             :         }
     328             : 
     329         492 :         for ( ll = hTdCngEnc->burst_ho_cnt; ll > 0; ll-- )
     330             :         {
     331         291 :             if ( ++( hTdCngEnc->ho_hist_ptr ) == HO_HIST_SIZE )
     332             :             {
     333          25 :                 hTdCngEnc->ho_hist_ptr = 0;
     334             :             }
     335             :             /* Conversion between 12.8k and 16k LSPs */
     336         291 :             if ( st->L_frame == L_FRAME && hTdCngEnc->ho_16k_lsp[s_ptr] == 1 )
     337             :             {
     338             :                 /* Conversion from 16k LPSs to 12k8 */
     339           0 :                 lsp_convert_poly( &( hTdCngEnc->ho_lsp_circ[s_ptr * M] ), st->L_frame, 0 );
     340             :             }
     341         291 :             else if ( st->L_frame == L_FRAME16k && hTdCngEnc->ho_16k_lsp[s_ptr] == 0 )
     342             :             {
     343             :                 /* 16k LSPs already converted and stored, just copy to the other buffer */
     344          61 :                 mvr2r( &( hTdCngEnc->ho_lsp_circ2[s_ptr * M] ), &( hTdCngEnc->ho_lsp_circ[s_ptr * M] ), M );
     345             :             }
     346             : 
     347             :             /* update circular buffers */
     348         291 :             mvr2r( &( hTdCngEnc->ho_lsp_circ[s_ptr * M] ), &( hTdCngEnc->ho_lsp_hist[hTdCngEnc->ho_hist_ptr * M] ), M );
     349         291 :             mvr2r( &( hTdCngEnc->ho_ener_circ[s_ptr] ), &( hTdCngEnc->ho_ener_hist[hTdCngEnc->ho_hist_ptr] ), 1 );
     350         291 :             hTdCngEnc->ho_sid_bw = ( hTdCngEnc->ho_sid_bw & 0x3fffffffL ) << 1;
     351         291 :             mvr2r( &( hTdCngEnc->ho_env_circ[s_ptr * NUM_ENV_CNG] ), &( hTdCngEnc->ho_env_hist[hTdCngEnc->ho_hist_ptr * NUM_ENV_CNG] ), NUM_ENV_CNG );
     352             : 
     353         291 :             hTdCngEnc->ho_hist_size++;
     354         291 :             if ( hTdCngEnc->ho_hist_size > HO_HIST_SIZE )
     355             :             {
     356          32 :                 hTdCngEnc->ho_hist_size = HO_HIST_SIZE;
     357             :             }
     358             : 
     359         291 :             s_ptr++;
     360             : 
     361         291 :             if ( s_ptr == hTdCngEnc->ho_circ_size )
     362             :             {
     363          35 :                 s_ptr = 0;
     364             :             }
     365             :         }
     366         201 :         if ( st->hTdCngEnc->burst_ho_cnt > 0 )
     367             :         {
     368          67 :             *allow_cn_step |= ( hDtxEnc->first_CNG || st->element_mode == EVS_MONO ) && ( hTdCngEnc->ho_ener_hist[hTdCngEnc->ho_hist_ptr] > lp_ener_thr_scale * hTdCngEnc->lp_ener );
     369             :         }
     370             : 
     371         201 :         if ( !*allow_cn_step && hTdCngEnc->ho_hist_size > 0 )
     372             :         {
     373         179 :             ptr = hTdCngEnc->ho_hist_ptr;
     374         179 :             mvr2r( &( hTdCngEnc->ho_lsp_hist[ptr * M] ), tmp, M );
     375         179 :             m1 = 0;
     376         179 :             if ( ( hTdCngEnc->ho_sid_bw & 0x1L ) == 0 )
     377             :             {
     378          67 :                 mvr2r( &hTdCngEnc->ho_env_hist[ptr * NUM_ENV_CNG], tmp_env, NUM_ENV_CNG );
     379          67 :                 m1 = 1;
     380             :             }
     381         179 :             enr = W_DTX_HO[0] * hTdCngEnc->ho_ener_hist[ptr];
     382         179 :             weights = W_DTX_HO[0];
     383         179 :             m = 1;
     384         845 :             for ( k = 1; k < hTdCngEnc->ho_hist_size; k++ )
     385             :             {
     386         666 :                 ptr--;
     387         666 :                 if ( ptr < 0 )
     388             :                 {
     389          33 :                     ptr = HO_HIST_SIZE - 1;
     390             :                 }
     391             : 
     392         666 :                 if ( hTdCngEnc->ho_ener_hist[ptr] < hTdCngEnc->ho_ener_hist[hTdCngEnc->ho_hist_ptr] * BUF_H_NRG &&
     393         364 :                      hTdCngEnc->ho_ener_hist[ptr] > hTdCngEnc->ho_ener_hist[hTdCngEnc->ho_hist_ptr] * BUF_L_NRG )
     394             :                 {
     395         315 :                     enr += W_DTX_HO[k] * hTdCngEnc->ho_ener_hist[ptr];
     396         315 :                     weights += W_DTX_HO[k];
     397         315 :                     mvr2r( &hTdCngEnc->ho_lsp_hist[ptr * M], &tmp[m * M], M );
     398         315 :                     if ( ( hTdCngEnc->ho_sid_bw & ( 0x1L << k ) ) == 0 )
     399             :                     {
     400         100 :                         mvr2r( &hTdCngEnc->ho_env_hist[ptr * NUM_ENV_CNG], &tmp_env[m1 * NUM_ENV_CNG], NUM_ENV_CNG );
     401         100 :                         m1++;
     402             :                     }
     403         315 :                     m++;
     404             :                 }
     405             :             }
     406             : 
     407         179 :             enr /= weights;
     408         179 :             hTdCngEnc->lp_ener = enr;
     409             : 
     410         179 :             set_f( max_val, 0.0f, 2 );
     411         179 :             set_s( max_idx, 0, 2 );
     412             : 
     413         673 :             for ( i = 0; i < m; i++ )
     414             :             {
     415         494 :                 if ( st->L_frame == L_FRAME )
     416             :                 {
     417         202 :                     lsp2lsf( &tmp[i * M], lsf_tmp, M, INT_FS_12k8 );
     418         202 :                     ftmp = 6400.0f / ( M + 1 );
     419         202 :                     C[i] = ( 6400.0f - lsf_tmp[M - 1] - ftmp ) * ( 6400.0f - lsf_tmp[M - 1] - ftmp );
     420             :                 }
     421             :                 else
     422             :                 {
     423         292 :                     lsp2lsf( &tmp[i * M], lsf_tmp, M, INT_FS_16k );
     424         292 :                     ftmp = 8000.0f / ( M + 1 );
     425         292 :                     C[i] = ( 8000.0f - lsf_tmp[M - 1] - ftmp ) * ( 8000.0f - lsf_tmp[M - 1] - ftmp );
     426             :                 }
     427             : 
     428         494 :                 C[i] += ( lsf_tmp[0] - ftmp ) * ( lsf_tmp[0] - ftmp );
     429             : 
     430        7904 :                 for ( j = 0; j < M - 1; j++ )
     431             :                 {
     432        7410 :                     C[i] += ( lsf_tmp[j + 1] - lsf_tmp[j] - ftmp ) * ( lsf_tmp[j + 1] - lsf_tmp[j] - ftmp );
     433             :                 }
     434             : 
     435         494 :                 C[i] *= 0.0588235f; /* 1/M+1 */
     436             : 
     437         494 :                 if ( C[i] > max_val[0] )
     438             :                 {
     439         323 :                     max_val[1] = max_val[0];
     440         323 :                     max_idx[1] = max_idx[0];
     441         323 :                     max_val[0] = C[i];
     442         323 :                     max_idx[0] = i;
     443             :                 }
     444         171 :                 else if ( C[i] > max_val[1] )
     445             :                 {
     446          87 :                     max_val[1] = C[i];
     447          87 :                     max_idx[1] = i;
     448             :                 }
     449             :             }
     450             : 
     451         179 :             if ( m == 1 )
     452             :             {
     453          54 :                 mvr2r( tmp, lsp_tmp, M );
     454             :             }
     455         125 :             else if ( m < 4 )
     456             :             {
     457        1377 :                 for ( i = 0; i < M; i++ )
     458             :                 {
     459        1296 :                     lsp_tmp[i] = 0.0f;
     460        4576 :                     for ( j = 0; j < m; j++ )
     461             :                     {
     462        3280 :                         lsp_tmp[i] += tmp[j * M + i];
     463             :                     }
     464             : 
     465        1296 :                     lsp_tmp[i] -= tmp[max_idx[0] * M + i];
     466        1296 :                     lsp_tmp[i] /= (float) ( m - 1 );
     467             :                 }
     468             :             }
     469             :             else
     470             :             {
     471         748 :                 for ( i = 0; i < M; i++ )
     472             :                 {
     473         704 :                     lsp_tmp[i] = 0.0f;
     474        4464 :                     for ( j = 0; j < m; j++ )
     475             :                     {
     476        3760 :                         lsp_tmp[i] += tmp[j * M + i];
     477             :                     }
     478             : 
     479         704 :                     lsp_tmp[i] -= ( tmp[max_idx[0] * M + i] + tmp[max_idx[1] * M + i] );
     480         704 :                     lsp_tmp[i] /= (float) ( m - 2 );
     481             :                 }
     482             :             }
     483             : 
     484         179 :             dist = 0.0f;
     485         179 :             max_dev = 0.0f;
     486        3043 :             for ( i = 0; i < M; i++ )
     487             :             {
     488        2864 :                 dev = (float) fabs( lsp_tmp[i] - lsp_new[i] );
     489        2864 :                 dist += dev;
     490        2864 :                 if ( dev > max_dev )
     491             :                 {
     492         881 :                     max_dev = dev;
     493             :                 }
     494             :             }
     495             : 
     496         179 :             if ( dist > 0.4f || max_dev > 0.1f )
     497             :             {
     498         153 :                 for ( i = 0; i < M; i++ )
     499             :                 {
     500         144 :                     hDtxEnc->lspCNG[i] = lsp_tmp[i];
     501             :                 }
     502             :             }
     503             :             else
     504             :             {
     505        2890 :                 for ( i = 0; i < M; i++ )
     506             :                 {
     507             :                     /* AR low-pass filter  */
     508        2720 :                     hDtxEnc->lspCNG[i] = 0.8f * lsp_tmp[i] + ( 1 - 0.8f ) * lsp_new[i];
     509             :                 }
     510             :             }
     511         179 :             if ( m1 > 0 )
     512             :             {
     513        2121 :                 for ( i = 0; i < NUM_ENV_CNG; i++ )
     514             :                 {
     515        2020 :                     env[i] = 0;
     516        5360 :                     for ( j = 0; j < m1; j++ )
     517             :                     {
     518        3340 :                         env[i] += tmp_env[j * NUM_ENV_CNG + i];
     519             :                     }
     520             : 
     521        2020 :                     env[i] /= (float) m1;
     522        2020 :                     env[i] = env[i] - 2 * hTdCngEnc->lp_ener;
     523             :                 }
     524         101 :                 mvr2r( env, hTdCngEnc->lp_env, NUM_ENV_CNG );
     525             :             }
     526             :         }
     527             :         else
     528             :         {
     529          22 :             mvr2r( lsp_new, hDtxEnc->lspCNG, M ); /* use newly analyzed parameters */
     530             :         }
     531             :     }
     532             : 
     533        2395 :     if ( st->Opt_AMR_WB )
     534             :     {
     535           0 :         isp2a( hDtxEnc->lspCNG, Aq, M );
     536             :     }
     537             :     else
     538             :     {
     539        2395 :         lsp2a_stab( hDtxEnc->lspCNG, Aq, M );
     540             :     }
     541             : 
     542       11124 :     for ( i = 1; i < st->L_frame / L_SUBFR; i++ )
     543             :     {
     544        8729 :         mvr2r( Aq, &Aq[i * ( M + 1 )], M + 1 );
     545             :     }
     546             : 
     547             :     /*-----------------------------------------------------------------*
     548             :      * Find residual signal
     549             :      * Calculate residual signal energy per sample
     550             :      *-----------------------------------------------------------------*/
     551             : 
     552             :     /* calculate the residual signal */
     553        2395 :     residu( Aq, M, speech, res, st->L_frame );
     554             : 
     555        2395 :     mvr2r( res, res1, st->L_frame );
     556             : 
     557        2395 :     if ( st->element_mode == IVAS_CPE_DFT || st->element_mode == IVAS_CPE_TD )
     558             :     {
     559        2395 :         att = powf( 10.0f, hTdCngEnc->CNG_att / 20.0f );
     560        2395 :         v_multc( res1, att, res1, st->L_frame );
     561             :     }
     562           0 :     else if ( st->bwidth != NB )
     563             :     {
     564           0 :         if ( st->bwidth == WB && hDtxEnc->CNG_mode >= 0 )
     565             :         {
     566           0 :             ftmp = HO_ATT[hDtxEnc->CNG_mode];
     567             :         }
     568             :         else
     569             :         {
     570           0 :             ftmp = 0.6f;
     571             :         }
     572             : 
     573           0 :         att = ftmp / 6.0f;
     574           0 :         att = 1.0f / ( 1 + att * 8 );
     575             : 
     576           0 :         if ( att < ftmp )
     577             :         {
     578           0 :             att = ftmp;
     579             :         }
     580             : 
     581           0 :         v_multc( res1, att, res1, st->L_frame );
     582             :     }
     583             : 
     584             :     /* calculate the spectrum of residual signal */
     585        2395 :     mvr2r( res1, fft_io, st->L_frame );
     586             : 
     587        2395 :     if ( st->L_frame == L_FRAME16k )
     588             :     {
     589        1544 :         modify_Fs( fft_io, L_FRAME16k, 16000, fft_io, 12800, hTdCngEnc->exc_mem2, 0 );
     590             :     }
     591             : 
     592        2395 :     fft_rel( fft_io, L_FFT, LOG2_L_FFT );
     593        2395 :     ptR = &fft_io[1];
     594        2395 :     ptI = &fft_io[L_FFT - 1];
     595       50295 :     for ( i = 0; i < NUM_ENV_CNG; i++ )
     596             :     {
     597       47900 :         env[i] = 2.0f * ( *ptR * *ptR + *ptI * *ptI ) / L_FFT;
     598       47900 :         ptR++;
     599       47900 :         ptI--;
     600             :     }
     601             : 
     602        2395 :     mvr2r( env, &( hTdCngEnc->cng_res_env[( hTdCngEnc->cng_hist_ptr ) * NUM_ENV_CNG] ), NUM_ENV_CNG );
     603             :     /* calculate the residual signal energy */
     604        2395 :     enr = dotp( res, res, st->L_frame ) / st->L_frame;
     605             : 
     606             :     /* convert log2 of residual signal energy */
     607        2395 :     enr = (float) log10( enr + 0.1f ) / (float) log10( 2.0f );
     608             : 
     609             :     /* update the circular buffer of old energies */
     610        2395 :     hTdCngEnc->cng_ener_hist[hTdCngEnc->cng_hist_ptr] = enr;
     611             : 
     612             :     /*-----------------------------------------------------------------*
     613             :      * Quantize residual signal energy (only in SID frame)
     614             :      *-----------------------------------------------------------------*/
     615             : 
     616        2395 :     if ( st->core_brate == SID_2k40 || st->core_brate == SID_1k75 )
     617             :     {
     618         433 :         if ( hDtxEnc->cng_cnt >= hDtxEnc->cng_hist_size - 1 )
     619             :         {
     620             :             /* average the envelope except outliers */
     621        4872 :             for ( i = 0; i < NUM_ENV_CNG; i++ )
     622             :             {
     623       41760 :                 for ( j = 0; j < hDtxEnc->cng_hist_size; j++ )
     624             :                 {
     625       37120 :                     env[i] += hTdCngEnc->cng_res_env[j * NUM_ENV_CNG + i];
     626             :                 }
     627             : 
     628        4640 :                 env[i] -= ( hTdCngEnc->cng_res_env[max_idx1[0] * NUM_ENV_CNG + i] + hTdCngEnc->cng_res_env[max_idx1[1] * NUM_ENV_CNG + i] );
     629        4640 :                 env[i] /= (float) ( hDtxEnc->cng_hist_size - 2 );
     630             :             }
     631             :             /* compute average excitation energy */
     632         232 :             enr = 0;
     633         232 :             weights = 0;
     634         232 :             ptr = hTdCngEnc->cng_hist_ptr;
     635             : 
     636        2088 :             for ( k = 0; k < hDtxEnc->cng_hist_size; k++ )
     637             :             {
     638        1856 :                 enr += W_HIST[k] * hTdCngEnc->cng_ener_hist[ptr--];
     639        1856 :                 if ( ptr < 0 )
     640             :                 {
     641         232 :                     ptr = DTX_HIST_SIZE - 1;
     642             :                 }
     643             : 
     644        1856 :                 weights += W_HIST[k];
     645             :             }
     646             : 
     647             :             /* normalize the average value */
     648         232 :             enr /= weights;
     649             :         }
     650             : 
     651         433 :         if ( st->element_mode == IVAS_SCE || st->element_mode == IVAS_CPE_DFT )
     652             :         {
     653         433 :             enr += hTdCngEnc->CNG_att * FAC_LOG2 / 10.0f;
     654             :         }
     655           0 :         else if ( st->bwidth != NB )
     656             :         {
     657           0 :             if ( st->bwidth == WB )
     658             :             {
     659           0 :                 if ( hDtxEnc->CNG_mode >= 0 )
     660             :                 {
     661             :                     /* Bitrate adapted attenuation */
     662           0 :                     att = ENR_ATT[hDtxEnc->CNG_mode];
     663             :                 }
     664             :                 else
     665             :                 {
     666             :                     /* Use least attenuation for higher bitrates */
     667           0 :                     att = ENR_ATT[4];
     668             :                 }
     669             :             }
     670             :             else
     671             :             {
     672           0 :                 att = 1.5f;
     673             :             }
     674           0 :             enr -= att;
     675             :         }
     676             : 
     677             :         /* intialize the energy quantization parameters */
     678         433 :         if ( !st->Opt_AMR_WB )
     679             :         {
     680         433 :             step = STEP_SID;
     681         433 :             maxl = 127;
     682         433 :             num_bits = 7;
     683             :         }
     684             :         else
     685             :         {
     686           0 :             step = STEP_AMR_WB_SID;
     687           0 :             maxl = 63;
     688           0 :             num_bits = 6;
     689             :         }
     690             : 
     691             :         /* calculate the energy quantization index */
     692         433 :         enr_index = (int16_t) ( ( enr + 2.0f ) * step );
     693             : 
     694             :         /* limit the energy quantization index */
     695         433 :         if ( enr_index > maxl )
     696             :         {
     697           0 :             enr_index = maxl;
     698             :         }
     699             : 
     700         433 :         if ( enr_index < 0 )
     701             :         {
     702          11 :             enr_index = 0;
     703             :         }
     704             : 
     705             :         /* allow only slow energy increase */
     706         433 :         if ( hDtxEnc->first_CNG && enr_index > hTdCngEnc->old_enr_index + MAX_DELTA_CNG )
     707             :         {
     708          65 :             if ( *allow_cn_step == 1 )
     709             :             {
     710           0 :                 enr_index = hTdCngEnc->old_enr_index + (int16_t) ( 0.85f * ( enr_index - hTdCngEnc->old_enr_index ) );
     711             :             }
     712             :             else
     713             :             {
     714          65 :                 enr_index = hTdCngEnc->old_enr_index + MAX_DELTA_CNG;
     715             :             }
     716             :         }
     717         433 :         hTdCngEnc->old_enr_index = enr_index;
     718             : 
     719         433 :         push_indice( hBstr, IND_ENERGY, enr_index, num_bits );
     720         433 :         if ( enr_index == 0 )
     721             :         {
     722          18 :             enr_index = -5;
     723             :         }
     724             :         /* find the quatized energy */
     725         433 :         hTdCngEnc->Enew = (float) enr_index / step - 2.0f;
     726         433 :         hTdCngEnc->Enew = (float) ( pow( 2.0f, hTdCngEnc->Enew ) );
     727         433 :         if ( st->core_brate == SID_2k40 )
     728             :         {
     729         433 :             enr1 = (float) log10( hTdCngEnc->Enew * st->L_frame + 0.1f ) / (float) log10( 2.0f );
     730        9093 :             for ( i = 0; i < NUM_ENV_CNG; i++ )
     731             :             {
     732        8660 :                 env[i] -= 2 * hTdCngEnc->Enew;
     733             : 
     734        8660 :                 if ( env[i] < 0.0f )
     735             :                 {
     736        4997 :                     env[i] = 0.1f;
     737             :                 }
     738             : 
     739        8660 :                 env[i] = (float) log10( env[i] + 0.1f ) / (float) log10( 2.0f );
     740        8660 :                 env[i] -= att;
     741             : 
     742        8660 :                 if ( env[i] < 0 )
     743             :                 {
     744        5022 :                     env[i] = 0;
     745             :                 }
     746             : 
     747        8660 :                 env[i] = enr1 - env[i];
     748             :             }
     749             : 
     750             :             /* codebook search */
     751         433 :             min1 = 9999.0f;
     752         433 :             min1_idx = 0;
     753             : 
     754       28145 :             for ( i = 0; i < 64; i++ )
     755             :             {
     756       27712 :                 d = 0.0f;
     757      581952 :                 for ( j = 0; j < NUM_ENV_CNG; j++ )
     758             :                 {
     759      554240 :                     d += ( env[j] - CNG_details_codebook[i][j] ) * ( env[j] - CNG_details_codebook[i][j] );
     760             :                 }
     761             : 
     762       27712 :                 if ( d < min1 )
     763             :                 {
     764        3267 :                     min1 = d;
     765        3267 :                     min1_idx = i;
     766             :                 }
     767             :             }
     768         433 :             push_indice( hBstr, IND_CNG_ENV1, min1_idx, 6 );
     769             :             /* get quantized res_env_details */
     770        9093 :             for ( i = 0; i < NUM_ENV_CNG; i++ )
     771             :             {
     772        8660 :                 q_env[i] = CNG_details_codebook[min1_idx][i];
     773             :             }
     774             :         }
     775             :         /* Update hangover memory during CNG */
     776         433 :         if ( !*allow_cn_step && ( hTdCngEnc->Enew < 1.5f * hTdCngEnc->lp_ener ) )
     777             :         {
     778             :             /* update the pointer to circular buffer of old LSP vectors */
     779         342 :             if ( ++( hTdCngEnc->ho_hist_ptr ) == HO_HIST_SIZE )
     780             :             {
     781          39 :                 hTdCngEnc->ho_hist_ptr = 0;
     782             :             }
     783             : 
     784             :             /* update the circular buffer of old LSP vectors with the new LSP vector */
     785         342 :             mvr2r( lsp_new, &( hTdCngEnc->ho_lsp_hist[( hTdCngEnc->ho_hist_ptr ) * M] ), M );
     786             : 
     787             :             /* update the hangover energy buffer */
     788         342 :             hTdCngEnc->ho_ener_hist[hTdCngEnc->ho_hist_ptr] = hTdCngEnc->Enew;
     789         342 :             if ( st->core_brate == SID_2k40 )
     790             :             {
     791        7182 :                 for ( i = 0; i < NUM_ENV_CNG; i++ )
     792             :                 {
     793             :                     /* get quantized envelope */
     794        6840 :                     env[i] = (float) ( pow( 2.0f, ( enr1 - q_env[i] ) ) + 2 * hTdCngEnc->Enew );
     795             :                 }
     796         342 :                 mvr2r( env, &( hTdCngEnc->ho_env_hist[( hTdCngEnc->ho_hist_ptr ) * NUM_ENV_CNG] ), NUM_ENV_CNG );
     797             :             }
     798         342 :             if ( ++( hTdCngEnc->ho_hist_size ) > HO_HIST_SIZE )
     799             :             {
     800         219 :                 hTdCngEnc->ho_hist_size = HO_HIST_SIZE;
     801             :             }
     802             :         }
     803             :     }
     804             : 
     805             :     /* dithering bit for AMR-WB IO mode is always set to 0 */
     806        2395 :     if ( st->core_brate == SID_1k75 )
     807             :     {
     808           0 :         push_indice( hBstr, IND_DITHERING, 0, 1 );
     809             :     }
     810             : 
     811        2395 :     if ( st->core_brate == SID_2k40 )
     812             :     {
     813         433 :         push_indice( hBstr, IND_ACELP_16KHZ, st->L_frame == L_FRAME16k ? 1 : 0, 1 );
     814             : 
     815             :         /*  transmit ho_cnt for use at decoder side as  CNG synthesis assistance   */
     816         433 :         if ( hTdCngEnc->burst_ho_cnt > ( HO_HIST_SIZE - 1 ) )
     817             :         {
     818           2 :             push_indice( hBstr, IND_CNG_HO, ( HO_HIST_SIZE - 1 ), 3 ); /* send max allowed value, limited to 7 */
     819             :         }
     820             :         else
     821             :         {
     822         431 :             push_indice( hBstr, IND_CNG_HO, hTdCngEnc->burst_ho_cnt, 3 ); /* send actual value */
     823             :         }
     824         433 :         hTdCngEnc->num_ho = m;
     825         433 :         push_indice( hBstr, IND_SID_TYPE, 0, 1 );
     826             : 
     827         433 :         if ( st->input_Fs < 32000 && st->element_mode != IVAS_CPE_DFT )
     828             :         {
     829           0 :             push_indice( hBstr, IND_SID_BW, 0, 1 );
     830           0 :             *sid_bw = 0;
     831             :         }
     832             :     }
     833             : 
     834             :     /*-----------------------------------------------------------------*
     835             :      * Updates
     836             :      *-----------------------------------------------------------------*/
     837             : 
     838             :     /* update the SID frames counter */
     839        2395 :     if ( st->core_brate == SID_2k40 || st->core_brate == SID_1k75 )
     840             :     {
     841         433 :         hDtxEnc->cng_cnt = 0;
     842             :         /* update frame length memory */
     843         433 :         hDtxEnc->last_CNG_L_frame = st->L_frame;
     844         433 :         hTdCngEnc->cng_hist_ptr = -1;
     845             :     }
     846             :     else
     847             :     {
     848        1962 :         hDtxEnc->cng_cnt++;
     849             :     }
     850             : 
     851        2395 :     return;
     852             : }
     853             : 
     854             : 
     855             : /*---------------------------------------------------------------------*
     856             :  * swb_CNG_enc()
     857             :  *
     858             :  * SWB DTX/CNG encoding
     859             :  *---------------------------------------------------------------------*/
     860             : 
     861       44242 : void swb_CNG_enc(
     862             :     Encoder_State *st,        /* i/o: State structure                                 */
     863             :     const float *shb_speech,  /* i  : SHB target signal (6-14kHz) at 16kHz            */
     864             :     const float *syn_12k8_16k /* i  : ACELP core synthesis at 12.8kHz or 16kHz        */
     865             : )
     866             : {
     867             :     int16_t shb_SID_updt;
     868             : 
     869       44242 :     if ( st->core_brate == SID_2k40 || st->core_brate == FRAME_NO_DATA )
     870             :     {
     871       13274 :         if ( st->cng_type == LP_CNG )
     872             :         {
     873        2395 :             if ( st->input_Fs >= L_FRAME32k * FRAMES_PER_SEC )
     874             :             {
     875             :                 /* decide if SHB SID encoding or not */
     876        2041 :                 shb_SID_updt = shb_DTX( st, shb_speech, syn_12k8_16k );
     877             : 
     878             :                 /* SHB CNG encoding */
     879        2041 :                 shb_CNG_encod( st, shb_SID_updt );
     880             :             }
     881         354 :             else if ( st->element_mode == IVAS_CPE_DFT && st->core_brate == SID_2k40 )
     882             :             {
     883             :                 /* LF-boost not used in DFT-stereo, instead the bandwidth is transmitted */
     884          48 :                 delete_indice( st->hBstr, IND_CNG_ENV1 );
     885          48 :                 push_indice( st->hBstr, IND_BWIDTH, st->bwidth, 2 );
     886          48 :                 push_indice( st->hBstr, IND_UNUSED, 0, 4 );
     887          48 :                 push_indice( st->hBstr, IND_SID_BW, 1, 1 );
     888             :             }
     889             :         }
     890       13274 :         st->hTdCngEnc->last_vad = 0;
     891             :     }
     892             :     else
     893             :     {
     894       30968 :         st->hTdCngEnc->last_vad = 1;
     895             :     }
     896             : 
     897       44242 :     return;
     898             : }
     899             : 
     900             : /*---------------------------------------------------------------------*
     901             :  * shb_CNG_encod()
     902             :  *
     903             :  * SID parameters encoding for SHB signal
     904             :  *---------------------------------------------------------------------*/
     905             : 
     906        2041 : static void shb_CNG_encod(
     907             :     Encoder_State *st,   /* i/o: State structure             */
     908             :     const int16_t update /* i  : SID update flag             */
     909             : )
     910             : {
     911        2041 :     int16_t idx_ener = 0;
     912        2041 :     BSTR_ENC_HANDLE hBstr = st->hBstr;
     913             :     float ener_mid_dec_thr;
     914             : 
     915        2041 :     if ( update == 1 )
     916             :     {
     917             :         /* SHB energy quantization */
     918         385 :         if ( st->element_mode == EVS_MONO )
     919             :         {
     920           0 :             idx_ener = (int16_t) ( 0.9f * ( 0.1f * st->hTdCngEnc->mov_shb_cng_ener / (float) log10( 2.0f ) + 6.0f ) + 0.5f );
     921             :         }
     922             :         else
     923             :         {
     924         385 :             idx_ener = (int16_t) ( 0.7f * ( 0.1f * st->hTdCngEnc->mov_shb_cng_ener / (float) log10( 2.0f ) + 6.0f ) + 0.5f );
     925             :         }
     926             : 
     927         385 :         if ( st->bwidth < SWB )
     928             :         {
     929           2 :             idx_ener = 0;
     930             :         }
     931             : 
     932         385 :         if ( idx_ener > 15 )
     933             :         {
     934           0 :             idx_ener = 15;
     935             :         }
     936         385 :         else if ( idx_ener < 0 )
     937             :         {
     938           5 :             idx_ener = 0;
     939             :         }
     940             : 
     941             :         /* prevent toggling of idx_ener by adding small dead-zone interval around decision thresholds */
     942         385 :         if ( st->element_mode != EVS_MONO )
     943             :         {
     944         385 :             if ( abs( idx_ener - st->hTdCngEnc->last_idx_ener ) == 1 )
     945             :             {
     946          29 :                 ener_mid_dec_thr = 0.5f * ( ( st->hTdCngEnc->last_idx_ener / 0.7f - 6.0f ) / 0.1f ) * (float) log10( 2.0f );
     947          29 :                 ener_mid_dec_thr += 0.5f * ( ( idx_ener / 0.7f - 6.0f ) / 0.1f ) * (float) log10( 2.0f );
     948             : 
     949          29 :                 if ( fabs( st->hTdCngEnc->mov_shb_cng_ener - ener_mid_dec_thr ) / ener_mid_dec_thr < ENER_MID_DEAD_ZONE )
     950             :                 {
     951           6 :                     idx_ener = st->hTdCngEnc->last_idx_ener;
     952             :                 }
     953             :             }
     954             :         }
     955             : 
     956         385 :         st->hTdCngEnc->last_idx_ener = idx_ener;
     957             : 
     958         385 :         push_indice( hBstr, IND_SHB_CNG_GAIN, idx_ener, 4 );
     959         385 :         push_indice( hBstr, IND_SID_BW, 1, 1 );
     960         385 :         delete_indice( hBstr, IND_CNG_ENV1 );
     961         385 :         if ( st->element_mode == IVAS_CPE_DFT )
     962             :         {
     963         385 :             push_indice( st->hBstr, IND_BWIDTH, st->bwidth, 2 );
     964             :         }
     965             :         else
     966             :         {
     967           0 :             push_indice( hBstr, IND_UNUSED, 0, 2 );
     968             :         }
     969         385 :         st->hTdCngEnc->ho_sid_bw = ( st->hTdCngEnc->ho_sid_bw & 0x3fffffffL ) << 1;
     970         385 :         st->hTdCngEnc->ho_sid_bw |= 0x1L;
     971             :     }
     972        1656 :     else if ( st->core_brate == SID_2k40 )
     973             :     {
     974           0 :         st->hTdCngEnc->ho_sid_bw = ( st->hTdCngEnc->ho_sid_bw & 0x3fffffffL ) << 1;
     975           0 :         push_indice( hBstr, IND_SID_BW, 0, 1 );
     976             :     }
     977             : 
     978        2041 :     return;
     979             : }
     980             : 
     981             : 
     982             : /*---------------------------------------------------------------------*
     983             :  * shb_DTX()
     984             :  *
     985             :  * Decide if encoding SHB SID or not
     986             :  *---------------------------------------------------------------------*/
     987             : 
     988        2041 : static int16_t shb_DTX(
     989             :     Encoder_State *st,        /* i/o: State structure                                 */
     990             :     const float *shb_speech,  /* i  : SHB target signal (6-14kHz) at 16kHz            */
     991             :     const float *syn_12k8_16k /* i  : ACELP core synthesis at 12.8kHz or 16kHz        */
     992             : )
     993             : {
     994             :     int16_t i;
     995             :     int16_t update;
     996             :     float shb_old_speech[( L_LOOK_12k8 + L_SUBFR + L_FRAME ) * 5 / 4];
     997             :     float *shb_new_speech;
     998             :     float wb_ener;
     999             :     float shb_ener;
    1000             :     float log_wb_ener;
    1001             :     float log_shb_ener;
    1002             :     float ftmp;
    1003        2041 :     int16_t allow_cn_step = 0;
    1004             :     float att;
    1005             : 
    1006        2041 :     TD_CNG_ENC_HANDLE hTdCngEnc = st->hTdCngEnc;
    1007             : 
    1008        2041 :     shb_new_speech = shb_old_speech + ( L_LOOK_12k8 + L_SUBFR ) * 5 / 4;
    1009        2041 :     mvr2r( st->hBWE_TD->old_speech_shb, shb_old_speech, ( L_LOOK_12k8 + L_SUBFR ) * 5 / 4 );
    1010        2041 :     mvr2r( shb_speech, shb_new_speech, L_FRAME16k );
    1011        2041 :     mvr2r( shb_old_speech + L_FRAME16k, st->hBWE_TD->old_speech_shb, ( L_LOOK_12k8 + L_SUBFR ) * 5 / 4 );
    1012             : 
    1013        2041 :     shb_ener = FLT_MIN * L_FRAME16k;
    1014      655161 :     for ( i = 0; i < L_FRAME16k; i++ )
    1015             :     {
    1016      653120 :         shb_ener += shb_old_speech[i] * shb_old_speech[i];
    1017             :     }
    1018        2041 :     shb_ener /= L_FRAME16k;
    1019             : 
    1020        2041 :     wb_ener = sum2_f( syn_12k8_16k, st->L_frame ) + 0.001f;
    1021        2041 :     wb_ener = wb_ener / st->L_frame;
    1022             : 
    1023        2041 :     log_wb_ener = 10 * (float) log10( wb_ener );
    1024        2041 :     if ( st->element_mode == IVAS_SCE || st->element_mode == IVAS_CPE_DFT )
    1025             :     {
    1026        2041 :         att = 0.0f;
    1027             : 
    1028        2041 :         apply_scale( &att, st->hFdCngEnc->hFdCngCom->CngBandwidth, st->hFdCngEnc->hFdCngCom->CngBitrate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO );
    1029             :     }
    1030             :     else
    1031             :     {
    1032           0 :         att = -6.5f;
    1033             :     }
    1034        2041 :     log_shb_ener = 10 * (float) log10( shb_ener ) + att;
    1035             : 
    1036        2041 :     if ( st->hDtxEnc->first_CNG == 0 )
    1037             :     {
    1038          22 :         hTdCngEnc->mov_wb_cng_ener = log_wb_ener;
    1039          22 :         hTdCngEnc->mov_shb_cng_ener = log_shb_ener;
    1040          22 :         hTdCngEnc->last_wb_cng_ener = log_wb_ener;
    1041          22 :         hTdCngEnc->last_shb_cng_ener = log_shb_ener;
    1042             :     }
    1043        2041 :     if ( fabs( log_wb_ener - hTdCngEnc->mov_wb_cng_ener ) > 12.0f )
    1044             :     {
    1045          20 :         allow_cn_step = 1;
    1046             :     }
    1047             : 
    1048             :     /* Also allow step if shb energy has dropped 12 dB */
    1049        2041 :     if ( ( st->element_mode == IVAS_CPE_DFT || st->element_mode == IVAS_CPE_TD ) && ( ( hTdCngEnc->mov_shb_cng_ener - log_shb_ener ) > 12.0f ) )
    1050             :     {
    1051          24 :         allow_cn_step = 1;
    1052             :     }
    1053             : 
    1054        2041 :     if ( allow_cn_step == 1 )
    1055             :     {
    1056          25 :         hTdCngEnc->mov_wb_cng_ener = log_wb_ener;
    1057          25 :         hTdCngEnc->mov_shb_cng_ener = log_shb_ener;
    1058             :     }
    1059             :     else
    1060             :     {
    1061        2016 :         ftmp = log_wb_ener - hTdCngEnc->mov_wb_cng_ener;
    1062             : 
    1063        2016 :         hTdCngEnc->mov_wb_cng_ener += 0.9f * ftmp;
    1064             : 
    1065        2016 :         ftmp = log_shb_ener - hTdCngEnc->mov_shb_cng_ener;
    1066             : 
    1067        2016 :         hTdCngEnc->mov_shb_cng_ener += 0.25f * ftmp;
    1068             :     }
    1069        2041 :     hTdCngEnc->shb_NO_DATA_cnt++;
    1070             : 
    1071        2041 :     update = 0;
    1072        2041 :     if ( st->core_brate == SID_2k40 )
    1073             :     {
    1074         385 :         if ( st->hDtxEnc->first_CNG == 0 )
    1075             :         {
    1076          22 :             update = 1;
    1077             :         }
    1078         363 :         else if ( hTdCngEnc->shb_cng_ini_cnt > 0 )
    1079             :         {
    1080          22 :             hTdCngEnc->shb_cng_ini_cnt--;
    1081          22 :             update = 1;
    1082             :         }
    1083         341 :         else if ( hTdCngEnc->last_vad == 1 )
    1084             :         {
    1085         149 :             update = 1;
    1086             :         }
    1087         192 :         else if ( hTdCngEnc->shb_NO_DATA_cnt >= 100 )
    1088             :         {
    1089           0 :             update = 1;
    1090             :         }
    1091         192 :         else if ( fabs( ( hTdCngEnc->mov_wb_cng_ener - hTdCngEnc->mov_shb_cng_ener ) - ( hTdCngEnc->last_wb_cng_ener - hTdCngEnc->last_shb_cng_ener ) ) > 3.0f )
    1092             :         {
    1093          75 :             update = 1;
    1094             :         }
    1095         117 :         else if ( ( st->bwidth >= SWB && hTdCngEnc->last_SID_bwidth < SWB ) || ( st->bwidth < SWB && hTdCngEnc->last_SID_bwidth >= SWB ) )
    1096             :         {
    1097           0 :             update = 1;
    1098             :         }
    1099             : 
    1100         385 :         hTdCngEnc->last_SID_bwidth = st->bwidth;
    1101             :     }
    1102             : 
    1103             :     /* LF-boost not yet implemented in decoder which means that the specific wb_sid information is not used */
    1104        2041 :     if ( ( st->element_mode == IVAS_CPE_DFT || st->element_mode == IVAS_CPE_TD ) && st->core_brate == SID_2k40 )
    1105             :     {
    1106         385 :         update = 1;
    1107             :     }
    1108             : 
    1109        2041 :     if ( update == 1 )
    1110             :     {
    1111         385 :         hTdCngEnc->last_wb_cng_ener = hTdCngEnc->mov_wb_cng_ener;
    1112         385 :         hTdCngEnc->last_shb_cng_ener = hTdCngEnc->mov_shb_cng_ener;
    1113         385 :         hTdCngEnc->shb_NO_DATA_cnt = 0;
    1114             :     }
    1115             : 
    1116        2041 :     return ( update );
    1117             : }
    1118             : 
    1119             : 
    1120             : /*---------------------------------------------------------------------*
    1121             :  * calculate_hangover_attenuation_gain()
    1122             :  *
    1123             :  *
    1124             :  *---------------------------------------------------------------------*/
    1125             : 
    1126      186122 : void calculate_hangover_attenuation_gain(
    1127             :     Encoder_State *st,           /* i  : encoder state structure         */
    1128             :     float *att,                  /* o  : attenuation factor              */
    1129             :     const int16_t vad_hover_flag /* i  : VAD hangover flag                       */
    1130             : )
    1131             : {
    1132             :     float lim;
    1133             : 
    1134      186122 :     *att = 1.0f;
    1135      186122 :     if ( st->hTdCngEnc != NULL && vad_hover_flag && st->hTdCngEnc->burst_ho_cnt > 0 && ( st->bwidth != NB || st->element_mode > EVS_MONO ) )
    1136             :     {
    1137        2678 :         if ( st->element_mode == IVAS_CPE_DFT || st->element_mode == IVAS_CPE_TD )
    1138             :         {
    1139        2280 :             *att = powf( 10.0f, ( st->hTdCngEnc->CNG_att / 160.0f ) * st->hTdCngEnc->burst_ho_cnt );
    1140             :         }
    1141             :         else
    1142             :         {
    1143         398 :             if ( st->bwidth == WB && st->hDtxEnc->CNG_mode >= 0 )
    1144             :             {
    1145           0 :                 lim = HO_ATT[st->hDtxEnc->CNG_mode];
    1146             :             }
    1147             :             else
    1148             :             {
    1149         398 :                 lim = 0.6f;
    1150             :             }
    1151             : 
    1152         398 :             *att = lim / 6.0f;
    1153         398 :             *att = 1.0f / ( 1 + *att * st->hTdCngEnc->burst_ho_cnt );
    1154             : 
    1155         398 :             if ( *att < lim )
    1156             :             {
    1157          16 :                 *att = lim;
    1158             :             }
    1159             :         }
    1160             :     }
    1161             : 
    1162      186122 :     return;
    1163             : }

Generated by: LCOV version 1.14