LCOV - code coverage report
Current view: top level - lib_com - tec_com.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ 6c9ddc4024a9c0e1ecb8f643f114a84a0e26ec6b Lines: 249 250 99.6 %
Date: 2025-05-23 08:37:30 Functions: 22 22 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 <assert.h>
      38             : #include <stdint.h>
      39             : #include "options.h"
      40             : #include <math.h>
      41             : #include "rom_com.h"
      42             : #include "prot.h"
      43             : #include "stat_dec.h"
      44             : #include "wmc_auto.h"
      45             : 
      46             : /*-------------------------------------------------------------------
      47             :  * Local constants
      48             :  *-------------------------------------------------------------------*/
      49             : 
      50             : #define LOBUF_NO_SMOOTHING_MODE 1
      51             : 
      52             : #define EPS                 ( 1e-12f )
      53             : #define ENV_SCALE_OFFSET_1  90.309f /* 10*log10(2^30) */
      54             : #define MAX_TEC_BW_LO       ( 12 )
      55             : #define MAX_NB_TEC_LOW_BAND ( 3 )
      56             : 
      57             : const float TecSC[] = { 0.3662f, 0.1078f, 0.1194f, 0.1289f, 0.1365f, 0.1412f };
      58             : const int16_t TecLowBandTable[] = { 0, 2, 4, 6 };
      59             : 
      60             : #define TecSmoothingDeg 5
      61             : #define NbTecLowBand    3
      62             : 
      63             : #define ratioHiLoFac    1.5894f
      64             : #define thRatio         0.3649f
      65             : #define thRatio2        2.0288f
      66             : #define thCorrCoef      0.8795f
      67             : #define ratioHiLoFacDec ( 1.5894f * 0.75f )
      68             : 
      69             : /*-------------------------------------------------------------------
      70             :  * calcLoBufferDec()
      71             :  *
      72             :  *
      73             :  *-------------------------------------------------------------------*/
      74             : 
      75        3750 : static void calcLoBufferDec(
      76             :     float **pCldfbReal,
      77             :     float **pCldfbImag,
      78             :     float *loBuffer,
      79             :     const int16_t startPos,
      80             :     const int16_t stopPos,
      81             :     const int16_t bandOffsetBottom,
      82             :     const float scaleOffset )
      83             : {
      84             :     int16_t slot, k, lb, li, ui;
      85             :     float nrg, tmp;
      86             : 
      87             :     /* calc loTempEnv */
      88       63750 :     for ( slot = startPos; slot < stopPos; slot++ )
      89             :     {
      90       60000 :         tmp = 0;
      91             : 
      92      240000 :         for ( lb = 0; lb < NbTecLowBand; lb++ )
      93             :         {
      94      180000 :             li = TecLowBandTable[lb];
      95      180000 :             ui = TecLowBandTable[lb + 1];
      96             : 
      97      180000 :             nrg = 0;
      98      540000 :             for ( k = li; k < ui; k++ )
      99             :             {
     100      360000 :                 nrg += pCldfbReal[slot][k + bandOffsetBottom] * pCldfbReal[slot][k + bandOffsetBottom] + pCldfbImag[slot][k + bandOffsetBottom] * pCldfbImag[slot][k + bandOffsetBottom];
     101             :             }
     102      180000 :             tmp += (float) log10( nrg * normReciprocal[ui - li] + EPS );
     103             :         }
     104             : 
     105       60000 :         loBuffer[slot] = 10.0f * tmp / NbTecLowBand + scaleOffset;
     106             :     }
     107             : 
     108        3750 :     return;
     109             : }
     110             : 
     111             : 
     112             : /*-------------------------------------------------------------------
     113             :  * calcLoBufferEnc()
     114             :  *
     115             :  *
     116             :  *-------------------------------------------------------------------*/
     117             : 
     118        3100 : static void calcLoBufferEnc(
     119             :     float **pCldfbPow,
     120             :     const int16_t startPos,
     121             :     const int16_t stopPos,
     122             :     const int16_t bandOffsetBottom,
     123             :     const float scaleOffset,
     124             :     float *loBuffer )
     125             : {
     126             :     int16_t slot, k, lb, li, ui;
     127             :     float nrg, tmp;
     128             : 
     129             :     /* calc loTempEnv */
     130       52700 :     for ( slot = startPos; slot < stopPos; slot++ )
     131             :     {
     132       49600 :         tmp = 0;
     133             : 
     134      198400 :         for ( lb = 0; lb < NbTecLowBand; lb++ )
     135             :         {
     136      148800 :             li = TecLowBandTable[lb];
     137      148800 :             ui = TecLowBandTable[lb + 1];
     138             : 
     139      148800 :             nrg = 0;
     140      446400 :             for ( k = li; k < ui; k++ )
     141             :             {
     142      297600 :                 nrg += pCldfbPow[slot][k + bandOffsetBottom];
     143             :             }
     144      148800 :             tmp += (float) log10( nrg * normReciprocal[ui - li] + EPS );
     145             :         }
     146             : 
     147       49600 :         loBuffer[slot] = 10.0f * tmp / NbTecLowBand + scaleOffset;
     148             :     }
     149             : 
     150        3100 :     return;
     151             : }
     152             : 
     153             : 
     154             : /*-------------------------------------------------------------------
     155             :  * calcLoTempEnv()
     156             :  *
     157             :  *
     158             :  *-------------------------------------------------------------------*/
     159             : 
     160        3100 : static void calcLoTempEnv(
     161             :     const float *loBuffer,
     162             :     const int16_t noCols,
     163             :     float *loTempEnv,
     164             :     const float adjFac )
     165             : {
     166             :     int16_t slot, i;
     167             : 
     168       52700 :     for ( slot = 0; slot < noCols; slot++ )
     169             :     {
     170       49600 :         loTempEnv[slot] = TecSC[0] * loBuffer[slot];
     171      297600 :         for ( i = 1; i < TecSmoothingDeg + 1; i++ )
     172             :         {
     173      248000 :             loTempEnv[slot] += TecSC[i] * loBuffer[slot - i];
     174             :         }
     175             : 
     176       49600 :         loTempEnv[slot] *= adjFac;
     177             :     }
     178             : 
     179        3100 :     return;
     180             : }
     181             : 
     182             : /*-------------------------------------------------------------------
     183             :  * calcHiTempEnv()
     184             :  *
     185             :  *
     186             :  *-------------------------------------------------------------------*/
     187             : 
     188        3100 : static void calcHiTempEnv(
     189             :     float **pCldfbPow,
     190             :     const int16_t startPos,
     191             :     const int16_t stopPos,
     192             :     const int16_t lowSubband,
     193             :     const int16_t highSubband,
     194             :     const float scaleOffset,
     195             :     float *hiTempEnv )
     196             : {
     197             :     int16_t timeIndex, k;
     198        3100 :     int16_t bwHigh = highSubband - lowSubband;
     199             : 
     200             :     /* set hiTempEnv */
     201       52700 :     for ( timeIndex = startPos; timeIndex < stopPos; timeIndex++ )
     202             :     {
     203       49600 :         hiTempEnv[timeIndex] = 0;
     204     1041600 :         for ( k = lowSubband; k < highSubband; k++ )
     205             :         {
     206      992000 :             hiTempEnv[timeIndex] += pCldfbPow[timeIndex][k];
     207             :         }
     208       49600 :         hiTempEnv[timeIndex] = (float) ( 10 * log10( hiTempEnv[timeIndex] / bwHigh + EPS ) + scaleOffset );
     209             :     }
     210             : 
     211        3100 :     return;
     212             : }
     213             : 
     214             : 
     215             : /*-------------------------------------------------------------------
     216             :  * calcVar()
     217             :  *
     218             :  *
     219             :  *-------------------------------------------------------------------*/
     220             : 
     221        9185 : static float calcVar(
     222             :     const float in[],
     223             :     const int16_t len,
     224             :     float *x )
     225             : {
     226             :     float xx;
     227             :     int16_t i;
     228             : 
     229        9185 :     xx = 0;
     230        9185 :     *x = 0;
     231             : 
     232      156145 :     for ( i = 0; i < len; i++ )
     233             :     {
     234      146960 :         xx += in[i] * in[i];
     235      146960 :         *x += in[i];
     236             :     }
     237             : 
     238        9185 :     return ( xx - ( *x * *x ) / (float) len );
     239             : }
     240             : 
     241             : 
     242             : /*-------------------------------------------------------------------
     243             :  * calcCorrelationCoefficient2()
     244             :  *
     245             :  *
     246             :  *-------------------------------------------------------------------*/
     247             : 
     248        2985 : static float calcCorrelationCoefficient2(
     249             :     const float in_vec1[],
     250             :     const float in_vec2[],
     251             :     const int16_t len,
     252             :     float var_x,
     253             :     float var_y,
     254             :     float x,
     255             :     float y )
     256             : {
     257             :     int16_t i;
     258             :     float xy;
     259             :     float ans;
     260             : 
     261        2985 :     xy = 0;
     262             : 
     263       50745 :     for ( i = 0; i < len; i++ )
     264             :     {
     265       47760 :         xy += ( in_vec1[i] * in_vec2[i] );
     266             :     }
     267             : 
     268        2985 :     ans = ( xy - x * y / (float) ( len ) ) / (float) sqrt( var_x * var_y + EPS );
     269             : 
     270        2985 :     return ans;
     271             : }
     272             : 
     273             : 
     274             : /*-------------------------------------------------------------------
     275             :  * resetTecDec()
     276             :  *
     277             :  *
     278             :  *-------------------------------------------------------------------*/
     279             : 
     280         123 : void resetTecDec(
     281             :     TEC_DEC_HANDLE hTecDec )
     282             : {
     283         123 :     set_f( hTecDec->pGainTemp, 0, CLDFB_NO_COL_MAX );
     284             : 
     285         123 :     set_f( hTecDec->loBuffer, 0.f, CLDFB_NO_COL_MAX + MAX_TEC_SMOOTHING_DEG );
     286             : 
     287         123 :     return;
     288             : }
     289             : 
     290             : 
     291             : /*-------------------------------------------------------------------
     292             :  * calcLoTempEnv_TBE()
     293             :  *
     294             :  *
     295             :  *-------------------------------------------------------------------*/
     296             : 
     297          15 : static void calcLoTempEnv_TBE(
     298             :     const float *loBuffer,
     299             :     const int16_t noCols,
     300             :     float *loTempEnv,
     301             :     const float adjFac )
     302             : {
     303             :     int16_t slot, i;
     304          15 :     int16_t delay = 1;
     305             : 
     306         255 :     for ( slot = 0; slot < noCols; slot++ )
     307             :     {
     308         240 :         loTempEnv[slot] = TecSC[0] * loBuffer[slot - delay];
     309             : 
     310        1440 :         for ( i = 1; i < TecSmoothingDeg + 1; i++ )
     311             :         {
     312        1200 :             loTempEnv[slot] += TecSC[i] * loBuffer[slot - delay - i];
     313             :         }
     314             : 
     315         240 :         loTempEnv[slot] *= adjFac;
     316             :     }
     317             : 
     318          15 :     return;
     319             : }
     320             : 
     321             : 
     322             : /*-------------------------------------------------------------------
     323             :  * set_TEC_TFA_code()
     324             :  *
     325             :  *
     326             :  *-------------------------------------------------------------------*/
     327             : 
     328         604 : void set_TEC_TFA_code(
     329             :     const int16_t corrFlag,
     330             :     int16_t *tec_flag,
     331             :     int16_t *tfa_flag )
     332             : {
     333         604 :     *tec_flag = 0;
     334         604 :     if ( *tfa_flag == 0 )
     335             :     {
     336         545 :         if ( corrFlag == 1 )
     337             :         {
     338           5 :             *tec_flag = 1;
     339             :         }
     340         540 :         else if ( corrFlag == 2 )
     341             :         {
     342           4 :             *tec_flag = 1;
     343           4 :             *tfa_flag = 1;
     344             :         }
     345             :     }
     346             : 
     347         604 :     return;
     348             : }
     349             : 
     350             : 
     351             : /*-------------------------------------------------------------------
     352             :  * calcLoTempEnv_ns_TBE()
     353             :  *
     354             :  *
     355             :  *-------------------------------------------------------------------*/
     356             : 
     357          12 : static void calcLoTempEnv_ns_TBE(
     358             :     const float *loBuffer,
     359             :     const int16_t noCols,
     360             :     float *loTempEnv )
     361             : {
     362             :     int16_t slot;
     363          12 :     int16_t delay = 1;
     364          12 :     float fac = 1.4f;
     365             : 
     366         204 :     for ( slot = 0; slot < noCols; slot++ )
     367             :     {
     368         192 :         loTempEnv[slot] = fac * loBuffer[slot - delay];
     369             :     }
     370             : 
     371          12 :     return;
     372             : }
     373             : 
     374             : 
     375             : /*-------------------------------------------------------------------
     376             :  * calcLoTempEnv_ns()
     377             :  *
     378             :  *
     379             :  *-------------------------------------------------------------------*/
     380             : 
     381        3100 : static void calcLoTempEnv_ns(
     382             :     const float *loBuffer,
     383             :     const int16_t noCols,
     384             :     float *loTempEnv )
     385             : {
     386             :     int16_t slot;
     387             : 
     388       52700 :     for ( slot = 0; slot < noCols; slot++ )
     389             :     {
     390       49600 :         loTempEnv[slot] = loBuffer[slot];
     391             :     }
     392             : 
     393        3100 :     return;
     394             : }
     395             : 
     396             : /*-------------------------------------------------------------------
     397             :  * calcGainLinear_TBE()
     398             :  *
     399             :  *
     400             :  *-------------------------------------------------------------------*/
     401             : 
     402          27 : static void calcGainLinear_TBE(
     403             :     const float *loTempEnv,
     404             :     const int16_t startPos,
     405             :     const int16_t stopPos,
     406             :     float *pGainTemp )
     407             : {
     408             :     int16_t timeIndex;
     409             :     float ftmp;
     410             : 
     411         459 :     for ( timeIndex = startPos; timeIndex < stopPos; timeIndex++ )
     412             :     {
     413         432 :         ftmp = loTempEnv[timeIndex];
     414         432 :         pGainTemp[timeIndex] = (float) pow( 10.0, 0.1 * ftmp );
     415             :     }
     416             : 
     417          27 :     return;
     418             : }
     419             : 
     420             : 
     421             : /*-------------------------------------------------------------------
     422             :  * calcGainTemp_TBE()
     423             :  *
     424             :  *
     425             :  *-------------------------------------------------------------------*/
     426             : 
     427        3750 : void calcGainTemp_TBE(
     428             :     float **pCldfbRealSrc,
     429             :     float **pCldfbImagSrc,
     430             :     float *loBuffer,
     431             :     const int16_t startPos,   /*!<  Start position of the current envelope. */
     432             :     const int16_t stopPos,    /*!<  Stop position of the current envelope. */
     433             :     const int16_t lowSubband, /* lowSubband */
     434             :     float *pGainTemp,
     435             :     const int16_t code )
     436             : {
     437             :     float loTempEnv[16];
     438        3750 :     const int16_t BW_LO = TecLowBandTable[NbTecLowBand];
     439             :     int16_t slot;
     440        3750 :     int16_t noCols = stopPos - startPos;
     441        3750 :     int16_t bandOffset = 0;
     442        3750 :     float scaleOffset = 0;
     443             : 
     444        3750 :     assert( lowSubband >= BW_LO );
     445             : 
     446        3750 :     bandOffset = lowSubband - BW_LO;
     447             : 
     448        3750 :     calcLoBufferDec( pCldfbRealSrc, pCldfbImagSrc, loBuffer + MAX_TEC_SMOOTHING_DEG, startPos, stopPos, bandOffset, scaleOffset );
     449             : 
     450        3750 :     if ( code > 0 )
     451             :     {
     452          27 :         if ( code != 2 )
     453             :         {
     454          15 :             calcLoTempEnv_TBE( loBuffer + MAX_TEC_SMOOTHING_DEG, noCols, loTempEnv, ratioHiLoFacDec );
     455             :         }
     456             :         else
     457             :         {
     458          12 :             calcLoTempEnv_ns_TBE( loBuffer + MAX_TEC_SMOOTHING_DEG, noCols, loTempEnv );
     459             :         }
     460             : 
     461          27 :         calcGainLinear_TBE( loTempEnv, startPos, stopPos, pGainTemp );
     462             :     }
     463             : 
     464             : 
     465       26250 :     for ( slot = 0; slot < MAX_TEC_SMOOTHING_DEG; slot++ )
     466             :     {
     467       22500 :         loBuffer[slot] = loBuffer[slot + stopPos];
     468             :     }
     469             : 
     470        3750 :     return;
     471             : }
     472             : 
     473             : 
     474             : /*-------------------------------------------------------------------
     475             :  * setSubfrConfig()
     476             :  *
     477             :  *
     478             :  *-------------------------------------------------------------------*/
     479             : 
     480         204 : static void setSubfrConfig(
     481             :     const int16_t i_offset,
     482             :     int16_t *k_offset,
     483             :     int16_t *n_subfr,
     484             :     const int16_t l_subfr )
     485             : {
     486         204 :     *n_subfr = N_TEC_TFA_SUBFR - i_offset;
     487         204 :     *k_offset = i_offset * l_subfr;
     488             : 
     489         204 :     return;
     490             : }
     491             : 
     492             : 
     493             : /*-------------------------------------------------------------------
     494             :  * calcSubfrNrg()
     495             :  *
     496             :  *
     497             :  *-------------------------------------------------------------------*/
     498             : 
     499         204 : static float calcSubfrNrg(
     500             :     const float *hb_synth,
     501             :     const int16_t i_offset,
     502             :     float *enr,
     503             :     const int16_t k_offset,
     504             :     const int16_t l_subfr )
     505             : {
     506             :     int16_t i, j, k;
     507         204 :     float enr_all = 1e-12f;
     508             : 
     509        3468 :     for ( i = i_offset, k = k_offset; i < N_TEC_TFA_SUBFR; i++ )
     510             :     {
     511        3264 :         enr[i] = 1e-12f;
     512      199104 :         for ( j = 0; j < l_subfr; j++ )
     513             :         {
     514      195840 :             enr[i] += hb_synth[k] * hb_synth[k];
     515      195840 :             k++;
     516             :         }
     517        3264 :         enr_all += enr[i];
     518             :     }
     519             : 
     520         204 :     return enr_all;
     521             : }
     522             : 
     523             : 
     524             : /*-------------------------------------------------------------------
     525             :  * procTfa()
     526             :  *
     527             :  *
     528             :  *-------------------------------------------------------------------*/
     529             : 
     530         177 : static void procTfa(
     531             :     float *hb_synth,
     532             :     const int16_t i_offset,
     533             :     const int16_t l_subfr )
     534             : {
     535             :     int16_t i, j, k;
     536             :     int16_t k_offset, n_subfr;
     537             :     float enr[N_TEC_TFA_SUBFR], enr_ave;
     538             : 
     539         177 :     setSubfrConfig( i_offset, &k_offset, &n_subfr, l_subfr );
     540             : 
     541         177 :     enr_ave = calcSubfrNrg( hb_synth, i_offset, enr, k_offset, l_subfr ) / n_subfr;
     542             : 
     543        3009 :     for ( i = i_offset, k = k_offset; i < N_TEC_TFA_SUBFR; i++ )
     544             :     {
     545             :         float gain;
     546             : 
     547        2832 :         gain = (float) sqrt( enr_ave / enr[i] );
     548             : 
     549      172752 :         for ( j = 0; j < l_subfr; j++ )
     550             :         {
     551      169920 :             hb_synth[k] *= gain;
     552      169920 :             k++;
     553             :         }
     554             :     }
     555             : 
     556         177 :     return;
     557             : }
     558             : 
     559             : 
     560             : /*-------------------------------------------------------------------
     561             :  * procTec()
     562             :  *
     563             :  *
     564             :  *-------------------------------------------------------------------*/
     565             : 
     566          27 : static void procTec(
     567             :     float *hb_synth,
     568             :     const int16_t i_offset,
     569             :     const int16_t l_subfr,
     570             :     float *gain,
     571             :     const int16_t code )
     572             : {
     573             :     int16_t i, j, k;
     574             :     int16_t k_offset, n_subfr;
     575             :     float enr[N_TEC_TFA_SUBFR], enr_ave, gain_ave;
     576             :     float inv_curr_enr[N_TEC_TFA_SUBFR];
     577             :     float max_inv_curr_enr, lower_limit_gain;
     578             :     float upper_limit_gain;
     579             :     float tmp;
     580             : 
     581          27 :     setSubfrConfig( i_offset, &k_offset, &n_subfr, l_subfr );
     582             : 
     583          27 :     enr_ave = calcSubfrNrg( hb_synth, i_offset, enr, k_offset, l_subfr ) / n_subfr;
     584             : 
     585          27 :     gain_ave = ( sum_f( &gain[i_offset], n_subfr ) + 1.0e-12f ) / n_subfr;
     586             : 
     587          27 :     max_inv_curr_enr = 10e-6f;
     588         459 :     for ( i = i_offset, k = k_offset; i < N_TEC_TFA_SUBFR; i++ )
     589             :     {
     590         432 :         inv_curr_enr[i] = enr_ave / enr[i];
     591         432 :         gain[i] /= gain_ave;
     592         432 :         if ( max_inv_curr_enr < inv_curr_enr[i] )
     593             :         {
     594         120 :             max_inv_curr_enr = inv_curr_enr[i];
     595             :         }
     596             :     }
     597             : 
     598          27 :     lower_limit_gain = 0.1f;
     599          27 :     if ( lower_limit_gain > ( tmp = 1.f / max_inv_curr_enr ) )
     600             :     {
     601          24 :         lower_limit_gain = tmp * 0.5f;
     602             :     }
     603             : 
     604          27 :     upper_limit_gain = 1.2f;
     605          27 :     if ( code == LOBUF_NO_SMOOTHING_MODE )
     606             :     {
     607          12 :         upper_limit_gain = 3.0;
     608             :     }
     609             : 
     610         459 :     for ( i = i_offset, k = k_offset; i < N_TEC_TFA_SUBFR; i++ )
     611             :     {
     612         432 :         if ( lower_limit_gain > gain[i] )
     613             :         {
     614          15 :             gain[i] = lower_limit_gain;
     615             :         }
     616         432 :         gain[i] *= inv_curr_enr[i];
     617             : 
     618         432 :         if ( gain[i] > upper_limit_gain )
     619             :         {
     620         138 :             gain[i] = upper_limit_gain;
     621             :         }
     622             : 
     623         432 :         gain[i] = (float) sqrt( gain[i] );
     624       26352 :         for ( j = 0; j < l_subfr; j++ )
     625             :         {
     626       25920 :             hb_synth[k] *= gain[i];
     627       25920 :             k++;
     628             :         }
     629             :     }
     630             : 
     631          27 :     return;
     632             : }
     633             : 
     634             : 
     635             : /*-------------------------------------------------------------------
     636             :  * procTecTfa_TBE()
     637             :  *
     638             :  *
     639             :  *-------------------------------------------------------------------*/
     640             : 
     641         204 : void procTecTfa_TBE(
     642             :     float *hb_synth,
     643             :     float *gain,
     644             :     const int16_t flat_flag,
     645             :     const int16_t last_core,
     646             :     const int16_t l_subfr,
     647             :     const int16_t code )
     648             : {
     649         204 :     int16_t i_offset = 0;
     650             : 
     651         204 :     if ( flat_flag )
     652             :     {
     653         177 :         procTfa( hb_synth, i_offset, l_subfr );
     654             :     }
     655             :     else
     656             :     {
     657          27 :         if ( last_core != ACELP_CORE )
     658             :         {
     659           0 :             i_offset = 1;
     660             :         }
     661             : 
     662          27 :         procTec( hb_synth, i_offset, l_subfr, gain, code );
     663             :     }
     664             : 
     665         204 :     return;
     666             : }
     667             : 
     668             : 
     669             : /*-------------------------------------------------------------------
     670             :  * resetTecEnc()
     671             :  *
     672             :  *
     673             :  *-------------------------------------------------------------------*/
     674             : 
     675         101 : void resetTecEnc(
     676             :     TEC_ENC_HANDLE hTecEnc,
     677             :     const int16_t flag )
     678             : {
     679         101 :     if ( flag == 0 )
     680             :     {
     681          27 :         set_f( hTecEnc->loBuffer, 0.f, CLDFB_NO_COL_MAX + MAX_TEC_SMOOTHING_DEG + DELAY_TEMP_ENV_BUFF_TEC );
     682          27 :         set_f( hTecEnc->hiTempEnv, 0.f, CLDFB_NO_COL_MAX + DELAY_TEMP_ENV_BUFF_TEC + EXT_DELAY_HI_TEMP_ENV );
     683          27 :         set_f( hTecEnc->loTempEnv, 0.f, CLDFB_NO_COL_MAX );
     684          27 :         set_f( hTecEnc->loTempEnv_ns, 0.f, CLDFB_NO_COL_MAX );
     685             :     }
     686             :     else
     687             :     {
     688          74 :         set_f( hTecEnc->loBuffer, 0.f, MAX_TEC_SMOOTHING_DEG );
     689             :     }
     690             : 
     691         101 :     return;
     692             : }
     693             : 
     694             : 
     695             : /*-------------------------------------------------------------------
     696             :  * calcHiEnvLoBuff()
     697             :  *
     698             :  *
     699             :  *-------------------------------------------------------------------*/
     700             : 
     701        3100 : void calcHiEnvLoBuff(
     702             :     const int16_t noCols,
     703             :     const int16_t *pFreqBandTable, /*!<  freqbandTable. */
     704             :     const int16_t nSfb,            /*!<  Number of scalefactors. */
     705             :     float **pCldfbPow,
     706             :     float *loBuffer,
     707             :     float *hiTempEnvOrig )
     708             : {
     709        3100 :     const int16_t BW_LO = TecLowBandTable[NbTecLowBand];
     710        3100 :     const int16_t lowSubband = pFreqBandTable[0];
     711        3100 :     const int16_t highSubband = pFreqBandTable[nSfb];
     712             : 
     713        3100 :     int16_t bandOffsetBottom = lowSubband - BW_LO;
     714             : 
     715        3100 :     float scaleOffset = 0;
     716        3100 :     float *hiTempEnv = hiTempEnvOrig + EXT_DELAY_HI_TEMP_ENV;
     717             : 
     718        3100 :     assert( bandOffsetBottom > 0 );
     719             : 
     720             :     /* calc hiTempEnv*/
     721        3100 :     calcHiTempEnv( pCldfbPow, 0, noCols, lowSubband, highSubband, scaleOffset, hiTempEnv + DELAY_TEMP_ENV_BUFF_TEC );
     722             : 
     723             :     /* calc loBuffer */
     724        3100 :     calcLoBufferEnc( pCldfbPow, 0, noCols, bandOffsetBottom, scaleOffset, loBuffer + MAX_TEC_SMOOTHING_DEG + DELAY_TEMP_ENV_BUFF_TEC );
     725             : 
     726        3100 :     return;
     727             : }
     728             : 
     729             : 
     730             : /*-------------------------------------------------------------------
     731             :  * calcLoEnvCheckCorrHiLo()
     732             :  *
     733             :  *
     734             :  *-------------------------------------------------------------------*/
     735             : 
     736        3100 : void calcLoEnvCheckCorrHiLo(
     737             :     const int16_t noCols,
     738             :     const int16_t *pFreqBandTable, /*!<  freqbandTable. */
     739             :     float *loBuffer,
     740             :     float *loTempEnv,
     741             :     float *loTempEnv_ns,
     742             :     float *hiTempEnvOrig,
     743             :     int16_t *corrFlag )
     744             : {
     745        3100 :     const int16_t BW_LO = TecLowBandTable[NbTecLowBand];
     746        3100 :     const int16_t lowSubband = pFreqBandTable[0];
     747             :     int16_t i;
     748             :     float corrCoef;
     749        3100 :     int16_t bandOffsetBottom = lowSubband - BW_LO;
     750             :     float ratio;
     751             :     float hiVar, loVar;
     752             :     float hiSum, loSum;
     753        3100 :     int16_t code = 0; /* SET TENTATIVELY */
     754             :     float loVar_ns;
     755             :     float loSum_ns;
     756             :     float diff_hi_lo_sum;
     757             : 
     758        3100 :     float *hiTempEnv = hiTempEnvOrig + EXT_DELAY_HI_TEMP_ENV;
     759             : 
     760        3100 :     assert( bandOffsetBottom > 0 );
     761             : 
     762        3100 :     hiVar = calcVar( hiTempEnv, noCols, &hiSum );
     763             : 
     764             :     /* calc loTempEnv */
     765        3100 :     calcLoTempEnv( loBuffer + MAX_TEC_SMOOTHING_DEG, noCols, loTempEnv, ratioHiLoFac );
     766             : 
     767        3100 :     calcLoTempEnv_ns( loBuffer + MAX_TEC_SMOOTHING_DEG, noCols, loTempEnv_ns );
     768             : 
     769        3100 :     loVar_ns = calcVar( loTempEnv_ns, noCols, &loSum_ns );
     770        3100 :     diff_hi_lo_sum = loSum_ns - hiSum;
     771             : 
     772        3100 :     if ( hiVar > 800 && loVar_ns > 720 && diff_hi_lo_sum < 100 )
     773             :     {
     774         115 :         code = 1;
     775             :     }
     776             : 
     777        3100 :     *corrFlag = 0;
     778             : 
     779        3100 :     assert( code == 0 || code == 1 );
     780             : 
     781        3100 :     if ( code )
     782             :     {
     783             :         /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
     784             :         /* ++++                     code == 1                      +++++*/
     785             :         /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
     786             :         int16_t maxPosHi, maxPosLo;
     787             :         float maxHi, maxLo;
     788             : 
     789         115 :         maxHi = hiTempEnv[0];
     790         115 :         maxLo = loTempEnv_ns[0];
     791         115 :         maxPosHi = maxPosLo = 0;
     792             : 
     793        1840 :         for ( i = 1; i < noCols; i++ )
     794             :         {
     795        1725 :             if ( maxHi < hiTempEnv[i] )
     796             :             {
     797         463 :                 maxHi = hiTempEnv[i];
     798         463 :                 maxPosHi = i;
     799             :             }
     800             : 
     801        1725 :             if ( maxLo < loTempEnv_ns[i] )
     802             :             {
     803         478 :                 maxLo = loTempEnv_ns[i];
     804         478 :                 maxPosLo = i;
     805             :             }
     806             :         }
     807             : 
     808         115 :         if ( abs( maxPosHi - maxPosLo ) < 2 )
     809             :         {
     810          90 :             *corrFlag = 2;
     811             :         }
     812             : 
     813             :         {
     814         115 :             float feature_max = 0;
     815         115 :             int16_t pos_feature_max = 0;
     816             :             float feature[16];
     817             : 
     818             :             float min_local, max_local;
     819             :             int16_t j;
     820         115 :             int16_t len_window = EXT_DELAY_HI_TEMP_ENV + 1;
     821         115 :             float *curr_pos = hiTempEnv;
     822             : 
     823         115 :             feature_max = 0;
     824         115 :             pos_feature_max = 0;
     825             : 
     826        1955 :             for ( i = 0; i < 16; i++, curr_pos++ )
     827             :             {
     828        1840 :                 max_local = min_local = curr_pos[0];
     829             : 
     830        5520 :                 for ( j = 1; j < len_window; j++ )
     831             :                 {
     832        3680 :                     if ( max_local < curr_pos[-j] )
     833             :                     {
     834        1333 :                         max_local = curr_pos[-j];
     835             :                     }
     836             : 
     837        3680 :                     if ( min_local > curr_pos[-j] )
     838             :                     {
     839        1458 :                         min_local = curr_pos[-j];
     840             :                     }
     841             :                 }
     842             : 
     843        1840 :                 feature[i] = max_local - min_local;
     844             : 
     845        1840 :                 if ( feature_max < feature[i] )
     846             :                 {
     847         371 :                     feature_max = feature[i];
     848         371 :                     pos_feature_max = i;
     849             :                 }
     850             :             }
     851             : 
     852         115 :             if ( *corrFlag > 0 )
     853             :             {
     854          90 :                 if ( !( feature_max > 20 && abs( pos_feature_max - maxPosHi ) < 3 ) )
     855             :                 {
     856          44 :                     *corrFlag = 0;
     857             :                 }
     858             :             }
     859             :         }
     860             :     }
     861             :     else
     862             :     {
     863             :         /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
     864             :         /* ++++                     code == 0                       ++++*/
     865             :         /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
     866             : 
     867             :         /* calc the variance of loTempEnv */
     868        2985 :         loVar = calcVar( loTempEnv, noCols, &loSum );
     869             : 
     870             :         /* calc correlation coefficient between loTempEnv and hiTempEnv */
     871        2985 :         corrCoef = calcCorrelationCoefficient2( hiTempEnv, loTempEnv, noCols, hiVar, loVar, hiSum, loSum );
     872             : 
     873        2985 :         ratio = hiVar / ( loVar + EPS );
     874             : 
     875        2985 :         if ( corrCoef >= thCorrCoef && ratio > thRatio && ratio < thRatio2 )
     876             :         {
     877          99 :             *corrFlag = 1;
     878             :         }
     879             :     }
     880             : 
     881       49600 :     for ( i = 0; i < MAX_TEC_SMOOTHING_DEG + DELAY_TEMP_ENV_BUFF_TEC; i++ )
     882             :     {
     883       46500 :         loBuffer[i] = loBuffer[noCols + i];
     884             :     }
     885             : 
     886       37200 :     for ( i = 0; i < DELAY_TEMP_ENV_BUFF_TEC + EXT_DELAY_HI_TEMP_ENV; i++ )
     887             :     {
     888       34100 :         hiTempEnvOrig[i] = hiTempEnvOrig[noCols + i];
     889             :     }
     890             : 
     891        3100 :     return;
     892             : }
     893             : 
     894             : 
     895             : /*-------------------------------------------------------------------
     896             :  * tecEnc_TBE()
     897             :  *
     898             :  *
     899             :  *-------------------------------------------------------------------*/
     900             : 
     901         604 : void tecEnc_TBE(
     902             :     int16_t *corrFlag,
     903             :     const float *voicing,
     904             :     const int16_t coder_type )
     905             : {
     906             :     float voice_sum;
     907             :     float voice_diff;
     908             : 
     909             :     /*-----------------------------------------------------------------*
     910             :      * TEC updates
     911             :      *-----------------------------------------------------------------*/
     912             : 
     913         604 :     voice_sum = voicing[0] + voicing[1];
     914         604 :     voice_diff = voicing[0] - voicing[1];
     915             : 
     916         604 :     if ( voice_diff < 0 )
     917             :     {
     918         299 :         voice_diff *= -1.0f;
     919             :     }
     920             : 
     921         604 :     if ( *corrFlag == 1 )
     922             :     {
     923          26 :         if ( coder_type == INACTIVE || ( ( voice_sum > 0.35 * 2 && voice_sum < 0.55 * 2 ) && ( voice_diff < 0.2 ) ) )
     924             :         {
     925           2 :             *corrFlag = 0;
     926             :         }
     927             :     }
     928         604 :     if ( voice_sum > 0.6 * 2 )
     929             :     {
     930         507 :         *corrFlag = 0;
     931             :     }
     932             : 
     933         604 :     return;
     934             : }

Generated by: LCOV version 1.14