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