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 @ d25741250ae73a0fdda3bc43a164fc404c15b66c Lines: 399 442 90.3 %
Date: 2026-02-27 05:21:15 Functions: 5 5 100.0 %

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

Generated by: LCOV version 1.14