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 "options.h"
34 : #include <stdlib.h>
35 : #include <math.h>
36 : #include "ivas_cnst.h"
37 : #include "ivas_prot.h"
38 : #include "prot.h"
39 : #include "ivas_prot_rend.h"
40 : #include "ivas_rom_com.h"
41 : #ifdef DEBUGGING
42 : #include "debug.h"
43 : #endif
44 : #include "wmc_auto.h"
45 :
46 : /*-------------------------------------------------------------------------
47 : * Local constants
48 : *------------------------------------------------------------------------*/
49 :
50 : #define EXT_RENDER_IIR_FAC 0.95f
51 :
52 : /*-------------------------------------------------------------------*
53 : * ivas_omasa_data_open()
54 : *
55 : * Allocate and initialize MASA_ISM rendering handle
56 : *-------------------------------------------------------------------*/
57 :
58 11263 : ivas_error ivas_omasa_data_open(
59 : Decoder_Struct *st_ivas /* i/o: IVAS decoder handle */
60 : )
61 : {
62 : MASA_ISM_DATA_HANDLE hMasaIsmData;
63 : int16_t ch;
64 : int16_t sf, obj_idx;
65 :
66 11263 : if ( ( hMasaIsmData = (MASA_ISM_DATA_HANDLE) malloc( sizeof( MASA_ISM_DATA ) ) ) == NULL )
67 : {
68 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA ISM data\n" ) );
69 : }
70 :
71 281575 : for ( int16_t band_idx = 0; band_idx < MASA_FREQUENCY_BANDS; band_idx++ )
72 : {
73 810936 : for ( ch = 0; ch < 2; ch++ )
74 : {
75 540624 : hMasaIsmData->ismPreprocMatrix[ch][ch][band_idx] = 1.0f;
76 540624 : hMasaIsmData->ismPreprocMatrix[1 - ch][ch][band_idx] = 0.0f;
77 540624 : hMasaIsmData->eneMoveIIR[ch][band_idx] = 0.0f;
78 540624 : hMasaIsmData->enePreserveIIR[ch][band_idx] = 0.0f;
79 : }
80 270312 : hMasaIsmData->eneOrigIIR[band_idx] = 0.0f;
81 270312 : hMasaIsmData->preprocEneTarget[band_idx] = 0.0f;
82 270312 : hMasaIsmData->preprocEneRealized[band_idx] = 0.0f;
83 : }
84 :
85 11263 : hMasaIsmData->objectsEdited = 0;
86 11263 : hMasaIsmData->delayBuffer = NULL;
87 :
88 56315 : for ( ch = 0; ch < MAX_NUM_OBJECTS; ch++ )
89 : {
90 45052 : hMasaIsmData->ism_dir_is_edited[ch] = 0;
91 45052 : hMasaIsmData->ism_gain_is_edited[ch] = 0;
92 45052 : hMasaIsmData->q_elevation_old[ch] = 0.0f;
93 45052 : hMasaIsmData->q_azimuth_old[ch] = 0.0f;
94 : }
95 11263 : hMasaIsmData->masa_gain_is_edited = 0;
96 11263 : hMasaIsmData->idx_separated_ism = -1;
97 :
98 56315 : for ( obj_idx = 0; obj_idx < MAX_NUM_OBJECTS; obj_idx++ )
99 : {
100 45052 : set_s( hMasaIsmData->azimuth_ism[obj_idx], 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR );
101 45052 : set_s( hMasaIsmData->elevation_ism[obj_idx], 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR );
102 315364 : for ( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR; sf++ )
103 : {
104 270312 : set_zero( hMasaIsmData->energy_ratio_ism[obj_idx][sf], CLDFB_NO_CHANNELS_MAX );
105 : }
106 : }
107 11263 : set_s( hMasaIsmData->azimuth_separated_ism, 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR );
108 11263 : set_s( hMasaIsmData->elevation_separated_ism, 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR );
109 :
110 11263 : hMasaIsmData->hExtData = NULL;
111 11263 : if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL )
112 : {
113 : MASA_ISM_EXT_DATA_HANDLE hExtData;
114 :
115 558 : if ( ( hExtData = (MASA_ISM_EXT_DATA_HANDLE) malloc( sizeof( MASA_ISM_EXT_DATA ) ) ) == NULL )
116 : {
117 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA ISM data\n" ) );
118 : }
119 :
120 558 : hExtData->prev_idx_separated_ism = 0;
121 :
122 2790 : for ( ch = 0; ch < MAX_NUM_OBJECTS; ch++ )
123 : {
124 2232 : set_zero( hExtData->prev_panning_gains[ch], 2 );
125 : }
126 :
127 2790 : for ( ch = 0; ch < MAX_NUM_OBJECTS; ch++ )
128 : {
129 2232 : set_zero( hExtData->ism_render_proto_energy[ch], CLDFB_NO_CHANNELS_MAX );
130 2232 : set_zero( hExtData->ism_render_target_energy[ch], CLDFB_NO_CHANNELS_MAX );
131 : }
132 558 : set_zero( hExtData->masa_render_proto_energy, CLDFB_NO_CHANNELS_MAX );
133 558 : set_zero( hExtData->masa_render_target_energy, CLDFB_NO_CHANNELS_MAX );
134 :
135 3906 : for ( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR; sf++ )
136 : {
137 3348 : set_zero( hExtData->masa_render_masa_to_total[sf], CLDFB_NO_CHANNELS_MAX );
138 : }
139 :
140 558 : hMasaIsmData->hExtData = hExtData;
141 : }
142 :
143 11263 : st_ivas->hMasaIsmData = hMasaIsmData;
144 :
145 11263 : return IVAS_ERR_OK;
146 : }
147 :
148 :
149 : /*-------------------------------------------------------------------*
150 : * ivas_omasa_data_close()
151 : *
152 : * Deallocate MASA_ISM rendering handle
153 : *-------------------------------------------------------------------*/
154 :
155 86865 : void ivas_omasa_data_close(
156 : MASA_ISM_DATA_HANDLE *hMasaIsmData /* i/o: MASA_ISM rendering handle */
157 : )
158 : {
159 : int16_t i;
160 :
161 86865 : if ( hMasaIsmData == NULL || *hMasaIsmData == NULL )
162 : {
163 75602 : return;
164 : }
165 :
166 11263 : if ( ( *hMasaIsmData )->delayBuffer != NULL )
167 : {
168 13449 : for ( i = 0; i < ( *hMasaIsmData )->delayBuffer_nchan; i++ )
169 : {
170 8816 : free( ( *hMasaIsmData )->delayBuffer[i] );
171 : }
172 4633 : free( ( *hMasaIsmData )->delayBuffer );
173 4633 : ( *hMasaIsmData )->delayBuffer = NULL;
174 : }
175 :
176 11263 : if ( ( *hMasaIsmData )->hExtData != NULL )
177 : {
178 558 : free( ( *hMasaIsmData )->hExtData );
179 558 : ( *hMasaIsmData )->hExtData = NULL;
180 : }
181 :
182 11263 : free( *hMasaIsmData );
183 11263 : *hMasaIsmData = NULL;
184 :
185 11263 : return;
186 : }
187 :
188 :
189 : /*--------------------------------------------------------------------------*
190 : * ivas_omasa_dec_config()
191 : *
192 : * oMASA decoder configuration
193 : *--------------------------------------------------------------------------*/
194 :
195 53358 : ivas_error ivas_omasa_dec_config(
196 : Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
197 : )
198 : {
199 : int16_t k, sce_id, nSCE_old, nchan_hp20_old, numCldfbAnalyses_old, numCldfbSyntheses_old;
200 : int32_t ivas_total_brate, ism_total_brate, cpe_brate;
201 : ISM_MODE ism_mode_old;
202 : IVAS_FORMAT ivas_format_orig;
203 : int16_t nchan_out_buff;
204 : ivas_error error;
205 : RENDERER_TYPE old_renderer_type;
206 :
207 : /* initializations */
208 53358 : ism_total_brate = 0;
209 53358 : ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
210 :
211 : /* save previous frame parameters */
212 53358 : ism_mode_old = ivas_omasa_ism_mode_select( st_ivas->hDecoderConfig->last_ivas_total_brate, st_ivas->nchan_ism );
213 53358 : st_ivas->ism_mode = ism_mode_old;
214 :
215 53358 : ivas_format_orig = st_ivas->ivas_format;
216 53358 : st_ivas->ivas_format = st_ivas->last_ivas_format;
217 53358 : ivas_init_dec_get_num_cldfb_instances( st_ivas, &numCldfbAnalyses_old, &numCldfbSyntheses_old );
218 53358 : st_ivas->ivas_format = ivas_format_orig;
219 :
220 53358 : nSCE_old = st_ivas->nSCE;
221 53358 : nchan_hp20_old = getNumChanSynthesis( st_ivas );
222 :
223 : /* set ism_mode of current frame */
224 53358 : st_ivas->ism_mode = ivas_omasa_ism_mode_select( ivas_total_brate, st_ivas->nchan_ism );
225 :
226 : /*-----------------------------------------------------------------*
227 : * Renderer selection
228 : *-----------------------------------------------------------------*/
229 :
230 53358 : old_renderer_type = st_ivas->renderer_type;
231 :
232 : /* MASA reconfig. */
233 53358 : cpe_brate = calculate_cpe_brate_MASA_ISM( st_ivas->ism_mode, ivas_total_brate, st_ivas->nchan_ism );
234 53358 : if ( st_ivas->ini_active_frame == 0 && ivas_total_brate != FRAME_NO_DATA && ( cpe_brate < MASA_STEREO_MIN_BITRATE ) && st_ivas->nCPE == 1 )
235 : {
236 0 : st_ivas->hCPE[0]->nchan_out = 1;
237 : }
238 53358 : else if ( ( error = ivas_masa_dec_reconfigure( st_ivas ) ) != IVAS_ERR_OK )
239 : {
240 0 : return error;
241 : }
242 :
243 53358 : if ( cpe_brate < MASA_STEREO_MIN_BITRATE )
244 : {
245 18190 : st_ivas->hCPE[0]->nchan_out = 1;
246 : }
247 : else
248 : {
249 35168 : st_ivas->hCPE[0]->nchan_out = 2;
250 : }
251 :
252 : /* OMASA reconfig. */
253 53358 : if ( st_ivas->hMasaIsmData == NULL && st_ivas->ivas_format == MASA_ISM_FORMAT )
254 : {
255 752 : if ( ( error = ivas_omasa_data_open( st_ivas ) ) != IVAS_ERR_OK )
256 : {
257 0 : return error;
258 : }
259 : }
260 :
261 53358 : ivas_set_omasa_TC( st_ivas->ism_mode, st_ivas->nchan_ism, &st_ivas->nSCE, &st_ivas->nCPE );
262 :
263 : /* re-configure hp20 memories */
264 53358 : if ( ( error = ivas_hp20_dec_reconfig( st_ivas, nchan_hp20_old ) ) != IVAS_ERR_OK )
265 : {
266 0 : return error;
267 : }
268 :
269 : /* reconfigure core-coders for ISMs */
270 53358 : k = 0;
271 431419 : while ( k < SIZE_IVAS_BRATE_TBL && ivas_total_brate != ivas_brate_tbl[k] )
272 : {
273 378061 : k++;
274 : }
275 :
276 122888 : for ( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ )
277 : {
278 69530 : ism_total_brate += sep_object_brate[k - 2][st_ivas->nSCE - 1];
279 : }
280 :
281 53358 : if ( ( error = ivas_corecoder_dec_reconfig( st_ivas, nSCE_old, 1, 2, 0, st_ivas->nSCE > 0 ? sep_object_brate[k - 2][st_ivas->nSCE - 1] : 0, ivas_total_brate - ism_total_brate ) ) != IVAS_ERR_OK )
282 : {
283 0 : return error;
284 : }
285 :
286 53358 : if ( ism_mode_old != st_ivas->ism_mode )
287 : {
288 : /* ISM MD reconfig. */
289 52526 : if ( st_ivas->hIsmMetaData[0] == NULL )
290 : {
291 752 : if ( ( error = ivas_ism_metadata_dec_create( st_ivas, st_ivas->nchan_ism, NULL ) ) != IVAS_ERR_OK )
292 : {
293 0 : return error;
294 : }
295 : }
296 : else
297 : {
298 217321 : for ( k = 0; k < st_ivas->nchan_ism; k++ )
299 : {
300 165547 : ivas_ism_reset_metadata_handle_dec( st_ivas->hIsmMetaData[k] );
301 : }
302 : }
303 :
304 52526 : st_ivas->hCPE[0]->element_brate = ivas_total_brate - ism_total_brate;
305 :
306 : /*-----------------------------------------------------------------*
307 : * Renderer selection
308 : *-----------------------------------------------------------------*/
309 :
310 52526 : ivas_renderer_select( st_ivas );
311 :
312 : /*-------------------------------------------------------------------*
313 : * Reallocate rendering handles
314 : *--------------------------------------------------------------------*/
315 :
316 52526 : if ( old_renderer_type != st_ivas->renderer_type )
317 : {
318 5889 : if ( st_ivas->renderer_type == RENDERER_MONO_DOWNMIX )
319 : {
320 1602 : if ( ( error = ivas_mono_dmx_renderer_open( st_ivas ) ) != IVAS_ERR_OK )
321 : {
322 0 : return error;
323 : }
324 : }
325 : else
326 : {
327 4287 : ivas_mono_dmx_renderer_close( &st_ivas->hMonoDmxRenderer );
328 : }
329 : }
330 :
331 : /* objects renderer reconfig. */
332 52526 : if ( st_ivas->hMasaIsmData != NULL || st_ivas->hIsmRendererData != NULL )
333 : {
334 : /* this calls also ivas_ism_renderer_close() closing st_ivas->hIsmRendererData used by the EXT renderers. also cleans st_ivas->hMasaIsmData */
335 52526 : ivas_omasa_separate_object_renderer_close( st_ivas );
336 : }
337 :
338 52526 : if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ && st_ivas->hMasaIsmData != NULL ) /* this structure is in use only in ISM_MASA_MODE_PARAM_ONE_OBJ */
339 : {
340 12522 : MASA_ISM_DATA_HANDLE hMasaIsmData = st_ivas->hMasaIsmData;
341 62610 : for ( int16_t obj_idx = 0; obj_idx < MAX_NUM_OBJECTS; obj_idx++ )
342 : {
343 50088 : set_s( hMasaIsmData->azimuth_ism[obj_idx], 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR );
344 50088 : set_s( hMasaIsmData->elevation_ism[obj_idx], 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR );
345 350616 : for ( int16_t sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR; sf++ )
346 : {
347 300528 : set_zero( hMasaIsmData->energy_ratio_ism[obj_idx][sf], CLDFB_NO_CHANNELS_MAX );
348 : }
349 : }
350 12522 : set_s( hMasaIsmData->azimuth_separated_ism, 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR );
351 12522 : set_s( hMasaIsmData->elevation_separated_ism, 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR );
352 : }
353 :
354 52526 : if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC )
355 : {
356 12805 : if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC )
357 : {
358 : /* Allocate TD renderer for the objects in DISC mode */
359 3484 : if ( st_ivas->hBinRendererTd == NULL )
360 : {
361 3484 : if ( ( error = ivas_td_binaural_open( st_ivas ) ) != IVAS_ERR_OK )
362 : {
363 0 : return error;
364 : }
365 :
366 3484 : if ( st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB )
367 : {
368 0 : if ( ( error = ivas_reverb_open( &st_ivas->hReverb, st_ivas->hHrtfStatistics, st_ivas->hRenderConfig, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK )
369 : {
370 0 : return error;
371 : }
372 : }
373 : }
374 :
375 : /* Allocate memory for delay buffer within 'hMasaIsmData' */
376 3484 : if ( ( error = ivas_omasa_objects_delay_open( st_ivas ) ) != IVAS_ERR_OK )
377 : {
378 0 : return error;
379 : }
380 : }
381 : else
382 : {
383 9321 : if ( st_ivas->hBinRendererTd != NULL )
384 : {
385 : /* TD renderer handle */
386 3487 : ivas_td_binaural_close( &st_ivas->hBinRendererTd );
387 : }
388 : /* ISM renderer handle + ISM data handle */
389 9321 : ivas_omasa_separate_object_renderer_close( st_ivas );
390 : }
391 : }
392 :
393 52526 : if ( st_ivas->renderer_type == RENDERER_DIRAC )
394 : {
395 17563 : if ( ( error = ivas_dirac_dec_config( st_ivas, DIRAC_RECONFIGURE ) ) != IVAS_ERR_OK )
396 : {
397 0 : return error;
398 : }
399 :
400 17563 : if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_DISC )
401 : {
402 : /* Allocate 'hIsmRendererData' handle and memory for delay buffer within 'hMasaIsmData' */
403 12351 : if ( ( error = ivas_omasa_objects_delay_open( st_ivas ) ) != IVAS_ERR_OK )
404 : {
405 0 : return error;
406 : }
407 12351 : if ( ( error = ivas_omasa_separate_object_renderer_open( st_ivas ) ) != IVAS_ERR_OK )
408 : {
409 0 : return error;
410 : }
411 : }
412 : else
413 : {
414 : /* ISM renderer handle + ISM data handle */
415 5212 : ivas_omasa_separate_object_renderer_close( st_ivas );
416 : }
417 : }
418 :
419 52526 : if ( st_ivas->renderer_type == RENDERER_OMASA_MIX_EXT )
420 : {
421 : /* Allocate 'hIsmRendererData' handle */
422 804 : if ( ( error = ivas_omasa_combine_separate_ism_with_masa_open( st_ivas ) ) != IVAS_ERR_OK )
423 : {
424 0 : return error;
425 : }
426 : }
427 :
428 52526 : if ( st_ivas->renderer_type == RENDERER_OMASA_OBJECT_EXT )
429 : {
430 806 : DIRAC_CONFIG_FLAG common_rend_config_flag = st_ivas->hSpatParamRendCom == NULL ? DIRAC_OPEN : DIRAC_RECONFIGURE;
431 :
432 : /* Allocate 'hIsmRendererData' handle and memory for delay buffer within 'hMasaIsmData' */
433 806 : if ( ( error = ivas_omasa_objects_delay_open( st_ivas ) ) != IVAS_ERR_OK )
434 : {
435 0 : return error;
436 : }
437 :
438 806 : if ( ( error = ivas_spat_hSpatParamRendCom_config( &st_ivas->hSpatParamRendCom, common_rend_config_flag, 0,
439 806 : st_ivas->ivas_format, st_ivas->mc_mode, st_ivas->hDecoderConfig->output_Fs, 0, 0 ) ) != IVAS_ERR_OK )
440 : {
441 0 : return error;
442 : }
443 : }
444 :
445 : /*-----------------------------------------------------------------*
446 : * TD Decorrelator
447 : *-----------------------------------------------------------------*/
448 :
449 52526 : if ( st_ivas->hDiracDecBin[0] != NULL )
450 : {
451 25851 : if ( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin[0]->hTdDecorr ), &( st_ivas->hDiracDecBin[0]->useTdDecorr ) ) ) != IVAS_ERR_OK )
452 : {
453 0 : return error;
454 : }
455 : }
456 :
457 : /*-----------------------------------------------------------------*
458 : * CLDFB instances
459 : *-----------------------------------------------------------------*/
460 :
461 52526 : if ( ( error = ivas_cldfb_dec_reconfig( st_ivas, 2, numCldfbAnalyses_old, numCldfbSyntheses_old ) ) != IVAS_ERR_OK )
462 : {
463 0 : return error;
464 : }
465 :
466 : /*-----------------------------------------------------------------*
467 : * floating-point output audio buffers
468 : *-----------------------------------------------------------------*/
469 :
470 52526 : nchan_out_buff = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 );
471 52526 : if ( ( error = ivas_output_buff_dec( st_ivas->p_output_f, nchan_out_buff, st_ivas->hDecoderConfig->Opt_tsm, st_ivas->hTcBuffer ) ) != IVAS_ERR_OK )
472 : {
473 0 : return error;
474 : }
475 : }
476 :
477 53358 : return IVAS_ERR_OK;
478 : }
479 :
480 :
481 : /*--------------------------------------------------------------------------*
482 : * ivas_set_surplus_brate_dec()
483 : *
484 : * set bit-rate surplus in combined format coding
485 : *--------------------------------------------------------------------------*/
486 :
487 630561 : void ivas_set_surplus_brate_dec(
488 : Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
489 : int32_t *ism_total_brate /* i/o: ISM total bitrate */
490 : )
491 : {
492 : int16_t n, bits_ism, bits_element[MAX_NUM_OBJECTS];
493 : int32_t ism_total_brate_ref, element_brate[MAX_NUM_OBJECTS];
494 :
495 630561 : *ism_total_brate = 0;
496 :
497 630561 : if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
498 : {
499 225922 : *ism_total_brate = ivas_interformat_brate( st_ivas->ism_mode, 1, st_ivas->hSCE[0]->element_brate, st_ivas->hIsmMetaData[0]->ism_imp, 0 );
500 :
501 225922 : st_ivas->hCPE[0]->brate_surplus = st_ivas->hSCE[0]->element_brate - *ism_total_brate;
502 :
503 : /* set 'st->total_brate'; there are no meta-data in ISM_MASA_MODE_PARAM_ONE_OBJ mode */
504 225922 : st_ivas->hSCE[0]->hCoreCoder[0]->total_brate = *ism_total_brate;
505 :
506 225922 : st_ivas->hSCE[0]->hCoreCoder[0]->low_rate_mode = 0;
507 225922 : if ( st_ivas->hIsmMetaData[0]->ism_imp == ISM_NO_META )
508 : {
509 3784 : st_ivas->hSCE[0]->hCoreCoder[0]->low_rate_mode = 1;
510 : }
511 : }
512 404639 : else if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC )
513 : {
514 : int16_t brate_limit_flag, ism_imp[MAX_NUM_OBJECTS];
515 :
516 1352553 : for ( n = 0; n < st_ivas->nchan_ism; n++ )
517 : {
518 947914 : ism_imp[n] = st_ivas->hIsmMetaData[n]->ism_imp;
519 : }
520 :
521 404639 : brate_limit_flag = calculate_brate_limit_flag( ism_imp, st_ivas->nchan_ism );
522 :
523 404639 : ism_total_brate_ref = 0;
524 1352553 : for ( n = 0; n < st_ivas->nchan_ism; n++ )
525 : {
526 947914 : ism_total_brate_ref += st_ivas->hSCE[n]->element_brate;
527 : }
528 :
529 404639 : bits_ism = (int16_t) ( ism_total_brate_ref / FRAMES_PER_SEC );
530 404639 : set_s( bits_element, bits_ism / st_ivas->nchan_ism, st_ivas->nchan_ism );
531 404639 : bits_element[st_ivas->nchan_ism - 1] += bits_ism % st_ivas->nchan_ism;
532 404639 : bitbudget_to_brate( bits_element, element_brate, st_ivas->nchan_ism );
533 :
534 404639 : *ism_total_brate = 0;
535 1352553 : for ( n = 0; n < st_ivas->nchan_ism; n++ )
536 : {
537 947914 : st_ivas->hSCE[n]->element_brate = element_brate[n];
538 :
539 947914 : *ism_total_brate += ivas_interformat_brate( ISM_MASA_MODE_DISC, st_ivas->nchan_ism, st_ivas->hSCE[n]->element_brate, st_ivas->hIsmMetaData[n]->ism_imp, brate_limit_flag );
540 :
541 947914 : if ( ism_imp[n] > 1 && st_ivas->flag_omasa_brate == 1 && brate_limit_flag >= 0 )
542 : {
543 11300 : *ism_total_brate -= ADJUST_ISM_BRATE_NEG;
544 : }
545 :
546 947914 : if ( brate_limit_flag == -1 && ism_imp[n] >= 1 && st_ivas->nchan_ism >= 3 && ( ism_total_brate_ref - *ism_total_brate > IVAS_48k ) )
547 : {
548 2800 : *ism_total_brate += ADJUST_ISM_BRATE_POS;
549 : }
550 : }
551 404639 : st_ivas->hCPE[0]->brate_surplus = ism_total_brate_ref - *ism_total_brate;
552 :
553 : /* 'st->total_brate' is set in ivas_ism_config */
554 : }
555 : else
556 : {
557 0 : st_ivas->hCPE[0]->brate_surplus = 0;
558 : }
559 :
560 630561 : return;
561 : }
562 :
563 :
564 : /*--------------------------------------------------------------------------*
565 : * ivas_omasa_ism_metadata_dec()
566 : *
567 : * decode ISM metadata in OMASA format
568 : *--------------------------------------------------------------------------*/
569 :
570 630561 : ivas_error ivas_omasa_ism_metadata_dec(
571 : Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
572 : const int32_t ism_total_brate, /* i : ISM total bitrate */
573 : int16_t *nchan_ism, /* o : number of ISM separated channels */
574 : int16_t *nchan_transport_ism, /* o : number of ISM TCs */
575 : const int16_t dirac_bs_md_write_idx, /* i : DirAC bitstream write index */
576 : int16_t nb_bits_metadata[] /* o : number of ISM metadata bits */
577 : )
578 : {
579 : int16_t n, block;
580 : int16_t azimuth_ism, elevation_ism, meta_write_index;
581 : ivas_error error;
582 :
583 : /* set ISM parameters */
584 630561 : *nchan_ism = st_ivas->nchan_ism;
585 630561 : *nchan_transport_ism = st_ivas->nchan_ism;
586 630561 : if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
587 : {
588 104636 : *nchan_ism = 1;
589 104636 : *nchan_transport_ism = 1;
590 : }
591 525925 : else if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
592 : {
593 121286 : *nchan_ism = 0;
594 121286 : *nchan_transport_ism = 1;
595 : }
596 :
597 630561 : if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC || st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
598 : {
599 : /* decode ISM metadata */
600 509275 : if ( ( error = ivas_ism_metadata_dec( ism_total_brate, *nchan_ism, nchan_transport_ism, st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->bfi,
601 509275 : nb_bits_metadata, st_ivas->ism_mode, st_ivas->hISMDTX, NULL, &st_ivas->ism_extmeta_active, &st_ivas->ism_extmeta_cnt, st_ivas->hSCE[0]->hCoreCoder[0] ) ) != IVAS_ERR_OK )
602 : {
603 0 : return error;
604 : }
605 :
606 509275 : if ( st_ivas->hDirAC != NULL )
607 : {
608 421937 : if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC )
609 : {
610 1098931 : for ( n = 0; n < st_ivas->nchan_ism; n++ )
611 : {
612 765604 : azimuth_ism = (int16_t) ( st_ivas->hIsmMetaData[n]->azimuth + 0.5f );
613 765604 : elevation_ism = (int16_t) ( st_ivas->hIsmMetaData[n]->elevation + 0.5f );
614 :
615 3828020 : for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
616 : {
617 3062416 : meta_write_index = ( dirac_bs_md_write_idx + block ) % st_ivas->hSpatParamRendCom->dirac_md_buffer_length;
618 3062416 : st_ivas->hMasaIsmData->azimuth_ism[n][meta_write_index] = azimuth_ism;
619 3062416 : st_ivas->hMasaIsmData->elevation_ism[n][meta_write_index] = elevation_ism;
620 : }
621 : }
622 : }
623 : else /* ISM_MASA_MODE_MASA_ONE_OBJ */
624 : {
625 88610 : azimuth_ism = (int16_t) ( st_ivas->hIsmMetaData[0]->azimuth + 0.5f );
626 88610 : elevation_ism = (int16_t) ( st_ivas->hIsmMetaData[0]->elevation + 0.5f );
627 :
628 443050 : for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
629 : {
630 354440 : meta_write_index = ( dirac_bs_md_write_idx + block ) % st_ivas->hSpatParamRendCom->dirac_md_buffer_length;
631 354440 : st_ivas->hMasaIsmData->azimuth_separated_ism[meta_write_index] = azimuth_ism;
632 354440 : st_ivas->hMasaIsmData->elevation_separated_ism[meta_write_index] = elevation_ism;
633 : }
634 : }
635 : }
636 87338 : else if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ && st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL )
637 : {
638 3984 : azimuth_ism = (int16_t) ( st_ivas->hIsmMetaData[0]->azimuth + 0.5f );
639 3984 : elevation_ism = (int16_t) ( st_ivas->hIsmMetaData[0]->elevation + 0.5f );
640 :
641 11952 : for ( block = 0; block < 2; block++ )
642 : {
643 7968 : st_ivas->hMasaIsmData->azimuth_separated_ism[block] = st_ivas->hMasaIsmData->azimuth_separated_ism[block + 2];
644 7968 : st_ivas->hMasaIsmData->elevation_separated_ism[block] = st_ivas->hMasaIsmData->elevation_separated_ism[block + 2];
645 : }
646 11952 : for ( block = 2; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
647 : {
648 7968 : st_ivas->hMasaIsmData->azimuth_separated_ism[block] = azimuth_ism;
649 7968 : st_ivas->hMasaIsmData->elevation_separated_ism[block] = elevation_ism;
650 : }
651 : }
652 : }
653 :
654 630561 : return IVAS_ERR_OK;
655 : }
656 :
657 :
658 : /*--------------------------------------------------------------------------*
659 : * ivas_omasa_dirac_rend_jbm()
660 : *
661 : * Rendering in OMASA format for JBM
662 : *--------------------------------------------------------------------------*/
663 :
664 305496 : void ivas_omasa_dirac_rend_jbm(
665 : Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */
666 : const uint16_t nSamplesAsked, /* i : number of samples requested */
667 : uint16_t *nSamplesRendered, /* o : number of samples rendered */
668 : uint16_t *nSamplesAvailable, /* o : number of samples still to render */
669 : const int16_t nchan_transport, /* i : number of transport channels */
670 : float *output_f[] /* o : rendered time signal */
671 : )
672 : {
673 : int16_t subframes_rendered;
674 : int16_t n;
675 : float data_separated_objects[MAX_NUM_OBJECTS][L_FRAME48k];
676 :
677 305496 : *nSamplesRendered = min( nSamplesAsked, st_ivas->hTcBuffer->n_samples_available );
678 :
679 305496 : if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
680 : {
681 102343 : mvr2r( &output_f[CPE_CHANNELS][st_ivas->hTcBuffer->n_samples_rendered], data_separated_objects[0], *nSamplesRendered );
682 :
683 102343 : if ( !st_ivas->hDecoderConfig->Opt_tsm && st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
684 : {
685 : /* Gain separated object, if edited */
686 145502 : for ( n = 0; n < st_ivas->nchan_ism; n++ )
687 : {
688 112638 : if ( st_ivas->hMasaIsmData->ism_gain_is_edited[n] && st_ivas->hMasaIsmData->idx_separated_ism == n )
689 : {
690 0 : v_multc( data_separated_objects[0], st_ivas->hMasaIsmData->gain_ism_edited[n], data_separated_objects[0], *nSamplesRendered );
691 : }
692 : }
693 : }
694 : }
695 : else
696 : {
697 654978 : for ( n = 0; n < st_ivas->nchan_ism; n++ )
698 : {
699 451825 : mvr2r( &output_f[n + CPE_CHANNELS][st_ivas->hTcBuffer->n_samples_rendered], data_separated_objects[n], *nSamplesRendered );
700 :
701 : /* Gain discrete objects, if edited */
702 451825 : if ( !st_ivas->hDecoderConfig->Opt_tsm && st_ivas->hMasaIsmData->ism_gain_is_edited[n] )
703 : {
704 0 : v_multc( data_separated_objects[n], st_ivas->hMasaIsmData->gain_ism_edited[n], data_separated_objects[n], *nSamplesRendered );
705 : }
706 : }
707 :
708 : /* Gain MASA part, if edited */
709 203153 : if ( !st_ivas->hDecoderConfig->Opt_tsm && st_ivas->hMasaIsmData->masa_gain_is_edited )
710 : {
711 0 : for ( int16_t ch = 0; ch < 2; ch++ )
712 : {
713 0 : v_multc( output_f[ch], st_ivas->hMasaIsmData->gain_masa_edited, output_f[ch], *nSamplesRendered );
714 : }
715 : }
716 : }
717 :
718 305496 : subframes_rendered = st_ivas->hSpatParamRendCom->subframes_rendered;
719 :
720 305496 : ivas_dirac_dec_render( st_ivas, nchan_transport, nSamplesAsked, nSamplesRendered, nSamplesAvailable, output_f );
721 :
722 305496 : ivas_omasa_separate_object_render_jbm( st_ivas, *nSamplesRendered, data_separated_objects, output_f, subframes_rendered );
723 :
724 305496 : return;
725 : }
726 :
727 :
728 : /*--------------------------------------------------------------------------*
729 : * ivas_omasa_dirac_td_binaural_render()
730 : *
731 : * Binaural rendering in OMASA format for JBM
732 : *--------------------------------------------------------------------------*/
733 :
734 47714 : ivas_error ivas_omasa_dirac_td_binaural_jbm(
735 : Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */
736 : const uint16_t nSamplesAsked, /* i : number of samples requested */
737 : uint16_t *nSamplesRendered, /* o : number of samples rendered */
738 : uint16_t *nSamplesAvailable, /* o : number of samples still to render */
739 : const int16_t nchan_transport, /* i : number of transport channels */
740 : float *output_f[] /* o : rendered time signal */
741 : )
742 : {
743 : int16_t n;
744 : float data_separated_objects[BINAURAL_CHANNELS][L_FRAME48k];
745 : ivas_error error;
746 : float *p_sepobj[BINAURAL_CHANNELS];
747 : int16_t slot_idx_start;
748 :
749 47714 : slot_idx_start = st_ivas->hSpatParamRendCom->slots_rendered;
750 :
751 143142 : for ( n = 0; n < BINAURAL_CHANNELS; n++ )
752 : {
753 95428 : p_sepobj[n] = &data_separated_objects[n][0];
754 : }
755 :
756 47714 : ivas_dirac_dec_binaural_render( st_ivas, nSamplesAsked, nSamplesRendered, nSamplesAvailable, nchan_transport, output_f );
757 :
758 : /* reset combined orientation access index before calling the td renderer */
759 47714 : ivas_combined_orientation_set_to_start_index( st_ivas->hCombinedOrientationData );
760 :
761 47714 : if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
762 0 : {
763 : int16_t slot_idx, num_cldfb_bands, nchan_transport_orig, cldfb_slots;
764 : float Cldfb_RealBuffer[CLDFB_NO_CHANNELS_MAX];
765 : float Cldfb_ImagBuffer[CLDFB_NO_CHANNELS_MAX];
766 : float *p_rend_obj[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS]; /* [8 * 2] */
767 :
768 0 : for ( n = 0; n < st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses * BINAURAL_CHANNELS; n++ )
769 : {
770 0 : p_rend_obj[n] = &output_f[n][0];
771 : }
772 :
773 0 : num_cldfb_bands = st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[0]->no_channels;
774 0 : nchan_transport_orig = st_ivas->nchan_transport;
775 0 : st_ivas->nchan_transport = st_ivas->nchan_ism;
776 :
777 0 : if ( ( error = ivas_td_binaural_renderer_sf_splitBinaural( st_ivas, p_rend_obj, *nSamplesRendered ) ) != IVAS_ERR_OK ) /* objects are read from st_ivas->hTcBuffer->tc[2..(1+n_isms)] */
778 : {
779 0 : return error;
780 : }
781 0 : st_ivas->nchan_transport = nchan_transport_orig;
782 0 : cldfb_slots = *nSamplesRendered / num_cldfb_bands;
783 :
784 0 : for ( n = 0; n < st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses * BINAURAL_CHANNELS; ++n )
785 : {
786 0 : for ( slot_idx = 0; slot_idx < cldfb_slots; slot_idx++ )
787 : {
788 0 : cldfbAnalysis_ts( &( p_rend_obj[n][num_cldfb_bands * slot_idx] ), Cldfb_RealBuffer, Cldfb_ImagBuffer, num_cldfb_bands, st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[n] );
789 :
790 : /* note: this intentionally differs from OSBA by: no scaling by 0.5 */
791 0 : v_add( st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[n][slot_idx_start + slot_idx], Cldfb_RealBuffer, st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[n][slot_idx_start + slot_idx], num_cldfb_bands );
792 0 : v_add( st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[n][slot_idx_start + slot_idx], Cldfb_ImagBuffer, st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[n][slot_idx_start + slot_idx], num_cldfb_bands );
793 : }
794 : }
795 : }
796 : else
797 : {
798 47714 : if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_sepobj, *nSamplesRendered ) ) != IVAS_ERR_OK )
799 : {
800 0 : return error;
801 : }
802 :
803 143142 : for ( n = 0; n < BINAURAL_CHANNELS; n++ )
804 : {
805 95428 : v_add( output_f[n], p_sepobj[n], output_f[n], *nSamplesRendered );
806 : }
807 : }
808 :
809 47714 : return IVAS_ERR_OK;
810 : }
811 :
812 :
813 : /*--------------------------------------------------------------------------*
814 : * ivas_omasa_rearrange_channels()
815 : *
816 : * in case of external rendering, rearrange the channels order
817 : *--------------------------------------------------------------------------*/
818 :
819 59832 : void ivas_omasa_rearrange_channels(
820 : float *output[], /* o : output synthesis signal */
821 : const int16_t nchan_transport_ism, /* o : number of ISM TCs */
822 : const int16_t output_frame /* i : output frame length per channel */
823 : )
824 : {
825 : int16_t n;
826 : float tmp_buff[CPE_CHANNELS][L_FRAME48k];
827 :
828 59832 : mvr2r( output[0], tmp_buff[0], output_frame );
829 59832 : mvr2r( output[1], tmp_buff[1], output_frame );
830 :
831 227964 : for ( n = 0; n < nchan_transport_ism; n++ )
832 : {
833 168132 : mvr2r( output[CPE_CHANNELS + n], output[n], output_frame );
834 : }
835 59832 : mvr2r( tmp_buff[0], output[n], output_frame );
836 59832 : mvr2r( tmp_buff[1], output[++n], output_frame );
837 :
838 59832 : return;
839 : }
840 :
841 :
842 : /*-------------------------------------------------------------------------*
843 : * ivas_omasa_combine_separate_ism_with_masa_open()
844 : *
845 : * Open structures, reserve memory, and init values.
846 : *-------------------------------------------------------------------------*/
847 :
848 852 : ivas_error ivas_omasa_combine_separate_ism_with_masa_open(
849 : Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
850 : )
851 : {
852 : int16_t i;
853 : int16_t interpolator_length;
854 :
855 852 : if ( ( st_ivas->hIsmRendererData = (ISM_RENDERER_HANDLE) malloc( sizeof( ISM_RENDERER_DATA ) ) ) == NULL )
856 : {
857 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for MASA ISM renderer \n" ) );
858 : }
859 :
860 4260 : for ( i = 0; i < MAX_NUM_OBJECTS; i++ )
861 : {
862 3408 : set_zero( st_ivas->hIsmRendererData->prev_gains[i], MAX_OUTPUT_CHANNELS );
863 : }
864 :
865 852 : interpolator_length = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES );
866 852 : st_ivas->hIsmRendererData->interpolator = (float *) malloc( sizeof( float ) * interpolator_length );
867 :
868 201492 : for ( i = 0; i < interpolator_length; i++ )
869 : {
870 200640 : st_ivas->hIsmRendererData->interpolator[i] = (float) i / ( (float) interpolator_length );
871 : }
872 852 : st_ivas->hIsmRendererData->interpolator_length = interpolator_length;
873 :
874 852 : return IVAS_ERR_OK;
875 : }
876 :
877 :
878 : /*--------------------------------------------------------------------------*
879 : * ivas_omasa_combine_separate_ism_with_masa()
880 : *
881 : * in case of external rendering, combine separated ISM signal with MASA stream
882 : *--------------------------------------------------------------------------*/
883 :
884 3984 : void ivas_omasa_combine_separate_ism_with_masa(
885 : Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */
886 : float *output[], /* i/o: output synthesis signal */
887 : const int16_t nchan_ism, /* i : number of ISMs */
888 : const int16_t output_frame /* i : output frame length per channel */
889 : )
890 : {
891 : int16_t n, sf, band, bin, k;
892 : MASA_DECODER_EXT_OUT_META_HANDLE masaMetaHandle;
893 : MASA_DECODER_EXT_OUT_META_HANDLE ismMetaHandle;
894 : MASA_DECODER_EXT_OUT_META ismMeta;
895 : float eneMasa[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
896 : float eneIsm[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
897 : float inRe[3][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
898 : float inIm[3][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
899 : float azimuth, elevation;
900 : uint16_t directionIndex;
901 : float old_panning_gains[2];
902 : float new_panning_gains[2];
903 : float panned_signal[L_FRAME48k];
904 : int16_t nchan_in;
905 : int16_t nBins;
906 : int16_t slot;
907 : int16_t mrange[2], brange[2];
908 : int16_t processing_len, offset;
909 : float g1, g2;
910 :
911 3984 : masaMetaHandle = st_ivas->hMasa->data.extOutMeta;
912 3984 : ismMetaHandle = &ismMeta;
913 :
914 : /* Compute CLDFB analysis */
915 3984 : nchan_in = st_ivas->nchan_transport + 1;
916 3984 : nBins = output_frame / CLDFB_NO_COL_MAX;
917 67728 : for ( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
918 : {
919 254976 : for ( n = 0; n < nchan_in; n++ )
920 : {
921 191232 : cldfbAnalysis_ts(
922 191232 : &( output[n][nBins * slot] ),
923 191232 : inRe[n][slot],
924 191232 : inIm[n][slot],
925 : nBins, st_ivas->cldfbAnaDec[n] );
926 : }
927 : }
928 :
929 : /* Determine energies */
930 19920 : for ( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
931 : {
932 15936 : mrange[0] = st_ivas->hMasa->config.block_grouping[sf];
933 15936 : mrange[1] = st_ivas->hMasa->config.block_grouping[sf + 1];
934 :
935 15936 : set_zero( eneMasa[sf], MASA_FREQUENCY_BANDS );
936 15936 : set_zero( eneIsm[sf], MASA_FREQUENCY_BANDS );
937 :
938 79680 : for ( slot = mrange[0]; slot < mrange[1]; slot++ )
939 : {
940 1593600 : for ( band = 0; band < MASA_FREQUENCY_BANDS; band++ )
941 : {
942 1529856 : brange[0] = st_ivas->hMasa->config.band_grouping[band];
943 1529856 : brange[1] = st_ivas->hMasa->config.band_grouping[band + 1];
944 :
945 1529856 : if ( brange[1] > nBins )
946 : {
947 63360 : brange[1] = nBins;
948 : }
949 :
950 4589568 : for ( n = 0; n < MASA_MAX_TRANSPORT_CHANNELS; n++ )
951 : {
952 9188352 : for ( bin = brange[0]; bin < brange[1]; bin++ )
953 : {
954 6128640 : eneMasa[sf][band] += inRe[n][slot][bin] * inRe[n][slot][bin] + inIm[n][slot][bin] * inIm[n][slot][bin];
955 : }
956 : }
957 4594176 : for ( bin = brange[0]; bin < brange[1]; bin++ )
958 : {
959 3064320 : eneIsm[sf][band] += inRe[MASA_MAX_TRANSPORT_CHANNELS][slot][bin] * inRe[MASA_MAX_TRANSPORT_CHANNELS][slot][bin] + inIm[MASA_MAX_TRANSPORT_CHANNELS][slot][bin] * inIm[MASA_MAX_TRANSPORT_CHANNELS][slot][bin];
960 : }
961 : }
962 : }
963 : }
964 :
965 : /* Determine MASA metadata for the object */
966 3984 : ismMetaHandle->descriptiveMeta.numberOfDirections = 0u;
967 19920 : for ( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
968 : {
969 15936 : azimuth = st_ivas->hMasaIsmData->azimuth_separated_ism[sf];
970 15936 : elevation = st_ivas->hMasaIsmData->elevation_separated_ism[sf];
971 :
972 15936 : directionIndex = index_theta_phi_16( &elevation, &azimuth, st_ivas->hMasa->data.sph_grid16 );
973 :
974 398400 : for ( band = 0; band < MASA_FREQUENCY_BANDS; band++ )
975 : {
976 382464 : ismMetaHandle->directionIndex[0][sf][band] = directionIndex;
977 382464 : ismMetaHandle->directToTotalRatio[0][sf][band] = UINT8_MAX;
978 382464 : ismMetaHandle->spreadCoherence[0][sf][band] = 0;
979 382464 : ismMetaHandle->surroundCoherence[sf][band] = 0;
980 382464 : ismMetaHandle->diffuseToTotalRatio[sf][band] = 0;
981 : }
982 : }
983 :
984 : /* Merge MASA metadatas */
985 3984 : ivas_prerend_merge_masa_metadata( masaMetaHandle, masaMetaHandle, IVAS_REND_AUDIO_CONFIG_TYPE_MASA, eneMasa, ismMetaHandle, IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED, eneIsm );
986 :
987 : /* Mix the separated object audio signal to the MASA audio signals */
988 3984 : ivas_get_stereo_panning_gains( st_ivas->hMasaIsmData->azimuth_separated_ism[0], st_ivas->hMasaIsmData->elevation_separated_ism[0], old_panning_gains );
989 3984 : ivas_get_stereo_panning_gains( st_ivas->hMasaIsmData->azimuth_separated_ism[2], st_ivas->hMasaIsmData->elevation_separated_ism[2], new_panning_gains );
990 :
991 3984 : processing_len = output_frame / 2;
992 11952 : for ( n = 0; n < MASA_MAX_TRANSPORT_CHANNELS; n++ )
993 : {
994 7968 : v_multc( output[MASA_MAX_TRANSPORT_CHANNELS], old_panning_gains[n], panned_signal, processing_len );
995 7968 : v_add( output[n], panned_signal, output[n], processing_len );
996 : }
997 3984 : offset = processing_len;
998 :
999 3984 : processing_len = output_frame / MAX_PARAM_SPATIAL_SUBFRAMES;
1000 11952 : for ( n = 0; n < MASA_MAX_TRANSPORT_CHANNELS; n++ )
1001 : {
1002 1540128 : for ( k = 0; k < processing_len; k++ )
1003 : {
1004 1532160 : g1 = st_ivas->hIsmRendererData->interpolator[k];
1005 1532160 : g2 = 1.0f - g1;
1006 1532160 : output[n][k + offset] += ( g1 * new_panning_gains[n] + g2 * old_panning_gains[n] ) * output[MASA_MAX_TRANSPORT_CHANNELS][k + offset];
1007 : }
1008 : }
1009 3984 : offset += processing_len;
1010 :
1011 11952 : for ( n = 0; n < MASA_MAX_TRANSPORT_CHANNELS; n++ )
1012 : {
1013 7968 : v_multc( &output[MASA_MAX_TRANSPORT_CHANNELS][offset], new_panning_gains[n], panned_signal, processing_len );
1014 7968 : v_add( &output[n][offset], panned_signal, &output[n][offset], processing_len );
1015 : }
1016 :
1017 : /* Zero output object channels */
1018 18732 : for ( n = 0; n < nchan_ism; n++ )
1019 : {
1020 14748 : set_zero( output[MASA_MAX_TRANSPORT_CHANNELS + n], output_frame );
1021 : }
1022 :
1023 3984 : return;
1024 : }
1025 :
1026 :
1027 : /*-------------------------------------------------------------------------*
1028 : * ivas_omasa_objects_delay_open()
1029 : *
1030 : * Open structures, reserve memory, and init values for dela buffers of objects.
1031 : *-------------------------------------------------------------------------*/
1032 :
1033 21271 : ivas_error ivas_omasa_objects_delay_open(
1034 : Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
1035 : )
1036 : {
1037 : int16_t i;
1038 :
1039 21271 : if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
1040 : {
1041 9492 : st_ivas->hMasaIsmData->delayBuffer_nchan = 1;
1042 : }
1043 : else
1044 : {
1045 11779 : st_ivas->hMasaIsmData->delayBuffer_nchan = st_ivas->nchan_ism;
1046 : }
1047 :
1048 21271 : st_ivas->hMasaIsmData->delayBuffer_size = (int16_t) ( ( st_ivas->hDecoderConfig->output_Fs / 50 ) / MAX_PARAM_SPATIAL_SUBFRAMES );
1049 :
1050 21271 : if ( ( st_ivas->hMasaIsmData->delayBuffer = (float **) malloc( st_ivas->hMasaIsmData->delayBuffer_nchan * sizeof( float * ) ) ) == NULL )
1051 : {
1052 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for MASA ISM delay buffer \n" ) );
1053 : }
1054 :
1055 64827 : for ( i = 0; i < st_ivas->hMasaIsmData->delayBuffer_nchan; i++ )
1056 : {
1057 43556 : if ( ( st_ivas->hMasaIsmData->delayBuffer[i] = (float *) malloc( st_ivas->hMasaIsmData->delayBuffer_size * sizeof( float ) ) ) == NULL )
1058 : {
1059 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for MASA ISM delay buffer \n" ) );
1060 : }
1061 43556 : set_zero( st_ivas->hMasaIsmData->delayBuffer[i], st_ivas->hMasaIsmData->delayBuffer_size );
1062 : }
1063 :
1064 21271 : return IVAS_ERR_OK;
1065 : }
1066 :
1067 :
1068 : /*--------------------------------------------------------------------------*
1069 : * ivas_omasa_render_objects_from_mix()
1070 : *
1071 : * In case of external rendering, render objects from the transport signal
1072 : * mix containing MASA audio and object audio.
1073 : *--------------------------------------------------------------------------*/
1074 :
1075 5484 : void ivas_omasa_render_objects_from_mix(
1076 : Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */
1077 : float *output[], /* o : output synthesis signal */
1078 : const int16_t nchan_ism, /* i : number of ISMs */
1079 : const int16_t output_frame /* i : output frame length per channel */
1080 : )
1081 : {
1082 : int16_t n, m, i;
1083 : MASA_ISM_EXT_DATA_HANDLE hExtData;
1084 : float separated_object[L_FRAME48k];
1085 : float rendered_objects[MAX_NUM_OBJECTS][L_FRAME48k];
1086 : int16_t coding_delay;
1087 : float new_panning_gains[2];
1088 : float panning_gains[2];
1089 : float azimuth, elevation;
1090 : float inRe[3][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
1091 : float inIm[3][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
1092 : float outRe[MAX_NUM_OBJECTS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
1093 : float outIm[MAX_NUM_OBJECTS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
1094 : float ism_proto_energy[MAX_NUM_OBJECTS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
1095 : float transport_energy[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
1096 : float ism_target_energy[MAX_NUM_OBJECTS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
1097 : float masa_target_energy[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
1098 : float ism_processing_gains[MAX_NUM_OBJECTS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
1099 : float masa_processing_gains[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
1100 : int16_t slot;
1101 : int16_t sf;
1102 : int16_t bin;
1103 : int16_t nchan_transport;
1104 : int16_t nBins;
1105 : float interpVal;
1106 : float *outSlotRePr, *outSlotImPr;
1107 : int16_t md_idx;
1108 : float iir_factor_prev, iir_factor_curr;
1109 :
1110 : /* Create slot to metadata map */
1111 27420 : for ( sf = 0, slot = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
1112 : {
1113 109680 : for ( i = 0; i < CLDFB_SLOTS_PER_SUBFRAME; i++, slot++ )
1114 : {
1115 87744 : st_ivas->hSpatParamRendCom->render_to_md_map[slot] = st_ivas->hSpatParamRendCom->dirac_read_idx;
1116 : }
1117 21936 : st_ivas->hSpatParamRendCom->dirac_read_idx = ( st_ivas->hSpatParamRendCom->dirac_read_idx + 1 ) % st_ivas->hSpatParamRendCom->dirac_md_buffer_length;
1118 : }
1119 :
1120 : /* Move separated object signal and object channels */
1121 5484 : mvr2r( output[CPE_CHANNELS], separated_object, output_frame );
1122 24444 : for ( n = 0; n < nchan_ism; n++ )
1123 : {
1124 18960 : set_zero( output[CPE_CHANNELS + n], output_frame );
1125 : }
1126 :
1127 : /* Delay the separated object signal by the CLDFB delay */
1128 5484 : delay_signal( separated_object, output_frame, st_ivas->hMasaIsmData->delayBuffer[0], st_ivas->hMasaIsmData->delayBuffer_size );
1129 :
1130 : /* Set object metadata to the ism struct */
1131 24444 : for ( n = 0; n < nchan_ism; n++ )
1132 : {
1133 18960 : st_ivas->hIsmMetaData[n]->azimuth = st_ivas->hMasaIsmData->azimuth_ism[n][st_ivas->hSpatParamRendCom->dirac_read_idx];
1134 18960 : st_ivas->hIsmMetaData[n]->elevation = st_ivas->hMasaIsmData->elevation_ism[n][st_ivas->hSpatParamRendCom->dirac_read_idx];
1135 : }
1136 :
1137 : /* Move the separated object signal to the correct output channel */
1138 5484 : hExtData = st_ivas->hMasaIsmData->hExtData;
1139 5484 : coding_delay = output_frame / 20 * 17; /* 17 ms of coding and CLDFB delay */
1140 5484 : mvr2r( separated_object, output[CPE_CHANNELS + hExtData->prev_idx_separated_ism], coding_delay );
1141 5484 : mvr2r( &separated_object[coding_delay], &output[CPE_CHANNELS + st_ivas->hMasaIsmData->idx_separated_ism][coding_delay], output_frame - coding_delay );
1142 :
1143 : /* Compute CLDFB analysis */
1144 5484 : nchan_transport = st_ivas->nchan_transport;
1145 5484 : nBins = output_frame / CLDFB_NO_COL_MAX;
1146 93228 : for ( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1147 : {
1148 263232 : for ( n = 0; n < nchan_transport; n++ )
1149 : {
1150 175488 : cldfbAnalysis_ts(
1151 175488 : &( output[n][nBins * slot] ),
1152 175488 : inRe[n][slot],
1153 175488 : inIm[n][slot],
1154 : nBins, st_ivas->cldfbAnaDec[n] );
1155 : }
1156 : }
1157 :
1158 : /* Create prototype signals */
1159 24444 : for ( n = 0; n < nchan_ism; n++ )
1160 : {
1161 18960 : azimuth = (float) st_ivas->hIsmMetaData[n]->azimuth;
1162 18960 : elevation = (float) st_ivas->hIsmMetaData[n]->elevation;
1163 18960 : ivas_get_stereo_panning_gains( azimuth, elevation, new_panning_gains );
1164 18960 : interpVal = 0.0f;
1165 :
1166 322320 : for ( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1167 : {
1168 303360 : interpVal += 1.0f / (float) CLDFB_NO_COL_MAX;
1169 910080 : for ( m = 0; m < 2; m++ )
1170 : {
1171 606720 : panning_gains[m] = ( 1.0f - interpVal ) * hExtData->prev_panning_gains[n][m] + interpVal * new_panning_gains[m];
1172 : }
1173 303360 : v_multc( inRe[0][slot], panning_gains[0], outRe[n][slot], nBins );
1174 303360 : v_multc( inIm[0][slot], panning_gains[0], outIm[n][slot], nBins );
1175 303360 : v_multc_acc( inRe[1][slot], panning_gains[1], outRe[n][slot], nBins );
1176 303360 : v_multc_acc( inIm[1][slot], panning_gains[1], outIm[n][slot], nBins );
1177 : }
1178 :
1179 56880 : for ( m = 0; m < 2; m++ )
1180 : {
1181 37920 : hExtData->prev_panning_gains[n][m] = new_panning_gains[m];
1182 : }
1183 : }
1184 :
1185 : /* Determine prototype energy */
1186 24444 : for ( n = 0; n < nchan_ism; n++ )
1187 : {
1188 322320 : for ( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1189 : {
1190 14703360 : for ( bin = 0; bin < nBins; bin++ )
1191 : {
1192 14400000 : ism_proto_energy[n][slot][bin] = ( outRe[n][slot][bin] * outRe[n][slot][bin] ) + ( outIm[n][slot][bin] * outIm[n][slot][bin] );
1193 : }
1194 : }
1195 : }
1196 :
1197 : /* Determine transport energy */
1198 93228 : for ( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1199 : {
1200 87744 : set_zero( transport_energy[slot], nBins );
1201 : }
1202 16452 : for ( n = 0; n < CPE_CHANNELS; n++ )
1203 : {
1204 186456 : for ( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1205 : {
1206 8423808 : for ( bin = 0; bin < nBins; bin++ )
1207 : {
1208 8248320 : transport_energy[slot][bin] += ( inRe[n][slot][bin] * inRe[n][slot][bin] ) + ( inIm[n][slot][bin] * inIm[n][slot][bin] );
1209 : }
1210 : }
1211 : }
1212 :
1213 : /* Determine target energy */
1214 24444 : for ( n = 0; n < nchan_ism; n++ )
1215 : {
1216 322320 : for ( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1217 : {
1218 303360 : md_idx = st_ivas->hSpatParamRendCom->render_to_md_map[slot];
1219 14703360 : for ( bin = 0; bin < nBins; bin++ )
1220 : {
1221 14400000 : ism_target_energy[n][slot][bin] = transport_energy[slot][bin] * st_ivas->hMasaIsmData->energy_ratio_ism[n][md_idx][bin];
1222 : }
1223 : }
1224 : }
1225 93228 : for ( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1226 : {
1227 87744 : md_idx = st_ivas->hSpatParamRendCom->render_to_md_map[slot];
1228 4211904 : for ( bin = 0; bin < nBins; bin++ )
1229 : {
1230 4124160 : masa_target_energy[slot][bin] = transport_energy[slot][bin] * hExtData->masa_render_masa_to_total[md_idx][bin];
1231 : }
1232 : }
1233 :
1234 : /* Determine temporally smoothed energies and determine gains using them */
1235 5484 : iir_factor_curr = ( 1.0f - EXT_RENDER_IIR_FAC );
1236 5484 : iir_factor_prev = EXT_RENDER_IIR_FAC;
1237 24444 : for ( n = 0; n < nchan_ism; n++ )
1238 : {
1239 322320 : for ( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1240 : {
1241 14703360 : for ( bin = 0; bin < nBins; bin++ )
1242 : {
1243 14400000 : hExtData->ism_render_proto_energy[n][bin] *= iir_factor_prev;
1244 14400000 : hExtData->ism_render_proto_energy[n][bin] += iir_factor_curr * ism_proto_energy[n][slot][bin];
1245 14400000 : hExtData->ism_render_target_energy[n][bin] *= iir_factor_prev;
1246 14400000 : hExtData->ism_render_target_energy[n][bin] += iir_factor_curr * ism_target_energy[n][slot][bin];
1247 :
1248 14400000 : ism_processing_gains[n][slot][bin] = fminf( 4.0f, sqrtf( hExtData->ism_render_target_energy[n][bin] / fmaxf( 1e-12f, hExtData->ism_render_proto_energy[n][bin] ) ) );
1249 : }
1250 : }
1251 : }
1252 93228 : for ( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1253 : {
1254 4211904 : for ( bin = 0; bin < nBins; bin++ )
1255 : {
1256 4124160 : hExtData->masa_render_proto_energy[bin] *= iir_factor_prev;
1257 4124160 : hExtData->masa_render_proto_energy[bin] += iir_factor_curr * transport_energy[slot][bin];
1258 4124160 : hExtData->masa_render_target_energy[bin] *= iir_factor_prev;
1259 4124160 : hExtData->masa_render_target_energy[bin] += iir_factor_curr * masa_target_energy[slot][bin];
1260 :
1261 4124160 : masa_processing_gains[slot][bin] = fminf( 4.0f, sqrtf( hExtData->masa_render_target_energy[bin] / fmaxf( 1e-12f, hExtData->masa_render_proto_energy[bin] ) ) );
1262 : }
1263 : }
1264 :
1265 : /* Determine output signals */
1266 24444 : for ( n = 0; n < nchan_ism; n++ )
1267 : {
1268 322320 : for ( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1269 : {
1270 14703360 : for ( bin = 0; bin < nBins; bin++ )
1271 : {
1272 14400000 : outRe[n][slot][bin] *= ism_processing_gains[n][slot][bin];
1273 14400000 : outIm[n][slot][bin] *= ism_processing_gains[n][slot][bin];
1274 : }
1275 : }
1276 : }
1277 16452 : for ( n = 0; n < MASA_MAX_TRANSPORT_CHANNELS; n++ )
1278 : {
1279 186456 : for ( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1280 : {
1281 8423808 : for ( bin = 0; bin < nBins; bin++ )
1282 : {
1283 8248320 : inRe[n][slot][bin] *= masa_processing_gains[slot][bin];
1284 8248320 : inIm[n][slot][bin] *= masa_processing_gains[slot][bin];
1285 : }
1286 : }
1287 : }
1288 :
1289 : /* Compute CLDFB synthesis */
1290 93228 : for ( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1291 : {
1292 263232 : for ( n = 0; n < nchan_transport; n++ )
1293 : {
1294 175488 : outSlotRePr = &( inRe[n][slot][0] );
1295 175488 : outSlotImPr = &( inIm[n][slot][0] );
1296 175488 : cldfbSynthesis( &outSlotRePr, &outSlotImPr, &( output[n][nBins * slot] ), nBins, st_ivas->cldfbSynDec[n] );
1297 : }
1298 :
1299 391104 : for ( n = 0; n < nchan_ism; n++ )
1300 : {
1301 303360 : outSlotRePr = &( outRe[n][slot][0] );
1302 303360 : outSlotImPr = &( outIm[n][slot][0] );
1303 303360 : cldfbSynthesis( &outSlotRePr, &outSlotImPr, &( rendered_objects[n][nBins * slot] ), nBins, st_ivas->cldfbSynDec[n + CPE_CHANNELS] );
1304 : }
1305 : }
1306 :
1307 : /* Combine the rendered objects with the separated objects */
1308 24444 : for ( n = 0; n < nchan_ism; n++ )
1309 : {
1310 18960 : v_add( output[CPE_CHANNELS + n], rendered_objects[n], output[CPE_CHANNELS + n], output_frame );
1311 : }
1312 :
1313 5484 : hExtData->prev_idx_separated_ism = st_ivas->hMasaIsmData->idx_separated_ism;
1314 :
1315 5484 : return;
1316 : }
1317 :
1318 :
1319 : /*--------------------------------------------------------------------------*
1320 : * ivas_omasa_gain_masa_tc()
1321 : *
1322 : * in case of external rendering with object editing, MASA transport channels
1323 : * need to be gained
1324 : *--------------------------------------------------------------------------*/
1325 :
1326 0 : void ivas_omasa_gain_masa_tc(
1327 : float *output[], /* i/o: output synthesis signal */
1328 : const float gainMasa, /* i : gain */
1329 : const int16_t nchan_transport_ism, /* i : number of ISM TCs */
1330 : const int16_t output_frame /* i : output frame length per channel */
1331 : )
1332 : {
1333 : /* Edited OMASA EXT MASA transport gaining */
1334 0 : for ( int16_t ch = 0; ch < CPE_CHANNELS; ch++ )
1335 : {
1336 0 : v_multc( output[nchan_transport_ism + ch], gainMasa, output[nchan_transport_ism + ch], output_frame );
1337 : }
1338 :
1339 0 : return;
1340 : }
|