LCOV - code coverage report
Current view: top level - lib_com - tns_base.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 574a190e3c6896c6c4ed10d7f23649709a0c4347 Lines: 535 580 92.2 %
Date: 2025-06-27 02:59:36 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             : /*----------------------------------------------------------------------------
      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       45392 : 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       45392 :     Word16 iFilter = 0;
      93       45392 :     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       45392 :     nSampleRate = bwMode2fs[bwidth];
     102       45392 :     move32();
     103       45392 :     startLineFilter = &pTnsConfig->iFilterBorders[1];
     104             : 
     105             :     /* Sanity checks */
     106       45392 :     assert( ( nSampleRate > 0 ) && ( frameLength > 0 ) && ( pTnsConfig != NULL ) );
     107       45392 :     test();
     108       45392 :     test();
     109       45392 :     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       45392 :     move16();
     117       45392 :     pTnsConfig->maxOrder = TNS_MAX_FILTER_ORDER;
     118             : 
     119       45392 :     IF( LE_32( total_brate, ACELP_32k ) )
     120             :     {
     121        6404 :         move16();
     122        6404 :         move16();
     123        6404 :         pTnsConfig->nMaxFilters = sizeof( tnsParametersIGF32kHz_LowBR ) / sizeof( tnsParametersIGF32kHz_LowBR[0] );
     124        6404 :         pTnsConfig->pTnsParameters = tnsParametersIGF32kHz_LowBR;
     125             :     }
     126             :     ELSE
     127             :     {
     128       38988 :         test();
     129       38988 :         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       29668 :         IF( GT_32( nSampleRate, INT_FS_16k ) )
     138             :         {
     139             :             {
     140             : 
     141       27769 :                 move16();
     142       27769 :                 pTnsConfig->nMaxFilters = sizeof( tnsParameters32kHz ) / sizeof( tnsParameters32kHz[0] );
     143             : 
     144       27769 :                 move16();
     145       27769 :                 pTnsConfig->pTnsParameters = tnsParameters32kHz;
     146             : 
     147       27769 :                 if ( EQ_32( nSampleRate, L_mult0( 100, frameLength ) ) ) /* sub-frame length is <= 10 ms */
     148             :                 {
     149        3043 :                     move16();
     150        3043 :                     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       45392 :     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      128506 :     FOR( iFilter = 0; iFilter < pTnsConfig->nMaxFilters; iFilter++ )
     177             :     {
     178       83114 :         assert( pTnsConfig->pTnsParameters[iFilter].startLineFrequency < 0.5f * nSampleRate );
     179       83114 :         assert( nSampleRate <= 96000 );
     180       83114 :         move16();
     181       83114 :         startLineFilter[iFilter] = divide3232( L_mult0( frameLength, pTnsConfig->pTnsParameters[iFilter].startLineFrequency ), L_shl( nSampleRate, 14 ) );
     182             :     }
     183             : 
     184       45392 :     IF( igfStopFreq > 0 )
     185             :     {
     186       34442 :         L_tmp = L_mult( frameLength, igfStopFreq );
     187       34442 :         s1 = sub( norm_l( L_tmp ), 1 );
     188       34442 :         s2 = norm_l( nSampleRate );
     189             : 
     190       34442 :         move16();
     191       34442 :         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       10950 :         move16();
     196       10950 :         pTnsConfig->iFilterBorders[0] = frameLength;
     197             :     }
     198       45392 :     return; /*TNS_NO_ERROR;*/
     199             : }
     200             : 
     201       82401 : 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       82401 :     Word16 iFilter = 0;
     211       82401 :     move16();
     212             :     Word16 *startLineFilter;
     213             :     Word32 L_tmp;
     214             :     Word32 nSampleRate;
     215             :     Word16 s1;
     216             :     Word16 s2;
     217             : 
     218       82401 :     nSampleRate = bwMode2fs[bwidth];
     219       82401 :     move32();
     220       82401 :     startLineFilter = &pTnsConfig->iFilterBorders[1]; /*Q0*/
     221             : 
     222             :     /* Sanity checks */
     223       82401 :     assert( ( nSampleRate > 0 ) && ( frameLength > 0 ) && ( pTnsConfig != NULL ) );
     224       82401 :     test();
     225       82401 :     test();
     226       82401 :     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       82401 :     move16();
     234       82401 :     pTnsConfig->maxOrder = TNS_MAX_FILTER_ORDER;
     235             : 
     236       82401 :     IF( LE_32( total_brate, ACELP_32k ) )
     237             :     {
     238       19836 :         move16();
     239       19836 :         pTnsConfig->nMaxFilters = (UWord8) idiv1616( sizeof( tnsParametersIGF32kHz_LowBR ), sizeof( tnsParametersIGF32kHz_LowBR[0] ) ); /*Q0*/
     240       19836 :         pTnsConfig->pTnsParameters = tnsParametersIGF32kHz_LowBR;
     241             :     }
     242             :     ELSE
     243             :     {
     244       62565 :         test();
     245       62565 :         IF( GT_32( nSampleRate, 32000 ) && EQ_32( nSampleRate, L_mult0( 100, frameLength ) ) )
     246             :         {
     247       16043 :             pTnsConfig->nMaxFilters = (UWord8) idiv1616( sizeof( tnsParameters48kHz_grouped ), sizeof( tnsParameters48kHz_grouped[0] ) ); /*Q0*/
     248       16043 :             move16();
     249       16043 :             pTnsConfig->pTnsParameters = tnsParameters48kHz_grouped;
     250             :         }
     251       46522 :         ELSE IF( GT_32( nSampleRate, INT_FS_16k ) )
     252             :         {
     253       44251 :             L_tmp = IVAS_32k;
     254       44251 :             move32();
     255       44251 :             if ( !is_mct )
     256             :             {
     257       27893 :                 L_tmp = IVAS_48k;
     258       27893 :                 move32();
     259             :             }
     260       44251 :             test();
     261       44251 :             IF( GT_16( element_mode, IVAS_SCE ) && GE_32( total_brate, L_tmp ) )
     262             :             {
     263       34430 :                 pTnsConfig->nMaxFilters = (UWord8) idiv1616( sizeof( tnsParameters32kHz_Stereo ), sizeof( tnsParameters32kHz_Stereo[0] ) ); /*Q0*/
     264       34430 :                 move16();
     265       34430 :                 IF( EQ_32( nSampleRate, L_mult0( 100, frameLength ) ) ) /* sub-frame length is <= 10 ms */
     266             :                 {
     267        3678 :                     pTnsConfig->pTnsParameters = tnsParameters32kHz_grouped;
     268             :                 }
     269             :                 ELSE
     270             :                 {
     271       30752 :                     pTnsConfig->pTnsParameters = tnsParameters32kHz_Stereo;
     272             :                 }
     273             :             }
     274             :             ELSE
     275             :             {
     276             : 
     277        9821 :                 move16();
     278        9821 :                 pTnsConfig->nMaxFilters = (UWord8) idiv1616( sizeof( tnsParameters32kHz ), sizeof( tnsParameters32kHz[0] ) ); /*Q0*/
     279             : 
     280        9821 :                 pTnsConfig->pTnsParameters = tnsParameters32kHz;
     281             : 
     282        9821 :                 if ( EQ_32( nSampleRate, L_mult0( 100, frameLength ) ) ) /* sub-frame length is <= 10 ms */
     283             :                 {
     284         377 :                     pTnsConfig->pTnsParameters = tnsParameters32kHz_grouped;
     285             :                 }
     286             :             }
     287             :         }
     288             :         ELSE
     289             :         {
     290        2271 :             IF( EQ_32( nSampleRate, L_mult0( 100, frameLength ) ) ) /* sub-frame length is <= 10 ms */
     291             :             {
     292         757 :                 move16();
     293         757 :                 pTnsConfig->nMaxFilters = (UWord8) idiv1616( sizeof( tnsParameters16kHz_grouped ), sizeof( tnsParameters16kHz_grouped[0] ) ); /*Q0*/
     294         757 :                 pTnsConfig->pTnsParameters = tnsParameters16kHz_grouped;
     295             :             }
     296             :             ELSE
     297             :             {
     298        1514 :                 move16();
     299        1514 :                 pTnsConfig->nMaxFilters = (UWord8) idiv1616( sizeof( tnsParameters16kHz ), sizeof( tnsParameters16kHz[0] ) ); /*Q0*/
     300        1514 :                 pTnsConfig->pTnsParameters = tnsParameters16kHz;
     301             :             }
     302             :         }
     303             :     }
     304             : 
     305       82401 :     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      225853 :     FOR( iFilter = 0; iFilter < pTnsConfig->nMaxFilters; iFilter++ )
     310             :     {
     311      143452 :         assert( pTnsConfig->pTnsParameters[iFilter].startLineFrequency < nSampleRate / 2 );
     312      143452 :         assert( nSampleRate <= 96000 );
     313      143452 :         move16();
     314      143452 :         startLineFilter[iFilter] = divide3232( L_mult0( frameLength, pTnsConfig->pTnsParameters[iFilter].startLineFrequency ), L_shl( nSampleRate, 14 ) ); /*Q0*/
     315             :     }
     316             : 
     317       82401 :     IF( igfStopFreq > 0 )
     318             :     {
     319       66534 :         L_tmp = L_mult( frameLength, igfStopFreq );
     320       66534 :         s1 = sub( norm_l( L_tmp ), 1 );
     321       66534 :         s2 = norm_l( nSampleRate );
     322             : 
     323       66534 :         move16();
     324       66534 :         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       15867 :         move16();
     329       15867 :         pTnsConfig->iFilterBorders[0] = frameLength; /*Q0*/
     330             :     }
     331             : 
     332       82401 :     pTnsConfig->allowTnsOnWhite = 0;
     333       82401 :     move16();
     334             : 
     335       82401 :     return; /*TNS_NO_ERROR;*/
     336             : }
     337             : 
     338             : 
     339             : /*-------------------------------------------------------------------*
     340             :  * ApplyTnsFilter()
     341             :  *
     342             :  *-------------------------------------------------------------------*/
     343             : 
     344      185583 : 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      185583 :     move16();
     358      185583 :     filter = IIRLattice;
     359      185583 :     if ( fIsAnalysis )
     360             :     {
     361       87239 :         filter = FIRLattice;
     362             :     }
     363      185583 :     set32_fx( state, 0, TNS_MAX_FILTER_ORDER );
     364      185583 :     move16();
     365      185583 :     pBorders = pTnsConfig->iFilterBorders; /*Q0*/
     366             : 
     367      553726 :     FOR( iFilter = pTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- )
     368             :     {
     369             :         Word16 parCoeff[TNS_MAX_FILTER_ORDER];
     370             :         const STnsFilter *pFilter;
     371             : 
     372      368143 :         move16();
     373      368143 :         move16();
     374      368143 :         pFilter = &pTnsData->filter[iFilter];
     375      368143 :         stopLine = pBorders[iFilter];
     376      368143 :         startLine = pBorders[iFilter + 1];
     377             : 
     378      368143 :         Index2Parcor( pFilter->coefIndex, parCoeff, pFilter->order );
     379             : 
     380      368143 :         TnsFilter( &spectrum[startLine], stopLine - startLine,
     381      368143 :                    parCoeff, pFilter->order,
     382             :                    filter, state,
     383      368143 :                    &spectrum[startLine] );
     384             :     }
     385             : 
     386      185583 :     move16();
     387             : 
     388      185583 :     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        1171 : 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        1171 :     Word16 const nSubdivisions = MAX_SUBDIVISIONS;
     429        1171 :     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        1171 :     Flag Overflow = 0;
     444        1171 :     move32();
     445             : #endif
     446             : 
     447        1171 :     move16();
     448        1171 :     move16();
     449        1171 :     move16();
     450             : 
     451        1171 :     if ( maxOrder <= 0 )
     452             :     {
     453           0 :         return 0;
     454             :     }
     455             : 
     456             :     /* Calculate norms for each spectrum part */
     457        4684 :     FOR( iSubdivisions = 0; iSubdivisions < nSubdivisions; iSubdivisions++ )
     458             :     {
     459        3513 :         assert( ( nSubdivisions == 1 ) || ( nSubdivisions == 3 ) );
     460             : 
     461        3513 :         tmp = sub( stopLine, startLine );
     462        3513 :         iStartLine = imult1616( tmp, iSubdivisions ); /*Q0*/
     463        3513 :         iEndLine = add( iStartLine, tmp );
     464             : 
     465        3513 :         if ( EQ_16( nSubdivisions, 3 ) )
     466        3513 :             iStartLine = mult( iStartLine, 0x2AAB ); /*Q0*/
     467        3513 :         iStartLine = add( iStartLine, startLine );
     468             : 
     469        3513 :         if ( EQ_16( nSubdivisions, 3 ) )
     470        3513 :             iEndLine = mult( iEndLine, 0x2AAB ); /*Q0*/
     471        3513 :         iEndLine = add( iEndLine, startLine );
     472        3513 :         headroom = getScaleFactor32( pSpectrum + iStartLine - IGF_START_MN, sub( iEndLine, iStartLine ) );
     473             :         /* Calculate norm of spectrum band */
     474        3513 :         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        3513 :         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        3513 :         tmp = sub( shift, norm_l( L_tmp ) ); /* exponent for normalized L_tmp */
     483        3513 :         tmp = shr( sub( 1, tmp ), 1 );       /* pre-shift to apply before autocorrelation */
     484        3513 :         shifts[iSubdivisions] = s_min( tmp, headroom );
     485        3513 :         move16();
     486             : 
     487             :         /* calc normalization factor */
     488        3513 :         facs[iSubdivisions] = 0;
     489        3513 :         move16();
     490        3513 :         facs_e[iSubdivisions] = 0;
     491        3513 :         move16();
     492             : 
     493        3513 :         if ( tmp32 > 0 )
     494             :         {
     495         688 :             facs[iSubdivisions] = 0x7FFF;
     496         688 :             move16(); /* normalization not needed for one subdivision */
     497             :         }
     498             : 
     499        3513 :         test();
     500        3513 :         IF( ( tmp32 > 0 ) && ( GT_16( nSubdivisions, 1 ) ) )
     501             :         {
     502         688 :             move16();
     503         688 :             facs_e[iSubdivisions] = shl( sub( tmp, shifts[iSubdivisions] ), 1 );
     504             : 
     505         688 :             tmp = sub( 1, shl( tmp, 1 ) );             /* exponent of autocorrelation */
     506         688 :             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         688 :             facs[iSubdivisions] = div_s( 0x2000, round_fx_sat( L_tmp ) ); /* L_tmp is >= 0x2000000 Q15*/
     510         688 :             move16();
     511             :         }
     512             :     }
     513             : 
     514             :     /* Calculate normalized autocorrelation for spectrum subdivision and get filter parameters based on it */
     515        1171 :     set32_fx( rxx, 0, ITF_MAX_FILTER_ORDER + 1 );
     516             : 
     517        1171 :     spectrumLength = sub( stopLine, startLine );
     518             : 
     519        1853 :     FOR( iSubdivisions = 0; iSubdivisions < nSubdivisions; iSubdivisions++ )
     520             :     {
     521        1734 :         IF( facs[iSubdivisions] == 0 )
     522             :         {
     523        1052 :             BREAK;
     524             :         }
     525             : 
     526             : 
     527         682 :         assert( ( nSubdivisions == 1 ) || ( nSubdivisions == 3 ) );
     528             : 
     529         682 :         iStartLine = imult1616( spectrumLength, iSubdivisions ); /*Q0*/
     530         682 :         iEndLine = add( iStartLine, spectrumLength );            /*Q0*/
     531             : 
     532         682 :         if ( EQ_16( nSubdivisions, 3 ) )
     533         682 :             iStartLine = mult( iStartLine, 0x2AAB ); /*Q0*/
     534         682 :         iStartLine = add( iStartLine, startLine );
     535             : 
     536         682 :         if ( EQ_16( nSubdivisions, 3 ) )
     537         682 :             iEndLine = mult( iEndLine, 0x2AAB ); /*Q0*/
     538         682 :         iEndLine = add( iEndLine, startLine );
     539             : 
     540             : 
     541         682 :         move16();
     542         682 :         shift = shifts[iSubdivisions];
     543             : 
     544         682 :         n = sub( iEndLine, iStartLine );
     545         682 :         assert( n < (Word16) ( sizeof( tmpbuf ) / sizeof( Word16 ) ) );
     546       81112 :         FOR( i = 0; i < n; i++ )
     547             :         {
     548       80430 :             tmpbuf[i] = round_fx_sat( L_shl_sat( pSpectrum[iStartLine + i - IGF_START_MN], shift ) ); /*Q + shift - 16*/
     549       80430 :             move16();
     550             :         }
     551             : 
     552        6820 :         FOR( lag = 0; lag <= maxOrder; lag++ )
     553             :         {
     554        6138 :             n = sub( sub( iEndLine, lag ), iStartLine );
     555             : 
     556             :             {
     557        6138 :                 Word64 tmp64 = 0;
     558      705456 :                 FOR( i = 0; i < n; i++ )
     559             :                 {
     560      699318 :                     tmp64 = W_mac0_16_16( tmp64, tmpbuf[i], tmpbuf[i + lag] ); /*2*(Q + shift) - 32*/
     561             :                 }
     562        6138 :                 L_tmp = W_sat_l( tmp64 ); /*2*(Q + shift) - 32*/
     563             :             }
     564             : 
     565        6138 :             L_tmp = Mpy_32_16_1( L_tmp, facs[iSubdivisions] ); /*2*(Q + shift) - 32*/
     566        6138 :             L_tmp = L_shl( L_tmp, facs_e[iSubdivisions] );     /*2*(Q + shift) - 32 + facs_e*/
     567             : 
     568        6138 :             rxx[lag] = L_add( rxx[lag], L_tmp );
     569        6138 :             move32();
     570             :         }
     571             :     }
     572             : 
     573        1171 :     IF( EQ_16( iSubdivisions, nSubdivisions ) ) /* meaning there is no subdivision with low energy */
     574             :     {
     575             :         /* Limit the maximum order to spectrum length/4 */
     576         119 :         ITF_GetFilterParameters_fx( rxx, s_min( maxOrder, shr( spectrumLength, 2 ) ), A, Q_A, predictionGain );
     577             : 
     578         119 :         *curr_order = maxOrder; /*Q0*/
     579         119 :         move16();
     580             :     }
     581             : 
     582        1171 :     return 1;
     583             : }
     584             : 
     585     1057344 : 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     1057344 :     IF( maxOrder <= 0 )
     611             :     {
     612           0 :         return 0;
     613             :     }
     614     1057344 :     pWindow = tnsAcfWindow_fx;
     615     1057344 :     set_zero_fx( norms, MAX_SUBDIVISIONS );
     616     1057344 :     set_zero_fx( rxx, ITF_MAX_FILTER_ORDER + 1 );     /* This initialization is required */
     617     1057344 :     set16_fx( q_rxx, Q31, ITF_MAX_FILTER_ORDER + 1 ); /* This initialization is required */
     618             : 
     619     1057344 :     spectrumLength = sub( stopLine, startLine );
     620     1057344 :     num_subdivisions = 0;
     621     1057344 :     move16();
     622             : 
     623             :     /* Calculate norms for each spectrum part */
     624     1713940 :     FOR( iSubdivisions = 0; iSubdivisions < MAX_SUBDIVISIONS; iSubdivisions++ )
     625             :     {
     626             :         /* iStartLine = startLine + ( stopLine - startLine ) * iSubdivisions / nSubdivisions; */
     627     1551433 :         iStartLine = add( startLine, mult( imult1616( spectrumLength, iSubdivisions ), 10923 /* 1/MAX_SUBDIVISIONS in Q15 */ ) ); /*Q0*/
     628             :         /* iEndLine = startLine + ( stopLine - startLine ) * ( iSubdivisions + 1 ) / nSubdivisions; */
     629     1551433 :         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     1551433 :         ptr_spectrum1 = pSpectrum + sub( iStartLine, IGF_START_MN );
     636     1551433 :         length = sub( iEndLine, iStartLine );
     637     1551433 :         headroom = L_norm_arr( ptr_spectrum1, length );
     638     1551433 :         guard_bits = find_guarded_bits_fx( length );
     639     1551433 :         shift = sub( headroom, guard_bits );
     640             : 
     641     1551433 :         Copy_Scale_sig32( ptr_spectrum1, temp_spectrum, length, shift ); // Q -> Q+shift
     642             : 
     643     1551433 :         sum = 0;
     644     1551433 :         move64();
     645   159521619 :         FOR( i = 0; i < length; i++ )
     646             :         {
     647   157970186 :             sum = W_mac_32_32( sum, temp_spectrum[i], temp_spectrum[i] ); // 2(Q+shift)+1
     648             :         }
     649             : 
     650     1551433 :         IF( LE_64( sum, W_shl( 32768 * 2 /* HLM_MIN_NRG in Q1 */, shl( add( Q, shift ), 1 ) ) ) )
     651             :         {
     652      894837 :             BREAK;
     653             :         }
     654             : 
     655             :         /* fac = 1.0f / norms[iSubdivisions]; */
     656      656596 :         exp = W_norm( sum );
     657      656596 :         sum = W_shl( sum, exp );                                    // 2(Q+shift)+1+exp
     658      656596 :         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      656596 :         q_fac = sub( 76, add( shl( add( Q, shift ), 1 ), exp ) );
     660      656596 :         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      656596 :         ptr_spectrum1 = temp_spectrum; // pSpectrum + iStartLine - IGF_START_MN;
     671     5909364 :         FOR( lag = 1; lag <= maxOrder; lag++ )
     672             :         {
     673             :             /* dotp( pSpectrum + iStartLine - IGF_START_MN, pSpectrum + iStartLine - IGF_START_MN + lag, iEndLine - iStartLine - lag ) */
     674     5252768 :             ptr_spectrum2 = temp_spectrum + lag; //  pSpectrum + iStartLine - IGF_START_MN + lag;
     675             : 
     676     5252768 :             sum = 0;
     677     5252768 :             move64();
     678   566869864 :             FOR( i = 0; i < iEndLine - iStartLine - lag; i++ )
     679             :             {
     680   561617096 :                 sum = W_mac_32_32( sum, ptr_spectrum1[i], ptr_spectrum2[i] ); // 2(Q+shift)+1
     681             :             }
     682     5252768 :             exp = W_norm( sum );
     683     5252768 :             sum = W_shl( sum, exp );                                          // 2(Q+shift)+1+exp
     684     5252768 :             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     5252768 :             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     5252768 :             q_min = sub( s_min( q_temp, q_rxx[lag] ), 1 );
     689     5252768 :             rxx[lag] = L_add( L_shl( rxx[lag], sub( q_min, q_rxx[lag] ) ), L_shl( temp, sub( q_min, q_temp ) ) );
     690     5252768 :             q_rxx[lag] = q_min;
     691     5252768 :             move32();
     692     5252768 :             move16();
     693             : 
     694     5252768 :             pWindow++;
     695             :         }
     696             : 
     697      656596 :         num_subdivisions = add( num_subdivisions, 1 );
     698             :     }
     699             : 
     700     1057344 :     minimum_s( q_rxx + 1, ITF_MAX_FILTER_ORDER, &q_min );
     701     1057344 :     q_min = s_min( Q29, q_min );
     702             : 
     703    16917504 :     FOR( i = 1; i < ITF_MAX_FILTER_ORDER; i++ )
     704             :     {
     705    15860160 :         rxx[i] = L_shl( rxx[i], sub( q_min, q_rxx[i] ) );
     706    15860160 :         move32();
     707             :     }
     708             : 
     709     1057344 :     IF( EQ_16( iSubdivisions, MAX_SUBDIVISIONS ) ) /* meaning there is no subdivision with low energy */
     710             :     {
     711      162507 :         rxx[0] = L_shl( MAX_SUBDIVISIONS, q_min );
     712      162507 :         move32();
     713             : 
     714             :         /* Limit the maximum order to spectrum length/4 */
     715      162507 :         ITF_GetFilterParameters_fx( rxx, s_min( maxOrder, shr( spectrumLength, 2 ) ), A, Q_A, predictionGain );
     716             : 
     717      162507 :         *curr_order = maxOrder; /*Q0*/
     718      162507 :         move16();
     719             :     }
     720             : 
     721     1057344 :     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     1439459 : static Word16 GetBitsFromTable( const Word16 value /*Q0*/, const Coding codes[], const Word16 nSize /*Q0*/ )
     730             : {
     731             :     (void) nSize;
     732     1439459 :     assert( ( value >= 0 ) && ( value < nSize ) && ( nSize >= 0 ) && ( nSize <= 256 ) );
     733             : 
     734     1439459 :     move16();
     735     1439459 :     cast16();
     736     1439459 :     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      711050 : static Word16 EncodeUsingTable( const Word16 value /*Q0*/, const Coding codes[], const Word16 nSize /*Q0*/ )
     743             : {
     744             :     (void) nSize;
     745      711050 :     assert( ( value >= 0 ) && ( value < nSize ) && ( nSize >= 0 ) && ( nSize <= 256 ) );
     746             : 
     747      711050 :     move16();
     748      711050 :     return codes[value].code; /*Q0*/
     749             : }
     750             : 
     751             : 
     752             : /** Decode a value from a bitstream using a Huffman table. */
     753      658993 : static Word16 DecodeUsingTable( Decoder_State *st, Word16 *pValue /*Q0*/, const Coding codes[], const Word16 nSize /*Q0*/ )
     754             : {
     755      658993 :     Word16 code = 0;
     756      658993 :     Word16 nBits = 0;
     757      658993 :     move16();
     758      658993 :     move16();
     759             :     Word16 valueIndex;
     760             : 
     761      658993 :     assert( ( nSize >= 0 ) && ( nSize <= 256 ) );
     762             : 
     763             : 
     764      658993 :     move16();
     765      658993 :     valueIndex = nSize;
     766             : 
     767             : 
     768     2368954 :     WHILE( valueIndex == nSize )
     769             :     {
     770     1709961 :         code = add( shl( code, 1 ), get_next_indice_fx( st, 1 ) ); /*Q0*/
     771     1709961 :         nBits = add( nBits, 1 );
     772     1709961 :         test();
     773     1709961 :         IF( GT_16( nBits, nSize ) || GT_16( nBits, 16 ) )
     774             :         {
     775           0 :             st->BER_detect = 1;
     776           0 :             move16();
     777           0 :             *pValue = 0;
     778           0 :             move16();
     779             : 
     780           0 :             return -1;
     781             :         }
     782             : 
     783    21986807 :         FOR( valueIndex = 0; valueIndex < nSize; valueIndex++ )
     784             :         {
     785             : 
     786    20935839 :             IF( s_and( (Word16) EQ_16( codes[valueIndex].nBits, nBits ), (Word16) EQ_16( codes[valueIndex].code, code ) ) )
     787             :             {
     788      658993 :                 BREAK;
     789             :             }
     790             :         }
     791             :     }
     792      658993 :     IF( LT_16( valueIndex, nSize ) )
     793             :     {
     794      658993 :         *pValue = (Word16) codes[valueIndex].value; /*Q0*/
     795      658993 :         move16();
     796             :     }
     797             :     ELSE
     798             :     {
     799           0 :         st->BER_detect = 1;
     800           0 :         move16();
     801           0 :         *pValue = 0;
     802           0 :         move16();
     803           0 :         return -1;
     804             :     }
     805             : 
     806      658993 :     return nBits; /*Q0*/
     807             : }
     808             : 
     809             : 
     810             : /* TNS filter coefficients */
     811             : 
     812      429272 : Word16 DecodeSWBTCX20TnsFilterCoeff_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
     813             : {
     814      429272 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     815      429272 :     return DecodeUsingTable( st, pValue, codesTnsCoeffSWBTCX20[index], nTnsCoeffCodes );
     816             : }
     817             : 
     818      121144 : Word16 DecodeSWBTCX10TnsFilterCoeff_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
     819             : {
     820      121144 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     821      121144 :     return DecodeUsingTable( st, pValue, codesTnsCoeffSWBTCX10[index], nTnsCoeffCodes );
     822             : }
     823             : 
     824        7562 : Word16 DecodeWBTCX20TnsFilterCoeff_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
     825             : {
     826        7562 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     827        7562 :     return DecodeUsingTable( st, pValue, codesTnsCoeffWBTCX20[index], nTnsCoeffCodes );
     828             : }
     829             : 
     830             : 
     831             : /* TNS filter order */
     832             : 
     833       74575 : Word16 DecodeTnsFilterOrderSWBTCX20_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
     834             : {
     835             :     (void) index;
     836       74575 :     return DecodeUsingTable( st, pValue, codesTnsOrderTCX20, nTnsOrderCodes );
     837             : }
     838             : 
     839           0 : Word16 GetTnsFilterOrderBitsSWBTCX10_flt( const Word16 value, const Word16 index )
     840             : {
     841             :     (void) index;
     842           0 :     return GetBitsFromTable( value - 1, codesTnsOrderTCX10, nTnsOrderCodes );
     843             : }
     844             : 
     845           0 : Word16 EncodeTnsFilterOrderSWBTCX10_flt( const Word16 value, const Word16 index )
     846             : {
     847             :     (void) index;
     848           0 :     return EncodeUsingTable( value - 1, codesTnsOrderTCX10, nTnsOrderCodes );
     849             : }
     850             : 
     851       25211 : Word16 DecodeTnsFilterOrderSWBTCX10_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
     852             : {
     853             :     (void) index;
     854       25211 :     return DecodeUsingTable( st, pValue, codesTnsOrderTCX10, nTnsOrderCodes );
     855             : }
     856             : 
     857             : 
     858      616528 : void const *GetTnsFilterCoeff( void const *p, const Word16 index /*Q0*/, Word16 *pValue /*Q0*/ )
     859             : {
     860      616528 :     *pValue = ( (Word16 const *) p )[index] + INDEX_SHIFT;
     861      616528 :     move16();
     862      616528 :     return NULL;
     863             : }
     864             : 
     865      571749 : void *SetTnsFilterCoeff( void *p, const Word16 index /*Q0*/, const Word16 value /*Q0*/ )
     866             : {
     867      571749 :     ( (Word16 *) p )[index] = sub( value, INDEX_SHIFT );
     868      571749 :     move16();
     869      571749 :     return NULL;
     870             : }
     871             : 
     872             : 
     873      937499 : Word16 GetSWBTCX20TnsFilterCoeffBits( const Word16 value, const Word16 index )
     874             : {
     875      937499 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     876             : 
     877      937499 :     return GetBitsFromTable( value, codesTnsCoeffSWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
     878             : }
     879             : 
     880      463074 : Word16 EncodeSWBTCX20TnsFilterCoeff( const Word16 value, const Word16 index )
     881             : {
     882      463074 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     883             : 
     884      463074 :     return EncodeUsingTable( value, codesTnsCoeffSWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
     885             : }
     886             : 
     887           0 : Word16 DecodeSWBTCX20TnsFilterCoeff( Decoder_State *st, const Word16 index, Word16 *pValue )
     888             : {
     889           0 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     890             : 
     891           0 :     return DecodeUsingTable( st, pValue, codesTnsCoeffSWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
     892             : }
     893             : 
     894      264768 : Word16 GetSWBTCX10TnsFilterCoeffBits( const Word16 value, const Word16 index )
     895             : {
     896      264768 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     897             : 
     898      264768 :     return GetBitsFromTable( value, codesTnsCoeffSWBTCX10[index], nTnsCoeffCodes ); /*Q0*/
     899             : }
     900             : 
     901      130839 : Word16 EncodeSWBTCX10TnsFilterCoeff( const Word16 value, const Word16 index )
     902             : {
     903      130839 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     904             : 
     905      130839 :     return EncodeUsingTable( value, codesTnsCoeffSWBTCX10[index], nTnsCoeffCodes ); /*Q0*/
     906             : }
     907             : 
     908           0 : Word16 DecodeSWBTCX10TnsFilterCoeff( Decoder_State *st, const Word16 index, Word16 *pValue )
     909             : {
     910           0 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     911             : 
     912           0 :     return DecodeUsingTable( st, pValue, codesTnsCoeffSWBTCX10[index], nTnsCoeffCodes ); /*Q0*/
     913             : }
     914             : 
     915       16308 : Word16 GetWBTCX20TnsFilterCoeffBits( const Word16 value, const Word16 index )
     916             : {
     917       16308 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     918             : 
     919       16308 :     return GetBitsFromTable( value, codesTnsCoeffWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
     920             : }
     921             : 
     922        8134 : Word16 EncodeWBTCX20TnsFilterCoeff( const Word16 value, const Word16 index )
     923             : {
     924        8134 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     925             : 
     926        8134 :     return EncodeUsingTable( value, codesTnsCoeffWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
     927             : }
     928             : 
     929           0 : Word16 DecodeWBTCX20TnsFilterCoeff( Decoder_State *st, const Word16 index, Word16 *pValue )
     930             : {
     931           0 :     assert( ( index >= 0 ) && ( index < nTnsCoeffTables ) );
     932             : 
     933           0 :     return DecodeUsingTable( st, pValue, codesTnsCoeffWBTCX20[index], nTnsCoeffCodes ); /*Q0*/
     934             : }
     935             : 
     936             : 
     937             : /* TNS filter order */
     938             : 
     939      111881 : void const *GetTnsFilterOrder( void const *p, const Word16 index, Word16 *pValue )
     940             : {
     941      111881 :     move16();
     942      111881 :     *pValue = ( (STnsFilter const *) p )[index].order; /*Q0*/
     943             : 
     944      111881 :     move16();
     945      111881 :     return ( (STnsFilter const *) p )[index].coefIndex; /*Q0*/
     946             : }
     947             : 
     948      103770 : void *SetTnsFilterOrder( void *p, const Word16 index, const Word16 value )
     949             : {
     950      103770 :     move16();
     951      103770 :     ( (STnsFilter *) p )[index].order = value; /*Q0*/
     952             : 
     953      103770 :     move16();
     954      103770 :     return ( (STnsFilter *) p )[index].coefIndex; /*Q0*/
     955             : }
     956             : 
     957      162945 : Word16 GetTnsFilterOrderBitsSWBTCX20( const Word16 value, const Word16 index )
     958             : {
     959             :     (void) index;
     960             : 
     961      162945 :     return GetBitsFromTable( sub( value, 1 ), codesTnsOrderTCX20, nTnsOrderCodes ); /*Q0*/
     962             : }
     963             : 
     964       80425 : Word16 EncodeTnsFilterOrderSWBTCX20( const Word16 value, const Word16 index )
     965             : {
     966             :     (void) index;
     967             : 
     968       80425 :     return EncodeUsingTable( sub( value, 1 ), codesTnsOrderTCX20, nTnsOrderCodes ); /*Q0*/
     969             : }
     970             : 
     971           0 : Word16 DecodeTnsFilterOrderSWBTCX20( Decoder_State *st, const Word16 index, Word16 *pValue )
     972             : {
     973             :     (void) index;
     974             : 
     975           0 :     return DecodeUsingTable( st, pValue, codesTnsOrderTCX20, nTnsOrderCodes ); /*Q0*/
     976             : }
     977             : 
     978       55319 : Word16 GetTnsFilterOrderBitsSWBTCX10( const Word16 value, const Word16 index )
     979             : {
     980             :     (void) index;
     981             : 
     982       55319 :     return GetBitsFromTable( sub( value, 1 ), codesTnsOrderTCX10, nTnsOrderCodes ); /*Q0*/
     983             : }
     984             : 
     985       27272 : Word16 EncodeTnsFilterOrderSWBTCX10( const Word16 value, const Word16 index )
     986             : {
     987             :     (void) index;
     988             : 
     989       27272 :     return EncodeUsingTable( sub( value, 1 ), codesTnsOrderTCX10, nTnsOrderCodes ); /*Q0*/
     990             : }
     991             : 
     992           0 : Word16 DecodeTnsFilterOrderSWBTCX10( Decoder_State *st, const Word16 index, Word16 *pValue )
     993             : {
     994             :     (void) index;
     995             : 
     996           0 :     return DecodeUsingTable( st, pValue, codesTnsOrderTCX10, nTnsOrderCodes ); /*Q0*/
     997             : }
     998             : 
     999        2620 : Word16 GetTnsFilterOrderBits( const Word16 value, const Word16 index )
    1000             : {
    1001             :     (void) index;
    1002             : 
    1003        2620 :     return GetBitsFromTable( sub( value, 1 ), codesTnsOrder, nTnsOrderCodes ); /*Q0*/
    1004             : }
    1005             : 
    1006        1306 : Word16 EncodeTnsFilterOrder( const Word16 value, const Word16 index )
    1007             : {
    1008             :     (void) index;
    1009             : 
    1010        1306 :     return EncodeUsingTable( sub( value, 1 ), codesTnsOrder, nTnsOrderCodes ); /*Q0*/
    1011             : }
    1012             : 
    1013           0 : Word16 DecodeTnsFilterOrder( Decoder_State *st, const Word16 index, Word16 *pValue )
    1014             : {
    1015             :     (void) index;
    1016             : 
    1017           0 :     return DecodeUsingTable( st, pValue, codesTnsOrder, nTnsOrderCodes ); /*Q0*/
    1018             : }
    1019             : 
    1020             : /* Number of TNS filters */
    1021             : 
    1022           0 : void const *GetNumOfTnsFilters( void const *p, const Word16 index, Word16 *pValue )
    1023             : {
    1024           0 :     move16();
    1025           0 :     *pValue = ( (STnsData const *) p )[index].nFilters; /*Q0*/
    1026           0 :     move16();
    1027           0 :     return ( (STnsData const *) p )[index].filter;
    1028             : }
    1029             : 
    1030           0 : void *SetNumOfTnsFilters( void *p, const Word16 index, Word16 value )
    1031             : {
    1032           0 :     move16();
    1033           0 :     ( (STnsData *) p )[index].nFilters = value; /*Q0*/
    1034           0 :     move16();
    1035           0 :     return ( (STnsData *) p )[index].filter;
    1036             : }
    1037             : 
    1038             : /* TNS enabled/disabled flag */
    1039             : 
    1040     1248537 : void const *GetTnsEnabled( void const *p, const Word16 index, Word16 *pValue )
    1041             : {
    1042     1248537 :     move16();
    1043     1248537 :     *pValue = 0;
    1044     1248537 :     if ( ( (STnsData const *) p )[index].nFilters != 0 )
    1045             :     {
    1046       85876 :         move16();
    1047       85876 :         *pValue = 1;
    1048             :     }
    1049     1248537 :     return NULL;
    1050             : }
    1051             : 
    1052      632464 : void *SetTnsEnabled( void *p, const Word16 index, const Word16 value )
    1053             : {
    1054             :     (void) p, (void) index, (void) value;
    1055      632464 :     return NULL;
    1056             : }
    1057             : 
    1058             : /* Number of TNS filters */
    1059             : 
    1060       85876 : void const *GetNumOfTnsFilters_flt( void const *p, const Word16 index, Word16 *pValue )
    1061             : {
    1062       85876 :     *pValue = (Word16) abs( ( (STnsData const *) p )[index].nFilters );
    1063       85876 :     return ( (STnsData const *) p )[index].filter;
    1064             : }
    1065             : 
    1066       79721 : void *SetNumOfTnsFilters_flt( void *p, const Word16 index, const Word16 value )
    1067             : {
    1068       79721 :     ( (STnsData *) p )[index].nFilters = (Word16) abs( value );
    1069       79721 :     return ( (STnsData *) p )[index].filter;
    1070             : }
    1071        1229 : Word16 DecodeTnsFilterOrder_flt( Decoder_State *st, const Word16 index, Word16 *pValue )
    1072             : {
    1073             :     (void) index;
    1074        1229 :     return DecodeUsingTable( st, pValue, codesTnsOrder, nTnsOrderCodes );
    1075             : }
    1076             : /* TNS on whitened spectra  flag */
    1077             : 
    1078       68634 : void const *GetTnsOnWhite( void const *p, const Word16 index, Word16 *pValue )
    1079             : {
    1080       68634 :     *pValue = ( (STnsData const *) p )[index].tnsOnWhitenedSpectra > 0 ? 1 : 0;
    1081       68634 :     return NULL;
    1082             : }
    1083             : 
    1084       63501 : void *SetTnsOnWhite( void *p, const Word16 index, const Word16 value )
    1085             : {
    1086       63501 :     ( (STnsData *) p )[index].tnsOnWhitenedSpectra = value;
    1087       63501 :     return NULL;
    1088             : }
    1089             : 
    1090      155010 : void const *GetTnsEnabledSingleFilter( void const *p, const Word16 index, Word16 *pValue )
    1091             : {
    1092      155010 :     move16();
    1093      155010 :     *pValue = 0;
    1094      155010 :     if ( ( (STnsData const *) p )[index].nFilters > 0 )
    1095             :     {
    1096        1314 :         move16();
    1097        1314 :         *pValue = 1;
    1098             :     }
    1099      155010 :     return ( (STnsData const *) p )[index].filter;
    1100             : }
    1101             : 
    1102       89901 : void *SetTnsEnabledSingleFilter( void *p, const Word16 index, const Word16 value )
    1103             : {
    1104       89901 :     ( (STnsData *) p )[index].nFilters = value; /*Q0*/
    1105       89901 :     move16();
    1106       89901 :     return ( (STnsData *) p )[index].filter;
    1107             : }
    1108             : 
    1109             : /*-------------------------------------------------------------------*
    1110             :  * ResetTnsData()
    1111             :  *
    1112             :  *-------------------------------------------------------------------*/
    1113             : 
    1114     2125912 : void ResetTnsData( STnsData *pTnsData )
    1115             : {
    1116             :     Word16 iFilter;
    1117             : 
    1118             : 
    1119     2125912 :     pTnsData->nFilters = 0;
    1120     2125912 :     move16();
    1121     2125912 :     pTnsData->tnsOnWhitenedSpectra = 0;
    1122     2125912 :     move16();
    1123     6377736 :     FOR( iFilter = 0; iFilter < (Word16) ( sizeof( pTnsData->filter ) / sizeof( pTnsData->filter[0] ) ); iFilter++ )
    1124             :     {
    1125     4251824 :         STnsFilter *const pTnsFilter = &pTnsData->filter[iFilter];
    1126     4251824 :         pTnsFilter->spectrumLength = 0;
    1127     4251824 :         move16();
    1128     4251824 :         pTnsFilter->predictionGain = ONE_IN_Q7; /*Q7*/
    1129     4251824 :         move16();
    1130     4251824 :         pTnsFilter->predictionGain32 = ONE_IN_Q23; /*Q23*/
    1131     4251824 :         move32();
    1132     4251824 :         pTnsFilter->predictionGain_e = PRED_GAIN_E;
    1133     4251824 :         move16();
    1134     4251824 :         pTnsFilter->avgSqrCoef = 0;
    1135     4251824 :         move16();
    1136     4251824 :         pTnsFilter->filterType = TNS_FILTER_OFF; /*Q0*/
    1137     4251824 :         move16();
    1138     4251824 :         ClearTnsFilterCoefficients( pTnsFilter );
    1139             :     }
    1140     2125912 : }
    1141             : /*-------------------------------------------------------------------*
    1142             :  * ClearTnsFilterCoefficients()
    1143             :  *
    1144             :  *-------------------------------------------------------------------*/
    1145             : 
    1146     7982162 : void ClearTnsFilterCoefficients(
    1147             :     STnsFilter *pTnsFilter )
    1148             : {
    1149     7982162 :     move16();
    1150     7982162 :     pTnsFilter->order = 0;
    1151     7982162 :     move16();
    1152             :     assert( TNS_MAX_FILTER_ORDER == 8 );
    1153     7982162 :     move16();
    1154     7982162 :     move16();
    1155     7982162 :     move16();
    1156     7982162 :     move16();
    1157     7982162 :     move16();
    1158     7982162 :     move16();
    1159     7982162 :     move16();
    1160     7982162 :     move16();
    1161     7982162 :     pTnsFilter->coefIndex[0] = 0;
    1162     7982162 :     pTnsFilter->coefIndex[1] = 0;
    1163     7982162 :     pTnsFilter->coefIndex[2] = 0;
    1164     7982162 :     pTnsFilter->coefIndex[3] = 0;
    1165     7982162 :     pTnsFilter->coefIndex[4] = 0;
    1166     7982162 :     pTnsFilter->coefIndex[5] = 0;
    1167     7982162 :     pTnsFilter->coefIndex[6] = 0;
    1168     7982162 :     pTnsFilter->coefIndex[7] = 0;
    1169     7982162 : }
    1170             : 
    1171             : /** Inverse quantization for reflection coefficients.
    1172             :  *
    1173             :  * @param index input quantized values.
    1174             :  * @param parCoeff output reflection coefficients.
    1175             :  * @param order number of coefficients/values.
    1176             :  */
    1177      368143 : static void Index2Parcor( const Word16 index[] /*Q0*/, Word16 parCoeff[] /*Q15*/, Word16 order /*Q0*/ )
    1178             : {
    1179             :     const Word16 *values;
    1180             :     Word16 i;
    1181             : 
    1182      368143 :     move16();
    1183      368143 :     values = tnsCoeff4; /*Q15*/
    1184             : 
    1185     1690607 :     FOR( i = 0; i < order; i++ )
    1186             :     {
    1187     1322464 :         move16();
    1188     1322464 :         parCoeff[i] = values[( index[i] + INDEX_SHIFT )]; /*Q15*/
    1189             :     }
    1190      368143 :     return;
    1191             : }
    1192             : 
    1193             : 
    1194             : /* Linear prediction analysis filter. */
    1195    49964336 : static Word32 FIRLattice(
    1196             :     const Word16 order, /*Q0*/
    1197             :     const Word16 *parCoeff /*Q15*/,
    1198             :     Word32 *state, /*Q0*/
    1199             :     Word32 x       /* Q0 */
    1200             : )
    1201             : {
    1202             :     Word16 i;
    1203             :     Word32 tmpSave, tmp;
    1204             : 
    1205             : 
    1206    49964336 :     tmpSave = x;
    1207    49964336 :     move32();
    1208   278001594 :     FOR( i = 0; i < order - 1; i++ )
    1209             :     {
    1210   228037258 :         tmp = L_add( state[i], Mpy_32_16_1( x, parCoeff[i] ) ); /*Q0*/
    1211   228037258 :         x = L_add( x, Mpy_32_16_1( state[i], parCoeff[i] ) );   /* exponent: 31+0 */
    1212   228037258 :         state[i] = tmpSave;                                     /*Q0*/
    1213   228037258 :         move32();
    1214   228037258 :         tmpSave = tmp; /*Q0*/
    1215   228037258 :         move32();
    1216             :     }
    1217             : 
    1218             :     /* last stage: only need half operations */
    1219    49964336 :     x = L_add( x, Mpy_32_16_1( state[order - 1], parCoeff[order - 1] ) ); /*Q0*/
    1220    49964336 :     state[order - 1] = tmpSave;                                           /*Q0*/
    1221    49964336 :     move32();
    1222             : 
    1223    49964336 :     return x; /*Q0*/
    1224             : }
    1225             : 
    1226    57151630 : static Word32 IIRLattice( Word16 order /*Q0*/, const Word16 *parCoeff /*Q15*/, Word32 *state /*Q0*/, Word32 x /*Q0*/ )
    1227             : {
    1228             :     Word16 i;
    1229             : 
    1230             : 
    1231             :     /* first stage: no need to calculate state[order-1] */
    1232    57151630 :     x = Msub_32_16( x, state[order - 1], parCoeff[order - 1] ); /*Q0*/
    1233             : 
    1234   312856218 :     FOR( i = order - 2; i >= 0; i-- )
    1235             :     {
    1236   255704588 :         x = Msub_32_16( x, state[i], parCoeff[i] );            /*Q0*/
    1237   255704588 :         state[i + 1] = Madd_32_16( state[i], x, parCoeff[i] ); /*Q0*/
    1238   255704588 :         move32();
    1239             :     }
    1240             : 
    1241    57151630 :     move32();
    1242    57151630 :     state[0] = x; /*Q0*/
    1243    57151630 :     return x;     /*Q0*/
    1244             : }
    1245             : /** TNS analysis/synthesis filter.
    1246             :   * @param spectrum input spectrum values.
    1247             :   * @param numOfLines number of lines in the spectrum.
    1248             :   * @param parCoeff filter (PARCOR) coefficients.
    1249             :   * @param order filter order.
    1250             :   * @param filter function that implements filtering.
    1251             :     By this function it is defined whether analysis or synthesis is performed.
    1252             :   * @param output filtered output spectrum values.
    1253             :     Inplace operation is supported, so it can be equal to spectrum.
    1254             :   */
    1255      368143 : static void TnsFilter(
    1256             :     const Word32 spectrum[], /*Qx*/
    1257             :     const Word16 numOfLines, /*Q0*/
    1258             :     const Word16 parCoeff[], /*Q15*/
    1259             :     const Word16 order,      /*Q0*/
    1260             :     TLinearPredictionFilter filter,
    1261             :     Word32 *state, /*Q0*/
    1262             :     Word32 output[] /*Qx*/ )
    1263             : {
    1264             :     Word16 j;
    1265             : 
    1266             : 
    1267      368143 :     assert( ( order >= 0 ) && ( order <= TNS_MAX_FILTER_ORDER ) );
    1268      368143 :     assert( ( numOfLines > 0 ) || ( ( numOfLines == 0 ) && ( order == 0 ) ) );
    1269             : 
    1270      368143 :     IF( order == 0 )
    1271             :     {
    1272             : 
    1273      127473 :         test();
    1274      127473 :         IF( s_and( ( spectrum != output ), numOfLines > 0 ) )
    1275             :         {
    1276           0 :             Copy32( spectrum, output, numOfLines ); /*Qx*/
    1277             :         }
    1278             :     }
    1279             :     ELSE
    1280             :     {
    1281             :         {
    1282             : 
    1283   107356636 :             FOR( j = 0; j < numOfLines; j++ )
    1284             :             {
    1285   107115966 :                 move32();
    1286   107115966 :                 output[j] = filter( order, parCoeff, state, spectrum[j] ); /*Qx*/
    1287             :             }
    1288             :         }
    1289             :     }
    1290      368143 :     return;
    1291             : }
    1292             : 
    1293      465347 : static void ITF_TnsFilter_fx(
    1294             :     const Word32 spectrum[], /*Qx*/
    1295             :     const Word16 numOfLines, /*Q0*/
    1296             :     const Word16 A[],        /* ifdef FIX_ITF_OVERFLOW Q_A else Q14 */
    1297             :     const Word16 Q_A,
    1298             :     const Word16 order, /*Q0*/
    1299             :     Word32 output[] /*Qx*/ )
    1300             : {
    1301             :     Word16 i, j;
    1302             :     Word32 buf[ITF_MAX_FILTER_ORDER + N_MAX];
    1303             :     Word32 *p;
    1304             :     Word16 shift;
    1305      465347 :     assert( ( order >= 0 ) && ( order <= ITF_MAX_FILTER_ORDER ) );
    1306      465347 :     assert( ( numOfLines > 0 ) || ( ( numOfLines == 0 ) && ( order == 0 ) ) );
    1307             : 
    1308      465347 :     IF( order == 0 )
    1309             :     {
    1310             : 
    1311      403055 :         test();
    1312      403055 :         IF( s_and( ( spectrum != output ), numOfLines > 0 ) )
    1313             :         {
    1314           0 :             Copy32( spectrum, output, numOfLines ); /*Qx*/
    1315             :         }
    1316             :     }
    1317             :     ELSE
    1318             :     {
    1319       62292 :         shift = sub( 15, Q_A );
    1320             : 
    1321       62292 :         p = buf + ITF_MAX_FILTER_ORDER;
    1322       62292 :         set32_fx( buf, 0, ITF_MAX_FILTER_ORDER );
    1323       62292 :         Copy32( spectrum, p, numOfLines ); /*Qx*/
    1324    20664452 :         FOR( j = 0; j < numOfLines; j++ )
    1325             :         {
    1326             :             Word32 L_tmp;
    1327             : 
    1328    20602160 :             L_tmp = L_add( p[0], 0 );
    1329   164817280 :             FOR( i = 1; i < order; i++ )
    1330             :             {
    1331   144215120 :                 L_tmp = L_add_sat( L_tmp, L_shl( Mpy_32_16_1( p[-i], A[i] ), shift ) ); /*Qx*/
    1332             :             }
    1333    20602160 :             output[j] = L_tmp; /*Qx*/
    1334    20602160 :             move32();
    1335    20602160 :             ++p;
    1336             :         }
    1337             :     }
    1338      465347 :     return;
    1339             : }
    1340             : 
    1341      162626 : static void ITF_GetFilterParameters_fx(
    1342             :     Word32 rxx[],          /*Qx*/
    1343             :     const Word16 maxOrder, /*Q0*/
    1344             :     Word16 *A,             /* ifdef FIX_ITF_OVERFLOW Q_A else Q14 */
    1345             :     Word16 *Q_A,
    1346             :     Word16 *predictionGain /*Q7*/ )
    1347             : {
    1348             :     Word16 i, j, i_2, tmp;
    1349             :     Word16 parCoeff[ITF_MAX_FILTER_ORDER];
    1350             :     Word32 epsP[ITF_MAX_FILTER_ORDER + 1], L_tmp;
    1351             : 
    1352             :     /* compute filter in ParCor form with LeRoux-Gueguen algorithm */
    1353      162626 :     L_tmp = E_LPC_schur( rxx, parCoeff, epsP, maxOrder );
    1354             :     BASOP_SATURATE_WARNING_OFF_EVS                                            /* Allow saturation, this value is compared against a threshold. */
    1355      162626 :         *predictionGain = divide3232( L_shr( epsP[0], PRED_GAIN_E ), L_tmp ); /*Q7*/
    1356      162626 :     move16();
    1357             :     BASOP_SATURATE_WARNING_ON_EVS
    1358             : 
    1359             :     {
    1360             :         Word32 A32[ITF_MAX_FILTER_ORDER];
    1361             :         Word16 tmp1_l, tmp1_h, tmp2_l, tmp2_h;
    1362             : 
    1363             :         /* Convert ParCor / reflection coefficients to LPC */
    1364      162626 :         A32[0] = 134217728l /*1.0 Q27*/;
    1365      162626 :         move32();                                        /* Q11+16 */
    1366      162626 :         A32[1] = L_shr( L_deposit_h( parCoeff[0] ), 4 ); /* Q11+16 */
    1367      162626 :         move32();
    1368             : 
    1369     1301008 :         FOR( i = 1; i < maxOrder; i++ )
    1370             :         {
    1371     1138382 :             L_tmp = L_shr( L_deposit_h( parCoeff[i] ), 3 ); /* Q11+16 */
    1372             : 
    1373     1138382 :             i_2 = shr( i, 1 );
    1374     3089894 :             FOR( j = 0; j < i_2; j++ )
    1375             :             {
    1376     1951512 :                 tmp1_l = L_Extract_lc( A32[i - 1 - j + 1], &tmp1_h );
    1377     1951512 :                 tmp2_l = L_Extract_lc( A32[j + 1], &tmp2_h );
    1378     1951512 :                 A32[j + 1] = Mac_32( A32[j + 1], parCoeff[i], 0, tmp1_h, tmp1_l ); /*+= parCoeff[i] * a[i-1-j+1]; Q11+16*/
    1379     1951512 :                 move32();
    1380     1951512 :                 A32[i - 1 - j + 1] = Mac_32( A32[i - 1 - j + 1], parCoeff[i], 0, tmp2_h, tmp2_l ); /*+= parCoeff[i] * tmp; Q11+16*/
    1381     1951512 :                 move32();
    1382             :             }
    1383     1138382 :             IF( s_and( i, 1 ) )
    1384             :             {
    1385      650504 :                 tmp2_l = L_Extract_lc( A32[j + 1], &tmp2_h );
    1386      650504 :                 A32[j + 1] = Mac_32( A32[j + 1], parCoeff[i], 0, tmp2_h, tmp2_l ); /*+= parCoeff[i] * a[j+1]; Q11+16*/
    1387      650504 :                 move32();
    1388             :             }
    1389             : 
    1390     1138382 :             A32[i + 1] = L_shr( L_deposit_h( parCoeff[i] ), 4 ); /* Q11+16 */
    1391     1138382 :             move32();
    1392             :         }
    1393             : 
    1394      162626 :         tmp = 3;
    1395      162626 :         move16(); /* assume Q11 -> Q14 */
    1396     1463634 :         FOR( i = 0; i < maxOrder; i++ )
    1397             :         {
    1398     1301008 :             tmp = s_min( tmp, norm_l( A32[i] ) );
    1399             :         }
    1400     1463634 :         FOR( i = 0; i < maxOrder; i++ )
    1401             :         {
    1402     1301008 :             A[i] = round_fx( L_shl( A32[i], tmp ) ); /* Q11+tmp */
    1403     1301008 :             move16();
    1404             :         }
    1405      162626 :         *Q_A = add( 11, tmp );
    1406      162626 :         move16();
    1407             :     }
    1408      162626 :     return;
    1409             : }

Generated by: LCOV version 1.14