LCOV - code coverage report
Current view: top level - lib_com - tns_base.c (source / functions) Hit Total Coverage
Test: Coverage on main -- dec/rend @ 4c82f1d24d39d0296b18d775f18a006f4c7d024b Lines: 330 580 56.9 %
Date: 2025-05-17 01:59:02 Functions: 24 57 42.1 %

          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      465347 : 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      465347 :     Word16 const nSubdivisions = MAX_SUBDIVISIONS;
     429      465347 :     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      465347 :     Flag Overflow = 0;
     444      465347 :     move32();
     445             : #endif
     446             : 
     447      465347 :     move16();
     448      465347 :     move16();
     449      465347 :     move16();
     450             : 
     451      465347 :     if ( maxOrder <= 0 )
     452             :     {
     453           0 :         return 0;
     454             :     }
     455             : 
     456             :     /* Calculate norms for each spectrum part */
     457     1861388 :     FOR( iSubdivisions = 0; iSubdivisions < nSubdivisions; iSubdivisions++ )
     458             :     {
     459     1396041 :         assert( ( nSubdivisions == 1 ) || ( nSubdivisions == 3 ) );
     460             : 
     461     1396041 :         tmp = sub( stopLine, startLine );
     462     1396041 :         iStartLine = imult1616( tmp, iSubdivisions ); /*Q0*/
     463     1396041 :         iEndLine = add( iStartLine, tmp );
     464             : 
     465     1396041 :         if ( EQ_16( nSubdivisions, 3 ) )
     466     1396041 :             iStartLine = mult( iStartLine, 0x2AAB ); /*Q0*/
     467     1396041 :         iStartLine = add( iStartLine, startLine );
     468             : 
     469     1396041 :         if ( EQ_16( nSubdivisions, 3 ) )
     470     1396041 :             iEndLine = mult( iEndLine, 0x2AAB ); /*Q0*/
     471     1396041 :         iEndLine = add( iEndLine, startLine );
     472     1396041 :         headroom = getScaleFactor32( pSpectrum + iStartLine - IGF_START_MN, sub( iEndLine, iStartLine ) );
     473             :         /* Calculate norm of spectrum band */
     474     1396041 :         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     1396041 :         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     1396041 :         tmp = sub( shift, norm_l( L_tmp ) ); /* exponent for normalized L_tmp */
     483     1396041 :         tmp = shr( sub( 1, tmp ), 1 );       /* pre-shift to apply before autocorrelation */
     484     1396041 :         shifts[iSubdivisions] = s_min( tmp, headroom );
     485     1396041 :         move16();
     486             : 
     487             :         /* calc normalization factor */
     488     1396041 :         facs[iSubdivisions] = 0;
     489     1396041 :         move16();
     490     1396041 :         facs_e[iSubdivisions] = 0;
     491     1396041 :         move16();
     492             : 
     493     1396041 :         if ( tmp32 > 0 )
     494             :         {
     495      276745 :             facs[iSubdivisions] = 0x7FFF;
     496      276745 :             move16(); /* normalization not needed for one subdivision */
     497             :         }
     498             : 
     499     1396041 :         test();
     500     1396041 :         IF( ( tmp32 > 0 ) && ( GT_16( nSubdivisions, 1 ) ) )
     501             :         {
     502      276745 :             move16();
     503      276745 :             facs_e[iSubdivisions] = shl( sub( tmp, shifts[iSubdivisions] ), 1 );
     504             : 
     505      276745 :             tmp = sub( 1, shl( tmp, 1 ) );             /* exponent of autocorrelation */
     506      276745 :             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      276745 :             facs[iSubdivisions] = div_s( 0x2000, round_fx_sat( L_tmp ) ); /* L_tmp is >= 0x2000000 Q15*/
     510      276745 :             move16();
     511             :         }
     512             :     }
     513             : 
     514             :     /* Calculate normalized autocorrelation for spectrum subdivision and get filter parameters based on it */
     515      465347 :     set32_fx( rxx, 0, ITF_MAX_FILTER_ORDER + 1 );
     516             : 
     517      465347 :     spectrumLength = sub( stopLine, startLine );
     518             : 
     519      722335 :     FOR( iSubdivisions = 0; iSubdivisions < nSubdivisions; iSubdivisions++ )
     520             :     {
     521      660033 :         IF( facs[iSubdivisions] == 0 )
     522             :         {
     523      403045 :             BREAK;
     524             :         }
     525             : 
     526             : 
     527      256988 :         assert( ( nSubdivisions == 1 ) || ( nSubdivisions == 3 ) );
     528             : 
     529      256988 :         iStartLine = imult1616( spectrumLength, iSubdivisions ); /*Q0*/
     530      256988 :         iEndLine = add( iStartLine, spectrumLength );            /*Q0*/
     531             : 
     532      256988 :         if ( EQ_16( nSubdivisions, 3 ) )
     533      256988 :             iStartLine = mult( iStartLine, 0x2AAB ); /*Q0*/
     534      256988 :         iStartLine = add( iStartLine, startLine );
     535             : 
     536      256988 :         if ( EQ_16( nSubdivisions, 3 ) )
     537      256988 :             iEndLine = mult( iEndLine, 0x2AAB ); /*Q0*/
     538      256988 :         iEndLine = add( iEndLine, startLine );
     539             : 
     540             : 
     541      256988 :         move16();
     542      256988 :         shift = shifts[iSubdivisions];
     543             : 
     544      256988 :         n = sub( iEndLine, iStartLine );
     545      256988 :         assert( n < (Word16) ( sizeof( tmpbuf ) / sizeof( Word16 ) ) );
     546    29258065 :         FOR( i = 0; i < n; i++ )
     547             :         {
     548    29001077 :             tmpbuf[i] = round_fx_sat( L_shl_sat( pSpectrum[iStartLine + i - IGF_START_MN], shift ) ); /*Q + shift - 16*/
     549    29001077 :             move16();
     550             :         }
     551             : 
     552     2569880 :         FOR( lag = 0; lag <= maxOrder; lag++ )
     553             :         {
     554     2312892 :             n = sub( sub( iEndLine, lag ), iStartLine );
     555             : 
     556             :             {
     557     2312892 :                 Word64 tmp64 = 0;
     558   254071017 :                 FOR( i = 0; i < n; i++ )
     559             :                 {
     560   251758125 :                     tmp64 = W_mac0_16_16( tmp64, tmpbuf[i], tmpbuf[i + lag] ); /*2*(Q + shift) - 32*/
     561             :                 }
     562     2312892 :                 L_tmp = W_sat_l( tmp64 ); /*2*(Q + shift) - 32*/
     563             :             }
     564             : 
     565     2312892 :             L_tmp = Mpy_32_16_1( L_tmp, facs[iSubdivisions] ); /*2*(Q + shift) - 32*/
     566     2312892 :             L_tmp = L_shl( L_tmp, facs_e[iSubdivisions] );     /*2*(Q + shift) - 32 + facs_e*/
     567             : 
     568     2312892 :             rxx[lag] = L_add( rxx[lag], L_tmp );
     569     2312892 :             move32();
     570             :         }
     571             :     }
     572             : 
     573      465347 :     IF( EQ_16( iSubdivisions, nSubdivisions ) ) /* meaning there is no subdivision with low energy */
     574             :     {
     575             :         /* Limit the maximum order to spectrum length/4 */
     576       62302 :         ITF_GetFilterParameters_fx( rxx, s_min( maxOrder, shr( spectrumLength, 2 ) ), A, Q_A, predictionGain );
     577             : 
     578       62302 :         *curr_order = maxOrder; /*Q0*/
     579       62302 :         move16();
     580             :     }
     581             : 
     582      465347 :     return 1;
     583             : }
     584             : 
     585           0 : 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           0 :     IF( maxOrder <= 0 )
     611             :     {
     612           0 :         return 0;
     613             :     }
     614           0 :     pWindow = tnsAcfWindow_fx;
     615           0 :     set_zero_fx( norms, MAX_SUBDIVISIONS );
     616           0 :     set_zero_fx( rxx, ITF_MAX_FILTER_ORDER + 1 );     /* This initialization is required */
     617           0 :     set16_fx( q_rxx, Q31, ITF_MAX_FILTER_ORDER + 1 ); /* This initialization is required */
     618             : 
     619           0 :     spectrumLength = sub( stopLine, startLine );
     620           0 :     num_subdivisions = 0;
     621           0 :     move16();
     622             : 
     623             :     /* Calculate norms for each spectrum part */
     624           0 :     FOR( iSubdivisions = 0; iSubdivisions < MAX_SUBDIVISIONS; iSubdivisions++ )
     625             :     {
     626             :         /* iStartLine = startLine + ( stopLine - startLine ) * iSubdivisions / nSubdivisions; */
     627           0 :         iStartLine = add( startLine, mult( imult1616( spectrumLength, iSubdivisions ), 10923 /* 1/MAX_SUBDIVISIONS in Q15 */ ) ); /*Q0*/
     628             :         /* iEndLine = startLine + ( stopLine - startLine ) * ( iSubdivisions + 1 ) / nSubdivisions; */
     629           0 :         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           0 :         ptr_spectrum1 = pSpectrum + sub( iStartLine, IGF_START_MN );
     636           0 :         length = sub( iEndLine, iStartLine );
     637           0 :         headroom = L_norm_arr( ptr_spectrum1, length );
     638           0 :         guard_bits = find_guarded_bits_fx( length );
     639           0 :         shift = sub( headroom, guard_bits );
     640             : 
     641           0 :         Copy_Scale_sig32( ptr_spectrum1, temp_spectrum, length, shift ); // Q -> Q+shift
     642             : 
     643           0 :         sum = 0;
     644           0 :         move64();
     645           0 :         FOR( i = 0; i < length; i++ )
     646             :         {
     647           0 :             sum = W_mac_32_32( sum, temp_spectrum[i], temp_spectrum[i] ); // 2(Q+shift)+1
     648             :         }
     649             : 
     650           0 :         IF( LE_64( sum, W_shl( 32768 * 2 /* HLM_MIN_NRG in Q1 */, shl( add( Q, shift ), 1 ) ) ) )
     651             :         {
     652           0 :             BREAK;
     653             :         }
     654             : 
     655             :         /* fac = 1.0f / norms[iSubdivisions]; */
     656           0 :         exp = W_norm( sum );
     657           0 :         sum = W_shl( sum, exp );                                    // 2(Q+shift)+1+exp
     658           0 :         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           0 :         q_fac = sub( 76, add( shl( add( Q, shift ), 1 ), exp ) );
     660           0 :         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           0 :         ptr_spectrum1 = temp_spectrum; // pSpectrum + iStartLine - IGF_START_MN;
     671           0 :         FOR( lag = 1; lag <= maxOrder; lag++ )
     672             :         {
     673             :             /* dotp( pSpectrum + iStartLine - IGF_START_MN, pSpectrum + iStartLine - IGF_START_MN + lag, iEndLine - iStartLine - lag ) */
     674           0 :             ptr_spectrum2 = temp_spectrum + lag; //  pSpectrum + iStartLine - IGF_START_MN + lag;
     675             : 
     676           0 :             sum = 0;
     677           0 :             move64();
     678           0 :             FOR( i = 0; i < iEndLine - iStartLine - lag; i++ )
     679             :             {
     680           0 :                 sum = W_mac_32_32( sum, ptr_spectrum1[i], ptr_spectrum2[i] ); // 2(Q+shift)+1
     681             :             }
     682           0 :             exp = W_norm( sum );
     683           0 :             sum = W_shl( sum, exp );                                          // 2(Q+shift)+1+exp
     684           0 :             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           0 :             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           0 :             q_min = sub( s_min( q_temp, q_rxx[lag] ), 1 );
     689           0 :             rxx[lag] = L_add( L_shl( rxx[lag], sub( q_min, q_rxx[lag] ) ), L_shl( temp, sub( q_min, q_temp ) ) );
     690           0 :             q_rxx[lag] = q_min;
     691           0 :             move32();
     692           0 :             move16();
     693             : 
     694           0 :             pWindow++;
     695             :         }
     696             : 
     697           0 :         num_subdivisions = add( num_subdivisions, 1 );
     698             :     }
     699             : 
     700           0 :     minimum_s( q_rxx + 1, ITF_MAX_FILTER_ORDER, &q_min );
     701           0 :     q_min = s_min( Q29, q_min );
     702             : 
     703           0 :     FOR( i = 1; i < ITF_MAX_FILTER_ORDER; i++ )
     704             :     {
     705           0 :         rxx[i] = L_shl( rxx[i], sub( q_min, q_rxx[i] ) );
     706           0 :         move32();
     707             :     }
     708             : 
     709           0 :     IF( EQ_16( iSubdivisions, MAX_SUBDIVISIONS ) ) /* meaning there is no subdivision with low energy */
     710             :     {
     711           0 :         rxx[0] = L_shl( MAX_SUBDIVISIONS, q_min );
     712           0 :         move32();
     713             : 
     714             :         /* Limit the maximum order to spectrum length/4 */
     715           0 :         ITF_GetFilterParameters_fx( rxx, s_min( maxOrder, shr( spectrumLength, 2 ) ), A, Q_A, predictionGain );
     716             : 
     717           0 :         *curr_order = maxOrder; /*Q0*/
     718           0 :         move16();
     719             :     }
     720             : 
     721           0 :     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 : int16_t DecodeSWBTCX20TnsFilterCoeff_flt( Decoder_State *st, const int16_t index, int16_t *pValue )
     813             : {
     814      429272 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     815      429272 :     return DecodeUsingTable( st, pValue, codesTnsCoeffSWBTCX20[index], nTnsCoeffCodes );
     816             : }
     817             : 
     818             : // int16_t GetSWBTCX10TnsFilterCoeffBits_flt( const int16_t value, const int16_t index )
     819             : //{
     820             : //     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     821             : //     return GetBitsFromTable( value, codesTnsCoeffSWBTCX10[index], nTnsCoeffCodes );
     822             : // }
     823             : 
     824             : // int16_t EncodeSWBTCX10TnsFilterCoeff_flt( const int16_t value, const int16_t index )
     825             : //{
     826             : //     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     827             : //     return EncodeUsingTable( value, codesTnsCoeffSWBTCX10[index], nTnsCoeffCodes );
     828             : // }
     829             : 
     830      121144 : int16_t DecodeSWBTCX10TnsFilterCoeff_flt( Decoder_State *st, const int16_t index, int16_t *pValue )
     831             : {
     832      121144 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     833      121144 :     return DecodeUsingTable( st, pValue, codesTnsCoeffSWBTCX10[index], nTnsCoeffCodes );
     834             : }
     835             : 
     836             : // int16_t GetWBTCX20TnsFilterCoeffBits_flt( const int16_t value, const int16_t index )
     837             : //{
     838             : //     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     839             : //     return GetBitsFromTable( value, codesTnsCoeffWBTCX20[index], nTnsCoeffCodes );
     840             : // }
     841             : 
     842             : // int16_t EncodeWBTCX20TnsFilterCoeff_flt( const int16_t value, const int16_t index )
     843             : //{
     844             : //     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     845             : //     return EncodeUsingTable( value, codesTnsCoeffWBTCX20[index], nTnsCoeffCodes );
     846             : // }
     847             : 
     848        7562 : int16_t DecodeWBTCX20TnsFilterCoeff_flt( Decoder_State *st, const int16_t index, int16_t *pValue )
     849             : {
     850        7562 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     851        7562 :     return DecodeUsingTable( st, pValue, codesTnsCoeffWBTCX20[index], nTnsCoeffCodes );
     852             : }
     853             : 
     854             : 
     855             : /* TNS filter order */
     856             : 
     857             : // void const *GetTnsFilterOrder_flt( void const *p, const int16_t index, int16_t *pValue )
     858             : //{
     859             : //     *pValue = ( (STnsFilter const *) p )[index].order;
     860             : //     return ( (STnsFilter const *) p )[index].coefIndex;
     861             : // }
     862             : 
     863             : // void *SetTnsFilterOrder_flt( void *p, const int16_t index, const int16_t value )
     864             : //{
     865             : //     ( (STnsFilter *) p )[index].order = value;
     866             : //     return ( (STnsFilter *) p )[index].coefIndex;
     867             : // }
     868             : 
     869             : // int16_t GetTnsFilterOrderBitsSWBTCX20_flt( const int16_t value, const int16_t index )
     870             : //{
     871             : //     (void) index;
     872             : //     return GetBitsFromTable( value - 1, codesTnsOrderTCX20, nTnsOrderCodes );
     873             : // }
     874             : 
     875             : // int16_t EncodeTnsFilterOrderSWBTCX20_flt( const int16_t value, const int16_t index )
     876             : //{
     877             : //     (void) index;
     878             : //     return EncodeUsingTable( value - 1, codesTnsOrderTCX20, nTnsOrderCodes );
     879             : // }
     880             : 
     881       74575 : int16_t DecodeTnsFilterOrderSWBTCX20_flt( Decoder_State *st, const int16_t index, int16_t *pValue )
     882             : {
     883             :     (void) index;
     884       74575 :     return DecodeUsingTable( st, pValue, codesTnsOrderTCX20, nTnsOrderCodes );
     885             : }
     886             : 
     887           0 : int16_t GetTnsFilterOrderBitsSWBTCX10_flt( const int16_t value, const int16_t index )
     888             : {
     889             :     (void) index;
     890           0 :     return GetBitsFromTable( value - 1, codesTnsOrderTCX10, nTnsOrderCodes );
     891             : }
     892             : 
     893           0 : int16_t EncodeTnsFilterOrderSWBTCX10_flt( const int16_t value, const int16_t index )
     894             : {
     895             :     (void) index;
     896           0 :     return EncodeUsingTable( value - 1, codesTnsOrderTCX10, nTnsOrderCodes );
     897             : }
     898             : 
     899       25211 : int16_t DecodeTnsFilterOrderSWBTCX10_flt( Decoder_State *st, const int16_t index, int16_t *pValue )
     900             : {
     901             :     (void) index;
     902       25211 :     return DecodeUsingTable( st, pValue, codesTnsOrderTCX10, nTnsOrderCodes );
     903             : }
     904             : 
     905             : 
     906           0 : void const *GetTnsFilterCoeff( void const *p, const Word16 index /*Q0*/, Word16 *pValue /*Q0*/ )
     907             : {
     908           0 :     *pValue = ( (Word16 const *) p )[index] + INDEX_SHIFT;
     909           0 :     move16();
     910           0 :     return NULL;
     911             : }
     912             : 
     913      571749 : void *SetTnsFilterCoeff( void *p, const Word16 index /*Q0*/, const Word16 value /*Q0*/ )
     914             : {
     915      571749 :     ( (Word16 *) p )[index] = sub( value, INDEX_SHIFT );
     916      571749 :     move16();
     917      571749 :     return NULL;
     918             : }
     919             : 
     920             : 
     921           0 : Word16 GetSWBTCX20TnsFilterCoeffBits( const Word16 value, const Word16 index )
     922             : {
     923           0 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     924             : 
     925           0 :     return GetBitsFromTable( value, codesTnsCoeffSWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
     926             : }
     927             : 
     928           0 : Word16 EncodeSWBTCX20TnsFilterCoeff( const Word16 value, const Word16 index )
     929             : {
     930           0 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     931             : 
     932           0 :     return EncodeUsingTable( value, codesTnsCoeffSWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
     933             : }
     934             : 
     935           0 : Word16 DecodeSWBTCX20TnsFilterCoeff( Decoder_State *st, const Word16 index, Word16 *pValue )
     936             : {
     937           0 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     938             : 
     939           0 :     return DecodeUsingTable( st, pValue, codesTnsCoeffSWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
     940             : }
     941             : 
     942           0 : Word16 GetSWBTCX10TnsFilterCoeffBits( const Word16 value, const Word16 index )
     943             : {
     944           0 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     945             : 
     946           0 :     return GetBitsFromTable( value, codesTnsCoeffSWBTCX10[index], nTnsCoeffCodes ); /*Q0*/
     947             : }
     948             : 
     949           0 : Word16 EncodeSWBTCX10TnsFilterCoeff( const Word16 value, const Word16 index )
     950             : {
     951           0 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     952             : 
     953           0 :     return EncodeUsingTable( value, codesTnsCoeffSWBTCX10[index], nTnsCoeffCodes ); /*Q0*/
     954             : }
     955             : 
     956           0 : Word16 DecodeSWBTCX10TnsFilterCoeff( Decoder_State *st, const Word16 index, Word16 *pValue )
     957             : {
     958           0 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     959             : 
     960           0 :     return DecodeUsingTable( st, pValue, codesTnsCoeffSWBTCX10[index], nTnsCoeffCodes ); /*Q0*/
     961             : }
     962             : 
     963           0 : Word16 GetWBTCX20TnsFilterCoeffBits( const Word16 value, const Word16 index )
     964             : {
     965           0 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     966             : 
     967           0 :     return GetBitsFromTable( value, codesTnsCoeffWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
     968             : }
     969             : 
     970           0 : Word16 EncodeWBTCX20TnsFilterCoeff( const Word16 value, const Word16 index )
     971             : {
     972           0 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     973             : 
     974           0 :     return EncodeUsingTable( value, codesTnsCoeffWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
     975             : }
     976             : 
     977           0 : Word16 DecodeWBTCX20TnsFilterCoeff( Decoder_State *st, const Word16 index, Word16 *pValue )
     978             : {
     979           0 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     980             : 
     981           0 :     return DecodeUsingTable( st, pValue, codesTnsCoeffWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
     982             : }
     983             : 
     984             : 
     985             : /* TNS filter order */
     986             : 
     987           0 : void const *GetTnsFilterOrder( void const *p, const Word16 index, Word16 *pValue )
     988             : {
     989           0 :     move16();
     990           0 :     *pValue = ( (STnsFilter const *) p )[index].order; /*Q0*/
     991             : 
     992           0 :     move16();
     993           0 :     return ( (STnsFilter const *) p )[index].coefIndex; /*Q0*/
     994             : }
     995             : 
     996      103770 : void *SetTnsFilterOrder( void *p, const Word16 index, const Word16 value )
     997             : {
     998      103770 :     move16();
     999      103770 :     ( (STnsFilter *) p )[index].order = value; /*Q0*/
    1000             : 
    1001      103770 :     move16();
    1002      103770 :     return ( (STnsFilter *) p )[index].coefIndex; /*Q0*/
    1003             : }
    1004             : 
    1005           0 : Word16 GetTnsFilterOrderBitsSWBTCX20( const Word16 value, const Word16 index )
    1006             : {
    1007             :     (void) index;
    1008             : 
    1009           0 :     return GetBitsFromTable( sub( value, 1 ), codesTnsOrderTCX20, nTnsOrderCodes ); /*Q0*/
    1010             : }
    1011             : 
    1012           0 : Word16 EncodeTnsFilterOrderSWBTCX20( const Word16 value, const Word16 index )
    1013             : {
    1014             :     (void) index;
    1015             : 
    1016           0 :     return EncodeUsingTable( sub( value, 1 ), codesTnsOrderTCX20, nTnsOrderCodes ); /*Q0*/
    1017             : }
    1018             : 
    1019           0 : Word16 DecodeTnsFilterOrderSWBTCX20( Decoder_State *st, const Word16 index, Word16 *pValue )
    1020             : {
    1021             :     (void) index;
    1022             : 
    1023           0 :     return DecodeUsingTable( st, pValue, codesTnsOrderTCX20, nTnsOrderCodes ); /*Q0*/
    1024             : }
    1025             : 
    1026           0 : Word16 GetTnsFilterOrderBitsSWBTCX10( const Word16 value, const Word16 index )
    1027             : {
    1028             :     (void) index;
    1029             : 
    1030           0 :     return GetBitsFromTable( sub( value, 1 ), codesTnsOrderTCX10, nTnsOrderCodes ); /*Q0*/
    1031             : }
    1032             : 
    1033           0 : Word16 EncodeTnsFilterOrderSWBTCX10( const Word16 value, const Word16 index )
    1034             : {
    1035             :     (void) index;
    1036             : 
    1037           0 :     return EncodeUsingTable( sub( value, 1 ), codesTnsOrderTCX10, nTnsOrderCodes ); /*Q0*/
    1038             : }
    1039             : 
    1040           0 : Word16 DecodeTnsFilterOrderSWBTCX10( Decoder_State *st, const Word16 index, Word16 *pValue )
    1041             : {
    1042             :     (void) index;
    1043             : 
    1044           0 :     return DecodeUsingTable( st, pValue, codesTnsOrderTCX10, nTnsOrderCodes ); /*Q0*/
    1045             : }
    1046             : 
    1047           0 : Word16 GetTnsFilterOrderBits( const Word16 value, const Word16 index )
    1048             : {
    1049             :     (void) index;
    1050             : 
    1051           0 :     return GetBitsFromTable( sub( value, 1 ), codesTnsOrder, nTnsOrderCodes ); /*Q0*/
    1052             : }
    1053             : 
    1054           0 : Word16 EncodeTnsFilterOrder( const Word16 value, const Word16 index )
    1055             : {
    1056             :     (void) index;
    1057             : 
    1058           0 :     return EncodeUsingTable( sub( value, 1 ), codesTnsOrder, nTnsOrderCodes ); /*Q0*/
    1059             : }
    1060             : 
    1061           0 : Word16 DecodeTnsFilterOrder( Decoder_State *st, const Word16 index, Word16 *pValue )
    1062             : {
    1063             :     (void) index;
    1064             : 
    1065           0 :     return DecodeUsingTable( st, pValue, codesTnsOrder, nTnsOrderCodes ); /*Q0*/
    1066             : }
    1067             : 
    1068             : /* Number of TNS filters */
    1069             : 
    1070           0 : void const *GetNumOfTnsFilters( void const *p, const Word16 index, Word16 *pValue )
    1071             : {
    1072           0 :     move16();
    1073           0 :     *pValue = ( (STnsData const *) p )[index].nFilters; /*Q0*/
    1074           0 :     move16();
    1075           0 :     return ( (STnsData const *) p )[index].filter;
    1076             : }
    1077             : 
    1078           0 : void *SetNumOfTnsFilters( void *p, const Word16 index, Word16 value )
    1079             : {
    1080           0 :     move16();
    1081           0 :     ( (STnsData *) p )[index].nFilters = value; /*Q0*/
    1082           0 :     move16();
    1083           0 :     return ( (STnsData *) p )[index].filter;
    1084             : }
    1085             : 
    1086             : /* TNS enabled/disabled flag */
    1087             : 
    1088           0 : void const *GetTnsEnabled( void const *p, const Word16 index, Word16 *pValue )
    1089             : {
    1090           0 :     move16();
    1091           0 :     *pValue = 0;
    1092           0 :     if ( ( (STnsData const *) p )[index].nFilters != 0 )
    1093             :     {
    1094           0 :         move16();
    1095           0 :         *pValue = 1;
    1096             :     }
    1097           0 :     return NULL;
    1098             : }
    1099             : 
    1100      632464 : void *SetTnsEnabled( void *p, const Word16 index, const Word16 value )
    1101             : {
    1102             :     (void) p, (void) index, (void) value;
    1103      632464 :     return NULL;
    1104             : }
    1105             : 
    1106             : /* Number of TNS filters */
    1107             : 
    1108           0 : void const *GetNumOfTnsFilters_flt( void const *p, const int16_t index, int16_t *pValue )
    1109             : {
    1110           0 :     *pValue = (int16_t) abs( ( (STnsData const *) p )[index].nFilters );
    1111           0 :     return ( (STnsData const *) p )[index].filter;
    1112             : }
    1113             : 
    1114       79721 : void *SetNumOfTnsFilters_flt( void *p, const int16_t index, const int16_t value )
    1115             : {
    1116       79721 :     ( (STnsData *) p )[index].nFilters = (int16_t) abs( value );
    1117       79721 :     return ( (STnsData *) p )[index].filter;
    1118             : }
    1119        1229 : int16_t DecodeTnsFilterOrder_flt( Decoder_State *st, const int16_t index, int16_t *pValue )
    1120             : {
    1121             :     (void) index;
    1122        1229 :     return DecodeUsingTable( st, pValue, codesTnsOrder, nTnsOrderCodes );
    1123             : }
    1124             : /* TNS on whitened spectra  flag */
    1125             : 
    1126           0 : void const *GetTnsOnWhite( void const *p, const int16_t index, int16_t *pValue )
    1127             : {
    1128           0 :     *pValue = ( (STnsData const *) p )[index].tnsOnWhitenedSpectra > 0 ? 1 : 0;
    1129           0 :     return NULL;
    1130             : }
    1131             : 
    1132       63501 : void *SetTnsOnWhite( void *p, const int16_t index, const int16_t value )
    1133             : {
    1134       63501 :     ( (STnsData *) p )[index].tnsOnWhitenedSpectra = value;
    1135       63501 :     return NULL;
    1136             : }
    1137             : 
    1138             : // void const *GetTnsEnabledSingleFilter( void const *p, const int16_t index, int16_t *pValue )
    1139             : //{
    1140             : //     *pValue = ( (STnsData const *) p )[index].nFilters != 0 ? 1 : 0;
    1141             : //     return ( (STnsData const *) p )[index].filter;
    1142             : // }
    1143             : 
    1144           0 : void const *GetTnsEnabledSingleFilter( void const *p, const Word16 index, Word16 *pValue )
    1145             : {
    1146           0 :     move16();
    1147           0 :     *pValue = 0;
    1148           0 :     if ( ( (STnsData const *) p )[index].nFilters > 0 )
    1149             :     {
    1150           0 :         move16();
    1151           0 :         *pValue = 1;
    1152             :     }
    1153           0 :     return ( (STnsData const *) p )[index].filter;
    1154             : }
    1155             : 
    1156       89901 : void *SetTnsEnabledSingleFilter( void *p, const Word16 index, const Word16 value )
    1157             : {
    1158       89901 :     ( (STnsData *) p )[index].nFilters = value; /*Q0*/
    1159       89901 :     move16();
    1160       89901 :     return ( (STnsData *) p )[index].filter;
    1161             : }
    1162             : 
    1163             : /*-------------------------------------------------------------------*
    1164             :  * ResetTnsData()
    1165             :  *
    1166             :  *-------------------------------------------------------------------*/
    1167             : 
    1168      722365 : void ResetTnsData( STnsData *pTnsData )
    1169             : {
    1170             :     Word16 iFilter;
    1171             : 
    1172             : 
    1173      722365 :     pTnsData->nFilters = 0;
    1174      722365 :     move16();
    1175      722365 :     pTnsData->tnsOnWhitenedSpectra = 0;
    1176      722365 :     move16();
    1177     2167095 :     FOR( iFilter = 0; iFilter < (Word16) ( sizeof( pTnsData->filter ) / sizeof( pTnsData->filter[0] ) ); iFilter++ )
    1178             :     {
    1179     1444730 :         STnsFilter *const pTnsFilter = &pTnsData->filter[iFilter];
    1180     1444730 :         pTnsFilter->spectrumLength = 0;
    1181     1444730 :         move16();
    1182     1444730 :         pTnsFilter->predictionGain = ONE_IN_Q7; /*Q7*/
    1183     1444730 :         move16();
    1184     1444730 :         pTnsFilter->predictionGain32 = ONE_IN_Q23; /*Q23*/
    1185     1444730 :         move32();
    1186     1444730 :         pTnsFilter->predictionGain_e = PRED_GAIN_E;
    1187     1444730 :         move16();
    1188     1444730 :         pTnsFilter->avgSqrCoef = 0;
    1189     1444730 :         move16();
    1190     1444730 :         pTnsFilter->filterType = TNS_FILTER_OFF; /*Q0*/
    1191     1444730 :         move16();
    1192     1444730 :         ClearTnsFilterCoefficients( pTnsFilter );
    1193             :     }
    1194      722365 : }
    1195             : /*-------------------------------------------------------------------*
    1196             :  * ClearTnsFilterCoefficients()
    1197             :  *
    1198             :  *-------------------------------------------------------------------*/
    1199             : 
    1200     1444730 : void ClearTnsFilterCoefficients(
    1201             :     STnsFilter *pTnsFilter )
    1202             : {
    1203     1444730 :     move16();
    1204     1444730 :     pTnsFilter->order = 0;
    1205     1444730 :     move16();
    1206             :     assert( TNS_MAX_FILTER_ORDER == 8 );
    1207     1444730 :     move16();
    1208     1444730 :     move16();
    1209     1444730 :     move16();
    1210     1444730 :     move16();
    1211     1444730 :     move16();
    1212     1444730 :     move16();
    1213     1444730 :     move16();
    1214     1444730 :     move16();
    1215     1444730 :     pTnsFilter->coefIndex[0] = 0;
    1216     1444730 :     pTnsFilter->coefIndex[1] = 0;
    1217     1444730 :     pTnsFilter->coefIndex[2] = 0;
    1218     1444730 :     pTnsFilter->coefIndex[3] = 0;
    1219     1444730 :     pTnsFilter->coefIndex[4] = 0;
    1220     1444730 :     pTnsFilter->coefIndex[5] = 0;
    1221     1444730 :     pTnsFilter->coefIndex[6] = 0;
    1222     1444730 :     pTnsFilter->coefIndex[7] = 0;
    1223     1444730 : }
    1224             : 
    1225             : /** Inverse quantization for reflection coefficients.
    1226             :  *
    1227             :  * @param index input quantized values.
    1228             :  * @param parCoeff output reflection coefficients.
    1229             :  * @param order number of coefficients/values.
    1230             :  */
    1231      160164 : static void Index2Parcor( const Word16 index[] /*Q0*/, Word16 parCoeff[] /*Q15*/, Word16 order /*Q0*/ )
    1232             : {
    1233             :     const Word16 *values;
    1234             :     Word16 i;
    1235             : 
    1236      160164 :     move16();
    1237      160164 :     values = tnsCoeff4; /*Q15*/
    1238             : 
    1239      729969 :     FOR( i = 0; i < order; i++ )
    1240             :     {
    1241      569805 :         move16();
    1242      569805 :         parCoeff[i] = values[( index[i] + INDEX_SHIFT )]; /*Q15*/
    1243             :     }
    1244      160164 :     return;
    1245             : }
    1246             : 
    1247             : 
    1248             : /* Linear prediction analysis filter. */
    1249           0 : static Word32 FIRLattice(
    1250             :     const Word16 order, /*Q0*/
    1251             :     const Word16 *parCoeff /*Q15*/,
    1252             :     Word32 *state, /*Q0*/
    1253             :     Word32 x       /* Q0 */
    1254             : )
    1255             : {
    1256             :     Word16 i;
    1257             :     Word32 tmpSave, tmp;
    1258             : 
    1259             : 
    1260           0 :     tmpSave = x;
    1261           0 :     move32();
    1262           0 :     FOR( i = 0; i < order - 1; i++ )
    1263             :     {
    1264           0 :         tmp = L_add( state[i], Mpy_32_16_1( x, parCoeff[i] ) ); /*Q0*/
    1265           0 :         x = L_add( x, Mpy_32_16_1( state[i], parCoeff[i] ) );   /* exponent: 31+0 */
    1266           0 :         state[i] = tmpSave;                                     /*Q0*/
    1267           0 :         move32();
    1268           0 :         tmpSave = tmp; /*Q0*/
    1269           0 :         move32();
    1270             :     }
    1271             : 
    1272             :     /* last stage: only need half operations */
    1273           0 :     x = L_add( x, Mpy_32_16_1( state[order - 1], parCoeff[order - 1] ) ); /*Q0*/
    1274           0 :     state[order - 1] = tmpSave;                                           /*Q0*/
    1275           0 :     move32();
    1276             : 
    1277           0 :     return x; /*Q0*/
    1278             : }
    1279             : 
    1280    46001276 : static Word32 IIRLattice( Word16 order /*Q0*/, const Word16 *parCoeff /*Q15*/, Word32 *state /*Q0*/, Word32 x /*Q0*/ )
    1281             : {
    1282             :     Word16 i;
    1283             : 
    1284             : 
    1285             :     /* first stage: no need to calculate state[order-1] */
    1286    46001276 :     x = Msub_32_16( x, state[order - 1], parCoeff[order - 1] ); /*Q0*/
    1287             : 
    1288   255810113 :     FOR( i = order - 2; i >= 0; i-- )
    1289             :     {
    1290   209808837 :         x = Msub_32_16( x, state[i], parCoeff[i] );            /*Q0*/
    1291   209808837 :         state[i + 1] = Madd_32_16( state[i], x, parCoeff[i] ); /*Q0*/
    1292   209808837 :         move32();
    1293             :     }
    1294             : 
    1295    46001276 :     move32();
    1296    46001276 :     state[0] = x; /*Q0*/
    1297    46001276 :     return x;     /*Q0*/
    1298             : }
    1299             : /** TNS analysis/synthesis filter.
    1300             :   * @param spectrum input spectrum values.
    1301             :   * @param numOfLines number of lines in the spectrum.
    1302             :   * @param parCoeff filter (PARCOR) coefficients.
    1303             :   * @param order filter order.
    1304             :   * @param filter function that implements filtering.
    1305             :     By this function it is defined whether analysis or synthesis is performed.
    1306             :   * @param output filtered output spectrum values.
    1307             :     Inplace operation is supported, so it can be equal to spectrum.
    1308             :   */
    1309      160164 : static void TnsFilter(
    1310             :     const Word32 spectrum[], /*Qx*/
    1311             :     const Word16 numOfLines, /*Q0*/
    1312             :     const Word16 parCoeff[], /*Q15*/
    1313             :     const Word16 order,      /*Q0*/
    1314             :     TLinearPredictionFilter filter,
    1315             :     Word32 *state, /*Q0*/
    1316             :     Word32 output[] /*Qx*/ )
    1317             : {
    1318             :     Word16 j;
    1319             : 
    1320             : 
    1321      160164 :     assert( ( order >= 0 ) && ( order <= TNS_MAX_FILTER_ORDER ) );
    1322      160164 :     assert( ( numOfLines > 0 ) || ( ( numOfLines == 0 ) && ( order == 0 ) ) );
    1323             : 
    1324      160164 :     IF( order == 0 )
    1325             :     {
    1326             : 
    1327       56762 :         test();
    1328       56762 :         IF( s_and( ( spectrum != output ), numOfLines > 0 ) )
    1329             :         {
    1330           0 :             Copy32( spectrum, output, numOfLines ); /*Qx*/
    1331             :         }
    1332             :     }
    1333             :     ELSE
    1334             :     {
    1335             :         {
    1336             : 
    1337    46104678 :             FOR( j = 0; j < numOfLines; j++ )
    1338             :             {
    1339    46001276 :                 move32();
    1340    46001276 :                 output[j] = filter( order, parCoeff, state, spectrum[j] ); /*Qx*/
    1341             :             }
    1342             :         }
    1343             :     }
    1344      160164 :     return;
    1345             : }
    1346             : 
    1347      465347 : static void ITF_TnsFilter_fx(
    1348             :     const Word32 spectrum[], /*Qx*/
    1349             :     const Word16 numOfLines, /*Q0*/
    1350             :     const Word16 A[],        /* ifdef FIX_ITF_OVERFLOW Q_A else Q14 */
    1351             :     const Word16 Q_A,
    1352             :     const Word16 order, /*Q0*/
    1353             :     Word32 output[] /*Qx*/ )
    1354             : {
    1355             :     Word16 i, j;
    1356             :     Word32 buf[ITF_MAX_FILTER_ORDER + N_MAX];
    1357             :     Word32 *p;
    1358             :     Word16 shift;
    1359      465347 :     assert( ( order >= 0 ) && ( order <= ITF_MAX_FILTER_ORDER ) );
    1360      465347 :     assert( ( numOfLines > 0 ) || ( ( numOfLines == 0 ) && ( order == 0 ) ) );
    1361             : 
    1362      465347 :     IF( order == 0 )
    1363             :     {
    1364             : 
    1365      403045 :         test();
    1366      403045 :         IF( s_and( ( spectrum != output ), numOfLines > 0 ) )
    1367             :         {
    1368           0 :             Copy32( spectrum, output, numOfLines ); /*Qx*/
    1369             :         }
    1370             :     }
    1371             :     ELSE
    1372             :     {
    1373       62302 :         shift = sub( 15, Q_A );
    1374             : 
    1375       62302 :         p = buf + ITF_MAX_FILTER_ORDER;
    1376       62302 :         set32_fx( buf, 0, ITF_MAX_FILTER_ORDER );
    1377       62302 :         Copy32( spectrum, p, numOfLines ); /*Qx*/
    1378    20666186 :         FOR( j = 0; j < numOfLines; j++ )
    1379             :         {
    1380             :             Word32 L_tmp;
    1381             : 
    1382    20603884 :             L_tmp = L_add( p[0], 0 );
    1383   164831072 :             FOR( i = 1; i < order; i++ )
    1384             :             {
    1385   144227188 :                 L_tmp = L_add_sat( L_tmp, L_shl( Mpy_32_16_1( p[-i], A[i] ), shift ) ); /*Qx*/
    1386             :             }
    1387    20603884 :             output[j] = L_tmp; /*Qx*/
    1388    20603884 :             move32();
    1389    20603884 :             ++p;
    1390             :         }
    1391             :     }
    1392      465347 :     return;
    1393             : }
    1394             : 
    1395       62302 : static void ITF_GetFilterParameters_fx(
    1396             :     Word32 rxx[],          /*Qx*/
    1397             :     const Word16 maxOrder, /*Q0*/
    1398             :     Word16 *A,             /* ifdef FIX_ITF_OVERFLOW Q_A else Q14 */
    1399             :     Word16 *Q_A,
    1400             :     Word16 *predictionGain /*Q7*/ )
    1401             : {
    1402             :     Word16 i, j, i_2, tmp;
    1403             :     Word16 parCoeff[ITF_MAX_FILTER_ORDER];
    1404             :     Word32 epsP[ITF_MAX_FILTER_ORDER + 1], L_tmp;
    1405             : 
    1406             :     /* compute filter in ParCor form with LeRoux-Gueguen algorithm */
    1407       62302 :     L_tmp = E_LPC_schur( rxx, parCoeff, epsP, maxOrder );
    1408             :     BASOP_SATURATE_WARNING_OFF_EVS                                            /* Allow saturation, this value is compared against a threshold. */
    1409       62302 :         *predictionGain = divide3232( L_shr( epsP[0], PRED_GAIN_E ), L_tmp ); /*Q7*/
    1410       62302 :     move16();
    1411             :     BASOP_SATURATE_WARNING_ON_EVS
    1412             : 
    1413             :     {
    1414             :         Word32 A32[ITF_MAX_FILTER_ORDER];
    1415             :         Word16 tmp1_l, tmp1_h, tmp2_l, tmp2_h;
    1416             : 
    1417             :         /* Convert ParCor / reflection coefficients to LPC */
    1418       62302 :         A32[0] = 134217728l /*1.0 Q27*/;
    1419       62302 :         move32();                                        /* Q11+16 */
    1420       62302 :         A32[1] = L_shr( L_deposit_h( parCoeff[0] ), 4 ); /* Q11+16 */
    1421       62302 :         move32();
    1422             : 
    1423      498416 :         FOR( i = 1; i < maxOrder; i++ )
    1424             :         {
    1425      436114 :             L_tmp = L_shr( L_deposit_h( parCoeff[i] ), 3 ); /* Q11+16 */
    1426             : 
    1427      436114 :             i_2 = shr( i, 1 );
    1428     1183738 :             FOR( j = 0; j < i_2; j++ )
    1429             :             {
    1430      747624 :                 tmp1_l = L_Extract_lc( A32[i - 1 - j + 1], &tmp1_h );
    1431      747624 :                 tmp2_l = L_Extract_lc( A32[j + 1], &tmp2_h );
    1432      747624 :                 A32[j + 1] = Mac_32( A32[j + 1], parCoeff[i], 0, tmp1_h, tmp1_l ); /*+= parCoeff[i] * a[i-1-j+1]; Q11+16*/
    1433      747624 :                 move32();
    1434      747624 :                 A32[i - 1 - j + 1] = Mac_32( A32[i - 1 - j + 1], parCoeff[i], 0, tmp2_h, tmp2_l ); /*+= parCoeff[i] * tmp; Q11+16*/
    1435      747624 :                 move32();
    1436             :             }
    1437      436114 :             IF( s_and( i, 1 ) )
    1438             :             {
    1439      249208 :                 tmp2_l = L_Extract_lc( A32[j + 1], &tmp2_h );
    1440      249208 :                 A32[j + 1] = Mac_32( A32[j + 1], parCoeff[i], 0, tmp2_h, tmp2_l ); /*+= parCoeff[i] * a[j+1]; Q11+16*/
    1441      249208 :                 move32();
    1442             :             }
    1443             : 
    1444      436114 :             A32[i + 1] = L_shr( L_deposit_h( parCoeff[i] ), 4 ); /* Q11+16 */
    1445      436114 :             move32();
    1446             :         }
    1447             : 
    1448       62302 :         tmp = 3;
    1449       62302 :         move16(); /* assume Q11 -> Q14 */
    1450      560718 :         FOR( i = 0; i < maxOrder; i++ )
    1451             :         {
    1452      498416 :             tmp = s_min( tmp, norm_l( A32[i] ) );
    1453             :         }
    1454      560718 :         FOR( i = 0; i < maxOrder; i++ )
    1455             :         {
    1456      498416 :             A[i] = round_fx( L_shl( A32[i], tmp ) ); /* Q11+tmp */
    1457      498416 :             move16();
    1458             :         }
    1459       62302 :         *Q_A = add( 11, tmp );
    1460       62302 :         move16();
    1461             :     }
    1462       62302 :     return;
    1463             : }

Generated by: LCOV version 1.14