Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 : #include <stdint.h>
5 : #include "options.h" /* Compilation switches */
6 : #include "cnst.h" /* Common constants */
7 : #include "rom_enc.h" /* Encoder static table prototypes */
8 : #include "rom_com_fx.h" /* Encoder static table prototypes */
9 : #include "rom_com.h" /* Encoder static table prototypes */
10 : #include "rom_dec.h"
11 : //#include "prot_fx.h" /* Function prototypes */
12 : #include "prot_fx.h" /* Function prototypes */
13 : #include "prot_fx_enc.h" /* Function prototypes */
14 :
15 : /*-------------------------------------------------------------------*
16 : * Local constants
17 : *-------------------------------------------------------------------*/
18 :
19 : #define MAX_DELTA 16 /* half-length of the delta search */
20 : #define COR_BUF_LEN ( L_INTERPOL1 * 2 + MAX_DELTA * 2 + 1 )
21 :
22 : /*-------------------------------------------------------------------*
23 : * pitch_ol2()
24 : *
25 : * Open-loop pitch precision improvement with 1/4 resolution
26 : * The pitch is searched in the interval <pitch_ol-delta, pitch_ol+delta),
27 : * i.e. the value pitch_ol + delta is not a part of the interval
28 : *-------------------------------------------------------------------*/
29 1185104 : void pitch_ol2_fx(
30 : const Word16 pit_min, /* i : minimum pitch value (20 or 29) */
31 : const Word16 pitch_ol, /* i : pitch to be improved */
32 : Word16 *pitch_fr_fx,
33 : /* o : adjusted 1/4 fractional pitch */ /*Q7*/
34 : Word16 *voicing_fr_fx,
35 : /* o : adjusted 1/4 fractional voicing */ /*Q15*/
36 : const Word16 pos, /* i : position in frame where to calculate the improv. */
37 : const Word16 *wsp_fx,
38 : /* i : weighted speech for current frame and look-ahead */ /*Q_new-1+shift*/
39 : const Word16 delta, /* i : delta for pitch search (2 or 7) */
40 : const Word16 element_mode /* i : EVS or IVAS */
41 : )
42 : {
43 : Word16 i, t, step, fraction, t0_min, t0_max, t_min, t_max;
44 : const Word16 *pt_wsp_fx;
45 : Word16 wsp_fr_fx[L_SUBFR];
46 : Word16 temp_fx, cor_max_fx, cor_fx[COR_BUF_LEN], *pt_cor_fx;
47 : Word32 cor_32[COR_BUF_LEN], *pt_cor_32, t0, t1;
48 : Word16 t0s, t1s;
49 : Word16 exp3;
50 : Word32 R1, R2;
51 : Word16 R0, exp_R0, exp_R1, exp_R2, j;
52 : Word16 pit_max;
53 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
54 1185104 : Flag Overflow = 0;
55 1185104 : move32();
56 : #endif
57 :
58 : /* initialization */
59 1185104 : pit_max = PIT_MAX;
60 1185104 : move16();
61 1185104 : t0_min = sub( pitch_ol, delta );
62 1185104 : t0_max = add( pitch_ol, sub( delta, 1 ) );
63 1185104 : t0_min = s_max( t0_min, pit_min );
64 1185104 : t_min = sub( t0_min, L_INTERPOL1 );
65 :
66 1185104 : t0_max = s_min( t0_max, pit_max );
67 1185104 : t_max = add( t0_max, L_INTERPOL1 );
68 :
69 1185104 : pt_wsp_fx = wsp_fx + pos;
70 1185104 : pt_cor_32 = cor_32;
71 1185104 : t1 = L_deposit_l( 0 );
72 26646596 : FOR( t = t_min; t <= t_max; t++ )
73 : {
74 25461492 : t0 = Dot_product( pt_wsp_fx, pt_wsp_fx - t, L_SUBFR );
75 25461492 : *pt_cor_32++ = t0;
76 25461492 : move32();
77 25461492 : t0 = L_abs( t0 );
78 25461492 : t1 = L_max( t1, t0 );
79 : }
80 1185104 : exp3 = norm_l( t1 );
81 1185104 : pt_cor_32 = cor_32;
82 1185104 : pt_cor_fx = cor_fx;
83 26646596 : FOR( t = t_min; t <= t_max; t++ )
84 : {
85 25461492 : t0 = L_shl_o( *pt_cor_32++, exp3, &Overflow );
86 25461492 : *pt_cor_fx++ = round_fx_o( t0, &Overflow );
87 25461492 : move16();
88 : }
89 :
90 1185104 : pt_cor_fx = cor_fx + L_INTERPOL1;
91 1185104 : cor_max_fx = *pt_cor_fx++;
92 1185104 : move16();
93 1185104 : t1s = t0_min;
94 1185104 : move16();
95 15980660 : FOR( t = t0_min + 1; t <= t0_max; t++ )
96 : {
97 14795556 : if ( GT_16( *pt_cor_fx, cor_max_fx ) )
98 : {
99 5882666 : t1s = t;
100 5882666 : move16();
101 : }
102 14795556 : cor_max_fx = s_max( cor_max_fx, *pt_cor_fx );
103 14795556 : pt_cor_fx++;
104 : }
105 :
106 : /*----------------------------------------------------------------*
107 : * Search fractionnal pitch with 1/4 subsample resolution.
108 : * search the fractions around t0 and choose the one which maximizes
109 : * the interpolated normalized correlation.
110 : *----------------------------------------------------------------*/
111 1185104 : pt_cor_fx = cor_fx + sub( L_INTERPOL1, t0_min );
112 1185104 : t0s = t1s;
113 1185104 : move16();
114 :
115 1185104 : step = 1;
116 1185104 : move16(); /* 1/4 subsample resolution */
117 1185104 : fraction = 1;
118 1185104 : move16();
119 :
120 1185104 : IF( NE_16( t0s, t0_min ) ) /* Process negative fractions */
121 : {
122 1086410 : t0s = sub( t0s, 1 );
123 1086410 : cor_max_fx = Interpol_4( &pt_cor_fx[t0s], fraction );
124 3259230 : FOR( i = fraction + step; i <= 3; i += step )
125 : {
126 2172820 : temp_fx = Interpol_4( &pt_cor_fx[t0s], i );
127 2172820 : if ( GT_16( temp_fx, cor_max_fx ) )
128 : {
129 2034158 : fraction = i;
130 2034158 : move16();
131 : }
132 2172820 : cor_max_fx = s_max( temp_fx, cor_max_fx );
133 : }
134 : }
135 : ELSE /* Limit case */
136 : {
137 98694 : fraction = 0;
138 98694 : move16();
139 98694 : cor_max_fx = Interpol_4( &pt_cor_fx[t0s], fraction );
140 98694 : move16();
141 : }
142 5925520 : FOR( i = 0; i <= 3; i += step ) /* Process positive fractions */
143 : {
144 4740416 : temp_fx = Interpol_4( &pt_cor_fx[t1s], i );
145 :
146 4740416 : IF( GT_16( temp_fx, cor_max_fx ) )
147 : {
148 1377363 : cor_max_fx = temp_fx;
149 1377363 : move16();
150 1377363 : fraction = i;
151 1377363 : move16();
152 1377363 : t0s = t1s;
153 1377363 : move16();
154 : }
155 : }
156 :
157 1185104 : *pitch_fr_fx = shl( add( shl( t0s, 2 ), fraction ), 4 );
158 1185104 : move16(); /*Q7*/
159 :
160 1185104 : IF( NE_32( t1, 1L ) )
161 : {
162 1169674 : IF( element_mode != EVS_MONO )
163 : {
164 1161280 : pred_lt4_ivas_fx( pt_wsp_fx, wsp_fr_fx, t0s, fraction, L_SUBFR, L_pitch_inter4_1, 4, PIT_UP_SAMP );
165 : }
166 : ELSE
167 : {
168 8394 : pred_lt4( pt_wsp_fx, wsp_fr_fx, t0s, fraction, L_SUBFR, pitch_inter4_1, 4, PIT_UP_SAMP );
169 : }
170 :
171 1169674 : R0 = cor_max_fx;
172 1169674 : move16();
173 1169674 : R1 = L_mult( pt_wsp_fx[0], pt_wsp_fx[0] );
174 1169674 : R2 = L_mult( wsp_fr_fx[0], wsp_fr_fx[0] );
175 74859136 : FOR( j = 1; j < L_SUBFR; j++ )
176 : {
177 73689462 : R1 = L_mac_sat( R1, pt_wsp_fx[j], pt_wsp_fx[j] );
178 73689462 : R2 = L_mac_sat( R2, wsp_fr_fx[j], wsp_fr_fx[j] );
179 : }
180 :
181 : /* *voicing_fr = cor_max * inv_sqrt(enr_wsp * enr_old) */
182 : /* *voicing_fr = R0 * inv_sqrt(R1 * R2) */
183 1169674 : exp_R0 = norm_s( R0 );
184 1169674 : R0 = shl( R0, exp_R0 );
185 :
186 1169674 : exp_R1 = norm_l( R1 );
187 1169674 : R1 = L_shl( R1, exp_R1 );
188 :
189 1169674 : exp_R2 = norm_l( R2 );
190 1169674 : R2 = L_shl( R2, exp_R2 );
191 :
192 1169674 : R1 = L_mult_o( round_fx_o( R1, &Overflow ), round_fx_o( R2, &Overflow ), &Overflow );
193 1169674 : i = norm_l( R1 );
194 1169674 : R1 = L_shl( R1, i );
195 :
196 1169674 : exp_R1 = add( exp_R1, exp_R2 );
197 1169674 : exp_R1 = add( exp_R1, i );
198 1169674 : exp_R1 = sub( 62, exp_R1 );
199 :
200 1169674 : R1 = Isqrt_lc( R1, &exp_R1 );
201 :
202 1169674 : R1 = L_mult( R0, round_fx_o( R1, &Overflow ) );
203 1169674 : exp_R0 = sub( 31, exp_R0 );
204 1169674 : exp_R0 = sub( add( exp_R0, exp_R1 ), exp3 );
205 :
206 1169674 : *voicing_fr_fx = round_fx_o( L_shl_o( R1, exp_R0, &Overflow ), &Overflow ); /*Q15*/
207 1169674 : move16();
208 : }
209 : ELSE
210 : {
211 15430 : *voicing_fr_fx = 0;
212 15430 : move16();
213 : }
214 :
215 1185104 : return;
216 : }
217 :
218 : /*-------------------------------------------------------------------*
219 : * StableHighPitchDetect()
220 : *
221 : * stable very short pitch detection
222 : *-------------------------------------------------------------------*/
223 3100 : void StableHighPitchDetect_fx(
224 : Word16 *flag_spitch, /* o : flag to indicate very short stable pitch */
225 : Word16 pitch[], /* i/o: OL pitch buffer */
226 : const Word16 voicing[], /* i : OL pitch gains */
227 : const Word16 wsp[], /* i : weighted speech */
228 : const Word16 localVAD, /* i : local VAD flag */
229 : Word16 *voicing_sm, /* i/o: smoothed open-loop pitch gains */
230 : Word16 *voicing0_sm, /* i/o: smoothed high pitch gains */
231 : Word16 *LF_EnergyRatio_sm, /* i/o: smoothed [0, 300Hz] relative peak energy*/
232 : Word16 *predecision_flag, /* i/o: predecision flag */
233 : Word32 *diff_sm, /* i/o: smoothed pitch frequency difference */
234 : Word32 *energy_sm, /* i/o: smoothed energy around pitch frequency */
235 : Word16 Q_new,
236 : Word16 EspecdB[] )
237 : {
238 : Word16 i, pitch_freq_point;
239 : Word16 T, Tp, pit_min;
240 : Word16 energy0_16, energy1_16, ratio, voicing_m;
241 : Word32 energy0, energy1, cor_max, diff, sum_energy;
242 : const Word16 *pt_wsp;
243 : Word16 tmp, tmp1, exp, diff16, cor_max16, exp1, exp2, pit_min_up;
244 : Word32 L_tmp, L_tmp1;
245 : Word16 Top;
246 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
247 3100 : Flag Overflow = 0;
248 3100 : move32();
249 : #endif
250 :
251 : /*voicing = (voicing[0] + voicing[1] + voicing[2] )/3;*/
252 3100 : L_tmp = L_mult( voicing[0], 10923 /*1/3 in Q15*/ );
253 3100 : L_tmp = L_mac( L_tmp, voicing[1], 10923 /*1/3 in Q15*/ );
254 3100 : L_tmp = L_mac( L_tmp, voicing[2], 10923 /*1/3 in Q15*/ );
255 3100 : voicing_m = round_fx_sat( L_tmp );
256 : /**voicing_sm = 0.75f*(*voicing_sm) + 0.25f*voicing;*/
257 3100 : *voicing_sm = round_fx( L_mac( L_mult( *voicing_sm, 24576 /*0.75f Q15*/ ), voicing_m, 8192 /*0.25f Q15*/ ) );
258 3100 : move16();
259 : /* pitch_freq_point = (short)(L_FFT/(mult_fact*T_op[1])+0.5f);*/
260 3100 : Top = pitch[1];
261 3100 : move16();
262 3100 : exp = norm_s( Top );
263 3100 : tmp = div_s( shl( 1, sub( 14, exp ) ), Top ); /*Q(29 - exp)*/
264 3100 : L_tmp = L_mult0( tmp, L_FFT ); /*Q(29 - exp)*/
265 3100 : pitch_freq_point = extract_h( L_add( L_shl( L_tmp, sub( exp, 13 ) ), 32768 ) ); /* Q0*/
266 3100 : diff = L_deposit_l( 0 );
267 3100 : sum_energy = L_deposit_l( 0 );
268 29228 : FOR( i = 1; i < 2 * pitch_freq_point; i++ )
269 : {
270 26128 : diff = L_add( diff, sub( EspecdB[pitch_freq_point], EspecdB[i] ) );
271 26128 : sum_energy = L_add( sum_energy, EspecdB[i] );
272 : }
273 : /*sum_energy /= (2*pitch_freq_point-1);*/
274 3100 : tmp = sub( shl( pitch_freq_point, 1 ), 1 );
275 3100 : exp = norm_s( tmp );
276 3100 : tmp1 = div_s( shl( 1, sub( 14, exp ) ), tmp ); /*Q(29-exp)*/
277 3100 : L_tmp = Mult_32_16( sum_energy, tmp1 );
278 3100 : sum_energy = L_shl( L_tmp, sub( exp, 14 ) );
279 : /**diff_sm = 0.2f * diff + 0.8f * *diff_sm;*/
280 3100 : *diff_sm = L_add( Mult_32_16( diff, 6554 ), Mult_32_16( *diff_sm, 26214 ) );
281 3100 : move32();
282 : /**energy_sm = 0.2f * sum_energy + 0.8f * *energy_sm;*/
283 3100 : *energy_sm = L_add( Mult_32_16( sum_energy, 6554 ), Mult_32_16( *energy_sm, 26214 ) );
284 3100 : move32();
285 : /*diff /= sum_energy;*/
286 :
287 3100 : IF( sum_energy )
288 : {
289 3100 : exp = norm_l( sum_energy );
290 3100 : tmp = extract_h( L_shl( sum_energy, exp ) );
291 3100 : exp = sub( sub( 30, exp ), 7 );
292 3100 : IF( tmp < 0 )
293 : {
294 187 : tmp = abs_s( tmp );
295 187 : tmp = div_s( 16384, tmp ); /*Q(15+exp)*/
296 : BASOP_SATURATE_WARNING_OFF_EVS
297 187 : diff = L_negate( L_shr_o( Mult_32_16( diff, tmp ), sub( exp + 7, 31 ), &Overflow ) );
298 : BASOP_SATURATE_WARNING_ON_EVS
299 187 : diff16 = round_fx_o( diff, &Overflow );
300 : }
301 : ELSE
302 : {
303 2913 : tmp = div_s( 16384, tmp ); /*Q(15+exp)*/
304 : BASOP_SATURATE_WARNING_OFF_EVS
305 2913 : diff = L_shr_o( Mult_32_16( diff, tmp ), sub( exp + 7, 31 ), &Overflow );
306 : BASOP_SATURATE_WARNING_ON_EVS
307 2913 : diff16 = round_fx_o( diff, &Overflow );
308 : }
309 : }
310 : ELSE
311 : {
312 0 : diff16 = round_fx_o( L_shl_o( diff, 25, &Overflow ), &Overflow );
313 : }
314 3100 : test();
315 3100 : test();
316 3100 : if ( LT_32( *diff_sm, -1280 /*-10.0f Q7*/ ) && LT_32( *energy_sm, 4928 /*38.5f Q7*/ ) && LT_16( diff16, -26214 /*-.8f Q15*/ ) )
317 : {
318 155 : *predecision_flag = 1;
319 155 : move16();
320 : }
321 3100 : test();
322 3100 : test();
323 3100 : if ( GT_32( *diff_sm, 1280 /*10.0f Q7*/ ) && GT_32( *energy_sm, 10624 /*83.0f Q7*/ ) && GT_16( diff16, 16384 /*.5 Q15*/ ) )
324 : {
325 140 : *predecision_flag = 0;
326 140 : move16();
327 : }
328 :
329 : /* short pitch possiblity pre-decision */
330 3100 : maximum_fx( EspecdB, 7, &energy0_16 );
331 3100 : maximum_fx( EspecdB + 8, 7, &energy1_16 );
332 3100 : ratio = s_max( sub( energy1_16, energy0_16 ), 0 ); /*Q7 */
333 : /*ratio *= max(voicing,0);*/
334 3100 : tmp = s_max( voicing_m, 0 );
335 3100 : ratio = mult_r( ratio, tmp ); /*Q7*/
336 : /**LF_EnergyRatio_sm = (15*(*LF_EnergyRatio_sm) + ratio)/16;*/
337 3100 : L_tmp = L_mult( ratio, 2048 );
338 3100 : L_tmp = L_mac( L_tmp, *LF_EnergyRatio_sm, 30720 );
339 3100 : *LF_EnergyRatio_sm = round_fx( L_tmp );
340 3100 : move16();
341 3100 : test();
342 3100 : if ( GT_16( *LF_EnergyRatio_sm, 4480 /*35.0f Q7*/ ) || GT_16( ratio, 6400 /*50.0f Q7*/ ) )
343 : {
344 1 : *predecision_flag = 1;
345 1 : move16();
346 : }
347 :
348 3100 : if ( LT_16( *LF_EnergyRatio_sm, 2048 /*16.0f Q7*/ ) )
349 : {
350 2979 : *predecision_flag = 0;
351 2979 : move16();
352 : }
353 :
354 : /* short pitch candidate detection */
355 3100 : Tp = pitch[1];
356 3100 : move16();
357 3100 : cor_max = 0;
358 3100 : move16();
359 3100 : pt_wsp = wsp + 3 * L_SUBFR;
360 3100 : pit_min = PIT_MIN_DOUBLEEXTEND;
361 3100 : move16();
362 3100 : pit_min_up = PIT_MIN;
363 3100 : move16();
364 58900 : FOR( T = pit_min; T <= pit_min_up; T++ )
365 : {
366 55800 : energy1 = Dot_product( pt_wsp, pt_wsp - T, L_SUBFR );
367 55800 : test();
368 55800 : IF( ( GT_32( energy1, cor_max ) ) || ( EQ_16( T, pit_min ) ) )
369 : {
370 20795 : cor_max = L_add( energy1, 0 );
371 20795 : Tp = T;
372 20795 : move16();
373 : }
374 : }
375 3100 : energy0 = Dot_product12( pt_wsp, pt_wsp, L_SUBFR, &exp1 );
376 3100 : exp1 = sub( exp1, shl( Q_new, 1 ) );
377 3100 : energy1 = Dot_product12( pt_wsp - Tp, pt_wsp - Tp, L_SUBFR, &exp2 );
378 3100 : exp2 = sub( exp2, shl( Q_new, 1 ) );
379 : /* cor_max *= inv_sqrt( energy0*energy1 );*/
380 3100 : L_tmp = Mult_32_32( energy0, energy1 );
381 3100 : exp = norm_l( L_tmp );
382 3100 : L_tmp1 = L_shl( L_tmp, exp );
383 :
384 3100 : exp = 31 - exp - ( 31 - exp1 - exp2 );
385 3100 : move16();
386 3100 : L_tmp1 = Isqrt_lc( L_tmp1, &exp ); /*Q(31-exp)*/
387 3100 : cor_max = Mult_32_32( cor_max, L_tmp1 );
388 3100 : exp = 31 - ( shl( Q_new, 1 ) + 1 ) - ( 31 - exp ) + 31;
389 3100 : cor_max16 = round_fx_o( L_shl_o( cor_max, exp, &Overflow ), &Overflow ); /*Q15*/
390 : /**voicing0_sm = add(mult_r(24576 ,(*voicing0_sm)) , mult_r(8192 , cor_max16));*/
391 3100 : *voicing0_sm = round_fx( L_mac( L_mult( 24576 /*.75f Q15*/, *voicing0_sm ), 8192 /*.25f Q15*/, cor_max16 ) );
392 3100 : move16();
393 :
394 : /* final short pitch detection */
395 3100 : test();
396 3100 : test();
397 3100 : test();
398 3100 : *flag_spitch = 0;
399 3100 : move16();
400 3100 : IF( ( EQ_16( localVAD, 1 ) ) && ( EQ_16( *predecision_flag, 1 ) ) &&
401 : ( GT_16( *voicing0_sm, 16384 ) ) && ( GT_16( *voicing0_sm, mult_r( *voicing_sm, 21299 ) ) ) )
402 : {
403 0 : *flag_spitch = 1;
404 0 : move16();
405 0 : pitch[0] = Tp;
406 0 : move16();
407 0 : pitch[1] = Tp;
408 0 : move16();
409 0 : pitch[2] = Tp;
410 0 : move16();
411 : }
412 :
413 3100 : return;
414 : }
415 :
416 :
417 : /*-------------------------------------------------------------------*
418 : * pitch_ol2()
419 : *
420 : * Open-loop pitch precision improvement with 1/4 resolution
421 : * The pitch is searched in the interval <pitch_ol-delta, pitch_ol+delta),
422 : * i.e. the value pitch_ol + delta is not a part of the interval
423 : *-------------------------------------------------------------------*/
424 :
425 : /*-------------------------------------------------------------------*
426 : * StableHighPitchDetect()
427 : *
428 : * Very short stable pitch detection
429 : *-------------------------------------------------------------------*/
430 1128984 : void StableHighPitchDetect_ivas_fx(
431 : Word16 *flag_spitch, /* o : flag to indicate very short stable pitch */
432 : Word16 pitch[], /* i/o: OL pitch buffer */
433 : const Word16 voicing[], /* i : OL pitch gains Q15 */
434 : const Word16 wsp[], /* i : weighted speech Qx */
435 : const Word16 localVAD, /* i : local VAD flag */
436 : Word16 *voicing_sm, /* i/o: smoothed open-loop pitch gains */
437 : Word16 *voicing0_sm, /* i/o: smoothed high pitch gains */
438 : Word16 *LF_EnergyRatio_sm, /* i/o: smoothed [0, 300Hz] relative peak energy Q7*/
439 : Word16 *predecision_flag, /* i/o: predecision flag */
440 : Word32 *diff_sm, /* i/o: smoothed pitch frequency difference Q7*/
441 : Word32 *energy_sm, /* i/o: smoothed energy around pitch frequency Q7*/
442 : Word16 Q_new,
443 : Word16 EspecdB[] /*Q8*/
444 : )
445 : {
446 : Word16 i, pitch_freq_point;
447 : Word16 T, Tp, pit_min;
448 : Word16 energy0_16, energy1_16, ratio, voicing_m;
449 : Word32 energy0, energy1, cor_max, diff, sum_energy;
450 : const Word16 *pt_wsp;
451 : Word16 tmp, tmp1, exp, diff16, cor_max16, exp1, exp2, pit_min_up;
452 : Word32 L_tmp, L_tmp1;
453 : Word16 Top;
454 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
455 1128984 : Flag Overflow = 0;
456 1128984 : move32();
457 : #endif
458 :
459 : /*voicing = (voicing[0] + voicing[1] + voicing[2] )/3;*/
460 1128984 : L_tmp = L_mult( voicing[0], 10923 /*1/3 in Q15*/ );
461 1128984 : L_tmp = L_mac( L_tmp, voicing[1], 10923 /*1/3 in Q15*/ );
462 1128984 : L_tmp = L_mac( L_tmp, voicing[2], 10923 /*1/3 in Q15*/ );
463 1128984 : voicing_m = round_fx_sat( L_tmp );
464 : /**voicing_sm = 0.75f*(*voicing_sm) + 0.25f*voicing;*/
465 1128984 : *voicing_sm = round_fx( L_mac( L_mult( *voicing_sm, 24576 /*0.75f Q15*/ ), voicing_m, 8192 /*0.25f Q15*/ ) );
466 1128984 : move16();
467 :
468 : /* pitch_freq_point = (short)(L_FFT/(mult_fact*T_op[1])+0.5f);*/
469 1128984 : Top = pitch[1];
470 1128984 : move16();
471 1128984 : pitch_freq_point = idiv1616( L_FFT, Top ); /* Q0*/
472 1128984 : sum_energy = L_deposit_l( 0 );
473 10072580 : FOR( i = 1; i < 2 * pitch_freq_point; i++ )
474 : {
475 8943596 : sum_energy = L_mac0( sum_energy, EspecdB[i], 1 ); // sum_energy
476 : }
477 1128984 : tmp = sub( shl( pitch_freq_point, 1 ), 1 );
478 :
479 : /* for ( i = 1; i < 2 * pitch_freq_point; i++ )
480 : {
481 : diff += ( EspecdB[pitch_freq_point] - EspecdB[i] );
482 : }
483 : sum energy is the accumulated value of EspecdB over the loop and EspecdB[pitch_freq_point] is constant for the loop
484 : diff can be computed as (2 * pitch_freq_point - 1) * EspecdB[pitch_freq_point] - sum_energy */
485 :
486 1128984 : diff = L_mac0( L_negate( sum_energy ), EspecdB[pitch_freq_point], tmp );
487 :
488 : /*sum_energy /= (2*pitch_freq_point-1);*/
489 :
490 1128984 : exp = norm_s( tmp );
491 1128984 : tmp1 = div_s( shl( 1, sub( 14, exp ) ), tmp ); /*Q(29-exp)*/
492 1128984 : L_tmp = Mult_32_16( sum_energy, tmp1 );
493 1128984 : sum_energy = L_shl( L_tmp, sub( exp, 14 ) );
494 : /**diff_sm = 0.2f * diff + 0.8f * *diff_sm;*/
495 1128984 : *diff_sm = L_add( Mult_32_16( diff, 6554 /*.2f Q15*/ ), Mult_32_16( *diff_sm, 26214 /*.8f Q15*/ ) );
496 1128984 : move32();
497 : /**energy_sm = 0.2f * sum_energy + 0.8f * *energy_sm;*/
498 1128984 : *energy_sm = L_add( Mult_32_16( sum_energy, 6554 /*.2f Q15*/ ), Mult_32_16( *energy_sm, 26214 /*.8f Q15*/ ) );
499 1128984 : move32();
500 : /*diff /= sum_energy;*/
501 :
502 1128984 : IF( sum_energy )
503 : {
504 1128939 : exp = norm_l( sum_energy );
505 1128939 : tmp = extract_h( L_shl( sum_energy, exp ) );
506 1128939 : exp = sub( sub( 30, exp ), 7 );
507 1128939 : IF( tmp < 0 )
508 : {
509 180627 : tmp = abs_s( tmp );
510 180627 : tmp = div_s( 16384, tmp ); /*Q(15+exp)*/
511 : BASOP_SATURATE_WARNING_OFF_EVS
512 180627 : diff = L_negate( L_shr_o( Mult_32_16( diff, tmp ), sub( exp + 7, 31 ), &Overflow ) );
513 : BASOP_SATURATE_WARNING_ON_EVS
514 180627 : diff16 = round_fx_o( diff, &Overflow );
515 : }
516 : ELSE
517 : {
518 948312 : tmp = div_s( 16384, tmp ); /*Q(15+exp)*/
519 : BASOP_SATURATE_WARNING_OFF_EVS
520 948312 : diff = L_shr_o( Mult_32_16( diff, tmp ), sub( exp + 7, 31 ), &Overflow );
521 : BASOP_SATURATE_WARNING_ON_EVS
522 948312 : diff16 = round_fx_o( diff, &Overflow );
523 : }
524 : }
525 : ELSE
526 : {
527 45 : diff16 = round_fx_o( L_shl_o( diff, 25, &Overflow ), &Overflow );
528 : }
529 1128984 : test();
530 1128984 : test();
531 1128984 : IF( LT_32( *diff_sm, -1280 /*-10.0f Q7*/ ) && LT_32( *energy_sm, 4928 /*38.5f Q7*/ ) && LT_16( diff16, -26214 /*-.8f Q15*/ ) )
532 : {
533 20900 : *predecision_flag = 1;
534 20900 : move16();
535 : }
536 1128984 : test();
537 1128984 : test();
538 1128984 : if ( GT_32( *diff_sm, 1280 /*10.0f Q7*/ ) && GT_32( *energy_sm, 10624 /*83.0f Q7*/ ) && GT_16( diff16, 16384 /*.5 Q15*/ ) )
539 : {
540 86519 : *predecision_flag = 0;
541 86519 : move16();
542 : }
543 :
544 : /* short pitch possiblity pre-decision */
545 1128984 : maximum_fx( EspecdB, 7, &energy0_16 );
546 1128984 : maximum_fx( EspecdB + 8, 7, &energy1_16 );
547 1128984 : test();
548 1128984 : IF( energy1_16 < 0 && energy0_16 > 0 )
549 : {
550 30514 : ratio = 0;
551 30514 : move16();
552 : }
553 : ELSE
554 : {
555 1098470 : ratio = s_max( sub( energy1_16, energy0_16 ), 0 ); /*Q7 */
556 : }
557 : /*ratio *= max(voicing,0);*/
558 1128984 : tmp = s_max( voicing_m, 0 );
559 1128984 : ratio = mult_r( ratio, tmp ); /*Q7*/
560 : /**LF_EnergyRatio_sm = (15*(*LF_EnergyRatio_sm) + ratio)/16;*/
561 1128984 : L_tmp = L_mult( ratio, 2048 );
562 1128984 : L_tmp = L_mac( L_tmp, *LF_EnergyRatio_sm, 30720 );
563 1128984 : *LF_EnergyRatio_sm = round_fx( L_tmp );
564 1128984 : move16();
565 1128984 : test();
566 1128984 : if ( GT_16( *LF_EnergyRatio_sm, 4480 /*35.0f Q7*/ ) || GT_16( ratio, 6400 /*50.0f Q7*/ ) )
567 : {
568 26816 : *predecision_flag = 1;
569 26816 : move16();
570 : }
571 :
572 1128984 : if ( LT_16( *LF_EnergyRatio_sm, 2048 /*16.0f Q7*/ ) )
573 : {
574 1081552 : *predecision_flag = 0;
575 1081552 : move16();
576 : }
577 :
578 : /* short pitch candidate detection */
579 1128984 : Tp = pitch[1];
580 1128984 : move16();
581 1128984 : cor_max = 0;
582 1128984 : move16();
583 1128984 : pt_wsp = wsp + 3 * L_SUBFR;
584 1128984 : pit_min = PIT_MIN_DOUBLEEXTEND;
585 1128984 : move16();
586 1128984 : pit_min_up = PIT_MIN;
587 1128984 : move16();
588 21450696 : FOR( T = pit_min; T <= pit_min_up; T++ )
589 : {
590 20321712 : energy1 = Dot_product( pt_wsp, pt_wsp - T, L_SUBFR );
591 20321712 : test();
592 20321712 : IF( ( GT_32( energy1, cor_max ) ) || ( EQ_16( T, pit_min ) ) )
593 : {
594 5936386 : cor_max = L_add( energy1, 0 );
595 5936386 : Tp = T;
596 5936386 : move16();
597 : }
598 : }
599 1128984 : energy0 = Dot_product12( pt_wsp, pt_wsp, L_SUBFR, &exp1 );
600 1128984 : exp1 = sub( exp1, shl( Q_new, 1 ) );
601 1128984 : energy1 = Dot_product12( pt_wsp - Tp, pt_wsp - Tp, L_SUBFR, &exp2 );
602 1128984 : exp2 = sub( exp2, shl( Q_new, 1 ) );
603 : /* cor_max *= inv_sqrt( energy0*energy1 );*/
604 1128984 : L_tmp = Mult_32_32( energy0, energy1 );
605 1128984 : exp = norm_l( L_tmp );
606 1128984 : L_tmp1 = L_shl( L_tmp, exp );
607 :
608 1128984 : exp = sub( sub( 31, exp ), ( sub( sub( 31, exp1 ), exp2 ) ) );
609 1128984 : move16();
610 1128984 : L_tmp1 = Isqrt_lc( L_tmp1, &exp ); /*Q(31-exp)*/
611 1128984 : cor_max = Mult_32_32( cor_max, L_tmp1 );
612 1128984 : exp = add( sub( sub( 31, add( shl( Q_new, 1 ), 1 ) ), sub( 31, exp ) ), 31 );
613 1128984 : cor_max16 = round_fx_o( L_shl_o( cor_max, exp, &Overflow ), &Overflow ); /*Q15*/
614 : /**voicing0_sm = add(mult_r(24576 ,(*voicing0_sm)) , mult_r(8192 , cor_max16));*/
615 1128984 : *voicing0_sm = round_fx( L_mac( L_mult( 24576 /*.75f Q15*/, *voicing0_sm ), 8192 /*.25f Q15*/, cor_max16 ) );
616 1128984 : move16();
617 :
618 : /* final short pitch detection */
619 1128984 : test();
620 1128984 : test();
621 1128984 : test();
622 1128984 : *flag_spitch = 0;
623 1128984 : move16();
624 1128984 : IF( ( EQ_16( localVAD, 1 ) ) && ( EQ_16( *predecision_flag, 1 ) ) &&
625 : ( GT_16( *voicing0_sm, 21299 /*.65f in Q15*/ ) ) && ( GT_16( *voicing0_sm, mult_r( *voicing_sm, 22938 /*.7f in Q15*/ ) ) ) )
626 : {
627 35500 : *flag_spitch = 1;
628 35500 : move16();
629 35500 : pitch[0] = Tp;
630 35500 : move16();
631 35500 : pitch[1] = Tp;
632 35500 : move16();
633 35500 : pitch[2] = Tp;
634 35500 : move16();
635 : }
636 :
637 1128984 : return;
638 : }
|