Line data Source code
1 : /******************************************************************************************************
2 :
3 : (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
4 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
5 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
6 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
7 : contributors to this repository. All Rights Reserved.
8 :
9 : This software is protected by copyright law and by international treaties.
10 : The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
11 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
12 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
13 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
14 : contributors to this repository retain full ownership rights in their respective contributions in
15 : the software. This notice grants no license of any kind, including but not limited to patent
16 : license, nor is any license granted by implication, estoppel or otherwise.
17 :
18 : Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
19 : contributions.
20 :
21 : This software is provided "AS IS", without any express or implied warranties. The software is in the
22 : development stage. It is intended exclusively for experts who have experience with such software and
23 : solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
24 : and fitness for a particular purpose are hereby disclaimed and excluded.
25 :
26 : Any dispute, controversy or claim arising under or in relation to providing this software shall be
27 : submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
28 : accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
29 : the United Nations Convention on Contracts on the International Sales of Goods.
30 :
31 : *******************************************************************************************************/
32 :
33 : #include <assert.h>
34 : #include <stdint.h>
35 : #include "options.h"
36 : #include <math.h>
37 : #include "cnst.h"
38 : #include "ivas_cnst.h"
39 : #include "prot_fx.h"
40 : #include "wmc_auto.h"
41 : #include "rom_com.h"
42 : #include "ivas_rom_com.h"
43 :
44 : #include "ivas_prot_fx.h"
45 : #include "ivas_rom_com_fx.h"
46 :
47 : /*---------------------------------------------------------------
48 : * Local function prototypes
49 : * ---------------------------------------------------------------*/
50 : static void unclr_calc_corr_features_fx(
51 : STEREO_CLASSIF_HANDLE hStereoClassif, /* i/o: stereo classifier handle */
52 : STEREO_TCA_ENC_HANDLE hStereoTCA, /* i/o: ICA Stereo Encoder handle */
53 : Word32 buf1[], /* i : left channel q_com*/
54 : Word32 buf2[], /* i : right channel q_com*/
55 : Word16 q_com,
56 : const Word16 length, /* i : length of input signal buffers Q0*/
57 : Word32 corrEst[], /* i : buffer containing inter-channel correlation values Q31-corrEst_exp*/
58 : Word16 corrEst_exp,
59 : const Word16 lagSearchRange[], /* i : minimum and maximum lags for corrEst[] Q0*/
60 : Word32 *corrEst_ncorr, /* o : norm. x-correlation btw. current and previous correlation buffers Q31-corrEst_ncorr_exp*/
61 : Word16 *corrEst_ncorr_exp );
62 :
63 :
64 : #define XL_BIAS_FX_Q15 6554
65 : #define XH_BIAS_FX_Q15 13107
66 : #define XL_WIDTH_FX_Q15 3932
67 : #define XH_WIDTH_FX_Q15 4915
68 : #define SMOOTH_DIST_FACTOR_FX_Q15 13107
69 : #define A_BIAS_FX_Q15 3277
70 : #define B_BIAS_FX_Q15 -16384
71 : #define A_WIDTH_FX_Q31 32212264
72 : #define B_WIDTH_FX_Q31 32212192
73 : #define SMOOTH_ENV_FACTOR_FX_Q15 19661
74 :
75 :
76 : /*---------------------------------------------------------------
77 : * tcaTargetCh_LA()
78 : *
79 : * Temporal channel adjustment of LA samples in target channel
80 : * ---------------------------------------------------------------*/
81 94 : static void tcaTargetCh_LA_fx(
82 : STEREO_TCA_ENC_HANDLE hStereoTCA,
83 : Word32 *ptrChanL, /* q_com */
84 : Word32 *ptrChanR, /* q_com */
85 : Word16 *q_com,
86 : const Word16 currentNCShift, /* Q0 */
87 : const Word16 input_frame /* Q0 */ )
88 : {
89 : Word16 i, j;
90 : Word16 tempS, temp, sine_inp;
91 : Word32 tempF1, tempF2, gAdj;
92 : Word16 tempF1_exp, tempF2_exp, gAdj_exp;
93 :
94 : Word32 *ref, *target;
95 : Word16 ref_exp, target_exp, target_exp_temp[L_FRAME48k + L_FRAME48k];
96 : Word16 win[240]; /* 5 ms at 48 kHz */
97 :
98 94 : ref_exp = sub( 31, *q_com );
99 94 : target_exp = sub( 31, *q_com );
100 94 : set16_fx( target_exp_temp, target_exp, L_FRAME48k + currentNCShift );
101 :
102 94 : IF( EQ_16( hStereoTCA->refChanIndx, L_CH_INDX ) )
103 : {
104 76 : ref = ptrChanL;
105 76 : target = ptrChanR;
106 : }
107 : ELSE
108 : {
109 18 : ref = ptrChanR;
110 18 : target = ptrChanL;
111 : }
112 :
113 94 : tempS = NS2SA_FX2( L_mult0( input_frame, FRAMES_PER_SEC ), L_SAMPLES_LA_NS );
114 94 : tempF1 = 0;
115 94 : move32();
116 94 : tempF1_exp = 0;
117 94 : move32();
118 94 : tempF2 = 0;
119 94 : move32();
120 94 : tempF2_exp = 0;
121 94 : move16();
122 55668 : FOR( i = 0; i < ( input_frame - currentNCShift ); i++ )
123 : {
124 55574 : tempF1 = BASOP_Util_Add_Mant32Exp( tempF1, tempF1_exp, L_abs( ref[i] ), ref_exp, &tempF1_exp ); /* Q31-tempF1_exp */
125 55574 : tempF2 = BASOP_Util_Add_Mant32Exp( tempF2, tempF2_exp, L_abs( target[i + currentNCShift] ), target_exp, &tempF2_exp ); /* Q31-tempF2_exp */
126 : }
127 :
128 94 : IF( tempF1 == 0 )
129 : {
130 0 : gAdj = ONE_IN_Q31; /* Q31 */
131 0 : move32();
132 0 : gAdj_exp = 0;
133 0 : move16();
134 : }
135 : ELSE
136 : {
137 94 : Word32 deno = BASOP_Util_Add_Mant32Exp( tempF1, tempF1_exp, -21475 /*0.00001f in Q31*/, 0, &temp ); /* Q31-temp */
138 : Word16 deno_exp;
139 94 : IF( deno > 0 )
140 : {
141 94 : deno = tempF1;
142 94 : move32();
143 94 : deno_exp = tempF1_exp;
144 94 : move16();
145 : }
146 : ELSE
147 : {
148 0 : deno = 21475;
149 0 : move32();
150 0 : deno_exp = 0;
151 0 : move16();
152 : }
153 94 : gAdj = BASOP_Util_Divide3232_Scale_newton( tempF2, deno, &gAdj_exp ); /* Q31-gAdj_exp */
154 94 : gAdj_exp = add( gAdj_exp, sub( tempF2_exp, deno_exp ) );
155 : }
156 :
157 2034 : FOR( i = 0; i < tempS; i++ )
158 : {
159 1940 : sine_inp = BASOP_Util_Divide1616_Scale( add( shl( i, 10 ), 512 /* 0.5 Q10 */ ), shl( tempS, 1 ), &temp ); /* Q15-(temp+(15-10)) */
160 1940 : sine_inp = shl_sat( sine_inp, add( temp, -10 ) ); /*Q0*/
161 1940 : win[i] = getSineWord16R2( shr( sine_inp, 1 ) ); /*Q15*/
162 1940 : move16();
163 : }
164 :
165 94 : j = 0;
166 94 : move16();
167 :
168 94 : Word16 exp_com = target_exp_temp[0];
169 94 : move16();
170 2034 : FOR( i = ( input_frame - ( currentNCShift + tempS ) ); i < ( input_frame - currentNCShift ); ( i++, j++ ) )
171 : {
172 1940 : target[i + currentNCShift] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( Mpy_32_16_1( gAdj, win[j] ), ref[i] ), add( ref_exp, gAdj_exp ), Mpy_32_16_1( target[i + currentNCShift], sub( MAX_16, win[j] ) ), target_exp, &temp ); /* Q31-temp */
173 1940 : move32();
174 1940 : target_exp_temp[i + currentNCShift] = temp;
175 1940 : move16();
176 1940 : exp_com = s_max( exp_com, temp );
177 : }
178 :
179 6600 : FOR( ; i < input_frame; i++ )
180 : {
181 6506 : target[i + currentNCShift] = Mpy_32_32( gAdj, ref[i] ); /* Q31-target_exp_temp */
182 6506 : move32();
183 6506 : target_exp_temp[i + currentNCShift] = add( gAdj_exp, ref_exp );
184 6506 : move16();
185 6506 : exp_com = s_max( exp_com, target_exp_temp[i + currentNCShift] );
186 : }
187 :
188 68680 : FOR( i = 0; i < input_frame + currentNCShift; i++ )
189 : {
190 68586 : target[i] = L_shl( target[i], sub( target_exp_temp[i], exp_com ) ); /* Q31-exp_com */
191 68586 : move32();
192 68586 : ref[i] = L_shl( ref[i], sub( ref_exp, exp_com ) ); /* Q31-exp_com */
193 68586 : move32();
194 : }
195 94 : *q_com = sub( 31, exp_com );
196 94 : move16();
197 :
198 94 : return;
199 : }
200 : /*---------------------------------------------------------------
201 : * spectral_balancer()
202 : *
203 : * Spectral-balancer to take care of the low-freq rumble and
204 : * compensate for the pre-emphasis.
205 : * ---------------------------------------------------------------*/
206 148 : void spectral_balancer_fx16(
207 : Word16 *signal, /* i/o : signal Qx */
208 : Word16 *mem, /* i/o : mem Qx */
209 : const Word16 lg, /* i : input signal length Q0*/
210 : const Word16 coeff_set /* i : coefficient set Q0*/
211 : )
212 : {
213 : Word16 i;
214 : Word16 x0, x1, x2, y0, y1, y2;
215 : Word32 a1, a2, b0, b1, b2;
216 :
217 148 : y1 = mem[0];
218 148 : y2 = mem[1];
219 148 : x0 = mem[2];
220 148 : x1 = mem[3];
221 148 : move16();
222 148 : move16();
223 148 : move16();
224 148 : move16();
225 :
226 : /* hp filter 60Hz at 3dB for 8000KHz sampling rate
227 : 1. [b,a] = butter(1, 60.0/8000.0, 'high');
228 : 2. spectral_balancing_filter
229 : <<gain = 0.97697627795388164 -> maybe not needed>>
230 : b =[1, -1] [1, -0.6]
231 : a =[1, -0.95395255590776329] [1, 0.5] */
232 148 : IF( coeff_set == 0 )
233 : {
234 : // a1 = 0.747789178258504f;
235 : // a2 = -0.272214937925007f;
236 : // b0 = 0.505001029045878f;
237 : // b1 = -1.01000205809176f;
238 : // b2 = 0.505001029045878f;
239 0 : a1 = 401466258; // Q29
240 0 : move32();
241 0 : a2 = -146144282; // Q29
242 0 : move32();
243 0 : b0 = 271120363; // Q29
244 0 : move32();
245 0 : b1 = -542240726; // Q29
246 0 : move32();
247 0 : b2 = 271120363; // Q29
248 0 : move32();
249 : }
250 : ELSE
251 : {
252 : // a1 = -0.13456126833218354f;
253 : // a2 = -0.38813694706072926f;
254 : // b0 = 1.0f;
255 : // b1 = -1.9980666374183167f;
256 : // b2 = 1.0f;
257 148 : a1 = -72242031; // Q29
258 148 : move32();
259 148 : a2 = -208379437; // Q29
260 148 : move32();
261 148 : b0 = 536870912; // Q29
262 148 : move32();
263 148 : b1 = -1072703858; // Q29
264 148 : move32();
265 148 : b2 = 536870912; // Q29
266 148 : move32();
267 : }
268 :
269 96148 : FOR( i = 0; i < lg; i++ )
270 : {
271 96000 : x2 = x1; /*Qx*/
272 96000 : move16();
273 96000 : x1 = x0; /*Qx*/
274 96000 : move16();
275 96000 : x0 = signal[i]; /*Qx*/
276 96000 : move16();
277 : // y0 = (y1 * a1) + (y2 * a2) + (x0 * b0) + (x1 * b1) + (x2 * b2);
278 96000 : y0 = extract_l( W_extract_l( W_shr( W_mac_32_16( W_mac_32_16( W_mac_32_16( W_mac_32_16( W_mult_32_16( a1, y1 ), a2, y2 ), b0, x0 ), b1, x1 ), b2, x2 ), 30 ) ) ); // Qx
279 96000 : signal[i] = y0; /*Qx*/
280 96000 : move16();
281 96000 : y2 = y1; /*Qx*/
282 96000 : move16();
283 96000 : y1 = y0; /*Qx*/
284 96000 : move16();
285 : }
286 :
287 148 : mem[0] = y1; /*Qx*/
288 148 : mem[1] = y2; /*Qx*/
289 148 : mem[2] = x0; /*Qx*/
290 148 : mem[3] = x1; /*Qx*/
291 148 : move16();
292 148 : move16();
293 148 : move16();
294 148 : move16();
295 :
296 148 : return;
297 : }
298 :
299 7622 : void spectral_balancer_fx(
300 : Word32 *signal, /* i/o : signal Qx */
301 : Word32 *mem, /* i/o : mem Qx */
302 : const Word16 lg, /* i : input signal length Q0*/
303 : const Word16 coeff_set /* i : coefficient set Q0*/
304 : )
305 : {
306 : Word16 i;
307 : Word32 x0, x1, x2, y0, y1, y2;
308 : Word32 a1, a2, b0, b1, b2;
309 :
310 7622 : y1 = mem[0]; /*Qx*/
311 7622 : y2 = mem[1]; /*Qx*/
312 7622 : x0 = mem[2]; /*Qx*/
313 7622 : x1 = mem[3]; /*Qx*/
314 7622 : move32();
315 7622 : move32();
316 7622 : move32();
317 7622 : move32();
318 :
319 : /* hp filter 60Hz at 3dB for 8000KHz sampling rate
320 : 1. [b,a] = butter(1, 60.0/8000.0, 'high');
321 : 2. spectral_balancing_filter
322 : <<gain = 0.97697627795388164 -> maybe not needed>>
323 : b =[1, -1] [1, -0.6]
324 : a =[1, -0.95395255590776329] [1, 0.5] */
325 7622 : IF( coeff_set == 0 )
326 : {
327 7622 : a1 = 401466258; // Q29
328 7622 : move32();
329 7622 : a2 = -146144282; // Q29
330 7622 : move32();
331 7622 : b0 = 271120363; // Q29
332 7622 : move32();
333 7622 : b1 = -542240726; // Q29
334 7622 : move32();
335 7622 : b2 = 271120363; // Q29
336 7622 : move32();
337 : }
338 : ELSE
339 : {
340 0 : a1 = -72242031; // Q29
341 0 : move32();
342 0 : a2 = -208379437; // Q29
343 0 : move32();
344 0 : b0 = 536870912; // Q29
345 0 : move32();
346 0 : b1 = -1072703858; // Q29
347 0 : move32();
348 0 : b2 = 536870912; // Q29
349 0 : move32();
350 : }
351 :
352 1227142 : FOR( i = 0; i < lg; i++ )
353 : {
354 1219520 : x2 = x1; /*Qx*/
355 1219520 : move16();
356 1219520 : x1 = x0; /*Qx*/
357 1219520 : move16();
358 1219520 : x0 = signal[i]; /*Qx*/
359 1219520 : move16();
360 1219520 : y0 = W_extract_l( W_shr( W_mac_32_32( W_mac_32_32( W_mac_32_32( W_mac_32_32( W_mult_32_32( a1, y1 ), a2, y2 ), b0, x0 ), b1, x1 ), b2, x2 ), 30 ) ); // Qx
361 1219520 : signal[i] = y0; /*Qx*/
362 1219520 : move16();
363 1219520 : y2 = y1; /*Qx*/
364 1219520 : move16();
365 1219520 : y1 = y0; /*Qx*/
366 1219520 : move16();
367 : }
368 :
369 7622 : mem[0] = y1; /*Qx*/
370 7622 : move32();
371 7622 : mem[1] = y2; /*Qx*/
372 7622 : move32();
373 7622 : mem[2] = x0; /*Qx*/
374 7622 : move32();
375 7622 : mem[3] = x1; /*Qx*/
376 7622 : move32();
377 :
378 7622 : return;
379 : }
380 :
381 :
382 : /*---------------------------------------------------------------
383 : * deEmphResample()
384 : *
385 : * De-emphasize and resample the L and R channels.
386 : * ---------------------------------------------------------------*/
387 3811 : static void deEmphResample_fx(
388 : STEREO_TCA_ENC_HANDLE hStereoTCA, /* i/o: Stereo TCA encoder handle */
389 : const Word32 *tempChan1_fx, /* i : Stereo data Qx*/
390 : const Word32 *tempChan2_fx, /* i : Stereo data Qx*/
391 : Word32 *chan1_fx, /*Qx*/
392 : Word32 *chan2_fx, /*Qx*/
393 : const Word16 input_frame, /*Q0*/
394 : const Word16 dsFactor /*Q0*/ )
395 : {
396 : Word32 buf1_fx[L_FRAME48k], buf2_fx[L_FRAME48k];
397 : Word32 tempBuf1_fx[2 * L_FRAME_DS], tempBuf2_fx[2 * L_FRAME_DS];
398 : Word16 i;
399 : Word16 dsFac1, dsFac2;
400 :
401 : /* Estimate first and second stage downsample factors */
402 3811 : dsFac1 = shr( dsFactor, 1 ); /*Qx*/
403 3811 : dsFac2 = idiv1616( dsFactor, dsFac1 ); /*Qx*/
404 :
405 : /* convert stereo data to two distinct channels, e.g., L, R */
406 3811 : Copy32( tempChan1_fx, buf1_fx, input_frame ); /*Qx*/
407 3811 : Copy32( tempChan2_fx, buf2_fx, input_frame ); /*Qx*/
408 :
409 : /* De-emphasis, 1/(1-mu z^-1), and resample, stage 1 */
410 :
411 3811 : deemph_fx_32( buf1_fx, PREEMPH_FAC_16k, input_frame, &hStereoTCA->memdecim_fx[0] );
412 3811 : deemph_fx_32( buf2_fx, PREEMPH_FAC_16k, input_frame, &hStereoTCA->memdecim_fx[1] );
413 :
414 1223331 : FOR( i = 0; i < ( input_frame / dsFac1 ); i++ )
415 : {
416 1219520 : tempBuf1_fx[i] = buf1_fx[i * dsFac1]; /*Qx*/
417 1219520 : move32();
418 1219520 : tempBuf2_fx[i] = buf2_fx[i * dsFac1]; /*Qx*/
419 1219520 : move32();
420 : }
421 :
422 : /* De-emphasis, 1/(1-mu z^-1), and resample, stage 2 */
423 3811 : deemph_fx_32( tempBuf1_fx, PREEMPH_FAC_16k, idiv1616( input_frame, dsFac1 ), &hStereoTCA->memdecim_fx[2] );
424 3811 : deemph_fx_32( tempBuf2_fx, PREEMPH_FAC_16k, idiv1616( input_frame, dsFac1 ), &hStereoTCA->memdecim_fx[3] );
425 :
426 613571 : FOR( i = 0; i < ( input_frame / dsFactor ); i++ )
427 : {
428 609760 : chan1_fx[i] = tempBuf1_fx[i * dsFac2]; /*Qx*/
429 609760 : move32();
430 609760 : chan2_fx[i] = tempBuf2_fx[i * dsFac2]; /*Qx*/
431 609760 : move32();
432 : }
433 :
434 3811 : spectral_balancer_fx( chan1_fx, &hStereoTCA->memdecim_fx[4], idiv1616( input_frame, dsFactor ), 0 ); /*4 mem */
435 3811 : spectral_balancer_fx( chan2_fx, &hStereoTCA->memdecim_fx[8], idiv1616( input_frame, dsFactor ), 0 ); /*4 mem */
436 :
437 3811 : return;
438 : }
439 : /*---------------------------------------------------------------
440 : * utilCrossCorr_mod()
441 : *
442 : * Biased crossCorr estimation between buf1, buf2 over the
443 : * lag range of (lagSearchRange[0], lagSearchRange[1]).
444 : * ---------------------------------------------------------------*/
445 3811 : static void utilCrossCorr_mod_fx(
446 : STEREO_TCA_ENC_HANDLE hStereoTCA, /* i/o: ICA Stereo Encoder handle */
447 : Word32 *buf1, /*q_com*/
448 : Word32 *buf2, /*q_com*/
449 : const Word16 q_com,
450 : Word32 *corrEst, /* o : correlation estimate Q31-corrEst_Exp*/
451 : Word16 *corrEst_Exp, /* o : correlation estimate Q31-corrEst_Exp*/
452 : const Word16 *lagSearchRange, /*Q0*/
453 : const Word16 len /*Q0*/ )
454 : {
455 : Word32 C, E1, E2, C_C_mem;
456 : Word16 i, j, E1_exp, E2_exp, Inv_Tot_E_exp, k, C_exp, exp, gb;
457 : Word16 Inv_Tot_E, corrEst_exp[2 * L_NCSHIFT_DS + 1];
458 : Word64 L64_sum;
459 :
460 3811 : set16_fx( corrEst_exp, -1000, 2 * L_NCSHIFT_DS + 1 );
461 3811 : E1_exp = sub( 31, q_com );
462 3811 : E2_exp = sub( 31, q_com );
463 :
464 3811 : gb = 0;
465 3811 : move16();
466 3811 : IF( LT_16( L_norm_arr( buf1, len ), 2 ) )
467 : {
468 0 : gb = 2;
469 0 : move16();
470 : }
471 3811 : E1 = sum2_32_exp_fx( buf1, len, &E1_exp, gb ); /* Q31-E1_exp */
472 :
473 3811 : gb = 0;
474 3811 : move16();
475 3811 : IF( LT_16( L_norm_arr( buf2, len ), 2 ) )
476 : {
477 0 : gb = 2;
478 0 : move16();
479 : }
480 3811 : E2 = sum2_32_exp_fx( buf2, len, &E2_exp, gb ); /* Q31-E2_exp */
481 :
482 : Word16 temp1, temp2;
483 3811 : Word32 E1_mul = BASOP_Util_Add_Mant32Exp( E1, E1_exp, hStereoTCA->E1_mem_fx, hStereoTCA->E1_mem_exp, &temp1 ); /* Q31-temp1 */
484 3811 : Word32 E2_mul = BASOP_Util_Add_Mant32Exp( E2, E2_exp, hStereoTCA->E2_mem_fx, hStereoTCA->E2_mem_exp, &temp2 ); /* Q31-temp2 */
485 3811 : Word32 sqr_inp = Mpy_32_32( E1_mul, E2_mul );
486 3811 : Word16 sq_exp = add( temp1, temp2 );
487 :
488 3811 : IF( sqr_inp )
489 : {
490 3811 : sqr_inp = Sqrt32( sqr_inp, &sq_exp ); /* Q31-sq_exp */
491 3811 : sqr_inp = Mpy_32_32( sqr_inp, 1342177280 /* 320 in Q22*/ ); /* Q31-sq_exp+22-31 */
492 3811 : sq_exp = add( sq_exp, 9 );
493 3811 : Inv_Tot_E = BASOP_Util_Divide3232_Scale( ONE_IN_Q31, sqr_inp, &Inv_Tot_E_exp ); /* Q15-Inv_Tot_E_exp */
494 3811 : Inv_Tot_E_exp = add( Inv_Tot_E_exp, sub( 0, sq_exp ) );
495 : }
496 : ELSE
497 : {
498 0 : Inv_Tot_E = 25088; /* 98.82 in Q8 */
499 0 : move16();
500 0 : Inv_Tot_E_exp = 7;
501 0 : move16();
502 : }
503 :
504 3811 : hStereoTCA->E1_mem_fx = E1; /* Q31-E1_exp */
505 3811 : move32();
506 3811 : hStereoTCA->E2_mem_fx = E2; /* Q31-E2_exp */
507 3811 : move32();
508 3811 : hStereoTCA->E1_mem_exp = E1_exp;
509 3811 : move16();
510 3811 : hStereoTCA->E2_mem_exp = E2_exp;
511 3811 : move16();
512 3811 : *corrEst_Exp = corrEst_exp[0];
513 3811 : move16();
514 :
515 160062 : FOR( ( i = lagSearchRange[0], j = 0 ); i <= 0; ( i++, j++ ) )
516 : {
517 156251 : L64_sum = 1;
518 156251 : move64();
519 25156411 : FOR( k = 0; k < len; k++ )
520 : {
521 25000160 : L64_sum = W_mac_32_32( L64_sum, buf1[k], buf2[k + i] ); /* 2*q_com+1 */
522 : }
523 156251 : k = W_norm( L64_sum );
524 156251 : L64_sum = W_shl( L64_sum, k ); /* 2*q_com+1+k */
525 156251 : C = W_extract_h( L64_sum ); // ener_side_q
526 156251 : C_exp = sub( 31, sub( add( add( shl( q_com, 1 ), 1 ), k ), 32 ) );
527 156251 : C_C_mem = BASOP_Util_Add_Mant32Exp( C, C_exp, hStereoTCA->C_mem_fx[j], hStereoTCA->C_mem_exp[j], &exp ); /* Q31-exp */
528 156251 : corrEst[j] = Mpy_32_16_1( C_C_mem, Inv_Tot_E ); /* Q31-corrEst_exp */
529 156251 : move32();
530 156251 : corrEst_exp[j] = add( Inv_Tot_E_exp, exp );
531 156251 : move16();
532 156251 : *corrEst_Exp = s_max( *corrEst_Exp, corrEst_exp[j] );
533 156251 : move16();
534 156251 : hStereoTCA->C_mem_fx[j] = C;
535 156251 : move32();
536 156251 : hStereoTCA->C_mem_exp[j] = C_exp;
537 156251 : move16();
538 : }
539 :
540 156251 : FOR( ; i <= lagSearchRange[1]; ( i++, j++ ) )
541 : {
542 152440 : L64_sum = 1;
543 152440 : move64();
544 24542840 : FOR( k = 0; k < len; k++ )
545 : {
546 24390400 : L64_sum = W_mac_32_32( L64_sum, buf1[k - i], buf2[k] ); /* 2*q_com+1 */
547 : }
548 152440 : k = W_norm( L64_sum );
549 152440 : L64_sum = W_shl( L64_sum, k ); /* 2*q_com+1+k */
550 152440 : C = W_extract_h( L64_sum ); // ener_side_q
551 152440 : C_exp = sub( 31, sub( add( add( shl( q_com, 1 ), 1 ), k ), 32 ) );
552 152440 : C_C_mem = BASOP_Util_Add_Mant32Exp( C, C_exp, hStereoTCA->C_mem_fx[j], hStereoTCA->C_mem_exp[j], &exp ); /* Q31-exp */
553 152440 : corrEst[j] = Mpy_32_16_1( C_C_mem, Inv_Tot_E ); /* Q31-corrEst_exp */
554 152440 : move32();
555 152440 : corrEst_exp[j] = add( Inv_Tot_E_exp, exp );
556 152440 : move16();
557 152440 : *corrEst_Exp = s_max( *corrEst_Exp, corrEst_exp[j] );
558 152440 : move16();
559 152440 : hStereoTCA->C_mem_fx[j] = C;
560 152440 : move32();
561 152440 : hStereoTCA->C_mem_exp[j] = C_exp;
562 152440 : move16();
563 : }
564 :
565 : /* Rescaling buffers */
566 :
567 312502 : FOR( i = 0; i < ( 2 * L_NCSHIFT_DS + 1 ); i++ )
568 : {
569 308691 : corrEst[i] = L_shl( corrEst[i], sub( corrEst_exp[i], *corrEst_Exp ) ); /* Q31-corrEst_Exp */
570 308691 : move32();
571 : }
572 :
573 3811 : return;
574 : }
575 : /*---------------------------------------------------------------
576 : * utilCrossCorr()
577 : *
578 : * crossCorr estimation between buf1, buf2 over the
579 : * lag range of (lagSearchRange[0], lagSearchRange[1]).
580 : * ---------------------------------------------------------------*/
581 241 : static void utilCrossCorr_fx(
582 : const Word32 *buf1, // buf1_q
583 : Word16 buf1_q,
584 : const Word32 *buf2, // buf2_q
585 : Word16 buf2_q,
586 : const Word32 *win, /*Qx*/
587 : Word32 *corrEst, /* o : correlation estimate corrEst_e */
588 : Word16 *corrEst_e,
589 : const Word16 *lagSearchRange, /*Q0*/
590 : const Word16 len, /*Q0*/
591 : const Word16 winSymmFlag /*Q0*/ )
592 : {
593 : Word32 tempBuf1[L_FRAME48k];
594 : Word32 tempBuf2[L_FRAME48k];
595 : Word32 temp, scale;
596 : Word16 res_e, tmp_e;
597 : Word64 L64_sum;
598 : Word16 i, j, k;
599 : Word16 corrEstTemp_e[N_MAX_SHIFT_CHANGE + 1];
600 241 : Word16 max_e = MIN16B;
601 241 : move16();
602 :
603 241 : Word16 gb1 = s_max( 0, sub( find_guarded_bits_fx( len ), getScaleFactor32( buf1, len ) ) );
604 241 : Word16 gb2 = s_max( 0, sub( find_guarded_bits_fx( len ), getScaleFactor32( buf2, len ) ) );
605 :
606 : /* Apply windowing */
607 241 : IF( win != NULL )
608 : {
609 0 : IF( EQ_16( winSymmFlag, 0 ) )
610 : {
611 0 : v_mult_fixed( buf1, win, tempBuf1, len );
612 0 : v_mult_fixed( buf2, win, tempBuf2, len );
613 : }
614 : ELSE
615 : {
616 0 : v_mult_fixed( buf1, win, tempBuf1, ( len >> 1 ) );
617 0 : v_mult_fixed( buf2, win, tempBuf2, ( len >> 1 ) );
618 :
619 0 : FOR( i = shr( len, 1 ); i < len; i++ )
620 : {
621 0 : tempBuf1[i] = Mpy_32_32( win[len - 1 - i], buf1[i] ); /* Qx+buf1_q-31 */
622 0 : move32();
623 0 : tempBuf2[i] = Mpy_32_32( win[len - 1 - i], buf2[i] ); /* Qx+buf2_q-31 */
624 0 : move32();
625 : }
626 : }
627 : }
628 : ELSE
629 : {
630 241 : Copy32( buf1, tempBuf1, len ); /* buf1_q */
631 241 : Copy32( buf2, tempBuf2, len ); /* buf2_q */
632 : }
633 :
634 241 : Word16 temp1_e = sub( Q31, buf1_q );
635 241 : Word16 temp2_e = sub( Q31, buf2_q );
636 :
637 241 : temp = sum2_32_exp_fx( tempBuf1, len, &temp1_e, gb1 ); // temp1_e
638 241 : temp = Mpy_32_32( temp, sum2_32_exp_fx( tempBuf2, len, &temp2_e, gb2 ) ); // temp2_e
639 241 : temp2_e = add( temp1_e, temp2_e );
640 :
641 241 : IF( temp == 0 )
642 : {
643 0 : scale = MAXVAL_WORD32;
644 0 : move32();
645 : }
646 : ELSE
647 : {
648 241 : scale = ISqrt32( temp, &temp2_e ); // temp2_e
649 : }
650 :
651 : /* starting point of lag search range should be less than the ending point */
652 241 : assert( lagSearchRange[0] <= lagSearchRange[1] );
653 :
654 : /* first part of noncausal corr est. */
655 406 : FOR( ( i = lagSearchRange[0], j = 0 ); i <= s_min( 0, lagSearchRange[1] ); ( i++, j++ ) )
656 : {
657 165 : L64_sum = 0;
658 165 : move64();
659 111349 : FOR( k = 0; k < ( len + i ); k++ )
660 : {
661 111184 : L64_sum = W_mac_32_32( L64_sum, buf1[k - i], buf2[k] ); /* buf1_q+buf2_q+1 */
662 : }
663 165 : k = W_norm( L64_sum );
664 165 : L64_sum = W_shl( L64_sum, k ); /* buf1_q+buf2_q+1+k */
665 165 : temp = W_extract_h( L64_sum ); /* buf1_q+buf2_q+1+k-32 */
666 165 : res_e = sub( 31, sub( add( add( add( buf1_q, buf2_q ), 1 ), k ), 32 ) );
667 :
668 165 : corrEst[j] = L_deposit_h( BASOP_Util_Divide3216_Scale( temp, ( len + i ), &tmp_e ) ); /* Q31-max_e */
669 165 : move32();
670 165 : corrEstTemp_e[j] = add( tmp_e, sub( res_e, 15 ) );
671 165 : move16();
672 165 : max_e = s_max( max_e, corrEstTemp_e[j] );
673 : }
674 :
675 : /* second part of noncausal corr est. */
676 656 : FOR( ; i <= lagSearchRange[1]; ( i++, j++ ) )
677 : {
678 415 : L64_sum = 1;
679 415 : move64();
680 250969 : FOR( k = 0; k < sub( len, i ); k++ )
681 : {
682 250554 : L64_sum = W_mac_32_32( L64_sum, buf1[k], buf2[k + i] ); /* buf1_q+buf2_q+1 */
683 : }
684 415 : k = W_norm( L64_sum );
685 415 : L64_sum = W_shl( L64_sum, k ); /* buf1_q+buf2_q+1+k */
686 415 : temp = W_extract_h( L64_sum ); /* buf1_q+buf2_q+1+k-32 */
687 415 : res_e = sub( 31, sub( add( add( add( buf1_q, buf2_q ), 1 ), k ), 32 ) );
688 :
689 415 : corrEst[j] = L_deposit_h( BASOP_Util_Divide3216_Scale( temp, ( len - i ), &tmp_e ) ); /* Q31-max_e */
690 415 : move32();
691 415 : corrEstTemp_e[j] = add( tmp_e, sub( res_e, 15 ) );
692 415 : move16();
693 415 : max_e = s_max( max_e, corrEstTemp_e[j] );
694 415 : move16();
695 : }
696 :
697 :
698 821 : FOR( i = 0; i < j; i++ )
699 : {
700 580 : corrEst[i] = L_shr( corrEst[i], sub( max_e, corrEstTemp_e[i] ) ); /* Q31-corrEstTemp_e */
701 580 : move32();
702 : }
703 :
704 241 : *corrEst_e = max_e;
705 241 : move16();
706 241 : v_multc_fixed( corrEst, scale, corrEst, j );
707 241 : *corrEst_e = add( *corrEst_e, temp2_e );
708 241 : move16();
709 :
710 241 : return;
711 : }
712 : /*---------------------------------------------------------------
713 : * corrStatsEst()
714 : *
715 : * Non-causal shift estimation to encode future samples.
716 : * ---------------------------------------------------------------*/
717 :
718 11485 : static Word16 TRUNC_FX( Word32 inp /*Q31-exp*/, Word16 exp )
719 : {
720 : Word16 ouptut;
721 : Word32 temp;
722 :
723 11485 : temp = L_shr( inp, sub( 31, exp ) ); /*Q0*/
724 11485 : test();
725 11485 : IF( GT_32( temp, 32767 ) || LT_32( temp, -32768 ) )
726 : {
727 0 : test();
728 0 : IF( temp < 0 )
729 : {
730 0 : ouptut = -32768; /*Q0*/
731 : }
732 : ELSE
733 : {
734 0 : ouptut = 32767; /*Q0*/
735 : }
736 0 : move16();
737 : }
738 : ELSE
739 : {
740 11485 : IF( NE_32( temp, L_shl_sat( 1, sub( 31, exp ) ) ) )
741 : {
742 11485 : Word32 temp1 = L_add_sat( inp, L_shl_sat( 1, sub( 31, add( exp, 1 ) ) ) ); /* Q31-exp */
743 11485 : ouptut = extract_l( L_shr( temp1, sub( 31, exp ) ) ); /*Q0*/
744 :
745 11485 : IF( temp < 0 )
746 : {
747 6630 : ouptut = add( ouptut, 1 ); /*Q0*/
748 : }
749 : }
750 : ELSE
751 : {
752 0 : ouptut = extract_l( temp ); /*Q0*/
753 0 : move16();
754 : }
755 : }
756 11485 : return ouptut; /*Q0*/
757 : }
758 3811 : static void corrStatsEst_fx(
759 : STEREO_TCA_ENC_HANDLE hStereoTCA, /* i/o: Stereo TCA Encoder handle */
760 : Word32 *buf1_fx, /* i : channel 1 q_com*/
761 : Word32 *buf2_fx, /* i : channel 2 q_com*/
762 : Word16 q_com,
763 : const Word16 bufLenDS, /* i : buffer length Q0*/
764 : const Word16 dsFactor, /* i : buffer length Q0*/
765 : const Word16 vad_flag1, /* i : VAD flag channel 1 Q0*/
766 : const Word16 vad_flag2, /* i : VAD flag channel 2 Q0*/
767 : STEREO_CLASSIF_HANDLE hStereoClassif /* i/o: stereo classifier handle */
768 : )
769 : {
770 : Word16 lagSearchRange[2];
771 : Word32 corrEst_fx[2 * L_NCSHIFT_DS + 1];
772 : Word16 corrLagStats[3];
773 : Word32 *tempRK_fx;
774 : const Word32 *winInterp_fx;
775 : Word32 rInterp_fx[MAX_INTERPOLATE];
776 : Word16 rInterp_exp[MAX_INTERPOLATE];
777 : Word16 interpMin, interpMax, interpLen;
778 : Word16 i, j, k, m;
779 : Word16 win_bias_fx;
780 : Word16 tempLen, win_width;
781 : Word16 loc_weight_win_fx[4 * L_NCSHIFT_DS + 1];
782 : Word32 X_hat_fx, Y_hat_fx, XY_hat_fx, X_SQR_hat_fx;
783 : Word32 alpha_reg_fx, beta_reg_fx, reg_prv_corr_fx, dist_reg_prv_corr_fx, bias_par_fx, width_par_fx;
784 : Word16 alpha_reg_exp, beta_reg_exp, reg_prv_corr_exp, dist_reg_prv_corr_exp, bias_par_exp, width_par_exp;
785 :
786 : Word16 alpha_fx;
787 : Word16 k1_fx, k2_fx;
788 : Word32 temp_A_fx, temp_B_fx, tempF_fx;
789 : Word16 stmp;
790 : Word32 corrEst_ncorr_fx, temp32;
791 : Word16 corrEst_exp, corrEst_ncorr_exp, temp;
792 : Word16 X_hat_exp, Y_hat_exp, XY_hat_exp, X_SQR_hat_exp, exp;
793 :
794 : /* init of regression parameters*/
795 3811 : X_hat_fx = 0;
796 3811 : move32();
797 3811 : X_hat_exp = 0;
798 3811 : move16();
799 3811 : X_SQR_hat_fx = 0;
800 3811 : move32();
801 3811 : X_SQR_hat_exp = 0;
802 3811 : move16();
803 3811 : XY_hat_fx = 0;
804 3811 : move32();
805 3811 : XY_hat_exp = 0;
806 3811 : move16();
807 :
808 : /* Initializations */
809 3811 : alpha_fx = 22938; /* 0.7 in Q15*/
810 3811 : move16();
811 3811 : lagSearchRange[0] = -L_NCSHIFT_DS;
812 3811 : move16();
813 3811 : lagSearchRange[1] = L_NCSHIFT_DS;
814 3811 : move16();
815 3811 : tempLen = ( 2 * L_NCSHIFT_DS + 1 );
816 3811 : move16();
817 :
818 3811 : set16_fx( corrLagStats, 0, 3 );
819 :
820 : /* First iteration of xcorr estimation */
821 3811 : utilCrossCorr_mod_fx( hStereoTCA, buf1_fx, buf2_fx, q_com, corrEst_fx, &corrEst_exp, lagSearchRange, sub( bufLenDS, L_XCORRMEM_DS ) );
822 :
823 : /* calculate features for the UNCLR classifier */
824 3811 : unclr_calc_corr_features_fx( hStereoClassif, hStereoTCA, buf1_fx, buf2_fx, q_com, sub( bufLenDS, L_XCORRMEM_DS ), corrEst_fx, corrEst_exp, lagSearchRange, &corrEst_ncorr_fx, &corrEst_ncorr_exp );
825 :
826 11433 : FOR( i = 1; i < 3; i++ )
827 : {
828 7622 : v_add_32( hStereoTCA->corrEstPrev_fx[i], hStereoTCA->corrEstPrev_fx[0], hStereoTCA->corrEstPrev_fx[0], tempLen );
829 : }
830 :
831 : /* back up the corrEst */
832 11433 : FOR( i = 0; i < 2; i++ )
833 : {
834 7622 : Copy32( hStereoTCA->corrEstPrev_fx[i + 1], hStereoTCA->corrEstPrev_fx[i], tempLen ); /* Q31-hStereoTCA->corrEstPrev_exp */
835 : }
836 :
837 3811 : temp = getScaleFactor32( corrEst_fx, 2 * L_NCSHIFT_DS + 1 );
838 3811 : scale_sig32( corrEst_fx, 2 * L_NCSHIFT_DS + 1, temp ); /* Q31-corrEst_exp */
839 3811 : corrEst_exp = sub( corrEst_exp, temp );
840 :
841 3811 : Copy32( corrEst_fx, hStereoTCA->corrEstPrev_fx[2], tempLen ); /* Q31-corrEst_exp */
842 3811 : hStereoTCA->corrEstPrev_exp = corrEst_exp;
843 3811 : move16();
844 3811 : Word16 gb = find_guarded_bits_fx( 2 * L_NCSHIFT_DS + 1 );
845 :
846 3811 : scale_sig32( hStereoTCA->corrEstPrev_fx[2], 2 * L_NCSHIFT_DS + 1, -gb ); /* Q31-hStereoTCA->corrEstPrev_exp-1 */
847 3811 : hStereoTCA->corrEstPrev_exp = add( hStereoTCA->corrEstPrev_exp, gb );
848 3811 : move16();
849 : Word32 buf1_fx_temp[L_FRAME_DS];
850 : Word32 buf2_fx_temp[L_FRAME_DS];
851 :
852 3811 : Copy32( buf1_fx, buf1_fx_temp, L_FRAME_DS ); /* q_com */
853 3811 : Copy32( buf2_fx, buf2_fx_temp, L_FRAME_DS ); /* q_com */
854 :
855 3811 : scale_sig32( buf1_fx_temp, L_FRAME_DS, -4 ); /* q_com-4 */
856 3811 : scale_sig32( buf2_fx_temp, L_FRAME_DS, -4 ); /* q_com-4 */
857 :
858 3811 : temp_A_fx = L_add( sumAbs_fx( buf1_fx_temp, L_FRAME_DS - L_XCORRMEM_DS ), sumAbs_fx( buf2_fx_temp, L_FRAME_DS - L_XCORRMEM_DS ) );
859 3811 : temp_B_fx = L_add( sumAbs_fx( buf1_fx_temp + ( L_FRAME_DS - L_XCORRMEM_DS ), L_XCORRMEM_DS ), sumAbs_fx( buf2_fx_temp + ( L_FRAME_DS - L_XCORRMEM_DS ), L_XCORRMEM_DS ) );
860 :
861 3811 : tempF_fx = BASOP_Util_Add_Mant32Exp( L_add( temp_A_fx, temp_B_fx ), sub( 31, sub( q_com, 4 ) ), hStereoTCA->mem_tempF_fx, hStereoTCA->mem_tempF_exp, &temp ); /* Q31-tempF_exp */
862 3811 : Word16 tempF_exp = temp;
863 3811 : hStereoTCA->mem_tempF_fx = temp_B_fx; /* Q31-hStereoTCA->mem_tempF_exp */
864 3811 : move32();
865 3811 : hStereoTCA->mem_tempF_exp = sub( 31, sub( q_com, 4 ) );
866 3811 : move16();
867 :
868 3811 : alpha_fx = 30474 /* 0.93f in Q15*/;
869 3811 : move16();
870 3811 : IF( BASOP_Util_Add_Mant32Exp( tempF_fx, tempF_exp, -hStereoTCA->ica_envVarLT_fx, add( hStereoTCA->ica_envVarLT_exp, 2 ), &temp ) > 0 )
871 : {
872 120 : alpha_fx = 27197 /* 0.83f in Q15*/;
873 : }
874 3691 : ELSE IF( BASOP_Util_Add_Mant32Exp( tempF_fx, tempF_exp, -hStereoTCA->ica_envVarLT_fx, add( hStereoTCA->ica_envVarLT_exp, 1 ), &temp ) > 0 )
875 : {
876 315 : alpha_fx = 27853 /* 0.85f in Q15*/;
877 : }
878 3376 : ELSE IF( BASOP_Util_Add_Mant32Exp( tempF_fx, tempF_exp, -hStereoTCA->ica_envVarLT_fx, hStereoTCA->ica_envVarLT_exp, &temp ) > 0 )
879 : {
880 1070 : alpha_fx = 29491 /* 0.9f in Q15*/;
881 : }
882 3811 : move16();
883 3811 : hStereoTCA->corrStatsSmoothFac_fx = alpha_fx;
884 3811 : move32();
885 :
886 : /* long term corr Stats estimation */
887 3811 : v_multc_fixed_16( hStereoTCA->corrEstLT_fx, alpha_fx, hStereoTCA->corrEstLT_fx, 2 * L_NCSHIFT_DS + 1 ); /* Q31-hStereoTCA->corrEstLT_exp */
888 3811 : v_multc_fixed_16( corrEst_fx, sub( MAX_16, alpha_fx ), corrEst_fx, 2 * L_NCSHIFT_DS + 1 ); /* Q31-corrEst_exp */
889 3811 : v_add_fixed_me( hStereoTCA->corrEstLT_fx, hStereoTCA->corrEstLT_exp, corrEst_fx, corrEst_exp, hStereoTCA->corrEstLT_fx, &hStereoTCA->corrEstLT_exp, 2 * L_NCSHIFT_DS + 1, 0 );
890 :
891 3811 : hStereoTCA->ica_envVarLT_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( hStereoTCA->ica_envVarLT_fx, SMOOTH_ENV_FACTOR_FX_Q15 ), hStereoTCA->ica_envVarLT_exp, Mpy_32_16_1( tempF_fx, ONE_IN_Q15 - SMOOTH_ENV_FACTOR_FX_Q15 ), tempF_exp, &hStereoTCA->ica_envVarLT_exp ); // SMOOTH_ENV_FACTOR_FX_Q15 (Q31-hStereoTCA->ica_envVarLT_exp)
892 3811 : move32();
893 :
894 3811 : Copy32( hStereoTCA->corrEstLT_fx, corrEst_fx, 2 * L_NCSHIFT_DS + 1 ); /* Q31-hStereoTCA->corrEstLT_exp */
895 3811 : corrEst_exp = hStereoTCA->corrEstLT_exp;
896 3811 : move16();
897 :
898 3811 : Y_hat_fx = hStereoTCA->delay_0_mem_fx[0]; /* Q31-hStereoTCA->delay_0_mem_exp */
899 3811 : move32();
900 3811 : Y_hat_exp = hStereoTCA->delay_0_mem_exp;
901 3811 : move16();
902 :
903 : /* Note: keep X_hat and X_SQR_hat calculations inside the loop to allow future tuning of MAX_DELAYREGLEN */
904 45732 : FOR( i = 1; i < MAX_DELAYREGLEN; i++ )
905 : {
906 41921 : X_hat_fx = BASOP_Util_Add_Mant32Exp( X_hat_fx, X_hat_exp, L_shl( i, 27 ), 4, &X_hat_exp ); /* Q31-X_hat_exp */
907 41921 : Y_hat_fx = BASOP_Util_Add_Mant32Exp( Y_hat_fx, Y_hat_exp, hStereoTCA->delay_0_mem_fx[i], hStereoTCA->delay_0_mem_exp, &Y_hat_exp ); /* Q31-Y_hat_exp */
908 41921 : XY_hat_fx = BASOP_Util_Add_Mant32Exp( XY_hat_fx, XY_hat_exp, Mpy_32_32( hStereoTCA->delay_0_mem_fx[i], L_shl( i, 27 ) ), add( 4, hStereoTCA->delay_0_mem_exp ), &XY_hat_exp ); /* Q31-XY_hat_exp */
909 41921 : X_SQR_hat_fx = BASOP_Util_Add_Mant32Exp( X_SQR_hat_fx, X_SQR_hat_exp, Mpy_32_32( L_shl( i, 27 ), L_shl( i, 27 ) ), 8, &X_SQR_hat_exp ); /* Q31-X_SQR_hat_exp */
910 : }
911 :
912 3811 : X_hat_fx = Mpy_32_16_1( X_hat_fx, INV_MAX_DELAYREGLEN_FX_Q15 ); /* Q31-X_hat_exp */
913 3811 : Y_hat_fx = Mpy_32_16_1( Y_hat_fx, INV_MAX_DELAYREGLEN_FX_Q15 ); /* Q31-Y_hat_exp */
914 3811 : XY_hat_fx = Mpy_32_16_1( XY_hat_fx, INV_MAX_DELAYREGLEN_FX_Q15 ); /* Q31-XY_hat_exp */
915 3811 : X_SQR_hat_fx = Mpy_32_16_1( X_SQR_hat_fx, INV_MAX_DELAYREGLEN_FX_Q15 ); /* Q31-X_SQR_hat_exp */
916 :
917 3811 : beta_reg_fx = 0;
918 3811 : move32();
919 3811 : beta_reg_exp = 0;
920 3811 : move16();
921 3811 : tempF_fx = BASOP_Util_Add_Mant32Exp( X_SQR_hat_fx, X_SQR_hat_exp, L_negate( Mpy_32_32( X_hat_fx, X_hat_fx ) ), shl( X_hat_exp, 1 ), &tempF_exp ); /* Q31-tempF_exp */
922 :
923 3811 : IF( tempF_fx != 0 )
924 : {
925 3811 : temp32 = BASOP_Util_Add_Mant32Exp( XY_hat_fx, XY_hat_exp, L_negate( Mpy_32_32( X_hat_fx, Y_hat_fx ) ), add( X_hat_exp, Y_hat_exp ), &exp ); /* Q31-exp */
926 3811 : beta_reg_fx = BASOP_Util_Divide3232_Scale_newton( temp32, tempF_fx, &beta_reg_exp ); /* Q31-beta_reg_exp */
927 3811 : if ( beta_reg_fx )
928 : {
929 3654 : beta_reg_exp = add( beta_reg_exp, sub( exp, tempF_exp ) );
930 : }
931 : }
932 :
933 3811 : alpha_reg_fx = BASOP_Util_Add_Mant32Exp( Y_hat_fx, Y_hat_exp, L_negate( Mpy_32_32( X_hat_fx, beta_reg_fx ) ), add( X_hat_exp, beta_reg_exp ), &alpha_reg_exp ); /* Q31-alpha_reg_exp */
934 3811 : reg_prv_corr_fx = BASOP_Util_Add_Mant32Exp( alpha_reg_fx, alpha_reg_exp, Mpy_32_32( beta_reg_fx, L_shl( MAX_DELAYREGLEN, 27 ) ), add( 4, beta_reg_exp ), ®_prv_corr_exp ); /* Q31-reg_prv_corr_exp */
935 :
936 3811 : reg_prv_corr_fx = L_shr( reg_prv_corr_fx, 1 );
937 3811 : reg_prv_corr_exp = add( reg_prv_corr_exp, 1 );
938 3811 : IF( LE_16( TRUNC_FX( reg_prv_corr_fx, reg_prv_corr_exp ), -L_NCSHIFT_DS ) )
939 : {
940 0 : reg_prv_corr_fx = -L_NCSHIFT_DS + 1;
941 0 : move32();
942 0 : reg_prv_corr_exp = 31;
943 0 : move16();
944 : }
945 :
946 3811 : IF( GE_16( TRUNC_FX( reg_prv_corr_fx, reg_prv_corr_exp ), L_NCSHIFT_DS ) )
947 : {
948 2 : reg_prv_corr_fx = L_NCSHIFT_DS - 1;
949 2 : move32();
950 2 : reg_prv_corr_exp = 31;
951 2 : move16();
952 : }
953 :
954 3811 : bias_par_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( hStereoTCA->smooth_dist_reg_prv_corr_fx, A_BIAS_FX_Q15 ), hStereoTCA->smooth_dist_reg_prv_corr_exp, L_shl( B_BIAS_FX_Q15, Q16 ), 0, &bias_par_exp ); /* Q31-bias_par_exp */
955 :
956 3811 : Word32 XH_BIAS_tmp = L_shl( XH_BIAS_FX_Q15, Q16 ); /* Q31 */
957 3811 : Word32 XL_BIAS_tmp = L_shl( XL_BIAS_FX_Q15, Q16 ); /* Q31 */
958 :
959 3811 : IF( bias_par_exp < 0 )
960 : {
961 3496 : bias_par_fx = L_shl( bias_par_fx, bias_par_exp ); /* Q31 */
962 3496 : bias_par_exp = 0;
963 3496 : move16();
964 : }
965 : ELSE
966 : {
967 315 : XH_BIAS_tmp = L_shr( XH_BIAS_tmp, bias_par_exp ); /* Q31-bias_par_exp */
968 315 : XL_BIAS_tmp = L_shr( XL_BIAS_tmp, bias_par_exp ); /* Q31-bias_par_exp */
969 : }
970 :
971 3811 : bias_par_fx = L_min( bias_par_fx, XH_BIAS_tmp );
972 3811 : bias_par_fx = L_max( bias_par_fx, XL_BIAS_tmp );
973 3811 : bias_par_fx = L_shr( bias_par_fx, bias_par_exp );
974 3811 : bias_par_exp = 0;
975 3811 : move16();
976 :
977 3811 : width_par_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( hStereoTCA->smooth_dist_reg_prv_corr_fx, A_WIDTH_FX_Q31 ), hStereoTCA->smooth_dist_reg_prv_corr_exp, B_WIDTH_FX_Q31, 0, &width_par_exp ); /* Q31-width_par_exp */
978 3811 : Word32 XH_WIDTH_tmp = L_shl( XH_WIDTH_FX_Q15, Q16 ); /* Q31 */
979 3811 : Word32 XL_WIDTH_tmp = L_shl( XL_WIDTH_FX_Q15, Q16 ); /* Q31 */
980 :
981 3811 : IF( width_par_exp < 0 )
982 : {
983 3811 : width_par_fx = L_shl( width_par_fx, width_par_exp ); /* Q31 */
984 3811 : width_par_exp = 0;
985 3811 : move16();
986 : }
987 : ELSE
988 : {
989 0 : XH_WIDTH_tmp = L_shr( XH_WIDTH_tmp, width_par_exp );
990 0 : XL_WIDTH_tmp = L_shr( XL_WIDTH_tmp, width_par_exp );
991 : }
992 3811 : width_par_fx = L_min( width_par_fx, XH_WIDTH_tmp );
993 3811 : width_par_fx = L_max( width_par_fx, XL_WIDTH_tmp );
994 3811 : width_par_fx = L_shl( width_par_fx, width_par_exp );
995 3811 : width_par_exp = 0;
996 3811 : move16();
997 :
998 3811 : win_width = (Word16) L_shr( Mpy_32_32( width_par_fx, 1350565888 /* ( 4L_NCSHIFT_DS + 1 ) in Q23 */ ), sub( 31, add( width_par_exp, 8 ) ) ); /* Q23-(31-(width_par_exp-8)) */
999 :
1000 3811 : win_bias_fx = round_fx( bias_par_fx ); // Q15
1001 :
1002 3811 : k1_fx = add( MAX_16 >> 1, shr( win_bias_fx, 1 ) ); // Q15
1003 3811 : k2_fx = sub( MAX_16 >> 1, shr( win_bias_fx, 1 ) ); // Q15
1004 :
1005 159379 : FOR( i = 0; i < ( 2 * L_NCSHIFT_DS - ( win_width * 2 ) ); i++ )
1006 : {
1007 155568 : loc_weight_win_fx[i] = win_bias_fx; // Q15
1008 155568 : move16();
1009 : }
1010 :
1011 306246 : FOR( i = ( 2 * L_NCSHIFT_DS - ( win_width * 2 ) ); i <= ( 2 * L_NCSHIFT_DS + ( win_width * 2 ) ); i++ )
1012 : {
1013 302435 : Word16 cos_inp = BASOP_Util_Divide1616_Scale( sub( i, 2 * L_NCSHIFT_DS ), shl( win_width, 1 ), &exp ); /* Q15-exp */
1014 302435 : cos_inp = shr_sat( cos_inp, sub( 0, exp ) );
1015 302435 : cos_inp = getCosWord16R2( shr( cos_inp, 1 ) ); // Q15
1016 302435 : loc_weight_win_fx[i] = add( k1_fx, mult( k2_fx, cos_inp ) ); // Q15
1017 302435 : move16();
1018 : }
1019 :
1020 163190 : FOR( i = ( 2 * L_NCSHIFT_DS + ( win_width * 2 ) ); i < ( 4 * L_NCSHIFT_DS + 1 ); i++ )
1021 : {
1022 159379 : loc_weight_win_fx[i] = win_bias_fx; // Q15
1023 159379 : move16();
1024 : }
1025 3811 : reg_prv_corr_fx = L_shr( reg_prv_corr_fx, 1 );
1026 3811 : reg_prv_corr_exp = add( reg_prv_corr_exp, 1 );
1027 3811 : Word16 x = TRUNC_FX( reg_prv_corr_fx, reg_prv_corr_exp ); /* Q0 */
1028 3811 : move16();
1029 312502 : for ( i = 0, j = ( L_NCSHIFT_DS - x ); i < 2 * L_NCSHIFT_DS + 1; i++, j++ )
1030 : {
1031 308691 : corrEst_fx[i] = Mpy_32_16_1( corrEst_fx[i], loc_weight_win_fx[j] ); /* Q31-corrEst_exp */
1032 308691 : move32();
1033 : }
1034 3811 : test();
1035 3811 : test();
1036 3811 : IF( LT_32( hStereoTCA->prevTargetGain_fx, 429496730 /*0.8f in Q29*/ ) && vad_flag1 )
1037 : {
1038 : /* ch 2 is prev reference channel */
1039 0 : v_multc_fixed( corrEst_fx, 644245095 /*1.2f in Q29*/, corrEst_fx, L_NCSHIFT_DS + 1 ); /* Q31-corrEst_exp */
1040 0 : v_multc_fixed( corrEst_fx + L_NCSHIFT_DS + 1, 447213470 /* 0.833 in Q29*/, corrEst_fx + L_NCSHIFT_DS + 1, L_NCSHIFT_DS ); /* Q31-corrEst_exp */
1041 0 : corrEst_exp = add( corrEst_exp, 2 );
1042 : }
1043 3811 : ELSE IF( GT_32( hStereoTCA->prevTargetGain_fx, 644245094 /*1.2f in Q29*/ ) && vad_flag1 )
1044 : {
1045 : /* ch 1 is prev reference channel */
1046 0 : v_multc_fixed( corrEst_fx, 447213470 /* 0.833 f in Q29*/, corrEst_fx, L_NCSHIFT_DS ); /* Q31-corrEst_exp */
1047 0 : v_multc_fixed( corrEst_fx + L_NCSHIFT_DS, 644245095 /*1.2f in Q29*/, corrEst_fx + L_NCSHIFT_DS, L_NCSHIFT_DS + 1 ); /* Q31-corrEst_exp */
1048 0 : corrEst_exp = add( corrEst_exp, 2 );
1049 : }
1050 3811 : test();
1051 3811 : IF( BASOP_Util_Add_Mant32Exp( corrEst_ncorr_fx, corrEst_ncorr_exp, -429496730 /*0.8f in Q29*/, 2, &exp ) > 0 && vad_flag1 )
1052 : {
1053 1586 : i = s_max( 0, add( hStereoTCA->prevCorrLagStats[0], -1 + L_NCSHIFT_DS ) );
1054 1586 : j = s_min( 2 * L_NCSHIFT_DS, add( hStereoTCA->prevCorrLagStats[0], 1 + L_NCSHIFT_DS ) );
1055 1586 : k = add( sub( j, i ), 1 );
1056 :
1057 1586 : v_multc_fixed( corrEst_fx, ONE_IN_Q29 /*1.0f in Q29*/, corrEst_fx, i ); // to allign in same exp (Q31-corrEst_exp)
1058 1586 : v_multc_fixed( corrEst_fx + i, 644245095 /*1.2f in Q29*/, corrEst_fx + i, k ); /* Q31-corrEst_exp */
1059 1586 : v_multc_fixed( corrEst_fx + i + k, ONE_IN_Q29 /*1.0f in Q29*/, corrEst_fx + i + k, sub( 2 * L_NCSHIFT_DS + 1, i + k ) ); // to allign in same exp (Q31-corrEst_exp)
1060 1586 : corrEst_exp = add( corrEst_exp, 2 );
1061 : }
1062 :
1063 : /* Initial corr lag estimate */
1064 3811 : corrLagStats[0] = maximum_32_fx( corrEst_fx, add( sub( lagSearchRange[1], lagSearchRange[0] ), 1 ), &tempF_fx );
1065 3811 : move16();
1066 3811 : tempF_exp = corrEst_exp;
1067 3811 : move16();
1068 3811 : corrLagStats[0] = add( corrLagStats[0], lagSearchRange[0] );
1069 3811 : move16();
1070 :
1071 3811 : stmp = i_mult( corrLagStats[0], dsFactor ); /* Q0 */
1072 3811 : hStereoClassif->unclr_fv_fx[E_corrLagStats0] = L_shl( stmp, Q15 ); /* Q15 */
1073 3811 : move32();
1074 3811 : hStereoClassif->xtalk_fv_fx[E_corrLagStats0] = L_shl( stmp, Q15 ); /* Q15 */
1075 3811 : move32();
1076 3811 : hStereoClassif->xtalk_fv_fx[E_ica_corr_value0] = L_shl( tempF_fx, sub( tempF_exp, Q16 ) ); /* Q15 */
1077 3811 : move32();
1078 :
1079 3811 : test();
1080 3811 : IF( vad_flag1 == 0 && GT_16( alpha_fx, 22938 /* 0.7f in Q15 */ ) )
1081 : {
1082 15 : corrLagStats[0] = 0;
1083 15 : move16();
1084 : }
1085 :
1086 3811 : dist_reg_prv_corr_fx = L_abs( BASOP_Util_Add_Mant32Exp( reg_prv_corr_fx, reg_prv_corr_exp, -corrLagStats[0], Q31, &dist_reg_prv_corr_exp ) ); /* Q31-dist_reg_prv_corr_exp */
1087 3811 : test();
1088 3811 : IF( EQ_16( vad_flag1, 1 ) && EQ_16( vad_flag2, 1 ) )
1089 3759 : {
1090 :
1091 3759 : hStereoTCA->smooth_dist_reg_prv_corr_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( hStereoTCA->smooth_dist_reg_prv_corr_fx, SMOOTH_DIST_FACTOR_FX_Q15 ), hStereoTCA->smooth_dist_reg_prv_corr_exp, Mpy_32_16_1( dist_reg_prv_corr_fx, MAX_16 - SMOOTH_DIST_FACTOR_FX_Q15 ), dist_reg_prv_corr_exp, &hStereoTCA->smooth_dist_reg_prv_corr_exp ); /* Q31-hStereoTCA->smooth_dist_reg_prv_corr_exp */
1092 3759 : move32();
1093 3759 : Copy32( &( hStereoTCA->delay_0_mem_fx[1] ), &( hStereoTCA->delay_0_mem_fx[0] ), MAX_DELAYREGLEN - 1 ); /* Q31-hStereoTCA->delay_0_mem_exp */
1094 :
1095 3759 : hStereoTCA->delay_0_mem_fx[MAX_DELAYREGLEN - 1] = BASOP_Util_Add_Mant32Exp( Mpy_32_32( hStereoTCA->delay_0_mem_fx[MAX_DELAYREGLEN - 1], 429496730 /* 0.2 in Q31*/ ), hStereoTCA->delay_0_mem_exp, L_mult0( 26214 /* 0.8 in Q15*/, corrLagStats[0] ), Q16, &temp ); /* Q31-temp */
1096 3759 : move32();
1097 3759 : Word32 inpp = L_abs( BASOP_Util_Add_Mant32Exp( reg_prv_corr_fx, reg_prv_corr_exp, L_negate( hStereoTCA->delay_0_mem_fx[0] ), hStereoTCA->delay_0_mem_exp, &exp ) ); /* Q31-exp */
1098 3759 : inpp = L_shl_sat( inpp, sub( exp, 5 ) ); /* Q26 */
1099 3759 : IF( GT_32( inpp, 1677721600 ) ) // 25 in Q26
1100 : {
1101 86 : set32_fx( &( hStereoTCA->delay_0_mem_fx[0] ), hStereoTCA->delay_0_mem_fx[MAX_DELAYREGLEN - 1], MAX_DELAYREGLEN - 1 );
1102 86 : hStereoTCA->delay_0_mem_exp = temp;
1103 86 : move16();
1104 : }
1105 : ELSE
1106 : {
1107 3673 : IF( GT_16( temp, hStereoTCA->delay_0_mem_exp ) )
1108 : {
1109 179 : scale_sig32( hStereoTCA->delay_0_mem_fx, MAX_DELAYREGLEN - 1, sub( hStereoTCA->delay_0_mem_exp, temp ) ); /* Q31-hStereoTCA->delay_0_mem_exp */
1110 179 : hStereoTCA->delay_0_mem_exp = temp;
1111 179 : move16();
1112 : }
1113 : ELSE
1114 : {
1115 3494 : hStereoTCA->delay_0_mem_fx[MAX_DELAYREGLEN - 1] = L_shl( hStereoTCA->delay_0_mem_fx[MAX_DELAYREGLEN - 1], sub( temp, hStereoTCA->delay_0_mem_exp ) ); /* Q31-temp */
1116 3494 : move32();
1117 : }
1118 : }
1119 : }
1120 : ELSE
1121 : {
1122 52 : hStereoTCA->smooth_dist_reg_prv_corr_fx = 0;
1123 52 : move32();
1124 52 : hStereoTCA->smooth_dist_reg_prv_corr_exp = 0;
1125 52 : move16();
1126 : }
1127 3811 : test();
1128 3811 : IF( vad_flag1 == 0 || vad_flag2 == 0 )
1129 : {
1130 52 : Word32 tmp_delay = L_shr( hStereoTCA->delay_0_mem_fx[MAX_DELAYREGLEN - 1], 1 );
1131 52 : Word16 tmp_delay_e = add( hStereoTCA->delay_0_mem_exp, 1 );
1132 52 : corrLagStats[0] = TRUNC_FX( tmp_delay, tmp_delay_e ); /* Q0 */
1133 52 : move32();
1134 : }
1135 :
1136 : /* second iteration of xcorr update @ inputFs with interp*/
1137 3811 : tempRK_fx = hStereoTCA->corrEstLT_fx + add( -lagSearchRange[0], corrLagStats[0] );
1138 3811 : set32_fx( rInterp_fx, 0, MAX_INTERPOLATE );
1139 3811 : set16_fx( rInterp_exp, 0, MAX_INTERPOLATE );
1140 :
1141 : /* select the Rk interp sinc window */
1142 3811 : winInterp_fx = ica_sincInterp4_fx + SINC_ORDER1;
1143 :
1144 3811 : IF( EQ_16( dsFactor, 2 ) )
1145 : {
1146 757 : winInterp_fx = ica_sincInterp2_fx + SINC_ORDER1;
1147 : }
1148 3054 : ELSE IF( EQ_16( dsFactor, 6 ) )
1149 : {
1150 1022 : winInterp_fx = ica_sincInterp6_fx + SINC_ORDER1;
1151 : }
1152 :
1153 3811 : corrLagStats[1] = i_mult( corrLagStats[0], dsFactor ); /* Q0 */
1154 3811 : move16();
1155 3811 : interpMin = s_max( -sub( dsFactor, 1 ), -add( corrLagStats[1], i_mult( L_NCSHIFT_DS, dsFactor ) ) );
1156 3811 : interpMax = s_min( sub( dsFactor, 1 ), sub( i_mult( L_NCSHIFT_DS, dsFactor ), corrLagStats[1] ) );
1157 3811 : interpLen = add( sub( interpMax, interpMin ), 1 );
1158 :
1159 31548 : for ( i = interpMin, k = 0; i <= interpMax; i++, k++ )
1160 : {
1161 27737 : rInterp_fx[k] = 0;
1162 27737 : move32();
1163 370602 : FOR( j = -( SINC_ORDER1 / dsFactor ); j <= ( SINC_ORDER1 / dsFactor ); j++ )
1164 : {
1165 342865 : m = i_mult( j, dsFactor ); /* Q0 */
1166 342865 : test();
1167 342865 : IF( GE_16( sub( m, i ), -SINC_ORDER1 ) && LE_16( sub( m, i ), SINC_ORDER1 ) )
1168 : {
1169 318939 : IF( GT_16( j, sub( lagSearchRange[1], corrLagStats[0] ) ) )
1170 : {
1171 50 : rInterp_fx[k] = BASOP_Util_Add_Mant32Exp( rInterp_fx[k], rInterp_exp[k], Mpy_32_32( tempRK_fx[lagSearchRange[1] - corrLagStats[0]], winInterp_fx[m - i] ), hStereoTCA->corrEstLT_exp, &temp ); /* Q31-temp */
1172 50 : move32();
1173 50 : rInterp_exp[k] = temp;
1174 50 : move16();
1175 : }
1176 318889 : ELSE IF( LT_16( j, sub( lagSearchRange[0], corrLagStats[0] ) ) )
1177 : {
1178 176 : rInterp_fx[k] = BASOP_Util_Add_Mant32Exp( rInterp_fx[k], rInterp_exp[k], Mpy_32_32( tempRK_fx[lagSearchRange[0] - corrLagStats[0]], winInterp_fx[m - i] ), hStereoTCA->corrEstLT_exp, &temp ); /* Q31-temp */
1179 176 : move32();
1180 176 : rInterp_exp[k] = temp;
1181 176 : move16();
1182 : }
1183 : ELSE
1184 : {
1185 318713 : rInterp_fx[k] = BASOP_Util_Add_Mant32Exp( rInterp_fx[k], rInterp_exp[k], Mpy_32_32( tempRK_fx[j], winInterp_fx[m - i] ), hStereoTCA->corrEstLT_exp, &temp ); /* Q31-temp */
1186 318713 : move32();
1187 318713 : rInterp_exp[k] = temp;
1188 318713 : move16();
1189 : }
1190 : }
1191 : }
1192 : }
1193 3811 : temp = rInterp_exp[0];
1194 3811 : move16();
1195 45732 : FOR( i = 0; i < MAX_INTERPOLATE; i++ )
1196 : {
1197 41921 : temp = s_max( temp, rInterp_exp[i] );
1198 : }
1199 :
1200 45732 : FOR( i = 0; i < MAX_INTERPOLATE; i++ )
1201 : {
1202 41921 : rInterp_fx[i] = L_shl( rInterp_fx[i], sub( rInterp_exp[i], temp ) ); /* Q31-rInterp_exp[i] */
1203 41921 : move32();
1204 : }
1205 :
1206 3811 : corrLagStats[1] = add( corrLagStats[1], add( maximum_32_fx( rInterp_fx, interpLen, &tempF_fx ), interpMin ) ); /* Q0 */
1207 3811 : move16();
1208 :
1209 : /* save corr lag stats for the current frame */
1210 3811 : Copy( corrLagStats, hStereoTCA->corrLagStats, 3 ); /* Q0 */
1211 :
1212 3811 : return;
1213 : }
1214 :
1215 : /*---------------------------------------------------------------
1216 : * Function estDownmixGain_fx()
1217 : *
1218 : * Down mix gain estimation module; convert L/R to M/S.
1219 : * ---------------------------------------------------------------*/
1220 :
1221 63470 : static void estDownmixGain_fx(
1222 : STEREO_TCA_ENC_HANDLE hStereoTCA, /* i/o: Stereo TCA Encoder handle */
1223 : const Word32 *chan1, /* i : reference signal q_chan */
1224 : const Word32 *chan2, /* i/o: target signal to be scaled q_chan */
1225 : const Word16 q_chan, /* i : Q of the channel signal Q0*/
1226 : const Word16 ncShift, /* i : shift Q0*/
1227 : const Word16 length, /* i : input frame length Q0*/
1228 : const Word16 element_mode, /* i : element mode Q0*/
1229 : STEREO_CLASSIF_HANDLE hStereoClassif, /* i/o: stereo classifier handle */
1230 : const Word16 tdm_LRTD_flag /* i : LRTD stereo mode flag Q0*/
1231 : )
1232 : {
1233 : Word16 i, i1, i2;
1234 : Word32 tempN, tempD;
1235 : Word16 alpha, temp;
1236 : Word16 currentGain, currentGain_e;
1237 : Word32 currentGain_log10;
1238 : Word32 unclr_instTargetGain;
1239 : Word32 prevTargetGain_log10;
1240 63470 : Word16 exp = 0;
1241 63470 : Word16 shift = 0;
1242 63470 : move16(); // exp
1243 63470 : move16(); // shift
1244 :
1245 63470 : IF( hStereoTCA->refChanIndx == L_CH_INDX )
1246 : {
1247 63452 : i1 = 0;
1248 63452 : move16();
1249 63452 : i2 = ncShift; /* Q0 */
1250 63452 : move16();
1251 : }
1252 : ELSE
1253 : {
1254 18 : i1 = ncShift; /* Q0 */
1255 18 : move16();
1256 18 : i2 = 0;
1257 18 : move16();
1258 : }
1259 :
1260 : /* abs sample sum estimation */
1261 63470 : tempN = 0;
1262 63470 : move32();
1263 63470 : tempD = 0;
1264 63470 : move32();
1265 43752964 : FOR( i = 0; i < length; i++ )
1266 : {
1267 43689494 : tempN = L_add( tempN, L_abs( chan1[i1 + i] ) ); /* q_chan */
1268 43689494 : tempD = L_add( tempD, L_abs( chan2[i2 + i] ) ); /* q_chan */
1269 : }
1270 :
1271 63470 : alpha = hStereoTCA->corrStatsSmoothFac_fx; /* Q15 */
1272 63470 : move16();
1273 63470 : IF( tempD == 0 )
1274 : {
1275 0 : currentGain_e = norm_l( hStereoTCA->prevTargetGain_fx );
1276 0 : currentGain = extract_h( L_shl( hStereoTCA->prevTargetGain_fx, currentGain_e ) );
1277 0 : currentGain_e = add( currentGain_e, 2 );
1278 : }
1279 : ELSE
1280 : {
1281 63470 : currentGain = BASOP_Util_Divide3232_Scale( tempN, tempD, &exp ); /* Q31-exp */
1282 63470 : currentGain_e = exp;
1283 63470 : move16();
1284 63470 : if ( currentGain == 0 )
1285 : {
1286 0 : currentGain_e = 0;
1287 0 : move16();
1288 : }
1289 : }
1290 :
1291 63470 : IF( GT_32( EPSILON_FX, currentGain ) )
1292 : {
1293 0 : currentGain = EPSILON_FX;
1294 0 : move16();
1295 0 : currentGain_e = 0;
1296 0 : move16();
1297 : }
1298 63470 : hStereoTCA->instTargetGain_fx = L_shl_sat( L_deposit_h( currentGain ), sub( currentGain_e, 2 ) );
1299 63470 : move32();
1300 63470 : prevTargetGain_log10 = BASOP_Util_Log10( hStereoTCA->prevTargetGain_fx, 2 ); // Output in Q25
1301 63470 : currentGain_log10 = BASOP_Util_Log10( L_deposit_h( currentGain ), currentGain_e ); // Output in Q25
1302 : // multiplication result will be Q25 should be fit to Q15 hence right shift by 10.
1303 : // Q25 - Q10 = Q15
1304 63470 : currentGain = extract_l( L_shr( Madd_32_16( Mpy_32_16_1( prevTargetGain_log10, alpha ), currentGain_log10, sub( MAX_16, alpha ) ), Q10 ) ); /* Q15 */
1305 63470 : currentGain_e = 0;
1306 63470 : move16();
1307 :
1308 63470 : test();
1309 63470 : IF( EQ_16( element_mode, IVAS_CPE_TD ) && hStereoClassif != NULL )
1310 : {
1311 3811 : Word16 exp_chan = sub( Q31, q_chan );
1312 : Word16 exp_div;
1313 : // tempD = powf( 10, currentGain );
1314 : // 10 ^ currentGain = 2 ^ (3.32192809488 * currentGain)
1315 : // 3.32192809488 in Q13 27213
1316 3811 : tempD = BASOP_util_Pow2( L_mult( currentGain, 27213 ), add( currentGain_e, Q2 ), &exp ); /* Q31-exp */
1317 3811 : unclr_instTargetGain = L_deposit_h( BASOP_Util_Divide3232_Scale( tempN, L_add( tempD, EPSILON_FX ), &exp_div ) ); /* Q31-exp */
1318 3811 : exp = add( sub( exp_chan, exp ), exp_div );
1319 3811 : if ( unclr_instTargetGain == 0 )
1320 : {
1321 0 : exp = 0;
1322 0 : move16();
1323 : }
1324 3811 : unclr_instTargetGain = BASOP_Util_Log10( L_add( unclr_instTargetGain, L_shr( MAX_32, sub( Q31, exp ) ) ), exp );
1325 : // unclr_fv_fx is expected in Q15 - log result will be in Q25 - hence rightshift by 10.
1326 3811 : hStereoClassif->unclr_fv_fx[E_ica_instTargetGain] = L_shr( unclr_instTargetGain, Q10 ); /* Q15 */
1327 3811 : move32();
1328 : }
1329 :
1330 63470 : test();
1331 63470 : IF( EQ_16( tdm_LRTD_flag, 1 ) )
1332 : {
1333 3690 : currentGain = 0;
1334 3690 : move32();
1335 : }
1336 59780 : ELSE IF( GT_16( hStereoTCA->LRTD_G_ATT_cnt, 1 ) ) /* lrtd_mode == 1 but tdm_LRTD_flag still 0 */
1337 : {
1338 211 : currentGain = BASOP_Util_Divide1616_Scale( currentGain, hStereoTCA->LRTD_G_ATT_cnt, &exp );
1339 211 : currentGain_e = add( exp, sub( currentGain_e, 15 ) );
1340 : }
1341 :
1342 63470 : IF( GE_16( norm_s( currentGain ), sub( currentGain_e, 1 ) ) )
1343 : {
1344 : /* convert currentGain into Q14 */
1345 63470 : currentGain = shl( currentGain, sub( currentGain_e, 1 ) ); /* Q14 */
1346 63470 : currentGain_e = 1;
1347 63470 : move16();
1348 : }
1349 : ELSE
1350 : {
1351 0 : shift = sub( currentGain_e, 1 );
1352 0 : move16();
1353 : }
1354 :
1355 : /* quantize the target gain */
1356 63470 : hStereoTCA->indx_ica_gD = usquant_fx( currentGain, &temp, shr( STEREO_TCA_GDMIN_FX_Q14, shift ), shr( STEREO_TCA_GDSTEP_FX_Q13, shift ), ( 1 << STEREO_BITS_TCA_GD ) ); /* Q13 */
1357 63470 : move16();
1358 : // hStereoTCA->targetGain_fx = powf( 10, temp );
1359 : // 10 ^ temp = 2 ^ (3.32192809488 * temp)
1360 : // 3.32192809488 in Q13 27213
1361 : // exponent of power function input will be 2 more since constant is in Q13
1362 63470 : exp = 2;
1363 63470 : move16();
1364 63470 : hStereoTCA->targetGain_fx = BASOP_util_Pow2( L_mult( temp, 27213 ), add( currentGain_e, 2 ), &exp ); /* Q31-exp */
1365 63470 : move32();
1366 63470 : hStereoTCA->targetGain_fx = L_shl( hStereoTCA->targetGain_fx, sub( exp, 2 ) ); // Q29
1367 63470 : move32();
1368 63470 : return;
1369 : }
1370 :
1371 : /*---------------------------------------------------------------
1372 : * Function icaMemUpdate()
1373 : *
1374 : * Recalculates the memories corresponding to the previous frame.
1375 : * ---------------------------------------------------------------*/
1376 3811 : static void icaMemUpdate_fx(
1377 : Encoder_State **sts, /* i/o: encoder state structure */
1378 : CPE_ENC_HANDLE hCPE, /* i : CPE encoder structure */
1379 : Word32 *bufChanL, /* i/o: L signal correction from previous frame q_com*/
1380 : Word32 *bufChanR, /* i/o: R signal correction from previous frame q_com*/
1381 : Word16 q_com,
1382 : const Word16 lMemRecalc, /* i : memory length at input Sampling Rate Q0*/
1383 : const Word16 lMemRecalc_SCh, /* i : SCh memory length at input Sampling Rate Q0*/
1384 : const Word16 input_frame /* i : frame length Q0*/
1385 : )
1386 : {
1387 : Word32 *ptr1, *ptr2;
1388 : Word16 i;
1389 : Word32 ratio_L, One_m_Ratio;
1390 :
1391 3811 : IF( EQ_16( hCPE->element_mode, IVAS_CPE_TD ) )
1392 : {
1393 : /* Recalc of the memories - Downmix @ inputFs */
1394 : /*----------------------------------------------------------------*
1395 : * Create first part of the mixture using the old ratios
1396 : *----------------------------------------------------------------*/
1397 :
1398 3811 : IF( hCPE->hStereoTD->tdm_last_SM_flag )
1399 : {
1400 0 : ratio_L = hCPE->hStereoTD->tdm_last_ratio_SM_fx; /* Q31 */
1401 0 : move32();
1402 0 : One_m_Ratio = L_sub( ratio_L, MAX_32 );
1403 : }
1404 : ELSE
1405 : {
1406 3811 : ratio_L = hCPE->hStereoTD->tdm_last_ratio_fx; /* Q31 */
1407 3811 : move32();
1408 3811 : One_m_Ratio = L_sub( MAX_32, ratio_L );
1409 : }
1410 :
1411 3811 : ptr1 = sts[0]->input32_fx - add( lMemRecalc, lMemRecalc_SCh ); /* Q31-sts[0]->q_inp32 */
1412 3811 : ptr2 = sts[1]->input32_fx - add( lMemRecalc, lMemRecalc_SCh ); /* Q31-sts[1]->q_inp32 */
1413 :
1414 3811 : IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_TD ) )
1415 : {
1416 3751 : IF( hCPE->hStereoTD->flag_skip_DMX )
1417 : {
1418 30932 : FOR( i = lMemRecalc_SCh; i < ( lMemRecalc + lMemRecalc_SCh ); i++ )
1419 : {
1420 30840 : ptr1[i] = bufChanL[i]; /* q_com */
1421 30840 : move32();
1422 30840 : ptr2[i] = bufChanR[i]; /* q_com */
1423 30840 : move32();
1424 : }
1425 : }
1426 : ELSE
1427 : {
1428 903299 : FOR( i = lMemRecalc_SCh; i < lMemRecalc + lMemRecalc_SCh; i++ )
1429 : {
1430 899640 : ptr1[i] = L_add( Mpy_32_32( bufChanR[i], One_m_Ratio ), Mpy_32_32( bufChanL[i], ratio_L ) ); /* q_com */
1431 899640 : move32();
1432 899640 : ptr2[i] = L_sub( Mpy_32_32( bufChanL[i], One_m_Ratio ), Mpy_32_32( bufChanR[i], ratio_L ) ); /* q_com */
1433 899640 : move32();
1434 : }
1435 : }
1436 : }
1437 : ELSE
1438 : {
1439 : Word16 fac, incr;
1440 : Word32 tmp1, tmp2;
1441 :
1442 : /* reset the past input signal (the signal is used in SWB BWE) */
1443 60 : set32_fx( sts[1]->input32_fx - input_frame, 0, input_frame );
1444 :
1445 60 : IF( hCPE->hStereoTD->flag_skip_DMX )
1446 : {
1447 : /* reconstruction of the Secondary channel past segment */
1448 813 : FOR( i = 0; i < lMemRecalc_SCh; i++ )
1449 : {
1450 805 : ptr2[i] = L_add( Mpy_32_32( bufChanL[i], One_m_Ratio ), Mpy_32_32( bufChanR[i], ratio_L ) ); /* q_com */
1451 805 : move32();
1452 : }
1453 :
1454 : /* overlap-add smoothing to equalize for different DMX signal energy between DFT and TD stereo */
1455 8 : fac = div_s( 1, lMemRecalc ); // Q15
1456 8 : incr = fac; // Q15
1457 8 : move16();
1458 :
1459 2768 : FOR( i = lMemRecalc_SCh; i < ( lMemRecalc + lMemRecalc_SCh ); i++ )
1460 : {
1461 2760 : tmp1 = bufChanL[i]; /* q_com */
1462 2760 : move32();
1463 2760 : tmp2 = bufChanR[i]; /* q_com */
1464 2760 : move32();
1465 :
1466 2760 : ptr1[i] = L_add( Mpy_32_16_1( ptr1[i], sub( MAX_16, fac ) ), Mpy_32_16_1( tmp1, fac ) ); /* q_com */
1467 2760 : move32();
1468 :
1469 : /*ptr2[i] = (1.0f - fac) * ptr2[i] + fac * tmp2;*/ /* the secondary channel (downmixed) buffer of DFT stereo is empty ! */
1470 2760 : ptr2[i] = tmp2; /* q_com */
1471 2760 : move32();
1472 :
1473 2760 : fac = add_sat( fac, incr );
1474 : }
1475 : }
1476 : ELSE
1477 : {
1478 : /* reconstruction of the Secondary channel past segment */
1479 3902 : FOR( i = 0; i < lMemRecalc_SCh; i++ )
1480 : {
1481 3850 : ptr2[i] = L_sub( Mpy_32_32( bufChanL[i], One_m_Ratio ), Mpy_32_32( bufChanR[i], ratio_L ) ); /* q_com */
1482 3850 : move32();
1483 : }
1484 :
1485 : /* overlap-add smoothing to equalize for different DMX signal energy between DFT and TD stereo */
1486 52 : fac = div_s( 1, lMemRecalc ); // Q15
1487 52 : incr = fac; // Q15
1488 52 : move16();
1489 13252 : FOR( i = lMemRecalc_SCh; i < ( lMemRecalc + lMemRecalc_SCh ); i++ )
1490 : {
1491 13200 : tmp1 = L_add( Mpy_32_32( bufChanR[i], One_m_Ratio ), Mpy_32_32( bufChanL[i], ratio_L ) ); /* q_com */
1492 13200 : tmp2 = L_sub( Mpy_32_32( bufChanL[i], One_m_Ratio ), Mpy_32_32( bufChanR[i], ratio_L ) ); /* q_com */
1493 :
1494 13200 : ptr1[i] = L_add( Mpy_32_16_1( ptr1[i], sub( MAX_16, fac ) ), Mpy_32_16_1( tmp1, fac ) ); /* q_com */
1495 13200 : move32();
1496 : /*ptr2[i] = (1.0f - fac) * ptr2[i] + fac * tmp2;*/ /* the secondary channel (downmixed) buffer of DFT stereo is empty ! */
1497 13200 : ptr2[i] = tmp2; /* q_com */
1498 13200 : move32();
1499 :
1500 13200 : fac = add_sat( fac, incr );
1501 : }
1502 : }
1503 : }
1504 : }
1505 :
1506 3811 : IF( hCPE->hStereoICBWE != NULL )
1507 : {
1508 : assert( L_MEM_RECALC_TBE_NS <= L_MEM_RECALC_NS );
1509 121 : i = NS2SA_FX2( sts[0]->input_Fs, L_MEM_RECALC_TBE_NS );
1510 121 : Copy_Scale_sig_32_16( bufChanL + sub( add( lMemRecalc, lMemRecalc_SCh ), i ), hCPE->hStereoICBWE->icbwe_inp_mem_fx[0], i, -Q16 ); /* q_com-16 */
1511 121 : Copy_Scale_sig_32_16( bufChanR + sub( add( lMemRecalc, lMemRecalc_SCh ), i ), hCPE->hStereoICBWE->icbwe_inp_mem_fx[1], i, -Q16 ); /* q_com-16 */
1512 121 : hCPE->hStereoICBWE->q_dataChan_fx = sub( q_com, Q16 );
1513 121 : move16();
1514 : }
1515 :
1516 3811 : return;
1517 : }
1518 : /*---------------------------------------------------------------
1519 : * stereo_tca_enc()
1520 : *
1521 : * Stereo temporal inter-channel adjustment/allocation processing module;
1522 : * Downmix, convert L/R to M/S.
1523 : * ---------------------------------------------------------------*/
1524 410255 : void stereo_tca_enc_fx(
1525 : CPE_ENC_HANDLE hCPE, /* i : CPE encoder structure */
1526 : const Word16 input_frame /* i : length of a frame per channel Q0*/
1527 : )
1528 : {
1529 : /* temp variables */
1530 : Word16 i, dsFactor, lMemRecalc;
1531 : Encoder_State **sts;
1532 : STEREO_TCA_ENC_HANDLE hStereoTCA;
1533 :
1534 : /* Buffers, input Left and right channels @ input_Fs*/
1535 : Word16 lMemRecalc_SCh;
1536 : Word32 input_mem_loc_fx[2][NS2SA( 48000, L_MEM_RECALC_NS + L_MEM_RECALC_SCH_NS )];
1537 : Word32 bufChanL_fx[L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX];
1538 : Word32 bufChanR_fx[L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX];
1539 : Word32 *ptrChanL_fx, *ptrChanR_fx;
1540 :
1541 410255 : set32_fx( bufChanL_fx, 0, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX );
1542 410255 : set32_fx( bufChanR_fx, 0, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX );
1543 410255 : set32_fx( input_mem_loc_fx[0], 0, NS2SA( 48000, L_MEM_RECALC_NS + L_MEM_RECALC_SCH_NS ) );
1544 410255 : set32_fx( input_mem_loc_fx[1], 0, NS2SA( 48000, L_MEM_RECALC_NS + L_MEM_RECALC_SCH_NS ) );
1545 : /* Buffers at internal sampling rate, i.e., CORR_INTER_FS */
1546 : Word32 bufChanL_DS_fx[L_FRAME_DS + ADDED_MEM_DS];
1547 : Word32 bufChanR_DS_fx[L_FRAME_DS + ADDED_MEM_DS];
1548 : Word32 *ptrChanL_DS_fx, *ptrChanR_DS_fx;
1549 : Word32 *target_fx;
1550 : Word16 target_idx;
1551 :
1552 : Word16 prevNCShift, currentNCShift;
1553 : Word16 tempLag[2];
1554 : Word32 corrEstStage2_fx[N_MAX_SHIFT_CHANGE + 1];
1555 : Word16 corrEstStage2_exp;
1556 : Word16 q_com, bufChan_q, input_mem_loc_q;
1557 : /* temp variables */
1558 : Word32 tempF1_fx, tempF_fx;
1559 : Word16 tempF1_exp;
1560 : Word16 tempS, tempS_buff[3];
1561 : Word16 maxCorrStatsDev, L_shift_adapt;
1562 410255 : Word16 musicMode = 0, neighborLimit;
1563 410255 : move16();
1564 : Word32 input_Fs;
1565 : Word16 prev_ICA_flag;
1566 :
1567 : /* initialization */
1568 410255 : sts = hCPE->hCoreCoder;
1569 410255 : hStereoTCA = hCPE->hStereoTCA;
1570 :
1571 410255 : input_Fs = sts[0]->input_Fs;
1572 410255 : move32();
1573 :
1574 410255 : q_com = sts[0]->q_inp32;
1575 410255 : move16();
1576 :
1577 410255 : lMemRecalc = NS2SA_FX2( input_Fs, L_MEM_RECALC_NS );
1578 410255 : move16();
1579 410255 : lMemRecalc_SCh = NS2SA_FX2( input_Fs, L_MEM_RECALC_SCH_NS );
1580 410255 : move16();
1581 :
1582 410255 : IF( EQ_16( hCPE->element_mode, IVAS_CPE_MDCT ) )
1583 : {
1584 346785 : return;
1585 : }
1586 :
1587 : /* populate L/R memories into current buffers */
1588 63470 : Word16 tempp_scale = L_norm_arr( hStereoTCA->memChanL_fx, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH );
1589 63470 : tempp_scale = s_min( tempp_scale, L_norm_arr( hStereoTCA->memChanR_fx, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH ) );
1590 63470 : scale_sig32( hStereoTCA->memChanL_fx, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH, tempp_scale ); /* hStereoTCA->memChan_q + tempp_scale */
1591 63470 : scale_sig32( hStereoTCA->memChanR_fx, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH, tempp_scale ); /* hStereoTCA->memChan_q + tempp_scale */
1592 63470 : hStereoTCA->memChan_q = add( hStereoTCA->memChan_q, tempp_scale );
1593 63470 : move16();
1594 63470 : Copy32( hStereoTCA->memChanL_fx, bufChanL_fx, add( lMemRecalc, lMemRecalc_SCh ) ); /* hStereoTCA->memChan_q */
1595 63470 : Copy32( hStereoTCA->memChanR_fx, bufChanR_fx, add( lMemRecalc, lMemRecalc_SCh ) ); /* hStereoTCA->memChan_q */
1596 63470 : bufChan_q = hStereoTCA->memChan_q;
1597 63470 : move16();
1598 : /* pointers to the current frame */
1599 63470 : ptrChanL_fx = bufChanL_fx + add( lMemRecalc, lMemRecalc_SCh ); // Q:bufChan_q
1600 63470 : ptrChanR_fx = bufChanR_fx + add( lMemRecalc, lMemRecalc_SCh ); // Q:bufChan_q
1601 :
1602 : /* copy interleaved stereo data to two channels, e.g., L, R */
1603 63470 : Copy32( sts[0]->input32_fx, ptrChanL_fx, input_frame ); /* sts[0]->q_inp32 */
1604 63470 : Copy32( sts[1]->input32_fx, ptrChanR_fx, input_frame ); /* sts[1]->q_inp32 */
1605 :
1606 : /* Scaling buffers to common Q*/
1607 63470 : scale_sig32( ptrChanL_fx, input_frame, sub( s_min( q_com, bufChan_q ), q_com ) ); /* s_min( q_com, bufChan_q ) */
1608 63470 : scale_sig32( ptrChanR_fx, input_frame, sub( s_min( q_com, bufChan_q ), q_com ) ); /* s_min( q_com, bufChan_q ) */
1609 63470 : scale_sig32( bufChanL_fx, add( lMemRecalc, lMemRecalc_SCh ), sub( s_min( q_com, bufChan_q ), bufChan_q ) ); /* s_min( q_com, bufChan_q ) */
1610 63470 : scale_sig32( bufChanR_fx, add( lMemRecalc, lMemRecalc_SCh ), sub( s_min( q_com, bufChan_q ), bufChan_q ) ); /* s_min( q_com, bufChan_q ) */
1611 63470 : bufChan_q = s_min( q_com, bufChan_q );
1612 63470 : q_com = bufChan_q;
1613 63470 : move16();
1614 : /* UNCLR classifier update */
1615 63470 : IF( hCPE->hStereoClassif->lrtd_mode == 0 ) /* Normal TD mode, no attenuation */
1616 : {
1617 59440 : hStereoTCA->LRTD_G_ATT_cnt = 1;
1618 59440 : move16();
1619 : }
1620 4030 : ELSE IF( hCPE->hStereoTD != NULL )
1621 : {
1622 3811 : IF( hCPE->hStereoTD->tdm_LRTD_flag == 0 ) /* lrtd_mode == 1, but in td section */
1623 : {
1624 121 : hStereoTCA->LRTD_G_ATT_cnt = add( hStereoTCA->LRTD_G_ATT_cnt, 1 );
1625 121 : move16();
1626 121 : hStereoTCA->LRTD_G_ATT_cnt = s_min( 1000, hStereoTCA->LRTD_G_ATT_cnt );
1627 121 : move16();
1628 : }
1629 : }
1630 :
1631 63470 : IF( NE_16( hCPE->element_mode, IVAS_CPE_TD ) )
1632 : {
1633 59659 : hStereoTCA->refChanIndx = L_CH_INDX;
1634 59659 : move16();
1635 59659 : hStereoTCA->corrStatsSmoothFac_fx = 22938 /*0.7 in Q15 */;
1636 59659 : move16();
1637 59659 : estDownmixGain_fx( hStereoTCA, ptrChanL_fx, ptrChanR_fx, q_com, 0, input_frame, hCPE->element_mode, NULL, 0 );
1638 59659 : hStereoTCA->prevTargetGain_fx = hStereoTCA->targetGain_fx;
1639 59659 : move16();
1640 :
1641 : /* back up the L/R missing target */
1642 59659 : Copy32( bufChanL_fx + input_frame, hStereoTCA->memChanL_fx, add( lMemRecalc, lMemRecalc_SCh ) ); // bufChan_q
1643 59659 : Copy32( bufChanR_fx + input_frame, hStereoTCA->memChanR_fx, add( lMemRecalc, lMemRecalc_SCh ) ); // bufChan_q
1644 59659 : hStereoTCA->memChan_q = q_com;
1645 59659 : move16();
1646 59659 : hStereoTCA->lMemRecalc = 0;
1647 59659 : move16();
1648 59659 : hStereoTCA->lMemRecalc_12k8 = 0;
1649 59659 : move16();
1650 59659 : hStereoTCA->lMemRecalc_16k = 0;
1651 59659 : move16();
1652 :
1653 59659 : return;
1654 : }
1655 3811 : ELSE IF( NE_16( hCPE->last_element_mode, IVAS_CPE_TD ) )
1656 : {
1657 60 : tempF_fx = hStereoTCA->targetGain_fx; // Q29
1658 60 : move32();
1659 60 : tempF1_fx = hStereoTCA->prevTargetGain_fx; // Q29
1660 60 : move32();
1661 60 : tempS = hStereoTCA->prevRefChanIndx;
1662 60 : move16();
1663 :
1664 60 : Copy( hStereoTCA->prevCorrLagStats, tempS_buff, 3 ); /* Q0 */
1665 :
1666 60 : stereo_tca_init_enc_fx( hStereoTCA, input_Fs );
1667 :
1668 60 : hStereoTCA->targetGain_fx = tempF_fx; // Q29
1669 60 : move32();
1670 60 : hStereoTCA->prevTargetGain_fx = tempF1_fx; // Q29
1671 60 : move32();
1672 :
1673 60 : IF( EQ_16( hCPE->hStereoClassif->lrtd_mode, 1 ) )
1674 : {
1675 60 : hStereoTCA->targetGain_fx = L_min( hStereoTCA->targetGain_fx, ONE_IN_Q29 ); // Q29
1676 60 : move32();
1677 60 : hStereoTCA->prevTargetGain_fx = L_min( hStereoTCA->prevTargetGain_fx, ONE_IN_Q29 ); // Q29
1678 60 : move32();
1679 :
1680 60 : hStereoTCA->prevTargetGain_fx = ONE_IN_Q29; // Q29
1681 60 : move32();
1682 : }
1683 :
1684 60 : hStereoTCA->prevRefChanIndx = tempS;
1685 60 : move16();
1686 60 : Copy( tempS_buff, hStereoTCA->prevCorrLagStats, 3 ); /* Q0 */
1687 :
1688 : /* populate memory */
1689 60 : IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_MDCT ) )
1690 : {
1691 8 : Copy32( sts[0]->input32_fx - add( lMemRecalc, lMemRecalc_SCh ), bufChanL_fx, add( lMemRecalc, lMemRecalc_SCh ) ); /* sts[0]->q_inp32 */
1692 8 : Copy32( sts[1]->input32_fx - add( lMemRecalc, lMemRecalc_SCh ), bufChanR_fx, add( lMemRecalc, lMemRecalc_SCh ) ); /* sts[1]->q_inp32 */
1693 : }
1694 : }
1695 :
1696 : /* populate L/R DS memories into current buffers */
1697 3811 : Copy32( hStereoTCA->memChanL_DS_fx, bufChanL_DS_fx, ADDED_MEM_DS ); // hStereoTCA->memChan_DS_q
1698 3811 : Copy32( hStereoTCA->memChanR_DS_fx, bufChanR_DS_fx, ADDED_MEM_DS ); // hStereoTCA->memChan_DS_q
1699 :
1700 3811 : scale_sig32( bufChanL_fx, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX, sub( s_min( hStereoTCA->memChan_DS_q, bufChan_q ), bufChan_q ) ); // s_min( hStereoTCA->memChan_DS_q, bufChan_q )
1701 3811 : scale_sig32( bufChanR_fx, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX, sub( s_min( hStereoTCA->memChan_DS_q, bufChan_q ), bufChan_q ) ); // s_min( hStereoTCA->memChan_DS_q, bufChan_q )
1702 :
1703 3811 : scale_sig32( bufChanL_DS_fx, ADDED_MEM_DS, sub( s_min( hStereoTCA->memChan_DS_q, bufChan_q ), hStereoTCA->memChan_DS_q ) ); // s_min( hStereoTCA->memChan_DS_q, bufChan_q )
1704 3811 : scale_sig32( bufChanR_DS_fx, ADDED_MEM_DS, sub( s_min( hStereoTCA->memChan_DS_q, bufChan_q ), hStereoTCA->memChan_DS_q ) ); // s_min( hStereoTCA->memChan_DS_q, bufChan_q )
1705 3811 : scale_sig32( hStereoTCA->memdecim_fx, 12, sub( s_min( hStereoTCA->memChan_DS_q, bufChan_q ), hStereoTCA->memChan_DS_q ) ); // s_min( hStereoTCA->memChan_DS_q, bufChan_q )
1706 :
1707 3811 : bufChan_q = s_min( hStereoTCA->memChan_DS_q, bufChan_q );
1708 3811 : q_com = bufChan_q;
1709 3811 : move16();
1710 3811 : hStereoTCA->memChan_DS_q = bufChan_q;
1711 3811 : move16();
1712 :
1713 : /* pointers to the current frame of DS */
1714 :
1715 3811 : ptrChanL_DS_fx = bufChanL_DS_fx + ADDED_MEM_DS; /* hStereoTCA->memChan_DS_q */
1716 3811 : ptrChanR_DS_fx = bufChanR_DS_fx + ADDED_MEM_DS; /* hStereoTCA->memChan_DS_q */
1717 :
1718 : /* resample factor */
1719 3811 : dsFactor = extract_l( Mpy_32_32( input_Fs, 268436 /* 1/CORR_INTER_FS in Q31*/ ) ); // Q0
1720 :
1721 : /* resample the stereo channels */
1722 3811 : deEmphResample_fx( hStereoTCA, ptrChanL_fx, ptrChanR_fx, ptrChanL_DS_fx, ptrChanR_DS_fx, input_frame, dsFactor );
1723 :
1724 : /**********************NEED to Allign first 40 index in each channel ************************************/
1725 : /* inter-channel corrStats estimation */
1726 3811 : corrStatsEst_fx( hStereoTCA, bufChanL_DS_fx + ADDED_MEM_DS, bufChanR_DS_fx + ADDED_MEM_DS, q_com, ( L_FRAME_DS + L_XCORRMEM_DS ), dsFactor, hCPE->hCoreCoder[0]->vad_flag, hCPE->hCoreCoder[1]->vad_flag, hCPE->hStereoClassif );
1727 :
1728 : /*-----------------------------------------------------------------*
1729 : * refine the ICA stats
1730 : *-----------------------------------------------------------------*/
1731 :
1732 3811 : prev_ICA_flag = 0;
1733 3811 : move16();
1734 3811 : test();
1735 3811 : if ( hCPE->hStereoTD->prev_fr_LRTD_TD_dec && abs_s( hStereoTCA->prevCorrLagStats[2] ) != 0 )
1736 : {
1737 33 : prev_ICA_flag = 1;
1738 33 : move16();
1739 : }
1740 :
1741 3811 : test();
1742 3811 : IF( hCPE->hStereoTD->prev_fr_LRTD_TD_dec == 0 || EQ_16( prev_ICA_flag, 1 ) )
1743 206 : {
1744 : /* initialize the refinement search for NC-shift */
1745 206 : hStereoTCA->corrLagStats[2] = hStereoTCA->corrLagStats[1];
1746 206 : move16();
1747 206 : maxCorrStatsDev = N_MAX_SHIFT_CHANGE;
1748 206 : move16();
1749 206 : IF( LE_16( hStereoTCA->corrStatsSmoothFac_fx, 22938 /*0.7f*/ ) )
1750 : {
1751 0 : maxCorrStatsDev = 160; /* L_NCSHIFT_MAX @ 32kHz */
1752 0 : move16();
1753 : }
1754 :
1755 206 : IF( LT_32( input_Fs, 32000 ) )
1756 : {
1757 35 : maxCorrStatsDev = extract_l( Mpy_32_32( imult3216( input_Fs, maxCorrStatsDev ), 67109 /* 1/32000.0f in Q31*/ ) ); // Q0
1758 : }
1759 :
1760 206 : musicMode = ( hCPE->hCoreCoder[0]->sp_aud_decision0 == 1 || sts[0]->last_core > ACELP_CORE );
1761 206 : move16();
1762 :
1763 206 : IF( musicMode )
1764 : {
1765 56 : maxCorrStatsDev = 1;
1766 56 : move16();
1767 56 : set16_fx( hStereoTCA->corrLagStats + 1, 0, 2 );
1768 : }
1769 :
1770 206 : tempS = sub( hStereoTCA->corrLagStats[1], hStereoTCA->prevCorrLagStats[2] ); /* Q0 */
1771 :
1772 206 : IF( GT_16( abs_s( tempS ), maxCorrStatsDev ) )
1773 : {
1774 85 : IF( tempS > 0 )
1775 : {
1776 24 : hStereoTCA->corrLagStats[2] = add( hStereoTCA->prevCorrLagStats[2], maxCorrStatsDev ); /* Q0 */
1777 : }
1778 : ELSE
1779 : {
1780 61 : hStereoTCA->corrLagStats[2] = add( hStereoTCA->prevCorrLagStats[2], -maxCorrStatsDev ); /* Q0 */
1781 : }
1782 85 : move16();
1783 : }
1784 :
1785 206 : neighborLimit = maxCorrStatsDev;
1786 206 : move16();
1787 : /* refine and search based on the corrlag stats */
1788 206 : test();
1789 206 : test();
1790 206 : IF( tempS != 0 && NE_16( dsFactor, 1 ) && prev_ICA_flag == 0 )
1791 : {
1792 147 : tempF_fx = 0;
1793 147 : move32();
1794 147 : corrEstStage2_exp = 0;
1795 147 : move16();
1796 147 : IF( !musicMode )
1797 : {
1798 126 : tempLag[0] = s_min( hStereoTCA->corrLagStats[2], hStereoTCA->prevCorrLagStats[2] ); /* Q0 */
1799 126 : move16();
1800 126 : tempLag[1] = s_max( hStereoTCA->corrLagStats[2], hStereoTCA->prevCorrLagStats[2] ); /* Q0 */
1801 126 : move16();
1802 :
1803 126 : neighborLimit = s_min( 3, maxCorrStatsDev );
1804 :
1805 126 : IF( LT_16( hStereoTCA->prevCorrLagStats[2], hStereoTCA->corrLagStats[2] ) )
1806 : {
1807 96 : tempLag[1] = s_min( tempLag[1], add( tempLag[0], neighborLimit ) ); /* Q0 */
1808 : }
1809 : ELSE
1810 : {
1811 30 : tempLag[0] = s_max( tempLag[0], sub( tempLag[1], neighborLimit ) ); /* Q0 */
1812 : }
1813 126 : move16();
1814 126 : utilCrossCorr_fx( ptrChanL_fx, q_com, ptrChanR_fx, q_com, NULL, corrEstStage2_fx, &corrEstStage2_exp, tempLag, input_frame, 0 );
1815 :
1816 126 : hStereoTCA->corrLagStats[2] = maximum_l( corrEstStage2_fx, add( sub( tempLag[1], tempLag[0] ), 1 ), &tempF_fx );
1817 126 : move16();
1818 126 : hStereoTCA->corrLagStats[2] = add( hStereoTCA->corrLagStats[2], tempLag[0] );
1819 126 : move16();
1820 : }
1821 :
1822 147 : IF( GT_16( abs_s( tempS ), neighborLimit ) )
1823 : {
1824 115 : tempLag[0] = hStereoTCA->corrLagStats[1]; /* Q0 */
1825 115 : move16();
1826 115 : tempLag[1] = hStereoTCA->corrLagStats[1]; /* Q0 */
1827 115 : move16();
1828 115 : utilCrossCorr_fx( ptrChanL_fx, q_com, ptrChanR_fx, q_com, NULL, &tempF1_fx, &tempF1_exp, tempLag, input_frame, 0 );
1829 :
1830 115 : test();
1831 115 : IF( ( BASOP_Util_Cmp_Mant32Exp( tempF1_fx, tempF1_exp, tempF_fx, corrEstStage2_exp ) > 0 ) || musicMode )
1832 : {
1833 32 : IF( tempS > 0 )
1834 : {
1835 8 : hStereoTCA->corrLagStats[2] = add( hStereoTCA->prevCorrLagStats[2], s_min( abs_s( tempS ), maxCorrStatsDev ) ); /* Q0 */
1836 : }
1837 : ELSE
1838 : {
1839 24 : hStereoTCA->corrLagStats[2] = add( hStereoTCA->prevCorrLagStats[2], s_max( -abs_s( tempS ), -maxCorrStatsDev ) ); /* Q0 */
1840 : }
1841 32 : move16();
1842 : }
1843 : }
1844 :
1845 : /* restrict the reference channel for +/- variation */
1846 147 : test();
1847 147 : test();
1848 147 : test();
1849 147 : if ( ( hStereoTCA->corrLagStats[2] < 0 && hStereoTCA->prevCorrLagStats[2] > 0 ) || ( hStereoTCA->corrLagStats[2] > 0 && hStereoTCA->prevCorrLagStats[2] < 0 ) )
1850 : {
1851 1 : hStereoTCA->corrLagStats[2] = 0;
1852 1 : move16();
1853 : }
1854 : }
1855 :
1856 206 : IF( EQ_16( hCPE->hStereoTD->prev_fr_LRTD_TD_dec /*hCPE->hStereoClassif->lrtd_mode*/, 1 ) ) /* Content is considered as uncorrelated -> ICA shift is turned off */
1857 : {
1858 33 : hStereoTCA->corrLagStats[2] = 0;
1859 33 : move16();
1860 :
1861 33 : test();
1862 33 : if ( EQ_16( hCPE->hStereoTD->tdm_LRTD_flag, 1 ) && prev_ICA_flag == 0 )
1863 : {
1864 0 : hStereoTCA->prevCorrLagStats[2] = 0;
1865 0 : move16();
1866 : }
1867 : }
1868 :
1869 : /* Perform the following:
1870 : 1. adjust samples,
1871 : 2. interp shift variation,
1872 : 3. gain estimation */
1873 206 : prevNCShift = abs_s( hStereoTCA->prevCorrLagStats[2] ); /* Q0 */
1874 206 : currentNCShift = abs_s( hStereoTCA->corrLagStats[2] ); /* Q0 */
1875 :
1876 206 : IF( EQ_16( hStereoTCA->prevRefChanIndx, L_CH_INDX ) )
1877 : {
1878 188 : v_multc_fixed( bufChanL_fx, ONE_IN_Q29, bufChanL_fx, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX ); /* TO make in common Q bufChan_q - 2*/
1879 188 : Copy32( ptrChanL_fx - add( lMemRecalc, lMemRecalc_SCh ), input_mem_loc_fx[0], add( lMemRecalc, lMemRecalc_SCh ) ); // bufChan_q - 2
1880 188 : v_multc_fixed( ptrChanR_fx + sub( prevNCShift, add( lMemRecalc, lMemRecalc_SCh ) ), hStereoTCA->prevTargetGain_fx, input_mem_loc_fx[1], add( lMemRecalc, lMemRecalc_SCh ) ); // bufChan_q-2
1881 188 : v_multc_fixed( bufChanR_fx, ONE_IN_Q29, bufChanR_fx, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX ); /* TO make in common Q bufChan_q -2*/
1882 : }
1883 : ELSE
1884 : {
1885 18 : v_multc_fixed( bufChanL_fx, ONE_IN_Q29, bufChanL_fx, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX ); /* TO make in common Q bufChan_q -2*/
1886 18 : Copy32( ptrChanL_fx + sub( prevNCShift, add( lMemRecalc, lMemRecalc_SCh ) ), input_mem_loc_fx[0], add( lMemRecalc, lMemRecalc_SCh ) ); // bufChan_q -2
1887 18 : v_multc_fixed( ptrChanR_fx - add( lMemRecalc, lMemRecalc_SCh ), hStereoTCA->prevTargetGain_fx, input_mem_loc_fx[1], add( lMemRecalc, lMemRecalc_SCh ) ); // bufChan_q -2
1888 18 : v_multc_fixed( bufChanR_fx, ONE_IN_Q29, bufChanR_fx, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX ); /* TO make in common Q bufChan_q -2*/
1889 : }
1890 206 : bufChan_q = sub( bufChan_q, 2 );
1891 206 : q_com = bufChan_q;
1892 206 : move16();
1893 206 : input_mem_loc_q = bufChan_q;
1894 206 : move16();
1895 206 : target_fx = ptrChanR_fx; /* bufChan_q -2 */
1896 206 : target_idx = R_CH_INDX; /* Q0 */
1897 206 : move16();
1898 : /* identify target signal to correct for shift variations */
1899 206 : test();
1900 206 : test();
1901 206 : IF( ( prevNCShift == 0 && hStereoTCA->corrLagStats[2] < 0 ) || EQ_16( hStereoTCA->prevRefChanIndx, R_CH_INDX ) )
1902 : {
1903 35 : target_fx = ptrChanL_fx; /* bufChan_q - 2 */
1904 35 : target_idx = L_CH_INDX;
1905 35 : move16();
1906 : }
1907 :
1908 : /* target signal adjustment for temporal shift variations */
1909 206 : IF( sub( prevNCShift, currentNCShift ) != 0 )
1910 : {
1911 110 : L_shift_adapt = L_SHIFT_ADAPT_16k;
1912 110 : move16();
1913 110 : if ( GT_32( input_Fs, INT_FS_16k ) )
1914 : {
1915 92 : L_shift_adapt = L_SHIFT_ADAPT_MAX;
1916 92 : move16();
1917 : }
1918 :
1919 : /* Note!! : Always keep the assert (prevNCShift>>1) below according to the equation used here to get tempS */
1920 110 : tempS = shr( currentNCShift, 1 ); /* Q0 */
1921 :
1922 110 : IF( LE_32( abs_s( sub( currentNCShift, prevNCShift ) ), L_min( N_MAX_SHIFT_CHANGE, Mpy_32_32( imult3216( input_Fs, N_MAX_SHIFT_CHANGE ), 67109 /* 1/32000.0f in Q31*/ ) ) ) )
1923 : {
1924 93 : adjustTargetSignal_fx( ( target_fx - tempS ), prevNCShift, currentNCShift, L_shift_adapt, 0 );
1925 : }
1926 : ELSE
1927 : {
1928 17 : tempS = s_min( s_max( tempS, add( sub( prevNCShift, currentNCShift ), sub( L_shift_adapt, input_frame ) ) ), add( sub( prevNCShift, currentNCShift ), lMemRecalc ) ); /* Q0 */
1929 :
1930 17 : adjustTargetSignal_fx( ( target_fx - tempS ), prevNCShift, currentNCShift, L_shift_adapt, 1 );
1931 : }
1932 :
1933 110 : IF( target_idx == L_CH_INDX )
1934 : {
1935 34 : Copy32( target_fx - tempS, &( input_mem_loc_fx[target_idx][lMemRecalc + lMemRecalc_SCh - tempS - currentNCShift] ), add( currentNCShift, tempS ) ); /* bufChan_q - 2 */
1936 : }
1937 : ELSE
1938 : {
1939 76 : v_multc_fixed( target_fx - tempS, hStereoTCA->prevTargetGain_fx, &( input_mem_loc_fx[target_idx][lMemRecalc + lMemRecalc_SCh - tempS - currentNCShift] ), add( currentNCShift, tempS ) ); /* bufChan_q - 2 */
1940 76 : scale_sig32( input_mem_loc_fx[target_idx], sub( sub( add( lMemRecalc, lMemRecalc_SCh ), tempS ), currentNCShift ), -2 );
1941 76 : scale_sig32( &input_mem_loc_fx[target_idx][lMemRecalc + lMemRecalc_SCh], sub( NS2SA( 48000, L_MEM_RECALC_NS + L_MEM_RECALC_SCH_NS ), add( lMemRecalc, lMemRecalc_SCh ) ), -2 );
1942 76 : scale_sig32( input_mem_loc_fx[0], NS2SA( 48000, L_MEM_RECALC_NS + L_MEM_RECALC_SCH_NS ), -2 );
1943 76 : input_mem_loc_q = sub( bufChan_q, 2 );
1944 : }
1945 : }
1946 :
1947 : /* reference channel index */
1948 206 : IF( hStereoTCA->corrLagStats[2] >= 0 )
1949 : {
1950 188 : hStereoTCA->refChanIndx = L_CH_INDX;
1951 : }
1952 : ELSE
1953 : {
1954 18 : hStereoTCA->refChanIndx = R_CH_INDX;
1955 : }
1956 206 : move16();
1957 :
1958 : /* Estimate and quantize the gain for scaling */
1959 :
1960 206 : estDownmixGain_fx( hStereoTCA, ptrChanL_fx, ptrChanR_fx, q_com, currentNCShift, sub( input_frame, currentNCShift ), hCPE->element_mode, hCPE->hStereoClassif, hCPE->hStereoTD->tdm_LRTD_flag );
1961 :
1962 : /* quantize the corrStats */
1963 :
1964 : Word16 temp_exp, tempF_16fx;
1965 206 : Word16 scalar_value = BASOP_Util_Divide1616_Scale( currentNCShift, dsFactor, &temp_exp ); /* Q15-temp_exp */
1966 :
1967 206 : scalar_value = shl_sat( scalar_value, sub( temp_exp, 5 ) ); /*Q10*/
1968 206 : hStereoTCA->indx_ica_NCShift = usquant_fx( scalar_value, &tempF_16fx, 0, 512 /* 0.5 in Q10 */, ( 1 << STEREO_BITS_TCA_CORRSTATS ) ); /* Q0 */
1969 :
1970 206 : tempF_fx = tempF_16fx;
1971 206 : move32();
1972 : }
1973 : ELSE
1974 : {
1975 3605 : hStereoTCA->refChanIndx = L_CH_INDX;
1976 3605 : move16();
1977 3605 : hStereoTCA->corrLagStats[2] = 0;
1978 3605 : move16();
1979 3605 : hStereoTCA->prevCorrLagStats[2] = 0;
1980 3605 : move16();
1981 3605 : hStereoTCA->indx_ica_NCShift = 0;
1982 3605 : move16();
1983 :
1984 3605 : currentNCShift = 0; /* only to avoid compilation warning */
1985 3605 : move16();
1986 3605 : target_fx = ptrChanL_fx; /* only to avoid compilation warning bufChan_q*/
1987 3605 : move16();
1988 3605 : target_idx = L_CH_INDX; /* only to avoid compilation warning */
1989 3605 : move16();
1990 :
1991 3605 : v_multc_fixed( bufChanL_fx, ONE_IN_Q29, bufChanL_fx, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX ); /* TO make in common Q bufChan_q -2*/
1992 :
1993 3605 : Copy32( ptrChanL_fx - add( lMemRecalc, lMemRecalc_SCh ), input_mem_loc_fx[0], add( lMemRecalc, lMemRecalc_SCh ) ); // bufChan_q -2
1994 3605 : v_multc_fixed( ptrChanR_fx - add( lMemRecalc, lMemRecalc_SCh ), hStereoTCA->prevTargetGain_fx, input_mem_loc_fx[1], add( lMemRecalc, lMemRecalc_SCh ) ); // bufChan_q -2
1995 :
1996 3605 : v_multc_fixed( bufChanR_fx, ONE_IN_Q29, bufChanR_fx, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX ); /* TO make in common Q bufChan_q -2 */
1997 3605 : bufChan_q = sub( bufChan_q, 2 );
1998 3605 : q_com = bufChan_q;
1999 3605 : move16();
2000 3605 : input_mem_loc_q = bufChan_q;
2001 3605 : move16();
2002 : /* Estimate and quantize the gain for scaling */
2003 :
2004 3605 : estDownmixGain_fx( hStereoTCA, ptrChanL_fx, ptrChanR_fx, q_com, 0, input_frame, hCPE->element_mode, hCPE->hStereoClassif, hCPE->hStereoTD->tdm_LRTD_flag );
2005 : }
2006 :
2007 : /*-----------------------------------------------------------------*
2008 : * updates and memory backups
2009 : *-----------------------------------------------------------------*/
2010 :
2011 : /* back up the L/R missing target */
2012 3811 : Copy32( bufChanL_fx + input_frame, hStereoTCA->memChanL_fx, add( lMemRecalc, lMemRecalc_SCh ) ); /* bufChan_q */
2013 3811 : Copy32( bufChanR_fx + input_frame, hStereoTCA->memChanR_fx, add( lMemRecalc, lMemRecalc_SCh ) ); /* bufChan_q */
2014 3811 : hStereoTCA->memChan_q = bufChan_q;
2015 :
2016 3811 : IF( currentNCShift != 0 )
2017 : {
2018 : /* Temporal channel adjustment of the LA samples based on the NC shift */
2019 94 : tcaTargetCh_LA_fx( hStereoTCA, ptrChanL_fx, ptrChanR_fx, &q_com, currentNCShift, input_frame );
2020 :
2021 94 : scale_sig32( bufChanL_fx, add( lMemRecalc, lMemRecalc_SCh ), sub( s_min( q_com, bufChan_q ), bufChan_q ) ); // s_min( q_com, bufChan_q )
2022 94 : scale_sig32( bufChanL_fx + add( lMemRecalc, lMemRecalc_SCh ), add( input_frame, currentNCShift ), sub( s_min( q_com, bufChan_q ), q_com ) ); // s_min( q_com, bufChan_q )
2023 94 : scale_sig32( bufChanL_fx + add( add( lMemRecalc, lMemRecalc_SCh ), add( input_frame, currentNCShift ) ), sub( L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX, add( add( lMemRecalc, lMemRecalc_SCh ), add( input_frame, currentNCShift ) ) ), sub( s_min( q_com, bufChan_q ), bufChan_q ) ); // s_min( q_com, bufChan_q )
2024 :
2025 : /* Scaling to common Q*/
2026 94 : scale_sig32( bufChanR_fx, add( lMemRecalc, lMemRecalc_SCh ), sub( s_min( q_com, bufChan_q ), bufChan_q ) ); // s_min( q_com, bufChan_q )
2027 94 : scale_sig32( bufChanR_fx + add( lMemRecalc, lMemRecalc_SCh ), add( input_frame, currentNCShift ), sub( s_min( q_com, bufChan_q ), q_com ) ); // s_min( q_com, bufChan_q )
2028 94 : scale_sig32( bufChanR_fx + add( add( lMemRecalc, lMemRecalc_SCh ), add( input_frame, currentNCShift ) ), sub( L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX, add( add( lMemRecalc, lMemRecalc_SCh ), add( input_frame, currentNCShift ) ) ), sub( s_min( q_com, bufChan_q ), bufChan_q ) ); // s_min( q_com, bufChan_q )
2029 94 : bufChan_q = s_min( q_com, bufChan_q );
2030 94 : q_com = bufChan_q;
2031 : }
2032 :
2033 : /* Update of changed samples corresponding to the memory */
2034 : /* Scaling to common Q*/
2035 3811 : scale_sig32( input_mem_loc_fx[0], NS2SA( 48000, L_MEM_RECALC_NS + L_MEM_RECALC_SCH_NS ), sub( s_min( input_mem_loc_q, sts[0]->q_inp32 ), input_mem_loc_q ) ); // s_min( input_mem_loc_q, sts[0]->q_inp32 )
2036 3811 : scale_sig32( input_mem_loc_fx[1], NS2SA( 48000, L_MEM_RECALC_NS + L_MEM_RECALC_SCH_NS ), sub( s_min( input_mem_loc_q, sts[0]->q_inp32 ), input_mem_loc_q ) ); // s_min( input_mem_loc_q, sts[0]->q_inp32 )
2037 3811 : scale_sig32( sts[0]->input_buff32_fx, L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), sub( s_min( input_mem_loc_q, sts[0]->q_inp32 ), sts[0]->q_inp32 ) ); // s_min( input_mem_loc_q, sts[0]->q_inp32 )
2038 3811 : scale_sig32( sts[1]->input_buff32_fx, L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), sub( s_min( input_mem_loc_q, sts[1]->q_inp32 ), sts[1]->q_inp32 ) ); // s_min( input_mem_loc_q, sts[0]->q_inp32 )
2039 :
2040 3811 : input_mem_loc_q = s_min( input_mem_loc_q, sts[0]->q_inp32 ); /* sts[0]->q_inp32 */
2041 3811 : sts[0]->q_inp32 = input_mem_loc_q;
2042 3811 : move16();
2043 3811 : sts[1]->q_inp32 = input_mem_loc_q;
2044 3811 : move16();
2045 :
2046 3811 : icaMemUpdate_fx( sts, hCPE, input_mem_loc_fx[0], input_mem_loc_fx[1], input_mem_loc_q, lMemRecalc, lMemRecalc_SCh, input_frame );
2047 :
2048 : /* populate the st->input target buffer */
2049 3811 : test();
2050 3811 : IF( hCPE->hStereoTD->prev_fr_LRTD_TD_dec == 0 || EQ_16( prev_ICA_flag, 1 ) )
2051 : {
2052 206 : Word16 shift = sub( q_com, sts[target_idx]->q_inp32 );
2053 133326 : FOR( Word16 idx = 0; idx < input_frame; idx++ )
2054 : {
2055 133120 : sts[target_idx]->input32_fx[idx] = L_shr( target_fx[currentNCShift + idx], shift );
2056 133120 : move32();
2057 : }
2058 : }
2059 :
2060 3811 : IF( NE_16( hCPE->element_mode, IVAS_CPE_DFT ) )
2061 : {
2062 : /* Scale the Right channel with the gain */
2063 : Word16 j;
2064 3811 : Word16 l_ica_ovl = NS2SA_FX2( input_Fs, STEREO_L_TCA_OVLP_NS );
2065 :
2066 3811 : Word16 winSlope = div_s( 1, l_ica_ovl ); // Q15
2067 :
2068 3811 : tempF1_fx = hStereoTCA->targetGain_fx; // Q29
2069 3811 : move32();
2070 3811 : tempF_fx = hStereoTCA->prevTargetGain_fx; // Q29
2071 3811 : move32();
2072 :
2073 634771 : FOR( ( i = 0, j = 0 ); i < l_ica_ovl; ( i++, j++ ) )
2074 : {
2075 630960 : sts[1]->input32_fx[i] = L_add( Mpy_32_32( sts[1]->input32_fx[i], Mpy_32_16_1( tempF_fx, sub( MAX_16, imult1616( j, winSlope ) ) ) ), Mpy_32_32( sts[1]->input32_fx[i], Mpy_32_16_1( tempF1_fx, imult1616( j, winSlope ) ) ) ); // inpq-2
2076 630960 : move32();
2077 : }
2078 :
2079 1896691 : FOR( ; i < input_frame; i++ )
2080 : {
2081 1892880 : sts[1]->input32_fx[i] = Mpy_32_32( sts[1]->input32_fx[i], tempF1_fx ); // inpq-2
2082 1892880 : move32();
2083 : }
2084 :
2085 3811 : scale_sig32( sts[1]->input_buff32_fx, (Word16) Mpy_32_32( input_Fs, 42949673 ) /* 1/50 in Q31*/, -2 ); // inpq-2
2086 3811 : scale_sig32( sts[0]->input_buff32_fx, L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ), -2 ); // inpq-2
2087 3811 : sts[0]->q_inp32 = sub( sts[0]->q_inp32, 2 );
2088 3811 : move16();
2089 3811 : sts[1]->q_inp32 = sub( sts[1]->q_inp32, 2 );
2090 3811 : move16();
2091 3811 : sts[0]->q_old_inp32 = sub( sts[0]->q_old_inp32, 2 );
2092 3811 : move16();
2093 3811 : sts[1]->q_old_inp32 = sub( sts[1]->q_old_inp32, 2 );
2094 3811 : move16();
2095 : }
2096 :
2097 : /* update L/R DS memories */
2098 3811 : Copy32( bufChanL_DS_fx + L_FRAME_DS, hStereoTCA->memChanL_DS_fx, ADDED_MEM_DS ); /* hStereoTCA->memChan_DS_q */
2099 3811 : Copy32( bufChanR_DS_fx + L_FRAME_DS, hStereoTCA->memChanR_DS_fx, ADDED_MEM_DS ); /* hStereoTCA->memChan_DS_q */
2100 :
2101 : /* save the reference channel index for next frame */
2102 3811 : hStereoTCA->prevRefChanIndx = hStereoTCA->refChanIndx; /* Q0 */
2103 3811 : move16();
2104 : /* save the corr lag stats for next frame */
2105 3811 : Copy( hStereoTCA->corrLagStats, hStereoTCA->prevCorrLagStats, 3 ); /* Q0 */
2106 :
2107 : /* save the target gain for next frame */
2108 3811 : hStereoTCA->prevTargetGain_fx = hStereoTCA->targetGain_fx; // Q29
2109 3811 : move32();
2110 3811 : return;
2111 : }
2112 : /*-------------------------------------------------------------------*
2113 : * stereo_tca_init_enc()
2114 : *
2115 : * Stereo temporal inter-channel adjustment (ICA) encoder initialization
2116 : *-------------------------------------------------------------------*/
2117 891 : void stereo_tca_init_enc_fx(
2118 : STEREO_TCA_ENC_HANDLE hStereoTCA, /* i/o: Stereo ICA handle */
2119 : const Word32 input_Fs /* i : input sampling frequency Q0*/
2120 : )
2121 : {
2122 : Word16 div1;
2123 : Word16 div_e;
2124 891 : hStereoTCA->lMemRecalc = NS2SA_FX2( input_Fs, L_MEM_RECALC_NS );
2125 891 : move16();
2126 891 : div1 = BASOP_Util_Divide3232_Scale( L_mult( hStereoTCA->lMemRecalc, INT_FS_12k8 ), input_Fs, &div_e ); /* Q15-div_e */
2127 891 : hStereoTCA->lMemRecalc_12k8 = shr( div1, 1 + sub( 15, div_e ) );
2128 891 : move16();
2129 :
2130 891 : div1 = BASOP_Util_Divide3232_Scale( L_mult( hStereoTCA->lMemRecalc, INT_FS_16k ), input_Fs, &div_e ); /* Q15-div_e */
2131 891 : hStereoTCA->lMemRecalc_16k = shr( div1, 1 + sub( 15, div_e ) );
2132 891 : move16();
2133 :
2134 891 : hStereoTCA->refChanIndx = L_CH_INDX;
2135 891 : hStereoTCA->prevRefChanIndx = L_CH_INDX;
2136 891 : move16();
2137 891 : move16();
2138 :
2139 891 : hStereoTCA->targetGain_fx = ONE_IN_Q29; // Q29
2140 891 : hStereoTCA->prevTargetGain_fx = ONE_IN_Q29; // Q29
2141 891 : hStereoTCA->instTargetGain_fx = ONE_IN_Q29; // Q29
2142 891 : move32();
2143 891 : move32();
2144 891 : move32();
2145 891 : hStereoTCA->corrStatsSmoothFac_fx = 22938; // Q15
2146 891 : move16();
2147 :
2148 891 : set16_fx( hStereoTCA->corrLagStats, 0, 3 );
2149 891 : set16_fx( hStereoTCA->prevCorrLagStats, 0, 3 );
2150 :
2151 891 : set32_fx( hStereoTCA->memChanL_fx, 0, add( L_MEM_RECALC_48K, L_MEM_RECALC_48k_SCH ) );
2152 891 : set32_fx( hStereoTCA->memChanR_fx, 0, add( L_MEM_RECALC_48K, L_MEM_RECALC_48k_SCH ) );
2153 891 : hStereoTCA->memChan_q = 31;
2154 891 : move16();
2155 891 : set32_fx( hStereoTCA->memChanL_DS_fx, 0, ADDED_MEM_DS );
2156 891 : set32_fx( hStereoTCA->memChanR_DS_fx, 0, ADDED_MEM_DS );
2157 891 : hStereoTCA->memChan_DS_q = Q31;
2158 891 : move16();
2159 891 : hStereoTCA->mem_tempF_fx = 0;
2160 891 : move32();
2161 891 : hStereoTCA->mem_tempF_exp = 0;
2162 891 : move16();
2163 891 : set32_fx( hStereoTCA->corrEstPrev_fx[0], 0, add( shl( L_NCSHIFT_DS, 1 ), 1 ) );
2164 891 : set32_fx( hStereoTCA->corrEstPrev_fx[1], 0, add( shl( L_NCSHIFT_DS, 1 ), 1 ) );
2165 891 : set32_fx( hStereoTCA->corrEstPrev_fx[2], 0, add( shl( L_NCSHIFT_DS, 1 ), 1 ) );
2166 891 : hStereoTCA->corrEstPrev_exp = 0;
2167 891 : move16();
2168 891 : set32_fx( hStereoTCA->corrEstLT_fx, 0, add( shl( L_NCSHIFT_DS, 1 ), 1 ) );
2169 891 : hStereoTCA->corrEstLT_exp = 0;
2170 891 : move16();
2171 891 : set32_fx( hStereoTCA->memdecim_fx, 0, 12 );
2172 891 : hStereoTCA->ica_envVarLT_fx = 2097152000; // 2000 in Q20
2173 891 : move32();
2174 891 : hStereoTCA->ica_envVarLT_exp = 11; // 2000 in Q20
2175 891 : move16();
2176 :
2177 891 : set32_fx( hStereoTCA->C_mem_fx, 0, add( shl( L_NCSHIFT_DS, 1 ), 1 ) );
2178 891 : set16_fx( hStereoTCA->C_mem_exp, 0, add( shl( L_NCSHIFT_DS, 1 ), 1 ) );
2179 891 : hStereoTCA->E1_mem_fx = 0;
2180 891 : move32();
2181 891 : hStereoTCA->E2_mem_fx = 0;
2182 891 : move32();
2183 891 : hStereoTCA->E1_mem_exp = 0;
2184 891 : move16();
2185 891 : hStereoTCA->E2_mem_exp = 0;
2186 891 : move16();
2187 891 : set32_fx( hStereoTCA->delay_0_mem_fx, 0, MAX_DELAYREGLEN );
2188 891 : hStereoTCA->delay_0_mem_exp = 0;
2189 891 : move16();
2190 891 : hStereoTCA->smooth_dist_reg_prv_corr_fx = MAX_32; // Q15
2191 891 : hStereoTCA->smooth_dist_reg_prv_corr_exp = 0; // Q15
2192 891 : hStereoTCA->LRTD_G_ATT_cnt = 1;
2193 891 : move16();
2194 891 : move16();
2195 :
2196 891 : return;
2197 : }
2198 : /*-------------------------------------------------------------------*
2199 : * Function unclr_calc_corr_features()
2200 : *
2201 : *-------------------------------------------------------------------*/
2202 3811 : static void unclr_calc_corr_features_fx(
2203 : STEREO_CLASSIF_HANDLE hStereoClassif, /* i/o: stereo classifier handle */
2204 : STEREO_TCA_ENC_HANDLE hStereoTCA, /* i/o: ICA Stereo Encoder handle */
2205 : Word32 buf1[], /* i : left channel q_com*/
2206 : Word32 buf2[], /* i : right channel q_com*/
2207 : Word16 q_com,
2208 : const Word16 length, /* i : length of input signal buffers Q0*/
2209 : Word32 corrEst[], /* i : buffer containing inter-channel correlation values corrEst_exp*/
2210 : Word16 corrEst_exp,
2211 : const Word16 lagSearchRange[], /* i : minimum and maximum lags for corrEst[] Q0*/
2212 : Word32 *corrEst_ncorr, /* o : norm. x-correlation btw. current and previous correlation buffers corrEst_ncorr_exp*/
2213 : Word16 *corrEst_ncorr_exp )
2214 : {
2215 : Word16 i, corrLagMax, d_corrLagMax, tempLen, k;
2216 : Word32 num, den;
2217 : Word32 corrL, corrR, ener, ener_side, mono_i, side_i, ic_Lm, ic_Rm, tdm_es_em, m_corrL_corrR, d_corrL_corrR;
2218 : Word32 sum_prod, corrEstMax;
2219 : Word16 corrL_exp, corrR_exp, ener_exp, ener_side_exp, sum_prod_exp, exp, exp1, exp2, num_exp, den_exp;
2220 :
2221 3811 : corrL = ONE_IN_Q31;
2222 3811 : move32();
2223 3811 : corrL_exp = 0;
2224 3811 : move16();
2225 3811 : corrR = ONE_IN_Q31;
2226 3811 : move32();
2227 3811 : corrR_exp = 0;
2228 3811 : move16();
2229 3811 : ener = ONE_IN_Q31;
2230 3811 : move32();
2231 3811 : ener_exp = 0;
2232 3811 : move16();
2233 3811 : ener_side = ONE_IN_Q31;
2234 3811 : move32();
2235 3811 : ener_side_exp = 0;
2236 3811 : move16();
2237 3811 : sum_prod = 0;
2238 3811 : move32();
2239 3811 : sum_prod_exp = 0;
2240 3811 : move16();
2241 :
2242 613571 : FOR( i = 0; i < length; i++ )
2243 : {
2244 609760 : mono_i = BASOP_Util_Add_Mant32Exp( L_shr( buf1[i], 1 ), sub( 31, q_com ), L_shr( buf2[i], 1 ), sub( 31, q_com ), &exp ); /* Q31-exp */
2245 609760 : corrL = BASOP_Util_Add_Mant32Exp( corrL, corrL_exp, Mpy_32_32( buf1[i], mono_i ), add( sub( 31, q_com ), exp ), &corrL_exp ); /* Q31-corrL_exp */
2246 609760 : corrR = BASOP_Util_Add_Mant32Exp( corrR, corrR_exp, Mpy_32_32( buf2[i], mono_i ), add( sub( 31, q_com ), exp ), &corrR_exp ); /* Q31-corrR_exp */
2247 609760 : ener = BASOP_Util_Add_Mant32Exp( ener, ener_exp, Mpy_32_32( mono_i, mono_i ), shl( exp, 1 ), &ener_exp );
2248 :
2249 609760 : side_i = BASOP_Util_Add_Mant32Exp( L_shr( buf1[i], 1 ), sub( 31, q_com ), L_negate( L_shr( buf2[i], 1 ) ), sub( 31, q_com ), &exp ); /* Q31-exp */
2250 609760 : ener_side = BASOP_Util_Add_Mant32Exp( ener_side, ener_side_exp, Mpy_32_32( side_i, side_i ), shl( exp, 1 ), &ener_side_exp ); /* Q31-ener_side_exp */
2251 :
2252 : Word16 n1, n2, prod_i_exp;
2253 : Word32 x, y, prod_i;
2254 609760 : n1 = norm_l( buf1[i] );
2255 609760 : n2 = norm_l( buf2[i] );
2256 609760 : x = L_shl( buf1[i], n1 ); // q: q_com + n1
2257 609760 : y = L_shl( buf2[i], n2 ); // q: q_com + n2
2258 609760 : prod_i = Mpy_32_32( x, y ); // q: q_com * 2 + n1 + n2 - 31
2259 609760 : prod_i_exp = sub( 62, add( shl( q_com, 1 ), add( n1, n2 ) ) );
2260 609760 : sum_prod = BASOP_Util_Add_Mant32Exp( sum_prod, sum_prod_exp, prod_i, prod_i_exp, &sum_prod_exp ); /* Q31-sum_prod_exp */
2261 : }
2262 :
2263 : /* average energy of L and R channels */
2264 3811 : hStereoClassif->ave_ener_L_fx = Mpy_32_32( hStereoTCA->E1_mem_fx, 13421772 /* 1/length in Q31*/ ); /* Q31-hStereoClassif->ave_ener_L_fx_e */
2265 3811 : move32();
2266 3811 : hStereoClassif->ave_ener_L_fx_e = hStereoTCA->E1_mem_exp;
2267 3811 : move16();
2268 3811 : hStereoClassif->ave_ener_R_fx = Mpy_32_32( hStereoTCA->E2_mem_fx, 13421772 /* 1/length in Q31*/ ); /* Q31-hStereoClassif->ave_ener_R_fx_e */
2269 3811 : move32();
2270 3811 : hStereoClassif->ave_ener_R_fx_e = hStereoTCA->E2_mem_exp;
2271 3811 : move16();
2272 :
2273 : /* unnormalized L/R correlation */
2274 3811 : IF( sum_prod )
2275 : {
2276 3811 : sum_prod = BASOP_Util_Log10( L_abs( sum_prod ), sum_prod_exp ); /* Q31-sum_prod_exp */
2277 3811 : sum_prod_exp = 6;
2278 3811 : move16();
2279 : }
2280 : ELSE
2281 : {
2282 0 : sum_prod = 0;
2283 0 : move32();
2284 0 : sum_prod_exp = 0;
2285 0 : move16();
2286 : }
2287 :
2288 3811 : hStereoClassif->unclr_fv_fx[E_sum_prod] = L_shr( sum_prod, 10 ); // Q15
2289 3811 : move32();
2290 3811 : hStereoClassif->xtalk_fv_fx[E_sum_prod] = L_shr( sum_prod, 10 ); // Q15
2291 3811 : move32();
2292 : /* S/M energy ratio */
2293 3811 : Word32 inp1 = Sqrt32( Mpy_32_32( ener_side, 13421773 /* 1/L_FRAME_DS in Q31*/ ), &ener_side_exp ); /* Q31-ener_side_exp */
2294 3811 : inp1 = BASOP_Util_Log10( inp1, ener_side_exp ); /* Q31-ener_side_exp */
2295 3811 : Word16 temp = ener_exp;
2296 3811 : move16();
2297 3811 : Word32 inp2 = Sqrt32( Mpy_32_32( ener, 13421773 /* 1/L_FRAME_DS in Q31*/ ), &ener_exp ); /* Q31-ener_exp */
2298 3811 : inp2 = BASOP_Util_Log10( inp2, ener_exp ); /* Q31-ener_exp */
2299 3811 : ener_exp = temp;
2300 3811 : move16();
2301 :
2302 3811 : tdm_es_em = L_abs( Mpy_32_32( L_sub( inp1, inp2 ), 1342177280 ) ); /* Q25 + Q27 - Q31 = 21*/
2303 :
2304 3811 : hStereoClassif->unclr_fv_fx[E_tdm_es_em] = L_shr( tdm_es_em, 6 ); // Q15
2305 3811 : move32();
2306 3811 : hStereoClassif->xtalk_fv_fx[E_tdm_es_em] = L_shr( tdm_es_em, 6 ); // Q15
2307 3811 : move32();
2308 :
2309 : /* L/R correlation values (zero lag, maximum) */
2310 3811 : corrLagMax = maximum_l( corrEst, sub( lagSearchRange[1], add( lagSearchRange[0], 1 ) ), &corrEstMax );
2311 3811 : d_corrLagMax = sub( corrLagMax, hStereoClassif->unclr_corrLagMax_prev );
2312 :
2313 3811 : hStereoClassif->unclr_fv_fx[E_d_corrLagMax] = L_shl( d_corrLagMax, 15 );
2314 3811 : move32();
2315 3811 : hStereoClassif->unclr_corrLagMax_prev = corrLagMax;
2316 3811 : move32();
2317 3811 : hStereoClassif->xtalk_fv_fx[E_d_corrLagMax] = L_shl( d_corrLagMax, 15 );
2318 3811 : move32();
2319 :
2320 3811 : if ( corrEstMax < 0 )
2321 : {
2322 0 : corrEstMax = 0;
2323 0 : move32();
2324 : }
2325 :
2326 3811 : hStereoClassif->unclr_fv_fx[E_corrEst0] = L_shl_sat( corrEst[abs_s( lagSearchRange[0] )], sub( corrEst_exp, 16 ) ); /* Q15 */
2327 3811 : move32();
2328 3811 : hStereoClassif->unclr_fv_fx[E_corrEstMax] = L_shl_sat( corrEstMax, sub( corrEst_exp, 16 ) ); /* Q15 */
2329 3811 : move32();
2330 3811 : hStereoClassif->unclr_fv_fx[E_corrLagMax] = L_shl_sat( corrLagMax, 15 ); /* Q15 */
2331 3811 : move32();
2332 3811 : hStereoClassif->xtalk_fv_fx[E_corrEst0] = L_shl_sat( corrEst[abs_s( lagSearchRange[0] )], sub( corrEst_exp, 16 ) ); /* Q15 */
2333 3811 : move32();
2334 3811 : hStereoClassif->xtalk_fv_fx[E_corrEstMax] = L_shl_sat( corrEstMax, sub( corrEst_exp, 16 ) ); /* Q15 */
2335 3811 : move32();
2336 3811 : hStereoClassif->xtalk_fv_fx[E_corrLagMax] = L_shl_sat( corrLagMax, 15 ); /* Q15 */
2337 3811 : move32();
2338 :
2339 : /* L/M and R/M correlation */
2340 3811 : if ( corrL < 0 )
2341 : {
2342 113 : corrL = 0;
2343 113 : move32();
2344 : }
2345 :
2346 3811 : if ( corrR < 0 )
2347 : {
2348 58 : corrR = 0;
2349 58 : move32();
2350 : }
2351 :
2352 3811 : ic_Lm = BASOP_Util_Divide3232_Scale_newton( corrL, ener, &exp1 ); /* Q31-exp1 */
2353 3811 : exp1 = add( exp1, sub( corrL_exp, ener_exp ) );
2354 3811 : ic_Rm = BASOP_Util_Divide3232_Scale_newton( corrR, ener, &exp2 ); /* Q31-exp2 */
2355 3811 : exp2 = add( exp2, sub( corrR_exp, ener_exp ) );
2356 :
2357 3811 : m_corrL_corrR = L_sub( L_max( L_abs( L_shl( ic_Lm, sub( exp1, s_max( exp1, exp2 ) ) ) ), L_abs( L_shl( ic_Rm, sub( exp2, s_max( exp1, exp2 ) ) ) ) ), L_min( L_abs( L_shl( ic_Lm, sub( exp1, s_max( exp1, exp2 ) ) ) ), L_abs( L_shl( ic_Rm, sub( exp2, s_max( exp1, exp2 ) ) ) ) ) ); // s_max(exp1, exp2)
2358 :
2359 3811 : inp1 = BASOP_Util_Add_Mant32Exp( corrL, corrL_exp, L_negate( corrR ), corrR_exp, &exp ); /* Q31-exp */
2360 3811 : IF( inp1 )
2361 : {
2362 3811 : d_corrL_corrR = BASOP_Util_Log10( L_abs( inp1 ), exp ); // Q25
2363 : }
2364 : ELSE
2365 : {
2366 0 : d_corrL_corrR = 0;
2367 0 : move32();
2368 : }
2369 :
2370 3811 : hStereoClassif->unclr_fv_fx[E_m_corrL_corrR] = L_shl( m_corrL_corrR, sub( s_max( exp1, exp2 ), 16 ) ); // Q15
2371 3811 : move32();
2372 3811 : hStereoClassif->unclr_fv_fx[E_d_corrL_corrR] = L_shr( d_corrL_corrR, 10 ); // Q15
2373 3811 : move32();
2374 3811 : hStereoClassif->xtalk_fv_fx[E_m_corrL_corrR] = L_shl( m_corrL_corrR, sub( s_max( exp1, exp2 ), 16 ) ); // Q15
2375 3811 : move32();
2376 :
2377 : /* norm. x-correlation btw. current and previous correlation buffers */
2378 3811 : tempLen = ( 2 * L_NCSHIFT_DS + 1 );
2379 3811 : move16();
2380 :
2381 3811 : Word64 L64_sum = 0;
2382 3811 : move64();
2383 312502 : FOR( k = 0; k < tempLen; k++ )
2384 : {
2385 308691 : L64_sum = W_mac_32_32( L64_sum, corrEst[k], hStereoTCA->corrEstPrev_fx[2][k] ); /* 2*(Q31-corrEst_exp)+1 */
2386 : }
2387 3811 : k = W_norm( L64_sum );
2388 3811 : L64_sum = W_shl( L64_sum, k ); /* 2*(Q31-corrEst_exp)+1+k */
2389 3811 : num = W_extract_h( L64_sum ); // ener_side_q
2390 3811 : num_exp = sub( 31, sub( add( add( add( sub( 31, corrEst_exp ), sub( 31, hStereoTCA->corrEstPrev_exp ) ), 1 ), k ), 32 ) );
2391 :
2392 3811 : exp1 = corrEst_exp;
2393 3811 : move16();
2394 3811 : inp1 = sum2_32_exp_fx( corrEst, tempLen, &exp1, 3 );
2395 :
2396 3811 : exp2 = hStereoTCA->corrEstPrev_exp;
2397 3811 : move16();
2398 3811 : inp2 = sum2_32_exp_fx( hStereoTCA->corrEstPrev_fx[2], tempLen, &exp2, 3 );
2399 :
2400 3811 : den_exp = add( exp1, exp2 );
2401 3811 : den = Sqrt32( Mpy_32_32( inp1, inp2 ), &den_exp ); /* Q31-den_exp */
2402 :
2403 3811 : IF( den == 0 )
2404 : {
2405 60 : *corrEst_ncorr = 0;
2406 60 : move32();
2407 60 : *corrEst_ncorr_exp = 0;
2408 60 : move16();
2409 : }
2410 : ELSE
2411 : {
2412 3751 : *corrEst_ncorr = BASOP_Util_Divide3232_Scale_newton( num, den, &exp ); /* Q31-corrEst_ncorr_exp */
2413 3751 : *corrEst_ncorr_exp = add( exp, sub( num_exp, den_exp ) );
2414 3751 : move32();
2415 3751 : move16();
2416 : }
2417 :
2418 3811 : hStereoClassif->unclr_fv_fx[E_corrEst_ncorr] = L_shl( *corrEst_ncorr, sub( *corrEst_ncorr_exp, 16 ) ); /* Q15 */
2419 3811 : move32();
2420 3811 : hStereoClassif->xtalk_fv_fx[E_corrEst_ncorr] = L_shl( *corrEst_ncorr, sub( *corrEst_ncorr_exp, 16 ) ); /* Q15 */
2421 3811 : move32();
2422 :
2423 3811 : return;
2424 : }
|