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