LCOV - code coverage report
Current view: top level - lib_enc - igf_enc_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ a00cb1a4e00ddb5714e6edf7a8c2107a29ea8765 Lines: 709 796 89.1 %
Date: 2025-07-09 01:57:24 Functions: 23 24 95.8 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : 
       5             : #include <stdio.h>
       6             : #include <stdlib.h>
       7             : #include <assert.h>
       8             : #include "options.h"
       9             : #include "cnst.h"
      10             : #include "stl.h"
      11             : #include "prot_fx.h"
      12             : #include "prot_fx_enc.h" /* Function prototypes                    */
      13             : #include "stat_enc.h"
      14             : #include "basop_util.h"
      15             : 
      16             : /**********************************************************************/ /*
      17             : write single bit to stream
      18             : **************************************************************************/
      19        7106 : static void IGF_write_bit_fx(
      20             :     BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle       */
      21             :     Word16 *bitCount,      /**< in/out: | bit counter              */
      22             :     Word16 bit             /**< in:     | value of bit             */
      23             : )
      24             : {
      25        7106 :     IGFCommonFuncsWriteSerialBit( hBstr, bitCount, bit );
      26        7106 : }
      27             : 
      28             : /**********************************************************************/ /*
      29             : write bits to stream
      30             : **************************************************************************/
      31        5832 : static void IGF_write_bits(
      32             :     BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle       */
      33             :     Word16 *bitCount,      /**< in/out: | bit counter              */
      34             :     Word16 value,          /**< in:     | value to be written      */
      35             :     Word16 bits            /**< in: Q0  | number of bits           */
      36             : )
      37             : {
      38             :     Word16 tmp;
      39             : 
      40       11664 :     WHILE( bits )
      41             :     {
      42        5832 :         bits = sub( bits, 1 );
      43        5832 :         tmp = s_and( value, shl( 1, bits ) );
      44        5832 :         IF( tmp == 0 )
      45             :         {
      46        2048 :             IGF_write_bit_fx( hBstr, bitCount, 0 );
      47             :         }
      48             :         ELSE
      49             :         {
      50        3784 :             IGF_write_bit_fx( hBstr, bitCount, 1 );
      51             :         }
      52             :     }
      53             : 
      54        5832 :     return;
      55             : }
      56             : 
      57             : 
      58             : /**********************************************************************/    /*
      59             :    envelope estimation
      60             :    **************************************************************************/
      61         637 : static void IGF_CalculateEnvelope( const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in:     | instance handle of IGF Encoder                     */
      62             :                                    Word32 *pMDCTSpectrum,                   /**< in: Q31 | MDCT spectrum                                      */
      63             :                                    Word16 MDCTSpectrum_e,                   /**< in:     | exponent of MDCT spectrum                          */
      64             :                                    Word32 *pPowerSpectrum,                  /**< in: Q31 | MDCT^2 + MDST^2 spectrum, or estimate              */
      65             :                                    Word16 PowerSpectrum_e,                  /**< in:     | exponent of MDCT^2 + MDST^2 spectrum, or estimate  */
      66             :                                    const Word16 igfGridIdx                  /**< in: Q0  | IGF grid index                                     */
      67             : 
      68             : )
      69             : {
      70             :     IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData;
      71             :     H_IGF_GRID hGrid;
      72             :     Word16 *swb_offset;
      73             :     Word16 sfb;   /* this is the actual scalefactor band */
      74             :     Word16 width; /* this is width in subbands of the actual scalefactor band */
      75             :     Word16 tile_idx;
      76             :     Word16 strt_cpy;
      77             :     Word16 gain; /* the gain which has to be applied to the source tile to get the destination energy */
      78             :     Word16 gain_exp;
      79             :     Word16 tb;
      80             :     Word16 zeroNrg; /* Q0 | flag indicating if the signal contains almost no energy */
      81             :     Word32 sfbEnergyR[IGF_MAX_SFB];
      82             :     Word16 sfbEnergyR_exp[IGF_MAX_SFB];
      83             :     Word32 sfbEnergyC[IGF_MAX_SFB]; /* the energy of the destination region of the tile */
      84             :     Word16 sfbEnergyC_exp[IGF_MAX_SFB];
      85             :     Word32 sfbEnergyTileR[IGF_MAX_SFB];
      86             :     Word16 sfbEnergyTileR_exp[IGF_MAX_SFB];
      87             :     Word32 sfbEnergyTileC[IGF_MAX_SFB]; /* the energy of the destination region of the tile */
      88             :     Word16 sfbEnergyTileC_exp[IGF_MAX_SFB];
      89             :     Word32 LFMDCTSpectrum[N_MAX];
      90             :     Word16 LFMDCTSpectrum_exp;
      91             :     Word32 LFPowerSpectrum[N_MAX];
      92             :     Word16 tmp;
      93             :     Word16 tmp_exp;
      94             :     Word32 L_tmp;
      95             :     Word16 shift;
      96             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
      97         637 :     Flag Overflow = 0;
      98         637 :     move32();
      99             : #endif
     100             : 
     101             :     /* initialize variables */
     102         637 :     Copy32( pMDCTSpectrum + IGF_START_MN, hInstance->spec_be_igf, hInstance->infoStopLine - IGF_START_MN );
     103         637 :     hPrivateData = &hInstance->igfData;
     104         637 :     hGrid = &hPrivateData->igfInfo.grid[igfGridIdx];
     105         637 :     swb_offset = hGrid->swb_offset;
     106         637 :     move16();
     107         637 :     hInstance->spec_be_igf_e = MDCTSpectrum_e;
     108         637 :     move16();
     109         637 :     zeroNrg = 0;
     110         637 :     move16();
     111             : 
     112             : 
     113         637 :     IF( pPowerSpectrum != NULL )
     114             :     {
     115        2271 :         FOR( tile_idx = 0; tile_idx < hGrid->nTiles; tile_idx++ )
     116             :         {
     117        1638 :             strt_cpy = hGrid->sbWrap[tile_idx];
     118        1638 :             move16();
     119        6180 :             FOR( sfb = hGrid->sfbWrap[tile_idx]; sfb < hGrid->sfbWrap[tile_idx + 1]; sfb++ )
     120             :             {
     121      231366 :                 FOR( tb = swb_offset[sfb]; tb < swb_offset[sfb + 1]; tb++ )
     122             :                 {
     123      226824 :                     LFMDCTSpectrum[tb] = pMDCTSpectrum[strt_cpy];
     124      226824 :                     move32();
     125      226824 :                     LFPowerSpectrum[tb] = pPowerSpectrum[strt_cpy];
     126      226824 :                     move32();
     127      226824 :                     strt_cpy = add( strt_cpy, 1 );
     128             :                 }
     129             :             }
     130             :         }
     131         633 :         IGFCommonFuncsCalcSfbEnergyPowerSpec( hGrid->startSfb,
     132         633 :                                               hGrid->stopSfb,
     133         633 :                                               hGrid->swb_offset,
     134             :                                               pPowerSpectrum,
     135             :                                               &PowerSpectrum_e,
     136             :                                               sfbEnergyC,
     137             :                                               sfbEnergyC_exp );
     138         633 :         IGFCommonFuncsCalcSfbEnergyPowerSpec( hGrid->startSfb,
     139         633 :                                               hGrid->stopSfb,
     140         633 :                                               hGrid->swb_offset,
     141             :                                               LFPowerSpectrum,
     142             :                                               &PowerSpectrum_e,
     143             :                                               sfbEnergyTileC,
     144             :                                               sfbEnergyTileC_exp );
     145         633 :         IGFCommonFuncsMDCTSquareSpec( hGrid->startLine,
     146         633 :                                       hGrid->stopLine,
     147             :                                       LFMDCTSpectrum,
     148             :                                       MDCTSpectrum_e,
     149             :                                       LFMDCTSpectrum,
     150             :                                       &LFMDCTSpectrum_exp,
     151             :                                       0 );
     152         633 :         IGFCommonFuncsCalcSfbEnergyPowerSpec( hGrid->startSfb,
     153         633 :                                               hGrid->stopSfb,
     154         633 :                                               hGrid->swb_offset,
     155             :                                               LFMDCTSpectrum,
     156             :                                               &LFMDCTSpectrum_exp,
     157             :                                               sfbEnergyTileR,
     158             :                                               sfbEnergyTileR_exp );
     159             :     }
     160             :     ELSE
     161             :     {
     162           4 :         IGFCommonFuncsMDCTSquareSpec( hGrid->startLine,
     163           4 :                                       hGrid->stopLine,
     164             :                                       pMDCTSpectrum,
     165             :                                       MDCTSpectrum_e,
     166             :                                       LFMDCTSpectrum,
     167             :                                       &LFMDCTSpectrum_exp,
     168             :                                       0 );
     169           4 :         IGFCommonFuncsCalcSfbEnergyPowerSpec( hGrid->startSfb,
     170           4 :                                               hGrid->stopSfb,
     171           4 :                                               hGrid->swb_offset,
     172             :                                               LFMDCTSpectrum,
     173             :                                               &LFMDCTSpectrum_exp,
     174             :                                               sfbEnergyR,
     175             :                                               sfbEnergyR_exp );
     176             :     }
     177             : 
     178        2287 :     FOR( tile_idx = 0; tile_idx < hGrid->nTiles; tile_idx++ )
     179             :     {
     180             : 
     181        6224 :         FOR( sfb = hGrid->sfbWrap[tile_idx]; sfb < hGrid->sfbWrap[tile_idx + 1]; sfb++ )
     182             :         {
     183             : 
     184             : 
     185        4574 :             width = sub( swb_offset[sfb + 1], swb_offset[sfb] );
     186        4574 :             L_tmp = 0;
     187        4574 :             move16();
     188        4574 :             gain_exp = 0;
     189        4574 :             move16();
     190             : 
     191        4574 :             IF( pPowerSpectrum )
     192             :             {
     193        4542 :                 IF( sfbEnergyTileR[sfb] == 0 )
     194             :                 {
     195           0 :                     sfbEnergyTileR[sfb] = 0x00010000;
     196           0 :                     move32();
     197           0 :                     sfbEnergyTileR_exp[sfb] = 0;
     198           0 :                     move16();
     199           0 :                     zeroNrg = 1;
     200           0 :                     move16();
     201             :                 }
     202        4542 :                 IF( sfbEnergyTileC[sfb] == 0 )
     203             :                 {
     204           0 :                     sfbEnergyTileC[sfb] = 0x00010000;
     205           0 :                     move32();
     206           0 :                     sfbEnergyTileC_exp[sfb] = 0;
     207           0 :                     move16();
     208           0 :                     zeroNrg = 1;
     209           0 :                     move16();
     210             :                 }
     211        4542 :                 IF( sfbEnergyC[sfb] == 0 )
     212             :                 {
     213           0 :                     sfbEnergyC[sfb] = 0x00010000;
     214           0 :                     move32();
     215           0 :                     sfbEnergyC_exp[sfb] = 0;
     216           0 :                     move16();
     217           0 :                     zeroNrg = 1;
     218           0 :                     move16();
     219             :                 }
     220             : 
     221        4542 :                 BASOP_Util_Divide_MantExp( round_fx_o( sfbEnergyTileR[sfb], &Overflow ), sfbEnergyTileR_exp[sfb], width, 15, &gain, &gain_exp );
     222        4542 :                 BASOP_Util_Divide_MantExp( round_fx_o( sfbEnergyC[sfb], &Overflow ), sfbEnergyC_exp[sfb], round_fx_o( sfbEnergyTileC[sfb], &Overflow ), sfbEnergyTileC_exp[sfb], &tmp, &tmp_exp );
     223        4542 :                 L_tmp = L_mult( gain, tmp );
     224        4542 :                 gain_exp = add( gain_exp, tmp_exp );
     225             :             }
     226             :             ELSE
     227             :             {
     228          32 :                 IF( sfbEnergyR[sfb] == 0 )
     229             :                 {
     230           0 :                     sfbEnergyR[sfb] = 0x00010000;
     231           0 :                     move32();
     232           0 :                     sfbEnergyR_exp[sfb] = 0;
     233           0 :                     move16();
     234           0 :                     zeroNrg = 1;
     235           0 :                     move16();
     236             :                 }
     237          32 :                 BASOP_Util_Divide_MantExp( round_fx_sat( sfbEnergyR[sfb] ),
     238          32 :                                            sfbEnergyR_exp[sfb],
     239             :                                            width,
     240             :                                            15,
     241             :                                            &gain,
     242             :                                            &gain_exp );
     243          32 :                 L_tmp = L_deposit_h( gain );
     244             :             }
     245             : 
     246             :             /* gain = 0.5f + (float)((2.885390081777927f * log(gain) + 16.f)); */
     247        4574 :             L_tmp = BASOP_Util_Log2( L_tmp );
     248        4574 :             L_tmp = L_add( L_tmp, L_deposit_h( shl( gain_exp, 15 - 6 ) ) );
     249        4574 :             shift = norm_l( L_tmp );
     250        4574 :             gain = round_fx_o( L_shl_o( L_tmp, shift, &Overflow ), &Overflow );
     251        4574 :             gain_exp = sub( 7, shift );
     252        4574 :             gain_exp = BASOP_Util_Add_MantExp( gain, gain_exp, 32767 /*16 Q11*/, 4, &gain );
     253        4574 :             gain_exp = BASOP_Util_Add_MantExp( gain, gain_exp, 0x4000, 0, &gain );
     254        4574 :             gain = shr( gain, s_min( sub( 15, gain_exp ), 15 ) );
     255             : 
     256        4574 :             if ( gain > 91 )
     257             :             {
     258           0 :                 gain = s_min( gain, 91 ); /* 13+15+63, see arithocde encode residual */
     259             :             }
     260        4574 :             if ( gain < 0 )
     261             :             {
     262           0 :                 gain = s_max( gain, 0 );
     263             :             }
     264             : 
     265             :             /* set gain to zero if the signal contains too less energy */
     266        4574 :             if ( zeroNrg != 0 )
     267             :             {
     268           0 :                 gain = 0;
     269           0 :                 move16();
     270             :             }
     271             : 
     272        4574 :             hPrivateData->igfScfQuantized[sfb] = gain;
     273        4574 :             move16();
     274             :         }
     275             :     }
     276             : 
     277         637 :     return;
     278             : }
     279             : 
     280             : /**********************************************************************/ /*
     281             : writes IGF SCF values
     282             : **************************************************************************/
     283        1274 : static void IGF_WriteEnvelope(                                           /**< out: Q0 | number of bits writen                                                        */
     284             :                                const IGF_ENC_INSTANCE_HANDLE hInstance,  /**< in:     | instance handle of IGF Encoder                                               */
     285             :                                BSTR_ENC_HANDLE hBstr,                    /* i/o: encoder bitstream handle       */
     286             :                                Word16 *pBitOffset,                       /**< in:     | ptr to bitOffset counter                                                     */
     287             :                                const Word16 igfGridIdx,                  /**< in: Q0  | igf grid index see declaration of IGF_GRID_IDX for details                   */
     288             :                                const Word16 isIndepFlag,                 /**< in: Q0  | if 1 frame is independent, 0 = frame is coded with data from previous frame  */
     289             :                                Word16 *igfAllZero                        /**< in: Q0  | returns 1 if all IGF scfs are zero, else 0                                   */
     290             : )
     291             : {
     292             :     IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData;
     293             :     H_IGF_GRID hGrid;
     294             :     Word16 sfb;
     295             : 
     296        1274 :     *igfAllZero = 1;
     297        1274 :     move16();
     298        1274 :     hPrivateData = &hInstance->igfData;
     299        1274 :     hGrid = &hPrivateData->igfInfo.grid[igfGridIdx];
     300             : 
     301        1274 :     FOR( sfb = hGrid->startSfb; sfb < hGrid->stopSfb; sfb++ )
     302             :     {
     303        1274 :         IF( hPrivateData->igfScfQuantized[sfb] != 0 )
     304             :         {
     305        1274 :             *igfAllZero = 0;
     306        1274 :             move16();
     307        1274 :             BREAK;
     308             :         }
     309             :     }
     310             : 
     311        1274 :     IF( *igfAllZero != 0 )
     312             :     {
     313           0 :         IGF_write_bit_fx( hBstr, pBitOffset, 1 );
     314           0 :         if ( NULL == hBstr )
     315             :         {
     316           0 :             IGFSCFEncoderSaveContextState_fx( &hPrivateData->hIGFSCFArithEnc, igfGridIdx );
     317             :         }
     318           0 :         IGFSCFEncoderReset_fx( &hPrivateData->hIGFSCFArithEnc );
     319           0 :         if ( NULL == hBstr )
     320             :         {
     321           0 :             IGFSCFEncoderRestoreContextState_fx( &hPrivateData->hIGFSCFArithEnc, igfGridIdx );
     322             :         }
     323             :     }
     324             :     ELSE
     325             :     {
     326        1274 :         IGF_write_bit_fx( hBstr, pBitOffset, 0 );
     327        1274 :         if ( NULL == hBstr )
     328             :         {
     329         637 :             IGFSCFEncoderSaveContextState_fx( &hPrivateData->hIGFSCFArithEnc, igfGridIdx );
     330             :         }
     331             : 
     332        1274 :         *pBitOffset = IGFSCFEncoderEncode_fx( &hPrivateData->hIGFSCFArithEnc, hBstr, *pBitOffset, &hPrivateData->igfScfQuantized[hGrid->startSfb], igfGridIdx, isIndepFlag );
     333        1274 :         move16();
     334             : 
     335        1274 :         if ( NULL == hBstr )
     336             :         {
     337         637 :             IGFSCFEncoderRestoreContextState_fx( &hPrivateData->hIGFSCFArithEnc, igfGridIdx );
     338             :         }
     339             :     }
     340        1274 : }
     341             : 
     342             : /**********************************************************************/ /*
     343             : identifies significant spectral content
     344             : **************************************************************************/
     345         637 : void IGF_ErodeSpectrum( Word16 *highPassEner_exp,                        /**< out:    | exponent of highPassEner       */
     346             :                         const IGF_ENC_INSTANCE_HANDLE hInstance,         /**< in:     | instance handle of IGF Encoder */
     347             :                         Word32 *pSpectrum,                               /**< in/out: | MDCT spectrum                  */
     348             :                         Word32 *pPowerSpectrum,                          /**< in/out: | power spectrum                 */
     349             :                         Word16 pPowerSpectrum_exp,                       /**< in:     | exponent of power spectrum     */
     350             :                         const Word16 igfGridIdx                          /**< in: Q0  | IGF grid index                 */
     351             : )
     352             : {
     353             :     IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData;
     354             :     H_IGF_GRID hGrid;
     355             :     Word16 i;
     356             :     Word16 igfBgn;
     357             :     Word16 igfEnd;
     358             :     Word32 highPassEner; /* Q31 */
     359             :     Word32 lastLine;
     360             :     Word32 nextLine;
     361             :     Word32 L_c;
     362             :     Word32 highPassEner_Ovfl;
     363             :     Word16 s;
     364             :     Word16 tmploop;
     365             :     Word16 *swb_offset;
     366             :     Word16 sfb;
     367             :     Word16 startSfb;
     368             :     Word16 stopSfb;
     369             :     Word16 line;
     370             :     Word16 flag;
     371             :     Word16 *igfScaleF;
     372             :     Word16 tmp;
     373             :     Word32 L_tmp;
     374             : 
     375             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     376         637 :     Flag Overflow = 0;
     377         637 :     Flag Carry = 0;
     378         637 :     move32();
     379         637 :     move32();
     380             : #endif
     381             : 
     382         637 :     hPrivateData = &hInstance->igfData;
     383         637 :     hGrid = &hPrivateData->igfInfo.grid[igfGridIdx];
     384         637 :     igfBgn = hGrid->startLine;
     385         637 :     move16();
     386         637 :     igfEnd = hGrid->stopLine;
     387         637 :     move16();
     388         637 :     swb_offset = hGrid->swb_offset;
     389         637 :     move16();
     390         637 :     startSfb = hGrid->startSfb;
     391         637 :     move16();
     392         637 :     stopSfb = hGrid->stopSfb;
     393         637 :     move16();
     394         637 :     igfScaleF = hPrivateData->igfScfQuantized;
     395         637 :     move16();
     396         637 :     *highPassEner_exp = 0;
     397         637 :     move16();
     398         637 :     highPassEner = 0;
     399         637 :     move32();
     400             : 
     401         637 :     IF( NULL == pPowerSpectrum )
     402             :     {
     403           0 :         FOR( i = igfBgn; i < hGrid->infoGranuleLen; i++ )
     404             :         {
     405           0 :             pSpectrum[i] = L_deposit_l( 0 );
     406             :         }
     407           0 :         return;
     408             :     }
     409             : 
     410         637 :     IF( igfBgn > 0 )
     411             :     {
     412         637 :         L_c = 0;
     413         637 :         move32();
     414      165885 :         FOR( i = 0; i < igfBgn; i++ )
     415             :         {
     416      165248 :             Carry = 0;
     417      165248 :             move32();
     418      165248 :             highPassEner = L_add_co( highPassEner, Mpy_32_16_1( pPowerSpectrum[i], shl( i, 4 ) /*Q4*/ ) /*Q20, pPowerSpectrum_exp*/, &Carry, &Overflow );
     419      165248 :             Overflow = 0;
     420      165248 :             move32();
     421      165248 :             L_c = L_macNs_co( L_c, 0, 0, &Carry, &Overflow );
     422             :         }
     423             : 
     424         637 :         highPassEner = norm_llQ31( L_c, highPassEner, highPassEner_exp ); /*Q20, highPassEner_exp*/
     425         637 :         *highPassEner_exp = add( *highPassEner_exp, pPowerSpectrum_exp );
     426         637 :         move16();
     427         637 :         test();
     428         637 :         test();
     429        1274 :         if ( NE_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_9600 ) &&
     430        1274 :              NE_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_RF_SWB_13200 ) &&
     431         637 :              NE_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_13200 ) )
     432             :         {
     433         376 :             igfBgn = shl( igfBgn, 1 );
     434             :         }
     435         637 :         highPassEner = L_deposit_l( BASOP_Util_Divide3216_Scale( highPassEner /*Q20, highPassEner_exp*/, igfBgn /*Q0*/, &s ) ); /*Q15, highPassEner_exp+11-16+s*/
     436         637 :         *highPassEner_exp = add( add( *highPassEner_exp, s ), 12 - 16 + ( 31 - 15 ) );                                          /*Q15->Q31,highPassEner_exp*/
     437         637 :         lastLine = pSpectrum[i - 1];
     438         637 :         move32();
     439         637 :         nextLine = 0;
     440         637 :         move32();
     441             : 
     442             :         /* May overflow - just for threshold comparison                                                   */
     443             :         /* negate because the negated may be 1 larger in abs,                                             */
     444             :         /* so whenever compared to the negation of a maximum possible pPowerspectrum, it is still larger  */
     445         637 :         highPassEner_Ovfl = L_shl_o( L_negate( highPassEner ), sub( *highPassEner_exp, pPowerSpectrum_exp ), &Overflow );
     446         637 :         L_tmp = L_add_o( pPowerSpectrum[i - 1], highPassEner_Ovfl, &Overflow );
     447             : 
     448         637 :         if ( L_tmp >= 0 )
     449             :         {
     450           0 :             nextLine = pSpectrum[i];
     451           0 :             move32();
     452             :         }
     453         637 :         tmploop = sub( igfEnd, 1 );
     454      228360 :         FOR( /*i*/; i < tmploop; i++ )
     455             :         {
     456             :             /* May overflow - just for threshold comparison */
     457             :             BASOP_SATURATE_WARNING_OFF_EVS
     458      227723 :             L_tmp = L_add_sat( pPowerSpectrum[i], highPassEner_Ovfl );
     459             :             BASOP_SATURATE_WARNING_ON_EVS;
     460             : 
     461      227723 :             IF( L_tmp < 0 )
     462             :             {
     463      227692 :                 lastLine = pSpectrum[i];
     464      227692 :                 move32();
     465      227692 :                 pSpectrum[i] = nextLine;
     466      227692 :                 move32();
     467      227692 :                 nextLine = 0;
     468      227692 :                 move32();
     469             :             }
     470             :             ELSE
     471             :             {
     472          31 :                 pSpectrum[i - 1] = lastLine;
     473          31 :                 move32();
     474          31 :                 lastLine = pSpectrum[i];
     475          31 :                 move32();
     476          31 :                 nextLine = pSpectrum[i + 1];
     477          31 :                 move32();
     478             :             }
     479             :         }
     480             : 
     481             :         /* May overflow - just for threshold comparison */
     482             :         BASOP_SATURATE_WARNING_OFF_EVS
     483         637 :         L_tmp = L_add_sat( pPowerSpectrum[i], highPassEner_Ovfl );
     484             :         BASOP_SATURATE_WARNING_ON_EVS
     485         637 :         if ( L_tmp < 0 )
     486             :         {
     487         637 :             pSpectrum[i] = L_deposit_l( 0 );
     488         637 :             move32();
     489             :         }
     490             :     }
     491             : 
     492             :     /* delete spectrum above igfEnd: */
     493       20149 :     FOR( i = igfEnd; i < hGrid->infoGranuleLen; i++ )
     494             :     {
     495       19512 :         pSpectrum[i] = L_deposit_l( 0 );
     496       19512 :         move32();
     497       19512 :         pPowerSpectrum[i] = L_deposit_l( 0 );
     498       19512 :         move32();
     499             :     }
     500             : 
     501        5211 :     FOR( sfb = startSfb; sfb < stopSfb; sfb++ )
     502             :     {
     503        4574 :         flag = 0;
     504        4574 :         move16();
     505      232934 :         FOR( line = swb_offset[sfb]; line < swb_offset[sfb + 1]; line++ )
     506             :         {
     507      228360 :             if ( pSpectrum[line] != 0 )
     508             :             {
     509          61 :                 flag = 1;
     510          61 :                 move16();
     511             :             }
     512             :         }
     513        4574 :         tmp = igfScaleF[sfb];
     514        4574 :         move16();
     515        4574 :         if ( flag )
     516             :         {
     517           7 :             tmp = sub( igfScaleF[sfb], 1 );
     518             :         }
     519        4574 :         if ( igfScaleF[sfb] )
     520             :         {
     521        4574 :             igfScaleF[sfb] = tmp;
     522        4574 :             move16();
     523             :         }
     524             :     }
     525             : }
     526             : 
     527      592511 : void IGF_ErodeSpectrum_ivas_fx( const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in:     | instance handle of IGF Encoder */
     528             :                                 Word32 *pSpectrum,                       /**< in/out: | MDCT spectrum                  Qx*/
     529             :                                 Word32 *pPowerSpectrum,                  /**< in/out: | power spectrum                 */
     530             :                                 Word16 pPowerSpectrum_exp,               /**< in:     | exponent of power spectrum     */
     531             :                                 const Word16 igfGridIdx,                 /**< in: Q0  | IGF grid index                 */
     532             :                                 const Word16 mct_on )
     533             : {
     534             :     IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData;
     535             :     H_IGF_GRID hGrid;
     536             :     Word16 i;
     537             :     Word16 igfBgn;
     538             :     Word16 igfEnd;
     539             :     Word32 highPassEner; /* Q31 */
     540             :     Word32 lastLine;
     541             :     Word32 nextLine;
     542             :     Word16 *swb_offset;
     543             :     Word16 sfb;
     544             :     Word16 startSfb;
     545             :     Word16 stopSfb;
     546             :     Word16 line;
     547             :     Word16 *igfScaleF;
     548             :     Word16 tmp;
     549             :     Word16 factor;
     550             :     Word16 exp1, exp2;
     551             :     Word16 num, den;
     552             :     Word32 temp;
     553             : 
     554      592511 :     hPrivateData = &hInstance->igfData;
     555      592511 :     hGrid = &hPrivateData->igfInfo.grid[igfGridIdx];
     556      592511 :     igfBgn = hGrid->startLine;
     557      592511 :     move16();
     558      592511 :     igfEnd = hGrid->stopLine;
     559      592511 :     move16();
     560      592511 :     swb_offset = hGrid->swb_offset;
     561      592511 :     move16();
     562      592511 :     startSfb = hGrid->startSfb;
     563      592511 :     move16();
     564      592511 :     stopSfb = hGrid->stopSfb;
     565      592511 :     move16();
     566      592511 :     igfScaleF = hPrivateData->igfScfQuantized;
     567      592511 :     move16();
     568             : 
     569      592511 :     IF( NULL == pPowerSpectrum )
     570             :     {
     571     4476056 :         FOR( i = igfBgn; i < hGrid->infoGranuleLen; i++ )
     572             :         {
     573     4453960 :             pSpectrum[i] = 0;
     574     4453960 :             move32();
     575             :         }
     576       22096 :         return;
     577             :     }
     578             : 
     579      570415 :     IF( igfBgn > 0 )
     580             :     {
     581      570415 :         Word64 sum = 0;
     582      570415 :         move64();
     583   259232651 :         FOR( i = 0; i < igfBgn; i++ )
     584             :         {
     585   258662236 :             sum = W_mac_32_16( sum, pPowerSpectrum[i], i ); // Q: 31-pPowerSpectrum_exp+1
     586             :         }
     587      570415 :         exp1 = W_norm( sum );
     588      570415 :         sum = W_shl( sum, sub( exp1, 1 ) );                // Q: 31-pPowerSpectrum_exp+1+exp1-1
     589      570415 :         num = extract_h( W_extract_h( sum ) );             // Q: 31-pPowerSpectrum_exp+exp1-48 = -pPowerSpectrum_exp+exp1-17
     590      570415 :         exp1 = add( 32, sub( pPowerSpectrum_exp, exp1 ) ); // exp: 32+pPowerSpectrum_exp-exp1
     591             : 
     592      570415 :         IF( EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_9600 ) ||
     593             :             EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_RF_SWB_13200 ) ||
     594             :             EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_13200 ) ||
     595             :             EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_16400_CPE ) )
     596             :         {
     597       27276 :             factor = ONE_IN_Q14; // Q14
     598       27276 :             move16();
     599             :         }
     600      543139 :         ELSE IF( mct_on && ( EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_48000_CPE ) || EQ_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_64000_CPE ) ) )
     601             :         {
     602        3908 :             factor = 11469; // 0.7f in Q14
     603        3908 :             move16();
     604             :         }
     605             :         ELSE
     606             :         {
     607      539231 :             factor = 32767; // 2.f in Q14
     608      539231 :             move16();
     609             :         }
     610             : 
     611      570415 :         temp = L_mult( igfBgn, factor ); // exp: 16
     612      570415 :         exp2 = norm_l( temp );
     613      570415 :         den = extract_h( L_shl( temp, exp2 ) ); // exp: 16-exp2
     614      570415 :         exp2 = sub( 16, exp2 );
     615             : 
     616      570415 :         highPassEner = L_deposit_h( div_s( num, den ) ); // exp: exp1-exp2
     617             : 
     618             :         /* highPassEner is used only for comparison, saturation doesn't effect the outcome */
     619      570415 :         highPassEner = L_shl_sat( highPassEner, sub( sub( exp1, exp2 ), pPowerSpectrum_exp ) ); // exp: pPowerSpectrum_exp
     620             : 
     621      570415 :         lastLine = pSpectrum[i - 1]; // Qx
     622      570415 :         move32();
     623      570415 :         nextLine = pSpectrum[i]; // Qx
     624      570415 :         move32();
     625             : 
     626      570415 :         if ( LT_32( pPowerSpectrum[i - 1], highPassEner ) )
     627             :         {
     628      570284 :             nextLine = 0;
     629      570284 :             move32();
     630             :         }
     631             : 
     632   168551956 :         FOR( /*i*/; i < igfEnd - 1; i++ )
     633             :         {
     634             :             /* May overflow - just for threshold comparison */
     635   167981541 :             IF( LT_32( pPowerSpectrum[i], highPassEner ) )
     636             :             {
     637   167934184 :                 lastLine = pSpectrum[i]; // Qx
     638   167934184 :                 move32();
     639   167934184 :                 pSpectrum[i] = nextLine; // Qx
     640   167934184 :                 move32();
     641   167934184 :                 nextLine = 0;
     642   167934184 :                 move32();
     643             :             }
     644             :             ELSE
     645             :             {
     646       47357 :                 pSpectrum[i - 1] = lastLine; // Qx
     647       47357 :                 move32();
     648       47357 :                 lastLine = pSpectrum[i]; // Qx
     649       47357 :                 move32();
     650       47357 :                 nextLine = pSpectrum[i + 1]; // Qx
     651       47357 :                 move32();
     652             :             }
     653             :         }
     654             : 
     655             :         /* May overflow - just for threshold comparison */
     656      570415 :         if ( LT_32( pPowerSpectrum[i], highPassEner ) )
     657             :         {
     658      570281 :             pSpectrum[i] = 0;
     659      570281 :             move32();
     660             :         }
     661             :     }
     662             : 
     663             :     /* delete spectrum above igfEnd: */
     664    68041583 :     FOR( i = igfEnd; i < hGrid->infoGranuleLen; i++ )
     665             :     {
     666    67471168 :         pSpectrum[i] = 0;
     667    67471168 :         pPowerSpectrum[i] = 0;
     668    67471168 :         move32();
     669    67471168 :         move32();
     670             :     }
     671             : 
     672             :     // Below check is present at the beginning of the function and is not required here
     673             :     /* IF( NULL != pPowerSpectrum ) */
     674             :     {
     675     3563156 :         FOR( sfb = startSfb; sfb < stopSfb; sfb++ )
     676             :         {
     677     2992741 :             tmp = 0;
     678     2992741 :             move16();
     679   171544697 :             FOR( line = swb_offset[sfb]; line < swb_offset[sfb + 1]; line++ )
     680             :             {
     681   168551956 :                 if ( pSpectrum[line] != 0 )
     682             :                 {
     683       15566 :                     tmp = add( tmp, 1 );
     684             :                 }
     685             :             }
     686             : 
     687     2992741 :             Word16 igfScaleF_cnt = igfScaleF[sfb];
     688     2992741 :             move16();
     689     2992741 :             test();
     690     2992741 :             if ( tmp && igfScaleF[sfb] )
     691             :             {
     692        2565 :                 igfScaleF_cnt = sub( igfScaleF[sfb], 1 );
     693             :             }
     694     2992741 :             igfScaleF[sfb] = igfScaleF_cnt;
     695     2992741 :             move16();
     696             :         }
     697             :     }
     698             : }
     699             : 
     700             : /**********************************************************************/ /*
     701             : crest factor calculation
     702             : **************************************************************************/
     703        1228 : Word16 IGF_getCrest(                                                     /**< out: Q15| crest factor                 */
     704             :                      Word16 *crest_exp,                                  /**< out:    | exponent of crest factor     */
     705             :                      const Word32 *powerSpectrum,                        /**< in: Q31 | power spectrum               */
     706             :                      const Word16 powerSpectrum_exp,                     /**< in:     | exponent of power spectrum   */
     707             :                      const Word16 start,                                 /**< in: Q0  | start subband index          */
     708             :                      const Word16 stop                                   /**< in: Q0  | stop subband index           */
     709             : )
     710             : {
     711             :     Word16 i;
     712             :     Word16 x;
     713             :     Word16 s;
     714             :     Word32 x_eff32;
     715             :     Word16 x_max;
     716             :     Word16 crest;
     717             :     Word16 tmp;
     718             :     Word32 tmp32;
     719             : 
     720        1228 :     x_eff32 = 0;
     721        1228 :     move32();
     722        1228 :     x_max = 0;
     723        1228 :     move16();
     724        1228 :     crest = 16384 /*.5f Q15*/;
     725        1228 :     move16();
     726        1228 :     *crest_exp = 1;
     727        1228 :     move16();
     728             : 
     729      198006 :     FOR( i = start; i < stop; i++ )
     730             :     {
     731             :         /*x      = max(0, (int)(log(powerSpectrum[i]) * INV_LOG_2));*/
     732             : 
     733             :         /*see IGF_getSFM for more comment */
     734      196778 :         x = sub( sub( powerSpectrum_exp, norm_l( powerSpectrum[i] ) ), 1 ); /*Q0*/
     735      196778 :         if ( powerSpectrum[i] == 0 )                                        /*special case: energy is zero*/
     736             :         {
     737         544 :             x = 0;
     738         544 :             move16();
     739             :         }
     740      196778 :         x = s_max( 0, x );
     741      196778 :         x_eff32 = L_mac0( x_eff32, x, x ); /*Q0*/
     742      196778 :         x_max = s_max( x_max, x );         /*Q0*/
     743             :     }
     744             : 
     745             :     /*x_eff /= (stop - start);*/
     746        1228 :     x_eff32 = BASOP_Util_Divide3216_Scale( x_eff32, sub( stop, start ), &s ); /*Q-1, s*/
     747        1228 :     s = add( s, 32 );                                                         /*make x_eff Q31*/
     748             : 
     749             :     /*trunkate to int*/
     750        1228 :     x_eff32 = L_shr( x_eff32, sub( 31, s ) );
     751        1228 :     x_eff32 = L_shl( x_eff32, sub( 31, s ) );
     752             : 
     753        1228 :     test();
     754        1228 :     IF( x_eff32 > 0 && x_max > 0 )
     755             :     {
     756             :         /*crest = max(1.f, (float)x_max/sqrt(x_eff));*/
     757        1048 :         tmp32 = ISqrt32( x_eff32, &s );                        /*Q31, s*/
     758        1048 :         tmp32 = Mpy_32_16_1( tmp32 /*Q31, s*/, x_max /*Q0*/ ); /*Q16, s*/
     759        1048 :         i = norm_l( tmp32 );
     760        1048 :         tmp32 = L_shl( tmp32, i ); /*Q31, s-i+15*/
     761        1048 :         crest = extract_h( tmp32 );
     762        1048 :         *crest_exp = add( sub( s, i ), 15 );
     763        1048 :         move16();
     764             :         /* limit crest factor to a lower bound of 1, may overflow */
     765             :         BASOP_SATURATE_WARNING_OFF_EVS
     766        1048 :         tmp = shl_sat( -1, sub( 15, *crest_exp ) ); /* build negative threshold */
     767        1048 :         tmp = add_sat( crest, tmp );
     768             :         BASOP_SATURATE_WARNING_ON_EVS
     769        1048 :         if ( tmp < 0 )
     770             :         {
     771           0 :             crest = 1;
     772           0 :             move16();
     773             :         }
     774        1048 :         if ( tmp < 0 )
     775             :         {
     776           0 :             *crest_exp = 15;
     777           0 :             move16();
     778             :         }
     779             :     }
     780             : 
     781        1228 :     return crest;
     782             : }
     783             : 
     784      796699 : Word16 IGF_getCrest_ivas(                                  /**< out: Q15| crest factor                 */
     785             :                           Word16 *crest_exp,               /**< out:    | exponent of crest factor     */
     786             :                           const Word32 *powerSpectrum,     /**< in: Q31 | power spectrum               */
     787             :                           const Word16 *powerSpectrum_exp, /**< in:     | exponent of power spectrum   */
     788             :                           const Word16 start,              /**< in: Q0  | start subband index          */
     789             :                           const Word16 stop                /**< in: Q0  | stop subband index           */
     790             : )
     791             : {
     792             :     Word16 i;
     793             :     Word16 x;
     794             :     Word16 s;
     795             :     Word32 x_eff32;
     796             :     Word16 x_max;
     797             :     Word16 crest;
     798             :     Word16 tmp;
     799             :     Word32 tmp32;
     800             : 
     801      796699 :     x_eff32 = 0;
     802      796699 :     move32();
     803      796699 :     x_max = 0;
     804      796699 :     move16();
     805      796699 :     crest = 16384 /*.5f Q15*/;
     806      796699 :     move16();
     807      796699 :     *crest_exp = 1;
     808      796699 :     move16();
     809             : 
     810    42470875 :     FOR( i = start; i < stop; i++ )
     811             :     {
     812             :         /*x      = max(0, (int)(log(powerSpectrum[i]) * INV_LOG_2));*/
     813             : 
     814             :         /*see IGF_getSFM for more comment */
     815    41674176 :         x = sub( sub( powerSpectrum_exp[i], norm_l( powerSpectrum[i] ) ), 1 ); /*Q0*/
     816    41674176 :         if ( powerSpectrum[i] == 0 )                                           /*special case: energy is zero*/
     817             :         {
     818         333 :             x = 0;
     819         333 :             move16();
     820             :         }
     821    41674176 :         x = s_max( 0, x );
     822    41674176 :         x_eff32 = L_mac0( x_eff32, x, x ); /*Q0*/
     823    41674176 :         x_max = s_max( x_max, x );         /*Q0*/
     824             :     }
     825             : 
     826             :     /*x_eff /= (stop - start);*/
     827      796699 :     x_eff32 = BASOP_Util_Divide3216_Scale( x_eff32, sub( stop, start ), &s ); /*Q-1, s*/
     828      796699 :     s = add( s, 32 );                                                         /*make x_eff Q31*/
     829             : 
     830             :     /*trunkate to int*/
     831      796699 :     x_eff32 = L_shr( x_eff32, sub( 31, s ) );
     832      796699 :     x_eff32 = L_shl( x_eff32, sub( 31, s ) );
     833             : 
     834      796699 :     test();
     835      796699 :     IF( x_eff32 > 0 && x_max > 0 )
     836             :     {
     837             :         /*crest = max(1.f, (float)x_max/sqrt(x_eff));*/
     838      734031 :         tmp32 = ISqrt32( x_eff32, &s );                        /*Q31, s*/
     839      734031 :         tmp32 = Mpy_32_16_1( tmp32 /*Q31, s*/, x_max /*Q0*/ ); /*Q16, s*/
     840      734031 :         i = norm_l( tmp32 );
     841      734031 :         tmp32 = L_shl( tmp32, i ); /*Q31, s-i+15*/
     842      734031 :         crest = extract_h( tmp32 );
     843      734031 :         *crest_exp = add( sub( s, i ), 15 );
     844      734031 :         move16();
     845             :         /* limit crest factor to a lower bound of 1, may overflow */
     846             :         BASOP_SATURATE_WARNING_OFF_EVS
     847      734031 :         tmp = shl_sat( -1, sub( 15, *crest_exp ) ); /* build negative threshold */
     848      734031 :         tmp = add_sat( crest, tmp );
     849             :         BASOP_SATURATE_WARNING_ON_EVS
     850      734031 :         if ( tmp < 0 )
     851             :         {
     852           0 :             crest = 1;
     853           0 :             move16();
     854             :         }
     855      734031 :         if ( tmp < 0 )
     856             :         {
     857           0 :             *crest_exp = 15;
     858           0 :             move16();
     859             :         }
     860             :     }
     861             : 
     862      796699 :     return crest;
     863             : }
     864             : 
     865             : /*************************************************************************
     866             : calculates spectral flatness measurment
     867             : **************************************************************************/
     868        1228 : Word16 IGF_getSFM(                           /**< out: Q15| SFM value              */
     869             :                    Word16 *SFM_exp,          /**< out:    | exponent of SFM Factor */
     870             :                    const Word32 *energy,     /**< in:  Q31| energies               */
     871             :                    const Word16 *energy_exp, /**< in:     | exponent of energies   */
     872             :                    const Word16 start,       /**< in:  Q0 | start subband index    */
     873             :                    const Word16 stop         /**< in:  Q0 | stop subband index     */
     874             : )
     875             : {
     876             :     Word16 n, i, s;
     877             :     Word32 num;
     878             :     Word32 denom;
     879             :     Word16 denom_exp;
     880             :     Word16 invDenom_exp, numf_exp;
     881             :     Word16 numf;
     882             :     Word32 SFM32;
     883             :     Word32 L_c;
     884             :     Word16 invDenom, SFM;
     885             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     886        1228 :     Flag Overflow = 0;
     887        1228 :     Flag Carry = 0;
     888        1228 :     move32();
     889        1228 :     move32();
     890             : #endif
     891             : 
     892        1228 :     L_c = 0;
     893        1228 :     move32();
     894        1228 :     num = 0;
     895        1228 :     move32();
     896        1228 :     denom = L_shr( 2147483 /*0,001 in Q31 - float is "1", here*/, s_min( *energy_exp, 31 ) );
     897        1228 :     denom = L_max( denom, 1 );
     898        1228 :     *SFM_exp = 0;
     899        1228 :     move16();
     900        1228 :     SFM = 32767 /*1.0f Q15*/;
     901        1228 :     move16();
     902             : 
     903      198006 :     FOR( i = start; i < stop; i++ )
     904             :     {
     905             :         /*ln(x * 2^-Qx * 2^xExp) = ln(x) - Qx + xExp*/
     906             : 
     907             :         /* n       = sub(sub(31,norm_l(tmp32)),1);  */ /*<- ld    */
     908             :         /* n       = sub(n,31);                     */ /*<- -Qx   */
     909             :         /* n       = add(n,*energy_exp);            */ /*<- +xExp */
     910             : 
     911      196778 :         n = sub( sub( *energy_exp, norm_l( energy[i] ) ), 1 ); /*<-- short form*/
     912             : 
     913      196778 :         if ( energy[i] == 0 ) /*special case: energy is zero*/
     914             :         {
     915         544 :             n = 0;
     916         544 :             move16();
     917             :         }
     918             : 
     919      196778 :         n = s_max( 0, n );
     920      196778 :         num = L_add( num, L_deposit_l( n ) ); /*Q0*/
     921             : 
     922      196778 :         Carry = 0;
     923      196778 :         move32();
     924      196778 :         denom = L_add_co( energy[i], denom, &Carry, &Overflow );
     925      196778 :         Overflow = 0;
     926      196778 :         move32();
     927      196778 :         L_c = L_macNs_co( L_c, 0, 0, &Carry, &Overflow );
     928             :     }
     929             : 
     930        1228 :     denom = norm_llQ31( L_c, denom, &denom_exp ); /*Q31*/
     931        1228 :     denom_exp = add( denom_exp, *energy_exp );
     932             : 
     933             :     /* calculate SFM only if signal is present */
     934        1228 :     IF( denom != 0 )
     935             :     {
     936             :         /*numf   = (float)num / (float)(stop - start);*/
     937        1228 :         numf = BASOP_Util_Divide3216_Scale( num,                /*Q0*/
     938        1228 :                                             sub( stop, start ), /*Q0*/
     939             :                                             &s );               /*Q-1 s*/
     940        1228 :         numf_exp = add( s, 16 );                                /*-> numf Q15 numf_exp*/
     941             :         /*denom /= (float)(stop - start);*/
     942             :         /*return ((float)pow(2.0, numf + 0.5f) / denom);*/
     943             : 
     944             :         /*SFM= ((float)pow(2.0, numf + 0.5f) * invDenom);*/
     945        1228 :         invDenom = BASOP_Util_Divide3232_uu_1616_Scale( L_deposit_l( sub( stop, start ) ) /*Q0*/,
     946             :                                                         denom /*Q31, denom_exp*/,
     947             :                                                         &s ); /*Q-16, s-denom_exp*/
     948        1228 :         invDenom_exp = add( sub( s, denom_exp ), 31 );        /*invDenom: Q15, invDenom_exp*/
     949             : 
     950             :         /*add .5f to numf*/
     951        1228 :         SFM32 = L_add( L_shl( L_deposit_l( numf ), numf_exp ) /*16Q15*/, 16384l /*.5f Q15*/ ); /*16Q15*/
     952        1228 :         s = norm_l( SFM32 );
     953        1228 :         SFM32 = L_shl( SFM32, s );
     954        1228 :         s = sub( 16, s ); /*SFM32(numf) is Q31 now*/
     955             : 
     956             :         /*do the pow2 and the mult*/
     957        1228 :         SFM32 = BASOP_util_Pow2( SFM32, s, &s );
     958        1228 :         SFM32 = Mpy_32_16_1( SFM32, invDenom );
     959        1228 :         *SFM_exp = add( s, invDenom_exp );
     960             : 
     961             :         /*Transform to Q15*/
     962        1228 :         s = norm_l( SFM32 );
     963        1228 :         SFM = round_fx_sat( L_shl_sat( SFM32, s ) );
     964        1228 :         *SFM_exp = sub( *SFM_exp, s );
     965        1228 :         move16();
     966             :         /**SFM_exp = s_min(*SFM_exp, 0);*/
     967        1228 :         IF( *SFM_exp > 0 )
     968             :         {
     969         180 :             *SFM_exp = 0;
     970         180 :             move16();
     971         180 :             SFM = 32767 /*1.0f Q15*/;
     972         180 :             move16();
     973             :         }
     974             :     }
     975             : 
     976        1228 :     return SFM /*Q15*/;
     977             : }
     978             : 
     979             : /*************************************************************************
     980             : calculates spectral flatness measurment
     981             : **************************************************************************/
     982      796699 : Word16 IGF_getSFM_ivas_fx(                           /**< out: Q15| SFM value              */
     983             :                            Word16 *SFM_exp,          /**< out:    | exponent of SFM Factor */
     984             :                            const Word32 *energy,     /**< in:  Q31| energies               */
     985             :                            const Word16 *energy_exp, /**< in:     | exponent of energies   */
     986             :                            const Word16 start,       /**< in:  Q0 | start subband index    */
     987             :                            const Word16 stop         /**< in:  Q0 | stop subband index     */
     988             : )
     989             : {
     990             :     Word16 n, i, s;
     991             :     Word32 num;
     992             :     Word32 denom;
     993             :     Word16 denom_exp;
     994             :     Word16 invDenom_exp, numf_exp;
     995             :     Word16 numf;
     996             :     Word32 SFM32;
     997             :     Word16 invDenom, SFM;
     998             : 
     999      796699 :     num = 0;
    1000      796699 :     move32();
    1001      796699 :     denom = 65536; // 1.f in Q16
    1002      796699 :     denom_exp = 15;
    1003      796699 :     *SFM_exp = 0;
    1004      796699 :     move16();
    1005      796699 :     SFM = 32767 /*1.0f Q15*/;
    1006      796699 :     move16();
    1007             : 
    1008    42470875 :     FOR( i = start; i < stop; i++ )
    1009             :     {
    1010             :         /*ln(x * 2^-Qx * 2^xExp) = ln(x) - Qx + xExp*/
    1011             : 
    1012             :         /* n       = sub(sub(31,norm_l(tmp32)),1);  */ /*<- ld    */
    1013             :         /* n       = sub(n,31);                     */ /*<- -Qx   */
    1014             :         /* n       = add(n,*energy_exp);            */ /*<- +xExp */
    1015             : 
    1016    41674176 :         n = sub( sub( energy_exp[i], norm_l( energy[i] ) ), 1 ); /*<-- short form*/
    1017             : 
    1018    41674176 :         if ( energy[i] == 0 ) /*special case: energy is zero*/
    1019             :         {
    1020         333 :             n = 0;
    1021         333 :             move16();
    1022             :         }
    1023             : 
    1024    41674176 :         n = s_max( 0, n );
    1025    41674176 :         num = L_add( num, L_deposit_l( n ) ); /*Q0*/
    1026             : 
    1027    41674176 :         denom = BASOP_Util_Add_Mant32Exp( energy[i], energy_exp[i], denom, denom_exp, &denom_exp );
    1028             :     }
    1029             : 
    1030             :     /* calculate SFM only if signal is present */
    1031      796699 :     IF( denom != 0 )
    1032             :     {
    1033             :         /*numf   = (float)num / (float)(stop - start);*/
    1034      796699 :         numf = BASOP_Util_Divide3216_Scale( num,                /*Q0*/
    1035      796699 :                                             sub( stop, start ), /*Q0*/
    1036             :                                             &s );               /*Q-1 s*/
    1037      796699 :         numf_exp = add( s, 16 );                                /*-> numf Q15 numf_exp*/
    1038             :         /*denom /= (float)(stop - start);*/
    1039             :         /*return ((float)pow(2.0, numf + 0.5f) / denom);*/
    1040             : 
    1041             :         /*SFM= ((float)pow(2.0, numf + 0.5f) * invDenom);*/
    1042      796699 :         invDenom = BASOP_Util_Divide3232_uu_1616_Scale( L_deposit_l( sub( stop, start ) ) /*Q0*/,
    1043             :                                                         denom /*Q31, denom_exp*/,
    1044             :                                                         &s ); /*Q-16, s-denom_exp*/
    1045      796699 :         invDenom_exp = add( sub( s, denom_exp ), 31 );        /*invDenom: Q15, invDenom_exp*/
    1046             : 
    1047             :         /*add .5f to numf*/
    1048      796699 :         SFM32 = L_add( L_shl( L_deposit_l( numf ), numf_exp ) /*16Q15*/, 16384l /*.5f Q15*/ ); /*16Q15*/
    1049      796699 :         s = norm_l( SFM32 );
    1050      796699 :         SFM32 = L_shl( SFM32, s );
    1051      796699 :         s = sub( 16, s ); /*SFM32(numf) is Q31 now*/
    1052             : 
    1053             :         /*do the pow2 and the mult*/
    1054      796699 :         SFM32 = BASOP_util_Pow2( SFM32, s, &s );
    1055      796699 :         SFM32 = Mpy_32_16_1( SFM32, invDenom );
    1056      796699 :         *SFM_exp = add( s, invDenom_exp );
    1057             : 
    1058             :         /*Transform to Q15*/
    1059      796699 :         s = norm_l( SFM32 );
    1060      796699 :         SFM = round_fx_sat( L_shl_sat( SFM32, s ) );
    1061      796699 :         *SFM_exp = sub( *SFM_exp, s );
    1062      796699 :         move16();
    1063             :         /**SFM_exp = s_min(*SFM_exp, 0);*/
    1064      796699 :         IF( *SFM_exp > 0 )
    1065             :         {
    1066       61198 :             *SFM_exp = 0;
    1067       61198 :             move16();
    1068       61198 :             SFM = 32767 /*1.0f Q15*/;
    1069       61198 :             move16();
    1070             :         }
    1071             :     }
    1072             : 
    1073      796699 :     return SFM /*Q15*/;
    1074             : }
    1075             : 
    1076             : /**********************************************************************/ /*
    1077             : calculates the IGF whitening levels by SFM and crest
    1078             : **************************************************************************/
    1079         637 : static void IGF_Whitening( const IGF_ENC_INSTANCE_HANDLE hInstance,      /**< in:     | instance handle of IGF Encoder               */
    1080             :                            Word32 *powerSpectrum,                        /**< in: Q31 | MDCT/MDST power spectrum                     */
    1081             :                            const Word16 powerSpectrum_exp,               /**< in:     | exponent of powerspectrum                    */
    1082             :                            const Word16 igfGridIdx,                      /**< in: Q0  | IGF grid index                               */
    1083             :                            Word16 isTransient,                           /**< in: Q0  | boolean, indicating if transient is detected */
    1084             :                            Word16 last_core_acelp                        /**< in: Q0  | indictaor if last frame was acelp coded      */
    1085             : )
    1086             : {
    1087             :     IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData;
    1088             :     H_IGF_GRID hGrid;
    1089             :     Word16 p; /*Q0*/
    1090             :     Word16 tmp;
    1091             :     Word16 SFM;
    1092             :     Word16 crest;
    1093             :     Word16 SFM_exp;
    1094             :     Word16 crest_exp;
    1095             :     Word16 s;
    1096             :     Word32 tmp32;
    1097             :     Word32 SFM32;
    1098             : 
    1099         637 :     hPrivateData = &hInstance->igfData;
    1100         637 :     hGrid = &hPrivateData->igfInfo.grid[igfGridIdx];
    1101             : 
    1102         637 :     IF( igfGridIdx != IGF_GRID_LB_NORM )
    1103             :     {
    1104         125 :         FOR( p = 0; p < hGrid->nTiles; p++ )
    1105             :         {
    1106             :             /* reset filter */
    1107          91 :             hPrivateData->prevSFM_FIR[p] = L_deposit_l( 0 );
    1108          91 :             move32();
    1109          91 :             hPrivateData->prevSFM_IIR[p] = 0;
    1110          91 :             move16();
    1111             : 
    1112             :             /* preset values: */
    1113          91 :             hPrivateData->igfCurrWhiteningLevel[p] = IGF_WHITENING_OFF;
    1114          91 :             move16();
    1115             :         }
    1116             :     }
    1117        7007 :     FOR( p = 0; p < IGF_MAX_TILES; p++ )
    1118             :     {
    1119             :         /* update prev data: */
    1120        6370 :         hPrivateData->igfPrevWhiteningLevel[p] = hPrivateData->igfCurrWhiteningLevel[p];
    1121        6370 :         move16();
    1122             :         /* preset values: */
    1123        6370 :         hPrivateData->igfCurrWhiteningLevel[p] = IGF_WHITENING_OFF;
    1124        6370 :         move16();
    1125             :     }
    1126             : 
    1127         637 :     IF( !s_or( isTransient, hPrivateData->wasTransient ) )
    1128             :     {
    1129         614 :         IF( powerSpectrum )
    1130             :         {
    1131         614 :             Word16 nT = hGrid->nTiles;
    1132         614 :             move16();
    1133         614 :             SWITCH( hPrivateData->igfInfo.bitRateIndex )
    1134             :             {
    1135         374 :                 case IGF_BITRATE_WB_9600:
    1136             :                 case IGF_BITRATE_SWB_9600:
    1137             :                 case IGF_BITRATE_SWB_16400:
    1138             :                 case IGF_BITRATE_SWB_24400:
    1139             :                 case IGF_BITRATE_SWB_32000:
    1140             :                 case IGF_BITRATE_FB_16400:
    1141             :                 case IGF_BITRATE_FB_24400:
    1142             :                 case IGF_BITRATE_FB_32000:
    1143         374 :                     nT = sub( nT, 1 );
    1144         374 :                     BREAK;
    1145         240 :                 default:
    1146         240 :                     BREAK;
    1147             :             }
    1148        1842 :             FOR( p = 0; p < nT; p++ )
    1149             :             {
    1150             :                 /*tmp  = IGF_getSFM(powerSpectrum, hGrid->tile[p], hGrid->tile[p+1]) / IGF_getCrest(powerSpectrum, hGrid->tile[p], hGrid->tile[p+1]);*/
    1151        1228 :                 SFM = IGF_getSFM( &SFM_exp, powerSpectrum, &powerSpectrum_exp, hGrid->tile[p], hGrid->tile[p + 1] );
    1152        1228 :                 crest = IGF_getCrest( &crest_exp, powerSpectrum, powerSpectrum_exp, hGrid->tile[p], hGrid->tile[p + 1] );
    1153             : 
    1154        1228 :                 tmp = BASOP_Util_Divide1616_Scale( SFM, crest, &s ); /*   Q15 */
    1155        1228 :                 s = add( s, sub( SFM_exp, crest_exp ) );
    1156        1228 :                 tmp32 = L_shl( L_deposit_l( tmp ) /*16Q15, s*/, add( s, 1 ) ); /* 15Q16 */
    1157             : 
    1158        1228 :                 test();
    1159        1228 :                 IF( last_core_acelp || hPrivateData->wasTransient )
    1160             :                 {
    1161          68 :                     hPrivateData->prevSFM_FIR[p] = tmp32; /* 15Q16 */
    1162          68 :                     move32();
    1163          68 :                     hPrivateData->prevSFM_IIR[p] = shr( tmp, 2 ); /*  2Q13 */
    1164          68 :                     move16();
    1165             :                 }
    1166             : 
    1167             :                 /*SFM  = tmp + hPrivateData->prevSFM_FIR[p] + 0.5f * hPrivateData->prevSFM_IIR[p];*/
    1168        1228 :                 SFM32 = L_add( tmp32, hPrivateData->prevSFM_FIR[p] );
    1169        1228 :                 SFM32 = L_mac0( SFM32, hPrivateData->prevSFM_IIR[p] /*Q13*/, 4 /*.5f Q3*/ ); /*15Q16*/
    1170             : 
    1171             :                 BASOP_SATURATE_WARNING_OFF_EVS
    1172             :                 /*SFM  = min(2.7f, SFM);*/
    1173             :                 /*Overflow possible in shift, intended*/
    1174        1228 :                 tmp = add_sat( crest, tmp );
    1175        1228 :                 SFM = s_min( 22118 /*2.7f Q13*/, extract_h( L_shr_sat( SFM32, 16 - 29 ) /*->Q29*/ ) /*->Q13*/ );
    1176             :                 BASOP_SATURATE_WARNING_ON_EVS
    1177             : 
    1178        1228 :                 hPrivateData->prevSFM_FIR[p] = tmp32; /*15Q16*/
    1179        1228 :                 move32();
    1180        1228 :                 hPrivateData->prevSFM_IIR[p] = SFM;
    1181        1228 :                 move16();
    1182             : 
    1183        1228 :                 IF( GT_16( SFM, hGrid->whiteningThreshold[1][p] ) )
    1184             :                 {
    1185         627 :                     hPrivateData->igfCurrWhiteningLevel[p] = IGF_WHITENING_STRONG;
    1186         627 :                     move16();
    1187             :                 }
    1188         601 :                 ELSE IF( GT_16( SFM, hGrid->whiteningThreshold[0][p] ) )
    1189             :                 {
    1190         395 :                     hPrivateData->igfCurrWhiteningLevel[p] = IGF_WHITENING_MID;
    1191         395 :                     move16();
    1192             :                 }
    1193             :             }
    1194         614 :             SWITCH( hPrivateData->igfInfo.bitRateIndex )
    1195             :             {
    1196         374 :                 case IGF_BITRATE_WB_9600:
    1197             :                 case IGF_BITRATE_RF_WB_13200:
    1198             :                 case IGF_BITRATE_RF_SWB_13200:
    1199             :                 case IGF_BITRATE_SWB_9600:
    1200             :                 case IGF_BITRATE_SWB_16400:
    1201             :                 case IGF_BITRATE_SWB_24400:
    1202             :                 case IGF_BITRATE_SWB_32000:
    1203             :                 case IGF_BITRATE_FB_16400:
    1204             :                 case IGF_BITRATE_FB_24400:
    1205             :                 case IGF_BITRATE_FB_32000:
    1206         374 :                     move16();
    1207         374 :                     hPrivateData->igfCurrWhiteningLevel[hGrid->nTiles - 1] = hPrivateData->igfCurrWhiteningLevel[hGrid->nTiles - 2];
    1208         374 :                     BREAK;
    1209         240 :                 default:
    1210         240 :                     BREAK;
    1211             :             }
    1212             :         }
    1213             :         ELSE
    1214             :         {
    1215           0 :             FOR( p = 0; p < hGrid->nTiles; p++ )
    1216             :             {
    1217           0 :                 hPrivateData->igfCurrWhiteningLevel[p] = IGF_WHITENING_MID;
    1218           0 :                 move16();
    1219             :             }
    1220             :         }
    1221             :     }
    1222             :     ELSE
    1223             :     {
    1224             :         /* reset filter */
    1225         253 :         FOR( p = 0; p < IGF_MAX_TILES; p++ )
    1226             :         {
    1227         230 :             hPrivateData->prevSFM_FIR[p] = L_deposit_l( 0 );
    1228         230 :             move32();
    1229         230 :             hPrivateData->prevSFM_IIR[p] = 0;
    1230         230 :             move16();
    1231             :         }
    1232             :     }
    1233         637 :     hPrivateData->wasTransient = isTransient;
    1234         637 :     move16();
    1235         637 : }
    1236             : 
    1237             : /**********************************************************************/ /*
    1238             : write whitening levels into bitstream
    1239             : **************************************************************************/
    1240        1970 : static void IGF_WriteWhiteningTile_fx(                                   /**< out: Q0 | number of bits written     */
    1241             :                                        BSTR_ENC_HANDLE hBstr,            /* i/o: encoder bitstream handle       */
    1242             :                                        Word16 *pBitOffset,               /**< in:     | ptr to bitOffset counter   */
    1243             :                                        Word16 whiteningLevel             /**< in: Q0  | whitening levels to write  */
    1244             : )
    1245             : {
    1246        1970 :     IF( EQ_32( whiteningLevel, IGF_WHITENING_MID ) )
    1247             :     {
    1248         656 :         IGF_write_bits( hBstr, pBitOffset, 0, 1 );
    1249             :     }
    1250             :     ELSE
    1251             :     {
    1252        1314 :         IGF_write_bits( hBstr, pBitOffset, 1, 1 );
    1253        1314 :         IF( EQ_32( whiteningLevel, IGF_WHITENING_OFF ) )
    1254             :         {
    1255         394 :             IGF_write_bits( hBstr, pBitOffset, 0, 1 );
    1256             :         }
    1257             :         ELSE
    1258             :         {
    1259         920 :             IGF_write_bits( hBstr, pBitOffset, 1, 1 );
    1260             :         }
    1261             :     }
    1262        1970 : }
    1263             : 
    1264             : /**********************************************************************/          /*
    1265             :          writes the whitening levels
    1266             :          **************************************************************************/
    1267        1274 : static void IGF_WriteWhiteningLevels_fx(                                          /**< out: Q0 | total number of bits written                                                 */
    1268             :                                          const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in:     | instance handle of IGF encoder                                               */
    1269             :                                          BSTR_ENC_HANDLE hBstr,                   /* i/o: encoder bitstream handle       */
    1270             :                                          Word16 *pBitOffset,                      /**< in:     | ptr to bitOffset counter                                                     */
    1271             :                                          const Word16 igfGridIdx,                 /**< in: Q0  | igf grid index see declaration of IGF_GRID_IDX for details                   */
    1272             :                                          const Word16 isIndepFlag                 /**< in: Q0  | if 1 frame is independent, 0 = frame is coded with data from previous frame  */
    1273             : )
    1274             : {
    1275             :     IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData;
    1276             :     H_IGF_GRID hGrid;
    1277             :     Word16 p;
    1278             :     Word16 nTiles;
    1279             :     Word16 isSame;
    1280             :     Word32 tmp32;
    1281             : 
    1282             : 
    1283        1274 :     isSame = 1;
    1284        1274 :     move16();
    1285        1274 :     hPrivateData = &hInstance->igfData;
    1286        1274 :     hGrid = &hPrivateData->igfInfo.grid[igfGridIdx];
    1287        1274 :     nTiles = hGrid->nTiles;
    1288        1274 :     move16();
    1289             : 
    1290        1274 :     IF( isIndepFlag )
    1291             :     {
    1292        1274 :         isSame = 0;
    1293        1274 :         move16();
    1294             :     }
    1295             :     ELSE
    1296             :     {
    1297           0 :         p = 0;
    1298           0 :         move16();
    1299           0 :         tmp32 = 0;
    1300           0 :         move32();
    1301           0 :         test();
    1302           0 :         WHILE( ( LT_16( p, nTiles ) ) && ( tmp32 == 0 ) )
    1303             :         {
    1304           0 :             test();
    1305           0 :             tmp32 = L_sub( hPrivateData->igfCurrWhiteningLevel[p], hPrivateData->igfPrevWhiteningLevel[p] );
    1306           0 :             if ( tmp32 != 0 )
    1307             :             {
    1308           0 :                 isSame = 0;
    1309           0 :                 move16();
    1310             :             }
    1311           0 :             p++;
    1312             :         }
    1313             :     }
    1314        1274 :     IF( isSame )
    1315             :     {
    1316           0 :         IGF_write_bits( hBstr, pBitOffset, 1, 1 );
    1317             :     }
    1318             :     ELSE
    1319             :     {
    1320        1274 :         IF( !isIndepFlag )
    1321             :         {
    1322           0 :             IGF_write_bits( hBstr, pBitOffset, 0, 1 );
    1323             :         }
    1324        1274 :         IGF_WriteWhiteningTile_fx( hBstr, pBitOffset, hPrivateData->igfCurrWhiteningLevel[0] );
    1325        1274 :         p = 1;
    1326        1274 :         move16();
    1327        1274 :         tmp32 = 0;
    1328        1274 :         move32();
    1329        1274 :         if ( LT_16( p, nTiles ) )
    1330             :         {
    1331        1274 :             isSame = 1;
    1332        1274 :             move16();
    1333             :         }
    1334        1274 :         test();
    1335        3024 :         WHILE( ( LT_16( p, nTiles ) ) && ( tmp32 == 0 ) )
    1336             :         {
    1337        1750 :             test();
    1338        1750 :             tmp32 = L_sub( hPrivateData->igfCurrWhiteningLevel[p], hPrivateData->igfCurrWhiteningLevel[p - 1] );
    1339        1750 :             if ( tmp32 != 0 )
    1340             :             {
    1341         420 :                 isSame = 0;
    1342         420 :                 move16();
    1343             :             }
    1344        1750 :             p++;
    1345             :         }
    1346             : 
    1347        1274 :         IF( !isSame )
    1348             :         {
    1349         420 :             IGF_write_bits( hBstr, pBitOffset, 1, 1 );
    1350        1116 :             FOR( p = 1; p < nTiles; p++ )
    1351             :             {
    1352         696 :                 IGF_WriteWhiteningTile_fx( hBstr, pBitOffset, hPrivateData->igfCurrWhiteningLevel[p] );
    1353             :             }
    1354             :         }
    1355             :         ELSE
    1356             :         {
    1357         854 :             IGF_write_bits( hBstr, pBitOffset, 0, 1 );
    1358             :         }
    1359             :     }
    1360        1274 : }
    1361             : 
    1362             : /**********************************************************************/            /*
    1363             :            write flattening trigger
    1364             :            **************************************************************************/
    1365        1274 : static void IGF_WriteFlatteningTrigger_fx(                                          /**< out:    | number of bits written         */
    1366             :                                            const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in:     | instance handle of IGF Encoder */
    1367             :                                            BSTR_ENC_HANDLE hBstr,                   /* i/o: encoder bitstream handle       */
    1368             :                                            Word16 *pBitOffset                       /**< in:     | ptr to bitOffset counter       */
    1369             : )
    1370             : {
    1371             :     Word16 flatteningTrigger;
    1372             : 
    1373             : 
    1374        1274 :     flatteningTrigger = hInstance->flatteningTrigger;
    1375        1274 :     move16();
    1376             : 
    1377        1274 :     IGF_write_bits( hBstr, pBitOffset, flatteningTrigger, 1 );
    1378        1274 : }
    1379             : 
    1380             : /**********************************************************************/ /*
    1381             : updates the start/stop frequency of IGF according to igfGridIdx
    1382             : **************************************************************************/
    1383     1185659 : void IGF_UpdateInfo( const IGF_ENC_INSTANCE_HANDLE hInstance,            /**< in:     | instance handle of IGF Encoder */
    1384             :                      const Word16 igfGridIdx                             /**< in: Q0  | IGF grid index                 */
    1385             : )
    1386             : {
    1387             :     IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData;
    1388             :     H_IGF_GRID hGrid;
    1389             : 
    1390             : 
    1391     1185659 :     hPrivateData = &hInstance->igfData;
    1392     1185659 :     hGrid = &hPrivateData->igfInfo.grid[igfGridIdx];
    1393     1185659 :     hInstance->infoStartFrequency = hGrid->startFrequency;
    1394     1185659 :     move16();
    1395     1185659 :     hInstance->infoStopFrequency = hGrid->stopFrequency;
    1396     1185659 :     move16();
    1397     1185659 :     hInstance->infoStartLine = hGrid->startLine;
    1398     1185659 :     move16();
    1399     1185659 :     hInstance->infoStopLine = hGrid->stopLine;
    1400     1185659 :     move16();
    1401             : 
    1402     1185659 :     return;
    1403             : }
    1404             : 
    1405             : /**********************************************************************/ /*
    1406             : IGF bitsream writer
    1407             : **************************************************************************/
    1408        1274 : Word16 IGFEncWriteBitstream_fx(                                          /**< out:    | number of bits written per frame                                             */
    1409             :                                 const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in:     | instance handle of IGF Encoder                                               */
    1410             :                                 BSTR_ENC_HANDLE hBstr,                   /* i/o: encoder bitstream handle       */
    1411             :                                 Word16 *pBitOffset,                      /**< in:     | ptr to bitOffset counter                                                     */
    1412             :                                 const Word16 igfGridIdx,                 /**< in: Q0  | igf grid index see declaration of IGF_GRID_IDX for details                   */
    1413             :                                 const Word16 isIndepFlag                 /**< in: Q0  | if 1 frame is independent, 0 = frame is coded with data from previous frame  */
    1414             : )
    1415             : {
    1416             :     Word16 igfAllZero;
    1417             :     Word16 startBitCount;
    1418             : 
    1419             : 
    1420        1274 :     startBitCount = *pBitOffset;
    1421        1274 :     move16();
    1422        1274 :     hInstance->infoTotalBitsPerFrameWritten = 0;
    1423        1274 :     move16();
    1424             : 
    1425        1274 :     if ( isIndepFlag )
    1426             :     {
    1427        1274 :         hInstance->infoTotalBitsWritten = 0;
    1428        1274 :         move16();
    1429             :     }
    1430             : 
    1431        1274 :     IGF_WriteEnvelope( hInstance,     /* i: instance handle of IGF Encoder                                              */
    1432             :                        hBstr,         /* i: encoder state                                                               */
    1433             :                        pBitOffset,    /* i: ptr to bitOffset counter                                                    */
    1434             :                        igfGridIdx,    /* i: igf grid index see definition of IGF_GRID_IDX for details                   */
    1435             :                        isIndepFlag,   /* i: if 1 frame is independent, 0 = frame is coded with data from previous frame */
    1436             :                        &igfAllZero ); /* o: *igfAllZero                                                                 */
    1437             : 
    1438        1274 :     IGF_WriteWhiteningLevels_fx( hInstance,     /* i: instance handle of IGF Encoder                                              */
    1439             :                                  hBstr,         /* i: encoder state                                                               */
    1440             :                                  pBitOffset,    /* i: ptr to bitOffset counter                                                    */
    1441             :                                  igfGridIdx,    /* i: igf grid index see definition of IGF_GRID_IDX for details                   */
    1442             :                                  isIndepFlag ); /* i: if 1 frame is independent, 0 = frame is coded with data from previous frame */
    1443             : 
    1444        1274 :     IGF_WriteFlatteningTrigger_fx( hInstance,    /* i: instance handle of IGF Encoder                                              */
    1445             :                                    hBstr,        /* i: encoder state                                                               */
    1446             :                                    pBitOffset ); /* i: ptr to bitOffset counter                                                    */
    1447             : 
    1448        1274 :     hInstance->infoTotalBitsPerFrameWritten = sub( *pBitOffset, startBitCount );
    1449        1274 :     hInstance->infoTotalBitsWritten = add( hInstance->infoTotalBitsWritten, hInstance->infoTotalBitsPerFrameWritten );
    1450        1274 :     move16();
    1451        1274 :     move16();
    1452        1274 :     return hInstance->infoTotalBitsPerFrameWritten;
    1453             : }
    1454             : 
    1455             : /**********************************************************************/ /*
    1456             : sets the IGF mode according to given bitrate
    1457             : **************************************************************************/
    1458          81 : void IGFEncSetMode_fx(
    1459             :     const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i/o: instance handle of IGF Encoder */
    1460             :     const Word32 total_brate,              /* i  : encoder total bitrate          */
    1461             :     const Word16 bwidth,                   /* i  : encoder audio bandwidth        */
    1462             :     const Word16 element_mode,             /* i  : IVAS element mode              */
    1463             :     const Word16 rf_mode                   /* i  : flag to signal the RF mode     */
    1464             : )
    1465             : {
    1466             :     IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData;
    1467             :     Word16 i;
    1468             : 
    1469          81 :     hPrivateData = &hIGFEnc->igfData;
    1470          81 :     hPrivateData->igfBitstreamBits = 0;
    1471          81 :     move16();
    1472          81 :     set16_fx( hPrivateData->igfScfQuantized, 0, IGF_MAX_SFB );
    1473          81 :     set16_fx( hPrivateData->igfCurrWhiteningLevel, 0, IGF_MAX_TILES );
    1474          81 :     set16_fx( hPrivateData->igfPrevWhiteningLevel, 0, IGF_MAX_TILES );
    1475       26001 :     FOR( i = 0; i < IGF_BITBUFSIZE / 8; i++ )
    1476             :     {
    1477       25920 :         hPrivateData->igfBitstream[i] = 0;
    1478       25920 :         move16();
    1479             :     }
    1480          81 :     hPrivateData->wasTransient = 0;
    1481          81 :     move16();
    1482          81 :     set32_fx( hPrivateData->prevSFM_FIR, 0, IGF_MAX_TILES );
    1483          81 :     set16_fx( hPrivateData->prevSFM_IIR, 0, IGF_MAX_TILES );
    1484             : 
    1485          81 :     IF( IGFCommonFuncsIGFConfiguration( total_brate, bwidth, element_mode, &hPrivateData->igfInfo, rf_mode ) != 0 )
    1486             :     {
    1487          81 :         IGFSCFEncoderOpen_fx( &hPrivateData->hIGFSCFArithEnc, &hPrivateData->igfInfo, total_brate, bwidth, element_mode, rf_mode );
    1488             : 
    1489          81 :         hIGFEnc->infoSamplingRate = hPrivateData->igfInfo.sampleRate;
    1490          81 :         move32();
    1491          81 :         hIGFEnc->infoStartFrequency = hPrivateData->igfInfo.grid[0].startFrequency;
    1492          81 :         move16();
    1493          81 :         hIGFEnc->infoStopFrequency = hPrivateData->igfInfo.grid[0].stopFrequency;
    1494          81 :         move16();
    1495          81 :         hIGFEnc->infoStartLine = hPrivateData->igfInfo.grid[0].startLine;
    1496          81 :         move16();
    1497          81 :         hIGFEnc->infoStopLine = hPrivateData->igfInfo.grid[0].stopLine;
    1498          81 :         move16();
    1499             :     }
    1500             :     ELSE
    1501             :     {
    1502             :         /* IGF configuration failed -> error! */
    1503           0 :         hIGFEnc->infoSamplingRate = 0;
    1504           0 :         move32();
    1505           0 :         hIGFEnc->infoStartFrequency = -1;
    1506           0 :         move16();
    1507           0 :         hIGFEnc->infoStopFrequency = -1;
    1508           0 :         move16();
    1509           0 :         hIGFEnc->infoStartLine = -1;
    1510           0 :         move16();
    1511           0 :         hIGFEnc->infoStopLine = -1;
    1512           0 :         move16();
    1513           0 :         fprintf( stderr, "IGFEncSetMode_fx: initialization error!\n" );
    1514             :     }
    1515             : 
    1516             :     /* reset remaining variables */
    1517          81 :     hIGFEnc->infoTotalBitsWritten = 0;
    1518          81 :     move16();
    1519          81 :     hIGFEnc->infoTotalBitsPerFrameWritten = 0;
    1520          81 :     move16();
    1521          81 :     hIGFEnc->flatteningTrigger = 0;
    1522          81 :     move16();
    1523          81 :     hIGFEnc->spec_be_igf_e = 0;
    1524          81 :     move16();
    1525          81 :     hIGFEnc->tns_predictionGain = 0;
    1526          81 :     move16();
    1527          81 :     set32_fx( hIGFEnc->spec_be_igf, 0, N_MAX_TCX - IGF_START_MN );
    1528          81 :     return;
    1529             : }
    1530             : 
    1531             : /*-------------------------------------------------------------------*
    1532             :  * pack_bit()
    1533             :  *
    1534             :  * insert a bit into packed octet
    1535             :  *-------------------------------------------------------------------*/
    1536             : 
    1537      495184 : static void pack_bit_ivas_fx(
    1538             :     const Word16 bit, /* i  : bit to be packed */
    1539             :     UWord8 **pt,      /* i/o: pointer to octet array into which bit will be placed */
    1540             :     UWord8 *omask     /* i/o: output mask to indicate where in the octet the bit is to be written */
    1541             : )
    1542             : {
    1543      495184 :     if ( EQ_16( *omask, 0x80 ) )
    1544             :     {
    1545       66890 :         **pt = 0;
    1546       66890 :         move16();
    1547             :     }
    1548             : 
    1549      495184 :     if ( bit != 0 )
    1550             :     {
    1551      264914 :         **pt = (UWord8) s_or( **pt, *omask );
    1552      264914 :         move16();
    1553             :     }
    1554             : 
    1555      495184 :     *omask = (UWord8) UL_lshr( *omask, 1 );
    1556      495184 :     move16();
    1557      495184 :     IF( *omask == 0 )
    1558             :     {
    1559       57074 :         *omask = 0x80;
    1560       57074 :         move16();
    1561       57074 :         ( *pt )++;
    1562             :     }
    1563             : 
    1564      495184 :     return;
    1565             : }
    1566             : 
    1567             : /*-------------------------------------------------------------------*
    1568             :  * IGFEncConcatenateBitstream_fx()
    1569             :  *
    1570             :  * IGF bitstream concatenation for TCX10 modes
    1571             :  *-------------------------------------------------------------------*/
    1572             : 
    1573       22096 : void IGFEncConcatenateBitstream_ivas_fx( const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i  : instance handle of IGF Encoder                  */
    1574             :                                          const Word16 bsBits,                   /* i  : number of IGF bits written to list of indices   */
    1575             :                                          BSTR_ENC_HANDLE hBstr                  /* i/o: bitstream handle                                */
    1576             : )
    1577             : {
    1578             :     Word16 i;
    1579             :     IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData;
    1580             :     Indice *ind_list;
    1581             :     UWord8 *pFrame;      /* byte array with bit packet and byte aligned coded speech data */
    1582             :     Word16 *pFrame_size; /* number of bits in the binary encoded access unit [bits]       */
    1583             :     Word16 k, nb_bits_written;
    1584             :     Word32 imask;
    1585             :     UWord8 omask;
    1586             : 
    1587       22096 :     hPrivateData = &hIGFEnc->igfData;
    1588             : 
    1589       22096 :     ind_list = &hBstr->ind_list[hBstr->nb_ind_tot - bsBits]; /* here, we assume that each bit has been written as a single indice */
    1590       22096 :     pFrame = hPrivateData->igfBitstream;
    1591       22096 :     move16();
    1592       22096 :     pFrame_size = &hPrivateData->igfBitstreamBits;
    1593       22096 :     move16();
    1594       22096 :     nb_bits_written = 0;
    1595       22096 :     move16();
    1596             : 
    1597       22096 :     omask = (UWord8) UL_lshr( 0x80, s_and( *pFrame_size, 0x7 ) );
    1598       22096 :     move16();
    1599       22096 :     pFrame += *pFrame_size >> 3;
    1600             : 
    1601             :     /* bitstream packing (conversion of individual indices into a serial stream) */
    1602      517280 :     FOR( i = 0; i < bsBits; i++ ){
    1603      495184 :         IF( ind_list[i].nb_bits > 0 ){
    1604             :             /* mask from MSB to LSB */
    1605      495184 :             imask = L_shl( 1, sub( ind_list[i].nb_bits, 1 ) );
    1606             : 
    1607             :     /* write bit by bit */
    1608      990368 :     FOR( k = 0; k < ind_list[i].nb_bits; k++ )
    1609             :     {
    1610      495184 :         pack_bit_ivas_fx( extract_l( L_and( ind_list[i].value, imask ) ), &pFrame, &omask );
    1611      495184 :         imask = L_shr( imask, 1 );
    1612             :     }
    1613      495184 :     nb_bits_written = add( nb_bits_written, ind_list[i].nb_bits );
    1614             : 
    1615             :     /* delete the indice */
    1616      495184 :     ind_list[i].nb_bits = -1;
    1617      495184 :     move16();
    1618             : }
    1619             : }
    1620             : 
    1621       22096 : *pFrame_size = add( *pFrame_size, nb_bits_written );
    1622       22096 : move16();
    1623             : 
    1624             : /* update list of indices */
    1625       22096 : hBstr->nb_ind_tot = sub( hBstr->nb_ind_tot, bsBits );
    1626       22096 : hBstr->nb_bits_tot = sub( hBstr->nb_bits_tot, nb_bits_written );
    1627             : 
    1628       22096 : return;
    1629             : }
    1630             : /**********************************************************************/    /*
    1631             :    IGF reset bitsream bit counter for TCX10 modes
    1632             :    **************************************************************************/
    1633       11048 : void IGFEncResetTCX10BitCounter_fx( const IGF_ENC_INSTANCE_HANDLE hInstance /**< in:     | instance handle of IGF Encoder */
    1634             : )
    1635             : {
    1636             :     IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData;
    1637             : 
    1638       11048 :     hPrivateData = &hInstance->igfData;
    1639       11048 :     hPrivateData->igfBitstreamBits = 0;
    1640       11048 :     move16();
    1641       11048 :     hInstance->infoTotalBitsWritten = 0;
    1642       11048 :     move16();
    1643             : 
    1644       11048 :     return;
    1645             : }
    1646             : 
    1647             : /**********************************************************************/             /*
    1648             :             IGF write concatenated bitsream for TCX10 modes
    1649             :             **************************************************************************/
    1650           0 : Word16 IGFEncWriteConcatenatedBitstream_fx(                                          /**< out: Q0 | total number of bits written   */
    1651             :                                             const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in:     | instance handle of IGF Encoder */
    1652             :                                             BSTR_ENC_HANDLE hBstr                    /* i/o: encoder bitstream handle       */
    1653             : )
    1654             : {
    1655             :     IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData;
    1656             :     Word16 i;
    1657             :     Word16 tmp;
    1658             :     Word16 bitsLeft;
    1659             :     UWord8 *pBitstream;
    1660             : 
    1661           0 :     hPrivateData = &hInstance->igfData;
    1662           0 :     pBitstream = &hPrivateData->igfBitstream[0];
    1663             : 
    1664           0 :     tmp = shr( hPrivateData->igfBitstreamBits, 3 );
    1665           0 :     FOR( i = 0; i < tmp; i++ )
    1666             :     {
    1667           0 :         push_next_indice( hBstr, pBitstream[i], 8 );
    1668             :     }
    1669             : 
    1670           0 :     bitsLeft = s_and( hPrivateData->igfBitstreamBits, 0x7 );
    1671           0 :     IF( bitsLeft > 0 )
    1672             :     {
    1673           0 :         push_next_indice( hBstr, shr( pBitstream[i], sub( 8, bitsLeft ) ), bitsLeft );
    1674             :     }
    1675             : 
    1676           0 :     return hInstance->infoTotalBitsWritten;
    1677             : }
    1678       11048 : Word16 IGFEncWriteConcatenatedBitstream_ivas_fx(                                          /**< out: Q0 | total number of bits written   */
    1679             :                                                  const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in:     | instance handle of IGF Encoder */
    1680             :                                                  BSTR_ENC_HANDLE hBstr                    /* i/o: encoder bitstream handle       */
    1681             : )
    1682             : {
    1683             :     IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData;
    1684             :     Word16 i;
    1685             :     Word16 tmp;
    1686             :     Word16 bitsLeft;
    1687             :     UWord8 *pBitstream;
    1688             : 
    1689       11048 :     hPrivateData = &hInstance->igfData;
    1690       11048 :     pBitstream = &hPrivateData->igfBitstream[0];
    1691             : 
    1692       11048 :     tmp = shr( hPrivateData->igfBitstreamBits, 3 );
    1693       68122 :     FOR( i = 0; i < tmp; i++ )
    1694             :     {
    1695       57074 :         push_next_indice( hBstr, pBitstream[i], 8 );
    1696             :     }
    1697             : 
    1698       11048 :     bitsLeft = s_and( hPrivateData->igfBitstreamBits, 0x7 );
    1699       11048 :     IF( bitsLeft > 0 )
    1700             :     {
    1701        9816 :         push_next_indice( hBstr, shr( pBitstream[i], sub( 8, bitsLeft ) ), bitsLeft );
    1702             :     }
    1703             : 
    1704       11048 :     return hInstance->infoTotalBitsWritten;
    1705             : }
    1706             : 
    1707             : /**********************************************************************/ /*
    1708             : apply the IGF encoder, main encoder interface
    1709             : **************************************************************************/
    1710         637 : void IGFEncApplyMono_fx( const IGF_ENC_INSTANCE_HANDLE hInstance,        /**< in:     | instance handle of IGF Encoder                         */
    1711             :                          const Word16 igfGridIdx,                        /**< in: Q0  | IGF grid index                                         */
    1712             :                          Encoder_State *st,                              /**< in:     | Encoder state                                          */
    1713             :                          Word32 *pMDCTSpectrum,                          /**< in: Q31 | MDCT spectrum                                          */
    1714             :                          Word16 MDCTSpectrum_e,                          /**< in:     | exponent of MDCT spectrum                              */
    1715             :                          Word32 *pPowerSpectrum,                         /**< in: Q31 | MDCT^2 + MDST^2 spectrum, or estimate                  */
    1716             :                          Word16 PowerSpectrum_e,                         /**< in:     | exponent of pPowerSpectrum                             */
    1717             :                          Word16 isTCX20,                                 /**< in: Q0  | flag indicating if the input is TCX20 or TCX10/2xTCX5  */
    1718             :                          Word16 isTNSActive,                             /**< in: Q0  | flag indicating if the TNS is active                   */
    1719             :                          Word16 last_core_acelp                          /**< in: Q0  | indicator if last frame was acelp coded                */
    1720             : )
    1721             : {
    1722             :     Word32 *pPowerSpectrumParameter;          /* If it is NULL it informs a function that specific handling is needed */
    1723             :     Word32 *pPowerSpectrumParameterWhitening; /* If it is NULL it informs a function that specific handling is needed */
    1724             :     Word16 highPassEner_exp;                  /*exponent of highpass energy - maybe not needed*/
    1725             : 
    1726             : 
    1727         637 :     pPowerSpectrumParameter = NULL;
    1728         637 :     test();
    1729         637 :     if ( ( isTNSActive == 0 ) && ( isTCX20 != 0 ) )
    1730             :     {
    1731         633 :         pPowerSpectrumParameter = pPowerSpectrum;
    1732             :     }
    1733         637 :     pPowerSpectrumParameterWhitening = NULL;
    1734         637 :     if ( isTCX20 != 0 )
    1735             :     {
    1736         637 :         pPowerSpectrumParameterWhitening = pPowerSpectrum;
    1737             :     }
    1738             : 
    1739         637 :     IGF_UpdateInfo( hInstance,    /* i: instance handle of IGF Encoder            */
    1740             :                     igfGridIdx ); /* i: IGF grid index                            */
    1741             : 
    1742         637 :     IGF_CalculateEnvelope( hInstance,               /* i: instance handle of IGF Encoder            */
    1743             :                            pMDCTSpectrum,           /* i: MDCT spectrum                             */
    1744             :                            MDCTSpectrum_e,          /* i: exponent of MDCT spectrum                 */
    1745             :                            pPowerSpectrumParameter, /* i: MDCT^2 + MDST^2 spectrum, or estimate     */
    1746             :                            PowerSpectrum_e,         /* i: exponent of pPowerSpectrum                */
    1747             :                            igfGridIdx               /* i: IGF grid index                            */
    1748             :     );
    1749             : 
    1750             : 
    1751         637 :     IGF_Whitening( hInstance,                        /* i: instance handle of IGF Encoder            */
    1752             :                    pPowerSpectrumParameterWhitening, /* i: MDCT^2 + MDST^2 spectrum, or estimate     */
    1753             :                    PowerSpectrum_e,                  /* i: exponent of powerSpectrum                 */
    1754             :                    igfGridIdx,                       /* i: IGF grid index                            */
    1755         637 :                    ( st->transientDetection.transientDetector.bIsAttackPresent == 1 ),
    1756             :                    last_core_acelp ); /* i: last frame was acelp indicator            */
    1757             : 
    1758         637 :     pPowerSpectrumParameter = NULL;
    1759         637 :     if ( isTCX20 != 0 )
    1760             :     {
    1761         637 :         pPowerSpectrumParameter = pPowerSpectrum;
    1762             :     }
    1763             : 
    1764         637 :     IGF_ErodeSpectrum(                          /* o: highpass energy                           */
    1765             :                        &highPassEner_exp,       /* o: exponent of highPassEner                  */
    1766             :                        hInstance,               /* i: instance handle of IGF Encoder            */
    1767             :                        pMDCTSpectrum,           /* i: MDCT spectrum                             */
    1768             :                        pPowerSpectrumParameter, /* i: MDCT^2 + MDST^2 spectrum, or estimate     */
    1769             :                        PowerSpectrum_e,         /* i: exponent of pPowerSpectrum                */
    1770             :                        igfGridIdx );            /* i: IGF grid index                            */
    1771         637 : }
    1772             : 
    1773             : 
    1774       13357 : ivas_error IGF_Reconfig_fx(
    1775             :     IGF_ENC_INSTANCE_HANDLE *hIGFEnc, /* i/o: instance handle of IGF Encoder  */
    1776             :     const Word16 igf,                 /* i  : IGF on/off                      */
    1777             :     const Word16 reset,               /* i  : reset flag                      */
    1778             :     const Word32 brate,               /* i  : bitrate for configuration       */
    1779             :     const Word16 bwidth,              /* i  : signal bandwidth                */
    1780             :     const Word16 element_mode,        /* i  : IVAS element mode               */
    1781             :     const Word16 rf_mode              /* i  : flag to signal the RF mode      */
    1782             : )
    1783             : {
    1784             :     ivas_error error;
    1785             : 
    1786       13357 :     error = IVAS_ERR_OK;
    1787       13357 :     move32();
    1788             : 
    1789       13357 :     test();
    1790       13357 :     test();
    1791       13357 :     test();
    1792       13357 :     IF( igf && *hIGFEnc == NULL )
    1793             :     {
    1794         831 :         IF( ( *hIGFEnc = (IGF_ENC_INSTANCE_HANDLE) malloc( sizeof( IGF_ENC_INSTANCE ) ) ) == NULL )
    1795             :         {
    1796           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for hIGFEnc\n" ) );
    1797             :         }
    1798         831 :         IGFEncSetMode_ivas_fx( *hIGFEnc, brate, bwidth, element_mode, rf_mode );
    1799             :     }
    1800       12526 :     ELSE IF( igf && reset )
    1801             :     {
    1802           0 :         IGFEncSetMode_ivas_fx( *hIGFEnc, brate, bwidth, element_mode, rf_mode );
    1803             :     }
    1804       12526 :     ELSE IF( !igf && *hIGFEnc != NULL )
    1805             :     {
    1806        1018 :         free( *hIGFEnc );
    1807        1018 :         *hIGFEnc = NULL;
    1808             :     }
    1809             : 
    1810       13357 :     return error;
    1811             : }

Generated by: LCOV version 1.14