LCOV - code coverage report
Current view: top level - lib_com - tns_base.c (source / functions) Hit Total Coverage
Test: Coverage on main @ b9bfbe380d1c207f5198ba67a82398b3d313550e Lines: 533 578 92.2 %
Date: 2025-11-15 04:01:59 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       87022 : 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       87022 :     Word16 iFilter = 0;
      92       87022 :     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       87022 :     nSampleRate = bwMode2fs[bwidth];
     101       87022 :     move32();
     102       87022 :     startLineFilter = &pTnsConfig->iFilterBorders[1];
     103             : 
     104             :     /* Sanity checks */
     105       87022 :     assert( ( nSampleRate > 0 ) && ( frameLength > 0 ) && ( pTnsConfig != NULL ) );
     106       87022 :     test();
     107       87022 :     test();
     108       87022 :     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       87022 :     move16();
     116       87022 :     pTnsConfig->maxOrder = TNS_MAX_FILTER_ORDER;
     117             : 
     118       87022 :     IF( LE_32( total_brate, ACELP_32k ) )
     119             :     {
     120       14026 :         move16();
     121       14026 :         move16();
     122       14026 :         pTnsConfig->nMaxFilters = sizeof( tnsParametersIGF32kHz_LowBR ) / sizeof( tnsParametersIGF32kHz_LowBR[0] );
     123       14026 :         pTnsConfig->pTnsParameters = tnsParametersIGF32kHz_LowBR;
     124             :     }
     125             :     ELSE
     126             :     {
     127       72996 :         test();
     128       72996 :         IF( GT_32( nSampleRate, 32000 ) && EQ_32( nSampleRate, L_mult0( 100, frameLength ) ) )
     129             :         {
     130       19802 :             move16();
     131       19802 :             pTnsConfig->nMaxFilters = sizeof( tnsParameters48kHz_grouped ) / sizeof( tnsParameters48kHz_grouped[0] );
     132       19802 :             move16();
     133       19802 :             pTnsConfig->pTnsParameters = tnsParameters48kHz_grouped;
     134             :         }
     135             :         ELSE
     136       53194 :         IF( GT_32( nSampleRate, INT_FS_16k ) )
     137             :         {
     138             :             {
     139             : 
     140       50227 :                 move16();
     141       50227 :                 pTnsConfig->nMaxFilters = sizeof( tnsParameters32kHz ) / sizeof( tnsParameters32kHz[0] );
     142             : 
     143       50227 :                 move16();
     144       50227 :                 pTnsConfig->pTnsParameters = tnsParameters32kHz;
     145             : 
     146       50227 :                 if ( EQ_32( nSampleRate, L_mult0( 100, frameLength ) ) ) /* sub-frame length is <= 10 ms */
     147             :                 {
     148        3541 :                     move16();
     149        3541 :                     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       87022 :     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      245062 :     FOR( iFilter = 0; iFilter < pTnsConfig->nMaxFilters; iFilter++ )
     176             :     {
     177      158040 :         assert( pTnsConfig->pTnsParameters[iFilter].startLineFrequency < nSampleRate / 2 );
     178      158040 :         assert( nSampleRate <= 96000 );
     179      158040 :         move16();
     180      158040 :         startLineFilter[iFilter] = divide3232( L_mult0( frameLength, pTnsConfig->pTnsParameters[iFilter].startLineFrequency ), L_shl( nSampleRate, 14 ) );
     181             :     }
     182             : 
     183       87022 :     IF( igfStopFreq > 0 )
     184             :     {
     185       69394 :         L_tmp = L_mult( frameLength, igfStopFreq );
     186       69394 :         s1 = sub( norm_l( L_tmp ), 1 );
     187       69394 :         s2 = norm_l( nSampleRate );
     188             : 
     189       69394 :         move16();
     190       69394 :         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       17628 :         move16();
     195       17628 :         pTnsConfig->iFilterBorders[0] = frameLength;
     196             :     }
     197       87022 :     return; /*TNS_NO_ERROR;*/
     198             : }
     199             : 
     200      137153 : 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      137153 :     Word16 iFilter = 0;
     210      137153 :     move16();
     211             :     Word16 *startLineFilter;
     212             :     Word32 L_tmp;
     213             :     Word32 nSampleRate;
     214             :     Word16 s1;
     215             :     Word16 s2;
     216             : 
     217      137153 :     nSampleRate = bwMode2fs[bwidth];
     218      137153 :     move32();
     219      137153 :     startLineFilter = &pTnsConfig->iFilterBorders[1]; /*Q0*/
     220             : 
     221             :     /* Sanity checks */
     222      137153 :     assert( ( nSampleRate > 0 ) && ( frameLength > 0 ) && ( pTnsConfig != NULL ) );
     223      137153 :     test();
     224      137153 :     test();
     225      137153 :     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      137153 :     move16();
     233      137153 :     pTnsConfig->maxOrder = TNS_MAX_FILTER_ORDER;
     234             : 
     235      137153 :     IF( LE_32( total_brate, ACELP_32k ) )
     236             :     {
     237       34322 :         move16();
     238       34322 :         pTnsConfig->nMaxFilters = (UWord8) idiv1616( sizeof( tnsParametersIGF32kHz_LowBR ), sizeof( tnsParametersIGF32kHz_LowBR[0] ) ); /*Q0*/
     239       34322 :         pTnsConfig->pTnsParameters = tnsParametersIGF32kHz_LowBR;
     240             :     }
     241             :     ELSE
     242             :     {
     243      102831 :         test();
     244      102831 :         IF( GT_32( nSampleRate, 32000 ) && EQ_32( nSampleRate, L_mult0( 100, frameLength ) ) )
     245             :         {
     246       28251 :             pTnsConfig->nMaxFilters = (UWord8) idiv1616( sizeof( tnsParameters48kHz_grouped ), sizeof( tnsParameters48kHz_grouped[0] ) ); /*Q0*/
     247       28251 :             move16();
     248       28251 :             pTnsConfig->pTnsParameters = tnsParameters48kHz_grouped;
     249             :         }
     250       74580 :         ELSE IF( GT_32( nSampleRate, INT_FS_16k ) )
     251             :         {
     252       70935 :             L_tmp = IVAS_32k;
     253       70935 :             move32();
     254       70935 :             if ( !is_mct )
     255             :             {
     256       50645 :                 L_tmp = IVAS_48k;
     257       50645 :                 move32();
     258             :             }
     259       70935 :             test();
     260       70935 :             IF( GT_16( element_mode, IVAS_SCE ) && GE_32( total_brate, L_tmp ) )
     261             :             {
     262       53114 :                 pTnsConfig->nMaxFilters = (UWord8) idiv1616( sizeof( tnsParameters32kHz_Stereo ), sizeof( tnsParameters32kHz_Stereo[0] ) ); /*Q0*/
     263       53114 :                 move16();
     264       53114 :                 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       48700 :                     pTnsConfig->pTnsParameters = tnsParameters32kHz_Stereo;
     271             :                 }
     272             :             }
     273             :             ELSE
     274             :             {
     275             : 
     276       17821 :                 move16();
     277       17821 :                 pTnsConfig->nMaxFilters = (UWord8) idiv1616( sizeof( tnsParameters32kHz ), sizeof( tnsParameters32kHz[0] ) ); /*Q0*/
     278             : 
     279       17821 :                 pTnsConfig->pTnsParameters = tnsParameters32kHz;
     280             : 
     281       17821 :                 if ( EQ_32( nSampleRate, L_mult0( 100, frameLength ) ) ) /* sub-frame length is <= 10 ms */
     282             :                 {
     283         397 :                     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      137153 :     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      374707 :     FOR( iFilter = 0; iFilter < pTnsConfig->nMaxFilters; iFilter++ )
     309             :     {
     310      237554 :         assert( pTnsConfig->pTnsParameters[iFilter].startLineFrequency < nSampleRate / 2 );
     311      237554 :         assert( nSampleRate <= 96000 );
     312      237554 :         move16();
     313      237554 :         startLineFilter[iFilter] = divide3232( L_mult0( frameLength, pTnsConfig->pTnsParameters[iFilter].startLineFrequency ), L_shl( nSampleRate, 14 ) ); /*Q0*/
     314             :     }
     315             : 
     316      137153 :     IF( igfStopFreq > 0 )
     317             :     {
     318      113918 :         L_tmp = L_mult( frameLength, igfStopFreq );
     319      113918 :         s1 = sub( norm_l( L_tmp ), 1 );
     320      113918 :         s2 = norm_l( nSampleRate );
     321             : 
     322      113918 :         move16();
     323      113918 :         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       23235 :         move16();
     328       23235 :         pTnsConfig->iFilterBorders[0] = frameLength; /*Q0*/
     329             :     }
     330             : 
     331      137153 :     pTnsConfig->allowTnsOnWhite = 0;
     332      137153 :     move16();
     333             : 
     334      137153 :     return; /*TNS_NO_ERROR;*/
     335             : }
     336             : 
     337             : 
     338             : /*-------------------------------------------------------------------*
     339             :  * ApplyTnsFilter()
     340             :  *
     341             :  *-------------------------------------------------------------------*/
     342             : 
     343      234600 : 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      234600 :     move16();
     357      234600 :     filter = IIRLattice;
     358      234600 :     if ( fIsAnalysis )
     359             :     {
     360      106082 :         filter = FIRLattice;
     361             :     }
     362      234600 :     set32_fx( state, 0, TNS_MAX_FILTER_ORDER );
     363      234600 :     move16();
     364      234600 :     pBorders = pTnsConfig->iFilterBorders; /*Q0*/
     365             : 
     366      696821 :     FOR( iFilter = pTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
     367             :     {
     368             :         Word16 parCoeff[TNS_MAX_FILTER_ORDER];
     369             :         const STnsFilter *pFilter;
     370             : 
     371      462221 :         move16();
     372      462221 :         move16();
     373      462221 :         pFilter = &pTnsData->filter[iFilter];
     374      462221 :         stopLine = pBorders[iFilter];
     375      462221 :         startLine = pBorders[iFilter + 1];
     376             : 
     377      462221 :         Index2Parcor( pFilter->coefIndex, parCoeff, pFilter->order );
     378             : 
     379      462221 :         TnsFilter( &spectrum[startLine], stopLine - startLine,
     380      462221 :                    parCoeff, pFilter->order,
     381             :                    filter, state,
     382      462221 :                    &spectrum[startLine] );
     383             :     }
     384             : 
     385      234600 :     move16();
     386             : 
     387      234600 :     return /*result*/;
     388             : }
     389             : 
     390             : /*-------------------------------------------------------------------*
     391             :  * ITF_Apply()
     392             :  *
     393             :  *-------------------------------------------------------------------*/
     394             : 
     395      614613 : 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      614613 :     ITF_TnsFilter_fx( &spectrum[startLine], sub( stopLine, startLine ), A, Q_A, order, &spectrum[startLine] );
     405             : 
     406      614613 :     return /*TNS_NO_ERROR*/;
     407             : }
     408             : /*-------------------------------------------------------------------*
     409             :  * ITF_Detect()
     410             :  *
     411             :  *
     412             :  *-------------------------------------------------------------------*/
     413             : 
     414        2477 : 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        2477 :     Word16 const nSubdivisions = MAX_SUBDIVISIONS;
     428        2477 :     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        2477 :     move16();
     442        2477 :     move16();
     443        2477 :     move16();
     444             : 
     445        2477 :     if ( maxOrder <= 0 )
     446             :     {
     447           0 :         return 0;
     448             :     }
     449             : 
     450             :     /* Calculate norms for each spectrum part */
     451        9908 :     FOR( iSubdivisions = 0; iSubdivisions < nSubdivisions; iSubdivisions++ )
     452             :     {
     453        7431 :         assert( ( nSubdivisions == 1 ) || ( nSubdivisions == 3 ) );
     454             : 
     455        7431 :         tmp = sub( stopLine, startLine );
     456        7431 :         iStartLine = imult1616( tmp, iSubdivisions ); /*Q0*/
     457        7431 :         iEndLine = add( iStartLine, tmp );
     458             : 
     459        7431 :         if ( EQ_16( nSubdivisions, 3 ) )
     460        7431 :             iStartLine = mult( iStartLine, 0x2AAB ); /*Q0*/
     461        7431 :         iStartLine = add( iStartLine, startLine );
     462             : 
     463        7431 :         if ( EQ_16( nSubdivisions, 3 ) )
     464        7431 :             iEndLine = mult( iEndLine, 0x2AAB ); /*Q0*/
     465        7431 :         iEndLine = add( iEndLine, startLine );
     466        7431 :         headroom = getScaleFactor32( pSpectrum + iStartLine - IGF_START_MN, sub( iEndLine, iStartLine ) );
     467             :         /* Calculate norm of spectrum band */
     468        7431 :         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        7431 :         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        7431 :         tmp = sub( shift, norm_l( L_tmp ) ); /* exponent for normalized L_tmp */
     477        7431 :         tmp = shr( sub( 1, tmp ), 1 );       /* pre-shift to apply before autocorrelation */
     478        7431 :         shifts[iSubdivisions] = s_min( tmp, headroom );
     479        7431 :         move16();
     480             : 
     481             :         /* calc normalization factor */
     482        7431 :         facs[iSubdivisions] = 0;
     483        7431 :         move16();
     484        7431 :         facs_e[iSubdivisions] = 0;
     485        7431 :         move16();
     486             : 
     487        7431 :         if ( tmp32 > 0 )
     488             :         {
     489        1452 :             facs[iSubdivisions] = 0x7FFF;
     490        1452 :             move16(); /* normalization not needed for one subdivision */
     491             :         }
     492             : 
     493        7431 :         test();
     494        7431 :         IF( ( tmp32 > 0 ) && ( GT_16( nSubdivisions, 1 ) ) )
     495             :         {
     496        1452 :             move16();
     497        1452 :             facs_e[iSubdivisions] = shl( sub( tmp, shifts[iSubdivisions] ), 1 );
     498             : 
     499        1452 :             tmp = sub( 1, shl( tmp, 1 ) );             /* exponent of autocorrelation */
     500        1452 :             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        1452 :             facs[iSubdivisions] = div_s( 0x2000, round_fx_sat( L_tmp ) ); /* L_tmp is >= 0x2000000 Q15*/
     504        1452 :             move16();
     505             :         }
     506             :     }
     507             : 
     508             :     /* Calculate normalized autocorrelation for spectrum subdivision and get filter parameters based on it */
     509        2477 :     set32_fx( rxx, 0, ITF_MAX_FILTER_ORDER + 1 );
     510             : 
     511        2477 :     spectrumLength = sub( stopLine, startLine );
     512             : 
     513        3919 :     FOR( iSubdivisions = 0; iSubdivisions < nSubdivisions; iSubdivisions++ )
     514             :     {
     515        3680 :         IF( facs[iSubdivisions] == 0 )
     516             :         {
     517        2238 :             BREAK;
     518             :         }
     519             : 
     520             : 
     521        1442 :         assert( ( nSubdivisions == 1 ) || ( nSubdivisions == 3 ) );
     522             : 
     523        1442 :         iStartLine = imult1616( spectrumLength, iSubdivisions ); /*Q0*/
     524        1442 :         iEndLine = add( iStartLine, spectrumLength );            /*Q0*/
     525             : 
     526        1442 :         if ( EQ_16( nSubdivisions, 3 ) )
     527        1442 :             iStartLine = mult( iStartLine, 0x2AAB ); /*Q0*/
     528        1442 :         iStartLine = add( iStartLine, startLine );
     529             : 
     530        1442 :         if ( EQ_16( nSubdivisions, 3 ) )
     531        1442 :             iEndLine = mult( iEndLine, 0x2AAB ); /*Q0*/
     532        1442 :         iEndLine = add( iEndLine, startLine );
     533             : 
     534             : 
     535        1442 :         move16();
     536        1442 :         shift = shifts[iSubdivisions];
     537             : 
     538        1442 :         n = sub( iEndLine, iStartLine );
     539        1442 :         assert( n < (Word16) ( sizeof( tmpbuf ) / sizeof( Word16 ) ) );
     540      171371 :         FOR( i = 0; i < n; i++ )
     541             :         {
     542      169929 :             tmpbuf[i] = round_fx_sat( L_shl_sat( pSpectrum[iStartLine + i - IGF_START_MN], shift ) ); /*Q + shift - 16*/
     543      169929 :             move16();
     544             :         }
     545             : 
     546       14420 :         FOR( lag = 0; lag <= maxOrder; lag++ )
     547             :         {
     548       12978 :             n = sub( sub( iEndLine, lag ), iStartLine );
     549             : 
     550             :             {
     551       12978 :                 Word64 tmp64 = 0;
     552     1490427 :                 FOR( i = 0; i < n; i++ )
     553             :                 {
     554     1477449 :                     tmp64 = W_mac0_16_16( tmp64, tmpbuf[i], tmpbuf[i + lag] ); /*2*(Q + shift) - 32*/
     555             :                 }
     556       12978 :                 L_tmp = W_sat_l( tmp64 ); /*2*(Q + shift) - 32*/
     557             :             }
     558             : 
     559       12978 :             L_tmp = Mpy_32_16_1( L_tmp, facs[iSubdivisions] ); /*2*(Q + shift) - 32*/
     560       12978 :             L_tmp = L_shl( L_tmp, facs_e[iSubdivisions] );     /*2*(Q + shift) - 32 + facs_e*/
     561             : 
     562       12978 :             rxx[lag] = L_add( rxx[lag], L_tmp );
     563       12978 :             move32();
     564             :         }
     565             :     }
     566             : 
     567        2477 :     IF( EQ_16( iSubdivisions, nSubdivisions ) ) /* meaning there is no subdivision with low energy */
     568             :     {
     569             :         /* Limit the maximum order to spectrum length/4 */
     570         239 :         ITF_GetFilterParameters_fx( rxx, s_min( maxOrder, shr( spectrumLength, 2 ) ), A, Q_A, predictionGain );
     571             : 
     572         239 :         *curr_order = maxOrder; /*Q0*/
     573         239 :         move16();
     574             :     }
     575             : 
     576        2477 :     return 1;
     577             : }
     578             : 
     579     1331905 : 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     1331905 :     IF( maxOrder <= 0 )
     605             :     {
     606           0 :         return 0;
     607             :     }
     608     1331905 :     pWindow = tnsAcfWindow_fx;
     609     1331905 :     set_zero_fx( norms, MAX_SUBDIVISIONS );
     610     1331905 :     set_zero_fx( rxx, ITF_MAX_FILTER_ORDER + 1 );     /* This initialization is required */
     611     1331905 :     set16_fx( q_rxx, Q31, ITF_MAX_FILTER_ORDER + 1 ); /* This initialization is required */
     612             : 
     613     1331905 :     spectrumLength = sub( stopLine, startLine );
     614     1331905 :     num_subdivisions = 0;
     615     1331905 :     move16();
     616             : 
     617             :     /* Calculate norms for each spectrum part */
     618     2271725 :     FOR( iSubdivisions = 0; iSubdivisions < MAX_SUBDIVISIONS; iSubdivisions++ )
     619             :     {
     620             :         /* iStartLine = startLine + ( stopLine - startLine ) * iSubdivisions / nSubdivisions; */
     621     2038299 :         iStartLine = add( startLine, mult( imult1616( spectrumLength, iSubdivisions ), 10923 /* 1/MAX_SUBDIVISIONS in Q15 */ ) ); /*Q0*/
     622             :         /* iEndLine = startLine + ( stopLine - startLine ) * ( iSubdivisions + 1 ) / nSubdivisions; */
     623     2038299 :         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     2038299 :         ptr_spectrum1 = pSpectrum + sub( iStartLine, IGF_START_MN );
     630     2038299 :         length = sub( iEndLine, iStartLine );
     631     2038299 :         headroom = L_norm_arr( ptr_spectrum1, length );
     632     2038299 :         guard_bits = find_guarded_bits_fx( length );
     633     2038299 :         shift = sub( headroom, guard_bits );
     634             : 
     635     2038299 :         Copy_Scale_sig32( ptr_spectrum1, temp_spectrum, length, shift ); // Q -> Q+shift
     636             : 
     637     2038299 :         sum = 0;
     638     2038299 :         move64();
     639   217942870 :         FOR( i = 0; i < length; i++ )
     640             :         {
     641   215904571 :             sum = W_mac_32_32( sum, temp_spectrum[i], temp_spectrum[i] ); // 2(Q+shift)+1
     642             :         }
     643     2038299 :         IF( LE_64( sum, W_shl( 32768 * 2 /* HLM_MIN_NRG in Q1 */, s_min( 63, shl( add( Q, shift ), 1 ) ) ) ) )
     644             :         {
     645     1098479 :             BREAK;
     646             :         }
     647             : 
     648             :         /* fac = 1.0f / norms[iSubdivisions]; */
     649      939820 :         exp = W_norm( sum );
     650      939820 :         sum = W_shl( sum, exp );                                    // 2(Q+shift)+1+exp
     651      939820 :         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      939820 :         q_fac = sub( 76, add( shl( add( Q, shift ), 1 ), exp ) );
     653      939820 :         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      939820 :         ptr_spectrum1 = temp_spectrum; // pSpectrum + iStartLine - IGF_START_MN;
     664     8458380 :         FOR( lag = 1; lag <= maxOrder; lag++ )
     665             :         {
     666             :             /* dotp( pSpectrum + iStartLine - IGF_START_MN, pSpectrum + iStartLine - IGF_START_MN + lag, iEndLine - iStartLine - lag ) */
     667     7518560 :             ptr_spectrum2 = temp_spectrum + lag; //  pSpectrum + iStartLine - IGF_START_MN + lag;
     668             : 
     669     7518560 :             sum = 0;
     670     7518560 :             move64();
     671   838597560 :             FOR( i = 0; i < iEndLine - iStartLine - lag; i++ )
     672             :             {
     673   831079000 :                 sum = W_mac_32_32( sum, ptr_spectrum1[i], ptr_spectrum2[i] ); // 2(Q+shift)+1
     674             :             }
     675     7518560 :             exp = W_norm( sum );
     676     7518560 :             sum = W_shl( sum, exp );                                          // 2(Q+shift)+1+exp
     677     7518560 :             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     7518560 :             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     7518560 :             q_min = sub( s_min( q_temp, q_rxx[lag] ), 1 );
     682     7518560 :             rxx[lag] = L_add( L_shl( rxx[lag], sub( q_min, q_rxx[lag] ) ), L_shl( temp, sub( q_min, q_temp ) ) );
     683     7518560 :             q_rxx[lag] = q_min;
     684     7518560 :             move32();
     685     7518560 :             move16();
     686             : 
     687     7518560 :             pWindow++;
     688             :         }
     689             : 
     690      939820 :         num_subdivisions = add( num_subdivisions, 1 );
     691             :     }
     692             : 
     693     1331905 :     minimum_s( q_rxx + 1, ITF_MAX_FILTER_ORDER, &q_min );
     694     1331905 :     q_min = s_min( Q29, q_min );
     695             : 
     696    21310480 :     FOR( i = 1; i < ITF_MAX_FILTER_ORDER; i++ )
     697             :     {
     698    19978575 :         rxx[i] = L_shl( rxx[i], sub( q_min, q_rxx[i] ) );
     699    19978575 :         move32();
     700             :     }
     701             : 
     702     1331905 :     IF( EQ_16( iSubdivisions, MAX_SUBDIVISIONS ) ) /* meaning there is no subdivision with low energy */
     703             :     {
     704      233426 :         rxx[0] = L_shl( MAX_SUBDIVISIONS, q_min );
     705      233426 :         move32();
     706             : 
     707             :         /* Limit the maximum order to spectrum length/4 */
     708      233426 :         ITF_GetFilterParameters_fx( rxx, s_min( maxOrder, shr( spectrumLength, 2 ) ), A, Q_A, predictionGain );
     709             : 
     710      233426 :         *curr_order = maxOrder; /*Q0*/
     711      233426 :         move16();
     712             :     }
     713             : 
     714     1331905 :     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     1793132 : static Word16 GetBitsFromTable( const Word16 value /*Q0*/, const Coding codes[], const Word16 nSize /*Q0*/ )
     723             : {
     724             :     (void) nSize;
     725     1793132 :     assert( ( value >= 0 ) && ( value < nSize ) && ( nSize >= 0 ) && ( nSize <= 256 ) );
     726             : 
     727     1793132 :     move16();
     728     1793132 :     cast16();
     729     1793132 :     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      884251 : static Word16 EncodeUsingTable( const Word16 value /*Q0*/, const Coding codes[], const Word16 nSize /*Q0*/ )
     736             : {
     737             :     (void) nSize;
     738      884251 :     assert( ( value >= 0 ) && ( value < nSize ) && ( nSize >= 0 ) && ( nSize <= 256 ) );
     739             : 
     740      884251 :     move16();
     741      884251 :     return codes[value].code; /*Q0*/
     742             : }
     743             : 
     744             : 
     745             : /** Decode a value from a bitstream using a Huffman table. */
     746      872470 : static Word16 DecodeUsingTable( Decoder_State *st, Word16 *pValue /*Q0*/, const Coding codes[], const Word16 nSize /*Q0*/ )
     747             : {
     748      872470 :     Word16 code = 0;
     749      872470 :     Word16 nBits = 0;
     750      872470 :     move16();
     751      872470 :     move16();
     752             :     Word16 valueIndex;
     753             : 
     754      872470 :     assert( ( nSize >= 0 ) && ( nSize <= 256 ) );
     755             : 
     756             : 
     757      872470 :     move16();
     758      872470 :     valueIndex = nSize;
     759             : 
     760             : 
     761     3189131 :     WHILE( valueIndex == nSize )
     762             :     {
     763     2316661 :         code = add( shl( code, 1 ), get_next_indice_fx( st, 1 ) ); /*Q0*/
     764     2316661 :         nBits = add( nBits, 1 );
     765     2316661 :         test();
     766     2316661 :         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    30017809 :         FOR( valueIndex = 0; valueIndex < nSize; valueIndex++ )
     777             :         {
     778             : 
     779    28573618 :             IF( s_and( (Word16) EQ_16( codes[valueIndex].nBits, nBits ), (Word16) EQ_16( codes[valueIndex].code, code ) ) )
     780             :             {
     781      872470 :                 BREAK;
     782             :             }
     783             :         }
     784             :     }
     785      872470 :     IF( LT_16( valueIndex, nSize ) )
     786             :     {
     787      872470 :         *pValue = (Word16) codes[valueIndex].value; /*Q0*/
     788      872470 :         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      872470 :     return nBits; /*Q0*/
     800             : }
     801             : 
     802             : 
     803             : /* TNS filter coefficients */
     804             : 
     805      555786 : Word16 DecodeSWBTCX20TnsFilterCoeff_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
     806             : {
     807      555786 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     808      555786 :     return DecodeUsingTable( st, pValue, codesTnsCoeffSWBTCX20[index], nTnsCoeffCodes );
     809             : }
     810             : 
     811      165570 : Word16 DecodeSWBTCX10TnsFilterCoeff_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
     812             : {
     813      165570 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     814      165570 :     return DecodeUsingTable( st, pValue, codesTnsCoeffSWBTCX10[index], nTnsCoeffCodes );
     815             : }
     816             : 
     817       17104 : Word16 DecodeWBTCX20TnsFilterCoeff_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
     818             : {
     819       17104 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     820       17104 :     return DecodeUsingTable( st, pValue, codesTnsCoeffWBTCX20[index], nTnsCoeffCodes );
     821             : }
     822             : 
     823             : 
     824             : /* TNS filter order */
     825             : 
     826       96327 : Word16 DecodeTnsFilterOrderSWBTCX20_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
     827             : {
     828             :     (void) index;
     829       96327 :     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       35098 : Word16 DecodeTnsFilterOrderSWBTCX10_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
     845             : {
     846             :     (void) index;
     847       35098 :     return DecodeUsingTable( st, pValue, codesTnsOrderTCX10, nTnsOrderCodes );
     848             : }
     849             : 
     850             : 
     851      768775 : void const *GetTnsFilterCoeff( void const *p, const Word16 index /*Q0*/, Word16 *pValue /*Q0*/ )
     852             : {
     853      768775 :     *pValue = ( (Word16 const *) p )[index] + INDEX_SHIFT;
     854      768775 :     move16();
     855      768775 :     return NULL;
     856             : }
     857             : 
     858      758795 : void *SetTnsFilterCoeff( void *p, const Word16 index /*Q0*/, const Word16 value /*Q0*/ )
     859             : {
     860      758795 :     ( (Word16 *) p )[index] = sub( value, INDEX_SHIFT );
     861      758795 :     move16();
     862      758795 :     return NULL;
     863             : }
     864             : 
     865             : 
     866     1140470 : Word16 GetSWBTCX20TnsFilterCoeffBits( const Word16 value, const Word16 index )
     867             : {
     868     1140470 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     869             : 
     870     1140470 :     return GetBitsFromTable( value, codesTnsCoeffSWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
     871             : }
     872             : 
     873      562580 : Word16 EncodeSWBTCX20TnsFilterCoeff( const Word16 value, const Word16 index )
     874             : {
     875      562580 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     876             : 
     877      562580 :     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      341316 : Word16 GetSWBTCX10TnsFilterCoeffBits( const Word16 value, const Word16 index )
     888             : {
     889      341316 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     890             : 
     891      341316 :     return GetBitsFromTable( value, codesTnsCoeffSWBTCX10[index], nTnsCoeffCodes ); /*Q0*/
     892             : }
     893             : 
     894      168135 : Word16 EncodeSWBTCX10TnsFilterCoeff( const Word16 value, const Word16 index )
     895             : {
     896      168135 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     897             : 
     898      168135 :     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       35360 : Word16 GetWBTCX20TnsFilterCoeffBits( const Word16 value, const Word16 index )
     909             : {
     910       35360 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     911             : 
     912       35360 :     return GetBitsFromTable( value, codesTnsCoeffWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
     913             : }
     914             : 
     915       17656 : Word16 EncodeWBTCX20TnsFilterCoeff( const Word16 value, const Word16 index )
     916             : {
     917       17656 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     918             : 
     919       17656 :     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      140106 : void const *GetTnsFilterOrder( void const *p, const Word16 index, Word16 *pValue )
     933             : {
     934      140106 :     move16();
     935      140106 :     *pValue = ( (STnsFilter const *) p )[index].order; /*Q0*/
     936             : 
     937      140106 :     move16();
     938      140106 :     return ( (STnsFilter const *) p )[index].coefIndex; /*Q0*/
     939             : }
     940             : 
     941      138203 : void *SetTnsFilterOrder( void *p, const Word16 index, const Word16 value )
     942             : {
     943      138203 :     move16();
     944      138203 :     ( (STnsFilter *) p )[index].order = value; /*Q0*/
     945             : 
     946      138203 :     move16();
     947      138203 :     return ( (STnsFilter *) p )[index].coefIndex; /*Q0*/
     948             : }
     949             : 
     950      198014 : Word16 GetTnsFilterOrderBitsSWBTCX20( const Word16 value, const Word16 index )
     951             : {
     952             :     (void) index;
     953             : 
     954      198014 :     return GetBitsFromTable( sub( value, 1 ), codesTnsOrderTCX20, nTnsOrderCodes ); /*Q0*/
     955             : }
     956             : 
     957       97540 : Word16 EncodeTnsFilterOrderSWBTCX20( const Word16 value, const Word16 index )
     958             : {
     959             :     (void) index;
     960             : 
     961       97540 :     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       72627 : Word16 GetTnsFilterOrderBitsSWBTCX10( const Word16 value, const Word16 index )
     972             : {
     973             :     (void) index;
     974             : 
     975       72627 :     return GetBitsFromTable( sub( value, 1 ), codesTnsOrderTCX10, nTnsOrderCodes ); /*Q0*/
     976             : }
     977             : 
     978       35672 : Word16 EncodeTnsFilterOrderSWBTCX10( const Word16 value, const Word16 index )
     979             : {
     980             :     (void) index;
     981             : 
     982       35672 :     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        5345 : Word16 GetTnsFilterOrderBits( const Word16 value, const Word16 index )
     993             : {
     994             :     (void) index;
     995             : 
     996        5345 :     return GetBitsFromTable( sub( value, 1 ), codesTnsOrder, nTnsOrderCodes ); /*Q0*/
     997             : }
     998             : 
     999        2668 : Word16 EncodeTnsFilterOrder( const Word16 value, const Word16 index )
    1000             : {
    1001             :     (void) index;
    1002             : 
    1003        2668 :     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     1462000 : void const *GetTnsEnabled( void const *p, const Word16 index, Word16 *pValue )
    1034             : {
    1035     1462000 :     move16();
    1036     1462000 :     *pValue = 0;
    1037     1462000 :     if ( ( (STnsData const *) p )[index].nFilters != 0 )
    1038             :     {
    1039      103344 :         move16();
    1040      103344 :         *pValue = 1;
    1041             :     }
    1042     1462000 :     return NULL;
    1043             : }
    1044             : 
    1045      795799 : void *SetTnsEnabled( void *p, const Word16 index, const Word16 value )
    1046             : {
    1047             :     (void) p, (void) index, (void) value;
    1048      795799 :     return NULL;
    1049             : }
    1050             : 
    1051             : /* Number of TNS filters */
    1052             : 
    1053      103344 : void const *GetNumOfTnsFilters_flt( void const *p, const Word16 index, Word16 *pValue )
    1054             : {
    1055      103344 :     *pValue = (Word16) abs( ( (STnsData const *) p )[index].nFilters );
    1056      103344 :     return ( (STnsData const *) p )[index].filter;
    1057             : }
    1058             : 
    1059      102050 : void *SetNumOfTnsFilters_flt( void *p, const Word16 index, const Word16 value )
    1060             : {
    1061      102050 :     ( (STnsData *) p )[index].nFilters = (Word16) abs( value );
    1062      102050 :     return ( (STnsData *) p )[index].filter;
    1063             : }
    1064        2585 : Word16 DecodeTnsFilterOrder_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
    1065             : {
    1066             :     (void) index;
    1067        2585 :     return DecodeUsingTable( st, pValue, codesTnsOrder, nTnsOrderCodes );
    1068             : }
    1069             : /* TNS on whitened spectra  flag */
    1070             : 
    1071       80836 : void const *GetTnsOnWhite( void const *p, const Word16 index, Word16 *pValue )
    1072             : {
    1073       80836 :     *pValue = ( (STnsData const *) p )[index].tnsOnWhitenedSpectra > 0 ? 1 : 0;
    1074       80836 :     return NULL;
    1075             : }
    1076             : 
    1077       79891 : void *SetTnsOnWhite( void *p, const Word16 index, const Word16 value )
    1078             : {
    1079       79891 :     ( (STnsData *) p )[index].tnsOnWhitenedSpectra = value;
    1080       79891 :     return NULL;
    1081             : }
    1082             : 
    1083      191499 : void const *GetTnsEnabledSingleFilter( void const *p, const Word16 index, Word16 *pValue )
    1084             : {
    1085      191499 :     move16();
    1086      191499 :     *pValue = 0;
    1087      191499 :     if ( ( (STnsData const *) p )[index].nFilters > 0 )
    1088             :     {
    1089        2677 :         move16();
    1090        2677 :         *pValue = 1;
    1091             :     }
    1092      191499 :     return ( (STnsData const *) p )[index].filter;
    1093             : }
    1094             : 
    1095      124231 : void *SetTnsEnabledSingleFilter( void *p, const Word16 index, const Word16 value )
    1096             : {
    1097      124231 :     ( (STnsData *) p )[index].nFilters = value; /*Q0*/
    1098      124231 :     move16();
    1099      124231 :     return ( (STnsData *) p )[index].filter;
    1100             : }
    1101             : 
    1102             : /*-------------------------------------------------------------------*
    1103             :  * ResetTnsData()
    1104             :  *
    1105             :  *-------------------------------------------------------------------*/
    1106             : 
    1107     2573529 : void ResetTnsData( STnsData *pTnsData )
    1108             : {
    1109             :     Word16 iFilter;
    1110             : 
    1111             : 
    1112     2573529 :     pTnsData->nFilters = 0;
    1113     2573529 :     move16();
    1114     2573529 :     pTnsData->tnsOnWhitenedSpectra = 0;
    1115     2573529 :     move16();
    1116     7720587 :     FOR( iFilter = 0; iFilter < (Word16) ( sizeof( pTnsData->filter ) / sizeof( pTnsData->filter[0] ) ); iFilter++ )
    1117             :     {
    1118     5147058 :         STnsFilter *const pTnsFilter = &pTnsData->filter[iFilter];
    1119     5147058 :         pTnsFilter->spectrumLength = 0;
    1120     5147058 :         move16();
    1121     5147058 :         pTnsFilter->predictionGain = ONE_IN_Q7; /*Q7*/
    1122     5147058 :         move16();
    1123     5147058 :         pTnsFilter->predictionGain32 = ONE_IN_Q23; /*Q23*/
    1124     5147058 :         move32();
    1125     5147058 :         pTnsFilter->predictionGain_e = PRED_GAIN_E;
    1126     5147058 :         move16();
    1127     5147058 :         pTnsFilter->avgSqrCoef = 0;
    1128     5147058 :         move16();
    1129     5147058 :         pTnsFilter->filterType = TNS_FILTER_OFF; /*Q0*/
    1130     5147058 :         move16();
    1131     5147058 :         ClearTnsFilterCoefficients( pTnsFilter );
    1132             :     }
    1133     2573529 : }
    1134             : /*-------------------------------------------------------------------*
    1135             :  * ClearTnsFilterCoefficients()
    1136             :  *
    1137             :  *-------------------------------------------------------------------*/
    1138             : 
    1139     9504772 : void ClearTnsFilterCoefficients(
    1140             :     STnsFilter *pTnsFilter )
    1141             : {
    1142     9504772 :     move16();
    1143     9504772 :     pTnsFilter->order = 0;
    1144     9504772 :     move16();
    1145             :     assert( TNS_MAX_FILTER_ORDER == 8 );
    1146     9504772 :     move16();
    1147     9504772 :     move16();
    1148     9504772 :     move16();
    1149     9504772 :     move16();
    1150     9504772 :     move16();
    1151     9504772 :     move16();
    1152     9504772 :     move16();
    1153     9504772 :     move16();
    1154     9504772 :     pTnsFilter->coefIndex[0] = 0;
    1155     9504772 :     pTnsFilter->coefIndex[1] = 0;
    1156     9504772 :     pTnsFilter->coefIndex[2] = 0;
    1157     9504772 :     pTnsFilter->coefIndex[3] = 0;
    1158     9504772 :     pTnsFilter->coefIndex[4] = 0;
    1159     9504772 :     pTnsFilter->coefIndex[5] = 0;
    1160     9504772 :     pTnsFilter->coefIndex[6] = 0;
    1161     9504772 :     pTnsFilter->coefIndex[7] = 0;
    1162     9504772 : }
    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      462221 : static void Index2Parcor( const Word16 index[] /*Q0*/, Word16 parCoeff[] /*Q15*/, Word16 order /*Q0*/ )
    1171             : {
    1172             :     const Word16 *values;
    1173             :     Word16 i;
    1174             : 
    1175      462221 :     move16();
    1176      462221 :     values = tnsCoeff4; /*Q15*/
    1177             : 
    1178     2183523 :     FOR( i = 0; i < order; i++ )
    1179             :     {
    1180     1721302 :         move16();
    1181     1721302 :         parCoeff[i] = values[( index[i] + INDEX_SHIFT )]; /*Q15*/
    1182             :     }
    1183      462221 :     return;
    1184             : }
    1185             : 
    1186             : 
    1187             : /* Linear prediction analysis filter. */
    1188    61755743 : 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    61755743 :     tmpSave = x;
    1200    61755743 :     move32();
    1201   343413064 :     FOR( i = 0; i < order - 1; i++ )
    1202             :     {
    1203   281657321 :         tmp = Madd_32_16( state[i], x, parCoeff[i] ); /*Q0*/
    1204   281657321 :         x = Madd_32_16( x, state[i], parCoeff[i] );   /* exponent: 31+0 */
    1205   281657321 :         state[i] = tmpSave;                           /*Q0*/
    1206   281657321 :         move32();
    1207   281657321 :         tmpSave = tmp; /*Q0*/
    1208   281657321 :         move32();
    1209             :     }
    1210             : 
    1211             :     /* last stage: only need half operations */
    1212    61755743 :     x = Madd_32_16( x, state[order - 1], parCoeff[order - 1] ); /*Q0*/
    1213    61755743 :     state[order - 1] = tmpSave;                                 /*Q0*/
    1214    61755743 :     move32();
    1215             : 
    1216    61755743 :     return x; /*Q0*/
    1217             : }
    1218             : 
    1219    76439876 : 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    76439876 :     x = Msub_32_16( x, state[order - 1], parCoeff[order - 1] ); /*Q0*/
    1226             : 
    1227   422318525 :     FOR( i = order - 2; i >= 0; i-- )
    1228             :     {
    1229   345878649 :         x = Msub_32_16( x, state[i], parCoeff[i] );            /*Q0*/
    1230   345878649 :         state[i + 1] = Madd_32_16( state[i], x, parCoeff[i] ); /*Q0*/
    1231   345878649 :         move32();
    1232             :     }
    1233             : 
    1234    76439876 :     move32();
    1235    76439876 :     state[0] = x; /*Q0*/
    1236    76439876 :     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      462221 : 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      462221 :     assert( ( order >= 0 ) && ( order <= TNS_MAX_FILTER_ORDER ) );
    1261      462221 :     assert( ( numOfLines > 0 ) || ( ( numOfLines == 0 ) && ( order == 0 ) ) );
    1262             : 
    1263      462221 :     IF( order == 0 )
    1264             :     {
    1265             : 
    1266      148878 :         test();
    1267      148878 :         IF( s_and( ( spectrum != output ), numOfLines > 0 ) )
    1268             :         {
    1269           0 :             Copy32( spectrum, output, numOfLines ); /*Qx*/
    1270             :         }
    1271             :     }
    1272             :     ELSE
    1273             :     {
    1274             :         {
    1275             : 
    1276   138508962 :             FOR( j = 0; j < numOfLines; j++ )
    1277             :             {
    1278   138195619 :                 move32();
    1279   138195619 :                 output[j] = filter( order, parCoeff, state, spectrum[j] ); /*Qx*/
    1280             :             }
    1281             :         }
    1282             :     }
    1283      462221 :     return;
    1284             : }
    1285             : 
    1286      614613 : 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      614613 :     assert( ( order >= 0 ) && ( order <= ITF_MAX_FILTER_ORDER ) );
    1299      614613 :     assert( ( numOfLines > 0 ) || ( ( numOfLines == 0 ) && ( order == 0 ) ) );
    1300             : 
    1301      614613 :     IF( order == 0 )
    1302             :     {
    1303             : 
    1304      516180 :         test();
    1305      516180 :         IF( s_and( ( spectrum != output ), numOfLines > 0 ) )
    1306             :         {
    1307           0 :             Copy32( spectrum, output, numOfLines ); /*Qx*/
    1308             :         }
    1309             :     }
    1310             :     ELSE
    1311             :     {
    1312       98433 :         shift = sub( 15, Q_A );
    1313             : 
    1314       98433 :         p = buf + ITF_MAX_FILTER_ORDER;
    1315       98433 :         set32_fx( buf, 0, ITF_MAX_FILTER_ORDER );
    1316       98433 :         Copy32( spectrum, p, numOfLines ); /*Qx*/
    1317    33646747 :         FOR( j = 0; j < numOfLines; j++ )
    1318             :         {
    1319             :             Word32 L_tmp;
    1320             : 
    1321    33548314 :             L_tmp = L_add( p[0], 0 );
    1322   268386512 :             FOR( i = 1; i < order; i++ )
    1323             :             {
    1324   234838198 :                 L_tmp = L_add_sat( L_tmp, L_shl( Mpy_32_16_1( p[-i], A[i] ), shift ) ); /*Qx*/
    1325             :             }
    1326    33548314 :             output[j] = L_tmp; /*Qx*/
    1327    33548314 :             move32();
    1328    33548314 :             ++p;
    1329             :         }
    1330             :     }
    1331      614613 :     return;
    1332             : }
    1333             : 
    1334      233665 : 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      233665 :     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      233665 :         *predictionGain = divide3232( L_shr( epsP[0], PRED_GAIN_E ), L_tmp ); /*Q7*/
    1349      233665 :     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      233665 :         A32[0] = 134217728l /*1.0 Q27*/;
    1358      233665 :         move32();                                        /* Q11+16 */
    1359      233665 :         A32[1] = L_shr( L_deposit_h( parCoeff[0] ), 4 ); /* Q11+16 */
    1360      233665 :         move32();
    1361             : 
    1362     1869320 :         FOR( i = 1; i < maxOrder; i++ )
    1363             :         {
    1364     1635655 :             L_tmp = L_shr( L_deposit_h( parCoeff[i] ), 3 ); /* Q11+16 */
    1365             : 
    1366     1635655 :             i_2 = shr( i, 1 );
    1367     4439635 :             FOR( j = 0; j < i_2; j++ )
    1368             :             {
    1369     2803980 :                 tmp1_l = L_Extract_lc( A32[i - 1 - j + 1], &tmp1_h );
    1370     2803980 :                 tmp2_l = L_Extract_lc( A32[j + 1], &tmp2_h );
    1371     2803980 :                 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     2803980 :                 move32();
    1373     2803980 :                 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     2803980 :                 move32();
    1375             :             }
    1376     1635655 :             IF( s_and( i, 1 ) )
    1377             :             {
    1378      934660 :                 tmp2_l = L_Extract_lc( A32[j + 1], &tmp2_h );
    1379      934660 :                 A32[j + 1] = Mac_32( A32[j + 1], parCoeff[i], 0, tmp2_h, tmp2_l ); /*+= parCoeff[i] * a[j+1]; Q11+16*/
    1380      934660 :                 move32();
    1381             :             }
    1382             : 
    1383     1635655 :             A32[i + 1] = L_shr( L_deposit_h( parCoeff[i] ), 4 ); /* Q11+16 */
    1384     1635655 :             move32();
    1385             :         }
    1386             : 
    1387      233665 :         tmp = 3;
    1388      233665 :         move16(); /* assume Q11 -> Q14 */
    1389     2102985 :         FOR( i = 0; i < maxOrder; i++ )
    1390             :         {
    1391     1869320 :             tmp = s_min( tmp, norm_l( A32[i] ) );
    1392             :         }
    1393     2102985 :         FOR( i = 0; i < maxOrder; i++ )
    1394             :         {
    1395     1869320 :             A[i] = round_fx( L_shl( A32[i], tmp ) ); /* Q11+tmp */
    1396     1869320 :             move16();
    1397             :         }
    1398      233665 :         *Q_A = add( 11, tmp );
    1399      233665 :         move16();
    1400             :     }
    1401      233665 :     return;
    1402             : }

Generated by: LCOV version 1.14