LCOV - code coverage report
Current view: top level - lib_enc - analy_sp_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main enc/dec/rend @ 574a190e3c6896c6c4ed10d7f23649709a0c4347 Lines: 463 476 97.3 %
Date: 2025-06-27 02:59:36 Functions: 5 5 100.0 %

          Line data    Source code
       1             : /*====================================================================================
       2             :     EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
       3             :   ====================================================================================*/
       4             : 
       5             : #include <stdint.h>
       6             : #include "options.h"
       7             : #include "cnst.h"
       8             : #include "basop_util.h"
       9             : // #include "prot_fx.h"
      10             : #include "prot_fx.h"     /* Function prototypes                    */
      11             : #include "prot_fx_enc.h" /* Function prototypes                    */
      12             : #include "rom_enc.h"
      13             : #include "rom_com.h"
      14             : #include <assert.h>
      15             : #include <math.h>
      16             : /*-------------------------------------------------------------------*
      17             :  * Local prototypes
      18             :  *-------------------------------------------------------------------*/
      19             : 
      20             : static void find_enr( Word16 data[], Word32 band[], Word32 *ptE, Word32 *LEtot, const Word16 min_band, const Word16 max_band, const Word16 Q_new2, const Word32 e_min, Word32 *Bin_E, Word16 BIN_FREQ_FX, Word32 *band_energies );
      21             : static void ivas_find_enr( Word16 *data, Word16 q_data, Word32 *band, Word16 *q_band, Word32 *ptE, Word16 *q_ptE, Word64 *LEtot, const Word16 min_band, const Word16 max_band, Word32 *Bin_E, Word16 BIN_FREQ_FX, Word32 *band_energies );
      22             : 
      23             : 
      24             : /*-------------------------------------------------------------------*
      25             :  * analy_sp_fx()
      26             :  *
      27             :  * Spectral analysis of 12.8kHz input
      28             :  *-------------------------------------------------------------------*/
      29             : 
      30        3100 : void analy_sp_fx(
      31             :     const Word16 element_mode, /* i  : element mode                                    */
      32             :     Word16 *speech,            /* i  : speech buffer                          Q_new - preemph_bits */
      33             :     const Word16 Q_new,        /* i  : current scaling exp                    Q0                 */
      34             :     Word32 *fr_bands,          /* o  : energy in critical frequency bands     Q_new + QSCALE    */
      35             :     Word32 *lf_E,              /* o  : per bin E for first...                 Q_new + QSCALE - 2*/
      36             :     Word16 *Etot,              /* o  : total input energy                     Q8                 */
      37             :     const Word16 min_band,     /* i  : minimum critical band                  Q0                 */
      38             :     const Word16 max_band,     /* i  : maximum critical band                  Q0                 */
      39             :     const Word32 e_min_scaled, /* i  : minimum energy scaled                  Q_new + QSCALE    */
      40             :     Word16 Scale_fac[2],       /* o  : FFT scales factors (2 values by frame) Q0                 */
      41             :     Word32 *Bin_E,             /* o  : per-bin energy spectrum                                  */
      42             :     Word32 *Bin_E_old,         /* o  : per-bin energy spectrum of the previous frame            */
      43             :     Word32 *PS,                /* o  : per-bin energy spectrum                                  */
      44             :     Word16 *EspecdB,           /* o  : per-bin log energy spectrum (with f=0) Q7                */
      45             :     Word32 *band_energies,     /* o  : energy in critical frequency bands without minimum noise floor MODE2_E_MIN */
      46             :     Word16 *fft_buff           /* o  : FFT coefficients                                         */
      47             : )
      48             : {
      49             :     Word16 *pt;
      50             :     Word16 i_subfr, i, exp_etot, frac_etot, exp, exp_frac, exp2;
      51             :     Word32 *pt_bands;
      52             :     Word32 Ltmp, LEtot, L_tmp2;
      53             :     Word16 *pt_fft;
      54             :     Word16 Min_val, Max_val;
      55             :     Word16 Scale_fac2;
      56             :     Word16 fft_temp[L_FFT];
      57             : 
      58             :     /*-----------------------------------------------------------------*
      59             :      * Compute spectrum
      60             :      * find energy per critical frequency band and total energy in dB
      61             :      *-----------------------------------------------------------------*/
      62             : 
      63        3100 :     pt_bands = fr_bands; /* Q_new + QSCALE */
      64        3100 :     pt_fft = fft_buff;
      65        3100 :     LEtot = L_deposit_l( 0 );
      66        3100 :     IF( NE_16( element_mode, IVAS_CPE_DFT ) )
      67             :     {
      68        9300 :         FOR( i_subfr = 0; i_subfr <= 1; i_subfr++ )
      69             :         {
      70        6200 :             pt = speech + 3 * ( L_SUBFR / 2 ) - L_FFT / 2; /* Q_new - preemph_bits */
      71        6200 :             if ( i_subfr != 0 )
      72             :             {
      73        3100 :                 pt = speech + 7 * ( L_SUBFR / 2 ) - L_FFT / 2; /* Q_new - preemph_bits */
      74             :             }
      75             : 
      76             :             /* Clear 1st value of 1st part, copy 1st value of 2nd part */
      77        6200 :             fft_temp[0] = 0;
      78        6200 :             move16();
      79        6200 :             fft_temp[L_FFT / 2] = pt[L_FFT / 2]; /* Q_new - preemph_bits */
      80        6200 :             move16();
      81        6200 :             Max_val = s_max( fft_temp[0], fft_temp[L_FFT / 2] ); /* Q_new - preemph_bits */
      82        6200 :             Min_val = s_min( fft_temp[0], fft_temp[L_FFT / 2] ); /* Q_new - preemph_bits */
      83             : 
      84      793600 :             FOR( i = 1; i < L_FFT / 2; i++ )
      85             :             {
      86             :                 /* 1st windowed part */
      87      787400 :                 fft_temp[i] = mult_r( pt[i], sqrt_han_window_fx[i] ); /* Q_new - preemph_bits */
      88      787400 :                 move16();
      89      787400 :                 IF( fft_temp[i] > 0 )
      90             :                 {
      91      396122 :                     Max_val = s_max( Max_val, fft_temp[i] ); /* Q_new - preemph_bits */
      92             :                 }
      93      787400 :                 IF( fft_temp[i] < 0 )
      94             :                 {
      95      387710 :                     Min_val = s_min( Min_val, fft_temp[i] ); /* Q_new - preemph_bits */
      96             :                 }
      97             : 
      98             :                 /* 2nd windowed part  */
      99      787400 :                 fft_temp[L_FFT - i] = mult_r( pt[L_FFT - i], sqrt_han_window_fx[i] ); /* Q_new - preemph_bits */
     100      787400 :                 move16();
     101      787400 :                 IF( fft_temp[L_FFT - i] > 0 )
     102             :                 {
     103      396130 :                     Max_val = s_max( Max_val, fft_temp[L_FFT - i] ); /* Q_new - preemph_bits */
     104             :                 }
     105      787400 :                 IF( fft_temp[L_FFT - i] < 0 )
     106             :                 {
     107      387633 :                     Min_val = s_min( Min_val, fft_temp[L_FFT - i] ); /* Q_new - preemph_bits */
     108             :                 }
     109             :             }
     110             : 
     111             :             /* Combine -Min_val and Max_val into one */
     112        6200 :             Max_val = s_max( negate( Min_val ), Max_val );
     113             : 
     114        6200 :             Scale_fac[i_subfr] = s_min( sub( norm_s( Max_val ), 1 ), 6 );
     115        6200 :             move16();
     116        6200 :             Scale_fac2 = shl( Scale_fac[i_subfr], 1 );
     117        6200 :             Scale_sig( fft_temp, L_FRAME_12k8, Scale_fac[i_subfr] ); /* Q_new - preemph_bits + Scale_fac */
     118             : 
     119        6200 :             r_fft_fx_lc( FFT_W128, SIZE_256, SIZE2_256, NUM_STAGE_256, fft_temp, pt_fft, 1 );
     120             : 
     121             :             /* find energy per critical band */
     122        6200 :             find_enr( pt_fft, pt_bands, lf_E + i_subfr * VOIC_BINS, &LEtot, min_band, max_band,
     123        6200 :                       add( Q_new, Scale_fac2 ), e_min_scaled, &Bin_E[i_subfr * L_FFT / 2], BIN, band_energies + i_subfr * NB_BANDS );
     124             : 
     125        6200 :             pt_bands += NB_BANDS;
     126        6200 :             pt_fft += L_FFT;
     127             :         }
     128             :     }
     129             : 
     130             :     /* Average total log energy over both half-frames */
     131        3100 :     frac_etot = 0;
     132        3100 :     move16();
     133        3100 :     exp_etot = norm_l( LEtot );
     134        3100 :     IF( LEtot != 0 ) /* Log2_norm_lc doesn't Support Input <= 0; deal with it here */
     135             :     {
     136        3100 :         frac_etot = Log2_norm_lc( L_shl( LEtot, exp_etot ) );
     137        3100 :         exp_etot = sub( 30, exp_etot );
     138             :     }
     139        3100 :     exp_etot = sub( exp_etot, add( Q_new, 1 + 3 ) ); /* remove scaling effect, 4 already removed */
     140        3100 :     Ltmp = Mpy_32( exp_etot, frac_etot, LG10, 0 );
     141             : 
     142             :     /*Q8 Averaged the total energy over both half-frames in log10  */
     143        3100 :     *Etot = extract_l( L_shr( Ltmp, 14 - 8 ) ); /* Q8 */
     144             : 
     145        3100 :     Bin_E[L_FFT / 2 - 1] = Bin_E[L_FFT / 2 - 2];
     146        3100 :     move32();
     147        3100 :     Bin_E[L_FFT - 1] = Bin_E[L_FFT - 2];
     148        3100 :     move32();
     149             : 
     150             :     /* Per-bin log-energy spectrum */
     151        3100 :     exp2 = sub( 31, add( Q_new, QSCALE - 2 ) );
     152        3100 :     L_tmp2 = L_mac( -56783L, exp2, 28391 );
     153      399900 :     FOR( i = 0; i < L_FFT / 2; i++ )
     154             :     {
     155      396800 :         Bin_E_old[i] = Bin_E[i];
     156      396800 :         move32();
     157             : 
     158             :         /* tmp = (input[i] + input[i+Len]+0.001f)/2.0f */
     159      396800 :         Ltmp = L_max( 1, L_add( L_shr( Bin_E[i], 1 ), L_shr( Bin_E[i + L_FFT / 2], 1 ) ) );
     160      396800 :         if ( PS != NULL )
     161             :         {
     162      396800 :             PS[i] = Ltmp;
     163      396800 :             move32();
     164             :         }
     165             : 
     166             :         /* 10.0*log((float)tmp)                                  */
     167             :         /* 10.0*Log(2)*Log2(L_tmp/2)                             */
     168             :         /* 6.93147*Log2(L_tmp/2)                                 */
     169             :         /* 0.86643*(Log2(L_tmp)-1)*8                             */
     170             :         /* 0.86643*Log2(L_tmp)*8 - 6.93147                       */
     171             :         /* We'll put it in Q8                                    */
     172      396800 :         exp = norm_l( Ltmp );
     173      396800 :         exp_frac = Log2_norm_lc( L_shl( Ltmp, exp ) );
     174             :         /* -56783L is to substract 0.86643 in Q16                */
     175             :         /* 28391 is 0.86643 in Q15                               */
     176             :         /* 1774 is (0.86643 in Q15) * 8 / 128 (/128 to go in Q7) */
     177      396800 :         EspecdB[i] = mac_r( L_shl( L_msu( L_tmp2, exp, 28391 ), 3 + 7 ), exp_frac, 887 ); /* Q7 */
     178      396800 :         move16();
     179             :     }
     180             : 
     181             : 
     182        3100 :     return;
     183             : }
     184             : 
     185             : /*------------------------------------------------------------------------*
     186             :  * find_enr_dft_fx()
     187             :  *
     188             :  * find input signal energy for each critical band using the DFT buffers
     189             :  *------------------------------------------------------------------------*/
     190             : 
     191             : 
     192       59659 : static void find_enr_dft_ivas_fx(
     193             :     CPE_ENC_HANDLE hCPE,      /* i/o: CPE encoder structure                            */
     194             :     const Word32 input_Fs,    /* i  : input sampling rate                              Q0*/
     195             :     Word32 DFT_past_DMX_fx[], /* i  :input DFT_Dmx      (Q_inp_dmx )                   */
     196             :     Word32 band_fx[],         /* o  : per band energy   (*q_band)                      */
     197             :     Word16 *q_band,           /* o  : Q of per band energy                             */
     198             :     Word32 *ptE_fx,           /* o  : per bin energy  for low frequencies  (*q_ptE)    */
     199             :     Word16 *q_ptE,            /* o  : Q of per bin energy  for low frequencies         */
     200             :     Word64 *Etot_fx,          /* i/o: total energy      (Q8)                           */
     201             :     const Word16 min_band,    /* i  : minimum critical band                            Q0*/
     202             :     const Word16 max_band,    /* i  : maximum critical band                            Q0*/
     203             :     Word32 *Bin_E_fx,         /* o  : Per bin energy      (Q7)                         */
     204             :     Word16 *q_Bin_E,          /* o  : Q of Per bin energy           (*q_band)          */
     205             :     Word32 *band_ener_fx,     /* o  : per band energy without E_MIN                    */
     206             :     Word16 Q_inp_dmx )
     207             : {
     208             :     Word16 i;
     209             :     Word64 tot_ener;
     210             :     Word32 freq;
     211             :     const Word32 *ptR_fx, *ptI_fx;
     212             :     Word16 norm_val_fx;
     213             :     Word16 bin_cnt;
     214             :     Word32 c_fx, s_fx;
     215             :     Word32 g_fx;
     216             :     Word32 scaleWin_fx;
     217             :     Word16 bin_freq;
     218             :     Word16 temp1, temp2, exp, exp1;
     219             :     Word16 q_norm_val;
     220             :     Word32 BinE_fx[STEREO_DFT_N_12k8_ENC / 2]; /* NB_BANDS = 20 (=  6350Hz) = highest band available for SR 12.8  -> bin_cnt = 158 */
     221             :     Word32 c_1_fx, s_1_fx, g_1_fx, g_2_fx;
     222             :     Word64 band_ener;
     223             :     Word32 BinE, tmp_fx;
     224             :     Word32 start_freq;
     225             :     Word32 min_ener;
     226       59659 :     Word16 shift = 0;
     227       59659 :     move16();
     228             : 
     229             :     /* One window - 40ms*12.8kHz = 512 samples */
     230       59659 :     c_1_fx = 1073660991; // 0.999924719 in Q30, cosf( PI2 / STEREO_DFT_N_12k8_ENC )
     231       59659 :     s_1_fx = 13176464;   // 0.0122715384 in Q30, sinf( PI2 / STEREO_DFT_N_12k8_ENC )
     232       59659 :     g_1_fx = 1570240043; // 1.4624 in Q30, ( 1.f + 0.68f * 0.68f )
     233       59659 :     g_2_fx = 1460288880; // 1.36 in Q30, 2 * 0.68f
     234       59659 :     move32();
     235       59659 :     move32();
     236       59659 :     move32();
     237       59659 :     move32();
     238             : 
     239       59659 :     bin_cnt = 0;
     240       59659 :     move16();
     241             : 
     242             :     /* input_Fs / (float) hCPE->hStereoDft->NFFT;*/ /* adaptive frequency bin width */
     243       59659 :     bin_freq = BASOP_Util_Divide3216_Scale( input_Fs, hCPE->hStereoDft->NFFT, &exp );
     244       59659 :     bin_freq = shl( bin_freq, add( 1, exp ) ); // Q0
     245             : 
     246             :     /* scaleWin = 1 / ( 2 * hCPE->hStereoDft->win_ana_energy );
     247             :        scaleWin *= (float) BIN / bin_freq; */
     248             : 
     249       59659 :     temp2 = BASOP_Util_Divide3216_Scale( BIN, bin_freq, &exp );
     250       59659 :     temp2 = shl( temp2, add( 1, exp ) ); // Q0
     251       59659 :     exp = norm_s( hCPE->hStereoDft->win_ana_energy_fx );
     252       59659 :     temp1 = div_s( ONE_IN_Q14, shl( hCPE->hStereoDft->win_ana_energy_fx, exp ) ); // 14-(15+exp-1)+15 = 15+exp
     253       59659 :     scaleWin_fx = L_mult0( temp1, temp2 );                                        // 15+exp
     254             : 
     255             :     /* scaleWin * 4.0f makes Q of scaleWin_fx from 15+exp to 13+exp
     256             :        norm_val = scaleWin * 4.0f / ( hCPE->hStereoDft->NFFT * hCPE->hStereoDft->NFFT ); */
     257             : 
     258       59659 :     norm_val_fx = BASOP_Util_Divide3232_Scale( scaleWin_fx, L_mult0( hCPE->hStereoDft->NFFT, hCPE->hStereoDft->NFFT ), &exp1 ); // 13+exp+15-exp1 = 28+exp-exp1
     259       59659 :     q_norm_val = add( 28, sub( exp, exp1 ) );
     260             : 
     261       59659 :     ptR_fx = &DFT_past_DMX_fx[2]; /* first real  */
     262       59659 :     ptI_fx = &DFT_past_DMX_fx[3]; /* first imaginary */
     263             : 
     264       59659 :     c_fx = c_1_fx; // Q30
     265       59659 :     s_fx = s_1_fx; // Q30
     266       59659 :     move32();
     267       59659 :     move32();
     268             : 
     269             :     /* for low frequency bins, save per bin energy for the use in find_tilt() */
     270       59659 :     freq = bin_freq;
     271       59659 :     move32();
     272             : 
     273       59659 :     *q_band = add( shl( Q_inp_dmx, 1 ), sub( q_norm_val, 48 ) );
     274       59659 :     move16();
     275       59659 :     *q_Bin_E = *q_band;
     276       59659 :     move16();
     277             : 
     278       59659 :     IF( GT_16( *q_band, 39 ) )
     279             :     {
     280           0 :         shift = sub( *q_band, 39 );
     281           0 :         *q_band = 39;
     282           0 :         move16();
     283             :     }
     284             : 
     285       59659 :     min_ener = L_shl( E_MIN_FXQ31 /* 0.0035 in Q31 */, sub( *q_band, 31 ) );
     286     1193180 :     FOR( i = 0; i < NB_BANDS - 1; i++ ) /* up to maximum allowed voiced critical band */
     287             :     {
     288     1133521 :         band_ener = 0;
     289     1133521 :         move64();
     290     1133521 :         start_freq = freq;
     291     1133521 :         move32();
     292             : 
     293             :         /* bins up to crit_band 17 (<= 3700 Hz):
     294             :          * bin_cnt old (bin_width 50 Hz): 74 (74 * FRAMES_PER_SEC = 3700)
     295             :          * bin_cnt new (bin_width 40 Hz): 92 (92 * 40 = 3680)
     296             :          */
     297             : 
     298    13781229 :         WHILE( LE_32( freq, crit_bands_fx[i] ) )
     299             :         {
     300             :             // g_fx = L_sub( g_1_fx, L_shl( Mpy_32_32( g_2_fx, c_fx ), 1 ) );            // 30
     301    12647708 :             g_fx = L_sub( L_shr( g_1_fx, 1 ), Mpy_32_32( g_2_fx, c_fx ) );            // 29
     302    12647708 :             tmp_fx = Msub_32_32( Mpy_32_32( c_fx, c_1_fx ), s_fx, s_1_fx );           // 29
     303    12647708 :             s_fx = L_shl( Madd_32_32( Mpy_32_32( s_fx, c_1_fx ), c_fx, s_1_fx ), 1 ); // 30
     304    12647708 :             c_fx = L_shl( tmp_fx, 1 );                                                // 30
     305             : 
     306    12647708 :             BinE = Madd_32_32( Mpy_32_32( *ptR_fx, *ptR_fx ), *ptI_fx, *ptI_fx );   // 2*Q_inp_dmx-31
     307    12647708 :             BinE_fx[bin_cnt] = Mpy_32_32( BinE, Mpy_32_16_1( g_fx, norm_val_fx ) ); // (2*Q_inp_dmx-31)+(q_norm_val+29-15)-31 = 2*Q_inp_dmx+q_norm_val-48 = *q_Bin_E
     308    12647708 :             move32();
     309             : 
     310             :             /*
     311             :                 BIN_FREQ_FX = BIN, cnt = ( ( crit_bands_fx[i] - start_freq ) / bin_freq ) + 1
     312             :                 band[i] = BinE[bin_cnt];
     313             :                 band[i] *= inv_tbl[cnt]; // normalization per frequency bin
     314             :             */
     315    12647708 :             band_ener = W_mac_32_16( band_ener, BinE_fx[bin_cnt], inv_tbl_fx[( ( crit_bands_fx[i] - start_freq ) / bin_freq ) + 1] ); // *q_band+shift+16
     316             : 
     317    12647708 :             ptR_fx += 2;
     318    12647708 :             ptI_fx += 2;
     319    12647708 :             freq = L_mac0( freq, bin_freq, 1 );
     320    12647708 :             bin_cnt = add( bin_cnt, 1 );
     321             :         }
     322             : 
     323             :         /* normalization per frequency bin */
     324     1133521 :         band_fx[i] = W_extract_h( W_shl( band_ener, sub( Q16, shift ) ) ); // *q_band
     325     1133521 :         move32();
     326             : 
     327             :         /* per band energy without E_MIN   */
     328     1133521 :         band_ener_fx[i] = band_fx[i]; // *q_band
     329     1133521 :         move32();
     330             : 
     331     1133521 :         if ( LT_32( band_fx[i], min_ener ) )
     332             :         {
     333       67804 :             band_fx[i] = min_ener; // *q_band
     334       67804 :             move32();
     335             :         }
     336             :     }
     337             : 
     338             :     /* continue computing the energy per critical band for higher frequencies */
     339             : 
     340             :     /* old version, FFT 256 @ SR12.8 (-> bin_width = 50 Hz):
     341             :        NB_BANDS = 20 (=  6350Hz) = highest band available for SR 12.8 -> bin_cnt = 127 = L_FFT/2-1*/
     342             : 
     343             :     /* new version: DFT (1200/800/400) @ input SR (48/32/16) (-> bin_width = 40 Hz):
     344             :      *
     345             :      */
     346             :     /* NB_BANDS = 20 (=  6350Hz) = highest band available for SR 12.8  -> bin_cnt = 158 */
     347             :     /* NB_BANDS = 21 (=  7700Hz) = highest band available for SR 16    -> bin_cnt = 192 */
     348             :     /* NB_BANDS = 24 (= 15500Hz) = highest band available for SR 32    -> bin_cnt = 387 */
     349             :     /* NB_BANDS = 24 (= 15500Hz) = highest band available for SR 48    -> bin_cnt = 387 */
     350             : 
     351      119318 :     FOR( ; i < NB_BANDS; i++ )
     352             :     {
     353       59659 :         band_ener = 0;
     354       59659 :         move64();
     355       59659 :         start_freq = freq;
     356       59659 :         move32();
     357             : 
     358     2624996 :         WHILE( LT_32( freq, 6399 ) )
     359             :         {
     360             : 
     361             :             // g_fx = L_sub( g_1_fx, L_shl( Mpy_32_32( g_2_fx, c_fx ), 1 ) ); // 30
     362     2565337 :             g_fx = L_sub( L_shr( g_1_fx, 1 ), Mpy_32_32( g_2_fx, c_fx ) ); // 29
     363             : 
     364     2565337 :             BinE = Madd_32_32( Mpy_32_32( *ptR_fx, *ptR_fx ), *ptI_fx, *ptI_fx );   // 2*Q_inp_dmx-31
     365     2565337 :             BinE_fx[bin_cnt] = Mpy_32_32( BinE, Mpy_32_16_1( g_fx, norm_val_fx ) ); // (2*Q_inp_dmx-31)+(q_norm_val+29-15)-31 = 2*Q_inp_dmx+q_norm_val-48 = *q_Bin_E
     366     2565337 :             move32();
     367             : 
     368             :             /*
     369             :                 BIN_FREQ_FX = BIN, cnt = ( ( 6399 - start_freq ) / bin_freq ) + 1
     370             :                 band[i] = BinE[bin_cnt];
     371             :                 band[i] *= inv_tbl[cnt]; // normalization per frequency bin
     372             :             */
     373     2565337 :             band_ener = W_mac_32_16( band_ener, BinE_fx[bin_cnt], inv_tbl_fx[( ( 6399 - start_freq ) / bin_freq ) + 1] ); // *q_band+shift
     374             : 
     375     2565337 :             ptR_fx += 2;
     376     2565337 :             ptI_fx += 2;
     377     2565337 :             freq = L_mac0( freq, bin_freq, 1 );
     378     2565337 :             bin_cnt = add( bin_cnt, 1 );
     379             :         }
     380             : 
     381             :         /* normalization per frequency bin */
     382       59659 :         band_fx[i] = W_extract_h( W_shl( band_ener, sub( Q16, shift ) ) ); // *q_band
     383       59659 :         move32();
     384             : 
     385             :         /* per band energy without E_MIN   */
     386       59659 :         band_ener_fx[i] = band_fx[i]; // *q_band
     387       59659 :         move32();
     388             : 
     389       59659 :         if ( LT_32( band_fx[i], min_ener ) )
     390             :         {
     391        3057 :             band_fx[i] = min_ener; // *q_band
     392        3057 :             move32();
     393             :         }
     394             :     }
     395             : 
     396             :     /* put bin energies from BinE into Bin_E[L_FFT/2-1] (interpolate 40 Hz bin values to fit into 50 Hz bins) */
     397             :     /* Last value of Bin_E is handled outside this function*/
     398       59659 :     assert( bin_cnt == ( STEREO_DFT_N_12k8_ENC / 2 - 1 ) );
     399       59659 :     BinE_fx[STEREO_DFT_N_12k8_ENC / 2 - 1] = BinE_fx[STEREO_DFT_N_12k8_ENC / 2 - 2]; // // *q_Bin_E
     400       59659 :     move32();
     401             : 
     402       59659 :     Word16 norm = getScaleFactor32( BinE_fx, L_FFT );
     403       59659 :     scale_sig32( BinE_fx, L_FFT, norm );
     404       59659 :     *q_Bin_E = add( *q_Bin_E, norm );
     405       59659 :     move16();
     406       59659 :     L_lerp_fx( BinE_fx, Bin_E_fx, L_FFT / 2, STEREO_DFT_N_12k8_ENC / 2, q_Bin_E );
     407             : 
     408       59659 :     MVR2R_WORD32( Bin_E_fx, ptE_fx, VOIC_BINS ); // *q_Bin_E
     409       59659 :     *q_ptE = *q_Bin_E;
     410       59659 :     move16();
     411             : 
     412             :     /* find the total log energy */
     413       59659 :     tot_ener = *Etot_fx;
     414       59659 :     move64();
     415             : 
     416     1252839 :     FOR( i = min_band; i <= max_band; i++ )
     417             :     {
     418     1193180 :         tot_ener = W_mac_32_32( tot_ener, band_fx[i], 1 ); // *q_band+1
     419             :     }
     420             : 
     421       59659 :     *Etot_fx = tot_ener;
     422       59659 :     move64();
     423             : 
     424       59659 :     return;
     425             : }
     426             : /*-------------------------------------------------------------------*
     427             :  * ivas_analy_sp_fx()
     428             :  *
     429             :  * Spectral analysis of 12.8kHz input
     430             :  *-------------------------------------------------------------------*/
     431     1192920 : void ivas_analy_sp_fx(
     432             :     const Word16 element_mode, /* i  : element mode                                    Q0                 */
     433             :     CPE_ENC_HANDLE hCPE,       /* i/o: CPE encoder structure                                              */
     434             :     const Word32 input_Fs,     /* i  : input sampling rate                             Q0                 */
     435             :     Word16 *speech,            /* i  : speech buffer                                   Q_new              */
     436             :     const Word16 Q_new,        /* i  : current scaling exp                             Q0                 */
     437             :     Word32 *fr_bands,          /* o  : energy in critical frequency bands              q_fr_bands         */
     438             :     Word16 *q_fr_bands,        /* o  : energy in critical frequency bands              Q0                 */
     439             :     Word32 *lf_E,              /* o  : per bin E for first...                          q_lf_E             */
     440             :     Word16 *q_lf_E,            /* o  : per bin E for first...                          Q0                 */
     441             :     Word32 *Etot,              /* o  : total input energy                              Q24                 */
     442             :     const Word16 min_band,     /* i  : minimum critical band                           Q0                 */
     443             :     const Word16 max_band,     /* i  : maximum critical band                           Q0                 */
     444             :     Word32 *Bin_E,             /* o  : per-bin energy spectrum                         q_Bin_E            */
     445             :     Word16 *q_Bin_E,           /* o  : per-bin energy spectrum                         Q0                 */
     446             :     Word32 *Bin_E_old,         /* o  : per-bin energy spectrum of the previous frame   q_Bin_E_old        */
     447             :     Word16 *q_Bin_E_old,       /* o  : per-bin energy spectrum of the previous frame   Q0                 */
     448             :     Word32 *PS,                /* o  : per-bin energy spectrum                         q_PS               */
     449             :     Word16 *q_PS,              /* o  : per-bin energy spectrum                         Q0                 */
     450             :     Word16 *EspecdB,           /* o  : per-bin log energy spectrum (with f=0)          Q7                 */
     451             :     Word32 *band_energies,     /* o  : energy in critical frequency bands without minimum noise floor MODE2_E_MIN (q_band_energies) */
     452             :     Word16 *q_band_energies,   /* o  : Q of energy in critical frequency bands without minimum noise floor MODE2_E_MIN              */
     453             :     Word16 *fft_buff,          /* o  : FFT coefficients                                (q_fft_buff)       */
     454             :     Word16 *q_fft_buff         /* o  : Q of FFT coefficients                           Q0                 */
     455             : )
     456             : {
     457             :     Word16 *pt;
     458             :     Word16 i_subfr, i;
     459             :     Word32 *pt_bands;
     460             :     Word32 Ltmp;
     461             :     Word16 *pt_fft;
     462             :     Word16 exp, tmp;
     463             :     Word16 resultant_q;
     464             :     Word16 exp2;
     465             :     Word64 LEtot;
     466     1192920 :     LEtot = 0;
     467     1192920 :     move64();
     468             :     /*-----------------------------------------------------------------*
     469             :      * Compute spectrum
     470             :      * find energy per critical frequency band and total energy in dB
     471             :      *-----------------------------------------------------------------*/
     472             : 
     473     1192920 :     pt_bands = fr_bands;
     474     1192920 :     pt_fft = fft_buff;
     475             : 
     476     1192920 :     IF( NE_16( element_mode, IVAS_CPE_DFT ) )
     477             :     {
     478     1133261 :         IF( is_zero_arr16( speech + 3 * ( L_SUBFR / 2 ) - L_FFT / 2, L_FFT + 4 * ( L_SUBFR / 2 ) ) )
     479             :         {
     480       73950 :             set16_fx( pt_fft, 0, 2 * L_FFT );
     481       73950 :             *q_fft_buff = Q15;
     482       73950 :             move16();
     483             : 
     484       73950 :             set32_fx( Bin_E, 0, L_FFT );
     485       73950 :             set32_fx( lf_E, 0, 2 * VOIC_BINS );
     486       73950 :             set32_fx( band_energies, 0, 2 * NB_BANDS );
     487       73950 :             set32_fx( fr_bands, E_MIN_FXQ31, 2 * NB_BANDS ); // Q31 (*q_fr_bands)
     488             : 
     489       73950 :             LEtot = W_shl( W_mult_32_16( E_MIN_FXQ31, add( sub( max_band, min_band ), 1 ) ), 1 ); // Q32 (*q_fr_bands+1)
     490       73950 :             *q_fr_bands = Q31;
     491       73950 :             *q_lf_E = *q_fr_bands;
     492       73950 :             move16();
     493       73950 :             move16();
     494             :         }
     495             :         ELSE
     496             :         {
     497     1059311 :             Word16 scale = 0, shift;
     498     1059311 :             move16();
     499     1059311 :             shift = s_min( norm_arr( speech + 3 * ( L_SUBFR / 2 ) - L_FFT / 2, L_FFT ), norm_arr( speech + 7 * ( L_SUBFR / 2 ) - L_FFT / 2, L_FFT ) );
     500     3177933 :             FOR( i_subfr = 0; i_subfr <= 1; i_subfr++ )
     501             :             {
     502             :                 /* set pointer to the beginning of the signal for spectral analysis */
     503             :                 /* set the pointer for first analysis window */
     504     2118622 :                 pt = speech + 3 * ( L_SUBFR / 2 ) - L_FFT / 2;
     505     2118622 :                 if ( i_subfr != 0 )
     506             :                 {
     507             :                     /* set the pointer for second analysis window */
     508     1059311 :                     pt = speech + 7 * ( L_SUBFR / 2 ) - L_FFT / 2;
     509             :                 }
     510             :                 /* Clear 1st value of 1st part, copy 1st value of 2nd part */
     511     2118622 :                 pt_fft[0] = 0;
     512     2118622 :                 move16();
     513     2118622 :                 pt_fft[L_FFT / 2] = shl( pt[L_FFT / 2], shift ); // (Q_new + shift) - preemph_bits
     514     2118622 :                 move16();
     515             : 
     516   271183616 :                 FOR( i = 1; i < L_FFT / 2; i++ )
     517             :                 {
     518             :                     /* 1st windowed part */
     519   269064994 :                     pt_fft[i] = mult_r( shl( pt[i], shift ), sqrt_han_window_fx[i] ); // (Q_new + shift) - preemph_bits
     520   269064994 :                     move16();
     521             : 
     522             :                     /* 2nd windowed part  */
     523   269064994 :                     pt_fft[L_FFT - i] = mult_r( shl( pt[L_FFT - i], shift ), sqrt_han_window_fx[i] ); // (Q_new + shift) - preemph_bits
     524   269064994 :                     move16();
     525             :                 }
     526             : 
     527             :                 /* compute the spectrum */
     528     2118622 :                 fft_rel_16_32fx( pt_fft, &scale, i_subfr, L_FFT, LOG2_L_FFT );
     529     2118622 :                 *q_fft_buff = add( add( Q_new, shift ), scale ); // resultant q for fft_buff
     530     2118622 :                 move16();
     531     2118622 :                 IF( EQ_16( i_subfr, 1 ) )
     532             :                 {
     533     1059311 :                     Word16 new_q_lf_E = add( shl( *q_fft_buff, 1 ), 14 );
     534     1059311 :                     Word16 new_q_bands = new_q_lf_E;
     535     1059311 :                     IF( GT_16( new_q_bands, 39 ) )
     536             :                     {
     537         645 :                         new_q_bands = 39;
     538         645 :                         move16();
     539             :                     }
     540     1059311 :                     scale_sig32( fr_bands, NB_BANDS, sub( new_q_bands, *q_fr_bands ) );
     541     1059311 :                     scale_sig32( lf_E, VOIC_BINS, sub( new_q_lf_E, *q_lf_E ) );
     542     1059311 :                     LEtot = W_shl( LEtot, sub( new_q_bands, *q_fr_bands ) );
     543     1059311 :                     scale_sig32( Bin_E, L_FFT / 2, sub( new_q_lf_E, *q_lf_E ) );
     544     1059311 :                     scale_sig32( band_energies, NB_BANDS, sub( new_q_bands, *q_fr_bands ) );
     545             :                 }
     546             :                 /* find energy per critical band */
     547     2118622 :                 ivas_find_enr( pt_fft, *q_fft_buff, pt_bands, q_fr_bands, lf_E + i_subfr * VOIC_BINS, q_lf_E, &LEtot, min_band, max_band,
     548     2118622 :                                &Bin_E[i_subfr * L_FFT / 2], BIN, band_energies + i_subfr * NB_BANDS );
     549             : 
     550     2118622 :                 pt_bands += NB_BANDS;
     551     2118622 :                 pt_fft += L_FFT;
     552             :             }
     553             :         }
     554             : 
     555     1133261 :         *q_Bin_E = *q_lf_E;
     556     1133261 :         move16();
     557             : 
     558             :         /* Average total log energy over both half-frames */
     559             :         /* *Etot = 10.0f * (float)log10(0.5f * *Etot); */
     560     1133261 :         *Etot = -838860800 /* 10.f * log10f(0.00001f) in Q24 : This is when LEtot is 0*/;
     561     1133261 :         move16();
     562     1133261 :         IF( LEtot != 0 )
     563             :         {
     564             :             /* Q of LEtot is  q_fr_bands+1, LEtot / 2 can be considered as LEtot in q_fr_bands+2 */
     565     1133261 :             exp = W_norm( LEtot );
     566     1133261 :             LEtot = W_shl( LEtot, exp );                                                                                        // q_fr_bands+2+exp
     567     1133261 :             Ltmp = BASOP_Util_Log10( W_extract_h( LEtot ), sub( 61, add( *q_fr_bands, exp ) ) /* 31-(q_fr_bands+2+exp-32) */ ); // Q25
     568     1133261 :             Ltmp = Mpy_32_32( Ltmp, 1342177280 /* 10.f in Q27 */ );                                                             // (Q25, Q27) -> Q21
     569     1133261 :             *Etot = L_shl( Ltmp, Q24 - Q21 );                                                                                   // Q24
     570     1133261 :             move16();
     571             :         }
     572     1133261 :         *q_band_energies = *q_fr_bands;
     573     1133261 :         move16();
     574             :     }
     575             :     ELSE
     576             :     {
     577       59659 :         IF( is_zero_arr( hCPE->hStereoDft->DFT_fx[0], STEREO_DFT_N_MAX_ENC ) )
     578             :         {
     579           0 :             set32_fx( Bin_E, 0, L_FFT );
     580           0 :             set32_fx( lf_E, 0, 2 * VOIC_BINS );
     581           0 :             set32_fx( band_energies, 0, 2 * NB_BANDS );
     582           0 :             set32_fx( fr_bands, E_MIN_FXQ31, 2 * NB_BANDS ); // Q31 (*q_fr_bands)
     583           0 :             *Etot = -193760400;                              // Q24
     584           0 :             *q_fr_bands = Q31;
     585           0 :             *q_lf_E = *q_fr_bands;
     586           0 :             move32();
     587           0 :             move16();
     588           0 :             move16();
     589             :         }
     590             :         ELSE
     591             :         {
     592       59659 :             exp = sub( getScaleFactor32( hCPE->hStereoDft->DFT_fx[0], STEREO_DFT_N_MAX_ENC ), 1 );
     593       59659 :             scale_sig32( hCPE->hStereoDft->DFT_fx[0], STEREO_DFT_N_MAX_ENC, exp ); /* exp(hCPE->hStereoDft->DFT_fx_e[0] - exp) */
     594       59659 :             hCPE->hStereoDft->DFT_fx_e[0] = sub( hCPE->hStereoDft->DFT_fx_e[0], exp );
     595       59659 :             move16();
     596       59659 :             find_enr_dft_ivas_fx( hCPE, input_Fs, hCPE->hStereoDft->DFT_fx[0], pt_bands, q_fr_bands, lf_E, q_lf_E, &LEtot, min_band, max_band, Bin_E, q_Bin_E, band_energies, sub( Q31, hCPE->hStereoDft->DFT_fx_e[0] ) );
     597       59659 :             MVR2R_WORD32( lf_E, lf_E + VOIC_BINS, VOIC_BINS );
     598       59659 :             MVR2R_WORD32( Bin_E, Bin_E + ( L_FFT / 2 ), L_FFT / 2 );
     599       59659 :             MVR2R_WORD32( band_energies, band_energies + NB_BANDS, NB_BANDS );
     600       59659 :             MVR2R_WORD32( pt_bands, pt_bands + NB_BANDS, NB_BANDS );
     601             : 
     602             :             /* Average total log energy over both half-frames */
     603       59659 :             *Etot = -838860800 /* 10.f * log10f(0.00001f) in Q24 : This is when LEtot is 0*/;
     604       59659 :             move16();
     605       59659 :             IF( LEtot != 0 )
     606             :             {
     607       59659 :                 exp = W_norm( LEtot );
     608       59659 :                 LEtot = W_shl( LEtot, exp );                                                                                        // q_fr_bands+exp
     609       59659 :                 Ltmp = BASOP_Util_Log10( W_extract_h( LEtot ), sub( 62, add( *q_fr_bands, exp ) ) /* 31-(q_fr_bands+1+exp-32) */ ); // Q25
     610       59659 :                 Ltmp = Mpy_32_32( Ltmp, 1342177280 /* 10.f in Q27 */ );                                                             // (Q25, Q27) -> Q21
     611       59659 :                 *Etot = L_shl( Ltmp, Q24 - Q21 );                                                                                   // Q24
     612       59659 :                 move16();
     613             :             }
     614             :         }
     615       59659 :         *q_band_energies = *q_fr_bands;
     616       59659 :         move16();
     617             :     }
     618             : 
     619     1192920 :     exp = sub( getScaleFactor32( fr_bands, 2 * NB_BANDS ), 1 );
     620     1192920 :     scale_sig32( fr_bands, 2 * NB_BANDS, exp ); /* q_fr_bands + exp */
     621     1192920 :     *q_fr_bands = add( *q_fr_bands, exp );
     622     1192920 :     move16();
     623             : 
     624     1192920 :     exp = getScaleFactor32( band_energies, 2 * NB_BANDS );
     625     1192920 :     scale_sig32( band_energies, 2 * NB_BANDS, exp ); /* q_band_energies + exp */
     626     1192920 :     *q_band_energies = add( *q_band_energies, exp );
     627     1192920 :     move16();
     628             : 
     629     1192920 :     *q_Bin_E_old = *q_Bin_E;
     630     1192920 :     move16();
     631             : 
     632             : 
     633             :     /* Per-bin log-energy spectrum */
     634     1192920 :     Bin_E[L_FFT / 2 - 1] = Bin_E[L_FFT / 2 - 2]; // *q_Bin_E
     635     1192920 :     move32();
     636     1192920 :     Bin_E[L_FFT - 1] = Bin_E[L_FFT - 2]; // *q_Bin_E
     637     1192920 :     move32();
     638     1192920 :     Word32 add_const = 21475; // 1e-5 in Q31
     639   153886680 :     FOR( i = 0; i < L_FFT / 2; i++ )
     640             :     {
     641   152693760 :         Bin_E_old[i] = Bin_E[i]; // *q_Bin_E
     642   152693760 :         move32();
     643             : 
     644             :         /* PS[i] = ( Bin_E[i] + 1e-5f + Bin_E[i + L_FFT / 2] + 1e-5f ) / 2.0f; */
     645             : #ifndef FIX_1762_COMPILER_ISSUE
     646             :         PS[i] = W_extract_h( W_add( W_mac_32_32( W_mult_32_32( Bin_E[i], ONE_IN_Q30 ), Bin_E[i + L_FFT / 2], ONE_IN_Q30 ), W_shr( W_shl( add_const, 32 ), sub( 31, *q_Bin_E ) ) ) ); // *q_Bin_E
     647             : #else
     648   152693760 :         PS[i] = W_extract_h( W_add( W_shl( W_add( W_deposit32_l( Bin_E[i] ), W_deposit32_l( Bin_E[i + L_FFT / 2] ) ), 31 ), W_shr( W_shl( add_const, 32 ), sub( 31, *q_Bin_E ) ) ) ); // *q_Bin_E
     649             : #endif
     650   152693760 :         move32();
     651             : 
     652             :         /* Bin_E[i] = (float) ( 10.0f * log( PS[i] ) ); */
     653   152693760 :         IF( EspecdB != NULL )
     654             :         {
     655   144509952 :             EspecdB[i] = -14736; /* ln(1e-5) in Q7 */
     656   144509952 :             move16();
     657             :         }
     658             : 
     659   152693760 :         Bin_E[i] = -482887093; /* ln(1e-5) in Q22 */
     660   152693760 :         move32();
     661             : 
     662   152693760 :         IF( GT_32( PS[i], L_shl_sat( 21475, sub( *q_Bin_E, Q31 ) ) ) /*1e - 5 in *q_bin_E */ )
     663             :         {
     664   143209422 :             Ltmp = L_add( BASOP_Util_Log2( PS[i] ), L_shl( sub( Q31, *q_Bin_E ), Q25 ) );
     665   143209422 :             Bin_E[i] = Mpy_32_32( Ltmp, 1860652798 /*10.0*logf(2) in Q28 */ ); // Q22
     666   143209422 :             move32();
     667             : 
     668   143209422 :             tmp = extract_h( L_shl( Bin_E[i], Q23 - Q22 ) ); // Q7
     669   143209422 :             if ( EspecdB != NULL )
     670             :             {
     671   135025614 :                 EspecdB[i] = tmp; // Q7
     672   135025614 :                 move16();
     673             :             }
     674             :         }
     675             :     }
     676             : 
     677     1192920 :     if ( q_PS != NULL )
     678             :     {
     679     1128984 :         *q_PS = *q_Bin_E;
     680     1128984 :         move16();
     681             :     }
     682             : 
     683     1192920 :     exp = L_norm_arr( Bin_E, L_FFT / 2 );
     684     1192920 :     exp2 = L_norm_arr( Bin_E + L_FFT / 2, L_FFT / 2 );
     685     1192920 :     resultant_q = s_min( Q22, s_min( add( *q_Bin_E, exp2 ), add( exp, Q22 ) ) ); // calculating resultant q after scaling
     686     1192920 :     scale_sig32( Bin_E, L_FFT / 2, sub( resultant_q, Q22 ) );                    // Q22=>resultant_q
     687     1192920 :     scale_sig32( Bin_E + L_FFT / 2, L_FFT / 2, sub( resultant_q, *q_Bin_E ) );   // q_Bin_E=>resultant_q
     688     1192920 :     *q_Bin_E = resultant_q;
     689     1192920 :     move16();
     690             : 
     691     1192920 :     return;
     692             : }
     693             : 
     694             : /*------------------------------------------------------------------------*
     695             :  * find_enr()
     696             :  *
     697             :  * find input signal energy for each critical band and first 74 LF bins
     698             :  * The energy is normalized by the number of frequency bins in a channel
     699             :  *------------------------------------------------------------------------*/
     700             : 
     701             : /* Merge with ivas_find_enr function once analy_sp is unified */
     702     2118622 : static void ivas_find_enr(
     703             :     Word16 data[],         /* i  : fft result                                                  */
     704             :     Word16 q_data,         /* i  : Q of fft result                                             */
     705             :     Word32 band[],         /* o  : per band energy                           q_band            */
     706             :     Word16 *q_band,        /* o  : Q of per band energy                                                            */
     707             :     Word32 *ptE,           /* o  : per bin energy  for low frequencies       q_ptE             */
     708             :     Word16 *q_ptE,         /* o  : Q of per bin energy  for low frequencies  Q0                */
     709             :     Word64 *LEtot,         /* o  : total energy                              q_band+1          */
     710             :     const Word16 min_band, /* i  : minimum critical band                     Q0                */
     711             :     const Word16 max_band, /* i  : maximum critical band                     Q0                */
     712             :     Word32 *Bin_E,         /* o  : Per bin energy                            q_ptE             */
     713             :     Word16 BIN_FREQ_FX,    /* i  : Number of frequency bins                  Q0                */
     714             :     Word32 *band_energies  /* o  : per band energy without MODE2_E_MIN       q_band            */
     715             : )
     716             : {
     717             :     Word16 i;
     718             :     Word16 freq;
     719             :     Word16 *ptR, *ptI;
     720             :     Word16 voic_band;
     721             :     Word64 etot, band_ener;
     722             :     Word16 start_freq;
     723             :     Word32 min_ener;
     724     2118622 :     Word16 shift = 0;
     725     2118622 :     move16();
     726             : 
     727     2118622 :     ptR = &data[1];         /* first real */
     728     2118622 :     ptI = &data[L_FFT - 1]; /* first imaginary */
     729             : 
     730     2118622 :     voic_band = VOIC_BAND_8k;
     731     2118622 :     move16();
     732             :     assert( VOIC_BAND == VOIC_BAND_8k );
     733             : 
     734             :     /*-----------------------------------------------------------------*
     735             :      * For low frequency bins, save per bin energy for the use
     736             :      * in NS and find_tilt()
     737             :      *-----------------------------------------------------------------*/
     738             : 
     739     2118622 :     *q_ptE = add( shl( q_data, 1 ), 14 );
     740     2118622 :     move16();
     741     2118622 :     *q_band = add( shl( q_data, 1 ), 14 );
     742     2118622 :     move16();
     743             : 
     744     2118622 :     IF( GT_16( *q_band, 39 ) )
     745             :     {
     746        1848 :         shift = sub( *q_band, 39 );
     747        1848 :         *q_band = 39;
     748        1848 :         move16();
     749             :     }
     750             : 
     751     2118622 :     min_ener = L_shl( E_MIN_FXQ31, sub( *q_band, Q31 ) ); // *q_band
     752             : 
     753     2118622 :     freq = BIN_FREQ_FX;
     754     2118622 :     move16();
     755    38135196 :     FOR( i = 0; i < voic_band; i++ ) /* up to maximum allowed voiced critical band  */
     756             :     {
     757    36016574 :         band_ener = 0;
     758    36016574 :         move64();
     759    36016574 :         start_freq = freq;
     760    36016574 :         move16();
     761   192794602 :         WHILE( LE_32( freq, crit_bands_fx[i] ) )
     762             :         {
     763             :             /*
     764             :                *ptE = *ptR * *ptR + *ptI * *ptI;
     765             : 
     766             :                Overflow occurs in the above operation only when ptR and ptI values are equal to -32768.
     767             :                In that case, energy value will be 2^31 (only one greater than max 32 bit value).
     768             :                Hence, saturation is added.
     769             : 
     770             :                *ptE *= norm_val;
     771             :                norm_val = 4 / (256 * 256), As the value is in power's of 2, result can be obtained by increasing the Q factor
     772             : 
     773             :                Q of energy = 2 * q_data + 14 = *q_ptE
     774             :            */
     775             : 
     776   156778028 :             *ptE = L_mac0_sat( L_mult0( *ptR, *ptR ), *ptI, *ptI ); // *q_ptE
     777   156778028 :             move32();
     778             : 
     779   156778028 :             *Bin_E++ = *ptE; // *q_ptE
     780   156778028 :             move32();
     781             : 
     782             :             /*
     783             :                 BIN_FREQ_FX = BIN, cnt = ( ( crit_bands_fx[i] - start_freq ) / BIN ) + 1
     784             :                 band[i] += *ptE++;
     785             :                 band[i] *= inv_tbl[cnt]; // normalization per frequency bin
     786             :             */
     787   156778028 :             band_ener = W_mac_32_16( band_ener, *ptE, inv_tbl_fx[( ( crit_bands_fx[i] - start_freq ) / BIN ) + 1] ); // *q_band+16+shift
     788   156778028 :             ptR++;
     789   156778028 :             ptI--;
     790   156778028 :             ptE++;
     791   156778028 :             freq = add( freq, BIN_FREQ_FX );
     792             :         }
     793             : 
     794    36016574 :         band[i] = W_extract_h( W_shl( band_ener, sub( Q16, shift ) ) ); // *q_band
     795    36016574 :         move32();
     796             : 
     797    36016574 :         band_energies[i] = band[i]; /* per band energy without E_MIN   */ // *q_band
     798    36016574 :         move32();
     799             : 
     800    36016574 :         if ( LT_32( band[i], min_ener ) ) // *q_band
     801             :         {
     802     1954311 :             band[i] = min_ener; // *q_band
     803     1954311 :             move32();
     804             :         }
     805             :     }
     806             : 
     807     2118622 :     IF( EQ_16( BIN_FREQ_FX, 50 ) )
     808             :     {
     809             :         /*-----------------------------------------------------------------*
     810             :          * Continue compute the E per critical band for high frequencies
     811             :          *-----------------------------------------------------------------*/
     812             : 
     813     8474488 :         FOR( i = voic_band; i < NB_BANDS; i++ )
     814             :         {
     815     6355866 :             band_ener = 0;
     816     6355866 :             move64();
     817     6355866 :             start_freq = freq;
     818     6355866 :             move16();
     819   118642832 :             WHILE( LE_32( freq, crit_bands_fx[i] ) )
     820             :             {
     821             :                 /*
     822             :                   *Bin_E = *ptR * *ptR + *ptI * *ptI;
     823             : 
     824             :                   Overflow occurs in the below operation only when ptR and ptI values are equal to - 32768.
     825             :                   In that case, energy value will be 2 ^ 31 (only one greater than max 32 bit value).
     826             :                   Hence, saturation is added.
     827             : 
     828             :                   *Bin_E *= norm_val;
     829             :                   norm_val = 4 / (256 * 256), As the value is in power's of 2, result can be obtained by increasing the Q factor
     830             : 
     831             :                   Q of energy = 2 * q_data + 14 = *q_ptE
     832             :                 */
     833             : 
     834   112286966 :                 *Bin_E = L_mac0_sat( L_mult0( *ptR, *ptR ), *ptI, *ptI ); // 2*q_data+14 = *q_ptE
     835   112286966 :                 move32();
     836             : 
     837             :                 /*
     838             :                    BIN_FREQ_FX = BIN, cnt = ( ( crit_bands_fx[i] - start_freq ) / BIN ) + 1
     839             :                    band[i] += *ptE++;
     840             :                    band[i] *= inv_tbl[cnt]; // normalization per frequency bin
     841             :                 */
     842   112286966 :                 band_ener = W_mac_32_16( band_ener, *Bin_E, inv_tbl_fx[( ( crit_bands_fx[i] - start_freq ) / BIN ) + 1] ); // *q_band+16+shift
     843   112286966 :                 ptR++;
     844   112286966 :                 ptI--;
     845   112286966 :                 Bin_E++;
     846             : 
     847   112286966 :                 freq = add( freq, BIN_FREQ_FX );
     848             :             }
     849             : 
     850     6355866 :             band[i] = W_extract_h( W_shl_nosat( band_ener, sub( Q16, shift ) ) ); // *q_band
     851     6355866 :             move32();
     852             : 
     853     6355866 :             band_energies[i] = band[i]; /* per band energy without E_MIN   */ // *q_band
     854     6355866 :             move32();
     855             : 
     856     6355866 :             if ( LT_32( band[i], min_ener ) ) // *q_band
     857             :             {
     858      369998 :                 band[i] = min_ener; // *q_band
     859      369998 :                 move32();
     860             :             }
     861             :         }
     862             :     }
     863             : 
     864             :     /*-----------------------------------------------------------------*
     865             :      * Find the total energy over the input bandwidth
     866             :      *-----------------------------------------------------------------*/
     867             : 
     868     2118622 :     etot = *LEtot; // *q_band+1
     869     2118622 :     move64();
     870    44457974 :     FOR( i = min_band; i <= max_band; i++ )
     871             :     {
     872    42339352 :         etot = W_mac_32_32( etot, band[i], 1 ); // *q_band+1
     873             :     }
     874     2118622 :     *LEtot = etot; // *q_band+1
     875     2118622 :     move64();
     876             : 
     877     2118622 :     return;
     878             : }
     879             : 
     880        6200 : static void find_enr(
     881             :     Word16 data[],         /* i  : fft result                                                  */
     882             :     Word32 band[],         /* o  : per band energy                           Q_new + QSCALE   */
     883             :     Word32 *ptE,           /* o  : per bin energy  for low frequencies       Q_new + QSCALE-2 */
     884             :     Word32 *LEtot,         /* o  : total energy                              Q_new + QSCALE   */
     885             :     const Word16 min_band, /* i  : minimum critical band                     Q0                */
     886             :     const Word16 max_band, /* i  : maximum critical band                     Q0                */
     887             :     const Word16 Q_new2,   /* i  : scaling factor                            Q0                */
     888             :     const Word32 e_min,    /* i  : minimum energy scaled                     Q_new + QSCALE   */
     889             :     Word32 *Bin_E,         /* o  : Per bin energy                            Q_new + QSCALE-2 */
     890             :     Word16 BIN_FREQ_FX,    /* i  : Number of frequency bins                  Q0               */
     891             :     Word32 *band_energies  /* o  : per band energy without MODE2_E_MIN        */
     892             : )
     893             : {
     894             :     Word16 i, cnt, shift_to_norm;
     895             :     Word16 freq, wtmp;
     896             :     Word16 *ptR, *ptI, diff_scaleP1, diff_scaleM2;
     897             :     Word16 exp_band;
     898             :     Word32 Ltmp, Ltmp1;
     899             :     Word16 voic_band;
     900             :     Word32 etot;
     901             :     Word16 exp_etot;
     902             :     Word32 *tmpptr;
     903             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
     904        6200 :     Flag Overflow = 0;
     905        6200 :     move32();
     906             : #endif
     907             : 
     908             : 
     909        6200 :     ptR = &data[1];         /* first real */
     910        6200 :     ptI = &data[L_FFT - 1]; /* first imaginary */
     911             : 
     912             :     /*-----------------------------------------------------------------------------------*
     913             :      * Scaling needed by band and ptE output
     914             :      * Wants all energies scaled by Q_new + QSCALE to maintain maximum
     915             :      * precision on bckr noise in clean speech
     916             :      * First shift left by Q_new + QSCALE than shift right by 2*Q_new-1
     917             :      * shift left (Q_new + QSCALE - (2*Q_new -1))
     918             :      * shift left (QSCALE - Q_new + 1) == shift left by (QSCALE+1) - Q_new
     919             :      *-----------------------------------------------------------------------------------*/
     920             : 
     921        6200 :     diff_scaleP1 = sub( QSCALE + 1 + 1, Q_new2 );
     922        6200 :     diff_scaleM2 = sub( QSCALE + 1 - 2, Q_new2 );
     923             : 
     924        6200 :     voic_band = VOIC_BAND_8k;
     925        6200 :     move16();
     926             :     assert( VOIC_BAND == VOIC_BAND_8k );
     927             : 
     928        6200 :     etot = L_deposit_l( 0 );
     929        6200 :     exp_etot = 0;
     930        6200 :     move16();
     931             : 
     932             :     /*-----------------------------------------------------------------*
     933             :      * For low frequency bins, save per bin energy for the use
     934             :      * in NS and find_tilt()
     935             :      *-----------------------------------------------------------------*/
     936             : 
     937        6200 :     freq = BIN_FREQ_FX;
     938        6200 :     move16();
     939      111600 :     FOR( i = 0; i < voic_band; i++ ) /* up to maximum allowed voiced critical band  */
     940             :     {
     941      105400 :         tmpptr = Bin_E; /* Q_new + QSCALE - 2 */
     942      105400 :         move16();
     943      105400 :         Ltmp1 = L_deposit_l( 0 );
     944             : 
     945      564200 :         FOR( ; LE_32( freq, crit_bands_fx[i] ); freq += BIN_FREQ_FX )
     946             :         {
     947             :             /*ptE = *ptR * *ptR + *ptI * *ptI */ /* energy */
     948      458800 :             Ltmp = L_mult( *ptI, *ptI );
     949      458800 :             Ltmp = L_mac( Ltmp, *ptR, *ptR );
     950             : 
     951             :             /* *ptE *= 4.0 / (L_FFT*L_FFT) */
     952             :             /* normalization - corresponds to FFT normalization by 2/L_FFT */
     953             :             BASOP_SATURATE_WARNING_OFF_EVS;                  /* saturation seems to have no effect (tested by simulation) */
     954      458800 :             *ptE = L_shl_o( Ltmp, diff_scaleM2, &Overflow ); /* Q_new + QSCALE - 2 */
     955      458800 :             move32();                                        /* scaled by Q_new + QSCALE - 2 */
     956             :             BASOP_SATURATE_WARNING_ON_EVS;
     957             :             /*band[i] += *ptE++;*/
     958      458800 :             *Bin_E = *ptE;
     959      458800 :             move32();
     960      458800 :             Bin_E++;
     961      458800 :             Ltmp1 = L_add( Ltmp1, Ltmp );
     962             : 
     963      458800 :             ptE++;
     964      458800 :             ptR++;
     965      458800 :             ptI--;
     966             :         }
     967             : 
     968      105400 :         exp_band = sub( norm_l( Ltmp1 ), 1 ); /* divide by 2 to ensure band < cnt */
     969      105400 :         wtmp = round_fx( L_shl( Ltmp1, exp_band ) );
     970             : 
     971             :         /* band[i] /= cnt */ /* normalization per frequency bin */
     972      105400 :         cnt = (Word16) ( Bin_E - tmpptr );
     973      105400 :         shift_to_norm = norm_s( cnt );
     974      105400 :         wtmp = div_s( wtmp, shl( cnt, shift_to_norm ) ); /* Q15 */
     975      105400 :         Ltmp1 = L_deposit_l( wtmp );                     /* Q15 */
     976             : 
     977      105400 :         exp_band = sub( exp_band, shift_to_norm );
     978      105400 :         exp_band = sub( diff_scaleP1, exp_band );
     979             :         BASOP_SATURATE_WARNING_OFF_EVS;                  /* saturation seems to have no effect (tested by simulation) */
     980      105400 :         band[i] = L_shl_o( Ltmp1, exp_band, &Overflow ); /* Q15 + exp_band */
     981      105400 :         move32();                                        /* band scaled by Q_new + QSCALE */
     982             :         BASOP_SATURATE_WARNING_ON_EVS;
     983             : 
     984      105400 :         test();
     985      105400 :         IF( GE_16( i, min_band ) && LE_16( i, max_band ) )
     986             :         {
     987      105400 :             IF( LT_32( band[i], e_min ) )
     988             :             {
     989        1369 :                 Ltmp1 = L_shl( e_min, 0 );
     990        1369 :                 exp_band = 0;
     991        1369 :                 move16();
     992             :             }
     993             : 
     994      105400 :             wtmp = sub( exp_band, exp_etot );
     995      105400 :             if ( wtmp > 0 )
     996             :             {
     997       15770 :                 etot = L_shr( etot, wtmp );
     998             :             }
     999      105400 :             exp_etot = s_max( exp_etot, exp_band );
    1000      105400 :             etot = L_add( etot, L_shl( Ltmp1, sub( exp_band, exp_etot ) ) );
    1001             :         }
    1002             : 
    1003      105400 :         band_energies[i] = band[i]; /* Q_new + QSCALE */
    1004      105400 :         move32();
    1005             : 
    1006      105400 :         band[i] = L_max( band[i], e_min );
    1007      105400 :         move32();
    1008             :     }
    1009             : 
    1010        6200 :     IF( EQ_16( BIN_FREQ_FX, 50 ) )
    1011             :     {
    1012             :         /*-----------------------------------------------------------------*
    1013             :          * Continue compute the E per critical band for high frequencies
    1014             :          *-----------------------------------------------------------------*/
    1015             : 
    1016       24800 :         FOR( i = voic_band; i < NB_BANDS; i++ )
    1017             :         {
    1018       18600 :             tmpptr = Bin_E;
    1019       18600 :             move16();
    1020       18600 :             Ltmp1 = L_deposit_l( 0 );
    1021             : 
    1022      347200 :             FOR( ; LE_32( freq, crit_bands_fx[i] ); freq += BIN_FREQ_FX )
    1023             :             {
    1024             :                 /* *ptE = *ptR * *ptR + *ptI * *ptI */
    1025      328600 :                 Ltmp = L_mult( *ptI, *ptI );
    1026      328600 :                 Ltmp = L_mac( Ltmp, *ptR, *ptR );
    1027             : 
    1028             :                 /* *ptE *= 4.0 / (L_FFT*L_FFT) */
    1029             :                 /* normalization - corresponds to FFT normalization by 2/L_FFT  */
    1030             :                 BASOP_SATURATE_WARNING_OFF_EVS;                    /* saturation seems to have no effect (tested by simulation) */
    1031      328600 :                 *Bin_E = L_shl_o( Ltmp, diff_scaleM2, &Overflow ); /* Q_new + QSCALE */
    1032      328600 :                 move32();                                          /* scaled by Q_new + QSCALE - 2 */
    1033             :                 BASOP_SATURATE_WARNING_ON_EVS;
    1034      328600 :                 Bin_E++;
    1035      328600 :                 Ltmp1 = L_add( Ltmp1, Ltmp );
    1036             : 
    1037      328600 :                 ptR++;
    1038      328600 :                 ptI--;
    1039             :             }
    1040             : 
    1041       18600 :             exp_band = sub( norm_l( Ltmp1 ), 1 ); /* divide by 2 to ensure band < cnt */
    1042       18600 :             wtmp = round_fx( L_shl( Ltmp1, exp_band ) );
    1043             : 
    1044             :             /* band[i] /= cnt */ /* normalization per frequency bin */
    1045       18600 :             cnt = (Word16) ( Bin_E - tmpptr );
    1046       18600 :             shift_to_norm = norm_s( cnt );
    1047       18600 :             wtmp = div_s( wtmp, shl( cnt, shift_to_norm ) );
    1048       18600 :             Ltmp1 = L_deposit_l( wtmp );
    1049             : 
    1050       18600 :             exp_band = sub( exp_band, shift_to_norm );
    1051       18600 :             exp_band = sub( diff_scaleP1, exp_band );
    1052             :             BASOP_SATURATE_WARNING_OFF_EVS; /* saturation seems to have no effect (tested by simulation) */
    1053       18600 :             band[i] = L_shl_o( Ltmp1, exp_band, &Overflow );
    1054       18600 :             move32(); /* band scaled by Q_new + QSCALE */
    1055             :             BASOP_SATURATE_WARNING_ON_EVS;
    1056             : 
    1057       18600 :             test();
    1058       18600 :             IF( GE_16( i, min_band ) && LE_16( i, max_band ) )
    1059             :             {
    1060       18600 :                 IF( LT_32( band[i], e_min ) )
    1061             :                 {
    1062          40 :                     Ltmp1 = L_shl( e_min, 0 );
    1063          40 :                     exp_band = 0;
    1064          40 :                     move16();
    1065             :                 }
    1066             : 
    1067       18600 :                 wtmp = sub( exp_band, exp_etot );
    1068       18600 :                 if ( wtmp > 0 )
    1069             :                 {
    1070         469 :                     etot = L_shr( etot, wtmp );
    1071             :                 }
    1072       18600 :                 exp_etot = s_max( exp_etot, exp_band );
    1073             : 
    1074       18600 :                 etot = L_add( etot, L_shl( Ltmp1, sub( exp_band, exp_etot ) ) );
    1075             :             }
    1076             : 
    1077       18600 :             band_energies[i] = band[i];
    1078       18600 :             move32();
    1079             : 
    1080       18600 :             band[i] = L_max( band[i], e_min );
    1081       18600 :             move32();
    1082             :         }
    1083             :     }
    1084             : 
    1085             :     /*-----------------------------------------------------------------*
    1086             :      * Find the total energy over the input bandwidth
    1087             :      *-----------------------------------------------------------------*/
    1088             : 
    1089        6200 :     etot = L_add_sat( *LEtot, L_shl_sat( etot, sub( exp_etot, 4 ) ) );
    1090        6200 :     *LEtot = etot;
    1091        6200 :     move32();
    1092             : 
    1093             : 
    1094        6200 :     return;
    1095             : }

Generated by: LCOV version 1.14