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 10287 : 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 10287 : 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 257175 : for ( int16_t band_idx = 0; band_idx < MASA_FREQUENCY_BANDS; band_idx++ )
72 : {
73 740664 : for ( ch = 0; ch < 2; ch++ )
74 : {
75 493776 : hMasaIsmData->ismPreprocMatrix[ch][ch][band_idx] = 1.0f;
76 493776 : hMasaIsmData->ismPreprocMatrix[1 - ch][ch][band_idx] = 0.0f;
77 493776 : hMasaIsmData->eneMoveIIR[ch][band_idx] = 0.0f;
78 493776 : hMasaIsmData->enePreserveIIR[ch][band_idx] = 0.0f;
79 : }
80 246888 : hMasaIsmData->eneOrigIIR[band_idx] = 0.0f;
81 246888 : hMasaIsmData->preprocEneTarget[band_idx] = 0.0f;
82 246888 : hMasaIsmData->preprocEneRealized[band_idx] = 0.0f;
83 : }
84 :
85 10287 : hMasaIsmData->objectsEdited = 0;
86 10287 : hMasaIsmData->delayBuffer = NULL;
87 :
88 51435 : for ( ch = 0; ch < MAX_NUM_OBJECTS; ch++ )
89 : {
90 41148 : hMasaIsmData->ism_dir_is_edited[ch] = 0;
91 41148 : hMasaIsmData->ism_gain_is_edited[ch] = 0;
92 41148 : hMasaIsmData->q_elevation_old[ch] = 0.0f;
93 41148 : hMasaIsmData->q_azimuth_old[ch] = 0.0f;
94 : }
95 10287 : hMasaIsmData->masa_gain_is_edited = 0;
96 10287 : hMasaIsmData->idx_separated_ism = -1;
97 :
98 51435 : for ( obj_idx = 0; obj_idx < MAX_NUM_OBJECTS; obj_idx++ )
99 : {
100 41148 : set_s( hMasaIsmData->azimuth_ism[obj_idx], 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR );
101 41148 : set_s( hMasaIsmData->elevation_ism[obj_idx], 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR );
102 288036 : for ( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR; sf++ )
103 : {
104 246888 : set_zero( hMasaIsmData->energy_ratio_ism[obj_idx][sf], CLDFB_NO_CHANNELS_MAX );
105 : }
106 : }
107 10287 : set_s( hMasaIsmData->azimuth_separated_ism, 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR );
108 10287 : set_s( hMasaIsmData->elevation_separated_ism, 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR );
109 :
110 10287 : hMasaIsmData->hExtData = NULL;
111 10287 : if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL )
112 : {
113 : MASA_ISM_EXT_DATA_HANDLE hExtData;
114 :
115 554 : 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 554 : hExtData->prev_idx_separated_ism = 0;
121 :
122 2770 : for ( ch = 0; ch < MAX_NUM_OBJECTS; ch++ )
123 : {
124 2216 : set_zero( hExtData->prev_panning_gains[ch], 2 );
125 : }
126 :
127 2770 : for ( ch = 0; ch < MAX_NUM_OBJECTS; ch++ )
128 : {
129 2216 : set_zero( hExtData->ism_render_proto_energy[ch], CLDFB_NO_CHANNELS_MAX );
130 2216 : set_zero( hExtData->ism_render_target_energy[ch], CLDFB_NO_CHANNELS_MAX );
131 : }
132 554 : set_zero( hExtData->masa_render_proto_energy, CLDFB_NO_CHANNELS_MAX );
133 554 : set_zero( hExtData->masa_render_target_energy, CLDFB_NO_CHANNELS_MAX );
134 :
135 3878 : for ( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR; sf++ )
136 : {
137 3324 : set_zero( hExtData->masa_render_masa_to_total[sf], CLDFB_NO_CHANNELS_MAX );
138 : }
139 :
140 554 : hMasaIsmData->hExtData = hExtData;
141 : }
142 :
143 10287 : st_ivas->hMasaIsmData = hMasaIsmData;
144 :
145 10287 : return IVAS_ERR_OK;
146 : }
147 :
148 :
149 : /*-------------------------------------------------------------------*
150 : * ivas_omasa_data_close()
151 : *
152 : * Deallocate MASA_ISM rendering handle
153 : *-------------------------------------------------------------------*/
154 :
155 86930 : 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 86930 : if ( hMasaIsmData == NULL || *hMasaIsmData == NULL )
162 : {
163 76643 : return;
164 : }
165 :
166 10287 : if ( ( *hMasaIsmData )->delayBuffer != NULL )
167 : {
168 14116 : for ( i = 0; i < ( *hMasaIsmData )->delayBuffer_nchan; i++ )
169 : {
170 9234 : free( ( *hMasaIsmData )->delayBuffer[i] );
171 : }
172 4882 : free( ( *hMasaIsmData )->delayBuffer );
173 4882 : ( *hMasaIsmData )->delayBuffer = NULL;
174 : }
175 :
176 10287 : if ( ( *hMasaIsmData )->hExtData != NULL )
177 : {
178 554 : free( ( *hMasaIsmData )->hExtData );
179 554 : ( *hMasaIsmData )->hExtData = NULL;
180 : }
181 :
182 10287 : free( *hMasaIsmData );
183 10287 : *hMasaIsmData = NULL;
184 :
185 10287 : return;
186 : }
187 :
188 :
189 : /*--------------------------------------------------------------------------*
190 : * ivas_omasa_dec_config()
191 : *
192 : * oMASA decoder configuration
193 : *--------------------------------------------------------------------------*/
194 :
195 24906 : 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 24906 : ism_total_brate = 0;
209 24906 : ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
210 :
211 : /* save previous frame parameters */
212 24906 : ism_mode_old = ivas_omasa_ism_mode_select( st_ivas->hDecoderConfig->last_ivas_total_brate, st_ivas->nchan_ism );
213 24906 : st_ivas->ism_mode = ism_mode_old;
214 :
215 24906 : ivas_format_orig = st_ivas->ivas_format;
216 24906 : st_ivas->ivas_format = st_ivas->last_ivas_format;
217 24906 : ivas_init_dec_get_num_cldfb_instances( st_ivas, &numCldfbAnalyses_old, &numCldfbSyntheses_old );
218 24906 : st_ivas->ivas_format = ivas_format_orig;
219 :
220 24906 : nSCE_old = st_ivas->nSCE;
221 24906 : nchan_hp20_old = getNumChanSynthesis( st_ivas );
222 :
223 : /* set ism_mode of current frame */
224 24906 : st_ivas->ism_mode = ivas_omasa_ism_mode_select( ivas_total_brate, st_ivas->nchan_ism );
225 :
226 : /*-----------------------------------------------------------------*
227 : * Renderer selection
228 : *-----------------------------------------------------------------*/
229 :
230 24906 : old_renderer_type = st_ivas->renderer_type;
231 :
232 : /* MASA reconfig. */
233 24906 : cpe_brate = calculate_cpe_brate_MASA_ISM( st_ivas->ism_mode, ivas_total_brate, st_ivas->nchan_ism );
234 24906 : 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 24906 : else if ( ( error = ivas_masa_dec_reconfigure( st_ivas ) ) != IVAS_ERR_OK )
239 : {
240 0 : return error;
241 : }
242 :
243 24906 : if ( cpe_brate < MASA_STEREO_MIN_BITRATE )
244 : {
245 8571 : st_ivas->hCPE[0]->nchan_out = 1;
246 : }
247 : else
248 : {
249 16335 : st_ivas->hCPE[0]->nchan_out = 2;
250 : }
251 :
252 : /* OMASA reconfig. */
253 24906 : if ( st_ivas->hMasaIsmData == NULL && st_ivas->ivas_format == MASA_ISM_FORMAT )
254 : {
255 750 : if ( ( error = ivas_omasa_data_open( st_ivas ) ) != IVAS_ERR_OK )
256 : {
257 0 : return error;
258 : }
259 : }
260 :
261 24906 : 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 24906 : 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 24906 : k = 0;
271 205140 : while ( k < SIZE_IVAS_BRATE_TBL && ivas_total_brate != ivas_brate_tbl[k] )
272 : {
273 180234 : k++;
274 : }
275 :
276 57771 : for ( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ )
277 : {
278 32865 : ism_total_brate += sep_object_brate[k - 2][st_ivas->nSCE - 1];
279 : }
280 :
281 24906 : 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 24906 : if ( ism_mode_old != st_ivas->ism_mode )
287 : {
288 : /* ISM MD reconfig. */
289 24120 : if ( st_ivas->hIsmMetaData[0] == NULL )
290 : {
291 750 : 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 97824 : for ( k = 0; k < st_ivas->nchan_ism; k++ )
299 : {
300 74454 : ivas_ism_reset_metadata_handle_dec( st_ivas->hIsmMetaData[k] );
301 : }
302 : }
303 :
304 24120 : st_ivas->hCPE[0]->element_brate = ivas_total_brate - ism_total_brate;
305 :
306 : /*-----------------------------------------------------------------*
307 : * Renderer selection
308 : *-----------------------------------------------------------------*/
309 :
310 24120 : ivas_renderer_select( st_ivas );
311 :
312 : /*-------------------------------------------------------------------*
313 : * Reallocate rendering handles
314 : *--------------------------------------------------------------------*/
315 :
316 24120 : if ( old_renderer_type != st_ivas->renderer_type )
317 : {
318 2769 : if ( st_ivas->renderer_type == RENDERER_MONO_DOWNMIX )
319 : {
320 759 : if ( ( error = ivas_mono_dmx_renderer_open( st_ivas ) ) != IVAS_ERR_OK )
321 : {
322 0 : return error;
323 : }
324 : }
325 : else
326 : {
327 2010 : ivas_mono_dmx_renderer_close( &st_ivas->hMonoDmxRenderer );
328 : }
329 : }
330 :
331 : /* objects renderer reconfig. */
332 24120 : 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 24120 : ivas_omasa_separate_object_renderer_close( st_ivas );
336 : }
337 :
338 24120 : 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 5568 : MASA_ISM_DATA_HANDLE hMasaIsmData = st_ivas->hMasaIsmData;
341 27840 : for ( int16_t obj_idx = 0; obj_idx < MAX_NUM_OBJECTS; obj_idx++ )
342 : {
343 22272 : set_s( hMasaIsmData->azimuth_ism[obj_idx], 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR );
344 22272 : set_s( hMasaIsmData->elevation_ism[obj_idx], 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR );
345 155904 : for ( int16_t sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR; sf++ )
346 : {
347 133632 : set_zero( hMasaIsmData->energy_ratio_ism[obj_idx][sf], CLDFB_NO_CHANNELS_MAX );
348 : }
349 : }
350 5568 : set_s( hMasaIsmData->azimuth_separated_ism, 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR );
351 5568 : set_s( hMasaIsmData->elevation_separated_ism, 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR );
352 : }
353 :
354 24120 : if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC )
355 : {
356 7527 : if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC )
357 : {
358 : /* Allocate TD renderer for the objects in DISC mode */
359 2025 : if ( st_ivas->hBinRendererTd == NULL )
360 : {
361 2025 : if ( ( error = ivas_td_binaural_open( st_ivas ) ) != IVAS_ERR_OK )
362 : {
363 0 : return error;
364 : }
365 :
366 2025 : 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 2025 : if ( ( error = ivas_omasa_objects_delay_open( st_ivas ) ) != IVAS_ERR_OK )
377 : {
378 0 : return error;
379 : }
380 : }
381 : else
382 : {
383 5502 : if ( st_ivas->hBinRendererTd != NULL )
384 : {
385 : /* TD renderer handle */
386 2034 : ivas_td_binaural_close( &st_ivas->hBinRendererTd );
387 : }
388 : /* ISM renderer handle + ISM data handle */
389 5502 : ivas_omasa_separate_object_renderer_close( st_ivas );
390 : }
391 : }
392 :
393 24120 : if ( st_ivas->renderer_type == RENDERER_DIRAC )
394 : {
395 6159 : if ( ( error = ivas_dirac_dec_config( st_ivas, DIRAC_RECONFIGURE ) ) != IVAS_ERR_OK )
396 : {
397 0 : return error;
398 : }
399 :
400 6159 : 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 4161 : if ( ( error = ivas_omasa_objects_delay_open( st_ivas ) ) != IVAS_ERR_OK )
404 : {
405 0 : return error;
406 : }
407 4161 : 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 1998 : ivas_omasa_separate_object_renderer_close( st_ivas );
416 : }
417 : }
418 :
419 24120 : if ( st_ivas->renderer_type == RENDERER_OMASA_MIX_EXT )
420 : {
421 : /* Allocate 'hIsmRendererData' handle */
422 375 : if ( ( error = ivas_omasa_combine_separate_ism_with_masa_open( st_ivas ) ) != IVAS_ERR_OK )
423 : {
424 0 : return error;
425 : }
426 : }
427 :
428 24120 : if ( st_ivas->renderer_type == RENDERER_OMASA_OBJECT_EXT )
429 : {
430 375 : 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 375 : if ( ( error = ivas_omasa_objects_delay_open( st_ivas ) ) != IVAS_ERR_OK )
434 : {
435 0 : return error;
436 : }
437 :
438 375 : if ( ( error = ivas_spat_hSpatParamRendCom_config( &st_ivas->hSpatParamRendCom, common_rend_config_flag, 0,
439 375 : 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 24120 : if ( st_ivas->hDiracDecBin[0] != NULL )
450 : {
451 13611 : 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 24120 : 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 24120 : nchan_out_buff = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 );
471 24120 : 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 24906 : 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 539381 : 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 539381 : *ism_total_brate = 0;
496 :
497 539381 : if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
498 : {
499 162393 : *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 162393 : 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 162393 : st_ivas->hSCE[0]->hCoreCoder[0]->total_brate = *ism_total_brate;
505 :
506 162393 : st_ivas->hSCE[0]->hCoreCoder[0]->low_rate_mode = 0;
507 162393 : if ( st_ivas->hIsmMetaData[0]->ism_imp == ISM_NO_META )
508 : {
509 927 : st_ivas->hSCE[0]->hCoreCoder[0]->low_rate_mode = 1;
510 : }
511 : }
512 376988 : else if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC )
513 : {
514 : int16_t brate_limit_flag, ism_imp[MAX_NUM_OBJECTS];
515 :
516 1218913 : for ( n = 0; n < st_ivas->nchan_ism; n++ )
517 : {
518 841925 : ism_imp[n] = st_ivas->hIsmMetaData[n]->ism_imp;
519 : }
520 :
521 376988 : brate_limit_flag = calculate_brate_limit_flag( ism_imp, st_ivas->nchan_ism );
522 :
523 376988 : ism_total_brate_ref = 0;
524 1218913 : for ( n = 0; n < st_ivas->nchan_ism; n++ )
525 : {
526 841925 : ism_total_brate_ref += st_ivas->hSCE[n]->element_brate;
527 : }
528 :
529 376988 : bits_ism = (int16_t) ( ism_total_brate_ref / FRAMES_PER_SEC );
530 376988 : set_s( bits_element, bits_ism / st_ivas->nchan_ism, st_ivas->nchan_ism );
531 376988 : bits_element[st_ivas->nchan_ism - 1] += bits_ism % st_ivas->nchan_ism;
532 376988 : bitbudget_to_brate( bits_element, element_brate, st_ivas->nchan_ism );
533 :
534 376988 : *ism_total_brate = 0;
535 1218913 : for ( n = 0; n < st_ivas->nchan_ism; n++ )
536 : {
537 841925 : st_ivas->hSCE[n]->element_brate = element_brate[n];
538 :
539 841925 : *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 841925 : if ( ism_imp[n] > 1 && st_ivas->flag_omasa_brate == 1 && brate_limit_flag >= 0 )
542 : {
543 8166 : *ism_total_brate -= ADJUST_ISM_BRATE_NEG;
544 : }
545 :
546 841925 : 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 376988 : 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 539381 : return;
561 : }
562 :
563 :
564 : /*--------------------------------------------------------------------------*
565 : * ivas_omasa_ism_metadata_dec()
566 : *
567 : * decode ISM metadata in OMASA format
568 : *--------------------------------------------------------------------------*/
569 :
570 539381 : 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 539381 : *nchan_ism = st_ivas->nchan_ism;
585 539381 : *nchan_transport_ism = st_ivas->nchan_ism;
586 539381 : if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ )
587 : {
588 74625 : *nchan_ism = 1;
589 74625 : *nchan_transport_ism = 1;
590 : }
591 464756 : else if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
592 : {
593 87768 : *nchan_ism = 0;
594 87768 : *nchan_transport_ism = 1;
595 : }
596 :
597 539381 : 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 451613 : if ( ( error = ivas_ism_metadata_dec( ism_total_brate, *nchan_ism, nchan_transport_ism, st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->bfi,
601 451613 : 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 451613 : if ( st_ivas->hDirAC != NULL )
607 : {
608 387593 : if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC )
609 : {
610 1034413 : for ( n = 0; n < st_ivas->nchan_ism; n++ )
611 : {
612 711449 : azimuth_ism = (int16_t) ( st_ivas->hIsmMetaData[n]->azimuth + 0.5f );
613 711449 : elevation_ism = (int16_t) ( st_ivas->hIsmMetaData[n]->elevation + 0.5f );
614 :
615 3557245 : for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
616 : {
617 2845796 : meta_write_index = ( dirac_bs_md_write_idx + block ) % st_ivas->hSpatParamRendCom->dirac_md_buffer_length;
618 2845796 : st_ivas->hMasaIsmData->azimuth_ism[n][meta_write_index] = azimuth_ism;
619 2845796 : st_ivas->hMasaIsmData->elevation_ism[n][meta_write_index] = elevation_ism;
620 : }
621 : }
622 : }
623 : else /* ISM_MASA_MODE_MASA_ONE_OBJ */
624 : {
625 64629 : azimuth_ism = (int16_t) ( st_ivas->hIsmMetaData[0]->azimuth + 0.5f );
626 64629 : elevation_ism = (int16_t) ( st_ivas->hIsmMetaData[0]->elevation + 0.5f );
627 :
628 323145 : for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
629 : {
630 258516 : meta_write_index = ( dirac_bs_md_write_idx + block ) % st_ivas->hSpatParamRendCom->dirac_md_buffer_length;
631 258516 : st_ivas->hMasaIsmData->azimuth_separated_ism[meta_write_index] = azimuth_ism;
632 258516 : st_ivas->hMasaIsmData->elevation_separated_ism[meta_write_index] = elevation_ism;
633 : }
634 : }
635 : }
636 64020 : else if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ && st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL )
637 : {
638 3126 : azimuth_ism = (int16_t) ( st_ivas->hIsmMetaData[0]->azimuth + 0.5f );
639 3126 : elevation_ism = (int16_t) ( st_ivas->hIsmMetaData[0]->elevation + 0.5f );
640 :
641 9378 : for ( block = 0; block < 2; block++ )
642 : {
643 6252 : st_ivas->hMasaIsmData->azimuth_separated_ism[block] = st_ivas->hMasaIsmData->azimuth_separated_ism[block + 2];
644 6252 : st_ivas->hMasaIsmData->elevation_separated_ism[block] = st_ivas->hMasaIsmData->elevation_separated_ism[block + 2];
645 : }
646 9378 : for ( block = 2; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
647 : {
648 6252 : st_ivas->hMasaIsmData->azimuth_separated_ism[block] = azimuth_ism;
649 6252 : st_ivas->hMasaIsmData->elevation_separated_ism[block] = elevation_ism;
650 : }
651 : }
652 : }
653 :
654 539381 : 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 264832 : 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 264832 : *nSamplesRendered = min( nSamplesAsked, st_ivas->hTcBuffer->n_samples_available );
678 :
679 264832 : if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
680 : {
681 83520 : mvr2r( &output_f[CPE_CHANNELS][st_ivas->hTcBuffer->n_samples_rendered], data_separated_objects[0], *nSamplesRendered );
682 :
683 83520 : if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
684 : {
685 : /* Gain separated object, if edited */
686 199250 : for ( n = 0; n < st_ivas->nchan_ism; n++ )
687 : {
688 153765 : 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 582089 : for ( n = 0; n < st_ivas->nchan_ism; n++ )
698 : {
699 400777 : 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 400777 : if ( st_ivas->hMasaIsmData->ism_gain_is_edited[n] )
703 : {
704 18666 : 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 in G192. MASA gaining with VOIP is done in ivas_dec_prepare_renderer() */
709 181312 : if ( !st_ivas->hDecoderConfig->Opt_tsm && st_ivas->hMasaIsmData->masa_gain_is_edited )
710 : {
711 0 : for ( n = 0; n < CPE_CHANNELS; n++ )
712 : {
713 0 : v_multc( output_f[n], st_ivas->hMasaIsmData->gain_masa_edited, output_f[n], *nSamplesRendered );
714 : }
715 : }
716 : }
717 :
718 264832 : subframes_rendered = st_ivas->hSpatParamRendCom->subframes_rendered;
719 :
720 264832 : ivas_dirac_dec_render( st_ivas, nchan_transport, nSamplesAsked, nSamplesRendered, nSamplesAvailable, output_f );
721 :
722 264832 : ivas_omasa_separate_object_render_jbm( st_ivas, *nSamplesRendered, data_separated_objects, output_f, subframes_rendered );
723 :
724 264832 : return;
725 : }
726 :
727 :
728 : /*--------------------------------------------------------------------------*
729 : * ivas_omasa_dirac_td_binaural_render()
730 : *
731 : * Binaural rendering in OMASA format for JBM
732 : *--------------------------------------------------------------------------*/
733 :
734 84056 : 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 : float *re, *im;
748 :
749 252168 : for ( n = 0; n < BINAURAL_CHANNELS; n++ )
750 : {
751 168112 : p_sepobj[n] = &data_separated_objects[n][0];
752 : }
753 :
754 84056 : ivas_dirac_dec_binaural_render( st_ivas, nSamplesAsked, nSamplesRendered, nSamplesAvailable, nchan_transport, output_f );
755 :
756 : /* reset combined orientation access index before calling the td renderer */
757 84056 : ivas_combined_orientation_set_to_start_index( st_ivas->hCombinedOrientationData );
758 :
759 84056 : if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
760 36959 : {
761 : int16_t slot_idx, num_cldfb_bands, nchan_transport_orig, cldfb_slots;
762 : float Cldfb_RealBuffer[CLDFB_NO_CHANNELS_MAX];
763 : float Cldfb_ImagBuffer[CLDFB_NO_CHANNELS_MAX];
764 : float *p_rend_obj[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS]; /* [8 * 2] */
765 :
766 338421 : for ( n = 0; n < st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses * BINAURAL_CHANNELS; n++ )
767 : {
768 301462 : p_rend_obj[n] = &output_f[n][0];
769 : }
770 :
771 36959 : num_cldfb_bands = st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[0]->no_channels;
772 36959 : nchan_transport_orig = st_ivas->nchan_transport;
773 36959 : st_ivas->nchan_transport = st_ivas->nchan_ism;
774 :
775 36959 : 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)] */
776 : {
777 0 : return error;
778 : }
779 36959 : st_ivas->nchan_transport = nchan_transport_orig;
780 36959 : cldfb_slots = *nSamplesRendered / num_cldfb_bands;
781 :
782 338421 : for ( n = 0; n < st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses * BINAURAL_CHANNELS; ++n )
783 : {
784 4174454 : for ( slot_idx = 0; slot_idx < cldfb_slots; slot_idx++ )
785 : {
786 3872992 : 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] );
787 :
788 3872992 : ivas_CLDFB_RINGBUF_GetByIdx( st_ivas->hSplitBinRend->hMultiBinCldfbData[n], &re, &im, slot_idx - cldfb_slots );
789 :
790 3872992 : v_add( re, Cldfb_RealBuffer, re, num_cldfb_bands );
791 3872992 : v_add( im, Cldfb_ImagBuffer, im, num_cldfb_bands );
792 : }
793 : }
794 : }
795 : else
796 : {
797 47097 : if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_sepobj, *nSamplesRendered ) ) != IVAS_ERR_OK )
798 : {
799 0 : return error;
800 : }
801 :
802 141291 : for ( n = 0; n < BINAURAL_CHANNELS; n++ )
803 : {
804 94194 : v_add( output_f[n], p_sepobj[n], output_f[n], *nSamplesRendered );
805 : }
806 : }
807 :
808 84056 : return IVAS_ERR_OK;
809 : }
810 :
811 :
812 : /*--------------------------------------------------------------------------*
813 : * ivas_omasa_rearrange_channels()
814 : *
815 : * in case of external rendering, rearrange the channels order
816 : *--------------------------------------------------------------------------*/
817 :
818 45576 : void ivas_omasa_rearrange_channels(
819 : float *output[], /* o : output synthesis signal */
820 : const int16_t nchan_transport_ism, /* o : number of ISM TCs */
821 : const int16_t output_frame /* i : output frame length per channel */
822 : )
823 : {
824 : int16_t n;
825 : float tmp_buff[CPE_CHANNELS][L_FRAME48k];
826 :
827 45576 : mvr2r( output[0], tmp_buff[0], output_frame );
828 45576 : mvr2r( output[1], tmp_buff[1], output_frame );
829 :
830 168384 : for ( n = 0; n < nchan_transport_ism; n++ )
831 : {
832 122808 : mvr2r( output[CPE_CHANNELS + n], output[n], output_frame );
833 : }
834 45576 : mvr2r( tmp_buff[0], output[n], output_frame );
835 45576 : mvr2r( tmp_buff[1], output[++n], output_frame );
836 :
837 45576 : return;
838 : }
839 :
840 :
841 : /*-------------------------------------------------------------------------*
842 : * ivas_omasa_combine_separate_ism_with_masa_open()
843 : *
844 : * Open structures, reserve memory, and init values.
845 : *-------------------------------------------------------------------------*/
846 :
847 423 : ivas_error ivas_omasa_combine_separate_ism_with_masa_open(
848 : Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
849 : )
850 : {
851 : int16_t i;
852 : int16_t interpolator_length;
853 :
854 423 : if ( ( st_ivas->hIsmRendererData = (ISM_RENDERER_HANDLE) malloc( sizeof( ISM_RENDERER_DATA ) ) ) == NULL )
855 : {
856 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for MASA ISM renderer \n" ) );
857 : }
858 :
859 2115 : for ( i = 0; i < MAX_NUM_OBJECTS; i++ )
860 : {
861 1692 : set_zero( st_ivas->hIsmRendererData->prev_gains[i], MAX_OUTPUT_CHANNELS );
862 : }
863 :
864 423 : interpolator_length = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES );
865 423 : st_ivas->hIsmRendererData->interpolator = (float *) malloc( sizeof( float ) * interpolator_length );
866 :
867 98103 : for ( i = 0; i < interpolator_length; i++ )
868 : {
869 97680 : st_ivas->hIsmRendererData->interpolator[i] = (float) i / ( (float) interpolator_length );
870 : }
871 423 : st_ivas->hIsmRendererData->interpolator_length = interpolator_length;
872 :
873 423 : return IVAS_ERR_OK;
874 : }
875 :
876 :
877 : /*--------------------------------------------------------------------------*
878 : * ivas_omasa_combine_separate_ism_with_masa()
879 : *
880 : * in case of external rendering, combine separated ISM signal with MASA stream
881 : *--------------------------------------------------------------------------*/
882 :
883 3126 : void ivas_omasa_combine_separate_ism_with_masa(
884 : Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */
885 : float *output[], /* i/o: output synthesis signal */
886 : const int16_t nchan_ism, /* i : number of ISMs */
887 : const int16_t output_frame /* i : output frame length per channel */
888 : )
889 : {
890 : int16_t n, sf, band, bin, k;
891 : MASA_DECODER_EXT_OUT_META_HANDLE masaMetaHandle;
892 : MASA_DECODER_EXT_OUT_META_HANDLE ismMetaHandle;
893 : MASA_DECODER_EXT_OUT_META ismMeta;
894 : float eneMasa[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
895 : float eneIsm[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS];
896 : float inRe[3][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
897 : float inIm[3][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
898 : float azimuth, elevation;
899 : uint16_t directionIndex;
900 : float old_panning_gains[2];
901 : float new_panning_gains[2];
902 : float panned_signal[L_FRAME48k];
903 : int16_t nchan_in;
904 : int16_t nBins;
905 : int16_t slot;
906 : int16_t mrange[2], brange[2];
907 : int16_t processing_len, offset;
908 : float g1, g2;
909 :
910 3126 : masaMetaHandle = st_ivas->hMasa->data.extOutMeta;
911 3126 : ismMetaHandle = &ismMeta;
912 :
913 : /* Compute CLDFB analysis */
914 3126 : nchan_in = st_ivas->nchan_transport + 1;
915 3126 : nBins = output_frame / CLDFB_NO_COL_MAX;
916 53142 : for ( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
917 : {
918 200064 : for ( n = 0; n < nchan_in; n++ )
919 : {
920 150048 : cldfbAnalysis_ts(
921 150048 : &( output[n][nBins * slot] ),
922 150048 : inRe[n][slot],
923 150048 : inIm[n][slot],
924 : nBins, st_ivas->cldfbAnaDec[n] );
925 : }
926 : }
927 :
928 : /* Determine energies */
929 15630 : for ( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
930 : {
931 12504 : mrange[0] = st_ivas->hMasa->config.block_grouping[sf];
932 12504 : mrange[1] = st_ivas->hMasa->config.block_grouping[sf + 1];
933 :
934 12504 : set_zero( eneMasa[sf], MASA_FREQUENCY_BANDS );
935 12504 : set_zero( eneIsm[sf], MASA_FREQUENCY_BANDS );
936 :
937 62520 : for ( slot = mrange[0]; slot < mrange[1]; slot++ )
938 : {
939 1250400 : for ( band = 0; band < MASA_FREQUENCY_BANDS; band++ )
940 : {
941 1200384 : brange[0] = st_ivas->hMasa->config.band_grouping[band];
942 1200384 : brange[1] = st_ivas->hMasa->config.band_grouping[band + 1];
943 :
944 1200384 : if ( brange[1] > nBins )
945 : {
946 63360 : brange[1] = nBins;
947 : }
948 :
949 3601152 : for ( n = 0; n < MASA_MAX_TRANSPORT_CHANNELS; n++ )
950 : {
951 6882048 : for ( bin = brange[0]; bin < brange[1]; bin++ )
952 : {
953 4481280 : eneMasa[sf][band] += inRe[n][slot][bin] * inRe[n][slot][bin] + inIm[n][slot][bin] * inIm[n][slot][bin];
954 : }
955 : }
956 3441024 : for ( bin = brange[0]; bin < brange[1]; bin++ )
957 : {
958 2240640 : 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];
959 : }
960 : }
961 : }
962 : }
963 :
964 : /* Determine MASA metadata for the object */
965 3126 : ismMetaHandle->descriptiveMeta.numberOfDirections = 0u;
966 15630 : for ( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
967 : {
968 12504 : azimuth = st_ivas->hMasaIsmData->azimuth_separated_ism[sf];
969 12504 : elevation = st_ivas->hMasaIsmData->elevation_separated_ism[sf];
970 :
971 12504 : directionIndex = index_theta_phi_16( &elevation, &azimuth, st_ivas->hMasa->data.sph_grid16 );
972 :
973 312600 : for ( band = 0; band < MASA_FREQUENCY_BANDS; band++ )
974 : {
975 300096 : ismMetaHandle->directionIndex[0][sf][band] = directionIndex;
976 300096 : ismMetaHandle->directToTotalRatio[0][sf][band] = UINT8_MAX;
977 300096 : ismMetaHandle->spreadCoherence[0][sf][band] = 0;
978 300096 : ismMetaHandle->surroundCoherence[sf][band] = 0;
979 300096 : ismMetaHandle->diffuseToTotalRatio[sf][band] = 0;
980 : }
981 : }
982 :
983 : /* Merge MASA metadatas */
984 3126 : ivas_prerend_merge_masa_metadata( masaMetaHandle, masaMetaHandle, IVAS_REND_AUDIO_CONFIG_TYPE_MASA, eneMasa, ismMetaHandle, IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED, eneIsm );
985 :
986 : /* Mix the separated object audio signal to the MASA audio signals */
987 3126 : ivas_get_stereo_panning_gains( st_ivas->hMasaIsmData->azimuth_separated_ism[0], st_ivas->hMasaIsmData->elevation_separated_ism[0], old_panning_gains );
988 3126 : ivas_get_stereo_panning_gains( st_ivas->hMasaIsmData->azimuth_separated_ism[2], st_ivas->hMasaIsmData->elevation_separated_ism[2], new_panning_gains );
989 :
990 3126 : processing_len = output_frame / 2;
991 9378 : for ( n = 0; n < MASA_MAX_TRANSPORT_CHANNELS; n++ )
992 : {
993 6252 : v_multc( output[MASA_MAX_TRANSPORT_CHANNELS], old_panning_gains[n], panned_signal, processing_len );
994 6252 : v_add( output[n], panned_signal, output[n], processing_len );
995 : }
996 3126 : offset = processing_len;
997 :
998 3126 : processing_len = output_frame / MAX_PARAM_SPATIAL_SUBFRAMES;
999 9378 : for ( n = 0; n < MASA_MAX_TRANSPORT_CHANNELS; n++ )
1000 : {
1001 1126572 : for ( k = 0; k < processing_len; k++ )
1002 : {
1003 1120320 : g1 = st_ivas->hIsmRendererData->interpolator[k];
1004 1120320 : g2 = 1.0f - g1;
1005 1120320 : output[n][k + offset] += ( g1 * new_panning_gains[n] + g2 * old_panning_gains[n] ) * output[MASA_MAX_TRANSPORT_CHANNELS][k + offset];
1006 : }
1007 : }
1008 3126 : offset += processing_len;
1009 :
1010 9378 : for ( n = 0; n < MASA_MAX_TRANSPORT_CHANNELS; n++ )
1011 : {
1012 6252 : v_multc( &output[MASA_MAX_TRANSPORT_CHANNELS][offset], new_panning_gains[n], panned_signal, processing_len );
1013 6252 : v_add( &output[n][offset], panned_signal, &output[n][offset], processing_len );
1014 : }
1015 :
1016 : /* Zero output object channels */
1017 14442 : for ( n = 0; n < nchan_ism; n++ )
1018 : {
1019 11316 : set_zero( output[MASA_MAX_TRANSPORT_CHANNELS + n], output_frame );
1020 : }
1021 :
1022 3126 : return;
1023 : }
1024 :
1025 :
1026 : /*-------------------------------------------------------------------------*
1027 : * ivas_omasa_objects_delay_open()
1028 : *
1029 : * Open structures, reserve memory, and init values for dela buffers of objects.
1030 : *-------------------------------------------------------------------------*/
1031 :
1032 11458 : ivas_error ivas_omasa_objects_delay_open(
1033 : Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
1034 : )
1035 : {
1036 : int16_t i;
1037 :
1038 11458 : if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
1039 : {
1040 3795 : st_ivas->hMasaIsmData->delayBuffer_nchan = 1;
1041 : }
1042 : else
1043 : {
1044 7663 : st_ivas->hMasaIsmData->delayBuffer_nchan = st_ivas->nchan_ism;
1045 : }
1046 :
1047 11458 : st_ivas->hMasaIsmData->delayBuffer_size = (int16_t) ( ( st_ivas->hDecoderConfig->output_Fs / 50 ) / MAX_PARAM_SPATIAL_SUBFRAMES );
1048 :
1049 11458 : if ( ( st_ivas->hMasaIsmData->delayBuffer = (float **) malloc( st_ivas->hMasaIsmData->delayBuffer_nchan * sizeof( float * ) ) ) == NULL )
1050 : {
1051 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for MASA ISM delay buffer \n" ) );
1052 : }
1053 :
1054 35521 : for ( i = 0; i < st_ivas->hMasaIsmData->delayBuffer_nchan; i++ )
1055 : {
1056 24063 : if ( ( st_ivas->hMasaIsmData->delayBuffer[i] = (float *) malloc( st_ivas->hMasaIsmData->delayBuffer_size * sizeof( float ) ) ) == NULL )
1057 : {
1058 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for MASA ISM delay buffer \n" ) );
1059 : }
1060 24063 : set_zero( st_ivas->hMasaIsmData->delayBuffer[i], st_ivas->hMasaIsmData->delayBuffer_size );
1061 : }
1062 :
1063 11458 : return IVAS_ERR_OK;
1064 : }
1065 :
1066 :
1067 : /*--------------------------------------------------------------------------*
1068 : * ivas_omasa_render_objects_from_mix()
1069 : *
1070 : * In case of external rendering, render objects from the transport signal
1071 : * mix containing MASA audio and object audio.
1072 : *--------------------------------------------------------------------------*/
1073 :
1074 4620 : void ivas_omasa_render_objects_from_mix(
1075 : Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */
1076 : float *output[], /* o : output synthesis signal */
1077 : const int16_t nchan_ism, /* i : number of ISMs */
1078 : const int16_t output_frame /* i : output frame length per channel */
1079 : )
1080 : {
1081 : int16_t n, m, i;
1082 : MASA_ISM_EXT_DATA_HANDLE hExtData;
1083 : float separated_object[L_FRAME48k];
1084 : float rendered_objects[MAX_NUM_OBJECTS][L_FRAME48k];
1085 : int16_t coding_delay;
1086 : float new_panning_gains[2];
1087 : float panning_gains[2];
1088 : float azimuth, elevation;
1089 : float inRe[3][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
1090 : float inIm[3][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
1091 : float outRe[MAX_NUM_OBJECTS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
1092 : float outIm[MAX_NUM_OBJECTS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
1093 : float ism_proto_energy[MAX_NUM_OBJECTS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
1094 : float transport_energy[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
1095 : float ism_target_energy[MAX_NUM_OBJECTS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
1096 : float masa_target_energy[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
1097 : float ism_processing_gains[MAX_NUM_OBJECTS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
1098 : float masa_processing_gains[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX];
1099 : int16_t slot;
1100 : int16_t sf;
1101 : int16_t bin;
1102 : int16_t nchan_transport;
1103 : int16_t nBins;
1104 : float interpVal;
1105 : float *outSlotRePr, *outSlotImPr;
1106 : int16_t md_idx;
1107 : float iir_factor_prev, iir_factor_curr;
1108 :
1109 : /* Create slot to metadata map */
1110 23100 : for ( sf = 0, slot = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
1111 : {
1112 92400 : for ( i = 0; i < CLDFB_SLOTS_PER_SUBFRAME; i++, slot++ )
1113 : {
1114 73920 : st_ivas->hSpatParamRendCom->render_to_md_map[slot] = st_ivas->hSpatParamRendCom->dirac_read_idx;
1115 : }
1116 18480 : st_ivas->hSpatParamRendCom->dirac_read_idx = ( st_ivas->hSpatParamRendCom->dirac_read_idx + 1 ) % st_ivas->hSpatParamRendCom->dirac_md_buffer_length;
1117 : }
1118 :
1119 : /* Move separated object signal and object channels */
1120 4620 : mvr2r( output[CPE_CHANNELS], separated_object, output_frame );
1121 20124 : for ( n = 0; n < nchan_ism; n++ )
1122 : {
1123 15504 : set_zero( output[CPE_CHANNELS + n], output_frame );
1124 : }
1125 :
1126 : /* Delay the separated object signal by the CLDFB delay */
1127 4620 : delay_signal( separated_object, output_frame, st_ivas->hMasaIsmData->delayBuffer[0], st_ivas->hMasaIsmData->delayBuffer_size );
1128 :
1129 : /* Set object metadata to the ism struct */
1130 20124 : for ( n = 0; n < nchan_ism; n++ )
1131 : {
1132 15504 : st_ivas->hIsmMetaData[n]->azimuth = st_ivas->hMasaIsmData->azimuth_ism[n][st_ivas->hSpatParamRendCom->dirac_read_idx];
1133 15504 : st_ivas->hIsmMetaData[n]->elevation = st_ivas->hMasaIsmData->elevation_ism[n][st_ivas->hSpatParamRendCom->dirac_read_idx];
1134 : }
1135 :
1136 : /* Move the separated object signal to the correct output channel */
1137 4620 : hExtData = st_ivas->hMasaIsmData->hExtData;
1138 4620 : coding_delay = output_frame / 20 * 17; /* 17 ms of coding and CLDFB delay */
1139 4620 : mvr2r( separated_object, output[CPE_CHANNELS + hExtData->prev_idx_separated_ism], coding_delay );
1140 4620 : mvr2r( &separated_object[coding_delay], &output[CPE_CHANNELS + st_ivas->hMasaIsmData->idx_separated_ism][coding_delay], output_frame - coding_delay );
1141 :
1142 : /* Compute CLDFB analysis */
1143 4620 : nchan_transport = st_ivas->nchan_transport;
1144 4620 : nBins = output_frame / CLDFB_NO_COL_MAX;
1145 78540 : for ( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1146 : {
1147 221760 : for ( n = 0; n < nchan_transport; n++ )
1148 : {
1149 147840 : cldfbAnalysis_ts(
1150 147840 : &( output[n][nBins * slot] ),
1151 147840 : inRe[n][slot],
1152 147840 : inIm[n][slot],
1153 : nBins, st_ivas->cldfbAnaDec[n] );
1154 : }
1155 : }
1156 :
1157 : /* Create prototype signals */
1158 20124 : for ( n = 0; n < nchan_ism; n++ )
1159 : {
1160 15504 : azimuth = (float) st_ivas->hIsmMetaData[n]->azimuth;
1161 15504 : elevation = (float) st_ivas->hIsmMetaData[n]->elevation;
1162 15504 : ivas_get_stereo_panning_gains( azimuth, elevation, new_panning_gains );
1163 15504 : interpVal = 0.0f;
1164 :
1165 263568 : for ( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1166 : {
1167 248064 : interpVal += 1.0f / (float) CLDFB_NO_COL_MAX;
1168 744192 : for ( m = 0; m < 2; m++ )
1169 : {
1170 496128 : panning_gains[m] = ( 1.0f - interpVal ) * hExtData->prev_panning_gains[n][m] + interpVal * new_panning_gains[m];
1171 : }
1172 248064 : v_multc( inRe[0][slot], panning_gains[0], outRe[n][slot], nBins );
1173 248064 : v_multc( inIm[0][slot], panning_gains[0], outIm[n][slot], nBins );
1174 248064 : v_multc_acc( inRe[1][slot], panning_gains[1], outRe[n][slot], nBins );
1175 248064 : v_multc_acc( inIm[1][slot], panning_gains[1], outIm[n][slot], nBins );
1176 : }
1177 :
1178 46512 : for ( m = 0; m < 2; m++ )
1179 : {
1180 31008 : hExtData->prev_panning_gains[n][m] = new_panning_gains[m];
1181 : }
1182 : }
1183 :
1184 : /* Determine prototype energy */
1185 20124 : for ( n = 0; n < nchan_ism; n++ )
1186 : {
1187 263568 : for ( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1188 : {
1189 11330304 : for ( bin = 0; bin < nBins; bin++ )
1190 : {
1191 11082240 : ism_proto_energy[n][slot][bin] = ( outRe[n][slot][bin] * outRe[n][slot][bin] ) + ( outIm[n][slot][bin] * outIm[n][slot][bin] );
1192 : }
1193 : }
1194 : }
1195 :
1196 : /* Determine transport energy */
1197 78540 : for ( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1198 : {
1199 73920 : set_zero( transport_energy[slot], nBins );
1200 : }
1201 13860 : for ( n = 0; n < CPE_CHANNELS; n++ )
1202 : {
1203 157080 : for ( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1204 : {
1205 6737280 : for ( bin = 0; bin < nBins; bin++ )
1206 : {
1207 6589440 : transport_energy[slot][bin] += ( inRe[n][slot][bin] * inRe[n][slot][bin] ) + ( inIm[n][slot][bin] * inIm[n][slot][bin] );
1208 : }
1209 : }
1210 : }
1211 :
1212 : /* Determine target energy */
1213 20124 : for ( n = 0; n < nchan_ism; n++ )
1214 : {
1215 263568 : for ( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1216 : {
1217 248064 : md_idx = st_ivas->hSpatParamRendCom->render_to_md_map[slot];
1218 11330304 : for ( bin = 0; bin < nBins; bin++ )
1219 : {
1220 11082240 : ism_target_energy[n][slot][bin] = transport_energy[slot][bin] * st_ivas->hMasaIsmData->energy_ratio_ism[n][md_idx][bin];
1221 : }
1222 : }
1223 : }
1224 78540 : for ( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1225 : {
1226 73920 : md_idx = st_ivas->hSpatParamRendCom->render_to_md_map[slot];
1227 3368640 : for ( bin = 0; bin < nBins; bin++ )
1228 : {
1229 3294720 : masa_target_energy[slot][bin] = transport_energy[slot][bin] * hExtData->masa_render_masa_to_total[md_idx][bin];
1230 : }
1231 : }
1232 :
1233 : /* Determine temporally smoothed energies and determine gains using them */
1234 4620 : iir_factor_curr = ( 1.0f - EXT_RENDER_IIR_FAC );
1235 4620 : iir_factor_prev = EXT_RENDER_IIR_FAC;
1236 20124 : for ( n = 0; n < nchan_ism; n++ )
1237 : {
1238 263568 : for ( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1239 : {
1240 11330304 : for ( bin = 0; bin < nBins; bin++ )
1241 : {
1242 11082240 : hExtData->ism_render_proto_energy[n][bin] *= iir_factor_prev;
1243 11082240 : hExtData->ism_render_proto_energy[n][bin] += iir_factor_curr * ism_proto_energy[n][slot][bin];
1244 11082240 : hExtData->ism_render_target_energy[n][bin] *= iir_factor_prev;
1245 11082240 : hExtData->ism_render_target_energy[n][bin] += iir_factor_curr * ism_target_energy[n][slot][bin];
1246 :
1247 11082240 : 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] ) ) );
1248 : }
1249 : }
1250 : }
1251 78540 : for ( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1252 : {
1253 3368640 : for ( bin = 0; bin < nBins; bin++ )
1254 : {
1255 3294720 : hExtData->masa_render_proto_energy[bin] *= iir_factor_prev;
1256 3294720 : hExtData->masa_render_proto_energy[bin] += iir_factor_curr * transport_energy[slot][bin];
1257 3294720 : hExtData->masa_render_target_energy[bin] *= iir_factor_prev;
1258 3294720 : hExtData->masa_render_target_energy[bin] += iir_factor_curr * masa_target_energy[slot][bin];
1259 :
1260 3294720 : masa_processing_gains[slot][bin] = fminf( 4.0f, sqrtf( hExtData->masa_render_target_energy[bin] / fmaxf( 1e-12f, hExtData->masa_render_proto_energy[bin] ) ) );
1261 : }
1262 : }
1263 :
1264 : /* Determine output signals */
1265 20124 : for ( n = 0; n < nchan_ism; n++ )
1266 : {
1267 263568 : for ( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1268 : {
1269 11330304 : for ( bin = 0; bin < nBins; bin++ )
1270 : {
1271 11082240 : outRe[n][slot][bin] *= ism_processing_gains[n][slot][bin];
1272 11082240 : outIm[n][slot][bin] *= ism_processing_gains[n][slot][bin];
1273 : }
1274 : }
1275 : }
1276 13860 : for ( n = 0; n < MASA_MAX_TRANSPORT_CHANNELS; n++ )
1277 : {
1278 157080 : for ( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1279 : {
1280 6737280 : for ( bin = 0; bin < nBins; bin++ )
1281 : {
1282 6589440 : inRe[n][slot][bin] *= masa_processing_gains[slot][bin];
1283 6589440 : inIm[n][slot][bin] *= masa_processing_gains[slot][bin];
1284 : }
1285 : }
1286 : }
1287 :
1288 : /* Compute CLDFB synthesis */
1289 78540 : for ( slot = 0; slot < CLDFB_NO_COL_MAX; slot++ )
1290 : {
1291 221760 : for ( n = 0; n < nchan_transport; n++ )
1292 : {
1293 147840 : outSlotRePr = &( inRe[n][slot][0] );
1294 147840 : outSlotImPr = &( inIm[n][slot][0] );
1295 147840 : cldfbSynthesis( &outSlotRePr, &outSlotImPr, &( output[n][nBins * slot] ), nBins, st_ivas->cldfbSynDec[n] );
1296 : }
1297 :
1298 321984 : for ( n = 0; n < nchan_ism; n++ )
1299 : {
1300 248064 : outSlotRePr = &( outRe[n][slot][0] );
1301 248064 : outSlotImPr = &( outIm[n][slot][0] );
1302 248064 : cldfbSynthesis( &outSlotRePr, &outSlotImPr, &( rendered_objects[n][nBins * slot] ), nBins, st_ivas->cldfbSynDec[n + CPE_CHANNELS] );
1303 : }
1304 : }
1305 :
1306 : /* Combine the rendered objects with the separated objects */
1307 20124 : for ( n = 0; n < nchan_ism; n++ )
1308 : {
1309 15504 : v_add( output[CPE_CHANNELS + n], rendered_objects[n], output[CPE_CHANNELS + n], output_frame );
1310 : }
1311 :
1312 4620 : hExtData->prev_idx_separated_ism = st_ivas->hMasaIsmData->idx_separated_ism;
1313 :
1314 4620 : return;
1315 : }
1316 :
1317 :
1318 : /*--------------------------------------------------------------------------*
1319 : * ivas_omasa_gain_masa_tc()
1320 : *
1321 : * in case of external rendering with object editing, MASA transport channels
1322 : * need to be gained
1323 : *--------------------------------------------------------------------------*/
1324 :
1325 0 : void ivas_omasa_gain_masa_tc(
1326 : float *output[], /* i/o: output synthesis signal */
1327 : const float gainMasa, /* i : gain */
1328 : const int16_t nchan_transport_ism, /* i : number of ISM TCs */
1329 : const int16_t output_frame /* i : output frame length per channel */
1330 : )
1331 : {
1332 : /* Edited OMASA EXT MASA transport gaining */
1333 0 : for ( int16_t ch = 0; ch < CPE_CHANNELS; ch++ )
1334 : {
1335 0 : v_multc( output[nchan_transport_ism + ch], gainMasa, output[nchan_transport_ism + ch], output_frame );
1336 : }
1337 :
1338 0 : return;
1339 : }
|