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

Generated by: LCOV version 1.14