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 : #ifdef DEBUGGING
36 : #include "debug.h"
37 : #include "assert.h"
38 : #endif
39 : #include "cnst.h"
40 : #include "rom_com.h"
41 : #include "prot.h"
42 : #include "ivas_prot.h"
43 : #include "ivas_rom_com.h"
44 : #include "wmc_auto.h"
45 : #include "math.h"
46 :
47 :
48 : /*-------------------------------------------------------------------*
49 : * stereo_td_init_enc()
50 : *
51 : * Initialize TD stereo encoder
52 : *-------------------------------------------------------------------*/
53 :
54 59 : void stereo_td_init_enc(
55 : STEREO_TD_ENC_DATA_HANDLE hStereoTD, /* i/o: TD stereo encoder handle */
56 : const int16_t last_element_mode /* i : last element mode */
57 : )
58 : {
59 59 : hStereoTD->tdm_lt_corr_RM = 0.01f;
60 59 : hStereoTD->tdm_lt_corr_LM = 0.01f;
61 59 : hStereoTD->tdm_last_ratio = 0.5f;
62 59 : hStereoTD->tdm_last_ratio_idx = LRTD_STEREO_MID_IS_PRIM;
63 59 : hStereoTD->tdm_lt_rms_L = 40.0f;
64 59 : hStereoTD->tdm_lt_rms_R = 40.0f;
65 59 : hStereoTD->tdm_last_diff_lt_corr = 0;
66 59 : hStereoTD->tdm_last_ener_lt_R = 0;
67 59 : hStereoTD->tdm_last_ener_lt_L = 0;
68 :
69 59 : hStereoTD->tdm_ratio_transition_mov_flag = 0;
70 59 : hStereoTD->tdm_ratio_transition_cnt = 0;
71 59 : hStereoTD->tdm_noop_mov_flag = 0;
72 59 : hStereoTD->tdm_noop_cnt = 0;
73 59 : hStereoTD->tdm_last_SM_flag = 0;
74 :
75 59 : hStereoTD->tdm_last_ratio_idx = LRTD_STEREO_MID_IS_PRIM;
76 59 : hStereoTD->tdm_prev_stable_idx = LRTD_STEREO_MID_IS_PRIM;
77 59 : hStereoTD->tdm_prev_desired_idx = LRTD_STEREO_MID_IS_PRIM;
78 59 : hStereoTD->tdm_FD2LRTD_SW_cnt = 0;
79 59 : hStereoTD->tdm_LT_es_em = 0.1f;
80 59 : hStereoTD->tdm_hyst_cnt = 0;
81 : /* NOOP parameters */
82 59 : hStereoTD->tdm_lt_corr_RM_SM = 0.01f;
83 59 : hStereoTD->tdm_lt_corr_LM_SM = 0.01f;
84 59 : hStereoTD->tdm_last_ratio_SM = 0.5f;
85 59 : hStereoTD->tdm_last_ratio_idx_SM = 0;
86 59 : hStereoTD->tdm_lt_rms_L_SM = 40.0f;
87 59 : hStereoTD->tdm_lt_rms_R_SM = 40.0f;
88 59 : hStereoTD->tdm_last_diff_lt_corr_SM = 0;
89 59 : hStereoTD->tdm_last_ener_lt_R_SM = 0;
90 59 : hStereoTD->tdm_last_ener_lt_L_SM = 0;
91 59 : hStereoTD->tdm_noop_mov_flag = 0;
92 59 : hStereoTD->tdm_NOOP_cnt = 0;
93 59 : hStereoTD->tdm_last_SM_flag_noop = 0;
94 59 : hStereoTD->tdm_last_ratio_idx_SM = LRTD_STEREO_MID_IS_PRIM;
95 59 : hStereoTD->tdm_prev_stable_idx_SM = LRTD_STEREO_MID_IS_PRIM;
96 59 : hStereoTD->tdm_prev_desired_idx_SM = LRTD_STEREO_MID_IS_PRIM;
97 59 : hStereoTD->tdm_LT_es_em_SM = 0.1f;
98 59 : hStereoTD->tdm_hyst_cnt_SM = 0;
99 59 : hStereoTD->tdm_noop_cnt = 0;
100 59 : hStereoTD->tdm_SM_flag = 0;
101 59 : hStereoTD->tdm_SM_last_clas[0] = VOICED_CLAS;
102 59 : hStereoTD->tdm_SM_last_clas[1] = VOICED_CLAS;
103 59 : hStereoTD->tdm_SM_last2_clas[0] = VOICED_CLAS;
104 59 : hStereoTD->tdm_SM_last2_clas[1] = VOICED_CLAS;
105 59 : hStereoTD->tdm_SM_modi_flag = 0;
106 59 : hStereoTD->tdm_SM_reset_flag = 0;
107 59 : hStereoTD->prev_fr_LRTD_TD_dec = 0;
108 59 : hStereoTD->tdm_LRTD_flag = 0;
109 59 : hStereoTD->tdm_inst_ratio_idx = LRTD_STEREO_RIGHT_IS_PRIM;
110 59 : hStereoTD->tdm_last_inst_ratio_idx = LRTD_STEREO_MID_IS_PRIM;
111 59 : hStereoTD->tdm_last_LRTD_frame_cnt = 0;
112 59 : hStereoTD->tdm_vad_hangover_cnt = 0;
113 59 : hStereoTD->tdm_ini_frame_cnt = 0;
114 59 : hStereoTD->tdm_last_LRTD_PriCh_cnt = 0;
115 :
116 59 : hStereoTD->flag_skip_DMX = 0;
117 59 : if ( last_element_mode == IVAS_CPE_MDCT )
118 : {
119 8 : hStereoTD->flag_skip_DMX = 1;
120 8 : hStereoTD->prev_fr_LRTD_TD_dec = 1;
121 8 : hStereoTD->tdm_last_ratio = 1.0f;
122 8 : hStereoTD->tdm_last_ratio_idx = LRTD_STEREO_LEFT_IS_PRIM;
123 8 : hStereoTD->tdm_prev_stable_idx = LRTD_STEREO_LEFT_IS_PRIM;
124 8 : hStereoTD->tdm_prev_desired_idx = LRTD_STEREO_LEFT_IS_PRIM;
125 : }
126 :
127 59 : hStereoTD->tdm_hBstr_tmp.ind_list = hStereoTD->tdm_ind_list_tmp;
128 59 : hStereoTD->tdm_hBstr_tmp.ivas_ind_list_zero = (Indice **) ( &hStereoTD->tdm_hBstr_tmp.ind_list );
129 59 : hStereoTD->max_ind_tdm_tmp = MAX_IND_TDM_TMP;
130 59 : hStereoTD->tdm_hBstr_tmp.ivas_max_num_indices = &hStereoTD->max_ind_tdm_tmp;
131 59 : hStereoTD->tdm_hBstr_tmp.st_ivas = NULL;
132 59 : reset_indices_enc( &hStereoTD->tdm_hBstr_tmp, MAX_IND_TDM_TMP );
133 :
134 59 : return;
135 : }
136 :
137 :
138 : /*-------------------------------------------------------------------*
139 : * stereo_set_tdm()
140 : *
141 : * Set TD stereo encoder parameters
142 : *-------------------------------------------------------------------*/
143 :
144 420855 : ivas_error stereo_set_tdm(
145 : CPE_ENC_HANDLE hCPE, /* i : CPE encoder structure */
146 : const int16_t input_frame /* i : input frame length per channel */
147 : )
148 : {
149 : Encoder_State **sts;
150 420855 : sts = hCPE->hCoreCoder;
151 : ivas_error error;
152 :
153 420855 : error = IVAS_ERR_OK;
154 :
155 : /* initialize TD stereo parameters */
156 420855 : if ( hCPE->hStereoTD != NULL )
157 : {
158 3791 : hCPE->hStereoTD->tdm_lp_reuse_flag = 0;
159 3791 : hCPE->hStereoTD->tdm_low_rate_mode = 0;
160 3791 : hCPE->hStereoTD->tdm_Pitch_reuse_flag = 0;
161 :
162 3791 : if ( hCPE->hStereoClassif->lrtd_mode == 1 )
163 : {
164 : /* initialize this flag when uncorrelated L&R channels have been detected in the previous frame */
165 3791 : if ( hCPE->hStereoTD->prev_fr_LRTD_TD_dec == 1 || hCPE->last_element_mode != IVAS_CPE_TD || hCPE->hStereoTD->tdm_FD2LRTD_SW_cnt < 5 )
166 : {
167 3665 : hCPE->hStereoTD->tdm_LRTD_flag = 1;
168 : }
169 : else
170 : {
171 126 : hCPE->hStereoTD->tdm_LRTD_flag = 0;
172 : }
173 : }
174 : else
175 : {
176 0 : hCPE->hStereoTD->tdm_LRTD_flag = hCPE->hStereoTD->prev_fr_LRTD_TD_dec;
177 : }
178 :
179 : #ifdef DEBUG_MODE_INFO
180 : dbgwrite( &hCPE->hStereoTD->tdm_LRTD_flag, 2, 1, (int16_t) ( hCPE->hCoreCoder[0]->input_Fs / FRAMES_PER_SEC ), "res/tdm_LRTD_flag" );
181 : #endif
182 :
183 : /* normal TD / LRTD switching */
184 3791 : if ( hCPE->hStereoTD->tdm_LRTD_flag == 0 )
185 : {
186 : Encoder_State *st;
187 126 : st = hCPE->hCoreCoder[1];
188 :
189 : /* deallocate CLDFB ana for secondary channel */
190 126 : if ( st->cldfbAnaEnc != NULL )
191 : {
192 33 : deleteCldfb( &st->cldfbAnaEnc );
193 : }
194 :
195 : /* deallocate BWEs for secondary channel */
196 126 : if ( st->hBWE_TD != NULL )
197 : {
198 33 : if ( st->hBWE_TD != NULL )
199 : {
200 33 : free( st->hBWE_TD );
201 33 : st->hBWE_TD = NULL;
202 : }
203 :
204 33 : deleteCldfb( &st->cldfbSynTd );
205 :
206 33 : if ( st->hBWE_FD != NULL )
207 : {
208 33 : free( st->hBWE_FD );
209 33 : st->hBWE_FD = NULL;
210 : }
211 : }
212 :
213 : /* allocate ICBWE structure */
214 126 : if ( hCPE->hStereoICBWE == NULL )
215 : {
216 33 : if ( ( hCPE->hStereoICBWE = (STEREO_ICBWE_ENC_HANDLE) malloc( sizeof( STEREO_ICBWE_ENC_DATA ) ) ) == NULL )
217 : {
218 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Stereo ICBWE \n" ) );
219 : }
220 :
221 33 : stereo_icBWE_init_enc( hCPE->hStereoICBWE );
222 : }
223 : }
224 : else /* tdm_LRTD_flag == 1 */
225 : {
226 : Encoder_State *st;
227 3665 : st = hCPE->hCoreCoder[1];
228 :
229 : /* deallocate ICBWE structure */
230 3665 : if ( hCPE->hStereoICBWE != NULL )
231 : {
232 51 : free( hCPE->hStereoICBWE );
233 51 : hCPE->hStereoICBWE = NULL;
234 : }
235 :
236 : /* allocate CLDFB ana for secondary channel */
237 3665 : if ( st->cldfbAnaEnc == NULL )
238 : {
239 59 : if ( ( error = openCldfb( &st->cldfbAnaEnc, CLDFB_ANALYSIS, st->input_Fs, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK )
240 : {
241 0 : return error;
242 : }
243 : }
244 :
245 : /* allocate BWEs for secondary channel */
246 3665 : if ( st->hBWE_TD == NULL )
247 : {
248 59 : if ( ( st->hBWE_TD = (TD_BWE_ENC_HANDLE) malloc( sizeof( TD_BWE_ENC_DATA ) ) ) == NULL )
249 : {
250 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD BWE\n" ) );
251 : }
252 :
253 59 : if ( ( error = openCldfb( &st->cldfbSynTd, CLDFB_SYNTHESIS, 16000, CLDFB_PROTOTYPE_1_25MS ) ) != IVAS_ERR_OK )
254 : {
255 0 : return error;
256 : }
257 :
258 59 : InitSWBencBuffer( st->hBWE_TD );
259 59 : ResetSHBbuffer_Enc( st->hBWE_TD );
260 :
261 59 : if ( ( st->hBWE_FD = (FD_BWE_ENC_HANDLE) malloc( sizeof( FD_BWE_ENC_DATA ) ) ) == NULL )
262 : {
263 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FD BWE\n" ) );
264 : }
265 :
266 59 : fd_bwe_enc_init( st->hBWE_FD );
267 : }
268 : }
269 :
270 3791 : if ( hCPE->hStereoClassif->lrtd_mode == 0 )
271 : {
272 0 : hCPE->hStereoTD->tdm_FD2LRTD_SW_cnt = 0;
273 : }
274 3791 : hCPE->hStereoTD->tdm_FD2LRTD_SW_cnt = min( 100, hCPE->hStereoTD->tdm_FD2LRTD_SW_cnt + 1 );
275 3791 : stereo_tdm_prep_dwnmx( hCPE, sts[1]->input, input_frame );
276 : }
277 : else
278 : {
279 : #ifdef DEBUG_MODE_INFO
280 : {
281 : int16_t tmp = -2;
282 : dbgwrite( &tmp, 2, 1, (int16_t) ( hCPE->hCoreCoder[0]->input_Fs / FRAMES_PER_SEC ), "res/tdm_LRTD_flag" );
283 : }
284 : #endif
285 : #ifdef DEBUG_MODE_TD
286 : {
287 : float ftmp = -0.0;
288 : int16_t tmp = -2;
289 : dbgwrite( &tmp, 2, 1, 320, "res/prev_fr_LRTD_TD_dec" );
290 : dbgwrite( &tmp, 2, 1, 320, "res/inst_ratio_L" );
291 : dbgwrite( &ftmp, 4, 1, 320, "res/ratio_L" );
292 : dbgwrite( &tmp, 2, 1, 320, "res/tdm_low_rate_mode" );
293 : // dbgwrite( &tmp, 2, 1, 320, "res/tdm_lp_reuse_flag" );
294 : // dbgwrite( &tmp, 2, 1, 320, "res/mod_ct.enx" );
295 : }
296 : #endif
297 417064 : hCPE->hCoreCoder[0]->tdm_LRTD_flag = 0;
298 417064 : hCPE->hCoreCoder[1]->tdm_LRTD_flag = 0;
299 : }
300 :
301 420855 : return error;
302 : }
303 :
304 :
305 : /*-------------------------------------------------------------------*
306 : * tdm_configure_enc()
307 : *
308 : * Configure TD stereo encoder
309 : *-------------------------------------------------------------------*/
310 :
311 3791 : void tdm_configure_enc(
312 : const int16_t ivas_format, /* i : IVAS format */
313 : const int16_t ism_mode, /* i : ISM mode in combined format */
314 : CPE_ENC_HANDLE hCPE, /* i : CPE encoder structure */
315 : const float Etot_last[CPE_CHANNELS], /* i/o: Energy of last frame */
316 : const int16_t tdm_SM_or_LRTD_Pri, /* i : channel combination scheme flag in TD stereo OR LRTD primary channel */
317 : const int16_t tdm_ratio_idx, /* i : ratio index */
318 : const int16_t tdm_ratio_idx_SM, /* i : ratio index in SM mode */
319 : const int16_t attack_flag, /* i : Primary channel attack flag */
320 : const int16_t nb_bits_metadata /* i : number of metadata bits */
321 : )
322 : {
323 : int16_t tdm_ratio_bit_alloc_idx, mod_ct;
324 : STEREO_TD_ENC_DATA_HANDLE hStereoTD;
325 : Encoder_State **sts;
326 : int16_t loc_coder_tyape_raw0;
327 :
328 3791 : hStereoTD = hCPE->hStereoTD;
329 3791 : sts = hCPE->hCoreCoder;
330 3791 : loc_coder_tyape_raw0 = sts[0]->coder_type_raw;
331 :
332 : /*----------------------------------------------------------------*
333 : * Overwrite certain decisions depending on the input
334 : *----------------------------------------------------------------*/
335 :
336 3791 : hStereoTD->tdm_use_IAWB_Ave_lpc = 0; /* Flag initialisation */
337 3791 : sts[0]->hSpMusClas->tdm_lt_Etot = 0.1f * Etot_last[0] + 0.9f * sts[0]->hSpMusClas->tdm_lt_Etot;
338 3791 : sts[1]->hSpMusClas->tdm_lt_Etot = 0.1f * Etot_last[1] + 0.9f * sts[1]->hSpMusClas->tdm_lt_Etot;
339 :
340 3791 : if ( hCPE->hStereoClassif->lrtd_mode == 0 && ( ( sts[1]->hSpMusClas->tdm_lt_Etot < 0 && hCPE->hCoreCoder[1]->vad_flag == 0 ) /* very clean signal */
341 0 : || ( hCPE->hCoreCoder[1]->vad_flag == 0 || ( Etot_last[1] < 30.0f && ( sts[0]->hSpMusClas->tdm_lt_Etot - sts[1]->hSpMusClas->tdm_lt_Etot ) > 26.0f ) ) ) )
342 : {
343 0 : sts[1]->coder_type = INACTIVE;
344 :
345 0 : if ( hStereoTD->tdm_lp_reuse_flag == 0 && hCPE->hCoreCoder[0]->vad_flag != 0 )
346 : {
347 0 : hStereoTD->tdm_use_IAWB_Ave_lpc = 1;
348 : }
349 0 : hStereoTD->tdm_lp_reuse_flag = 1;
350 : }
351 3791 : else if ( ( ( hCPE->hCoreCoder[1]->vad_flag == 0 ) || ( hCPE->hCoreCoder[0]->vad_flag == 0 && Etot_last[1] < 30.0f && ( sts[0]->hSpMusClas->tdm_lt_Etot - sts[1]->hSpMusClas->tdm_lt_Etot ) > 26.0f ) ) && ( hCPE->hStereoClassif->lrtd_mode == 1 ) /* && NO_DTX */ ) /* boths channels are inactive but not DTX used*/
352 : {
353 0 : sts[1]->coder_type = INACTIVE;
354 0 : if ( tdm_ratio_idx > 1 && tdm_ratio_idx < 29 )
355 : {
356 0 : if ( hStereoTD->tdm_lp_reuse_flag == 0 && hCPE->hCoreCoder[0]->vad_flag != 0 )
357 : {
358 0 : hStereoTD->tdm_use_IAWB_Ave_lpc = 1;
359 : }
360 0 : hStereoTD->tdm_lp_reuse_flag = 1;
361 : }
362 : }
363 3791 : else if ( !( sts[1]->sp_aud_decision0 ) && sts[1]->tc_cnt <= 0 && ( sts[1]->coder_type_raw == UNVOICED || ( hStereoTD->tdm_LRTD_flag == 1 && hStereoTD->tdm_lp_reuse_flag == 0 && ( hCPE->hCoreCoder[1]->vad_flag == 0 || ( Etot_last[1] < 30.0f && ( sts[0]->hSpMusClas->tdm_lt_Etot - sts[1]->hSpMusClas->tdm_lt_Etot ) > 26.0f ) ) ) ) )
364 : {
365 328 : sts[1]->coder_type = UNVOICED;
366 328 : if ( hStereoTD->tdm_LRTD_flag == 1 )
367 : {
368 252 : hStereoTD->tdm_lp_reuse_flag = 0;
369 : }
370 : }
371 3463 : else if ( ( sts[1]->coder_type < AUDIO && sts[1]->coder_type != UNVOICED ) || /* TC and VC are not supported in secondary channel */
372 49 : ( ( sts[1]->coder_type == AUDIO && hCPE->element_brate <= IVAS_24k4 ) || ( sts[0]->sp_aud_decision1 == 1 && hCPE->element_brate >= IVAS_16k4 ) || ( sts[1]->sp_aud_decision0 == 1 && hCPE->element_brate > IVAS_13k2 ) ) )
373 : {
374 3463 : sts[1]->coder_type = GENERIC;
375 : }
376 0 : else if ( sts[1]->coder_type == GENERIC && sts[1]->coder_type_raw == UNVOICED )
377 : {
378 0 : hStereoTD->tdm_lp_reuse_flag = 0;
379 : }
380 :
381 3791 : if ( hCPE->element_brate > IVAS_24k4 && hCPE->hStereoClassif->lrtd_mode == 1 )
382 : {
383 2087 : if ( sts[1]->coder_type == UNVOICED )
384 : {
385 200 : sts[1]->coder_type = GENERIC;
386 : }
387 :
388 2087 : if ( sts[0]->coder_type == UNVOICED )
389 : {
390 171 : sts[0]->coder_type = GENERIC;
391 171 : loc_coder_tyape_raw0 = GENERIC;
392 : }
393 : }
394 :
395 3791 : if ( hCPE->element_brate >= IVAS_24k4 && hCPE->hStereoClassif->lrtd_mode == 0 && sts[0]->coder_type == UNVOICED )
396 : {
397 0 : sts[0]->coder_type = GENERIC;
398 0 : loc_coder_tyape_raw0 = GENERIC;
399 : }
400 :
401 3791 : if ( sts[1]->coder_type != GENERIC )
402 : {
403 128 : hStereoTD->tdm_Pitch_reuse_flag = 0;
404 : }
405 :
406 3791 : if ( attack_flag != 0 )
407 : {
408 76 : if ( sts[1]->coder_type != INACTIVE )
409 : {
410 76 : hStereoTD->tdm_lp_reuse_flag = 0; /* Do not allow the LP filter reusing on TC or attack in the primary channel */
411 : }
412 : }
413 :
414 3791 : if ( tdm_SM_or_LRTD_Pri && hStereoTD->tdm_LRTD_flag == 0 )
415 : {
416 13 : tdm_ratio_bit_alloc_idx = tdm_ratio_idx_SM;
417 : }
418 : else
419 : {
420 3778 : tdm_ratio_bit_alloc_idx = tdm_ratio_idx;
421 : }
422 :
423 3791 : if ( ( hCPE->hStereoClassif->lrtd_mode == 1 && sts[1]->coder_type >= UNVOICED && abs( hStereoTD->tdm_last_ratio_idx - tdm_ratio_bit_alloc_idx ) > 15 ) /* channel inversion in lrtd */
424 3755 : || ( hStereoTD->tdm_FD2LRTD_SW_cnt < 4 && hStereoTD->tdm_last_LRTD_frame_cnt < 4 ) )
425 : {
426 213 : sts[1]->coder_type = GENERIC;
427 : }
428 :
429 3791 : if ( hCPE->element_brate - nb_bits_metadata * FRAMES_PER_SEC + hCPE->brate_surplus < 12000 )
430 : {
431 0 : if ( sts[1]->coder_type == UNVOICED )
432 : {
433 0 : sts[1]->coder_type = GENERIC;
434 : }
435 0 : hStereoTD->tdm_lp_reuse_flag = 1;
436 :
437 0 : if ( hCPE->element_brate - nb_bits_metadata * FRAMES_PER_SEC + hCPE->brate_surplus < 11000 )
438 : {
439 0 : sts[1]->coder_type = INACTIVE;
440 : }
441 : }
442 :
443 3791 : if ( hCPE->element_brate - nb_bits_metadata * FRAMES_PER_SEC + hCPE->brate_surplus < 14700 )
444 : {
445 0 : if ( sts[0]->coder_type == TRANSITION )
446 : {
447 0 : sts[0]->coder_type = GENERIC;
448 : }
449 : }
450 :
451 3791 : mod_ct = AUDIO;
452 3791 : if ( hCPE->element_brate < IVAS_24k4 )
453 : {
454 : /* 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. */
455 571 : if ( !( sts[0]->localVAD == 0 && sts[0]->coder_type == TRANSITION ) &&
456 571 : ( sts[0]->coder_type == TRANSITION ||
457 550 : ( ( ( sts[0]->last_L_frame >= L_FRAME16k && sts[0]->flag_ACELP16k == 0 ) ||
458 548 : ( sts[0]->last_L_frame == L_FRAME && sts[0]->flag_ACELP16k == 1 ) ) &&
459 2 : sts[0]->last_core_brate != FRAME_NO_DATA &&
460 2 : sts[0]->last_core_brate != SID_2k40 &&
461 2 : sts[0]->coder_type_raw != VOICED ) ) )
462 : {
463 23 : mod_ct = TRANSITION;
464 : }
465 : }
466 :
467 : /* Correction of tdm_inst_ratio_idx in case of TC in the seecondary channel */
468 3791 : if ( hStereoTD->flag_skip_DMX == 0 && hStereoTD->tdm_LRTD_flag == 1 && sts[1]->tc_cnt > 1 /*&& abs(hStereoTD->tdm_inst_ratio_idx-LRTD_STEREO_MID_IS_PRIM) > 5*/ )
469 : {
470 144 : if ( tdm_SM_or_LRTD_Pri == 0 ) /* Primary is right */
471 : {
472 0 : hStereoTD->tdm_inst_ratio_idx += LRTD_STEREO_QUARTER_RANGE;
473 : }
474 144 : else if ( tdm_SM_or_LRTD_Pri == 1 ) /* Primary is left */
475 : {
476 144 : hStereoTD->tdm_inst_ratio_idx -= LRTD_STEREO_QUARTER_RANGE;
477 : }
478 144 : hStereoTD->tdm_inst_ratio_idx = check_bounds_s( hStereoTD->tdm_inst_ratio_idx, 8, 22 );
479 : }
480 :
481 : /*----------------------------------------------------------------*
482 : * bitbudget distribution between channels (taking into account also metadata bitbudget)
483 : *----------------------------------------------------------------*/
484 :
485 3791 : tdm_bit_alloc( ivas_format, ism_mode, hCPE->element_brate - nb_bits_metadata * FRAMES_PER_SEC + hCPE->brate_surplus,
486 3791 : hStereoTD->tdm_lp_reuse_flag, &( sts[0]->total_brate ), &( sts[1]->total_brate ),
487 3791 : &( hStereoTD->tdm_low_rate_mode ), sts[1]->coder_type, tdm_ratio_bit_alloc_idx, hStereoTD->tdm_Pitch_reuse_flag,
488 3791 : sts[0]->bwidth, sts[1]->bwidth, sts[0]->flag_ACELP16k, hStereoTD->tdm_LRTD_flag, mod_ct, hStereoTD->tdm_inst_ratio_idx );
489 :
490 3791 : if ( sts[0]->GSC_IVAS_mode > 0 && sts[0]->total_brate <= STEREO_GSC_BIT_RATE_ALLOC )
491 : {
492 5 : sts[0]->GSC_IVAS_mode = 0;
493 : }
494 3791 : if ( sts[1]->GSC_IVAS_mode > 0 && ( sts[1]->total_brate <= STEREO_GSC_BIT_RATE_ALLOC || hStereoTD->tdm_low_rate_mode == 1 ) )
495 : {
496 0 : sts[1]->GSC_IVAS_mode = 0;
497 : }
498 :
499 3791 : if ( sts[0]->coder_type == GENERIC && loc_coder_tyape_raw0 == UNVOICED )
500 : {
501 0 : if ( sts[0]->total_brate <= MAX_UNVOICED_BRATE )
502 : {
503 0 : sts[0]->coder_type = UNVOICED;
504 : }
505 : }
506 :
507 : /*----------------------------------------------------------------*
508 : * Bitstream writing
509 : *----------------------------------------------------------------*/
510 :
511 : /* transmit the ratio index */
512 3791 : if ( tdm_SM_or_LRTD_Pri && hStereoTD->tdm_LRTD_flag == 0 )
513 : {
514 13 : push_indice( &hStereoTD->tdm_hBstr_tmp, IND_STEREO_TD_ALPHA, tdm_ratio_idx_SM, TDM_RATIO_BITS );
515 : }
516 : else
517 : {
518 3778 : if ( hStereoTD->tdm_LRTD_flag == 1 )
519 : {
520 3665 : push_indice( &hStereoTD->tdm_hBstr_tmp, IND_STEREO_TD_ALPHA, hStereoTD->tdm_inst_ratio_idx, TDM_RATIO_BITS );
521 : }
522 : else
523 : {
524 113 : push_indice( &hStereoTD->tdm_hBstr_tmp, IND_STEREO_TD_ALPHA, tdm_ratio_idx, TDM_RATIO_BITS );
525 : }
526 : }
527 :
528 : /* LPC reuse flag */
529 3791 : if ( sts[1]->coder_type == INACTIVE && tdm_ratio_idx < 29 && tdm_ratio_idx > 1 )
530 : {
531 : /* normal TD, tdm_lp_reuse_flag always on, tdm_use_IAWB_Ave_lpc varies tdm_ratio_idx<29 && tdm_ratio_idx> 1*/
532 0 : push_indice( &hStereoTD->tdm_hBstr_tmp, IND_STEREO_LPC_REUSE, hStereoTD->tdm_use_IAWB_Ave_lpc, TDM_LP_REUSE_BITS );
533 : }
534 : else
535 : {
536 3791 : push_indice( &hStereoTD->tdm_hBstr_tmp, IND_STEREO_LPC_REUSE, hStereoTD->tdm_lp_reuse_flag, TDM_LP_REUSE_BITS );
537 : }
538 :
539 : /* LRTD flag */
540 3791 : push_indice( &hStereoTD->tdm_hBstr_tmp, IND_STEREO_LRTD_FLAG, hStereoTD->tdm_LRTD_flag, TDM_LR_CONTENT_BITS );
541 :
542 : /* Stereo ICA parameters */
543 3791 : if ( hStereoTD->tdm_LRTD_flag == 0 )
544 : {
545 126 : push_indice( &hStereoTD->tdm_hBstr_tmp, IND_STEREO_REFCHAN, hCPE->hStereoTCA->refChanIndx, STEREO_BITS_TCA_CHAN );
546 126 : push_indice( &hStereoTD->tdm_hBstr_tmp, IND_STEREO_CORRSTATS, hCPE->hStereoTCA->indx_ica_NCShift, STEREO_BITS_TCA_CORRSTATS );
547 126 : push_indice( &hStereoTD->tdm_hBstr_tmp, IND_STEREO_GD, hCPE->hStereoTCA->indx_ica_gD, STEREO_BITS_TCA_GD );
548 : }
549 :
550 : #ifdef DEBUG_MODE_TD
551 : dbgwrite( &hStereoTD->tdm_low_rate_mode, 2, 1, 320, "res/tdm_low_rate_mode_c" );
552 : dbgwrite( &hStereoTD->tdm_lp_reuse_flag, 2, 1, 320, "res/tdm_lp_reuse_flag_c" );
553 : #endif
554 :
555 : /*----------------------------------------------------------------*
556 : * Updates
557 : *----------------------------------------------------------------*/
558 :
559 3791 : hStereoTD->tdm_last_ratio_idx = tdm_ratio_idx;
560 3791 : hStereoTD->tdm_last_ratio_idx_SM = tdm_ratio_idx_SM;
561 3791 : hStereoTD->tdm_last_SM_flag = tdm_SM_or_LRTD_Pri;
562 :
563 3791 : if ( hStereoTD->tdm_LRTD_flag == 1 )
564 : {
565 3665 : hStereoTD->tdm_last_SM_flag = 0;
566 : }
567 :
568 3791 : hStereoTD->tdm_last_inst_ratio_idx = hStereoTD->tdm_inst_ratio_idx;
569 :
570 3791 : return;
571 : }
572 :
573 :
574 : /*-------------------------------------------------------------------*
575 : * signaling_enc_secondary()
576 : *
577 : * Signalling of the secondary channel
578 : *-------------------------------------------------------------------*/
579 :
580 3791 : ivas_error signaling_enc_secondary(
581 : Encoder_State *st, /* i/o: Encoder structure */
582 : const int16_t tdm_SM_or_LRTD_Pri, /* i : channel combination scheme flag OR LRTD primary channel */
583 : const int16_t tdm_Pitch_reuse_flag /* i : primary channel pitch reuse flag*/
584 : )
585 : {
586 : int16_t ind;
587 3791 : BSTR_ENC_HANDLE hBstr = st->hBstr;
588 : ivas_error error;
589 :
590 3791 : error = IVAS_ERR_OK;
591 :
592 : /* The secondary channel band-witdh is always the same as the primary channel bandwidth */
593 :
594 3791 : ind = st->coder_type;
595 3791 : if ( tdm_Pitch_reuse_flag == 1 ) /* possible only for bitrate <= 24400 */
596 : {
597 33 : ind = 3;
598 : }
599 3758 : else if ( st->coder_type == GENERIC )
600 : {
601 3663 : ind = 2;
602 : }
603 95 : else if ( st->coder_type == AUDIO )
604 : {
605 0 : ind -= 2;
606 : }
607 : #ifdef DEBUGGING
608 : else if ( st->coder_type == TRANSITION || st->coder_type == VOICED )
609 : {
610 : return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Coder type not supported in secondary channel\n" );
611 : }
612 : #endif
613 :
614 3791 : ind <<= 1;
615 3791 : ind += tdm_SM_or_LRTD_Pri; /* addition of the channel combination scheme flag value or the LRTD primary channel*/
616 3791 : push_indice( hBstr, IND_STEREO_2ND_CODER_T, ind, TDM_SECONDARY_SIGNALLING );
617 :
618 : /* write extension layer flag to distinguish between TBE (0) and BWE (1) */
619 3791 : if ( st->extl_brate > 0 )
620 : {
621 2882 : if ( st->extl == WB_TBE || st->extl == SWB_TBE || st->extl == FB_TBE )
622 : {
623 2882 : push_indice( hBstr, IND_BWE_FLAG, 0, 1 );
624 : }
625 0 : else if ( st->extl == WB_BWE || st->extl == SWB_BWE || st->extl == FB_BWE )
626 : {
627 0 : push_indice( hBstr, IND_BWE_FLAG, 1, 1 );
628 : }
629 : }
630 :
631 3791 : return error;
632 : }
633 :
634 : /*-------------------------------------------------------------------*
635 : * Function tdm_downmix_plain()
636 : *
637 : * downmix Left+Right to Primary+Secondary channel
638 : *-------------------------------------------------------------------*/
639 :
640 3691 : static void tdm_downmix_plain(
641 : float FR_Y[], /* o : primary channel */
642 : float LR_X[], /* o : secondary channel */
643 : const float Left_in[], /* i : Left channel */
644 : const float Right_in[], /* i : Right channel */
645 : const float ratio_L, /* i : mixing ratio */
646 : const float One_m_Ratio, /* i : 1 - mixing ration */
647 : const int16_t start_index, /* i : start index */
648 : const int16_t end_index /* i : end index */
649 : )
650 : {
651 : int16_t i;
652 :
653 2416891 : for ( i = start_index; i < end_index; i++ )
654 : {
655 2413200 : FR_Y[i] = ( Right_in[i] * One_m_Ratio + ( Left_in[i] * ratio_L ) );
656 2413200 : LR_X[i] = ( Left_in[i] * One_m_Ratio - ( Right_in[i] * ratio_L ) );
657 : }
658 :
659 3691 : return;
660 : }
661 :
662 : /*-------------------------------------------------------------------*
663 : * Function tdm_downmix_fade()
664 : *
665 : * downmix Left+Right to Primary+Secondary channel with fade in/out
666 : *-------------------------------------------------------------------*/
667 :
668 89 : static void tdm_downmix_fade(
669 : float FR_Y[], /* o : primary channel */
670 : float LR_X[], /* o : secondary channel */
671 : const float Left_in[], /* i : Left channel */
672 : const float Right_in[], /* i : Right channel */
673 : const float ratio_L, /* i : mixing ratio */
674 : const float One_m_Ratio, /* i : 1 - mixing ratio */
675 : const float OldRatio_L, /* i : old mixing ratio */
676 : const float One_m_OldRatio, /* i : 1 - old mixing ratio */
677 : const int16_t start_index, /* i : start index */
678 : const int16_t end_index /* i : end index */
679 : )
680 : {
681 : int16_t i;
682 : float step, fade_in, fade_out;
683 :
684 89 : step = 1.0f / (float) ( end_index - start_index );
685 89 : fade_out = 1.0f;
686 89 : fade_in = 0.0f;
687 :
688 14089 : for ( i = start_index; i < end_index; i++ )
689 : {
690 14000 : FR_Y[i] = ( Right_in[i] * One_m_OldRatio + Left_in[i] * OldRatio_L ) * fade_out + ( Right_in[i] * One_m_Ratio + Left_in[i] * ratio_L ) * fade_in;
691 14000 : LR_X[i] = ( Left_in[i] * One_m_OldRatio - Right_in[i] * OldRatio_L ) * fade_out + ( Left_in[i] * One_m_Ratio - Right_in[i] * ratio_L ) * fade_in;
692 :
693 14000 : fade_in += step;
694 14000 : fade_out -= step;
695 : }
696 :
697 89 : return;
698 : }
699 :
700 : /*-------------------------------------------------------------------*
701 : * Function stereo_tdm_downmix()
702 : *
703 : * Compute the TD stereo downmix signal based on the ratio index
704 : *-------------------------------------------------------------------*/
705 :
706 3791 : void stereo_tdm_downmix(
707 : STEREO_TD_ENC_DATA_HANDLE hStereoTD, /* i : TD stereo IVAS encoder structure */
708 : float *Left_in, /* i/o: Left channel -> Primary channel */
709 : float *Right_in, /* i/o: Right channel -> Secondary channel */
710 : const int16_t input_frame, /* i : Number of samples */
711 : const int16_t tdm_ratio_idx, /* i : TDM ratio index */
712 : const int16_t tdm_SM_flag, /* i : channel combination scheme flag */
713 : const int16_t tdm_ratio_idx_SM /* i : TDM ratio index for SM mode */
714 : )
715 : {
716 : float FR_Y[L_FRAME48k], LR_X[L_FRAME48k];
717 : int16_t i, tdm_n_OVA;
718 : int16_t stereo_tdm_coder_type;
719 :
720 3791 : tdm_n_OVA = NS2SA( input_frame * FRAMES_PER_SEC, TDM_L_NOVA_NS );
721 :
722 3791 : if ( hStereoTD->flag_skip_DMX )
723 : {
724 100 : stereo_tdm_coder_type = 10; /* no DMX */
725 100 : mvr2r( Left_in, FR_Y, input_frame );
726 100 : mvr2r( Right_in, LR_X, input_frame );
727 : }
728 3691 : else if ( tdm_SM_flag == 1 )
729 : {
730 13 : if ( hStereoTD->tdm_last_SM_flag == 0 )
731 : {
732 1 : stereo_tdm_coder_type = 0; /* mode 1 : Switching from YX scheme to SM scheme*/
733 : }
734 : else
735 : {
736 12 : stereo_tdm_coder_type = 1; /* mode 2 : SM scheme*/
737 : }
738 : }
739 : else
740 : {
741 3678 : if ( hStereoTD->tdm_last_SM_flag == 1 )
742 : {
743 0 : stereo_tdm_coder_type = 2; /* mode 3 : Switching from SM scheme to YX scheme*/
744 : }
745 : else
746 : {
747 3678 : stereo_tdm_coder_type = 3; /* mode 4 : YX scheme*/
748 : }
749 : }
750 :
751 3791 : switch ( stereo_tdm_coder_type )
752 : {
753 1 : case ( 0 ):
754 : {
755 : /* Switching from YX scheme to SM scheme */
756 1 : tdm_downmix_fade( FR_Y, LR_X, Left_in, Right_in, tdm_ratio_tabl[tdm_ratio_idx_SM], tdm_ratio_tabl[tdm_ratio_idx_SM] - 1.0f, hStereoTD->tdm_last_ratio, 1.0f - hStereoTD->tdm_last_ratio, 0, tdm_n_OVA );
757 :
758 : /* Create new mixture of using the ratio computed above and formular for SM scheme */
759 1 : tdm_downmix_plain( FR_Y, LR_X, Left_in, Right_in, tdm_ratio_tabl[tdm_ratio_idx_SM], tdm_ratio_tabl[tdm_ratio_idx_SM] - 1.0f, tdm_n_OVA, input_frame );
760 : }
761 1 : break;
762 12 : case ( 1 ):
763 : {
764 : /* Create new mixture of using the ratio computed above and formular for SM scheme */
765 12 : if ( tdm_ratio_tabl[tdm_ratio_idx_SM] == hStereoTD->tdm_last_ratio_SM )
766 : {
767 10 : tdm_downmix_plain( FR_Y, LR_X, Left_in, Right_in, tdm_ratio_tabl[tdm_ratio_idx_SM], tdm_ratio_tabl[tdm_ratio_idx_SM] - 1.0f, 0, input_frame );
768 : }
769 : else
770 : {
771 2 : tdm_downmix_fade( FR_Y, LR_X, Left_in, Right_in, tdm_ratio_tabl[tdm_ratio_idx_SM], tdm_ratio_tabl[tdm_ratio_idx_SM] - 1.0f, hStereoTD->tdm_last_ratio_SM, hStereoTD->tdm_last_ratio_SM - 1.0f, 0, tdm_n_OVA );
772 2 : tdm_downmix_plain( FR_Y, LR_X, Left_in, Right_in, tdm_ratio_tabl[tdm_ratio_idx_SM], tdm_ratio_tabl[tdm_ratio_idx_SM] - 1.0f, tdm_n_OVA, input_frame );
773 : }
774 : }
775 12 : break;
776 0 : case ( 2 ):
777 : {
778 : /* Switching from SM scheme to YX scheme */
779 0 : tdm_downmix_fade( FR_Y, LR_X, Left_in, Right_in, tdm_ratio_tabl[tdm_ratio_idx], 1.0f - tdm_ratio_tabl[tdm_ratio_idx], hStereoTD->tdm_last_ratio_SM, hStereoTD->tdm_last_ratio_SM - 1.0f, 0, tdm_n_OVA );
780 :
781 : /* Create new mixture of using the ratio computed above and formular for YX scheme */
782 0 : tdm_downmix_plain( FR_Y, LR_X, Left_in, Right_in, tdm_ratio_tabl[tdm_ratio_idx], 1.0f - tdm_ratio_tabl[tdm_ratio_idx], tdm_n_OVA, input_frame );
783 : }
784 0 : break;
785 3678 : case ( 3 ):
786 : {
787 : /* Create new mixture of using the ratio computed above and formular for YX scheme */
788 3678 : if ( tdm_ratio_tabl[tdm_ratio_idx] == hStereoTD->tdm_last_ratio )
789 : {
790 3592 : tdm_downmix_plain( FR_Y, LR_X, Left_in, Right_in, tdm_ratio_tabl[tdm_ratio_idx], 1.0f - tdm_ratio_tabl[tdm_ratio_idx], 0, input_frame );
791 : }
792 : else
793 : {
794 86 : tdm_downmix_fade( FR_Y, LR_X, Left_in, Right_in, tdm_ratio_tabl[tdm_ratio_idx], 1.0f - tdm_ratio_tabl[tdm_ratio_idx], hStereoTD->tdm_last_ratio, 1.0f - hStereoTD->tdm_last_ratio, 0, tdm_n_OVA );
795 86 : tdm_downmix_plain( FR_Y, LR_X, Left_in, Right_in, tdm_ratio_tabl[tdm_ratio_idx], 1.0f - tdm_ratio_tabl[tdm_ratio_idx], tdm_n_OVA, input_frame );
796 : }
797 : }
798 3678 : break;
799 100 : default:
800 100 : break;
801 : }
802 :
803 2520591 : for ( i = 0; i < input_frame; i++ )
804 : {
805 2516800 : Left_in[i] = FR_Y[i];
806 2516800 : Right_in[i] = LR_X[i];
807 : }
808 :
809 3791 : hStereoTD->tdm_last_ratio = tdm_ratio_tabl[tdm_ratio_idx];
810 3791 : hStereoTD->tdm_last_ratio_SM = tdm_ratio_tabl[tdm_ratio_idx_SM];
811 :
812 3791 : return;
813 : }
814 :
815 : /*-------------------------------------------------------------------*
816 : * Function stereo_tdm_prep_dwnmx()
817 : *
818 : * Reactivate downmixing after bitrate switching from MDCT to lower rate
819 : *-------------------------------------------------------------------*/
820 :
821 3791 : void stereo_tdm_prep_dwnmx(
822 : CPE_ENC_HANDLE hCPE, /* i : CPE encoder structure */
823 : const float *input1, /* i : right channel input */
824 : const int16_t input_frame /* i : frame lenght */
825 : )
826 : {
827 : #define USER_ENER
828 : float mener;
829 : int16_t i, sw_pos, enr_len;
830 : Encoder_State **sts;
831 3791 : sts = hCPE->hCoreCoder;
832 :
833 3791 : i = input_frame / L_FRAME16k;
834 :
835 3791 : sw_pos = 22 * i;
836 3791 : enr_len = 6 * i;
837 : #ifdef DEBUG_MODE_TD
838 : assert( sw_pos > 15 );
839 : #endif
840 3791 : if ( hCPE->element_mode == IVAS_CPE_TD )
841 : {
842 3791 : if ( hCPE->hStereoTD->flag_skip_DMX == 1 ) /* hStereoTD is defined only if element mode == TD */
843 : {
844 100 : if ( hCPE->last_element_mode == IVAS_CPE_TD )
845 : {
846 92 : mener = sum2_f( input1 + input_frame - sw_pos, enr_len ) + EPSILON;
847 92 : mener = sqrtf( mener / enr_len );
848 92 : if ( mener < 10.0f && ( sts[1]->vad_flag == 0 || sts[1]->coder_type_raw == UNVOICED ) )
849 : {
850 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 */
851 : }
852 : }
853 8 : else if ( hCPE->last_element_mode == IVAS_CPE_DFT || hCPE->last_element_brate == IVAS_13k2 ) /* Just security check, should not happened */
854 : {
855 0 : hCPE->hStereoTD->flag_skip_DMX = 0;
856 : }
857 : }
858 : }
859 :
860 3791 : return;
861 : }
|