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 <math.h>
35 : #include "options.h"
36 : #include "cnst.h"
37 : #include "rom_com.h"
38 : #include "prot_fx.h"
39 : #include "ivas_rom_com.h"
40 : #include "wmc_auto.h"
41 : #ifdef DEBUGGING
42 : #include "debug.h"
43 : #endif
44 : #include "prot_fx_enc.h"
45 : #include "ivas_prot_fx.h"
46 : #include "ivas_rom_com_fx.h"
47 :
48 :
49 : /*-------------------------------------------------------------------*
50 : * stereo_td_init_enc()
51 : *
52 : * Initialize TD stereo encoder
53 : *-------------------------------------------------------------------*/
54 62 : void stereo_td_init_enc_fx(
55 : STEREO_TD_ENC_DATA_HANDLE hStereoTD, /* i/o: TD stereo encoder handle */
56 : const Word16 last_element_mode /* i : last element mode */
57 : )
58 : {
59 62 : hStereoTD->tdm_lt_corr_RM_fx = 167772; // Q24
60 62 : move32();
61 62 : hStereoTD->tdm_lt_corr_LM_fx = 167772; // Q24
62 62 : move32();
63 62 : hStereoTD->tdm_last_ratio_fx = 1073741824; // Q31
64 62 : move32();
65 62 : hStereoTD->tdm_last_ratio_idx = LRTD_STEREO_MID_IS_PRIM;
66 62 : move16();
67 62 : hStereoTD->tdm_lt_rms_L_fx = 2621440; // Q16
68 62 : move32();
69 62 : hStereoTD->tdm_lt_rms_R_fx = 2621440; // Q16
70 62 : move32();
71 62 : hStereoTD->tdm_last_diff_lt_corr_fx = 0;
72 62 : move32();
73 62 : hStereoTD->q_tdm_last_diff_lt_corr = Q31;
74 62 : move16();
75 62 : hStereoTD->tdm_last_ener_lt_R_fx = 0;
76 62 : move32();
77 62 : hStereoTD->tdm_last_ener_lt_L_fx = 0;
78 62 : move32();
79 :
80 62 : hStereoTD->tdm_ratio_transition_mov_flag = 0;
81 62 : move16();
82 62 : hStereoTD->tdm_ratio_transition_cnt = 0;
83 62 : move16();
84 62 : hStereoTD->tdm_noop_mov_flag = 0;
85 62 : move16();
86 62 : hStereoTD->tdm_noop_cnt = 0;
87 62 : move16();
88 62 : hStereoTD->tdm_last_SM_flag = 0;
89 62 : move16();
90 :
91 62 : hStereoTD->tdm_last_ratio_idx = LRTD_STEREO_MID_IS_PRIM;
92 62 : move16();
93 62 : hStereoTD->tdm_prev_stable_idx = LRTD_STEREO_MID_IS_PRIM;
94 62 : move16();
95 62 : hStereoTD->tdm_prev_desired_idx = LRTD_STEREO_MID_IS_PRIM;
96 62 : move16();
97 62 : hStereoTD->tdm_FD2LRTD_SW_cnt = 0;
98 62 : move16();
99 62 : hStereoTD->tdm_LT_es_em_fx = 209715; // Q21
100 62 : move32();
101 62 : hStereoTD->tdm_hyst_cnt = 0;
102 62 : move16();
103 : /* NOOP parameters */
104 62 : hStereoTD->tdm_lt_corr_RM_SM_fx = 167772 /*0.01f Q24*/;
105 62 : move32();
106 62 : hStereoTD->tdm_lt_corr_LM_SM_fx = 167772 /*0.01f Q24*/;
107 62 : hStereoTD->tdm_last_ratio_SM_fx = 1073741824; // Q31
108 62 : move32();
109 62 : hStereoTD->tdm_last_ratio_idx_SM = 0;
110 62 : move16();
111 62 : hStereoTD->q_tdm_last_diff_lt_corr_SM = Q31;
112 62 : move16();
113 62 : hStereoTD->tdm_lt_rms_L_SM_fx = 2621440; // Q16
114 62 : move32();
115 62 : hStereoTD->tdm_lt_rms_R_SM_fx = 2621440; // Q16
116 62 : move32();
117 62 : hStereoTD->tdm_last_diff_lt_corr_SM_fx = 0;
118 62 : move32();
119 62 : hStereoTD->q_tdm_last_diff_lt_corr_SM = Q31;
120 62 : move16();
121 62 : hStereoTD->tdm_last_ener_lt_R_SM_fx = 0;
122 62 : move32();
123 62 : hStereoTD->tdm_last_ener_lt_L_SM_fx = 0;
124 62 : move32();
125 62 : hStereoTD->tdm_noop_mov_flag = 0;
126 62 : move16();
127 62 : hStereoTD->tdm_NOOP_cnt = 0;
128 62 : move16();
129 62 : hStereoTD->tdm_last_SM_flag_noop = 0;
130 62 : move16();
131 62 : hStereoTD->tdm_last_ratio_idx_SM = LRTD_STEREO_MID_IS_PRIM;
132 62 : move16();
133 62 : hStereoTD->tdm_prev_stable_idx_SM = LRTD_STEREO_MID_IS_PRIM;
134 62 : move16();
135 62 : hStereoTD->tdm_prev_desired_idx_SM = LRTD_STEREO_MID_IS_PRIM;
136 62 : move16();
137 62 : hStereoTD->tdm_LT_es_em_SM_fx = 209715; // Q21
138 62 : move32();
139 62 : hStereoTD->tdm_hyst_cnt_SM = 0;
140 62 : move16();
141 62 : hStereoTD->tdm_noop_cnt = 0;
142 62 : move16();
143 62 : hStereoTD->tdm_SM_flag = 0;
144 62 : move16();
145 62 : hStereoTD->tdm_SM_last_clas[0] = VOICED_CLAS;
146 62 : move16();
147 62 : hStereoTD->tdm_SM_last_clas[1] = VOICED_CLAS;
148 62 : move16();
149 62 : hStereoTD->tdm_SM_last2_clas[0] = VOICED_CLAS;
150 62 : move16();
151 62 : hStereoTD->tdm_SM_last2_clas[1] = VOICED_CLAS;
152 62 : move16();
153 62 : hStereoTD->tdm_SM_modi_flag = 0;
154 62 : move16();
155 62 : hStereoTD->tdm_SM_reset_flag = 0;
156 62 : move16();
157 62 : hStereoTD->prev_fr_LRTD_TD_dec = 0;
158 62 : move16();
159 62 : hStereoTD->tdm_LRTD_flag = 0;
160 62 : move16();
161 62 : hStereoTD->tdm_inst_ratio_idx = LRTD_STEREO_RIGHT_IS_PRIM;
162 62 : move16();
163 62 : hStereoTD->tdm_last_inst_ratio_idx = LRTD_STEREO_MID_IS_PRIM;
164 62 : move16();
165 62 : hStereoTD->tdm_last_LRTD_frame_cnt = 0;
166 62 : move16();
167 62 : hStereoTD->tdm_vad_hangover_cnt = 0;
168 62 : move16();
169 62 : hStereoTD->tdm_ini_frame_cnt = 0;
170 62 : move16();
171 62 : hStereoTD->tdm_last_LRTD_PriCh_cnt = 0;
172 62 : move16();
173 :
174 62 : hStereoTD->flag_skip_DMX = 0;
175 62 : move16();
176 62 : IF( EQ_16( last_element_mode, IVAS_CPE_MDCT ) )
177 : {
178 8 : hStereoTD->flag_skip_DMX = 1;
179 8 : move16();
180 8 : hStereoTD->prev_fr_LRTD_TD_dec = 1;
181 8 : move16();
182 8 : hStereoTD->tdm_last_ratio_fx = MAX_32; // Q31
183 8 : move32();
184 8 : hStereoTD->tdm_last_ratio_idx = LRTD_STEREO_LEFT_IS_PRIM;
185 8 : move16();
186 8 : hStereoTD->tdm_prev_stable_idx = LRTD_STEREO_LEFT_IS_PRIM;
187 8 : move16();
188 8 : hStereoTD->tdm_prev_desired_idx = LRTD_STEREO_LEFT_IS_PRIM;
189 8 : move16();
190 : }
191 :
192 62 : hStereoTD->tdm_hBstr_tmp.ind_list = hStereoTD->tdm_ind_list_tmp;
193 62 : hStereoTD->tdm_hBstr_tmp.ivas_ind_list_zero = (Indice **) ( &hStereoTD->tdm_hBstr_tmp.ind_list );
194 62 : hStereoTD->max_ind_tdm_tmp = MAX_IND_TDM_TMP;
195 62 : move32();
196 62 : hStereoTD->tdm_hBstr_tmp.ivas_max_num_indices = &hStereoTD->max_ind_tdm_tmp;
197 62 : hStereoTD->tdm_hBstr_tmp.st_ivas = NULL;
198 62 : reset_indices_enc_fx( &hStereoTD->tdm_hBstr_tmp, MAX_IND_TDM_TMP );
199 :
200 62 : return;
201 : }
202 :
203 : /*-------------------------------------------------------------------*
204 : * stereo_set_tdm()
205 : *
206 : * Set TD stereo encoder parameters
207 : *-------------------------------------------------------------------*/
208 :
209 410255 : ivas_error stereo_set_tdm_fx(
210 : CPE_ENC_HANDLE hCPE, /* i : CPE encoder structure */
211 : const Word16 input_frame, /* i : input frame length per channel */
212 : Word16 input_q )
213 : {
214 : Encoder_State **sts;
215 410255 : sts = hCPE->hCoreCoder;
216 : ivas_error error;
217 :
218 410255 : error = IVAS_ERR_OK;
219 :
220 : /* initialize TD stereo parameters */
221 410255 : IF( hCPE->hStereoTD != NULL )
222 : {
223 3827 : hCPE->hStereoTD->tdm_lp_reuse_flag = 0;
224 3827 : move16();
225 3827 : hCPE->hStereoTD->tdm_low_rate_mode = 0;
226 3827 : move16();
227 3827 : hCPE->hStereoTD->tdm_Pitch_reuse_flag = 0;
228 3827 : move16();
229 :
230 3827 : IF( EQ_16( hCPE->hStereoClassif->lrtd_mode, 1 ) )
231 : {
232 : /* initialize this flag when uncorrelated L&R channels have been detected in the previous frame */
233 3827 : test();
234 3827 : test();
235 3827 : IF( EQ_16( hCPE->hStereoTD->prev_fr_LRTD_TD_dec, 1 ) || NE_16( hCPE->last_element_mode, IVAS_CPE_TD ) || LT_16( hCPE->hStereoTD->tdm_FD2LRTD_SW_cnt, 5 ) )
236 : {
237 3698 : hCPE->hStereoTD->tdm_LRTD_flag = 1;
238 3698 : move16();
239 : }
240 : ELSE
241 : {
242 129 : hCPE->hStereoTD->tdm_LRTD_flag = 0;
243 129 : move16();
244 : }
245 : }
246 : ELSE
247 : {
248 0 : hCPE->hStereoTD->tdm_LRTD_flag = hCPE->hStereoTD->prev_fr_LRTD_TD_dec;
249 0 : move16();
250 : }
251 :
252 : #ifdef DEBUG_MODE_INFO
253 : dbgwrite( &hCPE->hStereoTD->tdm_LRTD_flag, 2, 1, (int16_t) ( hCPE->hCoreCoder[0]->input_Fs / FRAMES_PER_SEC ), "res/tdm_LRTD_flag" );
254 : #endif
255 :
256 :
257 : /* normal TD / LRTD switching */
258 3827 : IF( EQ_16( hCPE->hStereoTD->tdm_LRTD_flag, 0 ) )
259 : {
260 : Encoder_State *st;
261 129 : st = hCPE->hCoreCoder[1];
262 :
263 : /* deallocate CLDFB ana for secondary channel */
264 129 : IF( st->cldfbAnaEnc != NULL )
265 : {
266 37 : deleteCldfb_ivas_fx( &st->cldfbAnaEnc );
267 : }
268 :
269 : /* deallocate BWEs for secondary channel */
270 129 : IF( st->hBWE_TD != NULL )
271 : {
272 37 : IF( st->hBWE_TD != NULL )
273 : {
274 37 : free( st->hBWE_TD );
275 37 : st->hBWE_TD = NULL;
276 : }
277 :
278 37 : deleteCldfb_ivas_fx( &st->cldfbSynTd );
279 :
280 37 : IF( st->hBWE_FD != NULL )
281 : {
282 37 : free( st->hBWE_FD );
283 37 : st->hBWE_FD = NULL;
284 : }
285 : }
286 :
287 : /* allocate ICBWE structure */
288 129 : IF( hCPE->hStereoICBWE == NULL )
289 : {
290 37 : IF( ( hCPE->hStereoICBWE = (STEREO_ICBWE_ENC_HANDLE) malloc( sizeof( STEREO_ICBWE_ENC_DATA ) ) ) == NULL )
291 : {
292 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Stereo ICBWE \n" ) );
293 : }
294 37 : stereo_icBWE_init_enc_fx( hCPE->hStereoICBWE );
295 : }
296 : }
297 : ELSE /* tdm_LRTD_flag == 1 */
298 : {
299 : Encoder_State *st;
300 3698 : st = hCPE->hCoreCoder[1];
301 :
302 : /* deallocate ICBWE structure */
303 3698 : IF( hCPE->hStereoICBWE != NULL )
304 : {
305 56 : free( hCPE->hStereoICBWE );
306 56 : hCPE->hStereoICBWE = NULL;
307 : }
308 :
309 : /* allocate CLDFB ana for secondary channel */
310 3698 : IF( st->cldfbAnaEnc == NULL )
311 : {
312 64 : IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS, ENC ) ), IVAS_ERR_OK ) )
313 : {
314 0 : return error;
315 : }
316 : }
317 :
318 : /* allocate BWEs for secondary channel */
319 3698 : IF( st->hBWE_TD == NULL )
320 : {
321 64 : IF( ( st->hBWE_TD = (TD_BWE_ENC_HANDLE) malloc( sizeof( TD_BWE_ENC_DATA ) ) ) == NULL )
322 : {
323 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD BWE\n" ) );
324 : }
325 64 : IF( NE_32( ( error = openCldfb_ivas_fx( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS, ENC ) ), IVAS_ERR_OK ) )
326 : {
327 0 : return error;
328 : }
329 :
330 64 : InitSWBencBuffer_ivas_fx( st );
331 64 : ResetSHBbuffer_Enc_fx( st );
332 :
333 64 : IF( ( st->hBWE_FD = (FD_BWE_ENC_HANDLE) malloc( sizeof( FD_BWE_ENC_DATA ) ) ) == NULL )
334 : {
335 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FD BWE\n" ) );
336 : }
337 :
338 64 : fd_bwe_enc_init_fx( st->hBWE_FD );
339 64 : st->Q_old_wtda = 0;
340 64 : move16();
341 : }
342 : }
343 :
344 3827 : IF( hCPE->hStereoClassif->lrtd_mode == 0 )
345 : {
346 0 : hCPE->hStereoTD->tdm_FD2LRTD_SW_cnt = 0;
347 0 : move16();
348 : }
349 3827 : hCPE->hStereoTD->tdm_FD2LRTD_SW_cnt = s_min( 100, hCPE->hStereoTD->tdm_FD2LRTD_SW_cnt + 1 );
350 3827 : move16();
351 3827 : stereo_tdm_prep_dwnmx_fx( hCPE, sts[1]->input32_fx, input_frame, input_q );
352 : }
353 : ELSE
354 : {
355 : #ifdef DEBUG_MODE_INFO
356 : {
357 : int16_t tmp = -2;
358 : dbgwrite( &tmp, 2, 1, (int16_t) ( hCPE->hCoreCoder[0]->input_Fs / FRAMES_PER_SEC ), "res/tdm_LRTD_flag" );
359 : }
360 : #endif
361 406428 : hCPE->hCoreCoder[0]->tdm_LRTD_flag = 0;
362 406428 : move16();
363 406428 : hCPE->hCoreCoder[1]->tdm_LRTD_flag = 0;
364 406428 : move16();
365 : }
366 :
367 410255 : return error;
368 : }
369 : /*-------------------------------------------------------------------*
370 : * tdm_configure_enc()
371 : *
372 : * Configure TD stereo encoder
373 : *-------------------------------------------------------------------*/
374 3827 : void tdm_configure_enc_fx(
375 : const Word16 ivas_format, /* i : IVAS format */
376 : const Word16 ism_mode, /* i : ISM mode in combined format */
377 : CPE_ENC_HANDLE hCPE, /* i : CPE encoder structure */
378 : const Word16 Etot_last_fx[CPE_CHANNELS], /* i/o: Energy of last frame Q8*/
379 : const Word16 tdm_SM_or_LRTD_Pri, /* i : channel combination scheme flag in TD stereo OR LRTD primary channel */
380 : const Word16 tdm_ratio_idx, /* i : ratio index */
381 : const Word16 tdm_ratio_idx_SM, /* i : ratio index in SM mode */
382 : const Word16 attack_flag, /* i : Primary channel attack flag */
383 : const Word16 nb_bits_metadata /* i : number of metadata bits */
384 : )
385 : {
386 : Word16 tdm_ratio_bit_alloc_idx, mod_ct;
387 : STEREO_TD_ENC_DATA_HANDLE hStereoTD;
388 : Encoder_State **sts;
389 : Word16 loc_coder_tyape_raw0;
390 3827 : hStereoTD = hCPE->hStereoTD;
391 3827 : sts = hCPE->hCoreCoder;
392 3827 : loc_coder_tyape_raw0 = sts[0]->coder_type_raw;
393 3827 : move16();
394 :
395 : /*----------------------------------------------------------------*
396 : * Overwrite certain decisions depending on the input
397 : *----------------------------------------------------------------*/
398 :
399 3827 : hStereoTD->tdm_use_IAWB_Ave_lpc = 0; /* Flag initialisation */
400 3827 : move16();
401 3827 : sts[0]->hSpMusClas->tdm_lt_Etot_fx = add( mult( 3277 /*0.1f in Q15*/, Etot_last_fx[0] ), mult( 29491 /* 0.9f*/, sts[0]->hSpMusClas->tdm_lt_Etot_fx ) );
402 3827 : move16();
403 3827 : sts[1]->hSpMusClas->tdm_lt_Etot_fx = add( mult( 3277 /*0.1f in Q15*/, Etot_last_fx[1] ), mult( 29491 /* 0.9f*/, sts[1]->hSpMusClas->tdm_lt_Etot_fx ) );
404 3827 : move16();
405 :
406 3827 : test();
407 3827 : test();
408 3827 : test();
409 3827 : test();
410 3827 : test();
411 3827 : test();
412 3827 : test();
413 3827 : test();
414 3827 : test();
415 3827 : test();
416 3827 : test();
417 3827 : test();
418 3827 : test();
419 3827 : test();
420 3827 : test();
421 3827 : test();
422 3827 : test();
423 3827 : test();
424 3827 : test();
425 3827 : test();
426 3827 : test();
427 3827 : test();
428 3827 : test();
429 3827 : test();
430 3827 : test();
431 3827 : IF( hCPE->hStereoClassif->lrtd_mode == 0 && ( ( sts[1]->hSpMusClas->tdm_lt_Etot_fx < 0 && hCPE->hCoreCoder[1]->vad_flag == 0 ) /* very clean signal */
432 : || ( hCPE->hCoreCoder[1]->vad_flag == 0 || ( LT_16( Etot_last_fx[1], 7680 /*30.0f*/ ) && GT_16( sub( sts[0]->hSpMusClas->tdm_lt_Etot_fx, sts[1]->hSpMusClas->tdm_lt_Etot_fx ), 6656 /*26.0f*/ ) ) ) ) )
433 : {
434 0 : sts[1]->coder_type = INACTIVE;
435 0 : move16();
436 :
437 0 : test();
438 0 : if ( hStereoTD->tdm_lp_reuse_flag == 0 && hCPE->hCoreCoder[0]->vad_flag != 0 )
439 : {
440 0 : hStereoTD->tdm_use_IAWB_Ave_lpc = 1;
441 0 : move16();
442 : }
443 0 : hStereoTD->tdm_lp_reuse_flag = 1;
444 0 : move16();
445 : }
446 3827 : ELSE IF( ( ( hCPE->hCoreCoder[1]->vad_flag == 0 ) || ( hCPE->hCoreCoder[0]->vad_flag == 0 && LT_16( Etot_last_fx[1], 7680 /*30.0f*/ ) && GT_16( sub( sts[0]->hSpMusClas->tdm_lt_Etot_fx, sts[1]->hSpMusClas->tdm_lt_Etot_fx ), 6656 /*26.0f*/ ) ) ) && ( EQ_16( hCPE->hStereoClassif->lrtd_mode, 1 ) ) /* && NO_DTX */ ) /* boths channels are inactive but not DTX used*/
447 : {
448 0 : sts[1]->coder_type = INACTIVE;
449 0 : move16();
450 0 : IF( GT_16( tdm_ratio_idx, 1 ) && LT_16( tdm_ratio_idx, 29 ) )
451 : {
452 0 : if ( hStereoTD->tdm_lp_reuse_flag == 0 && hCPE->hCoreCoder[0]->vad_flag != 0 )
453 : {
454 0 : hStereoTD->tdm_use_IAWB_Ave_lpc = 1;
455 0 : move16();
456 : }
457 0 : hStereoTD->tdm_lp_reuse_flag = 1;
458 0 : move16();
459 : }
460 : }
461 3827 : ELSE IF( !( sts[1]->sp_aud_decision0 ) && sts[1]->tc_cnt <= 0 && ( EQ_16( sts[1]->coder_type_raw, UNVOICED ) || ( EQ_16( hStereoTD->tdm_LRTD_flag, 1 ) && hStereoTD->tdm_lp_reuse_flag == 0 && ( hCPE->hCoreCoder[1]->vad_flag == 0 || ( LT_16( Etot_last_fx[1], 7680 /*30.0f*/ ) && GT_16( sub( sts[0]->hSpMusClas->tdm_lt_Etot_fx, sts[1]->hSpMusClas->tdm_lt_Etot_fx ), 6656 /*26.0f*/ ) ) ) ) ) )
462 : {
463 327 : sts[1]->coder_type = UNVOICED;
464 327 : move16();
465 327 : if ( EQ_16( hStereoTD->tdm_LRTD_flag, 1 ) )
466 : {
467 267 : hStereoTD->tdm_lp_reuse_flag = 0;
468 267 : move16();
469 : }
470 : }
471 3500 : ELSE IF( ( LT_16( sts[1]->coder_type, AUDIO ) && NE_16( sts[1]->coder_type, UNVOICED ) ) || /* TC and VC are not supported in secondary channel */
472 : ( ( EQ_16( sts[1]->coder_type, AUDIO ) && LE_32( hCPE->element_brate, IVAS_24k4 ) ) || ( EQ_16( sts[0]->sp_aud_decision1, 1 ) && GE_32( hCPE->element_brate, IVAS_16k4 ) ) || ( EQ_16( sts[1]->sp_aud_decision0, 1 ) && GT_32( hCPE->element_brate, IVAS_13k2 ) ) ) )
473 : {
474 3500 : sts[1]->coder_type = GENERIC;
475 3500 : move16();
476 : }
477 0 : ELSE IF( EQ_16( sts[1]->coder_type, GENERIC ) && EQ_16( sts[1]->coder_type_raw, UNVOICED ) )
478 : {
479 0 : hStereoTD->tdm_lp_reuse_flag = 0;
480 0 : move16();
481 : }
482 :
483 3827 : test();
484 3827 : IF( GT_32( hCPE->element_brate, IVAS_24k4 ) && EQ_16( hCPE->hStereoClassif->lrtd_mode, 1 ) )
485 : {
486 2127 : if ( EQ_16( sts[1]->coder_type, UNVOICED ) )
487 : {
488 199 : sts[1]->coder_type = GENERIC;
489 199 : move16();
490 : }
491 :
492 2127 : IF( EQ_16( sts[0]->coder_type, UNVOICED ) )
493 : {
494 174 : sts[0]->coder_type = GENERIC;
495 174 : move16();
496 174 : loc_coder_tyape_raw0 = GENERIC;
497 174 : move16();
498 : }
499 : }
500 3827 : test();
501 3827 : test();
502 3827 : IF( GE_32( hCPE->element_brate, IVAS_24k4 ) && hCPE->hStereoClassif->lrtd_mode == 0 && EQ_16( sts[0]->coder_type, UNVOICED ) )
503 : {
504 0 : sts[0]->coder_type = GENERIC;
505 0 : move16();
506 0 : loc_coder_tyape_raw0 = GENERIC;
507 0 : move16();
508 : }
509 :
510 3827 : if ( NE_16( sts[1]->coder_type, GENERIC ) )
511 : {
512 128 : hStereoTD->tdm_Pitch_reuse_flag = 0;
513 128 : move16();
514 : }
515 :
516 3827 : IF( attack_flag != 0 )
517 : {
518 79 : if ( sts[1]->coder_type != INACTIVE )
519 : {
520 79 : hStereoTD->tdm_lp_reuse_flag = 0; /* Do not allow the LP filter reusing on TC or attack in the primary channel */
521 79 : move16();
522 : }
523 : }
524 3827 : test();
525 3827 : IF( tdm_SM_or_LRTD_Pri && hStereoTD->tdm_LRTD_flag == 0 )
526 : {
527 0 : tdm_ratio_bit_alloc_idx = tdm_ratio_idx_SM;
528 0 : move16();
529 : }
530 : ELSE
531 : {
532 3827 : tdm_ratio_bit_alloc_idx = tdm_ratio_idx;
533 3827 : move16();
534 : }
535 3827 : test();
536 3827 : test();
537 3827 : test();
538 3827 : test();
539 3827 : if ( ( EQ_16( hCPE->hStereoClassif->lrtd_mode, 1 ) && GE_16( sts[1]->coder_type, UNVOICED ) && GT_16( abs_s( sub( hStereoTD->tdm_last_ratio_idx, tdm_ratio_bit_alloc_idx ) ), 15 ) ) /* channel inversion in lrtd */
540 3792 : || ( LT_16( hStereoTD->tdm_FD2LRTD_SW_cnt, 4 ) && LT_16( hStereoTD->tdm_last_LRTD_frame_cnt, 4 ) ) )
541 : {
542 219 : sts[1]->coder_type = GENERIC;
543 219 : move16();
544 : }
545 :
546 3827 : IF( LT_32( L_sub( L_add( hCPE->element_brate, hCPE->brate_surplus ), L_mult0( nb_bits_metadata, FRAMES_PER_SEC ) ), 12000 ) )
547 : {
548 0 : if ( EQ_16( sts[1]->coder_type, UNVOICED ) )
549 : {
550 0 : sts[1]->coder_type = GENERIC;
551 0 : move16();
552 : }
553 0 : hStereoTD->tdm_lp_reuse_flag = 1;
554 0 : move16();
555 :
556 0 : if ( LT_32( L_sub( L_add( hCPE->element_brate, hCPE->brate_surplus ), L_mult0( nb_bits_metadata, FRAMES_PER_SEC ) ), 11000 ) )
557 : {
558 0 : sts[1]->coder_type = INACTIVE;
559 0 : move16();
560 : }
561 : }
562 :
563 3827 : IF( LT_32( L_sub( L_add( hCPE->element_brate, hCPE->brate_surplus ), L_mult0( nb_bits_metadata, FRAMES_PER_SEC ) ), 14700 ) )
564 : {
565 0 : if ( EQ_16( sts[0]->coder_type, TRANSITION ) )
566 : {
567 0 : sts[0]->coder_type = GENERIC;
568 0 : move16();
569 : }
570 : }
571 :
572 3827 : mod_ct = AUDIO;
573 3827 : move16();
574 3827 : IF( LT_32( hCPE->element_brate, IVAS_24k4 ) )
575 : {
576 581 : test();
577 581 : test();
578 581 : test();
579 581 : test();
580 581 : test();
581 581 : test();
582 581 : test();
583 581 : test();
584 581 : test();
585 : /* In TD stereo, the TRANSITION mode has a specific bit allocation. All other formats share the same bit allocation. For these other formats, `mod_ct` is set to AUDIO to aid in debugging, though it does not have any functional impact. */
586 1162 : if ( !( sts[0]->localVAD == 0 && EQ_16( sts[0]->coder_type, TRANSITION ) ) &&
587 1141 : ( EQ_16( sts[0]->coder_type, TRANSITION ) ||
588 1120 : ( ( ( GE_16( sts[0]->last_L_frame, L_FRAME16k ) && sts[0]->flag_ACELP16k == 0 ) ||
589 1116 : ( EQ_16( sts[0]->last_L_frame, L_FRAME ) && EQ_16( sts[0]->flag_ACELP16k, 1 ) ) ) &&
590 4 : ( sts[0]->last_core_brate != FRAME_NO_DATA ) &&
591 4 : NE_32( sts[0]->last_core_brate, SID_2k40 ) &&
592 2 : NE_16( sts[0]->coder_type_raw, VOICED ) ) ) )
593 : {
594 23 : mod_ct = TRANSITION;
595 23 : move16();
596 : }
597 : }
598 :
599 :
600 : /* Correction of tdm_inst_ratio_idx in case of TC in the seecondary channel */
601 3827 : test();
602 3827 : test();
603 3827 : IF( hStereoTD->flag_skip_DMX == 0 && EQ_16( hStereoTD->tdm_LRTD_flag, 1 ) && GT_16( sts[1]->tc_cnt, 1 ) /*&& abs(hStereoTD->tdm_inst_ratio_idx-LRTD_STEREO_MID_IS_PRIM) > 5*/ )
604 : {
605 145 : IF( tdm_SM_or_LRTD_Pri == 0 ) /* Primary is right */
606 : {
607 0 : hStereoTD->tdm_inst_ratio_idx = add( hStereoTD->tdm_inst_ratio_idx, LRTD_STEREO_QUARTER_RANGE );
608 0 : move16();
609 : }
610 145 : ELSE IF( EQ_16( tdm_SM_or_LRTD_Pri, 1 ) ) /* Primary is left */
611 : {
612 145 : hStereoTD->tdm_inst_ratio_idx = sub( hStereoTD->tdm_inst_ratio_idx, LRTD_STEREO_QUARTER_RANGE );
613 145 : move16();
614 : }
615 145 : hStereoTD->tdm_inst_ratio_idx = check_bounds_s_fx( hStereoTD->tdm_inst_ratio_idx, 8, 22 );
616 145 : move16();
617 : }
618 :
619 : /*----------------------------------------------------------------*
620 : * bitbudget distribution between channels (taking into account also metadata bitbudget)
621 : *----------------------------------------------------------------*/
622 :
623 3827 : tdm_bit_alloc( ivas_format, ism_mode, L_sub( L_add( hCPE->element_brate, hCPE->brate_surplus ), L_mult0( nb_bits_metadata, FRAMES_PER_SEC ) ),
624 3827 : hStereoTD->tdm_lp_reuse_flag, &( sts[0]->total_brate ), &( sts[1]->total_brate ),
625 3827 : &( hStereoTD->tdm_low_rate_mode ), sts[1]->coder_type, tdm_ratio_bit_alloc_idx, hStereoTD->tdm_Pitch_reuse_flag,
626 3827 : sts[0]->bwidth, sts[1]->bwidth, sts[0]->flag_ACELP16k, hStereoTD->tdm_LRTD_flag, mod_ct, hStereoTD->tdm_inst_ratio_idx );
627 3827 : test();
628 3827 : if ( sts[0]->GSC_IVAS_mode > 0 && LE_32( sts[0]->total_brate, STEREO_GSC_BIT_RATE_ALLOC ) )
629 : {
630 5 : sts[0]->GSC_IVAS_mode = 0;
631 5 : move16();
632 : }
633 3827 : test();
634 3827 : test();
635 3827 : if ( sts[1]->GSC_IVAS_mode > 0 && ( LE_32( sts[1]->total_brate, STEREO_GSC_BIT_RATE_ALLOC ) || EQ_16( hStereoTD->tdm_low_rate_mode, 1 ) ) )
636 : {
637 0 : sts[1]->GSC_IVAS_mode = 0;
638 0 : move16();
639 : }
640 3827 : test();
641 3827 : IF( EQ_16( sts[0]->coder_type, GENERIC ) && EQ_16( loc_coder_tyape_raw0, UNVOICED ) )
642 : {
643 0 : if ( LT_32( sts[0]->total_brate, MAX_UNVOICED_BRATE ) )
644 : {
645 0 : sts[0]->coder_type = UNVOICED;
646 0 : move16();
647 : }
648 : }
649 :
650 : /*----------------------------------------------------------------*
651 : * Bitstream writing
652 : *----------------------------------------------------------------*/
653 :
654 : /* transmit the ratio index */
655 3827 : test();
656 3827 : IF( tdm_SM_or_LRTD_Pri && hStereoTD->tdm_LRTD_flag == 0 )
657 : {
658 0 : push_indice( &hStereoTD->tdm_hBstr_tmp, IND_STEREO_TD_ALPHA, tdm_ratio_idx_SM, TDM_RATIO_BITS );
659 : }
660 : ELSE
661 : {
662 3827 : IF( EQ_16( hStereoTD->tdm_LRTD_flag, 1 ) )
663 : {
664 3698 : push_indice( &hStereoTD->tdm_hBstr_tmp, IND_STEREO_TD_ALPHA, hStereoTD->tdm_inst_ratio_idx, TDM_RATIO_BITS );
665 : }
666 : ELSE
667 : {
668 129 : push_indice( &hStereoTD->tdm_hBstr_tmp, IND_STEREO_TD_ALPHA, tdm_ratio_idx, TDM_RATIO_BITS );
669 : }
670 : }
671 :
672 : /* LPC reuse flag */
673 3827 : test();
674 3827 : test();
675 3827 : IF( sts[1]->coder_type == INACTIVE && LT_16( tdm_ratio_idx, 29 ) && GT_16( tdm_ratio_idx, 1 ) )
676 : {
677 : /* normal TD, tdm_lp_reuse_flag always on, tdm_use_IAWB_Ave_lpc varies tdm_ratio_idx<29 && tdm_ratio_idx> 1*/
678 0 : push_indice( &hStereoTD->tdm_hBstr_tmp, IND_STEREO_LPC_REUSE, hStereoTD->tdm_use_IAWB_Ave_lpc, TDM_LP_REUSE_BITS );
679 : }
680 : ELSE
681 : {
682 3827 : push_indice( &hStereoTD->tdm_hBstr_tmp, IND_STEREO_LPC_REUSE, hStereoTD->tdm_lp_reuse_flag, TDM_LP_REUSE_BITS );
683 : }
684 :
685 : /* LRTD flag */
686 3827 : push_indice( &hStereoTD->tdm_hBstr_tmp, IND_STEREO_LRTD_FLAG, hStereoTD->tdm_LRTD_flag, TDM_LR_CONTENT_BITS );
687 :
688 : /* Stereo ICA parameters */
689 3827 : IF( hStereoTD->tdm_LRTD_flag == 0 )
690 : {
691 129 : push_indice( &hStereoTD->tdm_hBstr_tmp, IND_STEREO_REFCHAN, hCPE->hStereoTCA->refChanIndx, STEREO_BITS_TCA_CHAN );
692 129 : push_indice( &hStereoTD->tdm_hBstr_tmp, IND_STEREO_CORRSTATS, hCPE->hStereoTCA->indx_ica_NCShift, STEREO_BITS_TCA_CORRSTATS );
693 129 : push_indice( &hStereoTD->tdm_hBstr_tmp, IND_STEREO_GD, hCPE->hStereoTCA->indx_ica_gD, STEREO_BITS_TCA_GD );
694 : }
695 :
696 :
697 : /*----------------------------------------------------------------*
698 : * Updates
699 : *----------------------------------------------------------------*/
700 :
701 3827 : hStereoTD->tdm_last_ratio_idx = tdm_ratio_idx;
702 3827 : move16();
703 3827 : hStereoTD->tdm_last_ratio_idx_SM = tdm_ratio_idx_SM;
704 3827 : move16();
705 3827 : hStereoTD->tdm_last_SM_flag = tdm_SM_or_LRTD_Pri;
706 3827 : move16();
707 :
708 3827 : if ( EQ_16( hStereoTD->tdm_LRTD_flag, 1 ) )
709 : {
710 3698 : hStereoTD->tdm_last_SM_flag = 0;
711 3698 : move16();
712 : }
713 :
714 3827 : hStereoTD->tdm_last_inst_ratio_idx = hStereoTD->tdm_inst_ratio_idx;
715 3827 : move16();
716 :
717 3827 : return;
718 : }
719 :
720 : /*-------------------------------------------------------------------*
721 : * signaling_enc_secondary()
722 : *
723 : * Signalling of the secondary channel
724 : *-------------------------------------------------------------------*/
725 :
726 3827 : ivas_error signaling_enc_secondary_fx(
727 : Encoder_State *st, /* i/o: Encoder structure */
728 : const Word16 tdm_SM_or_LRTD_Pri, /* i : channel combination scheme flag OR LRTD primary channel */
729 : const Word16 tdm_Pitch_reuse_flag /* i : primary channel pitch reuse flag*/
730 : )
731 : {
732 : Word16 ind;
733 3827 : BSTR_ENC_HANDLE hBstr = st->hBstr;
734 : ivas_error error;
735 :
736 3827 : error = IVAS_ERR_OK;
737 3827 : move32();
738 :
739 : /* The secondary channel band-witdh is always the same as the primary channel bandwidth */
740 :
741 3827 : ind = st->coder_type;
742 3827 : move16();
743 3827 : IF( EQ_16( tdm_Pitch_reuse_flag, 1 ) ) /* possible only for bitrate <= 24400 */
744 : {
745 35 : ind = 3;
746 35 : move16();
747 : }
748 3792 : ELSE IF( EQ_16( st->coder_type, GENERIC ) )
749 : {
750 3697 : ind = 2;
751 3697 : move16();
752 : }
753 95 : ELSE IF( EQ_16( st->coder_type, AUDIO ) )
754 : {
755 0 : ind = sub( ind, 2 );
756 : }
757 :
758 3827 : ind = shl( ind, 1 );
759 3827 : ind = add( ind, tdm_SM_or_LRTD_Pri ); /* addition of the channel combination scheme flag value or the LRTD primary channel*/
760 3827 : push_indice( hBstr, IND_STEREO_2ND_CODER_T, ind, TDM_SECONDARY_SIGNALLING );
761 :
762 : /* write extension layer flag to distinguish between TBE (0) and BWE (1) */
763 3827 : IF( st->extl_brate > 0 )
764 : {
765 2860 : test();
766 2860 : test();
767 2860 : test();
768 2860 : test();
769 2860 : IF( EQ_16( st->extl, WB_TBE ) || EQ_16( st->extl, SWB_TBE ) || EQ_16( st->extl, FB_TBE ) )
770 : {
771 2860 : push_indice( hBstr, IND_BWE_FLAG, 0, 1 );
772 : }
773 0 : ELSE IF( EQ_16( st->extl, WB_BWE ) || EQ_16( st->extl, SWB_BWE ) || EQ_16( st->extl, FB_BWE ) )
774 : {
775 0 : push_indice( hBstr, IND_BWE_FLAG, 1, 1 );
776 : }
777 : }
778 :
779 3827 : return error;
780 : }
781 :
782 : /*-------------------------------------------------------------------*
783 : * Function tdm_downmix_plain()
784 : *
785 : * downmix Left+Right to Primary+Secondary channel
786 : *-------------------------------------------------------------------*/
787 :
788 3727 : static void tdm_downmix_plain_ivas_fx(
789 : Word16 FR_Y_fx[], /*Qx*/
790 : Word16 LR_X_fx[], /*Qx*/
791 : const Word16 Left_in_fx[], /*Qx*/
792 : const Word16 Right_in_fx[], /*Qx*/
793 : const Word32 ratio_L_fx, /* Q31 */
794 : const Word32 One_m_Ratio_fx, /* Q31 */
795 : const Word16 start_index, /* i : start index */
796 : const Word16 end_index /* i : end index */
797 : )
798 : {
799 : Word16 i;
800 :
801 2403567 : FOR( i = start_index; i < end_index; i++ )
802 : {
803 2399840 : FR_Y_fx[i] = add( mult( Right_in_fx[i], extract_h( One_m_Ratio_fx ) ), mult( Left_in_fx[i], extract_h( ratio_L_fx ) ) );
804 2399840 : LR_X_fx[i] = sub( mult( Left_in_fx[i], extract_h( One_m_Ratio_fx ) ), mult( Right_in_fx[i], extract_h( ratio_L_fx ) ) );
805 2399840 : move16();
806 2399840 : move16();
807 : }
808 :
809 3727 : return;
810 : }
811 :
812 : /*-------------------------------------------------------------------*
813 : * Function tdm_downmix_fade()
814 : *
815 : * downmix Left+Right to Primary+Secondary channel with fade in/out
816 : *-------------------------------------------------------------------*/
817 98 : static void tdm_downmix_fade_ivas_fx(
818 : Word16 FR_Y_fx[], /* o : primary channel Qx */
819 : Word16 LR_X_fx[], /* o : secondary channel Qx */
820 : const Word16 Left_in_fx[], /* i : Left channel Qx */
821 : const Word16 Right_in_fx[], /* i : Right channel Qx */
822 : const Word32 ratio_L_fx, /* i : mixing ratio Q31 */
823 : const Word32 One_m_Ratio_fx, /* i : 1 - mixing ratio Q31 */
824 : const Word32 OldRatio_L_fx, /* i : old mixing ratio Q31 */
825 : const Word32 One_m_OldRatio_fx, /* i : 1 - old mixing ratio Q31 */
826 : const Word16 start_index, /* i : start index */
827 : const Word16 end_index /* i : end index */
828 : )
829 : {
830 : Word16 i;
831 : Word16 step_fx, fade_in_fx, fade_out_fx, scale;
832 :
833 98 : step_fx = BASOP_Util_Divide1616_Scale( 1, sub( end_index, start_index ), &scale );
834 98 : step_fx = shl( step_fx, scale ); // Q15
835 98 : fade_out_fx = 32767;
836 98 : fade_in_fx = 0;
837 98 : move16();
838 98 : move16();
839 :
840 : Word16 tmp1, tmp2, tmp3, tmp4;
841 98 : tmp1 = extract_h( One_m_OldRatio_fx );
842 98 : tmp2 = extract_h( OldRatio_L_fx );
843 98 : tmp3 = extract_h( One_m_Ratio_fx );
844 98 : tmp4 = extract_h( ratio_L_fx );
845 :
846 14658 : FOR( i = start_index; i < end_index; i++ )
847 : {
848 14560 : FR_Y_fx[i] = extract_h( L_add( Mpy_32_16_1( L_mac( L_mult( Right_in_fx[i], tmp1 ), Left_in_fx[i], tmp2 ), fade_out_fx ),
849 14560 : Mpy_32_16_1( L_mac( L_mult( Right_in_fx[i], tmp3 ), Left_in_fx[i], tmp4 ), fade_in_fx ) ) ); // Qx
850 14560 : LR_X_fx[i] = extract_h( L_add( Mpy_32_16_1( L_msu( L_mult( Left_in_fx[i], tmp1 ), Right_in_fx[i], tmp2 ), fade_out_fx ),
851 14560 : Mpy_32_16_1( L_msu( L_mult( Left_in_fx[i], tmp3 ), Right_in_fx[i], tmp4 ),
852 : fade_in_fx ) ) ); // Qx
853 14560 : move16();
854 14560 : move16();
855 :
856 :
857 14560 : fade_in_fx = add( fade_in_fx, step_fx );
858 14560 : fade_out_fx = sub( fade_out_fx, step_fx );
859 : }
860 :
861 98 : return;
862 : }
863 :
864 :
865 : /*-------------------------------------------------------------------*
866 : * Function stereo_tdm_downmix()
867 : *
868 : * Compute the TD stereo downmix signal based on the ratio index
869 : *-------------------------------------------------------------------*/
870 3827 : void stereo_tdm_downmix_ivas_fx(
871 : STEREO_TD_ENC_DATA_HANDLE hStereoTD, /* i : TD stereo IVAS encoder structure */
872 : Word16 *Left_in_fx, /* Qx */
873 : Word16 *Right_in_fx, /* Qx */
874 : const Word16 input_frame, /* i : Number of samples */
875 : const Word16 tdm_ratio_idx, /* i : TDM ratio index */
876 : const Word16 tdm_SM_flag, /* i : channel combination scheme flag */
877 : const Word16 tdm_ratio_idx_SM /* i : TDM ratio index for SM mode */
878 : )
879 : {
880 : Word16 FR_Y_fx[L_FRAME48k], LR_X_fx[L_FRAME48k];
881 : Word16 i, tdm_n_OVA;
882 : Word16 stereo_tdm_coder_type;
883 :
884 3827 : tdm_n_OVA = NS2SA_FX2( L_mult0( input_frame, FRAMES_PER_SEC ), TDM_L_NOVA_NS );
885 3827 : move16();
886 :
887 3827 : IF( hStereoTD->flag_skip_DMX )
888 : {
889 100 : stereo_tdm_coder_type = 10; /* no DMX */
890 100 : move16();
891 :
892 100 : Copy( Left_in_fx, FR_Y_fx, input_frame );
893 100 : Copy( Right_in_fx, LR_X_fx, input_frame );
894 : }
895 3727 : ELSE IF( EQ_16( tdm_SM_flag, 1 ) )
896 : {
897 0 : IF( hStereoTD->tdm_last_SM_flag == 0 )
898 : {
899 0 : stereo_tdm_coder_type = 0; /* mode 1 : Switching from YX scheme to SM scheme*/
900 0 : move16();
901 : }
902 : ELSE
903 : {
904 0 : stereo_tdm_coder_type = 1; /* mode 2 : SM scheme*/
905 0 : move16();
906 : }
907 : }
908 : ELSE
909 : {
910 3727 : IF( EQ_16( hStereoTD->tdm_last_SM_flag, 1 ) )
911 : {
912 0 : stereo_tdm_coder_type = 2; /* mode 3 : Switching from SM scheme to YX scheme*/
913 0 : move16();
914 : }
915 : ELSE
916 : {
917 3727 : stereo_tdm_coder_type = 3; /* mode 4 : YX scheme*/
918 3727 : move16();
919 : }
920 : }
921 :
922 3827 : SWITCH( stereo_tdm_coder_type )
923 : {
924 0 : case ( 0 ):
925 : {
926 : /* Switching from YX scheme to SM scheme */
927 0 : tdm_downmix_fade_ivas_fx( FR_Y_fx, LR_X_fx, Left_in_fx, Right_in_fx, tdm_ratio_tabl_fx[tdm_ratio_idx_SM], L_sub( tdm_ratio_tabl_fx[tdm_ratio_idx_SM], 2147483647 ), hStereoTD->tdm_last_ratio_fx, L_sub( 2147483647, hStereoTD->tdm_last_ratio_fx ), 0, tdm_n_OVA ); // 1.0 in Q31 -> 2147483647
928 :
929 : /* Create new mixture of using the ratio computed above and formular for SM scheme */
930 0 : tdm_downmix_plain_ivas_fx( FR_Y_fx, LR_X_fx, Left_in_fx, Right_in_fx, tdm_ratio_tabl_fx[tdm_ratio_idx_SM], L_sub( tdm_ratio_tabl_fx[tdm_ratio_idx_SM], 2147483647 ), tdm_n_OVA, input_frame ); // 1.0 in Q31 -> 2147483647
931 : }
932 0 : BREAK;
933 0 : case ( 1 ):
934 : {
935 : /* Create new mixture of using the ratio computed above and formular for SM scheme */
936 0 : IF( EQ_32( tdm_ratio_tabl_fx[tdm_ratio_idx_SM], hStereoTD->tdm_last_ratio_SM_fx ) )
937 : {
938 0 : tdm_downmix_plain_ivas_fx( FR_Y_fx, LR_X_fx, Left_in_fx, Right_in_fx, tdm_ratio_tabl_fx[tdm_ratio_idx_SM], L_sub( (Word32) tdm_ratio_tabl_fx[tdm_ratio_idx_SM], 2147483647 ), 0, input_frame ); // 1.0 in Q31 -> 2147483647
939 : }
940 : ELSE
941 : {
942 0 : tdm_downmix_fade_ivas_fx( FR_Y_fx, LR_X_fx, Left_in_fx, Right_in_fx, tdm_ratio_tabl_fx[tdm_ratio_idx_SM], L_sub( tdm_ratio_tabl_fx[tdm_ratio_idx_SM], 2147483647 ), hStereoTD->tdm_last_ratio_SM_fx, L_sub( hStereoTD->tdm_last_ratio_SM_fx, 2147483647 ), 0, tdm_n_OVA ); // 1.0 in Q31 -> 2147483647
943 :
944 0 : tdm_downmix_plain_ivas_fx( FR_Y_fx, LR_X_fx, Left_in_fx, Right_in_fx, tdm_ratio_tabl_fx[tdm_ratio_idx_SM], L_sub( tdm_ratio_tabl_fx[tdm_ratio_idx_SM], 2147483647 ), tdm_n_OVA, input_frame ); // 1.0 in Q31 -> 2147483647
945 : }
946 : }
947 0 : BREAK;
948 0 : case ( 2 ):
949 : {
950 : /* Switching from SM scheme to YX scheme */
951 0 : tdm_downmix_fade_ivas_fx( FR_Y_fx, LR_X_fx, Left_in_fx, Right_in_fx, tdm_ratio_tabl_fx[tdm_ratio_idx], L_sub( 2147483647, tdm_ratio_tabl_fx[tdm_ratio_idx] ), hStereoTD->tdm_last_ratio_SM_fx, L_sub( hStereoTD->tdm_last_ratio_SM_fx, 2147483647 ), 0, tdm_n_OVA ); // 1.0 in Q31 -> 2147483647
952 :
953 : /* Create new mixture of using the ratio computed above and formular for YX scheme */
954 0 : tdm_downmix_plain_ivas_fx( FR_Y_fx, LR_X_fx, Left_in_fx, Right_in_fx, tdm_ratio_tabl_fx[tdm_ratio_idx], L_sub( 2147483647, tdm_ratio_tabl_fx[tdm_ratio_idx] ), tdm_n_OVA, input_frame ); // 1.0 in Q31 -> 2147483647
955 : }
956 0 : BREAK;
957 3727 : case ( 3 ):
958 : {
959 : /* Create new mixture of using the ratio computed above and formular for YX scheme */
960 3727 : IF( EQ_32( tdm_ratio_tabl_fx[tdm_ratio_idx],
961 : hStereoTD->tdm_last_ratio_fx ) )
962 : {
963 3629 : tdm_downmix_plain_ivas_fx( FR_Y_fx, LR_X_fx, Left_in_fx, Right_in_fx, tdm_ratio_tabl_fx[tdm_ratio_idx], L_sub( 2147483647, tdm_ratio_tabl_fx[tdm_ratio_idx] ), 0, input_frame ); // 1.0 in Q31 -> 2147483647
964 : }
965 : ELSE
966 : {
967 98 : tdm_downmix_fade_ivas_fx( FR_Y_fx, LR_X_fx, Left_in_fx, Right_in_fx, tdm_ratio_tabl_fx[tdm_ratio_idx], L_sub( 2147483647, tdm_ratio_tabl_fx[tdm_ratio_idx] ), hStereoTD->tdm_last_ratio_fx, L_sub( 2147483647, hStereoTD->tdm_last_ratio_fx ), 0, tdm_n_OVA ); // 1.0 in Q31 -> 2147483647
968 :
969 98 : tdm_downmix_plain_ivas_fx( FR_Y_fx, LR_X_fx, Left_in_fx, Right_in_fx, tdm_ratio_tabl_fx[tdm_ratio_idx], L_sub( 2147483647, tdm_ratio_tabl_fx[tdm_ratio_idx] ), tdm_n_OVA, input_frame ); // 1.0 in Q31 -> 2147483647
970 : }
971 : }
972 3727 : BREAK;
973 100 : default:
974 100 : BREAK;
975 : }
976 :
977 2507827 : FOR( i = 0; i < input_frame; i++ )
978 : {
979 2504000 : Left_in_fx[i] = FR_Y_fx[i]; // Qx
980 2504000 : Right_in_fx[i] = LR_X_fx[i]; // Qx
981 2504000 : move16();
982 2504000 : move16();
983 : }
984 :
985 3827 : hStereoTD->tdm_last_ratio_fx = tdm_ratio_tabl_fx[tdm_ratio_idx]; // Q31
986 3827 : hStereoTD->tdm_last_ratio_SM_fx = tdm_ratio_tabl_fx[tdm_ratio_idx_SM]; // Q31
987 3827 : move32();
988 3827 : move32();
989 :
990 3827 : return;
991 : }
992 :
993 : /*-------------------------------------------------------------------*
994 : * Function stereo_tdm_prep_dwnmx()
995 : *
996 : * Reactivate downmixing after bitrate switching from MDCT to lower rate
997 : *-------------------------------------------------------------------*/
998 :
999 3827 : void stereo_tdm_prep_dwnmx_fx(
1000 : CPE_ENC_HANDLE hCPE, /* i : CPE encoder structure */
1001 : const Word32 *input1, /* i : right channel input */
1002 : const Word16 input_frame, /* i : frame lenght */
1003 : const Word16 input_q /* i : frame lenght */
1004 : )
1005 : {
1006 : Word32 mener;
1007 : Word16 i, sw_pos, enr_len;
1008 : Encoder_State **sts;
1009 : Word16 mener_e;
1010 3827 : sts = hCPE->hCoreCoder;
1011 :
1012 3827 : i = idiv1616( input_frame, L_FRAME16k );
1013 :
1014 3827 : sw_pos = i_mult( 22, i );
1015 3827 : enr_len = i_mult( 6, i );
1016 3827 : IF( EQ_16( hCPE->element_mode, IVAS_CPE_TD ) )
1017 : {
1018 3827 : IF( EQ_16( hCPE->hStereoTD->flag_skip_DMX, 1 ) ) /* hStereoTD is defined only if element mode == TD */
1019 : {
1020 100 : IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_TD ) )
1021 : {
1022 : Word16 tmp_e;
1023 92 : mener_e = sub( 31, input_q );
1024 92 : mener = L_add( sum2_32_fx( input1 + sub( input_frame, sw_pos ), enr_len, &mener_e ), EPSILON_FX );
1025 92 : mener = BASOP_Util_Divide3232_Scale( mener, (Word32) enr_len, &tmp_e );
1026 92 : mener_e = add( mener_e, sub( tmp_e, 15 ) );
1027 92 : mener = Sqrt32( mener, &mener_e );
1028 92 : test();
1029 92 : test();
1030 92 : IF( ( BASOP_Util_Cmp_Mant32Exp( mener, mener_e, 10, Q31 ) < 0 ) && ( sts[1]->vad_flag == 0 || EQ_16( sts[1]->coder_type_raw, UNVOICED ) ) )
1031 : {
1032 0 : hCPE->hStereoTD->flag_skip_DMX = 0; /* Can start using the TD downmix whenever the right channel is sufficiently low energy to limit switching artefacts */
1033 0 : move16();
1034 : }
1035 : }
1036 8 : ELSE IF( EQ_16( hCPE->last_element_mode, IVAS_CPE_DFT ) || EQ_32( hCPE->last_element_brate, IVAS_13k2 ) ) /* Just security check, should not happened */
1037 : {
1038 0 : hCPE->hStereoTD->flag_skip_DMX = 0;
1039 0 : move16();
1040 : }
1041 100 : test();
1042 : }
1043 : }
1044 :
1045 3827 : return;
1046 : }
|