LCOV - code coverage report
Current view: top level - lib_com - tns_base.c (source / functions) Hit Total Coverage
Test: Coverage on main @ e95243e9e67ddeb69dddf129509de1b3d95b402e Lines: 533 578 92.2 %
Date: 2025-09-15 02:22:33 Functions: 47 57 82.5 %

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

Generated by: LCOV version 1.14