LCOV - code coverage report
Current view: top level - lib_com - tns_base.c (source / functions) Hit Total Coverage
Test: Coverage on main @ b8e0d5b93229a45388410f93fd14fda7bdd8ab4a Lines: 533 578 92.2 %
Date: 2025-11-08 02:37:03 Functions: 47 57 82.5 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : 
       5             : 
       6             : #include <assert.h>
       7             : #include <stdint.h>
       8             : #include <memory.h>
       9             : #include "options.h"
      10             : #include "stat_com.h"
      11             : #include "cnst.h"
      12             : #include "rom_com.h"
      13             : #include "prot_fx.h"
      14             : #include "basop_util.h"
      15             : 
      16             : /*----------------------------------------------------------------------------
      17             :  * Local constants
      18             :  *---------------------------------------------------------------------------*/
      19             : 
      20             : #define HLM_MIN_NRG      32768.0f
      21             : #define HLM_MIN_NRG_FX   32768 /*Q0*/
      22             : #define MAX_SUBDIVISIONS 3
      23             : 
      24             : /*----------------------------------------------------------------------------
      25             :  * Local prototypes
      26             :  *---------------------------------------------------------------------------*/
      27             : 
      28             : /** Linear prediction analysis/synthesis filter definition.
      29             :  * @param order filter order.
      30             :  * @param parCoeff filter (PARCOR) coefficients.
      31             :  * @param state state of the filter. Must be at least of 'order' size.
      32             :  * @param x the current input value.
      33             :  * @return the output of the filter.
      34             :  */
      35             : typedef Word32 ( *TLinearPredictionFilter )( Word16 order, Word16 const parCoeff[], Word32 *state, Word32 x );
      36             : 
      37             : /** Inverse quantization for reflection coefficients.
      38             :  *
      39             :  * @param index input quantized values.
      40             :  * @param parCoeff output reflection coefficients.
      41             :  * @param order number of coefficients/values.
      42             :  */
      43             : static void Index2Parcor( Word16 const index[], Word16 parCoeff[], Word16 order );
      44             : 
      45             : /** Linear prediction analysis filter.
      46             :  * See TLinearPredictionFilter for details.
      47             :  */
      48             : static Word32 FIRLattice( const Word16 order, const Word16 *parCoeff, Word32 *state, Word32 x );
      49             : 
      50             : /** Linear prediction synthesis filter.
      51             :  * See TLinearPredictionFilter for details.
      52             :  */
      53             : static Word32 IIRLattice( Word16 order, const Word16 *parCoeff, Word32 *state, Word32 x );
      54             : 
      55             : /** TNS analysis/synthesis filter.
      56             :   * @param spectrum input spectrum values.
      57             :   * @param numOfLines number of lines in the spectrum.
      58             :   * @param parCoeff filter (PARCOR) coefficients.
      59             :   * @param order filter order.
      60             :   * @param filter function that implements filtering.
      61             :     By this function it is defined whether analysis or synthesis is performed.
      62             :   * @param output filtered output spectrum values.
      63             :     Inplace operation is supported, so it can be equal to spectrum.
      64             :   */
      65             : static void TnsFilter( const Word32 spectrum[], const Word16 numOfLines, const Word16 parCoeff[], const Word16 order, TLinearPredictionFilter filter, Word32 *state, Word32 output[] );
      66             : 
      67             : static void ITF_TnsFilter_fx( const Word32 spectrum[], const Word16 numOfLines, const Word16 A[], /* Q14 */ const Word16 Q_A, const Word16 order, Word32 output[] );
      68             : 
      69             : static void ITF_GetFilterParameters_fx( Word32 rxx[], const Word16 maxOrder, Word16 *A, /* Q14 */ Word16 *Q_A, Word16 *predictionGain );
      70             : 
      71             : /********************************/
      72             : /*      Interface functions     */
      73             : /********************************/
      74             : 
      75             : /** Init TNS configuration.
      76             :  * Fills STnsConfig structure with sensible content.
      77             :  * @param nSampleRate Sampling rate of the input.
      78             :  * @param nFrameLength Frame length.
      79             :  * @param pTnsConfig TNS configuration to be initialized.
      80             :  * @return 0 on success, otherwise 1.
      81             :  */
      82       68287 : void InitTnsConfiguration(
      83             :     const Word16 bwidth,
      84             :     const Word16 frameLength,
      85             :     STnsConfig *pTnsConfig,
      86             :     const Word16 igfStopFreq,
      87             :     const Word32 total_brate,
      88             :     const Word16 element_mode,
      89             :     const Word16 is_mct )
      90             : {
      91       68287 :     Word16 iFilter = 0;
      92       68287 :     move16();
      93             :     Word16 *startLineFilter;
      94             :     Word32 L_tmp;
      95             :     Word32 nSampleRate;
      96             :     Word16 s1;
      97             :     Word16 s2;
      98             :     (void) ( element_mode );
      99             :     (void) ( is_mct );
     100       68287 :     nSampleRate = bwMode2fs[bwidth];
     101       68287 :     move32();
     102       68287 :     startLineFilter = &pTnsConfig->iFilterBorders[1];
     103             : 
     104             :     /* Sanity checks */
     105       68287 :     assert( ( nSampleRate > 0 ) && ( frameLength > 0 ) && ( pTnsConfig != NULL ) );
     106       68287 :     test();
     107       68287 :     test();
     108       68287 :     IF( ( nSampleRate <= 0 ) || ( frameLength <= 0 ) || ( pTnsConfig == NULL ) )
     109             :     {
     110           0 :         return /*TNS_FATAL_ERROR*/;
     111             :     }
     112             : 
     113             : 
     114             :     /* Initialize TNS filter flag and maximum order */
     115       68287 :     move16();
     116       68287 :     pTnsConfig->maxOrder = TNS_MAX_FILTER_ORDER;
     117             : 
     118       68287 :     IF( LE_32( total_brate, ACELP_32k ) )
     119             :     {
     120       10486 :         move16();
     121       10486 :         move16();
     122       10486 :         pTnsConfig->nMaxFilters = sizeof( tnsParametersIGF32kHz_LowBR ) / sizeof( tnsParametersIGF32kHz_LowBR[0] );
     123       10486 :         pTnsConfig->pTnsParameters = tnsParametersIGF32kHz_LowBR;
     124             :     }
     125             :     ELSE
     126             :     {
     127       57801 :         test();
     128       57801 :         IF( GT_32( nSampleRate, 32000 ) && EQ_32( nSampleRate, L_mult0( 100, frameLength ) ) )
     129             :         {
     130       14738 :             move16();
     131       14738 :             pTnsConfig->nMaxFilters = sizeof( tnsParameters48kHz_grouped ) / sizeof( tnsParameters48kHz_grouped[0] );
     132       14738 :             move16();
     133       14738 :             pTnsConfig->pTnsParameters = tnsParameters48kHz_grouped;
     134             :         }
     135             :         ELSE
     136       43063 :         IF( GT_32( nSampleRate, INT_FS_16k ) )
     137             :         {
     138             :             {
     139             : 
     140       40096 :                 move16();
     141       40096 :                 pTnsConfig->nMaxFilters = sizeof( tnsParameters32kHz ) / sizeof( tnsParameters32kHz[0] );
     142             : 
     143       40096 :                 move16();
     144       40096 :                 pTnsConfig->pTnsParameters = tnsParameters32kHz;
     145             : 
     146       40096 :                 if ( EQ_32( nSampleRate, L_mult0( 100, frameLength ) ) ) /* sub-frame length is <= 10 ms */
     147             :                 {
     148        3540 :                     move16();
     149        3540 :                     pTnsConfig->pTnsParameters = tnsParameters32kHz_grouped;
     150             :                 }
     151             :             }
     152             :         }
     153             :         ELSE
     154             :         {
     155        2967 :             IF( EQ_32( nSampleRate, L_mult0( 100, frameLength ) ) ) /* sub-frame length is <= 10 ms */
     156             :             {
     157         989 :                 move16();
     158         989 :                 pTnsConfig->nMaxFilters = sizeof( tnsParameters16kHz_grouped ) / sizeof( tnsParameters16kHz_grouped[0] );
     159         989 :                 pTnsConfig->pTnsParameters = tnsParameters16kHz_grouped;
     160             :             }
     161             :             ELSE
     162             :             {
     163        1978 :                 move16();
     164        1978 :                 move16();
     165        1978 :                 pTnsConfig->nMaxFilters = sizeof( tnsParameters16kHz ) / sizeof( tnsParameters16kHz[0] );
     166        1978 :                 pTnsConfig->pTnsParameters = tnsParameters16kHz;
     167             :             }
     168             :         }
     169             :     }
     170             : 
     171       68287 :     assert( pTnsConfig->nMaxFilters <= TNS_MAX_NUM_OF_FILTERS );
     172             : 
     173             :     /* Set starting MDCT line for each filter based on the starting frequencies from the TNS table */
     174             : 
     175      192397 :     FOR( iFilter = 0; iFilter < pTnsConfig->nMaxFilters; iFilter++ )
     176             :     {
     177      124110 :         assert( pTnsConfig->pTnsParameters[iFilter].startLineFrequency < nSampleRate / 2 );
     178      124110 :         assert( nSampleRate <= 96000 );
     179      124110 :         move16();
     180      124110 :         startLineFilter[iFilter] = divide3232( L_mult0( frameLength, pTnsConfig->pTnsParameters[iFilter].startLineFrequency ), L_shl( nSampleRate, 14 ) );
     181             :     }
     182             : 
     183       68287 :     IF( igfStopFreq > 0 )
     184             :     {
     185       52711 :         L_tmp = L_mult( frameLength, igfStopFreq );
     186       52711 :         s1 = sub( norm_l( L_tmp ), 1 );
     187       52711 :         s2 = norm_l( nSampleRate );
     188             : 
     189       52711 :         move16();
     190       52711 :         pTnsConfig->iFilterBorders[0] = shr( div_l( L_shl( L_tmp, s1 ), extract_h( L_shl( nSampleRate, s2 ) ) ), sub( WORD16_BITS - 1, sub( s2, s1 ) ) );
     191             :     }
     192             :     ELSE
     193             :     {
     194       15576 :         move16();
     195       15576 :         pTnsConfig->iFilterBorders[0] = frameLength;
     196             :     }
     197       68287 :     return; /*TNS_NO_ERROR;*/
     198             : }
     199             : 
     200      110794 : void InitTnsConfiguration_ivas_fx(
     201             :     const Word16 bwidth,      /*Q0*/
     202             :     const Word16 frameLength, /*Q0*/
     203             :     STnsConfig *pTnsConfig,
     204             :     const Word16 igfStopFreq,  /*Q0*/
     205             :     const Word32 total_brate,  /*Q0*/
     206             :     const Word16 element_mode, /*Q0*/
     207             :     const Word16 is_mct /*Q0*/ )
     208             : {
     209      110794 :     Word16 iFilter = 0;
     210      110794 :     move16();
     211             :     Word16 *startLineFilter;
     212             :     Word32 L_tmp;
     213             :     Word32 nSampleRate;
     214             :     Word16 s1;
     215             :     Word16 s2;
     216             : 
     217      110794 :     nSampleRate = bwMode2fs[bwidth];
     218      110794 :     move32();
     219      110794 :     startLineFilter = &pTnsConfig->iFilterBorders[1]; /*Q0*/
     220             : 
     221             :     /* Sanity checks */
     222      110794 :     assert( ( nSampleRate > 0 ) && ( frameLength > 0 ) && ( pTnsConfig != NULL ) );
     223      110794 :     test();
     224      110794 :     test();
     225      110794 :     IF( ( nSampleRate <= 0 ) || ( frameLength <= 0 ) || ( pTnsConfig == NULL ) )
     226             :     {
     227           0 :         return /*TNS_FATAL_ERROR*/;
     228             :     }
     229             : 
     230             : 
     231             :     /* Initialize TNS filter flag and maximum order */
     232      110794 :     move16();
     233      110794 :     pTnsConfig->maxOrder = TNS_MAX_FILTER_ORDER;
     234             : 
     235      110794 :     IF( LE_32( total_brate, ACELP_32k ) )
     236             :     {
     237       27556 :         move16();
     238       27556 :         pTnsConfig->nMaxFilters = (UWord8) idiv1616( sizeof( tnsParametersIGF32kHz_LowBR ), sizeof( tnsParametersIGF32kHz_LowBR[0] ) ); /*Q0*/
     239       27556 :         pTnsConfig->pTnsParameters = tnsParametersIGF32kHz_LowBR;
     240             :     }
     241             :     ELSE
     242             :     {
     243       83238 :         test();
     244       83238 :         IF( GT_32( nSampleRate, 32000 ) && EQ_32( nSampleRate, L_mult0( 100, frameLength ) ) )
     245             :         {
     246       21721 :             pTnsConfig->nMaxFilters = (UWord8) idiv1616( sizeof( tnsParameters48kHz_grouped ), sizeof( tnsParameters48kHz_grouped[0] ) ); /*Q0*/
     247       21721 :             move16();
     248       21721 :             pTnsConfig->pTnsParameters = tnsParameters48kHz_grouped;
     249             :         }
     250       61517 :         ELSE IF( GT_32( nSampleRate, INT_FS_16k ) )
     251             :         {
     252       57872 :             L_tmp = IVAS_32k;
     253       57872 :             move32();
     254       57872 :             if ( !is_mct )
     255             :             {
     256       39494 :                 L_tmp = IVAS_48k;
     257       39494 :                 move32();
     258             :             }
     259       57872 :             test();
     260       57872 :             IF( GT_16( element_mode, IVAS_SCE ) && GE_32( total_brate, L_tmp ) )
     261             :             {
     262       44122 :                 pTnsConfig->nMaxFilters = (UWord8) idiv1616( sizeof( tnsParameters32kHz_Stereo ), sizeof( tnsParameters32kHz_Stereo[0] ) ); /*Q0*/
     263       44122 :                 move16();
     264       44122 :                 IF( EQ_32( nSampleRate, L_mult0( 100, frameLength ) ) ) /* sub-frame length is <= 10 ms */
     265             :                 {
     266        4414 :                     pTnsConfig->pTnsParameters = tnsParameters32kHz_grouped;
     267             :                 }
     268             :                 ELSE
     269             :                 {
     270       39708 :                     pTnsConfig->pTnsParameters = tnsParameters32kHz_Stereo;
     271             :                 }
     272             :             }
     273             :             ELSE
     274             :             {
     275             : 
     276       13750 :                 move16();
     277       13750 :                 pTnsConfig->nMaxFilters = (UWord8) idiv1616( sizeof( tnsParameters32kHz ), sizeof( tnsParameters32kHz[0] ) ); /*Q0*/
     278             : 
     279       13750 :                 pTnsConfig->pTnsParameters = tnsParameters32kHz;
     280             : 
     281       13750 :                 if ( EQ_32( nSampleRate, L_mult0( 100, frameLength ) ) ) /* sub-frame length is <= 10 ms */
     282             :                 {
     283         396 :                     pTnsConfig->pTnsParameters = tnsParameters32kHz_grouped;
     284             :                 }
     285             :             }
     286             :         }
     287             :         ELSE
     288             :         {
     289        3645 :             IF( EQ_32( nSampleRate, L_mult0( 100, frameLength ) ) ) /* sub-frame length is <= 10 ms */
     290             :             {
     291        1215 :                 move16();
     292        1215 :                 pTnsConfig->nMaxFilters = (UWord8) idiv1616( sizeof( tnsParameters16kHz_grouped ), sizeof( tnsParameters16kHz_grouped[0] ) ); /*Q0*/
     293        1215 :                 pTnsConfig->pTnsParameters = tnsParameters16kHz_grouped;
     294             :             }
     295             :             ELSE
     296             :             {
     297        2430 :                 move16();
     298        2430 :                 pTnsConfig->nMaxFilters = (UWord8) idiv1616( sizeof( tnsParameters16kHz ), sizeof( tnsParameters16kHz[0] ) ); /*Q0*/
     299        2430 :                 pTnsConfig->pTnsParameters = tnsParameters16kHz;
     300             :             }
     301             :         }
     302             :     }
     303             : 
     304      110794 :     assert( pTnsConfig->nMaxFilters <= TNS_MAX_NUM_OF_FILTERS );
     305             : 
     306             :     /* Set starting MDCT line for each filter based on the starting frequencies from the TNS table */
     307             : 
     308      302396 :     FOR( iFilter = 0; iFilter < pTnsConfig->nMaxFilters; iFilter++ )
     309             :     {
     310      191602 :         assert( pTnsConfig->pTnsParameters[iFilter].startLineFrequency < nSampleRate / 2 );
     311      191602 :         assert( nSampleRate <= 96000 );
     312      191602 :         move16();
     313      191602 :         startLineFilter[iFilter] = divide3232( L_mult0( frameLength, pTnsConfig->pTnsParameters[iFilter].startLineFrequency ), L_shl( nSampleRate, 14 ) ); /*Q0*/
     314             :     }
     315             : 
     316      110794 :     IF( igfStopFreq > 0 )
     317             :     {
     318       90019 :         L_tmp = L_mult( frameLength, igfStopFreq );
     319       90019 :         s1 = sub( norm_l( L_tmp ), 1 );
     320       90019 :         s2 = norm_l( nSampleRate );
     321             : 
     322       90019 :         move16();
     323       90019 :         pTnsConfig->iFilterBorders[0] = shr( div_l( L_shl( L_tmp, s1 ), extract_h( L_shl( nSampleRate, s2 ) ) ), sub( WORD16_BITS - 1, sub( s2, s1 ) ) ); /*Q0*/
     324             :     }
     325             :     ELSE
     326             :     {
     327       20775 :         move16();
     328       20775 :         pTnsConfig->iFilterBorders[0] = frameLength; /*Q0*/
     329             :     }
     330             : 
     331      110794 :     pTnsConfig->allowTnsOnWhite = 0;
     332      110794 :     move16();
     333             : 
     334      110794 :     return; /*TNS_NO_ERROR;*/
     335             : }
     336             : 
     337             : 
     338             : /*-------------------------------------------------------------------*
     339             :  * ApplyTnsFilter()
     340             :  *
     341             :  *-------------------------------------------------------------------*/
     342             : 
     343      223402 : void ApplyTnsFilter(
     344             :     STnsConfig const *pTnsConfig,
     345             :     STnsData const *pTnsData,
     346             :     Word32 spectrum[], /*Qx*/
     347             :     const Word8 fIsAnalysis /*Q0*/ )
     348             : {
     349             :     TLinearPredictionFilter filter;
     350             :     Word32 state[TNS_MAX_FILTER_ORDER];
     351             :     Word16 iFilter;
     352             :     Word16 stopLine, startLine;
     353             :     Word16 const *pBorders;
     354             : 
     355             : 
     356      223402 :     move16();
     357      223402 :     filter = IIRLattice;
     358      223402 :     if ( fIsAnalysis )
     359             :     {
     360      101290 :         filter = FIRLattice;
     361             :     }
     362      223402 :     set32_fx( state, 0, TNS_MAX_FILTER_ORDER );
     363      223402 :     move16();
     364      223402 :     pBorders = pTnsConfig->iFilterBorders; /*Q0*/
     365             : 
     366      664282 :     FOR( iFilter = pTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
     367             :     {
     368             :         Word16 parCoeff[TNS_MAX_FILTER_ORDER];
     369             :         const STnsFilter *pFilter;
     370             : 
     371      440880 :         move16();
     372      440880 :         move16();
     373      440880 :         pFilter = &pTnsData->filter[iFilter];
     374      440880 :         stopLine = pBorders[iFilter];
     375      440880 :         startLine = pBorders[iFilter + 1];
     376             : 
     377      440880 :         Index2Parcor( pFilter->coefIndex, parCoeff, pFilter->order );
     378             : 
     379      440880 :         TnsFilter( &spectrum[startLine], stopLine - startLine,
     380      440880 :                    parCoeff, pFilter->order,
     381             :                    filter, state,
     382      440880 :                    &spectrum[startLine] );
     383             :     }
     384             : 
     385      223402 :     move16();
     386             : 
     387      223402 :     return /*result*/;
     388             : }
     389             : 
     390             : /*-------------------------------------------------------------------*
     391             :  * ITF_Apply()
     392             :  *
     393             :  *-------------------------------------------------------------------*/
     394             : 
     395      596014 : void ITF_Apply_fx(
     396             :     Word32 spectrum[], /*Qx*/
     397             :     Word16 startLine,  /*Q0*/
     398             :     Word16 stopLine,   /*Q0*/
     399             :     const Word16 *A,   /*Q_A*/
     400             :     Word16 Q_A,
     401             :     Word16 order /*Q0*/ )
     402             : {
     403             : 
     404      596014 :     ITF_TnsFilter_fx( &spectrum[startLine], sub( stopLine, startLine ), A, Q_A, order, &spectrum[startLine] );
     405             : 
     406      596014 :     return /*TNS_NO_ERROR*/;
     407             : }
     408             : /*-------------------------------------------------------------------*
     409             :  * ITF_Detect()
     410             :  *
     411             :  *
     412             :  *-------------------------------------------------------------------*/
     413             : 
     414        1194 : Word16 ITF_Detect_fx(
     415             :     const Word32 pSpectrum[], /*Q*/
     416             :     const Word16 startLine,   /*Q0*/
     417             :     const Word16 stopLine,    /*Q0*/
     418             :     const Word16 maxOrder,    /*Q0*/
     419             :     Word16 *A,                /*Q_A*/
     420             :     Word16 *Q_A,
     421             :     Word16 *predictionGain, /*Q7*/
     422             :     Word16 *curr_order,     /*Q0*/
     423             :     Word16 Q )
     424             : {
     425             : 
     426             :     Word16 spectrumLength;
     427        1194 :     Word16 const nSubdivisions = MAX_SUBDIVISIONS;
     428        1194 :     move16();
     429             :     Word16 iSubdivisions;
     430             :     Word16 iStartLine;
     431             :     Word16 iEndLine;
     432             :     Word16 facs[MAX_SUBDIVISIONS];
     433             :     Word16 facs_e[MAX_SUBDIVISIONS]; /* exponents of facs[][] */
     434             :     Word16 shifts[MAX_SUBDIVISIONS];
     435             :     Word16 tmp, headroom, shift;
     436             :     Word32 rxx[ITF_MAX_FILTER_ORDER + 1];
     437             :     Word16 lag;
     438             :     Word32 L_tmp, tmp32;
     439             :     Word16 tmpbuf[325];
     440             :     Word16 n, i;
     441        1194 :     move16();
     442        1194 :     move16();
     443        1194 :     move16();
     444             : 
     445        1194 :     if ( maxOrder <= 0 )
     446             :     {
     447           0 :         return 0;
     448             :     }
     449             : 
     450             :     /* Calculate norms for each spectrum part */
     451        4776 :     FOR( iSubdivisions = 0; iSubdivisions < nSubdivisions; iSubdivisions++ )
     452             :     {
     453        3582 :         assert( ( nSubdivisions == 1 ) || ( nSubdivisions == 3 ) );
     454             : 
     455        3582 :         tmp = sub( stopLine, startLine );
     456        3582 :         iStartLine = imult1616( tmp, iSubdivisions ); /*Q0*/
     457        3582 :         iEndLine = add( iStartLine, tmp );
     458             : 
     459        3582 :         if ( EQ_16( nSubdivisions, 3 ) )
     460        3582 :             iStartLine = mult( iStartLine, 0x2AAB ); /*Q0*/
     461        3582 :         iStartLine = add( iStartLine, startLine );
     462             : 
     463        3582 :         if ( EQ_16( nSubdivisions, 3 ) )
     464        3582 :             iEndLine = mult( iEndLine, 0x2AAB ); /*Q0*/
     465        3582 :         iEndLine = add( iEndLine, startLine );
     466        3582 :         headroom = getScaleFactor32( pSpectrum + iStartLine - IGF_START_MN, sub( iEndLine, iStartLine ) );
     467             :         /* Calculate norm of spectrum band */
     468        3582 :         L_tmp = Norm32Norm( pSpectrum + iStartLine - IGF_START_MN, headroom, sub( iEndLine, iStartLine ), &shift ); /*Q31 - shift*/
     469             : 
     470             :         /* Check threshold HLM_MIN_NRG */
     471             :         BASOP_SATURATE_WARNING_OFF_EVS;
     472        3582 :         tmp32 = L_sub( L_shl_sat( L_tmp, sub( shift, sub( 24, Q ) ) ), 4194304l /*HLM_MIN_NRG Q7*/ ); /*Q7*/
     473             :         BASOP_SATURATE_WARNING_ON_EVS;
     474             : 
     475             :         /* get pre-shift for autocorrelation */
     476        3582 :         tmp = sub( shift, norm_l( L_tmp ) ); /* exponent for normalized L_tmp */
     477        3582 :         tmp = shr( sub( 1, tmp ), 1 );       /* pre-shift to apply before autocorrelation */
     478        3582 :         shifts[iSubdivisions] = s_min( tmp, headroom );
     479        3582 :         move16();
     480             : 
     481             :         /* calc normalization factor */
     482        3582 :         facs[iSubdivisions] = 0;
     483        3582 :         move16();
     484        3582 :         facs_e[iSubdivisions] = 0;
     485        3582 :         move16();
     486             : 
     487        3582 :         if ( tmp32 > 0 )
     488             :         {
     489         692 :             facs[iSubdivisions] = 0x7FFF;
     490         692 :             move16(); /* normalization not needed for one subdivision */
     491             :         }
     492             : 
     493        3582 :         test();
     494        3582 :         IF( ( tmp32 > 0 ) && ( GT_16( nSubdivisions, 1 ) ) )
     495             :         {
     496         692 :             move16();
     497         692 :             facs_e[iSubdivisions] = shl( sub( tmp, shifts[iSubdivisions] ), 1 );
     498             : 
     499         692 :             tmp = sub( 1, shl( tmp, 1 ) );             /* exponent of autocorrelation */
     500         692 :             L_tmp = L_shl( L_tmp, sub( shift, tmp ) ); /* shift L_tmp to that exponent */
     501             : 
     502             :             /* calc factor (with 2 bits headroom for sum of 3 subdivisions) */
     503         692 :             facs[iSubdivisions] = div_s( 0x2000, round_fx_sat( L_tmp ) ); /* L_tmp is >= 0x2000000 Q15*/
     504         692 :             move16();
     505             :         }
     506             :     }
     507             : 
     508             :     /* Calculate normalized autocorrelation for spectrum subdivision and get filter parameters based on it */
     509        1194 :     set32_fx( rxx, 0, ITF_MAX_FILTER_ORDER + 1 );
     510             : 
     511        1194 :     spectrumLength = sub( stopLine, startLine );
     512             : 
     513        1881 :     FOR( iSubdivisions = 0; iSubdivisions < nSubdivisions; iSubdivisions++ )
     514             :     {
     515        1766 :         IF( facs[iSubdivisions] == 0 )
     516             :         {
     517        1079 :             BREAK;
     518             :         }
     519             : 
     520             : 
     521         687 :         assert( ( nSubdivisions == 1 ) || ( nSubdivisions == 3 ) );
     522             : 
     523         687 :         iStartLine = imult1616( spectrumLength, iSubdivisions ); /*Q0*/
     524         687 :         iEndLine = add( iStartLine, spectrumLength );            /*Q0*/
     525             : 
     526         687 :         if ( EQ_16( nSubdivisions, 3 ) )
     527         687 :             iStartLine = mult( iStartLine, 0x2AAB ); /*Q0*/
     528         687 :         iStartLine = add( iStartLine, startLine );
     529             : 
     530         687 :         if ( EQ_16( nSubdivisions, 3 ) )
     531         687 :             iEndLine = mult( iEndLine, 0x2AAB ); /*Q0*/
     532         687 :         iEndLine = add( iEndLine, startLine );
     533             : 
     534             : 
     535         687 :         move16();
     536         687 :         shift = shifts[iSubdivisions];
     537             : 
     538         687 :         n = sub( iEndLine, iStartLine );
     539         687 :         assert( n < (Word16) ( sizeof( tmpbuf ) / sizeof( Word16 ) ) );
     540       82015 :         FOR( i = 0; i < n; i++ )
     541             :         {
     542       81328 :             tmpbuf[i] = round_fx_sat( L_shl_sat( pSpectrum[iStartLine + i - IGF_START_MN], shift ) ); /*Q + shift - 16*/
     543       81328 :             move16();
     544             :         }
     545             : 
     546        6870 :         FOR( lag = 0; lag <= maxOrder; lag++ )
     547             :         {
     548        6183 :             n = sub( sub( iEndLine, lag ), iStartLine );
     549             : 
     550             :             {
     551        6183 :                 Word64 tmp64 = 0;
     552      713403 :                 FOR( i = 0; i < n; i++ )
     553             :                 {
     554      707220 :                     tmp64 = W_mac0_16_16( tmp64, tmpbuf[i], tmpbuf[i + lag] ); /*2*(Q + shift) - 32*/
     555             :                 }
     556        6183 :                 L_tmp = W_sat_l( tmp64 ); /*2*(Q + shift) - 32*/
     557             :             }
     558             : 
     559        6183 :             L_tmp = Mpy_32_16_1( L_tmp, facs[iSubdivisions] ); /*2*(Q + shift) - 32*/
     560        6183 :             L_tmp = L_shl( L_tmp, facs_e[iSubdivisions] );     /*2*(Q + shift) - 32 + facs_e*/
     561             : 
     562        6183 :             rxx[lag] = L_add( rxx[lag], L_tmp );
     563        6183 :             move32();
     564             :         }
     565             :     }
     566             : 
     567        1194 :     IF( EQ_16( iSubdivisions, nSubdivisions ) ) /* meaning there is no subdivision with low energy */
     568             :     {
     569             :         /* Limit the maximum order to spectrum length/4 */
     570         115 :         ITF_GetFilterParameters_fx( rxx, s_min( maxOrder, shr( spectrumLength, 2 ) ), A, Q_A, predictionGain );
     571             : 
     572         115 :         *curr_order = maxOrder; /*Q0*/
     573         115 :         move16();
     574             :     }
     575             : 
     576        1194 :     return 1;
     577             : }
     578             : 
     579     1291153 : Word16 ITF_Detect_ivas_fx(
     580             :     const Word32 pSpectrum[], /*Q*/
     581             :     const Word16 startLine,   /*Q0*/
     582             :     const Word16 stopLine,    /*Q0*/
     583             :     const Word16 maxOrder,    /*Q0*/
     584             :     Word16 *A,                /*Q_A*/
     585             :     Word16 *Q_A,
     586             :     Word16 *predictionGain, /*Q7*/
     587             :     Word16 *curr_order,     /*Q0*/
     588             :     Word16 Q )
     589             : {
     590             :     Word32 norms[MAX_SUBDIVISIONS];
     591             :     Word16 num_subdivisions, i, length;
     592             :     Word16 iStartLine, iEndLine, spectrumLength;
     593             :     Word32 rxx[ITF_MAX_FILTER_ORDER + 1];
     594             :     Word16 q_rxx[ITF_MAX_FILTER_ORDER + 1];
     595             :     Word32 temp_spectrum[640];
     596             :     const Word16 *pWindow;
     597             :     const Word32 *ptr_spectrum1, *ptr_spectrum2;
     598             :     Word16 iSubdivisions, lag;
     599             :     Word16 headroom, guard_bits, shift, q_min;
     600             :     Word64 sum;
     601             :     Word16 fac, q_fac, exp, q_temp;
     602             :     Word32 temp;
     603             : 
     604     1291153 :     IF( maxOrder <= 0 )
     605             :     {
     606           0 :         return 0;
     607             :     }
     608     1291153 :     pWindow = tnsAcfWindow_fx;
     609     1291153 :     set_zero_fx( norms, MAX_SUBDIVISIONS );
     610     1291153 :     set_zero_fx( rxx, ITF_MAX_FILTER_ORDER + 1 );     /* This initialization is required */
     611     1291153 :     set16_fx( q_rxx, Q31, ITF_MAX_FILTER_ORDER + 1 ); /* This initialization is required */
     612             : 
     613     1291153 :     spectrumLength = sub( stopLine, startLine );
     614     1291153 :     num_subdivisions = 0;
     615     1291153 :     move16();
     616             : 
     617             :     /* Calculate norms for each spectrum part */
     618     2191413 :     FOR( iSubdivisions = 0; iSubdivisions < MAX_SUBDIVISIONS; iSubdivisions++ )
     619             :     {
     620             :         /* iStartLine = startLine + ( stopLine - startLine ) * iSubdivisions / nSubdivisions; */
     621     1968634 :         iStartLine = add( startLine, mult( imult1616( spectrumLength, iSubdivisions ), 10923 /* 1/MAX_SUBDIVISIONS in Q15 */ ) ); /*Q0*/
     622             :         /* iEndLine = startLine + ( stopLine - startLine ) * ( iSubdivisions + 1 ) / nSubdivisions; */
     623     1968634 :         iEndLine = add( startLine, mult( imult1616( spectrumLength, add( iSubdivisions, 1 ) ), 10923 /* 1/MAX_SUBDIVISIONS in Q15 */ ) ); /*Q0*/
     624             : 
     625             : 
     626             :         /*         Variable initialization             */
     627             :         /* norms[iSubdivisions] = sum2_f(pSpectrum + iStartLine - IGF_START_MN, iEndLine - iStartLine); */
     628             : 
     629     1968634 :         ptr_spectrum1 = pSpectrum + sub( iStartLine, IGF_START_MN );
     630     1968634 :         length = sub( iEndLine, iStartLine );
     631     1968634 :         headroom = L_norm_arr( ptr_spectrum1, length );
     632     1968634 :         guard_bits = find_guarded_bits_fx( length );
     633     1968634 :         shift = sub( headroom, guard_bits );
     634             : 
     635     1968634 :         Copy_Scale_sig32( ptr_spectrum1, temp_spectrum, length, shift ); // Q -> Q+shift
     636             : 
     637     1968634 :         sum = 0;
     638     1968634 :         move64();
     639   209121132 :         FOR( i = 0; i < length; i++ )
     640             :         {
     641   207152498 :             sum = W_mac_32_32( sum, temp_spectrum[i], temp_spectrum[i] ); // 2(Q+shift)+1
     642             :         }
     643     1968634 :         IF( LE_64( sum, W_shl( 32768 * 2 /* HLM_MIN_NRG in Q1 */, s_min( 63, shl( add( Q, shift ), 1 ) ) ) ) )
     644             :         {
     645     1068374 :             BREAK;
     646             :         }
     647             : 
     648             :         /* fac = 1.0f / norms[iSubdivisions]; */
     649      900260 :         exp = W_norm( sum );
     650      900260 :         sum = W_shl( sum, exp );                                    // 2(Q+shift)+1+exp
     651      900260 :         fac = div_s( ONE_IN_Q14, extract_h( W_extract_h( sum ) ) ); // 15+14-(2(Q+shift)+1+exp-48) = 76-(2(Q+shift)+exp)
     652      900260 :         q_fac = sub( 76, add( shl( add( Q, shift ), 1 ), exp ) );
     653      900260 :         pWindow = tnsAcfWindow_fx;
     654             : 
     655             :         /* For additional loop condition */
     656             :         /* Variable initialization */
     657             :         /*for ( lag = 1; lag <= maxOrder; lag++ )
     658             :         {
     659             :             rxx[lag] += fac * ( *pWindow ) * dotp( pSpectrum + iStartLine - IGF_START_MN, pSpectrum + iStartLine - IGF_START_MN + lag, iEndLine - iStartLine - lag );
     660             :             pWindow++;
     661             :         }*/
     662             : 
     663      900260 :         ptr_spectrum1 = temp_spectrum; // pSpectrum + iStartLine - IGF_START_MN;
     664     8102340 :         FOR( lag = 1; lag <= maxOrder; lag++ )
     665             :         {
     666             :             /* dotp( pSpectrum + iStartLine - IGF_START_MN, pSpectrum + iStartLine - IGF_START_MN + lag, iEndLine - iStartLine - lag ) */
     667     7202080 :             ptr_spectrum2 = temp_spectrum + lag; //  pSpectrum + iStartLine - IGF_START_MN + lag;
     668             : 
     669     7202080 :             sum = 0;
     670     7202080 :             move64();
     671   797969872 :             FOR( i = 0; i < iEndLine - iStartLine - lag; i++ )
     672             :             {
     673   790767792 :                 sum = W_mac_32_32( sum, ptr_spectrum1[i], ptr_spectrum2[i] ); // 2(Q+shift)+1
     674             :             }
     675     7202080 :             exp = W_norm( sum );
     676     7202080 :             sum = W_shl( sum, exp );                                          // 2(Q+shift)+1+exp
     677     7202080 :             temp = Mpy_32_32( L_mult0( fac, *pWindow ), W_extract_h( sum ) ); // (q_fac+15)+(2(Q+shift)+1+exp-32)-31 = q_fac+2(Q+shift)+exp-47
     678     7202080 :             q_temp = sub( add( q_fac, add( shl( add( Q, shift ), 1 ), exp ) ), 47 );
     679             : 
     680             :             /* rxx[lag] += fac * (*pWindow) * dotp(pSpectrum + iStartLine - IGF_START_MN, pSpectrum + iStartLine - IGF_START_MN + lag, iEndLine - iStartLine - lag); */
     681     7202080 :             q_min = sub( s_min( q_temp, q_rxx[lag] ), 1 );
     682     7202080 :             rxx[lag] = L_add( L_shl( rxx[lag], sub( q_min, q_rxx[lag] ) ), L_shl( temp, sub( q_min, q_temp ) ) );
     683     7202080 :             q_rxx[lag] = q_min;
     684     7202080 :             move32();
     685     7202080 :             move16();
     686             : 
     687     7202080 :             pWindow++;
     688             :         }
     689             : 
     690      900260 :         num_subdivisions = add( num_subdivisions, 1 );
     691             :     }
     692             : 
     693     1291153 :     minimum_s( q_rxx + 1, ITF_MAX_FILTER_ORDER, &q_min );
     694     1291153 :     q_min = s_min( Q29, q_min );
     695             : 
     696    20658448 :     FOR( i = 1; i < ITF_MAX_FILTER_ORDER; i++ )
     697             :     {
     698    19367295 :         rxx[i] = L_shl( rxx[i], sub( q_min, q_rxx[i] ) );
     699    19367295 :         move32();
     700             :     }
     701             : 
     702     1291153 :     IF( EQ_16( iSubdivisions, MAX_SUBDIVISIONS ) ) /* meaning there is no subdivision with low energy */
     703             :     {
     704      222779 :         rxx[0] = L_shl( MAX_SUBDIVISIONS, q_min );
     705      222779 :         move32();
     706             : 
     707             :         /* Limit the maximum order to spectrum length/4 */
     708      222779 :         ITF_GetFilterParameters_fx( rxx, s_min( maxOrder, shr( spectrumLength, 2 ) ), A, Q_A, predictionGain );
     709             : 
     710      222779 :         *curr_order = maxOrder; /*Q0*/
     711      222779 :         move16();
     712             :     }
     713             : 
     714     1291153 :     return 1;
     715             : }
     716             : /* Helper functions for Hufmann table coding */
     717             : 
     718             : 
     719             : /** Get number of bits from a Huffman table.
     720             :  * The table must be sorted by values.
     721             :  */
     722     1699441 : static Word16 GetBitsFromTable( const Word16 value /*Q0*/, const Coding codes[], const Word16 nSize /*Q0*/ )
     723             : {
     724             :     (void) nSize;
     725     1699441 :     assert( ( value >= 0 ) && ( value < nSize ) && ( nSize >= 0 ) && ( nSize <= 256 ) );
     726             : 
     727     1699441 :     move16();
     728     1699441 :     cast16();
     729     1699441 :     return (Word16) codes[value].nBits; /*Q0*/
     730             : }
     731             : 
     732             : /** Get the code for a value from a Huffman table.
     733             :  * The table must be sorted by values.
     734             :  */
     735      838437 : static Word16 EncodeUsingTable( const Word16 value /*Q0*/, const Coding codes[], const Word16 nSize /*Q0*/ )
     736             : {
     737             :     (void) nSize;
     738      838437 :     assert( ( value >= 0 ) && ( value < nSize ) && ( nSize >= 0 ) && ( nSize <= 256 ) );
     739             : 
     740      838437 :     move16();
     741      838437 :     return codes[value].code; /*Q0*/
     742             : }
     743             : 
     744             : 
     745             : /** Decode a value from a bitstream using a Huffman table. */
     746      827715 : static Word16 DecodeUsingTable( Decoder_State *st, Word16 *pValue /*Q0*/, const Coding codes[], const Word16 nSize /*Q0*/ )
     747             : {
     748      827715 :     Word16 code = 0;
     749      827715 :     Word16 nBits = 0;
     750      827715 :     move16();
     751      827715 :     move16();
     752             :     Word16 valueIndex;
     753             : 
     754      827715 :     assert( ( nSize >= 0 ) && ( nSize <= 256 ) );
     755             : 
     756             : 
     757      827715 :     move16();
     758      827715 :     valueIndex = nSize;
     759             : 
     760             : 
     761     3013977 :     WHILE( valueIndex == nSize )
     762             :     {
     763     2186262 :         code = add( shl( code, 1 ), get_next_indice_fx( st, 1 ) ); /*Q0*/
     764     2186262 :         nBits = add( nBits, 1 );
     765     2186262 :         test();
     766     2186262 :         IF( GT_16( nBits, nSize ) || GT_16( nBits, 16 ) )
     767             :         {
     768           0 :             st->BER_detect = 1;
     769           0 :             move16();
     770           0 :             *pValue = 0;
     771           0 :             move16();
     772             : 
     773           0 :             return -1;
     774             :         }
     775             : 
     776    28270332 :         FOR( valueIndex = 0; valueIndex < nSize; valueIndex++ )
     777             :         {
     778             : 
     779    26911785 :             IF( s_and( (Word16) EQ_16( codes[valueIndex].nBits, nBits ), (Word16) EQ_16( codes[valueIndex].code, code ) ) )
     780             :             {
     781      827715 :                 BREAK;
     782             :             }
     783             :         }
     784             :     }
     785      827715 :     IF( LT_16( valueIndex, nSize ) )
     786             :     {
     787      827715 :         *pValue = (Word16) codes[valueIndex].value; /*Q0*/
     788      827715 :         move16();
     789             :     }
     790             :     ELSE
     791             :     {
     792           0 :         st->BER_detect = 1;
     793           0 :         move16();
     794           0 :         *pValue = 0;
     795           0 :         move16();
     796           0 :         return -1;
     797             :     }
     798             : 
     799      827715 :     return nBits; /*Q0*/
     800             : }
     801             : 
     802             : 
     803             : /* TNS filter coefficients */
     804             : 
     805      530167 : Word16 DecodeSWBTCX20TnsFilterCoeff_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
     806             : {
     807      530167 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     808      530167 :     return DecodeUsingTable( st, pValue, codesTnsCoeffSWBTCX20[index], nTnsCoeffCodes );
     809             : }
     810             : 
     811      155920 : Word16 DecodeSWBTCX10TnsFilterCoeff_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
     812             : {
     813      155920 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     814      155920 :     return DecodeUsingTable( st, pValue, codesTnsCoeffSWBTCX10[index], nTnsCoeffCodes );
     815             : }
     816             : 
     817       14523 : Word16 DecodeWBTCX20TnsFilterCoeff_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
     818             : {
     819       14523 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     820       14523 :     return DecodeUsingTable( st, pValue, codesTnsCoeffWBTCX20[index], nTnsCoeffCodes );
     821             : }
     822             : 
     823             : 
     824             : /* TNS filter order */
     825             : 
     826       92125 : Word16 DecodeTnsFilterOrderSWBTCX20_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
     827             : {
     828             :     (void) index;
     829       92125 :     return DecodeUsingTable( st, pValue, codesTnsOrderTCX20, nTnsOrderCodes );
     830             : }
     831             : 
     832           0 : Word16 GetTnsFilterOrderBitsSWBTCX10_flt( const Word16 value, const Word16 index )
     833             : {
     834             :     (void) index;
     835           0 :     return GetBitsFromTable( value - 1, codesTnsOrderTCX10, nTnsOrderCodes );
     836             : }
     837             : 
     838           0 : Word16 EncodeTnsFilterOrderSWBTCX10_flt( const Word16 value, const Word16 index )
     839             : {
     840             :     (void) index;
     841           0 :     return EncodeUsingTable( value - 1, codesTnsOrderTCX10, nTnsOrderCodes );
     842             : }
     843             : 
     844       32740 : Word16 DecodeTnsFilterOrderSWBTCX10_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
     845             : {
     846             :     (void) index;
     847       32740 :     return DecodeUsingTable( st, pValue, codesTnsOrderTCX10, nTnsOrderCodes );
     848             : }
     849             : 
     850             : 
     851      728337 : void const *GetTnsFilterCoeff( void const *p, const Word16 index /*Q0*/, Word16 *pValue /*Q0*/ )
     852             : {
     853      728337 :     *pValue = ( (Word16 const *) p )[index] + INDEX_SHIFT;
     854      728337 :     move16();
     855      728337 :     return NULL;
     856             : }
     857             : 
     858      719349 : void *SetTnsFilterCoeff( void *p, const Word16 index /*Q0*/, const Word16 value /*Q0*/ )
     859             : {
     860      719349 :     ( (Word16 *) p )[index] = sub( value, INDEX_SHIFT );
     861      719349 :     move16();
     862      719349 :     return NULL;
     863             : }
     864             : 
     865             : 
     866     1086857 : Word16 GetSWBTCX20TnsFilterCoeffBits( const Word16 value, const Word16 index )
     867             : {
     868     1086857 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     869             : 
     870     1086857 :     return GetBitsFromTable( value, codesTnsCoeffSWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
     871             : }
     872             : 
     873      536289 : Word16 EncodeSWBTCX20TnsFilterCoeff( const Word16 value, const Word16 index )
     874             : {
     875      536289 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     876             : 
     877      536289 :     return EncodeUsingTable( value, codesTnsCoeffSWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
     878             : }
     879             : 
     880           0 : Word16 DecodeSWBTCX20TnsFilterCoeff( Decoder_State *st, const Word16 index, Word16 *pValue )
     881             : {
     882           0 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     883             : 
     884           0 :     return DecodeUsingTable( st, pValue, codesTnsCoeffSWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
     885             : }
     886             : 
     887      321134 : Word16 GetSWBTCX10TnsFilterCoeffBits( const Word16 value, const Word16 index )
     888             : {
     889      321134 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     890             : 
     891      321134 :     return GetBitsFromTable( value, codesTnsCoeffSWBTCX10[index], nTnsCoeffCodes ); /*Q0*/
     892             : }
     893             : 
     894      158369 : Word16 EncodeSWBTCX10TnsFilterCoeff( const Word16 value, const Word16 index )
     895             : {
     896      158369 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     897             : 
     898      158369 :     return EncodeUsingTable( value, codesTnsCoeffSWBTCX10[index], nTnsCoeffCodes ); /*Q0*/
     899             : }
     900             : 
     901           0 : Word16 DecodeSWBTCX10TnsFilterCoeff( Decoder_State *st, const Word16 index, Word16 *pValue )
     902             : {
     903           0 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     904             : 
     905           0 :     return DecodeUsingTable( st, pValue, codesTnsCoeffSWBTCX10[index], nTnsCoeffCodes ); /*Q0*/
     906             : }
     907             : 
     908       29960 : Word16 GetWBTCX20TnsFilterCoeffBits( const Word16 value, const Word16 index )
     909             : {
     910       29960 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     911             : 
     912       29960 :     return GetBitsFromTable( value, codesTnsCoeffWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
     913             : }
     914             : 
     915       14956 : Word16 EncodeWBTCX20TnsFilterCoeff( const Word16 value, const Word16 index )
     916             : {
     917       14956 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     918             : 
     919       14956 :     return EncodeUsingTable( value, codesTnsCoeffWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
     920             : }
     921             : 
     922           0 : Word16 DecodeWBTCX20TnsFilterCoeff( Decoder_State *st, const Word16 index, Word16 *pValue )
     923             : {
     924           0 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     925             : 
     926           0 :     return DecodeUsingTable( st, pValue, codesTnsCoeffWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
     927             : }
     928             : 
     929             : 
     930             : /* TNS filter order */
     931             : 
     932      132667 : void const *GetTnsFilterOrder( void const *p, const Word16 index, Word16 *pValue )
     933             : {
     934      132667 :     move16();
     935      132667 :     *pValue = ( (STnsFilter const *) p )[index].order; /*Q0*/
     936             : 
     937      132667 :     move16();
     938      132667 :     return ( (STnsFilter const *) p )[index].coefIndex; /*Q0*/
     939             : }
     940             : 
     941      130935 : void *SetTnsFilterOrder( void *p, const Word16 index, const Word16 value )
     942             : {
     943      130935 :     move16();
     944      130935 :     ( (STnsFilter *) p )[index].order = value; /*Q0*/
     945             : 
     946      130935 :     move16();
     947      130935 :     return ( (STnsFilter *) p )[index].coefIndex; /*Q0*/
     948             : }
     949             : 
     950      189210 : Word16 GetTnsFilterOrderBitsSWBTCX20( const Word16 value, const Word16 index )
     951             : {
     952             :     (void) index;
     953             : 
     954      189210 :     return GetBitsFromTable( sub( value, 1 ), codesTnsOrderTCX20, nTnsOrderCodes ); /*Q0*/
     955             : }
     956             : 
     957       93236 : Word16 EncodeTnsFilterOrderSWBTCX20( const Word16 value, const Word16 index )
     958             : {
     959             :     (void) index;
     960             : 
     961       93236 :     return EncodeUsingTable( sub( value, 1 ), codesTnsOrderTCX20, nTnsOrderCodes ); /*Q0*/
     962             : }
     963             : 
     964           0 : Word16 DecodeTnsFilterOrderSWBTCX20( Decoder_State *st, const Word16 index, Word16 *pValue )
     965             : {
     966             :     (void) index;
     967             : 
     968           0 :     return DecodeUsingTable( st, pValue, codesTnsOrderTCX20, nTnsOrderCodes ); /*Q0*/
     969             : }
     970             : 
     971       67655 : Word16 GetTnsFilterOrderBitsSWBTCX10( const Word16 value, const Word16 index )
     972             : {
     973             :     (void) index;
     974             : 
     975       67655 :     return GetBitsFromTable( sub( value, 1 ), codesTnsOrderTCX10, nTnsOrderCodes ); /*Q0*/
     976             : }
     977             : 
     978       33279 : Word16 EncodeTnsFilterOrderSWBTCX10( const Word16 value, const Word16 index )
     979             : {
     980             :     (void) index;
     981             : 
     982       33279 :     return EncodeUsingTable( sub( value, 1 ), codesTnsOrderTCX10, nTnsOrderCodes ); /*Q0*/
     983             : }
     984             : 
     985           0 : Word16 DecodeTnsFilterOrderSWBTCX10( Decoder_State *st, const Word16 index, Word16 *pValue )
     986             : {
     987             :     (void) index;
     988             : 
     989           0 :     return DecodeUsingTable( st, pValue, codesTnsOrderTCX10, nTnsOrderCodes ); /*Q0*/
     990             : }
     991             : 
     992        4625 : Word16 GetTnsFilterOrderBits( const Word16 value, const Word16 index )
     993             : {
     994             :     (void) index;
     995             : 
     996        4625 :     return GetBitsFromTable( sub( value, 1 ), codesTnsOrder, nTnsOrderCodes ); /*Q0*/
     997             : }
     998             : 
     999        2308 : Word16 EncodeTnsFilterOrder( const Word16 value, const Word16 index )
    1000             : {
    1001             :     (void) index;
    1002             : 
    1003        2308 :     return EncodeUsingTable( sub( value, 1 ), codesTnsOrder, nTnsOrderCodes ); /*Q0*/
    1004             : }
    1005             : 
    1006           0 : Word16 DecodeTnsFilterOrder( Decoder_State *st, const Word16 index, Word16 *pValue )
    1007             : {
    1008             :     (void) index;
    1009             : 
    1010           0 :     return DecodeUsingTable( st, pValue, codesTnsOrder, nTnsOrderCodes ); /*Q0*/
    1011             : }
    1012             : 
    1013             : /* Number of TNS filters */
    1014             : 
    1015           0 : void const *GetNumOfTnsFilters( void const *p, const Word16 index, Word16 *pValue )
    1016             : {
    1017           0 :     move16();
    1018           0 :     *pValue = ( (STnsData const *) p )[index].nFilters; /*Q0*/
    1019           0 :     move16();
    1020           0 :     return ( (STnsData const *) p )[index].filter;
    1021             : }
    1022             : 
    1023           0 : void *SetNumOfTnsFilters( void *p, const Word16 index, Word16 value )
    1024             : {
    1025           0 :     move16();
    1026           0 :     ( (STnsData *) p )[index].nFilters = value; /*Q0*/
    1027           0 :     move16();
    1028           0 :     return ( (STnsData *) p )[index].filter;
    1029             : }
    1030             : 
    1031             : /* TNS enabled/disabled flag */
    1032             : 
    1033     1427667 : void const *GetTnsEnabled( void const *p, const Word16 index, Word16 *pValue )
    1034             : {
    1035     1427667 :     move16();
    1036     1427667 :     *pValue = 0;
    1037     1427667 :     if ( ( (STnsData const *) p )[index].nFilters != 0 )
    1038             :     {
    1039       98912 :         move16();
    1040       98912 :         *pValue = 1;
    1041             :     }
    1042     1427667 :     return NULL;
    1043             : }
    1044             : 
    1045      776024 : void *SetTnsEnabled( void *p, const Word16 index, const Word16 value )
    1046             : {
    1047             :     (void) p, (void) index, (void) value;
    1048      776024 :     return NULL;
    1049             : }
    1050             : 
    1051             : /* Number of TNS filters */
    1052             : 
    1053       98912 : void const *GetNumOfTnsFilters_flt( void const *p, const Word16 index, Word16 *pValue )
    1054             : {
    1055       98912 :     *pValue = (Word16) abs( ( (STnsData const *) p )[index].nFilters );
    1056       98912 :     return ( (STnsData const *) p )[index].filter;
    1057             : }
    1058             : 
    1059       97711 : void *SetNumOfTnsFilters_flt( void *p, const Word16 index, const Word16 value )
    1060             : {
    1061       97711 :     ( (STnsData *) p )[index].nFilters = (Word16) abs( value );
    1062       97711 :     return ( (STnsData *) p )[index].filter;
    1063             : }
    1064        2240 : Word16 DecodeTnsFilterOrder_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
    1065             : {
    1066             :     (void) index;
    1067        2240 :     return DecodeUsingTable( st, pValue, codesTnsOrder, nTnsOrderCodes );
    1068             : }
    1069             : /* TNS on whitened spectra  flag */
    1070             : 
    1071       77776 : void const *GetTnsOnWhite( void const *p, const Word16 index, Word16 *pValue )
    1072             : {
    1073       77776 :     *pValue = ( (STnsData const *) p )[index].tnsOnWhitenedSpectra > 0 ? 1 : 0;
    1074       77776 :     return NULL;
    1075             : }
    1076             : 
    1077       76890 : void *SetTnsOnWhite( void *p, const Word16 index, const Word16 value )
    1078             : {
    1079       76890 :     ( (STnsData *) p )[index].tnsOnWhitenedSpectra = value;
    1080       76890 :     return NULL;
    1081             : }
    1082             : 
    1083      187501 : void const *GetTnsEnabledSingleFilter( void const *p, const Word16 index, Word16 *pValue )
    1084             : {
    1085      187501 :     move16();
    1086      187501 :     *pValue = 0;
    1087      187501 :     if ( ( (STnsData const *) p )[index].nFilters > 0 )
    1088             :     {
    1089        2317 :         move16();
    1090        2317 :         *pValue = 1;
    1091             :     }
    1092      187501 :     return ( (STnsData const *) p )[index].filter;
    1093             : }
    1094             : 
    1095      120315 : void *SetTnsEnabledSingleFilter( void *p, const Word16 index, const Word16 value )
    1096             : {
    1097      120315 :     ( (STnsData *) p )[index].nFilters = value; /*Q0*/
    1098      120315 :     move16();
    1099      120315 :     return ( (STnsData *) p )[index].filter;
    1100             : }
    1101             : 
    1102             : /*-------------------------------------------------------------------*
    1103             :  * ResetTnsData()
    1104             :  *
    1105             :  *-------------------------------------------------------------------*/
    1106             : 
    1107     2511507 : void ResetTnsData( STnsData *pTnsData )
    1108             : {
    1109             :     Word16 iFilter;
    1110             : 
    1111             : 
    1112     2511507 :     pTnsData->nFilters = 0;
    1113     2511507 :     move16();
    1114     2511507 :     pTnsData->tnsOnWhitenedSpectra = 0;
    1115     2511507 :     move16();
    1116     7534521 :     FOR( iFilter = 0; iFilter < (Word16) ( sizeof( pTnsData->filter ) / sizeof( pTnsData->filter[0] ) ); iFilter++ )
    1117             :     {
    1118     5023014 :         STnsFilter *const pTnsFilter = &pTnsData->filter[iFilter];
    1119     5023014 :         pTnsFilter->spectrumLength = 0;
    1120     5023014 :         move16();
    1121     5023014 :         pTnsFilter->predictionGain = ONE_IN_Q7; /*Q7*/
    1122     5023014 :         move16();
    1123     5023014 :         pTnsFilter->predictionGain32 = ONE_IN_Q23; /*Q23*/
    1124     5023014 :         move32();
    1125     5023014 :         pTnsFilter->predictionGain_e = PRED_GAIN_E;
    1126     5023014 :         move16();
    1127     5023014 :         pTnsFilter->avgSqrCoef = 0;
    1128     5023014 :         move16();
    1129     5023014 :         pTnsFilter->filterType = TNS_FILTER_OFF; /*Q0*/
    1130     5023014 :         move16();
    1131     5023014 :         ClearTnsFilterCoefficients( pTnsFilter );
    1132             :     }
    1133     2511507 : }
    1134             : /*-------------------------------------------------------------------*
    1135             :  * ClearTnsFilterCoefficients()
    1136             :  *
    1137             :  *-------------------------------------------------------------------*/
    1138             : 
    1139     9286052 : void ClearTnsFilterCoefficients(
    1140             :     STnsFilter *pTnsFilter )
    1141             : {
    1142     9286052 :     move16();
    1143     9286052 :     pTnsFilter->order = 0;
    1144     9286052 :     move16();
    1145             :     assert( TNS_MAX_FILTER_ORDER == 8 );
    1146     9286052 :     move16();
    1147     9286052 :     move16();
    1148     9286052 :     move16();
    1149     9286052 :     move16();
    1150     9286052 :     move16();
    1151     9286052 :     move16();
    1152     9286052 :     move16();
    1153     9286052 :     move16();
    1154     9286052 :     pTnsFilter->coefIndex[0] = 0;
    1155     9286052 :     pTnsFilter->coefIndex[1] = 0;
    1156     9286052 :     pTnsFilter->coefIndex[2] = 0;
    1157     9286052 :     pTnsFilter->coefIndex[3] = 0;
    1158     9286052 :     pTnsFilter->coefIndex[4] = 0;
    1159     9286052 :     pTnsFilter->coefIndex[5] = 0;
    1160     9286052 :     pTnsFilter->coefIndex[6] = 0;
    1161     9286052 :     pTnsFilter->coefIndex[7] = 0;
    1162     9286052 : }
    1163             : 
    1164             : /** Inverse quantization for reflection coefficients.
    1165             :  *
    1166             :  * @param index input quantized values.
    1167             :  * @param parCoeff output reflection coefficients.
    1168             :  * @param order number of coefficients/values.
    1169             :  */
    1170      440880 : static void Index2Parcor( const Word16 index[] /*Q0*/, Word16 parCoeff[] /*Q15*/, Word16 order /*Q0*/ )
    1171             : {
    1172             :     const Word16 *values;
    1173             :     Word16 i;
    1174             : 
    1175      440880 :     move16();
    1176      440880 :     values = tnsCoeff4; /*Q15*/
    1177             : 
    1178     2065763 :     FOR( i = 0; i < order; i++ )
    1179             :     {
    1180     1624883 :         move16();
    1181     1624883 :         parCoeff[i] = values[( index[i] + INDEX_SHIFT )]; /*Q15*/
    1182             :     }
    1183      440880 :     return;
    1184             : }
    1185             : 
    1186             : 
    1187             : /* Linear prediction analysis filter. */
    1188    58669844 : static Word32 FIRLattice(
    1189             :     const Word16 order, /*Q0*/
    1190             :     const Word16 *parCoeff /*Q15*/,
    1191             :     Word32 *state, /*Q0*/
    1192             :     Word32 x       /* Q0 */
    1193             : )
    1194             : {
    1195             :     Word16 i;
    1196             :     Word32 tmpSave, tmp;
    1197             : 
    1198             : 
    1199    58669844 :     tmpSave = x;
    1200    58669844 :     move32();
    1201   325565693 :     FOR( i = 0; i < order - 1; i++ )
    1202             :     {
    1203   266895849 :         tmp = Madd_32_16( state[i], x, parCoeff[i] ); /*Q0*/
    1204   266895849 :         x = Madd_32_16( x, state[i], parCoeff[i] );   /* exponent: 31+0 */
    1205   266895849 :         state[i] = tmpSave;                           /*Q0*/
    1206   266895849 :         move32();
    1207   266895849 :         tmpSave = tmp; /*Q0*/
    1208   266895849 :         move32();
    1209             :     }
    1210             : 
    1211             :     /* last stage: only need half operations */
    1212    58669844 :     x = Madd_32_16( x, state[order - 1], parCoeff[order - 1] ); /*Q0*/
    1213    58669844 :     state[order - 1] = tmpSave;                                 /*Q0*/
    1214    58669844 :     move32();
    1215             : 
    1216    58669844 :     return x; /*Q0*/
    1217             : }
    1218             : 
    1219    72274095 : static Word32 IIRLattice( Word16 order /*Q0*/, const Word16 *parCoeff /*Q15*/, Word32 *state /*Q0*/, Word32 x /*Q0*/ )
    1220             : {
    1221             :     Word16 i;
    1222             : 
    1223             : 
    1224             :     /* first stage: no need to calculate state[order-1] */
    1225    72274095 :     x = Msub_32_16( x, state[order - 1], parCoeff[order - 1] ); /*Q0*/
    1226             : 
    1227   397481420 :     FOR( i = order - 2; i >= 0; i-- )
    1228             :     {
    1229   325207325 :         x = Msub_32_16( x, state[i], parCoeff[i] );            /*Q0*/
    1230   325207325 :         state[i + 1] = Madd_32_16( state[i], x, parCoeff[i] ); /*Q0*/
    1231   325207325 :         move32();
    1232             :     }
    1233             : 
    1234    72274095 :     move32();
    1235    72274095 :     state[0] = x; /*Q0*/
    1236    72274095 :     return x;     /*Q0*/
    1237             : }
    1238             : /** TNS analysis/synthesis filter.
    1239             :   * @param spectrum input spectrum values.
    1240             :   * @param numOfLines number of lines in the spectrum.
    1241             :   * @param parCoeff filter (PARCOR) coefficients.
    1242             :   * @param order filter order.
    1243             :   * @param filter function that implements filtering.
    1244             :     By this function it is defined whether analysis or synthesis is performed.
    1245             :   * @param output filtered output spectrum values.
    1246             :     Inplace operation is supported, so it can be equal to spectrum.
    1247             :   */
    1248      440880 : static void TnsFilter(
    1249             :     const Word32 spectrum[], /*Qx*/
    1250             :     const Word16 numOfLines, /*Q0*/
    1251             :     const Word16 parCoeff[], /*Q15*/
    1252             :     const Word16 order,      /*Q0*/
    1253             :     TLinearPredictionFilter filter,
    1254             :     Word32 *state, /*Q0*/
    1255             :     Word32 output[] /*Qx*/ )
    1256             : {
    1257             :     Word16 j;
    1258             : 
    1259             : 
    1260      440880 :     assert( ( order >= 0 ) && ( order <= TNS_MAX_FILTER_ORDER ) );
    1261      440880 :     assert( ( numOfLines > 0 ) || ( ( numOfLines == 0 ) && ( order == 0 ) ) );
    1262             : 
    1263      440880 :     IF( order == 0 )
    1264             :     {
    1265             : 
    1266      144959 :         test();
    1267      144959 :         IF( s_and( ( spectrum != output ), numOfLines > 0 ) )
    1268             :         {
    1269           0 :             Copy32( spectrum, output, numOfLines ); /*Qx*/
    1270             :         }
    1271             :     }
    1272             :     ELSE
    1273             :     {
    1274             :         {
    1275             : 
    1276   131239860 :             FOR( j = 0; j < numOfLines; j++ )
    1277             :             {
    1278   130943939 :                 move32();
    1279   130943939 :                 output[j] = filter( order, parCoeff, state, spectrum[j] ); /*Qx*/
    1280             :             }
    1281             :         }
    1282             :     }
    1283      440880 :     return;
    1284             : }
    1285             : 
    1286      596014 : static void ITF_TnsFilter_fx(
    1287             :     const Word32 spectrum[], /*Qx*/
    1288             :     const Word16 numOfLines, /*Q0*/
    1289             :     const Word16 A[],        /* ifdef FIX_ITF_OVERFLOW Q_A else Q14 */
    1290             :     const Word16 Q_A,
    1291             :     const Word16 order, /*Q0*/
    1292             :     Word32 output[] /*Qx*/ )
    1293             : {
    1294             :     Word16 i, j;
    1295             :     Word32 buf[ITF_MAX_FILTER_ORDER + N_MAX];
    1296             :     Word32 *p;
    1297             :     Word16 shift;
    1298      596014 :     assert( ( order >= 0 ) && ( order <= ITF_MAX_FILTER_ORDER ) );
    1299      596014 :     assert( ( numOfLines > 0 ) || ( ( numOfLines == 0 ) && ( order == 0 ) ) );
    1300             : 
    1301      596014 :     IF( order == 0 )
    1302             :     {
    1303             : 
    1304      502101 :         test();
    1305      502101 :         IF( s_and( ( spectrum != output ), numOfLines > 0 ) )
    1306             :         {
    1307           0 :             Copy32( spectrum, output, numOfLines ); /*Qx*/
    1308             :         }
    1309             :     }
    1310             :     ELSE
    1311             :     {
    1312       93913 :         shift = sub( 15, Q_A );
    1313             : 
    1314       93913 :         p = buf + ITF_MAX_FILTER_ORDER;
    1315       93913 :         set32_fx( buf, 0, ITF_MAX_FILTER_ORDER );
    1316       93913 :         Copy32( spectrum, p, numOfLines ); /*Qx*/
    1317    31822247 :         FOR( j = 0; j < numOfLines; j++ )
    1318             :         {
    1319             :             Word32 L_tmp;
    1320             : 
    1321    31728334 :             L_tmp = L_add( p[0], 0 );
    1322   253826672 :             FOR( i = 1; i < order; i++ )
    1323             :             {
    1324   222098338 :                 L_tmp = L_add_sat( L_tmp, L_shl( Mpy_32_16_1( p[-i], A[i] ), shift ) ); /*Qx*/
    1325             :             }
    1326    31728334 :             output[j] = L_tmp; /*Qx*/
    1327    31728334 :             move32();
    1328    31728334 :             ++p;
    1329             :         }
    1330             :     }
    1331      596014 :     return;
    1332             : }
    1333             : 
    1334      222894 : static void ITF_GetFilterParameters_fx(
    1335             :     Word32 rxx[],          /*Qx*/
    1336             :     const Word16 maxOrder, /*Q0*/
    1337             :     Word16 *A,             /* ifdef FIX_ITF_OVERFLOW Q_A else Q14 */
    1338             :     Word16 *Q_A,
    1339             :     Word16 *predictionGain /*Q7*/ )
    1340             : {
    1341             :     Word16 i, j, i_2, tmp;
    1342             :     Word16 parCoeff[ITF_MAX_FILTER_ORDER];
    1343             :     Word32 epsP[ITF_MAX_FILTER_ORDER + 1], L_tmp;
    1344             : 
    1345             :     /* compute filter in ParCor form with LeRoux-Gueguen algorithm */
    1346      222894 :     L_tmp = E_LPC_schur( rxx, parCoeff, epsP, maxOrder );
    1347             :     BASOP_SATURATE_WARNING_OFF_EVS                                            /* Allow saturation, this value is compared against a threshold. */
    1348      222894 :         *predictionGain = divide3232( L_shr( epsP[0], PRED_GAIN_E ), L_tmp ); /*Q7*/
    1349      222894 :     move16();
    1350             :     BASOP_SATURATE_WARNING_ON_EVS
    1351             : 
    1352             :     {
    1353             :         Word32 A32[ITF_MAX_FILTER_ORDER];
    1354             :         Word16 tmp1_l, tmp1_h, tmp2_l, tmp2_h;
    1355             : 
    1356             :         /* Convert ParCor / reflection coefficients to LPC */
    1357      222894 :         A32[0] = 134217728l /*1.0 Q27*/;
    1358      222894 :         move32();                                        /* Q11+16 */
    1359      222894 :         A32[1] = L_shr( L_deposit_h( parCoeff[0] ), 4 ); /* Q11+16 */
    1360      222894 :         move32();
    1361             : 
    1362     1783152 :         FOR( i = 1; i < maxOrder; i++ )
    1363             :         {
    1364     1560258 :             L_tmp = L_shr( L_deposit_h( parCoeff[i] ), 3 ); /* Q11+16 */
    1365             : 
    1366     1560258 :             i_2 = shr( i, 1 );
    1367     4234986 :             FOR( j = 0; j < i_2; j++ )
    1368             :             {
    1369     2674728 :                 tmp1_l = L_Extract_lc( A32[i - 1 - j + 1], &tmp1_h );
    1370     2674728 :                 tmp2_l = L_Extract_lc( A32[j + 1], &tmp2_h );
    1371     2674728 :                 A32[j + 1] = Mac_32( A32[j + 1], parCoeff[i], 0, tmp1_h, tmp1_l ); /*+= parCoeff[i] * a[i-1-j+1]; Q11+16*/
    1372     2674728 :                 move32();
    1373     2674728 :                 A32[i - 1 - j + 1] = Mac_32( A32[i - 1 - j + 1], parCoeff[i], 0, tmp2_h, tmp2_l ); /*+= parCoeff[i] * tmp; Q11+16*/
    1374     2674728 :                 move32();
    1375             :             }
    1376     1560258 :             IF( s_and( i, 1 ) )
    1377             :             {
    1378      891576 :                 tmp2_l = L_Extract_lc( A32[j + 1], &tmp2_h );
    1379      891576 :                 A32[j + 1] = Mac_32( A32[j + 1], parCoeff[i], 0, tmp2_h, tmp2_l ); /*+= parCoeff[i] * a[j+1]; Q11+16*/
    1380      891576 :                 move32();
    1381             :             }
    1382             : 
    1383     1560258 :             A32[i + 1] = L_shr( L_deposit_h( parCoeff[i] ), 4 ); /* Q11+16 */
    1384     1560258 :             move32();
    1385             :         }
    1386             : 
    1387      222894 :         tmp = 3;
    1388      222894 :         move16(); /* assume Q11 -> Q14 */
    1389     2006046 :         FOR( i = 0; i < maxOrder; i++ )
    1390             :         {
    1391     1783152 :             tmp = s_min( tmp, norm_l( A32[i] ) );
    1392             :         }
    1393     2006046 :         FOR( i = 0; i < maxOrder; i++ )
    1394             :         {
    1395     1783152 :             A[i] = round_fx( L_shl( A32[i], tmp ) ); /* Q11+tmp */
    1396     1783152 :             move16();
    1397             :         }
    1398      222894 :         *Q_A = add( 11, tmp );
    1399      222894 :         move16();
    1400             :     }
    1401      222894 :     return;
    1402             : }

Generated by: LCOV version 1.14