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