LCOV - code coverage report
Current view: top level - lib_enc - cng_enc.c (source / functions) Hit Total Coverage
Test: Coverage on main @ 6baab0c613aa6c7100498ed7b93676aa8198a493 Lines: 437 442 98.9 %
Date: 2025-05-28 04:28:20 Functions: 5 5 100.0 %

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : /*====================================================================================
      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       10992 : 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       10992 :     int16_t m = 0;
      91             :     float tmp[HO_HIST_SIZE * M];
      92             :     int16_t ll, s_ptr;
      93       10992 :     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       10992 :     int16_t max_idx1[2] = { 0, 0 };
     104             :     float fft_io[L_FRAME16k];
     105             :     float *ptR, *ptI;
     106       10992 :     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       10992 :     int16_t force_cn_step = 0;
     114             : 
     115             :     float st_lp_sp_enr;
     116             : 
     117             :     float lp_ener_thr_scale;
     118             : 
     119       10992 :     BSTR_ENC_HANDLE hBstr = st->hBstr;
     120       10992 :     TD_CNG_ENC_HANDLE hTdCngEnc = st->hTdCngEnc;
     121       10992 :     DTX_ENC_HANDLE hDtxEnc = st->hDtxEnc;
     122             : 
     123       10992 :     st_lp_sp_enr = hTdCngEnc->lp_sp_enr;
     124             : 
     125       10992 :     lp_ener_thr_scale = 4.0f;
     126       10992 :     if ( st->element_mode != EVS_MONO )
     127             :     {
     128        9170 :         lp_ener_thr_scale = 3.5f;
     129             :     }
     130             : 
     131             :     /* calculate input energy */
     132       10992 :     sp_enr = (float) log10( sum2_f( speech, st->L_frame ) / st->L_frame + 0.1f ) / (float) log10( 2.0f );
     133             : 
     134       10992 :     if ( sp_enr < 0.0f )
     135             :     {
     136        2909 :         sp_enr = 0.0f;
     137             :     }
     138             : 
     139       10992 :     if ( hDtxEnc->first_CNG == 0 || hTdCngEnc->old_enr_index < 0 )
     140             :     {
     141          88 :         hTdCngEnc->lp_sp_enr = sp_enr;
     142             :     }
     143             :     else
     144             :     {
     145       10904 :         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          27 :             hTdCngEnc->lp_sp_enr = sp_enr;
     148          27 :             force_cn_step = 1;
     149             :         }
     150             :         else
     151             :         {
     152       10877 :             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       10992 :     if ( ++( hTdCngEnc->cng_hist_ptr ) == DTX_HIST_SIZE )
     158             :     {
     159          58 :         hTdCngEnc->cng_hist_ptr = 0;
     160             :     }
     161             : 
     162             :     /* update the circular buffer of old LSP vectors with the new LSP vector */
     163       10992 :     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       10992 :     if ( ( st->core_brate == SID_2k40 || st->core_brate == SID_1k75 ) && hDtxEnc->cng_cnt >= ( hDtxEnc->cng_hist_size - 1 ) )
     171             :     {
     172        1028 :         set_f( max_val, 0.0f, 2 );
     173        1028 :         set_s( max_idx, 0, 2 );
     174             : 
     175        9227 :         for ( i = 0; i < hDtxEnc->cng_hist_size; i++ )
     176             :         {
     177        8199 :             if ( st->L_frame == L_FRAME )
     178             :             {
     179        3975 :                 lsp2lsf( &hTdCngEnc->cng_lsp_hist[i * M], lsf_tmp, M, INT_FS_12k8 );
     180        3975 :                 ftmp = 6400.0f / ( M + 1 );
     181        3975 :                 C[i] = ( 6400.0f - lsf_tmp[M - 1] - ftmp ) * ( 6400.0f - lsf_tmp[M - 1] - ftmp );
     182             :             }
     183             :             else
     184             :             {
     185        4224 :                 lsp2lsf( &hTdCngEnc->cng_lsp_hist[i * M], lsf_tmp, M, INT_FS_16k );
     186        4224 :                 ftmp = 8000.0f / ( M + 1 );
     187        4224 :                 C[i] = ( 8000.0f - lsf_tmp[M - 1] - ftmp ) * ( 8000.0f - lsf_tmp[M - 1] - ftmp );
     188             :             }
     189             : 
     190        8199 :             C[i] += ( lsf_tmp[0] - ftmp ) * ( lsf_tmp[0] - ftmp );
     191             : 
     192      131184 :             for ( j = 0; j < M - 1; j++ )
     193             :             {
     194      122985 :                 C[i] += ( lsf_tmp[j + 1] - lsf_tmp[j] - ftmp ) * ( lsf_tmp[j + 1] - lsf_tmp[j] - ftmp );
     195             :             }
     196             : 
     197        8199 :             C[i] *= 0.0588235f; /* 1/M+1 */
     198             : 
     199        8199 :             if ( C[i] > max_val[0] )
     200             :             {
     201        2780 :                 max_val[1] = max_val[0];
     202        2780 :                 max_idx[1] = max_idx[0];
     203        2780 :                 max_val[0] = C[i];
     204        2780 :                 max_idx[0] = i;
     205             :             }
     206        5419 :             else if ( C[i] > max_val[1] )
     207             :             {
     208        1738 :                 max_val[1] = C[i];
     209        1738 :                 max_idx[1] = i;
     210             :             }
     211             :         }
     212             : 
     213       17476 :         for ( i = 0; i < M; i++ )
     214             :         {
     215       16448 :             lsp_new[i] = 0.0f;
     216      147632 :             for ( j = 0; j < hDtxEnc->cng_hist_size; j++ )
     217             :             {
     218      131184 :                 lsp_new[i] += hTdCngEnc->cng_lsp_hist[j * M + i];
     219             :             }
     220             : 
     221       16448 :             lsp_new[i] -= ( hTdCngEnc->cng_lsp_hist[max_idx[0] * M + i] + hTdCngEnc->cng_lsp_hist[max_idx[1] * M + i] );
     222       16448 :             lsp_new[i] /= (float) ( hDtxEnc->cng_hist_size - 2 );
     223             :         }
     224        1028 :         max_idx1[0] = max_idx[0];
     225        1028 :         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       24374 :     *allow_cn_step = ( ( hDtxEnc->cng_cnt == 0 ) &&
     235        2390 :                        ( hTdCngEnc->lp_sp_enr > 6.0f ) &&
     236        1838 :                        ( ( st_lp_sp_enr + 4.0f ) < sp_enr ) &&
     237          99 :                        ( hDtxEnc->first_CNG != 0 ) &&
     238          32 :                        ( hTdCngEnc->old_enr_index >= 0 ) &&
     239       13382 :                        ( 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       10992 :     if ( hDtxEnc->first_CNG == 0 )
     244             :     {
     245          88 :         mvr2r( st->lsp_old, hDtxEnc->lspCNG, M );
     246             : 
     247             :         /* Average the CNG spectral envelope in case of the very first CNG frame */
     248          88 :         if ( st->element_mode != EVS_MONO )
     249             :         {
     250        1360 :             for ( i = 0; i < M; i++ )
     251             :             {
     252        1280 :                 lsp_new[i] = 0.5f * ( lsp_mid[i] + lsp_new[i] );
     253             :             }
     254             :         }
     255             :     }
     256             : 
     257       10992 :     if ( st->core_brate == SID_2k40 || st->core_brate == SID_1k75 )
     258             :     {
     259             :         /* LSF quantization */
     260        1870 :         if ( st->Opt_AMR_WB )
     261             :         {
     262         107 :             isf_enc_amr_wb( st, lsf_new, lsp_new, 0 );
     263             :         }
     264             :         else
     265             :         {
     266        1763 :             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        1870 :         if ( st->bwidth == WB && hDtxEnc->first_CNG && st->L_frame != hDtxEnc->last_CNG_L_frame )
     271             :         {
     272          14 :             hTdCngEnc->ho_hist_size = 0;
     273             :         }
     274             :     }
     275             :     else
     276             :     {
     277             :         /* Use old LSP vector */
     278        9122 :         mvr2r( st->lsp_old, lsp_new, M );
     279        9122 :         mvr2r( st->lsf_old, lsf_new, M );
     280             :     }
     281             : 
     282             : 
     283             :     /*---------------------------------------------------------------------*
     284             :      * CNG spectral envelope update
     285             :      * Find A(z) coefficients
     286             :      *---------------------------------------------------------------------*/
     287             : 
     288       10992 :     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       10155 :         if ( st->core_brate > FRAME_NO_DATA )
     292             :         {
     293        1033 :             hTdCngEnc->num_ho = 0;
     294             :         }
     295             :         /* Update LSPs if last SID energy not outlier or insufficient number of hangover frames */
     296       10155 :         if ( hTdCngEnc->num_ho < 3 || hTdCngEnc->Enew < 1.5f * hTdCngEnc->lp_ener )
     297             :         {
     298      167960 :             for ( i = 0; i < M; i++ )
     299             :             {
     300             :                 /* AR low-pass filter  */
     301      158080 :                 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         837 :         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          11 :             if ( hDtxEnc->last_active_brate > ACELP_16k40 )
     311             :             {
     312           4 :                 hDtxEnc->CNG_mode = -1;
     313             :             }
     314             :             else
     315             :             {
     316           7 :                 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         837 :         hTdCngEnc->burst_ho_cnt = min( hTdCngEnc->burst_ho_cnt, hTdCngEnc->ho_circ_size );
     322         837 :         hTdCngEnc->act_cnt = 0;
     323         837 :         s_ptr = hTdCngEnc->ho_circ_ptr - hTdCngEnc->burst_ho_cnt + 1;
     324         837 :         if ( s_ptr < 0 )
     325             :         {
     326         232 :             s_ptr += hTdCngEnc->ho_circ_size;
     327             :         }
     328             : 
     329        3021 :         for ( ll = hTdCngEnc->burst_ho_cnt; ll > 0; ll-- )
     330             :         {
     331        2184 :             if ( ++( hTdCngEnc->ho_hist_ptr ) == HO_HIST_SIZE )
     332             :             {
     333         249 :                 hTdCngEnc->ho_hist_ptr = 0;
     334             :             }
     335             :             /* Conversion between 12.8k and 16k LSPs */
     336        2184 :             if ( st->L_frame == L_FRAME && hTdCngEnc->ho_16k_lsp[s_ptr] == 1 )
     337             :             {
     338             :                 /* Conversion from 16k LPSs to 12k8 */
     339           2 :                 lsp_convert_poly( &( hTdCngEnc->ho_lsp_circ[s_ptr * M] ), st->L_frame, 0 );
     340             :             }
     341        2182 :             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         281 :                 mvr2r( &( hTdCngEnc->ho_lsp_circ2[s_ptr * M] ), &( hTdCngEnc->ho_lsp_circ[s_ptr * M] ), M );
     345             :             }
     346             : 
     347             :             /* update circular buffers */
     348        2184 :             mvr2r( &( hTdCngEnc->ho_lsp_circ[s_ptr * M] ), &( hTdCngEnc->ho_lsp_hist[hTdCngEnc->ho_hist_ptr * M] ), M );
     349        2184 :             mvr2r( &( hTdCngEnc->ho_ener_circ[s_ptr] ), &( hTdCngEnc->ho_ener_hist[hTdCngEnc->ho_hist_ptr] ), 1 );
     350        2184 :             hTdCngEnc->ho_sid_bw = ( hTdCngEnc->ho_sid_bw & 0x3fffffffL ) << 1;
     351        2184 :             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        2184 :             hTdCngEnc->ho_hist_size++;
     354        2184 :             if ( hTdCngEnc->ho_hist_size > HO_HIST_SIZE )
     355             :             {
     356         292 :                 hTdCngEnc->ho_hist_size = HO_HIST_SIZE;
     357             :             }
     358             : 
     359        2184 :             s_ptr++;
     360             : 
     361        2184 :             if ( s_ptr == hTdCngEnc->ho_circ_size )
     362             :             {
     363         287 :                 s_ptr = 0;
     364             :             }
     365             :         }
     366         837 :         if ( st->hTdCngEnc->burst_ho_cnt > 0 )
     367             :         {
     368         443 :             *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         837 :         if ( !*allow_cn_step && hTdCngEnc->ho_hist_size > 0 )
     372             :         {
     373         673 :             ptr = hTdCngEnc->ho_hist_ptr;
     374         673 :             mvr2r( &( hTdCngEnc->ho_lsp_hist[ptr * M] ), tmp, M );
     375         673 :             m1 = 0;
     376         673 :             if ( ( hTdCngEnc->ho_sid_bw & 0x1L ) == 0 )
     377             :             {
     378         382 :                 mvr2r( &hTdCngEnc->ho_env_hist[ptr * NUM_ENV_CNG], tmp_env, NUM_ENV_CNG );
     379         382 :                 m1 = 1;
     380             :             }
     381         673 :             enr = W_DTX_HO[0] * hTdCngEnc->ho_ener_hist[ptr];
     382         673 :             weights = W_DTX_HO[0];
     383         673 :             m = 1;
     384        3796 :             for ( k = 1; k < hTdCngEnc->ho_hist_size; k++ )
     385             :             {
     386        3123 :                 ptr--;
     387        3123 :                 if ( ptr < 0 )
     388             :                 {
     389         290 :                     ptr = HO_HIST_SIZE - 1;
     390             :                 }
     391             : 
     392        3123 :                 if ( hTdCngEnc->ho_ener_hist[ptr] < hTdCngEnc->ho_ener_hist[hTdCngEnc->ho_hist_ptr] * BUF_H_NRG &&
     393        1663 :                      hTdCngEnc->ho_ener_hist[ptr] > hTdCngEnc->ho_ener_hist[hTdCngEnc->ho_hist_ptr] * BUF_L_NRG )
     394             :                 {
     395        1169 :                     enr += W_DTX_HO[k] * hTdCngEnc->ho_ener_hist[ptr];
     396        1169 :                     weights += W_DTX_HO[k];
     397        1169 :                     mvr2r( &hTdCngEnc->ho_lsp_hist[ptr * M], &tmp[m * M], M );
     398        1169 :                     if ( ( hTdCngEnc->ho_sid_bw & ( 0x1L << k ) ) == 0 )
     399             :                     {
     400         555 :                         mvr2r( &hTdCngEnc->ho_env_hist[ptr * NUM_ENV_CNG], &tmp_env[m1 * NUM_ENV_CNG], NUM_ENV_CNG );
     401         555 :                         m1++;
     402             :                     }
     403        1169 :                     m++;
     404             :                 }
     405             :             }
     406             : 
     407         673 :             enr /= weights;
     408         673 :             hTdCngEnc->lp_ener = enr;
     409             : 
     410         673 :             set_f( max_val, 0.0f, 2 );
     411         673 :             set_s( max_idx, 0, 2 );
     412             : 
     413        2515 :             for ( i = 0; i < m; i++ )
     414             :             {
     415        1842 :                 if ( st->L_frame == L_FRAME )
     416             :                 {
     417         769 :                     lsp2lsf( &tmp[i * M], lsf_tmp, M, INT_FS_12k8 );
     418         769 :                     ftmp = 6400.0f / ( M + 1 );
     419         769 :                     C[i] = ( 6400.0f - lsf_tmp[M - 1] - ftmp ) * ( 6400.0f - lsf_tmp[M - 1] - ftmp );
     420             :                 }
     421             :                 else
     422             :                 {
     423        1073 :                     lsp2lsf( &tmp[i * M], lsf_tmp, M, INT_FS_16k );
     424        1073 :                     ftmp = 8000.0f / ( M + 1 );
     425        1073 :                     C[i] = ( 8000.0f - lsf_tmp[M - 1] - ftmp ) * ( 8000.0f - lsf_tmp[M - 1] - ftmp );
     426             :                 }
     427             : 
     428        1842 :                 C[i] += ( lsf_tmp[0] - ftmp ) * ( lsf_tmp[0] - ftmp );
     429             : 
     430       29472 :                 for ( j = 0; j < M - 1; j++ )
     431             :                 {
     432       27630 :                     C[i] += ( lsf_tmp[j + 1] - lsf_tmp[j] - ftmp ) * ( lsf_tmp[j + 1] - lsf_tmp[j] - ftmp );
     433             :                 }
     434             : 
     435        1842 :                 C[i] *= 0.0588235f; /* 1/M+1 */
     436             : 
     437        1842 :                 if ( C[i] > max_val[0] )
     438             :                 {
     439        1145 :                     max_val[1] = max_val[0];
     440        1145 :                     max_idx[1] = max_idx[0];
     441        1145 :                     max_val[0] = C[i];
     442        1145 :                     max_idx[0] = i;
     443             :                 }
     444         697 :                 else if ( C[i] > max_val[1] )
     445             :                 {
     446         349 :                     max_val[1] = C[i];
     447         349 :                     max_idx[1] = i;
     448             :                 }
     449             :             }
     450             : 
     451         673 :             if ( m == 1 )
     452             :             {
     453         201 :                 mvr2r( tmp, lsp_tmp, M );
     454             :             }
     455         472 :             else if ( m < 4 )
     456             :             {
     457        5100 :                 for ( i = 0; i < M; i++ )
     458             :                 {
     459        4800 :                     lsp_tmp[i] = 0.0f;
     460       16736 :                     for ( j = 0; j < m; j++ )
     461             :                     {
     462       11936 :                         lsp_tmp[i] += tmp[j * M + i];
     463             :                     }
     464             : 
     465        4800 :                     lsp_tmp[i] -= tmp[max_idx[0] * M + i];
     466        4800 :                     lsp_tmp[i] /= (float) ( m - 1 );
     467             :                 }
     468             :             }
     469             :             else
     470             :             {
     471        2924 :                 for ( i = 0; i < M; i++ )
     472             :                 {
     473        2752 :                     lsp_tmp[i] = 0.0f;
     474       17072 :                     for ( j = 0; j < m; j++ )
     475             :                     {
     476       14320 :                         lsp_tmp[i] += tmp[j * M + i];
     477             :                     }
     478             : 
     479        2752 :                     lsp_tmp[i] -= ( tmp[max_idx[0] * M + i] + tmp[max_idx[1] * M + i] );
     480        2752 :                     lsp_tmp[i] /= (float) ( m - 2 );
     481             :                 }
     482             :             }
     483             : 
     484         673 :             dist = 0.0f;
     485         673 :             max_dev = 0.0f;
     486       11441 :             for ( i = 0; i < M; i++ )
     487             :             {
     488       10768 :                 dev = (float) fabs( lsp_tmp[i] - lsp_new[i] );
     489       10768 :                 dist += dev;
     490       10768 :                 if ( dev > max_dev )
     491             :                 {
     492        3324 :                     max_dev = dev;
     493             :                 }
     494             :             }
     495             : 
     496         673 :             if ( dist > 0.4f || max_dev > 0.1f )
     497             :             {
     498         714 :                 for ( i = 0; i < M; i++ )
     499             :                 {
     500         672 :                     hDtxEnc->lspCNG[i] = lsp_tmp[i];
     501             :                 }
     502             :             }
     503             :             else
     504             :             {
     505       10727 :                 for ( i = 0; i < M; i++ )
     506             :                 {
     507             :                     /* AR low-pass filter  */
     508       10096 :                     hDtxEnc->lspCNG[i] = 0.8f * lsp_tmp[i] + ( 1 - 0.8f ) * lsp_new[i];
     509             :                 }
     510             :             }
     511         673 :             if ( m1 > 0 )
     512             :             {
     513        9219 :                 for ( i = 0; i < NUM_ENV_CNG; i++ )
     514             :                 {
     515        8780 :                     env[i] = 0;
     516       27520 :                     for ( j = 0; j < m1; j++ )
     517             :                     {
     518       18740 :                         env[i] += tmp_env[j * NUM_ENV_CNG + i];
     519             :                     }
     520             : 
     521        8780 :                     env[i] /= (float) m1;
     522        8780 :                     env[i] = env[i] - 2 * hTdCngEnc->lp_ener;
     523             :                 }
     524         439 :                 mvr2r( env, hTdCngEnc->lp_env, NUM_ENV_CNG );
     525             :             }
     526             :         }
     527             :         else
     528             :         {
     529         164 :             mvr2r( lsp_new, hDtxEnc->lspCNG, M ); /* use newly analyzed parameters */
     530             :         }
     531             :     }
     532             : 
     533       10992 :     if ( st->Opt_AMR_WB )
     534             :     {
     535         894 :         isp2a( hDtxEnc->lspCNG, Aq, M );
     536             :     }
     537             :     else
     538             :     {
     539       10098 :         lsp2a_stab( hDtxEnc->lspCNG, Aq, M );
     540             :     }
     541             : 
     542       49784 :     for ( i = 1; i < st->L_frame / L_SUBFR; i++ )
     543             :     {
     544       38792 :         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       10992 :     residu( Aq, M, speech, res, st->L_frame );
     554             : 
     555       10992 :     mvr2r( res, res1, st->L_frame );
     556             : 
     557       10992 :     if ( st->element_mode == IVAS_CPE_DFT || st->element_mode == IVAS_CPE_TD )
     558             :     {
     559        8162 :         att = powf( 10.0f, hTdCngEnc->CNG_att / 20.0f );
     560        8162 :         v_multc( res1, att, res1, st->L_frame );
     561             :     }
     562        2830 :     else if ( st->bwidth != NB )
     563             :     {
     564        2368 :         if ( st->bwidth == WB && hDtxEnc->CNG_mode >= 0 )
     565             :         {
     566         913 :             ftmp = HO_ATT[hDtxEnc->CNG_mode];
     567             :         }
     568             :         else
     569             :         {
     570        1455 :             ftmp = 0.6f;
     571             :         }
     572             : 
     573        2368 :         att = ftmp / 6.0f;
     574        2368 :         att = 1.0f / ( 1 + att * 8 );
     575             : 
     576        2368 :         if ( att < ftmp )
     577             :         {
     578        2368 :             att = ftmp;
     579             :         }
     580             : 
     581        2368 :         v_multc( res1, att, res1, st->L_frame );
     582             :     }
     583             : 
     584             :     /* calculate the spectrum of residual signal */
     585       10992 :     mvr2r( res1, fft_io, st->L_frame );
     586             : 
     587       10992 :     if ( st->L_frame == L_FRAME16k )
     588             :     {
     589        5816 :         modify_Fs( fft_io, L_FRAME16k, 16000, fft_io, 12800, hTdCngEnc->exc_mem2, 0 );
     590             :     }
     591             : 
     592       10992 :     fft_rel( fft_io, L_FFT, LOG2_L_FFT );
     593       10992 :     ptR = &fft_io[1];
     594       10992 :     ptI = &fft_io[L_FFT - 1];
     595      230832 :     for ( i = 0; i < NUM_ENV_CNG; i++ )
     596             :     {
     597      219840 :         env[i] = 2.0f * ( *ptR * *ptR + *ptI * *ptI ) / L_FFT;
     598      219840 :         ptR++;
     599      219840 :         ptI--;
     600             :     }
     601             : 
     602       10992 :     mvr2r( env, &( hTdCngEnc->cng_res_env[( hTdCngEnc->cng_hist_ptr ) * NUM_ENV_CNG] ), NUM_ENV_CNG );
     603             :     /* calculate the residual signal energy */
     604       10992 :     enr = dotp( res, res, st->L_frame ) / st->L_frame;
     605             : 
     606             :     /* convert log2 of residual signal energy */
     607       10992 :     enr = (float) log10( enr + 0.1f ) / (float) log10( 2.0f );
     608             : 
     609             :     /* update the circular buffer of old energies */
     610       10992 :     hTdCngEnc->cng_ener_hist[hTdCngEnc->cng_hist_ptr] = enr;
     611             : 
     612             :     /*-----------------------------------------------------------------*
     613             :      * Quantize residual signal energy (only in SID frame)
     614             :      *-----------------------------------------------------------------*/
     615             : 
     616       10992 :     if ( st->core_brate == SID_2k40 || st->core_brate == SID_1k75 )
     617             :     {
     618        1870 :         if ( hDtxEnc->cng_cnt >= hDtxEnc->cng_hist_size - 1 )
     619             :         {
     620             :             /* average the envelope except outliers */
     621       21588 :             for ( i = 0; i < NUM_ENV_CNG; i++ )
     622             :             {
     623      184540 :                 for ( j = 0; j < hDtxEnc->cng_hist_size; j++ )
     624             :                 {
     625      163980 :                     env[i] += hTdCngEnc->cng_res_env[j * NUM_ENV_CNG + i];
     626             :                 }
     627             : 
     628       20560 :                 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       20560 :                 env[i] /= (float) ( hDtxEnc->cng_hist_size - 2 );
     630             :             }
     631             :             /* compute average excitation energy */
     632        1028 :             enr = 0;
     633        1028 :             weights = 0;
     634        1028 :             ptr = hTdCngEnc->cng_hist_ptr;
     635             : 
     636        9227 :             for ( k = 0; k < hDtxEnc->cng_hist_size; k++ )
     637             :             {
     638        8199 :                 enr += W_HIST[k] * hTdCngEnc->cng_ener_hist[ptr--];
     639        8199 :                 if ( ptr < 0 )
     640             :                 {
     641        1028 :                     ptr = DTX_HIST_SIZE - 1;
     642             :                 }
     643             : 
     644        8199 :                 weights += W_HIST[k];
     645             :             }
     646             : 
     647             :             /* normalize the average value */
     648        1028 :             enr /= weights;
     649             :         }
     650             : 
     651        1870 :         if ( st->element_mode == IVAS_SCE || st->element_mode == IVAS_CPE_DFT )
     652             :         {
     653        1655 :             enr += hTdCngEnc->CNG_att * FAC_LOG2 / 10.0f;
     654             :         }
     655         215 :         else if ( st->bwidth != NB )
     656             :         {
     657         161 :             if ( st->bwidth == WB )
     658             :             {
     659         161 :                 if ( hDtxEnc->CNG_mode >= 0 )
     660             :                 {
     661             :                     /* Bitrate adapted attenuation */
     662         116 :                     att = ENR_ATT[hDtxEnc->CNG_mode];
     663             :                 }
     664             :                 else
     665             :                 {
     666             :                     /* Use least attenuation for higher bitrates */
     667          45 :                     att = ENR_ATT[4];
     668             :                 }
     669             :             }
     670             :             else
     671             :             {
     672           0 :                 att = 1.5f;
     673             :             }
     674         161 :             enr -= att;
     675             :         }
     676             : 
     677             :         /* intialize the energy quantization parameters */
     678        1870 :         if ( !st->Opt_AMR_WB )
     679             :         {
     680        1763 :             step = STEP_SID;
     681        1763 :             maxl = 127;
     682        1763 :             num_bits = 7;
     683             :         }
     684             :         else
     685             :         {
     686         107 :             step = STEP_AMR_WB_SID;
     687         107 :             maxl = 63;
     688         107 :             num_bits = 6;
     689             :         }
     690             : 
     691             :         /* calculate the energy quantization index */
     692        1870 :         enr_index = (int16_t) ( ( enr + 2.0f ) * step );
     693             : 
     694             :         /* limit the energy quantization index */
     695        1870 :         if ( enr_index > maxl )
     696             :         {
     697           0 :             enr_index = maxl;
     698             :         }
     699             : 
     700        1870 :         if ( enr_index < 0 )
     701             :         {
     702         342 :             enr_index = 0;
     703             :         }
     704             : 
     705             :         /* allow only slow energy increase */
     706        1870 :         if ( hDtxEnc->first_CNG && enr_index > hTdCngEnc->old_enr_index + MAX_DELTA_CNG )
     707             :         {
     708         338 :             if ( *allow_cn_step == 1 )
     709             :             {
     710          78 :                 enr_index = hTdCngEnc->old_enr_index + (int16_t) ( 0.85f * ( enr_index - hTdCngEnc->old_enr_index ) );
     711             :             }
     712             :             else
     713             :             {
     714         260 :                 enr_index = hTdCngEnc->old_enr_index + MAX_DELTA_CNG;
     715             :             }
     716             :         }
     717        1870 :         hTdCngEnc->old_enr_index = enr_index;
     718             : 
     719        1870 :         push_indice( hBstr, IND_ENERGY, enr_index, num_bits );
     720        1870 :         if ( enr_index == 0 )
     721             :         {
     722         408 :             enr_index = -5;
     723             :         }
     724             :         /* find the quatized energy */
     725        1870 :         hTdCngEnc->Enew = (float) enr_index / step - 2.0f;
     726        1870 :         hTdCngEnc->Enew = (float) ( pow( 2.0f, hTdCngEnc->Enew ) );
     727        1870 :         if ( st->core_brate == SID_2k40 )
     728             :         {
     729        1763 :             enr1 = (float) log10( hTdCngEnc->Enew * st->L_frame + 0.1f ) / (float) log10( 2.0f );
     730       37023 :             for ( i = 0; i < NUM_ENV_CNG; i++ )
     731             :             {
     732       35260 :                 env[i] -= 2 * hTdCngEnc->Enew;
     733             : 
     734       35260 :                 if ( env[i] < 0.0f )
     735             :                 {
     736       22482 :                     env[i] = 0.1f;
     737             :                 }
     738             : 
     739       35260 :                 env[i] = (float) log10( env[i] + 0.1f ) / (float) log10( 2.0f );
     740       35260 :                 env[i] -= att;
     741             : 
     742       35260 :                 if ( env[i] < 0 )
     743             :                 {
     744       23600 :                     env[i] = 0;
     745             :                 }
     746             : 
     747       35260 :                 env[i] = enr1 - env[i];
     748             :             }
     749             : 
     750             :             /* codebook search */
     751        1763 :             min1 = 9999.0f;
     752        1763 :             min1_idx = 0;
     753             : 
     754      114595 :             for ( i = 0; i < 64; i++ )
     755             :             {
     756      112832 :                 d = 0.0f;
     757     2369472 :                 for ( j = 0; j < NUM_ENV_CNG; j++ )
     758             :                 {
     759     2256640 :                     d += ( env[j] - CNG_details_codebook[i][j] ) * ( env[j] - CNG_details_codebook[i][j] );
     760             :                 }
     761             : 
     762      112832 :                 if ( d < min1 )
     763             :                 {
     764       10116 :                     min1 = d;
     765       10116 :                     min1_idx = i;
     766             :                 }
     767             :             }
     768        1763 :             push_indice( hBstr, IND_CNG_ENV1, min1_idx, 6 );
     769             :             /* get quantized res_env_details */
     770       37023 :             for ( i = 0; i < NUM_ENV_CNG; i++ )
     771             :             {
     772       35260 :                 q_env[i] = CNG_details_codebook[min1_idx][i];
     773             :             }
     774             :         }
     775             :         /* Update hangover memory during CNG */
     776        1870 :         if ( !*allow_cn_step && ( hTdCngEnc->Enew < 1.5f * hTdCngEnc->lp_ener ) )
     777             :         {
     778             :             /* update the pointer to circular buffer of old LSP vectors */
     779        1365 :             if ( ++( hTdCngEnc->ho_hist_ptr ) == HO_HIST_SIZE )
     780             :             {
     781         151 :                 hTdCngEnc->ho_hist_ptr = 0;
     782             :             }
     783             : 
     784             :             /* update the circular buffer of old LSP vectors with the new LSP vector */
     785        1365 :             mvr2r( lsp_new, &( hTdCngEnc->ho_lsp_hist[( hTdCngEnc->ho_hist_ptr ) * M] ), M );
     786             : 
     787             :             /* update the hangover energy buffer */
     788        1365 :             hTdCngEnc->ho_ener_hist[hTdCngEnc->ho_hist_ptr] = hTdCngEnc->Enew;
     789        1365 :             if ( st->core_brate == SID_2k40 )
     790             :             {
     791       26502 :                 for ( i = 0; i < NUM_ENV_CNG; i++ )
     792             :                 {
     793             :                     /* get quantized envelope */
     794       25240 :                     env[i] = (float) ( pow( 2.0f, ( enr1 - q_env[i] ) ) + 2 * hTdCngEnc->Enew );
     795             :                 }
     796        1262 :                 mvr2r( env, &( hTdCngEnc->ho_env_hist[( hTdCngEnc->ho_hist_ptr ) * NUM_ENV_CNG] ), NUM_ENV_CNG );
     797             :             }
     798        1365 :             if ( ++( hTdCngEnc->ho_hist_size ) > HO_HIST_SIZE )
     799             :             {
     800         913 :                 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       10992 :     if ( st->core_brate == SID_1k75 )
     807             :     {
     808         107 :         push_indice( hBstr, IND_DITHERING, 0, 1 );
     809             :     }
     810             : 
     811       10992 :     if ( st->core_brate == SID_2k40 )
     812             :     {
     813        1763 :         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        1763 :         if ( hTdCngEnc->burst_ho_cnt > ( HO_HIST_SIZE - 1 ) )
     817             :         {
     818          58 :             push_indice( hBstr, IND_CNG_HO, ( HO_HIST_SIZE - 1 ), 3 ); /* send max allowed value, limited to 7 */
     819             :         }
     820             :         else
     821             :         {
     822        1705 :             push_indice( hBstr, IND_CNG_HO, hTdCngEnc->burst_ho_cnt, 3 ); /* send actual value */
     823             :         }
     824        1763 :         hTdCngEnc->num_ho = m;
     825        1763 :         push_indice( hBstr, IND_SID_TYPE, 0, 1 );
     826             : 
     827        1763 :         if ( st->input_Fs < 32000 && st->element_mode != IVAS_CPE_DFT )
     828             :         {
     829          88 :             push_indice( hBstr, IND_SID_BW, 0, 1 );
     830          88 :             *sid_bw = 0;
     831             :         }
     832             :     }
     833             : 
     834             :     /*-----------------------------------------------------------------*
     835             :      * Updates
     836             :      *-----------------------------------------------------------------*/
     837             : 
     838             :     /* update the SID frames counter */
     839       10992 :     if ( st->core_brate == SID_2k40 || st->core_brate == SID_1k75 )
     840             :     {
     841        1870 :         hDtxEnc->cng_cnt = 0;
     842             :         /* update frame length memory */
     843        1870 :         hDtxEnc->last_CNG_L_frame = st->L_frame;
     844        1870 :         hTdCngEnc->cng_hist_ptr = -1;
     845             :     }
     846             :     else
     847             :     {
     848        9122 :         hDtxEnc->cng_cnt++;
     849             :     }
     850             : 
     851       10992 :     return;
     852             : }
     853             : 
     854             : 
     855             : /*---------------------------------------------------------------------*
     856             :  * swb_CNG_enc()
     857             :  *
     858             :  * SWB DTX/CNG encoding
     859             :  *---------------------------------------------------------------------*/
     860             : 
     861      656311 : 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      656311 :     if ( st->core_brate == SID_2k40 || st->core_brate == FRAME_NO_DATA )
     870             :     {
     871       47272 :         if ( st->cng_type == LP_CNG )
     872             :         {
     873        9326 :             if ( st->input_Fs >= L_FRAME32k * FRAMES_PER_SEC )
     874             :             {
     875             :                 /* decide if SHB SID encoding or not */
     876        8093 :                 shb_SID_updt = shb_DTX( st, shb_speech, syn_12k8_16k );
     877             : 
     878             :                 /* SHB CNG encoding */
     879        8093 :                 shb_CNG_encod( st, shb_SID_updt );
     880             :             }
     881        1233 :             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         205 :                 delete_indice( st->hBstr, IND_CNG_ENV1 );
     885         205 :                 push_indice( st->hBstr, IND_BWIDTH, st->bwidth, 2 );
     886         205 :                 push_indice( st->hBstr, IND_UNUSED, 0, 4 );
     887         205 :                 push_indice( st->hBstr, IND_SID_BW, 1, 1 );
     888             :             }
     889             :         }
     890       47272 :         st->hTdCngEnc->last_vad = 0;
     891             :     }
     892             :     else
     893             :     {
     894      609039 :         st->hTdCngEnc->last_vad = 1;
     895             :     }
     896             : 
     897      656311 :     return;
     898             : }
     899             : 
     900             : /*---------------------------------------------------------------------*
     901             :  * shb_CNG_encod()
     902             :  *
     903             :  * SID parameters encoding for SHB signal
     904             :  *---------------------------------------------------------------------*/
     905             : 
     906        8093 : 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        8093 :     int16_t idx_ener = 0;
     912        8093 :     BSTR_ENC_HANDLE hBstr = st->hBstr;
     913             :     float ener_mid_dec_thr;
     914             : 
     915        8093 :     if ( update == 1 )
     916             :     {
     917             :         /* SHB energy quantization */
     918        1376 :         if ( st->element_mode == EVS_MONO )
     919             :         {
     920           6 :             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        1370 :             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        1376 :         if ( st->bwidth < SWB )
     928             :         {
     929          24 :             idx_ener = 0;
     930             :         }
     931             : 
     932        1376 :         if ( idx_ener > 15 )
     933             :         {
     934           0 :             idx_ener = 15;
     935             :         }
     936        1376 :         else if ( idx_ener < 0 )
     937             :         {
     938         112 :             idx_ener = 0;
     939             :         }
     940             : 
     941             :         /* prevent toggling of idx_ener by adding small dead-zone interval around decision thresholds */
     942        1376 :         if ( st->element_mode != EVS_MONO )
     943             :         {
     944        1370 :             if ( abs( idx_ener - st->hTdCngEnc->last_idx_ener ) == 1 )
     945             :             {
     946         232 :                 ener_mid_dec_thr = 0.5f * ( ( st->hTdCngEnc->last_idx_ener / 0.7f - 6.0f ) / 0.1f ) * (float) log10( 2.0f );
     947         232 :                 ener_mid_dec_thr += 0.5f * ( ( idx_ener / 0.7f - 6.0f ) / 0.1f ) * (float) log10( 2.0f );
     948             : 
     949         232 :                 if ( fabs( st->hTdCngEnc->mov_shb_cng_ener - ener_mid_dec_thr ) / ener_mid_dec_thr < ENER_MID_DEAD_ZONE )
     950             :                 {
     951         158 :                     idx_ener = st->hTdCngEnc->last_idx_ener;
     952             :                 }
     953             :             }
     954             :         }
     955             : 
     956        1376 :         st->hTdCngEnc->last_idx_ener = idx_ener;
     957             : 
     958        1376 :         push_indice( hBstr, IND_SHB_CNG_GAIN, idx_ener, 4 );
     959        1376 :         push_indice( hBstr, IND_SID_BW, 1, 1 );
     960        1376 :         delete_indice( hBstr, IND_CNG_ENV1 );
     961        1376 :         if ( st->element_mode == IVAS_CPE_DFT )
     962             :         {
     963        1312 :             push_indice( st->hBstr, IND_BWIDTH, st->bwidth, 2 );
     964             :         }
     965             :         else
     966             :         {
     967          64 :             push_indice( hBstr, IND_UNUSED, 0, 2 );
     968             :         }
     969        1376 :         st->hTdCngEnc->ho_sid_bw = ( st->hTdCngEnc->ho_sid_bw & 0x3fffffffL ) << 1;
     970        1376 :         st->hTdCngEnc->ho_sid_bw |= 0x1L;
     971             :     }
     972        6717 :     else if ( st->core_brate == SID_2k40 )
     973             :     {
     974          94 :         st->hTdCngEnc->ho_sid_bw = ( st->hTdCngEnc->ho_sid_bw & 0x3fffffffL ) << 1;
     975          94 :         push_indice( hBstr, IND_SID_BW, 0, 1 );
     976             :     }
     977             : 
     978        8093 :     return;
     979             : }
     980             : 
     981             : 
     982             : /*---------------------------------------------------------------------*
     983             :  * shb_DTX()
     984             :  *
     985             :  * Decide if encoding SHB SID or not
     986             :  *---------------------------------------------------------------------*/
     987             : 
     988        8093 : 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        8093 :     int16_t allow_cn_step = 0;
    1004             :     float att;
    1005             : 
    1006        8093 :     TD_CNG_ENC_HANDLE hTdCngEnc = st->hTdCngEnc;
    1007             : 
    1008        8093 :     shb_new_speech = shb_old_speech + ( L_LOOK_12k8 + L_SUBFR ) * 5 / 4;
    1009        8093 :     mvr2r( st->hBWE_TD->old_speech_shb, shb_old_speech, ( L_LOOK_12k8 + L_SUBFR ) * 5 / 4 );
    1010        8093 :     mvr2r( shb_speech, shb_new_speech, L_FRAME16k );
    1011        8093 :     mvr2r( shb_old_speech + L_FRAME16k, st->hBWE_TD->old_speech_shb, ( L_LOOK_12k8 + L_SUBFR ) * 5 / 4 );
    1012             : 
    1013        8093 :     shb_ener = FLT_MIN * L_FRAME16k;
    1014     2597853 :     for ( i = 0; i < L_FRAME16k; i++ )
    1015             :     {
    1016     2589760 :         shb_ener += shb_old_speech[i] * shb_old_speech[i];
    1017             :     }
    1018        8093 :     shb_ener /= L_FRAME16k;
    1019             : 
    1020        8093 :     wb_ener = sum2_f( syn_12k8_16k, st->L_frame ) + 0.001f;
    1021        8093 :     wb_ener = wb_ener / st->L_frame;
    1022             : 
    1023        8093 :     log_wb_ener = 10 * (float) log10( wb_ener );
    1024        8093 :     if ( st->element_mode == IVAS_SCE || st->element_mode == IVAS_CPE_DFT )
    1025             :     {
    1026        7937 :         att = 0.0f;
    1027             : 
    1028        7937 :         apply_scale( &att, st->hFdCngEnc->hFdCngCom->CngBandwidth, st->hFdCngEnc->hFdCngCom->CngBitrate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO );
    1029             :     }
    1030             :     else
    1031             :     {
    1032         156 :         att = -6.5f;
    1033             :     }
    1034        8093 :     log_shb_ener = 10 * (float) log10( shb_ener ) + att;
    1035             : 
    1036        8093 :     if ( st->hDtxEnc->first_CNG == 0 )
    1037             :     {
    1038          69 :         hTdCngEnc->mov_wb_cng_ener = log_wb_ener;
    1039          69 :         hTdCngEnc->mov_shb_cng_ener = log_shb_ener;
    1040          69 :         hTdCngEnc->last_wb_cng_ener = log_wb_ener;
    1041          69 :         hTdCngEnc->last_shb_cng_ener = log_shb_ener;
    1042             :     }
    1043        8093 :     if ( fabs( log_wb_ener - hTdCngEnc->mov_wb_cng_ener ) > 12.0f )
    1044             :     {
    1045         137 :         allow_cn_step = 1;
    1046             :     }
    1047             : 
    1048             :     /* Also allow step if shb energy has dropped 12 dB */
    1049        8093 :     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         190 :         allow_cn_step = 1;
    1052             :     }
    1053             : 
    1054        8093 :     if ( allow_cn_step == 1 )
    1055             :     {
    1056         266 :         hTdCngEnc->mov_wb_cng_ener = log_wb_ener;
    1057         266 :         hTdCngEnc->mov_shb_cng_ener = log_shb_ener;
    1058             :     }
    1059             :     else
    1060             :     {
    1061        7827 :         ftmp = log_wb_ener - hTdCngEnc->mov_wb_cng_ener;
    1062             : 
    1063        7827 :         hTdCngEnc->mov_wb_cng_ener += 0.9f * ftmp;
    1064             : 
    1065        7827 :         ftmp = log_shb_ener - hTdCngEnc->mov_shb_cng_ener;
    1066             : 
    1067        7827 :         hTdCngEnc->mov_shb_cng_ener += 0.25f * ftmp;
    1068             :     }
    1069        8093 :     hTdCngEnc->shb_NO_DATA_cnt++;
    1070             : 
    1071        8093 :     update = 0;
    1072        8093 :     if ( st->core_brate == SID_2k40 )
    1073             :     {
    1074        1470 :         if ( st->hDtxEnc->first_CNG == 0 )
    1075             :         {
    1076          69 :             update = 1;
    1077             :         }
    1078        1401 :         else if ( hTdCngEnc->shb_cng_ini_cnt > 0 )
    1079             :         {
    1080          53 :             hTdCngEnc->shb_cng_ini_cnt--;
    1081          53 :             update = 1;
    1082             :         }
    1083        1348 :         else if ( hTdCngEnc->last_vad == 1 )
    1084             :         {
    1085         612 :             update = 1;
    1086             :         }
    1087         736 :         else if ( hTdCngEnc->shb_NO_DATA_cnt >= 100 )
    1088             :         {
    1089           0 :             update = 1;
    1090             :         }
    1091         736 :         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         285 :             update = 1;
    1094             :         }
    1095         451 :         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        1470 :         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        8093 :     if ( ( st->element_mode == IVAS_CPE_DFT || st->element_mode == IVAS_CPE_TD ) && st->core_brate == SID_2k40 )
    1105             :     {
    1106        1312 :         update = 1;
    1107             :     }
    1108             : 
    1109        8093 :     if ( update == 1 )
    1110             :     {
    1111        1376 :         hTdCngEnc->last_wb_cng_ener = hTdCngEnc->mov_wb_cng_ener;
    1112        1376 :         hTdCngEnc->last_shb_cng_ener = hTdCngEnc->mov_shb_cng_ener;
    1113        1376 :         hTdCngEnc->shb_NO_DATA_cnt = 0;
    1114             :     }
    1115             : 
    1116        8093 :     return ( update );
    1117             : }
    1118             : 
    1119             : 
    1120             : /*---------------------------------------------------------------------*
    1121             :  * calculate_hangover_attenuation_gain()
    1122             :  *
    1123             :  *
    1124             :  *---------------------------------------------------------------------*/
    1125             : 
    1126     2312769 : 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     2312769 :     *att = 1.0f;
    1135     2312769 :     if ( st->hTdCngEnc != NULL && vad_hover_flag && st->hTdCngEnc->burst_ho_cnt > 0 && ( st->bwidth != NB || st->element_mode > EVS_MONO ) )
    1136             :     {
    1137       12859 :         if ( st->element_mode == IVAS_CPE_DFT || st->element_mode == IVAS_CPE_TD )
    1138             :         {
    1139       11136 :             *att = powf( 10.0f, ( st->hTdCngEnc->CNG_att / 160.0f ) * st->hTdCngEnc->burst_ho_cnt );
    1140             :         }
    1141             :         else
    1142             :         {
    1143        1723 :             if ( st->bwidth == WB && st->hDtxEnc->CNG_mode >= 0 )
    1144             :             {
    1145          27 :                 lim = HO_ATT[st->hDtxEnc->CNG_mode];
    1146             :             }
    1147             :             else
    1148             :             {
    1149        1696 :                 lim = 0.6f;
    1150             :             }
    1151             : 
    1152        1723 :             *att = lim / 6.0f;
    1153        1723 :             *att = 1.0f / ( 1 + *att * st->hTdCngEnc->burst_ho_cnt );
    1154             : 
    1155        1723 :             if ( *att < lim )
    1156             :             {
    1157         266 :                 *att = lim;
    1158             :             }
    1159             :         }
    1160             :     }
    1161             : 
    1162     2312769 :     return;
    1163             : }

Generated by: LCOV version 1.14