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 @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 674 757 89.0 %
Date: 2025-05-03 01:55:50 Functions: 22 23 95.7 %

          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        7466 : 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        7466 :     IGFCommonFuncsWriteSerialBit( hBstr, bitCount, bit );
      26        7466 : }
      27             : 
      28             : /**********************************************************************/ /*
      29             : write bits to stream
      30             : **************************************************************************/
      31        6142 : 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       12284 :     WHILE( bits )
      41             :     {
      42        6142 :         bits = sub( bits, 1 );
      43        6142 :         tmp = s_and( value, shl( 1, bits ) );
      44        6142 :         IF( tmp == 0 )
      45             :         {
      46        2104 :             IGF_write_bit_fx( hBstr, bitCount, 0 );
      47             :         }
      48             :         ELSE
      49             :         {
      50        4038 :             IGF_write_bit_fx( hBstr, bitCount, 1 );
      51             :         }
      52             :     }
      53             : 
      54        6142 :     return;
      55             : }
      56             : 
      57             : 
      58             : /**********************************************************************/    /*
      59             :    envelope estimation
      60             :    **************************************************************************/
      61         662 : 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         662 :     Flag Overflow = 0;
      98         662 :     move32();
      99             : #endif
     100             : 
     101             :     /* initialize variables */
     102         662 :     Copy32( pMDCTSpectrum + IGF_START_MN, hInstance->spec_be_igf, hInstance->infoStopLine - IGF_START_MN );
     103         662 :     hPrivateData = &hInstance->igfData;
     104         662 :     hGrid = &hPrivateData->igfInfo.grid[igfGridIdx];
     105         662 :     swb_offset = hGrid->swb_offset;
     106         662 :     move16();
     107         662 :     hInstance->spec_be_igf_e = MDCTSpectrum_e;
     108         662 :     move16();
     109         662 :     zeroNrg = 0;
     110         662 :     move16();
     111             : 
     112             : 
     113         662 :     IF( pPowerSpectrum != NULL )
     114             :     {
     115        2372 :         FOR( tile_idx = 0; tile_idx < hGrid->nTiles; tile_idx++ )
     116             :         {
     117        1714 :             strt_cpy = hGrid->sbWrap[tile_idx];
     118        1714 :             move16();
     119        6458 :             FOR( sfb = hGrid->sfbWrap[tile_idx]; sfb < hGrid->sfbWrap[tile_idx + 1]; sfb++ )
     120             :             {
     121      241686 :                 FOR( tb = swb_offset[sfb]; tb < swb_offset[sfb + 1]; tb++ )
     122             :                 {
     123      236942 :                     LFMDCTSpectrum[tb] = pMDCTSpectrum[strt_cpy];
     124      236942 :                     move32();
     125      236942 :                     LFPowerSpectrum[tb] = pPowerSpectrum[strt_cpy];
     126      236942 :                     move32();
     127      236942 :                     strt_cpy = add( strt_cpy, 1 );
     128             :                 }
     129             :             }
     130             :         }
     131         658 :         IGFCommonFuncsCalcSfbEnergyPowerSpec( hGrid->startSfb,
     132         658 :                                               hGrid->stopSfb,
     133         658 :                                               hGrid->swb_offset,
     134             :                                               pPowerSpectrum,
     135             :                                               &PowerSpectrum_e,
     136             :                                               sfbEnergyC,
     137             :                                               sfbEnergyC_exp );
     138         658 :         IGFCommonFuncsCalcSfbEnergyPowerSpec( hGrid->startSfb,
     139         658 :                                               hGrid->stopSfb,
     140         658 :                                               hGrid->swb_offset,
     141             :                                               LFPowerSpectrum,
     142             :                                               &PowerSpectrum_e,
     143             :                                               sfbEnergyTileC,
     144             :                                               sfbEnergyTileC_exp );
     145         658 :         IGFCommonFuncsMDCTSquareSpec( hGrid->startLine,
     146         658 :                                       hGrid->stopLine,
     147             :                                       LFMDCTSpectrum,
     148             :                                       MDCTSpectrum_e,
     149             :                                       LFMDCTSpectrum,
     150             :                                       &LFMDCTSpectrum_exp,
     151             :                                       0 );
     152         658 :         IGFCommonFuncsCalcSfbEnergyPowerSpec( hGrid->startSfb,
     153         658 :                                               hGrid->stopSfb,
     154         658 :                                               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        2388 :     FOR( tile_idx = 0; tile_idx < hGrid->nTiles; tile_idx++ )
     179             :     {
     180             : 
     181        6502 :         FOR( sfb = hGrid->sfbWrap[tile_idx]; sfb < hGrid->sfbWrap[tile_idx + 1]; sfb++ )
     182             :         {
     183             : 
     184             : 
     185        4776 :             width = sub( swb_offset[sfb + 1], swb_offset[sfb] );
     186        4776 :             L_tmp = 0;
     187        4776 :             move16();
     188        4776 :             gain_exp = 0;
     189        4776 :             move16();
     190             : 
     191        4776 :             IF( pPowerSpectrum )
     192             :             {
     193        4744 :                 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        4744 :                 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        4744 :                 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        4744 :                 BASOP_Util_Divide_MantExp( round_fx_o( sfbEnergyTileR[sfb], &Overflow ), sfbEnergyTileR_exp[sfb], width, 15, &gain, &gain_exp );
     222        4744 :                 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        4744 :                 L_tmp = L_mult( gain, tmp );
     224        4744 :                 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        4776 :             L_tmp = BASOP_Util_Log2( L_tmp );
     248        4776 :             L_tmp = L_add( L_tmp, L_deposit_h( shl( gain_exp, 15 - 6 ) ) );
     249        4776 :             shift = norm_l( L_tmp );
     250        4776 :             gain = round_fx_o( L_shl_o( L_tmp, shift, &Overflow ), &Overflow );
     251        4776 :             gain_exp = sub( 7, shift );
     252        4776 :             gain_exp = BASOP_Util_Add_MantExp( gain, gain_exp, 32767 /*16 Q11*/, 4, &gain );
     253        4776 :             gain_exp = BASOP_Util_Add_MantExp( gain, gain_exp, 0x4000, 0, &gain );
     254        4776 :             gain = shr( gain, s_min( sub( 15, gain_exp ), 15 ) );
     255             : 
     256        4776 :             if ( gain > 91 )
     257             :             {
     258           0 :                 gain = s_min( gain, 91 ); /* 13+15+63, see arithocde encode residual */
     259             :             }
     260        4776 :             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        4776 :             if ( zeroNrg != 0 )
     267             :             {
     268           0 :                 gain = 0;
     269           0 :                 move16();
     270             :             }
     271             : 
     272        4776 :             hPrivateData->igfScfQuantized[sfb] = gain;
     273        4776 :             move16();
     274             :         }
     275             :     }
     276             : 
     277         662 :     return;
     278             : }
     279             : 
     280             : /**********************************************************************/ /*
     281             : writes IGF SCF values
     282             : **************************************************************************/
     283        1324 : 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        1324 :     *igfAllZero = 1;
     297        1324 :     move16();
     298        1324 :     hPrivateData = &hInstance->igfData;
     299        1324 :     hGrid = &hPrivateData->igfInfo.grid[igfGridIdx];
     300             : 
     301        1324 :     FOR( sfb = hGrid->startSfb; sfb < hGrid->stopSfb; sfb++ )
     302             :     {
     303        1324 :         IF( hPrivateData->igfScfQuantized[sfb] != 0 )
     304             :         {
     305        1324 :             *igfAllZero = 0;
     306        1324 :             move16();
     307        1324 :             BREAK;
     308             :         }
     309             :     }
     310             : 
     311        1324 :     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        1324 :         IGF_write_bit_fx( hBstr, pBitOffset, 0 );
     327        1324 :         if ( NULL == hBstr )
     328             :         {
     329         662 :             IGFSCFEncoderSaveContextState_fx( &hPrivateData->hIGFSCFArithEnc, igfGridIdx );
     330             :         }
     331             : 
     332        1324 :         *pBitOffset = IGFSCFEncoderEncode_fx( &hPrivateData->hIGFSCFArithEnc, hBstr, *pBitOffset, &hPrivateData->igfScfQuantized[hGrid->startSfb], igfGridIdx, isIndepFlag );
     333        1324 :         move16();
     334             : 
     335        1324 :         if ( NULL == hBstr )
     336             :         {
     337         662 :             IGFSCFEncoderRestoreContextState_fx( &hPrivateData->hIGFSCFArithEnc, igfGridIdx );
     338             :         }
     339             :     }
     340        1324 : }
     341             : 
     342             : /**********************************************************************/ /*
     343             : identifies significant spectral content
     344             : **************************************************************************/
     345         662 : 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         662 :     Flag Overflow = 0;
     377         662 :     Flag Carry = 0;
     378         662 :     move32();
     379         662 :     move32();
     380             : #endif
     381             : 
     382         662 :     hPrivateData = &hInstance->igfData;
     383         662 :     hGrid = &hPrivateData->igfInfo.grid[igfGridIdx];
     384         662 :     igfBgn = hGrid->startLine;
     385         662 :     move16();
     386         662 :     igfEnd = hGrid->stopLine;
     387         662 :     move16();
     388         662 :     swb_offset = hGrid->swb_offset;
     389         662 :     move16();
     390         662 :     startSfb = hGrid->startSfb;
     391         662 :     move16();
     392         662 :     stopSfb = hGrid->stopSfb;
     393         662 :     move16();
     394         662 :     igfScaleF = hPrivateData->igfScfQuantized;
     395         662 :     move16();
     396         662 :     *highPassEner_exp = 0;
     397         662 :     move16();
     398         662 :     highPassEner = 0;
     399         662 :     move32();
     400             : 
     401         662 :     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         662 :     IF( igfBgn > 0 )
     411             :     {
     412         662 :         L_c = 0;
     413         662 :         move32();
     414      172630 :         FOR( i = 0; i < igfBgn; i++ )
     415             :         {
     416      171968 :             Carry = 0;
     417      171968 :             move32();
     418      171968 :             highPassEner = L_add_co( highPassEner, Mpy_32_16_1( pPowerSpectrum[i], shl( i, 4 ) /*Q4*/ ) /*Q20, pPowerSpectrum_exp*/, &Carry, &Overflow );
     419      171968 :             Overflow = 0;
     420      171968 :             move32();
     421      171968 :             L_c = L_macNs_co( L_c, 0, 0, &Carry, &Overflow );
     422             :         }
     423             : 
     424         662 :         highPassEner = norm_llQ31( L_c, highPassEner, highPassEner_exp ); /*Q20, highPassEner_exp*/
     425         662 :         *highPassEner_exp = add( *highPassEner_exp, pPowerSpectrum_exp );
     426         662 :         move16();
     427         662 :         test();
     428         662 :         test();
     429        1324 :         if ( NE_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_9600 ) &&
     430        1324 :              NE_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_RF_SWB_13200 ) &&
     431         662 :              NE_16( hPrivateData->igfInfo.bitRateIndex, IGF_BITRATE_SWB_13200 ) )
     432             :         {
     433         402 :             igfBgn = shl( igfBgn, 1 );
     434             :         }
     435         662 :         highPassEner = L_deposit_l( BASOP_Util_Divide3216_Scale( highPassEner /*Q20, highPassEner_exp*/, igfBgn /*Q0*/, &s ) ); /*Q15, highPassEner_exp+11-16+s*/
     436         662 :         *highPassEner_exp = add( add( *highPassEner_exp, s ), 12 - 16 + ( 31 - 15 ) );                                          /*Q15->Q31,highPassEner_exp*/
     437         662 :         lastLine = pSpectrum[i - 1];
     438         662 :         move32();
     439         662 :         nextLine = 0;
     440         662 :         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         662 :         highPassEner_Ovfl = L_shl_o( L_negate( highPassEner ), sub( *highPassEner_exp, pPowerSpectrum_exp ), &Overflow );
     446         662 :         L_tmp = L_add_o( pPowerSpectrum[i - 1], highPassEner_Ovfl, &Overflow );
     447             : 
     448         662 :         if ( L_tmp >= 0 )
     449             :         {
     450           0 :             nextLine = pSpectrum[i];
     451           0 :             move32();
     452             :         }
     453         662 :         tmploop = sub( igfEnd, 1 );
     454      238478 :         FOR( /*i*/; i < tmploop; i++ )
     455             :         {
     456             :             /* May overflow - just for threshold comparison */
     457             :             BASOP_SATURATE_WARNING_OFF_EVS
     458      237816 :             L_tmp = L_add_sat( pPowerSpectrum[i], highPassEner_Ovfl );
     459             :             BASOP_SATURATE_WARNING_ON_EVS;
     460             : 
     461      237816 :             IF( L_tmp < 0 )
     462             :             {
     463      237780 :                 lastLine = pSpectrum[i];
     464      237780 :                 move32();
     465      237780 :                 pSpectrum[i] = nextLine;
     466      237780 :                 move32();
     467      237780 :                 nextLine = 0;
     468      237780 :                 move32();
     469             :             }
     470             :             ELSE
     471             :             {
     472          36 :                 pSpectrum[i - 1] = lastLine;
     473          36 :                 move32();
     474          36 :                 lastLine = pSpectrum[i];
     475          36 :                 move32();
     476          36 :                 nextLine = pSpectrum[i + 1];
     477          36 :                 move32();
     478             :             }
     479             :         }
     480             : 
     481             :         /* May overflow - just for threshold comparison */
     482             :         BASOP_SATURATE_WARNING_OFF_EVS
     483         662 :         L_tmp = L_add_sat( pPowerSpectrum[i], highPassEner_Ovfl );
     484             :         BASOP_SATURATE_WARNING_ON_EVS
     485         662 :         if ( L_tmp < 0 )
     486             :         {
     487         662 :             pSpectrum[i] = L_deposit_l( 0 );
     488         662 :             move32();
     489             :         }
     490             :     }
     491             : 
     492             :     /* delete spectrum above igfEnd: */
     493       20136 :     FOR( i = igfEnd; i < hGrid->infoGranuleLen; i++ )
     494             :     {
     495       19474 :         pSpectrum[i] = L_deposit_l( 0 );
     496       19474 :         move32();
     497       19474 :         pPowerSpectrum[i] = L_deposit_l( 0 );
     498       19474 :         move32();
     499             :     }
     500             : 
     501        5438 :     FOR( sfb = startSfb; sfb < stopSfb; sfb++ )
     502             :     {
     503        4776 :         flag = 0;
     504        4776 :         move16();
     505      243254 :         FOR( line = swb_offset[sfb]; line < swb_offset[sfb + 1]; line++ )
     506             :         {
     507      238478 :             if ( pSpectrum[line] != 0 )
     508             :             {
     509          74 :                 flag = 1;
     510          74 :                 move16();
     511             :             }
     512             :         }
     513        4776 :         tmp = igfScaleF[sfb];
     514        4776 :         move16();
     515        4776 :         if ( flag )
     516             :         {
     517          11 :             tmp = sub( igfScaleF[sfb], 1 );
     518             :         }
     519        4776 :         if ( igfScaleF[sfb] )
     520             :         {
     521        4776 :             igfScaleF[sfb] = tmp;
     522        4776 :             move16();
     523             :         }
     524             :     }
     525             : }
     526             : 
     527      591988 : 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      591988 :     hPrivateData = &hInstance->igfData;
     555      591988 :     hGrid = &hPrivateData->igfInfo.grid[igfGridIdx];
     556      591988 :     igfBgn = hGrid->startLine;
     557      591988 :     move16();
     558      591988 :     igfEnd = hGrid->stopLine;
     559      591988 :     move16();
     560      591988 :     swb_offset = hGrid->swb_offset;
     561      591988 :     move16();
     562      591988 :     startSfb = hGrid->startSfb;
     563      591988 :     move16();
     564      591988 :     stopSfb = hGrid->stopSfb;
     565      591988 :     move16();
     566      591988 :     igfScaleF = hPrivateData->igfScfQuantized;
     567      591988 :     move16();
     568             : 
     569      591988 :     IF( NULL == pPowerSpectrum )
     570             :     {
     571     4473324 :         FOR( i = igfBgn; i < hGrid->infoGranuleLen; i++ )
     572             :         {
     573     4451240 :             pSpectrum[i] = 0;
     574     4451240 :             move32();
     575             :         }
     576       22084 :         return;
     577             :     }
     578             : 
     579      569904 :     IF( igfBgn > 0 )
     580             :     {
     581      569904 :         Word64 sum = 0;
     582      569904 :         move64();
     583   258979648 :         FOR( i = 0; i < igfBgn; i++ )
     584             :         {
     585   258409744 :             sum = W_mac_32_16( sum, pPowerSpectrum[i], i ); // Q: 31-pPowerSpectrum_exp+1
     586             :         }
     587      569904 :         exp1 = W_norm( sum );
     588      569904 :         sum = W_shl( sum, sub( exp1, 1 ) );                // Q: 31-pPowerSpectrum_exp+1+exp1-1
     589      569904 :         num = extract_h( W_extract_h( sum ) );             // Q: 31-pPowerSpectrum_exp+exp1-48 = -pPowerSpectrum_exp+exp1-17
     590      569904 :         exp1 = add( 32, sub( pPowerSpectrum_exp, exp1 ) ); // exp: 32+pPowerSpectrum_exp-exp1
     591             : 
     592      569904 :         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       27307 :             factor = ONE_IN_Q14; // Q14
     598       27307 :             move16();
     599             :         }
     600      542597 :         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        3906 :             factor = 11469; // 0.7f in Q14
     603        3906 :             move16();
     604             :         }
     605             :         ELSE
     606             :         {
     607      538691 :             factor = 32767; // 2.f in Q14
     608      538691 :             move16();
     609             :         }
     610             : 
     611      569904 :         temp = L_mult( igfBgn, factor ); // exp: 16
     612      569904 :         exp2 = norm_l( temp );
     613      569904 :         den = extract_h( L_shl( temp, exp2 ) ); // exp: 16-exp2
     614      569904 :         exp2 = sub( 16, exp2 );
     615             : 
     616      569904 :         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      569904 :         highPassEner = L_shl_sat( highPassEner, sub( sub( exp1, exp2 ), pPowerSpectrum_exp ) ); // exp: pPowerSpectrum_exp
     620             : 
     621      569904 :         lastLine = pSpectrum[i - 1]; // Qx
     622      569904 :         move32();
     623      569904 :         nextLine = pSpectrum[i]; // Qx
     624      569904 :         move32();
     625             : 
     626      569904 :         if ( LT_32( pPowerSpectrum[i - 1], highPassEner ) )
     627             :         {
     628      569761 :             nextLine = 0;
     629      569761 :             move32();
     630             :         }
     631             : 
     632   168832992 :         FOR( /*i*/; i < igfEnd - 1; i++ )
     633             :         {
     634             :             /* May overflow - just for threshold comparison */
     635   168263088 :             IF( LT_32( pPowerSpectrum[i], highPassEner ) )
     636             :             {
     637   168210255 :                 lastLine = pSpectrum[i]; // Qx
     638   168210255 :                 move32();
     639   168210255 :                 pSpectrum[i] = nextLine; // Qx
     640   168210255 :                 move32();
     641   168210255 :                 nextLine = 0;
     642   168210255 :                 move32();
     643             :             }
     644             :             ELSE
     645             :             {
     646       52833 :                 pSpectrum[i - 1] = lastLine; // Qx
     647       52833 :                 move32();
     648       52833 :                 lastLine = pSpectrum[i]; // Qx
     649       52833 :                 move32();
     650       52833 :                 nextLine = pSpectrum[i + 1]; // Qx
     651       52833 :                 move32();
     652             :             }
     653             :         }
     654             : 
     655             :         /* May overflow - just for threshold comparison */
     656      569904 :         if ( LT_32( pPowerSpectrum[i], highPassEner ) )
     657             :         {
     658      569758 :             pSpectrum[i] = 0;
     659      569758 :             move32();
     660             :         }
     661             :     }
     662             : 
     663             :     /* delete spectrum above igfEnd: */
     664    68401568 :     FOR( i = igfEnd; i < hGrid->infoGranuleLen; i++ )
     665             :     {
     666    67831664 :         pSpectrum[i] = 0;
     667    67831664 :         pPowerSpectrum[i] = 0;
     668    67831664 :         move32();
     669    67831664 :         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     3563931 :         FOR( sfb = startSfb; sfb < stopSfb; sfb++ )
     676             :         {
     677     2994027 :             tmp = 0;
     678     2994027 :             move16();
     679   171827019 :             FOR( line = swb_offset[sfb]; line < swb_offset[sfb + 1]; line++ )
     680             :             {
     681   168832992 :                 if ( pSpectrum[line] != 0 )
     682             :                 {
     683       15596 :                     tmp = add( tmp, 1 );
     684             :                 }
     685             :             }
     686             : 
     687     2994027 :             Word16 igfScaleF_cnt = igfScaleF[sfb];
     688     2994027 :             move16();
     689     2994027 :             test();
     690     2994027 :             if ( tmp && igfScaleF[sfb] )
     691             :             {
     692        2547 :                 igfScaleF_cnt = sub( igfScaleF[sfb], 1 );
     693             :             }
     694     2994027 :             igfScaleF[sfb] = igfScaleF_cnt;
     695     2994027 :             move16();
     696             :         }
     697             :     }
     698             : }
     699             : 
     700             : /**********************************************************************/ /*
     701             : crest factor calculation
     702             : **************************************************************************/
     703      801841 : 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      801841 :     x_eff32 = 0;
     721      801841 :     move32();
     722      801841 :     x_max = 0;
     723      801841 :     move16();
     724      801841 :     crest = 16384 /*.5f Q15*/;
     725      801841 :     move16();
     726      801841 :     *crest_exp = 1;
     727      801841 :     move16();
     728             : 
     729    42857197 :     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    42055356 :         x = sub( sub( powerSpectrum_exp, norm_l( powerSpectrum[i] ) ), 1 ); /*Q0*/
     735    42055356 :         if ( powerSpectrum[i] == 0 )                                        /*special case: energy is zero*/
     736             :         {
     737        1236 :             x = 0;
     738        1236 :             move16();
     739             :         }
     740    42055356 :         x = s_max( 0, x );
     741    42055356 :         x_eff32 = L_mac0( x_eff32, x, x ); /*Q0*/
     742    42055356 :         x_max = s_max( x_max, x );         /*Q0*/
     743             :     }
     744             : 
     745             :     /*x_eff /= (stop - start);*/
     746      801841 :     x_eff32 = BASOP_Util_Divide3216_Scale( x_eff32, sub( stop, start ), &s ); /*Q-1, s*/
     747      801841 :     s = add( s, 32 );                                                         /*make x_eff Q31*/
     748             : 
     749             :     /*trunkate to int*/
     750      801841 :     x_eff32 = L_shr( x_eff32, sub( 31, s ) );
     751      801841 :     x_eff32 = L_shl( x_eff32, sub( 31, s ) );
     752             : 
     753      801841 :     test();
     754      801841 :     IF( x_eff32 > 0 && x_max > 0 )
     755             :     {
     756             :         /*crest = max(1.f, (float)x_max/sqrt(x_eff));*/
     757      738382 :         tmp32 = ISqrt32( x_eff32, &s );                        /*Q31, s*/
     758      738382 :         tmp32 = Mpy_32_16_1( tmp32 /*Q31, s*/, x_max /*Q0*/ ); /*Q16, s*/
     759      738382 :         i = norm_l( tmp32 );
     760      738382 :         tmp32 = L_shl( tmp32, i ); /*Q31, s-i+15*/
     761      738382 :         crest = extract_h( tmp32 );
     762      738382 :         *crest_exp = add( sub( s, i ), 15 );
     763      738382 :         move16();
     764             :         /* limit crest factor to a lower bound of 1, may overflow */
     765             :         BASOP_SATURATE_WARNING_OFF_EVS
     766      738382 :         tmp = shl_sat( -1, sub( 15, *crest_exp ) ); /* build negative threshold */
     767      738382 :         tmp = add_sat( crest, tmp );
     768             :         BASOP_SATURATE_WARNING_ON_EVS
     769      738382 :         if ( tmp < 0 )
     770             :         {
     771           0 :             crest = 1;
     772           0 :             move16();
     773             :         }
     774      738382 :         if ( tmp < 0 )
     775             :         {
     776           0 :             *crest_exp = 15;
     777           0 :             move16();
     778             :         }
     779             :     }
     780             : 
     781      801841 :     return crest;
     782             : }
     783             : 
     784             : /*************************************************************************
     785             : calculates spectral flatness measurment
     786             : **************************************************************************/
     787        1282 : Word16 IGF_getSFM(                           /**< out: Q15| SFM value              */
     788             :                    Word16 *SFM_exp,          /**< out:    | exponent of SFM Factor */
     789             :                    const Word32 *energy,     /**< in:  Q31| energies               */
     790             :                    const Word16 *energy_exp, /**< in:     | exponent of energies   */
     791             :                    const Word16 start,       /**< in:  Q0 | start subband index    */
     792             :                    const Word16 stop         /**< in:  Q0 | stop subband index     */
     793             : )
     794             : {
     795             :     Word16 n, i, s;
     796             :     Word32 num;
     797             :     Word32 denom;
     798             :     Word16 denom_exp;
     799             :     Word16 invDenom_exp, numf_exp;
     800             :     Word16 numf;
     801             :     Word32 SFM32;
     802             :     Word32 L_c;
     803             :     Word16 invDenom, SFM;
     804             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     805        1282 :     Flag Overflow = 0;
     806        1282 :     Flag Carry = 0;
     807        1282 :     move32();
     808        1282 :     move32();
     809             : #endif
     810             : 
     811        1282 :     L_c = 0;
     812        1282 :     move32();
     813        1282 :     num = 0;
     814        1282 :     move32();
     815        1282 :     denom = L_shr( 2147483 /*0,001 in Q31 - float is "1", here*/, s_min( *energy_exp, 31 ) );
     816        1282 :     denom = L_max( denom, 1 );
     817        1282 :     *SFM_exp = 0;
     818        1282 :     move16();
     819        1282 :     SFM = 32767 /*1.0f Q15*/;
     820        1282 :     move16();
     821             : 
     822      207086 :     FOR( i = start; i < stop; i++ )
     823             :     {
     824             :         /*ln(x * 2^-Qx * 2^xExp) = ln(x) - Qx + xExp*/
     825             : 
     826             :         /* n       = sub(sub(31,norm_l(tmp32)),1);  */ /*<- ld    */
     827             :         /* n       = sub(n,31);                     */ /*<- -Qx   */
     828             :         /* n       = add(n,*energy_exp);            */ /*<- +xExp */
     829             : 
     830      205804 :         n = sub( sub( *energy_exp, norm_l( energy[i] ) ), 1 ); /*<-- short form*/
     831             : 
     832      205804 :         if ( energy[i] == 0 ) /*special case: energy is zero*/
     833             :         {
     834         562 :             n = 0;
     835         562 :             move16();
     836             :         }
     837             : 
     838      205804 :         n = s_max( 0, n );
     839      205804 :         num = L_add( num, L_deposit_l( n ) ); /*Q0*/
     840             : 
     841      205804 :         Carry = 0;
     842      205804 :         move32();
     843      205804 :         denom = L_add_co( energy[i], denom, &Carry, &Overflow );
     844      205804 :         Overflow = 0;
     845      205804 :         move32();
     846      205804 :         L_c = L_macNs_co( L_c, 0, 0, &Carry, &Overflow );
     847             :     }
     848             : 
     849        1282 :     denom = norm_llQ31( L_c, denom, &denom_exp ); /*Q31*/
     850        1282 :     denom_exp = add( denom_exp, *energy_exp );
     851             : 
     852             :     /* calculate SFM only if signal is present */
     853        1282 :     IF( denom != 0 )
     854             :     {
     855             :         /*numf   = (float)num / (float)(stop - start);*/
     856        1282 :         numf = BASOP_Util_Divide3216_Scale( num,                /*Q0*/
     857        1282 :                                             sub( stop, start ), /*Q0*/
     858             :                                             &s );               /*Q-1 s*/
     859        1282 :         numf_exp = add( s, 16 );                                /*-> numf Q15 numf_exp*/
     860             :         /*denom /= (float)(stop - start);*/
     861             :         /*return ((float)pow(2.0, numf + 0.5f) / denom);*/
     862             : 
     863             :         /*SFM= ((float)pow(2.0, numf + 0.5f) * invDenom);*/
     864        1282 :         invDenom = BASOP_Util_Divide3232_uu_1616_Scale( L_deposit_l( sub( stop, start ) ) /*Q0*/,
     865             :                                                         denom /*Q31, denom_exp*/,
     866             :                                                         &s ); /*Q-16, s-denom_exp*/
     867        1282 :         invDenom_exp = add( sub( s, denom_exp ), 31 );        /*invDenom: Q15, invDenom_exp*/
     868             : 
     869             :         /*add .5f to numf*/
     870        1282 :         SFM32 = L_add( L_shl( L_deposit_l( numf ), numf_exp ) /*16Q15*/, 16384l /*.5f Q15*/ ); /*16Q15*/
     871        1282 :         s = norm_l( SFM32 );
     872        1282 :         SFM32 = L_shl( SFM32, s );
     873        1282 :         s = sub( 16, s ); /*SFM32(numf) is Q31 now*/
     874             : 
     875             :         /*do the pow2 and the mult*/
     876        1282 :         SFM32 = BASOP_util_Pow2( SFM32, s, &s );
     877        1282 :         SFM32 = Mpy_32_16_1( SFM32, invDenom );
     878        1282 :         *SFM_exp = add( s, invDenom_exp );
     879             : 
     880             :         /*Transform to Q15*/
     881        1282 :         s = norm_l( SFM32 );
     882        1282 :         SFM = round_fx_sat( L_shl_sat( SFM32, s ) );
     883        1282 :         *SFM_exp = sub( *SFM_exp, s );
     884        1282 :         move16();
     885             :         /**SFM_exp = s_min(*SFM_exp, 0);*/
     886        1282 :         IF( *SFM_exp > 0 )
     887             :         {
     888         182 :             *SFM_exp = 0;
     889         182 :             move16();
     890         182 :             SFM = 32767 /*1.0f Q15*/;
     891         182 :             move16();
     892             :         }
     893             :     }
     894             : 
     895        1282 :     return SFM /*Q15*/;
     896             : }
     897             : 
     898             : /*************************************************************************
     899             : calculates spectral flatness measurment
     900             : **************************************************************************/
     901      800559 : Word16 IGF_getSFM_ivas_fx(                           /**< out: Q15| SFM value              */
     902             :                            Word16 *SFM_exp,          /**< out:    | exponent of SFM Factor */
     903             :                            const Word32 *energy,     /**< in:  Q31| energies               */
     904             :                            const Word16 *energy_exp, /**< in:     | exponent of energies   */
     905             :                            const Word16 start,       /**< in:  Q0 | start subband index    */
     906             :                            const Word16 stop         /**< in:  Q0 | stop subband index     */
     907             : )
     908             : {
     909             :     Word16 n, i, s;
     910             :     Word32 num;
     911             :     Word32 denom;
     912             :     Word16 denom_exp;
     913             :     Word16 invDenom_exp, numf_exp;
     914             :     Word16 numf;
     915             :     Word32 SFM32;
     916             :     Word16 invDenom, SFM;
     917             : 
     918      800559 :     num = 0;
     919      800559 :     move32();
     920      800559 :     denom = 65536; // 1.f in Q16
     921      800559 :     denom_exp = 15;
     922      800559 :     *SFM_exp = 0;
     923      800559 :     move16();
     924      800559 :     SFM = 32767 /*1.0f Q15*/;
     925      800559 :     move16();
     926             : 
     927    42650111 :     FOR( i = start; i < stop; i++ )
     928             :     {
     929             :         /*ln(x * 2^-Qx * 2^xExp) = ln(x) - Qx + xExp*/
     930             : 
     931             :         /* n       = sub(sub(31,norm_l(tmp32)),1);  */ /*<- ld    */
     932             :         /* n       = sub(n,31);                     */ /*<- -Qx   */
     933             :         /* n       = add(n,*energy_exp);            */ /*<- +xExp */
     934             : 
     935    41849552 :         n = sub( sub( *energy_exp, norm_l( energy[i] ) ), 1 ); /*<-- short form*/
     936             : 
     937    41849552 :         if ( energy[i] == 0 ) /*special case: energy is zero*/
     938             :         {
     939         674 :             n = 0;
     940         674 :             move16();
     941             :         }
     942             : 
     943    41849552 :         n = s_max( 0, n );
     944    41849552 :         num = L_add( num, L_deposit_l( n ) ); /*Q0*/
     945             : 
     946    41849552 :         denom = BASOP_Util_Add_Mant32Exp( energy[i], *energy_exp, denom, denom_exp, &denom_exp );
     947             :     }
     948             : 
     949             :     /* calculate SFM only if signal is present */
     950      800559 :     IF( denom != 0 )
     951             :     {
     952             :         /*numf   = (float)num / (float)(stop - start);*/
     953      800559 :         numf = BASOP_Util_Divide3216_Scale( num,                /*Q0*/
     954      800559 :                                             sub( stop, start ), /*Q0*/
     955             :                                             &s );               /*Q-1 s*/
     956      800559 :         numf_exp = add( s, 16 );                                /*-> numf Q15 numf_exp*/
     957             :         /*denom /= (float)(stop - start);*/
     958             :         /*return ((float)pow(2.0, numf + 0.5f) / denom);*/
     959             : 
     960             :         /*SFM= ((float)pow(2.0, numf + 0.5f) * invDenom);*/
     961      800559 :         invDenom = BASOP_Util_Divide3232_uu_1616_Scale( L_deposit_l( sub( stop, start ) ) /*Q0*/,
     962             :                                                         denom /*Q31, denom_exp*/,
     963             :                                                         &s ); /*Q-16, s-denom_exp*/
     964      800559 :         invDenom_exp = add( sub( s, denom_exp ), 31 );        /*invDenom: Q15, invDenom_exp*/
     965             : 
     966             :         /*add .5f to numf*/
     967      800559 :         SFM32 = L_add( L_shl( L_deposit_l( numf ), numf_exp ) /*16Q15*/, 16384l /*.5f Q15*/ ); /*16Q15*/
     968      800559 :         s = norm_l( SFM32 );
     969      800559 :         SFM32 = L_shl( SFM32, s );
     970      800559 :         s = sub( 16, s ); /*SFM32(numf) is Q31 now*/
     971             : 
     972             :         /*do the pow2 and the mult*/
     973      800559 :         SFM32 = BASOP_util_Pow2( SFM32, s, &s );
     974      800559 :         SFM32 = Mpy_32_16_1( SFM32, invDenom );
     975      800559 :         *SFM_exp = add( s, invDenom_exp );
     976             : 
     977             :         /*Transform to Q15*/
     978      800559 :         s = norm_l( SFM32 );
     979      800559 :         SFM = round_fx_sat( L_shl_sat( SFM32, s ) );
     980      800559 :         *SFM_exp = sub( *SFM_exp, s );
     981      800559 :         move16();
     982             :         /**SFM_exp = s_min(*SFM_exp, 0);*/
     983      800559 :         IF( *SFM_exp > 0 )
     984             :         {
     985       61907 :             *SFM_exp = 0;
     986       61907 :             move16();
     987       61907 :             SFM = 32767 /*1.0f Q15*/;
     988       61907 :             move16();
     989             :         }
     990             :     }
     991             : 
     992      800559 :     return SFM /*Q15*/;
     993             : }
     994             : 
     995             : /**********************************************************************/ /*
     996             : calculates the IGF whitening levels by SFM and crest
     997             : **************************************************************************/
     998         662 : static void IGF_Whitening( const IGF_ENC_INSTANCE_HANDLE hInstance,      /**< in:     | instance handle of IGF Encoder               */
     999             :                            Word32 *powerSpectrum,                        /**< in: Q31 | MDCT/MDST power spectrum                     */
    1000             :                            const Word16 powerSpectrum_exp,               /**< in:     | exponent of powerspectrum                    */
    1001             :                            const Word16 igfGridIdx,                      /**< in: Q0  | IGF grid index                               */
    1002             :                            Word16 isTransient,                           /**< in: Q0  | boolean, indicating if transient is detected */
    1003             :                            Word16 last_core_acelp                        /**< in: Q0  | indictaor if last frame was acelp coded      */
    1004             : )
    1005             : {
    1006             :     IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData;
    1007             :     H_IGF_GRID hGrid;
    1008             :     Word16 p; /*Q0*/
    1009             :     Word16 tmp;
    1010             :     Word16 SFM;
    1011             :     Word16 crest;
    1012             :     Word16 SFM_exp;
    1013             :     Word16 crest_exp;
    1014             :     Word16 s;
    1015             :     Word32 tmp32;
    1016             :     Word32 SFM32;
    1017             : 
    1018         662 :     hPrivateData = &hInstance->igfData;
    1019         662 :     hGrid = &hPrivateData->igfInfo.grid[igfGridIdx];
    1020             : 
    1021         662 :     IF( igfGridIdx != IGF_GRID_LB_NORM )
    1022             :     {
    1023         143 :         FOR( p = 0; p < hGrid->nTiles; p++ )
    1024             :         {
    1025             :             /* reset filter */
    1026         104 :             hPrivateData->prevSFM_FIR[p] = L_deposit_l( 0 );
    1027         104 :             move32();
    1028         104 :             hPrivateData->prevSFM_IIR[p] = 0;
    1029         104 :             move16();
    1030             : 
    1031             :             /* preset values: */
    1032         104 :             hPrivateData->igfCurrWhiteningLevel[p] = IGF_WHITENING_OFF;
    1033         104 :             move16();
    1034             :         }
    1035             :     }
    1036        7282 :     FOR( p = 0; p < IGF_MAX_TILES; p++ )
    1037             :     {
    1038             :         /* update prev data: */
    1039        6620 :         hPrivateData->igfPrevWhiteningLevel[p] = hPrivateData->igfCurrWhiteningLevel[p];
    1040        6620 :         move16();
    1041             :         /* preset values: */
    1042        6620 :         hPrivateData->igfCurrWhiteningLevel[p] = IGF_WHITENING_OFF;
    1043        6620 :         move16();
    1044             :     }
    1045             : 
    1046         662 :     IF( !s_or( isTransient, hPrivateData->wasTransient ) )
    1047             :     {
    1048         641 :         IF( powerSpectrum )
    1049             :         {
    1050         641 :             Word16 nT = hGrid->nTiles;
    1051         641 :             move16();
    1052         641 :             SWITCH( hPrivateData->igfInfo.bitRateIndex )
    1053             :             {
    1054         400 :                 case IGF_BITRATE_WB_9600:
    1055             :                 case IGF_BITRATE_SWB_9600:
    1056             :                 case IGF_BITRATE_SWB_16400:
    1057             :                 case IGF_BITRATE_SWB_24400:
    1058             :                 case IGF_BITRATE_SWB_32000:
    1059             :                 case IGF_BITRATE_FB_16400:
    1060             :                 case IGF_BITRATE_FB_24400:
    1061             :                 case IGF_BITRATE_FB_32000:
    1062         400 :                     nT = sub( nT, 1 );
    1063         400 :                     BREAK;
    1064         241 :                 default:
    1065         241 :                     BREAK;
    1066             :             }
    1067        1923 :             FOR( p = 0; p < nT; p++ )
    1068             :             {
    1069             :                 /*tmp  = IGF_getSFM(powerSpectrum, hGrid->tile[p], hGrid->tile[p+1]) / IGF_getCrest(powerSpectrum, hGrid->tile[p], hGrid->tile[p+1]);*/
    1070        1282 :                 SFM = IGF_getSFM( &SFM_exp, powerSpectrum, &powerSpectrum_exp, hGrid->tile[p], hGrid->tile[p + 1] );
    1071        1282 :                 crest = IGF_getCrest( &crest_exp, powerSpectrum, powerSpectrum_exp, hGrid->tile[p], hGrid->tile[p + 1] );
    1072             : 
    1073        1282 :                 tmp = BASOP_Util_Divide1616_Scale( SFM, crest, &s ); /*   Q15 */
    1074        1282 :                 s = add( s, sub( SFM_exp, crest_exp ) );
    1075        1282 :                 tmp32 = L_shl( L_deposit_l( tmp ) /*16Q15, s*/, add( s, 1 ) ); /* 15Q16 */
    1076             : 
    1077        1282 :                 test();
    1078        1282 :                 IF( last_core_acelp || hPrivateData->wasTransient )
    1079             :                 {
    1080          78 :                     hPrivateData->prevSFM_FIR[p] = tmp32; /* 15Q16 */
    1081          78 :                     move32();
    1082          78 :                     hPrivateData->prevSFM_IIR[p] = shr( tmp, 2 ); /*  2Q13 */
    1083          78 :                     move16();
    1084             :                 }
    1085             : 
    1086             :                 /*SFM  = tmp + hPrivateData->prevSFM_FIR[p] + 0.5f * hPrivateData->prevSFM_IIR[p];*/
    1087        1282 :                 SFM32 = L_add( tmp32, hPrivateData->prevSFM_FIR[p] );
    1088        1282 :                 SFM32 = L_mac0( SFM32, hPrivateData->prevSFM_IIR[p] /*Q13*/, 4 /*.5f Q3*/ ); /*15Q16*/
    1089             : 
    1090             :                 BASOP_SATURATE_WARNING_OFF_EVS
    1091             :                 /*SFM  = min(2.7f, SFM);*/
    1092             :                 /*Overflow possible in shift, intended*/
    1093        1282 :                 tmp = add_sat( crest, tmp );
    1094        1282 :                 SFM = s_min( 22118 /*2.7f Q13*/, extract_h( L_shr_sat( SFM32, 16 - 29 ) /*->Q29*/ ) /*->Q13*/ );
    1095             :                 BASOP_SATURATE_WARNING_ON_EVS
    1096             : 
    1097        1282 :                 hPrivateData->prevSFM_FIR[p] = tmp32; /*15Q16*/
    1098        1282 :                 move32();
    1099        1282 :                 hPrivateData->prevSFM_IIR[p] = SFM;
    1100        1282 :                 move16();
    1101             : 
    1102        1282 :                 IF( GT_16( SFM, hGrid->whiteningThreshold[1][p] ) )
    1103             :                 {
    1104         656 :                     hPrivateData->igfCurrWhiteningLevel[p] = IGF_WHITENING_STRONG;
    1105         656 :                     move16();
    1106             :                 }
    1107         626 :                 ELSE IF( GT_16( SFM, hGrid->whiteningThreshold[0][p] ) )
    1108             :                 {
    1109         423 :                     hPrivateData->igfCurrWhiteningLevel[p] = IGF_WHITENING_MID;
    1110         423 :                     move16();
    1111             :                 }
    1112             :             }
    1113         641 :             SWITCH( hPrivateData->igfInfo.bitRateIndex )
    1114             :             {
    1115         400 :                 case IGF_BITRATE_WB_9600:
    1116             :                 case IGF_BITRATE_RF_WB_13200:
    1117             :                 case IGF_BITRATE_RF_SWB_13200:
    1118             :                 case IGF_BITRATE_SWB_9600:
    1119             :                 case IGF_BITRATE_SWB_16400:
    1120             :                 case IGF_BITRATE_SWB_24400:
    1121             :                 case IGF_BITRATE_SWB_32000:
    1122             :                 case IGF_BITRATE_FB_16400:
    1123             :                 case IGF_BITRATE_FB_24400:
    1124             :                 case IGF_BITRATE_FB_32000:
    1125         400 :                     move16();
    1126         400 :                     hPrivateData->igfCurrWhiteningLevel[hGrid->nTiles - 1] = hPrivateData->igfCurrWhiteningLevel[hGrid->nTiles - 2];
    1127         400 :                     BREAK;
    1128         241 :                 default:
    1129         241 :                     BREAK;
    1130             :             }
    1131             :         }
    1132             :         ELSE
    1133             :         {
    1134           0 :             FOR( p = 0; p < hGrid->nTiles; p++ )
    1135             :             {
    1136           0 :                 hPrivateData->igfCurrWhiteningLevel[p] = IGF_WHITENING_MID;
    1137           0 :                 move16();
    1138             :             }
    1139             :         }
    1140             :     }
    1141             :     ELSE
    1142             :     {
    1143             :         /* reset filter */
    1144         231 :         FOR( p = 0; p < IGF_MAX_TILES; p++ )
    1145             :         {
    1146         210 :             hPrivateData->prevSFM_FIR[p] = L_deposit_l( 0 );
    1147         210 :             move32();
    1148         210 :             hPrivateData->prevSFM_IIR[p] = 0;
    1149         210 :             move16();
    1150             :         }
    1151             :     }
    1152         662 :     hPrivateData->wasTransient = isTransient;
    1153         662 :     move16();
    1154         662 : }
    1155             : 
    1156             : /**********************************************************************/ /*
    1157             : write whitening levels into bitstream
    1158             : **************************************************************************/
    1159        2108 : static void IGF_WriteWhiteningTile_fx(                                   /**< out: Q0 | number of bits written     */
    1160             :                                        BSTR_ENC_HANDLE hBstr,            /* i/o: encoder bitstream handle       */
    1161             :                                        Word16 *pBitOffset,               /**< in:     | ptr to bitOffset counter   */
    1162             :                                        Word16 whiteningLevel             /**< in: Q0  | whitening levels to write  */
    1163             : )
    1164             : {
    1165        2108 :     IF( EQ_32( whiteningLevel, IGF_WHITENING_MID ) )
    1166             :     {
    1167         722 :         IGF_write_bits( hBstr, pBitOffset, 0, 1 );
    1168             :     }
    1169             :     ELSE
    1170             :     {
    1171        1386 :         IGF_write_bits( hBstr, pBitOffset, 1, 1 );
    1172        1386 :         IF( EQ_32( whiteningLevel, IGF_WHITENING_OFF ) )
    1173             :         {
    1174         386 :             IGF_write_bits( hBstr, pBitOffset, 0, 1 );
    1175             :         }
    1176             :         ELSE
    1177             :         {
    1178        1000 :             IGF_write_bits( hBstr, pBitOffset, 1, 1 );
    1179             :         }
    1180             :     }
    1181        2108 : }
    1182             : 
    1183             : /**********************************************************************/          /*
    1184             :          writes the whitening levels
    1185             :          **************************************************************************/
    1186        1324 : static void IGF_WriteWhiteningLevels_fx(                                          /**< out: Q0 | total number of bits written                                                 */
    1187             :                                          const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in:     | instance handle of IGF encoder                                               */
    1188             :                                          BSTR_ENC_HANDLE hBstr,                   /* i/o: encoder bitstream handle       */
    1189             :                                          Word16 *pBitOffset,                      /**< in:     | ptr to bitOffset counter                                                     */
    1190             :                                          const Word16 igfGridIdx,                 /**< in: Q0  | igf grid index see declaration of IGF_GRID_IDX for details                   */
    1191             :                                          const Word16 isIndepFlag                 /**< in: Q0  | if 1 frame is independent, 0 = frame is coded with data from previous frame  */
    1192             : )
    1193             : {
    1194             :     IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData;
    1195             :     H_IGF_GRID hGrid;
    1196             :     Word16 p;
    1197             :     Word16 nTiles;
    1198             :     Word16 isSame;
    1199             :     Word32 tmp32;
    1200             : 
    1201             : 
    1202        1324 :     isSame = 1;
    1203        1324 :     move16();
    1204        1324 :     hPrivateData = &hInstance->igfData;
    1205        1324 :     hGrid = &hPrivateData->igfInfo.grid[igfGridIdx];
    1206        1324 :     nTiles = hGrid->nTiles;
    1207        1324 :     move16();
    1208             : 
    1209        1324 :     IF( isIndepFlag )
    1210             :     {
    1211        1324 :         isSame = 0;
    1212        1324 :         move16();
    1213             :     }
    1214             :     ELSE
    1215             :     {
    1216           0 :         p = 0;
    1217           0 :         move16();
    1218           0 :         tmp32 = 0;
    1219           0 :         move32();
    1220           0 :         test();
    1221           0 :         WHILE( ( LT_16( p, nTiles ) ) && ( tmp32 == 0 ) )
    1222             :         {
    1223           0 :             test();
    1224           0 :             tmp32 = L_sub( hPrivateData->igfCurrWhiteningLevel[p], hPrivateData->igfPrevWhiteningLevel[p] );
    1225           0 :             if ( tmp32 != 0 )
    1226             :             {
    1227           0 :                 isSame = 0;
    1228           0 :                 move16();
    1229             :             }
    1230           0 :             p++;
    1231             :         }
    1232             :     }
    1233        1324 :     IF( isSame )
    1234             :     {
    1235           0 :         IGF_write_bits( hBstr, pBitOffset, 1, 1 );
    1236             :     }
    1237             :     ELSE
    1238             :     {
    1239        1324 :         IF( !isIndepFlag )
    1240             :         {
    1241           0 :             IGF_write_bits( hBstr, pBitOffset, 0, 1 );
    1242             :         }
    1243        1324 :         IGF_WriteWhiteningTile_fx( hBstr, pBitOffset, hPrivateData->igfCurrWhiteningLevel[0] );
    1244        1324 :         p = 1;
    1245        1324 :         move16();
    1246        1324 :         tmp32 = 0;
    1247        1324 :         move32();
    1248        1324 :         if ( LT_16( p, nTiles ) )
    1249             :         {
    1250        1324 :             isSame = 1;
    1251        1324 :             move16();
    1252             :         }
    1253        1324 :         test();
    1254        3144 :         WHILE( ( LT_16( p, nTiles ) ) && ( tmp32 == 0 ) )
    1255             :         {
    1256        1820 :             test();
    1257        1820 :             tmp32 = L_sub( hPrivateData->igfCurrWhiteningLevel[p], hPrivateData->igfCurrWhiteningLevel[p - 1] );
    1258        1820 :             if ( tmp32 != 0 )
    1259             :             {
    1260         476 :                 isSame = 0;
    1261         476 :                 move16();
    1262             :             }
    1263        1820 :             p++;
    1264             :         }
    1265             : 
    1266        1324 :         IF( !isSame )
    1267             :         {
    1268         476 :             IGF_write_bits( hBstr, pBitOffset, 1, 1 );
    1269        1260 :             FOR( p = 1; p < nTiles; p++ )
    1270             :             {
    1271         784 :                 IGF_WriteWhiteningTile_fx( hBstr, pBitOffset, hPrivateData->igfCurrWhiteningLevel[p] );
    1272             :             }
    1273             :         }
    1274             :         ELSE
    1275             :         {
    1276         848 :             IGF_write_bits( hBstr, pBitOffset, 0, 1 );
    1277             :         }
    1278             :     }
    1279        1324 : }
    1280             : 
    1281             : /**********************************************************************/            /*
    1282             :            write flattening trigger
    1283             :            **************************************************************************/
    1284        1324 : static void IGF_WriteFlatteningTrigger_fx(                                          /**< out:    | number of bits written         */
    1285             :                                            const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in:     | instance handle of IGF Encoder */
    1286             :                                            BSTR_ENC_HANDLE hBstr,                   /* i/o: encoder bitstream handle       */
    1287             :                                            Word16 *pBitOffset                       /**< in:     | ptr to bitOffset counter       */
    1288             : )
    1289             : {
    1290             :     Word16 flatteningTrigger;
    1291             : 
    1292             : 
    1293        1324 :     flatteningTrigger = hInstance->flatteningTrigger;
    1294        1324 :     move16();
    1295             : 
    1296        1324 :     IGF_write_bits( hBstr, pBitOffset, flatteningTrigger, 1 );
    1297        1324 : }
    1298             : 
    1299             : /**********************************************************************/ /*
    1300             : updates the start/stop frequency of IGF according to igfGridIdx
    1301             : **************************************************************************/
    1302     1184638 : void IGF_UpdateInfo( const IGF_ENC_INSTANCE_HANDLE hInstance,            /**< in:     | instance handle of IGF Encoder */
    1303             :                      const Word16 igfGridIdx                             /**< in: Q0  | IGF grid index                 */
    1304             : )
    1305             : {
    1306             :     IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData;
    1307             :     H_IGF_GRID hGrid;
    1308             : 
    1309             : 
    1310     1184638 :     hPrivateData = &hInstance->igfData;
    1311     1184638 :     hGrid = &hPrivateData->igfInfo.grid[igfGridIdx];
    1312     1184638 :     hInstance->infoStartFrequency = hGrid->startFrequency;
    1313     1184638 :     move16();
    1314     1184638 :     hInstance->infoStopFrequency = hGrid->stopFrequency;
    1315     1184638 :     move16();
    1316     1184638 :     hInstance->infoStartLine = hGrid->startLine;
    1317     1184638 :     move16();
    1318     1184638 :     hInstance->infoStopLine = hGrid->stopLine;
    1319     1184638 :     move16();
    1320             : 
    1321     1184638 :     return;
    1322             : }
    1323             : 
    1324             : /**********************************************************************/ /*
    1325             : IGF bitsream writer
    1326             : **************************************************************************/
    1327        1324 : Word16 IGFEncWriteBitstream_fx(                                          /**< out:    | number of bits written per frame                                             */
    1328             :                                 const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in:     | instance handle of IGF Encoder                                               */
    1329             :                                 BSTR_ENC_HANDLE hBstr,                   /* i/o: encoder bitstream handle       */
    1330             :                                 Word16 *pBitOffset,                      /**< in:     | ptr to bitOffset counter                                                     */
    1331             :                                 const Word16 igfGridIdx,                 /**< in: Q0  | igf grid index see declaration of IGF_GRID_IDX for details                   */
    1332             :                                 const Word16 isIndepFlag                 /**< in: Q0  | if 1 frame is independent, 0 = frame is coded with data from previous frame  */
    1333             : )
    1334             : {
    1335             :     Word16 igfAllZero;
    1336             :     Word16 startBitCount;
    1337             : 
    1338             : 
    1339        1324 :     startBitCount = *pBitOffset;
    1340        1324 :     move16();
    1341        1324 :     hInstance->infoTotalBitsPerFrameWritten = 0;
    1342        1324 :     move16();
    1343             : 
    1344        1324 :     if ( isIndepFlag )
    1345             :     {
    1346        1324 :         hInstance->infoTotalBitsWritten = 0;
    1347        1324 :         move16();
    1348             :     }
    1349             : 
    1350        1324 :     IGF_WriteEnvelope( hInstance,     /* i: instance handle of IGF Encoder                                              */
    1351             :                        hBstr,         /* i: encoder state                                                               */
    1352             :                        pBitOffset,    /* i: ptr to bitOffset counter                                                    */
    1353             :                        igfGridIdx,    /* i: igf grid index see definition of IGF_GRID_IDX for details                   */
    1354             :                        isIndepFlag,   /* i: if 1 frame is independent, 0 = frame is coded with data from previous frame */
    1355             :                        &igfAllZero ); /* o: *igfAllZero                                                                 */
    1356             : 
    1357        1324 :     IGF_WriteWhiteningLevels_fx( hInstance,     /* i: instance handle of IGF Encoder                                              */
    1358             :                                  hBstr,         /* i: encoder state                                                               */
    1359             :                                  pBitOffset,    /* i: ptr to bitOffset counter                                                    */
    1360             :                                  igfGridIdx,    /* i: igf grid index see definition of IGF_GRID_IDX for details                   */
    1361             :                                  isIndepFlag ); /* i: if 1 frame is independent, 0 = frame is coded with data from previous frame */
    1362             : 
    1363        1324 :     IGF_WriteFlatteningTrigger_fx( hInstance,    /* i: instance handle of IGF Encoder                                              */
    1364             :                                    hBstr,        /* i: encoder state                                                               */
    1365             :                                    pBitOffset ); /* i: ptr to bitOffset counter                                                    */
    1366             : 
    1367        1324 :     hInstance->infoTotalBitsPerFrameWritten = sub( *pBitOffset, startBitCount );
    1368        1324 :     hInstance->infoTotalBitsWritten = add( hInstance->infoTotalBitsWritten, hInstance->infoTotalBitsPerFrameWritten );
    1369        1324 :     move16();
    1370        1324 :     move16();
    1371        1324 :     return hInstance->infoTotalBitsPerFrameWritten;
    1372             : }
    1373             : 
    1374             : /**********************************************************************/ /*
    1375             : sets the IGF mode according to given bitrate
    1376             : **************************************************************************/
    1377          64 : void IGFEncSetMode_fx(
    1378             :     const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i/o: instance handle of IGF Encoder */
    1379             :     const Word32 total_brate,              /* i  : encoder total bitrate          */
    1380             :     const Word16 bwidth,                   /* i  : encoder audio bandwidth        */
    1381             :     const Word16 element_mode,             /* i  : IVAS element mode              */
    1382             :     const Word16 rf_mode                   /* i  : flag to signal the RF mode     */
    1383             : )
    1384             : {
    1385             :     IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData;
    1386             :     Word16 i;
    1387             : 
    1388          64 :     hPrivateData = &hIGFEnc->igfData;
    1389          64 :     hPrivateData->igfBitstreamBits = 0;
    1390          64 :     move16();
    1391          64 :     set16_fx( hPrivateData->igfScfQuantized, 0, IGF_MAX_SFB );
    1392          64 :     set16_fx( hPrivateData->igfCurrWhiteningLevel, 0, IGF_MAX_TILES );
    1393          64 :     set16_fx( hPrivateData->igfPrevWhiteningLevel, 0, IGF_MAX_TILES );
    1394       20544 :     FOR( i = 0; i < IGF_BITBUFSIZE / 8; i++ )
    1395             :     {
    1396       20480 :         hPrivateData->igfBitstream[i] = 0;
    1397       20480 :         move16();
    1398             :     }
    1399          64 :     hPrivateData->wasTransient = 0;
    1400          64 :     move16();
    1401          64 :     set32_fx( hPrivateData->prevSFM_FIR, 0, IGF_MAX_TILES );
    1402          64 :     set16_fx( hPrivateData->prevSFM_IIR, 0, IGF_MAX_TILES );
    1403             : 
    1404          64 :     IF( IGFCommonFuncsIGFConfiguration( total_brate, bwidth, element_mode, &hPrivateData->igfInfo, rf_mode ) != 0 )
    1405             :     {
    1406          64 :         IGFSCFEncoderOpen_fx( &hPrivateData->hIGFSCFArithEnc, &hPrivateData->igfInfo, total_brate, bwidth, element_mode, rf_mode );
    1407             : 
    1408          64 :         hIGFEnc->infoSamplingRate = hPrivateData->igfInfo.sampleRate;
    1409          64 :         move32();
    1410          64 :         hIGFEnc->infoStartFrequency = hPrivateData->igfInfo.grid[0].startFrequency;
    1411          64 :         move16();
    1412          64 :         hIGFEnc->infoStopFrequency = hPrivateData->igfInfo.grid[0].stopFrequency;
    1413          64 :         move16();
    1414          64 :         hIGFEnc->infoStartLine = hPrivateData->igfInfo.grid[0].startLine;
    1415          64 :         move16();
    1416          64 :         hIGFEnc->infoStopLine = hPrivateData->igfInfo.grid[0].stopLine;
    1417          64 :         move16();
    1418             :     }
    1419             :     ELSE
    1420             :     {
    1421             :         /* IGF configuration failed -> error! */
    1422           0 :         hIGFEnc->infoSamplingRate = 0;
    1423           0 :         move32();
    1424           0 :         hIGFEnc->infoStartFrequency = -1;
    1425           0 :         move16();
    1426           0 :         hIGFEnc->infoStopFrequency = -1;
    1427           0 :         move16();
    1428           0 :         hIGFEnc->infoStartLine = -1;
    1429           0 :         move16();
    1430           0 :         hIGFEnc->infoStopLine = -1;
    1431           0 :         move16();
    1432           0 :         fprintf( stderr, "IGFEncSetMode_fx: initialization error!\n" );
    1433             :     }
    1434             : 
    1435             :     /* reset remaining variables */
    1436          64 :     hIGFEnc->infoTotalBitsWritten = 0;
    1437          64 :     move16();
    1438          64 :     hIGFEnc->infoTotalBitsPerFrameWritten = 0;
    1439          64 :     move16();
    1440          64 :     hIGFEnc->flatteningTrigger = 0;
    1441          64 :     move16();
    1442          64 :     hIGFEnc->spec_be_igf_e = 0;
    1443          64 :     move16();
    1444          64 :     hIGFEnc->tns_predictionGain = 0;
    1445          64 :     move16();
    1446          64 :     set32_fx( hIGFEnc->spec_be_igf, 0, N_MAX_TCX - IGF_START_MN );
    1447          64 :     return;
    1448             : }
    1449             : 
    1450             : /*-------------------------------------------------------------------*
    1451             :  * pack_bit()
    1452             :  *
    1453             :  * insert a bit into packed octet
    1454             :  *-------------------------------------------------------------------*/
    1455             : 
    1456      494890 : static void pack_bit_ivas_fx(
    1457             :     const Word16 bit, /* i  : bit to be packed */
    1458             :     UWord8 **pt,      /* i/o: pointer to octet array into which bit will be placed */
    1459             :     UWord8 *omask     /* i/o: output mask to indicate where in the octet the bit is to be written */
    1460             : )
    1461             : {
    1462      494890 :     if ( EQ_16( *omask, 0x80 ) )
    1463             :     {
    1464       66857 :         **pt = 0;
    1465       66857 :         move16();
    1466             :     }
    1467             : 
    1468      494890 :     if ( bit != 0 )
    1469             :     {
    1470      264891 :         **pt = (UWord8) s_or( **pt, *omask );
    1471      264891 :         move16();
    1472             :     }
    1473             : 
    1474      494890 :     *omask = (UWord8) UL_lshr( *omask, 1 );
    1475      494890 :     move16();
    1476      494890 :     IF( *omask == 0 )
    1477             :     {
    1478       57027 :         *omask = 0x80;
    1479       57027 :         move16();
    1480       57027 :         ( *pt )++;
    1481             :     }
    1482             : 
    1483      494890 :     return;
    1484             : }
    1485             : 
    1486             : /*-------------------------------------------------------------------*
    1487             :  * IGFEncConcatenateBitstream_fx()
    1488             :  *
    1489             :  * IGF bitstream concatenation for TCX10 modes
    1490             :  *-------------------------------------------------------------------*/
    1491             : 
    1492       22084 : void IGFEncConcatenateBitstream_ivas_fx( const IGF_ENC_INSTANCE_HANDLE hIGFEnc, /* i  : instance handle of IGF Encoder                  */
    1493             :                                          const Word16 bsBits,                   /* i  : number of IGF bits written to list of indices   */
    1494             :                                          BSTR_ENC_HANDLE hBstr                  /* i/o: bitstream handle                                */
    1495             : )
    1496             : {
    1497             :     Word16 i;
    1498             :     IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData;
    1499             :     Indice *ind_list;
    1500             :     UWord8 *pFrame;      /* byte array with bit packet and byte aligned coded speech data */
    1501             :     Word16 *pFrame_size; /* number of bits in the binary encoded access unit [bits]       */
    1502             :     Word16 k, nb_bits_written;
    1503             :     Word32 imask;
    1504             :     UWord8 omask;
    1505             : 
    1506       22084 :     hPrivateData = &hIGFEnc->igfData;
    1507             : 
    1508       22084 :     ind_list = &hBstr->ind_list[hBstr->nb_ind_tot - bsBits]; /* here, we assume that each bit has been written as a single indice */
    1509       22084 :     pFrame = hPrivateData->igfBitstream;
    1510       22084 :     move16();
    1511       22084 :     pFrame_size = &hPrivateData->igfBitstreamBits;
    1512       22084 :     move16();
    1513       22084 :     nb_bits_written = 0;
    1514       22084 :     move16();
    1515             : 
    1516       22084 :     omask = (UWord8) UL_lshr( 0x80, s_and( *pFrame_size, 0x7 ) );
    1517       22084 :     move16();
    1518       22084 :     pFrame += *pFrame_size >> 3;
    1519             : 
    1520             :     /* bitstream packing (conversion of individual indices into a serial stream) */
    1521      516974 :     FOR( i = 0; i < bsBits; i++ ){
    1522      494890 :         IF( ind_list[i].nb_bits > 0 ){
    1523             :             /* mask from MSB to LSB */
    1524      494890 :             imask = L_shl( 1, sub( ind_list[i].nb_bits, 1 ) );
    1525             : 
    1526             :     /* write bit by bit */
    1527      989780 :     FOR( k = 0; k < ind_list[i].nb_bits; k++ )
    1528             :     {
    1529      494890 :         pack_bit_ivas_fx( extract_l( L_and( ind_list[i].value, imask ) ), &pFrame, &omask );
    1530      494890 :         imask = L_shr( imask, 1 );
    1531             :     }
    1532      494890 :     nb_bits_written = add( nb_bits_written, ind_list[i].nb_bits );
    1533             : 
    1534             :     /* delete the indice */
    1535      494890 :     ind_list[i].nb_bits = -1;
    1536      494890 :     move16();
    1537             : }
    1538             : }
    1539             : 
    1540       22084 : *pFrame_size = add( *pFrame_size, nb_bits_written );
    1541       22084 : move16();
    1542             : 
    1543             : /* update list of indices */
    1544       22084 : hBstr->nb_ind_tot = sub( hBstr->nb_ind_tot, bsBits );
    1545       22084 : hBstr->nb_bits_tot = sub( hBstr->nb_bits_tot, nb_bits_written );
    1546             : 
    1547       22084 : return;
    1548             : }
    1549             : #ifndef HARM_PUSH_BIT                                                        /* old bitstream */
    1550             : /**********************************************************************/     /*
    1551             :     IGF bitsream concatenation for TCX10 modes
    1552             :     **************************************************************************/
    1553             : void IGFEncConcatenateBitstream_fx( const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in:     | instance handle of IGF Encoder                 */
    1554             :                                     Word16 bsBits,                           /**< in: Q0  | number of IGF bits written to list of indices  */
    1555             :                                     Word16 *next_ind,                        /**< in/out: | pointer to actual bit indice                   */
    1556             :                                     Word16 *nb_bits,                         /**< in/out: | total number of bits already written           */
    1557             :                                     Indice *ind_list_fx                      /**< in:     | pointer to list of indices                     */
    1558             : )
    1559             : {
    1560             :     IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData;
    1561             : 
    1562             :     hPrivateData = &hInstance->igfData;
    1563             :     *next_ind = *next_ind - bsBits;
    1564             :     move16();
    1565             :     indices_to_serial_generic(
    1566             :         &ind_list_fx[*next_ind],
    1567             :         bsBits,
    1568             :         hPrivateData->igfBitstream,
    1569             :         &hPrivateData->igfBitstreamBits );
    1570             : 
    1571             :     *nb_bits = sub( *nb_bits, bsBits );
    1572             :     move16();
    1573             :     return;
    1574             : }
    1575             : #endif
    1576             : /**********************************************************************/    /*
    1577             :    IGF reset bitsream bit counter for TCX10 modes
    1578             :    **************************************************************************/
    1579       11042 : void IGFEncResetTCX10BitCounter_fx( const IGF_ENC_INSTANCE_HANDLE hInstance /**< in:     | instance handle of IGF Encoder */
    1580             : )
    1581             : {
    1582             :     IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData;
    1583             : 
    1584       11042 :     hPrivateData = &hInstance->igfData;
    1585       11042 :     hPrivateData->igfBitstreamBits = 0;
    1586       11042 :     move16();
    1587       11042 :     hInstance->infoTotalBitsWritten = 0;
    1588       11042 :     move16();
    1589             : 
    1590       11042 :     return;
    1591             : }
    1592             : 
    1593             : /**********************************************************************/             /*
    1594             :             IGF write concatenated bitsream for TCX10 modes
    1595             :             **************************************************************************/
    1596           0 : Word16 IGFEncWriteConcatenatedBitstream_fx(                                          /**< out: Q0 | total number of bits written   */
    1597             :                                             const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in:     | instance handle of IGF Encoder */
    1598             :                                             BSTR_ENC_HANDLE hBstr                    /* i/o: encoder bitstream handle       */
    1599             : )
    1600             : {
    1601             :     IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData;
    1602             :     Word16 i;
    1603             :     Word16 tmp;
    1604             :     Word16 bitsLeft;
    1605             :     UWord8 *pBitstream;
    1606             : 
    1607           0 :     hPrivateData = &hInstance->igfData;
    1608           0 :     pBitstream = &hPrivateData->igfBitstream[0];
    1609             : 
    1610           0 :     tmp = shr( hPrivateData->igfBitstreamBits, 3 );
    1611           0 :     FOR( i = 0; i < tmp; i++ )
    1612             :     {
    1613           0 :         push_next_indice( hBstr, pBitstream[i], 8 );
    1614             :     }
    1615             : 
    1616           0 :     bitsLeft = s_and( hPrivateData->igfBitstreamBits, 0x7 );
    1617           0 :     IF( bitsLeft > 0 )
    1618             :     {
    1619           0 :         push_next_indice( hBstr, shr( pBitstream[i], sub( 8, bitsLeft ) ), bitsLeft );
    1620             :     }
    1621             : 
    1622           0 :     return hInstance->infoTotalBitsWritten;
    1623             : }
    1624       11042 : Word16 IGFEncWriteConcatenatedBitstream_ivas_fx(                                          /**< out: Q0 | total number of bits written   */
    1625             :                                                  const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in:     | instance handle of IGF Encoder */
    1626             :                                                  BSTR_ENC_HANDLE hBstr                    /* i/o: encoder bitstream handle       */
    1627             : )
    1628             : {
    1629             :     IGF_ENC_PRIVATE_DATA_HANDLE hPrivateData;
    1630             :     Word16 i;
    1631             :     Word16 tmp;
    1632             :     Word16 bitsLeft;
    1633             :     UWord8 *pBitstream;
    1634             : 
    1635       11042 :     hPrivateData = &hInstance->igfData;
    1636       11042 :     pBitstream = &hPrivateData->igfBitstream[0];
    1637             : 
    1638       11042 :     tmp = shr( hPrivateData->igfBitstreamBits, 3 );
    1639       68069 :     FOR( i = 0; i < tmp; i++ )
    1640             :     {
    1641       57027 :         push_next_indice( hBstr, pBitstream[i], 8 );
    1642             :     }
    1643             : 
    1644       11042 :     bitsLeft = s_and( hPrivateData->igfBitstreamBits, 0x7 );
    1645       11042 :     IF( bitsLeft > 0 )
    1646             :     {
    1647        9830 :         push_next_indice( hBstr, shr( pBitstream[i], sub( 8, bitsLeft ) ), bitsLeft );
    1648             :     }
    1649             : 
    1650       11042 :     return hInstance->infoTotalBitsWritten;
    1651             : }
    1652             : 
    1653             : /**********************************************************************/ /*
    1654             : apply the IGF encoder, main encoder interface
    1655             : **************************************************************************/
    1656         662 : void IGFEncApplyMono_fx( const IGF_ENC_INSTANCE_HANDLE hInstance,        /**< in:     | instance handle of IGF Encoder                         */
    1657             :                          const Word16 igfGridIdx,                        /**< in: Q0  | IGF grid index                                         */
    1658             :                          Encoder_State *st,                              /**< in:     | Encoder state                                          */
    1659             :                          Word32 *pMDCTSpectrum,                          /**< in: Q31 | MDCT spectrum                                          */
    1660             :                          Word16 MDCTSpectrum_e,                          /**< in:     | exponent of MDCT spectrum                              */
    1661             :                          Word32 *pPowerSpectrum,                         /**< in: Q31 | MDCT^2 + MDST^2 spectrum, or estimate                  */
    1662             :                          Word16 PowerSpectrum_e,                         /**< in:     | exponent of pPowerSpectrum                             */
    1663             :                          Word16 isTCX20,                                 /**< in: Q0  | flag indicating if the input is TCX20 or TCX10/2xTCX5  */
    1664             :                          Word16 isTNSActive,                             /**< in: Q0  | flag indicating if the TNS is active                   */
    1665             :                          Word16 last_core_acelp                          /**< in: Q0  | indicator if last frame was acelp coded                */
    1666             : )
    1667             : {
    1668             :     Word32 *pPowerSpectrumParameter;          /* If it is NULL it informs a function that specific handling is needed */
    1669             :     Word32 *pPowerSpectrumParameterWhitening; /* If it is NULL it informs a function that specific handling is needed */
    1670             :     Word16 highPassEner_exp;                  /*exponent of highpass energy - maybe not needed*/
    1671             : 
    1672             : 
    1673         662 :     pPowerSpectrumParameter = NULL;
    1674         662 :     test();
    1675         662 :     if ( ( isTNSActive == 0 ) && ( isTCX20 != 0 ) )
    1676             :     {
    1677         658 :         pPowerSpectrumParameter = pPowerSpectrum;
    1678             :     }
    1679         662 :     pPowerSpectrumParameterWhitening = NULL;
    1680         662 :     if ( isTCX20 != 0 )
    1681             :     {
    1682         662 :         pPowerSpectrumParameterWhitening = pPowerSpectrum;
    1683             :     }
    1684             : 
    1685         662 :     IGF_UpdateInfo( hInstance,    /* i: instance handle of IGF Encoder            */
    1686             :                     igfGridIdx ); /* i: IGF grid index                            */
    1687             : 
    1688         662 :     IGF_CalculateEnvelope( hInstance,               /* i: instance handle of IGF Encoder            */
    1689             :                            pMDCTSpectrum,           /* i: MDCT spectrum                             */
    1690             :                            MDCTSpectrum_e,          /* i: exponent of MDCT spectrum                 */
    1691             :                            pPowerSpectrumParameter, /* i: MDCT^2 + MDST^2 spectrum, or estimate     */
    1692             :                            PowerSpectrum_e,         /* i: exponent of pPowerSpectrum                */
    1693             :                            igfGridIdx               /* i: IGF grid index                            */
    1694             :     );
    1695             : 
    1696             : 
    1697         662 :     IGF_Whitening( hInstance,                        /* i: instance handle of IGF Encoder            */
    1698             :                    pPowerSpectrumParameterWhitening, /* i: MDCT^2 + MDST^2 spectrum, or estimate     */
    1699             :                    PowerSpectrum_e,                  /* i: exponent of powerSpectrum                 */
    1700             :                    igfGridIdx,                       /* i: IGF grid index                            */
    1701         662 :                    ( st->transientDetection.transientDetector.bIsAttackPresent == 1 ),
    1702             :                    last_core_acelp ); /* i: last frame was acelp indicator            */
    1703             : 
    1704         662 :     pPowerSpectrumParameter = NULL;
    1705         662 :     if ( isTCX20 != 0 )
    1706             :     {
    1707         662 :         pPowerSpectrumParameter = pPowerSpectrum;
    1708             :     }
    1709             : 
    1710         662 :     IGF_ErodeSpectrum(                          /* o: highpass energy                           */
    1711             :                        &highPassEner_exp,       /* o: exponent of highPassEner                  */
    1712             :                        hInstance,               /* i: instance handle of IGF Encoder            */
    1713             :                        pMDCTSpectrum,           /* i: MDCT spectrum                             */
    1714             :                        pPowerSpectrumParameter, /* i: MDCT^2 + MDST^2 spectrum, or estimate     */
    1715             :                        PowerSpectrum_e,         /* i: exponent of pPowerSpectrum                */
    1716             :                        igfGridIdx );            /* i: IGF grid index                            */
    1717         662 : }
    1718             : 
    1719             : 
    1720       13335 : ivas_error IGF_Reconfig_fx(
    1721             :     IGF_ENC_INSTANCE_HANDLE *hIGFEnc, /* i/o: instance handle of IGF Encoder  */
    1722             :     const Word16 igf,                 /* i  : IGF on/off                      */
    1723             :     const Word16 reset,               /* i  : reset flag                      */
    1724             :     const Word32 brate,               /* i  : bitrate for configuration       */
    1725             :     const Word16 bwidth,              /* i  : signal bandwidth                */
    1726             :     const Word16 element_mode,        /* i  : IVAS element mode               */
    1727             :     const Word16 rf_mode              /* i  : flag to signal the RF mode      */
    1728             : )
    1729             : {
    1730             :     ivas_error error;
    1731             : 
    1732       13335 :     error = IVAS_ERR_OK;
    1733       13335 :     move32();
    1734             : 
    1735       13335 :     test();
    1736       13335 :     test();
    1737       13335 :     test();
    1738       13335 :     IF( igf && *hIGFEnc == NULL )
    1739             :     {
    1740         831 :         IF( ( *hIGFEnc = (IGF_ENC_INSTANCE_HANDLE) malloc( sizeof( IGF_ENC_INSTANCE ) ) ) == NULL )
    1741             :         {
    1742           0 :             return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for hIGFEnc\n" ) );
    1743             :         }
    1744         831 :         IGFEncSetMode_ivas_fx( *hIGFEnc, brate, bwidth, element_mode, rf_mode );
    1745             :     }
    1746       12504 :     ELSE IF( igf && reset )
    1747             :     {
    1748           0 :         IGFEncSetMode_ivas_fx( *hIGFEnc, brate, bwidth, element_mode, rf_mode );
    1749             :     }
    1750       12504 :     ELSE IF( !igf && *hIGFEnc != NULL )
    1751             :     {
    1752        1018 :         free( *hIGFEnc );
    1753        1018 :         *hIGFEnc = NULL;
    1754             :     }
    1755             : 
    1756       13335 :     return error;
    1757             : }

Generated by: LCOV version 1.14