LCOV - code coverage report
Current view: top level - lib_enc - fd_cng_enc_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 3b2f07138c61dcf997bbf4165d0882f794b2995f Lines: 994 1565 63.5 %
Date: 2025-05-03 01:55:50 Functions: 15 19 78.9 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : 
       5             : 
       6             : #include <assert.h>
       7             : #include "stl.h"
       8             : #include "options.h"
       9             : #include "cnst.h"
      10             : #include "stl.h"
      11             : #include "rom_com_fx.h"
      12             : #include "rom_com.h"
      13             : #include "rom_enc.h"
      14             : #include "prot_fx.h"
      15             : #include "prot_fx_enc.h"
      16             : #include "ivas_prot_fx.h"
      17             : #include "basop_util.h"
      18             : #include "rom_basop_util.h"
      19             : 
      20             : 
      21             : /********************************
      22             :  * External functions            *
      23             :  ********************************/
      24             : #ifndef swap
      25             : #define swap( x, y, type ) \
      26             :     {                      \
      27             :         type u__p;         \
      28             :         u__p = x;          \
      29             :         x = y;             \
      30             :         y = u__p;          \
      31             :     }
      32             : #endif
      33             : extern void BASOP_getTables( const PWord16 **ptwiddle, const PWord16 **sin_twiddle, Word16 *psin_step, Word16 length );
      34             : 
      35             : /*************************************
      36             :  * Create an instance of type FD_CNG *
      37             :  *************************************/
      38         480 : void createFdCngEnc_fx( HANDLE_FD_CNG_ENC *hFdCngEnc )
      39             : {
      40             :     HANDLE_FD_CNG_ENC hs;
      41             : 
      42             :     /* Allocate memory */
      43         480 :     hs = (HANDLE_FD_CNG_ENC) calloc( 1, sizeof( FD_CNG_ENC ) );
      44         480 :     move16();
      45             : 
      46             : 
      47         480 :     createFdCngCom_fx( &( hs->hFdCngCom ) );
      48         480 :     *hFdCngEnc = hs;
      49         480 :     move16();
      50             : 
      51         480 :     return;
      52             : }
      53             : 
      54         480 : void initFdCngEnc_fx(
      55             :     HANDLE_FD_CNG_ENC hsEnc,
      56             :     Word32 input_Fs, /* Q0 */
      57             :     Word16 scale )
      58             : {
      59             :     Word16 j;
      60         480 :     HANDLE_FD_CNG_COM hsCom = hsEnc->hFdCngCom;
      61             : 
      62             :     /* Initialize common */
      63         480 :     initFdCngCom( hsCom, scale );
      64             : 
      65             :     /* Configure the Noise Estimator */
      66             : 
      67         480 :     hsCom->numSlots = 16;
      68         480 :     move16();
      69         480 :     hsCom->numCoreBands = 16;
      70         480 :     move16();
      71         480 :     hsCom->regularStopBand = idiv1616U( extract_l( L_shr( input_Fs, 5 ) ), 25 ); /* Q0 */
      72         480 :     move16();
      73         480 :     if ( GT_16( hsCom->regularStopBand, 40 ) )
      74             :     {
      75         351 :         hsCom->regularStopBand = 40;
      76         351 :         move16();
      77             :     }
      78             : 
      79         480 :     hsCom->startBand = 2;
      80         480 :     move16();
      81         480 :     IF( EQ_16( hsCom->regularStopBand, 10 ) )
      82             :     {
      83           0 :         hsCom->stopFFTbin = 160;
      84           0 :         move16();
      85           0 :         hsCom->stopBand = 160;
      86           0 :         move16();
      87           0 :         hsCom->nFFTpart = 17;
      88           0 :         move16();
      89             :     }
      90             :     ELSE
      91             :     {
      92         480 :         hsCom->stopFFTbin = 256;
      93         480 :         move16();
      94         480 :         hsCom->stopBand = add( sub( hsCom->regularStopBand, hsCom->numCoreBands ), hsCom->stopFFTbin ); /* Q0 */
      95         480 :         move16();
      96         480 :         hsCom->nFFTpart = 20;
      97         480 :         move16();
      98             :     }
      99             : 
     100         480 :     initPartitions( sidparts_encoder_noise_est, SIZE_SIDPARTS_ENC_NOISE_EST, hsCom->startBand, hsCom->stopBand, hsCom->part, &hsCom->npart, hsCom->midband, hsCom->psize, hsCom->psize_norm, &hsCom->psize_norm_exp, hsCom->psize_inv, 0 );
     101             : 
     102         480 :     hsCom->nCLDFBpart = sub( hsCom->npart, hsCom->nFFTpart ); /* Q0 */
     103         480 :     move16();
     104        2316 :     FOR( j = 0; j < hsCom->nCLDFBpart; j++ )
     105             :     {
     106        1836 :         hsCom->CLDFBpart[j] = sub( hsCom->part[j + hsCom->nFFTpart], sub( 256, hsCom->startBand ) ); /* Q0 */
     107        1836 :         hsCom->CLDFBpsize_inv[j] = hsCom->psize_inv[j + hsCom->nFFTpart];                            /* Q15 */
     108        1836 :         move16();
     109        1836 :         move16();
     110             :     }
     111             : 
     112             :     /* Initialize noise estimation algorithm */
     113         480 :     set32_fx( hsEnc->msPeriodog_fx, 0, NPART );
     114         480 :     hsEnc->msPeriodog_fx_exp_fft = 0;
     115         480 :     move16();
     116         480 :     hsEnc->msPeriodog_fx_exp_cldfb = 0;
     117         480 :     move16();
     118         480 :     hsEnc->msPeriodog_fx_exp = 31;
     119         480 :     move16();
     120         480 :     set32_fx( hsEnc->msAlpha_fx, 0, NPART );
     121         480 :     set32_fx( hsEnc->msBminWin_fx, 0, NPART );
     122         480 :     set32_fx( hsEnc->msBminSubWin_fx, 0, NPART );
     123             : 
     124         480 :     set32_fx( hsEnc->msNoiseEst_fx, 0, NPART );
     125         480 :     hsEnc->msNoiseEst_fx_exp = 0;
     126         480 :     move16();
     127         480 :     set32_fx( hsEnc->energy_ho_fx, 0, NPART );
     128         480 :     set32_fx( hsEnc->msNoiseEst_old_fx, 0, NPART );
     129         480 :     hsEnc->msNoiseEst_old_fx_exp = 0;
     130         480 :     move16();
     131         480 :     set16_fx( hsEnc->msLogPeriodog_fx, 0, NPART );
     132         480 :     set16_fx( hsEnc->msLogNoiseEst_fx, 0, NPART );
     133         480 :     set16_fx( hsEnc->msPsd_fx, 0, NPART );
     134         480 :     set16_fx( hsEnc->msNoiseFloor_fx, 0, NPART );
     135         480 :     set32_fx( hsEnc->msMinBuf_fx, 2147483647l /*1.0 Q31*/, MSNUMSUBFR * NPART );
     136         480 :     set32_fx( hsEnc->msCurrentMin_fx, 2147483647l /*1.0 Q31*/, NPART );
     137         480 :     set32_fx( hsEnc->msCurrentMinOut_fx, 2147483647l /*1.0 Q31*/, NPART );
     138         480 :     set32_fx( hsEnc->msCurrentMinSubWindow_fx, 2147483647l /*1.0 Q31*/, NPART );
     139         480 :     set16_fx( hsEnc->msPsdFirstMoment_fx, 0, NPART );
     140         480 :     set16_fx( hsEnc->msPeriodogBuf_fx, 0, MSBUFLEN * NPART );
     141             : 
     142         480 :     set16_fx( hsEnc->msLocalMinFlag, 0, NPART );
     143         480 :     set16_fx( hsEnc->msNewMinFlag, 0, NPART );
     144         480 :     hsEnc->msPeriodogBufPtr = 0;
     145         480 :     move16();
     146         480 :     set32_fx( hsEnc->msPsdSecondMoment_fx, 0, NPART );
     147         480 :     set32_fx( hsEnc->mem_coherence_fx, EPSILON_FX, 4 );
     148         480 :     set16_fx( hsEnc->mem_coherence_exp, 0, 4 );
     149             : 
     150         480 :     return;
     151             : }
     152             : 
     153             : /************************************
     154             :  * Configure FD_CNG                 *
     155             :  ************************************/
     156           3 : void configureFdCngEnc_fx( HANDLE_FD_CNG_ENC hsEnc, /* i/o: Contains the variables related to the FD-based CNG process */
     157             :                            Word16 bandwidth,        /* i:   bandwidth   Q0*/
     158             :                            Word32 bitrate           /* Q0 */
     159             : )
     160             : {
     161           3 :     HANDLE_FD_CNG_COM hsCom = hsEnc->hFdCngCom;
     162             :     Word16 psizeDec[NPART];
     163             :     Word16 psizeDec_norm[NPART];
     164             :     Word16 psizeDec_norm_exp;
     165             :     Word16 psize_invDec[NPART];
     166             : 
     167           3 :     set16_fx( psizeDec, 0, NPART );
     168             : 
     169           3 :     hsCom->CngBandwidth = bandwidth;
     170           3 :     move16();
     171           3 :     IF( EQ_16( hsCom->CngBandwidth, FB ) )
     172             :     {
     173           0 :         hsCom->CngBandwidth = SWB;
     174           0 :         move16();
     175             :     }
     176           3 :     hsCom->CngBitrate = bitrate; /* Q0 */
     177           3 :     move32();
     178             : 
     179             :     /* NB configuration */
     180           3 :     IF( EQ_16( bandwidth, NB ) )
     181             :     {
     182           0 :         hsCom->FdCngSetup = FdCngSetup_nb; /* PTR assignation -> no move needed*/
     183             :     }
     184             : 
     185             :     /* WB configuration */
     186           3 :     ELSE IF( EQ_16( bandwidth, WB ) )
     187             :     {
     188             :         /* FFT 6.4kHz, no CLDFB */
     189           0 :         IF( LE_32( bitrate, ACELP_8k00 ) )
     190             :         {
     191           0 :             hsCom->FdCngSetup = FdCngSetup_wb1;
     192             :         }
     193             :         /* FFT 6.4kHz, CLDFB 8.0kHz */
     194           0 :         ELSE IF( LE_32( bitrate, ACELP_13k20 ) )
     195             :         {
     196           0 :             hsCom->FdCngSetup = FdCngSetup_wb2;
     197             :         }
     198             :         /* FFT 8.0kHz, no CLDFB */
     199             :         ELSE
     200             :         {
     201           0 :             hsCom->FdCngSetup = FdCngSetup_wb3;
     202             :         }
     203             :     }
     204             : 
     205             :     /* SWB/FB configuration */
     206             :     ELSE
     207             :     {
     208             :         /* FFT 6.4kHz, CLDFB 14kHz */
     209           3 :         IF( LE_32( bitrate, ACELP_13k20 ) )
     210             :         {
     211           1 :             hsCom->FdCngSetup = FdCngSetup_swb1;
     212             :         }
     213             :         /* FFT 8.0kHz, CLDFB 16kHz */
     214             :         ELSE
     215             :         {
     216           2 :             hsCom->FdCngSetup = FdCngSetup_swb2;
     217             :         }
     218             :     }
     219           3 :     hsCom->fftlen = hsCom->FdCngSetup.fftlen; /* Q0 */
     220           3 :     move16();
     221           3 :     hsEnc->stopFFTbinDec = hsCom->FdCngSetup.stopFFTbin; /* Q0 */
     222           3 :     move16();
     223             : 
     224             :     /* Configure the SID quantizer and the Confort Noise Generator */
     225             : 
     226           3 :     hsEnc->startBandDec = hsCom->startBand; /* Q0 */
     227           3 :     move16();
     228           3 :     hsEnc->stopBandDec = add( hsCom->FdCngSetup.sidPartitions[hsCom->FdCngSetup.numPartitions - 1], 1 ); /* Q0 */
     229           3 :     move16();
     230           3 :     initPartitions( hsCom->FdCngSetup.sidPartitions,
     231           3 :                     hsCom->FdCngSetup.numPartitions,
     232           3 :                     hsEnc->startBandDec,
     233           3 :                     hsEnc->stopBandDec,
     234           3 :                     hsEnc->partDec,
     235             :                     &hsEnc->npartDec,
     236           3 :                     hsEnc->midbandDec,
     237             :                     psizeDec,
     238             :                     psizeDec_norm,
     239             :                     &psizeDec_norm_exp,
     240             :                     psize_invDec,
     241             :                     0 );
     242           3 :     IF( EQ_16( hsEnc->stopFFTbinDec, 160 ) )
     243             :     {
     244           0 :         hsEnc->nFFTpartDec = 17;
     245           0 :         move16();
     246             :     }
     247           3 :     ELSE IF( EQ_16( hsEnc->stopFFTbinDec, 256 ) )
     248             :     {
     249           1 :         hsEnc->nFFTpartDec = 20;
     250           1 :         move16();
     251             :     }
     252             :     ELSE
     253             :     {
     254           2 :         hsEnc->nFFTpartDec = 21;
     255           2 :         move16();
     256             :     }
     257             : 
     258           3 :     SWITCH( hsCom->fftlen )
     259             :     {
     260           1 :         case 512:
     261           1 :             hsCom->fftlenShift = 8;
     262           1 :             move16();
     263           1 :             hsCom->fftlenFac = 32767 /*1.0 Q15*/;
     264           1 :             move16();
     265           1 :             BREAK;
     266           2 :         case 640:
     267           2 :             hsCom->fftlenShift = 9;
     268           2 :             move16();
     269           2 :             hsCom->fftlenFac = 20480 /*0.625 Q15*/;
     270           2 :             move16();
     271           2 :             BREAK;
     272           0 :         default:
     273           0 :             assert( !"Unsupported FFT length for FD-based CNG" );
     274             :             BREAK;
     275             :     }
     276           3 :     BASOP_getTables( &hsCom->olapWinAna, NULL, NULL, shr( hsCom->fftlen, 1 ) );
     277           3 :     BASOP_getTables( &hsCom->olapWinSyn, NULL, NULL, shr( hsCom->fftlen, 2 ) );
     278           3 :     hsCom->frameSize = shr( hsCom->fftlen, 1 );
     279           3 :     move16();
     280           3 : }
     281             : 
     282       35556 : void configureFdCngEnc_ivas_fx(
     283             :     HANDLE_FD_CNG_ENC hFdCngEnc, /* i/o: Contains the variables related to the FD-based CNG process */
     284             :     const Word16 bwidth,         /* Q0 */
     285             :     const Word32 total_brate     /* Q0 */
     286             : )
     287             : {
     288       35556 :     HANDLE_FD_CNG_COM hsCom = hFdCngEnc->hFdCngCom;
     289             :     Word16 psizeDec[NPART];
     290             :     Word16 psizeDec_norm[NPART];
     291             :     Word16 psizeDec_norm_exp;
     292             :     Word16 psize_invDec[NPART];
     293             : 
     294       35556 :     set16_fx( psizeDec, 0, NPART );
     295             : 
     296       35556 :     hsCom->CngBandwidth = bwidth; /* Q0 */
     297       35556 :     move16();
     298       35556 :     IF( EQ_16( hsCom->CngBandwidth, FB ) )
     299             :     {
     300       25861 :         hsCom->CngBandwidth = SWB;
     301       25861 :         move16();
     302             :     }
     303       35556 :     hsCom->CngBitrate = total_brate; /* Q0 */
     304       35556 :     move32();
     305             : 
     306             :     /* NB configuration */
     307       35556 :     IF( EQ_16( bwidth, NB ) )
     308             :     {
     309           0 :         hsCom->FdCngSetup = FdCngSetup_nb; /* PTR assignation -> no move needed*/
     310             :     }
     311             : 
     312             :     /* WB configuration */
     313       35556 :     ELSE IF( EQ_16( bwidth, WB ) )
     314             :     {
     315             :         /* FFT 6.4kHz, no CLDFB */
     316        3960 :         IF( LE_32( total_brate, ACELP_8k00 ) )
     317             :         {
     318           0 :             hsCom->FdCngSetup = FdCngSetup_wb1;
     319             :         }
     320             :         /* FFT 6.4kHz, CLDFB 8.0kHz */
     321        3960 :         ELSE IF( LE_32( total_brate, ACELP_13k20 ) )
     322             :         {
     323        1467 :             hsCom->FdCngSetup = FdCngSetup_wb2;
     324             :         }
     325             :         /* FFT 8.0kHz, no CLDFB */
     326             :         ELSE
     327             :         {
     328        2493 :             hsCom->FdCngSetup = FdCngSetup_wb3;
     329             :         }
     330             :     }
     331             : 
     332             :     /* SWB/FB configuration */
     333             :     ELSE
     334             :     {
     335             :         /* FFT 6.4kHz, CLDFB 14kHz */
     336       31596 :         IF( LE_32( total_brate, ACELP_13k20 ) )
     337             :         {
     338       17041 :             hsCom->FdCngSetup = FdCngSetup_swb1;
     339             :         }
     340             :         /* FFT 8.0kHz, CLDFB 16kHz */
     341             :         ELSE
     342             :         {
     343       14555 :             hsCom->FdCngSetup = FdCngSetup_swb2;
     344             :         }
     345             :     }
     346       35556 :     hsCom->fftlen = hsCom->FdCngSetup.fftlen; /* Q0 */
     347       35556 :     move16();
     348       35556 :     hFdCngEnc->stopFFTbinDec = hsCom->FdCngSetup.stopFFTbin; /* Q0 */
     349       35556 :     move16();
     350             : 
     351             :     /* Configure the SID quantizer and the Confort Noise Generator */
     352             : 
     353       35556 :     hFdCngEnc->startBandDec = hsCom->startBand; /* Q0 */
     354       35556 :     move16();
     355       35556 :     hFdCngEnc->stopBandDec = add( hsCom->FdCngSetup.sidPartitions[hsCom->FdCngSetup.numPartitions - 1], 1 ); /* Q0 */
     356       35556 :     move16();
     357       35556 :     initPartitions( hsCom->FdCngSetup.sidPartitions,
     358       35556 :                     hsCom->FdCngSetup.numPartitions,
     359       35556 :                     hFdCngEnc->startBandDec,
     360       35556 :                     hFdCngEnc->stopBandDec,
     361       35556 :                     hFdCngEnc->partDec,
     362             :                     &hFdCngEnc->npartDec,
     363       35556 :                     hFdCngEnc->midbandDec,
     364             :                     psizeDec,
     365             :                     psizeDec_norm,
     366             :                     &psizeDec_norm_exp,
     367             :                     psize_invDec,
     368             :                     0 );
     369       35556 :     IF( EQ_16( hFdCngEnc->stopFFTbinDec, 160 ) )
     370             :     {
     371           0 :         hFdCngEnc->nFFTpartDec = 17;
     372           0 :         move16();
     373             :     }
     374       35556 :     ELSE IF( EQ_16( hFdCngEnc->stopFFTbinDec, 256 ) )
     375             :     {
     376       18508 :         hFdCngEnc->nFFTpartDec = 20;
     377       18508 :         move16();
     378             :     }
     379             :     ELSE
     380             :     {
     381       17048 :         hFdCngEnc->nFFTpartDec = 21;
     382       17048 :         move16();
     383             :     }
     384             : 
     385       35556 :     SWITCH( hsCom->fftlen )
     386             :     {
     387       18508 :         case 512:
     388       18508 :             hsCom->fftSineTab_fx = NULL;
     389       18508 :             hsCom->olapWinAna_fx = olapWinAna512_fx; /* Q30 */
     390       18508 :             hsCom->olapWinSyn_fx = olapWinSyn256_fx; /* Q15 */
     391       18508 :             hsCom->fftlenShift = 8;
     392       18508 :             move16();
     393       18508 :             hsCom->fftlenFac = 32767 /*1.0 Q15*/;
     394       18508 :             move16();
     395       18508 :             BREAK;
     396       17048 :         case 640:
     397       17048 :             hsCom->fftSineTab_fx = fftSineTab640_fx; /* Q15 */
     398       17048 :             hsCom->olapWinAna_fx = olapWinAna640_fx; /* Q30 */
     399       17048 :             hsCom->olapWinSyn_fx = olapWinSyn320_fx; /* Q15 */
     400       17048 :             hsCom->fftlenShift = 9;
     401       17048 :             move16();
     402       17048 :             hsCom->fftlenFac = 20480 /*0.625 Q15*/;
     403       17048 :             move16();
     404       17048 :             BREAK;
     405           0 :         default:
     406           0 :             assert( !"Unsupported FFT length for FD-based CNG" );
     407             :             BREAK;
     408             :     }
     409       35556 :     BASOP_getTables( &hsCom->olapWinAna, NULL, NULL, shr( hsCom->fftlen, 1 ) );
     410       35556 :     BASOP_getTables( &hsCom->olapWinSyn, NULL, NULL, shr( hsCom->fftlen, 2 ) );
     411       35556 :     hsCom->frameSize = shr( hsCom->fftlen, 1 );
     412       35556 :     move16();
     413             : 
     414       35556 :     return;
     415             : }
     416             : 
     417             : /**************************************
     418             :  * Delete the instance of type FD_CNG *
     419             :  **************************************/
     420        8313 : void deleteFdCngEnc_fx( HANDLE_FD_CNG_ENC *hFdCngEnc )
     421             : {
     422             : 
     423             :     HANDLE_FD_CNG_ENC hsEnc;
     424        8313 :     hsEnc = *hFdCngEnc;
     425        8313 :     move16();
     426        8313 :     IF( hsEnc != NULL )
     427             :     {
     428         480 :         deleteFdCngCom_fx( &( hsEnc->hFdCngCom ) );
     429         480 :         free( hsEnc );
     430         480 :         *hFdCngEnc = NULL;
     431         480 :         move16();
     432             :     }
     433        8313 : }
     434             : 
     435             : 
     436      156230 : void resetFdCngEnc_fx(
     437             :     Encoder_State *st )
     438             : {
     439             :     Word16 tmpTest;
     440             :     Word16 n;
     441             :     Word16 totalNoiseIncrease;
     442      156230 :     Word16 thresh = 5 * 256; /*  5.0 in Q8 */
     443      156230 :     NOISE_EST_HANDLE hNoiseEst = st->hNoiseEst;
     444             : 
     445             :     /* st->totalNoise_fx;   Q8 Noise estimator - total noise energy */
     446             : 
     447             :     /* Detect fast increase of totalNoise */
     448      156230 :     totalNoiseIncrease = sub( hNoiseEst->totalNoise_fx, st->last_totalNoise_fx ); // Q8
     449      156230 :     st->last_totalNoise_fx = hNoiseEst->totalNoise_fx;                            // Q8
     450      156230 :     move16();
     451      156230 :     IF( totalNoiseIncrease > 0 )
     452             :     {
     453       14312 :         IF( EQ_16( st->totalNoise_increase_len, TOTALNOISE_HIST_SIZE ) )
     454             :         {
     455        5936 :             FOR( n = 0; n < TOTALNOISE_HIST_SIZE - 1; n++ )
     456             :             {
     457        4452 :                 st->totalNoise_increase_hist_fx[n] = st->totalNoise_increase_hist_fx[n + 1]; // Q8
     458        4452 :                 move16();
     459             :             }
     460        1484 :             st->totalNoise_increase_hist_fx[TOTALNOISE_HIST_SIZE - 1] = totalNoiseIncrease; // Q8
     461        1484 :             move16();
     462             :         }
     463             :         ELSE
     464             :         {
     465       12828 :             st->totalNoise_increase_hist_fx[st->totalNoise_increase_len] = totalNoiseIncrease; // Q8
     466       12828 :             move16();
     467       12828 :             st->totalNoise_increase_len = add( st->totalNoise_increase_len, 1 ); // Q0
     468             :         }
     469             :     }
     470             :     ELSE
     471             :     {
     472      141918 :         st->totalNoise_increase_len = 0;
     473      141918 :         move16();
     474             :     }
     475      156230 :     totalNoiseIncrease = 0;
     476      156230 :     move16();
     477      180873 :     FOR( n = 0; n < st->totalNoise_increase_len; n++ )
     478             :     {
     479       24643 :         totalNoiseIncrease = add( totalNoiseIncrease, st->totalNoise_increase_hist_fx[n] ); // Q8
     480             :     }
     481             : 
     482      156230 :     test();
     483      156230 :     test();
     484      156230 :     tmpTest = ( ( GT_16( totalNoiseIncrease, thresh ) ) && ( EQ_16( st->totalNoise_increase_len, TOTALNOISE_HIST_SIZE ) ) && ( GT_16( st->ini_frame, 150 ) ) );
     485             : 
     486      156230 :     test();
     487      156230 :     IF( tmpTest || ( GT_16( st->input_bwidth, st->last_input_bwidth ) ) || EQ_16( st->last_core, AMR_WB_CORE ) )
     488             :     {
     489         351 :         st->fd_cng_reset_flag = 1;
     490         351 :         move16();
     491         351 :         st->hFdCngEnc->hFdCngCom->msFrCnt_init_counter = 0;
     492         351 :         move16();
     493         351 :         st->hFdCngEnc->hFdCngCom->init_old = 32767;
     494         351 :         move16();
     495             :     }
     496      155879 :     ELSE IF( s_and( ( st->fd_cng_reset_flag > 0 ), (Word16) ( LT_16( st->fd_cng_reset_flag, 10 ) ) ) )
     497             :     {
     498        3132 :         st->fd_cng_reset_flag = add( st->fd_cng_reset_flag, 1 );
     499             :     }
     500             :     ELSE
     501             :     {
     502      152747 :         st->fd_cng_reset_flag = 0;
     503      152747 :         move16();
     504             :     }
     505      156230 : }
     506             : 
     507             : /*
     508             :    perform_noise_estimation_enc_fx
     509             : 
     510             :     Parameters:
     511             : 
     512             :     band_energies        i:   energy in critical bands without minimum noise floor MODE2_E_MIN
     513             :     band_energies_exp    i:   exponent for energy in critical bands without minimum noise floor MODE2_E_MIN
     514             :     cldfbBufferReal,     i:   real part of the CLDFB buffer
     515             :     cldfbBufferImag,     i:   imaginary part of the CLDFB buffer
     516             :     cldfbBufferExp,      i:   exponent for CLDFB buffer
     517             :     bitrate              i:   bitrate
     518             :     st                   i/o: FD_CNG structure containing all buffers and variables
     519             : 
     520             :     Function:
     521             :     Perform noise estimation
     522             : 
     523             :     Returns:
     524             :     void
     525             : */
     526        3100 : void perform_noise_estimation_enc_fx( Word32 *band_energies,    /* i: energy in critical bands without minimum noise floor MODE2_E_MIN          band_energies_exp*/
     527             :                                       Word16 band_energies_exp, /* i: exponent for energy in critical bands without minimum noise floor MODE2_E_MIN */
     528             :                                       Word32 *enerBuffer,       /* enerBuffer_exp */
     529             :                                       Word16 enerBuffer_exp,
     530             :                                       HANDLE_FD_CNG_ENC st /* i/o: FD_CNG structure containing all buffers and variables */
     531             : )
     532             : {
     533             :     Word16 i, j, s, s1, s2;
     534             :     Word16 nFFTpart;
     535             :     Word16 nCLDFBpart;
     536             :     Word16 numBands;
     537             :     Word16 numCoreBands;
     538             :     Word16 regularStopBand;
     539             :     Word16 numSlots;
     540             :     Word32 tmp;
     541             :     Word32 *periodog;
     542             :     Word32 *ptr_per;
     543             :     Word32 *msPeriodog;
     544             : 
     545             : 
     546        3100 :     nFFTpart = st->hFdCngCom->nFFTpart;
     547        3100 :     move16();
     548        3100 :     nCLDFBpart = st->hFdCngCom->nCLDFBpart;
     549        3100 :     move16();
     550        3100 :     numCoreBands = st->hFdCngCom->numCoreBands;
     551        3100 :     move16();
     552        3100 :     regularStopBand = st->hFdCngCom->regularStopBand;
     553        3100 :     move16();
     554        3100 :     numSlots = st->hFdCngCom->numSlots;
     555        3100 :     move16();
     556        3100 :     periodog = st->hFdCngCom->periodog;
     557        3100 :     move16();
     558        3100 :     ptr_per = periodog;
     559        3100 :     move16();
     560        3100 :     msPeriodog = st->msPeriodog_fx;
     561        3100 :     move16();
     562             : 
     563        3100 :     assert( numSlots == 16 );
     564             : 
     565             :     /* preemphasis compensation and grouping of per bin energies into msPeriodog */
     566       65100 :     FOR( i = 0; i < nFFTpart; i++ )
     567             :     {
     568       62000 :         tmp = L_add( L_shr( band_energies[i], 1 ), L_shr( band_energies[i + NB_BANDS], 1 ) ); /* exp(band_energies_exp) */
     569       62000 :         msPeriodog[i] = Mpy_32_16_1( tmp, preemphCompensation_fx[i] );                        /* exp(band_energies_exp + 4) */
     570       62000 :         move32();
     571             :     }
     572             : 
     573             :     /* exponent for fft part of msPeriodog */
     574        3100 :     st->msPeriodog_fx_exp_fft = add( band_energies_exp, PREEMPH_COMPENSATION_EXP );
     575        3100 :     move16();
     576             : 
     577        3100 :     numBands = sub( regularStopBand, numCoreBands ); /* Q0 */
     578             : 
     579        3100 :     IF( numBands > 0 )
     580             :     {
     581             :         /* Adjust to the desired time resolution by averaging the periodograms over the CLDFB time slots */
     582             : 
     583       77500 :         FOR( j = numCoreBands; j < regularStopBand; j++ )
     584             :         {
     585       74400 :             *ptr_per = Mpy_32_16_1( enerBuffer[j], st->hFdCngCom->scalingFactor ); /* exp(enerBuffer_exp) */
     586       74400 :             move32();
     587             : 
     588       74400 :             ptr_per++;
     589             :         }
     590             : 
     591             :         /* exponent for cldfb part of msPeriodog */
     592        3100 :         st->hFdCngCom->exp_cldfb_periodog = add( sub( enerBuffer_exp, 4 ), CLDFBscalingFactor_EXP );
     593             : 
     594             :         /* Adjust CLDFB filterbank to the desired frequency resolution by averaging over spectral partitions for SID transmission */
     595        3100 :         bandcombinepow(
     596             :             periodog,
     597        3100 :             st->hFdCngCom->exp_cldfb_periodog,
     598             :             numBands,
     599        3100 :             st->hFdCngCom->CLDFBpart,
     600        3100 :             st->hFdCngCom->nCLDFBpart,
     601        3100 :             st->hFdCngCom->CLDFBpsize_inv,
     602        3100 :             &msPeriodog[nFFTpart],
     603             :             &st->msPeriodog_fx_exp_cldfb );
     604             : 
     605             :         /* find common exponent for fft part and cldfb part of msperiodog */
     606        3100 :         s1 = getScaleFactor32( msPeriodog, nFFTpart );
     607        3100 :         s2 = getScaleFactor32( &msPeriodog[nFFTpart], nCLDFBpart );
     608             : 
     609        3100 :         s = s_max( sub( st->msPeriodog_fx_exp_fft, s1 ), sub( st->msPeriodog_fx_exp_cldfb, s2 ) );
     610        3100 :         s1 = sub( s, st->msPeriodog_fx_exp_fft );
     611        3100 :         s2 = sub( s, st->msPeriodog_fx_exp_cldfb );
     612             : 
     613        3100 :         st->msPeriodog_fx_exp_fft = s;
     614        3100 :         move16();
     615        3100 :         st->msPeriodog_fx_exp_cldfb = s;
     616        3100 :         move16();
     617             : 
     618       65100 :         FOR( i = 0; i < nFFTpart; i++ )
     619             :         {
     620       62000 :             msPeriodog[i] = L_shr( msPeriodog[i], s1 ); // st->msPeriodog_fx_exp_fft
     621       62000 :             move32();
     622             :         }
     623             : 
     624       15500 :         FOR( i = 0; i < nCLDFBpart; i++ )
     625             :         {
     626       12400 :             msPeriodog[nFFTpart + i] = L_shr( msPeriodog[nFFTpart + i], s_min( 31, s2 ) ); // st->msPeriodog_fx_exp_fft
     627       12400 :             move32();
     628             :         }
     629             :     }
     630             : 
     631             :     /* exponent for entire msPeriodog vector */
     632        3100 :     st->msPeriodog_fx_exp = st->msPeriodog_fx_exp_fft;
     633        3100 :     move16();
     634             : 
     635             :     /* Compress MS inputs */
     636        3100 :     compress_range( st->msPeriodog_fx, st->msPeriodog_fx_exp, st->msLogPeriodog_fx, st->hFdCngCom->npart );
     637             : 
     638             :     /* Call the minimum statistics routine for noise estimation */
     639        3100 :     minimum_statistics(
     640        3100 :         st->hFdCngCom->npart,
     641        3100 :         st->hFdCngCom->nFFTpart,
     642        3100 :         st->hFdCngCom->psize_norm,
     643        3100 :         st->msLogPeriodog_fx,
     644        3100 :         st->msNoiseFloor_fx,
     645        3100 :         st->msLogNoiseEst_fx,
     646        3100 :         st->msAlpha_fx,
     647        3100 :         st->msPsd_fx,
     648        3100 :         st->msPsdFirstMoment_fx,
     649        3100 :         st->msPsdSecondMoment_fx,
     650        3100 :         st->msMinBuf_fx,
     651        3100 :         st->msBminWin_fx,
     652        3100 :         st->msBminSubWin_fx,
     653        3100 :         st->msCurrentMin_fx,
     654        3100 :         st->msCurrentMinOut_fx,
     655        3100 :         st->msCurrentMinSubWindow_fx,
     656        3100 :         st->msLocalMinFlag,
     657        3100 :         st->msNewMinFlag,
     658        3100 :         st->msPeriodogBuf_fx,
     659             :         &( st->msPeriodogBufPtr ),
     660             :         st->hFdCngCom );
     661             : 
     662             :     /* Expand MS outputs */
     663        3100 :     expand_range( st->msLogNoiseEst_fx, st->msNoiseEst_fx, &st->msNoiseEst_fx_exp, st->hFdCngCom->npart );
     664        3100 : }
     665             : 
     666             : /*
     667             :    AdjustFirstSID_fx
     668             : 
     669             :     Parameters:
     670             : 
     671             :     npart                   i    : number of parts
     672             :     msPeriodog              i    : pointer to periodog vector
     673             :     msPeriodog_exp          i    : exponent of periodog vector
     674             :     energy_ho               i/o  : pointer to energy
     675             :     energy_ho_exp           i/o  : pointer to exponent of energy
     676             :     msNoiseEst              i/o  : pointer to estimated noise
     677             :     msNoiseEst_exp          i/o  : pointer to exponent of estimated noise
     678             :     msNoiseEst_old          i/o  : pointer to old estimated noise
     679             :     msNoiseEst_old_exp      i/o  : pointer to exponent of old estimated noise
     680             :     active_frame_counter    i/o  : pointer to active frame counter
     681             :     stcod                   i    : pointer to Coder_State structure
     682             : 
     683             :     Function:
     684             :     Adjust the noise estimator at the beginning of each CNG phase (encoder-side)
     685             : 
     686             :     Returns:
     687             :     void
     688             : */
     689      121162 : Word16 AdjustFirstSID_fx(
     690             :     Word16 npart,                 /* i    : number of parts                                                             Q0*/
     691             :     Word32 *msPeriodog,           /* i    : pointer to periodog vector                                  msPeriodog_exp  */
     692             :     Word16 msPeriodog_exp,        /* i    : exponent of periodog vector                                 */
     693             :     Word32 *energy_ho,            /* i/o  : pointer to energy                                                   energy_ho_exp*/
     694             :     Word16 *energy_ho_exp,        /* i/o  : pointer to exponent of energy                               */
     695             :     Word32 *msNoiseEst,           /* i/o  : pointer to estimated noise                                  msNoiseEst_exp*/
     696             :     Word16 *msNoiseEst_exp,       /* i/o  : pointer to exponent of estimated noise              */
     697             :     Word32 *msNoiseEst_old,       /* i/o  : pointer to old estimated noise                              msNoiseEst_old_exp*/
     698             :     Word16 *msNoiseEst_old_exp,   /* i/o  : pointer to exponent of old estimated noise  */
     699             :     Word16 *active_frame_counter, /* i/o  : pointer to active frame counter                             Q0*/
     700             :     Encoder_State *stcod          /* i    : pointer to Coder_State_Plus structure               */
     701             : )
     702             : {
     703             :     Word16 i, sc, s1, s2, lambda, lambdaM1, invFac;
     704             :     Word32 tmp32, energy_ho_local, msNoiseEst_local;
     705      121162 :     DTX_ENC_HANDLE hDtxEnc = stcod->hDtxEnc;
     706             : 
     707      121162 :     test();
     708      121162 :     IF( EQ_16( hDtxEnc->cnt_SID, 1 ) && GT_32( stcod->last_core_brate, SID_2k40 ) )
     709             :     {
     710             :         /* Detect the hangover period and the first SID frame at the beginning of each CNG phase */
     711             : 
     712             :         /* First hangover frame */
     713        2889 :         Copy32( msPeriodog, energy_ho, npart ); /* exp(msPeriodog_exp) */
     714        2889 :         *energy_ho_exp = msPeriodog_exp;
     715        2889 :         move16();
     716             : 
     717             :         /* Set first SID to current input level but add some smoothing */
     718        2889 :         IF( GE_16( *active_frame_counter, 254 ) )
     719             :         {
     720           5 :             lambda = 0;
     721           5 :             move16();
     722           5 :             lambdaM1 = 0x7FFF;
     723           5 :             move16();
     724             :         }
     725             :         ELSE
     726             :         {
     727             :             /* -0.94229902485 = 1024.0*log10(0.96)/log10(2.0)/64.0 */
     728             :             /* active_frame_counter scaled by (1/1024.0) for compensation */
     729        2884 :             tmp32 = L_shl( L_deposit_l( add( *active_frame_counter, 1 ) ), WORD32_BITS - 1 - 10 );
     730        2884 :             tmp32 = BASOP_Util_InvLog2( Mpy_32_16_1( tmp32, -30877 /*-0.94229902485 Q15*/ ) );
     731        2884 :             lambda = extract_h( tmp32 ); /* Q15 */
     732        2884 :             lambdaM1 = extract_h( L_sub( 0x7FFFFFFF /* 1.0f in Q31*/, tmp32 ) );
     733             :         }
     734             : 
     735        2889 :         invFac = getNormReciprocalWord16( 1 );
     736             : 
     737             :         /* one bit headroom for addition */
     738        2889 :         sc = add( s_max( *msNoiseEst_old_exp, *energy_ho_exp ), 1 );
     739        2889 :         s1 = limitScale32( sub( sc, *msNoiseEst_old_exp ) );
     740        2889 :         s2 = limitScale32( sub( sc, *energy_ho_exp ) );
     741        2889 :         *energy_ho_exp = sc;
     742        2889 :         move16();
     743             : 
     744       70566 :         FOR( i = 0; i < npart; i++ )
     745             :         {
     746       67677 :             msNoiseEst_old[i] = Mpy_32_16_1( msNoiseEst_old[i], lambda ); /* exp(msNoiseEst_old) */
     747       67677 :             move32();
     748       67677 :             tmp32 = Mpy_32_16_1( Mpy_32_16_1( energy_ho[i], invFac ), lambdaM1 );
     749       67677 :             energy_ho[i] = L_add( L_shr( msNoiseEst_old[i], s1 ), L_shr( tmp32, s2 ) );
     750       67677 :             move32();
     751             :         }
     752             : 
     753        2889 :         sc = s_max( *msNoiseEst_exp, *energy_ho_exp );
     754        2889 :         s1 = limitScale32( sub( sc, *msNoiseEst_exp ) );
     755        2889 :         s2 = limitScale32( sub( sc, *energy_ho_exp ) );
     756        2889 :         *msNoiseEst_exp = sc;
     757        2889 :         move16();
     758             : 
     759        2889 :         tmp32 = 0;
     760        2889 :         move32();
     761       70566 :         FOR( i = 0; i < npart; i++ )
     762             :         {
     763       67677 :             msNoiseEst_local = L_shr( msNoiseEst[i], s1 ); /* exp(msNoiseEst + s1) */
     764       67677 :             energy_ho_local = L_shr( energy_ho[i], s2 );   /* exp(energy_ho_exp + s2) */
     765       67677 :             IF( GT_32( msNoiseEst_local, energy_ho_local ) )
     766             :             {
     767       38025 :                 msNoiseEst[i] = energy_ho_local; /* exp(energy_ho_exp + s2) */
     768       38025 :                 move32();
     769             :             }
     770             :             ELSE
     771             :             {
     772       29652 :                 msNoiseEst[i] = msNoiseEst_local; /* exp(energy_ho_exp + s2) */
     773       29652 :                 move32();
     774             :             }
     775       67677 :             if ( msNoiseEst[i] > 0 )
     776             :             {
     777       63317 :                 tmp32 = 1;
     778       63317 :                 move32();
     779             :             }
     780             :         }
     781             :         /* Set exponent to zero if msNoiseEst is zero */
     782        2889 :         if ( tmp32 == 0 )
     783             :         {
     784         174 :             *msNoiseEst_exp = 0;
     785         174 :             move16();
     786             :         }
     787             : 
     788        2889 :         *active_frame_counter = 0;
     789        2889 :         move16();
     790             :     }
     791      121162 :     test();
     792      121162 :     IF( NE_32( stcod->core_brate, SID_2k40 ) && NE_32( stcod->core_brate, FRAME_NO_DATA ) )
     793             :     {
     794             :         /* Count the number of active frames in a row */
     795       90037 :         *active_frame_counter = add( *active_frame_counter, 1 ); /* Q0 */
     796       90037 :         move16();
     797             :     }
     798             :     ELSE
     799             :     {
     800             :         /* Store the noise estimate obtained in the CNG phases */
     801       31125 :         Copy32( msNoiseEst, msNoiseEst_old, npart ); /* exp(msNoiseEst_exp) */
     802       31125 :         *msNoiseEst_old_exp = *msNoiseEst_exp;
     803       31125 :         move16();
     804             :     }
     805             : 
     806             : 
     807      121162 :     return 0;
     808             : }
     809             : 
     810             : 
     811             : /*
     812             :    msvq_encoder
     813             : 
     814             :     Parameters:
     815             : 
     816             :     cb               i  : Codebook (indexed cb[stages][levels][p]) format Q9.7
     817             :     u[]              i  : Vector to be encoded (prediction and mean removed) format Q9.7
     818             :     levels           i  : Number of levels in each stage
     819             :     maxC             i  : Tree search size
     820             :     stages           i  : Number of stages
     821             :     N                i  : Vector dimension
     822             :     maxN             i  : Codebook vector dimension
     823             :     Idx              o  : Indices
     824             : 
     825             : 
     826             :     Function:
     827             :     multi stage vector quantisation
     828             : 
     829             :     Returns:
     830             :     void
     831             : */
     832           0 : static void msvq_encoder( const Word16 *const cb[], /* i  : Codebook (indexed cb[*stages][levels][p]) scaled with 8 bits Q9.7*/
     833             :                           Word16 u[],               /* i  : Vector to be encoded (prediction and mean removed)                   Q9.7*/
     834             :                           const Word16 levels[],    /* i  : Number of levels in each stage                               Q0*/
     835             :                           Word16 maxC,              /* i  : Tree search size                                             Q0*/
     836             :                           Word16 stages,            /* i  : Number of stages                                             Q0*/
     837             :                           Word16 N,                 /* i  : Vector dimension                                             Q0*/
     838             :                           Word16 maxN,              /* i  : Codebook vector dimension                                    Q0*/
     839             :                           Word16 Idx[]              /* o  : Indices                                                      Q0*/
     840             : )
     841             : {
     842             :     Word32 *dist[2];
     843             :     Word32 t1, en, ss2, tmp;
     844             :     const Word16 *cbp, *cb_stage, *p2;
     845             :     Word16 *p1, *pTmp;
     846             :     Word16 *indices[2], *resid[2], Tmp[M_MAX];
     847             :     Word16 i, j, m, s, c, c2, p_max;
     848             :     Word16 parents[MBEST_MAX];
     849             :     Word32 dist_buf[2 * MBEST_MAX];
     850             :     Word16 resid_buf[2 * MBEST_MAX * M_MAX];
     851             :     Word16 idx_buf[2 * MBEST_MAX * NSTAGES_MAX];
     852             : 
     853             : 
     854             :     /*----------------------------------------------------------------*
     855             :      * Allocate memory for previous (parent) and current nodes.
     856             :      *   Parent node is indexed [0], current node is indexed [1].
     857             :      *----------------------------------------------------------------*/
     858             : 
     859           0 :     indices[0] = idx_buf;
     860           0 :     indices[1] = idx_buf + maxC * stages;
     861           0 :     set16_fx( idx_buf, 0, 2 * stages * maxC );
     862             : 
     863           0 :     resid[0] = resid_buf;
     864           0 :     resid[1] = resid_buf + maxC * N;
     865             : 
     866           0 :     dist[0] = dist_buf;
     867           0 :     dist[1] = dist_buf + maxC;
     868             : 
     869           0 :     set16_fx( parents, 0, maxC );
     870             : 
     871             :     /*----------------------------------------------------------------*
     872             :      * ISF weights are normalized, so it is always better to multiply it first
     873             :      * Set up inital distance vector
     874             :      *----------------------------------------------------------------*/
     875             : 
     876           0 :     ss2 = L_mult( u[0], u[0] );
     877           0 :     FOR( j = 1; j < N; j++ )
     878             :     {
     879           0 :         ss2 = L_mac( ss2, u[j], u[j] );
     880             :     }
     881             : 
     882           0 :     FOR( j = 0; j < maxC; j++ )
     883             :     {
     884           0 :         dist[1][j] = ss2;
     885           0 :         move32();
     886             :     }
     887             : 
     888             :     /* Set up inital error (residual) vectors */
     889           0 :     pTmp = resid[1];
     890           0 :     FOR( c = 0; c < maxC; c++ )
     891             :     {
     892           0 :         FOR( j = 0; j < N; j++ )
     893             :         {
     894           0 :             *pTmp++ = u[j];
     895           0 :             move16();
     896             :         }
     897             :     }
     898             : 
     899             :     /* Loop over all stages */
     900           0 :     m = 1;
     901           0 :     move16();
     902           0 :     FOR( s = 0; s < stages; s++ )
     903             :     {
     904           0 :         cbp = cb[s];
     905             : 
     906             :         /* Save pointer to beginning of current stage */
     907           0 :         cb_stage = cbp;
     908             : 
     909             :         /* Set up pointers to parent and current nodes */
     910           0 :         swap( indices[0], indices[1], Word16 * );
     911           0 :         swap( resid[0], resid[1], Word16 * );
     912           0 :         swap( dist[0], dist[1], Word32 * );
     913             : 
     914             :         /* p_max points to maximum distortion node (worst of best) */
     915           0 :         p_max = 0;
     916           0 :         move16();
     917             : 
     918             :         /* Set distortions to a large value */
     919           0 :         FOR( j = 0; j < maxC; j++ )
     920             :         {
     921           0 :             dist[1][j] = MAXVAL_WORD32;
     922           0 :             move32();
     923             :         }
     924             : 
     925           0 :         FOR( j = 0; j < levels[s]; j++ )
     926             :         {
     927             :             /* Compute weighted codebook element and its energy */
     928           0 :             Tmp[0] = cbp[0];
     929           0 :             move16();
     930           0 :             en = L_mult( cbp[0], cbp[0] );
     931           0 :             FOR( i = 1; i < N; i++ )
     932             :             {
     933           0 :                 Tmp[i] = cbp[i];
     934           0 :                 move16();
     935           0 :                 en = L_mac( en, cbp[i], cbp[i] );
     936             :             }
     937             : 
     938           0 :             cbp += maxN;
     939             : 
     940             :             /* Iterate over all parent nodes */
     941           0 :             FOR( c = 0; c < m; c++ )
     942             :             {
     943           0 :                 pTmp = &resid[0][c * N];
     944             : 
     945           0 :                 t1 = L_mult( pTmp[0], Tmp[0] );
     946           0 :                 FOR( i = 1; i < N; i++ )
     947             :                 {
     948           0 :                     t1 = L_mac( t1, pTmp[i], Tmp[i] );
     949             :                 }
     950             : 
     951           0 :                 tmp = L_add( dist[0][c], L_sub( en, L_shl( t1, 1 ) ) );
     952             : 
     953             :                 BASOP_SATURATE_WARNING_OFF_EVS
     954           0 :                 t1 = L_sub_sat( tmp, dist[1][p_max] );
     955             :                 BASOP_SATURATE_WARNING_ON_EVS
     956           0 :                 IF( t1 <= 0 )
     957             :                 /* IF (L_sub(L_shr(tmp,1), L_shr(dist[1][p_max],1) ) <= 0 ) */
     958             :                 {
     959             :                     /* Replace worst */
     960           0 :                     dist[1][p_max] = tmp;
     961           0 :                     move32();
     962           0 :                     indices[1][p_max * stages + s] = j;
     963           0 :                     move16();
     964           0 :                     parents[p_max] = c;
     965           0 :                     move16();
     966             : 
     967           0 :                     p_max = 0;
     968           0 :                     move16();
     969             : 
     970           0 :                     FOR( i = 1; i < maxC; i++ )
     971             :                     {
     972           0 :                         if ( GT_32( dist[1][i], dist[1][p_max] ) )
     973             :                         {
     974           0 :                             p_max = i;
     975           0 :                             move16();
     976             :                         }
     977             :                     }
     978             :                 }
     979             :             }
     980             :         } /* FOR (j=0; j<levels[s]; j++) */
     981             : 
     982             :         /*------------------------------------------------------------*
     983             :          * Compute error vectors for each node
     984             :          *------------------------------------------------------------*/
     985           0 :         pTmp = resid[1];
     986             : 
     987           0 :         FOR( c = 0; c < maxC; c++ )
     988             :         {
     989             :             /* Subtract codebook entry from residual vector of parent node and multiply with scale factor */
     990           0 :             p1 = resid[0] + parents[c] * N;
     991           0 :             p2 = cb_stage + ( indices[1][c * stages + s] ) * maxN;
     992             : 
     993           0 :             FOR( j = 0; j < N; j++ )
     994             :             {
     995           0 :                 pTmp[j] = sub( p1[j], p2[j] );
     996           0 :                 move16();
     997             :             }
     998           0 :             pTmp += N;
     999             : 
    1000             :             /* Get indices that were used for parent node */
    1001           0 :             Copy( indices[0] + parents[c] * stages, indices[1] + c * stages, s ); // Q0
    1002             :         }
    1003           0 :         m = maxC;
    1004           0 :         move16();
    1005             :     } /* FOR (s=0; s<stages; s++) */
    1006             : 
    1007             :     /* Find the optimum candidate (search for minimum) */
    1008           0 :     c2 = 0;
    1009           0 :     move16();
    1010           0 :     FOR( i = 1; i < maxC; i++ )
    1011             :     {
    1012           0 :         if ( LT_32( dist[1][i], dist[1][c2] ) )
    1013             :         {
    1014           0 :             c2 = i;
    1015           0 :             move16();
    1016             :         }
    1017             :     }
    1018             : 
    1019           0 :     Copy( indices[1] + c2 * stages, Idx, stages );
    1020           0 : }
    1021             : 
    1022             : 
    1023             : /*
    1024             :    FdCng_encodeSID_fx
    1025             : 
    1026             :     Parameters:
    1027             : 
    1028             :     stenc               i/o: pointer to FD_CNG structure containing all buffers and variables
    1029             :     bitstream           o  : pointer to bitstream
    1030             :     total_nbbits        o  : pointer to total number of encoded bits
    1031             :     bitrate             i  : bitrate
    1032             :     amrwb_io            i  : amr wideband mode
    1033             :     preemph_fac         i  : preemphase factor
    1034             : 
    1035             : 
    1036             :     Function:
    1037             :     Generate a bitstream out of the partition levels
    1038             : 
    1039             :     Returns:
    1040             :     void
    1041             : */
    1042           0 : void FdCng_encodeSID_fx( HANDLE_FD_CNG_ENC stenc, /* i/o: pointer to FD_CNG structure containing all buffers and variables */
    1043             :                          Encoder_State *corest,
    1044             :                          Word16 preemph_fac /* i  : preemphase factor */
    1045             : )
    1046             : {
    1047             :     Word16 i, index, N;
    1048             :     Word16 E_Exp, normFacN, normShiftN;
    1049             :     Word16 normFacGain, normShiftGain, sidNoiseEst_Exp;
    1050             : 
    1051             :     Word32 tmp, gain, e, maxVal;
    1052             :     Word32 *E, E_ExpLd64;
    1053             :     Word32 v[32];
    1054             : 
    1055             :     Word16 indices[32];
    1056             :     Word16 v16[32];
    1057           0 :     BSTR_ENC_HANDLE hBstr = corest->hBstr;
    1058             :     HANDLE_FD_CNG_COM st;
    1059           0 :     Word16 maxC_37bits = FD_CNG_maxC_37bits, stages_37bits = FD_CNG_stages_37bits, maxN_37bits = FD_CNG_maxN_37bits;
    1060             : 
    1061             :     /* Init */
    1062           0 :     st = stenc->hFdCngCom;
    1063             : 
    1064           0 :     E_Exp = stenc->msNoiseEst_fx_exp;
    1065           0 :     move16();
    1066           0 :     E_ExpLd64 = L_shl( E_Exp, WORD32_BITS - 1 - LD_DATA_SCALE );
    1067           0 :     E = stenc->msNoiseEst_fx;
    1068             : 
    1069           0 :     N = stenc->npartDec;
    1070           0 :     move16();
    1071             : 
    1072           0 :     normFacN = getNormReciprocalWord16( N );
    1073           0 :     normShiftN = BASOP_util_norm_s_bands2shift( N );
    1074             : 
    1075           0 :     normFacGain = getNormReciprocalWord16( N_GAIN_MAX - N_GAIN_MIN );
    1076           0 :     normShiftGain = BASOP_util_norm_s_bands2shift( N_GAIN_MAX - N_GAIN_MIN );
    1077             : 
    1078             :     /* Convert to LOG */
    1079             : 
    1080             :     /* e: Q14.23 format, v: Q9.23 format */
    1081           0 :     e = L_deposit_l( 0 );
    1082           0 :     tmp = Mpy_32_32_r( L_shl( 1, sub( 31, E_Exp ) ), 214748 ); /* 1e-4f, Q31-E_Exp */
    1083           0 :     FOR( i = 0; i < N; i++ )
    1084             :     {
    1085             :         /* assert( E[i] != 0 ); */
    1086             :         /* constant: 0.75257498916 = 10.0 * log10(2.0)/log10(10.0) * 0.25 */
    1087           0 :         v[i] = Mpy_32_16_1( L_add( BASOP_Util_Log2( L_add( E[i], L_max( 1, tmp ) ) ), E_ExpLd64 ), 24660 /*0.75257498916 Q15*/ );
    1088           0 :         move32();
    1089           0 :         e = L_add( e, L_shr( v[i], normShiftN ) );
    1090             :     }
    1091           0 :     e = L_shl( Mpy_32_16_1( e, shl( normFacN, sub( normShiftN, 1 ) ) ), 1 );
    1092             : 
    1093             : 
    1094             :     /* Normalize MSVQ input */
    1095             : 
    1096             :     /* gain: Q9.23 format */
    1097           0 :     gain = L_deposit_l( 0 );
    1098           0 :     FOR( i = N_GAIN_MIN; i < N_GAIN_MAX; i++ )
    1099             :     {
    1100           0 :         gain = L_add( gain, L_shr( v[i], normShiftGain ) );
    1101             :     }
    1102           0 :     gain = L_shl( Mpy_32_16_1( gain, shl( normFacGain, sub( normShiftGain, 1 ) ) ), 1 );
    1103             : 
    1104           0 :     FOR( i = 0; i < N; i++ )
    1105             :     {
    1106           0 :         v16[i] = extract_h( L_sub( v[i], gain ) );
    1107             :     }
    1108             : 
    1109             :     {
    1110             :         /* MSVQ encoder */
    1111           0 :         msvq_encoder( cdk_37bits, v16, levels_37bits, maxC_37bits, stages_37bits, N, maxN_37bits, indices );
    1112             : 
    1113             :         /* MSVQ decoder */
    1114           0 :         msvq_decoder( cdk_37bits, stages_37bits, N, maxN_37bits, indices, v16 );
    1115             :     }
    1116           0 :     FOR( i = 0; i < N; i++ )
    1117             :     {
    1118           0 :         v[i] = L_deposit_h( v16[i] );
    1119             :     }
    1120             : 
    1121             : 
    1122             :     /* Compute gain, Q9.23 format */
    1123           0 :     gain = 0;
    1124           0 :     FOR( i = 0; i < N; i++ )
    1125             :     {
    1126           0 :         gain = L_add( gain, L_shr( v[i], normShiftN ) );
    1127             :     }
    1128           0 :     gain = L_sub( e, L_shl( Mpy_32_16_1( gain, shl( normFacN, sub( normShiftN, 1 ) ) ), 1 ) );
    1129             : 
    1130             : 
    1131             :     /* Apply bitrate-dependant scale */
    1132             :     {
    1133           0 :         apply_scale( &gain, st->CngBandwidth, st->CngBitrate, scaleTableMono, SIZE_SCALE_TABLE_MONO );
    1134             :     }
    1135             : 
    1136             :     /* Quantize gain, Q14.23 format */
    1137           0 :     gain = L_add( gain, L_shr( gain, 1 ) );
    1138           0 :     gain = L_add( gain, 507510784l /*60.5 Q23*/ );
    1139           0 :     index = extract_l( L_shr( gain, WORD32_BITS - 1 - 8 ) );
    1140             : 
    1141           0 :     if ( index < 0 )
    1142             :     {
    1143           0 :         index = 0;
    1144           0 :         move16();
    1145             :     }
    1146             : 
    1147           0 :     if ( GT_16( index, 127 ) )
    1148             :     {
    1149           0 :         index = 127;
    1150           0 :         move16();
    1151             :     }
    1152             : 
    1153             :     /* gain Q14.23 format */
    1154           0 :     gain = L_shl( L_deposit_l( index ), WORD32_BITS - 1 - 8 );
    1155           0 :     gain = L_sub( gain, 503316480l /*60.0 Q23*/ );
    1156           0 :     gain = Mpy_32_16_1( gain, 21845 /*2.0f/3.0f Q15*/ );
    1157             : 
    1158             :     /* Apply gain and undo log */
    1159             : 
    1160             :     /* sidNoiseEst: format Q6.26, 0.66438561897 = log10(10)/log10(2.0) / 10.0 * 2.0 */
    1161             : 
    1162             :     /* calculate worst case for scaling */
    1163           0 :     maxVal = 0x80000000 /*-1.0 Q31*/;
    1164           0 :     move32();
    1165           0 :     FOR( i = 0; i < N; i++ )
    1166             :     {
    1167           0 :         maxVal = L_max( maxVal, v[i] );
    1168             :     }
    1169             : 
    1170           0 :     maxVal = L_add( maxVal, gain );
    1171           0 :     maxVal = L_shl( Mpy_32_16_1( maxVal, 21771 /*0.66438561897 Q15*/ ), 1 );
    1172             :     // PMT("st must be replaced by hFdCngCom")
    1173           0 :     sidNoiseEst_Exp = 0;
    1174           0 :     move16();
    1175           0 :     WHILE( maxVal >= 0 )
    1176             :     {
    1177           0 :         maxVal = L_sub( maxVal, 33554432l /*0.015625 Q31*/ );
    1178           0 :         sidNoiseEst_Exp = add( sidNoiseEst_Exp, 1 );
    1179             :     }
    1180           0 :     st->sidNoiseEstExp = sidNoiseEst_Exp;
    1181           0 :     move16();
    1182           0 :     E_ExpLd64 = L_shl( sidNoiseEst_Exp, WORD32_BITS - 1 - LD_DATA_SCALE );
    1183             : 
    1184           0 :     FOR( i = 0; i < N; i++ )
    1185             :     {
    1186           0 :         tmp = L_add( v[i], gain );
    1187           0 :         tmp = L_shl( Mpy_32_16_1( tmp, 21771 /*0.66438561897 Q15*/ ), 1 );
    1188           0 :         tmp = L_sub( tmp, E_ExpLd64 );
    1189           0 :         assert( tmp < 0 );
    1190           0 :         st->sidNoiseEst[i] = BASOP_Util_InvLog2( tmp );
    1191           0 :         move32();
    1192             :     }
    1193             : 
    1194             :     /* NB last band energy compensation */
    1195           0 :     IF( EQ_16( st->CngBandwidth, NB ) )
    1196             :     {
    1197           0 :         st->sidNoiseEst[N - 1] = Mpy_32_16_1( st->sidNoiseEst[N - 1], NB_LAST_BAND_SCALE );
    1198           0 :         move32();
    1199             :     }
    1200             : 
    1201           0 :     test();
    1202           0 :     if ( EQ_16( st->CngBandwidth, SWB ) && LE_32( st->CngBitrate, ACELP_13k20 ) )
    1203             :     {
    1204           0 :         st->sidNoiseEst[N - 1] = Mpy_32_16_1( st->sidNoiseEst[N - 1], SWB_13k2_LAST_BAND_SCALE );
    1205           0 :         move32();
    1206             :     }
    1207             : 
    1208             : 
    1209             :     /* Write bitstream */
    1210           0 :     IF( EQ_16( corest->codec_mode, MODE2 ) )
    1211             :     {
    1212           0 :         FOR( i = 0; i < stages_37bits; i++ )
    1213             :         {
    1214           0 :             push_next_indice( hBstr, indices[i], bits_37bits[i] );
    1215             :         }
    1216           0 :         push_next_indice( hBstr, index, 7 );
    1217             :     }
    1218             :     ELSE
    1219             :     {
    1220           0 :         push_indice( hBstr, IND_SID_TYPE, 1, 1 );
    1221           0 :         push_indice( hBstr, IND_ACELP_16KHZ, corest->bwidth, 2 );
    1222           0 :         IF( EQ_16( corest->L_frame, L_FRAME16k ) )
    1223             :         {
    1224           0 :             push_indice( hBstr, IND_ACELP_16KHZ, 1, 1 );
    1225             :         }
    1226             :         ELSE
    1227             :         {
    1228           0 :             push_indice( hBstr, IND_ACELP_16KHZ, 0, 1 );
    1229             :         }
    1230           0 :         FOR( i = 0; i < stages_37bits; i++ )
    1231             :         {
    1232           0 :             push_indice( hBstr, IND_LSF, indices[i], bits_37bits[i] );
    1233             :         }
    1234           0 :         push_indice( hBstr, IND_ENERGY, index, 7 );
    1235             :     }
    1236             : 
    1237             :     /* Interpolate the bin/band-wise levels from the partition levels */
    1238             :     /* sidNoiseEst: Q6.26 format => cngNoiseLevel: Q6.26 format */
    1239           0 :     scalebands( st->sidNoiseEst, stenc->partDec, stenc->npartDec, stenc->midbandDec, stenc->nFFTpartDec, sub( stenc->stopBandDec, stenc->startBandDec ), st->cngNoiseLevel, 1 );
    1240           0 :     st->cngNoiseLevelExp = st->sidNoiseEstExp;
    1241           0 :     move16();
    1242             : 
    1243             : 
    1244           0 :     lpc_from_spectrum( st, stenc->startBandDec, stenc->stopFFTbinDec, preemph_fac );
    1245           0 : }
    1246             : 
    1247             : 
    1248           0 : void generate_comfort_noise_enc_fx( Encoder_State *stcod,
    1249             :                                     Word16 Q_new,
    1250             :                                     Word16 gen_exc )
    1251             : {
    1252             :     Word16 i, s, sn, cnt;
    1253             :     Word16 startBand2;
    1254             :     Word16 stopFFTbin2;
    1255             :     Word16 preemph_fac;
    1256             :     Word32 sqrtNoiseLevel;
    1257             :     Word16 randGaussExp;
    1258             :     Word16 fftBufferExp;
    1259             :     Word16 cngNoiseLevelExp;
    1260             :     Word16 *seed;
    1261             :     Word16 *timeDomainOutput;
    1262             :     Word32 *ptr_r, *ptr_i;
    1263             :     Word32 *cngNoiseLevel;
    1264             :     Word32 *ptr_level;
    1265             :     Word32 *fftBuffer;
    1266             :     Word16 old_syn_pe_tmp[16];
    1267           0 :     Word16 tcx_transition = 0;
    1268           0 :     HANDLE_FD_CNG_ENC stenc = stcod->hFdCngEnc;
    1269           0 :     HANDLE_FD_CNG_COM st = stenc->hFdCngCom;
    1270           0 :     DTX_ENC_HANDLE hDtxEnc = stcod->hDtxEnc;
    1271           0 :     TD_CNG_ENC_HANDLE hTdCngEnc = stcod->hTdCngEnc;
    1272             : 
    1273           0 :     LPD_state_HANDLE hLPDmem = stcod->hLPDmem;
    1274           0 :     TCX_ENC_HANDLE hTcxEnc = stcod->hTcxEnc;
    1275             : 
    1276             :     /* Warning fix */
    1277           0 :     s = 0;
    1278             : 
    1279             :     /* pointer initialization */
    1280             : 
    1281           0 :     cngNoiseLevel = st->cngNoiseLevel;
    1282           0 :     cngNoiseLevelExp = st->cngNoiseLevelExp;
    1283           0 :     ptr_level = cngNoiseLevel;
    1284           0 :     seed = &( st->seed );
    1285           0 :     fftBuffer = st->fftBuffer;
    1286           0 :     timeDomainOutput = st->timeDomainBuffer;
    1287             : 
    1288             :     /*
    1289             :       Generate Gaussian random noise in real and imaginary parts of the FFT bins
    1290             :       Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each bin
    1291             :       scaling Gaussian random noise: format Q3.29
    1292             :     */
    1293           0 :     sn = 0;
    1294           0 :     move16();
    1295           0 :     IF( s_and( cngNoiseLevelExp, 1 ) != 0 )
    1296             :     {
    1297           0 :         sn = add( sn, 1 );
    1298           0 :         cngNoiseLevelExp = add( cngNoiseLevelExp, sn );
    1299           0 :         move16();
    1300             :     }
    1301             : 
    1302           0 :     randGaussExp = CNG_RAND_GAUSS_SHIFT;
    1303           0 :     move16();
    1304           0 :     cnt = sub( stenc->stopFFTbinDec, stenc->startBandDec );
    1305           0 :     IF( stenc->startBandDec == 0 )
    1306             :     {
    1307             :         /* DC component in FFT */
    1308           0 :         s = 0;
    1309           0 :         move16();
    1310           0 :         sqrtNoiseLevel = Sqrt32( L_shr( *ptr_level, sn ), &s );
    1311             : 
    1312           0 :         fftBuffer[0] = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s );
    1313           0 :         move32();
    1314             : 
    1315             :         /* Nyquist frequency is discarded */
    1316           0 :         fftBuffer[1] = L_deposit_l( 0 );
    1317             : 
    1318           0 :         ptr_level = ptr_level + 1;
    1319           0 :         ptr_r = fftBuffer + 2;
    1320           0 :         cnt = sub( cnt, 1 );
    1321             :     }
    1322             :     ELSE
    1323             :     {
    1324           0 :         startBand2 = shl( stenc->startBandDec, 1 );
    1325           0 :         set32_fx( fftBuffer, 0, startBand2 );
    1326           0 :         ptr_r = fftBuffer + startBand2;
    1327             :     }
    1328             : 
    1329           0 :     sn = add( sn, 1 );
    1330           0 :     ptr_i = ptr_r + 1;
    1331           0 :     FOR( i = 0; i < cnt; i++ )
    1332             :     {
    1333           0 :         s = 0;
    1334           0 :         move16();
    1335           0 :         sqrtNoiseLevel = Sqrt32( L_shr( *ptr_level, sn ), &s );
    1336             : 
    1337             :         /* Real part in FFT bins */
    1338           0 :         *ptr_r = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s );
    1339           0 :         move32();
    1340             : 
    1341             :         /* Imaginary part in FFT bins */
    1342           0 :         *ptr_i = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s );
    1343           0 :         move32();
    1344             : 
    1345           0 :         ptr_r = ptr_r + 2;
    1346           0 :         ptr_i = ptr_i + 2;
    1347           0 :         ptr_level = ptr_level + 1;
    1348             :     }
    1349             : 
    1350             :     /* Remaining FFT bins are set to zero */
    1351           0 :     stopFFTbin2 = shl( stenc->stopFFTbinDec, 1 );
    1352           0 :     set32_fx( fftBuffer + stopFFTbin2, 0, sub( st->fftlen, stopFFTbin2 ) );
    1353             : 
    1354           0 :     fftBufferExp = add( shr( cngNoiseLevelExp, 1 ), randGaussExp );
    1355             : 
    1356             :     /* If previous frame is active, reset the overlap-add buffer */
    1357           0 :     IF( GT_32( stcod->last_core_brate, SID_2k40 ) )
    1358             :     {
    1359           0 :         set16_fx( st->olapBufferSynth, 0, st->fftlen );
    1360           0 :         test();
    1361           0 :         test();
    1362           0 :         IF( ( GT_32( stcod->last_core, ACELP_CORE ) && EQ_16( stcod->codec_mode, MODE2 ) ) || EQ_16( stcod->codec_mode, MODE1 ) )
    1363             :         {
    1364           0 :             tcx_transition = 1;
    1365           0 :             move16();
    1366             :         }
    1367             :     }
    1368             : 
    1369             :     /* Perform STFT synthesis */
    1370           0 :     SynthesisSTFT( fftBuffer, fftBufferExp, timeDomainOutput, st->olapBufferSynth, st->olapWinSyn,
    1371             :                    tcx_transition, st, gen_exc, &Q_new, -1, -1 );
    1372             :     {
    1373             :         Word32 Lener, att;
    1374             :         Word16 exp;
    1375             :         /* update CNG excitation energy for LP_CNG */
    1376             : 
    1377             :         /* calculate the residual signal energy */
    1378             :         /*enr = dotp( st->exc_cng, st->exc_cng, st->frameSize ) / st->frameSize;*/
    1379           0 :         Lener = Dot_productSq16HQ( 1, st->exc_cng, stcod->L_frame, &exp );
    1380           0 :         exp = add( sub( shl( sub( 15, Q_new ), 1 ), 8 ), exp ); /*8 = log2(256)*/
    1381             : 
    1382             :         /* convert log2 of residual signal energy */
    1383             :         /*(float)log10( enr + 0.1f ) / (float)log10( 2.0f );*/
    1384           0 :         Lener = BASOP_Util_Log2( Lener );
    1385           0 :         Lener = L_add( Lener, L_shl( L_deposit_l( exp ), WORD32_BITS - 1 - LD_DATA_SCALE ) ); /*Q25*/
    1386           0 :         if ( EQ_16( stcod->L_frame, L_FRAME16k ) )
    1387             :         {
    1388           0 :             Lener = L_sub( Lener, 10802114l /*0.3219280949f Q25*/ ); /*log2(320) = 8.3219280949f*/
    1389             :         }
    1390             :         /* decrease the energy in case of WB input */
    1391           0 :         IF( NE_16( stcod->bwidth, NB ) )
    1392             :         {
    1393           0 :             IF( EQ_16( stcod->bwidth, WB ) )
    1394             :             {
    1395           0 :                 IF( hDtxEnc->CNG_mode >= 0 )
    1396             :                 {
    1397             :                     /* Bitrate adapted attenuation */
    1398           0 :                     att = L_shl( L_deposit_l( ENR_ATT_fx[hDtxEnc->CNG_mode] ), 17 );
    1399             :                 }
    1400             :                 ELSE
    1401             :                 {
    1402             :                     /* Use least attenuation for higher bitrates */
    1403           0 :                     att = L_shl( L_deposit_l( ENR_ATT_fx[4] ), 17 );
    1404             :                 }
    1405             :             }
    1406             :             ELSE
    1407             :             {
    1408           0 :                 att = 384 << 17;
    1409           0 :                 move32(); /*1.5 Q8<<17=Q25*/
    1410             :             }
    1411           0 :             Lener = L_sub( Lener, att );
    1412             :         }
    1413             :         /*stdec->lp_ener = 0.8f * stcod->lp_ener + 0.2f * pow( 2.0f, enr );*/
    1414           0 :         Lener = BASOP_util_Pow2( Lener, 6, &exp );
    1415           0 :         Lener = Mult_32_16( Lener, 6554 /*0.2f Q15*/ );
    1416           0 :         exp = sub( 25, exp );
    1417           0 :         Lener = L_shr( Lener, exp );                                                                     /*Q6*/
    1418           0 :         hTdCngEnc->lp_ener_fx = L_add( Mult_32_16( hTdCngEnc->lp_ener_fx, 26214 /*0.8f Q15*/ ), Lener ); /*Q6*/
    1419             :     }
    1420             : 
    1421             :     /* Overlap-add when previous frame is active */
    1422           0 :     test();
    1423           0 :     IF( ( GT_32( stcod->last_core_brate, SID_2k40 ) ) && ( EQ_16( stcod->codec_mode, MODE2 ) ) )
    1424             :     {
    1425             :         Word32 old_exc_ener, gain, noise32;
    1426             :         Word16 seed_loc, lpcorder, old_syn, tmp, gain16, N, N2, N4, N8;
    1427             :         Word16 old_exc_ener_exp, gain_exp;
    1428             :         Word16 normFacE, normShiftE, normShiftEM1;
    1429             :         Word16 normFacG, normShiftG, normShiftGM1;
    1430             :         Word16 noiseExp, *old_exc, old_Aq[M + 1], *old_syn_pe;
    1431             :         Word16 noise[640], normShiftP2;
    1432             :         Word16 Q_exc, Q_syn;
    1433             : 
    1434             : 
    1435           0 :         assert( st->frameSize <= 640 );
    1436             : 
    1437           0 :         seed_loc = st->seed;
    1438           0 :         move16();
    1439           0 :         N = st->frameSize;
    1440           0 :         move16();
    1441           0 :         N2 = shr( st->frameSize, 1 );
    1442             : 
    1443           0 :         IF( GT_16( stcod->last_core, ACELP_CORE ) )
    1444             :         {
    1445             :             Word16 left_overlap_mode;
    1446           0 :             left_overlap_mode = stcod->hTcxCfg->tcx_last_overlap_mode;
    1447           0 :             move16();
    1448           0 :             if ( EQ_16( left_overlap_mode, ALDO_WINDOW ) )
    1449             :             {
    1450           0 :                 left_overlap_mode = FULL_OVERLAP;
    1451           0 :                 move16();
    1452             :             }
    1453             : 
    1454           0 :             tcx_windowing_synthesis_current_frame( timeDomainOutput,
    1455           0 :                                                    stcod->hTcxCfg->tcx_mdct_window, /*Keep sine windows for limiting Time modulation*/
    1456           0 :                                                    stcod->hTcxCfg->tcx_mdct_window_half,
    1457           0 :                                                    stcod->hTcxCfg->tcx_mdct_window_minimum,
    1458           0 :                                                    stcod->hTcxCfg->tcx_mdct_window_length,
    1459           0 :                                                    stcod->hTcxCfg->tcx_mdct_window_half_length,
    1460           0 :                                                    stcod->hTcxCfg->tcx_mdct_window_min_length,
    1461             :                                                    0,
    1462             :                                                    left_overlap_mode,
    1463             :                                                    NULL,
    1464             :                                                    NULL,
    1465             :                                                    NULL,
    1466             :                                                    NULL,
    1467             :                                                    NULL,
    1468             :                                                    N / 2,
    1469           0 :                                                    shr( sub( abs_s( stcod->hTcxCfg->tcx_offset ), stcod->hTcxCfg->tcx_offset ), 1 ), /* equivalent to: stdec->hTcxCfg->tcx_offset<0?-stdec->hTcxCfg->tcx_offset:0 */
    1470             :                                                    1,
    1471             :                                                    0,
    1472             :                                                    0 );
    1473             : 
    1474           0 :             IF( stcod->hTcxCfg->last_aldo != 0 )
    1475             :             {
    1476           0 :                 FOR( i = 0; i < st->frameSize; i++ )
    1477             :                 {
    1478           0 :                     timeDomainOutput[i] = add( timeDomainOutput[i], shr_r( hTcxEnc->old_out_fx[i + NS2SA_FX2( stcod->sr_core, N_ZERO_MDCT_NS )], hTcxEnc->Q_old_out ) );
    1479           0 :                     move16();
    1480             :                 }
    1481             :             }
    1482             :             ELSE
    1483             :             {
    1484           0 :                 tcx_windowing_synthesis_past_frame( hTcxEnc->Txnq,
    1485           0 :                                                     stcod->hTcxCfg->tcx_aldo_window_1_trunc,
    1486           0 :                                                     stcod->hTcxCfg->tcx_mdct_window_half,
    1487           0 :                                                     stcod->hTcxCfg->tcx_mdct_window_minimum,
    1488           0 :                                                     stcod->hTcxCfg->tcx_mdct_window_length,
    1489           0 :                                                     stcod->hTcxCfg->tcx_mdct_window_half_length,
    1490           0 :                                                     stcod->hTcxCfg->tcx_mdct_window_min_length,
    1491           0 :                                                     stcod->hTcxCfg->tcx_last_overlap_mode );
    1492             : 
    1493           0 :                 FOR( i = 0; i < N2; i++ )
    1494             :                 {
    1495           0 :                     timeDomainOutput[i] = add( timeDomainOutput[i], shl( hTcxEnc->Txnq[i], TCX_IMDCT_HEADROOM ) );
    1496           0 :                     move16();
    1497             :                 }
    1498             :             }
    1499             :         }
    1500             :         ELSE
    1501             :         {
    1502             : 
    1503             :             /*
    1504             :               - the scaling of the LPCs (e.g. old_Aq) is always Q12 (encoder or decoder)
    1505             : 
    1506             :               - the scaling of the deemphasized signals (e.g. old_syn) is always Q0 (encoder or decoder)
    1507             : 
    1508             :               - the scaling of the excitation signals in the encoder (e.g. old_exc) is Q_new
    1509             :               - the scaling of the preemphasized signals in the encoder (e.g. old_syn_pe) is Q_new-1
    1510             : 
    1511             :               - the scaling of the excitation signals in the decoder (e.g. old_exc) is Q_exc (or stdec->Q_exc)
    1512             :               - the scaling of the preemphasized signals in the decoder (e.g. old_syn_pe) is Q_syn (or stdec->Q_syn)
    1513             :             */
    1514             : 
    1515           0 :             lpcorder = M;
    1516           0 :             move16();
    1517           0 :             E_LPC_f_lsp_a_conversion( stcod->lsp_old_fx, old_Aq, M );
    1518           0 :             old_exc = hLPDmem->old_exc + sub( L_EXC_MEM, N2 );
    1519           0 :             old_syn_pe = hLPDmem->mem_syn2;
    1520           0 :             old_syn = hLPDmem->syn[lpcorder];
    1521           0 :             move16();
    1522           0 :             preemph_fac = stcod->preemph_fac;
    1523           0 :             move16();
    1524           0 :             Q_exc = Q_new;
    1525           0 :             Q_syn = sub( Q_new, 1 );
    1526             : 
    1527             :             /* shift to be in the range of values supported by getNormReciprocalWord16() */
    1528           0 :             N8 = shr( N2, CNG_NORM_RECIPROCAL_RANGE_SHIFT );
    1529             : 
    1530           0 :             assert( N2 == ( N8 << CNG_NORM_RECIPROCAL_RANGE_SHIFT ) );
    1531             : 
    1532           0 :             normFacE = getNormReciprocalWord16( N8 );
    1533           0 :             normShiftE = BASOP_util_norm_s_bands2shift( N8 );
    1534           0 :             normShiftEM1 = sub( normShiftE, 1 );
    1535           0 :             normShiftP2 = add( normShiftE, CNG_NORM_RECIPROCAL_RANGE_SHIFT );
    1536             : 
    1537           0 :             old_exc_ener = L_shr( L_mult( old_exc[0], old_exc[0] ), normShiftP2 );
    1538           0 :             FOR( i = 1; i < N2; i++ )
    1539             :             {
    1540           0 :                 old_exc_ener = L_add( old_exc_ener, L_shr( L_mult( old_exc[i], old_exc[i] ), normShiftP2 ) );
    1541             :             }
    1542           0 :             old_exc_ener = L_shl( Mpy_32_16_1( old_exc_ener, shl( normFacE, normShiftEM1 ) ), 1 );
    1543             : 
    1544           0 :             old_exc_ener_exp = 0;
    1545           0 :             move16();
    1546           0 :             old_exc_ener = Sqrt32( old_exc_ener, &old_exc_ener_exp );
    1547           0 :             old_exc_ener_exp = add( old_exc_ener_exp, ( sub( 15, Q_exc ) ) );
    1548             : 
    1549             :             /* shift to be in the range of values supported by getNormReciprocalWord16() */
    1550           0 :             N4 = shr( N, CNG_NORM_RECIPROCAL_RANGE_SHIFT );
    1551             : 
    1552           0 :             assert( N == ( N4 << CNG_NORM_RECIPROCAL_RANGE_SHIFT ) );
    1553             : 
    1554           0 :             normFacG = getNormReciprocalWord16( N4 );
    1555           0 :             normShiftG = BASOP_util_norm_s_bands2shift( N4 );
    1556           0 :             normShiftGM1 = sub( normShiftG, 1 );
    1557           0 :             normShiftP2 = add( normShiftG, CNG_NORM_RECIPROCAL_RANGE_SHIFT );
    1558             : 
    1559           0 :             gain = L_deposit_l( 0 );
    1560           0 :             FOR( i = 0; i < N; i++ )
    1561             :             {
    1562           0 :                 noise32 = rand_gauss( &seed_loc );
    1563           0 :                 noise[i] = extract_h( noise32 );
    1564           0 :                 gain = L_add( gain, L_shr( L_mult( noise[i], noise[i] ), normShiftP2 ) );
    1565             :             }
    1566           0 :             gain = L_shl( Mpy_32_16_1( gain, shl( normFacG, normShiftGM1 ) ), 1 );
    1567             : 
    1568           0 :             gain_exp = 2 * CNG_RAND_GAUSS_SHIFT;
    1569           0 :             move16();
    1570           0 :             gain = ISqrt32( gain, &gain_exp );
    1571             : 
    1572           0 :             gain = Mpy_32_32( old_exc_ener, gain );
    1573           0 :             gain16 = extract_h( gain );
    1574             : 
    1575           0 :             gain_exp = add( old_exc_ener_exp, gain_exp );
    1576           0 :             noiseExp = add( CNG_RAND_GAUSS_SHIFT, gain_exp );
    1577             : 
    1578           0 :             s = sub( 15 - NOISE_HEADROOM, noiseExp );
    1579           0 :             FOR( i = 0; i < N; i++ )
    1580             :             {
    1581           0 :                 noise[i] = shr_sat( mult( noise[i], gain16 ), s );
    1582           0 :                 move16();
    1583             :             }
    1584             : 
    1585           0 :             assert( lpcorder <= 16 );
    1586             : 
    1587           0 :             s = sub( 15 - NOISE_HEADROOM, ( sub( 15, Q_syn ) ) );
    1588           0 :             FOR( i = 0; i < lpcorder; i++ )
    1589             :             {
    1590           0 :                 old_syn_pe_tmp[i] = shr_sat( old_syn_pe[i], s );
    1591           0 :                 move16();
    1592             :             }
    1593             : 
    1594           0 :             E_UTIL_synthesis(
    1595             :                 0,              /* i  : scaling to apply for a[0]                 Q0   */
    1596             :                 old_Aq,         /* i  : LP filter coefficients                    Q12  */
    1597             :                 noise,          /* i  : input signal                              Qx   */
    1598             :                 noise,          /* o  : output signal                             Qx-s */
    1599             :                 N,              /* i  : size of filtering                         Q0   */
    1600             :                 old_syn_pe_tmp, /* i/o: memory associated with this filtering.    Q0 */
    1601             :                 0,              /* i  : 0=no update, 1=update of memory.          Q0   */
    1602             :                 lpcorder        /* i  : order of LP filter                        Q0   */
    1603             :             );
    1604             : 
    1605           0 :             tmp = old_syn;
    1606           0 :             move16();
    1607             : 
    1608           0 :             E_UTIL_deemph2(
    1609             :                 NOISE_HEADROOM,
    1610             :                 noise,       /* I/O: signal              Qx */
    1611             :                 preemph_fac, /* I: deemphasis factor      Qx */
    1612             :                 N,           /* I: vector size              */
    1613             :                 &tmp         /* I/O: memory (signal[-1]) Qx */
    1614             :             );
    1615             : 
    1616           0 :             FOR( i = 0; i < N4; i++ )
    1617             :             {
    1618           0 :                 tmp = mult( noise[i], st->olapWinSyn[i].v.re );
    1619           0 :                 timeDomainOutput[i] = add( timeDomainOutput[i], tmp );
    1620           0 :                 move16();
    1621           0 :                 tmp = mult( noise[i + N4], st->olapWinSyn[N4 - 1 - i].v.im );
    1622           0 :                 timeDomainOutput[i + N4] = add( timeDomainOutput[i + N4], tmp );
    1623           0 :                 move16();
    1624             :             }
    1625             :         }
    1626             :     }
    1627           0 : }
    1628             : 
    1629       12598 : void generate_comfort_noise_enc_ivas_fx( Encoder_State *stcod,
    1630             :                                          Word16 Q_new,
    1631             :                                          Word16 gen_exc )
    1632             : {
    1633             :     Word16 i, s, sn, cnt;
    1634             :     Word16 startBand2;
    1635             :     Word16 stopFFTbin2;
    1636             :     Word16 preemph_fac;
    1637             :     Word32 sqrtNoiseLevel;
    1638             :     Word16 randGaussExp;
    1639             :     Word16 fftBufferExp;
    1640             :     Word16 cngNoiseLevelExp;
    1641             :     Word16 *seed;
    1642             :     Word16 *timeDomainOutput;
    1643             :     Word32 *ptr_r, *ptr_i;
    1644             :     Word32 *cngNoiseLevel;
    1645             :     Word32 *ptr_level;
    1646             :     Word32 *fftBuffer;
    1647             :     Word16 old_syn_pe_tmp[16];
    1648       12598 :     Word16 tcx_transition = 0;
    1649       12598 :     move16();
    1650       12598 :     HANDLE_FD_CNG_ENC stenc = stcod->hFdCngEnc;
    1651       12598 :     HANDLE_FD_CNG_COM st = stenc->hFdCngCom;
    1652       12598 :     DTX_ENC_HANDLE hDtxEnc = stcod->hDtxEnc;
    1653       12598 :     TD_CNG_ENC_HANDLE hTdCngEnc = stcod->hTdCngEnc;
    1654             : 
    1655       12598 :     LPD_state_HANDLE hLPDmem = stcod->hLPDmem;
    1656       12598 :     TCX_ENC_HANDLE hTcxEnc = stcod->hTcxEnc;
    1657             : 
    1658             :     /* Warning fix */
    1659       12598 :     s = 0;
    1660       12598 :     move16();
    1661             : 
    1662             :     /* pointer initialization */
    1663             : 
    1664       12598 :     cngNoiseLevel = st->cngNoiseLevel;
    1665       12598 :     cngNoiseLevelExp = st->cngNoiseLevelExp;
    1666       12598 :     move16();
    1667       12598 :     ptr_level = cngNoiseLevel; // cngNoiseLevelExp
    1668       12598 :     seed = &( st->seed );
    1669       12598 :     fftBuffer = st->fftBuffer;               // st->fftBuffer_exp
    1670       12598 :     timeDomainOutput = st->timeDomainBuffer; // Q15
    1671             : 
    1672             :     /*
    1673             :       Generate Gaussian random noise in real and imaginary parts of the FFT bins
    1674             :       Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each bin
    1675             :       scaling Gaussian random noise: format Q3.29
    1676             :     */
    1677       12598 :     sn = 0;
    1678       12598 :     move16();
    1679       12598 :     IF( s_and( cngNoiseLevelExp, 1 ) != 0 )
    1680             :     {
    1681        7119 :         sn = add( sn, 1 );
    1682        7119 :         cngNoiseLevelExp = add( cngNoiseLevelExp, sn );
    1683             :     }
    1684             : 
    1685       12598 :     randGaussExp = CNG_RAND_GAUSS_SHIFT;
    1686       12598 :     move16();
    1687       12598 :     cnt = sub( stenc->stopFFTbinDec, stenc->startBandDec ); // Q)=0
    1688       12598 :     IF( stenc->startBandDec == 0 )
    1689             :     {
    1690             :         /* DC component in FFT */
    1691           0 :         s = 0;
    1692           0 :         move16();
    1693           0 :         sqrtNoiseLevel = Sqrt32( L_shr( *ptr_level, sn ), &s );
    1694             : 
    1695           0 :         fftBuffer[0] = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s );
    1696           0 :         move32();
    1697             : 
    1698             :         /* Nyquist frequency is discarded */
    1699           0 :         fftBuffer[1] = L_deposit_l( 0 );
    1700           0 :         move32();
    1701             : 
    1702           0 :         ptr_level = ptr_level + 1;
    1703           0 :         ptr_r = fftBuffer + 2;
    1704           0 :         cnt = sub( cnt, 1 );
    1705             :     }
    1706             :     ELSE
    1707             :     {
    1708       12598 :         startBand2 = shl( stenc->startBandDec, 1 );
    1709       12598 :         set32_fx( fftBuffer, 0, startBand2 );
    1710       12598 :         ptr_r = fftBuffer + startBand2;
    1711             :     }
    1712             : 
    1713       12598 :     sn = add( sn, 1 );
    1714       12598 :     ptr_i = ptr_r + 1;
    1715     3605514 :     FOR( i = 0; i < cnt; i++ )
    1716             :     {
    1717     3592916 :         s = 0;
    1718     3592916 :         move16();
    1719     3592916 :         sqrtNoiseLevel = Sqrt32( L_shr( *ptr_level, sn ), &s );
    1720             : 
    1721             :         /* Real part in FFT bins */
    1722     3592916 :         *ptr_r = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s );
    1723     3592916 :         move32();
    1724             : 
    1725             :         /* Imaginary part in FFT bins */
    1726     3592916 :         *ptr_i = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s );
    1727     3592916 :         move32();
    1728             : 
    1729     3592916 :         ptr_r = ptr_r + 2;
    1730     3592916 :         ptr_i = ptr_i + 2;
    1731     3592916 :         ptr_level = ptr_level + 1;
    1732             :     }
    1733             : 
    1734             :     /* Remaining FFT bins are set to zero */
    1735       12598 :     stopFFTbin2 = shl( stenc->stopFFTbinDec, 1 );
    1736       12598 :     set32_fx( fftBuffer + stopFFTbin2, 0, sub( st->fftlen, stopFFTbin2 ) );
    1737             : 
    1738       12598 :     fftBufferExp = add( shr( cngNoiseLevelExp, 1 ), randGaussExp );
    1739             : 
    1740             :     /* If previous frame is active, reset the overlap-add buffer */
    1741       12598 :     IF( GT_32( stcod->last_core_brate, SID_2k40 ) )
    1742             :     {
    1743         659 :         set16_fx( st->olapBufferSynth, 0, st->fftlen );
    1744         659 :         test();
    1745         659 :         test();
    1746         659 :         IF( ( GT_32( stcod->last_core, ACELP_CORE ) && EQ_16( stcod->codec_mode, MODE2 ) ) || EQ_16( stcod->codec_mode, MODE1 ) )
    1747             :         {
    1748         659 :             tcx_transition = 1;
    1749         659 :             move16();
    1750             :         }
    1751             :     }
    1752             : 
    1753             :     /* Perform STFT synthesis */
    1754       12598 :     SynthesisSTFT_enc_ivas_fx( fftBuffer, fftBufferExp, timeDomainOutput, st->olapBufferSynth, st->olapWinSyn,
    1755             :                                tcx_transition, st, gen_exc, &Q_new, -1, -1 );
    1756       12598 :     IF( hTdCngEnc != NULL )
    1757             :     {
    1758             :         Word32 Lener, att;
    1759             :         Word16 exp;
    1760             :         /* update CNG excitation energy for LP_CNG */
    1761             : 
    1762             :         /* calculate the residual signal energy */
    1763             :         /*enr = dotp( st->exc_cng, st->exc_cng, st->frameSize ) / st->frameSize;*/
    1764       10483 :         Lener = Dot_productSq16HQ( 1, st->exc_cng, stcod->L_frame, &exp );
    1765       10483 :         exp = add( sub( shl( sub( 15, Q_new ), 1 ), 8 ), exp ); /*8 = log2(256)*/
    1766             : 
    1767             :         /* convert log2 of residual signal energy */
    1768             :         /*(float)log10( enr + 0.1f ) / (float)log10( 2.0f );*/
    1769       10483 :         Lener = BASOP_Util_Log2( Lener );
    1770       10483 :         Lener = L_add( Lener, L_shl( L_deposit_l( exp ), WORD32_BITS - 1 - LD_DATA_SCALE ) ); /*Q25*/
    1771       10483 :         if ( EQ_16( stcod->L_frame, L_FRAME16k ) )
    1772             :         {
    1773        5977 :             Lener = L_sub( Lener, 10802114l /*0.3219280949f Q25*/ ); /*log2(320) = 8.3219280949f*/
    1774             :         }
    1775             :         /* decrease the energy in case of WB input */
    1776       10483 :         IF( NE_16( stcod->bwidth, NB ) )
    1777             :         {
    1778       10483 :             IF( EQ_16( stcod->bwidth, WB ) )
    1779             :             {
    1780        3706 :                 IF( hDtxEnc->CNG_mode >= 0 )
    1781             :                 {
    1782             :                     /* Bitrate adapted attenuation */
    1783           0 :                     att = L_shl( L_deposit_l( ENR_ATT_fx[hDtxEnc->CNG_mode] ), 17 );
    1784             :                 }
    1785             :                 ELSE
    1786             :                 {
    1787             :                     /* Use least attenuation for higher bitrates */
    1788        3706 :                     att = L_shl( L_deposit_l( ENR_ATT_fx[4] ), 17 );
    1789             :                 }
    1790             :             }
    1791             :             ELSE
    1792             :             {
    1793        6777 :                 att = 384 << 17;
    1794        6777 :                 move32(); /*1.5 Q8<<17=Q25*/
    1795             :             }
    1796       10483 :             Lener = L_sub( Lener, att );
    1797             :         }
    1798             :         /*stdec->lp_ener = 0.8f * stcod->lp_ener + 0.2f * pow( 2.0f, enr );*/
    1799       10483 :         Lener = BASOP_util_Pow2( Lener, 6, &exp );
    1800       10483 :         Lener = Mult_32_16( Lener, 6554 /*0.2f Q15*/ );
    1801       10483 :         exp = sub( 25, exp );
    1802       10483 :         Lener = L_shr( Lener, exp );                                                                     /*Q6*/
    1803       10483 :         hTdCngEnc->lp_ener_fx = L_add( Mult_32_16( hTdCngEnc->lp_ener_fx, 26214 /*0.8f Q15*/ ), Lener ); /*Q6*/
    1804       10483 :         move32();
    1805             :     }
    1806             : 
    1807             :     /* Overlap-add when previous frame is active */
    1808       12598 :     test();
    1809       12598 :     IF( ( GT_32( stcod->last_core_brate, SID_2k40 ) ) && ( EQ_16( stcod->codec_mode, MODE2 ) ) )
    1810             :     {
    1811             :         Word32 old_exc_ener, gain, noise32;
    1812             :         Word16 seed_loc, lpcorder, old_syn, tmp, gain16, N, N2, N4, N8;
    1813             :         Word16 old_exc_ener_exp, gain_exp;
    1814             :         Word16 normFacE, normShiftE, normShiftEM1;
    1815             :         Word16 normFacG, normShiftG, normShiftGM1;
    1816             :         Word16 noiseExp, *old_exc, old_Aq[M + 1], *old_syn_pe;
    1817             :         Word16 noise[640], normShiftP2;
    1818             :         Word16 Q_exc, Q_syn;
    1819             : 
    1820             : 
    1821           0 :         assert( st->frameSize <= 640 );
    1822             : 
    1823           0 :         seed_loc = st->seed;
    1824           0 :         move16();
    1825           0 :         N = st->frameSize; // Q0
    1826           0 :         move16();
    1827           0 :         N2 = shr( st->frameSize, 1 );
    1828             : 
    1829           0 :         IF( GT_16( stcod->last_core, ACELP_CORE ) )
    1830             :         {
    1831             :             Word16 left_overlap_mode;
    1832           0 :             left_overlap_mode = stcod->hTcxCfg->tcx_last_overlap_mode;
    1833           0 :             move16();
    1834           0 :             if ( EQ_16( left_overlap_mode, ALDO_WINDOW ) )
    1835             :             {
    1836           0 :                 left_overlap_mode = FULL_OVERLAP;
    1837           0 :                 move16();
    1838             :             }
    1839             : 
    1840           0 :             tcx_windowing_synthesis_current_frame( timeDomainOutput,
    1841           0 :                                                    stcod->hTcxCfg->tcx_mdct_window, /*Keep sine windows for limiting Time modulation*/
    1842           0 :                                                    stcod->hTcxCfg->tcx_mdct_window_half,
    1843           0 :                                                    stcod->hTcxCfg->tcx_mdct_window_minimum,
    1844           0 :                                                    stcod->hTcxCfg->tcx_mdct_window_length,
    1845           0 :                                                    stcod->hTcxCfg->tcx_mdct_window_half_length,
    1846           0 :                                                    stcod->hTcxCfg->tcx_mdct_window_min_length,
    1847             :                                                    0,
    1848             :                                                    left_overlap_mode,
    1849             :                                                    NULL,
    1850             :                                                    NULL,
    1851             :                                                    NULL,
    1852             :                                                    NULL,
    1853             :                                                    NULL,
    1854             :                                                    N / 2,
    1855           0 :                                                    shr( sub( abs_s( stcod->hTcxCfg->tcx_offset ), stcod->hTcxCfg->tcx_offset ), 1 ), /* equivalent to: stdec->hTcxCfg->tcx_offset<0?-stdec->hTcxCfg->tcx_offset:0 */
    1856             :                                                    1,
    1857             :                                                    0,
    1858             :                                                    0 );
    1859             : 
    1860           0 :             IF( stcod->hTcxCfg->last_aldo != 0 )
    1861             :             {
    1862           0 :                 FOR( i = 0; i < st->frameSize; i++ )
    1863             :                 {
    1864           0 :                     timeDomainOutput[i] = add( timeDomainOutput[i], shr_r( hTcxEnc->old_out_fx[i + NS2SA_FX2( stcod->sr_core, N_ZERO_MDCT_NS )], hTcxEnc->Q_old_out ) );
    1865           0 :                     move16();
    1866             :                 }
    1867             :             }
    1868             :             ELSE
    1869             :             {
    1870           0 :                 tcx_windowing_synthesis_past_frame( hTcxEnc->Txnq,
    1871           0 :                                                     stcod->hTcxCfg->tcx_aldo_window_1_trunc,
    1872           0 :                                                     stcod->hTcxCfg->tcx_mdct_window_half,
    1873           0 :                                                     stcod->hTcxCfg->tcx_mdct_window_minimum,
    1874           0 :                                                     stcod->hTcxCfg->tcx_mdct_window_length,
    1875           0 :                                                     stcod->hTcxCfg->tcx_mdct_window_half_length,
    1876           0 :                                                     stcod->hTcxCfg->tcx_mdct_window_min_length,
    1877           0 :                                                     stcod->hTcxCfg->tcx_last_overlap_mode );
    1878             : 
    1879           0 :                 FOR( i = 0; i < N2; i++ )
    1880             :                 {
    1881           0 :                     timeDomainOutput[i] = add( timeDomainOutput[i], shl( hTcxEnc->Txnq[i], TCX_IMDCT_HEADROOM ) ); // Q15
    1882           0 :                     move16();
    1883             :                 }
    1884             :             }
    1885             :         }
    1886             :         ELSE
    1887             :         {
    1888             : 
    1889             :             /*
    1890             :               - the scaling of the LPCs (e.g. old_Aq) is always Q12 (encoder or decoder)
    1891             : 
    1892             :               - the scaling of the deemphasized signals (e.g. old_syn) is always Q0 (encoder or decoder)
    1893             : 
    1894             :               - the scaling of the excitation signals in the encoder (e.g. old_exc) is Q_new
    1895             :               - the scaling of the preemphasized signals in the encoder (e.g. old_syn_pe) is Q_new-1
    1896             : 
    1897             :               - the scaling of the excitation signals in the decoder (e.g. old_exc) is Q_exc (or stdec->Q_exc)
    1898             :               - the scaling of the preemphasized signals in the decoder (e.g. old_syn_pe) is Q_syn (or stdec->Q_syn)
    1899             :             */
    1900             : 
    1901           0 :             lpcorder = M;
    1902           0 :             move16();
    1903           0 :             E_LPC_f_lsp_a_conversion( stcod->lsp_old_fx, old_Aq, M );
    1904           0 :             old_exc = hLPDmem->old_exc + sub( L_EXC_MEM, N2 );
    1905           0 :             old_syn_pe = hLPDmem->mem_syn2;
    1906           0 :             old_syn = hLPDmem->syn[lpcorder];
    1907           0 :             move16();
    1908           0 :             preemph_fac = stcod->preemph_fac;
    1909           0 :             move16();
    1910           0 :             Q_exc = Q_new;
    1911           0 :             move16();
    1912           0 :             Q_syn = sub( Q_new, 1 );
    1913             : 
    1914             :             /* shift to be in the range of values supported by getNormReciprocalWord16() */
    1915           0 :             N8 = shr( N2, CNG_NORM_RECIPROCAL_RANGE_SHIFT );
    1916             : 
    1917           0 :             assert( N2 == ( N8 << CNG_NORM_RECIPROCAL_RANGE_SHIFT ) );
    1918             : 
    1919           0 :             normFacE = getNormReciprocalWord16( N8 );
    1920           0 :             normShiftE = BASOP_util_norm_s_bands2shift( N8 );
    1921           0 :             normShiftEM1 = sub( normShiftE, 1 );
    1922           0 :             normShiftP2 = add( normShiftE, CNG_NORM_RECIPROCAL_RANGE_SHIFT );
    1923             : 
    1924           0 :             old_exc_ener = L_shr( L_mult( old_exc[0], old_exc[0] ), normShiftP2 );
    1925           0 :             FOR( i = 1; i < N2; i++ )
    1926             :             {
    1927           0 :                 old_exc_ener = L_add( old_exc_ener, L_shr( L_mult( old_exc[i], old_exc[i] ), normShiftP2 ) );
    1928             :             }
    1929           0 :             old_exc_ener = L_shl( Mpy_32_16_1( old_exc_ener, shl( normFacE, normShiftEM1 ) ), 1 );
    1930             : 
    1931           0 :             old_exc_ener_exp = 0;
    1932           0 :             move16();
    1933           0 :             old_exc_ener = Sqrt32( old_exc_ener, &old_exc_ener_exp );
    1934           0 :             old_exc_ener_exp = add( old_exc_ener_exp, ( sub( 15, Q_exc ) ) );
    1935             : 
    1936             :             /* shift to be in the range of values supported by getNormReciprocalWord16() */
    1937           0 :             N4 = shr( N, CNG_NORM_RECIPROCAL_RANGE_SHIFT );
    1938             : 
    1939           0 :             assert( N == ( N4 << CNG_NORM_RECIPROCAL_RANGE_SHIFT ) );
    1940             : 
    1941           0 :             normFacG = getNormReciprocalWord16( N4 );
    1942           0 :             normShiftG = BASOP_util_norm_s_bands2shift( N4 );
    1943           0 :             normShiftGM1 = sub( normShiftG, 1 );
    1944           0 :             normShiftP2 = add( normShiftG, CNG_NORM_RECIPROCAL_RANGE_SHIFT );
    1945             : 
    1946           0 :             gain = L_deposit_l( 0 );
    1947           0 :             FOR( i = 0; i < N; i++ )
    1948             :             {
    1949           0 :                 noise32 = rand_gauss( &seed_loc );
    1950           0 :                 noise[i] = extract_h( noise32 );
    1951           0 :                 move16();
    1952           0 :                 gain = L_add( gain, L_shr( L_mult( noise[i], noise[i] ), normShiftP2 ) );
    1953             :             }
    1954           0 :             gain = L_shl( Mpy_32_16_1( gain, shl( normFacG, normShiftGM1 ) ), 1 );
    1955             : 
    1956           0 :             gain_exp = 2 * CNG_RAND_GAUSS_SHIFT;
    1957           0 :             move16();
    1958           0 :             gain = ISqrt32( gain, &gain_exp );
    1959             : 
    1960           0 :             gain = Mpy_32_32( old_exc_ener, gain );
    1961           0 :             gain16 = extract_h( gain );
    1962             : 
    1963           0 :             gain_exp = add( old_exc_ener_exp, gain_exp );
    1964           0 :             noiseExp = add( CNG_RAND_GAUSS_SHIFT, gain_exp );
    1965             : 
    1966           0 :             s = sub( 15 - NOISE_HEADROOM, noiseExp );
    1967           0 :             FOR( i = 0; i < N; i++ )
    1968             :             {
    1969           0 :                 noise[i] = shr_sat( mult( noise[i], gain16 ), s );
    1970           0 :                 move16();
    1971             :             }
    1972             : 
    1973           0 :             assert( lpcorder <= 16 );
    1974             : 
    1975           0 :             s = sub( 15 - NOISE_HEADROOM, ( sub( 15, Q_syn ) ) );
    1976           0 :             FOR( i = 0; i < lpcorder; i++ )
    1977             :             {
    1978           0 :                 old_syn_pe_tmp[i] = shr_sat( old_syn_pe[i], s );
    1979           0 :                 move16();
    1980             :             }
    1981             : 
    1982           0 :             E_UTIL_synthesis(
    1983             :                 0,              /* i  : scaling to apply for a[0]                 Q0   */
    1984             :                 old_Aq,         /* i  : LP filter coefficients                    Q12  */
    1985             :                 noise,          /* i  : input signal                              Qx   */
    1986             :                 noise,          /* o  : output signal                             Qx-s */
    1987             :                 N,              /* i  : size of filtering                         Q0   */
    1988             :                 old_syn_pe_tmp, /* i/o: memory associated with this filtering.    Q0 */
    1989             :                 0,              /* i  : 0=no update, 1=update of memory.          Q0   */
    1990             :                 lpcorder        /* i  : order of LP filter                        Q0   */
    1991             :             );
    1992             : 
    1993           0 :             tmp = old_syn;
    1994           0 :             move16();
    1995             : 
    1996           0 :             E_UTIL_deemph2(
    1997             :                 NOISE_HEADROOM,
    1998             :                 noise,       /* I/O: signal              Qx */
    1999             :                 preemph_fac, /* I: deemphasis factor      Qx */
    2000             :                 N,           /* I: vector size              */
    2001             :                 &tmp         /* I/O: memory (signal[-1]) Qx */
    2002             :             );
    2003             : 
    2004           0 :             FOR( i = 0; i < N4; i++ )
    2005             :             {
    2006           0 :                 tmp = mult( noise[i], st->olapWinSyn[i].v.re );
    2007           0 :                 timeDomainOutput[i] = add( timeDomainOutput[i], tmp );
    2008           0 :                 move16();
    2009           0 :                 tmp = mult( noise[i + N4], st->olapWinSyn[N4 - 1 - i].v.im );
    2010           0 :                 timeDomainOutput[i + N4] = add( timeDomainOutput[i + N4], tmp );
    2011           0 :                 move16();
    2012             :             }
    2013             :         }
    2014             :     }
    2015       12598 : }
    2016             : 
    2017             : /*-------------------------------------------------------------------*
    2018             :  * cng_energy_fx()
    2019             :  *
    2020             :  *
    2021             :  *-------------------------------------------------------------------*/
    2022             : 
    2023             : /*! r: CNG energy */
    2024           0 : Word16 cng_energy_fx(
    2025             :     const Word16 element_mode, /* i  : element mode                 Q0*/
    2026             :     const Word16 bwidth,       /* i  : audio bandwidh               Q0*/
    2027             :     const Word16 CNG_mode,     /* i  : mode for DTX configuration   Q0*/
    2028             :     const Word16 CNG_att,      /* i  : attenuation factor for CNG   Q7*/
    2029             :     const Word16 *exc,         /* i  : input signal                 Q_new*/
    2030             :     const Word16 len,          /* i  : vector length                Q0*/
    2031             :     const Word16 Q_new         /* i  : Input scaling                */
    2032             : )
    2033             : {
    2034             :     Word16 i, maxv, scale;
    2035             :     Word16 hi, lo, enr, tmp16, att;
    2036             :     const Word16 *pt_res;
    2037             :     Word32 L_ener, L_tmp;
    2038             : 
    2039           0 :     maxv = 0;
    2040           0 :     move16();
    2041           0 :     FOR( i = 0; i < len; i++ )
    2042             :     {
    2043           0 :         maxv = s_max( maxv, abs_s( exc[i] ) );
    2044             :     }
    2045           0 :     scale = norm_s( maxv );
    2046           0 :     pt_res = exc;
    2047           0 :     L_ener = L_deposit_l( 1 );
    2048           0 :     IF( EQ_16( len, L_FRAME ) )
    2049             :     {
    2050           0 :         FOR( i = 0; i < 128; i++ )
    2051             :         {
    2052           0 :             tmp16 = shl( *pt_res, scale );
    2053           0 :             L_tmp = L_mult0( tmp16, tmp16 );
    2054           0 :             pt_res++;
    2055           0 :             tmp16 = shl( *pt_res, scale );
    2056           0 :             L_tmp = L_mac0_sat( L_tmp, tmp16, tmp16 ); /* 2*(Q_new+scale) */
    2057           0 :             pt_res++;
    2058           0 :             L_ener = L_add( L_ener, L_shr( L_tmp, 7 ) ); /* 2*(Q_new+scale)+1, divide by L_frame done here */
    2059             :         }
    2060             :     }
    2061             :     ELSE /* L_FRAME16k */
    2062             :     {
    2063           0 :         FOR( i = 0; i < 160; i++ )
    2064             :         {
    2065           0 :             tmp16 = shl( *pt_res, scale );
    2066           0 :             L_tmp = L_mult0( tmp16, tmp16 );
    2067           0 :             pt_res++;
    2068           0 :             tmp16 = shl( *pt_res, scale );
    2069           0 :             L_tmp = L_mac0_sat( L_tmp, tmp16, tmp16 ); /* 2*(Q_new+scale) */
    2070           0 :             pt_res++;
    2071           0 :             L_ener = L_add( L_ener, L_shr( Mult_32_16( L_tmp, 26214 /* 256/320, Q15 */ ), 7 ) ); /* 2*(Q_new+scale)+15+1-16+1, divide by L_frame done here */
    2072             :         }
    2073             :     }
    2074             : 
    2075           0 :     hi = norm_l( L_ener );
    2076           0 :     lo = Log2_norm_lc( L_shl( L_ener, hi ) );
    2077           0 :     hi = sub( 30, add( hi, shl( add( Q_new, scale ), 1 ) ) ); /* log2 exp in Q2*(Q_new+scale) */
    2078           0 :     L_tmp = L_Comp( hi, lo );                                 /* Q16 */
    2079           0 :     enr = round_fx( L_shl( L_tmp, 8 ) );                      /* Q8 (16+8-16) */
    2080             : 
    2081             :     /* decrease the energy in case of WB input */
    2082           0 :     test();
    2083           0 :     IF( EQ_16( element_mode, IVAS_CPE_DFT ) || EQ_16( element_mode, IVAS_CPE_TD ) )
    2084             :     {
    2085             :         (void) CNG_att;
    2086             :     }
    2087           0 :     ELSE IF( NE_16( bwidth, NB ) )
    2088             :     {
    2089           0 :         IF( EQ_16( bwidth, WB ) )
    2090             :         {
    2091           0 :             IF( CNG_mode >= 0 )
    2092             :             {
    2093             :                 /* Bitrate adapted attenuation */
    2094           0 :                 att = ENR_ATT_fx[CNG_mode];
    2095             :             }
    2096             :             ELSE
    2097             :             {
    2098             :                 /* Use least attenuation for higher bitrates */
    2099           0 :                 att = ENR_ATT_fx[4];
    2100             :             }
    2101             :         }
    2102             :         ELSE
    2103             :         {
    2104           0 :             att = 384;
    2105           0 :             move16(); /*Q8*/
    2106             :         }
    2107           0 :         enr = sub( enr, att );
    2108             :     }
    2109           0 :     return enr;
    2110             : }
    2111             : 
    2112             : /*-------------------------------------------------------------------*
    2113             :  * cng_energy_ivas_fx()
    2114             :  *
    2115             :  *
    2116             :  *-------------------------------------------------------------------*/
    2117             : 
    2118             : /*! r: CNG energy */
    2119        1419 : Word16 cng_energy_ivas_fx(
    2120             :     const Word16 element_mode, /* i  : element mode                   Q0*/
    2121             :     const Word16 bwidth,       /* i  : audio bandwidh                 Q0*/
    2122             :     const Word16 CNG_mode,     /* i  : mode for DTX configuration     Q0*/
    2123             :     const Word16 CNG_att,      /* i  : attenuation factor for CNG         Q7*/
    2124             :     const Word16 *exc,         /* i  : input signal                   Q_new*/
    2125             :     const Word16 len,          /* i  : vector length                  */
    2126             :     const Word16 Q_new         /* i  : Input scaling                  */
    2127             : )
    2128             : {
    2129             :     Word16 i, maxv, scale;
    2130             :     Word16 hi, lo, enr, tmp16, att;
    2131             :     const Word16 *pt_res;
    2132             :     Word32 L_ener, L_tmp;
    2133             : 
    2134        1419 :     maxv = 0;
    2135        1419 :     move16();
    2136      416395 :     FOR( i = 0; i < len; i++ )
    2137             :     {
    2138      414976 :         maxv = s_max( maxv, abs_s( exc[i] ) );
    2139             :     }
    2140        1419 :     scale = norm_s( maxv );
    2141        1419 :     pt_res = exc;
    2142        1419 :     L_ener = L_deposit_l( 1 );
    2143        1419 :     IF( EQ_16( len, L_FRAME ) )
    2144             :     {
    2145       78819 :         FOR( i = 0; i < 128; i++ )
    2146             :         {
    2147       78208 :             tmp16 = shl( *pt_res, sub( scale, 4 ) ); // Q_new + scale - 4
    2148       78208 :             L_tmp = L_mult0( tmp16, tmp16 );
    2149       78208 :             pt_res++;
    2150       78208 :             tmp16 = shl( *pt_res, sub( scale, 4 ) ); // Q_new + scale - 4
    2151       78208 :             L_tmp = L_mac0( L_tmp, tmp16, tmp16 );   /* 2*(Q_new+scale) + 7 */
    2152       78208 :             pt_res++;
    2153       78208 :             L_ener = L_add( L_ener, L_tmp ); /* 2*(Q_new+scale)+1, divide by L_frame done here */
    2154             :         }
    2155             :     }
    2156             :     ELSE /* L_FRAME16k */
    2157             :     {
    2158      130088 :         FOR( i = 0; i < 160; i++ )
    2159             :         {
    2160      129280 :             tmp16 = shl( *pt_res, sub( scale, 4 ) ); // Q_new + scale - 4
    2161      129280 :             L_tmp = L_mult( tmp16, tmp16 );
    2162      129280 :             pt_res++;
    2163      129280 :             tmp16 = shl( *pt_res, sub( scale, 4 ) ); // Q_new + scale - 4
    2164      129280 :             L_tmp = L_mac( L_tmp, tmp16, tmp16 );    /* 2*(Q_new+scale) - 7 */
    2165      129280 :             pt_res++;
    2166      129280 :             L_ener = L_add( L_ener, Mult_32_16( L_tmp, 26214 /* 256/320, Q15 */ ) ); /* 2*(Q_new+scale)+15+1-16+1, divide by L_frame done here */
    2167             :         }
    2168             :     }
    2169             : 
    2170        1419 :     hi = norm_l( L_ener );
    2171        1419 :     lo = Log2_norm_lc( L_shl( L_ener, hi ) );
    2172        1419 :     hi = sub( 30, add( hi, shl( add( Q_new, scale ), 1 ) ) ); /* log2 exp in Q2*(Q_new+scale) */
    2173        1419 :     L_tmp = L_Comp( hi, lo );                                 /* Q16 */
    2174        1419 :     enr = round_fx( L_shl( L_tmp, 8 ) );                      /* Q8 (16+8-16) */
    2175             : 
    2176             :     /* decrease the energy in case of WB input */
    2177        1419 :     test();
    2178        1419 :     IF( EQ_16( element_mode, IVAS_CPE_DFT ) || EQ_16( element_mode, IVAS_CPE_TD ) )
    2179             :     {
    2180             :         // PMT(" IVAS CNG ener computing is missing")
    2181        1075 :         enr = add( enr, mult( CNG_att, FAC_LOG2_BY10_Q16 ) ); /* Q8 (7+16-15) */
    2182             :     }
    2183         344 :     ELSE IF( NE_16( bwidth, NB ) )
    2184             :     {
    2185         344 :         IF( EQ_16( bwidth, WB ) )
    2186             :         {
    2187         223 :             IF( CNG_mode >= 0 )
    2188             :             {
    2189             :                 /* Bitrate adapted attenuation */
    2190           0 :                 att = ENR_ATT_fx[CNG_mode];
    2191           0 :                 move16();
    2192             :             }
    2193             :             ELSE
    2194             :             {
    2195             :                 /* Use least attenuation for higher bitrates */
    2196         223 :                 att = ENR_ATT_fx[4];
    2197         223 :                 move16();
    2198             :             }
    2199             :         }
    2200             :         ELSE
    2201             :         {
    2202         121 :             att = 384;
    2203         121 :             move16(); /*Q8*/
    2204             :         }
    2205         344 :         enr = sub( enr, att );
    2206             :     }
    2207        1419 :     return enr;
    2208             : }
    2209             : 
    2210      121132 : void perform_noise_estimation_enc_ivas_fx(
    2211             :     Word32 *band_energies, /* i: energy in critical bands without minimum noise floor MODE2_E_MIN       band_energies_exp*/
    2212             :     Word16 band_energies_exp,
    2213             :     Word32 *enerBuffer, /* enerBuffer_exp */
    2214             :     Word16 enerBuffer_exp,
    2215             :     HANDLE_FD_CNG_ENC hFdCngEnc, /* i/o: CNG structure containing all buffers and variables        */
    2216             :     const Word32 input_Fs,       /* i  : input sampling rate                                       Q0*/
    2217             :     CPE_ENC_HANDLE hCPE          /* i  : CPE encoder structure                                     */
    2218             : )
    2219             : {
    2220             :     Word16 i, j, s, s1, s2;
    2221             :     Word16 numBands;
    2222      121132 :     Word16 numCoreBands = hFdCngEnc->hFdCngCom->numCoreBands; /* Q0 */
    2223      121132 :     move16();
    2224      121132 :     Word16 regularStopBand = hFdCngEnc->hFdCngCom->regularStopBand; /* Q0 */
    2225      121132 :     move16();
    2226      121132 :     Word16 numSlots = hFdCngEnc->hFdCngCom->numSlots; /* Q0 */
    2227      121132 :     move16();
    2228      121132 :     assert( numSlots == 16 );
    2229             : 
    2230      121132 :     Word32 numSlots_inv_fx = 1073741824; // Q34 of .0625
    2231      121132 :     move32();
    2232      121132 :     Word32 *periodog = hFdCngEnc->hFdCngCom->periodog; /* exp(peridog_exp) */
    2233      121132 :     Word32 *ptr_per_fx = periodog;
    2234             :     Word64 periodog_64;
    2235             :     Word16 periodog_exp[PERIODOGLEN];
    2236      121132 :     Word16 npart = hFdCngEnc->hFdCngCom->npart; /* Q0 */
    2237      121132 :     move16();
    2238      121132 :     Word16 nFFTpart = hFdCngEnc->hFdCngCom->nFFTpart; /* Q0 */
    2239      121132 :     move16();
    2240      121132 :     Word16 nCLDFBpart = hFdCngEnc->hFdCngCom->nCLDFBpart; /* Q0 */
    2241      121132 :     move16();
    2242             : 
    2243      121132 :     Word16 *psize = hFdCngEnc->hFdCngCom->psize; // 6Q9
    2244      121132 :     Word32 *msPeriodog_fx = hFdCngEnc->msPeriodog_fx;
    2245      121132 :     Word32 *msNoiseEst_fx = hFdCngEnc->msNoiseEst_fx; /* exp(msNoiseEst_fx_exp) */
    2246             : 
    2247      121132 :     Word16 *msLogPeriodog_fx = hFdCngEnc->msLogPeriodog_fx;
    2248      121132 :     Word16 *msLogNoiseEst_fx = hFdCngEnc->msLogNoiseEst_fx;
    2249             : 
    2250      121132 :     Word32 scaleEB_fx = 0;
    2251      121132 :     move32();
    2252             :     Word32 tmp;
    2253             : 
    2254      121132 :     test();
    2255      121132 :     IF( hCPE != NULL && hCPE->hStereoDft != NULL )
    2256             :     {
    2257             :         // band_res_dft = ( (float) input_Fs ) / hCPE->hStereoDft->NFFT;
    2258             :         // chan_width_f = 24000.f / CLDFB_NO_CHANNELS_MAX;
    2259             :         // chan_width_bins = chan_width_f / band_res_dft;
    2260             : 
    2261             :         ///* Scaling of Energy buffer to get energy per sample, same scaling as for band_energies, 3 is to compensate for the 1/3 scaling in calculate_energy_buffer */
    2262             :         // scaleEB = 3 * 4.0f / ( hCPE->hStereoDft->NFFT * hCPE->hStereoDft->NFFT );
    2263             : 
    2264             :         ///* Scale with number of bins in one band */
    2265             :         // scaleEB = scaleEB / chan_width_bins;
    2266             : 
    2267       30299 :         SWITCH( input_Fs )
    2268             :         {
    2269           0 :             case 8000:
    2270           0 :                 scaleEB_fx = 251648; // Q35
    2271           0 :                 move32();
    2272           0 :                 BREAK;
    2273        6282 :             case 16000:
    2274        6282 :                 scaleEB_fx = 62912; // Q35
    2275        6282 :                 move32();
    2276        6282 :                 BREAK;
    2277       15751 :             case 32000:
    2278       15751 :                 scaleEB_fx = 15728; // Q35
    2279       15751 :                 move32();
    2280       15751 :                 BREAK;
    2281        8266 :             case 48000:
    2282        8266 :                 scaleEB_fx = 6991; // Q35
    2283        8266 :                 move32();
    2284        8266 :                 BREAK;
    2285           0 :             default:
    2286           0 :                 assert( 0 && "invalid sample rate" );
    2287             :         }
    2288             :     }
    2289             :     ELSE
    2290             :     {
    2291       90833 :         scaleEB_fx = Mpy_32_32( numSlots_inv_fx, L_deposit_l( hFdCngEnc->hFdCngCom->scalingFactor ) ); // Q34 + Q30 - Q31 = Q33
    2292       90833 :         scaleEB_fx = L_shl( scaleEB_fx, 2 );                                                           // Q35
    2293             :     }
    2294             : 
    2295             :     /* preemphasis compensation and grouping of per bin energies into msPeriodog */
    2296     2543772 :     FOR( i = 0; i < nFFTpart; i++ )
    2297             :     {
    2298     2422640 :         tmp = L_add( L_shr( band_energies[i], 1 ), L_shr( band_energies[i + NB_BANDS], 1 ) );
    2299     2422640 :         msPeriodog_fx[i] = Mpy_32_16_1( tmp, preemphCompensation_fx[i] );
    2300     2422640 :         move32();
    2301             :     }
    2302             : 
    2303             :     /* exponent for fft part of msPeriodog */
    2304      121132 :     hFdCngEnc->msPeriodog_fx_exp_fft = add( band_energies_exp, PREEMPH_COMPENSATION_EXP );
    2305      121132 :     move16();
    2306             : 
    2307      121132 :     Word16 max_exp = -31;
    2308      121132 :     move16();
    2309      121132 :     i = 0;
    2310      121132 :     move16();
    2311             :     /* Adjust to the desired time resolution by averaging the periodograms over the time slots */
    2312     2684300 :     FOR( j = numCoreBands; j < regularStopBand; j++ )
    2313             :     {
    2314     2563168 :         periodog_64 = W_mult_32_32( enerBuffer[j], scaleEB_fx );
    2315     2563168 :         Word16 scale = W_norm( periodog_64 );
    2316     2563168 :         *ptr_per_fx = W_extract_h( W_shl( periodog_64, scale ) );
    2317     2563168 :         move32();
    2318     2563168 :         periodog_exp[i] = sub( Q31, add( add( sub( Q31, enerBuffer_exp ), 35 - 31 ), scale ) );
    2319     2563168 :         move16();
    2320     2563168 :         if ( *ptr_per_fx )
    2321             :         {
    2322     2540850 :             max_exp = s_max( max_exp, periodog_exp[i] );
    2323             :         }
    2324     2563168 :         ptr_per_fx++;
    2325     2563168 :         i++;
    2326             :     }
    2327             :     /* exponent for cldfb part of msPeriodog */
    2328             :     // hFdCngEnc->hFdCngCom->exp_cldfb_periodog = add( sub( enerBuffer_exp, 4 ), CLDFBscalingFactor_EXP );
    2329             :     //  move16();
    2330             : 
    2331      121132 :     numBands = sub( regularStopBand, numCoreBands ); /* Q0 */
    2332     2684300 :     FOR( i = 0; i < numBands; i++ )
    2333             :     {
    2334             : 
    2335     2563168 :         periodog[i] = L_shr( periodog[i], sub( max_exp, periodog_exp[i] ) );
    2336             : 
    2337     2563168 :         move16();
    2338             :     }
    2339      121132 :     hFdCngEnc->hFdCngCom->exp_cldfb_periodog = max_exp;
    2340      121132 :     move16();
    2341      121132 :     IF( numBands > 0 )
    2342             :     {
    2343             :         ///* Adjust CLDFB filterbank to the desired frequency resolution by averaging over spectral partitions for SID transmission */
    2344      121132 :         bandcombinepow(
    2345             :             periodog,
    2346      121132 :             hFdCngEnc->hFdCngCom->exp_cldfb_periodog,
    2347             :             numBands,
    2348      121132 :             hFdCngEnc->hFdCngCom->CLDFBpart,
    2349             :             nCLDFBpart,
    2350      121132 :             hFdCngEnc->hFdCngCom->CLDFBpsize_inv,
    2351      121132 :             &msPeriodog_fx[nFFTpart],
    2352             :             &hFdCngEnc->msPeriodog_fx_exp_cldfb );
    2353             : 
    2354             :         ///* find common exponent for fft part and cldfb part of msperiodog */
    2355      121132 :         s1 = L_norm_arr( msPeriodog_fx, nFFTpart );
    2356      121132 :         s2 = L_norm_arr( &msPeriodog_fx[nFFTpart], nCLDFBpart );
    2357             : 
    2358      121132 :         s = s_max( sub( hFdCngEnc->msPeriodog_fx_exp_fft, s1 ), sub( hFdCngEnc->msPeriodog_fx_exp_cldfb, s2 ) );
    2359      121132 :         s1 = sub( s, hFdCngEnc->msPeriodog_fx_exp_fft );
    2360      121132 :         s2 = sub( s, hFdCngEnc->msPeriodog_fx_exp_cldfb );
    2361             : 
    2362      121132 :         hFdCngEnc->msPeriodog_fx_exp_fft = s;
    2363      121132 :         move16();
    2364      121132 :         hFdCngEnc->msPeriodog_fx_exp_cldfb = s;
    2365      121132 :         move16();
    2366             : 
    2367     2543772 :         FOR( i = 0; i < nFFTpart; i++ )
    2368             :         {
    2369     2422640 :             msPeriodog_fx[i] = L_shr( msPeriodog_fx[i], s1 ); /*  hFdCngEnc->msPeriodog_fx_exp_fft */
    2370     2422640 :             move32();
    2371             :         }
    2372             : 
    2373      554060 :         FOR( i = 0; i < nCLDFBpart; i++ )
    2374             :         {
    2375      432928 :             msPeriodog_fx[nFFTpart + i] = L_shr( msPeriodog_fx[nFFTpart + i], s2 ); /*  hFdCngEnc->msPeriodog_fx_exp_fft */
    2376      432928 :             move32();
    2377             :         }
    2378             :     }
    2379             :     /* exponent for entire msPeriodog vector */
    2380      121132 :     hFdCngEnc->msPeriodog_fx_exp = hFdCngEnc->msPeriodog_fx_exp_fft;
    2381      121132 :     move16();
    2382             : 
    2383             :     /* Compress MS inputs */
    2384             :     // compress_range_flt( msPeriodog, msLogPeriodog, npart );
    2385      121132 :     compress_range( msPeriodog_fx, hFdCngEnc->msPeriodog_fx_exp, msLogPeriodog_fx, npart );
    2386             : 
    2387             : 
    2388             :     /* Call the minimum statistics routine for noise estimation */
    2389             : 
    2390      121132 :     minimum_statistics_fx( npart, nFFTpart, psize, msLogPeriodog_fx, hFdCngEnc->msNoiseFloor_fx, msLogNoiseEst_fx, hFdCngEnc->msAlpha_fx, hFdCngEnc->msPsd_fx, hFdCngEnc->msPsdFirstMoment_fx,
    2391      121132 :                            hFdCngEnc->msPsdSecondMoment_fx, hFdCngEnc->msMinBuf_fx, hFdCngEnc->msBminWin_fx, hFdCngEnc->msBminSubWin_fx, hFdCngEnc->msCurrentMin_fx, hFdCngEnc->msCurrentMinOut_fx, hFdCngEnc->msCurrentMinSubWindow_fx, hFdCngEnc->msLocalMinFlag, hFdCngEnc->msNewMinFlag, hFdCngEnc->msPeriodogBuf_fx, &( hFdCngEnc->msPeriodogBufPtr ), hFdCngEnc->hFdCngCom,
    2392       68424 :                            ENC, ( hCPE == NULL ) ? 0 : hCPE->element_mode );
    2393             : 
    2394             :     /* Expand MS outputs */
    2395      121132 :     expand_range( msLogNoiseEst_fx, msNoiseEst_fx, &hFdCngEnc->msNoiseEst_fx_exp, hFdCngEnc->hFdCngCom->npart );
    2396             : 
    2397      121132 :     return;
    2398             : }
    2399             : 
    2400             : 
    2401             : /*-------------------------------------------------------------------*
    2402             :  * FdCng_encodeSID()
    2403             :  *
    2404             :  * Generate a bitstream out of the partition levels
    2405             :  *-------------------------------------------------------------------*/
    2406        1954 : void FdCng_encodeSID_ivas_fx(
    2407             :     Encoder_State *st /* i/o: encoder state structure     */
    2408             : )
    2409             : {
    2410             :     Word16 N;
    2411        1954 :     HANDLE_FD_CNG_ENC hFdCngEnc = st->hFdCngEnc;
    2412        1954 :     HANDLE_FD_CNG_COM hFdCngCom = hFdCngEnc->hFdCngCom;
    2413        1954 :     BSTR_ENC_HANDLE hBstr = st->hBstr;
    2414             : 
    2415             :     Word32 *invTrfMatrix_fx, *E_fx;
    2416             :     Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC];
    2417             :     Word32 v_fx[32], gain_fx, e_fx, temp;
    2418             :     Word16 w_fx[32], indices[32], exp[32];
    2419             :     Word32 dct_target_fx[FDCNG_VQ_DCT_MAXTRUNC];
    2420             :     Word32 tot_sig_ext_fx[FDCNG_VQ_MAX_LEN];
    2421             :     Word16 v_e, gain_q_offset, preemph_fac;
    2422             :     Word16 i, index;
    2423             : 
    2424        1954 :     gain_q_offset = GAIN_Q_OFFSET_IVAS_FX_Q0;
    2425        1954 :     move16();
    2426             : 
    2427        1954 :     if ( st->element_mode == EVS_MONO )
    2428             :     {
    2429           0 :         gain_q_offset = GAIN_Q_OFFSET_EVS_FX_Q0;
    2430           0 :         move16();
    2431             :     }
    2432             : 
    2433        1954 :     preemph_fac = st->preemph_fac; // Q15
    2434        1954 :     move16();
    2435             : 
    2436             :     /* Init */
    2437        1954 :     N = hFdCngEnc->npartDec;
    2438        1954 :     move16();
    2439             : 
    2440        1954 :     E_fx = hFdCngEnc->msNoiseEst_fx;
    2441             : 
    2442        1954 :     invTrfMatrix_fx = (Word32 *) tmpRAM_fx; /* dynamically filled  */
    2443             : 
    2444        1954 :     set_zero_fx( v_fx, FDCNG_VQ_MAX_LEN );
    2445             : 
    2446             :     /* Convert to LOG */
    2447        1954 :     e_fx = 0;
    2448        1954 :     move32();
    2449       47326 :     FOR( i = 0; i < N; i++ )
    2450             :     {
    2451       45372 :         IF( E_fx[i] == 0 )
    2452             :         {
    2453             :             /* 10 * log(1e-4) = 10 * (-4) = -40 */
    2454           4 :             v_fx[i] = -41943040; // -40.0 in Q20
    2455           4 :             move32();
    2456             :         }
    2457             :         ELSE
    2458             :         {
    2459       45368 :             v_fx[i] = Mpy_32_32( 671088640 /*10 in Q26*/, BASOP_Util_Log10( E_fx[i], hFdCngEnc->msNoiseEst_fx_exp ) ); // Q20 = 26+25-31
    2460       45368 :             move32();
    2461             :         }
    2462       45372 :         e_fx = L_add( e_fx, v_fx[i] ); // Q20
    2463             :     }
    2464             : 
    2465             :     /* Normalize MSVQ input */
    2466        1954 :     gain_fx = 0;
    2467        1954 :     move32();
    2468       27356 :     FOR( i = N_GAIN_MIN; i < N_GAIN_MAX; i++ )
    2469             :     {
    2470       25402 :         gain_fx = L_add( gain_fx, v_fx[i] ); // Q20
    2471             :     }
    2472             : 
    2473             :     /*gain /= (float) ( N_GAIN_MAX - N_GAIN_MIN );*/
    2474        1954 :     gain_fx = Mpy_32_32( gain_fx, 165191050 /* 1/13 in Q31*/ ); // Q20
    2475             : 
    2476       47326 :     FOR( i = 0; i < N; i++ )
    2477             :     {
    2478       45372 :         v_fx[i] = L_sub( v_fx[i], gain_fx ); // Q20
    2479       45372 :         move32();
    2480             :     }
    2481             : 
    2482        1954 :     v_e = 11; // Q20
    2483        1954 :     move16();
    2484             : 
    2485             :     /* MSVQ encoder */
    2486        1954 :     set_val_Word16( w_fx, ONE_IN_Q8, N );
    2487             : 
    2488        1954 :     IF( st->element_mode != EVS_MONO )
    2489             :     {
    2490             :         /* DCT domain compressed/truncated indices used for first stage  */
    2491             :         /*  quantization with stage1 stored in DCT24 domain,   stages 2 through 6 directly dearched
    2492             :            in FDCNG band domain
    2493             :         */
    2494        1954 :         IF( EQ_16( N, FDCNG_VQ_MAX_LEN_WB ) )
    2495             :         {
    2496             :             /* truncated DCT21 analysis */
    2497         508 :             create_IDCT_N_Matrix_fx( invTrfMatrix_fx, N, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM_fx ) / ( sizeof( Word32 ) ) ); // Q31
    2498             : 
    2499         508 :             dctT2_N_apply_matrix_fx( v_fx /*Q20*/, dct_target_fx, FDCNG_VQ_DCT_MAXTRUNC, N, invTrfMatrix_fx, FDCNG_VQ_DCT_MAXTRUNC, DCT_T2_21_XX ); // Q20
    2500             : 
    2501             :             /* truncated IDCT21 extension to 24 bands  */
    2502         508 :             extend_dctN_input_fx( v_fx, dct_target_fx, N, tot_sig_ext_fx, FDCNG_VQ_MAX_LEN, invTrfMatrix_fx, FDCNG_VQ_DCT_MAXTRUNC, IDCT_T2_XX_21 ); // Q20
    2503             : 
    2504         508 :             Copy32( tot_sig_ext_fx, v_fx, FDCNG_VQ_MAX_LEN ); /*  write  extended result as input to  VQ stage #1 */ // Q20
    2505             :         }
    2506             : 
    2507        1954 :         create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM_fx ) / ( sizeof( Word32 ) ) ); // Q31
    2508             : 
    2509        1954 :         msvq_enc_ivas_fx( ivas_cdk_37bits_fx, Q7, NULL, NULL, v_fx, v_e, levels_37bits, FD_CNG_maxC_37bits, FD_CNG_stages_37bits, w_fx, N, FD_CNG_maxN_37bits, 1, invTrfMatrix_fx, indices );
    2510             : 
    2511        1954 :         msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix_fx, v_fx, NULL, 7 );
    2512             : 
    2513        1954 :         v_e = sub( 31, sub( 20, find_guarded_bits_fx( N ) ) );
    2514             :     }
    2515             :     ELSE
    2516             :     { /* EVS_MONO tables */
    2517           0 :         msvq_enc_ivas_fx( ivas_cdk_37bits_fx, Q7, NULL, NULL, v_fx, v_e, levels_37bits, FD_CNG_maxC_37bits, FD_CNG_stages_37bits, w_fx, N, FD_CNG_maxN_37bits, 0, NULL, indices );
    2518             : 
    2519           0 :         msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 0, NULL, v_fx, NULL, 7 );
    2520             : 
    2521           0 :         v_e = sub( 31, sub( 20, find_guarded_bits_fx( N ) ) );
    2522             :     }
    2523             : 
    2524             :     /* Compute gain */
    2525        1954 :     gain_fx = 0;
    2526        1954 :     move32();
    2527       47326 :     FOR( i = 0; i < N; i++ )
    2528             :     {
    2529       45372 :         gain_fx = L_add( gain_fx, v_fx[i] ); // Q = 31 - v_e
    2530             :     }
    2531             : 
    2532        1954 :     e_fx = L_shl( e_fx, sub( 11, v_e ) );                           // Q = 31 - v_e
    2533        1954 :     gain_fx = Mpy_32_16_1( L_sub( e_fx, gain_fx ), div_s( 1, N ) ); // Q = 31 - v_e
    2534        1954 :     gain_fx = L_shl( gain_fx, sub( v_e, 8 ) );                      // Q23
    2535             : 
    2536             :     /* Apply bitrate-dependant scale */
    2537        1954 :     IF( st->element_mode > EVS_MONO )
    2538             :     {
    2539        1954 :         apply_scale( &gain_fx, hFdCngCom->CngBandwidth, hFdCngCom->CngBitrate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO );
    2540             :     }
    2541             :     ELSE
    2542             :     {
    2543           0 :         apply_scale( &gain_fx, hFdCngCom->CngBandwidth, hFdCngCom->CngBitrate, scaleTableMono, SIZE_SCALE_TABLE_MONO );
    2544             :     }
    2545             : 
    2546             :     /* Quantize gain */
    2547        1954 :     temp = Madd_32_32( L_shl( gain_q_offset, 22 ), gain_fx, 1610612736 /*1.5 in Q30*/ ); // Q22
    2548        1954 :     index = extract_l( L_shr( L_add( temp, ONE_IN_Q21 ), 22 ) );                         // Q0
    2549             : 
    2550        1954 :     if ( index < 0 )
    2551             :     {
    2552         364 :         index = 0;
    2553         364 :         move16();
    2554             :     }
    2555             : 
    2556        1954 :     if ( GT_16( index, 127 ) )
    2557             :     {
    2558           0 :         index = 127;
    2559           0 :         move16();
    2560             :     }
    2561             : 
    2562        1954 :     gain_fx = L_shl( L_mult0( sub( index, gain_q_offset ), 21845 /*1.5 in Q15*/ ), sub( 16, v_e ) ); // Q = 31-v_e
    2563             : 
    2564             :     /* Apply gain and undo log */
    2565       47326 :     FOR( i = 0; i < N; i++ )
    2566             :     {
    2567       45372 :         temp = Mpy_32_32( L_add( v_fx[i], gain_fx ), 214748365 /* 0.1 in Q31*/ ); // Q = 31-v_e
    2568       45372 :         hFdCngCom->sidNoiseEst[i] = BASOP_Util_fPow( 10, 31, temp, v_e, &exp[i] );
    2569       45372 :         move32();
    2570             :     }
    2571             : 
    2572        1954 :     maximum_s( exp, N, &hFdCngCom->sidNoiseEstExp );
    2573             : 
    2574       47326 :     FOR( i = 0; i < N; i++ )
    2575             :     {
    2576       45372 :         hFdCngCom->sidNoiseEst[i] = L_shr( hFdCngCom->sidNoiseEst[i], sub( hFdCngCom->sidNoiseEstExp, exp[i] ) ); // exp = hFdCngCom->sidNoiseEstExp
    2577       45372 :         move32();
    2578             :     }
    2579             : 
    2580             :     /* NB last band energy compensation */
    2581        1954 :     IF( hFdCngCom->CngBandwidth == NB )
    2582             :     {
    2583           0 :         hFdCngCom->sidNoiseEst[N - 1] = Mpy_32_16_1( hFdCngCom->sidNoiseEst[N - 1], NB_LAST_BAND_SCALE ); // exp(hFdCngCom->sidNoiseEstExp)
    2584           0 :         move32();
    2585             :     }
    2586             : 
    2587        1954 :     test();
    2588        1954 :     IF( EQ_16( hFdCngCom->CngBandwidth, SWB ) && LE_32( hFdCngCom->CngBitrate, ACELP_13k20 ) )
    2589             :     {
    2590         767 :         hFdCngCom->sidNoiseEst[N - 1] = Mpy_32_16_1( hFdCngCom->sidNoiseEst[N - 1], SWB_13k2_LAST_BAND_SCALE ); // exp(hFdCngCom->sidNoiseEstExp)
    2591         767 :         move32();
    2592             :     }
    2593             : 
    2594             :     /* Write bitstream */
    2595        1954 :     IF( EQ_16( st->codec_mode, MODE2 ) )
    2596             :     {
    2597           0 :         FOR( i = 0; i < FD_CNG_stages_37bits; i++ )
    2598             :         {
    2599           0 :             push_next_indice( hBstr, indices[i], bits_37bits[i] );
    2600             :         }
    2601             : 
    2602           0 :         push_next_indice( hBstr, index, 7 );
    2603             :     }
    2604             :     ELSE
    2605             :     {
    2606        1954 :         Word16 is_frame_len_16k = 0;
    2607        1954 :         move16();
    2608        1954 :         if ( EQ_16( st->L_frame, L_FRAME16k ) )
    2609             :         {
    2610         844 :             is_frame_len_16k = 1;
    2611         844 :             move16();
    2612             :         }
    2613        1954 :         push_indice( hBstr, IND_SID_TYPE, 1, 1 );
    2614        1954 :         push_indice( hBstr, IND_BWIDTH, st->bwidth, 2 );
    2615        1954 :         push_indice( hBstr, IND_ACELP_16KHZ, is_frame_len_16k, 1 );
    2616             : 
    2617       13678 :         FOR( i = 0; i < FD_CNG_stages_37bits; i++ )
    2618             :         {
    2619       11724 :             push_indice( hBstr, IND_LSF, indices[i], bits_37bits[i] );
    2620             :         }
    2621             : 
    2622        1954 :         push_indice( hBstr, IND_ENERGY, index, 7 );
    2623             :     }
    2624             : 
    2625             :     /* Interpolate the bin/band-wise levels from the partition levels */
    2626        1954 :     scalebands( hFdCngCom->sidNoiseEst, hFdCngEnc->partDec, hFdCngEnc->npartDec, hFdCngEnc->midbandDec, hFdCngEnc->nFFTpartDec, sub( hFdCngEnc->stopBandDec, hFdCngEnc->startBandDec ), hFdCngCom->cngNoiseLevel, 1 );
    2627        1954 :     hFdCngCom->cngNoiseLevelExp = hFdCngCom->sidNoiseEstExp;
    2628        1954 :     move16();
    2629             : 
    2630        1954 :     lpc_from_spectrum( hFdCngCom, hFdCngEnc->startBandDec, hFdCngEnc->stopFFTbinDec, preemph_fac );
    2631             : 
    2632        1954 :     return;
    2633             : }
    2634             : 
    2635             : 
    2636             : /*-------------------------------------------------------------------*
    2637             :  * stereoFdCngCoherence()
    2638             :  *
    2639             :  * compute coherence of channels for use in FD-CNG
    2640             :  *-------------------------------------------------------------------*/
    2641       18228 : void stereoFdCngCoherence_fx(
    2642             :     Encoder_State **sts,                        /* i/o: core encoder structures          */
    2643             :     const Word16 last_element_mode,             /* i  : last element mode                Q0*/
    2644             :     Word16 fft_buf_fx[CPE_CHANNELS][2 * L_FFT], /* i  : fft buffers for L and R channels fft_exp*/
    2645             :     Word16 fft_exp )
    2646             : {
    2647             :     const Word16 *pt_fftL, *pt_fftR;
    2648             :     Word16 i_subfr, i;
    2649             :     Word32 cr, ci, eL, eR;
    2650             :     Word16 cr_exp, ci_exp, eL_exp, eR_exp;
    2651             :     Word32 *mem;
    2652             :     Word16 *mem_exp;
    2653             : 
    2654       18228 :     IF( NE_16( last_element_mode, IVAS_CPE_MDCT ) )
    2655             :     {
    2656          63 :         set32_fx( sts[0]->hFdCngEnc->mem_coherence_fx, EPSILON_FX, 4 );
    2657          63 :         set16_fx( sts[0]->hFdCngEnc->mem_coherence_exp, 0, 4 );
    2658             :     }
    2659       18228 :     test();
    2660       18228 :     test();
    2661       18228 :     IF( EQ_32( sts[0]->core_brate, -1 ) || EQ_32( sts[1]->core_brate, -1 ) )
    2662             :     {
    2663             :         /* case: at least one channel has triggered VAD -> ACTIVE FRAME */
    2664       14492 :         IF( EQ_32( sts[0]->core_brate, -1 ) )
    2665             :         {
    2666       13972 :             sts[1]->total_brate = sts[0]->total_brate; /* Q0 */
    2667       13972 :             move32();
    2668       13972 :             sts[1]->active_cnt = sts[0]->active_cnt; /* Q0 */
    2669       13972 :             move16();
    2670       13972 :             if ( GE_32( sts[1]->active_cnt, CNG_TYPE_HO ) )
    2671             :             {
    2672       12840 :                 sts[1]->last_total_brate_cng = -1;
    2673       12840 :                 move16();
    2674             :             }
    2675             :         }
    2676       14492 :         IF( EQ_32( sts[1]->core_brate, -1 ) )
    2677             :         {
    2678       13679 :             sts[0]->total_brate = sts[1]->total_brate; /* Q0 */
    2679       13679 :             move32();
    2680       13679 :             sts[0]->active_cnt = sts[1]->active_cnt; /* Q0 */
    2681       13679 :             move16();
    2682       13679 :             if ( GE_16( sts[0]->active_cnt, CNG_TYPE_HO ) )
    2683             :             {
    2684       12589 :                 sts[0]->last_total_brate_cng = -1;
    2685       12589 :                 move16();
    2686             :             }
    2687             :         }
    2688       14492 :         sts[0]->core_brate = -1;
    2689       14492 :         move32();
    2690       14492 :         sts[1]->core_brate = -1;
    2691       14492 :         move32();
    2692       14492 :         sts[0]->hDtxEnc->cnt_SID = 0;
    2693       14492 :         move16();
    2694       14492 :         sts[1]->hDtxEnc->cnt_SID = 0;
    2695       14492 :         move16();
    2696             :     }
    2697        3736 :     ELSE IF( LE_32( sts[0]->core_brate, SID_2k40 ) && LE_32( sts[1]->core_brate, SID_2k40 ) )
    2698             :     {
    2699             :         /* case: no VAD for both channels -> INACTIVE FRAME */
    2700        3736 :         reset_indices_enc_fx( sts[0]->hBstr, sts[0]->hBstr->nb_ind_tot );
    2701             : 
    2702        3736 :         reset_indices_enc_fx( sts[1]->hBstr, sts[1]->hBstr->nb_ind_tot );
    2703             : 
    2704             :         /* synchronize SID sending for variable SID rate */
    2705        3736 :         IF( NE_32( sts[0]->core_brate, sts[1]->core_brate ) )
    2706             :         {
    2707           0 :             sts[0]->core_brate = SID_2k40;
    2708           0 :             move32();
    2709           0 :             sts[1]->core_brate = SID_2k40;
    2710           0 :             move32();
    2711             :         }
    2712             : 
    2713             :         /* synchronize SID counters */
    2714        3736 :         sts[0]->hDtxEnc->cnt_SID = s_min( sts[0]->hDtxEnc->cnt_SID, sts[1]->hDtxEnc->cnt_SID ); /* Q0 */
    2715        3736 :         sts[1]->hDtxEnc->cnt_SID = sts[0]->hDtxEnc->cnt_SID;                                    /* Q0 */
    2716        3736 :         move16();
    2717        3736 :         move16();
    2718             :     }
    2719             : 
    2720       18228 :     pt_fftL = fft_buf_fx[0];
    2721       18228 :     pt_fftR = fft_buf_fx[1];
    2722       18228 :     mem = sts[0]->hFdCngEnc->mem_coherence_fx; /* exp(sts[0]->hFdCngEnc->mem_coherence_exp) */
    2723       18228 :     mem_exp = sts[0]->hFdCngEnc->mem_coherence_exp;
    2724       54684 :     FOR( i_subfr = 0; i_subfr < 2; i_subfr++ )
    2725             :     {
    2726       36456 :         cr = ci = eL = eR = EPSILON_FX;
    2727       36456 :         move32();
    2728       36456 :         move32();
    2729       36456 :         move32();
    2730       36456 :         move32();
    2731       36456 :         cr_exp = ci_exp = eL_exp = eR_exp = 0;
    2732       36456 :         move16();
    2733       36456 :         move16();
    2734       36456 :         move16();
    2735       36456 :         move16();
    2736             : 
    2737       36456 :         cr = BASOP_Util_Add_Mant32Exp( cr, cr_exp, L_add( L_mult( pt_fftL[0], pt_fftR[0] ), L_mult( pt_fftL[L_FFT / 2], pt_fftR[L_FFT / 2] ) ), shl( fft_exp, 1 ), &cr_exp ); /* exp(cr_exp) */
    2738       36456 :         eL = BASOP_Util_Add_Mant32Exp( eL, eL_exp, L_add( L_mult( pt_fftL[0], pt_fftL[0] ), L_mult( pt_fftL[L_FFT / 2], pt_fftL[L_FFT / 2] ) ), shl( fft_exp, 1 ), &eL_exp ); /* exp(eL_exp) */
    2739       36456 :         eR = BASOP_Util_Add_Mant32Exp( eR, eR_exp, L_add( L_mult( pt_fftR[0], pt_fftR[0] ), L_mult( pt_fftR[L_FFT / 2], pt_fftR[L_FFT / 2] ) ), shl( fft_exp, 1 ), &eR_exp ); /* exp(eR_exp) */
    2740             : 
    2741     4666368 :         FOR( i = 1; i < L_FFT / 2; i++ )
    2742             :         {
    2743     4629912 :             cr = BASOP_Util_Add_Mant32Exp( cr, cr_exp, L_add( L_mult( pt_fftL[i], pt_fftR[i] ), L_mult( pt_fftL[L_FFT - i], pt_fftR[L_FFT - i] ) ), shl( fft_exp, 1 ), &cr_exp );  /* exp(cr_exp) */
    2744     4629912 :             ci = BASOP_Util_Add_Mant32Exp( ci, ci_exp, L_add( L_mult( -pt_fftL[i], pt_fftR[L_FFT - i] ), L_mult( pt_fftL[L_FFT - i], pt_fftR[i] ) ), shl( fft_exp, 1 ), &ci_exp ); /* exp(ci_exp) */
    2745     4629912 :             eL = BASOP_Util_Add_Mant32Exp( eL, eL_exp, L_add( L_mult( pt_fftL[i], pt_fftL[i] ), L_mult( pt_fftL[L_FFT - i], pt_fftL[L_FFT - i] ) ), shl( fft_exp, 1 ), &eL_exp );  /* exp(eL_exp) */
    2746     4629912 :             eR = BASOP_Util_Add_Mant32Exp( eR, eR_exp, L_add( L_mult( pt_fftR[i], pt_fftR[i] ), L_mult( pt_fftR[L_FFT - i], pt_fftR[L_FFT - i] ) ), shl( fft_exp, 1 ), &eR_exp );  /* exp(eR_exp) */
    2747             :         }
    2748       36456 :         test();
    2749       36456 :         test();
    2750       36456 :         IF( LE_32( sts[0]->ini_frame, 50 ) || ( sts[0]->vad_flag == 0 && sts[1]->vad_flag == 0 ) )
    2751             :         {
    2752       12666 :             mem[0] = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( mem[0], 31129 /*0.95f*/ ), mem_exp[0], Mpy_32_16_1( cr, 1638 /*0.05f*/ ), cr_exp, &mem_exp[0] ); /* exp(mem_exp[0]) */
    2753       12666 :             move32();
    2754       12666 :             mem[1] = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( mem[1], 31129 /*0.95f*/ ), mem_exp[1], Mpy_32_16_1( ci, 1638 /*0.05f*/ ), ci_exp, &mem_exp[1] ); /* exp(mem_exp[1]) */
    2755       12666 :             move32();
    2756       12666 :             mem[2] = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( mem[2], 31129 /*0.95f*/ ), mem_exp[2], Mpy_32_16_1( eL, 1638 /*0.05f*/ ), eL_exp, &mem_exp[2] ); /* exp(mem_exp[2]) */
    2757       12666 :             move32();
    2758       12666 :             mem[3] = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( mem[3], 31129 /*0.95f*/ ), mem_exp[3], Mpy_32_16_1( eR, 1638 /*0.05f*/ ), eR_exp, &mem_exp[3] ); /* exp(mem_exp[3]) */
    2759       12666 :             move32();
    2760             :         }
    2761             : 
    2762       36456 :         pt_fftL += L_FFT;
    2763       36456 :         pt_fftR += L_FFT;
    2764             :     }
    2765             : 
    2766             :     Word16 sqr_inp, temp, sqr_out, sqr_inp_exp;
    2767       18228 :     Word32 sqr_inp32 = BASOP_Util_Add_Mant32Exp( Mpy_32_32( mem[0], mem[0] ), shl( mem_exp[0], 1 ), Mpy_32_32( mem[1], mem[1] ), shl( mem_exp[1], 1 ), &sqr_inp_exp ); /* exp(sqr_inp_exp) */
    2768       18228 :     sqr_inp = BASOP_Util_Divide3232_Scale( sqr_inp32, Mpy_32_32( mem[2], mem[3] ), &temp );
    2769       18228 :     sqr_inp_exp = add( temp, sub( sqr_inp_exp, add( mem_exp[2], mem_exp[3] ) ) );
    2770       18228 :     sqr_out = Sqrt16( sqr_inp, &sqr_inp_exp );
    2771       18228 :     sts[0]->hFdCngEnc->hFdCngCom->coherence_fx = shl_sat( sqr_out, sqr_inp_exp ); // Q15 expected.
    2772       18228 :     move16();
    2773       18228 :     return;
    2774             : }
    2775             : 
    2776             : /*-------------------------------------------------------------------*
    2777             :  * FdCngEncodeMDCTStereoSID()
    2778             :  *
    2779             :  * Encode DTX parameters and noise shapes into SID for MDCT-Stereo DTX
    2780             :  *-------------------------------------------------------------------*/
    2781             : 
    2782         416 : void FdCngEncodeMDCTStereoSID_fx(
    2783             :     CPE_ENC_HANDLE hCPE /* i/o: CPE encoder state structure     */
    2784             : )
    2785             : {
    2786             :     ENC_CORE_HANDLE sts[CPE_CHANNELS];
    2787             :     Word16 indices[CPE_CHANNELS][FD_CNG_stages_37bits];
    2788             :     Word16 gain_idx[CPE_CHANNELS];
    2789             :     Word16 N, stages, ch, p, coh_idx;
    2790             :     Word32 *lr_in_ptr_fx[CPE_CHANNELS];
    2791             :     Word16 lr_in_ptr_e[CPE_CHANNELS];
    2792             :     Word32 *ms_ptr_fx[CPE_CHANNELS];
    2793             :     Word16 ms_ptr_e;
    2794             :     Word32 *lr_out_ptr_fx[CPE_CHANNELS];
    2795             :     Word16 lr_out_ptr_e[CPE_CHANNELS];
    2796             :     Word32 logNoiseEst_fx[CPE_CHANNELS][NPART];
    2797             :     Word32 E_fx[CPE_CHANNELS];
    2798             :     Word32 gain_fx[CPE_CHANNELS];
    2799             :     Word16 weights_fx[NPART];
    2800             :     Word32 side_energy_fx;
    2801             :     Word16 Qside_energy;
    2802             :     Word32 *invTrfMatrix_fx;
    2803             :     Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC];                                   /*24*18*/
    2804         416 :     invTrfMatrix_fx = (Word32 *) tmpRAM_fx;                                                      /* dynamically filled  */
    2805             :     Word32 tot_sig_ext_fx[FDCNG_VQ_MAX_LEN], dct_target_fx[CPE_CHANNELS][FDCNG_VQ_DCT_MAXTRUNC]; /* 24 +2*18*/
    2806             :     Word16 tmp, tmp_e;
    2807             :     Word16 no_side_flag;
    2808             :     Word16 is_inp_ms;
    2809             :     Word16 size_value, temp_e, gb, shift;
    2810             :     Word32 tmp32, t1, t2;
    2811             : 
    2812         416 :     is_inp_ms = 0;
    2813         416 :     move16();
    2814         416 :     IF( EQ_16( hCPE->hCoreCoder[0]->cng_sba_flag, 1 ) )
    2815             :     {
    2816           0 :         is_inp_ms = 1;
    2817           0 :         move16();
    2818             :     }
    2819             : 
    2820             :     /* set pointers and initialize */
    2821        1248 :     FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
    2822             :     {
    2823         832 :         sts[ch] = hCPE->hCoreCoder[ch];
    2824         832 :         lr_in_ptr_fx[ch] = &sts[ch]->hFdCngEnc->msNoiseEst_fx[0]; /* exp(sts[ch]->hFdCngEnc->msNoiseEst_fx_exp) */
    2825         832 :         lr_in_ptr_e[ch] = sts[ch]->hFdCngEnc->msNoiseEst_fx_exp;
    2826         832 :         ms_ptr_fx[ch] = &logNoiseEst_fx[ch][0];
    2827         832 :         lr_out_ptr_fx[ch] = &sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEst[0]; /* exp(sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEstExp) */
    2828         832 :         lr_out_ptr_e[ch] = sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEstExp;
    2829             :     }
    2830         416 :     N = sts[0]->hFdCngEnc->npartDec; /* Q0 */
    2831         416 :     move16();
    2832         416 :     set16_fx( weights_fx, ONE_IN_Q8, NPART );
    2833             : 
    2834             :     /* apply log and save energy of original left and right channels */
    2835        1248 :     FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
    2836             :     {
    2837             :         // E[ch] = 0.0f;
    2838         832 :         E_fx[ch] = 0;
    2839         832 :         move32();
    2840       19810 :         FOR( p = 0; p < N; p++ )
    2841             :         {
    2842       18978 :             IF( lr_in_ptr_fx[ch][p] )
    2843             :             {
    2844       18978 :                 t1 = BASOP_Util_Log2( lr_in_ptr_fx[ch][p] );                 // Q25
    2845       18978 :                 t2 = L_add( t1, L_shl( lr_in_ptr_e[ch], Q25 ) );             // Q25
    2846       18978 :                 ms_ptr_fx[ch][p] = Mpy_32_32( t2, TEN_MULT_LOG10_2_IN_Q29 ); // Q23
    2847       18978 :                 move32();
    2848             :             }
    2849             :             ELSE
    2850             :             {
    2851             :                 // 10.f * log10f( EPSILON ) --> -150.0f
    2852             :                 // Subsequent additions / subtractions happen on these numbers, so to avoid saturations
    2853             :                 // this value is set to -128.0f in Q23
    2854           0 :                 ms_ptr_fx[ch][p] = -ONE_IN_Q30; // Q23
    2855           0 :                 move32();
    2856             :             }
    2857       18978 :             E_fx[ch] = L_add( E_fx[ch], L_shr( ms_ptr_fx[ch][p], 4 ) ); // Q19
    2858       18978 :             move32();
    2859             :         }
    2860             :     }
    2861         416 :     ms_ptr_e = Q31 - Q23;
    2862         416 :     move16();
    2863             : 
    2864             :     /* M/S transform on log envelopes */
    2865         416 :     IF( is_inp_ms == 0 )
    2866             :     {
    2867         416 :         convertToMS_fx( N, ms_ptr_fx[0], ms_ptr_fx[1], ONE_IN_Q30 ); // ms_ptr_e = Q23;
    2868             :     }
    2869             : 
    2870         416 :     gb = find_guarded_bits_fx( N );
    2871         416 :     side_energy_fx = sum2_f_32_fx( ms_ptr_fx[1], N, gb );
    2872         416 :     Qside_energy = sub( sub( shl( sub( 31, ms_ptr_e ), 1 ), 31 ), gb );
    2873             : 
    2874             :     /* do not transmit side shape if initial noise shapes are very similar */
    2875         416 :     IF( LE_32( side_energy_fx, L_shl( 214748365, sub( Qside_energy, Q31 ) ) ) )
    2876             :     {
    2877          11 :         no_side_flag = 1;
    2878          11 :         move16();
    2879             :     }
    2880             :     ELSE
    2881             :     {
    2882         405 :         no_side_flag = 0;
    2883         405 :         move16();
    2884             :     }
    2885             : 
    2886             :     /* Quantize noise shapes */
    2887        1248 :     FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
    2888             :     {
    2889             :         /* Normalize MSVQ input */
    2890         832 :         gain_fx[ch] = 0;
    2891         832 :         move32();
    2892       11648 :         FOR( p = N_GAIN_MIN; p < N_GAIN_MAX; p++ )
    2893             :         {
    2894       10816 :             tmp32 = Mpy_32_32( ms_ptr_fx[ch][p], 165191050 /* 0.07 in Q31*/ ); // Q23
    2895       10816 :             gain_fx[ch] = L_add( gain_fx[ch], tmp32 );                         // Q23
    2896       10816 :             move32();
    2897             :         }
    2898             : 
    2899       19810 :         FOR( p = 0; p < N; p++ )
    2900             :         {
    2901       18978 :             ms_ptr_fx[ch][p] = L_sub( ms_ptr_fx[ch][p], gain_fx[ch] ); // Q23
    2902       18978 :             move32();
    2903             :         }
    2904             :     }
    2905             : 
    2906             :     /* always split channel targetloop */
    2907             : 
    2908             :     /* extend fdcng envelope from length 21 to a 24 length fdncg domain envelope signal */
    2909             :     /* High quality cosine smooth basis extension used  to not introduce noise in stage#1  DCT24 analysis and subsequent VQ-steps */
    2910         416 :     IF( EQ_16( N, FDCNG_VQ_MAX_LEN_WB ) )
    2911             :     {
    2912         165 :         size_value = BASOP_Util_Divide1616_Scale( sizeof( tmpRAM_fx ), ( sizeof( Word32 ) ), &temp_e ); /*Q15*/
    2913         165 :         size_value = shr( size_value, sub( 15, temp_e ) );
    2914         165 :         create_IDCT_N_Matrix_fx( invTrfMatrix_fx, N, FDCNG_VQ_DCT_MAXTRUNC, size_value ); // Q31 /*WB: create truncated IDCT21 matrix */
    2915         495 :         for ( ch = 0; ch < CPE_CHANNELS; ch++ )
    2916             :         {
    2917             :             /* run DCT_N N==21 , truncated at 18/21 ~= 86% , i.e use a bit better better quality in extrapolation , than subsequent DCT24 analysis which is truncated at 75%*/
    2918             :             /* truncated DCT 21 analysis */
    2919         330 :             dctT2_N_apply_matrix_fx( (const Word32 *) ms_ptr_fx[ch], dct_target_fx[ch], FDCNG_VQ_DCT_MAXTRUNC, N, invTrfMatrix_fx, FDCNG_VQ_DCT_MAXTRUNC, DCT_T2_21_XX );
    2920             :             /* extrapolate extend fdcng envelope signal in the fdncg ienvelope/"time" domain using DCT21 basis vectors,
    2921             :                 estimated DCT21 coeffs scaling extended basis vectors are used to create extrapolated   length 24 input target envelope signal */
    2922             :             /* this DCT21 extension does not introduce DCT24 coefficient noise for  the subsequent dct24 target analysis, and later in IDCT24 synthesis  */
    2923             : 
    2924             :             /* truncated IDCT 21 extension synthesis  */
    2925         330 :             extend_dctN_input_fx( ms_ptr_fx[ch], dct_target_fx[ch], N, tot_sig_ext_fx, FDCNG_VQ_MAX_LEN, invTrfMatrix_fx /* DCT_N basis vectors */, FDCNG_VQ_DCT_MAXTRUNC, IDCT_T2_XX_21 ); /* use 18 basis vectors*/
    2926             : 
    2927         330 :             Copy32( tot_sig_ext_fx, ms_ptr_fx[ch], FDCNG_VQ_MAX_LEN ); /*  write  extended result as input to  VQ */
    2928             :         }
    2929             :     }
    2930             : 
    2931         416 :     size_value = BASOP_Util_Divide1616_Scale( sizeof( tmpRAM_fx ), ( sizeof( Word32 ) ), &temp_e ); /*Q15*/
    2932         416 :     size_value = shr( size_value, sub( 15, temp_e ) );
    2933         416 :     create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, size_value ); /*always create/set up  IDCT24 matrix in RAM */
    2934             : 
    2935             :     /* end split */
    2936        1248 :     FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
    2937             :     {
    2938             :         /* MSVQ */
    2939         832 :         IF( ch )
    2940             :         {
    2941         416 :             stages = FD_CNG_JOINT_stages_25bits;
    2942         416 :             move16();
    2943             :         }
    2944             :         ELSE
    2945             :         {
    2946         416 :             stages = FD_CNG_stages_37bits;
    2947         416 :             move16();
    2948             :         }
    2949             : 
    2950             :         /* DCT24 domain compressed/truncated indices used for first stage  */
    2951             :         /*             mid  channel quantization using stages 1 through 6 */
    2952             :         /*           & side channel quantization using stages 1 through 4 */
    2953             : 
    2954             :         {
    2955         832 :             msvq_enc_ivas_fx( ivas_cdk_37bits_fx, Q7, NULL, NULL, ms_ptr_fx[ch], ms_ptr_e, levels_37bits, FD_CNG_maxC_37bits, stages, weights_fx, N, FD_CNG_maxN_37bits, 1, invTrfMatrix_fx, indices[ch] );
    2956         832 :             msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, stages, N, FD_CNG_maxN_37bits, indices[ch], 1, invTrfMatrix_fx, ms_ptr_fx[ch], NULL, 7 );
    2957             :         }
    2958             :     }
    2959         416 :     shift = find_guarded_bits_fx( N );
    2960         416 :     ms_ptr_e = sub( 31, sub( 20, shift ) );
    2961             : 
    2962         416 :     IF( no_side_flag )
    2963             :     {
    2964          11 :         set32_fx( ms_ptr_fx[1], 0, N );
    2965             :     }
    2966             : 
    2967             :     /* undo M/S */
    2968         416 :     IF( is_inp_ms == 0 )
    2969             :     {
    2970         416 :         convertToMS_fx( N, ms_ptr_fx[0], ms_ptr_fx[1], ONE_IN_Q31 );
    2971             :     }
    2972             : 
    2973             :     /* Compute gain against original left and right channels */
    2974        1248 :     FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
    2975             :     {
    2976         832 :         gain_fx[ch] = 0;
    2977         832 :         move32();
    2978             : 
    2979         832 :         tmp_e = 15;
    2980         832 :         move16();
    2981         832 :         tmp = Inv16( N, &tmp_e );
    2982       19810 :         FOR( p = 0; p < N; p++ )
    2983             :         {
    2984       18978 :             gain_fx[ch] = L_add( gain_fx[ch], Mpy_32_16_1( ms_ptr_fx[ch][p], shl( tmp, tmp_e ) ) ); // Q23
    2985       18978 :             move32();
    2986             :         }
    2987         832 :         gain_fx[ch] = L_sub( L_shl( Mpy_32_16_1( E_fx[ch], shl( tmp, tmp_e ) ), Q23 - Q19 ), L_shl( gain_fx[ch], sub( ms_ptr_e, 8 ) ) ); // Q23
    2988         832 :         move32();
    2989             : 
    2990         832 :         apply_scale( &gain_fx[ch], sts[ch]->hFdCngEnc->hFdCngCom->CngBandwidth, sts[ch]->element_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO );
    2991             : 
    2992             :         /* quantize gain */
    2993         832 :         gain_idx[ch] = (Word16) Mpy_32_32_r( L_add( gain_fx[ch], 251658240 ), 384 ); // Q23
    2994         832 :         move16();
    2995         832 :         gain_idx[ch] = s_max( 0, s_min( 127, gain_idx[ch] ) );
    2996         832 :         move16();
    2997             : 
    2998         832 :         gain_fx[ch] = Mpy_32_16_1( L_shl( sub( gain_idx[ch], GAIN_Q_OFFSET_IVAS_FX_Q0 ), 23 ), 21845 ); // Q23
    2999         832 :         move32();
    3000             :     }
    3001             : 
    3002             :     /* restore channel noise envelopes */
    3003        1248 :     FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
    3004             :     {
    3005         832 :         HANDLE_FD_CNG_ENC hFdCngEnc = sts[ch]->hFdCngEnc;
    3006         832 :         HANDLE_FD_CNG_COM hFdCngCom = hFdCngEnc->hFdCngCom;
    3007             : 
    3008         832 :         tmp_e = 0;
    3009         832 :         move16();
    3010             :         Word32 pow;
    3011             : 
    3012             :         Word16 e_lr_out[NPART];
    3013             : 
    3014       19810 :         FOR( p = 0; p < N; p++ )
    3015             :         {
    3016       18978 :             pow = L_shl( gain_fx[ch], 8 - ms_ptr_e );
    3017       18978 :             pow = L_add( ms_ptr_fx[ch][p], pow );
    3018       18978 :             pow = Mpy_32_32( pow, 214748365 ); /*pow = 0.1*/
    3019       18978 :             lr_out_ptr_fx[ch][p] = BASOP_Util_fPow( 10, 31, pow, ms_ptr_e, &e_lr_out[p] );
    3020       18978 :             move32();
    3021       18978 :             tmp_e = s_max( tmp_e, e_lr_out[p] );
    3022             :         }
    3023             : 
    3024       19810 :         FOR( p = 0; p < N; p++ )
    3025             :         {
    3026       18978 :             lr_out_ptr_fx[ch][p] = L_shl( lr_out_ptr_fx[ch][p], e_lr_out[p] - tmp_e );
    3027       18978 :             move32();
    3028             :         }
    3029         832 :         lr_out_ptr_e[ch] = tmp_e;
    3030         832 :         move32();
    3031             : 
    3032         832 :         sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEstExp = tmp_e;
    3033         832 :         move16();
    3034             : 
    3035             :         /* scale bands and get scalefactors */
    3036         832 :         scalebands( lr_out_ptr_fx[ch], hFdCngEnc->partDec, N, hFdCngEnc->midbandDec, hFdCngEnc->nFFTpartDec, sub( hFdCngEnc->stopBandDec, hFdCngEnc->startBandDec ), hFdCngCom->cngNoiseLevel, 1 );
    3037         832 :         hFdCngCom->cngNoiseLevelExp = lr_out_ptr_e[ch];
    3038         832 :         move16();
    3039             : 
    3040         832 :         lpc_from_spectrum( hFdCngCom, hFdCngEnc->startBandDec, hFdCngEnc->stopFFTbinDec, sts[ch]->preemph_fac );
    3041             : 
    3042         832 :         sts[ch]->hDtxEnc->last_CNG_L_frame = sts[ch]->L_frame;
    3043             :     }
    3044             : 
    3045             :     /* quantize channel coherence */
    3046         416 :     coh_idx = mult_r( sts[0]->hFdCngEnc->hFdCngCom->coherence_fx, 15 );
    3047         416 :     coh_idx = s_max( 0, s_min( coh_idx, 15 ) );
    3048             : 
    3049             :     /* ---- Write SID bitstream ---- */
    3050             : 
    3051             : 
    3052             :     /* noise shapes and channel gains */
    3053        1248 :     FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
    3054             :     {
    3055         832 :         IF( ch )
    3056             :         {
    3057         416 :             stages = FD_CNG_JOINT_stages_25bits;
    3058         416 :             sts[ch]->hBstr->ind_list = sts[0]->hBstr->ind_list + sts[0]->hBstr->nb_ind_tot;
    3059             : 
    3060             :             /* side info */
    3061         416 :             push_indice( sts[ch]->hBstr, IND_SID_TYPE, coh_idx, 4 );
    3062         416 :             push_indice( sts[ch]->hBstr, IND_SID_TYPE, no_side_flag, 1 );
    3063             :         }
    3064             :         ELSE
    3065             :         {
    3066         416 :             stages = FD_CNG_stages_37bits;
    3067             :             /* side info */
    3068         416 :             push_indice( sts[ch]->hBstr, IND_SID_TYPE, 1, 1 );
    3069         416 :             push_indice( sts[ch]->hBstr, IND_BWIDTH, sts[0]->bwidth, 2 );
    3070         416 :             push_indice( sts[ch]->hBstr, IND_ACELP_16KHZ, sts[0]->L_frame == L_FRAME16k ? 1 : 0, 1 );
    3071             :         }
    3072             : 
    3073        4992 :         FOR( Word16 i = 0; i < stages; i++ )
    3074             :         {
    3075        4160 :             push_indice( sts[ch]->hBstr, IND_LSF, indices[ch][i], bits_37bits[i] );
    3076             :         }
    3077         832 :         push_indice( sts[ch]->hBstr, IND_ENERGY, gain_idx[ch], 7 );
    3078             :     }
    3079             : 
    3080             :     /* pad with zeros to reach common SID frame size */
    3081         416 :     push_indice( sts[1]->hBstr, IND_ENERGY, 0, ( IVAS_SID_5k2 - 4400 ) / FRAMES_PER_SEC );
    3082             : 
    3083         416 :     return;
    3084             : }
    3085             : 
    3086             : /*-------------------------------------------------------------------*
    3087             :  * FdCngEncodeDiracMDCTStereoSID()
    3088             :  *
    3089             :  * Encode DTX parameters and noise shapes into SID for MDCT-Stereo DTX
    3090             :  * together with Dirac
    3091             :  *-------------------------------------------------------------------*/
    3092             : 
    3093         123 : void FdCngEncodeDiracMDCTStereoSID_fx(
    3094             :     CPE_ENC_HANDLE hCPE /* i/o: CPE encoder state structure     */
    3095             : )
    3096             : {
    3097             :     ENC_CORE_HANDLE sts[CPE_CHANNELS];
    3098             :     Word32 *lr_in_ptr_fx[CPE_CHANNELS];
    3099             :     Word16 lr_in_ptr_e[CPE_CHANNELS];
    3100             :     Word32 *ms_ptr_fx[CPE_CHANNELS];
    3101             :     Word16 ms_ptr_e;
    3102             :     Word32 *lr_out_ptr_fx[CPE_CHANNELS];
    3103             :     Word16 lr_out_ptr_e[CPE_CHANNELS];
    3104             :     Word32 logNoiseEst_fx[CPE_CHANNELS][NPART];
    3105             :     Word32 E_fx[CPE_CHANNELS];
    3106             :     Word32 gain_fx[CPE_CHANNELS];
    3107             :     Word16 weights_fx[NPART];
    3108             :     Word16 N[CPE_CHANNELS];
    3109             :     Word16 indices[CPE_CHANNELS][FD_CNG_stages_37bits];
    3110             :     Word16 gain_idx[CPE_CHANNELS];
    3111             :     Word16 ch, p;
    3112             :     Word16 tmp, tmp_e, shift;
    3113             :     Word32 *invTrfMatrix_fx;
    3114             :     Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC];
    3115             :     Word32 dct_target_fx[FDCNG_VQ_DCT_MAXTRUNC];
    3116             :     Word32 tot_sig_ext_fx[FDCNG_VQ_MAX_LEN];
    3117         123 :     invTrfMatrix_fx = (Word32 *) tmpRAM_fx; /* dynamically filled  */
    3118             :     Word32 t1, t2, tmp32;
    3119             :     /* set pointers and initialize */
    3120             : 
    3121         369 :     FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
    3122             :     {
    3123         246 :         sts[ch] = hCPE->hCoreCoder[ch];
    3124         246 :         N[ch] = sts[ch]->hFdCngEnc->npartDec;
    3125         246 :         lr_in_ptr_fx[ch] = &sts[ch]->hFdCngEnc->msNoiseEst_fx[0];
    3126         246 :         lr_in_ptr_e[ch] = sts[ch]->hFdCngEnc->msNoiseEst_fx_exp;
    3127         246 :         ms_ptr_fx[ch] = &logNoiseEst_fx[ch][0];
    3128         246 :         lr_out_ptr_fx[ch] = &sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEst[0];
    3129         246 :         lr_out_ptr_e[ch] = sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEstExp;
    3130         246 :         move16();
    3131             :     }
    3132         123 :     set16_fx( weights_fx, ONE_IN_Q8, NPART );
    3133             : 
    3134             :     /* apply log and save energy of original left and right channels */
    3135         369 :     FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
    3136             :     {
    3137             :         // E[ch] = 0.0f;
    3138         246 :         E_fx[ch] = 0;
    3139         246 :         move32();
    3140        6150 :         FOR( p = 0; p < N[ch]; p++ )
    3141             :         {
    3142        5904 :             t1 = BASOP_Util_Log2( lr_in_ptr_fx[ch][p] + EPSILLON_FX );   // Q25
    3143        5904 :             t2 = L_add( t1, L_shl( lr_in_ptr_e[ch], Q25 ) );             // Q25
    3144        5904 :             ms_ptr_fx[ch][p] = Mpy_32_32( t2, TEN_MULT_LOG10_2_IN_Q29 ); // Q23
    3145        5904 :             move32();
    3146        5904 :             E_fx[ch] = L_add( E_fx[ch], L_shr( ms_ptr_fx[ch][p], 5 ) ); // Q18
    3147        5904 :             move32();
    3148             :         }
    3149             :     }
    3150         123 :     ms_ptr_e = Q31 - Q23;
    3151         123 :     move16();
    3152             : 
    3153             :     /* M/S transform on log envelopes */
    3154         123 :     convertToMS_fx( N[0], ms_ptr_fx[0], ms_ptr_fx[1], ONE_IN_Q30 );
    3155         123 :     E_fx[0] = 0;
    3156         123 :     move32();
    3157        3075 :     FOR( p = 0; p < N[0]; p++ )
    3158             :     {
    3159        2952 :         E_fx[0] = L_add( E_fx[0], L_shr( ms_ptr_fx[0][p], 5 ) ); // Q18
    3160        2952 :         move32();
    3161             :     }
    3162             : 
    3163             :     /* Quantize M noise shape */
    3164             :     /* Normalize MSVQ input */
    3165         123 :     gain_fx[0] = 0;
    3166         123 :     move16();
    3167        1722 :     FOR( p = N_GAIN_MIN; p < N_GAIN_MAX; p++ )
    3168             :     {
    3169        1599 :         tmp32 = Mpy_32_32( ms_ptr_fx[0][p], 165191050 /* 0.07 in Q31 */ ); // Q23
    3170        1599 :         gain_fx[0] = L_add( gain_fx[0], tmp32 );                           // Q23
    3171        1599 :         move32();
    3172             :     }
    3173             : 
    3174        3075 :     FOR( p = 0; p < N[0]; p++ )
    3175             :     {
    3176        2952 :         ms_ptr_fx[0][p] = L_sub( ms_ptr_fx[0][p], gain_fx[0] ); // Q23
    3177        2952 :         move32();
    3178             :     }
    3179             : 
    3180             : 
    3181             :     /* MSVQ */
    3182             :     /* DCT domain compressed/truncated indices used for first stage  */
    3183             :     /*  mid quantization using stages #1 through 6 */
    3184         123 :     scale_sig32( ms_ptr_fx[0], N[0], -6 );
    3185         123 :     ms_ptr_e = add( ms_ptr_e, 6 );
    3186         123 :     move16();
    3187         123 :     IF( EQ_16( N[0], FDCNG_VQ_MAX_LEN_WB ) )
    3188             :     {
    3189           0 :         create_IDCT_N_Matrix_fx( invTrfMatrix_fx, N[0], FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM_fx ) / ( sizeof( Word32 ) ) );
    3190             :         /* truncated DCT 21 analysis */
    3191           0 :         dctT2_N_apply_matrix_fx( (const Word32 *) ms_ptr_fx[0], dct_target_fx, FDCNG_VQ_DCT_MAXTRUNC, N[0], invTrfMatrix_fx, FDCNG_VQ_DCT_MAXTRUNC, DCT_T2_21_XX );
    3192             :         /* truncated IDCT21 extension to 24 synthesis  */
    3193             : 
    3194           0 :         extend_dctN_input_fx( ms_ptr_fx[0], dct_target_fx, N[0], tot_sig_ext_fx, FDCNG_VQ_MAX_LEN, invTrfMatrix_fx, FDCNG_VQ_DCT_MAXTRUNC, IDCT_T2_XX_21 ); /* use 18 basis vectors*/
    3195             : 
    3196           0 :         Copy32( tot_sig_ext_fx, ms_ptr_fx[0], FDCNG_VQ_MAX_LEN ); /*  write  extended result as input to  VQ stage #1   Q23*/
    3197             :     }
    3198         123 :     create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM_fx ) / ( sizeof( Word32 ) ) );
    3199             : 
    3200         123 :     msvq_enc_ivas_fx( ivas_cdk_37bits_fx, Q7, NULL, NULL, ms_ptr_fx[0], ms_ptr_e, levels_37bits, FD_CNG_maxC_37bits, FD_CNG_stages_37bits, weights_fx, N[0], FD_CNG_maxN_37bits, 1, invTrfMatrix_fx, indices[0] );
    3201         123 :     msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, FD_CNG_stages_37bits, N[0], FD_CNG_maxN_37bits, indices[0], 1, invTrfMatrix_fx, ms_ptr_fx[0], NULL, 7 );
    3202         123 :     shift = find_guarded_bits_fx( N[0] );
    3203         123 :     ms_ptr_e = sub( 31, sub( 20, shift ) );
    3204         123 :     scale_sig32( ms_ptr_fx[1], N[1], sub( 8, ms_ptr_e ) ); /* Q31 - ms_ptr_e */
    3205             : 
    3206             :     /* set S to zero */
    3207         123 :     set32_fx( ms_ptr_fx[1], 0, NPART );
    3208             : 
    3209             :     /* compute M gain */
    3210         123 :     gain_fx[0] = 0;
    3211         123 :     move32();
    3212         123 :     tmp_e = 15;
    3213         123 :     move16();
    3214         123 :     tmp = Inv16( N[0], &tmp_e );
    3215        3075 :     FOR( p = 0; p < N[0]; p++ )
    3216             :     {
    3217        2952 :         gain_fx[0] = L_add( gain_fx[0], Mpy_32_16_1( ms_ptr_fx[0][p], shl( tmp, tmp_e ) ) ); // Q23
    3218        2952 :         move32();
    3219             :     }
    3220         123 :     gain_fx[0] = L_sub( L_shl( Mpy_32_16_1( E_fx[0], shl( tmp, tmp_e ) ), Q23 - Q18 ), L_shl( gain_fx[0], ms_ptr_e - 8 ) ); // Q23
    3221         123 :     move32();
    3222             : 
    3223         123 :     apply_scale( &gain_fx[0], sts[0]->hFdCngEnc->hFdCngCom->CngBandwidth, sts[0]->hDtxEnc->last_active_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO );
    3224             : 
    3225             :     /* quantize gain */
    3226         123 :     gain_idx[0] = extract_l( Mpy_32_32_r( L_add( gain_fx[0], 251658240 ), 384 ) );
    3227         123 :     move16();
    3228         123 :     gain_idx[0] = s_max( 0, s_min( 127, gain_idx[0] ) );
    3229         123 :     move16();
    3230             : 
    3231         123 :     gain_fx[0] = Mpy_32_16_1( L_shl( sub( gain_idx[0], GAIN_Q_OFFSET_IVAS_FX_Q0 ), 23 ), 21845 /* 0.66 in Q15 */ ); // Q23
    3232         123 :     move32();
    3233         123 :     gain_fx[1] = gain_fx[0]; // Q23
    3234         123 :     move32();
    3235             : 
    3236             :     /* undo M/S */
    3237         123 :     convertToMS_fx( NPART, ms_ptr_fx[0], ms_ptr_fx[1], ONE_IN_Q31 );
    3238             : 
    3239             :     /* restore channel noise envelopes */
    3240         369 :     FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
    3241             :     {
    3242         246 :         HANDLE_FD_CNG_ENC hFdCngEnc = sts[ch]->hFdCngEnc;
    3243         246 :         HANDLE_FD_CNG_COM hFdCngCom = hFdCngEnc->hFdCngCom;
    3244             : 
    3245             :         Word32 pow;
    3246             :         Word16 e_lr_out[NPART];
    3247         246 :         tmp_e = -MAX_16;
    3248        6150 :         FOR( p = 0; p < N[ch]; p++ )
    3249             :         {
    3250        5904 :             pow = L_shl( gain_fx[ch], sub( 8, ms_ptr_e ) );     /* Q31 - ms_ptr_e */
    3251        5904 :             pow = L_add( ms_ptr_fx[ch][p], pow );               /* Q31 - ms_ptr_e */
    3252        5904 :             pow = Mpy_32_32( pow, 214748365 /* 0.1 in Q31 */ ); /*pow = 0.1             Q31 - ms_ptr_e*/
    3253        5904 :             lr_out_ptr_fx[ch][p] = BASOP_Util_fPow( 10, 31, pow, ms_ptr_e, &e_lr_out[p] );
    3254        5904 :             tmp_e = s_max( tmp_e, e_lr_out[p] );
    3255             :         }
    3256             : 
    3257        6150 :         FOR( p = 0; p < N[ch]; p++ )
    3258             :         {
    3259        5904 :             lr_out_ptr_fx[ch][p] = L_shl( lr_out_ptr_fx[ch][p], sub( e_lr_out[p], tmp_e ) ); // Q(31 - tmp_e)
    3260             :         }
    3261             : 
    3262         246 :         sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEstExp = tmp_e;
    3263         246 :         move16();
    3264         246 :         lr_out_ptr_e[ch] = tmp_e;
    3265         246 :         move16();
    3266             : 
    3267             :         /* NB last band energy compensation */
    3268         246 :         IF( hFdCngCom->CngBandwidth == NB )
    3269             :         {
    3270           0 :             lr_out_ptr_fx[ch][N[ch] - 1] = Mpy_32_16_1( lr_out_ptr_fx[ch][N[ch] - 1], NB_LAST_BAND_SCALE ); // Q(31 - tmp_e)
    3271           0 :             move32();
    3272             :         }
    3273         246 :         ELSE IF( hFdCngCom->CngBandwidth == SWB && LE_32( hFdCngCom->CngBitrate, ACELP_13k20 ) )
    3274             :         {
    3275           0 :             lr_out_ptr_fx[ch][N[ch] - 1] = Mpy_32_16_1( lr_out_ptr_fx[ch][N[ch] - 1], SWB_13k2_LAST_BAND_SCALE ); // Q(31 - tmp_e)
    3276           0 :             move32();
    3277             :         }
    3278             :         /* scale bands and get scalefactors */
    3279         246 :         scalebands( lr_out_ptr_fx[ch], hFdCngEnc->partDec, N[ch], hFdCngEnc->midbandDec, hFdCngEnc->nFFTpartDec, sub( hFdCngEnc->stopBandDec, hFdCngEnc->startBandDec ), hFdCngCom->cngNoiseLevel, 1 );
    3280         246 :         hFdCngCom->cngNoiseLevelExp = lr_out_ptr_e[ch];
    3281         246 :         move16();
    3282         246 :         lpc_from_spectrum( hFdCngCom, hFdCngEnc->startBandDec, hFdCngEnc->stopFFTbinDec, sts[ch]->preemph_fac );
    3283         246 :         sts[ch]->hDtxEnc->last_CNG_L_frame = sts[ch]->L_frame;
    3284             :     }
    3285         123 :     sts[0]->hFdCngEnc->hFdCngCom->coherence_fx = 0;
    3286         123 :     move16();
    3287         123 :     sts[1]->hFdCngEnc->hFdCngCom->coherence_fx = 0;
    3288         123 :     move16();
    3289             : 
    3290             :     /* ---- Write SID bitstream ---- */
    3291             : 
    3292             :     /* side info */
    3293         123 :     push_indice( sts[0]->hBstr, IND_SID_TYPE, 1, 1 );
    3294         123 :     push_indice( sts[0]->hBstr, IND_BWIDTH, sts[0]->bwidth, 2 );
    3295         123 :     IF( EQ_16( sts[0]->L_frame, L_FRAME16k ) )
    3296             :     {
    3297         123 :         push_indice( sts[0]->hBstr, IND_ACELP_16KHZ, 1, 1 );
    3298             :     }
    3299             :     ELSE
    3300             :     {
    3301           0 :         push_indice( sts[0]->hBstr, IND_ACELP_16KHZ, 0, 1 );
    3302             :     }
    3303             : 
    3304             :     /* noise shapes and channel gains */
    3305         861 :     FOR( Word16 i = 0; i < FD_CNG_stages_37bits; i++ )
    3306             :     {
    3307         738 :         push_indice( sts[0]->hBstr, IND_LSF, indices[0][i], bits_37bits[i] );
    3308             :     }
    3309         123 :     push_indice( sts[0]->hBstr, IND_ENERGY, gain_idx[0], 7 );
    3310             : 
    3311         123 :     return;
    3312             : }

Generated by: LCOV version 1.14