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