LCOV - code coverage report
Current view: top level - lib_enc - ari_hm_enc.c (source / functions) Hit Total Coverage
Test: Coverage on main -- short test vectors @ a21f94bc6bac334fe001a5bad2f7b32b79038097 Lines: 187 187 100.0 %
Date: 2025-11-01 05:53:46 Functions: 9 9 100.0 %

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : /*====================================================================================
      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 "cnst.h"
      42             : #include "rom_enc.h"
      43             : #include "stl.h"
      44             : #include "basop_util.h"
      45             : #include "prot.h"
      46             : #include "rom_com.h"
      47             : #include "wmc_auto.h"
      48             : 
      49             : /*-------------------------------------------------------------------*
      50             :  * EncodeIndex()
      51             :  *
      52             :  *
      53             :  *-------------------------------------------------------------------*/
      54             : 
      55       31792 : int16_t EncodeIndex(
      56             :     const int16_t Bandwidth,
      57             :     int16_t PeriodicityIndex,
      58             :     BSTR_ENC_HANDLE hBstr )
      59             : {
      60       31792 :     if ( PeriodicityIndex & kLtpHmFlag )
      61             :     {
      62       14883 :         int16_t LtpPitchIndex = PeriodicityIndex >> 9;
      63       14883 :         assert( 0 <= LtpPitchIndex && LtpPitchIndex <= 16 );
      64       14883 :         --PeriodicityIndex;
      65       14883 :         assert( ( PeriodicityIndex & 0xff ) < ( 1 << NumRatioBits[Bandwidth][LtpPitchIndex] ) );
      66             : 
      67       14883 :         push_next_indice( hBstr, PeriodicityIndex & 0xff, NumRatioBits[Bandwidth][LtpPitchIndex] );
      68       14883 :         return NumRatioBits[Bandwidth][LtpPitchIndex];
      69             :     }
      70             :     else
      71             :     {
      72       16909 :         push_next_indice( hBstr, PeriodicityIndex, 8 );
      73       16909 :         return 8;
      74             :     }
      75             : }
      76             : 
      77             : 
      78             : /*-------------------------------------------------------------------*
      79             :  * GetWeight()
      80             :  *
      81             :  *
      82             :  *-------------------------------------------------------------------*/
      83             : 
      84  1361769263 : static float GetWeight( int16_t i )
      85             : {
      86  1361769263 :     i = 3 * i - 2;
      87             : 
      88  1361769263 :     return (float) ( pow( i, 0.3 ) / pow( 256 - 1, 0.3 ) );
      89             : }
      90             : 
      91             : 
      92             : /*-------------------------------------------------------------------*
      93             :  * SearchPeriodicityIndex_Single()
      94             :  *
      95             :  *
      96             :  *-------------------------------------------------------------------*/
      97             : 
      98    33846183 : static float SearchPeriodicityIndex_Single(
      99             :     const float AbsMdct3[],
     100             :     const int16_t NumToConsider,
     101             :     const int32_t Lag,
     102             :     const int16_t FractionalResolution )
     103             : {
     104             :     int16_t HighestMultiplier;
     105             :     float AbsMeanCurrent3; /* Mean for BucketWidth == 3 */
     106             :     int32_t Limit, OldIndex, i;
     107             : 
     108    33846183 :     Limit = ( NumToConsider - 1 ) << FractionalResolution;
     109    33846183 :     AbsMeanCurrent3 = 0;
     110    33846183 :     HighestMultiplier = 1;
     111             : 
     112  1395615446 :     for ( i = Lag; i < Limit; i += Lag )
     113             :     {
     114  1361769263 :         OldIndex = i >> FractionalResolution;
     115  1361769263 :         AbsMeanCurrent3 += AbsMdct3[OldIndex] * GetWeight( HighestMultiplier );
     116  1361769263 :         ++HighestMultiplier;
     117             :     }
     118             : 
     119    33846183 :     return AbsMeanCurrent3 / ( HighestMultiplier - 1 + 0.00001f );
     120             : }
     121             : 
     122             : 
     123             : /*-------------------------------------------------------------------*
     124             :  * SearchPeriodicityIndex_Range()
     125             :  *
     126             :  *
     127             :  *-------------------------------------------------------------------*/
     128             : 
     129     1422756 : static void SearchPeriodicityIndex_Range(
     130             :     const float AbsMdct3[],
     131             :     const int16_t NumToConsider,
     132             :     const int16_t Lo,
     133             :     const int16_t Hi,
     134             :     const int16_t FractionalResolution,
     135             :     const int16_t Adj,
     136             :     const int16_t Spacing,
     137             :     int16_t *PeriodicityIndex,
     138             :     float *Score )
     139             : {
     140             :     int16_t Index, BestIndex, B;
     141             :     float CurrentScore, BestScore;
     142             : 
     143     1422756 :     BestScore = -1e30f;
     144     1422756 :     BestIndex = 0;
     145             : 
     146    30048432 :     for ( Index = Lo; Index < Hi; Index += Spacing )
     147             :     {
     148    28625676 :         CurrentScore = SearchPeriodicityIndex_Single( AbsMdct3, NumToConsider, Index + Adj, FractionalResolution );
     149             : 
     150    28625676 :         if ( CurrentScore > BestScore )
     151             :         {
     152     4573292 :             BestScore = CurrentScore;
     153     4573292 :             BestIndex = Index;
     154             :         }
     155             :     }
     156             : 
     157     1422756 :     if ( BestScore > *Score )
     158             :     {
     159      395189 :         *Score = BestScore;
     160      395189 :         *PeriodicityIndex = BestIndex;
     161             :     }
     162             : 
     163             : 
     164     1422756 :     B = BestIndex - ( Spacing >> 1 );
     165     1422756 :     B = max( Lo, B );
     166             : 
     167     2689706 :     for ( Index = B; Index < BestIndex; ++Index )
     168             :     {
     169     1266950 :         CurrentScore = SearchPeriodicityIndex_Single( AbsMdct3, NumToConsider, Index + Adj, FractionalResolution );
     170             : 
     171     1266950 :         if ( CurrentScore > *Score )
     172             :         {
     173       83422 :             *Score = CurrentScore;
     174       83422 :             *PeriodicityIndex = Index;
     175             :         }
     176             :     }
     177             : 
     178     1422756 :     B = BestIndex + ( Spacing >> 1 );
     179             : 
     180     3140478 :     for ( Index = BestIndex + 1; Index <= B; ++Index )
     181             :     {
     182     1717722 :         CurrentScore = SearchPeriodicityIndex_Single( AbsMdct3, NumToConsider, Index + Adj, FractionalResolution );
     183             : 
     184     1717722 :         if ( CurrentScore > *Score )
     185             :         {
     186      195507 :             *Score = CurrentScore;
     187      195507 :             *PeriodicityIndex = Index;
     188             :         }
     189             :     }
     190             : 
     191     1422756 :     return;
     192             : }
     193             : 
     194             : 
     195             : /*-------------------------------------------------------------------*
     196             :  * SearchPeriodicityIndex()
     197             :  *
     198             :  *
     199             :  *-------------------------------------------------------------------*/
     200             : 
     201             : /*! r: PeriodicityIndex */
     202      375928 : int16_t SearchPeriodicityIndex(
     203             :     const float Mdct[],           /* i  : Coefficients, Mdct[0..NumCoeffs-1]                      */
     204             :     const float UnfilteredMdct[], /* i  : Unfiltered coefficients, UnfilteredMdct[0..NumCoeffs-1] */
     205             :     const int16_t NumCoeffs,      /* i  : Number of coefficients                                  */
     206             :     const int16_t TargetBits,     /* i  : Target bit budget (excl. Done flag)                     */
     207             :     const int16_t LtpPitchLag,    /* i  : TCX-LTP pitch                                           */
     208             :     const float LtpGain,          /* i  : LTP gain                                                */
     209             :     float *RelativeScore          /* o  : Energy concentration factor                             */
     210             : )
     211             : {
     212      375928 :     float AbsMdct3[MAX_LENGTH], A, B, C = 0.f;
     213             :     int16_t i;
     214             :     int16_t MaxAt;
     215             :     float Score;
     216             :     int16_t PeriodicityIndex;
     217             :     int16_t NumToConsider;
     218             :     float AbsTotal;
     219             : 
     220      375928 :     PeriodicityIndex = 0;
     221      375928 :     NumToConsider = NumCoeffs;
     222      375928 :     Score = -1e30f;
     223             : 
     224      375928 :     A = (float) fabs( Mdct[0] );
     225      375928 :     B = (float) fabs( Mdct[1] );
     226             : 
     227    99358879 :     for ( i = 1; i < NumToConsider - 3; i += 3 )
     228             :     {
     229    98982951 :         C = (float) fabs( Mdct[i + 1] );
     230    98982951 :         AbsMdct3[i] = A + B + C;
     231             : 
     232    98982951 :         A = (float) fabs( Mdct[i + 2] );
     233    98982951 :         AbsMdct3[i + 1] = A + B + C;
     234             : 
     235    98982951 :         B = (float) fabs( Mdct[i + 3] );
     236    98982951 :         AbsMdct3[i + 2] = A + B + C;
     237             :     }
     238             : 
     239      375928 :     if ( i < NumToConsider - 1 )
     240             :     {
     241      346682 :         C = (float) fabs( Mdct[i + 1] );
     242      346682 :         AbsMdct3[i] = A + B + C;
     243             :     }
     244             : 
     245             : 
     246      375928 :     if ( i + 1 < NumToConsider - 1 )
     247             :     {
     248      132129 :         A = (float) fabs( Mdct[i + 2] );
     249      132129 :         AbsMdct3[i + 1] = A + B + C;
     250             :     }
     251             : 
     252      375928 :     AbsTotal = 0.0f;
     253             : 
     254      375928 :     if ( UnfilteredMdct != NULL )
     255             :     {
     256    17616172 :         for ( i = 0; i < NumToConsider; ++i )
     257             :         {
     258    17587520 :             AbsTotal += (float) fabs( UnfilteredMdct[i] );
     259             :         }
     260             :     }
     261             :     else
     262             :     {
     263    93824707 :         for ( i = 1; i < NumToConsider - 1; i += 3 )
     264             :         {
     265    93477431 :             AbsTotal += AbsMdct3[i];
     266             :         }
     267             :     }
     268             : 
     269             : 
     270      375928 :     if ( ( LtpPitchLag > 0 ) && ( LtpGain > kLtpHmGainThr ) )
     271       89641 :     {
     272       89641 :         int16_t FractionalResolution = kLtpHmFractionalResolution;
     273             :         int16_t Multiplier, LtpPitchIndex, Bandwidth;
     274             : 
     275       89641 :         Bandwidth = NumCoeffs >= 256;
     276       89641 :         LtpPitchIndex = ( ( LtpPitchLag + ( 1 << ( kLtpHmFractionalResolution - 1 ) ) ) >> kLtpHmFractionalResolution ) - 2;
     277       89641 :         assert( 0 <= LtpPitchIndex && LtpPitchIndex <= 16 );
     278             : 
     279     2339233 :         for ( Multiplier = 1; Multiplier <= ( 1 << NumRatioBits[Bandwidth][LtpPitchIndex] ); ++Multiplier )
     280             :         {
     281             :             float CurrentScore;
     282             :             int32_t Lag;
     283             : 
     284     2249592 :             Lag = ( LtpPitchLag * (int16_t) ( 4 * Ratios[Bandwidth][LtpPitchIndex][Multiplier - 1] ) ) >> 2;
     285             : 
     286     2249592 :             if ( Lag >= ( 4 << FractionalResolution ) && ( Lag <= ( ( NumToConsider - 2 ) << FractionalResolution ) ) )
     287             :             {
     288     2235835 :                 CurrentScore = SearchPeriodicityIndex_Single( AbsMdct3, NumToConsider, Lag, FractionalResolution );
     289             : 
     290     2235835 :                 if ( CurrentScore > Score )
     291             :                 {
     292      133825 :                     Score = CurrentScore;
     293      133825 :                     PeriodicityIndex = Multiplier | kLtpHmFlag;
     294             :                 }
     295             :             }
     296             :         }
     297       89641 :         PeriodicityIndex |= LtpPitchIndex << 9;
     298             :     }
     299             :     else
     300             :     {
     301      286287 :         if ( UnfilteredMdct != NULL )
     302             :         {
     303       19615 :             MaxAt = 1;
     304       19615 :             A = AbsMdct3[1];
     305             : 
     306     4049436 :             for ( i = 4; i < NumToConsider - 1; i += 3 )
     307             :             {
     308             : 
     309     4029821 :                 if ( AbsMdct3[i] > AbsMdct3[MaxAt] )
     310             :                 {
     311       35707 :                     MaxAt = i;
     312             :                 }
     313     4029821 :                 A += AbsMdct3[i];
     314             :             }
     315             : 
     316       19615 :             if ( AbsMdct3[MaxAt] > A * 0.7f )
     317             :             {
     318          63 :                 NumToConsider = min( NumToConsider, MaxAt + 4 );
     319             :             }
     320             :         }
     321             : 
     322      286287 :         SearchPeriodicityIndex_Range( AbsMdct3, NumToConsider, 0, 16, 3, GET_ADJ2( 0, 6, 3 ), 4, &PeriodicityIndex, &Score );
     323             : 
     324      286287 :         SearchPeriodicityIndex_Range( AbsMdct3, NumToConsider, 16, 80, 4, GET_ADJ2( 16, 8, 4 ), 4, &PeriodicityIndex, &Score );
     325             : 
     326      286287 :         SearchPeriodicityIndex_Range( AbsMdct3, NumToConsider, 80, 208, 3, GET_ADJ2( 80, 12, 3 ), 4, &PeriodicityIndex, &Score );
     327             : 
     328      286287 :         if ( NumToConsider <= 128 )
     329             :         {
     330             :             /* no long lags for band-limited MDCTs */
     331             : 
     332          63 :             SearchPeriodicityIndex_Range( AbsMdct3, NumToConsider, 208, 88 + NumToConsider, 0, GET_ADJ2( 224, 188, 0 ), 1, &PeriodicityIndex, &Score );
     333             :         }
     334             :         else
     335             :         {
     336             : 
     337      286224 :             if ( TargetBits > kSmallerLagsTargetBitsThreshold && NumCoeffs >= 256 )
     338             :             {
     339      277608 :                 SearchPeriodicityIndex_Range( AbsMdct3, NumToConsider, 208, 224, 1, GET_ADJ2( 208, 28, 1 ), 1, &PeriodicityIndex, &Score );
     340             : 
     341      277608 :                 SearchPeriodicityIndex_Range( AbsMdct3, NumToConsider, 224, 256, 0, GET_ADJ2( 224, 188, 0 ), 1, &PeriodicityIndex, &Score );
     342             :             }
     343             :             else
     344             :             {
     345        8616 :                 SearchPeriodicityIndex_Range( AbsMdct3, NumToConsider, 208, 256, 1, GET_ADJ2( 208, 28, 1 ), 1, &PeriodicityIndex, &Score );
     346             :             }
     347             :         }
     348             :     }
     349             : 
     350      375928 :     if ( AbsTotal > 0 )
     351             :     {
     352      375590 :         *RelativeScore = Score / AbsTotal * (float) NumCoeffs;
     353             :     }
     354             :     else
     355             :     {
     356         338 :         *RelativeScore = 0;
     357             :     }
     358             : 
     359      375928 :     return PeriodicityIndex;
     360             : }
     361             : 
     362             : 
     363             : /*-------------------------------------------------------------------*
     364             :  * PeakFilter()
     365             :  *
     366             :  *
     367             :  *-------------------------------------------------------------------*/
     368             : 
     369             : #define kPeakElevationThreshold 1.0f
     370             : 
     371       28652 : static void PeakFilter(
     372             :     const float x[],      /* (I) absolute spectrum                              */
     373             :     float y[],            /* (O) filtered absolute spectrum, must not alias x[] */
     374             :     const int16_t L_frame /* (I) number of spectral lines                       */
     375             : )
     376             : {
     377             :     int16_t flen, i;
     378             :     float a, m;
     379             : 
     380       28652 :     flen = ( L_frame >> 4 );
     381       28652 :     m = kPeakElevationThreshold / (float) ( 2 * flen + 1 );
     382             : 
     383       28652 :     a = 0.0f;
     384     1127872 :     for ( i = 0; i < flen; ++i )
     385             :     {
     386     1099220 :         a += x[i];
     387             :     }
     388             : 
     389     1127872 :     for ( i = 0; i < flen; ++i )
     390             :     {
     391     1099220 :         y[i] = max( 0.0f, x[i] - a * m );
     392     1099220 :         a += x[i + flen];
     393             :     }
     394    15417732 :     for ( ; i < L_frame - flen; ++i )
     395             :     {
     396    15389080 :         y[i] = max( 0.0f, x[i] - a * m );
     397    15389080 :         a -= x[i - flen];
     398    15389080 :         a += x[i + flen];
     399             :     }
     400             : 
     401     1127872 :     for ( ; i < L_frame; ++i )
     402             :     {
     403     1099220 :         y[i] = max( 0.0f, x[i] - a * m );
     404     1099220 :         a -= x[i - flen];
     405             :     }
     406             : 
     407       28652 :     return;
     408             : }
     409             : 
     410             : 
     411             : /*-------------------------------------------------------------------*
     412             :  * tcx_hm_get_re()
     413             :  *
     414             :  *
     415             :  *-------------------------------------------------------------------*/
     416             : 
     417             : /*! r: RE error */
     418       61830 : static float tcx_hm_get_re(
     419             :     const float x[],   /* i  : absolute spectrum               */
     420             :     const Word16 gain, /* i  : HM gain (Q11)                   */
     421             :     const int32_t lag,
     422             :     const int16_t fract_res,
     423             :     const Word16 p[],     /* i  : harmonic model (Q13)            */
     424             :     const Word32 env[],   /* i  : envelope (Q16)                  */
     425             :     const int16_t L_frame /* i  : number of spectral lines        */
     426             : )
     427             : {
     428             :     Word32 ne[N_MAX_ARI];
     429             :     float G, e;
     430             :     int16_t i;
     431             : 
     432             :     /* Calculate new envelope with "gain" harmonic gain */
     433    37882790 :     for ( i = 0; i < L_frame; ++i )
     434             :     {
     435    37820960 :         ne[i] = env[i];
     436             :     }
     437             : 
     438       61830 :     tcx_hm_modify_envelope( gain, lag, fract_res, p, ne, L_frame );
     439             : 
     440             :     /* Normalize */
     441       61830 :     G = 0;
     442             : 
     443    37882790 :     for ( i = 0; i < L_frame; ++i )
     444             :     {
     445    37820960 :         G += x[i] * ne[i];
     446             :     }
     447       61830 :     G = 1.0f / G;
     448             : 
     449             :     /* Calculate error */
     450       61830 :     e = 0;
     451             : 
     452    37882790 :     for ( i = 0; i < L_frame; ++i )
     453             :     {
     454    37820960 :         e += (float) pow( x[i] * ( ne[i] * G ), 4 );
     455             :     }
     456             : 
     457       61830 :     return e;
     458             : }
     459             : 
     460             : 
     461             : /*-------------------------------------------------------------------*
     462             :  * tcx_hm_quantize_gain()
     463             :  *
     464             :  *
     465             :  *-------------------------------------------------------------------*/
     466             : 
     467       28652 : static void tcx_hm_quantize_gain(
     468             :     const float x[],    /* i  : absolute spectrum                     */
     469             :     const Word32 env[], /* i  : envelope (Q16)                        */
     470             :     const int32_t lag,
     471             :     const int16_t fract_res,
     472             :     Word16 p[],               /* i  : harmonic model (Q13)                  */
     473             :     const int16_t L_frame,    /* i  : number of spectral lines              */
     474             :     const int16_t coder_type, /* i  : GC/VC coder type                      */
     475             :     float relative_score,     /* i  : periodicity score                     */
     476             :     int16_t *gain_idx,        /* o  : quantization index                    */
     477             :     Word16 *gain              /* o  : quantized harmonic model gain (Q11)   */
     478             : )
     479             : {
     480             :     int16_t g, s;
     481             :     float be, e, pe;
     482       28652 :     const float kLowPeriodicityThr[2] = { 0.5f, 0.2f };
     483             : 
     484       28652 :     assert( coder_type == VOICED || coder_type == GENERIC );
     485             : 
     486       28652 :     s = 0;
     487       28652 :     if ( coder_type == VOICED )
     488             :     {
     489        4072 :         s = 1;
     490             :     }
     491             : 
     492       28652 :     *gain = 0;
     493             : 
     494             :     /* Disable the harmonic model if periodicity is very low */
     495       28652 :     if ( relative_score < kLowPeriodicityThr[s] )
     496             :     {
     497        3845 :         return;
     498             :     }
     499             : 
     500       24807 :     be = tcx_hm_get_re( x, *gain, lag, fract_res, p, env, L_frame );
     501             : 
     502       24807 :     if ( coder_type == GENERIC )
     503             :     {
     504       20735 :         e = tcx_hm_get_re( x, qGains[s][0], lag, fract_res, p, env, L_frame );
     505       20735 :         pe = 1.05f;
     506             : 
     507       20735 :         if ( e * pe < be )
     508             :         {
     509       11180 :             *gain_idx = 0;
     510       11180 :             *gain = qGains[s][0];
     511             :         }
     512             :     }
     513             :     else
     514             :     {
     515             :         /* Iterate over all possible gain values */
     516       20360 :         for ( g = 0; g < ( 1 << kTcxHmNumGainBits ); ++g )
     517             :         {
     518             : 
     519       16288 :             e = tcx_hm_get_re( x, qGains[s][g], lag, fract_res, p, env, L_frame );
     520             : 
     521             :             /* Add bit penalty */
     522       16288 :             pe = 1.0f;
     523       16288 :             if ( *gain == 0.0f )
     524             :             {
     525        6706 :                 pe = 1.05f;
     526             :             }
     527             : 
     528             :             /*  Minimum selection */
     529       16288 :             if ( e * pe < be )
     530             :             {
     531        6431 :                 be = e;
     532        6431 :                 *gain_idx = g;
     533        6431 :                 *gain = qGains[s][g];
     534             :             }
     535             :         }
     536             :     }
     537             : 
     538       24807 :     return;
     539             : }
     540             : 
     541             : 
     542             : /*-------------------------------------------------------------------*
     543             :  * tcx_hm_analyse()
     544             :  *
     545             :  *
     546             :  *-------------------------------------------------------------------*/
     547             : 
     548       32476 : void tcx_hm_analyse(
     549             :     const float abs_spectrum[], /* i  : absolute spectrum             */
     550             :     const int16_t L_frame,      /* i  : number of spectral lines      */
     551             :     Word32 env[],               /* i/o: envelope shape (Q16)          */
     552             :     const int16_t targetBits,   /* i  : target bit budget             */
     553             :     const int16_t coder_type,   /* i  : GC/VC coder type              */
     554             :     int16_t prm_hm[],           /* o  : HM parameters                 */
     555             :     int16_t LtpPitchLag,        /* i  : LTP pitch lag or -1 if none   */
     556             :     const float LtpGain,        /* i  : LTP gain                      */
     557             :     int16_t *hm_bits            /* o  : bit consumption               */
     558             : )
     559             : {
     560             :     int32_t lag;
     561             :     int32_t tmpL;
     562             :     int16_t fract_res;
     563             :     float fspec[N_MAX_ARI], RelativeScore;
     564             :     Word16 p[2 * kTcxHmParabolaHalfWidth + 1], gain;
     565             : 
     566             :     /* Disable HM for non-GC,VC coder types */
     567       32476 :     if ( ( coder_type != VOICED ) && ( coder_type != GENERIC ) )
     568             :     {
     569        3824 :         *hm_bits = 0;
     570        3824 :         prm_hm[0] = 0;
     571             : 
     572        3824 :         return;
     573             :     }
     574             : 
     575             :     /* Bit consumption for the HM off case: 1 bit flag */
     576       28652 :     *hm_bits = 1;
     577             : 
     578             :     /* Filter out noise and keep the peaks */
     579       28652 :     PeakFilter( abs_spectrum, fspec, L_frame );
     580             : 
     581             :     /* Get the best lag index */
     582       28652 :     prm_hm[1] = SearchPeriodicityIndex( fspec, abs_spectrum, L_frame, targetBits - *hm_bits, LtpPitchLag, LtpGain, &RelativeScore );
     583             : 
     584             :     /* Convert the index to lag */
     585       28652 :     UnmapIndex( prm_hm[1], L_frame >= 256, LtpPitchLag, ( targetBits - *hm_bits <= kSmallerLagsTargetBitsThreshold ) || ( L_frame < 256 ), &fract_res, &tmpL );
     586       28652 :     lag = tmpL;
     587             : 
     588             :     /* Render harmonic model */
     589       28652 :     tcx_hm_render( lag, fract_res, p );
     590             : 
     591             :     /* Calculate and quantize gain */
     592       28652 :     gain = 0;
     593             : 
     594       28652 :     tcx_hm_quantize_gain( abs_spectrum, env, lag, fract_res, p, L_frame, coder_type, RelativeScore, &prm_hm[2], &gain );
     595             : 
     596             :     /* Decision */
     597       28652 :     if ( gain > 0 )
     598             :     {
     599       14421 :         prm_hm[0] = 1; /* flag: on */
     600             : 
     601       14421 :         *hm_bits += CountIndexBits( L_frame >= 256, prm_hm[1] );
     602             : 
     603       14421 :         if ( coder_type == VOICED )
     604             :         {
     605        3241 :             *hm_bits += kTcxHmNumGainBits;
     606             :         }
     607             : 
     608       14421 :         tcx_hm_modify_envelope( gain, lag, fract_res, p, env, L_frame );
     609             :     }
     610             :     else
     611             :     {
     612       14231 :         prm_hm[0] = 0;  /* flag: off   */
     613       14231 :         prm_hm[1] = -1; /* pitch index */
     614       14231 :         prm_hm[2] = 0;  /* gain index  */
     615             :     }
     616             : 
     617       28652 :     return;
     618             : }

Generated by: LCOV version 1.14