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 "ivas_cnst.h"
36 : #include "ivas_prot_fx.h"
37 : #include "prot_fx.h"
38 : #include "ivas_prot_rend_fx.h"
39 : #include "ivas_rom_com.h"
40 : #include "wmc_auto.h"
41 : #include "ivas_prot_fx.h"
42 :
43 :
44 : /*-------------------------------------------------------------------------
45 : * Local constants
46 : *------------------------------------------------------------------------*/
47 :
48 : #define OMASA_TDREND_MATCHING_GAIN_FX 26026
49 :
50 : /*-------------------------------------------------------------------*
51 : * ivas_omasa_data_open()
52 : *
53 : * Allocate and initialize MASA_ISM rendering handle
54 : *-------------------------------------------------------------------*/
55 :
56 34 : ivas_error ivas_omasa_data_open_fx(
57 : Decoder_Struct *st_ivas /* i/o: IVAS decoder handle */
58 : )
59 : {
60 : MASA_ISM_DATA_HANDLE hMasaIsmData;
61 : Word16 ch, bin;
62 : Word16 sf, obj_idx;
63 :
64 34 : IF( ( hMasaIsmData = (MASA_ISM_DATA_HANDLE) malloc( sizeof( MASA_ISM_DATA ) ) ) == NULL )
65 : {
66 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MASA ISM data\n" ) );
67 : }
68 :
69 2074 : FOR( bin = 0; bin < CLDFB_NO_CHANNELS_MAX; bin++ )
70 : {
71 6120 : FOR( ch = 0; ch < 2; ch++ )
72 : {
73 4080 : hMasaIsmData->ismPreprocMatrix_fx[ch][ch][bin] = 32767; /* 1.0f in Q15 */
74 4080 : move16();
75 4080 : hMasaIsmData->ismPreprocMatrix_fx[1 - ch][ch][bin] = 0; // Q15
76 4080 : move16();
77 4080 : hMasaIsmData->eneMoveIIR_fx[ch][bin] = 0; // Q22
78 4080 : move32();
79 4080 : hMasaIsmData->enePreserveIIR_fx[ch][bin] = 0; // Q22
80 4080 : move32();
81 : }
82 2040 : hMasaIsmData->preprocEneTarget_fx[bin] = 0; // Q19
83 2040 : move32();
84 2040 : hMasaIsmData->preprocEneRealized_fx[bin] = 0; // Q19
85 2040 : move32();
86 : }
87 :
88 34 : hMasaIsmData->objectsMoved = 0;
89 34 : move16();
90 34 : hMasaIsmData->delayBuffer_fx = NULL;
91 :
92 170 : FOR( ch = 0; ch < MAX_NUM_OBJECTS; ch++ )
93 : {
94 136 : hMasaIsmData->ism_is_edited[ch] = 0;
95 136 : move16();
96 136 : hMasaIsmData->q_elevation_old_fx[ch] = 0; // Q22
97 136 : move32();
98 136 : hMasaIsmData->q_azimuth_old_fx[ch] = 0; // Q22
99 136 : move32();
100 : }
101 :
102 170 : FOR( obj_idx = 0; obj_idx < MAX_NUM_OBJECTS; obj_idx++ )
103 : {
104 136 : set16_fx( hMasaIsmData->azimuth_ism[obj_idx], 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR );
105 136 : set16_fx( hMasaIsmData->elevation_ism[obj_idx], 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR );
106 952 : FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR; sf++ )
107 : {
108 816 : set32_fx( hMasaIsmData->energy_ratio_ism_fx[obj_idx][sf], 0, CLDFB_NO_CHANNELS_MAX );
109 : }
110 : }
111 34 : set16_fx( hMasaIsmData->azimuth_separated_ism, 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR );
112 34 : set16_fx( hMasaIsmData->elevation_separated_ism, 0, MAX_PARAM_SPATIAL_SUBFRAMES + DELAY_MASA_PARAM_DEC_SFR );
113 :
114 34 : st_ivas->hMasaIsmData = hMasaIsmData;
115 :
116 34 : return IVAS_ERR_OK;
117 : }
118 :
119 :
120 : /*-------------------------------------------------------------------*
121 : * ivas_omasa_data_close()
122 : *
123 : * Deallocate MASA_ISM rendering handle
124 : *-------------------------------------------------------------------*/
125 :
126 604 : void ivas_omasa_data_close_fx(
127 : MASA_ISM_DATA_HANDLE *hMasaIsmData /* i/o: MASA_ISM rendering handle */
128 : )
129 : {
130 : Word16 i;
131 :
132 604 : test();
133 604 : IF( hMasaIsmData == NULL || *hMasaIsmData == NULL )
134 : {
135 570 : return;
136 : }
137 :
138 34 : IF( ( *hMasaIsmData )->delayBuffer_fx != NULL )
139 : {
140 39 : FOR( i = 0; i < ( *hMasaIsmData )->delayBuffer_nchan; i++ )
141 : {
142 27 : free( ( *hMasaIsmData )->delayBuffer_fx[i] ); // Q11
143 : }
144 12 : free( ( *hMasaIsmData )->delayBuffer_fx );
145 12 : ( *hMasaIsmData )->delayBuffer_fx = NULL;
146 : }
147 :
148 34 : free( *hMasaIsmData );
149 34 : *hMasaIsmData = NULL;
150 :
151 34 : return;
152 : }
153 :
154 :
155 : /*--------------------------------------------------------------------------*
156 : * ivas_omasa_dec_config()
157 : *
158 : * oMASA decoder configuration
159 : *--------------------------------------------------------------------------*/
160 :
161 1460 : ivas_error ivas_omasa_dec_config_fx(
162 : Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
163 : UWord16 *nSamplesRendered, /* o : number of samples flushed from the previous frame (JBM) */
164 : Word16 *num_src,
165 : Word16 SrcInd[MAX_NUM_TDREND_CHANNELS],
166 : Word16 *data /* o : output synthesis signal Qx*/
167 : )
168 : {
169 : Word16 k, sce_id, nSCE_old, nchan_hp20_old, numCldfbAnalyses_old, numCldfbSyntheses_old, n_MD;
170 : Word32 ivas_total_brate, ism_total_brate, cpe_brate;
171 : Word32 brate_SCE, brate_CPE;
172 : ISM_MODE ism_mode_old;
173 : IVAS_FORMAT ivas_format_orig;
174 : Word16 nchan_out_buff, nchan_out_buff_old;
175 : ivas_error error;
176 : RENDERER_TYPE old_renderer_type;
177 :
178 : /* initializations */
179 1460 : ism_total_brate = 0;
180 1460 : move32();
181 1460 : ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate;
182 1460 : move32();
183 :
184 : /* save previous frame parameters */
185 1460 : ism_mode_old = ivas_omasa_ism_mode_select_fx( st_ivas->hDecoderConfig->last_ivas_total_brate, st_ivas->nchan_ism );
186 1460 : move16();
187 1460 : st_ivas->ism_mode = ism_mode_old;
188 1460 : move16();
189 :
190 1460 : ivas_format_orig = st_ivas->ivas_format;
191 1460 : move16();
192 1460 : st_ivas->ivas_format = st_ivas->last_ivas_format;
193 1460 : move16();
194 1460 : ivas_init_dec_get_num_cldfb_instances_ivas_fx( st_ivas, &numCldfbAnalyses_old, &numCldfbSyntheses_old );
195 1460 : nchan_out_buff_old = ivas_get_nchan_buffers_dec_ivas_fx( st_ivas, -1, -1 );
196 1460 : move16();
197 :
198 1460 : st_ivas->ivas_format = ivas_format_orig;
199 1460 : move16();
200 :
201 1460 : nSCE_old = st_ivas->nSCE;
202 1460 : move16();
203 1460 : nchan_hp20_old = getNumChanSynthesis( st_ivas );
204 1460 : move16();
205 :
206 : /* set ism_mode of current frame */
207 1460 : st_ivas->ism_mode = ivas_omasa_ism_mode_select_fx( ivas_total_brate, st_ivas->nchan_ism );
208 1460 : move16();
209 :
210 : /*-----------------------------------------------------------------*
211 : * Renderer selection
212 : *-----------------------------------------------------------------*/
213 :
214 1460 : old_renderer_type = st_ivas->renderer_type;
215 1460 : move32();
216 :
217 : /* MASA reconfig. */
218 1460 : cpe_brate = calculate_cpe_brate_MASA_ISM_fx( st_ivas->ism_mode, ivas_total_brate, st_ivas->nchan_ism );
219 1460 : move32();
220 1460 : test();
221 1460 : test();
222 1460 : test();
223 1460 : IF( ( st_ivas->ini_active_frame == 0 ) && ( ivas_total_brate != FRAME_NO_DATA ) && LT_32( cpe_brate, MASA_STEREO_MIN_BITRATE ) && EQ_16( st_ivas->nCPE, 1 ) )
224 : {
225 0 : st_ivas->hCPE[0]->nchan_out = 1;
226 0 : move16();
227 : }
228 : ELSE
229 : {
230 1460 : IF( NE_32( ( error = ivas_masa_dec_reconfigure_fx( st_ivas, nSamplesRendered, data ) ), IVAS_ERR_OK ) )
231 : {
232 0 : return error;
233 : }
234 : }
235 :
236 1460 : IF( LT_32( cpe_brate, MASA_STEREO_MIN_BITRATE ) )
237 : {
238 479 : st_ivas->hCPE[0]->nchan_out = 1;
239 479 : move16();
240 : }
241 : ELSE
242 : {
243 981 : st_ivas->hCPE[0]->nchan_out = 2;
244 981 : move16();
245 : }
246 :
247 : /* OMASA reconfig. */
248 1460 : test();
249 1460 : IF( st_ivas->hMasaIsmData == NULL && EQ_32( st_ivas->ivas_format, MASA_ISM_FORMAT ) )
250 : {
251 2 : IF( NE_32( ( error = ivas_omasa_data_open_fx( st_ivas ) ), IVAS_ERR_OK ) )
252 : {
253 0 : return error;
254 : }
255 : }
256 :
257 1460 : ivas_set_omasa_TC_fx( st_ivas->ism_mode, st_ivas->nchan_ism, &st_ivas->nSCE, &st_ivas->nCPE );
258 :
259 : /* re-configure hp20 memories */
260 1460 : IF( NE_32( ( error = ivas_hp20_dec_reconfig_fx( st_ivas, nchan_hp20_old ) ), IVAS_ERR_OK ) )
261 : {
262 0 : return error;
263 : }
264 :
265 : /* reconfigure core-coders for ISMs */
266 1460 : k = 0;
267 1460 : move16();
268 11574 : WHILE( LT_16( k, SIZE_IVAS_BRATE_TBL ) && NE_32( ivas_total_brate, ivas_brate_tbl[k] ) )
269 : {
270 10114 : k = add( k, 1 );
271 : }
272 :
273 3355 : FOR( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ )
274 : {
275 1895 : ism_total_brate = L_add( ism_total_brate, sep_object_brate[k - 2][st_ivas->nSCE - 1] );
276 : }
277 :
278 1460 : brate_SCE = 0;
279 1460 : move32();
280 1460 : IF( st_ivas->nSCE > 0 )
281 : {
282 1066 : brate_SCE = sep_object_brate[k - 2][st_ivas->nSCE - 1];
283 1066 : move32();
284 : }
285 1460 : brate_CPE = L_sub( ivas_total_brate, ism_total_brate );
286 :
287 1460 : IF( NE_32( ( error = ivas_corecoder_dec_reconfig_fx( st_ivas, nSCE_old, 1, 2, 0, brate_SCE, brate_CPE ) ), IVAS_ERR_OK ) )
288 : {
289 0 : return error;
290 : }
291 :
292 1460 : IF( NE_16( ism_mode_old, st_ivas->ism_mode ) )
293 : {
294 : /* ISM MD reconfig. */
295 1459 : n_MD = 0;
296 1459 : move16();
297 :
298 1459 : test();
299 1459 : IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
300 : {
301 675 : n_MD = 1;
302 675 : move16();
303 :
304 675 : IF( st_ivas->hIsmMetaData[0] == NULL )
305 : {
306 233 : IF( NE_32( ( error = ivas_ism_metadata_dec_create_fx( st_ivas, 1, NULL ) ), IVAS_ERR_OK ) )
307 : {
308 0 : return error;
309 : }
310 : }
311 : }
312 784 : ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
313 : {
314 390 : n_MD = st_ivas->nchan_ism;
315 390 : move16();
316 :
317 390 : ivas_ism_metadata_close( st_ivas->hIsmMetaData, 0 );
318 :
319 390 : IF( NE_32( ( error = ivas_ism_metadata_dec_create_fx( st_ivas, st_ivas->nchan_ism, NULL ) ), IVAS_ERR_OK ) )
320 : {
321 0 : return error;
322 : }
323 : }
324 :
325 1459 : ivas_ism_metadata_close( st_ivas->hIsmMetaData, n_MD );
326 :
327 1459 : st_ivas->hCPE[0]->element_brate = L_sub( ivas_total_brate, ism_total_brate );
328 :
329 : /*-----------------------------------------------------------------*
330 : * Renderer selection
331 : *-----------------------------------------------------------------*/
332 :
333 1459 : ivas_renderer_select( st_ivas );
334 :
335 : /*-------------------------------------------------------------------*
336 : * Reallocate rendering handles
337 : *--------------------------------------------------------------------*/
338 :
339 1459 : IF( NE_16( old_renderer_type, st_ivas->renderer_type ) )
340 : {
341 76 : IF( EQ_32( st_ivas->renderer_type, RENDERER_MONO_DOWNMIX ) )
342 : {
343 38 : IF( NE_32( ( error = ivas_mono_dmx_renderer_open( st_ivas ) ), IVAS_ERR_OK ) )
344 : {
345 0 : return error;
346 : }
347 : }
348 : ELSE
349 : {
350 38 : ivas_mono_dmx_renderer_close( &st_ivas->hMonoDmxRenderer );
351 : }
352 : }
353 :
354 : /* objects renderer reconfig. */
355 1459 : IF( st_ivas->hMasaIsmData != NULL )
356 : {
357 1459 : ivas_omasa_separate_object_renderer_close( st_ivas );
358 : }
359 :
360 1459 : IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_PARAMETRIC ) )
361 : {
362 221 : IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
363 : {
364 : /* Allocate TD renderer for the objects in DISC mode */
365 54 : IF( st_ivas->hBinRendererTd == NULL )
366 : {
367 35 : IF( NE_32( ( error = ivas_td_binaural_open_fx( st_ivas, SrcInd, num_src ) ), IVAS_ERR_OK ) )
368 : {
369 0 : return error;
370 : }
371 : }
372 :
373 : /* Allocate 'hIsmRendererData' handle and memory for delay buffer within 'hMasaIsmData' */
374 54 : IF( NE_32( ( error = ivas_omasa_separate_object_renderer_open( st_ivas ) ), IVAS_ERR_OK ) )
375 : {
376 0 : return error;
377 : }
378 : }
379 : ELSE
380 : {
381 : /* TD renderer handle */
382 167 : test();
383 167 : IF( st_ivas->hBinRendererTd != NULL && EQ_16( st_ivas->hBinRendererTd->HrFiltSet_p->ModelParams.modelROM, TRUE ) )
384 : {
385 35 : ivas_td_binaural_close_fx( &st_ivas->hBinRendererTd );
386 :
387 35 : st_ivas->hHrtfTD = NULL;
388 : }
389 :
390 : /* ISM renderer handle + ISM data handle */
391 167 : ivas_omasa_separate_object_renderer_close( st_ivas );
392 : }
393 : }
394 :
395 1459 : IF( EQ_32( st_ivas->renderer_type, RENDERER_DIRAC ) )
396 : {
397 667 : IF( NE_32( ( error = ivas_dirac_dec_config_fx( st_ivas, DIRAC_RECONFIGURE ) ), IVAS_ERR_OK ) )
398 : {
399 0 : return error;
400 : }
401 :
402 667 : test();
403 667 : test();
404 667 : IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
405 : {
406 : /* Allocate 'hIsmRendererData' handle and memory for delay buffer within 'hMasaIsmData' */
407 485 : IF( NE_32( ( 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 182 : ivas_omasa_separate_object_renderer_close( st_ivas );
416 : }
417 : }
418 :
419 : /*-----------------------------------------------------------------*
420 : * TD Decorrelator
421 : *-----------------------------------------------------------------*/
422 :
423 1459 : IF( st_ivas->hDiracDecBin != NULL )
424 : {
425 657 : IF( NE_32( ( 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->hTdDecorr ), &( st_ivas->hDiracDecBin->useTdDecorr ) ) ), IVAS_ERR_OK ) )
426 :
427 : {
428 0 : return error;
429 : }
430 : }
431 :
432 : /*-----------------------------------------------------------------*
433 : * CLDFB instances
434 : *-----------------------------------------------------------------*/
435 :
436 1459 : IF( NE_32( ( error = ivas_cldfb_dec_reconfig_fx( st_ivas, 2, numCldfbAnalyses_old, numCldfbSyntheses_old ) ), IVAS_ERR_OK ) )
437 : {
438 0 : return error;
439 : }
440 :
441 : /*-----------------------------------------------------------------*
442 : * floating-point output audio buffers
443 : *-----------------------------------------------------------------*/
444 :
445 1459 : nchan_out_buff = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 );
446 1459 : IF( NE_32( ( error = ivas_output_buff_dec_fx( st_ivas->p_output_fx, nchan_out_buff_old, nchan_out_buff ) ), IVAS_ERR_OK ) )
447 : {
448 0 : return error;
449 : }
450 : }
451 :
452 1460 : return IVAS_ERR_OK;
453 : }
454 :
455 :
456 : /*--------------------------------------------------------------------------*
457 : * ivas_set_surplus_brate_dec()
458 : *
459 : * set bit-rate surplus in combined format coding
460 : *--------------------------------------------------------------------------*/
461 6418 : void ivas_set_surplus_brate_dec(
462 : Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
463 : Word32 *ism_total_brate /* i/o: ISM total bitrate */
464 : )
465 : {
466 : Word16 n, bits_ism, bits_element[MAX_NUM_OBJECTS];
467 : Word32 ism_total_brate_ref, element_brate[MAX_NUM_OBJECTS];
468 :
469 6418 : *ism_total_brate = 0;
470 6418 : move32();
471 :
472 6418 : test();
473 6418 : IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
474 : {
475 3652 : *ism_total_brate = ivas_interformat_brate_fx( st_ivas->ism_mode, 1, st_ivas->hSCE[0]->element_brate, st_ivas->hIsmMetaData[0]->ism_imp, 0 );
476 3652 : move32();
477 :
478 3652 : st_ivas->hCPE[0]->brate_surplus = L_sub( st_ivas->hSCE[0]->element_brate, *ism_total_brate );
479 3652 : move32();
480 :
481 : /* set 'st->total_brate'; there are no meta-data in ISM_MASA_MODE_PARAM_ONE_OBJ mode */
482 3652 : st_ivas->hSCE[0]->hCoreCoder[0]->total_brate = *ism_total_brate;
483 3652 : move32();
484 :
485 3652 : st_ivas->hSCE[0]->hCoreCoder[0]->low_rate_mode = 0;
486 3652 : move16();
487 3652 : if ( EQ_16( st_ivas->hIsmMetaData[0]->ism_imp, ISM_NO_META ) )
488 : {
489 0 : st_ivas->hSCE[0]->hCoreCoder[0]->low_rate_mode = 1;
490 0 : move16();
491 : }
492 : }
493 2766 : ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
494 : {
495 : Word16 brate_limit_flag, ism_imp[MAX_NUM_OBJECTS], tmp;
496 :
497 10097 : FOR( n = 0; n < st_ivas->nchan_ism; n++ )
498 : {
499 7331 : ism_imp[n] = st_ivas->hIsmMetaData[n]->ism_imp;
500 7331 : move16();
501 : }
502 :
503 2766 : brate_limit_flag = calculate_brate_limit_flag_fx( ism_imp, st_ivas->nchan_ism );
504 :
505 2766 : ism_total_brate_ref = 0;
506 2766 : move32();
507 10097 : FOR( n = 0; n < st_ivas->nchan_ism; n++ )
508 : {
509 7331 : ism_total_brate_ref = L_add( ism_total_brate_ref, st_ivas->hSCE[n]->element_brate );
510 : }
511 :
512 : /* bits_ism = (int16_t) ( ism_total_brate_ref / FRAMES_PER_SEC ); */
513 2766 : bits_ism = extract_l( Mpy_32_32( ism_total_brate_ref, ONE_BY_FRAMES_PER_SEC_Q31 ) );
514 :
515 2766 : tmp = 0;
516 2766 : move16();
517 2766 : IF( bits_ism != 0 )
518 : {
519 2766 : tmp = idiv1616( bits_ism, st_ivas->nchan_ism );
520 : }
521 2766 : set16_fx( bits_element, tmp, st_ivas->nchan_ism );
522 2766 : bits_element[st_ivas->nchan_ism - 1] = add( bits_element[st_ivas->nchan_ism - 1], bits_ism % st_ivas->nchan_ism );
523 2766 : move16();
524 2766 : bitbudget_to_brate( bits_element, element_brate, st_ivas->nchan_ism );
525 :
526 2766 : *ism_total_brate = 0;
527 2766 : move32();
528 10097 : FOR( n = 0; n < st_ivas->nchan_ism; n++ )
529 : {
530 7331 : st_ivas->hSCE[n]->element_brate = element_brate[n];
531 7331 : move32();
532 :
533 7331 : *ism_total_brate = L_add( *ism_total_brate, ivas_interformat_brate_fx( ISM_MASA_MODE_DISC, st_ivas->nchan_ism, st_ivas->hSCE[n]->element_brate, st_ivas->hIsmMetaData[n]->ism_imp, brate_limit_flag ) );
534 7331 : move32();
535 :
536 7331 : test();
537 7331 : test();
538 7331 : IF( GT_16( ism_imp[n], 1 ) && EQ_16( st_ivas->flag_omasa_brate, 1 ) && brate_limit_flag >= 0 )
539 : {
540 130 : *ism_total_brate = L_sub( *ism_total_brate, ADJUST_ISM_BRATE_NEG );
541 130 : move32();
542 : }
543 :
544 7331 : test();
545 7331 : test();
546 7331 : test();
547 7331 : IF( EQ_16( brate_limit_flag, -1 ) && GE_16( ism_imp[n], 1 ) && GE_16( st_ivas->nchan_ism, 3 ) && GT_32( L_sub( ism_total_brate_ref, *ism_total_brate ), IVAS_48k ) )
548 : {
549 0 : *ism_total_brate = L_add( *ism_total_brate, ADJUST_ISM_BRATE_POS );
550 0 : move32();
551 : }
552 : }
553 2766 : st_ivas->hCPE[0]->brate_surplus = L_sub( ism_total_brate_ref, *ism_total_brate );
554 2766 : move32();
555 :
556 : /* 'st->total_brate' is set in ivas_ism_config */
557 : }
558 : ELSE
559 : {
560 0 : st_ivas->hCPE[0]->brate_surplus = 0;
561 0 : move32();
562 : }
563 :
564 6418 : return;
565 : }
566 :
567 :
568 : /*--------------------------------------------------------------------------*
569 : * ivas_omasa_ism_metadata_dec()
570 : *
571 : * decode ISM metadata in OMASA format
572 : *--------------------------------------------------------------------------*/
573 6418 : ivas_error ivas_omasa_ism_metadata_dec_fx(
574 : Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
575 : const Word32 ism_total_brate, /* i : ISM total bitrate */
576 : Word16 *nchan_ism, /* o : number of ISM separated channels */
577 : Word16 *nchan_transport_ism, /* o : number of ISM TCs */
578 : const Word16 dirac_bs_md_write_idx, /* i : DirAC bitstream write index */
579 : Word16 nb_bits_metadata[] /* o : number of ISM metadata bits */
580 : )
581 : {
582 : Word16 n, block;
583 : Word16 azimuth_ism, elevation_ism, meta_write_index;
584 : ivas_error error;
585 :
586 : /* set ISM parameters */
587 6418 : *nchan_ism = st_ivas->nchan_ism;
588 6418 : move16();
589 6418 : *nchan_transport_ism = st_ivas->nchan_ism;
590 6418 : move16();
591 6418 : IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
592 : {
593 2029 : *nchan_ism = 1;
594 2029 : move16();
595 2029 : *nchan_transport_ism = 1;
596 2029 : move16();
597 : }
598 4389 : ELSE IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
599 : {
600 1623 : *nchan_ism = 0;
601 1623 : move16();
602 1623 : *nchan_transport_ism = 1;
603 1623 : move16();
604 : }
605 :
606 6418 : test();
607 6418 : IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
608 : {
609 : /* decode ISM metadata */
610 4795 : IF( NE_32( ( error = ivas_ism_metadata_dec_fx( ism_total_brate, *nchan_ism, nchan_transport_ism, st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->bfi,
611 : 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] ) ),
612 : IVAS_ERR_OK ) )
613 : {
614 0 : return error;
615 : }
616 :
617 4795 : IF( st_ivas->hDirAC != NULL )
618 : {
619 3592 : IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_DISC ) )
620 : {
621 6462 : FOR( n = 0; n < st_ivas->nchan_ism; n++ )
622 : {
623 : // azimuth_ism = (int16_t) ( st_ivas->hIsmMetaData[n]->azimuth + 0.5f );
624 : // elevation_ism = (int16_t) ( st_ivas->hIsmMetaData[n]->elevation + 0.5f );
625 4679 : azimuth_ism = extract_l( L_shr_r( L_abs( st_ivas->hIsmMetaData[n]->azimuth_fx /*Q22*/ ), 22 ) ); // Q0
626 4679 : if ( st_ivas->hIsmMetaData[n]->azimuth_fx < 0 )
627 : {
628 2474 : azimuth_ism = negate( azimuth_ism );
629 : }
630 4679 : elevation_ism = extract_l( L_shr_r( L_abs( st_ivas->hIsmMetaData[n]->elevation_fx /*Q22*/ ), 22 ) ); // Q0
631 4679 : if ( st_ivas->hIsmMetaData[n]->elevation_fx < 0 )
632 : {
633 1486 : elevation_ism = negate( elevation_ism );
634 : }
635 :
636 23395 : FOR( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
637 : {
638 18716 : meta_write_index = ( add( dirac_bs_md_write_idx, block ) ) % st_ivas->hSpatParamRendCom->dirac_md_buffer_length;
639 18716 : move16();
640 18716 : st_ivas->hMasaIsmData->azimuth_ism[n][meta_write_index] = azimuth_ism;
641 18716 : move16();
642 18716 : st_ivas->hMasaIsmData->elevation_ism[n][meta_write_index] = elevation_ism;
643 18716 : move16();
644 : }
645 : }
646 : }
647 : ELSE /* ISM_MASA_MODE_MASA_ONE_OBJ */
648 : {
649 1809 : azimuth_ism = extract_l( L_shr_r( L_abs( st_ivas->hIsmMetaData[0]->azimuth_fx ), 22 ) );
650 1809 : if ( st_ivas->hIsmMetaData[0]->azimuth_fx < 0 )
651 : {
652 986 : azimuth_ism = negate( azimuth_ism );
653 : }
654 1809 : elevation_ism = extract_l( L_shr_r( L_abs( st_ivas->hIsmMetaData[0]->elevation_fx ), 22 ) );
655 1809 : if ( st_ivas->hIsmMetaData[0]->elevation_fx < 0 )
656 : {
657 574 : elevation_ism = negate( elevation_ism );
658 : }
659 :
660 9045 : FOR( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
661 : {
662 7236 : meta_write_index = ( add( dirac_bs_md_write_idx, block ) ) % st_ivas->hSpatParamRendCom->dirac_md_buffer_length;
663 7236 : move16();
664 7236 : st_ivas->hMasaIsmData->azimuth_separated_ism[meta_write_index] = azimuth_ism;
665 7236 : move16();
666 7236 : st_ivas->hMasaIsmData->elevation_separated_ism[meta_write_index] = elevation_ism;
667 7236 : move16();
668 : }
669 : }
670 : }
671 : }
672 :
673 6418 : return IVAS_ERR_OK;
674 : }
675 :
676 : /*--------------------------------------------------------------------------*
677 : * ivas_omasa_dirac_rend_jbm_fx()
678 : *
679 : * Rendering in OMASA format for JBM
680 : *--------------------------------------------------------------------------*/
681 :
682 2705 : void ivas_omasa_dirac_rend_jbm_fx(
683 : Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */
684 : const UWord16 nSamplesAsked, /* i : number of samples requested */
685 : UWord16 *nSamplesRendered, /* o : number of samples rendered */
686 : UWord16 *nSamplesAvailable, /* o : number of samples still to render */
687 : const Word16 nchan_transport, /* i : number of transport channels */
688 : Word32 *output_f[] /* o : rendered time signal Q11*/
689 : )
690 : {
691 : Word16 subframes_rendered;
692 : Word16 slots_rendered;
693 : Word16 n;
694 : Word32 data_separated_objects[MAX_NUM_OBJECTS][L_FRAME48k];
695 :
696 2705 : test();
697 2705 : IF( EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_32( st_ivas->ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) )
698 : {
699 1634 : Copy32( output_f[CPE_CHANNELS], data_separated_objects[0], nSamplesAsked );
700 : }
701 : ELSE
702 : {
703 3820 : FOR( n = 0; n < st_ivas->nchan_ism; n++ )
704 : {
705 2749 : Copy32( output_f[n + CPE_CHANNELS], data_separated_objects[n], nSamplesAsked );
706 : }
707 : }
708 :
709 2705 : subframes_rendered = st_ivas->hSpatParamRendCom->subframes_rendered;
710 2705 : move16();
711 2705 : slots_rendered = st_ivas->hSpatParamRendCom->slots_rendered;
712 2705 : move16();
713 :
714 2705 : ivas_dirac_dec_render_fx( st_ivas, nchan_transport, nSamplesAsked, nSamplesRendered, nSamplesAvailable, output_f );
715 :
716 13525 : FOR( Word16 ind1 = 0; ind1 < MAX_NUM_OBJECTS; ind1++ )
717 : {
718 10820 : scale_sig32( st_ivas->hIsmRendererData->prev_gains_fx[ind1], MAX_OUTPUT_CHANNELS, -1 ); // Q30 -> Q29
719 : }
720 :
721 2705 : ivas_omasa_separate_object_render_jbm_fx( st_ivas, *nSamplesRendered, data_separated_objects, output_f, subframes_rendered, slots_rendered );
722 :
723 13525 : FOR( Word16 ind1 = 0; ind1 < MAX_NUM_OBJECTS; ind1++ )
724 : {
725 10820 : scale_sig32( st_ivas->hIsmRendererData->prev_gains_fx[ind1], MAX_OUTPUT_CHANNELS, 1 ); // Q29 -> Q30
726 : }
727 :
728 2705 : return;
729 : }
730 :
731 : /*--------------------------------------------------------------------------*
732 : * ivas_omasa_dirac_td_binaural_render()
733 : *
734 : * Binaural rendering in OMASA format for JBM
735 : *--------------------------------------------------------------------------*/
736 :
737 122 : ivas_error ivas_omasa_dirac_td_binaural_jbm_fx(
738 : Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */
739 : const UWord16 nSamplesAsked, /* i : number of samples requested */
740 : UWord16 *nSamplesRendered, /* o : number of samples rendered */
741 : UWord16 *nSamplesAvailable, /* o : number of samples still to render */
742 : const Word16 nchan_transport, /* i : number of transport channels */
743 : Word32 *output_fx[] /* o : rendered time signal Q11*/
744 : )
745 : {
746 : Word16 n;
747 122 : Word16 gain_fx = OMASA_TDREND_MATCHING_GAIN_FX; // Q15
748 122 : move16();
749 : ivas_error error;
750 : Word32 *tc_local_fx[MAX_TRANSPORT_CHANNELS];
751 : Word32 *p_sepobj_fx[MAX_NUM_OBJECTS]; // Q11
752 : Word32 data_separated_objects_fx[MAX_NUM_OBJECTS][L_FRAME48k];
753 122 : move16();
754 :
755 610 : FOR( n = 0; n < MAX_NUM_OBJECTS; n++ )
756 : {
757 488 : p_sepobj_fx[n] = &data_separated_objects_fx[n][0];
758 : }
759 :
760 : /* Delay the object signals to match the CLDFB delay. Delay the whole buffer with the first rendering call of the stretched buffer. */
761 122 : IF( st_ivas->hSpatParamRendCom->slots_rendered == 0 )
762 : {
763 : Word16 tcBufferSize;
764 :
765 108 : tcBufferSize = imult1616( st_ivas->hSpatParamRendCom->num_slots, st_ivas->hSpatParamRendCom->slot_size );
766 :
767 540 : FOR( n = 0; n < st_ivas->nchan_ism; n++ )
768 : {
769 432 : tc_local_fx[n] = st_ivas->hTcBuffer->tc_fx[n + 2]; // Q11
770 432 : v_multc_fixed_16( tc_local_fx[n], gain_fx, tc_local_fx[n], tcBufferSize );
771 :
772 432 : delay_signal32_fx( tc_local_fx[n], tcBufferSize, st_ivas->hMasaIsmData->delayBuffer_fx[n], st_ivas->hMasaIsmData->delayBuffer_size );
773 : }
774 : }
775 :
776 122 : ivas_dirac_dec_binaural_render_fx( st_ivas, nSamplesAsked, nSamplesRendered, nSamplesAvailable, nchan_transport, output_fx );
777 :
778 : /* reset combined orientation access index before calling the td renderer */
779 122 : ivas_combined_orientation_set_to_start_index( st_ivas->hCombinedOrientationData );
780 :
781 122 : IF( NE_32( ( error = ivas_td_binaural_renderer_sf_fx( st_ivas, p_sepobj_fx, *nSamplesRendered ) ), IVAS_ERR_OK ) )
782 : {
783 0 : return error;
784 : }
785 :
786 366 : FOR( n = 0; n < BINAURAL_CHANNELS; n++ )
787 : {
788 244 : v_add_fx( output_fx[n], p_sepobj_fx[n], output_fx[n], *nSamplesRendered );
789 : }
790 :
791 122 : return IVAS_ERR_OK;
792 : }
793 :
794 : /*--------------------------------------------------------------------------*
795 : * ivas_omasa_rearrange_channels()
796 : *
797 : * in case of external rendering, rearrange the channels order
798 : *--------------------------------------------------------------------------*/
799 :
800 603 : void ivas_omasa_rearrange_channels_fx(
801 : Word32 *output[], /* o : output synthesis signal Q11*/
802 : const Word16 nchan_transport_ism, /* o : number of ISM TCs */
803 : const Word16 output_frame /* i : output frame length per channel */
804 : )
805 : {
806 : Word16 n;
807 : Word32 tmp_buff[CPE_CHANNELS][L_FRAME48k]; // Q11
808 :
809 603 : Copy32( output[0], tmp_buff[0], output_frame );
810 603 : Copy32( output[1], tmp_buff[1], output_frame );
811 :
812 2115 : FOR( n = 0; n < nchan_transport_ism; n++ )
813 : {
814 1512 : Copy32( output[CPE_CHANNELS + n], output[n], output_frame );
815 : }
816 603 : Copy32( tmp_buff[0], output[n], output_frame );
817 603 : Copy32( tmp_buff[1], output[add( n, 1 )], output_frame );
818 :
819 603 : return;
820 : }
|