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 <stdint.h>
34 : #include "options.h"
35 : #include "ivas_cnst.h"
36 : #include "prot.h"
37 : #include "ivas_prot.h"
38 : #include "ivas_prot_rend.h"
39 : #include "ivas_stat_com.h"
40 : #include "ivas_rom_com.h"
41 : #include "ivas_rom_dec.h"
42 : #include <math.h>
43 : #ifdef DEBUGGING
44 : #include "debug.h"
45 : #endif
46 : #include "wmc_auto.h"
47 :
48 :
49 : /*-------------------------------------------------------------------------*
50 : * ivas_ism_renderer_open()
51 : *
52 : * Open struct for object rendering, reserve memory, and init values.
53 : *-------------------------------------------------------------------------*/
54 :
55 1281 : ivas_error ivas_ism_renderer_open(
56 : Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
57 : )
58 : {
59 : int16_t i;
60 : uint16_t interpolator_length;
61 : uint16_t init_interpolator_length;
62 : ivas_error error;
63 :
64 1281 : if ( ( st_ivas->hIsmRendererData = (ISM_RENDERER_HANDLE) malloc( sizeof( ISM_RENDERER_DATA ) ) ) == NULL )
65 : {
66 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for ISM renderer\n" ) );
67 : }
68 :
69 1281 : if ( st_ivas->hIntSetup.is_loudspeaker_setup &&
70 642 : st_ivas->hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_STEREO &&
71 549 : st_ivas->hIntSetup.ls_azimuth != NULL && st_ivas->hIntSetup.ls_elevation != NULL &&
72 549 : st_ivas->hEFAPdata == NULL )
73 : {
74 549 : if ( ( error = efap_init_data( &( st_ivas->hEFAPdata ), st_ivas->hIntSetup.ls_azimuth, st_ivas->hIntSetup.ls_elevation, st_ivas->hIntSetup.nchan_out_woLFE, EFAP_MODE_EFAP ) ) != IVAS_ERR_OK )
75 : {
76 0 : return error;
77 : }
78 : }
79 :
80 6405 : for ( i = 0; i < MAX_NUM_OBJECTS; i++ )
81 : {
82 5124 : set_f( st_ivas->hIsmRendererData->prev_gains[i], 0.0f, MAX_OUTPUT_CHANNELS );
83 5124 : set_f( st_ivas->hIsmRendererData->gains[i], 0.0f, MAX_OUTPUT_CHANNELS );
84 : }
85 :
86 1281 : if ( st_ivas->hDecoderConfig->Opt_tsm )
87 : {
88 303 : init_interpolator_length = NS2SA( st_ivas->hDecoderConfig->output_Fs, MAX_JBM_CLDFB_TIMESLOTS * CLDFB_SLOT_NS );
89 303 : interpolator_length = (uint16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC );
90 : }
91 : else
92 : {
93 978 : init_interpolator_length = (uint16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC );
94 978 : interpolator_length = init_interpolator_length;
95 : }
96 :
97 1281 : if ( ( st_ivas->hIsmRendererData->interpolator = (float *) malloc( sizeof( float ) * init_interpolator_length ) ) == NULL )
98 : {
99 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for ISM renderer interpolator\n" ) );
100 : }
101 :
102 1054401 : for ( i = 0; i < interpolator_length; i++ )
103 : {
104 1053120 : st_ivas->hIsmRendererData->interpolator[i] = (float) i / ( (float) interpolator_length - 1 );
105 : }
106 :
107 1281 : return IVAS_ERR_OK;
108 : }
109 :
110 :
111 : /*-------------------------------------------------------------------------*
112 : * ivas_ism_renderer_close()
113 : *
114 : * Close struct for object rendering.
115 : *-------------------------------------------------------------------------*/
116 :
117 9813 : void ivas_ism_renderer_close(
118 : ISM_RENDERER_HANDLE *hIsmRendererData /* i/o: ISM renderer handle */
119 : )
120 : {
121 9813 : if ( hIsmRendererData == NULL || *hIsmRendererData == NULL )
122 : {
123 6993 : return;
124 : }
125 :
126 2820 : if ( ( *hIsmRendererData )->interpolator != NULL )
127 : {
128 2820 : free( ( *hIsmRendererData )->interpolator );
129 2820 : ( *hIsmRendererData )->interpolator = NULL;
130 : }
131 :
132 2820 : free( *hIsmRendererData );
133 2820 : *hIsmRendererData = NULL;
134 :
135 2820 : return;
136 : }
137 :
138 :
139 : /*-------------------------------------------------------------------------*
140 : * ivas_ism_render_sf()
141 : *
142 : * Object rendering process
143 : *-------------------------------------------------------------------------*/
144 :
145 188283 : void ivas_ism_render_sf(
146 : Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
147 : const RENDERER_TYPE renderer_type, /* i : active renderer type */
148 : float *output_f[], /* i/o: core-coder transport channels/object output */
149 : const int16_t n_samples_to_render /* i : output frame length per channel */
150 : )
151 : {
152 : int16_t i, j, k, j2;
153 : float *g1, g2, *tc;
154 : int16_t num_objects, nchan_out_woLFE, lfe_index;
155 : int16_t azimuth, elevation;
156 : int16_t tc_offset;
157 : int16_t interp_offset;
158 : float gain, prev_gain;
159 : float tc_local[MAX_NUM_OBJECTS][L_FRAME48k];
160 : float *p_tc[MAX_NUM_OBJECTS];
161 : int16_t ism_md_subframe_update_jbm, slots_to_render, first_sf, last_sf, subframe_idx;
162 : int16_t n_samples_rendered_loop;
163 :
164 : /* loop for synthesis, assume we always have to render in multiples of 5ms subframes with spills */
165 188283 : slots_to_render = min( st_ivas->hTcBuffer->num_slots - st_ivas->hTcBuffer->slots_rendered, n_samples_to_render / st_ivas->hTcBuffer->n_samples_granularity );
166 188283 : first_sf = st_ivas->hTcBuffer->subframes_rendered;
167 188283 : last_sf = first_sf;
168 188283 : n_samples_rendered_loop = 0;
169 :
170 506757 : while ( slots_to_render > 0 )
171 : {
172 318474 : slots_to_render -= st_ivas->hTcBuffer->subframe_nbslots[last_sf];
173 318474 : last_sf++;
174 : }
175 : #ifdef DEBUGGING
176 : assert( slots_to_render == 0 );
177 : assert( last_sf <= st_ivas->hTcBuffer->nb_subframes );
178 : #endif
179 188283 : num_objects = st_ivas->nchan_ism;
180 :
181 188283 : nchan_out_woLFE = st_ivas->hIntSetup.nchan_out_woLFE;
182 :
183 188283 : tc_offset = st_ivas->hTcBuffer->n_samples_rendered;
184 188283 : interp_offset = st_ivas->hTcBuffer->n_samples_rendered;
185 :
186 : /* Number of subframes to delay metadata to sync with audio */
187 188283 : if ( st_ivas->hDecoderConfig->Opt_delay_comp )
188 : {
189 188283 : ism_md_subframe_update_jbm = max( 0, st_ivas->hTcBuffer->nb_subframes - 3 );
190 : }
191 : else
192 : {
193 0 : ism_md_subframe_update_jbm = st_ivas->hTcBuffer->nb_subframes - 2;
194 : }
195 :
196 188283 : if ( st_ivas->hDecoderConfig->Opt_tsm )
197 : {
198 65928 : for ( i = 0; i < num_objects; i++ )
199 : {
200 49446 : p_tc[i] = &st_ivas->hTcBuffer->tc[i][tc_offset];
201 : }
202 : }
203 : else
204 : {
205 637847 : for ( i = 0; i < num_objects; i++ )
206 : {
207 466046 : mvr2r( &output_f[i][tc_offset], tc_local[i], n_samples_to_render );
208 466046 : p_tc[i] = tc_local[i];
209 : }
210 : }
211 :
212 1899815 : for ( i = 0; i < nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; i++ )
213 : {
214 1711532 : set_f( output_f[i], 0.0f, n_samples_to_render );
215 : }
216 :
217 506757 : for ( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ )
218 : {
219 : int16_t n_samples_in_subframe;
220 :
221 318474 : n_samples_in_subframe = st_ivas->hTcBuffer->n_samples_granularity * st_ivas->hTcBuffer->subframe_nbslots[subframe_idx];
222 :
223 318474 : if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] == 1 )
224 : {
225 35976 : ivas_jbm_dec_get_adapted_linear_interpolator( n_samples_in_subframe, n_samples_in_subframe, st_ivas->hIsmRendererData->interpolator );
226 35976 : interp_offset = 0;
227 : }
228 :
229 1189284 : for ( i = 0; i < num_objects; i++ )
230 : {
231 : /* Combined rotation: rotate the object positions depending the head and external orientations */
232 870810 : if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] == 1 )
233 : {
234 35976 : if ( subframe_idx >= ism_md_subframe_update_jbm )
235 : {
236 26982 : rotateAziEle( st_ivas->hIsmMetaData[i]->edited_azimuth, st_ivas->hIsmMetaData[i]->edited_elevation, &azimuth, &elevation, st_ivas->hCombinedOrientationData->Rmat[st_ivas->hCombinedOrientationData->subframe_idx], st_ivas->hIntSetup.is_planar_setup );
237 : }
238 : else
239 : {
240 8994 : rotateAziEle( st_ivas->hIsmMetaData[i]->edited_azimuth, st_ivas->hIsmMetaData[i]->edited_elevation, &azimuth, &elevation, st_ivas->hCombinedOrientationData->Rmat[st_ivas->hCombinedOrientationData->subframe_idx], st_ivas->hIntSetup.is_planar_setup );
241 : }
242 :
243 35976 : if ( st_ivas->hEFAPdata != NULL )
244 : {
245 35976 : efap_determine_gains( st_ivas->hEFAPdata, st_ivas->hIsmRendererData->gains[i], azimuth, elevation, EFAP_MODE_EFAP );
246 35976 : v_multc( st_ivas->hIsmRendererData->gains[i], st_ivas->hIsmMetaData[i]->edited_gain, st_ivas->hIsmRendererData->gains[i], nchan_out_woLFE );
247 : }
248 : }
249 :
250 870810 : lfe_index = 0;
251 8101977 : for ( j = 0, j2 = 0; j < nchan_out_woLFE; j++, j2++ )
252 : {
253 7231167 : if ( ( st_ivas->hIntSetup.num_lfe > 0 ) && ( st_ivas->hIntSetup.index_lfe[lfe_index] == j ) )
254 : {
255 533361 : ( lfe_index < ( st_ivas->hIntSetup.num_lfe - 1 ) ) ? ( lfe_index++, j2++ ) : j2++;
256 : }
257 :
258 7231167 : gain = st_ivas->hIsmRendererData->gains[i][j];
259 7231167 : prev_gain = st_ivas->hIsmRendererData->prev_gains[i][j];
260 7231167 : if ( fabsf( gain ) > 0.0f || fabsf( prev_gain ) > 0.0f )
261 : {
262 3653355 : g1 = &st_ivas->hIsmRendererData->interpolator[interp_offset];
263 3653355 : tc = p_tc[i];
264 796874715 : for ( k = 0; k < n_samples_in_subframe; k++ )
265 : {
266 793221360 : g2 = 1.0f - *g1;
267 793221360 : output_f[j2][k + n_samples_rendered_loop] += ( *( g1++ ) * gain + g2 * prev_gain ) * *( tc++ );
268 : }
269 : }
270 :
271 : /* update here only in case of head rotation */
272 7231167 : if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] == 1 )
273 : {
274 395736 : st_ivas->hIsmRendererData->prev_gains[i][j] = gain;
275 : }
276 : }
277 870810 : p_tc[i] += n_samples_in_subframe;
278 : }
279 :
280 : /* update combined orientation access index */
281 318474 : ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, n_samples_in_subframe );
282 :
283 318474 : n_samples_rendered_loop += n_samples_in_subframe;
284 : /* update rendered subframe and slots info for all cases apart from a following crend call, the update will
285 : then happen in the crend call*/
286 318474 : if ( renderer_type != RENDERER_BINAURAL_MIXER_CONV_ROOM )
287 : {
288 188883 : st_ivas->hTcBuffer->subframes_rendered += 1;
289 188883 : st_ivas->hTcBuffer->slots_rendered += st_ivas->hTcBuffer->subframe_nbslots[subframe_idx];
290 : }
291 318474 : tc_offset += n_samples_in_subframe;
292 318474 : interp_offset += n_samples_in_subframe;
293 : }
294 :
295 188283 : return;
296 : }
297 :
298 :
299 : /*-------------------------------------------------------------------------*
300 : * ivas_ism_get_stereo_gains()
301 : *
302 : *
303 : *-------------------------------------------------------------------------*/
304 :
305 354400 : void ivas_ism_get_stereo_gains(
306 : const float azimuth, /* i : object azimuth */
307 : const float elevation, /* i : object elevation */
308 : float *left_gain, /* o : left channel gain */
309 : float *right_gain /* o : right channel gain */
310 : )
311 : {
312 : float aziRad, eleRad;
313 : float y, mappedX, aziRadMapped, A, A2, A3;
314 354400 : const float LsAngleRad = 30.0f * PI_OVER_180;
315 :
316 : /* Convert azi and ele to an azi value of the cone of confusion */
317 354400 : aziRad = azimuth * PI_OVER_180;
318 354400 : eleRad = elevation * PI_OVER_180;
319 354400 : y = ( sinf( aziRad ) * cosf( eleRad ) );
320 354400 : mappedX = sqrtf( max( 0.0f, 1.0f - ( y * y ) ) );
321 354400 : aziRadMapped = atan2f( y, mappedX );
322 :
323 : /* Determine the amplitude panning gains */
324 354400 : if ( aziRadMapped >= LsAngleRad )
325 : { /* Left side */
326 72152 : *left_gain = 1.0f;
327 72152 : *right_gain = 0.0f;
328 : }
329 282248 : else if ( aziRadMapped <= -LsAngleRad )
330 : { /* Right side */
331 74684 : *left_gain = 0.0f;
332 74684 : *right_gain = 1.0f;
333 : }
334 : else /* Tangent panning law */
335 : {
336 207564 : A = tanf( aziRadMapped ) / tanf( LsAngleRad );
337 207564 : A2 = ( A - 1.0f ) / max( 0.001f, A + 1.0f );
338 207564 : A3 = 1.0f / ( A2 * A2 + 1.0f );
339 207564 : *left_gain = sqrtf( A3 );
340 207564 : *right_gain = sqrtf( 1.0f - A3 );
341 : }
342 :
343 354400 : return;
344 : }
345 :
346 :
347 : /*-------------------------------------------------------------------------*
348 : * ivas_omasa_separate_object_renderer_open()
349 : *
350 : * Open structures, reserve memory, and init values.
351 : *-------------------------------------------------------------------------*/
352 :
353 1485 : ivas_error ivas_omasa_separate_object_renderer_open(
354 : Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
355 : )
356 : {
357 : int16_t interpolator_length;
358 : int16_t i;
359 : int16_t init_interpolator_length;
360 :
361 1485 : if ( ( st_ivas->hIsmRendererData = (ISM_RENDERER_HANDLE) malloc( sizeof( ISM_RENDERER_DATA ) ) ) == NULL )
362 : {
363 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for MASA ISM renderer \n" ) );
364 : }
365 :
366 7425 : for ( i = 0; i < MAX_NUM_OBJECTS; i++ )
367 : {
368 5940 : set_f( st_ivas->hIsmRendererData->prev_gains[i], 0.0f, MAX_OUTPUT_CHANNELS );
369 : }
370 :
371 1485 : init_interpolator_length = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES );
372 1485 : interpolator_length = init_interpolator_length;
373 1485 : if ( ( st_ivas->hIsmRendererData->interpolator = (float *) malloc( sizeof( float ) * init_interpolator_length ) ) == NULL )
374 : {
375 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for MASA ISM renderer interpolator \n" ) );
376 : }
377 :
378 357165 : for ( i = 0; i < interpolator_length; i++ )
379 : {
380 355680 : st_ivas->hIsmRendererData->interpolator[i] = (float) i / ( (float) interpolator_length );
381 : }
382 1485 : st_ivas->hIsmRendererData->interpolator_length = interpolator_length;
383 :
384 1485 : return IVAS_ERR_OK;
385 : }
386 :
387 :
388 : /*-------------------------------------------------------------------------*
389 : * ivas_omasa_separate_object_renderer_close()
390 : *
391 : * Close structures, free memory.
392 : *-------------------------------------------------------------------------*/
393 :
394 6012 : void ivas_omasa_separate_object_renderer_close(
395 : Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
396 : )
397 : {
398 : int16_t i;
399 :
400 6012 : if ( st_ivas->hMasaIsmData != NULL )
401 : {
402 6012 : if ( st_ivas->hMasaIsmData->delayBuffer != NULL )
403 : {
404 5184 : for ( i = 0; i < st_ivas->hMasaIsmData->delayBuffer_nchan; i++ )
405 : {
406 3441 : if ( st_ivas->hMasaIsmData->delayBuffer[i] != NULL )
407 : {
408 3441 : free( st_ivas->hMasaIsmData->delayBuffer[i] );
409 3441 : st_ivas->hMasaIsmData->delayBuffer[i] = NULL;
410 : }
411 : }
412 :
413 1743 : free( st_ivas->hMasaIsmData->delayBuffer );
414 1743 : st_ivas->hMasaIsmData->delayBuffer = NULL;
415 : }
416 : }
417 :
418 6012 : ivas_ism_renderer_close( &st_ivas->hIsmRendererData );
419 :
420 6012 : return;
421 : }
422 :
423 :
424 : /*-------------------------------------------------------------------------*
425 : * ivas_omasa_separate_object_render_jbm()
426 : *
427 : * Rendering separated objects and mixing them to the parametrically rendered signals for JBM
428 : *-------------------------------------------------------------------------*/
429 :
430 18845 : void ivas_omasa_separate_object_render_jbm(
431 : Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
432 : const uint16_t nSamplesRendered, /* i : number of samples rendered */
433 : float input_f_in[][L_FRAME48k], /* i : separated object signal */
434 : float *output_f[], /* o : rendered time signal */
435 : const int16_t subframes_rendered, /* i : number of subframes rendered */
436 : const int16_t slots_rendered /* i : number of CLDFB slots rendered */
437 : )
438 : {
439 : VBAP_HANDLE hVBAPdata;
440 : DIRAC_REND_HANDLE hDirACRend;
441 : SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom;
442 : int16_t nchan_out_woLFE, num_lfe;
443 : ISM_RENDERER_HANDLE hRendererData;
444 : int16_t j, k, j2;
445 : int16_t obj;
446 : float gains[MAX_OUTPUT_CHANNELS];
447 : float g1, g2;
448 : int16_t lfe_index;
449 : int16_t azimuth, elevation;
450 : int16_t num_objects;
451 : uint8_t single_separated;
452 : float *input_f[MAX_TRANSPORT_CHANNELS];
453 : float *output_f_local[MAX_OUTPUT_CHANNELS];
454 : int16_t offsetSamples;
455 : int16_t n_samples_sf, md_idx;
456 : int16_t slots_to_render, first_sf, last_sf, subframe_idx;
457 :
458 18845 : hVBAPdata = st_ivas->hVBAPdata;
459 18845 : hDirACRend = st_ivas->hDirACRend;
460 18845 : hSpatParamRendCom = st_ivas->hSpatParamRendCom;
461 18845 : nchan_out_woLFE = st_ivas->hIntSetup.nchan_out_woLFE;
462 18845 : num_lfe = st_ivas->hIntSetup.num_lfe;
463 18845 : hRendererData = st_ivas->hIsmRendererData;
464 18845 : lfe_index = hDirACRend->hOutSetup.index_lfe[0];
465 :
466 18845 : if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ )
467 : {
468 10491 : single_separated = 1;
469 10491 : num_objects = 1;
470 : }
471 : else
472 : {
473 8354 : single_separated = 0;
474 8354 : num_objects = st_ivas->nchan_ism;
475 : }
476 :
477 18845 : offsetSamples = slots_rendered * hSpatParamRendCom->slot_size;
478 :
479 191755 : for ( j = 0; j < nchan_out_woLFE + num_lfe; j++ )
480 : {
481 172910 : output_f_local[j] = output_f[j];
482 : }
483 :
484 18845 : if ( st_ivas->hDecoderConfig->Opt_tsm )
485 : {
486 17629 : for ( obj = 0; obj < num_objects; obj++ )
487 : {
488 11370 : input_f[obj] = &st_ivas->hTcBuffer->tc[obj + 2][offsetSamples];
489 : }
490 : }
491 : else
492 : {
493 31990 : for ( obj = 0; obj < num_objects; obj++ )
494 : {
495 19404 : input_f[obj] = input_f_in[obj];
496 : }
497 : }
498 :
499 18845 : slots_to_render = nSamplesRendered / hSpatParamRendCom->slot_size;
500 18845 : first_sf = subframes_rendered;
501 18845 : last_sf = first_sf;
502 :
503 49949 : while ( slots_to_render > 0 )
504 : {
505 31104 : slots_to_render -= hSpatParamRendCom->subframe_nbslots[last_sf];
506 31104 : last_sf++;
507 : }
508 :
509 49619 : for ( obj = 0; obj < num_objects; obj++ )
510 : {
511 30774 : offsetSamples = 0;
512 :
513 81369 : for ( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ )
514 : {
515 50595 : n_samples_sf = hSpatParamRendCom->subframe_nbslots[subframe_idx] * hSpatParamRendCom->slot_size;
516 50595 : if ( n_samples_sf != hRendererData->interpolator_length )
517 : {
518 743036 : for ( k = 0; k < n_samples_sf; k++ )
519 : {
520 738720 : hRendererData->interpolator[k] = (float) k / ( (float) n_samples_sf );
521 : }
522 4316 : hRendererData->interpolator_length = n_samples_sf;
523 : }
524 :
525 50595 : md_idx = hSpatParamRendCom->render_to_md_map[subframe_idx];
526 :
527 50595 : if ( single_separated )
528 : {
529 17325 : if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ && st_ivas->hMasaIsmData->ism_dir_is_edited[st_ivas->hMasaIsmData->idx_separated_ism] )
530 : {
531 0 : azimuth = st_ivas->hMasaIsmData->azimuth_ism_edited[st_ivas->hMasaIsmData->idx_separated_ism];
532 0 : elevation = st_ivas->hMasaIsmData->elevation_ism_edited[st_ivas->hMasaIsmData->idx_separated_ism];
533 : }
534 : else
535 : {
536 17325 : azimuth = st_ivas->hMasaIsmData->azimuth_separated_ism[md_idx];
537 17325 : elevation = st_ivas->hMasaIsmData->elevation_separated_ism[md_idx];
538 : }
539 : }
540 : else
541 : {
542 33270 : if ( st_ivas->hMasaIsmData->ism_dir_is_edited[obj] )
543 : {
544 4200 : azimuth = st_ivas->hMasaIsmData->azimuth_ism_edited[obj];
545 4200 : elevation = st_ivas->hMasaIsmData->elevation_ism_edited[obj];
546 : }
547 : else
548 : {
549 29070 : azimuth = st_ivas->hMasaIsmData->azimuth_ism[obj][md_idx];
550 29070 : elevation = st_ivas->hMasaIsmData->elevation_ism[obj][md_idx];
551 : }
552 : }
553 :
554 50595 : if ( st_ivas->hOutSetup.is_planar_setup )
555 : {
556 : /* If no elevation support in output format, then rendering should be done with zero elevation */
557 2175 : elevation = 0;
558 : }
559 :
560 50595 : if ( hVBAPdata != NULL )
561 : {
562 18477 : vbap_determine_gains( hVBAPdata, gains, azimuth, elevation, 1 );
563 : }
564 : else
565 : {
566 32118 : ivas_dirac_dec_get_response( azimuth, elevation, gains, hDirACRend->hOutSetup.ambisonics_order );
567 : }
568 :
569 538494 : for ( j = 0; j < nchan_out_woLFE; j++ )
570 : {
571 487899 : if ( hDirACRend->hOutSetup.num_lfe > 0 )
572 : {
573 156315 : j2 = j + ( j >= lfe_index );
574 : }
575 : else
576 : {
577 331584 : j2 = j;
578 : }
579 :
580 487899 : if ( fabsf( gains[j] ) > 0.0f || fabsf( hRendererData->prev_gains[obj][j] ) > 0.0f )
581 : {
582 74929161 : for ( k = 0; k < n_samples_sf; k++ )
583 : {
584 74551980 : g1 = hRendererData->interpolator[k];
585 74551980 : g2 = 1.0f - g1;
586 74551980 : output_f_local[j2][k + offsetSamples] += ( g1 * gains[j] + g2 * hRendererData->prev_gains[obj][j] ) * input_f[obj][k + offsetSamples];
587 : }
588 : }
589 487899 : hRendererData->prev_gains[obj][j] = gains[j];
590 : }
591 :
592 50595 : offsetSamples += n_samples_sf;
593 : }
594 : }
595 :
596 18845 : return;
597 : }
|