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 1404 : 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 1404 : if ( hStereoTCA->refChanIndx == L_CH_INDX )
96 : {
97 386 : ref = ptrChanL;
98 386 : target = ptrChanR;
99 : }
100 : else
101 : {
102 1018 : ref = ptrChanR;
103 1018 : target = ptrChanL;
104 : }
105 :
106 1404 : tempS = NS2SA( input_frame * FRAMES_PER_SEC, L_SAMPLES_LA_NS );
107 1404 : tempF1 = 0.0f;
108 1404 : tempF2 = 0.0f;
109 1240075 : for ( i = 0; i < ( input_frame - currentNCShift ); i++ )
110 : {
111 1238671 : tempF1 += fabsf( ref[i] );
112 1238671 : tempF2 += fabsf( target[i + currentNCShift] );
113 : }
114 1404 : gAdj = ( tempF1 == 0 ) ? 1.0f : tempF2 / max( tempF1, 0.00001f );
115 :
116 1404 : tempF1 = EVS_PI / ( 2.0f * (float) tempS );
117 41624 : for ( i = 0; i < tempS; i++ )
118 : {
119 40220 : win[i] = sinf( tempF1 * ( 0.5f + (float) i ) );
120 : }
121 :
122 1404 : j = 0;
123 41624 : for ( i = ( input_frame - currentNCShift - tempS ); i < input_frame - currentNCShift; i++, j++ )
124 : {
125 40220 : target[i + currentNCShift] = ( win[j] * gAdj ) * ref[i] + ( 1.0f - win[j] ) * target[i + currentNCShift];
126 : }
127 49773 : for ( ; i < input_frame; i++, j++ )
128 : {
129 48369 : target[i + currentNCShift] = gAdj * ref[i];
130 : }
131 :
132 1404 : 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 60368 : 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 60368 : y1 = mem[0];
153 60368 : y2 = mem[1];
154 60368 : x0 = mem[2];
155 60368 : 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 60368 : if ( coeff_set == 0 )
164 : {
165 57264 : a1 = 0.747789178258504f;
166 57264 : a2 = -0.272214937925007f;
167 57264 : b0 = 0.505001029045878f;
168 57264 : b1 = -1.01000205809176f;
169 57264 : b2 = 0.505001029045878f;
170 : }
171 : else
172 : {
173 3104 : a1 = -0.13456126833218354f;
174 3104 : a2 = -0.38813694706072926f;
175 3104 : b0 = 1.0f;
176 3104 : b1 = -1.9980666374183167f;
177 3104 : b2 = 1.0f;
178 : }
179 :
180 12131408 : for ( i = 0; i < lg; i++ )
181 : {
182 12071040 : x2 = x1;
183 12071040 : x1 = x0;
184 12071040 : x0 = signal[i];
185 12071040 : y0 = ( y1 * a1 ) + ( y2 * a2 ) + ( x0 * b0 ) + ( x1 * b1 ) + ( x2 * b2 );
186 12071040 : signal[i] = y0;
187 12071040 : y2 = y1;
188 12071040 : y1 = y0;
189 : }
190 :
191 60368 : mem[0] = ( ( y1 > 1e-10 ) | ( y1 < -1e-10 ) ) ? y1 : 0;
192 60368 : mem[1] = ( ( y2 > 1e-10 ) | ( y2 < -1e-10 ) ) ? y2 : 0;
193 60368 : mem[2] = ( ( x0 > 1e-10 ) | ( x0 < -1e-10 ) ) ? x0 : 0;
194 60368 : mem[3] = ( ( x1 > 1e-10 ) | ( x1 < -1e-10 ) ) ? x1 : 0;
195 :
196 60368 : return;
197 : }
198 :
199 :
200 : /*---------------------------------------------------------------
201 : * deEmphResample()
202 : *
203 : * De-emphasize and resample the L and R channels.
204 : * ---------------------------------------------------------------*/
205 :
206 28632 : 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 28632 : dsFac1 = ( dsFactor >> 1 );
222 28632 : dsFac2 = dsFactor / dsFac1;
223 :
224 : /* convert stereo data to two distinct channels, e.g., L, R */
225 28632 : mvr2r( tempChan1, buf1, input_frame );
226 28632 : mvr2r( tempChan2, buf2, input_frame );
227 :
228 : /* De-emphasis, 1/(1-mu z^-1), and resample, stage 1 */
229 28632 : deemph( buf1, PREEMPH_FAC_16k, input_frame, &hStereoTCA->memdecim[0] );
230 28632 : deemph( buf2, PREEMPH_FAC_16k, input_frame, &hStereoTCA->memdecim[1] );
231 :
232 9190872 : for ( i = 0; i < ( input_frame / dsFac1 ); i++ )
233 : {
234 9162240 : tempBuf1[i] = buf1[i * dsFac1];
235 9162240 : tempBuf2[i] = buf2[i * dsFac1];
236 : }
237 :
238 : /* De-emphasis, 1/(1-mu z^-1), and resample, stage 2 */
239 28632 : deemph( tempBuf1, PREEMPH_FAC_16k, ( input_frame / dsFac1 ), &hStereoTCA->memdecim[2] );
240 28632 : deemph( tempBuf2, PREEMPH_FAC_16k, ( input_frame / dsFac1 ), &hStereoTCA->memdecim[3] );
241 :
242 4609752 : for ( i = 0; i < ( input_frame / dsFactor ); i++ )
243 : {
244 4581120 : chan1[i] = tempBuf1[i * dsFac2];
245 4581120 : chan2[i] = tempBuf2[i * dsFac2];
246 : }
247 :
248 28632 : spectral_balancer( chan1, &hStereoTCA->memdecim[4], input_frame / dsFactor, 0 ); /*4 mem */
249 28632 : spectral_balancer( chan2, &hStereoTCA->memdecim[8], input_frame / dsFactor, 0 ); /*4 mem */
250 :
251 28632 : 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 28632 : 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 28632 : E1 = sum2_f( buf1, len );
274 28632 : E2 = sum2_f( buf2, len );
275 :
276 28632 : Inv_Tot_E = 1.0f / ( ( 2.0f * (float) len ) * sqrtf( ( E1 + hStereoTCA->E1_mem ) * ( E2 + hStereoTCA->E2_mem ) + 0.000000001f ) );
277 :
278 28632 : hStereoTCA->E1_mem = E1;
279 28632 : hStereoTCA->E2_mem = E2;
280 :
281 1202544 : for ( i = lagSearchRange[0], j = 0; i <= 0; i++, j++ )
282 : {
283 1173912 : C = dotp( buf1, buf2 + i, len );
284 1173912 : corrEst[j] = ( C + hStereoTCA->C_mem[j] ) * Inv_Tot_E;
285 1173912 : hStereoTCA->C_mem[j] = C;
286 : }
287 :
288 1173912 : for ( ; i <= lagSearchRange[1]; i++, j++ )
289 : {
290 1145280 : C = dotp( buf1 - i, buf2, len );
291 1145280 : corrEst[j] = ( C + hStereoTCA->C_mem[j] ) * Inv_Tot_E;
292 1145280 : hStereoTCA->C_mem[j] = C;
293 : }
294 :
295 28632 : 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 2070 : 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 2070 : 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 2070 : mvr2r( buf1, tempBuf1, len );
343 2070 : mvr2r( buf2, tempBuf2, len );
344 : }
345 :
346 2070 : temp = sum2_f( tempBuf1, len );
347 2070 : temp *= sum2_f( tempBuf2, len );
348 2070 : scale = ( temp == 0 ) ? 1.0f : inv_sqrt( temp );
349 :
350 : /* starting point of lag search range should be less than the ending point */
351 2070 : assert( lagSearchRange[0] <= lagSearchRange[1] );
352 :
353 : /* first part of noncausal corr est. */
354 5258 : for ( i = lagSearchRange[0], j = 0; i <= min( 0, lagSearchRange[1] ); i++, j++ )
355 : {
356 3188 : temp = dotp( tempBuf1 - i, tempBuf2, ( len + i ) );
357 3188 : corrEst[j] = temp / ( len + i );
358 : }
359 :
360 : /* second part of noncausal corr est. */
361 3919 : for ( ; i <= lagSearchRange[1]; i++, j++ )
362 : {
363 1849 : temp = dotp( tempBuf1, tempBuf2 + i, ( len - i ) );
364 1849 : corrEst[j] = temp / ( len - i );
365 : }
366 2070 : v_multc( corrEst, scale, corrEst, j );
367 :
368 2070 : return;
369 : }
370 :
371 : /*---------------------------------------------------------------
372 : * corrStatsEst()
373 : *
374 : * Non-causal shift estimation to encode future samples.
375 : * ---------------------------------------------------------------*/
376 :
377 28632 : 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 28632 : X_hat = 0;
408 28632 : X_SQR_hat = 0;
409 28632 : XY_hat = 0;
410 :
411 : /* Initializations */
412 28632 : alpha = 0.7f;
413 28632 : lagSearchRange[0] = -L_NCSHIFT_DS;
414 28632 : lagSearchRange[1] = L_NCSHIFT_DS;
415 28632 : tempLen = ( 2 * L_NCSHIFT_DS + 1 );
416 :
417 28632 : set_s( corrLagStats, 0, 3 );
418 :
419 : /* First iteration of xcorr estimation */
420 28632 : utilCrossCorr_mod( hStereoTCA, buf1, buf2, corrEst, lagSearchRange, bufLenDS - L_XCORRMEM_DS );
421 :
422 : /* calculate features for the UNCLR classifier */
423 28632 : unclr_calc_corr_features( hStereoClassif, hStereoTCA, buf1, buf2, bufLenDS - L_XCORRMEM_DS, corrEst, lagSearchRange, &corrEst_ncorr );
424 :
425 85896 : for ( i = 1; i < 3; i++ )
426 : {
427 57264 : v_add( hStereoTCA->corrEstPrev[i], hStereoTCA->corrEstPrev[0], hStereoTCA->corrEstPrev[0], tempLen );
428 : }
429 :
430 : /* back up the corrEst */
431 85896 : for ( i = 0; i < 2; i++ )
432 : {
433 57264 : mvr2r( hStereoTCA->corrEstPrev[i + 1], hStereoTCA->corrEstPrev[i], tempLen );
434 : }
435 28632 : mvr2r( corrEst, hStereoTCA->corrEstPrev[2], tempLen );
436 :
437 28632 : temp_A = sumAbs( buf1, L_FRAME_DS - L_XCORRMEM_DS ) + sumAbs( buf2, L_FRAME_DS - L_XCORRMEM_DS );
438 28632 : 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 28632 : tempF = temp_A + temp_B + hStereoTCA->mem_tempF;
440 28632 : hStereoTCA->mem_tempF = temp_B;
441 :
442 28632 : alpha = 0.93f;
443 28632 : if ( tempF > 4.0f * hStereoTCA->ica_envVarLT )
444 : {
445 1465 : alpha = 0.83f;
446 : }
447 27167 : else if ( tempF > 2.0f * hStereoTCA->ica_envVarLT )
448 : {
449 2491 : alpha = 0.85f;
450 : }
451 24676 : else if ( tempF > hStereoTCA->ica_envVarLT )
452 : {
453 8044 : alpha = 0.90f;
454 : }
455 :
456 28632 : hStereoTCA->corrStatsSmoothFac = alpha;
457 :
458 : /* long term corr Stats estimation */
459 28632 : v_multc( hStereoTCA->corrEstLT, alpha, hStereoTCA->corrEstLT, 2 * L_NCSHIFT_DS + 1 );
460 28632 : v_multc( corrEst, 1.0f - alpha, corrEst, 2 * L_NCSHIFT_DS + 1 );
461 28632 : v_add( hStereoTCA->corrEstLT, corrEst, hStereoTCA->corrEstLT, 2 * L_NCSHIFT_DS + 1 );
462 :
463 28632 : hStereoTCA->ica_envVarLT = SMOOTH_ENV_FACTOR * hStereoTCA->ica_envVarLT + ( 1 - SMOOTH_ENV_FACTOR ) * tempF;
464 :
465 28632 : mvr2r( hStereoTCA->corrEstLT, corrEst, 2 * L_NCSHIFT_DS + 1 );
466 28632 : 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 343584 : for ( i = 1; i < MAX_DELAYREGLEN; i++ )
469 : {
470 314952 : X_hat += (float) i;
471 314952 : Y_hat += hStereoTCA->delay_0_mem[i];
472 314952 : XY_hat += i * hStereoTCA->delay_0_mem[i];
473 314952 : X_SQR_hat += (float) ( i * i );
474 : }
475 28632 : X_hat *= INV_MAX_DELAYREGLEN;
476 28632 : Y_hat *= INV_MAX_DELAYREGLEN;
477 28632 : XY_hat *= INV_MAX_DELAYREGLEN;
478 28632 : X_SQR_hat *= INV_MAX_DELAYREGLEN;
479 :
480 28632 : beta_reg = 0;
481 28632 : tempF = X_SQR_hat - ( X_hat * X_hat );
482 28632 : if ( tempF != 0 )
483 : {
484 28632 : beta_reg = ( XY_hat - X_hat * Y_hat ) / tempF;
485 : }
486 28632 : alpha_reg = ( Y_hat - beta_reg * X_hat );
487 28632 : reg_prv_corr = beta_reg * MAX_DELAYREGLEN + alpha_reg;
488 :
489 28632 : if ( TRUNC( reg_prv_corr ) <= -L_NCSHIFT_DS )
490 : {
491 249 : reg_prv_corr = -L_NCSHIFT_DS + 1;
492 : }
493 :
494 28632 : if ( TRUNC( reg_prv_corr ) >= L_NCSHIFT_DS )
495 : {
496 243 : reg_prv_corr = L_NCSHIFT_DS - 1;
497 : }
498 :
499 28632 : bias_par = A_BIAS * hStereoTCA->smooth_dist_reg_prv_corr + B_BIAS;
500 28632 : bias_par = min( bias_par, XH_BIAS );
501 28632 : bias_par = max( bias_par, XL_BIAS );
502 :
503 28632 : width_par = A_WIDTH * hStereoTCA->smooth_dist_reg_prv_corr + B_WIDTH;
504 28632 : width_par = min( width_par, XH_WIDTH );
505 28632 : width_par = max( width_par, XL_WIDTH );
506 :
507 28632 : win_width = (int16_t) ( width_par * ( 4 * L_NCSHIFT_DS + 1 ) );
508 28632 : win_bias = bias_par;
509 28632 : k1 = 0.5f * ( 1.0f + win_bias );
510 28632 : k2 = 0.5f * ( 1.0f - win_bias );
511 :
512 1216362 : for ( i = 0; i < ( 2 * L_NCSHIFT_DS - 2 * win_width ); i++ )
513 : {
514 1187730 : loc_weight_win[i] = win_bias;
515 : }
516 :
517 2262924 : for ( i = ( 2 * L_NCSHIFT_DS - 2 * win_width ); i <= ( 2 * L_NCSHIFT_DS + 2 * win_width ); i++ )
518 : {
519 2234292 : loc_weight_win[i] = k1 + k2 * cosf( EVS_PI * ( ( i - 2 * L_NCSHIFT_DS ) / ( 2.0f * win_width ) ) );
520 : }
521 :
522 1244994 : for ( i = ( 2 * L_NCSHIFT_DS + 2 * win_width ); i < ( 4 * L_NCSHIFT_DS + 1 ); i++ )
523 : {
524 1216362 : loc_weight_win[i] = win_bias;
525 : }
526 :
527 2347824 : for ( i = 0, j = L_NCSHIFT_DS - TRUNC( reg_prv_corr ); i < 2 * L_NCSHIFT_DS + 1; i++, j++ )
528 : {
529 2319192 : corrEst[i] *= loc_weight_win[j];
530 : }
531 :
532 28632 : if ( hStereoTCA->prevTargetGain < 0.8f && vad_flag1 )
533 : {
534 : /* ch 2 is prev reference channel */
535 46 : v_multc( corrEst, 1.2f, corrEst, L_NCSHIFT_DS + 1 );
536 46 : v_multc( corrEst + L_NCSHIFT_DS + 1, 0.833f, corrEst + L_NCSHIFT_DS + 1, L_NCSHIFT_DS );
537 : }
538 28586 : else if ( hStereoTCA->prevTargetGain > 1.2f && vad_flag1 )
539 : {
540 : /* ch 1 is prev reference channel */
541 4 : v_multc( corrEst, 0.833f, corrEst, L_NCSHIFT_DS );
542 4 : v_multc( corrEst + L_NCSHIFT_DS, 1.2f, corrEst + L_NCSHIFT_DS, L_NCSHIFT_DS + 1 );
543 : }
544 :
545 28632 : if ( corrEst_ncorr > 0.8f && vad_flag1 )
546 : {
547 8601 : i = max( 0, hStereoTCA->prevCorrLagStats[0] - 1 + L_NCSHIFT_DS );
548 8601 : j = min( 2 * L_NCSHIFT_DS, hStereoTCA->prevCorrLagStats[0] + 1 + L_NCSHIFT_DS );
549 8601 : k = j - i + 1;
550 8601 : v_multc( corrEst + i, 1.2f, corrEst + i, k );
551 : }
552 :
553 : /* Initial corr lag estimate */
554 28632 : corrLagStats[0] = maximum( corrEst, ( lagSearchRange[1] - lagSearchRange[0] + 1 ), &tempF );
555 28632 : corrLagStats[0] += lagSearchRange[0];
556 :
557 28632 : stmp = corrLagStats[0] * dsFactor;
558 28632 : hStereoClassif->unclr_fv[E_corrLagStats0] = (float) stmp;
559 28632 : hStereoClassif->xtalk_fv[E_corrLagStats0] = (float) stmp;
560 28632 : hStereoClassif->xtalk_fv[E_ica_corr_value0] = tempF;
561 :
562 28632 : if ( vad_flag1 == 0 && alpha > 0.7f )
563 : {
564 1644 : corrLagStats[0] = 0;
565 : }
566 :
567 28632 : dist_reg_prv_corr = fabsf( reg_prv_corr - corrLagStats[0] );
568 :
569 28632 : if ( vad_flag1 == 1 && vad_flag2 == 1 )
570 : {
571 21575 : 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 21575 : mvr2r( &( hStereoTCA->delay_0_mem[1] ), &( hStereoTCA->delay_0_mem[0] ), MAX_DELAYREGLEN - 1 );
574 :
575 21575 : hStereoTCA->delay_0_mem[MAX_DELAYREGLEN - 1] = 0.2f * hStereoTCA->delay_0_mem[MAX_DELAYREGLEN - 1] + 0.8f * corrLagStats[0];
576 :
577 21575 : if ( fabsf( reg_prv_corr - hStereoTCA->delay_0_mem[0] ) > 25 )
578 : {
579 222 : set_f( &( hStereoTCA->delay_0_mem[0] ), hStereoTCA->delay_0_mem[MAX_DELAYREGLEN - 1], MAX_DELAYREGLEN - 1 );
580 : }
581 : }
582 : else
583 : {
584 7057 : hStereoTCA->smooth_dist_reg_prv_corr = 0.;
585 : }
586 :
587 28632 : if ( vad_flag1 == 0 || vad_flag2 == 0 )
588 : {
589 7057 : corrLagStats[0] = TRUNC( hStereoTCA->delay_0_mem[MAX_DELAYREGLEN - 1] );
590 : }
591 :
592 : /* second iteration of xcorr update @ inputFs with interp*/
593 28632 : tempRK = hStereoTCA->corrEstLT - lagSearchRange[0] + corrLagStats[0];
594 28632 : set_f( rInterp, 0, MAX_INTERPOLATE );
595 :
596 : /* select the Rk interp sinc window */
597 28632 : winInterp = ica_sincInterp4 + SINC_ORDER1;
598 28632 : if ( dsFactor == 2 )
599 : {
600 2116 : winInterp = ica_sincInterp2 + SINC_ORDER1;
601 : }
602 26516 : else if ( dsFactor == 6 )
603 : {
604 19420 : winInterp = ica_sincInterp6 + SINC_ORDER1;
605 : }
606 :
607 28632 : corrLagStats[1] = corrLagStats[0] * dsFactor;
608 :
609 28632 : interpMin = max( -( dsFactor - 1 ), -corrLagStats[1] - L_NCSHIFT_DS * dsFactor );
610 28632 : interpMax = min( ( dsFactor - 1 ), L_NCSHIFT_DS * dsFactor - corrLagStats[1] );
611 28632 : interpLen = interpMax - interpMin + 1;
612 :
613 290021 : for ( i = interpMin, k = 0; i <= interpMax; i++, k++ )
614 : {
615 261389 : rInterp[k] = 0.0f;
616 2893026 : for ( j = -SINC_ORDER1 / dsFactor; j <= SINC_ORDER1 / dsFactor; j++ )
617 : {
618 2631637 : m = j * dsFactor;
619 2631637 : if ( ( m - i >= -SINC_ORDER1 ) && ( m - i <= SINC_ORDER1 ) )
620 : {
621 2398880 : if ( j > lagSearchRange[1] - corrLagStats[0] )
622 : {
623 7591 : rInterp[k] += winInterp[m - i] * tempRK[lagSearchRange[1] - corrLagStats[0]];
624 : }
625 2391289 : else if ( j < lagSearchRange[0] - corrLagStats[0] )
626 : {
627 75760 : rInterp[k] += winInterp[m - i] * tempRK[lagSearchRange[0] - corrLagStats[0]];
628 : }
629 : else
630 : {
631 2315529 : rInterp[k] += winInterp[m - i] * tempRK[j];
632 : }
633 : }
634 : }
635 : }
636 28632 : corrLagStats[1] += ( maximum( rInterp, interpLen, &tempF ) + interpMin );
637 :
638 : /* save corr lag stats for the current frame */
639 28632 : mvs2s( corrLagStats, hStereoTCA->corrLagStats, 3 );
640 :
641 28632 : return;
642 : }
643 :
644 :
645 : /*---------------------------------------------------------------
646 : * Function estDownmixGain()
647 : *
648 : * Down mix gain estimation module; convert L/R to M/S.
649 : * ---------------------------------------------------------------*/
650 :
651 830116 : 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 830116 : if ( hStereoTCA->refChanIndx == L_CH_INDX )
668 : {
669 829098 : i1 = 0;
670 829098 : i2 = ncShift;
671 : }
672 : else
673 : {
674 1018 : i1 = ncShift;
675 1018 : i2 = 0;
676 : }
677 :
678 : /* abs sample sum estimation */
679 830116 : tempN = 0;
680 830116 : tempD = 0;
681 605524147 : for ( i = 0, tempN = 0.0f, tempD = 0.0f; i < length; i++ )
682 : {
683 604694031 : tempN += fabsf( chan1[i1 + i] );
684 604694031 : tempD += fabsf( chan2[i2 + i] );
685 : }
686 :
687 830116 : alpha = hStereoTCA->corrStatsSmoothFac;
688 830116 : currentGain = ( tempD == 0 ) ? ( hStereoTCA->prevTargetGain ) : ( tempN / tempD );
689 830116 : currentGain = max( 1e-5f, currentGain );
690 830116 : hStereoTCA->instTargetGain = currentGain;
691 830116 : currentGain = (alpha) *log10f( hStereoTCA->prevTargetGain ) + ( 1.0f - alpha ) * log10f( currentGain );
692 :
693 830116 : if ( element_mode == IVAS_CPE_TD && hStereoClassif != NULL )
694 : {
695 28632 : tempD = powf( 10, currentGain );
696 28632 : unclr_instTargetGain = log10f( tempN / ( tempD + 1e-5f ) + 1.0f );
697 28632 : hStereoClassif->unclr_fv[E_ica_instTargetGain] = unclr_instTargetGain;
698 : }
699 :
700 830116 : if ( tdm_LRTD_flag == 1 )
701 : {
702 26464 : currentGain = 0.0f;
703 : }
704 803652 : else if ( hStereoTCA->LRTD_G_ATT_cnt > 1 ) /* lrtd_mode == 1 but tdm_LRTD_flag still 0 */
705 : {
706 2379 : currentGain /= ( (float) hStereoTCA->LRTD_G_ATT_cnt );
707 : }
708 :
709 : /* quantize the target gain */
710 830116 : hStereoTCA->indx_ica_gD = (int16_t) usquant( currentGain, &tempD, STEREO_TCA_GDMIN, STEREO_TCA_GDSTEP, 1 << STEREO_BITS_TCA_GD );
711 830116 : hStereoTCA->targetGain = powf( 10, tempD );
712 :
713 830116 : return;
714 : }
715 :
716 : /*---------------------------------------------------------------
717 : * Function icaMemUpdate()
718 : *
719 : * Recalculates the memories corresponding to the previous frame.
720 : * ---------------------------------------------------------------*/
721 :
722 28632 : 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 28632 : 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 28632 : if ( hCPE->hStereoTD->tdm_last_SM_flag )
744 : {
745 24 : ratio_L = hCPE->hStereoTD->tdm_last_ratio_SM;
746 24 : One_m_Ratio = ratio_L - 1.0f;
747 : }
748 : else
749 : {
750 28608 : ratio_L = hCPE->hStereoTD->tdm_last_ratio;
751 28608 : One_m_Ratio = 1.0f - ratio_L;
752 : }
753 :
754 28632 : ptr1 = sts[0]->input - lMemRecalc - lMemRecalc_SCh;
755 28632 : ptr2 = sts[1]->input - lMemRecalc - lMemRecalc_SCh;
756 :
757 28632 : if ( hCPE->last_element_mode == IVAS_CPE_TD )
758 : {
759 28051 : if ( hCPE->hStereoTD->flag_skip_DMX )
760 : {
761 174147 : for ( i = lMemRecalc_SCh; i < lMemRecalc + lMemRecalc_SCh; i++ )
762 : {
763 173640 : ptr1[i] = bufChanL[i];
764 173640 : ptr2[i] = bufChanR[i];
765 : }
766 : }
767 : else
768 : {
769 8615464 : for ( i = lMemRecalc_SCh; i < lMemRecalc + lMemRecalc_SCh; i++ )
770 : {
771 8587920 : ptr1[i] = bufChanR[i] * One_m_Ratio + bufChanL[i] * ratio_L;
772 8587920 : 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 581 : set_f( sts[1]->input - input_frame, 0, input_frame );
782 :
783 581 : if ( hCPE->hStereoTD->flag_skip_DMX )
784 : {
785 : /* reconstruction of the Secondary channel past segment */
786 20361 : for ( i = 0; i < lMemRecalc_SCh; i++ )
787 : {
788 20160 : 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 201 : fac = 1.0f / (float) lMemRecalc;
793 201 : incr = fac;
794 :
795 69321 : for ( i = lMemRecalc_SCh; i < lMemRecalc + lMemRecalc_SCh; i++ )
796 : {
797 69120 : tmp1 = bufChanL[i];
798 69120 : tmp2 = bufChanR[i];
799 :
800 69120 : 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 69120 : ptr2[i] = tmp2;
803 :
804 69120 : fac += incr;
805 : }
806 : }
807 : else
808 : {
809 : /* reconstruction of the Secondary channel past segment */
810 34645 : for ( i = 0; i < lMemRecalc_SCh; i++ )
811 : {
812 34265 : 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 380 : fac = 1.0f / (float) lMemRecalc;
817 380 : incr = fac;
818 :
819 117860 : for ( i = lMemRecalc_SCh; i < lMemRecalc + lMemRecalc_SCh; i++ )
820 : {
821 117480 : tmp1 = bufChanR[i] * One_m_Ratio + bufChanL[i] * ratio_L;
822 117480 : tmp2 = bufChanL[i] * One_m_Ratio - bufChanR[i] * ratio_L;
823 :
824 117480 : 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 117480 : ptr2[i] = tmp2;
827 :
828 117480 : fac += incr;
829 : }
830 : }
831 : }
832 : }
833 :
834 28632 : if ( hCPE->hStereoICBWE != NULL )
835 : {
836 : assert( L_MEM_RECALC_TBE_NS <= L_MEM_RECALC_NS );
837 2168 : i = NS2SA( sts[0]->input_Fs, L_MEM_RECALC_TBE_NS );
838 2168 : mvr2r( bufChanL + lMemRecalc + lMemRecalc_SCh - i, hCPE->hStereoICBWE->icbwe_inp_mem[0], i );
839 2168 : mvr2r( bufChanR + lMemRecalc + lMemRecalc_SCh - i, hCPE->hStereoICBWE->icbwe_inp_mem[1], i );
840 : }
841 :
842 28632 : 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 6355819 : 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 6355819 : int16_t musicMode = 0, neighborLimit;
885 : int32_t input_Fs;
886 : int16_t prev_ICA_flag;
887 :
888 : /* initialization */
889 6355819 : sts = hCPE->hCoreCoder;
890 6355819 : hStereoTCA = hCPE->hStereoTCA;
891 :
892 6355819 : input_Fs = sts[0]->input_Fs;
893 :
894 6355819 : lMemRecalc = NS2SA( input_Fs, L_MEM_RECALC_NS );
895 6355819 : lMemRecalc_SCh = NS2SA( input_Fs, L_MEM_RECALC_SCH_NS );
896 :
897 6355819 : if ( hCPE->element_mode == IVAS_CPE_MDCT )
898 : {
899 5525703 : return;
900 : }
901 :
902 : /* populate L/R memories into current buffers */
903 830116 : mvr2r( hStereoTCA->memChanL, bufChanL, lMemRecalc + lMemRecalc_SCh );
904 830116 : mvr2r( hStereoTCA->memChanR, bufChanR, lMemRecalc + lMemRecalc_SCh );
905 :
906 : /* pointers to the current frame */
907 830116 : ptrChanL = bufChanL + lMemRecalc + lMemRecalc_SCh;
908 830116 : ptrChanR = bufChanR + lMemRecalc + lMemRecalc_SCh;
909 :
910 : /* copy interleaved stereo data to two channels, e.g., L, R */
911 830116 : mvr2r( sts[0]->input, ptrChanL, input_frame );
912 830116 : mvr2r( sts[1]->input, ptrChanR, input_frame );
913 :
914 : /* UNCLR classifier update */
915 830116 : if ( hCPE->hStereoClassif->lrtd_mode == 0 ) /* Normal TD mode, no attenuation */
916 : {
917 800690 : hStereoTCA->LRTD_G_ATT_cnt = 1;
918 : }
919 29426 : else if ( hCPE->hStereoTD != NULL )
920 : {
921 28632 : if ( hCPE->hStereoTD->tdm_LRTD_flag == 0 ) /* lrtd_mode == 1, but in td section */
922 : {
923 2168 : hStereoTCA->LRTD_G_ATT_cnt++;
924 2168 : hStereoTCA->LRTD_G_ATT_cnt = min( 1000, hStereoTCA->LRTD_G_ATT_cnt );
925 : }
926 : }
927 :
928 830116 : if ( hCPE->element_mode != IVAS_CPE_TD )
929 : {
930 801484 : hStereoTCA->refChanIndx = L_CH_INDX;
931 801484 : hStereoTCA->corrStatsSmoothFac = 0.7f;
932 801484 : estDownmixGain( hStereoTCA, ptrChanL, ptrChanR, 0, input_frame, hCPE->element_mode, NULL, 0 );
933 801484 : 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 801484 : mvr2r( bufChanL + input_frame, hStereoTCA->memChanL, lMemRecalc + lMemRecalc_SCh );
940 801484 : mvr2r( bufChanR + input_frame, hStereoTCA->memChanR, lMemRecalc + lMemRecalc_SCh );
941 :
942 801484 : hStereoTCA->lMemRecalc = 0;
943 801484 : hStereoTCA->lMemRecalc_12k8 = 0;
944 801484 : hStereoTCA->lMemRecalc_16k = 0;
945 :
946 801484 : return;
947 : }
948 28632 : else if ( hCPE->last_element_mode != IVAS_CPE_TD )
949 : {
950 581 : tempF = hStereoTCA->targetGain;
951 581 : tempF1 = hStereoTCA->prevTargetGain;
952 581 : tempS = hStereoTCA->prevRefChanIndx;
953 581 : mvs2s( hStereoTCA->prevCorrLagStats, tempS_buff, 3 );
954 581 : stereo_tca_init_enc( hStereoTCA, input_Fs );
955 581 : hStereoTCA->targetGain = tempF;
956 581 : hStereoTCA->prevTargetGain = tempF1;
957 :
958 581 : if ( hCPE->hStereoClassif->lrtd_mode == 1 )
959 : {
960 581 : hStereoTCA->targetGain = min( hStereoTCA->targetGain, 1.0f );
961 581 : hStereoTCA->prevTargetGain = min( hStereoTCA->prevTargetGain, 1.0f );
962 :
963 581 : hStereoTCA->prevTargetGain = 1;
964 : }
965 :
966 581 : hStereoTCA->prevRefChanIndx = tempS;
967 581 : mvs2s( tempS_buff, hStereoTCA->prevCorrLagStats, 3 );
968 :
969 : /* populate memory */
970 581 : if ( hCPE->last_element_mode == IVAS_CPE_MDCT )
971 : {
972 201 : mvr2r( sts[0]->input - lMemRecalc - lMemRecalc_SCh, bufChanL, lMemRecalc + lMemRecalc_SCh );
973 201 : mvr2r( sts[1]->input - lMemRecalc - lMemRecalc_SCh, bufChanR, lMemRecalc + lMemRecalc_SCh );
974 : }
975 : }
976 :
977 : /* populate L/R DS memories into current buffers */
978 28632 : mvr2r( hStereoTCA->memChanL_DS, bufChanL_DS, ADDED_MEM_DS );
979 28632 : mvr2r( hStereoTCA->memChanR_DS, bufChanR_DS, ADDED_MEM_DS );
980 :
981 : /* pointers to the current frame of DS */
982 28632 : ptrChanL_DS = bufChanL_DS + ADDED_MEM_DS;
983 28632 : ptrChanR_DS = bufChanR_DS + ADDED_MEM_DS;
984 :
985 : /* resample factor */
986 28632 : dsFactor = (int16_t) ( input_Fs / CORR_INTER_FS );
987 :
988 : /* resample the stereo channels */
989 28632 : deEmphResample( hStereoTCA, ptrChanL, ptrChanR, ptrChanL_DS, ptrChanR_DS, input_frame, dsFactor );
990 :
991 :
992 : /* inter-channel corrStats estimation */
993 28632 : 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 28632 : prev_ICA_flag = 0;
1000 28632 : if ( hCPE->hStereoTD->prev_fr_LRTD_TD_dec && abs( hStereoTCA->prevCorrLagStats[2] ) != 0 )
1001 : {
1002 332 : prev_ICA_flag = 1;
1003 : }
1004 :
1005 28632 : if ( hCPE->hStereoTD->prev_fr_LRTD_TD_dec == 0 || prev_ICA_flag == 1 )
1006 : {
1007 : /* initialize the refinement search for NC-shift */
1008 2880 : hStereoTCA->corrLagStats[2] = hStereoTCA->corrLagStats[1];
1009 :
1010 2880 : maxCorrStatsDev = N_MAX_SHIFT_CHANGE;
1011 2880 : if ( hStereoTCA->corrStatsSmoothFac <= 0.7f )
1012 : {
1013 0 : maxCorrStatsDev = 160; /* L_NCSHIFT_MAX @ 32kHz */
1014 : }
1015 :
1016 2880 : if ( input_Fs < 32000 )
1017 : {
1018 104 : maxCorrStatsDev = (int16_t) ( maxCorrStatsDev * input_Fs / 32000.0f );
1019 : }
1020 :
1021 2880 : musicMode = ( hCPE->hCoreCoder[0]->sp_aud_decision0 == 1 || sts[0]->last_core > ACELP_CORE );
1022 2880 : if ( musicMode )
1023 : {
1024 679 : maxCorrStatsDev = 1;
1025 679 : set_s( hStereoTCA->corrLagStats + 1, 0, 2 );
1026 : }
1027 :
1028 2880 : tempS = ( hStereoTCA->corrLagStats[1] - hStereoTCA->prevCorrLagStats[2] );
1029 2880 : if ( abs( tempS ) > maxCorrStatsDev )
1030 : {
1031 730 : hStereoTCA->corrLagStats[2] = hStereoTCA->prevCorrLagStats[2] + ( ( tempS > 0 ) ? maxCorrStatsDev : -maxCorrStatsDev );
1032 : }
1033 :
1034 2880 : neighborLimit = maxCorrStatsDev;
1035 :
1036 : /* refine and search based on the corrlag stats */
1037 2880 : if ( tempS != 0 && dsFactor != 1 && prev_ICA_flag == 0 )
1038 : {
1039 1319 : tempF = 0;
1040 1319 : if ( !musicMode )
1041 : {
1042 1158 : tempLag[0] = min( hStereoTCA->corrLagStats[2], hStereoTCA->prevCorrLagStats[2] );
1043 1158 : tempLag[1] = max( hStereoTCA->corrLagStats[2], hStereoTCA->prevCorrLagStats[2] );
1044 :
1045 1158 : neighborLimit = min( 3, maxCorrStatsDev );
1046 1158 : if ( hStereoTCA->prevCorrLagStats[2] < hStereoTCA->corrLagStats[2] )
1047 : {
1048 592 : tempLag[1] = min( tempLag[1], tempLag[0] + neighborLimit );
1049 : }
1050 : else
1051 : {
1052 566 : tempLag[0] = max( tempLag[0], tempLag[1] - neighborLimit );
1053 : }
1054 :
1055 1158 : utilCrossCorr( ptrChanL, ptrChanR, NULL, corrEstStage2, tempLag, input_frame, 0 );
1056 :
1057 1158 : hStereoTCA->corrLagStats[2] = maximum( corrEstStage2, ( tempLag[1] - tempLag[0] + 1 ), &tempF );
1058 1158 : hStereoTCA->corrLagStats[2] += tempLag[0];
1059 : }
1060 :
1061 1319 : if ( abs( tempS ) > neighborLimit )
1062 : {
1063 912 : tempLag[0] = hStereoTCA->corrLagStats[1];
1064 912 : tempLag[1] = hStereoTCA->corrLagStats[1];
1065 912 : utilCrossCorr( ptrChanL, ptrChanR, NULL, &tempF1, tempLag, input_frame, 0 );
1066 :
1067 912 : if ( tempF1 > tempF || musicMode )
1068 : {
1069 450 : 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 1319 : if ( ( hStereoTCA->corrLagStats[2] < 0 && hStereoTCA->prevCorrLagStats[2] > 0 ) || ( hStereoTCA->corrLagStats[2] > 0 && hStereoTCA->prevCorrLagStats[2] < 0 ) )
1075 : {
1076 5 : hStereoTCA->corrLagStats[2] = 0;
1077 : }
1078 : }
1079 :
1080 2880 : 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 332 : hStereoTCA->corrLagStats[2] = 0;
1083 :
1084 332 : 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 2880 : prevNCShift = (int16_t) abs( hStereoTCA->prevCorrLagStats[2] );
1095 2880 : currentNCShift = (int16_t) abs( hStereoTCA->corrLagStats[2] );
1096 :
1097 2880 : if ( hStereoTCA->prevRefChanIndx == L_CH_INDX )
1098 : {
1099 1852 : mvr2r( ptrChanL - lMemRecalc - lMemRecalc_SCh, input_mem_loc[0], lMemRecalc + lMemRecalc_SCh );
1100 1852 : v_multc( ptrChanR + prevNCShift - lMemRecalc - lMemRecalc_SCh, hStereoTCA->prevTargetGain, input_mem_loc[1], lMemRecalc + lMemRecalc_SCh );
1101 : }
1102 : else
1103 : {
1104 1028 : mvr2r( ptrChanL + prevNCShift - lMemRecalc - lMemRecalc_SCh, input_mem_loc[0], lMemRecalc + lMemRecalc_SCh );
1105 1028 : v_multc( ptrChanR - lMemRecalc - lMemRecalc_SCh, hStereoTCA->prevTargetGain, input_mem_loc[1], lMemRecalc + lMemRecalc_SCh );
1106 : }
1107 :
1108 2880 : target = ptrChanR;
1109 2880 : target_idx = R_CH_INDX;
1110 : /* identify target signal to correct for shift variations */
1111 2880 : if ( ( prevNCShift == 0 && hStereoTCA->corrLagStats[2] < 0 ) || ( hStereoTCA->prevRefChanIndx == R_CH_INDX ) )
1112 : {
1113 1201 : target = ptrChanL;
1114 1201 : target_idx = L_CH_INDX;
1115 : }
1116 :
1117 : /* target signal adjustment for temporal shift variations */
1118 2880 : if ( ( prevNCShift - currentNCShift ) != 0 )
1119 : {
1120 1203 : L_shift_adapt = L_SHIFT_ADAPT_16k;
1121 1203 : if ( input_Fs > INT_FS_16k )
1122 : {
1123 1148 : 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 1203 : tempS = ( currentNCShift >> 1 );
1128 1203 : 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 1095 : adjustTargetSignal( ( target - tempS ), prevNCShift, currentNCShift, L_shift_adapt, 0 );
1138 : }
1139 : else
1140 : {
1141 108 : tempS = min( max( tempS, prevNCShift - currentNCShift + L_shift_adapt - input_frame ), prevNCShift - currentNCShift + lMemRecalc );
1142 108 : adjustTargetSignal( ( target - tempS ), prevNCShift, currentNCShift, L_shift_adapt, 1 );
1143 : }
1144 :
1145 1203 : if ( target_idx == L_CH_INDX )
1146 : {
1147 764 : mvr2r( target - tempS, &( input_mem_loc[target_idx][lMemRecalc + lMemRecalc_SCh - tempS - currentNCShift] ), currentNCShift + tempS );
1148 : }
1149 : else
1150 : {
1151 439 : 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 2880 : if ( hStereoTCA->corrLagStats[2] >= 0 )
1157 : {
1158 1862 : hStereoTCA->refChanIndx = L_CH_INDX;
1159 : }
1160 : else
1161 : {
1162 1018 : hStereoTCA->refChanIndx = R_CH_INDX;
1163 : }
1164 :
1165 : /* Estimate and quantize the gain for scaling */
1166 2880 : estDownmixGain( hStereoTCA, ptrChanL, ptrChanR, currentNCShift, ( input_frame - currentNCShift ), hCPE->element_mode, hCPE->hStereoClassif, hCPE->hStereoTD->tdm_LRTD_flag );
1167 :
1168 : /* quantize the corrStats */
1169 2880 : hStereoTCA->indx_ica_NCShift = (int16_t) usquant( ( (float) currentNCShift ) / dsFactor, &tempF, 0, 1.0f, 1 << STEREO_BITS_TCA_CORRSTATS );
1170 : }
1171 : else
1172 : {
1173 25752 : hStereoTCA->refChanIndx = L_CH_INDX;
1174 25752 : hStereoTCA->corrLagStats[2] = 0;
1175 25752 : hStereoTCA->prevCorrLagStats[2] = 0;
1176 25752 : hStereoTCA->indx_ica_NCShift = 0;
1177 :
1178 25752 : currentNCShift = 0; /* only to avoid compilation warning */
1179 25752 : target = ptrChanL; /* only to avoid compilation warning */
1180 25752 : target_idx = L_CH_INDX; /* only to avoid compilation warning */
1181 :
1182 25752 : mvr2r( ptrChanL - lMemRecalc - lMemRecalc_SCh, input_mem_loc[0], lMemRecalc + lMemRecalc_SCh );
1183 25752 : 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 25752 : 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 28632 : mvr2r( bufChanL + input_frame, hStereoTCA->memChanL, lMemRecalc + lMemRecalc_SCh );
1195 28632 : mvr2r( bufChanR + input_frame, hStereoTCA->memChanR, lMemRecalc + lMemRecalc_SCh );
1196 :
1197 28632 : if ( currentNCShift != 0 )
1198 : {
1199 : /* Temporal channel adjustment of the LA samples based on the NC shift */
1200 1404 : tcaTargetCh_LA( hStereoTCA, ptrChanL, ptrChanR, currentNCShift, input_frame );
1201 : }
1202 :
1203 : /* Update of changed samples corresponding to the memory */
1204 28632 : 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 28632 : if ( hCPE->hStereoTD->prev_fr_LRTD_TD_dec == 0 || prev_ICA_flag == 1 )
1208 : {
1209 2880 : mvr2r( target + currentNCShift, sts[target_idx]->input, input_frame );
1210 : }
1211 :
1212 28632 : if ( hCPE->element_mode != IVAS_CPE_DFT )
1213 : {
1214 : /* Scale the Right channel with the gain */
1215 : int16_t j;
1216 28632 : int16_t l_ica_ovl = NS2SA( input_Fs, STEREO_L_TCA_OVLP_NS );
1217 28632 : float winSlope = 1.0f / (float) l_ica_ovl;
1218 :
1219 28632 : tempF1 = hStereoTCA->targetGain;
1220 28632 : tempF = hStereoTCA->prevTargetGain;
1221 :
1222 5994072 : for ( i = 0, j = 0; i < l_ica_ovl; i++, j++ )
1223 : {
1224 5965440 : sts[1]->input[i] = ( 1.0f - j * winSlope ) * tempF * sts[1]->input[i] + ( j * winSlope ) * tempF1 * sts[1]->input[i];
1225 : }
1226 17924952 : for ( ; i < input_frame; i++ )
1227 : {
1228 17896320 : sts[1]->input[i] *= tempF1;
1229 : }
1230 : }
1231 :
1232 : /* update L/R DS memories */
1233 28632 : mvr2r( bufChanL_DS + L_FRAME_DS, hStereoTCA->memChanL_DS, ADDED_MEM_DS );
1234 28632 : mvr2r( bufChanR_DS + L_FRAME_DS, hStereoTCA->memChanR_DS, ADDED_MEM_DS );
1235 :
1236 : /* save the reference channel index for next frame */
1237 28632 : hStereoTCA->prevRefChanIndx = hStereoTCA->refChanIndx;
1238 :
1239 : /* save the corr lag stats for next frame */
1240 28632 : mvs2s( hStereoTCA->corrLagStats, hStereoTCA->prevCorrLagStats, 3 );
1241 :
1242 : /* save the target gain for next frame */
1243 28632 : hStereoTCA->prevTargetGain = hStereoTCA->targetGain;
1244 :
1245 28632 : return;
1246 : }
1247 :
1248 : /*-------------------------------------------------------------------*
1249 : * stereo_tca_init_enc()
1250 : *
1251 : * Stereo temporal inter-channel adjustment (ICA) encoder initialization
1252 : *-------------------------------------------------------------------*/
1253 :
1254 18962 : 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 18962 : hStereoTCA->lMemRecalc = NS2SA( input_Fs, L_MEM_RECALC_NS );
1260 18962 : hStereoTCA->lMemRecalc_12k8 = (int16_t) ( ( hStereoTCA->lMemRecalc * INT_FS_12k8 ) / input_Fs );
1261 18962 : hStereoTCA->lMemRecalc_16k = (int16_t) ( ( hStereoTCA->lMemRecalc * INT_FS_16k ) / input_Fs );
1262 :
1263 18962 : hStereoTCA->refChanIndx = L_CH_INDX;
1264 18962 : hStereoTCA->prevRefChanIndx = L_CH_INDX;
1265 :
1266 18962 : hStereoTCA->targetGain = 1.0f;
1267 18962 : hStereoTCA->prevTargetGain = 1.0f;
1268 18962 : hStereoTCA->instTargetGain = 1.0f;
1269 18962 : hStereoTCA->corrStatsSmoothFac = 0.7f;
1270 :
1271 18962 : set_s( hStereoTCA->corrLagStats, 0, 3 );
1272 18962 : set_s( hStereoTCA->prevCorrLagStats, 0, 3 );
1273 :
1274 18962 : set_f( hStereoTCA->memChanL, 0.0f, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH );
1275 18962 : set_f( hStereoTCA->memChanR, 0.0f, L_MEM_RECALC_48K + L_MEM_RECALC_48k_SCH );
1276 18962 : set_f( hStereoTCA->memChanL_DS, 0.0f, ADDED_MEM_DS );
1277 18962 : set_f( hStereoTCA->memChanR_DS, 0.0f, ADDED_MEM_DS );
1278 18962 : hStereoTCA->mem_tempF = 0.;
1279 18962 : set_f( hStereoTCA->corrEstPrev[0], 0.0f, 2 * L_NCSHIFT_DS + 1 );
1280 18962 : set_f( hStereoTCA->corrEstPrev[1], 0.0f, 2 * L_NCSHIFT_DS + 1 );
1281 18962 : set_f( hStereoTCA->corrEstPrev[2], 0.0f, 2 * L_NCSHIFT_DS + 1 );
1282 :
1283 18962 : set_f( hStereoTCA->corrEstLT, 0.0f, 2 * L_NCSHIFT_DS + 1 );
1284 18962 : set_f( hStereoTCA->memdecim, 0.0f, 12 );
1285 18962 : hStereoTCA->ica_envVarLT = 2000.0f;
1286 :
1287 18962 : set_f( hStereoTCA->C_mem, 0.0f, 2 * L_NCSHIFT_DS + 1 );
1288 18962 : hStereoTCA->E1_mem = 0.0f;
1289 18962 : hStereoTCA->E2_mem = 0.0f;
1290 18962 : set_f( hStereoTCA->delay_0_mem, 0.0f, MAX_DELAYREGLEN );
1291 18962 : hStereoTCA->smooth_dist_reg_prv_corr = 1.0f;
1292 18962 : hStereoTCA->LRTD_G_ATT_cnt = 1;
1293 :
1294 18962 : return;
1295 : }
1296 :
1297 :
1298 : /*-------------------------------------------------------------------*
1299 : * Function unclr_calc_corr_features()
1300 : *
1301 : *-------------------------------------------------------------------*/
1302 :
1303 28632 : 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 28632 : corrL = 1.0f;
1320 28632 : corrR = 1.0f;
1321 28632 : ener = 1.0f;
1322 28632 : ener_side = 1.0f;
1323 28632 : sum_prod = 0.0f;
1324 :
1325 4609752 : for ( i = 0; i < length; i++ )
1326 : {
1327 4581120 : mono_i = ( buf1[i] + buf2[i] ) / 2.0f;
1328 4581120 : corrL += buf1[i] * mono_i;
1329 4581120 : corrR += buf2[i] * mono_i;
1330 4581120 : ener += mono_i * mono_i;
1331 4581120 : side_i = ( buf1[i] - buf2[i] ) / 2.0f;
1332 4581120 : ener_side += side_i * side_i;
1333 4581120 : prod_i = buf1[i] * buf2[i];
1334 4581120 : sum_prod += prod_i;
1335 : }
1336 :
1337 : /* average energy of L and R channels */
1338 28632 : hStereoClassif->ave_ener_L = hStereoTCA->E1_mem / length;
1339 28632 : hStereoClassif->ave_ener_R = hStereoTCA->E2_mem / length;
1340 :
1341 : /* unnormalized L/R correlation */
1342 28632 : sum_prod = log10f( fabsf( sum_prod ) + 1.0f );
1343 28632 : hStereoClassif->unclr_fv[E_sum_prod] = sum_prod;
1344 28632 : hStereoClassif->xtalk_fv[E_sum_prod] = sum_prod;
1345 :
1346 : /* S/M energy ratio */
1347 28632 : tdm_es_em = fabsf( 10.0f * ( log10f( sqrtf( ener_side / L_FRAME_DS ) ) - log10f( sqrtf( ener / L_FRAME_DS ) ) ) );
1348 28632 : hStereoClassif->unclr_fv[E_tdm_es_em] = tdm_es_em;
1349 28632 : hStereoClassif->xtalk_fv[E_tdm_es_em] = tdm_es_em;
1350 :
1351 : /* L/R correlation values (zero lag, maximum) */
1352 28632 : corrLagMax = maximum( corrEst, ( lagSearchRange[1] - lagSearchRange[0] + 1 ), &corrEstMax );
1353 28632 : d_corrLagMax = corrLagMax - hStereoClassif->unclr_corrLagMax_prev;
1354 28632 : hStereoClassif->unclr_fv[E_d_corrLagMax] = (float) d_corrLagMax;
1355 28632 : hStereoClassif->unclr_corrLagMax_prev = corrLagMax;
1356 28632 : hStereoClassif->xtalk_fv[E_d_corrLagMax] = (float) d_corrLagMax;
1357 :
1358 28632 : if ( corrEstMax < 0 )
1359 : {
1360 0 : corrEstMax = 0;
1361 : }
1362 :
1363 28632 : hStereoClassif->unclr_fv[E_corrEst0] = corrEst[abs( lagSearchRange[0] )];
1364 28632 : hStereoClassif->unclr_fv[E_corrEstMax] = corrEstMax;
1365 28632 : hStereoClassif->unclr_fv[E_corrLagMax] = corrLagMax;
1366 28632 : hStereoClassif->xtalk_fv[E_corrEst0] = corrEst[abs( lagSearchRange[0] )];
1367 28632 : hStereoClassif->xtalk_fv[E_corrEstMax] = corrEstMax;
1368 28632 : hStereoClassif->xtalk_fv[E_corrLagMax] = corrLagMax;
1369 :
1370 : /* L/M and R/M correlation */
1371 28632 : if ( corrL < 0 )
1372 : {
1373 1682 : corrL = 0;
1374 : }
1375 :
1376 28632 : if ( corrR < 0 )
1377 : {
1378 878 : corrR = 0;
1379 : }
1380 :
1381 28632 : ic_Lm = corrL / ener;
1382 28632 : ic_Rm = corrR / ener;
1383 28632 : m_corrL_corrR = max( fabsf( ic_Lm ), fabsf( ic_Rm ) ) - min( fabsf( ic_Lm ), fabsf( ic_Rm ) );
1384 28632 : d_corrL_corrR = log10f( fabsf( corrL - corrR ) + 1.0f );
1385 :
1386 28632 : hStereoClassif->unclr_fv[E_m_corrL_corrR] = m_corrL_corrR;
1387 28632 : hStereoClassif->unclr_fv[E_d_corrL_corrR] = d_corrL_corrR;
1388 28632 : hStereoClassif->xtalk_fv[E_m_corrL_corrR] = m_corrL_corrR;
1389 :
1390 : /* norm. x-correlation btw. current and previous correlation buffers */
1391 28632 : tempLen = ( 2 * L_NCSHIFT_DS + 1 );
1392 28632 : num = dotp( corrEst, hStereoTCA->corrEstPrev[2], tempLen );
1393 28632 : den = sqrtf( sum2_f( corrEst, tempLen ) * sum2_f( hStereoTCA->corrEstPrev[2], tempLen ) );
1394 :
1395 28632 : *corrEst_ncorr = ( den == 0 ) ? 0.0f : ( num / den );
1396 28632 : hStereoClassif->unclr_fv[E_corrEst_ncorr] = *corrEst_ncorr;
1397 28632 : hStereoClassif->xtalk_fv[E_corrEst_ncorr] = *corrEst_ncorr;
1398 :
1399 28632 : return;
1400 : }
|