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