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 "rom_com.h"
10 : #include "rom_enc.h"
11 : #include "prot_fx.h" /* Function prototypes */
12 : #include "prot_fx_enc.h" /* Function prototypes */
13 :
14 :
15 : /*-----------------------------------------------------------------*
16 : * Local Constants
17 : *-----------------------------------------------------------------*/
18 : #define PIT_MIN2 20 /* pit_min for pitch tracking */
19 : #define PIT_MIN_1 44 /* for second pitch track */
20 : #define PIT_MIN2_1 24
21 :
22 : #define THR_relE -2816 /* -11 (Q8) */
23 :
24 : #define THRES0 4792 /* Threshold to favor smaller pitch lags; 1.17 (Q12) */
25 : #define DELTA0 2 /* multiples' search range initial */
26 : #define STEP 1 /* multiples' search range increment */
27 :
28 : #define THRES1 13107 /* Threshold to favor pitch lags coherence for neighbours; 0.4 (Q15) */
29 : #define DELTA_COH 14 /* Maximum pitch lags difference for neighbours to be considered as coherent */
30 : #define THRES3 22938 /* Threshold to favor pitch lags coherence with previous frames; 0.7 (Q15) */
31 :
32 : #define CORR_TH0 13107 /* Noise threshold for past frame correlations; 0.4 (Q15) */
33 : #define CORR_TH1 16384 /* Noise threshold for past frame correlations; 0.5 (Q15) */
34 :
35 : #define LEN_X ( ( PIT_MAX / OPL_DECIM ) - ( PIT_MIN2 / OPL_DECIM ) + 1 ) /* Correlation buffer length */
36 : #define COH_FAC 5734 /* Factor for measuring the pitch coherence; 1.4 (Q12) */
37 :
38 : #define NSUBSECT 7
39 : #define NSECT 4
40 : #define NHFR 3
41 : #define L_FIR_PO 5
42 : #define L_MEM ( L_FIR_PO - 2 )
43 :
44 :
45 : /*-----------------------------------------------------------------*
46 : * Local function prototypes
47 : *-----------------------------------------------------------------*/
48 :
49 : static void LP_Decim2_Copy( const Word16 x[], Word16 y[], Word16 l, Word16 mem[] );
50 :
51 : static void pitch_neighbour_fx( Word16 sect0, Word16 pitch_tmp[], Word16 pitch[3][2 * NSECT], Word16 corr_tmp[], Word16 corr[3][2 * NSECT], Word16 thres1[2 * NHFR], Word16 ind_tmp[2 * NHFR] );
52 :
53 : static void find_mult_fx( Word16 *fac, Word16 pitch0, Word16 pitch1, Word16 pit_max0, Word16 *corr, Word16 *old_pitch, Word16 *old_corr, Word16 delta, Word16 step );
54 :
55 : static Word16 pitch_coherence_fx( Word16 pitch0, Word16 pitch1, Word16 fac_max, Word16 diff_max );
56 :
57 : static Word32 Dot_product12_OL( Word16 *sum1, const Word16 x[], const Word16 y[], const Word16 lg, const Word16 lg2, Word16 *exp, Word16 *exp2 );
58 :
59 : static Word32 Dot_product12_OL_back( Word16 *sum1, const Word16 x[], const Word16 y[], const Word16 lg, const Word16 lg2, Word16 *exp, Word16 *exp2 );
60 :
61 : /*-----------------------------------------------------------------*
62 : * pitch_ol_init()
63 : *
64 : * Open loop pitch variable initialization
65 : *-----------------------------------------------------------------*/
66 158523 : void pitch_ol_init_fx(
67 : Word16 *old_thres, /* o : threshold for reinforcement of past pitch influence */
68 : Word16 *old_pitch, /* o : pitch of the 2nd half-frame of previous frame */
69 : Word16 *delta_pit, /* o : pitch evolution extrapolation */
70 : Word16 *old_corr /* o : correlation */
71 : )
72 : {
73 158523 : *old_thres = 0;
74 158523 : move16();
75 158523 : *old_pitch = 0;
76 158523 : move16();
77 158523 : *delta_pit = 0;
78 158523 : move16();
79 158523 : *old_corr = 0;
80 158523 : move16();
81 158523 : }
82 :
83 :
84 : /*==================================================================================*/
85 : /* FUNCTION : pitch_ol_fx() */
86 : /*----------------------------------------------------------------------------------*/
87 : /* PURPOSE :
88 : * Compute the open loop pitch lag.
89 : *
90 : * The pitch lag search is divided into two sets.
91 : * Each set is divided into three sections.
92 : * Each section cannot have a pitch multiple.
93 : * We find a maximum for each section.
94 : * We compare the maxima of each section.
95 : *
96 : * 1st set 2nd set
97 : * 1st section: lag delay = 115 down to 62 and 115 down to 78
98 : * 2nd section: lag delay = 61 down to 32 and 77 down to 41
99 : * 3rd section: lag delay = 31 down to 17 and 40 down to 22
100 : * 4th section: lag delay = 16 down to 10 and 21 down to 12
101 : *
102 : * As there is a margin between section overlaps, especially for
103 : * longer delays, this section selection is more robust for not
104 : * to find multiples in the same section when pitch evolves rapidly.
105 : *
106 : * For each section, the length of the vectors to correlate is
107 : * greater/equal to the longest pitch delay. */
108 : /*----------------------------------------------------------------------------------*/
109 : /* INPUT ARGUMENTS : */
110 : /* _ (Word16[]) old_pitch : OL pitch of the 2nd half-frame of the last frame Q0 */
111 : /* _ (Word16[]) old_corr_fx : correlation Q15 */
112 : /* _ (Word16[]) corr_shift_fx : normalized correlation correction Q15 */
113 : /* _ (Word16[]) old_thres_fx : maximum correlation weighting with respect */
114 : /* to past frame pitch Q15 */
115 : /* _ (Word16[]) delta_pit : old pitch extrapolation correction Q0 */
116 : /* _ (Word16[]) st_old_wsp2_fx: weighted speech memory qwsp */
117 : /* _ (Word16[]) wsp_fx : weighted speech for current frame & look-ahead qwsp */
118 : /* _ (Word16[]) mem_decim2_fx : wsp decimation filter memory qwsp */
119 : /* _ (Word16[]) relE_fx : relative frame energy Q8 */
120 : /* _ (Word16[]) L_look : look-ahead Q0 */
121 : /* _ (Word16[]) Opt_SC_VBR : SC-VBR flag Q0 */
122 : /* _ (Word16*) qwsp : wsp & filter memory Qformat */
123 : /*----------------------------------------------------------------------------------*/
124 : /* OUTPUT ARGUMENTS : */
125 : /* _ (Word16[]) pitch : open loop pitch lag for each half-frame Q0 */
126 : /* _ (Word16[]) T_op : open loop pitch lag for each half-frm for quant Q0 */
127 : /* _ (Word16[]) voicing_fx : max normalized correlation for each half-frame QIn */
128 : /* _ (Word16[]) old_pitch : OL pitch of the 2nd half-frame of the last frame Q0 */
129 : /* _ (Word16[]) old_corr_fx : correlation Q15 */
130 : /* _ (Word16[]) old_thres_fx : maximum correlation weighting with respect */
131 : /* to past frame pitch Q15 */
132 : /* _ (Word16[]) delta_pit : old pitch extrapolation correction Q0 */
133 : /* _ (Word16[]) st_old_wsp2_fx: weighted speech memory qwsp */
134 : /* _ (Word16[]) mem_decim2_fx : wsp decimation filter memory qwsp */
135 : /*----------------------------------------------------------------------------------*/
136 :
137 : /*----------------------------------------------------------------------------------*/
138 : /* RETURN ARGUMENTS : */
139 : /* _ None */
140 : /*==================================================================================*/
141 :
142 3100 : void pitch_ol_fx(
143 : Word16 pitch[3], /* o : open loop pitch lag for each half-frame in range [29,231] Q0 */
144 : Word16 voicing[3], /* o : maximum normalized correlation for each half-frame in [0,1.0[ Q15 */
145 : Word16 *old_pitch, /* i/o: pitch of the 2nd half-frame of previous frame (i.e. pitch[1]) Q0 */
146 : Word16 *old_corr, /* i/o: correlation of old_pitch (i.e. voicing[1] or corr_mean) Q15 */
147 : Word16 corr_shift, /* i : normalized correlation correction Q15 */
148 : Word16 *old_thres, /* i/o: maximum correlation weighting with respect to past frame pitch Q15 */
149 : Word16 *delta_pit, /* i/o: old pitch extrapolation correction in range [-14,+14] Q0 */
150 : Word16 *st_old_wsp2, /* i/o: weighted speech memory qwsp */
151 : const Word16 *wsp, /* i : weighted speech for current frame and look-ahead qwsp */
152 : Word16 mem_decim2[3], /* i/o: wsp decimation filter memory qwsp */
153 : const Word16 relE, /* i : relative frame energy Q8 */
154 : const Word16 last_class, /* i : frame classification of last frame */
155 : const Word16 bwidth, /* i : bandwidth */
156 : const Word16 Opt_SC_VBR /* i : SC-VBR flag */
157 : )
158 : {
159 : Word16 ftmp, old_wsp2[( L_WSP - L_INTERPOL ) / OPL_DECIM], *wsp2;
160 : Word16 tmp_mem[3];
161 :
162 : Word16 scale1[2 * DELTA_COH - 1];
163 : Word16 scaled_buf[2 * LEN_X + 3 * ( DELTA_COH - 1 )];
164 : Word16 scaled_buf_exp[2 * LEN_X + 3 * ( DELTA_COH - 1 )], exp_sect[8], exp_sect1[8], exp_sect0;
165 : Word16 cor_buf[2 * LEN_X];
166 : Word16 *pt_exp1, *pt_exp2, *pt_exp3, *pt_exp4;
167 : Word16 *pt1, *pt2, *pt3, *pt4, *pt5, *pt6;
168 : Word16 *pt_cor0, *pt_cor1, *pt_cor2, *pt_cor3, *pt_cor4, *pt_cor5, *pt_cor6;
169 : Word16 thres1[6];
170 : Word16 diff, cnt, ind, ind1, offset, offset1, offset_la, offset_la1, coh_flag, coh_flag1;
171 : Word16 ind_corX, ind1_corX;
172 :
173 : Word16 i, j, k, m, pit_min, pit_min1, sect0, subsect0, add_sect0, sub_sect0, old_tmp, old_tmp1, len_x, len_x1;
174 : Word16 len_temp;
175 : Word16 pitchX[NHFR][2 * NSECT], pitch_tmp[2 * NHFR], ind_tmp[2 * NHFR], tmp_buf[NHFR + 1];
176 :
177 : Word16 enr0[NSECT], enr0_exp[NSECT], enr0_1[NSECT], enr0_1_exp[NSECT], enr1, enr1_exp, enr2_exp;
178 : Word32 enr, enr2, Ltmp;
179 : Word16 fac, tmp16, tmp16_2;
180 : Word16 qCorX, qScaledX;
181 : Word16 scaledX[NHFR][2 * NSECT], corX[NHFR][2 * NSECT], cor_tmp[2 * NHFR], cor_mean;
182 : const Word16 *len, *len1, *sublen, *sublen1, *pit_max, *sec_length, *sec_length1;
183 :
184 : Word16 pit_min_coding;
185 :
186 : /*--------------------------------------------------------------*
187 : * Initialization
188 : *--------------------------------------------------------------*/
189 3100 : len = len_12k8;
190 3100 : len1 = len1_12k8;
191 3100 : sublen = sublen_12k8;
192 3100 : sublen1 = sublen1_12k8;
193 3100 : pit_max = pit_max_12k8;
194 3100 : sec_length = sec_length_12k8;
195 3100 : sec_length1 = sec_length1_12k8;
196 :
197 3100 : test();
198 3100 : if ( ( LT_16( last_class, VOICED_TRANSITION ) ) && ( NE_16( bwidth, NB ) ) )
199 : {
200 : /*reset last pitch reinforcement in case of unvoiced or transitions: it avoids some pitch doublings*/
201 1560 : *old_thres = 0;
202 1560 : move16();
203 : }
204 :
205 3100 : pit_min_coding = PIT_MIN_EXTEND;
206 3100 : move16();
207 3100 : test();
208 3100 : test();
209 3100 : test();
210 3100 : test();
211 3100 : IF( ( ( NE_16( bwidth, NB ) ) && ( GT_16( *old_pitch, PIT_MIN ) ) ) ||
212 : ( ( EQ_16( bwidth, NB ) ) && ( ( GT_16( *old_pitch, PIT_MIN2_1 ) ) || ( LT_16( *old_thres, 3277 ) ) ) ) ) /* 0.1 inQ15*/
213 : {
214 1306 : pit_min = PIT_MIN / OPL_DECIM;
215 1306 : move16();
216 1306 : pit_min1 = PIT_MIN_1 / OPL_DECIM;
217 1306 : move16();
218 1306 : subsect0 = 2;
219 1306 : move16();
220 1306 : sect0 = 1;
221 1306 : move16();
222 : }
223 : ELSE
224 : {
225 1794 : pit_min = PIT_MIN2 / OPL_DECIM;
226 1794 : move16();
227 1794 : pit_min1 = PIT_MIN2_1 / OPL_DECIM;
228 1794 : move16();
229 1794 : subsect0 = 0;
230 1794 : move16();
231 1794 : sect0 = 0;
232 1794 : move16();
233 : }
234 :
235 3100 : len_x = ( PIT_MAX / OPL_DECIM - pit_min + 1 );
236 3100 : move16();
237 3100 : len_x1 = ( PIT_MAX / OPL_DECIM - pit_min1 + 1 );
238 3100 : move16();
239 :
240 : /*--------------------------------------------------------------*
241 : * Find decimated weighted speech
242 : * Update wsp buffer with the memory
243 : * decimation of wsp[] to search pitch in LF and to reduce complexity
244 : * Extend the decimation of wsp to the end of the speech buffer
245 : * Update wsp memory
246 : *--------------------------------------------------------------*/
247 3100 : Copy( st_old_wsp2, old_wsp2, ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM );
248 3100 : wsp2 = old_wsp2 + ( ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM );
249 :
250 3100 : LP_Decim2_Copy( wsp, wsp2, L_FRAME, mem_decim2 );
251 :
252 : /* Avoid uninitialized memory access */
253 3100 : set16_fx( wsp2 + L_FRAME / 2, 0, sizeof( old_wsp2 ) / sizeof( Word16 ) - ( ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM ) - L_FRAME / 2 );
254 3100 : tmp_mem[0] = mem_decim2[0];
255 3100 : move16();
256 3100 : tmp_mem[1] = mem_decim2[1];
257 3100 : move16();
258 3100 : tmp_mem[2] = mem_decim2[2];
259 3100 : move16();
260 :
261 3100 : LP_Decim2_Copy( &wsp[L_FRAME], &wsp2[( L_FRAME / 2 )], L_LOOK_12k8, tmp_mem ); /* shr() used instead of division by OPL_DECIM*/
262 :
263 3100 : Copy( &old_wsp2[L_FRAME / 2], st_old_wsp2, ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM );
264 :
265 : /*-----------------------------------------------------------------*
266 : * Attenuate the correlation correction factor due to noise.
267 : * Reset correlation buffer outside the useful range.
268 : * Find the scaling functions for immediate neigbours and
269 : * further ones.
270 : *-----------------------------------------------------------------*/
271 :
272 3100 : corr_shift = shr( corr_shift, 1 );
273 :
274 3100 : set16_fx( scaled_buf, 0, DELTA_COH - 1 );
275 3100 : set16_fx( scaled_buf + ( DELTA_COH - 1 ) + len_x, 0, DELTA_COH - 1 );
276 3100 : set16_fx( scaled_buf + 2 * ( DELTA_COH - 1 ) + len_x + len_x1, 0, DELTA_COH - 1 );
277 3100 : set16_fx( scaled_buf_exp, 0, len_x + len_x1 + 3 * ( DELTA_COH - 1 ) );
278 :
279 3100 : pt1 = scale1 + DELTA_COH - 1;
280 3100 : pt2 = pt1;
281 3100 : tmp16 = mult( negate( *old_thres ), MAX_16 / DELTA_COH );
282 3100 : k = *old_thres;
283 3100 : move16();
284 46500 : FOR( i = 0; i < DELTA_COH; i++ )
285 : {
286 : /*
287 : * *pt1 = ( -(*old_thres)/DELTA_COH * i + *old_thres+1.0f );
288 : * To keep Q15 values, the following code does not add 1 to the result.
289 : * A scaling factor must be applied accordingly (see next use of scale1)
290 : */
291 43400 : *pt1 = k;
292 43400 : move16();
293 43400 : k = add( k, tmp16 );
294 43400 : *pt2-- = *pt1++;
295 43400 : move16();
296 : }
297 :
298 : /*-----------------------------------------------------------------------------*
299 : * Estimate the new pitch by extrapolating the old pitch value for 2 half-frames
300 : *-----------------------------------------------------------------------------*/
301 3100 : old_tmp = add( *old_pitch, *delta_pit );
302 3100 : old_tmp = s_min( old_tmp, PIT_MAX / OPL_DECIM );
303 3100 : old_tmp = s_max( old_tmp, pit_min );
304 3100 : old_tmp1 = add( old_tmp, *delta_pit );
305 3100 : old_tmp1 = s_min( old_tmp1, PIT_MAX / OPL_DECIM );
306 3100 : old_tmp1 = s_max( old_tmp1, pit_min );
307 :
308 : /*-----------------------------------------------------------------*
309 : * Loop for all three half-frames (current frame + look-ahead)
310 : *-----------------------------------------------------------------*/
311 3100 : pt_cor0 = scaled_buf + DELTA_COH - 1;
312 :
313 3100 : pt_cor2 = pt_cor0 - pit_min + old_tmp;
314 3100 : pt_cor4 = pt_cor0 - pit_min1 + old_tmp + ( DELTA_COH - 1 ) + len_x;
315 :
316 12400 : FOR( i = 0; i < NHFR; i++ ) /* i = 0, 1, 2 */
317 : {
318 9300 : pt1 = wsp2 + i * 2 * ( L_SUBFR / OPL_DECIM ); /* *pt1 -> Q12 */
319 9300 : pt2 = pt1 - pit_min; /* *pt2 -> Q12 */
320 9300 : pt4 = pt1 - pit_min1; /* *pt4 -> Q12 */
321 :
322 9300 : enr = L_deposit_l( 1 );
323 :
324 9300 : pt_cor1 = pt_cor0;
325 9300 : pt_cor3 = pt_cor0 + ( DELTA_COH - 1 ) + len_x;
326 :
327 9300 : pt_exp1 = scaled_buf_exp + DELTA_COH - 1;
328 9300 : pt_exp2 = pt_exp1;
329 9300 : pt_exp3 = scaled_buf_exp + 2 * ( DELTA_COH - 1 ) + len_x;
330 9300 : pt_exp4 = pt_exp3;
331 :
332 9300 : IF( LT_16( i, NHFR - 1 ) ) /* First two half-frames (current frame) */
333 : {
334 6200 : pt3 = pt1;
335 6200 : pt5 = pt1;
336 :
337 28388 : FOR( j = sect0; j < NSECT; j++ ) /* loop for each section */
338 : {
339 : /*-----------------------------------------------------------------*
340 : * Find fixed vector energy
341 : *-----------------------------------------------------------------*/
342 :
343 : /* 1st set */
344 22188 : k = (Word16) ( pt1 - pt3 );
345 22188 : move16();
346 :
347 735188 : FOR( k = add( k, len[j] ); k > 0; k-- )
348 : {
349 713000 : enr = L_mac0( enr, *pt3, *pt3 );
350 713000 : pt3++;
351 : }
352 : /* keep Q15 normalized result */
353 22188 : cnt = norm_l( enr );
354 22188 : enr0[j] = extract_h( L_shl( enr, cnt ) );
355 22188 : enr0_exp[j] = sub( 30, cnt );
356 22188 : move16();
357 :
358 : /* Reduce complexity (length of 'enr2' section is equal or larger than 'enr') */
359 22188 : pt5 = pt3;
360 22188 : enr2 = enr; /* sets to 'enr' in 1 clock */
361 22188 : move32();
362 :
363 : /* 2nd set */
364 22188 : k = (Word16) ( pt1 - pt5 );
365 22188 : move16();
366 :
367 195788 : FOR( k = add( k, len1[j] ); k > 0; k-- )
368 : {
369 173600 : enr2 = L_mac0( enr2, *pt5, *pt5 );
370 173600 : pt5++;
371 : }
372 22188 : cnt = norm_l( enr2 );
373 22188 : enr0_1[j] = extract_h( L_shl( enr2, cnt ) );
374 22188 : enr0_1_exp[j] = sub( 30, cnt );
375 22188 : move16();
376 : }
377 :
378 : /*----------------------------------------------------------*
379 : * Find correlation for the non-overlapping pitch lag values
380 : *----------------------------------------------------------*/
381 6200 : exp_sect[subsect0] = 0;
382 6200 : move16();
383 6200 : pt_cor5 = pt_cor1;
384 6200 : pt_cor6 = pt_cor3;
385 :
386 6200 : tmp16 = exp_sect[subsect0];
387 6200 : move16();
388 :
389 6200 : k = (Word16) ( pt2 - pt1 + pit_max[subsect0] );
390 :
391 6200 : IF( k >= 0 )
392 : {
393 6200 : len_temp = sublen[0];
394 6200 : move16();
395 :
396 26436 : FOR( ; k >= 0; k-- )
397 : {
398 : /* Keep Q15 normalized result */
399 : /* shr by 1 to make room for scaling in the neighbourhood of the extrapolated pitch */
400 : /* Update exponent to reflect shr by 1 */
401 20236 : *pt_cor1 = extract_h( L_shr( Dot_product12( pt1, pt2--, len_temp, pt_exp1 ), 1 ) );
402 :
403 : /* save the biggest exponent */
404 20236 : tmp16 = s_max( tmp16, *pt_exp1 );
405 :
406 20236 : pt_cor1++;
407 20236 : pt_exp1++;
408 : }
409 : }
410 6200 : exp_sect[subsect0] = tmp16;
411 6200 : move16();
412 :
413 : /*----------------------------------------------------------*
414 : * For each subsection, find the correlation
415 : *----------------------------------------------------------*/
416 44376 : FOR( j = subsect0; j < NSUBSECT; j++ )
417 : {
418 38176 : len_temp = sublen[j];
419 38176 : move16();
420 :
421 38176 : k = (Word16) ( pt2 - pt1 );
422 38176 : move16();
423 38176 : k = add( k, pit_max[j + 1] );
424 38176 : exp_sect[j + 1] = 0;
425 38176 : move16();
426 38176 : exp_sect1[j] = 0;
427 38176 : move16();
428 :
429 38176 : IF( k >= 0 )
430 : {
431 38176 : ind = exp_sect[j + 1];
432 38176 : move16();
433 38176 : ind1 = exp_sect1[j];
434 38176 : move16();
435 :
436 656856 : FOR( ; k >= 0; k-- )
437 : {
438 : /* Keep Q15 normalized result */
439 : /* shr by 1 to make room for scaling in the neighbourhood of the extrapolated pitch */
440 : /* Update exponent to reflect shr by 1 (done in Dot_product12_OL() for pt_cor3/pt_exp3) */
441 618680 : *pt_cor1 = extract_h( L_shr( Dot_product12_OL( pt_cor3, pt1, pt2--, sublen[j], sublen1[j], pt_exp1, pt_exp3 ), 1 ) );
442 : /* The line above replaces:
443 : * *pt_cor1 = shr(extract_h(Dot_product12(pt1, pt2, Sublen[j], pt_exp1)),1); move16();
444 : * *pt_cor3 = shr(extract_h(Dot_product12(pt1, pt2--, Sublen1[j+i*7], pt_exp3)),1); move16();
445 : */
446 :
447 : /* save the biggest exponent */
448 618680 : ind = s_max( ind, *pt_exp1 );
449 618680 : ind1 = s_max( ind1, *pt_exp3 );
450 :
451 618680 : pt_cor1++;
452 618680 : pt_exp1++;
453 618680 : pt_cor3++;
454 618680 : pt_exp3++;
455 : }
456 38176 : exp_sect[j + 1] = ind;
457 38176 : move16();
458 38176 : exp_sect1[j] = ind1;
459 38176 : move16();
460 : } /* IF (k >= 0) */
461 : } /* FOR (j = subsect0; ... */
462 : }
463 : ELSE /* 3rd half-frame (look-ahead) */
464 : {
465 3100 : pt6 = pt1 + L_LOOK_12k8 / OPL_DECIM - 1;
466 3100 : pt3 = pt6;
467 3100 : pt5 = pt6;
468 :
469 : /*-----------------------------------------------------------------*
470 : * For each section in both sets, find fixed vector energy
471 : *-----------------------------------------------------------------*/
472 :
473 14194 : FOR( j = sect0; j < NSECT; j++ ) /* loop for each section */
474 : {
475 : /* 1st set */
476 11094 : k = (Word16) ( pt3 - pt6 );
477 11094 : move16();
478 :
479 367594 : FOR( k = add( k, len[j] ); k > 0; k-- )
480 : {
481 356500 : enr = L_mac0( enr, *pt3, *pt3 );
482 356500 : pt3--;
483 : }
484 :
485 11094 : cnt = norm_l( enr );
486 11094 : enr0[j] = extract_h( L_shl( enr, cnt ) ); /*qwsp+cnt-16*/
487 11094 : enr0_exp[j] = sub( 30, cnt );
488 11094 : move16();
489 :
490 : /* Reduce complexity (length of 'enr2' section is equal or larger than 'enr') */
491 11094 : pt5 = pt3;
492 11094 : enr2 = enr;
493 11094 : move16();
494 :
495 : /* 2nd set */
496 11094 : k = (Word16) ( pt5 - pt6 );
497 11094 : move16();
498 :
499 97894 : FOR( k = add( k, len1[j] ); k > 0; k-- )
500 : {
501 86800 : enr2 = L_mac0( enr2, *pt5, *pt5 );
502 86800 : pt5--;
503 : }
504 :
505 11094 : cnt = norm_l( enr2 );
506 11094 : enr0_1[j] = extract_h( L_shl( enr2, cnt ) ); /*qwsp+cnt-16*/
507 11094 : enr0_1_exp[j] = sub( 30, cnt );
508 11094 : move16();
509 : }
510 :
511 : /* Set pointers */
512 3100 : IF( sect0 != 0 )
513 : {
514 1306 : pt2 = pt6 - add( pit_max[1], 1 );
515 1306 : k = sub( pit_max[2], pit_max[1] );
516 1306 : move16();
517 : }
518 : ELSE
519 : {
520 1794 : pt2 = pt6 - pit_min;
521 1794 : k = 2;
522 1794 : move16();
523 : }
524 :
525 : /*-----------------------------------------------------------------*
526 : * Find correlation for the non-overlapping pitch lag values
527 : *-----------------------------------------------------------------*/
528 3100 : exp_sect[subsect0] = 0;
529 3100 : move16();
530 3100 : pt_cor5 = pt_cor1;
531 3100 : pt_cor6 = pt_cor3;
532 :
533 3100 : tmp16 = exp_sect[subsect0];
534 3100 : move16();
535 :
536 3100 : IF( k > 0 )
537 : {
538 3100 : len_temp = sublen[0];
539 3100 : move16();
540 :
541 13218 : FOR( ; k > 0; k-- )
542 : {
543 : /* Following lines are equivalent of Dot_product12() but with a backward incrementing */
544 10118 : Ltmp = L_deposit_l( 1 );
545 414838 : FOR( m = 0; m < len_temp; m++ )
546 : {
547 404720 : Ltmp = L_mac( Ltmp, pt6[-m], pt2[-m] );
548 : }
549 :
550 : /* Normalize acc in Q31 */
551 10118 : tmp16_2 = norm_l( Ltmp );
552 10118 : Ltmp = L_shl( Ltmp, tmp16_2 );
553 10118 : *pt_exp1 = sub( 30, tmp16_2 );
554 10118 : move16(); /* exponent = 0..30 */
555 :
556 : /* Save result */
557 10118 : *pt_cor1 = extract_h( L_shr( Ltmp, 1 ) );
558 :
559 : /* Save the biggest exponent */
560 10118 : tmp16 = s_max( tmp16, *pt_exp1 );
561 :
562 10118 : pt_cor1++;
563 10118 : pt_exp1++;
564 10118 : pt2--;
565 : }
566 3100 : exp_sect[subsect0] = tmp16;
567 3100 : move16();
568 : }
569 :
570 : /*-----------------------------------------------------------------*
571 : * For each subsection, find the correlation (overlapping pitch lag values)
572 : *-----------------------------------------------------------------*/
573 :
574 22188 : FOR( j = subsect0; j < NSUBSECT; j++ )
575 : {
576 19088 : exp_sect[j + 1] = 0;
577 19088 : move16();
578 19088 : exp_sect1[j] = 0;
579 19088 : move16();
580 :
581 19088 : ind = exp_sect[j + 1];
582 19088 : move16();
583 19088 : ind1 = exp_sect1[j];
584 19088 : move16();
585 :
586 19088 : k = sub( pit_max[j + 1], pit_max[j] );
587 :
588 328428 : FOR( ; k > 0; k-- )
589 : {
590 309340 : *pt_cor1 = extract_h( L_shr( Dot_product12_OL_back( pt_cor3, pt6, pt2--, sublen[j], sublen1[j], pt_exp1, pt_exp3 ), 1 ) );
591 :
592 : /* Save the biggest exponent */
593 309340 : ind = s_max( ind, *pt_exp1 );
594 309340 : ind1 = s_max( ind1, *pt_exp3 );
595 :
596 309340 : pt_cor1++;
597 309340 : pt_exp1++;
598 309340 : pt_cor3++;
599 309340 : pt_exp3++;
600 : }
601 19088 : exp_sect[j + 1] = ind;
602 19088 : move16();
603 19088 : exp_sect1[j] = ind1;
604 19088 : move16();
605 : }
606 : } /* 3rd half-frame (look-ahead) */
607 :
608 : /* Scale all values in each section to the same exponent for upcoming Find_max() */
609 9300 : offset = 0;
610 9300 : move16();
611 9300 : offset1 = 0;
612 9300 : move16();
613 9300 : exp_sect1[7] = 0; /* padding */
614 9300 : move16();
615 42582 : FOR( j = sect0; j < NSECT; j++ )
616 : {
617 33282 : exp_sect0 = s_max( exp_sect[j * 2], exp_sect[j * 2 + 1] );
618 :
619 : /* scaling of exp for track 1 */
620 33282 : offset = add( offset, sec_length[j] );
621 33282 : k = (Word16) ( pt_cor0 - pt_cor5 );
622 33282 : move16();
623 991656 : FOR( k = add( k, offset ); k > 0; k-- )
624 : {
625 958374 : cnt = sub( exp_sect0, *pt_exp2 );
626 958374 : tmp16 = s_min( 15, cnt );
627 958374 : if ( cnt > 0 )
628 : {
629 714208 : tmp16 = shr( *pt_cor5, tmp16 );
630 : }
631 958374 : if ( cnt > 0 )
632 : {
633 714208 : *pt_cor5 = tmp16;
634 714208 : move16();
635 : }
636 958374 : *pt_exp2 = s_max( *pt_exp2, exp_sect0 );
637 958374 : move16();
638 958374 : pt_cor5++;
639 958374 : pt_exp2++;
640 : }
641 :
642 33282 : exp_sect0 = s_max( exp_sect1[j * 2], exp_sect1[j * 2 + 1] );
643 :
644 : /* scaling of exp for track 2 */
645 33282 : offset1 = add( offset1, sec_length1[j] );
646 33282 : k = (Word16) ( pt_cor0 - pt_cor6 + ( DELTA_COH - 1 ) );
647 33282 : move16();
648 33282 : k = add( k, len_x );
649 961302 : FOR( k = add( k, offset1 ); k > 0; k-- )
650 : {
651 928020 : cnt = sub( exp_sect0, *pt_exp4 );
652 928020 : tmp16 = s_min( 15, cnt );
653 928020 : if ( cnt > 0 )
654 : {
655 685758 : tmp16 = shr( *pt_cor6, tmp16 );
656 : }
657 928020 : if ( cnt > 0 )
658 : {
659 685758 : *pt_cor6 = tmp16;
660 685758 : move16();
661 : }
662 928020 : *pt_exp4 = s_max( *pt_exp4, exp_sect0 );
663 928020 : move16();
664 928020 : pt_cor6++;
665 928020 : pt_exp4++;
666 : }
667 : } /* FOR (j = sect0; ... */
668 :
669 9300 : Copy( pt_cor0, cor_buf, len_x ); /* Save unscaled correlation vector */
670 9300 : Copy( pt_cor0 + ( DELTA_COH - 1 ) + len_x, cor_buf + len_x, len_x1 );
671 :
672 : /*-----------------------------------------------------------------*
673 : * Scale correlation function in the neighbourhood of
674 : * the extrapolated pitch
675 : *-----------------------------------------------------------------*/
676 9300 : pt_cor1 = pt_cor2 - ( DELTA_COH - 1 );
677 9300 : pt_cor3 = pt_cor4 - ( DELTA_COH - 1 );
678 9300 : pt2 = scale1;
679 :
680 260400 : FOR( k = 0; k < 2 * DELTA_COH - 1; k++ )
681 : {
682 : /* all Q15 here */
683 251100 : *pt_cor1 = add( *pt_cor1, mult( *pt_cor1, *pt2 ) );
684 251100 : move16();
685 251100 : *pt_cor3 = add( *pt_cor3, mult( *pt_cor3, *pt2++ ) );
686 251100 : move16();
687 :
688 251100 : pt_cor1++;
689 251100 : pt_cor3++;
690 : }
691 :
692 : /* Update for next half-frame & look-ahead */
693 9300 : pt_cor2 = pt_cor0 - pit_min + old_tmp1;
694 9300 : pt_cor4 = pt_cor0 - pit_min1 + old_tmp1 + ( DELTA_COH - 1 ) + len_x;
695 :
696 : /*-----------------------------------------------------------------*
697 : * For each section, find maximum correlation and compute
698 : * normalized correlation
699 : *-----------------------------------------------------------------*/
700 :
701 9300 : pt_cor1 = pt_cor0;
702 9300 : pt_exp1 = scaled_buf_exp + DELTA_COH - 1;
703 9300 : offset = 0;
704 9300 : move16();
705 9300 : pt_cor3 = pt_cor0 + ( DELTA_COH - 1 ) + len_x;
706 9300 : pt_exp3 = scaled_buf_exp + 2 * ( DELTA_COH - 1 ) + len_x;
707 9300 : offset1 = 0;
708 9300 : move16();
709 :
710 42582 : FOR( j = sect0; j < NSECT; j++ ) /* loop for each section */
711 : {
712 : /* 1st set */
713 33282 : offset_la = 0;
714 33282 : move16();
715 33282 : if ( EQ_16( i, 2 ) )
716 : {
717 11094 : offset_la = sub( L_LOOK_12k8 / OPL_DECIM, len[j] );
718 : }
719 :
720 : /* 2nd set */
721 33282 : offset_la1 = 0;
722 33282 : move16();
723 33282 : if ( EQ_16( i, 2 ) )
724 : {
725 11094 : offset_la1 = sub( L_LOOK_12k8 / OPL_DECIM, len1[j] );
726 : }
727 :
728 : /* 1st set of candidates */
729 33282 : ind = add( maximum_fx( pt_cor1, sec_length[j], &ftmp ), offset );
730 33282 : pitchX[i][j] = add( ind, pit_min );
731 33282 : move16();
732 33282 : pt2 = pt1 - pitchX[i][j] + /*-*/ offset_la; /* selected moving vector */
733 :
734 33282 : enr1_exp = 0;
735 33282 : move16();
736 33282 : enr1 = add_sat( extract_h( dotp_fx( pt2, pt2, len[j], &enr1_exp ) ), 1 );
737 :
738 33282 : enr2 = L_mult( enr0[j], enr1 );
739 33282 : enr2_exp = norm_l( enr2 );
740 33282 : enr2 = L_shl( enr2, enr2_exp );
741 33282 : enr2_exp = sub( 31, add( sub( 28, add( enr0_exp[j], enr1_exp ) ), add( enr2_exp, 1 ) ) );
742 :
743 33282 : enr2 = Isqrt_lc( enr2, &enr2_exp ); /* 1/sqrt(energy) */ /*31-enr2_exp*/
744 33282 : enr1_exp = norm_l( enr2 );
745 33282 : enr1 = extract_h( L_shl( enr2, enr1_exp ) ); /*31-enr2_exp+enr1_exp-16*/
746 33282 : enr1_exp = sub( enr2_exp, enr1_exp ); /*15-enr1_exp*/
747 :
748 33282 : Ltmp = L_mult0( cor_buf[ind], enr1 );
749 33282 : qCorX = add( sub( 15, enr1_exp ), sub( 14, pt_exp1[ind] ) );
750 33282 : corX[i][j] = extract_h( L_shr_sat( Ltmp, sub( qCorX, 31 ) ) );
751 33282 : qCorX = 31;
752 33282 : move16();
753 :
754 33282 : Ltmp = L_mult0( pt_cor0[ind], enr1 );
755 33282 : qScaledX = add( sub( 15, enr1_exp ), sub( 14, pt_exp1[ind] ) );
756 33282 : scaledX[i][j] = round_fx( L_shl( Ltmp, sub( 16 + 12, qScaledX ) ) );
757 33282 : qScaledX = 12;
758 33282 : move16();
759 :
760 33282 : pt_cor1 += sec_length[j];
761 33282 : move16();
762 33282 : offset = add( offset, sec_length[j] );
763 :
764 : /* 2nd set of candidates */
765 33282 : ind1 = add( maximum_fx( pt_cor3, sec_length1[j], &ftmp ), offset1 );
766 33282 : pitchX[i][j + NSECT] = add( ind1, pit_min1 );
767 33282 : move16();
768 33282 : pt4 = pt1 - pitchX[i][j + NSECT] + /*-*/ offset_la1;
769 33282 : move16(); /* selected moving vector */
770 33282 : enr1_exp = 0;
771 33282 : move16();
772 33282 : enr1 = add_sat( extract_h( dotp_fx( pt4, pt4, len1[j], &enr1_exp ) ), 1 );
773 :
774 33282 : enr2 = L_mult( enr0_1[j], enr1 );
775 33282 : enr2_exp = norm_l( enr2 );
776 33282 : enr2 = L_shl( enr2, enr2_exp );
777 :
778 33282 : enr2_exp = sub( 31, add( sub( 28, add( enr0_1_exp[j], enr1_exp ) ), add( enr2_exp, 1 ) ) );
779 33282 : enr2 = Isqrt_lc( enr2, &enr2_exp ); /* 1/sqrt(energy) */ /*31-enr2_exp*/
780 33282 : enr1_exp = norm_l( enr2 );
781 33282 : enr1 = extract_h( L_shl( enr2, enr1_exp ) ); /*31-enr2_exp+enr1_exp-16*/
782 33282 : enr1_exp = sub( enr2_exp, enr1_exp ); /*15-enr1_exp*/
783 :
784 33282 : Ltmp = L_mult0( cor_buf[ind1 + len_x], enr1 );
785 :
786 33282 : qCorX = add( sub( 15, enr1_exp ), sub( 14, pt_exp3[ind1] ) );
787 33282 : corX[i][j + NSECT] = extract_h( L_shr_sat( Ltmp, qCorX - 31 ) );
788 33282 : qCorX = 31;
789 33282 : move16();
790 :
791 33282 : Ltmp = L_mult0( pt_cor0[ind1 + ( DELTA_COH - 1 ) + len_x], enr1 );
792 33282 : qScaledX = add( sub( 15, enr1_exp ), sub( 14, pt_exp3[ind1] ) );
793 33282 : scaledX[i][j + NSECT] = round_fx( L_shl( Ltmp, sub( 16 + 12, qScaledX ) ) );
794 : /*scaledX[i][j+NSECT] = saturate(L_shr(Ltmp, qScaledX-12));*/
795 33282 : qScaledX = 12;
796 33282 : move16();
797 :
798 33282 : pt_cor3 += sec_length1[j];
799 33282 : move16();
800 33282 : offset1 = add( offset1, sec_length1[j] );
801 :
802 : } /* FOR j < NSECT */
803 : } /* FOR i < NHFR */
804 :
805 : /*-----------------------------------------------------------------*
806 : * Favor a smaller delay if it happens that it has its multiple
807 : * in the longer-delay sections (harmonics check)
808 : *-----------------------------------------------------------------*/
809 :
810 9300 : FOR( i = 0; i < 2; i++ ) /* loop for the 2 half-frames */
811 : {
812 6200 : fac = THRES0;
813 6200 : move16();
814 6200 : find_mult_fx( &fac, pitchX[i][2], pitchX[i][3], pit_max[7], &scaledX[i][2], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 3rd section */
815 6200 : find_mult_fx( &fac, pitchX[i][1], pitchX[i][2], pit_max[5], &scaledX[i][1], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
816 6200 : test();
817 6200 : IF( ( sect0 == 0 ) && GE_16( shl( pitchX[i][0], 1 ), pit_min_coding ) )
818 : {
819 3588 : find_mult_fx( &fac, pitchX[i][0], pitchX[i][1], pit_max[3], &scaledX[i][0], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
820 : }
821 6200 : fac = THRES0;
822 6200 : move16();
823 6200 : find_mult_fx( &fac, pitchX[i][NSECT + 2], pitchX[i][NSECT + 3], pit_max[7], &scaledX[i][NSECT + 2], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 3rd section */
824 6200 : find_mult_fx( &fac, pitchX[i][NSECT + 1], pitchX[i][NSECT + 2], pit_max[6], &scaledX[i][NSECT + 1], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
825 6200 : test();
826 6200 : IF( ( sect0 == 0 ) && GE_16( shl( pitchX[i][NSECT + 0], 1 ), pit_min_coding ) )
827 : {
828 3588 : find_mult_fx( &fac, pitchX[i][NSECT + 0], pitchX[i][NSECT + 1], pit_max[4], &scaledX[i][NSECT + 0], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
829 : }
830 : }
831 :
832 3100 : fac = THRES0;
833 3100 : move16(); /* the look-ahead */
834 3100 : find_mult_fx( &fac, pitchX[i][2], pitchX[i][3], pit_max[7], &scaledX[i][2], old_pitch, old_corr, 2, 2 ); /* Multiples in 3rd section */
835 3100 : find_mult_fx( &fac, pitchX[i][1], pitchX[i][2], pit_max[5], &scaledX[i][1], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
836 3100 : test();
837 3100 : IF( ( sect0 == 0 ) && GE_16( shl( pitchX[i][0], 1 ), pit_min_coding ) )
838 : {
839 1794 : find_mult_fx( &fac, pitchX[i][0], pitchX[i][1], pit_max[3], &scaledX[i][0], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
840 : }
841 3100 : fac = THRES0;
842 3100 : move16();
843 3100 : find_mult_fx( &fac, pitchX[i][NSECT + 2], pitchX[i][NSECT + 3], pit_max[7], &scaledX[i][NSECT + 2], old_pitch, old_corr, 2, 2 ); /* Multiples in 3rd section */
844 3100 : find_mult_fx( &fac, pitchX[i][NSECT + 1], pitchX[i][NSECT + 2], pit_max[6], &scaledX[i][NSECT + 1], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
845 3100 : test();
846 3100 : IF( ( sect0 == 0 ) && GE_16( shl( pitchX[i][NSECT + 0], 1 ), pit_min_coding ) )
847 : {
848 1794 : find_mult_fx( &fac, pitchX[i][NSECT + 0], pitchX[i][NSECT + 1], pit_max[4], &scaledX[i][NSECT + 0], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */ /* Multiples in 2nd section */
849 : }
850 :
851 : /*-----------------------------------------------------------------*
852 : * Do 1st estimate for pitch values
853 : * Adjust the normalized correlation using estimated noise level
854 : * Compute the maximum scaling for the neighbour correlation
855 : * reinforcement
856 : *-----------------------------------------------------------------*/
857 3100 : add_sect0 = add( NSECT, sect0 );
858 3100 : sub_sect0 = sub( NSECT, sect0 );
859 12400 : FOR( i = 0; i < NHFR; i++ )
860 : {
861 : /* 1st set of pitch candidates */
862 9300 : ind = add( maximum_fx( scaledX[i] + sect0, sub_sect0, &ftmp ), sect0 );
863 9300 : ind_tmp[i] = ind;
864 9300 : move16();
865 9300 : pitch_tmp[i] = pitchX[i][ind];
866 9300 : move16();
867 9300 : cor_tmp[i] = add_sat( corX[i][ind], corr_shift );
868 9300 : move16();
869 :
870 : /* Higher is the neighbour's correlation, higher is the weighting */
871 : /* operands are Q15, result is Q15 */
872 9300 : thres1[i] = mult( THRES1, cor_tmp[i] );
873 9300 : move16();
874 :
875 : /* 2nd set of pitch candidates */
876 9300 : ind1 = add( maximum_fx( scaledX[i] + add_sect0, sub_sect0, &ftmp ), add_sect0 );
877 9300 : ind_tmp[i + NHFR] = ind1;
878 9300 : move16();
879 9300 : pitch_tmp[i + NHFR] = pitchX[i][ind1];
880 9300 : move16();
881 9300 : cor_tmp[i + NHFR] = add_sat( corX[i][ind1], corr_shift );
882 9300 : move16();
883 :
884 : /* Higher is the neighbour's correlation, higher is the weighting */
885 : /* operands are Q15, result is Q15 */
886 9300 : thres1[i + NHFR] = mult( THRES1, cor_tmp[i + NHFR] );
887 9300 : move16();
888 : }
889 : /*-----------------------------------------------------------------*
890 : * Take into account previous and next pitch values of the present
891 : * frame and look-ahead. Choose the pitch lags and normalize
892 : * correlations for each half-frame & look-ahead
893 : *-----------------------------------------------------------------*/
894 :
895 3100 : pitch_neighbour_fx( sect0, pitch_tmp, pitchX, cor_tmp, scaledX, thres1, ind_tmp );
896 12400 : FOR( i = 0; i < NHFR; i++ )
897 : {
898 9300 : ind = add( maximum_fx( scaledX[i] + sect0, sub_sect0, &ftmp ), sect0 );
899 9300 : ind_corX = add( maximum_fx( corX[i] + sect0, sub_sect0, &ftmp ), sect0 );
900 :
901 9300 : ind1 = add( maximum_fx( scaledX[i] + add_sect0, sub_sect0, &ftmp ), add_sect0 );
902 9300 : ind1_corX = add( maximum_fx( corX[i] + add_sect0, sub_sect0, &ftmp ), add_sect0 );
903 :
904 9300 : if ( GT_16( scaledX[i][ind1], scaledX[i][ind] ) )
905 : {
906 4013 : ind = ind1;
907 4013 : move16();
908 : }
909 9300 : test();
910 9300 : if ( Opt_SC_VBR && GT_16( corX[i][ind1_corX], corX[i][ind_corX] ) )
911 : {
912 0 : ind_corX = ind1_corX;
913 0 : move16();
914 : }
915 9300 : test();
916 9300 : test();
917 9300 : test();
918 9300 : IF( Opt_SC_VBR && ( LT_16( mult( pitchX[i][ind], 13107 /*0.4 in Q15*/ ), pitchX[i][ind_corX] ) ) &&
919 : ( GT_16( mult( pitchX[i][ind], 19661 /*0.6 in Q15*/ ), pitchX[i][ind_corX] ) ) &&
920 : ( GE_16( corX[i][ind_corX], 29491 /*0.9 in Q15*/ ) ) )
921 : {
922 0 : pitch[i] = pitchX[i][ind_corX];
923 0 : move16();
924 0 : voicing[i] = corX[i][ind_corX];
925 0 : move16();
926 : }
927 : ELSE
928 : {
929 9300 : pitch[i] = pitchX[i][ind];
930 9300 : move16();
931 9300 : voicing[i] = corX[i][ind];
932 9300 : move16();
933 : }
934 : }
935 :
936 : /*-----------------------------------------------------------------*
937 : * Increase the threshold for correlation reinforcement with
938 : * the past if correlation high and pitch stable
939 : *-----------------------------------------------------------------*/
940 :
941 : /* all Q15 here */
942 : /* cor_mean = 0.5f * (voicing[0] + voicing[1]) + corr_shift; */
943 3100 : Ltmp = L_mult( voicing[0], 16384 );
944 3100 : Ltmp = L_mac( Ltmp, voicing[1], 16384 );
945 3100 : cor_mean = round_fx( L_add( Ltmp, corr_shift ) );
946 :
947 : /* pitch unstable in present frame or from previous frame or normalized correlation too low */
948 3100 : coh_flag = pitch_coherence_fx( pitch[0], pitch[1], COH_FAC, DELTA_COH );
949 3100 : move16();
950 3100 : coh_flag1 = pitch_coherence_fx( pitch[0], *old_pitch, COH_FAC, DELTA_COH );
951 3100 : move16();
952 :
953 3100 : test();
954 3100 : test();
955 3100 : test();
956 3100 : IF( ( coh_flag == 0 ) || ( coh_flag1 == 0 ) || ( LT_16( cor_mean, CORR_TH0 ) ) || ( LT_16( relE, THR_relE ) ) )
957 : {
958 : /* Reset the threshold */
959 1309 : *old_thres = 0;
960 1309 : move16();
961 : }
962 : ELSE
963 : {
964 : /* The threshold increase is directly dependent on normalized correlation */
965 : /* *old_thres += (0.16f * cor_mean); */
966 1791 : *old_thres = round_fx( L_mac( L_deposit_h( *old_thres ), 5243, cor_mean ) );
967 : }
968 :
969 3100 : *old_thres = s_min( *old_thres, THRES3 );
970 3100 : move16();
971 :
972 3100 : IF( GT_16( voicing[1], voicing[0] ) )
973 : {
974 1516 : *old_corr = voicing[1];
975 1516 : move16();
976 : }
977 : ELSE
978 : {
979 1584 : *old_corr = cor_mean;
980 1584 : move16();
981 : }
982 :
983 : /*-----------------------------------------------------------------*
984 : * Extrapolate the pitch value for the next frame by estimating
985 : * the pitch evolution. This value is added to the old_pitch
986 : * in the next frame and is then used when the normalized
987 : * correlation is reinforced by the past estimate
988 : *-----------------------------------------------------------------*/
989 3100 : tmp_buf[0] = *old_pitch;
990 3100 : move16();
991 12400 : FOR( i = 0; i < NHFR; i++ )
992 : {
993 9300 : tmp_buf[i + 1] = pitch[i];
994 9300 : move16();
995 : }
996 :
997 3100 : *delta_pit = 0;
998 3100 : move16();
999 3100 : cnt = 0;
1000 3100 : move16();
1001 :
1002 12400 : FOR( i = 0; i < NHFR; i++ )
1003 : {
1004 9300 : diff = sub( tmp_buf[i + 1], tmp_buf[i] );
1005 9300 : move16();
1006 9300 : coh_flag = pitch_coherence_fx( tmp_buf[i], tmp_buf[i + 1], COH_FAC, DELTA_COH );
1007 :
1008 9300 : if ( coh_flag != 0 )
1009 : {
1010 7882 : *delta_pit = add( *delta_pit, diff );
1011 7882 : move16();
1012 : }
1013 9300 : cnt = add( cnt, coh_flag );
1014 : }
1015 3100 : if ( EQ_16( cnt, 2 ) )
1016 : {
1017 : /* *delta_pit /= 2; */
1018 484 : *delta_pit = shr( *delta_pit, 1 );
1019 484 : move16();
1020 : }
1021 3100 : IF( EQ_16( cnt, 3 ) )
1022 : {
1023 2207 : k = *delta_pit;
1024 2207 : move16();
1025 : /* *delta_pit /= 3; */
1026 2207 : if ( k < 0 )
1027 : {
1028 496 : *delta_pit = mult( *delta_pit, -32768 );
1029 496 : move16();
1030 : }
1031 2207 : tmp16 = mult( *delta_pit, 10923 );
1032 2207 : if ( k < 0 )
1033 : {
1034 496 : tmp16 = mult( tmp16, -32768 );
1035 : }
1036 2207 : *delta_pit = tmp16;
1037 2207 : move16();
1038 : }
1039 :
1040 : /*--------------------------------------------------------------*
1041 : * Update old pitch, upsample pitch,
1042 : *--------------------------------------------------------------*/
1043 :
1044 3100 : *old_pitch = pitch[1];
1045 3100 : move16();
1046 :
1047 12400 : FOR( i = 0; i < NHFR; i++ )
1048 : {
1049 : /* compensate decimation */
1050 9300 : pitch[i] = i_mult2( pitch[i], OPL_DECIM );
1051 9300 : move16();
1052 : }
1053 :
1054 3100 : return;
1055 : }
1056 :
1057 1154754 : void pitch_ol_ivas_fx(
1058 : Word16 pitch[3], /* o : open loop pitch lag for each half-frame in range [29,231] Q0 */
1059 : Word16 voicing[3], /* o : maximum normalized correlation for each half-frame in [0,1.0[ Q15 */
1060 : Word16 *old_pitch, /* i/o: pitch of the 2nd half-frame of previous frame (i.e. pitch[1]) Q0 */
1061 : Word16 *old_corr, /* i/o: correlation of old_pitch (i.e. voicing[1] or corr_mean) Q15 */
1062 : Word16 corr_shift, /* i : normalized correlation correction Q15 */
1063 : Word16 *old_thres, /* i/o: maximum correlation weighting with respect to past frame pitch Q14 */
1064 : Word16 *delta_pit, /* i/o: old pitch extrapolation correction in range [-14,+14] Q0 */
1065 : Word16 *st_old_wsp2, /* i/o: weighted speech memory qwsp */
1066 : const Word16 *wsp, /* i : weighted speech for current frame and look-ahead qwsp */
1067 : Word16 mem_decim2[3], /* i/o: wsp decimation filter memory qwsp */
1068 : const Word16 relE, /* i : relative frame energy Q8 */
1069 : const Word16 last_class, /* i : frame classification of last frame */
1070 : const Word16 bwidth, /* i : bandwidth */
1071 : const Word16 Opt_SC_VBR, /* i : SC-VBR flag */
1072 : Word16 qwsp /* i : Q factor for wsp Q0 */
1073 : )
1074 : {
1075 : Word16 ftmp, old_wsp2[( L_WSP - L_INTERPOL ) / OPL_DECIM], *wsp2;
1076 : Word16 tmp_mem[3];
1077 :
1078 : Word16 scale1[2 * DELTA_COH - 1];
1079 : Word16 scaled_buf[2 * LEN_X + 3 * ( DELTA_COH - 1 )];
1080 : Word16 scaled_buf_exp[2 * LEN_X + 3 * ( DELTA_COH - 1 )];
1081 : Word16 cor_buf[2 * LEN_X], cor_buf_exp[2 * LEN_X];
1082 : Word16 *pt1, *pt2, *pt3, *pt4, *pt5, *pt6;
1083 : Word16 *pt_cor0, *pt_cor1, *pt_cor2, *pt_cor3, *pt_cor4;
1084 : Word16 *pt_cor0_exp, *pt_cor1_exp, *pt_cor2_exp, *pt_cor3_exp, *pt_cor4_exp;
1085 : Word16 thres1[6];
1086 : Word16 diff, cnt, ind, ind1, offset, offset1, offset_la, offset_la1, coh_flag, coh_flag1;
1087 : Word16 ind_corX, ind1_corX;
1088 :
1089 : Word16 i, j, k, m, pit_min, pit_min1, sect0, subsect0, add_sect0, sub_sect0, old_tmp, old_tmp1, len_x, len_x1;
1090 : Word16 len_temp;
1091 : Word16 pitchX[NHFR][2 * NSECT], pitch_tmp[2 * NHFR], ind_tmp[2 * NHFR], tmp_buf[NHFR + 1];
1092 :
1093 : Word16 enr0_exp[NSECT], enr0_1_exp[NSECT], enr1_exp;
1094 : Word32 enr0[NSECT], enr0_1[NSECT], enr1;
1095 : Word64 temp, temp1;
1096 : Word32 Ltmp;
1097 : Word16 fac, tmp16, tmp16_2;
1098 : Word16 scaledX[NHFR][2 * NSECT], corX[NHFR][2 * NSECT], cor_tmp[2 * NHFR], cor_mean;
1099 : const Word16 *len, *len1, *sublen, *sublen1, *pit_max, *sec_length, *sec_length1;
1100 :
1101 : Word16 pit_min_coding;
1102 : Word16 new_q;
1103 1154754 : new_q = sub( 63, shl( qwsp, 1 ) );
1104 :
1105 : /*--------------------------------------------------------------*
1106 : * Initialization
1107 : *--------------------------------------------------------------*/
1108 1154754 : len = len_12k8;
1109 1154754 : len1 = len1_12k8;
1110 1154754 : sublen = sublen_12k8;
1111 1154754 : sublen1 = sublen1_12k8;
1112 1154754 : pit_max = pit_max_12k8;
1113 1154754 : sec_length = sec_length_12k8;
1114 1154754 : sec_length1 = sec_length1_12k8;
1115 :
1116 1154754 : test();
1117 1154754 : if ( ( LT_16( last_class, VOICED_TRANSITION ) ) && ( NE_16( bwidth, NB ) ) )
1118 : {
1119 : /*reset last pitch reinforcement in case of unvoiced or transitions: it avoids some pitch doublings*/
1120 665678 : *old_thres = 0;
1121 665678 : move16();
1122 : }
1123 :
1124 1154754 : pit_min_coding = PIT_MIN_EXTEND;
1125 1154754 : move16();
1126 1154754 : test();
1127 1154754 : test();
1128 1154754 : test();
1129 1154754 : test();
1130 1154754 : IF( ( ( NE_16( bwidth, NB ) ) && ( GT_16( *old_pitch, PIT_MIN ) ) ) ||
1131 : ( ( EQ_16( bwidth, NB ) ) && ( ( GT_16( *old_pitch, PIT_MIN2_1 ) ) || ( LT_16( *old_thres, 1638 /* 0.1 in Q14*/ ) ) ) ) )
1132 : {
1133 514850 : pit_min = PIT_MIN / OPL_DECIM;
1134 514850 : move16();
1135 514850 : pit_min1 = PIT_MIN_1 / OPL_DECIM;
1136 514850 : move16();
1137 514850 : subsect0 = 2;
1138 514850 : move16();
1139 514850 : sect0 = 1;
1140 514850 : move16();
1141 : }
1142 : ELSE
1143 : {
1144 639904 : pit_min = PIT_MIN2 / OPL_DECIM;
1145 639904 : move16();
1146 639904 : pit_min1 = PIT_MIN2_1 / OPL_DECIM;
1147 639904 : move16();
1148 639904 : subsect0 = 0;
1149 639904 : move16();
1150 639904 : sect0 = 0;
1151 639904 : move16();
1152 : }
1153 :
1154 1154754 : len_x = ( PIT_MAX / OPL_DECIM - pit_min + 1 );
1155 1154754 : move16();
1156 1154754 : len_x1 = ( PIT_MAX / OPL_DECIM - pit_min1 + 1 );
1157 1154754 : move16();
1158 :
1159 : /*--------------------------------------------------------------*
1160 : * Find decimated weighted speech
1161 : * Update wsp buffer with the memory
1162 : * decimation of wsp[] to search pitch in LF and to reduce complexity
1163 : * Extend the decimation of wsp to the end of the speech buffer
1164 : * Update wsp memory
1165 : *--------------------------------------------------------------*/
1166 1154754 : Copy( st_old_wsp2, old_wsp2, ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM );
1167 1154754 : wsp2 = old_wsp2 + ( ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM );
1168 :
1169 1154754 : LP_Decim2_Copy( wsp, wsp2, L_FRAME, mem_decim2 );
1170 :
1171 : /* Avoid uninitialized memory access */
1172 1154754 : set16_fx( wsp2 + L_FRAME / 2, 0, sizeof( old_wsp2 ) / sizeof( Word16 ) - ( ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM ) - L_FRAME / 2 );
1173 1154754 : tmp_mem[0] = mem_decim2[0];
1174 1154754 : move16();
1175 1154754 : tmp_mem[1] = mem_decim2[1];
1176 1154754 : move16();
1177 1154754 : tmp_mem[2] = mem_decim2[2];
1178 1154754 : move16();
1179 :
1180 1154754 : LP_Decim2_Copy( &wsp[L_FRAME], &wsp2[L_FRAME / 2], L_LOOK_12k8, tmp_mem ); /* shr() used instead of division by OPL_DECIM*/
1181 :
1182 1154754 : Copy( &old_wsp2[L_FRAME / 2], st_old_wsp2, ( L_WSP_MEM - L_INTERPOL ) / OPL_DECIM );
1183 :
1184 : /*-----------------------------------------------------------------*
1185 : * Attenuate the correlation correction factor due to noise.
1186 : * Reset correlation buffer outside the useful range.
1187 : * Find the scaling functions for immediate neigbours and
1188 : * further ones.
1189 : *-----------------------------------------------------------------*/
1190 :
1191 1154754 : corr_shift = shr( corr_shift, 1 );
1192 :
1193 1154754 : set16_fx( scaled_buf, 0, DELTA_COH - 1 );
1194 1154754 : set16_fx( scaled_buf + ( DELTA_COH - 1 ) + len_x, 0, DELTA_COH - 1 );
1195 1154754 : set16_fx( scaled_buf + 2 * ( DELTA_COH - 1 ) + len_x + len_x1, 0, DELTA_COH - 1 );
1196 1154754 : set16_fx( scaled_buf_exp, 0, len_x + len_x1 + 3 * ( DELTA_COH - 1 ) );
1197 :
1198 1154754 : pt1 = scale1 + DELTA_COH - 1;
1199 1154754 : pt2 = pt1;
1200 1154754 : tmp16 = mult( *old_thres, -32768 / DELTA_COH ); // Q14
1201 1154754 : k = add( *old_thres, ONE_IN_Q14 ); // Q14
1202 17321310 : FOR( i = 0; i < DELTA_COH; i++ )
1203 : {
1204 16166556 : *pt1 = k; // Q14
1205 16166556 : *pt2-- = *pt1++; // Q14
1206 16166556 : move16();
1207 16166556 : move16();
1208 :
1209 16166556 : k = add( k, tmp16 ); // Q14
1210 : }
1211 :
1212 : /*-----------------------------------------------------------------------------*
1213 : * Estimate the new pitch by extrapolating the old pitch value for 2 half-frames
1214 : *-----------------------------------------------------------------------------*/
1215 1154754 : old_tmp = add( *old_pitch, *delta_pit );
1216 1154754 : old_tmp = s_min( old_tmp, PIT_MAX / OPL_DECIM );
1217 1154754 : old_tmp = s_max( old_tmp, pit_min );
1218 1154754 : old_tmp1 = add( old_tmp, *delta_pit );
1219 1154754 : old_tmp1 = s_min( old_tmp1, PIT_MAX / OPL_DECIM );
1220 1154754 : old_tmp1 = s_max( old_tmp1, pit_min );
1221 :
1222 : /*-----------------------------------------------------------------*
1223 : * Loop for all three half-frames (current frame + look-ahead)
1224 : *-----------------------------------------------------------------*/
1225 1154754 : pt_cor0 = scaled_buf + DELTA_COH - 1;
1226 1154754 : pt_cor0_exp = scaled_buf_exp + DELTA_COH - 1;
1227 :
1228 1154754 : pt_cor2 = pt_cor0 - pit_min + old_tmp;
1229 1154754 : pt_cor2_exp = pt_cor0_exp - pit_min + old_tmp;
1230 :
1231 1154754 : pt_cor4 = pt_cor0 - pit_min1 + old_tmp + ( DELTA_COH - 1 ) + len_x;
1232 1154754 : pt_cor4_exp = pt_cor0_exp - pit_min1 + old_tmp + ( DELTA_COH - 1 ) + len_x;
1233 :
1234 4619016 : FOR( i = 0; i < NHFR; i++ ) /* i = 0, 1, 2 */
1235 : {
1236 3464262 : pt1 = wsp2 + i * 2 * ( L_SUBFR / OPL_DECIM ); /* *pt1 -> Q12 */
1237 3464262 : pt2 = pt1 - pit_min; /* *pt2 -> Q12 */
1238 3464262 : pt4 = pt1 - pit_min1; /* *pt4 -> Q12 */
1239 :
1240 3464262 : temp = 0;
1241 3464262 : move64();
1242 :
1243 3464262 : pt_cor1 = pt_cor0;
1244 3464262 : pt_cor1_exp = pt_cor0_exp;
1245 :
1246 3464262 : pt_cor3 = pt_cor0 + ( DELTA_COH - 1 ) + len_x;
1247 3464262 : pt_cor3_exp = pt_cor0_exp + ( DELTA_COH - 1 ) + len_x;
1248 :
1249 3464262 : IF( LT_16( i, NHFR - 1 ) ) /* First two half-frames (current frame) */
1250 : {
1251 2309508 : pt3 = pt1;
1252 2309508 : pt5 = pt1;
1253 :
1254 10517840 : FOR( j = sect0; j < NSECT; j++ ) /* loop for each section */
1255 : {
1256 : /*-----------------------------------------------------------------*
1257 : * Find fixed vector energy
1258 : *-----------------------------------------------------------------*/
1259 :
1260 : /* 1st set */
1261 8208332 : k = (Word16) ( pt1 - pt3 );
1262 8208332 : move16();
1263 273801752 : FOR( k = add( k, len[j] ); k > 0; k-- )
1264 : {
1265 265593420 : temp = W_mac0_16_16( temp, *pt3, *pt3 ); // 2*qwsp
1266 265593420 : pt3++;
1267 : }
1268 8208332 : IF( temp == 0 )
1269 : {
1270 545509 : enr0[j] = 21474836; // 0.01 in Q31
1271 545509 : enr0_exp[j] = 0;
1272 545509 : move32();
1273 545509 : move16();
1274 : }
1275 : ELSE
1276 : {
1277 7662823 : cnt = W_norm( temp );
1278 7662823 : enr0[j] = W_extract_h( W_shl( temp, cnt ) ); // 2*qwsp+cnt-32
1279 7662823 : enr0_exp[j] = sub( new_q, cnt ); // 31-(2*qwsp+cnt-32)
1280 7662823 : move32();
1281 7662823 : move16();
1282 : }
1283 :
1284 : /* Reduce complexity (length of 'enr2' section is equal or larger than 'enr') */
1285 8208332 : pt5 = pt3;
1286 :
1287 : /* 2nd set */
1288 8208332 : k = (Word16) ( pt1 - pt5 );
1289 8208332 : move16();
1290 :
1291 8208332 : temp1 = temp;
1292 8208332 : move64();
1293 72874556 : FOR( k = ( k + len1[j] ); k > 0; k-- )
1294 : {
1295 64666224 : temp1 = W_mac0_16_16( temp1, *pt5, *pt5 ); // 2*qwsp
1296 64666224 : pt5++;
1297 : }
1298 8208332 : IF( temp1 == 0 )
1299 : {
1300 545011 : enr0_1[j] = 21474836; // 0.01 in Q31
1301 545011 : enr0_1_exp[j] = 0;
1302 545011 : move32();
1303 545011 : move16();
1304 : }
1305 : ELSE
1306 : {
1307 7663321 : cnt = W_norm( temp1 );
1308 7663321 : enr0_1[j] = W_extract_h( W_shl( temp1, cnt ) ); // 2*qwsp+cnt-32
1309 7663321 : enr0_1_exp[j] = sub( new_q, cnt ); // 31-(2*qwsp+cnt-32)
1310 7663321 : move32();
1311 7663321 : move16();
1312 : }
1313 : }
1314 :
1315 : /*----------------------------------------------------------*
1316 : * Find correlation for the non-overlapping pitch lag values
1317 : *----------------------------------------------------------*/
1318 :
1319 2309508 : k = (Word16) ( pt2 - pt1 + pit_max[subsect0] );
1320 2309508 : move16();
1321 :
1322 10017624 : FOR( ; k >= 0; k-- )
1323 : {
1324 7708116 : temp = 0;
1325 7708116 : move64();
1326 316032756 : FOR( m = 0; m < sublen[0]; m++ )
1327 : {
1328 308324640 : temp = W_mac0_16_16( temp, pt1[m], pt2[m] ); // 2*qwsp
1329 : }
1330 7708116 : cnt = W_norm( temp );
1331 7708116 : *pt_cor1 = extract_h( W_extract_h( W_shl( temp, cnt ) ) ); // 2*qwsp+cnt-32-16
1332 7708116 : *pt_cor1_exp = sub( new_q, cnt ); // 15-(2*qwsp+cnt-32-16)
1333 7708116 : move16();
1334 7708116 : move16();
1335 :
1336 7708116 : pt2--;
1337 7708116 : pt_cor1++;
1338 7708116 : pt_cor1_exp++;
1339 : }
1340 :
1341 : /*----------------------------------------------------------*
1342 : * For each subsection, find the correlation
1343 : *----------------------------------------------------------*/
1344 16416664 : FOR( j = subsect0; j < NSUBSECT; j++ )
1345 : {
1346 14107156 : len_temp = sublen[j];
1347 14107156 : move16();
1348 :
1349 14107156 : k = (Word16) ( pt2 - pt1 );
1350 14107156 : move16();
1351 14107156 : k = add( k, pit_max[j + 1] );
1352 :
1353 : /* Keep Q15 normalized result */
1354 14107156 : IF( LT_16( sublen[j], sublen1[j] ) )
1355 : {
1356 76213764 : FOR( ; k >= 0; k-- )
1357 : {
1358 71594748 : temp = W_mult0_16_16( pt1[0], pt2[0] ); // 2*qwsp
1359 3930782616 : FOR( m = 1; m < sublen[j]; m++ )
1360 : {
1361 3859187868 : temp = W_mac0_16_16( temp, pt1[m], pt2[m] ); // 2*qwsp
1362 : }
1363 71594748 : cnt = W_norm( temp );
1364 71594748 : *pt_cor1 = extract_h( W_extract_h( W_shl( temp, cnt ) ) ); // 2*qwsp+cnt-32-16
1365 71594748 : *pt_cor1_exp = sub( new_q, cnt );
1366 71594748 : move16();
1367 71594748 : move16();
1368 :
1369 1175539572 : FOR( ; m < sublen1[j]; m++ )
1370 : {
1371 1103944824 : temp = W_mac0_16_16( temp, pt1[m], pt2[m] ); // 2*qwsp
1372 : }
1373 71594748 : cnt = W_norm( temp );
1374 71594748 : *pt_cor3 = extract_h( W_extract_h( W_shl( temp, cnt ) ) ); // 2*qwsp+cnt-32-16
1375 71594748 : *pt_cor3_exp = sub( new_q, cnt );
1376 71594748 : move16();
1377 71594748 : move16();
1378 :
1379 71594748 : pt_cor1++;
1380 71594748 : pt_cor1_exp++;
1381 71594748 : pt_cor3++;
1382 71594748 : pt_cor3_exp++;
1383 71594748 : pt2--;
1384 : }
1385 : }
1386 : ELSE
1387 : {
1388 167785224 : FOR( ; k >= 0; k-- )
1389 : {
1390 158297084 : temp = W_mult0_16_16( pt1[0], pt2[0] ); // 2*qwsp
1391 14599922000 : FOR( m = 1; m < sublen1[j]; m++ )
1392 : {
1393 14441624916 : temp = W_mac0_16_16( temp, pt1[m], pt2[m] ); // 2*qwsp
1394 : }
1395 158297084 : cnt = W_norm( temp );
1396 158297084 : *pt_cor3 = extract_h( W_extract_h( W_shl( temp, cnt ) ) ); // 2*qwsp+cnt-32-16
1397 158297084 : *pt_cor3_exp = sub( new_q, cnt );
1398 158297084 : move16();
1399 158297084 : move16();
1400 :
1401 1701048428 : FOR( ; m < sublen[j]; m++ )
1402 : {
1403 1542751344 : temp = W_mac0_16_16( temp, pt1[m], pt2[m] ); // 2*qwsp
1404 : }
1405 158297084 : cnt = W_norm( temp );
1406 158297084 : *pt_cor1 = extract_h( W_extract_h( W_shl( temp, cnt ) ) ); // 2*qwsp+cnt-32-16
1407 158297084 : *pt_cor1_exp = sub( new_q, cnt );
1408 158297084 : move16();
1409 158297084 : move16();
1410 :
1411 158297084 : pt_cor1++;
1412 158297084 : pt_cor1_exp++;
1413 158297084 : pt_cor3++;
1414 158297084 : pt_cor3_exp++;
1415 158297084 : pt2--;
1416 : }
1417 : }
1418 : } /* FOR (j = subsect0; ... */
1419 : }
1420 : ELSE /* 3rd half-frame (look-ahead) */
1421 : {
1422 1154754 : pt6 = pt1 + L_LOOK_12k8 / OPL_DECIM - 1;
1423 1154754 : pt3 = pt6;
1424 1154754 : pt5 = pt6;
1425 :
1426 : /*-----------------------------------------------------------------*
1427 : * For each section in both sets, find fixed vector energy
1428 : *-----------------------------------------------------------------*/
1429 5258920 : FOR( j = sect0; j < NSECT; j++ ) /* loop for each section */
1430 : {
1431 : /* 1st set */
1432 4104166 : k = (Word16) ( pt3 - pt6 );
1433 4104166 : move16();
1434 :
1435 136900876 : FOR( k = add( k, len[j] ); k > 0; k-- )
1436 : {
1437 132796710 : temp = W_mac0_16_16( temp, *pt3, *pt3 );
1438 132796710 : pt3--;
1439 : }
1440 4104166 : IF( temp == 0 )
1441 : {
1442 264285 : enr0[j] = 21474836; // 0.01 in Q31
1443 264285 : enr0_exp[j] = 0;
1444 264285 : move32();
1445 264285 : move16();
1446 : }
1447 : ELSE
1448 : {
1449 3839881 : cnt = W_norm( temp );
1450 3839881 : enr0[j] = W_extract_h( W_shl( temp, cnt ) ); // 2*qwsp+cnt-32
1451 3839881 : enr0_exp[j] = sub( new_q, cnt ); // 31-(2*qwsp+cnt-32)
1452 3839881 : move32();
1453 3839881 : move16();
1454 : }
1455 :
1456 : /* Reduce complexity (length of 'enr2' section is equal or larger than 'enr') */
1457 4104166 : pt5 = pt3;
1458 4104166 : temp1 = temp;
1459 4104166 : move64();
1460 :
1461 : /* 2nd set */
1462 4104166 : k = (Word16) ( pt5 - pt6 );
1463 4104166 : move16();
1464 36437278 : FOR( k = add( k, len1[j] ); k > 0; k-- )
1465 : {
1466 32333112 : temp1 = W_mac0_16_16( temp1, *pt5, *pt5 ); // 2*qwsp
1467 32333112 : pt5--;
1468 : }
1469 4104166 : IF( temp1 == 0 )
1470 : {
1471 264075 : enr0_1[j] = 21474836; // 0.01 in Q31
1472 264075 : enr0_1_exp[j] = 0;
1473 264075 : move32();
1474 264075 : move16();
1475 : }
1476 : ELSE
1477 : {
1478 3840091 : cnt = W_norm( temp1 );
1479 3840091 : temp1 = W_shl( temp1, cnt ); // 2*qwsp+cnt
1480 3840091 : enr0_1[j] = W_extract_h( temp1 ); // 2*qwsp+cnt-32
1481 3840091 : enr0_1_exp[j] = sub( new_q, cnt ); // 31-(2*qwsp+cnt-32)
1482 3840091 : move32();
1483 3840091 : move16();
1484 : }
1485 : }
1486 :
1487 : /* Set pointers: same as IF/ELSE block */
1488 1154754 : pt2 = pt6 - pit_min;
1489 1154754 : k = 2;
1490 1154754 : move16();
1491 1154754 : IF( sect0 != 0 )
1492 : {
1493 514850 : pt2 = pt6 - add( pit_max[1], 1 );
1494 514850 : k = sub( pit_max[2], pit_max[1] );
1495 514850 : move16();
1496 : }
1497 :
1498 : /*-----------------------------------------------------------------*
1499 : * Find correlation for the non-overlapping pitch lag values
1500 : *-----------------------------------------------------------------*/
1501 :
1502 1154754 : len_temp = sublen[0];
1503 1154754 : move16();
1504 :
1505 5008812 : FOR( ; k > 0; k-- )
1506 : {
1507 3854058 : temp = 0;
1508 3854058 : move64();
1509 158016378 : FOR( m = 0; m < len_temp; m++ )
1510 : {
1511 154162320 : temp = W_mac0_16_16( temp, pt6[-m], pt2[-m] ); // 2*qwsp
1512 : }
1513 3854058 : tmp16_2 = W_norm( temp );
1514 3854058 : *pt_cor1 = extract_h( W_extract_h( W_shl( temp, tmp16_2 ) ) ); // 2*qwsp+tmp16_2
1515 3854058 : *pt_cor1_exp = sub( new_q, tmp16_2 ); // 2*qwsp+tmp16_2-32-16
1516 3854058 : move16();
1517 3854058 : move16();
1518 :
1519 3854058 : pt_cor1++;
1520 3854058 : pt_cor1_exp++;
1521 3854058 : pt2--;
1522 : }
1523 :
1524 : /*-----------------------------------------------------------------*
1525 : * For each subsection, find the correlation (overlapping pitch lag values)
1526 : *-----------------------------------------------------------------*/
1527 :
1528 8208332 : FOR( j = subsect0; j < NSUBSECT; j++ )
1529 : {
1530 7053578 : k = sub( pit_max[j + 1], pit_max[j] );
1531 :
1532 7053578 : IF( LT_16( sublen[j], sublen1[j] ) )
1533 : {
1534 38106882 : FOR( ; k > 0; k-- )
1535 : {
1536 35797374 : temp = W_mult0_16_16( pt6[0], pt2[0] ); // 2*qwsp
1537 1965391308 : FOR( m = 1; m < sublen[j]; m++ )
1538 : {
1539 1929593934 : temp = W_mac0_16_16( temp, pt6[-m], pt2[-m] ); // 2*qwsp
1540 : }
1541 35797374 : cnt = W_norm( temp );
1542 35797374 : *pt_cor1 = extract_h( W_extract_h( W_shl( temp, cnt ) ) ); // 2*qwsp+cnt-32-16
1543 35797374 : *pt_cor1_exp = sub( new_q, cnt );
1544 35797374 : move16();
1545 35797374 : move16();
1546 :
1547 587769786 : FOR( ; m < sublen1[j]; m++ )
1548 : {
1549 551972412 : temp = W_mac0_16_16( temp, pt6[-m], pt2[-m] ); // 2*qwsp
1550 : }
1551 35797374 : cnt = W_norm( temp );
1552 35797374 : *pt_cor3 = extract_h( W_extract_h( W_shl( temp, cnt ) ) ); // 2*qwsp+cnt-32-16
1553 35797374 : *pt_cor3_exp = sub( new_q, cnt );
1554 35797374 : move16();
1555 35797374 : move16();
1556 :
1557 35797374 : pt_cor1++;
1558 35797374 : pt_cor1_exp++;
1559 35797374 : pt_cor3++;
1560 35797374 : pt_cor3_exp++;
1561 35797374 : pt2--;
1562 : }
1563 : }
1564 : ELSE
1565 : {
1566 83892612 : FOR( ; k > 0; k-- )
1567 : {
1568 79148542 : temp = W_mult0_16_16( pt6[0], pt2[0] ); // 2*qwsp
1569 7299961000 : FOR( m = 1; m < sublen1[j]; m++ )
1570 : {
1571 7220812458 : temp = W_mac0_16_16( temp, pt6[-m], pt2[-m] ); // 2*qwsp
1572 : }
1573 79148542 : cnt = W_norm( temp );
1574 79148542 : *pt_cor3 = extract_h( W_extract_h( W_shl( temp, cnt ) ) ); // 2*qwsp+cnt-32-16
1575 79148542 : *pt_cor3_exp = sub( new_q, cnt );
1576 79148542 : move16();
1577 79148542 : move16();
1578 :
1579 850524214 : FOR( ; m < sublen[j]; m++ )
1580 : {
1581 771375672 : temp = W_mac0_16_16( temp, pt6[-m], pt2[-m] ); // 2*qwsp
1582 : }
1583 79148542 : cnt = W_norm( temp );
1584 79148542 : *pt_cor1 = extract_h( W_extract_h( W_shl( temp, cnt ) ) ); // 2*qwsp+cnt-32-16
1585 79148542 : *pt_cor1_exp = sub( new_q, cnt );
1586 79148542 : move16();
1587 79148542 : move16();
1588 :
1589 79148542 : pt_cor1++;
1590 79148542 : pt_cor1_exp++;
1591 79148542 : pt_cor3++;
1592 79148542 : pt_cor3_exp++;
1593 79148542 : pt2--;
1594 : }
1595 : }
1596 : }
1597 : } /* 3rd half-frame (look-ahead) */
1598 :
1599 : /* Scale all values in each section to the same exponent for upcoming Find_max() */
1600 3464262 : Copy( pt_cor0, cor_buf, len_x ); /* Save unscaled correlation vector */
1601 3464262 : Copy( pt_cor0_exp, cor_buf_exp, len_x ); /* Save unscaled correlation vector */
1602 3464262 : Copy( pt_cor0 + ( DELTA_COH - 1 ) + len_x, cor_buf + len_x, len_x1 );
1603 3464262 : Copy( pt_cor0_exp + ( DELTA_COH - 1 ) + len_x, cor_buf_exp + len_x, len_x1 );
1604 :
1605 : /*-----------------------------------------------------------------*
1606 : * Scale correlation function in the neighbourhood of
1607 : * the extrapolated pitch
1608 : *-----------------------------------------------------------------*/
1609 3464262 : pt_cor1 = pt_cor2 - ( DELTA_COH - 1 );
1610 3464262 : pt_cor1_exp = pt_cor2_exp - ( DELTA_COH - 1 );
1611 3464262 : pt_cor3 = pt_cor4 - ( DELTA_COH - 1 );
1612 3464262 : pt_cor3_exp = pt_cor4_exp - ( DELTA_COH - 1 );
1613 3464262 : pt2 = scale1;
1614 :
1615 96999336 : FOR( k = 0; k < 2 * DELTA_COH - 1; k++ )
1616 : {
1617 93535074 : *pt_cor1 = mult( *pt_cor1, *pt2 ); // *pt_cor1_exp+1
1618 93535074 : *pt_cor1_exp = add( *pt_cor1_exp, 1 ); // *pt_cor1_exp+1
1619 93535074 : move16();
1620 93535074 : move16();
1621 :
1622 93535074 : *pt_cor3 = mult( *pt_cor3, *pt2++ ); // *pt_cor3_exp+1
1623 93535074 : *pt_cor3_exp = add( *pt_cor3_exp, 1 ); // *pt_cor1_exp+1
1624 93535074 : move16();
1625 93535074 : move16();
1626 :
1627 93535074 : pt_cor1++;
1628 93535074 : pt_cor1_exp++;
1629 93535074 : pt_cor3++;
1630 93535074 : pt_cor3_exp++;
1631 : }
1632 :
1633 : /* Update for next half-frame & look-ahead */
1634 3464262 : pt_cor2 = pt_cor0 - pit_min + old_tmp1;
1635 3464262 : pt_cor2_exp = pt_cor0_exp - pit_min + old_tmp1;
1636 :
1637 3464262 : pt_cor4 = pt_cor0 - pit_min1 + old_tmp1 + ( DELTA_COH - 1 ) + len_x;
1638 3464262 : pt_cor4_exp = pt_cor0_exp - pit_min1 + old_tmp1 + ( DELTA_COH - 1 ) + len_x;
1639 :
1640 : /*-----------------------------------------------------------------*
1641 : * For each section, find maximum correlation and compute
1642 : * normalized correlation
1643 : *-----------------------------------------------------------------*/
1644 :
1645 3464262 : pt_cor1 = pt_cor0;
1646 3464262 : pt_cor1_exp = pt_cor0_exp;
1647 3464262 : offset = 0;
1648 3464262 : move16();
1649 3464262 : pt_cor3 = pt_cor0 + ( DELTA_COH - 1 ) + len_x;
1650 3464262 : pt_cor3_exp = pt_cor0_exp + ( DELTA_COH - 1 ) + len_x;
1651 3464262 : offset1 = 0;
1652 3464262 : move16();
1653 :
1654 15776760 : FOR( j = sect0; j < NSECT; j++ ) /* loop for each section */
1655 : {
1656 : /* 1st set */
1657 12312498 : offset_la = 0;
1658 12312498 : move16();
1659 12312498 : if ( EQ_16( i, 2 ) )
1660 : {
1661 4104166 : offset_la = sub( L_LOOK_12k8 / OPL_DECIM, len[j] );
1662 : }
1663 :
1664 : /* 2nd set */
1665 12312498 : offset_la1 = 0;
1666 12312498 : move16();
1667 12312498 : if ( EQ_16( i, 2 ) )
1668 : {
1669 4104166 : offset_la1 = sub( L_LOOK_12k8 / OPL_DECIM, len1[j] );
1670 : }
1671 :
1672 : /* 1st set of candidates */
1673 12312498 : ind = add( maximum_exp_fx( pt_cor1, pt_cor1_exp, sec_length[j] ), offset );
1674 12312498 : pitchX[i][j] = add( ind, pit_min );
1675 12312498 : move16();
1676 12312498 : pt2 = pt1 - pitchX[i][j] + /*-*/ offset_la; /* selected moving vector */
1677 :
1678 12312498 : enr1_exp = 0;
1679 12312498 : move16();
1680 :
1681 : /* enr1 = dotp( pt2, pt2, len[j] ) + 0.01f; */
1682 12312498 : temp = 0;
1683 12312498 : move64();
1684 840845832 : FOR( m = 0; m < len[j]; m++ )
1685 : {
1686 828533334 : temp = W_mac0_16_16( temp, pt2[m], pt2[m] ); // 2*qwsp
1687 : }
1688 :
1689 12312498 : temp = W_shl( temp, sub( Q24, shl( qwsp, 1 ) ) ); // Q24
1690 :
1691 12312498 : temp = W_add( temp, 167772 ); /*0.01f in Q24*/
1692 :
1693 12312498 : enr1_exp = W_norm( temp );
1694 12312498 : enr1 = W_extract_h( W_shl( temp, enr1_exp ) ); // enr1_exp+24-32
1695 12312498 : enr1_exp = sub( 39, enr1_exp ); // 31-(enr1_exp+24-32)
1696 :
1697 12312498 : enr1 = Mpy_32_32( enr0[j], enr1 );
1698 12312498 : enr1_exp = add( enr0_exp[j], enr1_exp );
1699 :
1700 12312498 : enr1 = ISqrt32( enr1, &enr1_exp ); /* 1/sqrt(energy) */ /*31-enr2_exp*/
1701 :
1702 12312498 : Ltmp = Mpy_32_16_1( enr1, cor_buf[ind] );
1703 12312498 : corX[i][j] = extract_h( L_shl_sat( Ltmp, add( enr1_exp, cor_buf_exp[ind] ) ) ); // Q15
1704 12312498 : move16();
1705 :
1706 12312498 : Ltmp = Mpy_32_16_1( enr1, pt_cor0[ind] );
1707 12312498 : scaledX[i][j] = round_fx( L_shl( Ltmp, sub( add( enr1_exp, pt_cor0_exp[ind] ), 3 ) ) ); // Q12
1708 12312498 : move16();
1709 :
1710 12312498 : pt_cor1 += sec_length[j];
1711 12312498 : pt_cor1_exp += sec_length[j];
1712 12312498 : offset = add( offset, sec_length[j] );
1713 :
1714 : /* 2nd set of candidates */
1715 12312498 : ind1 = add( maximum_exp_fx( pt_cor3, pt_cor3_exp, sec_length1[j] ), offset1 );
1716 12312498 : pitchX[i][j + NSECT] = add( ind1, pit_min1 );
1717 12312498 : move16();
1718 12312498 : pt4 = pt1 - pitchX[i][j + NSECT] + /*-*/ offset_la1;
1719 12312498 : move16(); /* selected moving vector */
1720 12312498 : enr1_exp = 0;
1721 12312498 : move16();
1722 :
1723 : /* enr1 = dotp(pt4, pt4, len1[j]) + 0.01f; */
1724 12312498 : temp = 0;
1725 12312498 : move64();
1726 12312498 : move64();
1727 937845168 : FOR( m = 0; m < len1[j]; m++ )
1728 : {
1729 925532670 : temp = W_mac0_16_16( temp, pt4[m], pt4[m] ); // 2*qwsp
1730 : }
1731 :
1732 12312498 : temp = W_shl( temp, sub( Q24, shl( qwsp, 1 ) ) ); // Q24
1733 :
1734 12312498 : temp = W_add( temp, 167772 ); /*0.01f in Q24*/
1735 :
1736 12312498 : enr1_exp = W_norm( temp );
1737 12312498 : enr1 = W_extract_h( W_shl( temp, enr1_exp ) ); // enr1_exp+24-32
1738 12312498 : enr1_exp = sub( 39, enr1_exp ); // 31-(enr1_exp+24-32)
1739 :
1740 12312498 : enr1 = Mpy_32_32( enr0_1[j], enr1 );
1741 12312498 : enr1_exp = add( enr0_1_exp[j], enr1_exp );
1742 :
1743 12312498 : enr1 = ISqrt32( enr1, &enr1_exp ); /* 1/sqrt(energy) */ /*31-enr1_exp*/
1744 :
1745 12312498 : Ltmp = Mpy_32_16_1( enr1, cor_buf[ind1 + len_x] );
1746 12312498 : corX[i][j + NSECT] = extract_h( L_shl_sat( Ltmp, add( enr1_exp, cor_buf_exp[ind1 + len_x] ) ) ); // Q15
1747 12312498 : move16();
1748 :
1749 12312498 : Ltmp = Mpy_32_16_1( enr1, pt_cor0[ind1 + ( DELTA_COH - 1 ) + len_x] );
1750 12312498 : scaledX[i][j + NSECT] = round_fx( L_shl( Ltmp, sub( add( enr1_exp, pt_cor0_exp[ind1 + ( DELTA_COH - 1 ) + len_x] ), 3 ) ) ); // Q12
1751 12312498 : move16();
1752 : /*scaledX[i][j+NSECT] = saturate(L_shr(Ltmp, qScaledX-12));*/
1753 :
1754 12312498 : pt_cor3 += sec_length1[j];
1755 12312498 : pt_cor3_exp += sec_length1[j];
1756 12312498 : offset1 = add( offset1, sec_length1[j] );
1757 :
1758 : } /* FOR j < NSECT */
1759 : } /* FOR i < NHFR */
1760 :
1761 : /*-----------------------------------------------------------------*
1762 : * Favor a smaller delay if it happens that it has its multiple
1763 : * in the longer-delay sections (harmonics check)
1764 : *-----------------------------------------------------------------*/
1765 :
1766 3464262 : FOR( i = 0; i < 2; i++ ) /* loop for the 2 half-frames */
1767 : {
1768 2309508 : fac = THRES0;
1769 2309508 : move16();
1770 2309508 : find_mult_fx( &fac, pitchX[i][2], pitchX[i][3], pit_max[7], &scaledX[i][2], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 3rd section */
1771 2309508 : find_mult_fx( &fac, pitchX[i][1], pitchX[i][2], pit_max[5], &scaledX[i][1], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
1772 2309508 : test();
1773 2309508 : IF( ( sect0 == 0 ) && GE_16( shl( pitchX[i][0], 1 ), pit_min_coding ) )
1774 : {
1775 1279808 : find_mult_fx( &fac, pitchX[i][0], pitchX[i][1], pit_max[3], &scaledX[i][0], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
1776 : }
1777 2309508 : fac = THRES0;
1778 2309508 : move16();
1779 2309508 : find_mult_fx( &fac, pitchX[i][NSECT + 2], pitchX[i][NSECT + 3], pit_max[7], &scaledX[i][NSECT + 2], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 3rd section */
1780 2309508 : find_mult_fx( &fac, pitchX[i][NSECT + 1], pitchX[i][NSECT + 2], pit_max[6], &scaledX[i][NSECT + 1], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
1781 2309508 : test();
1782 2309508 : IF( ( sect0 == 0 ) && GE_16( shl( pitchX[i][NSECT + 0], 1 ), pit_min_coding ) )
1783 : {
1784 1279808 : find_mult_fx( &fac, pitchX[i][NSECT + 0], pitchX[i][NSECT + 1], pit_max[4], &scaledX[i][NSECT + 0], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
1785 : }
1786 : }
1787 :
1788 1154754 : fac = THRES0;
1789 1154754 : move16(); /* the look-ahead */
1790 1154754 : find_mult_fx( &fac, pitchX[i][2], pitchX[i][3], pit_max[7], &scaledX[i][2], old_pitch, old_corr, 2, 2 ); /* Multiples in 3rd section */
1791 1154754 : find_mult_fx( &fac, pitchX[i][1], pitchX[i][2], pit_max[5], &scaledX[i][1], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
1792 1154754 : test();
1793 1154754 : IF( ( sect0 == 0 ) && GE_16( shl( pitchX[i][0], 1 ), pit_min_coding ) )
1794 : {
1795 639904 : find_mult_fx( &fac, pitchX[i][0], pitchX[i][1], pit_max[3], &scaledX[i][0], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
1796 : }
1797 1154754 : fac = THRES0;
1798 1154754 : move16();
1799 1154754 : find_mult_fx( &fac, pitchX[i][NSECT + 2], pitchX[i][NSECT + 3], pit_max[7], &scaledX[i][NSECT + 2], old_pitch, old_corr, 2, 2 ); /* Multiples in 3rd section */
1800 1154754 : find_mult_fx( &fac, pitchX[i][NSECT + 1], pitchX[i][NSECT + 2], pit_max[6], &scaledX[i][NSECT + 1], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */
1801 1154754 : test();
1802 1154754 : IF( ( sect0 == 0 ) && GE_16( shl( pitchX[i][NSECT + 0], 1 ), pit_min_coding ) )
1803 : {
1804 639904 : find_mult_fx( &fac, pitchX[i][NSECT + 0], pitchX[i][NSECT + 1], pit_max[4], &scaledX[i][NSECT + 0], old_pitch, old_corr, DELTA0, STEP ); /* Multiples in 2nd section */ /* Multiples in 2nd section */
1805 : }
1806 :
1807 : /*-----------------------------------------------------------------*
1808 : * Do 1st estimate for pitch values
1809 : * Adjust the normalized correlation using estimated noise level
1810 : * Compute the maximum scaling for the neighbour correlation
1811 : * reinforcement
1812 : *-----------------------------------------------------------------*/
1813 1154754 : add_sect0 = add( NSECT, sect0 );
1814 1154754 : sub_sect0 = sub( NSECT, sect0 );
1815 4619016 : FOR( i = 0; i < NHFR; i++ )
1816 : {
1817 : /* 1st set of pitch candidates */
1818 3464262 : ind = add( maximum_fx( scaledX[i] + sect0, sub_sect0, &ftmp ), sect0 );
1819 3464262 : ind_tmp[i] = ind;
1820 3464262 : move16();
1821 3464262 : pitch_tmp[i] = pitchX[i][ind];
1822 3464262 : move16();
1823 3464262 : cor_tmp[i] = add_sat( corX[i][ind], corr_shift );
1824 3464262 : move16();
1825 :
1826 : /* Higher is the neighbour's correlation, higher is the weighting */
1827 : /* operands are Q15, result is Q15 */
1828 3464262 : thres1[i] = mult( THRES1, cor_tmp[i] );
1829 3464262 : move16();
1830 :
1831 : /* 2nd set of pitch candidates */
1832 3464262 : ind1 = add( maximum_fx( scaledX[i] + add_sect0, sub_sect0, &ftmp ), add_sect0 );
1833 3464262 : ind_tmp[i + NHFR] = ind1;
1834 3464262 : move16();
1835 3464262 : pitch_tmp[i + NHFR] = pitchX[i][ind1];
1836 3464262 : move16();
1837 3464262 : cor_tmp[i + NHFR] = add_sat( corX[i][ind1], corr_shift );
1838 3464262 : move16();
1839 :
1840 : /* Higher is the neighbour's correlation, higher is the weighting */
1841 : /* operands are Q15, result is Q15 */
1842 3464262 : thres1[i + NHFR] = mult( THRES1, cor_tmp[i + NHFR] );
1843 3464262 : move16();
1844 : }
1845 : /*-----------------------------------------------------------------*
1846 : * Take into account previous and next pitch values of the present
1847 : * frame and look-ahead. Choose the pitch lags and normalize
1848 : * correlations for each half-frame & look-ahead
1849 : *-----------------------------------------------------------------*/
1850 :
1851 1154754 : pitch_neighbour_fx( sect0, pitch_tmp, pitchX, cor_tmp, scaledX, thres1, ind_tmp );
1852 4619016 : FOR( i = 0; i < NHFR; i++ )
1853 : {
1854 3464262 : ind = add( maximum_fx( scaledX[i] + sect0, sub_sect0, &ftmp ), sect0 );
1855 3464262 : ind_corX = add( maximum_fx( corX[i] + sect0, sub_sect0, &ftmp ), sect0 );
1856 :
1857 3464262 : ind1 = add( maximum_fx( scaledX[i] + add_sect0, sub_sect0, &ftmp ), add_sect0 );
1858 3464262 : ind1_corX = add( maximum_fx( corX[i] + add_sect0, sub_sect0, &ftmp ), add_sect0 );
1859 :
1860 3464262 : if ( GT_16( scaledX[i][ind1], scaledX[i][ind] ) )
1861 : {
1862 1383773 : ind = ind1;
1863 1383773 : move16();
1864 : }
1865 3464262 : test();
1866 3464262 : if ( Opt_SC_VBR && GT_16( corX[i][ind1_corX], corX[i][ind_corX] ) )
1867 : {
1868 0 : ind_corX = ind1_corX;
1869 0 : move16();
1870 : }
1871 3464262 : test();
1872 3464262 : test();
1873 3464262 : test();
1874 3464262 : IF( Opt_SC_VBR && ( LT_16( mult( pitchX[i][ind], 13107 /*0.4 in Q15*/ ), pitchX[i][ind_corX] ) ) &&
1875 : ( GT_16( mult( pitchX[i][ind], 19661 /*0.6 in Q15*/ ), pitchX[i][ind_corX] ) ) &&
1876 : ( GE_16( corX[i][ind_corX], 29491 /*0.9 in Q15*/ ) ) )
1877 : {
1878 0 : pitch[i] = pitchX[i][ind_corX];
1879 0 : move16();
1880 0 : voicing[i] = corX[i][ind_corX];
1881 0 : move16();
1882 : }
1883 : ELSE
1884 : {
1885 3464262 : pitch[i] = pitchX[i][ind];
1886 3464262 : move16();
1887 3464262 : voicing[i] = corX[i][ind];
1888 3464262 : move16();
1889 : }
1890 : }
1891 :
1892 : /*-----------------------------------------------------------------*
1893 : * Increase the threshold for correlation reinforcement with
1894 : * the past if correlation high and pitch stable
1895 : *-----------------------------------------------------------------*/
1896 :
1897 : /* all Q15 here */
1898 : /* cor_mean = 0.5f * (voicing[0] + voicing[1]) + corr_shift; */
1899 1154754 : Ltmp = L_mult( voicing[0], 16384 /*.5 Q15*/ );
1900 1154754 : Ltmp = L_mac( Ltmp, voicing[1], 16384 /*.5 Q15*/ );
1901 1154754 : cor_mean = round_fx( L_add( Ltmp, corr_shift ) );
1902 :
1903 : /* pitch unstable in present frame or from previous frame or normalized correlation too low */
1904 1154754 : coh_flag = pitch_coherence_fx( pitch[0], pitch[1], COH_FAC, DELTA_COH );
1905 1154754 : move16();
1906 1154754 : coh_flag1 = pitch_coherence_fx( pitch[0], *old_pitch, COH_FAC, DELTA_COH );
1907 1154754 : move16();
1908 :
1909 1154754 : test();
1910 1154754 : test();
1911 1154754 : test();
1912 1154754 : IF( ( coh_flag == 0 ) || ( coh_flag1 == 0 ) || ( LT_16( cor_mean, CORR_TH0 ) ) || ( LT_16( relE, THR_relE ) ) )
1913 : {
1914 : /* Reset the threshold */
1915 635456 : *old_thres = 0;
1916 635456 : move16();
1917 : }
1918 : ELSE
1919 : {
1920 : /* The threshold increase is directly dependent on normalized correlation */
1921 : /* *old_thres += (0.16f * cor_mean); */
1922 519298 : *old_thres = round_fx( L_mac0( L_deposit_h( *old_thres ), 5243 /* 0.16f in Q15 */, cor_mean ) ); // Q14
1923 519298 : move16();
1924 : }
1925 :
1926 1154754 : *old_thres = s_min( *old_thres, 11469 /* 0.7f in Q14 */ ); // Q14
1927 1154754 : move16();
1928 :
1929 1154754 : IF( GT_16( voicing[1], voicing[0] ) )
1930 : {
1931 554331 : *old_corr = voicing[1];
1932 554331 : move16();
1933 : }
1934 : ELSE
1935 : {
1936 600423 : *old_corr = cor_mean;
1937 600423 : move16();
1938 : }
1939 :
1940 : /*-----------------------------------------------------------------*
1941 : * Extrapolate the pitch value for the next frame by estimating
1942 : * the pitch evolution. This value is added to the old_pitch
1943 : * in the next frame and is then used when the normalized
1944 : * correlation is reinforced by the past estimate
1945 : *-----------------------------------------------------------------*/
1946 1154754 : tmp_buf[0] = *old_pitch;
1947 1154754 : move16();
1948 4619016 : FOR( i = 0; i < NHFR; i++ )
1949 : {
1950 3464262 : tmp_buf[i + 1] = pitch[i];
1951 3464262 : move16();
1952 : }
1953 :
1954 1154754 : *delta_pit = 0;
1955 1154754 : move16();
1956 1154754 : cnt = 0;
1957 1154754 : move16();
1958 :
1959 4619016 : FOR( i = 0; i < NHFR; i++ )
1960 : {
1961 3464262 : diff = sub( tmp_buf[i + 1], tmp_buf[i] );
1962 3464262 : move16();
1963 3464262 : coh_flag = pitch_coherence_fx( tmp_buf[i], tmp_buf[i + 1], COH_FAC, DELTA_COH );
1964 :
1965 3464262 : if ( coh_flag != 0 )
1966 : {
1967 2532416 : *delta_pit = add( *delta_pit, diff );
1968 2532416 : move16();
1969 : }
1970 3464262 : cnt = add( cnt, coh_flag );
1971 : }
1972 1154754 : if ( EQ_16( cnt, 2 ) )
1973 : {
1974 : /* *delta_pit /= 2; */
1975 269720 : *delta_pit = shr( *delta_pit, 1 );
1976 269720 : move16();
1977 : }
1978 1154754 : IF( EQ_16( cnt, 3 ) )
1979 : {
1980 602231 : k = *delta_pit;
1981 602231 : move16();
1982 : /* *delta_pit /= 3; */
1983 602231 : if ( k < 0 )
1984 : {
1985 139527 : *delta_pit = mult( *delta_pit, -32768 /*-1 Q15*/ );
1986 139527 : move16();
1987 : }
1988 602231 : tmp16 = mult( *delta_pit, 10923 /*1/3 Q15*/ );
1989 602231 : if ( k < 0 )
1990 : {
1991 139527 : tmp16 = mult( tmp16, -32768 /*-1 Q15*/ );
1992 : }
1993 602231 : *delta_pit = tmp16;
1994 602231 : move16();
1995 : }
1996 :
1997 : /*--------------------------------------------------------------*
1998 : * Update old pitch, upsample pitch,
1999 : *--------------------------------------------------------------*/
2000 :
2001 1154754 : *old_pitch = pitch[1];
2002 1154754 : move16();
2003 :
2004 4619016 : FOR( i = 0; i < NHFR; i++ )
2005 : {
2006 : /* compensate decimation */
2007 3464262 : pitch[i] = i_mult2( pitch[i], OPL_DECIM );
2008 3464262 : move16();
2009 : }
2010 :
2011 1154754 : return;
2012 : }
2013 :
2014 :
2015 : /*-----------------------------------------------------------------*
2016 : * find_mult_fx
2017 : *
2018 : * Verifies whether max pitch delays in higher sections have multiples
2019 : * in lower sections
2020 : *-----------------------------------------------------------------*/
2021 17744436 : static void find_mult_fx(
2022 : Word16 *fac, /* i/o: correlation scaling factor Q12 */
2023 : Word16 pitch0, /* i : pitch of max correlation in the c section */
2024 : Word16 pitch1, /* i : pitch of max correlation in the longer-delay section*/
2025 : Word16 pit_max0, /* i : max pitch delay in the longer-delay section */
2026 : Word16 *corr, /* i/o: max correlation in the shorter-delay section Q12 */
2027 : Word16 *old_pitch, /* i : pitch from previous frame */
2028 : Word16 *old_corr, /* i : max correlation from previous frame */
2029 : Word16 delta, /* i : initial multiples search range */
2030 : Word16 step /* i : increment in range of multiples search */
2031 : )
2032 : {
2033 : Word16 pit_min;
2034 : Word32 L_tmp;
2035 :
2036 17744436 : pit_min = shl( pitch0, 1 ); /* double the higher section pitch */
2037 :
2038 38929878 : WHILE( LE_16( pit_min, add( pit_max0, delta ) ) ) /* check for section boundary */
2039 : {
2040 21185442 : IF( LE_16( abs_s( sub( pit_min, pitch1 ) ), delta ) ) /* if multiple in the allowed range */
2041 : {
2042 6368007 : L_tmp = L_shl( L_mult( *corr, *fac ), 3 );
2043 :
2044 : /* if ( *old_corr < 0.6f || (float)pitch0 > (float)*old_pitch * 0.4f ) */
2045 6368007 : IF( s_max( sub( 19660 /*.6 Q15*/, *old_corr ), sub( pitch0, mult( *old_pitch, 13107 /*.4 Q15*/ ) ) ) > 0 )
2046 : {
2047 : /* reinforce the normalized correlation */
2048 : /* operands are Q12, result is Q12 */
2049 5878539 : *corr = extract_h( L_tmp );
2050 : }
2051 : /* operands are Q12, result is Q12 */
2052 6368007 : *fac = extract_h( L_shl( L_mult( *fac, THRES0 ), 3 ) );
2053 : }
2054 21185442 : pit_min = add( pit_min, pitch0 ); /* next multiple */
2055 21185442 : delta = add( delta, step ); /* the incertitude to the allowed range */
2056 : }
2057 17744436 : }
2058 :
2059 : /*---------------------------------------------------------------------------*
2060 : * pitch_neighbour_fx
2061 : *
2062 : * Verifies if the maximum correlation pitch lag is coherent with neighbour
2063 : * values
2064 : *---------------------------------------------------------------------------*/
2065 1157854 : static void pitch_neighbour_fx(
2066 : Word16 sect0, /* i : indicates whether section 0 (below PIT_MIN) is used */
2067 : Word16 pitch_tmp[], /* i : estimated pitch values for each half-frame & look-ahead */
2068 : Word16 pitch[3][2 * NSECT], /* i : tested pitch values for each half-frame & look-ahead */
2069 : Word16 corr_tmp[], /* i : raw normalized correlation (before different scalings) Q15*/
2070 : Word16 corr[3][2 * NSECT], /* i/o: normalized correlation for each half-frame & look-ahead Q12 */
2071 : Word16 thres1[2 * NHFR], /* i : maximum scaling for the immediate neighbours Q15 */
2072 : Word16 ind_tmp[2 * NHFR] /* i : best section index for each half-frame & look-ahead */
2073 : )
2074 : {
2075 : Word16 delta, i, j, k, K, coh_flag, fac;
2076 :
2077 : /*---------------------
2078 : * 1st set of sections
2079 : ---------------------*/
2080 5273114 : FOR( k = sect0; k < NSECT; k++ ) /* loop for each section */
2081 : {
2082 4115260 : K = 3;
2083 4115260 : move16();
2084 4115260 : if ( EQ_16( k, ( NSECT - 1 ) ) ) /* the number of tests depends on the section */
2085 : {
2086 1157854 : K = 2;
2087 1157854 : move16();
2088 : }
2089 : /*pt = &pitch[i][k] and pt = &corr[i][k]*/
2090 15303186 : FOR( i = 0; i < K; i++ ) /* for the 2 half-frames and look-ahead */
2091 : {
2092 : /* Compare pitch values of the present frame */
2093 42435996 : FOR( j = 0; j < K; j++ ) /* Verify pitch coherence with neighbours (including past pitch) */
2094 : {
2095 31248070 : IF( NE_16( j, i ) ) /* Exclude itself, of course */
2096 : {
2097 20060144 : IF( GE_16( corr_tmp[j], CORR_TH1 ) ) /* reinforcement can happen only if the correlation is high enough */
2098 : {
2099 15124006 : delta = abs_s( sub( pitch[i][k], pitch_tmp[j] ) ); /* Find difference of pitch values */
2100 15124006 : coh_flag = pitch_coherence_fx( pitch[i][k], pitch_tmp[j], COH_FAC, DELTA_COH );
2101 :
2102 15124006 : IF( coh_flag != 0 )
2103 : {
2104 : /* Favour stability across sections, favour closer values */
2105 5449771 : IF( EQ_16( ind_tmp[j], k ) )
2106 : {
2107 : /* corr[i][k] *= ( -thres1[j]/DELTA1 * delta + thres1[j]+1 ); */
2108 : /* operands are Q15, except corr[i][k] which is Q12 */
2109 4122251 : fac = mult( negate( thres1[j] ), MAX_16 / DELTA_COH );
2110 4122251 : fac = add( i_mult2( fac, delta ), thres1[j] );
2111 : }
2112 : ELSE
2113 : {
2114 : /* corr[i][k] *= ( -thres1[j]/DELTA1 * 0.625f * delta + 0.625f * thres1[j] +1.0f ); */
2115 1327520 : fac = mult( negate( thres1[j] ), 20479 / DELTA_COH );
2116 1327520 : fac = add( i_mult2( fac, delta ), mult( 20479 /*.625 Q15*/, thres1[j] ) );
2117 : }
2118 5449771 : corr[i][k] = add_sat( corr[i][k], mult( fac, corr[i][k] ) );
2119 5449771 : move16();
2120 : }
2121 : }
2122 : }
2123 : }
2124 : }
2125 : }
2126 :
2127 : /*---------------------
2128 : * 2nd set of sections
2129 : ---------------------*/
2130 5273114 : FOR( k = sect0; k < NSECT; k++ ) /* loop for each section */
2131 : {
2132 4115260 : K = 3;
2133 4115260 : move16();
2134 4115260 : if ( EQ_16( k, ( NSECT - 1 ) ) ) /* the number of tests depends on the section */
2135 : {
2136 1157854 : K = 2;
2137 1157854 : move16();
2138 : }
2139 : /*pt = &pitch[i][k] and pt = &corr[i][k]*/
2140 15303186 : FOR( i = 0; i < K; i++ ) /* BRANCH(1); for the 2 half-frames and look-ahead */
2141 : {
2142 : /* Compare pitch values of the present frame */
2143 42435996 : FOR( j = 0; j < K; j++ ) /* Verify pitch coherence with neighbours (including past pitch) */
2144 : {
2145 31248070 : IF( NE_16( j, i ) ) /* Exclude itself, of course */
2146 : {
2147 20060144 : IF( GE_16( corr_tmp[j + NHFR], CORR_TH1 ) ) /* reinforcement can happen only if the correlation is high enough */
2148 : {
2149 14798346 : delta = abs_s( sub( pitch[i][NSECT + k], pitch_tmp[j + NHFR] ) ); /* Find difference of pitch values */
2150 14798346 : coh_flag = pitch_coherence_fx( pitch[i][NSECT + k], pitch_tmp[j + NHFR], COH_FAC, DELTA_COH );
2151 :
2152 14798346 : IF( coh_flag != 0 )
2153 : {
2154 : /* Favour stability across sections, favour closer values */
2155 5569392 : IF( EQ_16( ind_tmp[j + NHFR], add( NSECT, k ) ) )
2156 : {
2157 : /* corr[i][k] *= ( -thres1[j+NHFR]/DELTA1 * delta + thres1[j+NHFR]+1 ); */
2158 : /* operands are Q15, except corr[i][NSECT+k] which is Q12 */
2159 4224574 : fac = mult( negate( thres1[j + NHFR] ), MAX_16 / DELTA_COH );
2160 4224574 : fac = add( extract_l( L_shr( L_mult( fac, delta ), 1 ) ), thres1[j + NHFR] );
2161 4224574 : corr[i][NSECT + k] = add_sat( corr[i][NSECT + k], mult( fac, corr[i][NSECT + k] ) );
2162 4224574 : move16();
2163 : }
2164 : ELSE
2165 : {
2166 : /* corr[i][k] *= ( -thres1[j+NHFR]/DELTA1 * 0.625f * delta + 0.625f * thres1[j+NHFR] +1.0f ); */
2167 1344818 : fac = mult( negate( thres1[j + NHFR] ), 20479 / DELTA_COH );
2168 1344818 : fac = add( extract_l( L_shr( L_mult( fac, delta ), 1 ) ), mult( 20479, thres1[j + NHFR] ) );
2169 1344818 : corr[i][NSECT + k] = add( corr[i][NSECT + k], mult( fac, corr[i][NSECT + k] ) );
2170 1344818 : move16();
2171 : }
2172 : }
2173 : }
2174 : }
2175 : }
2176 : }
2177 : }
2178 1157854 : }
2179 :
2180 : /*-----------------------------------------------------------------*
2181 : * pitch_coherence_fx
2182 : *
2183 : * Verify if pitch evolution is smooth
2184 : *-----------------------------------------------------------------*/
2185 35711622 : static Word16 pitch_coherence_fx(
2186 : Word16 pitch0, /* i : first pitch to compare */
2187 : Word16 pitch1, /* i : 2nd pitch to compare */
2188 : Word16 fac_max, /* i : max ratio of both values Q12 */
2189 : Word16 diff_max /* i : max difference of both values */
2190 : )
2191 : {
2192 : Word16 smaller, larger;
2193 : Word16 pc;
2194 :
2195 35711622 : smaller = s_min( pitch0, pitch1 );
2196 35711622 : larger = s_max( pitch0, pitch1 );
2197 :
2198 35711622 : pc = 0;
2199 35711622 : move16();
2200 35711622 : test();
2201 51533890 : if ( ( LE_16( larger, extract_h( L_shl( L_mult( fac_max, smaller ), 3 ) ) ) ) && /* Changed to <= to keep BE */
2202 15822268 : ( LT_16( sub( larger, smaller ), diff_max ) ) )
2203 : {
2204 15191043 : pc = 1;
2205 15191043 : move16();
2206 : }
2207 :
2208 35711622 : return pc;
2209 : }
2210 :
2211 : /*-----------------------------------------------------------------*
2212 : * LP_Decim2_Copy:
2213 : *
2214 : * Decimate a vector by 2 with 2nd order fir filter.
2215 : *-----------------------------------------------------------------*/
2216 2315708 : static void LP_Decim2_Copy(
2217 : const Word16 x[], /* i: signal to process */
2218 : Word16 y[], /* o: signal to process */
2219 : Word16 l, /* i : size of filtering */
2220 : Word16 mem[] /* i/o: memory (size=3) */
2221 : )
2222 : {
2223 : Word16 *p_x, x_buf[L_FRAME + L_MEM];
2224 : Word16 i, j, k;
2225 : Word32 L_tmp;
2226 :
2227 : /* copy initial filter states into buffer */
2228 2315708 : p_x = x_buf;
2229 9262832 : FOR( i = 0; i < L_MEM; i++ )
2230 : {
2231 6947124 : *p_x++ = mem[i];
2232 6947124 : move16();
2233 : }
2234 428405980 : FOR( i = 0; i < l; i++ )
2235 : {
2236 426090272 : *p_x++ = x[i];
2237 426090272 : move16();
2238 : }
2239 2315708 : if ( s_and( l, 1 ) ) /* Fix for valgrind error in case l is odd. Anyway this function will be removed. */
2240 : {
2241 0 : *p_x = *( p_x - 1 );
2242 0 : move16();
2243 : }
2244 :
2245 9262832 : FOR( i = 0; i < L_MEM; i++ )
2246 : {
2247 6947124 : mem[i] = x[l - L_MEM + i];
2248 6947124 : move16();
2249 : }
2250 2315708 : p_x = x_buf;
2251 2315708 : j = 0;
2252 2315708 : move16();
2253 215360844 : FOR( i = 0; i < l; i += 2 )
2254 : {
2255 213045136 : L_tmp = L_mult( *p_x, h_fir_fx[0] );
2256 1065225680 : FOR( k = 1; k < L_FIR_PO; k++ )
2257 : {
2258 852180544 : L_tmp = L_mac( L_tmp, p_x[k], h_fir_fx[k] );
2259 : }
2260 213045136 : p_x += 2;
2261 :
2262 213045136 : y[j++] = round_fx( L_tmp );
2263 213045136 : move16();
2264 : }
2265 2315708 : }
2266 : /*---------------------------------------------------------------------*
2267 : * Dot_product12_OL
2268 : *
2269 : * two different length dot products of x and y
2270 : *---------------------------------------------------------------------*/
2271 618680 : static Word32 Dot_product12_OL( /* o : Q31: normalized result (1 < val <= -1) */
2272 : Word16 *sum1, /* o : Q31: normalized result 2 */
2273 : const Word16 x[], /* i : 12bits: x vector */
2274 : const Word16 y[], /* i : 12bits: y vector */
2275 : const Word16 lg, /* i : vector length */
2276 : const Word16 lg2, /* i : vector length 2 */
2277 : Word16 *exp, /* o : exponent of result (0..+30) */
2278 : Word16 *exp2 /* o : exponent of result 2 (0..+30) */
2279 : )
2280 : {
2281 : Word16 i, sft;
2282 : Word32 L_sum, L_sum2;
2283 :
2284 618680 : L_sum = L_mac( 1, x[0], y[0] );
2285 618680 : IF( LE_16( lg, lg2 ) )
2286 : {
2287 39081600 : FOR( i = 1; i < lg; i++ )
2288 : {
2289 38617920 : L_sum = L_mac( L_sum, x[i], y[i] );
2290 : }
2291 : /* sets to 'L_sum' in 1 clock */
2292 463680 : L_sum2 = L_sum;
2293 463680 : move32();
2294 3427280 : FOR( ; i < lg2; i++ )
2295 : {
2296 2963600 : L_sum2 = L_mac( L_sum2, x[i], y[i] );
2297 : }
2298 : }
2299 : ELSE
2300 : {
2301 10726000 : FOR( i = 1; i < lg2; i++ )
2302 : {
2303 10571000 : L_sum = L_mac( L_sum, x[i], y[i] );
2304 : }
2305 : /* sets to 'L_sum' in 1 clock */
2306 155000 : L_sum2 = L_sum;
2307 155000 : move32();
2308 4296600 : FOR( ; i < lg; i++ )
2309 : {
2310 4141600 : L_sum = L_mac( L_sum, x[i], y[i] );
2311 : }
2312 : }
2313 :
2314 : /* Q31 */
2315 618680 : sft = norm_l( L_sum );
2316 618680 : L_sum = L_shl( L_sum, sft );
2317 618680 : *exp = sub( 30, sft );
2318 618680 : move16(); /* exponent = 0..30 */
2319 :
2320 618680 : sft = norm_l( L_sum2 );
2321 618680 : L_sum2 = L_shl( L_sum2, sft );
2322 618680 : *exp2 = sub( 30, sft );
2323 618680 : move16(); /* exponent = 0..30 */
2324 :
2325 618680 : *sum1 = extract_h( L_shr( L_sum2, 1 ) );
2326 618680 : move16();
2327 618680 : return L_sum;
2328 : }
2329 :
2330 : /*---------------------------------------------------------------------*
2331 : * Dot_product12_OL_back()
2332 : *
2333 : * two different length dot products of x and y, computed backward
2334 : *---------------------------------------------------------------------*/
2335 309340 : static Word32 Dot_product12_OL_back( /* o : Q31: normalized result (1 < val <= -1) */
2336 : Word16 *sum1, /* o : Q31: normalized result 2 */
2337 : const Word16 x[], /* i : 12bits: x vector */
2338 : const Word16 y[], /* i : 12bits: y vector */
2339 : const Word16 lg, /* i : vector length */
2340 : const Word16 lg2, /* i : vector length 2 */
2341 : Word16 *exp, /* o : exponent of result (0..+30) */
2342 : Word16 *exp2 /* o : exponent of result 2 (0..+30) */
2343 : )
2344 : {
2345 : Word16 i, sft;
2346 : Word32 L_sum, L_sum2;
2347 :
2348 309340 : L_sum = L_mac( 1, x[0], y[0] );
2349 309340 : IF( LE_16( lg, lg2 ) )
2350 : {
2351 19540800 : FOR( i = 1; i < lg; i++ )
2352 : {
2353 19308960 : L_sum = L_mac( L_sum, x[-i], y[-i] );
2354 : }
2355 : /* sets to 'L_sum' in 1 clock */
2356 231840 : L_sum2 = L_sum;
2357 231840 : move32();
2358 1713640 : FOR( ; i < lg2; i++ )
2359 : {
2360 1481800 : L_sum2 = L_mac( L_sum2, x[-i], y[-i] );
2361 : }
2362 : }
2363 : ELSE
2364 : {
2365 5363000 : FOR( i = 1; i < lg2; i++ )
2366 : {
2367 5285500 : L_sum = L_mac( L_sum, x[-i], y[-i] );
2368 : }
2369 : /* sets to 'L_sum' in 1 clock */
2370 77500 : L_sum2 = L_sum;
2371 77500 : move32();
2372 2148300 : FOR( ; i < lg; i++ )
2373 : {
2374 2070800 : L_sum = L_mac( L_sum, x[-i], y[-i] );
2375 : }
2376 : }
2377 :
2378 : /* Q31 */
2379 309340 : sft = norm_l( L_sum );
2380 309340 : L_sum = L_shl( L_sum, sft );
2381 309340 : *exp = sub( 30, sft );
2382 309340 : move16(); /* exponent = 0..30 */
2383 :
2384 309340 : sft = norm_l( L_sum2 );
2385 309340 : L_sum2 = L_shl( L_sum2, sft );
2386 309340 : *exp2 = sub( 30, sft );
2387 309340 : move16(); /* exponent = 0..30 */
2388 :
2389 309340 : *sum1 = extract_h( L_shr( L_sum2, 1 ) );
2390 309340 : move16();
2391 309340 : return L_sum;
2392 : }
2393 :
2394 0 : void pitchDoubling_det_fx(
2395 : Word16 *wspeech,
2396 : Word16 *pitch_ol,
2397 : Word16 *T_op_fr,
2398 : Word16 *voicing_fr )
2399 : {
2400 : Word16 new_op_fr[2];
2401 : Word16 new_voicing[2];
2402 : Word16 new_Top[2];
2403 : Word16 m, T;
2404 :
2405 :
2406 : /*save initial values*/
2407 :
2408 0 : new_Top[0] = pitch_ol[0];
2409 0 : move16();
2410 0 : new_Top[1] = pitch_ol[1];
2411 0 : move16();
2412 :
2413 0 : FOR( m = 2; m < 5; m++ )
2414 : {
2415 :
2416 : /* T= pitch_ol[0]/m; */
2417 0 : T = mult( pitch_ol[0], One_div_fx[m - 1] );
2418 :
2419 0 : IF( GE_16( T, PIT_MIN_12k8 ) )
2420 : {
2421 0 : pitch_ol2_fx( PIT_MIN_SHORTER, T, &( new_op_fr[0] ), &new_voicing[0], 0, wspeech, 2, EVS_MONO );
2422 0 : pitch_ol2_fx( PIT_MIN_SHORTER, T, &( new_op_fr[1] ), &new_voicing[1], L_SUBFR, wspeech, 2, EVS_MONO );
2423 : /* IF(sub(add(new_voicing[0],new_voicing[1]),add(voicing_fr[0],voicing_fr[1]))>0 */
2424 0 : IF( L_msu( L_msu( L_mac( L_mult( new_voicing[0], 8192 ), new_voicing[1], 8192 ), voicing_fr[0], 8192 ), voicing_fr[1], 8192 ) > 0 )
2425 : {
2426 0 : new_Top[0] = T;
2427 0 : move16();
2428 0 : T_op_fr[0] = new_op_fr[0];
2429 0 : move16();
2430 0 : T_op_fr[1] = new_op_fr[1];
2431 0 : move16();
2432 0 : voicing_fr[0] = new_voicing[0];
2433 0 : move16();
2434 0 : voicing_fr[1] = new_voicing[1];
2435 0 : move16();
2436 : }
2437 : }
2438 :
2439 : /* T= pitch_ol[1]/m; */
2440 0 : T = mult( pitch_ol[1], One_div_fx[m - 1] );
2441 :
2442 0 : IF( GE_16( T, PIT_MIN_12k8 ) )
2443 : {
2444 0 : pitch_ol2_fx( PIT_MIN_SHORTER, T, &( new_op_fr[0] ), &new_voicing[0], 2 * L_SUBFR, wspeech, 2, EVS_MONO );
2445 0 : pitch_ol2_fx( PIT_MIN_SHORTER, T, &( new_op_fr[1] ), &new_voicing[1], 3 * L_SUBFR, wspeech, 2, EVS_MONO );
2446 : /* IF(sub(add(new_voicing[0],new_voicing[1]),add(voicing_fr[2],voicing_fr[3]))>0) */
2447 0 : IF( L_msu( L_msu( L_mac( L_mult( new_voicing[0], 8192 ), new_voicing[1], 8192 ), voicing_fr[2], 8192 ), voicing_fr[3], 8192 ) > 0 )
2448 : {
2449 0 : new_Top[1] = T;
2450 0 : move16();
2451 0 : T_op_fr[2] = new_op_fr[0];
2452 0 : move16();
2453 0 : T_op_fr[3] = new_op_fr[1];
2454 0 : move16();
2455 0 : voicing_fr[2] = new_voicing[0];
2456 0 : move16();
2457 0 : voicing_fr[3] = new_voicing[1];
2458 0 : move16();
2459 : }
2460 : }
2461 : }
2462 :
2463 0 : pitch_ol[0] = new_Top[0];
2464 0 : move16();
2465 0 : pitch_ol[1] = new_Top[1];
2466 0 : move16();
2467 :
2468 0 : } /*end of pitch doubling detection*/
|