LCOV - code coverage report
Current view: top level - lib_com - tns_base.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ ca3146eb9de8185ed0247945c643267826a32a94 Lines: 387 578 67.0 %
Date: 2025-08-26 01:31:27 Functions: 25 57 43.9 %

          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       51068 : 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       51068 :     Word16 iFilter = 0;
      92       51068 :     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       51068 :     nSampleRate = bwMode2fs[bwidth];
     101       51068 :     move32();
     102       51068 :     startLineFilter = &pTnsConfig->iFilterBorders[1];
     103             : 
     104             :     /* Sanity checks */
     105       51068 :     assert( ( nSampleRate > 0 ) && ( frameLength > 0 ) && ( pTnsConfig != NULL ) );
     106       51068 :     test();
     107       51068 :     test();
     108       51068 :     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       51068 :     move16();
     116       51068 :     pTnsConfig->maxOrder = TNS_MAX_FILTER_ORDER;
     117             : 
     118       51068 :     IF( LE_32( total_brate, ACELP_32k ) )
     119             :     {
     120        6692 :         move16();
     121        6692 :         move16();
     122        6692 :         pTnsConfig->nMaxFilters = sizeof( tnsParametersIGF32kHz_LowBR ) / sizeof( tnsParametersIGF32kHz_LowBR[0] );
     123        6692 :         pTnsConfig->pTnsParameters = tnsParametersIGF32kHz_LowBR;
     124             :     }
     125             :     ELSE
     126             :     {
     127       44376 :         test();
     128       44376 :         IF( GT_32( nSampleRate, 32000 ) && EQ_32( nSampleRate, L_mult0( 100, frameLength ) ) )
     129             :         {
     130       10379 :             move16();
     131       10379 :             pTnsConfig->nMaxFilters = sizeof( tnsParameters48kHz_grouped ) / sizeof( tnsParameters48kHz_grouped[0] );
     132       10379 :             move16();
     133       10379 :             pTnsConfig->pTnsParameters = tnsParameters48kHz_grouped;
     134             :         }
     135             :         ELSE
     136       33997 :         IF( GT_32( nSampleRate, INT_FS_16k ) )
     137             :         {
     138             :             {
     139             : 
     140       31234 :                 move16();
     141       31234 :                 pTnsConfig->nMaxFilters = sizeof( tnsParameters32kHz ) / sizeof( tnsParameters32kHz[0] );
     142             : 
     143       31234 :                 move16();
     144       31234 :                 pTnsConfig->pTnsParameters = tnsParameters32kHz;
     145             : 
     146       31234 :                 if ( EQ_32( nSampleRate, L_mult0( 100, frameLength ) ) ) /* sub-frame length is <= 10 ms */
     147             :                 {
     148        3492 :                     move16();
     149        3492 :                     pTnsConfig->pTnsParameters = tnsParameters32kHz_grouped;
     150             :                 }
     151             :             }
     152             :         }
     153             :         ELSE
     154             :         {
     155        2763 :             IF( EQ_32( nSampleRate, L_mult0( 100, frameLength ) ) ) /* sub-frame length is <= 10 ms */
     156             :             {
     157         921 :                 move16();
     158         921 :                 pTnsConfig->nMaxFilters = sizeof( tnsParameters16kHz_grouped ) / sizeof( tnsParameters16kHz_grouped[0] );
     159         921 :                 pTnsConfig->pTnsParameters = tnsParameters16kHz_grouped;
     160             :             }
     161             :             ELSE
     162             :             {
     163        1842 :                 move16();
     164        1842 :                 move16();
     165        1842 :                 pTnsConfig->nMaxFilters = sizeof( tnsParameters16kHz ) / sizeof( tnsParameters16kHz[0] );
     166        1842 :                 pTnsConfig->pTnsParameters = tnsParameters16kHz;
     167             :             }
     168             :         }
     169             :     }
     170             : 
     171       51068 :     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      144670 :     FOR( iFilter = 0; iFilter < pTnsConfig->nMaxFilters; iFilter++ )
     176             :     {
     177       93602 :         assert( pTnsConfig->pTnsParameters[iFilter].startLineFrequency < 0.5f * nSampleRate );
     178       93602 :         assert( nSampleRate <= 96000 );
     179       93602 :         move16();
     180       93602 :         startLineFilter[iFilter] = divide3232( L_mult0( frameLength, pTnsConfig->pTnsParameters[iFilter].startLineFrequency ), L_shl( nSampleRate, 14 ) );
     181             :     }
     182             : 
     183       51068 :     IF( igfStopFreq > 0 )
     184             :     {
     185       38363 :         L_tmp = L_mult( frameLength, igfStopFreq );
     186       38363 :         s1 = sub( norm_l( L_tmp ), 1 );
     187       38363 :         s2 = norm_l( nSampleRate );
     188             : 
     189       38363 :         move16();
     190       38363 :         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       12705 :         move16();
     195       12705 :         pTnsConfig->iFilterBorders[0] = frameLength;
     196             :     }
     197       51068 :     return; /*TNS_NO_ERROR;*/
     198             : }
     199             : 
     200           0 : 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           0 :     Word16 iFilter = 0;
     210           0 :     move16();
     211             :     Word16 *startLineFilter;
     212             :     Word32 L_tmp;
     213             :     Word32 nSampleRate;
     214             :     Word16 s1;
     215             :     Word16 s2;
     216             : 
     217           0 :     nSampleRate = bwMode2fs[bwidth];
     218           0 :     move32();
     219           0 :     startLineFilter = &pTnsConfig->iFilterBorders[1]; /*Q0*/
     220             : 
     221             :     /* Sanity checks */
     222           0 :     assert( ( nSampleRate > 0 ) && ( frameLength > 0 ) && ( pTnsConfig != NULL ) );
     223           0 :     test();
     224           0 :     test();
     225           0 :     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           0 :     move16();
     233           0 :     pTnsConfig->maxOrder = TNS_MAX_FILTER_ORDER;
     234             : 
     235           0 :     IF( LE_32( total_brate, ACELP_32k ) )
     236             :     {
     237           0 :         move16();
     238           0 :         pTnsConfig->nMaxFilters = (UWord8) idiv1616( sizeof( tnsParametersIGF32kHz_LowBR ), sizeof( tnsParametersIGF32kHz_LowBR[0] ) ); /*Q0*/
     239           0 :         pTnsConfig->pTnsParameters = tnsParametersIGF32kHz_LowBR;
     240             :     }
     241             :     ELSE
     242             :     {
     243           0 :         test();
     244           0 :         IF( GT_32( nSampleRate, 32000 ) && EQ_32( nSampleRate, L_mult0( 100, frameLength ) ) )
     245             :         {
     246           0 :             pTnsConfig->nMaxFilters = (UWord8) idiv1616( sizeof( tnsParameters48kHz_grouped ), sizeof( tnsParameters48kHz_grouped[0] ) ); /*Q0*/
     247           0 :             move16();
     248           0 :             pTnsConfig->pTnsParameters = tnsParameters48kHz_grouped;
     249             :         }
     250           0 :         ELSE IF( GT_32( nSampleRate, INT_FS_16k ) )
     251             :         {
     252           0 :             L_tmp = IVAS_32k;
     253           0 :             move32();
     254           0 :             if ( !is_mct )
     255             :             {
     256           0 :                 L_tmp = IVAS_48k;
     257           0 :                 move32();
     258             :             }
     259           0 :             test();
     260           0 :             IF( GT_16( element_mode, IVAS_SCE ) && GE_32( total_brate, L_tmp ) )
     261             :             {
     262           0 :                 pTnsConfig->nMaxFilters = (UWord8) idiv1616( sizeof( tnsParameters32kHz_Stereo ), sizeof( tnsParameters32kHz_Stereo[0] ) ); /*Q0*/
     263           0 :                 move16();
     264           0 :                 IF( EQ_32( nSampleRate, L_mult0( 100, frameLength ) ) ) /* sub-frame length is <= 10 ms */
     265             :                 {
     266           0 :                     pTnsConfig->pTnsParameters = tnsParameters32kHz_grouped;
     267             :                 }
     268             :                 ELSE
     269             :                 {
     270           0 :                     pTnsConfig->pTnsParameters = tnsParameters32kHz_Stereo;
     271             :                 }
     272             :             }
     273             :             ELSE
     274             :             {
     275             : 
     276           0 :                 move16();
     277           0 :                 pTnsConfig->nMaxFilters = (UWord8) idiv1616( sizeof( tnsParameters32kHz ), sizeof( tnsParameters32kHz[0] ) ); /*Q0*/
     278             : 
     279           0 :                 pTnsConfig->pTnsParameters = tnsParameters32kHz;
     280             : 
     281           0 :                 if ( EQ_32( nSampleRate, L_mult0( 100, frameLength ) ) ) /* sub-frame length is <= 10 ms */
     282             :                 {
     283           0 :                     pTnsConfig->pTnsParameters = tnsParameters32kHz_grouped;
     284             :                 }
     285             :             }
     286             :         }
     287             :         ELSE
     288             :         {
     289           0 :             IF( EQ_32( nSampleRate, L_mult0( 100, frameLength ) ) ) /* sub-frame length is <= 10 ms */
     290             :             {
     291           0 :                 move16();
     292           0 :                 pTnsConfig->nMaxFilters = (UWord8) idiv1616( sizeof( tnsParameters16kHz_grouped ), sizeof( tnsParameters16kHz_grouped[0] ) ); /*Q0*/
     293           0 :                 pTnsConfig->pTnsParameters = tnsParameters16kHz_grouped;
     294             :             }
     295             :             ELSE
     296             :             {
     297           0 :                 move16();
     298           0 :                 pTnsConfig->nMaxFilters = (UWord8) idiv1616( sizeof( tnsParameters16kHz ), sizeof( tnsParameters16kHz[0] ) ); /*Q0*/
     299           0 :                 pTnsConfig->pTnsParameters = tnsParameters16kHz;
     300             :             }
     301             :         }
     302             :     }
     303             : 
     304           0 :     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           0 :     FOR( iFilter = 0; iFilter < pTnsConfig->nMaxFilters; iFilter++ )
     309             :     {
     310           0 :         assert( pTnsConfig->pTnsParameters[iFilter].startLineFrequency < nSampleRate / 2 );
     311           0 :         assert( nSampleRate <= 96000 );
     312           0 :         move16();
     313           0 :         startLineFilter[iFilter] = divide3232( L_mult0( frameLength, pTnsConfig->pTnsParameters[iFilter].startLineFrequency ), L_shl( nSampleRate, 14 ) ); /*Q0*/
     314             :     }
     315             : 
     316           0 :     IF( igfStopFreq > 0 )
     317             :     {
     318           0 :         L_tmp = L_mult( frameLength, igfStopFreq );
     319           0 :         s1 = sub( norm_l( L_tmp ), 1 );
     320           0 :         s2 = norm_l( nSampleRate );
     321             : 
     322           0 :         move16();
     323           0 :         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           0 :         move16();
     328           0 :         pTnsConfig->iFilterBorders[0] = frameLength; /*Q0*/
     329             :     }
     330             : 
     331           0 :     pTnsConfig->allowTnsOnWhite = 0;
     332           0 :     move16();
     333             : 
     334           0 :     return; /*TNS_NO_ERROR;*/
     335             : }
     336             : 
     337             : 
     338             : /*-------------------------------------------------------------------*
     339             :  * ApplyTnsFilter()
     340             :  *
     341             :  *-------------------------------------------------------------------*/
     342             : 
     343       86581 : 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       86581 :     move16();
     357       86581 :     filter = IIRLattice;
     358       86581 :     if ( fIsAnalysis )
     359             :     {
     360           0 :         filter = FIRLattice;
     361             :     }
     362       86581 :     set32_fx( state, 0, TNS_MAX_FILTER_ORDER );
     363       86581 :     move16();
     364       86581 :     pBorders = pTnsConfig->iFilterBorders; /*Q0*/
     365             : 
     366      258341 :     FOR( iFilter = pTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
     367             :     {
     368             :         Word16 parCoeff[TNS_MAX_FILTER_ORDER];
     369             :         const STnsFilter *pFilter;
     370             : 
     371      171760 :         move16();
     372      171760 :         move16();
     373      171760 :         pFilter = &pTnsData->filter[iFilter];
     374      171760 :         stopLine = pBorders[iFilter];
     375      171760 :         startLine = pBorders[iFilter + 1];
     376             : 
     377      171760 :         Index2Parcor( pFilter->coefIndex, parCoeff, pFilter->order );
     378             : 
     379      171760 :         TnsFilter( &spectrum[startLine], stopLine - startLine,
     380      171760 :                    parCoeff, pFilter->order,
     381             :                    filter, state,
     382      171760 :                    &spectrum[startLine] );
     383             :     }
     384             : 
     385       86581 :     move16();
     386             : 
     387       86581 :     return /*result*/;
     388             : }
     389             : 
     390             : /*-------------------------------------------------------------------*
     391             :  * ITF_Apply()
     392             :  *
     393             :  *-------------------------------------------------------------------*/
     394             : 
     395      494193 : 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      494193 :     ITF_TnsFilter_fx( &spectrum[startLine], sub( stopLine, startLine ), A, Q_A, order, &spectrum[startLine] );
     405             : 
     406      494193 :     return /*TNS_NO_ERROR*/;
     407             : }
     408             : /*-------------------------------------------------------------------*
     409             :  * ITF_Detect()
     410             :  *
     411             :  *
     412             :  *-------------------------------------------------------------------*/
     413             : 
     414         538 : 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         538 :     Word16 const nSubdivisions = MAX_SUBDIVISIONS;
     428         538 :     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             : #ifndef ISSUE_1836_replace_overflow_libcom
     442             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     443             :     Flag Overflow = 0;
     444             :     move32();
     445             : #endif
     446             : #endif
     447             : 
     448         538 :     move16();
     449         538 :     move16();
     450         538 :     move16();
     451             : 
     452         538 :     if ( maxOrder <= 0 )
     453             :     {
     454           0 :         return 0;
     455             :     }
     456             : 
     457             :     /* Calculate norms for each spectrum part */
     458        2152 :     FOR( iSubdivisions = 0; iSubdivisions < nSubdivisions; iSubdivisions++ )
     459             :     {
     460        1614 :         assert( ( nSubdivisions == 1 ) || ( nSubdivisions == 3 ) );
     461             : 
     462        1614 :         tmp = sub( stopLine, startLine );
     463        1614 :         iStartLine = imult1616( tmp, iSubdivisions ); /*Q0*/
     464        1614 :         iEndLine = add( iStartLine, tmp );
     465             : 
     466        1614 :         if ( EQ_16( nSubdivisions, 3 ) )
     467        1614 :             iStartLine = mult( iStartLine, 0x2AAB ); /*Q0*/
     468        1614 :         iStartLine = add( iStartLine, startLine );
     469             : 
     470        1614 :         if ( EQ_16( nSubdivisions, 3 ) )
     471        1614 :             iEndLine = mult( iEndLine, 0x2AAB ); /*Q0*/
     472        1614 :         iEndLine = add( iEndLine, startLine );
     473        1614 :         headroom = getScaleFactor32( pSpectrum + iStartLine - IGF_START_MN, sub( iEndLine, iStartLine ) );
     474             :         /* Calculate norm of spectrum band */
     475        1614 :         L_tmp = Norm32Norm( pSpectrum + iStartLine - IGF_START_MN, headroom, sub( iEndLine, iStartLine ), &shift ); /*Q31 - shift*/
     476             : 
     477             :         /* Check threshold HLM_MIN_NRG */
     478             :         BASOP_SATURATE_WARNING_OFF_EVS;
     479             : #ifdef ISSUE_1836_replace_overflow_libcom
     480        1614 :         tmp32 = L_sub( L_shl_sat( L_tmp, sub( shift, sub( 24, Q ) ) ), 4194304l /*HLM_MIN_NRG Q7*/ ); /*Q7*/
     481             : #else
     482             :         tmp32 = L_sub( L_shl_o( L_tmp, sub( shift, sub( 24, Q ) ), &Overflow ), 4194304l /*HLM_MIN_NRG Q7*/ ); /*Q7*/
     483             : #endif
     484             :         BASOP_SATURATE_WARNING_ON_EVS;
     485             : 
     486             :         /* get pre-shift for autocorrelation */
     487        1614 :         tmp = sub( shift, norm_l( L_tmp ) ); /* exponent for normalized L_tmp */
     488        1614 :         tmp = shr( sub( 1, tmp ), 1 );       /* pre-shift to apply before autocorrelation */
     489        1614 :         shifts[iSubdivisions] = s_min( tmp, headroom );
     490        1614 :         move16();
     491             : 
     492             :         /* calc normalization factor */
     493        1614 :         facs[iSubdivisions] = 0;
     494        1614 :         move16();
     495        1614 :         facs_e[iSubdivisions] = 0;
     496        1614 :         move16();
     497             : 
     498        1614 :         if ( tmp32 > 0 )
     499             :         {
     500         200 :             facs[iSubdivisions] = 0x7FFF;
     501         200 :             move16(); /* normalization not needed for one subdivision */
     502             :         }
     503             : 
     504        1614 :         test();
     505        1614 :         IF( ( tmp32 > 0 ) && ( GT_16( nSubdivisions, 1 ) ) )
     506             :         {
     507         200 :             move16();
     508         200 :             facs_e[iSubdivisions] = shl( sub( tmp, shifts[iSubdivisions] ), 1 );
     509             : 
     510         200 :             tmp = sub( 1, shl( tmp, 1 ) );             /* exponent of autocorrelation */
     511         200 :             L_tmp = L_shl( L_tmp, sub( shift, tmp ) ); /* shift L_tmp to that exponent */
     512             : 
     513             :             /* calc factor (with 2 bits headroom for sum of 3 subdivisions) */
     514         200 :             facs[iSubdivisions] = div_s( 0x2000, round_fx_sat( L_tmp ) ); /* L_tmp is >= 0x2000000 Q15*/
     515         200 :             move16();
     516             :         }
     517             :     }
     518             : 
     519             :     /* Calculate normalized autocorrelation for spectrum subdivision and get filter parameters based on it */
     520         538 :     set32_fx( rxx, 0, ITF_MAX_FILTER_ORDER + 1 );
     521             : 
     522         538 :     spectrumLength = sub( stopLine, startLine );
     523             : 
     524         737 :     FOR( iSubdivisions = 0; iSubdivisions < nSubdivisions; iSubdivisions++ )
     525             :     {
     526         715 :         IF( facs[iSubdivisions] == 0 )
     527             :         {
     528         516 :             BREAK;
     529             :         }
     530             : 
     531             : 
     532         199 :         assert( ( nSubdivisions == 1 ) || ( nSubdivisions == 3 ) );
     533             : 
     534         199 :         iStartLine = imult1616( spectrumLength, iSubdivisions ); /*Q0*/
     535         199 :         iEndLine = add( iStartLine, spectrumLength );            /*Q0*/
     536             : 
     537         199 :         if ( EQ_16( nSubdivisions, 3 ) )
     538         199 :             iStartLine = mult( iStartLine, 0x2AAB ); /*Q0*/
     539         199 :         iStartLine = add( iStartLine, startLine );
     540             : 
     541         199 :         if ( EQ_16( nSubdivisions, 3 ) )
     542         199 :             iEndLine = mult( iEndLine, 0x2AAB ); /*Q0*/
     543         199 :         iEndLine = add( iEndLine, startLine );
     544             : 
     545             : 
     546         199 :         move16();
     547         199 :         shift = shifts[iSubdivisions];
     548             : 
     549         199 :         n = sub( iEndLine, iStartLine );
     550         199 :         assert( n < (Word16) ( sizeof( tmpbuf ) / sizeof( Word16 ) ) );
     551       24091 :         FOR( i = 0; i < n; i++ )
     552             :         {
     553       23892 :             tmpbuf[i] = round_fx_sat( L_shl_sat( pSpectrum[iStartLine + i - IGF_START_MN], shift ) ); /*Q + shift - 16*/
     554       23892 :             move16();
     555             :         }
     556             : 
     557        1990 :         FOR( lag = 0; lag <= maxOrder; lag++ )
     558             :         {
     559        1791 :             n = sub( sub( iEndLine, lag ), iStartLine );
     560             : 
     561             :             {
     562        1791 :                 Word64 tmp64 = 0;
     563      209655 :                 FOR( i = 0; i < n; i++ )
     564             :                 {
     565      207864 :                     tmp64 = W_mac0_16_16( tmp64, tmpbuf[i], tmpbuf[i + lag] ); /*2*(Q + shift) - 32*/
     566             :                 }
     567        1791 :                 L_tmp = W_sat_l( tmp64 ); /*2*(Q + shift) - 32*/
     568             :             }
     569             : 
     570        1791 :             L_tmp = Mpy_32_16_1( L_tmp, facs[iSubdivisions] ); /*2*(Q + shift) - 32*/
     571        1791 :             L_tmp = L_shl( L_tmp, facs_e[iSubdivisions] );     /*2*(Q + shift) - 32 + facs_e*/
     572             : 
     573        1791 :             rxx[lag] = L_add( rxx[lag], L_tmp );
     574        1791 :             move32();
     575             :         }
     576             :     }
     577             : 
     578         538 :     IF( EQ_16( iSubdivisions, nSubdivisions ) ) /* meaning there is no subdivision with low energy */
     579             :     {
     580             :         /* Limit the maximum order to spectrum length/4 */
     581          22 :         ITF_GetFilterParameters_fx( rxx, s_min( maxOrder, shr( spectrumLength, 2 ) ), A, Q_A, predictionGain );
     582             : 
     583          22 :         *curr_order = maxOrder; /*Q0*/
     584          22 :         move16();
     585             :     }
     586             : 
     587         538 :     return 1;
     588             : }
     589             : 
     590      493655 : Word16 ITF_Detect_ivas_fx(
     591             :     const Word32 pSpectrum[], /*Q*/
     592             :     const Word16 startLine,   /*Q0*/
     593             :     const Word16 stopLine,    /*Q0*/
     594             :     const Word16 maxOrder,    /*Q0*/
     595             :     Word16 *A,                /*Q_A*/
     596             :     Word16 *Q_A,
     597             :     Word16 *predictionGain, /*Q7*/
     598             :     Word16 *curr_order,     /*Q0*/
     599             :     Word16 Q )
     600             : {
     601             :     Word32 norms[MAX_SUBDIVISIONS];
     602             :     Word16 num_subdivisions, i, length;
     603             :     Word16 iStartLine, iEndLine, spectrumLength;
     604             :     Word32 rxx[ITF_MAX_FILTER_ORDER + 1];
     605             :     Word16 q_rxx[ITF_MAX_FILTER_ORDER + 1];
     606             :     Word32 temp_spectrum[640];
     607             :     const Word16 *pWindow;
     608             :     const Word32 *ptr_spectrum1, *ptr_spectrum2;
     609             :     Word16 iSubdivisions, lag;
     610             :     Word16 headroom, guard_bits, shift, q_min;
     611             :     Word64 sum;
     612             :     Word16 fac, q_fac, exp, q_temp;
     613             :     Word32 temp;
     614             : 
     615      493655 :     IF( maxOrder <= 0 )
     616             :     {
     617           0 :         return 0;
     618             :     }
     619      493655 :     pWindow = tnsAcfWindow_fx;
     620      493655 :     set_zero_fx( norms, MAX_SUBDIVISIONS );
     621      493655 :     set_zero_fx( rxx, ITF_MAX_FILTER_ORDER + 1 );     /* This initialization is required */
     622      493655 :     set16_fx( q_rxx, Q31, ITF_MAX_FILTER_ORDER + 1 ); /* This initialization is required */
     623             : 
     624      493655 :     spectrumLength = sub( stopLine, startLine );
     625      493655 :     num_subdivisions = 0;
     626      493655 :     move16();
     627             : 
     628             :     /* Calculate norms for each spectrum part */
     629      767627 :     FOR( iSubdivisions = 0; iSubdivisions < MAX_SUBDIVISIONS; iSubdivisions++ )
     630             :     {
     631             :         /* iStartLine = startLine + ( stopLine - startLine ) * iSubdivisions / nSubdivisions; */
     632      700472 :         iStartLine = add( startLine, mult( imult1616( spectrumLength, iSubdivisions ), 10923 /* 1/MAX_SUBDIVISIONS in Q15 */ ) ); /*Q0*/
     633             :         /* iEndLine = startLine + ( stopLine - startLine ) * ( iSubdivisions + 1 ) / nSubdivisions; */
     634      700472 :         iEndLine = add( startLine, mult( imult1616( spectrumLength, add( iSubdivisions, 1 ) ), 10923 /* 1/MAX_SUBDIVISIONS in Q15 */ ) ); /*Q0*/
     635             : 
     636             : 
     637             :         /*         Variable initialization             */
     638             :         /* norms[iSubdivisions] = sum2_f(pSpectrum + iStartLine - IGF_START_MN, iEndLine - iStartLine); */
     639             : 
     640      700472 :         ptr_spectrum1 = pSpectrum + sub( iStartLine, IGF_START_MN );
     641      700472 :         length = sub( iEndLine, iStartLine );
     642      700472 :         headroom = L_norm_arr( ptr_spectrum1, length );
     643      700472 :         guard_bits = find_guarded_bits_fx( length );
     644      700472 :         shift = sub( headroom, guard_bits );
     645             : 
     646      700472 :         Copy_Scale_sig32( ptr_spectrum1, temp_spectrum, length, shift ); // Q -> Q+shift
     647             : 
     648      700472 :         sum = 0;
     649      700472 :         move64();
     650    72346944 :         FOR( i = 0; i < length; i++ )
     651             :         {
     652    71646472 :             sum = W_mac_32_32( sum, temp_spectrum[i], temp_spectrum[i] ); // 2(Q+shift)+1
     653             :         }
     654             : #ifdef FIX_ISSUE_1811_EXCEEDING_W_SHIFTS
     655      700472 :         IF( LE_64( sum, W_shl( 32768 * 2 /* HLM_MIN_NRG in Q1 */, s_min( 63, shl( add( Q, shift ), 1 ) ) ) ) )
     656             : #else
     657             :         IF( LE_64( sum, W_shl( 32768 * 2 /* HLM_MIN_NRG in Q1 */, shl( add( Q, shift ), 1 ) ) ) )
     658             : #endif
     659             :         {
     660      426500 :             BREAK;
     661             :         }
     662             : 
     663             :         /* fac = 1.0f / norms[iSubdivisions]; */
     664      273972 :         exp = W_norm( sum );
     665      273972 :         sum = W_shl( sum, exp );                                    // 2(Q+shift)+1+exp
     666      273972 :         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)
     667      273972 :         q_fac = sub( 76, add( shl( add( Q, shift ), 1 ), exp ) );
     668      273972 :         pWindow = tnsAcfWindow_fx;
     669             : 
     670             :         /* For additional loop condition */
     671             :         /* Variable initialization */
     672             :         /*for ( lag = 1; lag <= maxOrder; lag++ )
     673             :         {
     674             :             rxx[lag] += fac * ( *pWindow ) * dotp( pSpectrum + iStartLine - IGF_START_MN, pSpectrum + iStartLine - IGF_START_MN + lag, iEndLine - iStartLine - lag );
     675             :             pWindow++;
     676             :         }*/
     677             : 
     678      273972 :         ptr_spectrum1 = temp_spectrum; // pSpectrum + iStartLine - IGF_START_MN;
     679     2465748 :         FOR( lag = 1; lag <= maxOrder; lag++ )
     680             :         {
     681             :             /* dotp( pSpectrum + iStartLine - IGF_START_MN, pSpectrum + iStartLine - IGF_START_MN + lag, iEndLine - iStartLine - lag ) */
     682     2191776 :             ptr_spectrum2 = temp_spectrum + lag; //  pSpectrum + iStartLine - IGF_START_MN + lag;
     683             : 
     684     2191776 :             sum = 0;
     685     2191776 :             move64();
     686   238216968 :             FOR( i = 0; i < iEndLine - iStartLine - lag; i++ )
     687             :             {
     688   236025192 :                 sum = W_mac_32_32( sum, ptr_spectrum1[i], ptr_spectrum2[i] ); // 2(Q+shift)+1
     689             :             }
     690     2191776 :             exp = W_norm( sum );
     691     2191776 :             sum = W_shl( sum, exp );                                          // 2(Q+shift)+1+exp
     692     2191776 :             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
     693     2191776 :             q_temp = sub( add( q_fac, add( shl( add( Q, shift ), 1 ), exp ) ), 47 );
     694             : 
     695             :             /* rxx[lag] += fac * (*pWindow) * dotp(pSpectrum + iStartLine - IGF_START_MN, pSpectrum + iStartLine - IGF_START_MN + lag, iEndLine - iStartLine - lag); */
     696     2191776 :             q_min = sub( s_min( q_temp, q_rxx[lag] ), 1 );
     697     2191776 :             rxx[lag] = L_add( L_shl( rxx[lag], sub( q_min, q_rxx[lag] ) ), L_shl( temp, sub( q_min, q_temp ) ) );
     698     2191776 :             q_rxx[lag] = q_min;
     699     2191776 :             move32();
     700     2191776 :             move16();
     701             : 
     702     2191776 :             pWindow++;
     703             :         }
     704             : 
     705      273972 :         num_subdivisions = add( num_subdivisions, 1 );
     706             :     }
     707             : 
     708      493655 :     minimum_s( q_rxx + 1, ITF_MAX_FILTER_ORDER, &q_min );
     709      493655 :     q_min = s_min( Q29, q_min );
     710             : 
     711     7898480 :     FOR( i = 1; i < ITF_MAX_FILTER_ORDER; i++ )
     712             :     {
     713     7404825 :         rxx[i] = L_shl( rxx[i], sub( q_min, q_rxx[i] ) );
     714     7404825 :         move32();
     715             :     }
     716             : 
     717      493655 :     IF( EQ_16( iSubdivisions, MAX_SUBDIVISIONS ) ) /* meaning there is no subdivision with low energy */
     718             :     {
     719       67155 :         rxx[0] = L_shl( MAX_SUBDIVISIONS, q_min );
     720       67155 :         move32();
     721             : 
     722             :         /* Limit the maximum order to spectrum length/4 */
     723       67155 :         ITF_GetFilterParameters_fx( rxx, s_min( maxOrder, shr( spectrumLength, 2 ) ), A, Q_A, predictionGain );
     724             : 
     725       67155 :         *curr_order = maxOrder; /*Q0*/
     726       67155 :         move16();
     727             :     }
     728             : 
     729      493655 :     return 1;
     730             : }
     731             : /* Helper functions for Hufmann table coding */
     732             : 
     733             : 
     734             : /** Get number of bits from a Huffman table.
     735             :  * The table must be sorted by values.
     736             :  */
     737           0 : static Word16 GetBitsFromTable( const Word16 value /*Q0*/, const Coding codes[], const Word16 nSize /*Q0*/ )
     738             : {
     739             :     (void) nSize;
     740           0 :     assert( ( value >= 0 ) && ( value < nSize ) && ( nSize >= 0 ) && ( nSize <= 256 ) );
     741             : 
     742           0 :     move16();
     743           0 :     cast16();
     744           0 :     return (Word16) codes[value].nBits; /*Q0*/
     745             : }
     746             : 
     747             : /** Get the code for a value from a Huffman table.
     748             :  * The table must be sorted by values.
     749             :  */
     750           0 : static Word16 EncodeUsingTable( const Word16 value /*Q0*/, const Coding codes[], const Word16 nSize /*Q0*/ )
     751             : {
     752             :     (void) nSize;
     753           0 :     assert( ( value >= 0 ) && ( value < nSize ) && ( nSize >= 0 ) && ( nSize <= 256 ) );
     754             : 
     755           0 :     move16();
     756           0 :     return codes[value].code; /*Q0*/
     757             : }
     758             : 
     759             : 
     760             : /** Decode a value from a bitstream using a Huffman table. */
     761      706956 : static Word16 DecodeUsingTable( Decoder_State *st, Word16 *pValue /*Q0*/, const Coding codes[], const Word16 nSize /*Q0*/ )
     762             : {
     763      706956 :     Word16 code = 0;
     764      706956 :     Word16 nBits = 0;
     765      706956 :     move16();
     766      706956 :     move16();
     767             :     Word16 valueIndex;
     768             : 
     769      706956 :     assert( ( nSize >= 0 ) && ( nSize <= 256 ) );
     770             : 
     771             : 
     772      706956 :     move16();
     773      706956 :     valueIndex = nSize;
     774             : 
     775             : 
     776     2544125 :     WHILE( valueIndex == nSize )
     777             :     {
     778     1837169 :         code = add( shl( code, 1 ), get_next_indice_fx( st, 1 ) ); /*Q0*/
     779     1837169 :         nBits = add( nBits, 1 );
     780     1837169 :         test();
     781     1837169 :         IF( GT_16( nBits, nSize ) || GT_16( nBits, 16 ) )
     782             :         {
     783           0 :             st->BER_detect = 1;
     784           0 :             move16();
     785           0 :             *pValue = 0;
     786           0 :             move16();
     787             : 
     788           0 :             return -1;
     789             :         }
     790             : 
     791    23624450 :         FOR( valueIndex = 0; valueIndex < nSize; valueIndex++ )
     792             :         {
     793             : 
     794    22494237 :             IF( s_and( (Word16) EQ_16( codes[valueIndex].nBits, nBits ), (Word16) EQ_16( codes[valueIndex].code, code ) ) )
     795             :             {
     796      706956 :                 BREAK;
     797             :             }
     798             :         }
     799             :     }
     800      706956 :     IF( LT_16( valueIndex, nSize ) )
     801             :     {
     802      706956 :         *pValue = (Word16) codes[valueIndex].value; /*Q0*/
     803      706956 :         move16();
     804             :     }
     805             :     ELSE
     806             :     {
     807           0 :         st->BER_detect = 1;
     808           0 :         move16();
     809           0 :         *pValue = 0;
     810           0 :         move16();
     811           0 :         return -1;
     812             :     }
     813             : 
     814      706956 :     return nBits; /*Q0*/
     815             : }
     816             : 
     817             : 
     818             : /* TNS filter coefficients */
     819             : 
     820      456267 : Word16 DecodeSWBTCX20TnsFilterCoeff_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
     821             : {
     822      456267 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     823      456267 :     return DecodeUsingTable( st, pValue, codesTnsCoeffSWBTCX20[index], nTnsCoeffCodes );
     824             : }
     825             : 
     826      133766 : Word16 DecodeSWBTCX10TnsFilterCoeff_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
     827             : {
     828      133766 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     829      133766 :     return DecodeUsingTable( st, pValue, codesTnsCoeffSWBTCX10[index], nTnsCoeffCodes );
     830             : }
     831             : 
     832        8312 : Word16 DecodeWBTCX20TnsFilterCoeff_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
     833             : {
     834        8312 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     835        8312 :     return DecodeUsingTable( st, pValue, codesTnsCoeffWBTCX20[index], nTnsCoeffCodes );
     836             : }
     837             : 
     838             : 
     839             : /* TNS filter order */
     840             : 
     841       79152 : Word16 DecodeTnsFilterOrderSWBTCX20_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
     842             : {
     843             :     (void) index;
     844       79152 :     return DecodeUsingTable( st, pValue, codesTnsOrderTCX20, nTnsOrderCodes );
     845             : }
     846             : 
     847           0 : Word16 GetTnsFilterOrderBitsSWBTCX10_flt( const Word16 value, const Word16 index )
     848             : {
     849             :     (void) index;
     850           0 :     return GetBitsFromTable( value - 1, codesTnsOrderTCX10, nTnsOrderCodes );
     851             : }
     852             : 
     853           0 : Word16 EncodeTnsFilterOrderSWBTCX10_flt( const Word16 value, const Word16 index )
     854             : {
     855             :     (void) index;
     856           0 :     return EncodeUsingTable( value - 1, codesTnsOrderTCX10, nTnsOrderCodes );
     857             : }
     858             : 
     859       28111 : Word16 DecodeTnsFilterOrderSWBTCX10_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
     860             : {
     861             :     (void) index;
     862       28111 :     return DecodeUsingTable( st, pValue, codesTnsOrderTCX10, nTnsOrderCodes );
     863             : }
     864             : 
     865             : 
     866           0 : void const *GetTnsFilterCoeff( void const *p, const Word16 index /*Q0*/, Word16 *pValue /*Q0*/ )
     867             : {
     868           0 :     *pValue = ( (Word16 const *) p )[index] + INDEX_SHIFT;
     869           0 :     move16();
     870           0 :     return NULL;
     871             : }
     872             : 
     873      613061 : void *SetTnsFilterCoeff( void *p, const Word16 index /*Q0*/, const Word16 value /*Q0*/ )
     874             : {
     875      613061 :     ( (Word16 *) p )[index] = sub( value, INDEX_SHIFT );
     876      613061 :     move16();
     877      613061 :     return NULL;
     878             : }
     879             : 
     880             : 
     881           0 : Word16 GetSWBTCX20TnsFilterCoeffBits( const Word16 value, const Word16 index )
     882             : {
     883           0 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     884             : 
     885           0 :     return GetBitsFromTable( value, codesTnsCoeffSWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
     886             : }
     887             : 
     888           0 : Word16 EncodeSWBTCX20TnsFilterCoeff( const Word16 value, const Word16 index )
     889             : {
     890           0 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     891             : 
     892           0 :     return EncodeUsingTable( value, codesTnsCoeffSWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
     893             : }
     894             : 
     895           0 : Word16 DecodeSWBTCX20TnsFilterCoeff( Decoder_State *st, const Word16 index, Word16 *pValue )
     896             : {
     897           0 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     898             : 
     899           0 :     return DecodeUsingTable( st, pValue, codesTnsCoeffSWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
     900             : }
     901             : 
     902           0 : Word16 GetSWBTCX10TnsFilterCoeffBits( const Word16 value, const Word16 index )
     903             : {
     904           0 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     905             : 
     906           0 :     return GetBitsFromTable( value, codesTnsCoeffSWBTCX10[index], nTnsCoeffCodes ); /*Q0*/
     907             : }
     908             : 
     909           0 : Word16 EncodeSWBTCX10TnsFilterCoeff( const Word16 value, const Word16 index )
     910             : {
     911           0 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     912             : 
     913           0 :     return EncodeUsingTable( value, codesTnsCoeffSWBTCX10[index], nTnsCoeffCodes ); /*Q0*/
     914             : }
     915             : 
     916           0 : Word16 DecodeSWBTCX10TnsFilterCoeff( Decoder_State *st, const Word16 index, Word16 *pValue )
     917             : {
     918           0 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     919             : 
     920           0 :     return DecodeUsingTable( st, pValue, codesTnsCoeffSWBTCX10[index], nTnsCoeffCodes ); /*Q0*/
     921             : }
     922             : 
     923           0 : Word16 GetWBTCX20TnsFilterCoeffBits( const Word16 value, const Word16 index )
     924             : {
     925           0 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     926             : 
     927           0 :     return GetBitsFromTable( value, codesTnsCoeffWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
     928             : }
     929             : 
     930           0 : Word16 EncodeWBTCX20TnsFilterCoeff( const Word16 value, const Word16 index )
     931             : {
     932           0 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     933             : 
     934           0 :     return EncodeUsingTable( value, codesTnsCoeffWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
     935             : }
     936             : 
     937           0 : Word16 DecodeWBTCX20TnsFilterCoeff( Decoder_State *st, const Word16 index, Word16 *pValue )
     938             : {
     939           0 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     940             : 
     941           0 :     return DecodeUsingTable( st, pValue, codesTnsCoeffWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
     942             : }
     943             : 
     944             : 
     945             : /* TNS filter order */
     946             : 
     947           0 : void const *GetTnsFilterOrder( void const *p, const Word16 index, Word16 *pValue )
     948             : {
     949           0 :     move16();
     950           0 :     *pValue = ( (STnsFilter const *) p )[index].order; /*Q0*/
     951             : 
     952           0 :     move16();
     953           0 :     return ( (STnsFilter const *) p )[index].coefIndex; /*Q0*/
     954             : }
     955             : 
     956      111545 : void *SetTnsFilterOrder( void *p, const Word16 index, const Word16 value )
     957             : {
     958      111545 :     move16();
     959      111545 :     ( (STnsFilter *) p )[index].order = value; /*Q0*/
     960             : 
     961      111545 :     move16();
     962      111545 :     return ( (STnsFilter *) p )[index].coefIndex; /*Q0*/
     963             : }
     964             : 
     965           0 : Word16 GetTnsFilterOrderBitsSWBTCX20( const Word16 value, const Word16 index )
     966             : {
     967             :     (void) index;
     968             : 
     969           0 :     return GetBitsFromTable( sub( value, 1 ), codesTnsOrderTCX20, nTnsOrderCodes ); /*Q0*/
     970             : }
     971             : 
     972           0 : Word16 EncodeTnsFilterOrderSWBTCX20( const Word16 value, const Word16 index )
     973             : {
     974             :     (void) index;
     975             : 
     976           0 :     return EncodeUsingTable( sub( value, 1 ), codesTnsOrderTCX20, nTnsOrderCodes ); /*Q0*/
     977             : }
     978             : 
     979           0 : Word16 DecodeTnsFilterOrderSWBTCX20( Decoder_State *st, const Word16 index, Word16 *pValue )
     980             : {
     981             :     (void) index;
     982             : 
     983           0 :     return DecodeUsingTable( st, pValue, codesTnsOrderTCX20, nTnsOrderCodes ); /*Q0*/
     984             : }
     985             : 
     986           0 : Word16 GetTnsFilterOrderBitsSWBTCX10( const Word16 value, const Word16 index )
     987             : {
     988             :     (void) index;
     989             : 
     990           0 :     return GetBitsFromTable( sub( value, 1 ), codesTnsOrderTCX10, nTnsOrderCodes ); /*Q0*/
     991             : }
     992             : 
     993           0 : Word16 EncodeTnsFilterOrderSWBTCX10( const Word16 value, const Word16 index )
     994             : {
     995             :     (void) index;
     996             : 
     997           0 :     return EncodeUsingTable( sub( value, 1 ), codesTnsOrderTCX10, nTnsOrderCodes ); /*Q0*/
     998             : }
     999             : 
    1000           0 : Word16 DecodeTnsFilterOrderSWBTCX10( Decoder_State *st, const Word16 index, Word16 *pValue )
    1001             : {
    1002             :     (void) index;
    1003             : 
    1004           0 :     return DecodeUsingTable( st, pValue, codesTnsOrderTCX10, nTnsOrderCodes ); /*Q0*/
    1005             : }
    1006             : 
    1007           0 : Word16 GetTnsFilterOrderBits( const Word16 value, const Word16 index )
    1008             : {
    1009             :     (void) index;
    1010             : 
    1011           0 :     return GetBitsFromTable( sub( value, 1 ), codesTnsOrder, nTnsOrderCodes ); /*Q0*/
    1012             : }
    1013             : 
    1014           0 : Word16 EncodeTnsFilterOrder( const Word16 value, const Word16 index )
    1015             : {
    1016             :     (void) index;
    1017             : 
    1018           0 :     return EncodeUsingTable( sub( value, 1 ), codesTnsOrder, nTnsOrderCodes ); /*Q0*/
    1019             : }
    1020             : 
    1021           0 : Word16 DecodeTnsFilterOrder( Decoder_State *st, const Word16 index, Word16 *pValue )
    1022             : {
    1023             :     (void) index;
    1024             : 
    1025           0 :     return DecodeUsingTable( st, pValue, codesTnsOrder, nTnsOrderCodes ); /*Q0*/
    1026             : }
    1027             : 
    1028             : /* Number of TNS filters */
    1029             : 
    1030           0 : void const *GetNumOfTnsFilters( void const *p, const Word16 index, Word16 *pValue )
    1031             : {
    1032           0 :     move16();
    1033           0 :     *pValue = ( (STnsData const *) p )[index].nFilters; /*Q0*/
    1034           0 :     move16();
    1035           0 :     return ( (STnsData const *) p )[index].filter;
    1036             : }
    1037             : 
    1038           0 : void *SetNumOfTnsFilters( void *p, const Word16 index, Word16 value )
    1039             : {
    1040           0 :     move16();
    1041           0 :     ( (STnsData *) p )[index].nFilters = value; /*Q0*/
    1042           0 :     move16();
    1043           0 :     return ( (STnsData *) p )[index].filter;
    1044             : }
    1045             : 
    1046             : /* TNS enabled/disabled flag */
    1047             : 
    1048           0 : void const *GetTnsEnabled( void const *p, const Word16 index, Word16 *pValue )
    1049             : {
    1050           0 :     move16();
    1051           0 :     *pValue = 0;
    1052           0 :     if ( ( (STnsData const *) p )[index].nFilters != 0 )
    1053             :     {
    1054           0 :         move16();
    1055           0 :         *pValue = 1;
    1056             :     }
    1057           0 :     return NULL;
    1058             : }
    1059             : 
    1060      676111 : void *SetTnsEnabled( void *p, const Word16 index, const Word16 value )
    1061             : {
    1062             :     (void) p, (void) index, (void) value;
    1063      676111 :     return NULL;
    1064             : }
    1065             : 
    1066             : /* Number of TNS filters */
    1067             : 
    1068           0 : void const *GetNumOfTnsFilters_flt( void const *p, const Word16 index, Word16 *pValue )
    1069             : {
    1070           0 :     *pValue = (Word16) abs( ( (STnsData const *) p )[index].nFilters );
    1071           0 :     return ( (STnsData const *) p )[index].filter;
    1072             : }
    1073             : 
    1074       85458 : void *SetNumOfTnsFilters_flt( void *p, const Word16 index, const Word16 value )
    1075             : {
    1076       85458 :     ( (STnsData *) p )[index].nFilters = (Word16) abs( value );
    1077       85458 :     return ( (STnsData *) p )[index].filter;
    1078             : }
    1079        1348 : Word16 DecodeTnsFilterOrder_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
    1080             : {
    1081             :     (void) index;
    1082        1348 :     return DecodeUsingTable( st, pValue, codesTnsOrder, nTnsOrderCodes );
    1083             : }
    1084             : /* TNS on whitened spectra  flag */
    1085             : 
    1086           0 : void const *GetTnsOnWhite( void const *p, const Word16 index, Word16 *pValue )
    1087             : {
    1088           0 :     *pValue = ( (STnsData const *) p )[index].tnsOnWhitenedSpectra > 0 ? 1 : 0;
    1089           0 :     return NULL;
    1090             : }
    1091             : 
    1092       69178 : void *SetTnsOnWhite( void *p, const Word16 index, const Word16 value )
    1093             : {
    1094       69178 :     ( (STnsData *) p )[index].tnsOnWhitenedSpectra = value;
    1095       69178 :     return NULL;
    1096             : }
    1097             : 
    1098           0 : void const *GetTnsEnabledSingleFilter( void const *p, const Word16 index, Word16 *pValue )
    1099             : {
    1100           0 :     move16();
    1101           0 :     *pValue = 0;
    1102           0 :     if ( ( (STnsData const *) p )[index].nFilters > 0 )
    1103             :     {
    1104           0 :         move16();
    1105           0 :         *pValue = 1;
    1106             :     }
    1107           0 :     return ( (STnsData const *) p )[index].filter;
    1108             : }
    1109             : 
    1110       99835 : void *SetTnsEnabledSingleFilter( void *p, const Word16 index, const Word16 value )
    1111             : {
    1112       99835 :     ( (STnsData *) p )[index].nFilters = value; /*Q0*/
    1113       99835 :     move16();
    1114       99835 :     return ( (STnsData *) p )[index].filter;
    1115             : }
    1116             : 
    1117             : /*-------------------------------------------------------------------*
    1118             :  * ResetTnsData()
    1119             :  *
    1120             :  *-------------------------------------------------------------------*/
    1121             : 
    1122      775946 : void ResetTnsData( STnsData *pTnsData )
    1123             : {
    1124             :     Word16 iFilter;
    1125             : 
    1126             : 
    1127      775946 :     pTnsData->nFilters = 0;
    1128      775946 :     move16();
    1129      775946 :     pTnsData->tnsOnWhitenedSpectra = 0;
    1130      775946 :     move16();
    1131     2327838 :     FOR( iFilter = 0; iFilter < (Word16) ( sizeof( pTnsData->filter ) / sizeof( pTnsData->filter[0] ) ); iFilter++ )
    1132             :     {
    1133     1551892 :         STnsFilter *const pTnsFilter = &pTnsData->filter[iFilter];
    1134     1551892 :         pTnsFilter->spectrumLength = 0;
    1135     1551892 :         move16();
    1136     1551892 :         pTnsFilter->predictionGain = ONE_IN_Q7; /*Q7*/
    1137     1551892 :         move16();
    1138     1551892 :         pTnsFilter->predictionGain32 = ONE_IN_Q23; /*Q23*/
    1139     1551892 :         move32();
    1140     1551892 :         pTnsFilter->predictionGain_e = PRED_GAIN_E;
    1141     1551892 :         move16();
    1142     1551892 :         pTnsFilter->avgSqrCoef = 0;
    1143     1551892 :         move16();
    1144     1551892 :         pTnsFilter->filterType = TNS_FILTER_OFF; /*Q0*/
    1145     1551892 :         move16();
    1146     1551892 :         ClearTnsFilterCoefficients( pTnsFilter );
    1147             :     }
    1148      775946 : }
    1149             : /*-------------------------------------------------------------------*
    1150             :  * ClearTnsFilterCoefficients()
    1151             :  *
    1152             :  *-------------------------------------------------------------------*/
    1153             : 
    1154     1551892 : void ClearTnsFilterCoefficients(
    1155             :     STnsFilter *pTnsFilter )
    1156             : {
    1157     1551892 :     move16();
    1158     1551892 :     pTnsFilter->order = 0;
    1159     1551892 :     move16();
    1160             :     assert( TNS_MAX_FILTER_ORDER == 8 );
    1161     1551892 :     move16();
    1162     1551892 :     move16();
    1163     1551892 :     move16();
    1164     1551892 :     move16();
    1165     1551892 :     move16();
    1166     1551892 :     move16();
    1167     1551892 :     move16();
    1168     1551892 :     move16();
    1169     1551892 :     pTnsFilter->coefIndex[0] = 0;
    1170     1551892 :     pTnsFilter->coefIndex[1] = 0;
    1171     1551892 :     pTnsFilter->coefIndex[2] = 0;
    1172     1551892 :     pTnsFilter->coefIndex[3] = 0;
    1173     1551892 :     pTnsFilter->coefIndex[4] = 0;
    1174     1551892 :     pTnsFilter->coefIndex[5] = 0;
    1175     1551892 :     pTnsFilter->coefIndex[6] = 0;
    1176     1551892 :     pTnsFilter->coefIndex[7] = 0;
    1177     1551892 : }
    1178             : 
    1179             : /** Inverse quantization for reflection coefficients.
    1180             :  *
    1181             :  * @param index input quantized values.
    1182             :  * @param parCoeff output reflection coefficients.
    1183             :  * @param order number of coefficients/values.
    1184             :  */
    1185      171760 : static void Index2Parcor( const Word16 index[] /*Q0*/, Word16 parCoeff[] /*Q15*/, Word16 order /*Q0*/ )
    1186             : {
    1187             :     const Word16 *values;
    1188             :     Word16 i;
    1189             : 
    1190      171760 :     move16();
    1191      171760 :     values = tnsCoeff4; /*Q15*/
    1192             : 
    1193      782881 :     FOR( i = 0; i < order; i++ )
    1194             :     {
    1195      611121 :         move16();
    1196      611121 :         parCoeff[i] = values[( index[i] + INDEX_SHIFT )]; /*Q15*/
    1197             :     }
    1198      171760 :     return;
    1199             : }
    1200             : 
    1201             : 
    1202             : /* Linear prediction analysis filter. */
    1203           0 : static Word32 FIRLattice(
    1204             :     const Word16 order, /*Q0*/
    1205             :     const Word16 *parCoeff /*Q15*/,
    1206             :     Word32 *state, /*Q0*/
    1207             :     Word32 x       /* Q0 */
    1208             : )
    1209             : {
    1210             :     Word16 i;
    1211             :     Word32 tmpSave, tmp;
    1212             : 
    1213             : 
    1214           0 :     tmpSave = x;
    1215           0 :     move32();
    1216           0 :     FOR( i = 0; i < order - 1; i++ )
    1217             :     {
    1218           0 :         tmp = Madd_32_16( state[i], x, parCoeff[i] ); /*Q0*/
    1219           0 :         x = Madd_32_16( x, state[i], parCoeff[i] );   /* exponent: 31+0 */
    1220           0 :         state[i] = tmpSave;                           /*Q0*/
    1221           0 :         move32();
    1222           0 :         tmpSave = tmp; /*Q0*/
    1223           0 :         move32();
    1224             :     }
    1225             : 
    1226             :     /* last stage: only need half operations */
    1227           0 :     x = Madd_32_16( x, state[order - 1], parCoeff[order - 1] ); /*Q0*/
    1228           0 :     state[order - 1] = tmpSave;                                 /*Q0*/
    1229           0 :     move32();
    1230             : 
    1231           0 :     return x; /*Q0*/
    1232             : }
    1233             : 
    1234    49264478 : static Word32 IIRLattice( Word16 order /*Q0*/, const Word16 *parCoeff /*Q15*/, Word32 *state /*Q0*/, Word32 x /*Q0*/ )
    1235             : {
    1236             :     Word16 i;
    1237             : 
    1238             : 
    1239             :     /* first stage: no need to calculate state[order-1] */
    1240    49264478 :     x = Msub_32_16( x, state[order - 1], parCoeff[order - 1] ); /*Q0*/
    1241             : 
    1242   274105782 :     FOR( i = order - 2; i >= 0; i-- )
    1243             :     {
    1244   224841304 :         x = Msub_32_16( x, state[i], parCoeff[i] );            /*Q0*/
    1245   224841304 :         state[i + 1] = Madd_32_16( state[i], x, parCoeff[i] ); /*Q0*/
    1246   224841304 :         move32();
    1247             :     }
    1248             : 
    1249    49264478 :     move32();
    1250    49264478 :     state[0] = x; /*Q0*/
    1251    49264478 :     return x;     /*Q0*/
    1252             : }
    1253             : /** TNS analysis/synthesis filter.
    1254             :   * @param spectrum input spectrum values.
    1255             :   * @param numOfLines number of lines in the spectrum.
    1256             :   * @param parCoeff filter (PARCOR) coefficients.
    1257             :   * @param order filter order.
    1258             :   * @param filter function that implements filtering.
    1259             :     By this function it is defined whether analysis or synthesis is performed.
    1260             :   * @param output filtered output spectrum values.
    1261             :     Inplace operation is supported, so it can be equal to spectrum.
    1262             :   */
    1263      171760 : static void TnsFilter(
    1264             :     const Word32 spectrum[], /*Qx*/
    1265             :     const Word16 numOfLines, /*Q0*/
    1266             :     const Word16 parCoeff[], /*Q15*/
    1267             :     const Word16 order,      /*Q0*/
    1268             :     TLinearPredictionFilter filter,
    1269             :     Word32 *state, /*Q0*/
    1270             :     Word32 output[] /*Qx*/ )
    1271             : {
    1272             :     Word16 j;
    1273             : 
    1274             : 
    1275      171760 :     assert( ( order >= 0 ) && ( order <= TNS_MAX_FILTER_ORDER ) );
    1276      171760 :     assert( ( numOfLines > 0 ) || ( ( numOfLines == 0 ) && ( order == 0 ) ) );
    1277             : 
    1278      171760 :     IF( order == 0 )
    1279             :     {
    1280             : 
    1281       60582 :         test();
    1282       60582 :         IF( s_and( ( spectrum != output ), numOfLines > 0 ) )
    1283             :         {
    1284           0 :             Copy32( spectrum, output, numOfLines ); /*Qx*/
    1285             :         }
    1286             :     }
    1287             :     ELSE
    1288             :     {
    1289             :         {
    1290             : 
    1291    49375656 :             FOR( j = 0; j < numOfLines; j++ )
    1292             :             {
    1293    49264478 :                 move32();
    1294    49264478 :                 output[j] = filter( order, parCoeff, state, spectrum[j] ); /*Qx*/
    1295             :             }
    1296             :         }
    1297             :     }
    1298      171760 :     return;
    1299             : }
    1300             : 
    1301      494193 : static void ITF_TnsFilter_fx(
    1302             :     const Word32 spectrum[], /*Qx*/
    1303             :     const Word16 numOfLines, /*Q0*/
    1304             :     const Word16 A[],        /* ifdef FIX_ITF_OVERFLOW Q_A else Q14 */
    1305             :     const Word16 Q_A,
    1306             :     const Word16 order, /*Q0*/
    1307             :     Word32 output[] /*Qx*/ )
    1308             : {
    1309             :     Word16 i, j;
    1310             :     Word32 buf[ITF_MAX_FILTER_ORDER + N_MAX];
    1311             :     Word32 *p;
    1312             :     Word16 shift;
    1313      494193 :     assert( ( order >= 0 ) && ( order <= ITF_MAX_FILTER_ORDER ) );
    1314      494193 :     assert( ( numOfLines > 0 ) || ( ( numOfLines == 0 ) && ( order == 0 ) ) );
    1315             : 
    1316      494193 :     IF( order == 0 )
    1317             :     {
    1318             : 
    1319      427016 :         test();
    1320      427016 :         IF( s_and( ( spectrum != output ), numOfLines > 0 ) )
    1321             :         {
    1322           0 :             Copy32( spectrum, output, numOfLines ); /*Qx*/
    1323             :         }
    1324             :     }
    1325             :     ELSE
    1326             :     {
    1327       67177 :         shift = sub( 15, Q_A );
    1328             : 
    1329       67177 :         p = buf + ITF_MAX_FILTER_ORDER;
    1330       67177 :         set32_fx( buf, 0, ITF_MAX_FILTER_ORDER );
    1331       67177 :         Copy32( spectrum, p, numOfLines ); /*Qx*/
    1332    22122961 :         FOR( j = 0; j < numOfLines; j++ )
    1333             :         {
    1334             :             Word32 L_tmp;
    1335             : 
    1336    22055784 :             L_tmp = L_add( p[0], 0 );
    1337   176446272 :             FOR( i = 1; i < order; i++ )
    1338             :             {
    1339   154390488 :                 L_tmp = L_add_sat( L_tmp, L_shl( Mpy_32_16_1( p[-i], A[i] ), shift ) ); /*Qx*/
    1340             :             }
    1341    22055784 :             output[j] = L_tmp; /*Qx*/
    1342    22055784 :             move32();
    1343    22055784 :             ++p;
    1344             :         }
    1345             :     }
    1346      494193 :     return;
    1347             : }
    1348             : 
    1349       67177 : static void ITF_GetFilterParameters_fx(
    1350             :     Word32 rxx[],          /*Qx*/
    1351             :     const Word16 maxOrder, /*Q0*/
    1352             :     Word16 *A,             /* ifdef FIX_ITF_OVERFLOW Q_A else Q14 */
    1353             :     Word16 *Q_A,
    1354             :     Word16 *predictionGain /*Q7*/ )
    1355             : {
    1356             :     Word16 i, j, i_2, tmp;
    1357             :     Word16 parCoeff[ITF_MAX_FILTER_ORDER];
    1358             :     Word32 epsP[ITF_MAX_FILTER_ORDER + 1], L_tmp;
    1359             : 
    1360             :     /* compute filter in ParCor form with LeRoux-Gueguen algorithm */
    1361       67177 :     L_tmp = E_LPC_schur( rxx, parCoeff, epsP, maxOrder );
    1362             :     BASOP_SATURATE_WARNING_OFF_EVS                                            /* Allow saturation, this value is compared against a threshold. */
    1363       67177 :         *predictionGain = divide3232( L_shr( epsP[0], PRED_GAIN_E ), L_tmp ); /*Q7*/
    1364       67177 :     move16();
    1365             :     BASOP_SATURATE_WARNING_ON_EVS
    1366             : 
    1367             :     {
    1368             :         Word32 A32[ITF_MAX_FILTER_ORDER];
    1369             :         Word16 tmp1_l, tmp1_h, tmp2_l, tmp2_h;
    1370             : 
    1371             :         /* Convert ParCor / reflection coefficients to LPC */
    1372       67177 :         A32[0] = 134217728l /*1.0 Q27*/;
    1373       67177 :         move32();                                        /* Q11+16 */
    1374       67177 :         A32[1] = L_shr( L_deposit_h( parCoeff[0] ), 4 ); /* Q11+16 */
    1375       67177 :         move32();
    1376             : 
    1377      537416 :         FOR( i = 1; i < maxOrder; i++ )
    1378             :         {
    1379      470239 :             L_tmp = L_shr( L_deposit_h( parCoeff[i] ), 3 ); /* Q11+16 */
    1380             : 
    1381      470239 :             i_2 = shr( i, 1 );
    1382     1276363 :             FOR( j = 0; j < i_2; j++ )
    1383             :             {
    1384      806124 :                 tmp1_l = L_Extract_lc( A32[i - 1 - j + 1], &tmp1_h );
    1385      806124 :                 tmp2_l = L_Extract_lc( A32[j + 1], &tmp2_h );
    1386      806124 :                 A32[j + 1] = Mac_32( A32[j + 1], parCoeff[i], 0, tmp1_h, tmp1_l ); /*+= parCoeff[i] * a[i-1-j+1]; Q11+16*/
    1387      806124 :                 move32();
    1388      806124 :                 A32[i - 1 - j + 1] = Mac_32( A32[i - 1 - j + 1], parCoeff[i], 0, tmp2_h, tmp2_l ); /*+= parCoeff[i] * tmp; Q11+16*/
    1389      806124 :                 move32();
    1390             :             }
    1391      470239 :             IF( s_and( i, 1 ) )
    1392             :             {
    1393      268708 :                 tmp2_l = L_Extract_lc( A32[j + 1], &tmp2_h );
    1394      268708 :                 A32[j + 1] = Mac_32( A32[j + 1], parCoeff[i], 0, tmp2_h, tmp2_l ); /*+= parCoeff[i] * a[j+1]; Q11+16*/
    1395      268708 :                 move32();
    1396             :             }
    1397             : 
    1398      470239 :             A32[i + 1] = L_shr( L_deposit_h( parCoeff[i] ), 4 ); /* Q11+16 */
    1399      470239 :             move32();
    1400             :         }
    1401             : 
    1402       67177 :         tmp = 3;
    1403       67177 :         move16(); /* assume Q11 -> Q14 */
    1404      604593 :         FOR( i = 0; i < maxOrder; i++ )
    1405             :         {
    1406      537416 :             tmp = s_min( tmp, norm_l( A32[i] ) );
    1407             :         }
    1408      604593 :         FOR( i = 0; i < maxOrder; i++ )
    1409             :         {
    1410      537416 :             A[i] = round_fx( L_shl( A32[i], tmp ) ); /* Q11+tmp */
    1411      537416 :             move16();
    1412             :         }
    1413       67177 :         *Q_A = add( 11, tmp );
    1414       67177 :         move16();
    1415             :     }
    1416       67177 :     return;
    1417             : }

Generated by: LCOV version 1.14