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 <stdint.h>
34 : #include "options.h"
35 : #include <math.h>
36 : #include "cnst.h"
37 : #include "rom_com.h"
38 : #include "prot.h"
39 : #include "ivas_prot.h"
40 : #include "ivas_rom_com.h"
41 : #include "ivas_cnst.h"
42 : #ifdef DEBUGGING
43 : #include "debug.h"
44 : #endif
45 : #include "wmc_auto.h"
46 :
47 : /*-------------------------------------------------------------------*
48 : * stereo_td_init_dec()
49 : *
50 : * Initialize TD stereo decoder
51 : *-------------------------------------------------------------------*/
52 :
53 177 : void stereo_td_init_dec(
54 : STEREO_TD_DEC_DATA_HANDLE hStereoTD, /* i/o: TD stereo decoder handle */
55 : const int16_t last_element_mode /* i : last element mode */
56 : )
57 : {
58 177 : hStereoTD->tdm_SM_flag = 0;
59 177 : hStereoTD->tdm_last_SM_flag = 0;
60 177 : hStereoTD->tdm_last_ratio_idx = LRTD_STEREO_MID_IS_PRIM;
61 177 : hStereoTD->tdm_prev_last_SM_flag = 0;
62 177 : hStereoTD->tdm_LRTD_flag = 0;
63 177 : hStereoTD->prevSP_ratio = 0.5f;
64 177 : hStereoTD->SP_ratio_LT = 0.0f;
65 177 : hStereoTD->c_LR_LT = 0.5f;
66 :
67 177 : hStereoTD->flag_skip_DMX = 0;
68 :
69 177 : if ( last_element_mode == IVAS_CPE_MDCT )
70 : {
71 24 : hStereoTD->tdm_last_ratio_idx = LRTD_STEREO_LEFT_IS_PRIM;
72 24 : hStereoTD->tdm_LRTD_flag = 1;
73 : }
74 :
75 177 : set_f( hStereoTD->TCX_old_syn_Overl, 0.0f, L_FRAME16k / 2 );
76 :
77 177 : return;
78 : }
79 :
80 :
81 : /*-------------------------------------------------------------------*
82 : * tdm_configure_dec()
83 : *
84 : * Configure TD stereo decoder
85 : *-------------------------------------------------------------------*/
86 :
87 10956 : void tdm_configure_dec(
88 : const int16_t ivas_format, /* i : IVAS format */
89 : const int16_t ism_mode, /* i : ISM mode in combined format */
90 : CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */
91 : int16_t *tdm_ratio_idx, /* o : ratio index */
92 : const int16_t nb_bits_metadata /* i : number of metadata bits */
93 : )
94 : {
95 : STEREO_TD_DEC_DATA_HANDLE hStereoTD;
96 : Decoder_State **sts;
97 : int16_t tdm_tmp_SM_LRTD_flag;
98 : int16_t mod_ct, core, bits_offset;
99 : int16_t idx_LRTD_pri_side, tdm_inst_ratio_idx;
100 : int32_t element_brate_adapt;
101 : int16_t bstr_last_pos;
102 :
103 10956 : hStereoTD = hCPE->hStereoTD;
104 10956 : sts = hCPE->hCoreCoder;
105 :
106 10956 : element_brate_adapt = hCPE->element_brate + hCPE->brate_surplus;
107 10956 : bstr_last_pos = (int16_t) ( hCPE->element_brate / FRAMES_PER_SEC ) - nb_bits_metadata + (int16_t) ( hCPE->brate_surplus / FRAMES_PER_SEC );
108 :
109 : /*----------------------------------------------------------------*
110 : * Decode CoreCoder signaling
111 : *----------------------------------------------------------------*/
112 :
113 : /* temporarily decode PCh signaling */
114 10956 : bits_offset = sts[0]->next_bit_pos;
115 10956 : core = get_indice_st( sts[0], hCPE->element_brate, bits_offset, 1 );
116 10956 : bits_offset += 1;
117 :
118 10956 : if ( core == ACELP_CORE && hCPE->element_brate < IVAS_24k4 )
119 : {
120 1632 : mod_ct = get_indice_st( sts[0], hCPE->element_brate, bits_offset, 3 );
121 : /* Only transition mode is important to decoder, otherwise mod_ct is set to AUDIO only to easy debugging if needed */
122 1632 : if ( mod_ct != TRANSITION )
123 : {
124 1563 : mod_ct = AUDIO;
125 : }
126 : }
127 : else /* core != ACELP_CORE */
128 : {
129 9324 : mod_ct = AUDIO; /* coder_type == VOICED || coder_type == GENERIC */
130 : }
131 :
132 : /* Get few parameters needed to decode the bitrate allocated to each channel */
133 : /* Get the coder_type of the secondary channel (last parameter on 2 bits) */
134 10956 : sts[1]->coder_type = get_indice_st( sts[0], element_brate_adapt, bstr_last_pos - TDM_SECONDARY_SIGNALLING, TDM_SECONDARY_SIGNALLING );
135 :
136 : /* Get the LRTD config flag: 1 = LRTD configuration, favor closer bitrate per channel;
137 : 0 = Pri/Sec configuration, bitrates linked wrt. the mono */
138 10956 : tdm_tmp_SM_LRTD_flag = sts[1]->coder_type & 0x1;
139 10956 : sts[1]->coder_type >>= 1;
140 10956 : hStereoTD->tdm_Pitch_reuse_flag = 0;
141 :
142 10956 : if ( sts[1]->coder_type == 2 )
143 : {
144 10572 : sts[1]->coder_type = GENERIC;
145 : }
146 384 : else if ( sts[1]->coder_type == 3 )
147 : {
148 99 : sts[1]->coder_type = AUDIO;
149 :
150 99 : if ( hCPE->element_brate <= IVAS_24k4 )
151 : {
152 99 : hStereoTD->tdm_Pitch_reuse_flag = 1;
153 99 : sts[1]->coder_type = GENERIC;
154 : }
155 : }
156 :
157 : /*----------------------------------------------------------------*
158 : * Decode TDM parameters
159 : *----------------------------------------------------------------*/
160 :
161 : /* Get the correlation ratio */
162 10956 : *tdm_ratio_idx = get_indice_st( sts[0], element_brate_adapt, (int16_t) ( bstr_last_pos - TDM_SECONDARY_SIGNALLING - TDM_RATIO_BITS ), TDM_RATIO_BITS );
163 :
164 10956 : hStereoTD->tdm_use_IAWB_Ave_lpc = 0;
165 10956 : if ( sts[1]->coder_type == INACTIVE )
166 : {
167 : /* Get the flag on the LPC reusage type (primary channel of ave LPC */
168 0 : hStereoTD->tdm_use_IAWB_Ave_lpc = get_indice_st( sts[0], element_brate_adapt, bstr_last_pos - TDM_SECONDARY_SIGNALLING - TDM_RATIO_BITS - TDM_LP_REUSE_BITS, TDM_LP_REUSE_BITS );
169 0 : hStereoTD->tdm_lp_reuse_flag = 1;
170 : }
171 : else
172 : {
173 : /* Get the flag on the LPC reusage */
174 10956 : hStereoTD->tdm_lp_reuse_flag = get_indice_st( sts[0], element_brate_adapt, bstr_last_pos - TDM_SECONDARY_SIGNALLING - TDM_RATIO_BITS - TDM_LP_REUSE_BITS, TDM_LP_REUSE_BITS );
175 : }
176 :
177 10956 : sts[0]->tdm_LRTD_flag = hStereoTD->tdm_LRTD_flag; /* the flag was already read in function stereo_memory_dec() */
178 10956 : sts[1]->tdm_LRTD_flag = hStereoTD->tdm_LRTD_flag;
179 :
180 10956 : tdm_inst_ratio_idx = *tdm_ratio_idx;
181 :
182 : /* update past tdm_SM_flag */
183 10956 : hStereoTD->tdm_prev_last_SM_flag = hStereoTD->tdm_last_SM_flag;
184 10956 : hStereoTD->tdm_last_SM_flag = hStereoTD->tdm_SM_flag;
185 :
186 10956 : idx_LRTD_pri_side = -1;
187 10956 : if ( hStereoTD->tdm_LRTD_flag == 1 )
188 : {
189 10602 : idx_LRTD_pri_side = tdm_tmp_SM_LRTD_flag;
190 10602 : hStereoTD->tdm_SM_flag = 0;
191 10602 : if ( tdm_inst_ratio_idx == TDM_NQ )
192 : {
193 300 : hStereoTD->flag_skip_DMX = 1;
194 : }
195 : else
196 : {
197 10302 : hStereoTD->flag_skip_DMX = 0;
198 : }
199 : /* Set primary channel */
200 10602 : *tdm_ratio_idx = LRTD_STEREO_RIGHT_IS_PRIM;
201 10602 : if ( idx_LRTD_pri_side == 1 )
202 : {
203 9825 : *tdm_ratio_idx = LRTD_STEREO_LEFT_IS_PRIM;
204 : }
205 : }
206 : else
207 : {
208 354 : hStereoTD->tdm_SM_flag = tdm_tmp_SM_LRTD_flag;
209 354 : if ( hCPE->nchan_out == 1 )
210 : {
211 : /* in case of mono output, use exclusively the YX upmixing scheme in order to deal with NOOP signals */
212 75 : hStereoTD->tdm_SM_flag = 0;
213 : }
214 : }
215 :
216 10956 : if ( sts[1]->coder_type == INACTIVE && ( *tdm_ratio_idx >= 29 || *tdm_ratio_idx <= 1 ) )
217 : {
218 0 : hStereoTD->tdm_lp_reuse_flag = hStereoTD->tdm_use_IAWB_Ave_lpc;
219 0 : hStereoTD->tdm_use_IAWB_Ave_lpc = 0;
220 : }
221 :
222 : /*sts[1]->tdm_inst_ratio_idx = sts[0]->tdm_inst_ratio_idx;*/
223 :
224 10956 : if ( hCPE->nchan_out == 1 && hCPE->hStereoDftDmx != NULL )
225 3864 : {
226 : /* in mono DMX, only targetGain is needed */
227 3864 : int16_t tmpS = 20;
228 3864 : if ( hStereoTD->tdm_LRTD_flag == 0 )
229 : {
230 75 : tmpS = get_indice_st( sts[0], element_brate_adapt, bstr_last_pos - TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS + STEREO_BITS_TCA_CHAN + STEREO_BITS_TCA_CORRSTATS, STEREO_BITS_TCA_GD );
231 : }
232 3864 : hCPE->hStereoDftDmx->targetGain = usdequant( tmpS, STEREO_TCA_GDMIN, STEREO_TCA_GDSTEP );
233 3864 : hCPE->hStereoDftDmx->targetGain = powf( 10, hCPE->hStereoDftDmx->targetGain );
234 : }
235 : else
236 : {
237 7092 : if ( hStereoTD->tdm_LRTD_flag == 0 )
238 : {
239 279 : hCPE->hStereoTCA->refChanIndx = get_indice_st( sts[0], element_brate_adapt, bstr_last_pos - TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS, STEREO_BITS_TCA_CHAN );
240 279 : hCPE->hStereoTCA->indx_ica_NCShift = get_indice_st( sts[0], element_brate_adapt, bstr_last_pos - TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS + STEREO_BITS_TCA_CHAN, STEREO_BITS_TCA_CORRSTATS );
241 279 : hCPE->hStereoTCA->indx_ica_gD = get_indice_st( sts[0], element_brate_adapt, bstr_last_pos - TDM_SIGNAL_BITS_READ_FROM_THE_END_OF_BS + STEREO_BITS_TCA_CHAN + STEREO_BITS_TCA_CORRSTATS, STEREO_BITS_TCA_GD );
242 : }
243 : else
244 : {
245 6813 : hCPE->hStereoTCA->refChanIndx = L_CH_INDX;
246 6813 : hCPE->hStereoTCA->indx_ica_NCShift = 0;
247 6813 : hCPE->hStereoTCA->indx_ica_gD = 20;
248 : }
249 7092 : hCPE->hStereoTCA->targetGain = usdequant( hCPE->hStereoTCA->indx_ica_gD, STEREO_TCA_GDMIN, STEREO_TCA_GDSTEP );
250 7092 : hCPE->hStereoTCA->targetGain = powf( 10, hCPE->hStereoTCA->targetGain );
251 : }
252 :
253 : #ifdef DEBUG_MODE_TD
254 : dbgwrite( tdm_ratio_idx, 2, 1, 320, "res/tdm_ratio_idx.dec" );
255 : dbgwrite( &tdm_inst_ratio_idx, 2, 1, 320, "res/tdm_inst_ratio_idx.dec" );
256 : dbgwrite( &hStereoTD->tdm_lp_reuse_flag, 2, 1, 320, "res/tdm_lp_reuse_flag.dec" );
257 : #endif
258 :
259 : /* set the BW of the secondary channel */
260 10956 : if ( hStereoTD->tdm_LRTD_flag && sts[1]->bits_frame_channel >= IVAS_16k4 / FRAMES_PER_SEC )
261 : {
262 : /* set BW of the secondary channel in LRTD stereo mode as the BW of the primary channel at higher bitrates */
263 10602 : sts[1]->bwidth = sts[0]->bwidth;
264 : }
265 : else
266 : {
267 : /* limit BW of the secondary channel in LRTD mode to WB for low bitrates */
268 354 : sts[1]->bwidth = WB;
269 : }
270 :
271 : /*----------------------------------------------------------------*
272 : * bitbudget distribution between channels (taking into account also metadata bitbudget)
273 : *----------------------------------------------------------------*/
274 :
275 10956 : tdm_bit_alloc( ivas_format, ism_mode, hCPE->element_brate - nb_bits_metadata * FRAMES_PER_SEC + hCPE->brate_surplus,
276 10956 : hStereoTD->tdm_lp_reuse_flag, &( sts[0]->total_brate ), &( sts[1]->total_brate ),
277 10956 : &hStereoTD->tdm_low_rate_mode, sts[1]->coder_type, *tdm_ratio_idx, hStereoTD->tdm_Pitch_reuse_flag,
278 10956 : sts[0]->bwidth, sts[1]->bwidth, sts[0]->flag_ACELP16k, hStereoTD->tdm_LRTD_flag, mod_ct, tdm_inst_ratio_idx );
279 :
280 10956 : return;
281 : }
282 :
283 :
284 : /*-------------------------------------------------------------------*
285 : * Function tdm_downmix_plain()
286 : *
287 : * downmix Left+Right to Primary+Secondary channel
288 : *-------------------------------------------------------------------*/
289 :
290 50691 : void tdm_upmix_plain(
291 : float Left[], /* o : left channel */
292 : float Right[], /* o : right channel */
293 : const float PCh_2_L[], /* i : primary channel */
294 : const float SCh_2_R[], /* i : secondary channel */
295 : const float LR_ratio, /* i : mixing ratio */
296 : const float inv_den_LR_ratio, /* i : inverse mixing ration */
297 : const int16_t start_index, /* i : start index */
298 : const int16_t end_index, /* i : end index */
299 : const int16_t plus_minus_flag /* i : plus/minus flag */
300 : )
301 : {
302 : int16_t i;
303 :
304 50691 : if ( plus_minus_flag == 1 )
305 : {
306 14584152 : for ( i = start_index; i < end_index; i++ )
307 : {
308 14533530 : Left[i] = ( LR_ratio * ( PCh_2_L[i] - SCh_2_R[i] ) + SCh_2_R[i] ) * inv_den_LR_ratio;
309 14533530 : Right[i] = ( -LR_ratio * ( PCh_2_L[i] + SCh_2_R[i] ) + PCh_2_L[i] ) * inv_den_LR_ratio;
310 : }
311 : }
312 : else
313 : {
314 21189 : for ( i = start_index; i < end_index; i++ )
315 : {
316 21120 : Left[i] = ( LR_ratio * ( PCh_2_L[i] + SCh_2_R[i] ) - SCh_2_R[i] ) * inv_den_LR_ratio;
317 21120 : Right[i] = ( LR_ratio * ( PCh_2_L[i] - SCh_2_R[i] ) - PCh_2_L[i] ) * inv_den_LR_ratio;
318 : }
319 : }
320 :
321 50691 : return;
322 : }
323 :
324 :
325 : /*-------------------------------------------------------------------*
326 : * Function tdm_downmix_fade()
327 : *
328 : * downmix Left+Right to Primary+Secondary channel with fade in/out
329 : *-------------------------------------------------------------------*/
330 :
331 336 : static void tdm_upmix_fade(
332 : float Left[], /* o : left channel */
333 : float Right[], /* o : right channel */
334 : const float PCh_2_L[], /* i : primary channel */
335 : const float SCh_2_R[], /* i : secondary channel */
336 : const float LR_ratio_mem, /* i : last mixing ratio */
337 : const float inv_den_LR_ratio_mem, /* i : last inverse mixing ration */
338 : const float LR_ratio, /* i : mixing ratio */
339 : const float inv_den_LR_ratio, /* i : inverse mixing ration */
340 : const int16_t start_index, /* i : start index */
341 : const int16_t end_index, /* i : end index */
342 : const int16_t fading_type /* i : fading type */
343 : )
344 : {
345 : int16_t i;
346 : float step, step2, fade_in, fade_out;
347 :
348 336 : step = 1.0f / (float) ( end_index - start_index );
349 336 : fade_out = 1.0f;
350 336 : fade_in = 0.0f;
351 :
352 336 : fade_out *= inv_den_LR_ratio_mem;
353 336 : fade_in *= inv_den_LR_ratio;
354 336 : step2 = step * inv_den_LR_ratio;
355 336 : step *= inv_den_LR_ratio_mem;
356 :
357 336 : if ( fading_type == 0 ) /* Switching from YX scheme to SM scheme */
358 : {
359 483 : for ( i = start_index; i < end_index; i++ )
360 : {
361 480 : Left[i] = ( LR_ratio_mem * ( PCh_2_L[i] - SCh_2_R[i] ) + SCh_2_R[i] ) * fade_out + ( LR_ratio * ( PCh_2_L[i] + SCh_2_R[i] ) - SCh_2_R[i] ) * fade_in;
362 480 : Right[i] = ( -LR_ratio_mem * ( PCh_2_L[i] + SCh_2_R[i] ) + PCh_2_L[i] ) * fade_out + ( LR_ratio * ( PCh_2_L[i] - SCh_2_R[i] ) - PCh_2_L[i] ) * fade_in;
363 480 : fade_in += step2;
364 480 : fade_out -= step;
365 : }
366 : }
367 333 : else if ( fading_type == 1 ) /* SM scheme */
368 : {
369 483 : for ( i = start_index; i < end_index; i++ )
370 : {
371 480 : Left[i] = ( LR_ratio_mem * ( PCh_2_L[i] + SCh_2_R[i] ) - SCh_2_R[i] ) * fade_out + ( LR_ratio * ( PCh_2_L[i] + SCh_2_R[i] ) - SCh_2_R[i] ) * fade_in;
372 480 : Right[i] = ( LR_ratio_mem * ( PCh_2_L[i] - SCh_2_R[i] ) - PCh_2_L[i] ) * fade_out + ( LR_ratio * ( PCh_2_L[i] - SCh_2_R[i] ) - PCh_2_L[i] ) * fade_in;
373 480 : fade_in += step2;
374 480 : fade_out -= step;
375 : }
376 : }
377 330 : else if ( fading_type == 2 ) /* Switching from SM scheme to YX scheme */
378 : {
379 0 : for ( i = start_index; i < end_index; i++ )
380 : {
381 0 : Left[i] = ( LR_ratio_mem * ( PCh_2_L[i] + SCh_2_R[i] ) - SCh_2_R[i] ) * fade_out + ( LR_ratio * ( PCh_2_L[i] - SCh_2_R[i] ) + SCh_2_R[i] ) * fade_in;
382 0 : Right[i] = ( LR_ratio_mem * ( PCh_2_L[i] - SCh_2_R[i] ) - PCh_2_L[i] ) * fade_out + ( -LR_ratio * ( PCh_2_L[i] + SCh_2_R[i] ) + PCh_2_L[i] ) * fade_in;
383 0 : fade_in += step2;
384 0 : fade_out -= step;
385 : }
386 : }
387 330 : else if ( fading_type == 3 ) /* YX scheme */
388 : {
389 51930 : for ( i = start_index; i < end_index; i++ )
390 : {
391 51600 : Left[i] = ( LR_ratio_mem * ( PCh_2_L[i] - SCh_2_R[i] ) + SCh_2_R[i] ) * fade_out + ( LR_ratio * ( PCh_2_L[i] - SCh_2_R[i] ) + SCh_2_R[i] ) * fade_in;
392 51600 : Right[i] = ( -LR_ratio_mem * ( PCh_2_L[i] + SCh_2_R[i] ) + PCh_2_L[i] ) * fade_out + ( -LR_ratio * ( PCh_2_L[i] + SCh_2_R[i] ) + PCh_2_L[i] ) * fade_in;
393 51600 : fade_in += step2;
394 51600 : fade_out -= step;
395 : }
396 : }
397 :
398 336 : return;
399 : }
400 :
401 :
402 : /*-------------------------------------------------------------------*
403 : * stereo_tdm_combine()
404 : *
405 : * Combine Primary and Secondary channels into L and R channels
406 : *-------------------------------------------------------------------*/
407 :
408 22305 : void stereo_tdm_combine(
409 : CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */
410 : float *PCh_2_L, /* i/o: Primary channel -> output as left channel */
411 : float *SCh_2_R, /* i/o: Secondary channel -> output as right channel*/
412 : const int16_t output_frame, /* i : Number of samples */
413 : const int16_t flag_HB, /* i : flag to distinguish between core (0) and HB (1) synthesis */
414 : const int16_t tdm_ratio_idx /* i : TDM ratio index */
415 : )
416 : {
417 : int16_t i;
418 : int32_t output_Fs;
419 : float LR_ratio, LR_ratio_mem;
420 : float Left[L_FRAME48k], Right[L_FRAME48k];
421 : int16_t upmixing_delay;
422 : int16_t stereo_tdm_coder_type;
423 : int16_t tdm_n_OVA;
424 22305 : int16_t tdm_last_ratio_idx = hCPE->hStereoTD->tdm_last_ratio_idx;
425 :
426 22305 : output_Fs = hCPE->hCoreCoder[0]->output_Fs;
427 22305 : tdm_n_OVA = NS2SA( output_Fs, TDM_L_NOVA_NS );
428 :
429 22305 : if ( flag_HB )
430 : {
431 10965 : upmixing_delay = NS2SA( output_Fs, ACELP_LOOK_NS + DELAY_BWE_TOTAL_NS );
432 : }
433 : else
434 : {
435 11340 : upmixing_delay = NS2SA( output_Fs, ACELP_LOOK_NS + DELAY_CLDFB_NS );
436 : }
437 :
438 22305 : LR_ratio = tdm_ratio_tabl[tdm_ratio_idx];
439 22305 : LR_ratio_mem = tdm_ratio_tabl[tdm_last_ratio_idx];
440 :
441 22305 : if ( hCPE->hStereoTD->flag_skip_DMX )
442 : {
443 600 : stereo_tdm_coder_type = 10; /* no DMX */
444 600 : mvr2r( PCh_2_L, Left, output_frame );
445 600 : mvr2r( SCh_2_R, Right, output_frame );
446 : }
447 21705 : else if ( hCPE->hStereoTD->tdm_last_SM_flag == 1 )
448 : {
449 36 : if ( hCPE->hStereoTD->tdm_prev_last_SM_flag == 0 )
450 : {
451 3 : stereo_tdm_coder_type = 0; /* mode 1 : Switching from YX scheme to SM scheme*/
452 : }
453 : else
454 : {
455 33 : stereo_tdm_coder_type = 1; /* mode 2 : SM scheme*/
456 : }
457 : }
458 : else
459 : {
460 21669 : if ( hCPE->hStereoTD->tdm_prev_last_SM_flag == 1 )
461 : {
462 0 : stereo_tdm_coder_type = 2; /* mode 3 : Switching from SM scheme to YX scheme*/
463 : }
464 : else
465 : {
466 21669 : stereo_tdm_coder_type = 3; /* mode 4 : YX scheme*/
467 : }
468 : }
469 :
470 22305 : switch ( stereo_tdm_coder_type )
471 : {
472 3 : case ( 0 ):
473 : {
474 : /* Do the upmixing of the first upmixing_delay samples with the old coefficient and formular for YX scheme */
475 3 : tdm_upmix_plain( Left, Right, PCh_2_L, SCh_2_R, LR_ratio_mem, tdm_den_ratio_tabl[tdm_last_ratio_idx], 0, upmixing_delay, 1 );
476 :
477 : /* Switching from YX scheme to SM scheme */
478 3 : tdm_upmix_fade( Left, Right, PCh_2_L, SCh_2_R, LR_ratio_mem, tdm_den_ratio_tabl[tdm_last_ratio_idx], LR_ratio, tdm_den_ratio_tabl[tdm_ratio_idx], upmixing_delay, upmixing_delay + tdm_n_OVA, 0 );
479 :
480 : /* Do the upmixing of the other samples with the new coefficient and formular for SM scheme */
481 3 : tdm_upmix_plain( Left, Right, PCh_2_L, SCh_2_R, LR_ratio, tdm_den_ratio_tabl[tdm_ratio_idx], upmixing_delay + tdm_n_OVA, output_frame, 0 );
482 : }
483 3 : break;
484 33 : case ( 1 ):
485 : {
486 : /* Do the upmixing of the first upmixing_delay samples with the old coefficient and formular for SM scheme */
487 33 : tdm_upmix_plain( Left, Right, PCh_2_L, SCh_2_R, LR_ratio_mem, tdm_den_ratio_tabl[tdm_last_ratio_idx], 0, upmixing_delay, 0 );
488 :
489 : /* Do the upmixing of the other samples with the new coefficient and formular for SM scheme */
490 33 : if ( LR_ratio == LR_ratio_mem )
491 : {
492 30 : tdm_upmix_plain( Left, Right, PCh_2_L, SCh_2_R, LR_ratio_mem, tdm_den_ratio_tabl[tdm_last_ratio_idx], upmixing_delay, output_frame, 0 );
493 : }
494 : else
495 : {
496 3 : tdm_upmix_fade( Left, Right, PCh_2_L, SCh_2_R, LR_ratio_mem, tdm_den_ratio_tabl[tdm_last_ratio_idx], LR_ratio, tdm_den_ratio_tabl[tdm_ratio_idx], upmixing_delay, upmixing_delay + tdm_n_OVA, 1 );
497 3 : tdm_upmix_plain( Left, Right, PCh_2_L, SCh_2_R, LR_ratio, tdm_den_ratio_tabl[tdm_ratio_idx], upmixing_delay + tdm_n_OVA, output_frame, 0 );
498 : }
499 : }
500 33 : break;
501 0 : case ( 2 ):
502 : {
503 : /* Do the upmixing of the first upmixing_delay samples with the old coefficient and formular for SM scheme */
504 0 : tdm_upmix_plain( Left, Right, PCh_2_L, SCh_2_R, LR_ratio_mem, tdm_den_ratio_tabl[tdm_last_ratio_idx], 0, upmixing_delay, 0 );
505 :
506 : /* Switching from SM scheme to YX scheme */
507 0 : tdm_upmix_fade( Left, Right, PCh_2_L, SCh_2_R, LR_ratio_mem, tdm_den_ratio_tabl[tdm_last_ratio_idx], LR_ratio, tdm_den_ratio_tabl[tdm_ratio_idx], upmixing_delay, upmixing_delay + tdm_n_OVA, 2 );
508 :
509 : /* Do the upmixing of the other samples with the new coefficient and formular for YX scheme */
510 0 : tdm_upmix_plain( Left, Right, PCh_2_L, SCh_2_R, LR_ratio, tdm_den_ratio_tabl[tdm_ratio_idx], upmixing_delay + tdm_n_OVA, output_frame, 1 );
511 : }
512 0 : break;
513 21669 : case ( 3 ):
514 : {
515 : /* Do the upmixing of the first upmixing_delay samples with the old coefficient and formular for YX scheme */
516 21669 : tdm_upmix_plain( Left, Right, PCh_2_L, SCh_2_R, LR_ratio_mem, tdm_den_ratio_tabl[tdm_last_ratio_idx], 0, upmixing_delay, 1 );
517 :
518 : /* Do the upmixing of the other samples with the new coefficient and formular for YX scheme */
519 21669 : if ( LR_ratio == LR_ratio_mem )
520 : {
521 21339 : tdm_upmix_plain( Left, Right, PCh_2_L, SCh_2_R, LR_ratio_mem, tdm_den_ratio_tabl[tdm_last_ratio_idx], upmixing_delay, output_frame, 1 );
522 : }
523 : else
524 : {
525 330 : tdm_upmix_fade( Left, Right, PCh_2_L, SCh_2_R, LR_ratio_mem, tdm_den_ratio_tabl[tdm_last_ratio_idx], LR_ratio, tdm_den_ratio_tabl[tdm_ratio_idx], upmixing_delay, upmixing_delay + tdm_n_OVA, 3 );
526 330 : tdm_upmix_plain( Left, Right, PCh_2_L, SCh_2_R, LR_ratio, tdm_den_ratio_tabl[tdm_ratio_idx], upmixing_delay + tdm_n_OVA, output_frame, 1 );
527 : }
528 : }
529 21669 : break;
530 600 : default:
531 600 : break;
532 : }
533 :
534 14351265 : for ( i = 0; i < output_frame; i++ )
535 : {
536 14328960 : PCh_2_L[i] = Left[i];
537 14328960 : SCh_2_R[i] = Right[i];
538 : }
539 :
540 : /* DFT -> TD stereo switching: equalize signal energies */
541 22305 : if ( hCPE->last_element_mode != IVAS_CPE_TD )
542 : {
543 : float incr, fac;
544 :
545 354 : if ( hCPE->hStereoDftDmx != NULL )
546 : {
547 132 : fac = 1.0f;
548 : }
549 : else
550 : {
551 222 : fac = hCPE->hStereoTCA->targetGain;
552 : }
553 :
554 354 : if ( fac < 1.0f )
555 : {
556 0 : incr = ( 1.0f - fac ) / NS2SA( output_Fs, ACELP_LOOK_NS );
557 :
558 0 : for ( i = 0; i < NS2SA( output_Fs, ACELP_LOOK_NS ); i++ )
559 : {
560 0 : PCh_2_L[i] *= fac;
561 0 : fac += incr;
562 : }
563 : }
564 : }
565 :
566 22305 : return;
567 : }
|