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 2607 : 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 2607 : if ( hMasaIsmData == NULL || *hMasaIsmData == NULL )
162 : {
163 1743 : 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;
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 : st_ivas->ivas_format = ivas_format_orig;
219 :
220 4818 : nSCE_old = st_ivas->nSCE;
221 4818 : nchan_hp20_old = getNumChanSynthesis( st_ivas );
222 :
223 : /* set ism_mode of current frame */
224 4818 : st_ivas->ism_mode = ivas_omasa_ism_mode_select( ivas_total_brate, st_ivas->nchan_ism );
225 :
226 : /*-----------------------------------------------------------------*
227 : * Renderer selection
228 : *-----------------------------------------------------------------*/
229 :
230 4818 : old_renderer_type = st_ivas->renderer_type;
231 :
232 : /* MASA reconfig. */
233 4818 : cpe_brate = calculate_cpe_brate_MASA_ISM( st_ivas->ism_mode, ivas_total_brate, st_ivas->nchan_ism );
234 4818 : 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 4818 : else if ( ( error = ivas_masa_dec_reconfigure( st_ivas ) ) != IVAS_ERR_OK )
239 : {
240 0 : return error;
241 : }
242 :
243 4818 : if ( cpe_brate < MASA_STEREO_MIN_BITRATE )
244 : {
245 1629 : st_ivas->hCPE[0]->nchan_out = 1;
246 : }
247 : else
248 : {
249 3189 : st_ivas->hCPE[0]->nchan_out = 2;
250 : }
251 :
252 : /* OMASA reconfig. */
253 4818 : if ( st_ivas->hMasaIsmData == NULL && st_ivas->ivas_format == MASA_ISM_FORMAT )
254 : {
255 6 : if ( ( error = ivas_omasa_data_open( st_ivas ) ) != IVAS_ERR_OK )
256 : {
257 0 : return error;
258 : }
259 : }
260 :
261 4818 : 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 4818 : 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 4818 : k = 0;
271 38013 : while ( k < SIZE_IVAS_BRATE_TBL && ivas_total_brate != ivas_brate_tbl[k] )
272 : {
273 33195 : k++;
274 : }
275 :
276 11037 : for ( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ )
277 : {
278 6219 : ism_total_brate += sep_object_brate[k - 2][st_ivas->nSCE - 1];
279 : }
280 :
281 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 )
282 : {
283 0 : return error;
284 : }
285 :
286 4818 : if ( ism_mode_old != st_ivas->ism_mode )
287 : {
288 : /* ISM MD reconfig. */
289 4815 : if ( st_ivas->hIsmMetaData[0] == NULL )
290 : {
291 6 : 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 20343 : for ( k = 0; k < st_ivas->nchan_ism; k++ )
299 : {
300 15534 : ivas_ism_reset_metadata_handle_dec( st_ivas->hIsmMetaData[k] );
301 : }
302 : }
303 :
304 4815 : st_ivas->hCPE[0]->element_brate = ivas_total_brate - ism_total_brate;
305 :
306 : /*-----------------------------------------------------------------*
307 : * Renderer selection
308 : *-----------------------------------------------------------------*/
309 :
310 4815 : ivas_renderer_select( st_ivas );
311 :
312 : /*-------------------------------------------------------------------*
313 : * Reallocate rendering handles
314 : *--------------------------------------------------------------------*/
315 :
316 4815 : if ( old_renderer_type != st_ivas->renderer_type )
317 : {
318 414 : if ( st_ivas->renderer_type == RENDERER_MONO_DOWNMIX )
319 : {
320 114 : if ( ( error = ivas_mono_dmx_renderer_open( st_ivas ) ) != IVAS_ERR_OK )
321 : {
322 0 : return error;
323 : }
324 : }
325 : else
326 : {
327 300 : ivas_mono_dmx_renderer_close( &st_ivas->hMonoDmxRenderer );
328 : }
329 : }
330 :
331 : /* objects renderer reconfig. */
332 4815 : 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 4815 : ivas_omasa_separate_object_renderer_close( st_ivas );
336 : }
337 :
338 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 */
339 : {
340 1185 : MASA_ISM_DATA_HANDLE hMasaIsmData = st_ivas->hMasaIsmData;
341 5925 : for ( int16_t obj_idx = 0; obj_idx < MAX_NUM_OBJECTS; obj_idx++ )
342 : {
343 4740 : set_s( hMasaIsmData->azimuth_ism[obj_idx], 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR );
344 4740 : set_s( hMasaIsmData->elevation_ism[obj_idx], 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR );
345 33180 : for ( int16_t sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR; sf++ )
346 : {
347 28440 : set_zero( hMasaIsmData->energy_ratio_ism[obj_idx][sf], CLDFB_NO_CHANNELS_MAX );
348 : }
349 : }
350 1185 : set_s( hMasaIsmData->azimuth_separated_ism, 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR );
351 1185 : set_s( hMasaIsmData->elevation_separated_ism, 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR );
352 : }
353 :
354 4815 : if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC )
355 : {
356 885 : if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC )
357 : {
358 : /* Allocate TD renderer for the objects in DISC mode */
359 234 : if ( st_ivas->hBinRendererTd == NULL )
360 : {
361 234 : if ( ( error = ivas_td_binaural_open( st_ivas ) ) != IVAS_ERR_OK )
362 : {
363 0 : return error;
364 : }
365 :
366 234 : 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 234 : if ( ( error = ivas_omasa_objects_delay_open( st_ivas ) ) != IVAS_ERR_OK )
377 : {
378 0 : return error;
379 : }
380 : }
381 : else
382 : {
383 651 : if ( st_ivas->hBinRendererTd != NULL )
384 : {
385 : /* TD renderer handle */
386 237 : ivas_td_binaural_close( &st_ivas->hBinRendererTd );
387 : }
388 : /* ISM renderer handle + ISM data handle */
389 651 : ivas_omasa_separate_object_renderer_close( st_ivas );
390 : }
391 : }
392 :
393 4815 : if ( st_ivas->renderer_type == RENDERER_DIRAC )
394 : {
395 2001 : if ( ( error = ivas_dirac_dec_config( st_ivas, DIRAC_RECONFIGURE ) ) != IVAS_ERR_OK )
396 : {
397 0 : return error;
398 : }
399 :
400 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 )
401 : {
402 : /* Allocate 'hIsmRendererData' handle and memory for delay buffer within 'hMasaIsmData' */
403 1455 : if ( ( error = ivas_omasa_objects_delay_open( st_ivas ) ) != IVAS_ERR_OK )
404 : {
405 0 : return error;
406 : }
407 1455 : 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 546 : ivas_omasa_separate_object_renderer_close( st_ivas );
416 : }
417 : }
418 :
419 4815 : if ( st_ivas->renderer_type == RENDERER_OMASA_MIX_EXT )
420 : {
421 : /* Allocate 'hIsmRendererData' handle */
422 54 : if ( ( error = ivas_omasa_combine_separate_ism_with_masa_open( st_ivas ) ) != IVAS_ERR_OK )
423 : {
424 0 : return error;
425 : }
426 : }
427 :
428 4815 : if ( st_ivas->renderer_type == RENDERER_OMASA_OBJECT_EXT )
429 : {
430 57 : 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 57 : if ( ( error = ivas_omasa_objects_delay_open( st_ivas ) ) != IVAS_ERR_OK )
434 : {
435 0 : return error;
436 : }
437 :
438 57 : if ( ( error = ivas_spat_hSpatParamRendCom_config( &st_ivas->hSpatParamRendCom, common_rend_config_flag, 0,
439 57 : 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 4815 : if ( st_ivas->hDiracDecBin[0] != NULL )
450 : {
451 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 )
452 : {
453 0 : return error;
454 : }
455 : }
456 :
457 : /*-----------------------------------------------------------------*
458 : * CLDFB instances
459 : *-----------------------------------------------------------------*/
460 :
461 4815 : 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 4815 : nchan_out_buff = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 );
471 4815 : 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 4818 : 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 21252 : 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 21252 : *ism_total_brate = 0;
496 :
497 21252 : if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
498 : {
499 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 );
500 :
501 11805 : 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 11805 : st_ivas->hSCE[0]->hCoreCoder[0]->total_brate = *ism_total_brate;
505 :
506 11805 : st_ivas->hSCE[0]->hCoreCoder[0]->low_rate_mode = 0;
507 11805 : if ( st_ivas->hIsmMetaData[0]->ism_imp == ISM_NO_META )
508 : {
509 0 : st_ivas->hSCE[0]->hCoreCoder[0]->low_rate_mode = 1;
510 : }
511 : }
512 9447 : else if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC )
513 : {
514 : int16_t brate_limit_flag, ism_imp[MAX_NUM_OBJECTS];
515 :
516 34854 : for ( n = 0; n < st_ivas->nchan_ism; n++ )
517 : {
518 25407 : ism_imp[n] = st_ivas->hIsmMetaData[n]->ism_imp;
519 : }
520 :
521 9447 : brate_limit_flag = calculate_brate_limit_flag( ism_imp, st_ivas->nchan_ism );
522 :
523 9447 : ism_total_brate_ref = 0;
524 34854 : for ( n = 0; n < st_ivas->nchan_ism; n++ )
525 : {
526 25407 : ism_total_brate_ref += st_ivas->hSCE[n]->element_brate;
527 : }
528 :
529 9447 : bits_ism = (int16_t) ( ism_total_brate_ref / FRAMES_PER_SEC );
530 9447 : set_s( bits_element, bits_ism / st_ivas->nchan_ism, st_ivas->nchan_ism );
531 9447 : bits_element[st_ivas->nchan_ism - 1] += bits_ism % st_ivas->nchan_ism;
532 9447 : bitbudget_to_brate( bits_element, element_brate, st_ivas->nchan_ism );
533 :
534 9447 : *ism_total_brate = 0;
535 34854 : for ( n = 0; n < st_ivas->nchan_ism; n++ )
536 : {
537 25407 : st_ivas->hSCE[n]->element_brate = element_brate[n];
538 :
539 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 );
540 :
541 25407 : if ( ism_imp[n] > 1 && st_ivas->flag_omasa_brate == 1 && brate_limit_flag >= 0 )
542 : {
543 429 : *ism_total_brate -= ADJUST_ISM_BRATE_NEG;
544 : }
545 :
546 25407 : 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 0 : *ism_total_brate += ADJUST_ISM_BRATE_POS;
549 : }
550 : }
551 9447 : 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 21252 : return;
561 : }
562 :
563 :
564 : /*--------------------------------------------------------------------------*
565 : * ivas_omasa_ism_metadata_dec()
566 : *
567 : * decode ISM metadata in OMASA format
568 : *--------------------------------------------------------------------------*/
569 :
570 21252 : 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 21252 : *nchan_ism = st_ivas->nchan_ism;
585 21252 : *nchan_transport_ism = st_ivas->nchan_ism;
586 21252 : if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
587 : {
588 6204 : *nchan_ism = 1;
589 6204 : *nchan_transport_ism = 1;
590 : }
591 15048 : else if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
592 : {
593 5601 : *nchan_ism = 0;
594 5601 : *nchan_transport_ism = 1;
595 : }
596 :
597 21252 : 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 15651 : if ( ( error = ivas_ism_metadata_dec( ism_total_brate, *nchan_ism, nchan_transport_ism, st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->bfi,
601 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 )
602 : {
603 0 : return error;
604 : }
605 :
606 15651 : if ( st_ivas->hDirAC != NULL )
607 : {
608 11826 : if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC )
609 : {
610 23409 : for ( n = 0; n < st_ivas->nchan_ism; n++ )
611 : {
612 17019 : azimuth_ism = (int16_t) ( st_ivas->hIsmMetaData[n]->azimuth + 0.5f );
613 17019 : elevation_ism = (int16_t) ( st_ivas->hIsmMetaData[n]->elevation + 0.5f );
614 :
615 85095 : for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
616 : {
617 68076 : meta_write_index = ( dirac_bs_md_write_idx + block ) % st_ivas->hSpatParamRendCom->dirac_md_buffer_length;
618 68076 : st_ivas->hMasaIsmData->azimuth_ism[n][meta_write_index] = azimuth_ism;
619 68076 : st_ivas->hMasaIsmData->elevation_ism[n][meta_write_index] = elevation_ism;
620 : }
621 : }
622 : }
623 : else /* ISM_MASA_MODE_MASA_ONE_OBJ */
624 : {
625 5436 : azimuth_ism = (int16_t) ( st_ivas->hIsmMetaData[0]->azimuth + 0.5f );
626 5436 : elevation_ism = (int16_t) ( st_ivas->hIsmMetaData[0]->elevation + 0.5f );
627 :
628 27180 : for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
629 : {
630 21744 : meta_write_index = ( dirac_bs_md_write_idx + block ) % st_ivas->hSpatParamRendCom->dirac_md_buffer_length;
631 21744 : st_ivas->hMasaIsmData->azimuth_separated_ism[meta_write_index] = azimuth_ism;
632 21744 : st_ivas->hMasaIsmData->elevation_separated_ism[meta_write_index] = elevation_ism;
633 : }
634 : }
635 : }
636 3825 : else if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ && st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL )
637 : {
638 108 : azimuth_ism = (int16_t) ( st_ivas->hIsmMetaData[0]->azimuth + 0.5f );
639 108 : elevation_ism = (int16_t) ( st_ivas->hIsmMetaData[0]->elevation + 0.5f );
640 :
641 324 : for ( block = 0; block < 2; block++ )
642 : {
643 216 : st_ivas->hMasaIsmData->azimuth_separated_ism[block] = st_ivas->hMasaIsmData->azimuth_separated_ism[block + 2];
644 216 : st_ivas->hMasaIsmData->elevation_separated_ism[block] = st_ivas->hMasaIsmData->elevation_separated_ism[block + 2];
645 : }
646 324 : for ( block = 2; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
647 : {
648 216 : st_ivas->hMasaIsmData->azimuth_separated_ism[block] = azimuth_ism;
649 216 : st_ivas->hMasaIsmData->elevation_separated_ism[block] = elevation_ism;
650 : }
651 : }
652 : }
653 :
654 21252 : 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 18845 : 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 18845 : *nSamplesRendered = min( nSamplesAsked, st_ivas->hTcBuffer->n_samples_available );
678 :
679 18845 : if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
680 : {
681 10491 : mvr2r( &output_f[CPE_CHANNELS][st_ivas->hTcBuffer->n_samples_rendered], data_separated_objects[0], *nSamplesRendered );
682 :
683 10491 : if ( !st_ivas->hDecoderConfig->Opt_tsm && st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
684 : {
685 : /* Gain separated object, if edited */
686 14252 : for ( n = 0; n < st_ivas->nchan_ism; n++ )
687 : {
688 11088 : 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 28637 : for ( n = 0; n < st_ivas->nchan_ism; n++ )
698 : {
699 20283 : 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 20283 : 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 8354 : 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 18845 : subframes_rendered = st_ivas->hSpatParamRendCom->subframes_rendered;
719 :
720 18845 : ivas_dirac_dec_render( st_ivas, nchan_transport, nSamplesAsked, nSamplesRendered, nSamplesAvailable, output_f );
721 :
722 18845 : ivas_omasa_separate_object_render_jbm( st_ivas, *nSamplesRendered, data_separated_objects, output_f, subframes_rendered );
723 :
724 18845 : return;
725 : }
726 :
727 :
728 : /*--------------------------------------------------------------------------*
729 : * ivas_omasa_dirac_td_binaural_render()
730 : *
731 : * Binaural rendering in OMASA format for JBM
732 : *--------------------------------------------------------------------------*/
733 :
734 2308 : 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 2308 : slot_idx_start = st_ivas->hSpatParamRendCom->slots_rendered;
750 :
751 6924 : for ( n = 0; n < BINAURAL_CHANNELS; n++ )
752 : {
753 4616 : p_sepobj[n] = &data_separated_objects[n][0];
754 : }
755 :
756 2308 : 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 2308 : ivas_combined_orientation_set_to_start_index( st_ivas->hCombinedOrientationData );
760 :
761 2308 : 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 2308 : if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_sepobj, *nSamplesRendered ) ) != IVAS_ERR_OK )
799 : {
800 0 : return error;
801 : }
802 :
803 6924 : for ( n = 0; n < BINAURAL_CHANNELS; n++ )
804 : {
805 4616 : v_add( output_f[n], p_sepobj[n], output_f[n], *nSamplesRendered );
806 : }
807 : }
808 :
809 2308 : 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 2259 : 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 2259 : mvr2r( output[0], tmp_buff[0], output_frame );
829 2259 : mvr2r( output[1], tmp_buff[1], output_frame );
830 :
831 8595 : for ( n = 0; n < nchan_transport_ism; n++ )
832 : {
833 6336 : mvr2r( output[CPE_CHANNELS + n], output[n], output_frame );
834 : }
835 2259 : mvr2r( tmp_buff[0], output[n], output_frame );
836 2259 : mvr2r( tmp_buff[1], output[++n], output_frame );
837 :
838 2259 : 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 54 : 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 54 : 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 270 : for ( i = 0; i < MAX_NUM_OBJECTS; i++ )
861 : {
862 216 : set_zero( st_ivas->hIsmRendererData->prev_gains[i], MAX_OUTPUT_CHANNELS );
863 : }
864 :
865 54 : interpolator_length = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES );
866 54 : st_ivas->hIsmRendererData->interpolator = (float *) malloc( sizeof( float ) * interpolator_length );
867 :
868 13014 : for ( i = 0; i < interpolator_length; i++ )
869 : {
870 12960 : st_ivas->hIsmRendererData->interpolator[i] = (float) i / ( (float) interpolator_length );
871 : }
872 54 : st_ivas->hIsmRendererData->interpolator_length = interpolator_length;
873 :
874 54 : 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 108 : 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 108 : masaMetaHandle = st_ivas->hMasa->data.extOutMeta;
912 108 : ismMetaHandle = &ismMeta;
913 :
914 : /* Compute CLDFB analysis */
915 108 : nchan_in = st_ivas->nchan_transport + 1;
916 108 : nBins = output_frame / CLDFB_NO_COL_MAX;
917 1836 : for ( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
918 : {
919 6912 : for ( n = 0; n < nchan_in; n++ )
920 : {
921 5184 : cldfbAnalysis_ts(
922 5184 : &( output[n][nBins * slot] ),
923 5184 : inRe[n][slot],
924 5184 : inIm[n][slot],
925 : nBins, st_ivas->cldfbAnaDec[n] );
926 : }
927 : }
928 :
929 : /* Determine energies */
930 540 : for ( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
931 : {
932 432 : mrange[0] = st_ivas->hMasa->config.block_grouping[sf];
933 432 : mrange[1] = st_ivas->hMasa->config.block_grouping[sf + 1];
934 :
935 432 : set_zero( eneMasa[sf], MASA_FREQUENCY_BANDS );
936 432 : set_zero( eneIsm[sf], MASA_FREQUENCY_BANDS );
937 :
938 2160 : for ( slot = mrange[0]; slot < mrange[1]; slot++ )
939 : {
940 43200 : for ( band = 0; band < MASA_FREQUENCY_BANDS; band++ )
941 : {
942 41472 : brange[0] = st_ivas->hMasa->config.band_grouping[band];
943 41472 : brange[1] = st_ivas->hMasa->config.band_grouping[band + 1];
944 :
945 41472 : if ( brange[1] > nBins )
946 : {
947 0 : brange[1] = nBins;
948 : }
949 :
950 124416 : for ( n = 0; n < MASA_MAX_TRANSPORT_CHANNELS; n++ )
951 : {
952 290304 : for ( bin = brange[0]; bin < brange[1]; bin++ )
953 : {
954 207360 : eneMasa[sf][band] += inRe[n][slot][bin] * inRe[n][slot][bin] + inIm[n][slot][bin] * inIm[n][slot][bin];
955 : }
956 : }
957 145152 : for ( bin = brange[0]; bin < brange[1]; bin++ )
958 : {
959 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];
960 : }
961 : }
962 : }
963 : }
964 :
965 : /* Determine MASA metadata for the object */
966 108 : ismMetaHandle->descriptiveMeta.numberOfDirections = 0u;
967 540 : for ( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
968 : {
969 432 : azimuth = st_ivas->hMasaIsmData->azimuth_separated_ism[sf];
970 432 : elevation = st_ivas->hMasaIsmData->elevation_separated_ism[sf];
971 :
972 432 : directionIndex = index_theta_phi_16( &elevation, &azimuth, st_ivas->hMasa->data.sph_grid16 );
973 :
974 10800 : for ( band = 0; band < MASA_FREQUENCY_BANDS; band++ )
975 : {
976 10368 : ismMetaHandle->directionIndex[0][sf][band] = directionIndex;
977 10368 : ismMetaHandle->directToTotalRatio[0][sf][band] = UINT8_MAX;
978 10368 : ismMetaHandle->spreadCoherence[0][sf][band] = 0;
979 10368 : ismMetaHandle->surroundCoherence[sf][band] = 0;
980 10368 : ismMetaHandle->diffuseToTotalRatio[sf][band] = 0;
981 : }
982 : }
983 :
984 : /* Merge MASA metadatas */
985 108 : 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 108 : ivas_get_stereo_panning_gains( st_ivas->hMasaIsmData->azimuth_separated_ism[0], st_ivas->hMasaIsmData->elevation_separated_ism[0], old_panning_gains );
989 108 : ivas_get_stereo_panning_gains( st_ivas->hMasaIsmData->azimuth_separated_ism[2], st_ivas->hMasaIsmData->elevation_separated_ism[2], new_panning_gains );
990 :
991 108 : processing_len = output_frame / 2;
992 324 : for ( n = 0; n < MASA_MAX_TRANSPORT_CHANNELS; n++ )
993 : {
994 216 : v_multc( output[MASA_MAX_TRANSPORT_CHANNELS], old_panning_gains[n], panned_signal, processing_len );
995 216 : v_add( output[n], panned_signal, output[n], processing_len );
996 : }
997 108 : offset = processing_len;
998 :
999 108 : processing_len = output_frame / MAX_PARAM_SPATIAL_SUBFRAMES;
1000 324 : for ( n = 0; n < MASA_MAX_TRANSPORT_CHANNELS; n++ )
1001 : {
1002 52056 : for ( k = 0; k < processing_len; k++ )
1003 : {
1004 51840 : g1 = st_ivas->hIsmRendererData->interpolator[k];
1005 51840 : g2 = 1.0f - g1;
1006 51840 : output[n][k + offset] += ( g1 * new_panning_gains[n] + g2 * old_panning_gains[n] ) * output[MASA_MAX_TRANSPORT_CHANNELS][k + offset];
1007 : }
1008 : }
1009 108 : offset += processing_len;
1010 :
1011 324 : for ( n = 0; n < MASA_MAX_TRANSPORT_CHANNELS; n++ )
1012 : {
1013 216 : v_multc( &output[MASA_MAX_TRANSPORT_CHANNELS][offset], new_panning_gains[n], panned_signal, processing_len );
1014 216 : v_add( &output[n][offset], panned_signal, &output[n][offset], processing_len );
1015 : }
1016 :
1017 : /* Zero output object channels */
1018 540 : for ( n = 0; n < nchan_ism; n++ )
1019 : {
1020 432 : set_zero( output[MASA_MAX_TRANSPORT_CHANNELS + n], output_frame );
1021 : }
1022 :
1023 108 : 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 1788 : 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 1788 : if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
1040 : {
1041 1023 : st_ivas->hMasaIsmData->delayBuffer_nchan = 1;
1042 : }
1043 : else
1044 : {
1045 765 : st_ivas->hMasaIsmData->delayBuffer_nchan = st_ivas->nchan_ism;
1046 : }
1047 :
1048 1788 : st_ivas->hMasaIsmData->delayBuffer_size = (int16_t) ( ( st_ivas->hDecoderConfig->output_Fs / 50 ) / MAX_PARAM_SPATIAL_SUBFRAMES );
1049 :
1050 1788 : 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 5331 : for ( i = 0; i < st_ivas->hMasaIsmData->delayBuffer_nchan; i++ )
1056 : {
1057 3543 : 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 3543 : set_zero( st_ivas->hMasaIsmData->delayBuffer[i], st_ivas->hMasaIsmData->delayBuffer_size );
1062 : }
1063 :
1064 1788 : 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 120 : 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 600 : for ( sf = 0, slot = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
1112 : {
1113 2400 : for ( i = 0; i < CLDFB_SLOTS_PER_SUBFRAME; i++, slot++ )
1114 : {
1115 1920 : st_ivas->hSpatParamRendCom->render_to_md_map[slot] = st_ivas->hSpatParamRendCom->dirac_read_idx;
1116 : }
1117 480 : 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 120 : mvr2r( output[CPE_CHANNELS], separated_object, output_frame );
1122 600 : for ( n = 0; n < nchan_ism; n++ )
1123 : {
1124 480 : set_zero( output[CPE_CHANNELS + n], output_frame );
1125 : }
1126 :
1127 : /* Delay the separated object signal by the CLDFB delay */
1128 120 : 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 600 : for ( n = 0; n < nchan_ism; n++ )
1132 : {
1133 480 : st_ivas->hIsmMetaData[n]->azimuth = st_ivas->hMasaIsmData->azimuth_ism[n][st_ivas->hSpatParamRendCom->dirac_read_idx];
1134 480 : 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 120 : hExtData = st_ivas->hMasaIsmData->hExtData;
1139 120 : coding_delay = output_frame / 20 * 17; /* 17 ms of coding and CLDFB delay */
1140 120 : mvr2r( separated_object, output[CPE_CHANNELS + hExtData->prev_idx_separated_ism], coding_delay );
1141 120 : 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 120 : nchan_transport = st_ivas->nchan_transport;
1145 120 : nBins = output_frame / CLDFB_NO_COL_MAX;
1146 2040 : for ( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1147 : {
1148 5760 : for ( n = 0; n < nchan_transport; n++ )
1149 : {
1150 3840 : cldfbAnalysis_ts(
1151 3840 : &( output[n][nBins * slot] ),
1152 3840 : inRe[n][slot],
1153 3840 : inIm[n][slot],
1154 : nBins, st_ivas->cldfbAnaDec[n] );
1155 : }
1156 : }
1157 :
1158 : /* Create prototype signals */
1159 600 : for ( n = 0; n < nchan_ism; n++ )
1160 : {
1161 480 : azimuth = (float) st_ivas->hIsmMetaData[n]->azimuth;
1162 480 : elevation = (float) st_ivas->hIsmMetaData[n]->elevation;
1163 480 : ivas_get_stereo_panning_gains( azimuth, elevation, new_panning_gains );
1164 480 : interpVal = 0.0f;
1165 :
1166 8160 : for ( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1167 : {
1168 7680 : interpVal += 1.0f / (float) CLDFB_NO_COL_MAX;
1169 23040 : for ( m = 0; m < 2; m++ )
1170 : {
1171 15360 : panning_gains[m] = ( 1.0f - interpVal ) * hExtData->prev_panning_gains[n][m] + interpVal * new_panning_gains[m];
1172 : }
1173 7680 : v_multc( inRe[0][slot], panning_gains[0], outRe[n][slot], nBins );
1174 7680 : v_multc( inIm[0][slot], panning_gains[0], outIm[n][slot], nBins );
1175 7680 : v_multc_acc( inRe[1][slot], panning_gains[1], outRe[n][slot], nBins );
1176 7680 : v_multc_acc( inIm[1][slot], panning_gains[1], outIm[n][slot], nBins );
1177 : }
1178 :
1179 1440 : for ( m = 0; m < 2; m++ )
1180 : {
1181 960 : hExtData->prev_panning_gains[n][m] = new_panning_gains[m];
1182 : }
1183 : }
1184 :
1185 : /* Determine prototype energy */
1186 600 : for ( n = 0; n < nchan_ism; n++ )
1187 : {
1188 8160 : for ( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1189 : {
1190 468480 : for ( bin = 0; bin < nBins; bin++ )
1191 : {
1192 460800 : 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 2040 : for ( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1199 : {
1200 1920 : set_zero( transport_energy[slot], nBins );
1201 : }
1202 360 : for ( n = 0; n < CPE_CHANNELS; n++ )
1203 : {
1204 4080 : for ( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1205 : {
1206 234240 : for ( bin = 0; bin < nBins; bin++ )
1207 : {
1208 230400 : 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 600 : for ( n = 0; n < nchan_ism; n++ )
1215 : {
1216 8160 : for ( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1217 : {
1218 7680 : md_idx = st_ivas->hSpatParamRendCom->render_to_md_map[slot];
1219 468480 : for ( bin = 0; bin < nBins; bin++ )
1220 : {
1221 460800 : ism_target_energy[n][slot][bin] = transport_energy[slot][bin] * st_ivas->hMasaIsmData->energy_ratio_ism[n][md_idx][bin];
1222 : }
1223 : }
1224 : }
1225 2040 : for ( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1226 : {
1227 1920 : md_idx = st_ivas->hSpatParamRendCom->render_to_md_map[slot];
1228 117120 : for ( bin = 0; bin < nBins; bin++ )
1229 : {
1230 115200 : 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 120 : iir_factor_curr = ( 1.0f - EXT_RENDER_IIR_FAC );
1236 120 : iir_factor_prev = EXT_RENDER_IIR_FAC;
1237 600 : for ( n = 0; n < nchan_ism; n++ )
1238 : {
1239 8160 : for ( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1240 : {
1241 468480 : for ( bin = 0; bin < nBins; bin++ )
1242 : {
1243 460800 : hExtData->ism_render_proto_energy[n][bin] *= iir_factor_prev;
1244 460800 : hExtData->ism_render_proto_energy[n][bin] += iir_factor_curr * ism_proto_energy[n][slot][bin];
1245 460800 : hExtData->ism_render_target_energy[n][bin] *= iir_factor_prev;
1246 460800 : hExtData->ism_render_target_energy[n][bin] += iir_factor_curr * ism_target_energy[n][slot][bin];
1247 :
1248 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] ) ) );
1249 : }
1250 : }
1251 : }
1252 2040 : for ( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1253 : {
1254 117120 : for ( bin = 0; bin < nBins; bin++ )
1255 : {
1256 115200 : hExtData->masa_render_proto_energy[bin] *= iir_factor_prev;
1257 115200 : hExtData->masa_render_proto_energy[bin] += iir_factor_curr * transport_energy[slot][bin];
1258 115200 : hExtData->masa_render_target_energy[bin] *= iir_factor_prev;
1259 115200 : hExtData->masa_render_target_energy[bin] += iir_factor_curr * masa_target_energy[slot][bin];
1260 :
1261 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] ) ) );
1262 : }
1263 : }
1264 :
1265 : /* Determine output signals */
1266 600 : for ( n = 0; n < nchan_ism; n++ )
1267 : {
1268 8160 : for ( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1269 : {
1270 468480 : for ( bin = 0; bin < nBins; bin++ )
1271 : {
1272 460800 : outRe[n][slot][bin] *= ism_processing_gains[n][slot][bin];
1273 460800 : outIm[n][slot][bin] *= ism_processing_gains[n][slot][bin];
1274 : }
1275 : }
1276 : }
1277 360 : for ( n = 0; n < MASA_MAX_TRANSPORT_CHANNELS; n++ )
1278 : {
1279 4080 : for ( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1280 : {
1281 234240 : for ( bin = 0; bin < nBins; bin++ )
1282 : {
1283 230400 : inRe[n][slot][bin] *= masa_processing_gains[slot][bin];
1284 230400 : inIm[n][slot][bin] *= masa_processing_gains[slot][bin];
1285 : }
1286 : }
1287 : }
1288 :
1289 : /* Compute CLDFB synthesis */
1290 2040 : for ( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1291 : {
1292 5760 : for ( n = 0; n < nchan_transport; n++ )
1293 : {
1294 3840 : outSlotRePr = &( inRe[n][slot][0] );
1295 3840 : outSlotImPr = &( inIm[n][slot][0] );
1296 3840 : cldfbSynthesis( &outSlotRePr, &outSlotImPr, &( output[n][nBins * slot] ), nBins, st_ivas->cldfbSynDec[n] );
1297 : }
1298 :
1299 9600 : for ( n = 0; n < nchan_ism; n++ )
1300 : {
1301 7680 : outSlotRePr = &( outRe[n][slot][0] );
1302 7680 : outSlotImPr = &( outIm[n][slot][0] );
1303 7680 : 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 600 : for ( n = 0; n < nchan_ism; n++ )
1309 : {
1310 480 : v_add( output[CPE_CHANNELS + n], rendered_objects[n], output[CPE_CHANNELS + n], output_frame );
1311 : }
1312 :
1313 120 : hExtData->prev_idx_separated_ism = st_ivas->hMasaIsmData->idx_separated_ism;
1314 :
1315 120 : 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 : }
|