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 396222 : Max_val = s_max( Max_val, fft_temp[i] ); /* Q_new - preemph_bits */
92 : }
93 787400 : IF( fft_temp[i] < 0 )
94 : {
95 387611 : 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 396243 : 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 387515 : 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 59643 : 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 59643 : Word16 shift = 0;
227 59643 : move16();
228 :
229 : /* One window - 40ms*12.8kHz = 512 samples */
230 59643 : c_1_fx = 1073660991; // 0.999924719 in Q30, cosf( PI2 / STEREO_DFT_N_12k8_ENC )
231 59643 : s_1_fx = 13176464; // 0.0122715384 in Q30, sinf( PI2 / STEREO_DFT_N_12k8_ENC )
232 59643 : g_1_fx = 1570240043; // 1.4624 in Q30, ( 1.f + 0.68f * 0.68f )
233 59643 : g_2_fx = 1460288880; // 1.36 in Q30, 2 * 0.68f
234 59643 : move32();
235 59643 : move32();
236 59643 : move32();
237 59643 : move32();
238 :
239 59643 : bin_cnt = 0;
240 59643 : move16();
241 :
242 : /* input_Fs / (float) hCPE->hStereoDft->NFFT;*/ /* adaptive frequency bin width */
243 59643 : bin_freq = BASOP_Util_Divide3216_Scale( input_Fs, hCPE->hStereoDft->NFFT, &exp );
244 59643 : 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 59643 : temp2 = BASOP_Util_Divide3216_Scale( BIN, bin_freq, &exp );
250 59643 : temp2 = shl( temp2, add( 1, exp ) ); // Q0
251 59643 : exp = norm_s( hCPE->hStereoDft->win_ana_energy_fx );
252 59643 : temp1 = div_s( ONE_IN_Q14, shl( hCPE->hStereoDft->win_ana_energy_fx, exp ) ); // 14-(15+exp-1)+15 = 15+exp
253 59643 : 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 59643 : 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 59643 : q_norm_val = add( 28, sub( exp, exp1 ) );
260 :
261 59643 : ptR_fx = &DFT_past_DMX_fx[2]; /* first real */
262 59643 : ptI_fx = &DFT_past_DMX_fx[3]; /* first imaginary */
263 :
264 59643 : c_fx = c_1_fx; // Q30
265 59643 : s_fx = s_1_fx; // Q30
266 59643 : move32();
267 59643 : move32();
268 :
269 : /* for low frequency bins, save per bin energy for the use in find_tilt() */
270 59643 : freq = bin_freq;
271 59643 : move32();
272 :
273 59643 : *q_band = add( shl( Q_inp_dmx, 1 ), sub( q_norm_val, 48 ) );
274 59643 : move16();
275 59643 : *q_Bin_E = *q_band;
276 59643 : move16();
277 :
278 59643 : 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 59643 : min_ener = L_shl( E_MIN_FXQ31 /* 0.0035 in Q31 */, sub( *q_band, 31 ) );
286 1192860 : FOR( i = 0; i < NB_BANDS - 1; i++ ) /* up to maximum allowed voiced critical band */
287 : {
288 1133217 : band_ener = 0;
289 1133217 : move64();
290 1133217 : start_freq = freq;
291 1133217 : 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 13777533 : 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 12644316 : g_fx = L_sub( L_shr( g_1_fx, 1 ), Mpy_32_32( g_2_fx, c_fx ) ); // 29
302 12644316 : tmp_fx = Msub_32_32( Mpy_32_32( c_fx, c_1_fx ), s_fx, s_1_fx ); // 29
303 12644316 : s_fx = L_shl( Madd_32_32( Mpy_32_32( s_fx, c_1_fx ), c_fx, s_1_fx ), 1 ); // 30
304 12644316 : c_fx = L_shl( tmp_fx, 1 ); // 30
305 :
306 12644316 : BinE = Madd_32_32( Mpy_32_32( *ptR_fx, *ptR_fx ), *ptI_fx, *ptI_fx ); // 2*Q_inp_dmx-31
307 12644316 : 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 12644316 : 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 12644316 : 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 12644316 : ptR_fx += 2;
318 12644316 : ptI_fx += 2;
319 12644316 : freq = L_mac0( freq, bin_freq, 1 );
320 12644316 : bin_cnt = add( bin_cnt, 1 );
321 : }
322 :
323 : /* normalization per frequency bin */
324 1133217 : band_fx[i] = W_extract_h( W_shl( band_ener, sub( Q16, shift ) ) ); // *q_band
325 1133217 : move32();
326 :
327 : /* per band energy without E_MIN */
328 1133217 : band_ener_fx[i] = band_fx[i]; // *q_band
329 1133217 : move32();
330 :
331 1133217 : if ( LT_32( band_fx[i], min_ener ) )
332 : {
333 67760 : band_fx[i] = min_ener; // *q_band
334 67760 : 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 119286 : FOR( ; i < NB_BANDS; i++ )
352 : {
353 59643 : band_ener = 0;
354 59643 : move64();
355 59643 : start_freq = freq;
356 59643 : move32();
357 :
358 2624292 : 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 2564649 : g_fx = L_sub( L_shr( g_1_fx, 1 ), Mpy_32_32( g_2_fx, c_fx ) ); // 29
363 :
364 2564649 : BinE = Madd_32_32( Mpy_32_32( *ptR_fx, *ptR_fx ), *ptI_fx, *ptI_fx ); // 2*Q_inp_dmx-31
365 2564649 : 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 2564649 : 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 2564649 : 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 2564649 : ptR_fx += 2;
376 2564649 : ptI_fx += 2;
377 2564649 : freq = L_mac0( freq, bin_freq, 1 );
378 2564649 : bin_cnt = add( bin_cnt, 1 );
379 : }
380 :
381 : /* normalization per frequency bin */
382 59643 : band_fx[i] = W_extract_h( W_shl( band_ener, sub( Q16, shift ) ) ); // *q_band
383 59643 : move32();
384 :
385 : /* per band energy without E_MIN */
386 59643 : band_ener_fx[i] = band_fx[i]; // *q_band
387 59643 : move32();
388 :
389 59643 : if ( LT_32( band_fx[i], min_ener ) )
390 : {
391 3050 : band_fx[i] = min_ener; // *q_band
392 3050 : 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 59643 : assert( bin_cnt == ( STEREO_DFT_N_12k8_ENC / 2 - 1 ) );
399 59643 : BinE_fx[STEREO_DFT_N_12k8_ENC / 2 - 1] = BinE_fx[STEREO_DFT_N_12k8_ENC / 2 - 2]; // // *q_Bin_E
400 59643 : move32();
401 :
402 59643 : Word16 norm = getScaleFactor32( BinE_fx, L_FFT );
403 59643 : scale_sig32( BinE_fx, L_FFT, norm );
404 59643 : *q_Bin_E = add( *q_Bin_E, norm );
405 59643 : move16();
406 59643 : L_lerp_fx( BinE_fx, Bin_E_fx, L_FFT / 2, STEREO_DFT_N_12k8_ENC / 2, q_Bin_E );
407 :
408 59643 : MVR2R_WORD32( Bin_E_fx, ptE_fx, VOIC_BINS ); // *q_Bin_E
409 59643 : *q_ptE = *q_Bin_E;
410 59643 : move16();
411 :
412 : /* find the total log energy */
413 59643 : tot_ener = *Etot_fx;
414 59643 : move64();
415 :
416 1252503 : FOR( i = min_band; i <= max_band; i++ )
417 : {
418 1192860 : tot_ener = W_mac_32_32( tot_ener, band_fx[i], 1 ); // *q_band+1
419 : }
420 :
421 59643 : *Etot_fx = tot_ener;
422 59643 : move64();
423 :
424 59643 : return;
425 : }
426 : /*-------------------------------------------------------------------*
427 : * ivas_analy_sp_fx()
428 : *
429 : * Spectral analysis of 12.8kHz input
430 : *-------------------------------------------------------------------*/
431 1192936 : 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 1192936 : LEtot = 0;
467 1192936 : move64();
468 : /*-----------------------------------------------------------------*
469 : * Compute spectrum
470 : * find energy per critical frequency band and total energy in dB
471 : *-----------------------------------------------------------------*/
472 :
473 1192936 : pt_bands = fr_bands;
474 1192936 : pt_fft = fft_buff;
475 :
476 1192936 : IF( NE_16( element_mode, IVAS_CPE_DFT ) )
477 : {
478 1133293 : IF( is_zero_arr16( speech + 3 * ( L_SUBFR / 2 ) - L_FFT / 2, L_FFT + 4 * ( L_SUBFR / 2 ) ) )
479 : {
480 73898 : set16_fx( pt_fft, 0, 2 * L_FFT );
481 73898 : *q_fft_buff = Q15;
482 73898 : move16();
483 :
484 73898 : set32_fx( Bin_E, 0, L_FFT );
485 73898 : set32_fx( lf_E, 0, 2 * VOIC_BINS );
486 73898 : set32_fx( band_energies, 0, 2 * NB_BANDS );
487 73898 : set32_fx( fr_bands, E_MIN_FXQ31, 2 * NB_BANDS ); // Q31 (*q_fr_bands)
488 :
489 73898 : LEtot = W_shl( W_mult_32_16( E_MIN_FXQ31, add( sub( max_band, min_band ), 1 ) ), 1 ); // Q32 (*q_fr_bands+1)
490 73898 : *q_fr_bands = Q31;
491 73898 : *q_lf_E = *q_fr_bands;
492 73898 : move16();
493 73898 : move16();
494 : }
495 : ELSE
496 : {
497 1059395 : Word16 scale = 0, shift;
498 1059395 : move16();
499 1059395 : 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 3178185 : 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 2118790 : pt = speech + 3 * ( L_SUBFR / 2 ) - L_FFT / 2;
505 2118790 : if ( i_subfr != 0 )
506 : {
507 : /* set the pointer for second analysis window */
508 1059395 : pt = speech + 7 * ( L_SUBFR / 2 ) - L_FFT / 2;
509 : }
510 : /* Clear 1st value of 1st part, copy 1st value of 2nd part */
511 2118790 : pt_fft[0] = 0;
512 2118790 : move16();
513 2118790 : pt_fft[L_FFT / 2] = shl( pt[L_FFT / 2], shift ); // (Q_new + shift) - preemph_bits
514 2118790 : move16();
515 :
516 271205120 : FOR( i = 1; i < L_FFT / 2; i++ )
517 : {
518 : /* 1st windowed part */
519 269086330 : pt_fft[i] = mult_r( shl( pt[i], shift ), sqrt_han_window_fx[i] ); // (Q_new + shift) - preemph_bits
520 269086330 : move16();
521 :
522 : /* 2nd windowed part */
523 269086330 : pt_fft[L_FFT - i] = mult_r( shl( pt[L_FFT - i], shift ), sqrt_han_window_fx[i] ); // (Q_new + shift) - preemph_bits
524 269086330 : move16();
525 : }
526 :
527 : /* compute the spectrum */
528 2118790 : fft_rel_16_32fx( pt_fft, &scale, i_subfr, L_FFT, LOG2_L_FFT );
529 2118790 : *q_fft_buff = add( add( Q_new, shift ), scale ); // resultant q for fft_buff
530 2118790 : move16();
531 2118790 : IF( EQ_16( i_subfr, 1 ) )
532 : {
533 1059395 : Word16 new_q_lf_E = add( shl( *q_fft_buff, 1 ), 14 );
534 1059395 : Word16 new_q_bands = new_q_lf_E;
535 1059395 : IF( GT_16( new_q_bands, 39 ) )
536 : {
537 758 : new_q_bands = 39;
538 758 : move16();
539 : }
540 1059395 : scale_sig32( fr_bands, NB_BANDS, sub( new_q_bands, *q_fr_bands ) );
541 1059395 : scale_sig32( lf_E, VOIC_BINS, sub( new_q_lf_E, *q_lf_E ) );
542 1059395 : LEtot = W_shl( LEtot, sub( new_q_bands, *q_fr_bands ) );
543 1059395 : scale_sig32( Bin_E, L_FFT / 2, sub( new_q_lf_E, *q_lf_E ) );
544 1059395 : scale_sig32( band_energies, NB_BANDS, sub( new_q_bands, *q_fr_bands ) );
545 : }
546 : /* find energy per critical band */
547 2118790 : 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 2118790 : &Bin_E[i_subfr * L_FFT / 2], BIN, band_energies + i_subfr * NB_BANDS );
549 :
550 2118790 : pt_bands += NB_BANDS;
551 2118790 : pt_fft += L_FFT;
552 : }
553 : }
554 :
555 1133293 : *q_Bin_E = *q_lf_E;
556 1133293 : move16();
557 :
558 : /* Average total log energy over both half-frames */
559 : /* *Etot = 10.0f * (float)log10(0.5f * *Etot); */
560 1133293 : *Etot = -838860800 /* 10.f * log10f(0.00001f) in Q24 : This is when LEtot is 0*/;
561 1133293 : move16();
562 1133293 : 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 1133293 : exp = W_norm( LEtot );
566 1133293 : LEtot = W_shl( LEtot, exp ); // q_fr_bands+2+exp
567 1133293 : Ltmp = BASOP_Util_Log10( W_extract_h( LEtot ), sub( 61, add( *q_fr_bands, exp ) ) /* 31-(q_fr_bands+2+exp-32) */ ); // Q25
568 1133293 : Ltmp = Mpy_32_32( Ltmp, 1342177280 /* 10.f in Q27 */ ); // (Q25, Q27) -> Q21
569 1133293 : *Etot = L_shl( Ltmp, Q24 - Q21 ); // Q24
570 1133293 : move16();
571 : }
572 : }
573 : ELSE
574 : {
575 59643 : IF( is_zero_arr( hCPE->hStereoDft->DFT_fx[0], STEREO_DFT_N_MAX_ENC ) )
576 : {
577 0 : set32_fx( Bin_E, 0, L_FFT );
578 0 : set32_fx( lf_E, 0, 2 * VOIC_BINS );
579 0 : set32_fx( band_energies, 0, 2 * NB_BANDS );
580 0 : set32_fx( fr_bands, E_MIN_FXQ31, 2 * NB_BANDS ); // Q31 (*q_fr_bands)
581 :
582 0 : LEtot = W_shl( W_mult_32_16( E_MIN_FXQ31, add( sub( max_band, min_band ), 1 ) ), 1 ); // Q32 (*q_fr_bands+1)
583 0 : *q_fr_bands = Q31;
584 0 : *q_lf_E = *q_fr_bands;
585 0 : move16();
586 0 : move16();
587 : }
588 : ELSE
589 : {
590 59643 : exp = sub( getScaleFactor32( hCPE->hStereoDft->DFT_fx[0], STEREO_DFT_N_MAX_ENC ), 1 );
591 59643 : scale_sig32( hCPE->hStereoDft->DFT_fx[0], STEREO_DFT_N_MAX_ENC, exp ); /* exp(hCPE->hStereoDft->DFT_fx_e[0] - exp) */
592 59643 : hCPE->hStereoDft->DFT_fx_e[0] = sub( hCPE->hStereoDft->DFT_fx_e[0], exp );
593 59643 : move16();
594 59643 : 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] ) );
595 59643 : MVR2R_WORD32( lf_E, lf_E + VOIC_BINS, VOIC_BINS );
596 59643 : MVR2R_WORD32( Bin_E, Bin_E + ( L_FFT / 2 ), L_FFT / 2 );
597 59643 : MVR2R_WORD32( band_energies, band_energies + NB_BANDS, NB_BANDS );
598 59643 : MVR2R_WORD32( pt_bands, pt_bands + NB_BANDS, NB_BANDS );
599 : }
600 :
601 : /* Average total log energy over both half-frames */
602 59643 : *Etot = -838860800 /* 10.f * log10f(0.00001f) in Q24 : This is when LEtot is 0*/;
603 59643 : move16();
604 59643 : IF( LEtot != 0 )
605 : {
606 59643 : exp = W_norm( LEtot );
607 59643 : LEtot = W_shl( LEtot, exp ); // q_fr_bands+exp
608 59643 : Ltmp = BASOP_Util_Log10( W_extract_h( LEtot ), sub( 62, add( *q_fr_bands, exp ) ) /* 31-(q_fr_bands+1+exp-32) */ ); // Q25
609 59643 : Ltmp = Mpy_32_32( Ltmp, 1342177280 /* 10.f in Q27 */ ); // (Q25, Q27) -> Q21
610 59643 : *Etot = L_shl( Ltmp, Q24 - Q21 ); // Q24
611 59643 : move16();
612 : }
613 : }
614 :
615 1192936 : *q_band_energies = *q_fr_bands;
616 1192936 : move16();
617 :
618 1192936 : exp = sub( getScaleFactor32( fr_bands, 2 * NB_BANDS ), 1 );
619 1192936 : scale_sig32( fr_bands, 2 * NB_BANDS, exp ); /* q_fr_bands + exp */
620 1192936 : *q_fr_bands = add( *q_fr_bands, exp );
621 1192936 : move16();
622 :
623 1192936 : exp = sub( getScaleFactor32( band_energies, 2 * NB_BANDS ), 1 );
624 1192936 : scale_sig32( band_energies, 2 * NB_BANDS, exp ); /* q_band_energies + exp */
625 1192936 : *q_band_energies = add( *q_band_energies, exp );
626 1192936 : move16();
627 :
628 1192936 : *q_Bin_E_old = *q_Bin_E;
629 1192936 : move16();
630 :
631 :
632 : /* Per-bin log-energy spectrum */
633 1192936 : Bin_E[L_FFT / 2 - 1] = Bin_E[L_FFT / 2 - 2]; // *q_Bin_E
634 1192936 : move32();
635 1192936 : Bin_E[L_FFT - 1] = Bin_E[L_FFT - 2]; // *q_Bin_E
636 1192936 : move32();
637 1192936 : Word32 add_const = 21475; // 1e-5 in Q31
638 153888744 : FOR( i = 0; i < L_FFT / 2; i++ )
639 : {
640 152695808 : Bin_E_old[i] = Bin_E[i]; // *q_Bin_E
641 152695808 : move32();
642 :
643 : /* PS[i] = ( Bin_E[i] + 1e-5f + Bin_E[i + L_FFT / 2] + 1e-5f ) / 2.0f; */
644 152695808 : 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
645 152695808 : move32();
646 :
647 : /* Bin_E[i] = (float) ( 10.0f * log( PS[i] ) ); */
648 152695808 : IF( EspecdB != NULL )
649 : {
650 144512000 : EspecdB[i] = -14736; /* ln(1e-5) in Q7 */
651 144512000 : move16();
652 : }
653 :
654 152695808 : Bin_E[i] = -482887093; /* ln(1e-5) in Q22 */
655 152695808 : move32();
656 :
657 152695808 : IF( GT_32( PS[i], L_shl_sat( 21475, sub( *q_Bin_E, Q31 ) ) ) /*1e - 5 in *q_bin_E */ )
658 : {
659 143218026 : Ltmp = L_add( BASOP_Util_Log2( PS[i] ), L_shl( sub( Q31, *q_Bin_E ), Q25 ) );
660 143218026 : Bin_E[i] = Mpy_32_32( Ltmp, 1860652798 /*10.0*logf(2) in Q28 */ ); // Q22
661 143218026 : move32();
662 :
663 143218026 : tmp = extract_h( L_shl( Bin_E[i], Q23 - Q22 ) ); // Q7
664 143218026 : if ( EspecdB != NULL )
665 : {
666 135034224 : EspecdB[i] = tmp; // Q7
667 135034224 : move16();
668 : }
669 : }
670 : }
671 :
672 1192936 : if ( q_PS != NULL )
673 : {
674 1129000 : *q_PS = *q_Bin_E;
675 1129000 : move16();
676 : }
677 :
678 1192936 : exp = L_norm_arr( Bin_E, L_FFT / 2 );
679 1192936 : exp2 = L_norm_arr( Bin_E + L_FFT / 2, L_FFT / 2 );
680 1192936 : resultant_q = s_min( Q22, s_min( add( *q_Bin_E, exp2 ), add( exp, Q22 ) ) ); // calculating resultant q after scaling
681 1192936 : scale_sig32( Bin_E, L_FFT / 2, sub( resultant_q, Q22 ) ); // Q22=>resultant_q
682 1192936 : scale_sig32( Bin_E + L_FFT / 2, L_FFT / 2, sub( resultant_q, *q_Bin_E ) ); // q_Bin_E=>resultant_q
683 1192936 : *q_Bin_E = resultant_q;
684 1192936 : move16();
685 :
686 1192936 : return;
687 : }
688 :
689 : /*------------------------------------------------------------------------*
690 : * find_enr()
691 : *
692 : * find input signal energy for each critical band and first 74 LF bins
693 : * The energy is normalized by the number of frequency bins in a channel
694 : *------------------------------------------------------------------------*/
695 :
696 : /* Merge with ivas_find_enr function once analy_sp is unified */
697 2118790 : static void ivas_find_enr(
698 : Word16 data[], /* i : fft result */
699 : Word16 q_data, /* i : Q of fft result */
700 : Word32 band[], /* o : per band energy q_band */
701 : Word16 *q_band, /* o : Q of per band energy */
702 : Word32 *ptE, /* o : per bin energy for low frequencies q_ptE */
703 : Word16 *q_ptE, /* o : Q of per bin energy for low frequencies Q0 */
704 : Word64 *LEtot, /* o : total energy q_band+1 */
705 : const Word16 min_band, /* i : minimum critical band Q0 */
706 : const Word16 max_band, /* i : maximum critical band Q0 */
707 : Word32 *Bin_E, /* o : Per bin energy q_ptE */
708 : Word16 BIN_FREQ_FX, /* i : Number of frequency bins Q0 */
709 : Word32 *band_energies /* o : per band energy without MODE2_E_MIN q_band */
710 : )
711 : {
712 : Word16 i;
713 : Word16 freq;
714 : Word16 *ptR, *ptI;
715 : Word16 voic_band;
716 : Word64 etot, band_ener;
717 : Word16 start_freq;
718 : Word32 min_ener;
719 2118790 : Word16 shift = 0;
720 2118790 : move16();
721 :
722 2118790 : ptR = &data[1]; /* first real */
723 2118790 : ptI = &data[L_FFT - 1]; /* first imaginary */
724 :
725 2118790 : voic_band = VOIC_BAND_8k;
726 2118790 : move16();
727 : assert( VOIC_BAND == VOIC_BAND_8k );
728 :
729 : /*-----------------------------------------------------------------*
730 : * For low frequency bins, save per bin energy for the use
731 : * in NS and find_tilt()
732 : *-----------------------------------------------------------------*/
733 :
734 2118790 : *q_ptE = add( shl( q_data, 1 ), 14 );
735 2118790 : move16();
736 2118790 : *q_band = add( shl( q_data, 1 ), 14 );
737 2118790 : move16();
738 :
739 2118790 : IF( GT_16( *q_band, 39 ) )
740 : {
741 2134 : shift = sub( *q_band, 39 );
742 2134 : *q_band = 39;
743 2134 : move16();
744 : }
745 :
746 2118790 : min_ener = L_shl( E_MIN_FXQ31, sub( *q_band, Q31 ) ); // *q_band
747 :
748 2118790 : freq = BIN_FREQ_FX;
749 2118790 : move16();
750 38138220 : FOR( i = 0; i < voic_band; i++ ) /* up to maximum allowed voiced critical band */
751 : {
752 36019430 : band_ener = 0;
753 36019430 : move64();
754 36019430 : start_freq = freq;
755 36019430 : move16();
756 192809890 : WHILE( LE_32( freq, crit_bands_fx[i] ) )
757 : {
758 : /*
759 : *ptE = *ptR * *ptR + *ptI * *ptI;
760 :
761 : Overflow occurs in the above operation only when ptR and ptI values are equal to -32768.
762 : In that case, energy value will be 2^31 (only one greater than max 32 bit value).
763 : Hence, saturation is added.
764 :
765 : *ptE *= norm_val;
766 : norm_val = 4 / (256 * 256), As the value is in power's of 2, result can be obtained by increasing the Q factor
767 :
768 : Q of energy = 2 * q_data + 14 = *q_ptE
769 : */
770 :
771 156790460 : *ptE = L_mac0_sat( L_mult0( *ptR, *ptR ), *ptI, *ptI ); // *q_ptE
772 156790460 : move32();
773 :
774 156790460 : *Bin_E++ = *ptE; // *q_ptE
775 156790460 : move32();
776 :
777 : /*
778 : BIN_FREQ_FX = BIN, cnt = ( ( crit_bands_fx[i] - start_freq ) / BIN ) + 1
779 : band[i] += *ptE++;
780 : band[i] *= inv_tbl[cnt]; // normalization per frequency bin
781 : */
782 156790460 : band_ener = W_mac_32_16( band_ener, *ptE, inv_tbl_fx[( ( crit_bands_fx[i] - start_freq ) / BIN ) + 1] ); // *q_band+16+shift
783 156790460 : ptR++;
784 156790460 : ptI--;
785 156790460 : ptE++;
786 156790460 : freq = add( freq, BIN_FREQ_FX );
787 : }
788 :
789 36019430 : band[i] = W_extract_h( W_shl( band_ener, sub( Q16, shift ) ) ); // *q_band
790 36019430 : move32();
791 :
792 36019430 : band_energies[i] = band[i]; /* per band energy without E_MIN */ // *q_band
793 36019430 : move32();
794 :
795 36019430 : if ( LT_32( band[i], min_ener ) ) // *q_band
796 : {
797 1946459 : band[i] = min_ener; // *q_band
798 1946459 : move32();
799 : }
800 : }
801 :
802 2118790 : IF( EQ_16( BIN_FREQ_FX, 50 ) )
803 : {
804 : /*-----------------------------------------------------------------*
805 : * Continue compute the E per critical band for high frequencies
806 : *-----------------------------------------------------------------*/
807 :
808 8475160 : FOR( i = voic_band; i < NB_BANDS; i++ )
809 : {
810 6356370 : band_ener = 0;
811 6356370 : move64();
812 6356370 : start_freq = freq;
813 6356370 : move16();
814 118652240 : WHILE( LE_32( freq, crit_bands_fx[i] ) )
815 : {
816 : /*
817 : *Bin_E = *ptR * *ptR + *ptI * *ptI;
818 :
819 : Overflow occurs in the below operation only when ptR and ptI values are equal to - 32768.
820 : In that case, energy value will be 2 ^ 31 (only one greater than max 32 bit value).
821 : Hence, saturation is added.
822 :
823 : *Bin_E *= norm_val;
824 : norm_val = 4 / (256 * 256), As the value is in power's of 2, result can be obtained by increasing the Q factor
825 :
826 : Q of energy = 2 * q_data + 14 = *q_ptE
827 : */
828 :
829 112295870 : *Bin_E = L_mac0_sat( L_mult0( *ptR, *ptR ), *ptI, *ptI ); // 2*q_data+14 = *q_ptE
830 112295870 : move32();
831 :
832 : /*
833 : BIN_FREQ_FX = BIN, cnt = ( ( crit_bands_fx[i] - start_freq ) / BIN ) + 1
834 : band[i] += *ptE++;
835 : band[i] *= inv_tbl[cnt]; // normalization per frequency bin
836 : */
837 112295870 : 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
838 112295870 : ptR++;
839 112295870 : ptI--;
840 112295870 : Bin_E++;
841 :
842 112295870 : freq = add( freq, BIN_FREQ_FX );
843 : }
844 :
845 6356370 : band[i] = W_extract_h( W_shl_nosat( band_ener, sub( Q16, shift ) ) ); // *q_band
846 6356370 : move32();
847 :
848 6356370 : band_energies[i] = band[i]; /* per band energy without E_MIN */ // *q_band
849 6356370 : move32();
850 :
851 6356370 : if ( LT_32( band[i], min_ener ) ) // *q_band
852 : {
853 363001 : band[i] = min_ener; // *q_band
854 363001 : move32();
855 : }
856 : }
857 : }
858 :
859 : /*-----------------------------------------------------------------*
860 : * Find the total energy over the input bandwidth
861 : *-----------------------------------------------------------------*/
862 :
863 2118790 : etot = *LEtot; // *q_band
864 2118790 : move64();
865 44464654 : FOR( i = min_band; i <= max_band; i++ )
866 : {
867 42345864 : etot = W_mac_32_32( etot, band[i], 1 ); // *q_band+1
868 : }
869 2118790 : *LEtot = etot; // *q_band+1
870 2118790 : move64();
871 :
872 2118790 : return;
873 : }
874 :
875 6200 : static void find_enr(
876 : Word16 data[], /* i : fft result */
877 : Word32 band[], /* o : per band energy Q_new + QSCALE */
878 : Word32 *ptE, /* o : per bin energy for low frequencies Q_new + QSCALE-2 */
879 : Word32 *LEtot, /* o : total energy Q_new + QSCALE */
880 : const Word16 min_band, /* i : minimum critical band Q0 */
881 : const Word16 max_band, /* i : maximum critical band Q0 */
882 : const Word16 Q_new2, /* i : scaling factor Q0 */
883 : const Word32 e_min, /* i : minimum energy scaled Q_new + QSCALE */
884 : Word32 *Bin_E, /* o : Per bin energy Q_new + QSCALE-2 */
885 : Word16 BIN_FREQ_FX, /* i : Number of frequency bins Q0 */
886 : Word32 *band_energies /* o : per band energy without MODE2_E_MIN */
887 : )
888 : {
889 : Word16 i, cnt, shift_to_norm;
890 : Word16 freq, wtmp;
891 : Word16 *ptR, *ptI, diff_scaleP1, diff_scaleM2;
892 : Word16 exp_band;
893 : Word32 Ltmp, Ltmp1;
894 : Word16 voic_band;
895 : Word32 etot;
896 : Word16 exp_etot;
897 : Word32 *tmpptr;
898 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
899 6200 : Flag Overflow = 0;
900 6200 : move32();
901 : #endif
902 :
903 :
904 6200 : ptR = &data[1]; /* first real */
905 6200 : ptI = &data[L_FFT - 1]; /* first imaginary */
906 :
907 : /*-----------------------------------------------------------------------------------*
908 : * Scaling needed by band and ptE output
909 : * Wants all energies scaled by Q_new + QSCALE to maintain maximum
910 : * precision on bckr noise in clean speech
911 : * First shift left by Q_new + QSCALE than shift right by 2*Q_new-1
912 : * shift left (Q_new + QSCALE - (2*Q_new -1))
913 : * shift left (QSCALE - Q_new + 1) == shift left by (QSCALE+1) - Q_new
914 : *-----------------------------------------------------------------------------------*/
915 :
916 6200 : diff_scaleP1 = sub( QSCALE + 1 + 1, Q_new2 );
917 6200 : diff_scaleM2 = sub( QSCALE + 1 - 2, Q_new2 );
918 :
919 6200 : voic_band = VOIC_BAND_8k;
920 6200 : move16();
921 : assert( VOIC_BAND == VOIC_BAND_8k );
922 :
923 6200 : etot = L_deposit_l( 0 );
924 6200 : exp_etot = 0;
925 6200 : move16();
926 :
927 : /*-----------------------------------------------------------------*
928 : * For low frequency bins, save per bin energy for the use
929 : * in NS and find_tilt()
930 : *-----------------------------------------------------------------*/
931 :
932 6200 : freq = BIN_FREQ_FX;
933 6200 : move16();
934 111600 : FOR( i = 0; i < voic_band; i++ ) /* up to maximum allowed voiced critical band */
935 : {
936 105400 : tmpptr = Bin_E; /* Q_new + QSCALE - 2 */
937 105400 : move16();
938 105400 : Ltmp1 = L_deposit_l( 0 );
939 :
940 564200 : FOR( ; LE_32( freq, crit_bands_fx[i] ); freq += BIN_FREQ_FX )
941 : {
942 : /*ptE = *ptR * *ptR + *ptI * *ptI */ /* energy */
943 458800 : Ltmp = L_mult( *ptI, *ptI );
944 458800 : Ltmp = L_mac( Ltmp, *ptR, *ptR );
945 :
946 : /* *ptE *= 4.0 / (L_FFT*L_FFT) */
947 : /* normalization - corresponds to FFT normalization by 2/L_FFT */
948 : BASOP_SATURATE_WARNING_OFF_EVS; /* saturation seems to have no effect (tested by simulation) */
949 458800 : *ptE = L_shl_o( Ltmp, diff_scaleM2, &Overflow ); /* Q_new + QSCALE - 2 */
950 458800 : move32(); /* scaled by Q_new + QSCALE - 2 */
951 : BASOP_SATURATE_WARNING_ON_EVS;
952 : /*band[i] += *ptE++;*/
953 458800 : *Bin_E = *ptE;
954 458800 : move32();
955 458800 : Bin_E++;
956 458800 : Ltmp1 = L_add( Ltmp1, Ltmp );
957 :
958 458800 : ptE++;
959 458800 : ptR++;
960 458800 : ptI--;
961 : }
962 :
963 105400 : exp_band = sub( norm_l( Ltmp1 ), 1 ); /* divide by 2 to ensure band < cnt */
964 105400 : wtmp = round_fx( L_shl( Ltmp1, exp_band ) );
965 :
966 : /* band[i] /= cnt */ /* normalization per frequency bin */
967 105400 : cnt = (Word16) ( Bin_E - tmpptr );
968 105400 : shift_to_norm = norm_s( cnt );
969 105400 : wtmp = div_s( wtmp, shl( cnt, shift_to_norm ) ); /* Q15 */
970 105400 : Ltmp1 = L_deposit_l( wtmp ); /* Q15 */
971 :
972 105400 : exp_band = sub( exp_band, shift_to_norm );
973 105400 : exp_band = sub( diff_scaleP1, exp_band );
974 : BASOP_SATURATE_WARNING_OFF_EVS; /* saturation seems to have no effect (tested by simulation) */
975 105400 : band[i] = L_shl_o( Ltmp1, exp_band, &Overflow ); /* Q15 + exp_band */
976 105400 : move32(); /* band scaled by Q_new + QSCALE */
977 : BASOP_SATURATE_WARNING_ON_EVS;
978 :
979 105400 : test();
980 105400 : IF( GE_16( i, min_band ) && LE_16( i, max_band ) )
981 : {
982 105400 : IF( LT_32( band[i], e_min ) )
983 : {
984 1360 : Ltmp1 = L_shl( e_min, 0 );
985 1360 : exp_band = 0;
986 1360 : move16();
987 : }
988 :
989 105400 : wtmp = sub( exp_band, exp_etot );
990 105400 : if ( wtmp > 0 )
991 : {
992 15770 : etot = L_shr( etot, wtmp );
993 : }
994 105400 : exp_etot = s_max( exp_etot, exp_band );
995 105400 : etot = L_add( etot, L_shl( Ltmp1, sub( exp_band, exp_etot ) ) );
996 : }
997 :
998 105400 : band_energies[i] = band[i]; /* Q_new + QSCALE */
999 105400 : move32();
1000 :
1001 105400 : band[i] = L_max( band[i], e_min );
1002 105400 : move32();
1003 : }
1004 :
1005 6200 : IF( EQ_16( BIN_FREQ_FX, 50 ) )
1006 : {
1007 : /*-----------------------------------------------------------------*
1008 : * Continue compute the E per critical band for high frequencies
1009 : *-----------------------------------------------------------------*/
1010 :
1011 24800 : FOR( i = voic_band; i < NB_BANDS; i++ )
1012 : {
1013 18600 : tmpptr = Bin_E;
1014 18600 : move16();
1015 18600 : Ltmp1 = L_deposit_l( 0 );
1016 :
1017 347200 : FOR( ; LE_32( freq, crit_bands_fx[i] ); freq += BIN_FREQ_FX )
1018 : {
1019 : /* *ptE = *ptR * *ptR + *ptI * *ptI */
1020 328600 : Ltmp = L_mult( *ptI, *ptI );
1021 328600 : Ltmp = L_mac( Ltmp, *ptR, *ptR );
1022 :
1023 : /* *ptE *= 4.0 / (L_FFT*L_FFT) */
1024 : /* normalization - corresponds to FFT normalization by 2/L_FFT */
1025 : BASOP_SATURATE_WARNING_OFF_EVS; /* saturation seems to have no effect (tested by simulation) */
1026 328600 : *Bin_E = L_shl_o( Ltmp, diff_scaleM2, &Overflow ); /* Q_new + QSCALE */
1027 328600 : move32(); /* scaled by Q_new + QSCALE - 2 */
1028 : BASOP_SATURATE_WARNING_ON_EVS;
1029 328600 : Bin_E++;
1030 328600 : Ltmp1 = L_add( Ltmp1, Ltmp );
1031 :
1032 328600 : ptR++;
1033 328600 : ptI--;
1034 : }
1035 :
1036 18600 : exp_band = sub( norm_l( Ltmp1 ), 1 ); /* divide by 2 to ensure band < cnt */
1037 18600 : wtmp = round_fx( L_shl( Ltmp1, exp_band ) );
1038 :
1039 : /* band[i] /= cnt */ /* normalization per frequency bin */
1040 18600 : cnt = (Word16) ( Bin_E - tmpptr );
1041 18600 : shift_to_norm = norm_s( cnt );
1042 18600 : wtmp = div_s( wtmp, shl( cnt, shift_to_norm ) );
1043 18600 : Ltmp1 = L_deposit_l( wtmp );
1044 :
1045 18600 : exp_band = sub( exp_band, shift_to_norm );
1046 18600 : exp_band = sub( diff_scaleP1, exp_band );
1047 : BASOP_SATURATE_WARNING_OFF_EVS; /* saturation seems to have no effect (tested by simulation) */
1048 18600 : band[i] = L_shl_o( Ltmp1, exp_band, &Overflow );
1049 18600 : move32(); /* band scaled by Q_new + QSCALE */
1050 : BASOP_SATURATE_WARNING_ON_EVS;
1051 :
1052 18600 : test();
1053 18600 : IF( GE_16( i, min_band ) && LE_16( i, max_band ) )
1054 : {
1055 18600 : IF( LT_32( band[i], e_min ) )
1056 : {
1057 39 : Ltmp1 = L_shl( e_min, 0 );
1058 39 : exp_band = 0;
1059 39 : move16();
1060 : }
1061 :
1062 18600 : wtmp = sub( exp_band, exp_etot );
1063 18600 : if ( wtmp > 0 )
1064 : {
1065 468 : etot = L_shr( etot, wtmp );
1066 : }
1067 18600 : exp_etot = s_max( exp_etot, exp_band );
1068 :
1069 18600 : etot = L_add( etot, L_shl( Ltmp1, sub( exp_band, exp_etot ) ) );
1070 : }
1071 :
1072 18600 : band_energies[i] = band[i];
1073 18600 : move32();
1074 :
1075 18600 : band[i] = L_max( band[i], e_min );
1076 18600 : move32();
1077 : }
1078 : }
1079 :
1080 : /*-----------------------------------------------------------------*
1081 : * Find the total energy over the input bandwidth
1082 : *-----------------------------------------------------------------*/
1083 :
1084 6200 : etot = L_add_sat( *LEtot, L_shl_sat( etot, sub( exp_etot, 4 ) ) );
1085 6200 : *LEtot = etot;
1086 6200 : move32();
1087 :
1088 :
1089 6200 : return;
1090 : }
|