Line data Source code
1 : /******************************************************************************************************
2 :
3 : (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
4 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
5 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
6 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
7 : contributors to this repository. All Rights Reserved.
8 :
9 : This software is protected by copyright law and by international treaties.
10 : The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
11 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
12 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
13 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
14 : contributors to this repository retain full ownership rights in their respective contributions in
15 : the software. This notice grants no license of any kind, including but not limited to patent
16 : license, nor is any license granted by implication, estoppel or otherwise.
17 :
18 : Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
19 : contributions.
20 :
21 : This software is provided "AS IS", without any express or implied warranties. The software is in the
22 : development stage. It is intended exclusively for experts who have experience with such software and
23 : solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
24 : and fitness for a particular purpose are hereby disclaimed and excluded.
25 :
26 : Any dispute, controversy or claim arising under or in relation to providing this software shall be
27 : submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
28 : accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
29 : the United Nations Convention on Contracts on the International Sales of Goods.
30 :
31 : *******************************************************************************************************/
32 :
33 : #include <assert.h>
34 : #include <stdint.h>
35 : #include "options.h"
36 : #include <math.h>
37 : #include "cnst.h"
38 : #include "ivas_cnst.h"
39 : #include "prot_fx.h"
40 : #include "wmc_auto.h"
41 : #include "rom_com.h"
42 : #include "ivas_rom_com.h"
43 : #include "ivas_prot_fx.h"
44 : #include "basop32.h"
45 : #include "ivas_stat_dec.h"
46 :
47 :
48 : /*---------------------------------------------------------------
49 : * stereo_tca_dec()
50 : *
51 : * Stereo temporal channel adjustment/allocation processing module;
52 : * upnmix, convert L/R to M/S.
53 : * ---------------------------------------------------------------*/
54 :
55 145402 : void stereo_tca_dec_fx(
56 : CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */
57 : Word32 *synth_fx[CPE_CHANNELS], /* i/o: output synth qsynth*/
58 : const Word16 output_frame /* i : length of a frame per channel Q0*/
59 : )
60 : {
61 : /* Buffers, input Left and right channels @ input_Fs*/
62 145402 : Word32 bufChanL_fx[L_DEC_MEM_LEN_ICA + L_FRAME48k] = { 0 };
63 145402 : Word32 bufChanR_fx[L_DEC_MEM_LEN_ICA + L_FRAME48k] = { 0 };
64 : Word32 *ptrChanL_fx, *ptrChanR_fx;
65 : Word32 *target_fx;
66 : Word16 target_idx, prevNCShift, currentNCShift, l_shift_adapt;
67 : Word16 dsFactor, tempMax;
68 : Word32 *ref_fx;
69 : Word16 bothChannelShift;
70 : Word32 output_Fs;
71 : STEREO_TCA_DEC_HANDLE hStereoTCA;
72 : Word16 exp_ds;
73 :
74 145402 : hStereoTCA = hCPE->hStereoTCA;
75 :
76 145402 : output_Fs = hCPE->hCoreCoder[0]->output_Fs; /* Q0 */
77 145402 : move32();
78 :
79 145402 : test();
80 145402 : IF( EQ_16( hCPE->nchan_out, 1 ) )
81 : {
82 30693 : IF( hCPE->hStereoDftDmx )
83 : {
84 23693 : IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) )
85 : {
86 22346 : hCPE->hStereoDftDmx->targetGain_fx = ONE_IN_Q29; /* Q29 */
87 22346 : move32();
88 : }
89 :
90 : /* save the target gain for next frame */
91 23693 : hCPE->hStereoDftDmx->prevTargetGain_fx = hCPE->hStereoDftDmx->targetGain_fx; /* Q29 */
92 23693 : move32();
93 : }
94 :
95 30693 : return;
96 : }
97 114709 : ELSE IF( EQ_16( hCPE->element_mode, IVAS_CPE_MDCT ) && !hCPE->hStereoMdct->use_itd )
98 : {
99 65693 : return;
100 : }
101 :
102 : /* populate L/R memories into current buffers */
103 49016 : Copy32( hStereoTCA->memChanL_fx, bufChanL_fx, L_DEC_MEM_LEN_ICA ); /* memChan_q */
104 49016 : Copy32( hStereoTCA->memChanR_fx, bufChanR_fx, L_DEC_MEM_LEN_ICA ); /* memChan_q */
105 :
106 : /* pointers to the current frame */
107 49016 : ptrChanL_fx = bufChanL_fx + L_DEC_MEM_LEN_ICA; /* memChan_q */
108 49016 : ptrChanR_fx = bufChanR_fx + L_DEC_MEM_LEN_ICA; /* memChan_q */
109 :
110 : /* copy interleaved stereo data to two channels, e.g., L, R */
111 49016 : Copy32( synth_fx[0], ptrChanL_fx, output_frame ); /* qsynth */
112 49016 : Copy32( synth_fx[1], ptrChanR_fx, output_frame ); /* qsynth */
113 :
114 : /* back up the L/R target synth for next frame */
115 49016 : Copy32( bufChanL_fx + output_frame, hStereoTCA->memChanL_fx, L_DEC_MEM_LEN_ICA ); /* memChan_q */
116 49016 : Copy32( bufChanR_fx + output_frame, hStereoTCA->memChanR_fx, L_DEC_MEM_LEN_ICA ); /* memChan_q */
117 :
118 : /* TCA parameter de-quantize */
119 49016 : dsFactor = BASOP_Util_Divide3232_Scale( output_Fs, 8000, &exp_ds );
120 49016 : dsFactor = shr( dsFactor, sub( 15, exp_ds ) ); /* Q0 */
121 :
122 49016 : tempMax = NS2SA_FX2( output_Fs, L_NCSHIFT_NS ); /* Q0 */
123 49016 : hStereoTCA->corrLagStats = s_min( hStereoTCA->indx_ica_NCShift * dsFactor, tempMax ); /* Q0 */
124 :
125 49016 : bothChannelShift = 0;
126 49016 : move16();
127 49016 : test();
128 49016 : IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) || EQ_16( hCPE->element_mode, IVAS_CPE_MDCT ) )
129 : {
130 46612 : hStereoTCA->corrLagStats = 0;
131 46612 : move16();
132 46612 : hStereoTCA->refChanIndx = L_CH_INDX; /* Q0 */
133 46612 : move16();
134 46612 : hStereoTCA->targetGain_fx = ONE_IN_Q29; /* Q29 */
135 46612 : move16();
136 :
137 46612 : IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) )
138 : {
139 36701 : hStereoTCA->corrLagStats = extract_l( L_shr( L_abs( hCPE->hStereoDft->itd_fx[1] ), Q15 ) ); /* Q0 */
140 :
141 36701 : IF( hCPE->hStereoDft->itd_fx[1] >= 0 )
142 : {
143 23751 : hStereoTCA->refChanIndx = ( L_CH_INDX ); /* Q0 */
144 : }
145 : ELSE
146 : {
147 12950 : hStereoTCA->refChanIndx = ( R_CH_INDX ); /* Q0 */
148 : }
149 36701 : move16();
150 36701 : move16();
151 : }
152 9911 : ELSE IF( EQ_16( hCPE->element_mode, IVAS_CPE_MDCT ) )
153 : {
154 : Word32 itd;
155 :
156 9911 : itd = hCPE->hStereoMdct->itd_fx;
157 9911 : move32();
158 9911 : hStereoTCA->corrLagStats = extract_l( L_shr( L_abs( itd ), Q15 ) ); /* Q0 */
159 :
160 9911 : IF( GE_32( itd, 0 ) )
161 : {
162 8060 : hStereoTCA->refChanIndx = ( L_CH_INDX ); /* Q0 */
163 : }
164 : ELSE
165 : {
166 1851 : hStereoTCA->refChanIndx = ( R_CH_INDX ); /* Q0 */
167 : }
168 9911 : move16();
169 : }
170 :
171 46612 : test();
172 46612 : IF( NE_16( hStereoTCA->refChanIndx, hStereoTCA->prevRefChanIndx ) && ( hStereoTCA->corrLagStats != 0 ) )
173 : {
174 360 : bothChannelShift = 1;
175 360 : move16();
176 : }
177 : }
178 :
179 49016 : prevNCShift = abs_s( hStereoTCA->prevCorrLagStats ); /* Q0 */
180 49016 : currentNCShift = abs_s( hStereoTCA->corrLagStats ); /* Q0 */
181 :
182 49016 : test();
183 49016 : IF( EQ_16( hCPE->element_mode, IVAS_CPE_TD ) && EQ_16( hCPE->last_element_mode, IVAS_CPE_TD ) )
184 : {
185 2368 : test();
186 2368 : IF( EQ_16( hStereoTCA->corrLagStats, hStereoTCA->prevCorrLagStats ) && EQ_16( hStereoTCA->interp_dec_switch_to_zero_diff, 0 ) )
187 : {
188 1191 : hStereoTCA->interp_dec_switch_to_zero_diff = 1;
189 1191 : move16();
190 : }
191 : ELSE
192 : {
193 1177 : hStereoTCA->interp_dec_switch_to_zero_diff = 0;
194 1177 : move16();
195 : }
196 :
197 2368 : IF( currentNCShift != 0 )
198 : {
199 4 : currentNCShift = add( mult( 19660 /* 0.6 in Q15 */, prevNCShift ), mult( 13106 /* 0.4 in Q15 */, currentNCShift ) ); /* Q0 */
200 : }
201 :
202 2368 : prevNCShift = hStereoTCA->interp_dec_prevNCShift; /* Q0 */
203 2368 : move16();
204 2368 : hStereoTCA->interp_dec_prevNCShift = currentNCShift; /* Q0 */
205 2368 : move16();
206 : }
207 : ELSE
208 : {
209 46648 : hStereoTCA->interp_dec_prevNCShift = currentNCShift; /* Q0 */
210 46648 : move16();
211 46648 : hStereoTCA->interp_dec_switch_to_zero_diff = 0;
212 46648 : move16();
213 : }
214 :
215 49016 : ref_fx = ptrChanL_fx; /* qsynth */
216 49016 : target_fx = ptrChanR_fx; /* qsynth */
217 49016 : target_idx = R_CH_INDX;
218 49016 : move16();
219 : /* identify target signal to adjust for shift variations */
220 49016 : test();
221 49016 : test();
222 49016 : IF( ( ( prevNCShift == 0 ) && EQ_16( hStereoTCA->refChanIndx, R_CH_INDX ) ) || EQ_16( hStereoTCA->prevRefChanIndx, R_CH_INDX ) )
223 : {
224 14926 : ref_fx = ptrChanR_fx; /* qsynth */
225 14926 : target_fx = ptrChanL_fx; /* qsynth */
226 14926 : target_idx = L_CH_INDX;
227 14926 : move16();
228 : }
229 :
230 49016 : IF( EQ_16( bothChannelShift, 1 ) )
231 : {
232 360 : ref_fx = ptrChanL_fx; /* qsynth */
233 360 : target_fx = ptrChanR_fx; /* qsynth */
234 360 : target_idx = R_CH_INDX;
235 360 : move16();
236 360 : IF( EQ_16( hStereoTCA->refChanIndx, R_CH_INDX ) )
237 : {
238 285 : ref_fx = ptrChanR_fx; /* qsynth */
239 285 : target_fx = ptrChanL_fx; /* qsynth */
240 285 : target_idx = L_CH_INDX;
241 285 : move16();
242 : }
243 : }
244 :
245 : /* target signal adjustment for temporal shift variations */
246 49016 : test();
247 49016 : test();
248 49016 : test();
249 49016 : IF( NE_16( hStereoTCA->prevCorrLagStats, hStereoTCA->corrLagStats ) || bothChannelShift || ( EQ_16( hStereoTCA->interp_dec_switch_to_zero_diff, 1 ) && EQ_16( hCPE->element_mode, IVAS_CPE_TD ) ) )
250 : {
251 3716 : l_shift_adapt = L_SHIFT_ADAPT_16k;
252 3716 : move16();
253 3716 : IF( GT_32( output_Fs, 16000 ) )
254 : {
255 2879 : l_shift_adapt = L_SHIFT_ADAPT_MAX; /* Q0 */
256 2879 : move16();
257 : }
258 :
259 3716 : test();
260 3716 : IF( EQ_16( hCPE->element_mode, IVAS_CPE_TD ) && EQ_16( hCPE->last_element_mode, IVAS_CPE_DFT ) )
261 : {
262 12 : l_shift_adapt = shr( l_shift_adapt, 1 ); /* Q0 */
263 : }
264 :
265 3716 : test();
266 3716 : IF( LE_16( abs_s( sub( currentNCShift, prevNCShift ) ), N_MAX_SHIFT_CHANGE ) && EQ_16( bothChannelShift, 0 ) )
267 : {
268 3099 : adjustTargetSignal_fx( target_fx - currentNCShift, currentNCShift, prevNCShift, l_shift_adapt, 0 );
269 : }
270 : ELSE
271 : {
272 617 : IF( EQ_16( bothChannelShift, 1 ) )
273 : {
274 360 : adjustTargetSignal_fx( ref_fx, 0, prevNCShift, l_shift_adapt, 1 );
275 360 : adjustTargetSignal_fx( target_fx - currentNCShift, currentNCShift, 0, l_shift_adapt, 1 );
276 : }
277 : ELSE
278 : {
279 257 : adjustTargetSignal_fx( target_fx - currentNCShift, currentNCShift, prevNCShift, l_shift_adapt, 1 );
280 : }
281 : }
282 : }
283 :
284 : /* temporal channel adjustment */
285 49016 : Copy32( target_fx - currentNCShift, synth_fx[target_idx], output_frame ); /* qsynth */
286 :
287 49016 : Copy32( ref_fx, synth_fx[!target_idx], output_frame ); /* qsynth */
288 :
289 : /* Scale the Right channel with the gain */
290 49016 : stereo_tca_scale_R_channel_fx( hCPE, synth_fx[1], output_frame );
291 :
292 : /*-----------------------------------------------------------------*
293 : * updates and memory backups
294 : *-----------------------------------------------------------------*/
295 :
296 : /* save the reference channel index for next frame */
297 49016 : hStereoTCA->prevRefChanIndx = hStereoTCA->refChanIndx; /* Q0 */
298 49016 : move16();
299 :
300 : /* save the corr lag stats for next frame */
301 49016 : hStereoTCA->prevCorrLagStats = hStereoTCA->corrLagStats; /* Q0 */
302 49016 : move16();
303 :
304 : /* save the target gain for next frame */
305 49016 : hStereoTCA->prevTargetGain_fx = hStereoTCA->targetGain_fx; /* qsynth */
306 49016 : move32();
307 49016 : return;
308 : }
309 : /*-------------------------------------------------------------------*
310 : * stereo_tca_scale_R_channel()
311 : *
312 : * Scale the Right channel with the gain
313 : *-------------------------------------------------------------------*/
314 :
315 : #define MAX_TARGET_GAIN_Q29 1904890240
316 50370 : void stereo_tca_scale_R_channel_fx(
317 : CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */
318 : Word32 *output_fx, /* i/o: output synthesis, R channel q_out*/
319 : const Word16 output_frame /* i : frame length Q0*/
320 : )
321 : {
322 : STEREO_TCA_DEC_HANDLE hStereoTCA;
323 : Word16 j, l_ica_ovl, flat_old;
324 : Word16 i_fx;
325 50370 : Word32 tempF_fx, tempF1_fx, winSlope_fx = 0;
326 : Word32 output_Fs;
327 50370 : move16();
328 :
329 50370 : hStereoTCA = hCPE->hStereoTCA;
330 50370 : output_Fs = hCPE->hCoreCoder[0]->output_Fs; /* Q0 */
331 50370 : move32();
332 :
333 50370 : test();
334 50370 : IF( LE_32( hCPE->hCoreCoder[0]->core_brate, SID_2k40 ) && EQ_16( hCPE->nchan_out, 2 ) )
335 : {
336 7284 : return;
337 : }
338 : /* Scale the Right channel with the gain */
339 43086 : l_ica_ovl = NS2SA_FX2( output_Fs, STEREO_L_TCA_OVLP_NS ); /* Q0 */
340 43086 : move16();
341 :
342 43086 : test();
343 43086 : IF( EQ_16( hCPE->nchan_out, 1 ) )
344 : {
345 : /* in mono DMX, the scaling is done before synchro_synthesis() */
346 1354 : flat_old = NS2SA_FX2( output_Fs, ACELP_LOOK_NS + IVAS_DEC_DELAY_NS - DELAY_CLDFB_NS ); /* Q0 */
347 1354 : move16();
348 :
349 1354 : test();
350 1354 : IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_TD ) && EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) )
351 : {
352 : Word64 local_value;
353 : // to be deleted next MR
354 : // hCPE->hStereoDftDmx->prevTargetGain *= 2.0f;
355 : // hCPE->hStereoDftDmx->prevTargetGain = min( hCPE->hStereoDftDmx->prevTargetGain, powf( 10, ( ( 1 << STEREO_BITS_TCA_GD ) - 1 ) * STEREO_TCA_GDSTEP + STEREO_TCA_GDMIN ) );
356 7 : local_value = W_shl( hCPE->hStereoDftDmx->prevTargetGain_fx, 1 ); /* Q29 */
357 7 : hCPE->hStereoDftDmx->prevTargetGain_fx = (Word32) min( local_value, MAX_TARGET_GAIN_Q29 ); /* Q29 */
358 7 : hCPE->hStereoDftDmx->targetGain_fx = ONE_IN_Q29; /* Q29 */
359 7 : move32();
360 :
361 7 : flat_old = NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS ); /* Q0 */
362 7 : move16();
363 : }
364 : }
365 41732 : ELSE IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_TD ) && EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) )
366 : {
367 14 : flat_old = NS2SA_FX2( output_Fs, IVAS_DEC_DELAY_NS ); /* Q0 */
368 14 : move16();
369 : }
370 : ELSE
371 : {
372 41718 : flat_old = NS2SA_FX2( output_Fs, ACELP_LOOK_NS + IVAS_DEC_DELAY_NS ); /* Q0 */
373 41718 : move16();
374 : }
375 :
376 43086 : IF( EQ_16( hCPE->nchan_out, 1 ) )
377 : {
378 1354 : IF( EQ_32( hCPE->hStereoDftDmx->targetGain_fx, ONE_IN_Q29 ) )
379 : {
380 1354 : tempF1_fx = ONE_IN_Q27; /* Q27 */
381 1354 : move32();
382 : }
383 : ELSE
384 : {
385 0 : Word16 temp_a = (Word16) L_shr( hCPE->hStereoDftDmx->targetGain_fx, (Word16) 16 ); /* Q13 */
386 0 : Word16 temp_a_q = 2;
387 0 : move16();
388 0 : tempF1_fx = Inv16( temp_a, &temp_a_q ); /* Q13 */
389 0 : tempF1_fx = L_shl( tempF1_fx, sub( ( 31 - 4 ), sub( 15, temp_a_q ) ) ); /* Q27 */
390 : }
391 :
392 1354 : IF( EQ_32( hCPE->hStereoDftDmx->prevTargetGain_fx, ONE_IN_Q29 ) )
393 : {
394 1347 : tempF_fx = ONE_IN_Q27; /* Q27 */
395 1347 : move32();
396 : }
397 : ELSE
398 : {
399 7 : Word16 temp_b = (Word16) L_shr( hCPE->hStereoDftDmx->prevTargetGain_fx, 16 ); /* Q13 */
400 7 : Word16 temp_b_q = 2;
401 7 : move16();
402 7 : tempF_fx = Inv16( temp_b, &temp_b_q ); /* Q13 */
403 7 : tempF_fx = L_shl( tempF_fx, sub( ( 31 - 4 ), sub( 15, temp_b_q ) ) ); /* Q27 */
404 : }
405 : }
406 : ELSE
407 : {
408 :
409 41732 : IF( EQ_32( hStereoTCA->targetGain_fx, ONE_IN_Q29 ) )
410 : {
411 41732 : tempF1_fx = ONE_IN_Q27; /* Q27 */
412 41732 : move32();
413 : }
414 : ELSE
415 : {
416 0 : Word16 temp_a = (Word16) L_shr( hStereoTCA->targetGain_fx, (Word16) 16 ); /* Q13 */
417 0 : Word16 temp_a_q = 2;
418 0 : move16();
419 0 : tempF1_fx = Inv16( temp_a, &temp_a_q ); /* Q13 */
420 0 : tempF1_fx = L_shl( tempF1_fx, sub( ( 31 - 4 ), sub( 15, temp_a_q ) ) ); /* Q27 */
421 : }
422 :
423 :
424 41732 : IF( EQ_32( hStereoTCA->prevTargetGain_fx, ONE_IN_Q29 ) )
425 : {
426 41732 : tempF_fx = ONE_IN_Q27; /* Q27 */
427 41732 : move32();
428 : }
429 : ELSE
430 : {
431 0 : Word16 temp_b = (Word16) L_shr( hStereoTCA->prevTargetGain_fx, (Word16) 16 ); /* Q13 */
432 0 : Word16 temp_b_q = 2;
433 0 : move16();
434 0 : tempF_fx = Inv16( temp_b, &temp_b_q ); /* Q13 */
435 0 : tempF_fx = L_shl( tempF_fx, sub( ( 31 - 4 ), sub( 15, temp_b_q ) ) ); /* Q27 */
436 : }
437 : }
438 43086 : SWITCH( output_Fs )
439 : {
440 14232 : case 16000:
441 14232 : winSlope_fx = 26843546; // 0.0125 in Q31
442 14232 : move32();
443 14232 : BREAK;
444 15645 : case 32000:
445 15645 : winSlope_fx = 13421773; // 0.00625 in Q30
446 15645 : move32();
447 15645 : BREAK;
448 13209 : case 48000:
449 13209 : winSlope_fx = 8947849; // 0.00416 in Q30
450 13209 : move32();
451 13209 : BREAK;
452 : }
453 :
454 43086 : IF( EQ_32( tempF_fx, ONE_IN_Q27 ) )
455 : {
456 16334395 : FOR( i_fx = 0; i_fx < flat_old; i_fx++ )
457 : {
458 16291316 : output_fx[i_fx] = output_fx[i_fx]; /* q_out */
459 16291316 : move32();
460 : }
461 : }
462 : ELSE
463 : {
464 839 : FOR( i_fx = 0; i_fx < flat_old; i_fx++ )
465 : {
466 832 : output_fx[i_fx] = L_shl_sat( Mpy_32_32( output_fx[i_fx], tempF_fx ), 4 ); /* q_out */
467 832 : move32();
468 : }
469 : }
470 :
471 43086 : test();
472 43086 : IF( EQ_32( tempF1_fx, ONE_IN_Q27 ) && EQ_32( tempF_fx, ONE_IN_Q27 ) )
473 : {
474 6853719 : FOR( j = 0; i_fx < flat_old + l_ica_ovl; ( i_fx++, j++ ) )
475 : {
476 6810640 : Word32 slope_gain_decend = L_sub( ONE_IN_Q31, imult3216( winSlope_fx, j ) ); /* Q31 */
477 6810640 : Word32 slope_gain_ascend = imult3216( winSlope_fx, j ); /* Q31 */
478 6810640 : Word32 left_res = Mpy_32_32( slope_gain_decend, output_fx[i_fx] ); /* q_out */
479 6810640 : Word32 right_res = Mpy_32_32( slope_gain_ascend, output_fx[i_fx] ); /* q_out */
480 6810640 : output_fx[i_fx] = L_add( left_res, right_res ); /* q_out */
481 6810640 : move32();
482 : }
483 : }
484 : ELSE
485 : {
486 1287 : FOR( j = 0; i_fx < flat_old + l_ica_ovl; ( i_fx++, j++ ) )
487 : {
488 1280 : Word32 slope_gain_decend = L_sub( ONE_IN_Q31, imult3216( winSlope_fx, j ) ); /* Q31 */
489 1280 : Word32 slope_gain_ascend = imult3216( winSlope_fx, j ); /* Q31 */
490 1280 : Word32 left_res = Mpy_32_32( slope_gain_decend, output_fx[i_fx] ); /* q_out */
491 1280 : Word32 right_res = Mpy_32_32( slope_gain_ascend, output_fx[i_fx] ); /* q_out */
492 1280 : output_fx[i_fx] = L_add_sat( L_shl_sat( Mpy_32_32( tempF_fx, left_res ), 4 ), L_shl_sat( Mpy_32_32( right_res, tempF1_fx ), 4 ) ); /* q_out */
493 1280 : move32();
494 : }
495 : }
496 :
497 43086 : IF( EQ_32( tempF1_fx, ONE_IN_Q27 ) )
498 : {
499 4186698 : FOR( ; i_fx < output_frame; i_fx++ )
500 : {
501 4143612 : output_fx[i_fx] = output_fx[i_fx]; /* q_out */
502 4143612 : move32();
503 : }
504 : }
505 : ELSE
506 : {
507 0 : FOR( ; i_fx < output_frame; i_fx++ )
508 : {
509 0 : output_fx[i_fx] = L_shl_sat( Mpy_32_32( output_fx[i_fx], tempF1_fx ), 4 ); /* q_out */
510 0 : move32();
511 : }
512 : }
513 :
514 43086 : return;
515 : }
516 :
517 : /*-------------------------------------------------------------------*
518 : * stereo_tca_init_dec()
519 : *
520 : * Stereo temporal channel adjustment (TCA) decoder initialization
521 : *-------------------------------------------------------------------*/
522 :
523 :
524 488 : void stereo_tca_init_dec_fx(
525 : STEREO_TCA_DEC_HANDLE hStereoTCA /* i/o: Stereo TCA handle */
526 : )
527 : {
528 488 : hStereoTCA->refChanIndx = L_CH_INDX;
529 488 : move16();
530 488 : hStereoTCA->prevRefChanIndx = L_CH_INDX;
531 488 : move16();
532 488 : hStereoTCA->indx_ica_NCShift = 0;
533 488 : move16();
534 488 : hStereoTCA->indx_ica_gD = 0;
535 488 : move16();
536 488 : hStereoTCA->targetGain_fx = ONE_IN_Q29; /* Q29 */
537 488 : move32();
538 488 : hStereoTCA->prevTargetGain_fx = ONE_IN_Q29; /* Q29 */
539 488 : move32();
540 :
541 488 : hStereoTCA->corrLagStats = 0;
542 488 : move16();
543 488 : hStereoTCA->prevCorrLagStats = 0;
544 488 : move16();
545 :
546 488 : hStereoTCA->interp_dec_prevNCShift = 0;
547 488 : move16();
548 488 : hStereoTCA->interp_dec_switch_to_zero_diff = 0;
549 488 : move16();
550 :
551 488 : set32_fx( hStereoTCA->memChanL_fx, 0, L_DEC_MEM_LEN_ICA );
552 488 : set32_fx( hStereoTCA->memChanR_fx, 0, L_DEC_MEM_LEN_ICA );
553 :
554 488 : return;
555 : }
|