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 : }
|