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

Generated by: LCOV version 1.14