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.h"
40 : #include "ivas_prot.h"
41 : #ifdef DEBUGGING
42 : #include "debug.h"
43 : #endif
44 : #include "wmc_auto.h"
45 : #include "rom_com.h"
46 : #include "ivas_rom_com.h"
47 :
48 :
49 : /*---------------------------------------------------------------
50 : * Local function prototypes
51 : * ---------------------------------------------------------------*/
52 :
53 : static void unclr_calc_corr_features( STEREO_CLASSIF_HANDLE hStereoClassif, STEREO_TCA_ENC_HANDLE hStereoTCA, const float buf1[], const float buf2[], const int16_t length, const float corrEst[], const int16_t lagSearchRange[], float *corrEst_ncorr );
54 :
55 :
56 : /*-------------------------------------------------------------------*
57 : * Local constants
58 : *-------------------------------------------------------------------*/
59 :
60 : #define XL_BIAS 0.20f
61 : #define XH_BIAS 0.40f
62 : #define XL_WIDTH 0.12f
63 : #define XH_WIDTH 0.15f /* 0.25 is MAX */
64 : #define YL_DIST 7.0f
65 : #define YH_DIST 9.0f
66 : #define SMOOTH_DIST_FACTOR 0.4f
67 : #define SMOOTH_ENV_FACTOR 0.6f
68 :
69 : #define A_BIAS ( ( XH_BIAS - XL_BIAS ) / ( YH_DIST - YL_DIST ) )
70 : #define B_BIAS ( XH_BIAS - ( A_BIAS * YH_DIST ) )
71 : #define A_WIDTH ( ( XH_WIDTH - XL_WIDTH ) / ( YH_DIST - YL_DIST ) )
72 : #define B_WIDTH ( XH_WIDTH - ( A_WIDTH * YH_DIST ) )
73 :
74 :
75 : /*---------------------------------------------------------------
76 : * tcaTargetCh_LA()
77 : *
78 : * Temporal channel adjustment of LA samples in target channel
79 : * ---------------------------------------------------------------*/
80 :
81 49 : static void tcaTargetCh_LA(
82 : STEREO_TCA_ENC_HANDLE hStereoTCA,
83 : float *ptrChanL,
84 : float *ptrChanR,
85 : const int16_t currentNCShift,
86 : const int16_t input_frame )
87 : {
88 : int16_t i, j;
89 : int16_t tempS;
90 : float tempF1, tempF2, gAdj;
91 :
92 : float *ref, *target;
93 : float win[240]; /* 5 ms at 48 kHz */
94 :
95 49 : if ( hStereoTCA->refChanIndx == L_CH_INDX )
96 : {
97 32 : ref = ptrChanL;
98 32 : target = ptrChanR;
99 : }
100 : else
101 : {
102 17 : ref = ptrChanR;
103 17 : target = ptrChanL;
104 : }
105 :
106 49 : tempS = NS2SA( input_frame * FRAMES_PER_SEC, L_SAMPLES_LA_NS );
107 49 : tempF1 = 0.0f;
108 49 : tempF2 = 0.0f;
109 29353 : for ( i = 0; i < ( input_frame - currentNCShift ); i++ )
110 : {
111 29304 : tempF1 += fabsf( ref[i] );
112 29304 : tempF2 += fabsf( target[i + currentNCShift] );
113 : }
114 49 : gAdj = ( tempF1 == 0 ) ? 1.0f : tempF2 / max( tempF1, 0.00001f );
115 :
116 49 : tempF1 = EVS_PI / ( 2.0f * (float) tempS );
117 1049 : for ( i = 0; i < tempS; i++ )
118 : {
119 1000 : win[i] = sinf( tempF1 * ( 0.5f + (float) i ) );
120 : }
121 :
122 49 : j = 0;
123 1049 : for ( i = ( input_frame - currentNCShift - tempS ); i < input_frame - currentNCShift; i++, j++ )
124 : {
125 1000 : target[i + currentNCShift] = ( win[j] * gAdj ) * ref[i] + ( 1.0f - win[j] ) * target[i + currentNCShift];
126 : }
127 2745 : for ( ; i < input_frame; i++, j++ )
128 : {
129 2696 : target[i + currentNCShift] = gAdj * ref[i];
130 : }
131 :
132 49 : return;
133 : }
134 :
135 : /*---------------------------------------------------------------
136 : * spectral_balancer()
137 : *
138 : * Spectral-balancer to take care of the low-freq rumble and
139 : * compensate for the pre-emphasis.
140 : * ---------------------------------------------------------------*/
141 :
142 7650 : void spectral_balancer(
143 : float *signal,
144 : float *mem,
145 : const int16_t lg,
146 : const int16_t coeff_set )
147 : {
148 : int16_t i;
149 : float x0, x1, x2, y0, y1, y2;
150 : float a1, a2, b0, b1, b2;
151 :
152 7650 : y1 = mem[0];
153 7650 : y2 = mem[1];
154 7650 : x0 = mem[2];
155 7650 : x1 = mem[3];
156 :
157 : /* hp filter 60Hz at 3dB for 8000KHz sampling rate
158 : 1. [b,a] = butter(1, 60.0/8000.0, 'high');
159 : 2. spectral_balancing_filter
160 : <<gain = 0.97697627795388164 -> maybe not needed>>
161 : b =[1, -1] [1, -0.6]
162 : a =[1, -0.95395255590776329] [1, 0.5] */
163 7650 : if ( coeff_set == 0 )
164 : {
165 7582 : a1 = 0.747789178258504f;
166 7582 : a2 = -0.272214937925007f;
167 7582 : b0 = 0.505001029045878f;
168 7582 : b1 = -1.01000205809176f;
169 7582 : b2 = 0.505001029045878f;
170 : }
171 : else
172 : {
173 68 : a1 = -0.13456126833218354f;
174 68 : a2 = -0.38813694706072926f;
175 68 : b0 = 1.0f;
176 68 : b1 = -1.9980666374183167f;
177 68 : b2 = 1.0f;
178 : }
179 :
180 1266850 : for ( i = 0; i < lg; i++ )
181 : {
182 1259200 : x2 = x1;
183 1259200 : x1 = x0;
184 1259200 : x0 = signal[i];
185 1259200 : y0 = ( y1 * a1 ) + ( y2 * a2 ) + ( x0 * b0 ) + ( x1 * b1 ) + ( x2 * b2 );
186 1259200 : signal[i] = y0;
187 1259200 : y2 = y1;
188 1259200 : y1 = y0;
189 : }
190 :
191 7650 : mem[0] = ( ( y1 > 1e-10 ) | ( y1 < -1e-10 ) ) ? y1 : 0;
192 7650 : mem[1] = ( ( y2 > 1e-10 ) | ( y2 < -1e-10 ) ) ? y2 : 0;
193 7650 : mem[2] = ( ( x0 > 1e-10 ) | ( x0 < -1e-10 ) ) ? x0 : 0;
194 7650 : mem[3] = ( ( x1 > 1e-10 ) | ( x1 < -1e-10 ) ) ? x1 : 0;
195 :
196 7650 : return;
197 : }
198 :
199 :
200 : /*---------------------------------------------------------------
201 : * deEmphResample()
202 : *
203 : * De-emphasize and resample the L and R channels.
204 : * ---------------------------------------------------------------*/
205 :
206 3791 : static void deEmphResample(
207 : STEREO_TCA_ENC_HANDLE hStereoTCA, /* i/o: Stereo TCA encoder handle */
208 : const float *tempChan1, /* i : Stereo data */
209 : const float *tempChan2, /* i : Stereo data */
210 : float *chan1,
211 : float *chan2,
212 : const int16_t input_frame,
213 : const int16_t dsFactor )
214 : {
215 : float buf1[L_FRAME48k], buf2[L_FRAME48k];
216 : float tempBuf1[2 * L_FRAME_DS], tempBuf2[2 * L_FRAME_DS];
217 : int16_t i;
218 : int16_t dsFac1, dsFac2;
219 :
220 : /* Estimate first and second stage downsample factors */
221 3791 : dsFac1 = ( dsFactor >> 1 );
222 3791 : dsFac2 = dsFactor / dsFac1;
223 :
224 : /* convert stereo data to two distinct channels, e.g., L, R */
225 3791 : mvr2r( tempChan1, buf1, input_frame );
226 3791 : mvr2r( tempChan2, buf2, input_frame );
227 :
228 : /* De-emphasis, 1/(1-mu z^-1), and resample, stage 1 */
229 3791 : deemph( buf1, PREEMPH_FAC_16k, input_frame, &hStereoTCA->memdecim[0] );
230 3791 : deemph( buf2, PREEMPH_FAC_16k, input_frame, &hStereoTCA->memdecim[1] );
231 :
232 1216911 : for ( i = 0; i < ( input_frame / dsFac1 ); i++ )
233 : {
234 1213120 : tempBuf1[i] = buf1[i * dsFac1];
235 1213120 : tempBuf2[i] = buf2[i * dsFac1];
236 : }
237 :
238 : /* De-emphasis, 1/(1-mu z^-1), and resample, stage 2 */
239 3791 : deemph( tempBuf1, PREEMPH_FAC_16k, ( input_frame / dsFac1 ), &hStereoTCA->memdecim[2] );
240 3791 : deemph( tempBuf2, PREEMPH_FAC_16k, ( input_frame / dsFac1 ), &hStereoTCA->memdecim[3] );
241 :
242 610351 : for ( i = 0; i < ( input_frame / dsFactor ); i++ )
243 : {
244 606560 : chan1[i] = tempBuf1[i * dsFac2];
245 606560 : chan2[i] = tempBuf2[i * dsFac2];
246 : }
247 :
248 3791 : spectral_balancer( chan1, &hStereoTCA->memdecim[4], input_frame / dsFactor, 0 ); /*4 mem */
249 3791 : spectral_balancer( chan2, &hStereoTCA->memdecim[8], input_frame / dsFactor, 0 ); /*4 mem */
250 :
251 3791 : return;
252 : }
253 :
254 : /*---------------------------------------------------------------
255 : * utilCrossCorr_mod()
256 : *
257 : * Biased crossCorr estimation between buf1, buf2 over the
258 : * lag range of (lagSearchRange[0], lagSearchRange[1]).
259 : * ---------------------------------------------------------------*/
260 :
261 3791 : static void utilCrossCorr_mod(
262 : STEREO_TCA_ENC_HANDLE hStereoTCA, /* i/o: ICA Stereo Encoder handle */
263 : const float *buf1,
264 : const float *buf2,
265 : float *corrEst, /* o : correlation estimate */
266 : const int16_t *lagSearchRange,
267 : const int16_t len )
268 : {
269 : float C, E1, E2;
270 : int16_t i, j;
271 : float Inv_Tot_E;
272 :
273 3791 : E1 = sum2_f( buf1, len );
274 3791 : E2 = sum2_f( buf2, len );
275 :
276 3791 : Inv_Tot_E = 1.0f / ( ( 2.0f * (float) len ) * sqrtf( ( E1 + hStereoTCA->E1_mem ) * ( E2 + hStereoTCA->E2_mem ) + 0.000000001f ) );
277 :
278 3791 : hStereoTCA->E1_mem = E1;
279 3791 : hStereoTCA->E2_mem = E2;
280 :
281 159222 : for ( i = lagSearchRange[0], j = 0; i <= 0; i++, j++ )
282 : {
283 155431 : C = dotp( buf1, buf2 + i, len );
284 155431 : corrEst[j] = ( C + hStereoTCA->C_mem[j] ) * Inv_Tot_E;
285 155431 : hStereoTCA->C_mem[j] = C;
286 : }
287 :
288 155431 : for ( ; i <= lagSearchRange[1]; i++, j++ )
289 : {
290 151640 : C = dotp( buf1 - i, buf2, len );
291 151640 : corrEst[j] = ( C + hStereoTCA->C_mem[j] ) * Inv_Tot_E;
292 151640 : hStereoTCA->C_mem[j] = C;
293 : }
294 :
295 3791 : return;
296 : }
297 :
298 :
299 : /*---------------------------------------------------------------
300 : * utilCrossCorr()
301 : *
302 : * crossCorr estimation between buf1, buf2 over the
303 : * lag range of (lagSearchRange[0], lagSearchRange[1]).
304 : * ---------------------------------------------------------------*/
305 :
306 161 : static void utilCrossCorr(
307 : const float *buf1,
308 : const float *buf2,
309 : const float *win,
310 : float *corrEst, /* o : correlation estimate */
311 : const int16_t *lagSearchRange,
312 : const int16_t len,
313 : const int16_t winSymmFlag )
314 : {
315 : float tempBuf1[L_FRAME48k];
316 : float tempBuf2[L_FRAME48k];
317 : float temp, scale;
318 : int16_t i, j;
319 :
320 : /* Apply windowing */
321 161 : if ( win != NULL )
322 : {
323 0 : if ( winSymmFlag == 0 )
324 : {
325 0 : v_mult( buf1, win, tempBuf1, len );
326 0 : v_mult( buf2, win, tempBuf2, len );
327 : }
328 : else
329 : {
330 0 : v_mult( buf1, win, tempBuf1, ( len >> 1 ) );
331 0 : v_mult( buf2, win, tempBuf2, ( len >> 1 ) );
332 :
333 0 : for ( i = ( len >> 1 ); i < len; i++ )
334 : {
335 0 : tempBuf1[i] = win[len - 1 - i] * buf1[i];
336 0 : tempBuf2[i] = win[len - 1 - i] * buf2[i];
337 : }
338 : }
339 : }
340 : else
341 : {
342 161 : mvr2r( buf1, tempBuf1, len );
343 161 : mvr2r( buf2, tempBuf2, len );
344 : }
345 :
346 161 : temp = sum2_f( tempBuf1, len );
347 161 : temp *= sum2_f( tempBuf2, len );
348 161 : scale = ( temp == 0 ) ? 1.0f : inv_sqrt( temp );
349 :
350 : /* starting point of lag search range should be less than the ending point */
351 161 : assert( lagSearchRange[0] <= lagSearchRange[1] );
352 :
353 : /* first part of noncausal corr est. */
354 311 : for ( i = lagSearchRange[0], j = 0; i <= min( 0, lagSearchRange[1] ); i++, j++ )
355 : {
356 150 : temp = dotp( tempBuf1 - i, tempBuf2, ( len + i ) );
357 150 : corrEst[j] = temp / ( len + i );
358 : }
359 :
360 : /* second part of noncausal corr est. */
361 391 : for ( ; i <= lagSearchRange[1]; i++, j++ )
362 : {
363 230 : temp = dotp( tempBuf1, tempBuf2 + i, ( len - i ) );
364 230 : corrEst[j] = temp / ( len - i );
365 : }
366 161 : v_multc( corrEst, scale, corrEst, j );
367 :
368 161 : return;
369 : }
370 :
371 : /*---------------------------------------------------------------
372 : * corrStatsEst()
373 : *
374 : * Non-causal shift estimation to encode future samples.
375 : * ---------------------------------------------------------------*/
376 :
377 3791 : static void corrStatsEst(
378 : STEREO_TCA_ENC_HANDLE hStereoTCA, /* i/o: Stereo TCA Encoder handle */
379 : const float *buf1, /* i : channel 1 */
380 : const float *buf2, /* i : channel 2 */
381 : const int16_t bufLenDS, /* i : buffer length */
382 : const int16_t dsFactor, /* i : buffer length */
383 : const int16_t vad_flag1, /* i : VAD flag channel 1 */
384 : const int16_t vad_flag2, /* i : VAD flag channel 2 */
385 : STEREO_CLASSIF_HANDLE hStereoClassif /* i/o: stereo classifier handle */
386 : )
387 : {
388 : int16_t lagSearchRange[2];
389 : float corrEst[2 * L_NCSHIFT_DS + 1];
390 : int16_t corrLagStats[3];
391 : float *tempRK;
392 : const float *winInterp;
393 : float rInterp[MAX_INTERPOLATE];
394 : int16_t interpMin, interpMax, interpLen;
395 : int16_t i, j, k, m;
396 : float tempF, alpha;
397 : float win_bias;
398 : int16_t tempLen, win_width;
399 : float loc_weight_win[4 * L_NCSHIFT_DS + 1];
400 : float X_hat, Y_hat, XY_hat, X_SQR_hat;
401 : float alpha_reg, beta_reg, reg_prv_corr, dist_reg_prv_corr, bias_par, width_par;
402 : float k1, k2, temp_A, temp_B;
403 : int16_t stmp;
404 : float corrEst_ncorr;
405 :
406 : /* init of regression parameters*/
407 3791 : X_hat = 0;
408 3791 : X_SQR_hat = 0;
409 3791 : XY_hat = 0;
410 :
411 : /* Initializations */
412 3791 : alpha = 0.7f;
413 3791 : lagSearchRange[0] = -L_NCSHIFT_DS;
414 3791 : lagSearchRange[1] = L_NCSHIFT_DS;
415 3791 : tempLen = ( 2 * L_NCSHIFT_DS + 1 );
416 :
417 3791 : set_s( corrLagStats, 0, 3 );
418 :
419 : /* First iteration of xcorr estimation */
420 3791 : utilCrossCorr_mod( hStereoTCA, buf1, buf2, corrEst, lagSearchRange, bufLenDS - L_XCORRMEM_DS );
421 :
422 : /* calculate features for the UNCLR classifier */
423 3791 : unclr_calc_corr_features( hStereoClassif, hStereoTCA, buf1, buf2, bufLenDS - L_XCORRMEM_DS, corrEst, lagSearchRange, &corrEst_ncorr );
424 :
425 11373 : for ( i = 1; i < 3; i++ )
426 : {
427 7582 : v_add( hStereoTCA->corrEstPrev[i], hStereoTCA->corrEstPrev[0], hStereoTCA->corrEstPrev[0], tempLen );
428 : }
429 :
430 : /* back up the corrEst */
431 11373 : for ( i = 0; i < 2; i++ )
432 : {
433 7582 : mvr2r( hStereoTCA->corrEstPrev[i + 1], hStereoTCA->corrEstPrev[i], tempLen );
434 : }
435 3791 : mvr2r( corrEst, hStereoTCA->corrEstPrev[2], tempLen );
436 :
437 3791 : temp_A = sumAbs( buf1, L_FRAME_DS - L_XCORRMEM_DS ) + sumAbs( buf2, L_FRAME_DS - L_XCORRMEM_DS );
438 3791 : temp_B = sumAbs( buf1 + ( L_FRAME_DS - L_XCORRMEM_DS ), L_XCORRMEM_DS ) + sumAbs( buf2 + ( L_FRAME_DS - L_XCORRMEM_DS ), L_XCORRMEM_DS );
439 3791 : tempF = temp_A + temp_B + hStereoTCA->mem_tempF;
440 3791 : hStereoTCA->mem_tempF = temp_B;
441 :
442 3791 : alpha = 0.93f;
443 3791 : if ( tempF > 4.0f * hStereoTCA->ica_envVarLT )
444 : {
445 122 : alpha = 0.83f;
446 : }
447 3669 : else if ( tempF > 2.0f * hStereoTCA->ica_envVarLT )
448 : {
449 313 : alpha = 0.85f;
450 : }
451 3356 : else if ( tempF > hStereoTCA->ica_envVarLT )
452 : {
453 1055 : alpha = 0.90f;
454 : }
455 :
456 3791 : hStereoTCA->corrStatsSmoothFac = alpha;
457 :
458 : /* long term corr Stats estimation */
459 3791 : v_multc( hStereoTCA->corrEstLT, alpha, hStereoTCA->corrEstLT, 2 * L_NCSHIFT_DS + 1 );
460 3791 : v_multc( corrEst, 1.0f - alpha, corrEst, 2 * L_NCSHIFT_DS + 1 );
461 3791 : v_add( hStereoTCA->corrEstLT, corrEst, hStereoTCA->corrEstLT, 2 * L_NCSHIFT_DS + 1 );
462 :
463 3791 : hStereoTCA->ica_envVarLT = SMOOTH_ENV_FACTOR * hStereoTCA->ica_envVarLT + ( 1 - SMOOTH_ENV_FACTOR ) * tempF;
464 :
465 3791 : mvr2r( hStereoTCA->corrEstLT, corrEst, 2 * L_NCSHIFT_DS + 1 );
466 3791 : Y_hat = hStereoTCA->delay_0_mem[0];
467 : /* Note: keep X_hat and X_SQR_hat calculations inside the loop to allow future tuning of MAX_DELAYREGLEN */
468 45492 : for ( i = 1; i < MAX_DELAYREGLEN; i++ )
469 : {
470 41701 : X_hat += (float) i;
471 41701 : Y_hat += hStereoTCA->delay_0_mem[i];
472 41701 : XY_hat += i * hStereoTCA->delay_0_mem[i];
473 41701 : X_SQR_hat += (float) ( i * i );
474 : }
475 3791 : X_hat *= INV_MAX_DELAYREGLEN;
476 3791 : Y_hat *= INV_MAX_DELAYREGLEN;
477 3791 : XY_hat *= INV_MAX_DELAYREGLEN;
478 3791 : X_SQR_hat *= INV_MAX_DELAYREGLEN;
479 :
480 3791 : beta_reg = 0;
481 3791 : tempF = X_SQR_hat - ( X_hat * X_hat );
482 3791 : if ( tempF != 0 )
483 : {
484 3791 : beta_reg = ( XY_hat - X_hat * Y_hat ) / tempF;
485 : }
486 3791 : alpha_reg = ( Y_hat - beta_reg * X_hat );
487 3791 : reg_prv_corr = beta_reg * MAX_DELAYREGLEN + alpha_reg;
488 :
489 3791 : if ( TRUNC( reg_prv_corr ) <= -L_NCSHIFT_DS )
490 : {
491 0 : reg_prv_corr = -L_NCSHIFT_DS + 1;
492 : }
493 :
494 3791 : if ( TRUNC( reg_prv_corr ) >= L_NCSHIFT_DS )
495 : {
496 0 : reg_prv_corr = L_NCSHIFT_DS - 1;
497 : }
498 :
499 3791 : bias_par = A_BIAS * hStereoTCA->smooth_dist_reg_prv_corr + B_BIAS;
500 3791 : bias_par = min( bias_par, XH_BIAS );
501 3791 : bias_par = max( bias_par, XL_BIAS );
502 :
503 3791 : width_par = A_WIDTH * hStereoTCA->smooth_dist_reg_prv_corr + B_WIDTH;
504 3791 : width_par = min( width_par, XH_WIDTH );
505 3791 : width_par = max( width_par, XL_WIDTH );
506 :
507 3791 : win_width = (int16_t) ( width_par * ( 4 * L_NCSHIFT_DS + 1 ) );
508 3791 : win_bias = bias_par;
509 3791 : k1 = 0.5f * ( 1.0f + win_bias );
510 3791 : k2 = 0.5f * ( 1.0f - win_bias );
511 :
512 159085 : for ( i = 0; i < ( 2 * L_NCSHIFT_DS - 2 * win_width ); i++ )
513 : {
514 155294 : loc_weight_win[i] = win_bias;
515 : }
516 :
517 303554 : for ( i = ( 2 * L_NCSHIFT_DS - 2 * win_width ); i <= ( 2 * L_NCSHIFT_DS + 2 * win_width ); i++ )
518 : {
519 299763 : loc_weight_win[i] = k1 + k2 * cosf( EVS_PI * ( ( i - 2 * L_NCSHIFT_DS ) / ( 2.0f * win_width ) ) );
520 : }
521 :
522 162876 : for ( i = ( 2 * L_NCSHIFT_DS + 2 * win_width ); i < ( 4 * L_NCSHIFT_DS + 1 ); i++ )
523 : {
524 159085 : loc_weight_win[i] = win_bias;
525 : }
526 :
527 310862 : for ( i = 0, j = L_NCSHIFT_DS - TRUNC( reg_prv_corr ); i < 2 * L_NCSHIFT_DS + 1; i++, j++ )
528 : {
529 307071 : corrEst[i] *= loc_weight_win[j];
530 : }
531 :
532 3791 : if ( hStereoTCA->prevTargetGain < 0.8f && vad_flag1 )
533 : {
534 : /* ch 2 is prev reference channel */
535 0 : v_multc( corrEst, 1.2f, corrEst, L_NCSHIFT_DS + 1 );
536 0 : v_multc( corrEst + L_NCSHIFT_DS + 1, 0.833f, corrEst + L_NCSHIFT_DS + 1, L_NCSHIFT_DS );
537 : }
538 3791 : else if ( hStereoTCA->prevTargetGain > 1.2f && vad_flag1 )
539 : {
540 : /* ch 1 is prev reference channel */
541 0 : v_multc( corrEst, 0.833f, corrEst, L_NCSHIFT_DS );
542 0 : v_multc( corrEst + L_NCSHIFT_DS, 1.2f, corrEst + L_NCSHIFT_DS, L_NCSHIFT_DS + 1 );
543 : }
544 :
545 3791 : if ( corrEst_ncorr > 0.8f && vad_flag1 )
546 : {
547 1544 : i = max( 0, hStereoTCA->prevCorrLagStats[0] - 1 + L_NCSHIFT_DS );
548 1544 : j = min( 2 * L_NCSHIFT_DS, hStereoTCA->prevCorrLagStats[0] + 1 + L_NCSHIFT_DS );
549 1544 : k = j - i + 1;
550 1544 : v_multc( corrEst + i, 1.2f, corrEst + i, k );
551 : }
552 :
553 : /* Initial corr lag estimate */
554 3791 : corrLagStats[0] = maximum( corrEst, ( lagSearchRange[1] - lagSearchRange[0] + 1 ), &tempF );
555 3791 : corrLagStats[0] += lagSearchRange[0];
556 :
557 3791 : stmp = corrLagStats[0] * dsFactor;
558 3791 : hStereoClassif->unclr_fv[E_corrLagStats0] = (float) stmp;
559 3791 : hStereoClassif->xtalk_fv[E_corrLagStats0] = (float) stmp;
560 3791 : hStereoClassif->xtalk_fv[E_ica_corr_value0] = tempF;
561 :
562 3791 : if ( vad_flag1 == 0 && alpha > 0.7f )
563 : {
564 15 : corrLagStats[0] = 0;
565 : }
566 :
567 3791 : dist_reg_prv_corr = fabsf( reg_prv_corr - corrLagStats[0] );
568 :
569 3791 : if ( vad_flag1 == 1 && vad_flag2 == 1 )
570 : {
571 3740 : hStereoTCA->smooth_dist_reg_prv_corr = SMOOTH_DIST_FACTOR * hStereoTCA->smooth_dist_reg_prv_corr + ( 1.0f - SMOOTH_DIST_FACTOR ) * dist_reg_prv_corr;
572 :
573 3740 : mvr2r( &( hStereoTCA->delay_0_mem[1] ), &( hStereoTCA->delay_0_mem[0] ), MAX_DELAYREGLEN - 1 );
574 :
575 3740 : hStereoTCA->delay_0_mem[MAX_DELAYREGLEN - 1] = 0.2f * hStereoTCA->delay_0_mem[MAX_DELAYREGLEN - 1] + 0.8f * corrLagStats[0];
576 :
577 3740 : if ( fabsf( reg_prv_corr - hStereoTCA->delay_0_mem[0] ) > 25 )
578 : {
579 85 : set_f( &( hStereoTCA->delay_0_mem[0] ), hStereoTCA->delay_0_mem[MAX_DELAYREGLEN - 1], MAX_DELAYREGLEN - 1 );
580 : }
581 : }
582 : else
583 : {
584 51 : hStereoTCA->smooth_dist_reg_prv_corr = 0.;
585 : }
586 :
587 3791 : if ( vad_flag1 == 0 || vad_flag2 == 0 )
588 : {
589 51 : corrLagStats[0] = TRUNC( hStereoTCA->delay_0_mem[MAX_DELAYREGLEN - 1] );
590 : }
591 :
592 : /* second iteration of xcorr update @ inputFs with interp*/
593 3791 : tempRK = hStereoTCA->corrEstLT - lagSearchRange[0] + corrLagStats[0];
594 3791 : set_f( rInterp, 0, MAX_INTERPOLATE );
595 :
596 : /* select the Rk interp sinc window */
597 3791 : winInterp = ica_sincInterp4 + SINC_ORDER1;
598 3791 : if ( dsFactor == 2 )
599 : {
600 745 : winInterp = ica_sincInterp2 + SINC_ORDER1;
601 : }
602 3046 : else if ( dsFactor == 6 )
603 : {
604 1028 : winInterp = ica_sincInterp6 + SINC_ORDER1;
605 : }
606 :
607 3791 : corrLagStats[1] = corrLagStats[0] * dsFactor;
608 :
609 3791 : interpMin = max( -( dsFactor - 1 ), -corrLagStats[1] - L_NCSHIFT_DS * dsFactor );
610 3791 : interpMax = min( ( dsFactor - 1 ), L_NCSHIFT_DS * dsFactor - corrLagStats[1] );
611 3791 : interpLen = interpMax - interpMin + 1;
612 :
613 31460 : for ( i = interpMin, k = 0; i <= interpMax; i++, k++ )
614 : {
615 27669 : rInterp[k] = 0.0f;
616 368954 : for ( j = -SINC_ORDER1 / dsFactor; j <= SINC_ORDER1 / dsFactor; j++ )
617 : {
618 341285 : m = j * dsFactor;
619 341285 : if ( ( m - i >= -SINC_ORDER1 ) && ( m - i <= SINC_ORDER1 ) )
620 : {
621 317407 : if ( j > lagSearchRange[1] - corrLagStats[0] )
622 : {
623 8 : rInterp[k] += winInterp[m - i] * tempRK[lagSearchRange[1] - corrLagStats[0]];
624 : }
625 317399 : else if ( j < lagSearchRange[0] - corrLagStats[0] )
626 : {
627 176 : rInterp[k] += winInterp[m - i] * tempRK[lagSearchRange[0] - corrLagStats[0]];
628 : }
629 : else
630 : {
631 317223 : rInterp[k] += winInterp[m - i] * tempRK[j];
632 : }
633 : }
634 : }
635 : }
636 3791 : corrLagStats[1] += ( maximum( rInterp, interpLen, &tempF ) + interpMin );
637 :
638 : /* save corr lag stats for the current frame */
639 3791 : mvs2s( corrLagStats, hStereoTCA->corrLagStats, 3 );
640 :
641 3791 : return;
642 : }
643 :
644 :
645 : /*---------------------------------------------------------------
646 : * Function estDownmixGain()
647 : *
648 : * Down mix gain estimation module; convert L/R to M/S.
649 : * ---------------------------------------------------------------*/
650 :
651 63470 : static void estDownmixGain(
652 : STEREO_TCA_ENC_HANDLE hStereoTCA, /* i/o: Stereo TCA Encoder handle */
653 : const float *chan1, /* i : reference signal */
654 : const float *chan2, /* i/o: target signal to be scaled */
655 : const int16_t ncShift, /* i : shift */
656 : const int16_t length, /* i : input frame length */
657 : const int16_t element_mode, /* i : element mode */
658 : STEREO_CLASSIF_HANDLE hStereoClassif, /* i/o: stereo classifier handle */
659 : const int16_t tdm_LRTD_flag /* i : LRTD stereo mode flag */
660 : )
661 : {
662 : int16_t i, i1, i2;
663 : float tempN, tempD;
664 : float alpha, currentGain;
665 : float unclr_instTargetGain;
666 :
667 63470 : if ( hStereoTCA->refChanIndx == L_CH_INDX )
668 : {
669 63453 : i1 = 0;
670 63453 : i2 = ncShift;
671 : }
672 : else
673 : {
674 17 : i1 = ncShift;
675 17 : i2 = 0;
676 : }
677 :
678 : /* abs sample sum estimation */
679 63470 : tempN = 0;
680 63470 : tempD = 0;
681 43756774 : for ( i = 0, tempN = 0.0f, tempD = 0.0f; i < length; i++ )
682 : {
683 43693304 : tempN += fabsf( chan1[i1 + i] );
684 43693304 : tempD += fabsf( chan2[i2 + i] );
685 : }
686 :
687 63470 : alpha = hStereoTCA->corrStatsSmoothFac;
688 63470 : currentGain = ( tempD == 0 ) ? ( hStereoTCA->prevTargetGain ) : ( tempN / tempD );
689 63470 : currentGain = max( 1e-5f, currentGain );
690 63470 : hStereoTCA->instTargetGain = currentGain;
691 63470 : currentGain = (alpha) *log10f( hStereoTCA->prevTargetGain ) + ( 1.0f - alpha ) * log10f( currentGain );
692 :
693 63470 : if ( element_mode == IVAS_CPE_TD && hStereoClassif != NULL )
694 : {
695 3791 : tempD = powf( 10, currentGain );
696 3791 : unclr_instTargetGain = log10f( tempN / ( tempD + 1e-5f ) + 1.0f );
697 3791 : hStereoClassif->unclr_fv[E_ica_instTargetGain] = unclr_instTargetGain;
698 : }
699 :
700 63470 : if ( tdm_LRTD_flag == 1 )
701 : {
702 3665 : currentGain = 0.0f;
703 : }
704 59805 : else if ( hStereoTCA->LRTD_G_ATT_cnt > 1 ) /* lrtd_mode == 1 but tdm_LRTD_flag still 0 */
705 : {
706 216 : currentGain /= ( (float) hStereoTCA->LRTD_G_ATT_cnt );
707 : }
708 :
709 : /* quantize the target gain */
710 63470 : hStereoTCA->indx_ica_gD = (int16_t) usquant( currentGain, &tempD, STEREO_TCA_GDMIN, STEREO_TCA_GDSTEP, 1 << STEREO_BITS_TCA_GD );
711 63470 : hStereoTCA->targetGain = powf( 10, tempD );
712 :
713 63470 : return;
714 : }
715 :
716 : /*---------------------------------------------------------------
717 : * Function icaMemUpdate()
718 : *
719 : * Recalculates the memories corresponding to the previous frame.
720 : * ---------------------------------------------------------------*/
721 :
722 3791 : static void icaMemUpdate(
723 : Encoder_State **sts, /* i/o: encoder state structure */
724 : CPE_ENC_HANDLE hCPE, /* i : CPE encoder structure */
725 : float *bufChanL, /* i/o: L signal correction from previous frame */
726 : float *bufChanR, /* i/o: R signal correction from previous frame */
727 : const int16_t lMemRecalc, /* i : memory length at input Sampling Rate */
728 : const int16_t lMemRecalc_SCh, /* i : SCh memory length at input Sampling Rate*/
729 : const int16_t input_frame /* i : frame length */
730 : )
731 : {
732 : float *ptr1, *ptr2;
733 : int16_t i;
734 : float ratio_L, One_m_Ratio;
735 :
736 3791 : if ( hCPE->element_mode == IVAS_CPE_TD )
737 : {
738 : /* Recalc of the memories - Downmix @ inputFs */
739 : /*----------------------------------------------------------------*
740 : * Create first part of the mixture using the old ratios
741 : *----------------------------------------------------------------*/
742 :
743 3791 : if ( hCPE->hStereoTD->tdm_last_SM_flag )
744 : {
745 12 : ratio_L = hCPE->hStereoTD->tdm_last_ratio_SM;
746 12 : One_m_Ratio = ratio_L - 1.0f;
747 : }
748 : else
749 : {
750 3779 : ratio_L = hCPE->hStereoTD->tdm_last_ratio;
751 3779 : One_m_Ratio = 1.0f - ratio_L;
752 : }
753 :
754 3791 : ptr1 = sts[0]->input - lMemRecalc - lMemRecalc_SCh;
755 3791 : ptr2 = sts[1]->input - lMemRecalc - lMemRecalc_SCh;
756 :
757 3791 : if ( hCPE->last_element_mode == IVAS_CPE_TD )
758 : {
759 3732 : if ( hCPE->hStereoTD->flag_skip_DMX )
760 : {
761 30932 : for ( i = lMemRecalc_SCh; i < lMemRecalc + lMemRecalc_SCh; i++ )
762 : {
763 30840 : ptr1[i] = bufChanL[i];
764 30840 : ptr2[i] = bufChanR[i];
765 : }
766 : }
767 : else
768 : {
769 901000 : for ( i = lMemRecalc_SCh; i < lMemRecalc + lMemRecalc_SCh; i++ )
770 : {
771 897360 : ptr1[i] = bufChanR[i] * One_m_Ratio + bufChanL[i] * ratio_L;
772 897360 : ptr2[i] = bufChanL[i] * One_m_Ratio - bufChanR[i] * ratio_L;
773 : }
774 : }
775 : }
776 : else
777 : {
778 : float fac, incr, tmp1, tmp2;
779 :
780 : /* reset the past input signal (the signal is used in SWB BWE) */
781 59 : set_f( sts[1]->input - input_frame, 0, input_frame );
782 :
783 59 : if ( hCPE->hStereoTD->flag_skip_DMX )
784 : {
785 : /* reconstruction of the Secondary channel past segment */
786 813 : for ( i = 0; i < lMemRecalc_SCh; i++ )
787 : {
788 805 : ptr2[i] = bufChanL[i] * One_m_Ratio + bufChanR[i] * ratio_L;
789 : }
790 :
791 : /* overlap-add smoothing to equalize for different DMX signal energy between DFT and TD stereo */
792 8 : fac = 1.0f / (float) lMemRecalc;
793 8 : incr = fac;
794 :
795 2768 : for ( i = lMemRecalc_SCh; i < lMemRecalc + lMemRecalc_SCh; i++ )
796 : {
797 2760 : tmp1 = bufChanL[i];
798 2760 : tmp2 = bufChanR[i];
799 :
800 2760 : ptr1[i] = ( 1.0f - fac ) * ptr1[i] + fac * tmp1;
801 : /*ptr2[i] = (1.0f - fac) * ptr2[i] + fac * tmp2;*/ /* the secondary channel (downmixed) buffer of DFT stereo is empty ! */
802 2760 : ptr2[i] = tmp2;
803 :
804 2760 : fac += incr;
805 : }
806 : }
807 : else
808 : {
809 : /* reconstruction of the Secondary channel past segment */
810 3796 : for ( i = 0; i < lMemRecalc_SCh; i++ )
811 : {
812 3745 : ptr2[i] = bufChanL[i] * One_m_Ratio - bufChanR[i] * ratio_L;
813 : }
814 :
815 : /* overlap-add smoothing to equalize for different DMX signal energy between DFT and TD stereo */
816 51 : fac = 1.0f / (float) lMemRecalc;
817 51 : incr = fac;
818 :
819 12891 : for ( i = lMemRecalc_SCh; i < lMemRecalc + lMemRecalc_SCh; i++ )
820 : {
821 12840 : tmp1 = bufChanR[i] * One_m_Ratio + bufChanL[i] * ratio_L;
822 12840 : tmp2 = bufChanL[i] * One_m_Ratio - bufChanR[i] * ratio_L;
823 :
824 12840 : ptr1[i] = ( 1.0f - fac ) * ptr1[i] + fac * tmp1;
825 : /*ptr2[i] = (1.0f - fac) * ptr2[i] + fac * tmp2;*/ /* the secondary channel (downmixed) buffer of DFT stereo is empty ! */
826 12840 : ptr2[i] = tmp2;
827 :
828 12840 : fac += incr;
829 : }
830 : }
831 : }
832 : }
833 :
834 3791 : if ( hCPE->hStereoICBWE != NULL )
835 : {
836 : assert( L_MEM_RECALC_TBE_NS <= L_MEM_RECALC_NS );
837 126 : i = NS2SA( sts[0]->input_Fs, L_MEM_RECALC_TBE_NS );
838 126 : mvr2r( bufChanL + lMemRecalc + lMemRecalc_SCh - i, hCPE->hStereoICBWE->icbwe_inp_mem[0], i );
839 126 : mvr2r( bufChanR + lMemRecalc + lMemRecalc_SCh - i, hCPE->hStereoICBWE->icbwe_inp_mem[1], i );
840 : }
841 :
842 3791 : return;
843 : }
844 :
845 : /*---------------------------------------------------------------
846 : * stereo_tca_enc()
847 : *
848 : * Stereo temporal inter-channel adjustment/allocation processing module;
849 : * Downmix, convert L/R to M/S.
850 : * ---------------------------------------------------------------*/
851 :
852 420855 : void stereo_tca_enc(
853 : CPE_ENC_HANDLE hCPE, /* i : CPE encoder structure */
854 : const int16_t input_frame /* i : length of a frame per channel */
855 : )
856 : {
857 : /* temp variables */
858 : int16_t i, dsFactor, lMemRecalc;
859 : Encoder_State **sts;
860 : STEREO_TCA_ENC_HANDLE hStereoTCA;
861 :
862 : /* Buffers, input Left and right channels @ input_Fs*/
863 : int16_t lMemRecalc_SCh;
864 : float bufChanL[L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX];
865 : float bufChanR[L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH + L_FRAME48k + L_NCSHIFTMAX];
866 : float input_mem_loc[2][NS2SA( 48000, L_MEM_RECALC_NS + L_MEM_RECALC_SCH_NS )];
867 : float *ptrChanL, *ptrChanR;
868 :
869 : /* Buffers at internal sampling rate, i.e., CORR_INTER_FS */
870 : float bufChanL_DS[L_FRAME_DS + ADDED_MEM_DS];
871 : float bufChanR_DS[L_FRAME_DS + ADDED_MEM_DS];
872 : float *ptrChanL_DS, *ptrChanR_DS;
873 : float *target;
874 : int16_t target_idx;
875 :
876 : int16_t prevNCShift, currentNCShift;
877 : int16_t tempLag[2];
878 : float corrEstStage2[N_MAX_SHIFT_CHANGE + 1];
879 :
880 : /* temp variables */
881 : float tempF, tempF1;
882 : int16_t tempS, tempS_buff[3];
883 : int16_t maxCorrStatsDev, L_shift_adapt;
884 420855 : int16_t musicMode = 0, neighborLimit;
885 : int32_t input_Fs;
886 : int16_t prev_ICA_flag;
887 :
888 : /* initialization */
889 420855 : sts = hCPE->hCoreCoder;
890 420855 : hStereoTCA = hCPE->hStereoTCA;
891 :
892 420855 : input_Fs = sts[0]->input_Fs;
893 :
894 420855 : lMemRecalc = NS2SA( input_Fs, L_MEM_RECALC_NS );
895 420855 : lMemRecalc_SCh = NS2SA( input_Fs, L_MEM_RECALC_SCH_NS );
896 :
897 420855 : if ( hCPE->element_mode == IVAS_CPE_MDCT )
898 : {
899 357385 : return;
900 : }
901 :
902 : /* populate L/R memories into current buffers */
903 63470 : mvr2r( hStereoTCA->memChanL, bufChanL, lMemRecalc + lMemRecalc_SCh );
904 63470 : mvr2r( hStereoTCA->memChanR, bufChanR, lMemRecalc + lMemRecalc_SCh );
905 :
906 : /* pointers to the current frame */
907 63470 : ptrChanL = bufChanL + lMemRecalc + lMemRecalc_SCh;
908 63470 : ptrChanR = bufChanR + lMemRecalc + lMemRecalc_SCh;
909 :
910 : /* copy interleaved stereo data to two channels, e.g., L, R */
911 63470 : mvr2r( sts[0]->input, ptrChanL, input_frame );
912 63470 : mvr2r( sts[1]->input, ptrChanR, input_frame );
913 :
914 : /* UNCLR classifier update */
915 63470 : if ( hCPE->hStereoClassif->lrtd_mode == 0 ) /* Normal TD mode, no attenuation */
916 : {
917 59461 : hStereoTCA->LRTD_G_ATT_cnt = 1;
918 : }
919 4009 : else if ( hCPE->hStereoTD != NULL )
920 : {
921 3791 : if ( hCPE->hStereoTD->tdm_LRTD_flag == 0 ) /* lrtd_mode == 1, but in td section */
922 : {
923 126 : hStereoTCA->LRTD_G_ATT_cnt++;
924 126 : hStereoTCA->LRTD_G_ATT_cnt = min( 1000, hStereoTCA->LRTD_G_ATT_cnt );
925 : }
926 : }
927 :
928 63470 : if ( hCPE->element_mode != IVAS_CPE_TD )
929 : {
930 59679 : hStereoTCA->refChanIndx = L_CH_INDX;
931 59679 : hStereoTCA->corrStatsSmoothFac = 0.7f;
932 59679 : estDownmixGain( hStereoTCA, ptrChanL, ptrChanR, 0, input_frame, hCPE->element_mode, NULL, 0 );
933 59679 : hStereoTCA->prevTargetGain = hStereoTCA->targetGain;
934 : #ifdef DEBUG_MODE_INFO
935 : hStereoTCA->indx_ica_NCShift = 0;
936 : #endif
937 :
938 : /* back up the L/R missing target */
939 59679 : mvr2r( bufChanL + input_frame, hStereoTCA->memChanL, lMemRecalc + lMemRecalc_SCh );
940 59679 : mvr2r( bufChanR + input_frame, hStereoTCA->memChanR, lMemRecalc + lMemRecalc_SCh );
941 :
942 59679 : hStereoTCA->lMemRecalc = 0;
943 59679 : hStereoTCA->lMemRecalc_12k8 = 0;
944 59679 : hStereoTCA->lMemRecalc_16k = 0;
945 :
946 59679 : return;
947 : }
948 3791 : else if ( hCPE->last_element_mode != IVAS_CPE_TD )
949 : {
950 59 : tempF = hStereoTCA->targetGain;
951 59 : tempF1 = hStereoTCA->prevTargetGain;
952 59 : tempS = hStereoTCA->prevRefChanIndx;
953 59 : mvs2s( hStereoTCA->prevCorrLagStats, tempS_buff, 3 );
954 59 : stereo_tca_init_enc( hStereoTCA, input_Fs );
955 59 : hStereoTCA->targetGain = tempF;
956 59 : hStereoTCA->prevTargetGain = tempF1;
957 :
958 59 : if ( hCPE->hStereoClassif->lrtd_mode == 1 )
959 : {
960 59 : hStereoTCA->targetGain = min( hStereoTCA->targetGain, 1.0f );
961 59 : hStereoTCA->prevTargetGain = min( hStereoTCA->prevTargetGain, 1.0f );
962 :
963 59 : hStereoTCA->prevTargetGain = 1;
964 : }
965 :
966 59 : hStereoTCA->prevRefChanIndx = tempS;
967 59 : mvs2s( tempS_buff, hStereoTCA->prevCorrLagStats, 3 );
968 :
969 : /* populate memory */
970 59 : if ( hCPE->last_element_mode == IVAS_CPE_MDCT )
971 : {
972 8 : mvr2r( sts[0]->input - lMemRecalc - lMemRecalc_SCh, bufChanL, lMemRecalc + lMemRecalc_SCh );
973 8 : mvr2r( sts[1]->input - lMemRecalc - lMemRecalc_SCh, bufChanR, lMemRecalc + lMemRecalc_SCh );
974 : }
975 : }
976 :
977 : /* populate L/R DS memories into current buffers */
978 3791 : mvr2r( hStereoTCA->memChanL_DS, bufChanL_DS, ADDED_MEM_DS );
979 3791 : mvr2r( hStereoTCA->memChanR_DS, bufChanR_DS, ADDED_MEM_DS );
980 :
981 : /* pointers to the current frame of DS */
982 3791 : ptrChanL_DS = bufChanL_DS + ADDED_MEM_DS;
983 3791 : ptrChanR_DS = bufChanR_DS + ADDED_MEM_DS;
984 :
985 : /* resample factor */
986 3791 : dsFactor = (int16_t) ( input_Fs / CORR_INTER_FS );
987 :
988 : /* resample the stereo channels */
989 3791 : deEmphResample( hStereoTCA, ptrChanL, ptrChanR, ptrChanL_DS, ptrChanR_DS, input_frame, dsFactor );
990 :
991 :
992 : /* inter-channel corrStats estimation */
993 3791 : corrStatsEst( hStereoTCA, bufChanL_DS + ADDED_MEM_DS, bufChanR_DS + ADDED_MEM_DS, ( L_FRAME_DS + L_XCORRMEM_DS ), dsFactor, hCPE->hCoreCoder[0]->vad_flag, hCPE->hCoreCoder[1]->vad_flag, hCPE->hStereoClassif );
994 :
995 : /*-----------------------------------------------------------------*
996 : * refine the ICA stats
997 : *-----------------------------------------------------------------*/
998 :
999 3791 : prev_ICA_flag = 0;
1000 3791 : if ( hCPE->hStereoTD->prev_fr_LRTD_TD_dec && abs( hStereoTCA->prevCorrLagStats[2] ) != 0 )
1001 : {
1002 33 : prev_ICA_flag = 1;
1003 : }
1004 :
1005 3791 : if ( hCPE->hStereoTD->prev_fr_LRTD_TD_dec == 0 || prev_ICA_flag == 1 )
1006 : {
1007 : /* initialize the refinement search for NC-shift */
1008 210 : hStereoTCA->corrLagStats[2] = hStereoTCA->corrLagStats[1];
1009 :
1010 210 : maxCorrStatsDev = N_MAX_SHIFT_CHANGE;
1011 210 : if ( hStereoTCA->corrStatsSmoothFac <= 0.7f )
1012 : {
1013 0 : maxCorrStatsDev = 160; /* L_NCSHIFT_MAX @ 32kHz */
1014 : }
1015 :
1016 210 : if ( input_Fs < 32000 )
1017 : {
1018 35 : maxCorrStatsDev = (int16_t) ( maxCorrStatsDev * input_Fs / 32000.0f );
1019 : }
1020 :
1021 210 : musicMode = ( hCPE->hCoreCoder[0]->sp_aud_decision0 == 1 || sts[0]->last_core > ACELP_CORE );
1022 210 : if ( musicMode )
1023 : {
1024 104 : maxCorrStatsDev = 1;
1025 104 : set_s( hStereoTCA->corrLagStats + 1, 0, 2 );
1026 : }
1027 :
1028 210 : tempS = ( hStereoTCA->corrLagStats[1] - hStereoTCA->prevCorrLagStats[2] );
1029 210 : if ( abs( tempS ) > maxCorrStatsDev )
1030 : {
1031 66 : hStereoTCA->corrLagStats[2] = hStereoTCA->prevCorrLagStats[2] + ( ( tempS > 0 ) ? maxCorrStatsDev : -maxCorrStatsDev );
1032 : }
1033 :
1034 210 : neighborLimit = maxCorrStatsDev;
1035 :
1036 : /* refine and search based on the corrlag stats */
1037 210 : if ( tempS != 0 && dsFactor != 1 && prev_ICA_flag == 0 )
1038 : {
1039 103 : tempF = 0;
1040 103 : if ( !musicMode )
1041 : {
1042 83 : tempLag[0] = min( hStereoTCA->corrLagStats[2], hStereoTCA->prevCorrLagStats[2] );
1043 83 : tempLag[1] = max( hStereoTCA->corrLagStats[2], hStereoTCA->prevCorrLagStats[2] );
1044 :
1045 83 : neighborLimit = min( 3, maxCorrStatsDev );
1046 83 : if ( hStereoTCA->prevCorrLagStats[2] < hStereoTCA->corrLagStats[2] )
1047 : {
1048 61 : tempLag[1] = min( tempLag[1], tempLag[0] + neighborLimit );
1049 : }
1050 : else
1051 : {
1052 22 : tempLag[0] = max( tempLag[0], tempLag[1] - neighborLimit );
1053 : }
1054 :
1055 83 : utilCrossCorr( ptrChanL, ptrChanR, NULL, corrEstStage2, tempLag, input_frame, 0 );
1056 :
1057 83 : hStereoTCA->corrLagStats[2] = maximum( corrEstStage2, ( tempLag[1] - tempLag[0] + 1 ), &tempF );
1058 83 : hStereoTCA->corrLagStats[2] += tempLag[0];
1059 : }
1060 :
1061 103 : if ( abs( tempS ) > neighborLimit )
1062 : {
1063 78 : tempLag[0] = hStereoTCA->corrLagStats[1];
1064 78 : tempLag[1] = hStereoTCA->corrLagStats[1];
1065 78 : utilCrossCorr( ptrChanL, ptrChanR, NULL, &tempF1, tempLag, input_frame, 0 );
1066 :
1067 78 : if ( tempF1 > tempF || musicMode )
1068 : {
1069 20 : hStereoTCA->corrLagStats[2] = hStereoTCA->prevCorrLagStats[2] + ( ( tempS > 0 ) ? min( (int16_t) abs( tempS ), maxCorrStatsDev ) : max( (int16_t) -abs( tempS ), -maxCorrStatsDev ) );
1070 : }
1071 : }
1072 :
1073 : /* restrict the reference channel for +/- variation */
1074 103 : if ( ( hStereoTCA->corrLagStats[2] < 0 && hStereoTCA->prevCorrLagStats[2] > 0 ) || ( hStereoTCA->corrLagStats[2] > 0 && hStereoTCA->prevCorrLagStats[2] < 0 ) )
1075 : {
1076 1 : hStereoTCA->corrLagStats[2] = 0;
1077 : }
1078 : }
1079 :
1080 210 : if ( hCPE->hStereoTD->prev_fr_LRTD_TD_dec /*hCPE->hStereoClassif->lrtd_mode*/ == 1 ) /* Content is considered as uncorrelated -> ICA shift is turned off */
1081 : {
1082 33 : hStereoTCA->corrLagStats[2] = 0;
1083 :
1084 33 : if ( hCPE->hStereoTD->tdm_LRTD_flag == 1 && prev_ICA_flag == 0 )
1085 : {
1086 0 : hStereoTCA->prevCorrLagStats[2] = 0;
1087 : }
1088 : }
1089 :
1090 : /* Perform the following:
1091 : 1. adjust samples,
1092 : 2. interp shift variation,
1093 : 3. gain estimation */
1094 210 : prevNCShift = (int16_t) abs( hStereoTCA->prevCorrLagStats[2] );
1095 210 : currentNCShift = (int16_t) abs( hStereoTCA->corrLagStats[2] );
1096 :
1097 210 : if ( hStereoTCA->prevRefChanIndx == L_CH_INDX )
1098 : {
1099 193 : mvr2r( ptrChanL - lMemRecalc - lMemRecalc_SCh, input_mem_loc[0], lMemRecalc + lMemRecalc_SCh );
1100 193 : v_multc( ptrChanR + prevNCShift - lMemRecalc - lMemRecalc_SCh, hStereoTCA->prevTargetGain, input_mem_loc[1], lMemRecalc + lMemRecalc_SCh );
1101 : }
1102 : else
1103 : {
1104 17 : mvr2r( ptrChanL + prevNCShift - lMemRecalc - lMemRecalc_SCh, input_mem_loc[0], lMemRecalc + lMemRecalc_SCh );
1105 17 : v_multc( ptrChanR - lMemRecalc - lMemRecalc_SCh, hStereoTCA->prevTargetGain, input_mem_loc[1], lMemRecalc + lMemRecalc_SCh );
1106 : }
1107 :
1108 210 : target = ptrChanR;
1109 210 : target_idx = R_CH_INDX;
1110 : /* identify target signal to correct for shift variations */
1111 210 : if ( ( prevNCShift == 0 && hStereoTCA->corrLagStats[2] < 0 ) || ( hStereoTCA->prevRefChanIndx == R_CH_INDX ) )
1112 : {
1113 33 : target = ptrChanL;
1114 33 : target_idx = L_CH_INDX;
1115 : }
1116 :
1117 : /* target signal adjustment for temporal shift variations */
1118 210 : if ( ( prevNCShift - currentNCShift ) != 0 )
1119 : {
1120 79 : L_shift_adapt = L_SHIFT_ADAPT_16k;
1121 79 : if ( input_Fs > INT_FS_16k )
1122 : {
1123 62 : L_shift_adapt = L_SHIFT_ADAPT_MAX;
1124 : }
1125 :
1126 : /* Note!! : Always keep the assert (prevNCShift>>1) below according to the equation used here to get tempS */
1127 79 : tempS = ( currentNCShift >> 1 );
1128 79 : if ( abs( currentNCShift - prevNCShift ) <= min( N_MAX_SHIFT_CHANGE, N_MAX_SHIFT_CHANGE * input_Fs / 32000.0f ) )
1129 : {
1130 : #ifdef DEBUGGING
1131 : /* Max sample looked in INTERP1 should lie within the bounds of input_frame and memory populated */
1132 : assert( ( ( abs( currentNCShift - prevNCShift ) + 1 ) + SINC_ORDER1 / INTERP_FACTOR1 ) + L_shift_adapt - tempS < input_frame );
1133 : assert( ( ( abs( currentNCShift - prevNCShift ) + 1 ) + SINC_ORDER1 / INTERP_FACTOR1 + tempS ) < L_NCSHIFTMAX );
1134 : assert( tempS + currentNCShift <= lMemRecalc );
1135 : assert( input_frame - ( min( N_MAX_SHIFT_CHANGE, ( N_MAX_SHIFT_CHANGE * input_Fs ) / 32000 ) + 1 + SINC_ORDER1 / INTERP_FACTOR1 ) - ( prevNCShift >> 1 ) >= L_shift_adapt - tempS );
1136 : #endif
1137 62 : adjustTargetSignal( ( target - tempS ), prevNCShift, currentNCShift, L_shift_adapt, 0 );
1138 : }
1139 : else
1140 : {
1141 17 : tempS = min( max( tempS, prevNCShift - currentNCShift + L_shift_adapt - input_frame ), prevNCShift - currentNCShift + lMemRecalc );
1142 17 : adjustTargetSignal( ( target - tempS ), prevNCShift, currentNCShift, L_shift_adapt, 1 );
1143 : }
1144 :
1145 79 : if ( target_idx == L_CH_INDX )
1146 : {
1147 32 : mvr2r( target - tempS, &( input_mem_loc[target_idx][lMemRecalc + lMemRecalc_SCh - tempS - currentNCShift] ), currentNCShift + tempS );
1148 : }
1149 : else
1150 : {
1151 47 : v_multc( target - tempS, hStereoTCA->prevTargetGain, &( input_mem_loc[target_idx][lMemRecalc + lMemRecalc_SCh - tempS - currentNCShift] ), currentNCShift + tempS );
1152 : }
1153 : }
1154 :
1155 : /* reference channel index */
1156 210 : if ( hStereoTCA->corrLagStats[2] >= 0 )
1157 : {
1158 193 : hStereoTCA->refChanIndx = L_CH_INDX;
1159 : }
1160 : else
1161 : {
1162 17 : hStereoTCA->refChanIndx = R_CH_INDX;
1163 : }
1164 :
1165 : /* Estimate and quantize the gain for scaling */
1166 210 : estDownmixGain( hStereoTCA, ptrChanL, ptrChanR, currentNCShift, ( input_frame - currentNCShift ), hCPE->element_mode, hCPE->hStereoClassif, hCPE->hStereoTD->tdm_LRTD_flag );
1167 :
1168 : /* quantize the corrStats */
1169 210 : hStereoTCA->indx_ica_NCShift = (int16_t) usquant( ( (float) currentNCShift ) / dsFactor, &tempF, 0, 1.0f, 1 << STEREO_BITS_TCA_CORRSTATS );
1170 : }
1171 : else
1172 : {
1173 3581 : hStereoTCA->refChanIndx = L_CH_INDX;
1174 3581 : hStereoTCA->corrLagStats[2] = 0;
1175 3581 : hStereoTCA->prevCorrLagStats[2] = 0;
1176 3581 : hStereoTCA->indx_ica_NCShift = 0;
1177 :
1178 3581 : currentNCShift = 0; /* only to avoid compilation warning */
1179 3581 : target = ptrChanL; /* only to avoid compilation warning */
1180 3581 : target_idx = L_CH_INDX; /* only to avoid compilation warning */
1181 :
1182 3581 : mvr2r( ptrChanL - lMemRecalc - lMemRecalc_SCh, input_mem_loc[0], lMemRecalc + lMemRecalc_SCh );
1183 3581 : v_multc( ptrChanR - lMemRecalc - lMemRecalc_SCh, hStereoTCA->prevTargetGain, input_mem_loc[1], lMemRecalc + lMemRecalc_SCh );
1184 :
1185 : /* Estimate and quantize the gain for scaling */
1186 3581 : estDownmixGain( hStereoTCA, ptrChanL, ptrChanR, 0, input_frame, hCPE->element_mode, hCPE->hStereoClassif, hCPE->hStereoTD->tdm_LRTD_flag );
1187 : }
1188 :
1189 : /*-----------------------------------------------------------------*
1190 : * updates and memory backups
1191 : *-----------------------------------------------------------------*/
1192 :
1193 : /* back up the L/R missing target */
1194 3791 : mvr2r( bufChanL + input_frame, hStereoTCA->memChanL, lMemRecalc + lMemRecalc_SCh );
1195 3791 : mvr2r( bufChanR + input_frame, hStereoTCA->memChanR, lMemRecalc + lMemRecalc_SCh );
1196 :
1197 3791 : if ( currentNCShift != 0 )
1198 : {
1199 : /* Temporal channel adjustment of the LA samples based on the NC shift */
1200 49 : tcaTargetCh_LA( hStereoTCA, ptrChanL, ptrChanR, currentNCShift, input_frame );
1201 : }
1202 :
1203 : /* Update of changed samples corresponding to the memory */
1204 3791 : icaMemUpdate( sts, hCPE, input_mem_loc[0], input_mem_loc[1], lMemRecalc, lMemRecalc_SCh, input_frame );
1205 :
1206 : /* populate the st->input target buffer */
1207 3791 : if ( hCPE->hStereoTD->prev_fr_LRTD_TD_dec == 0 || prev_ICA_flag == 1 )
1208 : {
1209 210 : mvr2r( target + currentNCShift, sts[target_idx]->input, input_frame );
1210 : }
1211 :
1212 3791 : if ( hCPE->element_mode != IVAS_CPE_DFT )
1213 : {
1214 : /* Scale the Right channel with the gain */
1215 : int16_t j;
1216 3791 : int16_t l_ica_ovl = NS2SA( input_Fs, STEREO_L_TCA_OVLP_NS );
1217 3791 : float winSlope = 1.0f / (float) l_ica_ovl;
1218 :
1219 3791 : tempF1 = hStereoTCA->targetGain;
1220 3791 : tempF = hStereoTCA->prevTargetGain;
1221 :
1222 632991 : for ( i = 0, j = 0; i < l_ica_ovl; i++, j++ )
1223 : {
1224 629200 : sts[1]->input[i] = ( 1.0f - j * winSlope ) * tempF * sts[1]->input[i] + ( j * winSlope ) * tempF1 * sts[1]->input[i];
1225 : }
1226 1891391 : for ( ; i < input_frame; i++ )
1227 : {
1228 1887600 : sts[1]->input[i] *= tempF1;
1229 : }
1230 : }
1231 :
1232 : /* update L/R DS memories */
1233 3791 : mvr2r( bufChanL_DS + L_FRAME_DS, hStereoTCA->memChanL_DS, ADDED_MEM_DS );
1234 3791 : mvr2r( bufChanR_DS + L_FRAME_DS, hStereoTCA->memChanR_DS, ADDED_MEM_DS );
1235 :
1236 : /* save the reference channel index for next frame */
1237 3791 : hStereoTCA->prevRefChanIndx = hStereoTCA->refChanIndx;
1238 :
1239 : /* save the corr lag stats for next frame */
1240 3791 : mvs2s( hStereoTCA->corrLagStats, hStereoTCA->prevCorrLagStats, 3 );
1241 :
1242 : /* save the target gain for next frame */
1243 3791 : hStereoTCA->prevTargetGain = hStereoTCA->targetGain;
1244 :
1245 3791 : return;
1246 : }
1247 :
1248 : /*-------------------------------------------------------------------*
1249 : * stereo_tca_init_enc()
1250 : *
1251 : * Stereo temporal inter-channel adjustment (ICA) encoder initialization
1252 : *-------------------------------------------------------------------*/
1253 :
1254 890 : void stereo_tca_init_enc(
1255 : STEREO_TCA_ENC_HANDLE hStereoTCA, /* i/o: Stereo ICA handle */
1256 : const int32_t input_Fs /* i : input sampling frequency */
1257 : )
1258 : {
1259 890 : hStereoTCA->lMemRecalc = NS2SA( input_Fs, L_MEM_RECALC_NS );
1260 890 : hStereoTCA->lMemRecalc_12k8 = (int16_t) ( ( hStereoTCA->lMemRecalc * INT_FS_12k8 ) / input_Fs );
1261 890 : hStereoTCA->lMemRecalc_16k = (int16_t) ( ( hStereoTCA->lMemRecalc * INT_FS_16k ) / input_Fs );
1262 :
1263 890 : hStereoTCA->refChanIndx = L_CH_INDX;
1264 890 : hStereoTCA->prevRefChanIndx = L_CH_INDX;
1265 :
1266 890 : hStereoTCA->targetGain = 1.0f;
1267 890 : hStereoTCA->prevTargetGain = 1.0f;
1268 890 : hStereoTCA->instTargetGain = 1.0f;
1269 890 : hStereoTCA->corrStatsSmoothFac = 0.7f;
1270 :
1271 890 : set_s( hStereoTCA->corrLagStats, 0, 3 );
1272 890 : set_s( hStereoTCA->prevCorrLagStats, 0, 3 );
1273 :
1274 890 : set_f( hStereoTCA->memChanL, 0.0f, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH );
1275 890 : set_f( hStereoTCA->memChanR, 0.0f, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH );
1276 890 : set_f( hStereoTCA->memChanL_DS, 0.0f, ADDED_MEM_DS );
1277 890 : set_f( hStereoTCA->memChanR_DS, 0.0f, ADDED_MEM_DS );
1278 890 : hStereoTCA->mem_tempF = 0.;
1279 890 : set_f( hStereoTCA->corrEstPrev[0], 0.0f, 2 * L_NCSHIFT_DS + 1 );
1280 890 : set_f( hStereoTCA->corrEstPrev[1], 0.0f, 2 * L_NCSHIFT_DS + 1 );
1281 890 : set_f( hStereoTCA->corrEstPrev[2], 0.0f, 2 * L_NCSHIFT_DS + 1 );
1282 :
1283 890 : set_f( hStereoTCA->corrEstLT, 0.0f, 2 * L_NCSHIFT_DS + 1 );
1284 890 : set_f( hStereoTCA->memdecim, 0.0f, 12 );
1285 890 : hStereoTCA->ica_envVarLT = 2000.0f;
1286 :
1287 890 : set_f( hStereoTCA->C_mem, 0.0f, 2 * L_NCSHIFT_DS + 1 );
1288 890 : hStereoTCA->E1_mem = 0.0f;
1289 890 : hStereoTCA->E2_mem = 0.0f;
1290 890 : set_f( hStereoTCA->delay_0_mem, 0.0f, MAX_DELAYREGLEN );
1291 890 : hStereoTCA->smooth_dist_reg_prv_corr = 1.0f;
1292 890 : hStereoTCA->LRTD_G_ATT_cnt = 1;
1293 :
1294 890 : return;
1295 : }
1296 :
1297 :
1298 : /*-------------------------------------------------------------------*
1299 : * Function unclr_calc_corr_features()
1300 : *
1301 : *-------------------------------------------------------------------*/
1302 :
1303 3791 : static void unclr_calc_corr_features(
1304 : STEREO_CLASSIF_HANDLE hStereoClassif, /* i/o: stereo classifier handle */
1305 : STEREO_TCA_ENC_HANDLE hStereoTCA, /* i/o: ICA Stereo Encoder handle */
1306 : const float buf1[], /* i : left channel */
1307 : const float buf2[], /* i : right channel */
1308 : const int16_t length, /* i : length of input signal buffers */
1309 : const float corrEst[], /* i : buffer containing inter-channel correlation values */
1310 : const int16_t lagSearchRange[], /* i : minimum and maximum lags for corrEst[] */
1311 : float *corrEst_ncorr /* o : norm. x-correlation btw. current and previous correlation buffers */
1312 : )
1313 : {
1314 : int16_t i, corrLagMax, d_corrLagMax, tempLen;
1315 : float num, den;
1316 : float corrL, corrR, ener, ener_side, mono_i, side_i, ic_Lm, ic_Rm, tdm_es_em, m_corrL_corrR, d_corrL_corrR;
1317 : float prod_i, sum_prod, corrEstMax;
1318 :
1319 3791 : corrL = 1.0f;
1320 3791 : corrR = 1.0f;
1321 3791 : ener = 1.0f;
1322 3791 : ener_side = 1.0f;
1323 3791 : sum_prod = 0.0f;
1324 :
1325 610351 : for ( i = 0; i < length; i++ )
1326 : {
1327 606560 : mono_i = ( buf1[i] + buf2[i] ) / 2.0f;
1328 606560 : corrL += buf1[i] * mono_i;
1329 606560 : corrR += buf2[i] * mono_i;
1330 606560 : ener += mono_i * mono_i;
1331 606560 : side_i = ( buf1[i] - buf2[i] ) / 2.0f;
1332 606560 : ener_side += side_i * side_i;
1333 606560 : prod_i = buf1[i] * buf2[i];
1334 606560 : sum_prod += prod_i;
1335 : }
1336 :
1337 : /* average energy of L and R channels */
1338 3791 : hStereoClassif->ave_ener_L = hStereoTCA->E1_mem / length;
1339 3791 : hStereoClassif->ave_ener_R = hStereoTCA->E2_mem / length;
1340 :
1341 : /* unnormalized L/R correlation */
1342 3791 : sum_prod = log10f( fabsf( sum_prod ) + 1.0f );
1343 3791 : hStereoClassif->unclr_fv[E_sum_prod] = sum_prod;
1344 3791 : hStereoClassif->xtalk_fv[E_sum_prod] = sum_prod;
1345 :
1346 : /* S/M energy ratio */
1347 3791 : tdm_es_em = fabsf( 10.0f * ( log10f( sqrtf( ener_side / L_FRAME_DS ) ) - log10f( sqrtf( ener / L_FRAME_DS ) ) ) );
1348 3791 : hStereoClassif->unclr_fv[E_tdm_es_em] = tdm_es_em;
1349 3791 : hStereoClassif->xtalk_fv[E_tdm_es_em] = tdm_es_em;
1350 :
1351 : /* L/R correlation values (zero lag, maximum) */
1352 3791 : corrLagMax = maximum( corrEst, ( lagSearchRange[1] - lagSearchRange[0] + 1 ), &corrEstMax );
1353 3791 : d_corrLagMax = corrLagMax - hStereoClassif->unclr_corrLagMax_prev;
1354 3791 : hStereoClassif->unclr_fv[E_d_corrLagMax] = (float) d_corrLagMax;
1355 3791 : hStereoClassif->unclr_corrLagMax_prev = corrLagMax;
1356 3791 : hStereoClassif->xtalk_fv[E_d_corrLagMax] = (float) d_corrLagMax;
1357 :
1358 3791 : if ( corrEstMax < 0 )
1359 : {
1360 0 : corrEstMax = 0;
1361 : }
1362 :
1363 3791 : hStereoClassif->unclr_fv[E_corrEst0] = corrEst[abs( lagSearchRange[0] )];
1364 3791 : hStereoClassif->unclr_fv[E_corrEstMax] = corrEstMax;
1365 3791 : hStereoClassif->unclr_fv[E_corrLagMax] = corrLagMax;
1366 3791 : hStereoClassif->xtalk_fv[E_corrEst0] = corrEst[abs( lagSearchRange[0] )];
1367 3791 : hStereoClassif->xtalk_fv[E_corrEstMax] = corrEstMax;
1368 3791 : hStereoClassif->xtalk_fv[E_corrLagMax] = corrLagMax;
1369 :
1370 : /* L/M and R/M correlation */
1371 3791 : if ( corrL < 0 )
1372 : {
1373 97 : corrL = 0;
1374 : }
1375 :
1376 3791 : if ( corrR < 0 )
1377 : {
1378 57 : corrR = 0;
1379 : }
1380 :
1381 3791 : ic_Lm = corrL / ener;
1382 3791 : ic_Rm = corrR / ener;
1383 3791 : m_corrL_corrR = max( fabsf( ic_Lm ), fabsf( ic_Rm ) ) - min( fabsf( ic_Lm ), fabsf( ic_Rm ) );
1384 3791 : d_corrL_corrR = log10f( fabsf( corrL - corrR ) + 1.0f );
1385 :
1386 3791 : hStereoClassif->unclr_fv[E_m_corrL_corrR] = m_corrL_corrR;
1387 3791 : hStereoClassif->unclr_fv[E_d_corrL_corrR] = d_corrL_corrR;
1388 3791 : hStereoClassif->xtalk_fv[E_m_corrL_corrR] = m_corrL_corrR;
1389 :
1390 : /* norm. x-correlation btw. current and previous correlation buffers */
1391 3791 : tempLen = ( 2 * L_NCSHIFT_DS + 1 );
1392 3791 : num = dotp( corrEst, hStereoTCA->corrEstPrev[2], tempLen );
1393 3791 : den = sqrtf( sum2_f( corrEst, tempLen ) * sum2_f( hStereoTCA->corrEstPrev[2], tempLen ) );
1394 :
1395 3791 : *corrEst_ncorr = ( den == 0 ) ? 0.0f : ( num / den );
1396 3791 : hStereoClassif->unclr_fv[E_corrEst_ncorr] = *corrEst_ncorr;
1397 3791 : hStereoClassif->xtalk_fv[E_corrEst_ncorr] = *corrEst_ncorr;
1398 :
1399 3791 : return;
1400 : }
|