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 <math.h>
36 : #include "prot.h"
37 : #include "ivas_prot.h"
38 : #include "ivas_prot_rend.h"
39 : #include "cnst.h"
40 : #include "ivas_cnst.h"
41 : #include "ivas_rom_rend.h"
42 : #include "ivas_rom_dec.h"
43 : #include "ivas_rom_com.h"
44 : #include "ivas_rom_binauralRenderer.h"
45 : #ifdef DEBUGGING
46 : #include "debug.h"
47 : #endif
48 : #include "wmc_auto.h"
49 :
50 :
51 : /*-------------------------------------------------------------------------
52 : * Local constants
53 : *------------------------------------------------------------------------*/
54 :
55 : #define REVERB_INPUT_DOWNMIX_CHANNELS ( 11 )
56 : /* Downmix table for sparse frequency domain reverberator */
57 : const float dmxmtx_table[BINAURAL_CHANNELS][REVERB_INPUT_DOWNMIX_CHANNELS] = {
58 : { 1.0f, 0.0f, 0.70709997f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f },
59 : { 0.0f, 1.0f, 0.70709997f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f },
60 : };
61 :
62 : /*-------------------------------------------------------------------------
63 : * ivas_binRenderer_filterModule()
64 : *
65 : *
66 : *-------------------------------------------------------------------------*/
67 :
68 483522 : static void ivas_binRenderer_filterModule(
69 : float out_Conv_CLDFB_real[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : real part of Binaural signals */
70 : float out_Conv_CLDFB_imag[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : imag part of Binaural signals */
71 : float CLDFB_real[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : real part of LS signals */
72 : float CLDFB_imag[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : imag part of LS signals */
73 : const int16_t numTimeSlots, /* i : number of time slots to process */
74 : BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: fastconv binaural renderer handle */
75 : const int16_t pos_idx /* i : pose index */
76 : )
77 : {
78 : int16_t bandIdx, k, chIdx, tapIdx;
79 : float *filterStatesLeftRealPtr, *filterStatesLeftImagPtr;
80 : const float *filterTapsLeftRealPtr, *filterTapsLeftImagPtr, *filterTapsRightRealPtr, *filterTapsRightImagPtr;
81 :
82 22561812 : for ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
83 : {
84 317447130 : for ( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ )
85 : {
86 295368840 : filterStatesLeftRealPtr = (float *) &( hBinRenderer->hBinRenConvModule->filterStatesLeftReal[pos_idx][bandIdx][chIdx][0] );
87 295368840 : filterStatesLeftImagPtr = (float *) &( hBinRenderer->hBinRenConvModule->filterStatesLeftImag[pos_idx][bandIdx][chIdx][0] );
88 :
89 295368840 : filterTapsLeftRealPtr = hBinRenderer->hBinRenConvModule->filterTapsLeftReal[bandIdx][chIdx];
90 295368840 : filterTapsLeftImagPtr = hBinRenderer->hBinRenConvModule->filterTapsLeftImag[bandIdx][chIdx];
91 295368840 : filterTapsRightRealPtr = hBinRenderer->hBinRenConvModule->filterTapsRightReal[bandIdx][chIdx];
92 295368840 : filterTapsRightImagPtr = hBinRenderer->hBinRenConvModule->filterTapsRightImag[bandIdx][chIdx];
93 :
94 1475459880 : for ( k = 0; k < numTimeSlots; k++ )
95 : {
96 1180091040 : float outRealLeft = 0.0f, outRealRight = 0.0f, outImagLeft = 0.0f, outImagRight = 0.0f;
97 :
98 14682327360 : for ( tapIdx = hBinRenderer->hBinRenConvModule->numTapsArray[bandIdx] - 1; tapIdx > 0; tapIdx-- )
99 : {
100 13502236320 : filterStatesLeftRealPtr[tapIdx] = filterStatesLeftRealPtr[tapIdx - 1];
101 13502236320 : filterStatesLeftImagPtr[tapIdx] = filterStatesLeftImagPtr[tapIdx - 1];
102 :
103 : /* Left Real and Imag */
104 13502236320 : outRealLeft += ( filterStatesLeftRealPtr[tapIdx] * filterTapsLeftRealPtr[tapIdx] ) - ( filterStatesLeftImagPtr[tapIdx] * filterTapsLeftImagPtr[tapIdx] );
105 13502236320 : outImagLeft += ( filterStatesLeftRealPtr[tapIdx] * filterTapsLeftImagPtr[tapIdx] ) + ( filterStatesLeftImagPtr[tapIdx] * filterTapsLeftRealPtr[tapIdx] );
106 :
107 : /* Right Real and Imag*/
108 13502236320 : outRealRight += ( filterStatesLeftRealPtr[tapIdx] * filterTapsRightRealPtr[tapIdx] ) - ( filterStatesLeftImagPtr[tapIdx] * filterTapsRightImagPtr[tapIdx] );
109 13502236320 : outImagRight += ( filterStatesLeftRealPtr[tapIdx] * filterTapsRightImagPtr[tapIdx] ) + ( filterStatesLeftImagPtr[tapIdx] * filterTapsRightRealPtr[tapIdx] );
110 : }
111 :
112 1180091040 : filterStatesLeftRealPtr[0] = CLDFB_real[chIdx][k][bandIdx];
113 1180091040 : filterStatesLeftImagPtr[0] = CLDFB_imag[chIdx][k][bandIdx];
114 :
115 :
116 : /* Left Real and Imag */
117 1180091040 : out_Conv_CLDFB_real[0][k][bandIdx] += outRealLeft + ( filterStatesLeftRealPtr[0] * filterTapsLeftRealPtr[0] ) - ( filterStatesLeftImagPtr[0] * filterTapsLeftImagPtr[0] );
118 1180091040 : out_Conv_CLDFB_imag[0][k][bandIdx] += outImagLeft + ( filterStatesLeftRealPtr[0] * filterTapsLeftImagPtr[0] ) + ( filterStatesLeftImagPtr[0] * filterTapsLeftRealPtr[0] );
119 :
120 : /* Right Real and Imag */
121 1180091040 : out_Conv_CLDFB_real[1][k][bandIdx] += outRealRight + ( filterStatesLeftRealPtr[0] * filterTapsRightRealPtr[0] ) - ( filterStatesLeftImagPtr[0] * filterTapsRightImagPtr[0] );
122 1180091040 : out_Conv_CLDFB_imag[1][k][bandIdx] += outImagRight + ( filterStatesLeftRealPtr[0] * filterTapsRightImagPtr[0] ) + ( filterStatesLeftImagPtr[0] * filterTapsRightRealPtr[0] );
123 : }
124 : }
125 : }
126 :
127 483522 : return;
128 : }
129 :
130 :
131 : /*-------------------------------------------------------------------------
132 : * ivas_binRenderer_convModuleOpen()
133 : *
134 : * Open convolution module handle of fastconv binaural renderer
135 : *-------------------------------------------------------------------------*/
136 :
137 1065 : static ivas_error ivas_binRenderer_convModuleOpen(
138 : BINAURAL_RENDERER_HANDLE hBinRenderer,
139 : const int16_t renderer_type,
140 : const int16_t isLoudspeaker,
141 : const AUDIO_CONFIG input_config,
142 : const HRTFS_FASTCONV_HANDLE hHrtf,
143 : const int16_t num_poses )
144 : {
145 : int16_t bandIdx, chIdx;
146 : BINRENDERER_CONV_MODULE_HANDLE hBinRenConvModule;
147 : int16_t pos_idx;
148 :
149 : /*-----------------------------------------------------------------*
150 : * prepare library opening
151 : *-----------------------------------------------------------------*/
152 :
153 1065 : if ( ( hBinRenConvModule = (BINRENDERER_CONV_MODULE_HANDLE) malloc( sizeof( BINRENDERER_CONV_MODULE ) ) ) == NULL )
154 : {
155 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
156 : }
157 :
158 1065 : if ( !isLoudspeaker )
159 : {
160 606 : hBinRenderer->nInChannels = audioCfg2channels( input_config );
161 : }
162 : else
163 : {
164 : /* Note: needs to be revisited if multiple LFE support is required */
165 459 : hBinRenderer->nInChannels = ( audioCfg2channels( input_config ) - isLoudspeaker );
166 : }
167 :
168 1065 : hBinRenConvModule->numTaps = hHrtf->ntaps;
169 :
170 1065 : if ( renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM )
171 : {
172 : /* Use variable order filtering */
173 207 : bandIdx = 0;
174 1242 : for ( ; bandIdx < 5; bandIdx++ )
175 : {
176 1035 : hBinRenConvModule->numTapsArray[bandIdx] = hBinRenConvModule->numTaps;
177 : }
178 1242 : for ( ; bandIdx < 10; bandIdx++ )
179 : {
180 1035 : hBinRenConvModule->numTapsArray[bandIdx] = (int16_t) ceilf( 0.6f * hBinRenConvModule->numTaps );
181 : }
182 2277 : for ( ; bandIdx < 20; bandIdx++ )
183 : {
184 2070 : hBinRenConvModule->numTapsArray[bandIdx] = (int16_t) ceilf( 0.5f * hBinRenConvModule->numTaps );
185 : }
186 2277 : for ( ; bandIdx < 30; bandIdx++ )
187 : {
188 2070 : hBinRenConvModule->numTapsArray[bandIdx] = (int16_t) ceilf( 0.4f * hBinRenConvModule->numTaps );
189 : }
190 3957 : for ( ; bandIdx < hBinRenderer->conv_band; bandIdx++ )
191 : {
192 3750 : hBinRenConvModule->numTapsArray[bandIdx] = (int16_t) ceilf( 0.3f * hBinRenConvModule->numTaps );
193 : }
194 : }
195 : else
196 : {
197 : /* Use fixed order filtering */
198 858 : bandIdx = 0;
199 35238 : for ( ; bandIdx < hBinRenderer->conv_band; bandIdx++ )
200 : {
201 34380 : hBinRenConvModule->numTapsArray[bandIdx] = hBinRenConvModule->numTaps;
202 : }
203 : }
204 :
205 : /* allocate memory for filter states */
206 1065 : if ( ( hBinRenConvModule->filterTapsLeftReal = (float ***) malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL )
207 : {
208 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
209 : }
210 :
211 1065 : if ( ( hBinRenConvModule->filterTapsLeftImag = (float ***) malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL )
212 : {
213 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
214 : }
215 :
216 1065 : if ( ( hBinRenConvModule->filterTapsRightReal = (float ***) malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL )
217 : {
218 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
219 : }
220 :
221 1065 : if ( ( hBinRenConvModule->filterTapsRightImag = (float ***) malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL )
222 : {
223 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
224 : }
225 :
226 45315 : for ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
227 : {
228 44250 : if ( ( hBinRenConvModule->filterTapsLeftReal[bandIdx] = (float **) malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL )
229 : {
230 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
231 : }
232 :
233 44250 : if ( ( hBinRenConvModule->filterTapsLeftImag[bandIdx] = (float **) malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL )
234 : {
235 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
236 : }
237 :
238 44250 : if ( ( hBinRenConvModule->filterTapsRightReal[bandIdx] = (float **) malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL )
239 : {
240 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
241 : }
242 :
243 44250 : if ( ( hBinRenConvModule->filterTapsRightImag[bandIdx] = (float **) malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL )
244 : {
245 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
246 : }
247 : }
248 :
249 1065 : if ( ( hBinRenConvModule->filterStatesLeftReal = (float ****) malloc( num_poses * sizeof( float *** ) ) ) == NULL )
250 : {
251 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
252 : }
253 :
254 1065 : if ( ( hBinRenConvModule->filterStatesLeftImag = (float ****) malloc( num_poses * sizeof( float *** ) ) ) == NULL )
255 : {
256 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
257 : }
258 :
259 2130 : for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ )
260 : {
261 1065 : if ( ( hBinRenConvModule->filterStatesLeftReal[pos_idx] = (float ***) malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL )
262 : {
263 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
264 : }
265 :
266 1065 : if ( ( hBinRenConvModule->filterStatesLeftImag[pos_idx] = (float ***) malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL )
267 : {
268 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
269 : }
270 :
271 45315 : for ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
272 : {
273 44250 : if ( ( hBinRenConvModule->filterStatesLeftReal[pos_idx][bandIdx] = (float **) malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL )
274 : {
275 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
276 : }
277 :
278 44250 : if ( ( hBinRenConvModule->filterStatesLeftImag[pos_idx][bandIdx] = (float **) malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL )
279 : {
280 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
281 : }
282 :
283 572940 : for ( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ )
284 : {
285 528690 : if ( ( hBinRenConvModule->filterStatesLeftReal[pos_idx][bandIdx][chIdx] = (float *) malloc( hBinRenConvModule->numTapsArray[bandIdx] * sizeof( float ) ) ) == NULL )
286 : {
287 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
288 : }
289 :
290 528690 : if ( ( hBinRenConvModule->filterStatesLeftImag[pos_idx][bandIdx][chIdx] = (float *) malloc( hBinRenConvModule->numTapsArray[bandIdx] * sizeof( float ) ) ) == NULL )
291 : {
292 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
293 : }
294 : }
295 : }
296 : }
297 :
298 : /* set memories */
299 45315 : for ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
300 : {
301 572940 : for ( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ )
302 : {
303 528690 : int16_t tmp = 0;
304 :
305 528690 : tmp = chIdx;
306 528690 : if ( isLoudspeaker )
307 : {
308 102450 : if ( input_config == IVAS_AUDIO_CONFIG_5_1 )
309 : {
310 75450 : tmp = channelIndex_CICP6[chIdx];
311 : }
312 27000 : else if ( input_config == IVAS_AUDIO_CONFIG_7_1 )
313 : {
314 0 : tmp = channelIndex_CICP12[chIdx];
315 : }
316 27000 : else if ( input_config == IVAS_AUDIO_CONFIG_5_1_2 )
317 : {
318 1260 : tmp = channelIndex_CICP14[chIdx];
319 : }
320 25740 : else if ( input_config == IVAS_AUDIO_CONFIG_5_1_4 )
321 : {
322 0 : tmp = channelIndex_CICP16[chIdx];
323 : }
324 25740 : else if ( input_config == IVAS_AUDIO_CONFIG_7_1_4 )
325 : {
326 25740 : tmp = channelIndex_CICP19[chIdx];
327 : }
328 : #ifdef DEBUGGING
329 : else
330 : {
331 : return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error: Channel configuration not specified!\n\n" );
332 : }
333 : #endif
334 : }
335 :
336 528690 : hBinRenConvModule->filterTapsLeftReal[bandIdx][chIdx] = hHrtf->leftReal[bandIdx][tmp];
337 528690 : hBinRenConvModule->filterTapsLeftImag[bandIdx][chIdx] = hHrtf->leftImag[bandIdx][tmp];
338 528690 : hBinRenConvModule->filterTapsRightReal[bandIdx][chIdx] = hHrtf->rightReal[bandIdx][tmp];
339 528690 : hBinRenConvModule->filterTapsRightImag[bandIdx][chIdx] = hHrtf->rightImag[bandIdx][tmp];
340 : }
341 : }
342 :
343 2130 : for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ )
344 : {
345 45315 : for ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
346 : {
347 572940 : for ( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ )
348 : {
349 : /* set the memories to zero */
350 528690 : set_zero( hBinRenConvModule->filterStatesLeftReal[pos_idx][bandIdx][chIdx], hBinRenConvModule->numTapsArray[bandIdx] );
351 528690 : set_zero( hBinRenConvModule->filterStatesLeftImag[pos_idx][bandIdx][chIdx], hBinRenConvModule->numTapsArray[bandIdx] );
352 : }
353 : }
354 : }
355 :
356 1065 : hBinRenderer->hBinRenConvModule = hBinRenConvModule;
357 :
358 1065 : return IVAS_ERR_OK;
359 : }
360 :
361 :
362 : /*-------------------------------------------------------------------------*
363 : * ivas_init_binaural_hrtf()
364 : *
365 : * initialize memory for HrtfFastConv structure elements
366 : *-------------------------------------------------------------------------*/
367 :
368 342 : void ivas_init_binaural_hrtf(
369 : HRTFS_FASTCONV *HrtfFastConv /* i/o: FASTCONV HRTF structure */
370 : )
371 : {
372 : int16_t i;
373 :
374 342 : HrtfFastConv->leftReal = NULL;
375 342 : HrtfFastConv->leftImag = NULL;
376 342 : HrtfFastConv->rightReal = NULL;
377 342 : HrtfFastConv->rightImag = NULL;
378 342 : HrtfFastConv->FASTCONV_latency_s = 0x00;
379 :
380 342 : HrtfFastConv->n_channels = 0;
381 342 : HrtfFastConv->allocate_init_flag = 0x00;
382 342 : HrtfFastConv->ntaps = 0;
383 :
384 20862 : for ( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ )
385 : {
386 20520 : HrtfFastConv->fastconvReverberationEneCorrections[i] = 0x00;
387 20520 : HrtfFastConv->fastconvReverberationEneCorrections[i] = 0x00;
388 : }
389 :
390 342 : return;
391 : }
392 :
393 :
394 : /*-------------------------------------------------------------------------*
395 : * ivas_alloc_pppMem()
396 : *
397 : * Allocate memory for tripple pointer elements
398 : *-------------------------------------------------------------------------*/
399 :
400 1368 : static ivas_error ivas_alloc_pppMem(
401 : float ****pppMem,
402 : const int16_t dim1,
403 : const int16_t dim2,
404 : const int16_t dim3,
405 : const int16_t allocate_init_flag )
406 : {
407 : int16_t i, j;
408 1368 : float ***localMem = NULL;
409 :
410 1368 : if ( ( localMem = (float ***) malloc( dim1 * sizeof( float ** ) ) ) == NULL )
411 : {
412 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HRTF memory" );
413 : }
414 :
415 69768 : for ( i = 0; i < dim1; i++ )
416 : {
417 68400 : if ( ( localMem[i] = (float **) malloc( dim2 * sizeof( float * ) ) ) == NULL )
418 : {
419 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HRTF memory" );
420 : }
421 68400 : if ( allocate_init_flag == 0 )
422 : {
423 689400 : for ( j = 0; j < dim2; j++ )
424 : {
425 648600 : if ( ( localMem[i][j] = (float *) malloc( dim3 * sizeof( float ) ) ) == NULL )
426 : {
427 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HRTF memory" );
428 : }
429 : }
430 : }
431 : }
432 :
433 1368 : *pppMem = localMem;
434 :
435 1368 : return IVAS_ERR_OK;
436 : }
437 :
438 :
439 : /*-------------------------------------------------------------------------*
440 : * ivas_allocate_binaural_hrtf()
441 : *
442 : * Allocate memory for HrtfFastConv structure elements
443 : *-------------------------------------------------------------------------*/
444 :
445 357 : ivas_error ivas_allocate_binaural_hrtf(
446 : HRTFS_FASTCONV *HrtfFastConv, /* i/o: FASTCONV HRTF structure */
447 : const int16_t n_channels, /* i : number of input channels */
448 : const int16_t allocate_init_flag /* i : Memory allocation flag */
449 : )
450 : {
451 357 : HrtfFastConv->n_channels = n_channels;
452 :
453 357 : if ( ( HrtfFastConv->leftReal != NULL ) && ( HrtfFastConv->leftImag != NULL ) && ( HrtfFastConv->rightReal != NULL ) && ( HrtfFastConv->rightImag != NULL ) )
454 : {
455 15 : return IVAS_ERR_OK;
456 : }
457 : else
458 : {
459 342 : if ( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->leftReal, BINAURAL_CONVBANDS, n_channels, HrtfFastConv->ntaps, allocate_init_flag ) )
460 : {
461 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HrtfFastConv->leftReal" );
462 : }
463 342 : if ( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->leftImag, BINAURAL_CONVBANDS, n_channels, HrtfFastConv->ntaps, allocate_init_flag ) )
464 : {
465 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HrtfFastConv->leftImag" );
466 : }
467 342 : if ( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->rightReal, BINAURAL_CONVBANDS, n_channels, HrtfFastConv->ntaps, allocate_init_flag ) )
468 : {
469 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HrtfFastConv->rightReal" );
470 : }
471 342 : if ( IVAS_ERR_OK != ivas_alloc_pppMem( &HrtfFastConv->rightImag, BINAURAL_CONVBANDS, n_channels, HrtfFastConv->ntaps, allocate_init_flag ) )
472 : {
473 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HrtfFastConv->rightImag" );
474 : }
475 : }
476 :
477 342 : return IVAS_ERR_OK;
478 : }
479 :
480 :
481 : /*-------------------------------------------------------------------------*
482 : * ivas_binaural_hrtf_open()
483 : *
484 : *
485 : *-------------------------------------------------------------------------*/
486 :
487 1065 : static ivas_error ivas_binaural_hrtf_open(
488 : HRTFS_FASTCONV_HANDLE *hHrtfFastConv, /* i : fastconv HRTF handle */
489 : const AUDIO_CONFIG input_config, /* i : output configuration */
490 : const RENDERER_TYPE renderer_type /* i : renderer type */
491 : )
492 : {
493 : int16_t i, j;
494 : ivas_error error;
495 : int16_t n_channels;
496 :
497 1065 : if ( hHrtfFastConv != NULL && *hHrtfFastConv != NULL )
498 : {
499 : /* Tables already loaded from file */
500 927 : return IVAS_ERR_OK;
501 : }
502 : else
503 : {
504 : /* Initialise tables from ROM */
505 : HRTFS_FASTCONV *HrtfFastConv;
506 :
507 138 : if ( ( HrtfFastConv = (HRTFS_FASTCONV *) malloc( sizeof( HRTFS_FASTCONV ) ) ) == NULL )
508 : {
509 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate memory for FastConv HRTF tables" );
510 : }
511 :
512 138 : ivas_init_binaural_hrtf( HrtfFastConv );
513 :
514 138 : if ( input_config == IVAS_AUDIO_CONFIG_BINAURAL || renderer_type == RENDERER_BINAURAL_FASTCONV )
515 : {
516 99 : HrtfFastConv->FASTCONV_latency_s = FASTCONV_HRIR_latency_s;
517 99 : HrtfFastConv->ntaps = BINAURAL_NTAPS;
518 : }
519 138 : if ( input_config == IVAS_AUDIO_CONFIG_HOA2 )
520 : {
521 0 : HrtfFastConv->FASTCONV_latency_s = FASTCONV_HOA2_latency_s;
522 0 : HrtfFastConv->ntaps = BINAURAL_NTAPS_SBA;
523 : }
524 138 : if ( input_config == IVAS_AUDIO_CONFIG_HOA3 )
525 : {
526 105 : HrtfFastConv->FASTCONV_latency_s = FASTCONV_HOA3_latency_s;
527 105 : HrtfFastConv->ntaps = BINAURAL_NTAPS_SBA;
528 : }
529 138 : if ( input_config == IVAS_AUDIO_CONFIG_FOA )
530 : {
531 0 : HrtfFastConv->FASTCONV_latency_s = FASTCONV_FOA_latency_s;
532 0 : HrtfFastConv->ntaps = BINAURAL_NTAPS_SBA;
533 : }
534 138 : if ( input_config == IVAS_AUDIO_CONFIG_BINAURAL || renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM )
535 : {
536 39 : HrtfFastConv->FASTCONV_latency_s = FASTCONV_BRIR_latency_s;
537 39 : HrtfFastConv->ntaps = BINAURAL_NTAPS_MAX;
538 : }
539 :
540 138 : HrtfFastConv->allocate_init_flag = 1;
541 :
542 138 : n_channels = 0;
543 138 : if ( ( renderer_type == RENDERER_BINAURAL_FASTCONV || renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) && input_config != IVAS_AUDIO_CONFIG_INVALID )
544 : {
545 138 : n_channels = HRTF_LS_CHANNELS;
546 : }
547 :
548 138 : if ( renderer_type == RENDERER_BINAURAL_FASTCONV )
549 : {
550 99 : if ( input_config == IVAS_AUDIO_CONFIG_HOA3 )
551 : {
552 84 : n_channels = HOA3_CHANNELS;
553 : }
554 15 : else if ( input_config == IVAS_AUDIO_CONFIG_HOA2 )
555 : {
556 0 : n_channels = HOA2_CHANNELS;
557 : }
558 15 : else if ( input_config == IVAS_AUDIO_CONFIG_FOA )
559 : {
560 0 : n_channels = FOA_CHANNELS;
561 : }
562 : }
563 :
564 138 : if ( ( error = ivas_allocate_binaural_hrtf( HrtfFastConv, n_channels, HrtfFastConv->allocate_init_flag ) ) != IVAS_ERR_OK )
565 : {
566 0 : return error;
567 : }
568 :
569 7038 : for ( i = 0; i < BINAURAL_CONVBANDS; i++ )
570 : {
571 6900 : if ( renderer_type == RENDERER_BINAURAL_FASTCONV && HrtfFastConv->n_channels == HRTF_LS_CHANNELS )
572 : {
573 12000 : for ( j = 0; j < HRTF_LS_CHANNELS; j++ )
574 : {
575 11250 : HrtfFastConv->leftReal[i][j] = leftHRIRReal[i][j];
576 11250 : HrtfFastConv->leftImag[i][j] = leftHRIRImag[i][j];
577 11250 : HrtfFastConv->rightReal[i][j] = rightHRIRReal[i][j];
578 11250 : HrtfFastConv->rightImag[i][j] = rightHRIRImag[i][j];
579 : }
580 : }
581 6150 : else if ( renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM && HrtfFastConv->n_channels == HRTF_LS_CHANNELS )
582 : {
583 31200 : for ( j = 0; j < HRTF_LS_CHANNELS; j++ )
584 : {
585 29250 : HrtfFastConv->leftReal[i][j] = leftBRIRReal[i][j];
586 29250 : HrtfFastConv->leftImag[i][j] = leftBRIRImag[i][j];
587 29250 : HrtfFastConv->rightReal[i][j] = rightBRIRReal[i][j];
588 29250 : HrtfFastConv->rightImag[i][j] = rightBRIRImag[i][j];
589 : }
590 : }
591 :
592 6900 : if ( input_config == IVAS_AUDIO_CONFIG_HOA3 && HrtfFastConv->n_channels == HOA3_CHANNELS )
593 : {
594 71400 : for ( j = 0; j < HOA3_CHANNELS; j++ )
595 : {
596 67200 : HrtfFastConv->leftReal[i][j] = leftHRIRReal_HOA3[i][j];
597 67200 : HrtfFastConv->leftImag[i][j] = leftHRIRImag_HOA3[i][j];
598 67200 : HrtfFastConv->rightReal[i][j] = rightHRIRReal_HOA3[i][j];
599 67200 : HrtfFastConv->rightImag[i][j] = rightHRIRImag_HOA3[i][j];
600 : }
601 : }
602 :
603 : /* Note: IVAS_AUDIO_CONFIG_HOA2 and IVAS_AUDIO_CONFIG_FOA input configs. are not relevant in internal renderer
604 : as SBA to binaural always synthesizes HOA3 output for binauralization. However, the external renderer can use them. */
605 6900 : if ( input_config == IVAS_AUDIO_CONFIG_HOA2 && HrtfFastConv->n_channels == HOA2_CHANNELS )
606 : {
607 0 : for ( j = 0; j < HOA2_CHANNELS; j++ )
608 : {
609 0 : HrtfFastConv->leftReal[i][j] = leftHRIRReal_HOA2[i][j];
610 0 : HrtfFastConv->leftImag[i][j] = leftHRIRImag_HOA2[i][j];
611 0 : HrtfFastConv->rightReal[i][j] = rightHRIRReal_HOA2[i][j];
612 0 : HrtfFastConv->rightImag[i][j] = rightHRIRImag_HOA2[i][j];
613 : }
614 : }
615 :
616 6900 : if ( input_config == IVAS_AUDIO_CONFIG_FOA && HrtfFastConv->n_channels == FOA_CHANNELS )
617 : {
618 0 : for ( j = 0; j < FOA_CHANNELS; j++ )
619 : {
620 0 : HrtfFastConv->leftReal[i][j] = leftHRIRReal_FOA[i][j];
621 0 : HrtfFastConv->leftImag[i][j] = leftHRIRImag_FOA[i][j];
622 0 : HrtfFastConv->rightReal[i][j] = rightHRIRReal_FOA[i][j];
623 0 : HrtfFastConv->rightImag[i][j] = rightHRIRImag_FOA[i][j];
624 : }
625 : }
626 : }
627 :
628 138 : mvr2r( fastconvReverberationTimes, HrtfFastConv->fastconvReverberationTimes, CLDFB_NO_CHANNELS_MAX );
629 138 : mvr2r( fastconvReverberationEneCorrections, HrtfFastConv->fastconvReverberationEneCorrections, CLDFB_NO_CHANNELS_MAX );
630 :
631 138 : *hHrtfFastConv = HrtfFastConv;
632 :
633 138 : return IVAS_ERR_OK;
634 : }
635 : }
636 :
637 :
638 : /*-------------------------------------------------------------------------*
639 : * ivas_binaural_obtain_DMX()
640 : *
641 : *
642 : *-------------------------------------------------------------------------*/
643 :
644 302550 : static void ivas_binaural_obtain_DMX(
645 : const int16_t numTimeSlots,
646 : BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: fastconv binaural renderer handle */
647 : float RealBuffer[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : Contains the LS signals */
648 : float ImagBuffer[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : Contains the LS signals */
649 : float realDMX[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX],
650 : float imagDMX[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] )
651 : {
652 : int16_t chIdx, bandIdx, k;
653 :
654 302550 : if ( hBinRenderer->ivas_format == MC_FORMAT )
655 : {
656 : /* Obtain the downmix */
657 : float P_in[CLDFB_NO_CHANNELS_MAX];
658 : float P_out, factEQ;
659 : int16_t chOutIdx;
660 : float temp1, temp2;
661 :
662 411600 : for ( k = 0; k < numTimeSlots; k++ )
663 : {
664 987840 : for ( chOutIdx = 0; chOutIdx < BINAURAL_CHANNELS; chOutIdx++ )
665 : {
666 658560 : set_zero( realDMX[chOutIdx][k], CLDFB_NO_CHANNELS_MAX );
667 658560 : set_zero( imagDMX[chOutIdx][k], CLDFB_NO_CHANNELS_MAX );
668 : }
669 : }
670 :
671 246960 : for ( chOutIdx = 0; chOutIdx < BINAURAL_CHANNELS; chOutIdx++ )
672 : {
673 164640 : set_zero( P_in, hBinRenderer->conv_band );
674 :
675 1442880 : for ( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ )
676 : {
677 1278240 : float dmxConst = dmxmtx_table[chOutIdx][chIdx];
678 :
679 61175040 : for ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
680 : {
681 299484000 : for ( k = 0; k < numTimeSlots; k++ )
682 : {
683 239587200 : temp1 = RealBuffer[chIdx][k][bandIdx] * dmxConst;
684 239587200 : temp2 = ImagBuffer[chIdx][k][bandIdx] * dmxConst;
685 239587200 : realDMX[chOutIdx][k][bandIdx] += temp1;
686 239587200 : imagDMX[chOutIdx][k][bandIdx] += temp2;
687 :
688 239587200 : P_in[bandIdx] += temp1 * temp1 + temp2 * temp2;
689 : }
690 : }
691 : }
692 :
693 7890240 : for ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
694 : {
695 7725600 : P_out = 0.f;
696 38628000 : for ( k = 0; k < numTimeSlots; k++ )
697 : {
698 30902400 : temp1 = realDMX[chOutIdx][k][bandIdx];
699 30902400 : temp2 = imagDMX[chOutIdx][k][bandIdx];
700 30902400 : P_out += temp1 * temp1 + temp2 * temp2;
701 : }
702 7725600 : factEQ = sqrtf( P_in[bandIdx] / ( P_out + 1e-20f ) );
703 7725600 : if ( ( factEQ <= 1e-20f ) || ( P_in[bandIdx] <= 1e-20f ) || ( P_out <= 1e-20f ) )
704 : {
705 111012 : factEQ = 1.0f;
706 : }
707 :
708 7725600 : factEQ = max( min( factEQ, 2.0f ), 0.5f );
709 38628000 : for ( k = 0; k < numTimeSlots; k++ )
710 : {
711 30902400 : realDMX[chOutIdx][k][bandIdx] *= factEQ;
712 30902400 : imagDMX[chOutIdx][k][bandIdx] *= factEQ;
713 : }
714 : }
715 : }
716 : }
717 220230 : else if ( hBinRenderer->ivas_format == SBA_FORMAT || hBinRenderer->ivas_format == MASA_FORMAT )
718 : {
719 : float *outRealLeftPtr, *outImagLeftPtr, *outRealRightPtr, *outImagRightPtr;
720 : float *inRealPtr, *inImagPtr;
721 :
722 : /*compute DMX */
723 1099347 : for ( k = 0; k < numTimeSlots; k++ )
724 : {
725 879117 : outRealLeftPtr = realDMX[0][k];
726 879117 : outImagLeftPtr = imagDMX[0][k];
727 879117 : outRealRightPtr = realDMX[1][k];
728 879117 : outImagRightPtr = imagDMX[1][k];
729 879117 : set_zero( outRealLeftPtr, CLDFB_NO_CHANNELS_MAX );
730 879117 : set_zero( outImagLeftPtr, CLDFB_NO_CHANNELS_MAX );
731 879117 : set_zero( outRealRightPtr, CLDFB_NO_CHANNELS_MAX );
732 879117 : set_zero( outImagRightPtr, CLDFB_NO_CHANNELS_MAX );
733 :
734 : /*Ambisonics input requires different processing*/
735 879117 : if ( hBinRenderer->nInChannels == HOA3_CHANNELS )
736 : {
737 : float *inRealPtr_W, *inImagPtr_W;
738 : float *inRealPtr_Y, *inImagPtr_Y;
739 :
740 543165 : inRealPtr_W = (float *) &( RealBuffer[0][k][0] );
741 543165 : inImagPtr_W = (float *) &( ImagBuffer[0][k][0] );
742 :
743 543165 : inRealPtr_Y = (float *) &( RealBuffer[1][k][0] );
744 543165 : inImagPtr_Y = (float *) &( ImagBuffer[1][k][0] );
745 :
746 24096525 : for ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
747 : {
748 23553360 : outRealLeftPtr[bandIdx] = inRealPtr_W[bandIdx] + inRealPtr_Y[bandIdx];
749 23553360 : outImagLeftPtr[bandIdx] = inImagPtr_W[bandIdx] + inImagPtr_Y[bandIdx];
750 :
751 23553360 : outRealRightPtr[bandIdx] = inRealPtr_W[bandIdx] - inRealPtr_Y[bandIdx];
752 23553360 : outImagRightPtr[bandIdx] = inImagPtr_W[bandIdx] - inImagPtr_Y[bandIdx];
753 : }
754 : }
755 : else
756 : {
757 4031424 : for ( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ )
758 : {
759 3695472 : float foa_const = hBinRenderer->hReverb->foa_enc[chIdx][1];
760 :
761 3695472 : inRealPtr = (float *) &( RealBuffer[chIdx][k][0] );
762 3695472 : inImagPtr = (float *) &( ImagBuffer[chIdx][k][0] );
763 :
764 156789072 : for ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
765 : {
766 153093600 : outRealLeftPtr[bandIdx] += inRealPtr[bandIdx] * ( 1.f + foa_const );
767 153093600 : outImagLeftPtr[bandIdx] += inImagPtr[bandIdx] * ( 1.f + foa_const );
768 :
769 153093600 : outRealRightPtr[bandIdx] += inRealPtr[bandIdx] * ( 1.f - foa_const );
770 153093600 : outImagRightPtr[bandIdx] += inImagPtr[bandIdx] * ( 1.f - foa_const );
771 : }
772 : }
773 : }
774 : }
775 : }
776 :
777 302550 : return;
778 : }
779 :
780 :
781 : /*-------------------------------------------------------------------------
782 : * ivas_rend_openCldfbRend()
783 : *
784 : * Allocate and initialize CLDFB fast conv renderer handle
785 : *------------------------------------------------------------------------*/
786 :
787 0 : ivas_error ivas_rend_openCldfbRend(
788 : CLDFB_REND_WRAPPER *pCldfbRend,
789 : const AUDIO_CONFIG inConfig,
790 : const AUDIO_CONFIG outConfig,
791 : const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
792 : const int32_t output_Fs )
793 : {
794 : BINAURAL_RENDERER_HANDLE hBinRenderer;
795 : int16_t convBand;
796 : ivas_error error;
797 :
798 0 : error = IVAS_ERR_OK;
799 :
800 : /*-----------------------------------------------------------------*
801 : * prepare library opening
802 : *-----------------------------------------------------------------*/
803 :
804 0 : if ( ( hBinRenderer = (BINAURAL_RENDERER_HANDLE) malloc( sizeof( BINAURAL_RENDERER ) ) ) == NULL )
805 : {
806 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural Renderer\n" ) );
807 : }
808 :
809 0 : if ( ( hBinRenderer->hInputSetup = (IVAS_OUTPUT_SETUP_HANDLE) malloc( sizeof( IVAS_OUTPUT_SETUP ) ) ) == NULL )
810 : {
811 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for output setup Binaural Renderer\n" ) );
812 : }
813 :
814 0 : hBinRenderer->rotInCldfb = 1;
815 0 : hBinRenderer->ivas_format = SBA_FORMAT;
816 :
817 0 : hBinRenderer->max_band = (int16_t) ( ( BINAURAL_MAXBANDS * output_Fs ) / 48000 );
818 0 : convBand = hBinRenderer->max_band;
819 :
820 0 : hBinRenderer->timeSlots = MAX_PARAM_SPATIAL_SUBFRAMES; /* Corresponds to 5 msec sound to motion latency */
821 :
822 0 : if ( convBand > BINAURAL_CONVBANDS )
823 : {
824 0 : hBinRenderer->conv_band = BINAURAL_CONVBANDS;
825 : }
826 : else
827 : {
828 0 : hBinRenderer->conv_band = convBand;
829 : }
830 :
831 0 : ivas_output_init( hBinRenderer->hInputSetup, inConfig );
832 0 : if ( ( error = getAudioConfigNumChannels( inConfig, &hBinRenderer->hInputSetup->nchan_out_woLFE ) ) != IVAS_ERR_OK )
833 : {
834 0 : return error;
835 : }
836 :
837 0 : if ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
838 : {
839 : #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
840 : hBinRenderer->numPoses = pMultiBinPoseData->num_poses + 1;
841 : #else
842 0 : hBinRenderer->numPoses = pMultiBinPoseData->num_poses;
843 : #endif
844 : }
845 : else
846 : {
847 0 : hBinRenderer->numPoses = 1;
848 : }
849 :
850 : /* Load HRTF tables */
851 0 : if ( ( error = ivas_binaural_hrtf_open( &pCldfbRend->hHrtfFastConv, hBinRenderer->hInputSetup->output_config, RENDERER_BINAURAL_FASTCONV ) ) != IVAS_ERR_OK )
852 : {
853 0 : return error;
854 : }
855 :
856 : /* Allocate memories and buffers needed for convolutional module */
857 0 : if ( ( error = ivas_binRenderer_convModuleOpen( hBinRenderer, RENDERER_BINAURAL_FASTCONV, hBinRenderer->hInputSetup->is_loudspeaker_setup, inConfig, pCldfbRend->hHrtfFastConv, hBinRenderer->numPoses ) ) != IVAS_ERR_OK )
858 : {
859 0 : return error;
860 : }
861 :
862 0 : pCldfbRend->binaural_latency_ns = (int32_t) ( pCldfbRend->hHrtfFastConv->FASTCONV_latency_s * 1000000000.f );
863 :
864 0 : hBinRenderer->hReverb = NULL;
865 0 : hBinRenderer->hEFAPdata = NULL;
866 :
867 0 : pCldfbRend->hCldfbRend = hBinRenderer;
868 :
869 0 : return error;
870 : }
871 :
872 :
873 : /*-------------------------------------------------------------------------
874 : * ivas_binRenderer_open()
875 : *
876 : * Open fastconv binaural renderer handle
877 : *-------------------------------------------------------------------------*/
878 :
879 1065 : ivas_error ivas_binRenderer_open(
880 : Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
881 : )
882 : {
883 : BINAURAL_RENDERER_HANDLE hBinRenderer;
884 : int16_t convBand, k;
885 : ivas_error error;
886 : const IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pRoomAcoustics;
887 :
888 1065 : error = IVAS_ERR_OK;
889 :
890 : /*-----------------------------------------------------------------*
891 : * prepare library opening
892 : *-----------------------------------------------------------------*/
893 :
894 1065 : if ( ( hBinRenderer = (BINAURAL_RENDERER_HANDLE) malloc( sizeof( BINAURAL_RENDERER ) ) ) == NULL )
895 : {
896 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural Renderer\n" ) );
897 : }
898 :
899 1065 : hBinRenderer->hInputSetup = &st_ivas->hIntSetup;
900 :
901 : /* Define of head rotation has to be done in binRendeder in CLDFB*/
902 1065 : hBinRenderer->rotInCldfb = 0;
903 1065 : if ( st_ivas->ivas_format == MC_FORMAT || st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT )
904 : {
905 1065 : hBinRenderer->rotInCldfb = 1;
906 : }
907 :
908 1065 : if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
909 : {
910 : #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
911 : hBinRenderer->numPoses = st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses + 1;
912 : #else
913 0 : hBinRenderer->numPoses = st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses;
914 : #endif
915 : }
916 : else
917 : {
918 1065 : hBinRenderer->numPoses = 1;
919 : }
920 :
921 : /* Declare some common variables needed for renderer */
922 : /* Which format used for binaural rendering (needed for late reverb) ? MC or SBA */
923 1065 : if ( st_ivas->hIntSetup.is_loudspeaker_setup )
924 : {
925 438 : hBinRenderer->ivas_format = MC_FORMAT;
926 : }
927 : else
928 : {
929 627 : hBinRenderer->ivas_format = SBA_FORMAT;
930 : }
931 1065 : hBinRenderer->max_band = (int16_t) ( ( BINAURAL_MAXBANDS * st_ivas->hDecoderConfig->output_Fs ) / 48000 );
932 1065 : convBand = hBinRenderer->max_band;
933 :
934 1065 : hBinRenderer->timeSlots = MAX_PARAM_SPATIAL_SUBFRAMES; /* Corresponds to 5 msec sound to motion latency */
935 :
936 1065 : if ( convBand > BINAURAL_CONVBANDS )
937 : {
938 681 : hBinRenderer->conv_band = BINAURAL_CONVBANDS;
939 : }
940 : else
941 : {
942 384 : hBinRenderer->conv_band = convBand;
943 : }
944 :
945 : /*LFE rendering switched off by default*/
946 1065 : hBinRenderer->render_lfe = 0;
947 :
948 1065 : if ( st_ivas->ivas_format != ISM_FORMAT && st_ivas->hIntSetup.is_loudspeaker_setup )
949 : {
950 438 : hBinRenderer->render_lfe = 1;
951 : }
952 :
953 1065 : if ( st_ivas->hHrtfFastConv == NULL && st_ivas->hDecoderConfig->Opt_HRTF_binary )
954 : {
955 0 : return IVAS_ERROR( IVAS_ERR_INTERNAL, "HRTF binary file present but not used in FastConv renderer" );
956 : }
957 :
958 : /* Load HRTF tables */
959 1065 : if ( ( error = ivas_binaural_hrtf_open( &st_ivas->hHrtfFastConv, st_ivas->hIntSetup.output_config, st_ivas->renderer_type ) ) != IVAS_ERR_OK )
960 : {
961 0 : return error;
962 : }
963 :
964 1065 : if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM && ( st_ivas->hIntSetup.is_loudspeaker_setup == 0 ) )
965 21 : {
966 : IVAS_OUTPUT_SETUP out_setup;
967 :
968 : /* Allocate memories and buffers needed for convolutional module in CICP19 */
969 21 : if ( ( error = ivas_binRenderer_convModuleOpen( hBinRenderer, st_ivas->renderer_type, 1, IVAS_AUDIO_CONFIG_7_1_4, st_ivas->hHrtfFastConv, hBinRenderer->numPoses ) ) != IVAS_ERR_OK )
970 : {
971 0 : return error;
972 : }
973 :
974 21 : ivas_output_init( &out_setup, IVAS_AUDIO_CONFIG_7_1_4 );
975 :
976 21 : if ( st_ivas->hoa_dec_mtx == NULL )
977 : {
978 21 : if ( ( error = ivas_sba_get_hoa_dec_matrix( out_setup, &st_ivas->hoa_dec_mtx, st_ivas->hIntSetup.ambisonics_order ) ) != IVAS_ERR_OK )
979 : {
980 0 : return error;
981 : }
982 : }
983 :
984 21 : hBinRenderer->hoa_dec_mtx = st_ivas->hoa_dec_mtx;
985 21 : st_ivas->binaural_latency_ns = (int32_t) ( st_ivas->hHrtfFastConv->FASTCONV_latency_s * 1000000000.f );
986 : }
987 : else
988 : {
989 : /* Allocate memories and buffers needed for convolutional module */
990 1044 : if ( ( error = ivas_binRenderer_convModuleOpen( hBinRenderer, st_ivas->renderer_type, st_ivas->hIntSetup.is_loudspeaker_setup, st_ivas->hIntSetup.output_config, st_ivas->hHrtfFastConv, hBinRenderer->numPoses ) ) != IVAS_ERR_OK )
991 : {
992 0 : return error;
993 : }
994 :
995 1044 : st_ivas->binaural_latency_ns = (int32_t) ( st_ivas->hHrtfFastConv->FASTCONV_latency_s * 1000000000.f );
996 : }
997 :
998 : /* Allocate memories needed for reverb module */
999 1065 : if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM || ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV && st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) )
1000 : {
1001 576 : pRoomAcoustics = ( st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ? &( st_ivas->hRenderConfig->roomAcoustics ) : NULL;
1002 576 : if ( ( error = ivas_binaural_reverb_init( &( hBinRenderer->hReverb ),
1003 : st_ivas->hHrtfStatistics,
1004 576 : hBinRenderer->conv_band,
1005 576 : hBinRenderer->timeSlots,
1006 : pRoomAcoustics,
1007 576 : st_ivas->hDecoderConfig->output_Fs,
1008 576 : st_ivas->hHrtfFastConv->fastconvReverberationTimes,
1009 576 : st_ivas->hHrtfFastConv->fastconvReverberationEneCorrections,
1010 576 : hBinRenderer->earlyPartEneCorrection ) ) != IVAS_ERR_OK )
1011 : {
1012 0 : return error;
1013 : }
1014 : }
1015 : else
1016 : {
1017 489 : hBinRenderer->hReverb = NULL;
1018 : }
1019 :
1020 1065 : hBinRenderer->hEFAPdata = NULL;
1021 :
1022 1065 : if ( hBinRenderer->hReverb != NULL && hBinRenderer->nInChannels != HOA3_CHANNELS )
1023 : {
1024 375 : if ( hBinRenderer->hInputSetup->is_loudspeaker_setup == 0 )
1025 : {
1026 252 : for ( k = 0; k < 11; k++ )
1027 : {
1028 231 : ivas_dirac_dec_get_response( (int16_t) ls_azimuth_CICP19[k], (int16_t) ls_elevation_CICP19[k], hBinRenderer->hReverb->foa_enc[k], 1 );
1029 : }
1030 : }
1031 354 : else if ( st_ivas->ivas_format == MC_FORMAT && ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) )
1032 : {
1033 6 : 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 )
1034 : {
1035 0 : return error;
1036 : }
1037 :
1038 : /* Copy handles to bin renderer handle*/
1039 6 : hBinRenderer->hEFAPdata = st_ivas->hEFAPdata;
1040 : }
1041 : }
1042 :
1043 : /* Copy the handles to main handle */
1044 1065 : st_ivas->hBinRenderer = hBinRenderer;
1045 :
1046 1065 : return error;
1047 : }
1048 :
1049 :
1050 : /*-------------------------------------------------------------------------
1051 : * ivas_binRenderer_convModuleClose()
1052 : *
1053 : * Close convolution module handle of fastconv binaural renderer
1054 : *------------------------------------------------------------------------*/
1055 :
1056 1065 : static void ivas_binRenderer_convModuleClose(
1057 : BINAURAL_RENDERER_HANDLE *hBinRenderer, /* i/o: fastconv binaural renderer handle */
1058 : const int16_t num_poses /* i : number of poses */
1059 : )
1060 : {
1061 : int16_t bandIdx, chIdx;
1062 : int16_t posIdx;
1063 : BINRENDERER_CONV_MODULE_HANDLE hBinRenConvModule;
1064 :
1065 1065 : hBinRenConvModule = ( *hBinRenderer )->hBinRenConvModule;
1066 :
1067 1065 : if ( hBinRenConvModule == NULL )
1068 : {
1069 0 : return;
1070 : }
1071 :
1072 45315 : for ( bandIdx = 0; bandIdx < ( *hBinRenderer )->conv_band; bandIdx++ )
1073 : {
1074 44250 : free( hBinRenConvModule->filterTapsLeftReal[bandIdx] );
1075 44250 : hBinRenConvModule->filterTapsLeftReal[bandIdx] = NULL;
1076 :
1077 44250 : free( hBinRenConvModule->filterTapsLeftImag[bandIdx] );
1078 44250 : hBinRenConvModule->filterTapsLeftImag[bandIdx] = NULL;
1079 :
1080 44250 : free( hBinRenConvModule->filterTapsRightReal[bandIdx] );
1081 44250 : hBinRenConvModule->filterTapsRightReal[bandIdx] = NULL;
1082 :
1083 44250 : free( hBinRenConvModule->filterTapsRightImag[bandIdx] );
1084 44250 : hBinRenConvModule->filterTapsRightImag[bandIdx] = NULL;
1085 : }
1086 :
1087 1065 : free( hBinRenConvModule->filterTapsLeftReal );
1088 1065 : hBinRenConvModule->filterTapsLeftReal = NULL;
1089 :
1090 1065 : free( hBinRenConvModule->filterTapsLeftImag );
1091 1065 : hBinRenConvModule->filterTapsLeftImag = NULL;
1092 :
1093 1065 : free( hBinRenConvModule->filterTapsRightReal );
1094 1065 : hBinRenConvModule->filterTapsRightReal = NULL;
1095 :
1096 1065 : free( hBinRenConvModule->filterTapsRightImag );
1097 1065 : hBinRenConvModule->filterTapsRightImag = NULL;
1098 :
1099 2130 : for ( posIdx = 0; posIdx < num_poses; posIdx++ )
1100 : {
1101 45315 : for ( bandIdx = 0; bandIdx < ( *hBinRenderer )->conv_band; bandIdx++ )
1102 : {
1103 572940 : for ( chIdx = 0; chIdx < ( *hBinRenderer )->nInChannels; chIdx++ )
1104 : {
1105 528690 : free( hBinRenConvModule->filterStatesLeftReal[posIdx][bandIdx][chIdx] );
1106 528690 : hBinRenConvModule->filterStatesLeftReal[posIdx][bandIdx][chIdx] = NULL;
1107 :
1108 528690 : free( hBinRenConvModule->filterStatesLeftImag[posIdx][bandIdx][chIdx] );
1109 528690 : hBinRenConvModule->filterStatesLeftImag[posIdx][bandIdx][chIdx] = NULL;
1110 : }
1111 :
1112 44250 : free( hBinRenConvModule->filterStatesLeftReal[posIdx][bandIdx] );
1113 44250 : hBinRenConvModule->filterStatesLeftReal[posIdx][bandIdx] = NULL;
1114 :
1115 44250 : free( hBinRenConvModule->filterStatesLeftImag[posIdx][bandIdx] );
1116 44250 : hBinRenConvModule->filterStatesLeftImag[posIdx][bandIdx] = NULL;
1117 : }
1118 :
1119 1065 : free( hBinRenConvModule->filterStatesLeftReal[posIdx] );
1120 1065 : hBinRenConvModule->filterStatesLeftReal[posIdx] = NULL;
1121 :
1122 1065 : free( hBinRenConvModule->filterStatesLeftImag[posIdx] );
1123 1065 : hBinRenConvModule->filterStatesLeftImag[posIdx] = NULL;
1124 : }
1125 1065 : free( hBinRenConvModule->filterStatesLeftReal );
1126 1065 : hBinRenConvModule->filterStatesLeftReal = NULL;
1127 :
1128 1065 : free( hBinRenConvModule->filterStatesLeftImag );
1129 1065 : hBinRenConvModule->filterStatesLeftImag = NULL;
1130 :
1131 1065 : free( ( *hBinRenderer )->hBinRenConvModule );
1132 1065 : ( *hBinRenderer )->hBinRenConvModule = NULL;
1133 :
1134 1065 : return;
1135 : }
1136 :
1137 :
1138 : /*-------------------------------------------------------------------------
1139 : * ivas_binRenderer_close()
1140 : *
1141 : * Close fastconv binaural renderer memories
1142 : *------------------------------------------------------------------------*/
1143 :
1144 2805 : void ivas_binRenderer_close(
1145 : BINAURAL_RENDERER_HANDLE *hBinRenderer /* i/o: fastconv binaural renderer handle */
1146 : )
1147 : {
1148 2805 : if ( hBinRenderer == NULL || *hBinRenderer == NULL )
1149 : {
1150 1740 : return;
1151 : }
1152 :
1153 1065 : if ( ( *hBinRenderer )->hBinRenConvModule != NULL )
1154 : {
1155 1065 : ivas_binRenderer_convModuleClose( hBinRenderer, ( *hBinRenderer )->numPoses );
1156 : }
1157 :
1158 1065 : if ( ( *hBinRenderer )->hReverb != NULL )
1159 : {
1160 576 : ivas_binaural_reverb_close( &( ( *hBinRenderer )->hReverb ) );
1161 : }
1162 :
1163 1065 : free( *hBinRenderer );
1164 1065 : *hBinRenderer = NULL;
1165 :
1166 1065 : return;
1167 : }
1168 :
1169 :
1170 : /*-------------------------------------------------------------------------
1171 : * ivas_free_pppHrtfMem()
1172 : *
1173 : * Free fastconv binaural renderer hrtf memories
1174 : *------------------------------------------------------------------------*/
1175 :
1176 1368 : static void ivas_free_pppHrtfMem(
1177 : float ****ppppHRIR,
1178 : const int16_t dim,
1179 : const int16_t alloc_init )
1180 : {
1181 : int16_t i, j;
1182 :
1183 1368 : if ( *ppppHRIR != NULL )
1184 : {
1185 69768 : for ( i = 0; i < BINAURAL_CONVBANDS; i++ )
1186 : {
1187 68400 : if ( alloc_init == 0 )
1188 : {
1189 689400 : for ( j = 0; j < dim; j++ )
1190 : {
1191 648600 : free( ( *ppppHRIR )[i][j] );
1192 648600 : ( *ppppHRIR )[i][j] = NULL;
1193 : }
1194 : }
1195 68400 : free( ( *ppppHRIR )[i] );
1196 68400 : ( *ppppHRIR )[i] = NULL;
1197 : }
1198 1368 : free( *ppppHRIR );
1199 1368 : *ppppHRIR = NULL;
1200 : }
1201 :
1202 1368 : return;
1203 : }
1204 :
1205 :
1206 : /*-------------------------------------------------------------------------
1207 : * ivas_binaural_hrtf_close()
1208 : *
1209 : * Close fastconv binaural renderer hrtf memories
1210 : *------------------------------------------------------------------------*/
1211 :
1212 3644 : void ivas_binaural_hrtf_close(
1213 : HRTFS_FASTCONV_HANDLE *hHrtfFastConv /* i : fastconv HRTF handle */
1214 : )
1215 : {
1216 : int16_t allocate_init_flag;
1217 : int16_t n_channels;
1218 :
1219 3644 : if ( hHrtfFastConv == NULL || *hHrtfFastConv == NULL )
1220 : {
1221 3302 : return;
1222 : }
1223 :
1224 342 : allocate_init_flag = ( *hHrtfFastConv )->allocate_init_flag;
1225 342 : n_channels = ( *hHrtfFastConv )->n_channels;
1226 :
1227 342 : ivas_free_pppHrtfMem( &( *hHrtfFastConv )->leftReal, n_channels, allocate_init_flag );
1228 342 : ivas_free_pppHrtfMem( &( *hHrtfFastConv )->leftImag, n_channels, allocate_init_flag );
1229 342 : ivas_free_pppHrtfMem( &( *hHrtfFastConv )->rightReal, n_channels, allocate_init_flag );
1230 342 : ivas_free_pppHrtfMem( &( *hHrtfFastConv )->rightImag, n_channels, allocate_init_flag );
1231 :
1232 342 : return;
1233 : }
1234 :
1235 :
1236 : /*-------------------------------------------------------------------------*
1237 : * ivas_binaural_add_LFE()
1238 : *
1239 : * The functions adds the LFE to the left and right channels after binaural rendering
1240 : *-------------------------------------------------------------------------*/
1241 :
1242 117634 : void ivas_binaural_add_LFE(
1243 : Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
1244 : int16_t output_frame, /* i : length of input frame */
1245 : float *input_f[], /* i : transport channels */
1246 : float *output_f[] /* o : synthesized core-coder transport channels/DirAC output */
1247 : )
1248 : {
1249 : int16_t render_lfe, idx_lfe;
1250 : float gain;
1251 : float lfe_tc[L_FRAME48k];
1252 :
1253 117634 : if ( st_ivas->hBinRenderer != NULL )
1254 : {
1255 1120 : render_lfe = st_ivas->hBinRenderer->render_lfe;
1256 : }
1257 : else
1258 : {
1259 116514 : render_lfe = TRUE;
1260 : }
1261 :
1262 117634 : if ( render_lfe )
1263 : {
1264 117634 : if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD )
1265 : {
1266 21882 : gain = GAIN_LFE;
1267 : }
1268 : else
1269 : {
1270 95752 : gain = ( ( st_ivas->hCrendWrapper != NULL ) && ( st_ivas->hCrendWrapper->hHrtfCrend != NULL ) ) ? st_ivas->hCrendWrapper->hHrtfCrend->gain_lfe : GAIN_LFE;
1271 : }
1272 :
1273 233781 : for ( idx_lfe = 0; idx_lfe < st_ivas->hIntSetup.num_lfe; idx_lfe++ )
1274 : {
1275 116147 : v_multc( input_f[st_ivas->hIntSetup.index_lfe[idx_lfe]], gain, lfe_tc, output_frame );
1276 : /* copy LFE to left and right channels */
1277 116147 : v_add( output_f[0], lfe_tc, output_f[0], output_frame );
1278 116147 : v_add( output_f[1], lfe_tc, output_f[1], output_frame );
1279 : }
1280 : }
1281 :
1282 117634 : return;
1283 : }
1284 :
1285 :
1286 : #ifdef DEBUGGING
1287 : /*-------------------------------------------------------------------------*
1288 : * ivas_binaural_cldfb()
1289 : *
1290 : * Perform CLDFB analysis, fastconv binaural rendering and CLDFB synthesis
1291 : *-------------------------------------------------------------------------*/
1292 :
1293 : void ivas_binaural_cldfb(
1294 : Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
1295 : float *output_f[] /* i/o: synthesized core-coder transport channels/DirAC output */
1296 : )
1297 : {
1298 : float Cldfb_RealBuffer[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
1299 : float Cldfb_ImagBuffer[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
1300 : float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
1301 : float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
1302 : int16_t slot_idx, subframeIdx, index_slot, idx_in, idx_lfe, maxBand, ch;
1303 :
1304 : /* Implement a 5 msec loops */
1305 : maxBand = (int16_t) ( ( CLDFB_NO_CHANNELS_MAX * st_ivas->hDecoderConfig->output_Fs ) / 48000 );
1306 :
1307 : for ( subframeIdx = 0; subframeIdx < ( CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES ); subframeIdx++ )
1308 : {
1309 : for ( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ )
1310 : {
1311 : index_slot = subframeIdx * MAX_PARAM_SPATIAL_SUBFRAMES + slot_idx;
1312 :
1313 : /* Implement CLDFB analysis */
1314 : idx_in = 0;
1315 : idx_lfe = 0;
1316 :
1317 : for ( ch = 0; ch < ( st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ); ch++ )
1318 : {
1319 : if ( ( st_ivas->hIntSetup.num_lfe > 0 ) && ( st_ivas->hIntSetup.index_lfe[idx_lfe] == ch ) )
1320 : {
1321 : if ( idx_lfe < ( st_ivas->hIntSetup.num_lfe - 1 ) )
1322 : {
1323 : idx_lfe++;
1324 : }
1325 : }
1326 : else
1327 : {
1328 : cldfbAnalysis_ts( &( output_f[ch][maxBand * index_slot] ), Cldfb_RealBuffer[idx_in][slot_idx], Cldfb_ImagBuffer[idx_in][slot_idx], maxBand, st_ivas->cldfbAnaDec[idx_in] );
1329 : idx_in++;
1330 : }
1331 : }
1332 : /*LFE handling for split rendering cases*/
1333 : if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
1334 : {
1335 : for ( idx_lfe = 0; idx_lfe < st_ivas->hIntSetup.num_lfe; idx_lfe++ )
1336 : {
1337 : ch = st_ivas->hIntSetup.index_lfe[idx_lfe];
1338 : cldfbAnalysis_ts( &( output_f[ch][maxBand * index_slot] ), Cldfb_RealBuffer[idx_in][slot_idx], Cldfb_ImagBuffer[idx_in][slot_idx], maxBand, st_ivas->cldfbAnaDec[idx_in] );
1339 : idx_in++;
1340 : }
1341 :
1342 : if ( st_ivas->hSplitBinRend->hCldfbDataOut != NULL )
1343 : {
1344 : for ( ch = 0; ch < ( st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ); ch++ )
1345 : {
1346 : mvr2r( Cldfb_RealBuffer[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_RealBuffer[ch][( subframeIdx * JBM_CLDFB_SLOTS_IN_SUBFRAME ) + slot_idx], maxBand );
1347 : mvr2r( Cldfb_ImagBuffer[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_ImagBuffer[ch][( subframeIdx * JBM_CLDFB_SLOTS_IN_SUBFRAME ) + slot_idx], maxBand );
1348 : }
1349 : st_ivas->hSplitBinRend->hCldfbDataOut->config = st_ivas->hIntSetup.output_config;
1350 : }
1351 : }
1352 : }
1353 :
1354 : /* Implement binaural rendering */
1355 : ivas_binRenderer(
1356 : st_ivas->hBinRenderer,
1357 : &st_ivas->hSplitBinRend->splitrend.multiBinPoseData,
1358 : st_ivas->hCombinedOrientationData,
1359 : JBM_CLDFB_SLOTS_IN_SUBFRAME,
1360 : #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
1361 : NULL,
1362 : #endif
1363 : Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural,
1364 : Cldfb_RealBuffer, Cldfb_ImagBuffer );
1365 :
1366 : if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
1367 : {
1368 : int16_t pos_idx;
1369 : for ( slot_idx = 0; slot_idx < JBM_CLDFB_SLOTS_IN_SUBFRAME; slot_idx++ )
1370 : {
1371 : if ( st_ivas->hIntSetup.num_lfe > 0 )
1372 : {
1373 : v_multc( Cldfb_RealBuffer[st_ivas->hIntSetup.nchan_out_woLFE][slot_idx], GAIN_LFE, Cldfb_RealBuffer[st_ivas->hIntSetup.nchan_out_woLFE][slot_idx], maxBand );
1374 : v_multc( Cldfb_ImagBuffer[st_ivas->hIntSetup.nchan_out_woLFE][slot_idx], GAIN_LFE, Cldfb_ImagBuffer[st_ivas->hIntSetup.nchan_out_woLFE][slot_idx], maxBand );
1375 : }
1376 : }
1377 :
1378 : for ( pos_idx = 0; pos_idx < st_ivas->hBinRenderer->numPoses; pos_idx++ )
1379 : {
1380 : for ( slot_idx = 0; slot_idx < JBM_CLDFB_SLOTS_IN_SUBFRAME; slot_idx++ )
1381 : {
1382 : for ( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ )
1383 : {
1384 : if ( st_ivas->hIntSetup.num_lfe > 0 )
1385 : {
1386 : v_add( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx],
1387 : Cldfb_RealBuffer[st_ivas->hIntSetup.nchan_out_woLFE][slot_idx],
1388 : Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx],
1389 : maxBand );
1390 :
1391 : v_add( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx],
1392 : Cldfb_ImagBuffer[st_ivas->hIntSetup.nchan_out_woLFE][slot_idx],
1393 : Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx],
1394 : maxBand );
1395 : }
1396 :
1397 : mvr2r( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][( subframeIdx * JBM_CLDFB_SLOTS_IN_SUBFRAME ) + slot_idx], maxBand );
1398 : mvr2r( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][( subframeIdx * JBM_CLDFB_SLOTS_IN_SUBFRAME ) + slot_idx], maxBand );
1399 : }
1400 : }
1401 : }
1402 : }
1403 :
1404 : /* update combined orientation access index */
1405 : ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, maxBand * MAX_PARAM_SPATIAL_SUBFRAMES );
1406 :
1407 : /* Implement CLDFB synthesis */
1408 : for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
1409 : {
1410 : float *RealBuffer[MAX_PARAM_SPATIAL_SUBFRAMES];
1411 : float *ImagBuffer[MAX_PARAM_SPATIAL_SUBFRAMES];
1412 :
1413 : index_slot = subframeIdx * MAX_PARAM_SPATIAL_SUBFRAMES;
1414 :
1415 : for ( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ )
1416 : {
1417 : RealBuffer[slot_idx] = Cldfb_RealBuffer_Binaural[0][ch][slot_idx];
1418 : ImagBuffer[slot_idx] = Cldfb_ImagBuffer_Binaural[0][ch][slot_idx];
1419 : }
1420 :
1421 : cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][index_slot * maxBand] ), maxBand * MAX_PARAM_SPATIAL_SUBFRAMES, st_ivas->cldfbSynDec[ch] );
1422 : }
1423 : }
1424 :
1425 : return;
1426 : }
1427 :
1428 :
1429 : /*-------------------------------------------------------------------------*
1430 : * ivas_binaural_cldfb_sf()
1431 : *
1432 : * Perform CLDFB analysis, fastconv binaural rendering and CLDFB synthesis
1433 : *-------------------------------------------------------------------------*/
1434 :
1435 : void ivas_binaural_cldfb_sf(
1436 : Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
1437 : const int16_t n_samples_to_render, /* i : output frame length per channel */
1438 : const int16_t slot_size, /* i : JBM slot size */
1439 : float *output_f[] /* i/o: synthesized core-coder transport channels/DirAC output */
1440 : )
1441 : {
1442 : float Cldfb_RealBuffer[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
1443 : float Cldfb_ImagBuffer[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
1444 : float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
1445 : float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
1446 : int16_t slot_idx, subframeIdx, index_slot, idx_in, idx_lfe, maxBand, ch;
1447 : int16_t slots_to_render, first_sf, last_sf;
1448 : int16_t slot_index_start, slot_index_start_cldfb;
1449 :
1450 : /* Implement a 5 msec loops */
1451 : maxBand = (int16_t) ( ( CLDFB_NO_CHANNELS_MAX * st_ivas->hDecoderConfig->output_Fs ) / 48000 );
1452 :
1453 : /* loop for synthesis, assume we always have to render in multiples of 5ms subframes with spills */
1454 : slots_to_render = min( st_ivas->hTcBuffer->num_slots - st_ivas->hTcBuffer->slots_rendered, n_samples_to_render / slot_size );
1455 : first_sf = st_ivas->hTcBuffer->subframes_rendered;
1456 : last_sf = first_sf;
1457 : slot_index_start = st_ivas->hTcBuffer->slots_rendered;
1458 : slot_index_start_cldfb = 0;
1459 : st_ivas->hTcBuffer->slots_rendered += slots_to_render;
1460 :
1461 : while ( slots_to_render > 0 )
1462 : {
1463 : slots_to_render -= st_ivas->hTcBuffer->subframe_nbslots[last_sf];
1464 : last_sf++;
1465 : }
1466 : for ( subframeIdx = first_sf; subframeIdx < last_sf; subframeIdx++ )
1467 : {
1468 : for ( slot_idx = 0; slot_idx < st_ivas->hTcBuffer->subframe_nbslots[subframeIdx]; slot_idx++ )
1469 : {
1470 : index_slot = slot_index_start + slot_idx;
1471 :
1472 : /* Implement CLDFB analysis */
1473 : idx_in = 0;
1474 : idx_lfe = 0;
1475 :
1476 : for ( ch = 0; ch < ( st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ); ch++ )
1477 : {
1478 : if ( ( st_ivas->hIntSetup.num_lfe > 0 ) && ( st_ivas->hIntSetup.index_lfe[idx_lfe] == ch ) )
1479 : {
1480 : if ( idx_lfe < ( st_ivas->hIntSetup.num_lfe - 1 ) )
1481 : {
1482 : idx_lfe++;
1483 : }
1484 : }
1485 : else
1486 : {
1487 : cldfbAnalysis_ts( &( st_ivas->hTcBuffer->tc[ch][maxBand * index_slot] ), Cldfb_RealBuffer[idx_in][slot_idx], Cldfb_ImagBuffer[idx_in][slot_idx], maxBand, st_ivas->cldfbAnaDec[idx_in] );
1488 : idx_in++;
1489 : }
1490 : }
1491 :
1492 : /*LFE handling for split rendering cases*/
1493 : if ( ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) ||
1494 : ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) )
1495 : {
1496 : for ( idx_lfe = 0; idx_lfe < st_ivas->hIntSetup.num_lfe; idx_lfe++ )
1497 : {
1498 : ch = st_ivas->hIntSetup.index_lfe[idx_lfe];
1499 : cldfbAnalysis_ts( &( output_f[ch][maxBand * index_slot] ), Cldfb_RealBuffer[idx_in][slot_idx], Cldfb_ImagBuffer[idx_in][slot_idx], maxBand, st_ivas->cldfbAnaDec[idx_in] );
1500 : idx_in++;
1501 : }
1502 :
1503 : if ( st_ivas->hSplitBinRend->hCldfbDataOut != NULL )
1504 : {
1505 : for ( ch = 0; ch < ( st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ); ch++ )
1506 : {
1507 : mvr2r( Cldfb_RealBuffer[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_RealBuffer[ch][slot_index_start + slot_idx], maxBand );
1508 : mvr2r( Cldfb_ImagBuffer[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_ImagBuffer[ch][slot_index_start + slot_idx], maxBand );
1509 : }
1510 : st_ivas->hSplitBinRend->hCldfbDataOut->config = st_ivas->hIntSetup.output_config;
1511 : }
1512 : }
1513 : }
1514 :
1515 : /* Implement binaural rendering */
1516 : ivas_binRenderer(
1517 : st_ivas->hBinRenderer,
1518 : &st_ivas->hSplitBinRend->splitrend.multiBinPoseData,
1519 : st_ivas->hCombinedOrientationData,
1520 : st_ivas->hTcBuffer->subframe_nbslots[subframeIdx],
1521 : #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
1522 : NULL,
1523 : #endif
1524 : Cldfb_RealBuffer_Binaural,
1525 : Cldfb_ImagBuffer_Binaural,
1526 : Cldfb_RealBuffer,
1527 : Cldfb_ImagBuffer );
1528 :
1529 : if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM )
1530 : {
1531 : int16_t pos_idx;
1532 : for ( pos_idx = 0; pos_idx < st_ivas->hBinRenderer->numPoses; pos_idx++ )
1533 : {
1534 : for ( slot_idx = 0; slot_idx < st_ivas->hTcBuffer->subframe_nbslots[subframeIdx]; slot_idx++ )
1535 : {
1536 : for ( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ )
1537 : {
1538 : mvr2r( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_index_start + slot_idx], maxBand );
1539 : mvr2r( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_index_start + slot_idx], maxBand );
1540 : }
1541 : }
1542 : }
1543 : }
1544 :
1545 : /* update combined orientation access index */
1546 : ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, maxBand * st_ivas->hTcBuffer->subframe_nbslots[subframeIdx] );
1547 :
1548 : /* Implement CLDFB synthesis */
1549 : for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ )
1550 : {
1551 : float *RealBuffer[MAX_PARAM_SPATIAL_SUBFRAMES];
1552 : float *ImagBuffer[MAX_PARAM_SPATIAL_SUBFRAMES];
1553 :
1554 : for ( slot_idx = 0; slot_idx < st_ivas->hTcBuffer->subframe_nbslots[subframeIdx]; slot_idx++ )
1555 : {
1556 : RealBuffer[slot_idx] = Cldfb_RealBuffer_Binaural[0][ch][slot_idx];
1557 : ImagBuffer[slot_idx] = Cldfb_ImagBuffer_Binaural[0][ch][slot_idx];
1558 : }
1559 :
1560 : cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][slot_index_start_cldfb * maxBand] ), maxBand * st_ivas->hTcBuffer->subframe_nbslots[subframeIdx], st_ivas->cldfbSynDec[ch] );
1561 : }
1562 : slot_index_start += st_ivas->hTcBuffer->subframe_nbslots[subframeIdx];
1563 : slot_index_start_cldfb += st_ivas->hTcBuffer->subframe_nbslots[subframeIdx];
1564 : }
1565 :
1566 : st_ivas->hTcBuffer->subframes_rendered = last_sf;
1567 :
1568 : return;
1569 : }
1570 : #endif
1571 :
1572 :
1573 : /*-------------------------------------------------------------------------
1574 : * ivas_binRenderer()
1575 : *
1576 : * Fastconv binaural renderer main function
1577 : *-------------------------------------------------------------------------*/
1578 :
1579 483522 : void ivas_binRenderer(
1580 : BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: binaural renderer handle */
1581 : const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
1582 : COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined head and external orientation handle*/
1583 : const int16_t numTimeSlots, /* i : number of time slots to render */
1584 : #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
1585 : HEAD_TRACK_DATA_HANDLE hPostRendHeadTrackData,
1586 : #endif
1587 : float Cldfb_RealBuffer_Binaural[][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Rotated Binaural signals */
1588 : float Cldfb_ImagBuffer_Binaural[][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Rotated Binaural signals */
1589 : float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */
1590 : float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX] /* i : LS signals */
1591 : )
1592 : {
1593 : int16_t chIdx, k;
1594 : int16_t pos_idx, num_poses;
1595 : float RealBuffer_local[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
1596 : float ImagBuffer_local[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
1597 :
1598 483522 : push_wmops( "fastconv_binaural_rendering" );
1599 483522 : num_poses = hBinRenderer->numPoses;
1600 :
1601 : /* Compute Convolution */
1602 : /* memory reset for the binaural output */
1603 967044 : for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ )
1604 : {
1605 1450566 : for ( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ )
1606 : {
1607 4831614 : for ( k = 0; k < numTimeSlots; k++ )
1608 : {
1609 3864570 : set_zero( Cldfb_RealBuffer_Binaural[pos_idx][chIdx][k], CLDFB_NO_CHANNELS_MAX );
1610 3864570 : set_zero( Cldfb_ImagBuffer_Binaural[pos_idx][chIdx][k], CLDFB_NO_CHANNELS_MAX );
1611 : }
1612 : }
1613 : }
1614 :
1615 7369266 : for ( chIdx = 0; chIdx < hBinRenderer->hInputSetup->nchan_out_woLFE; chIdx++ )
1616 : {
1617 34399872 : for ( k = 0; k < numTimeSlots; k++ )
1618 : {
1619 27514128 : mvr2r( RealBuffer[chIdx][k], RealBuffer_local[chIdx][k], CLDFB_NO_CHANNELS_MAX );
1620 27514128 : mvr2r( ImagBuffer[chIdx][k], ImagBuffer_local[chIdx][k], CLDFB_NO_CHANNELS_MAX );
1621 : }
1622 : }
1623 :
1624 : /* Head rotation in HOA3 or CICPx */
1625 483522 : if ( hCombinedOrientationData != NULL && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] && hBinRenderer->rotInCldfb )
1626 : {
1627 192333 : if ( hBinRenderer->hInputSetup->is_loudspeaker_setup == 0 )
1628 : {
1629 : /* Rotation in SHD (HOA3) */
1630 168333 : if ( hCombinedOrientationData->shd_rot_max_order == -1 )
1631 : {
1632 56733 : rotateFrame_shd_cldfb( RealBuffer, ImagBuffer, hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx], hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, 3 );
1633 : }
1634 111600 : else if ( hCombinedOrientationData->shd_rot_max_order > 0 )
1635 : {
1636 1200 : rotateFrame_shd_cldfb( RealBuffer, ImagBuffer, hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx], hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, hCombinedOrientationData->shd_rot_max_order );
1637 : }
1638 : }
1639 : else
1640 : {
1641 : /* Rotation in SD (CICPx) */
1642 24000 : rotateFrame_sd_cldfb( hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx], RealBuffer, ImagBuffer, hBinRenderer->hInputSetup, hBinRenderer->hEFAPdata, numTimeSlots, hBinRenderer->conv_band );
1643 : }
1644 : }
1645 :
1646 : /* HOA decoding to CICP19 if needed*/
1647 483522 : if ( hBinRenderer->hInputSetup->is_loudspeaker_setup == 0 &&
1648 385314 : ( hBinRenderer->nInChannels != HOA3_CHANNELS && hBinRenderer->nInChannels != HOA2_CHANNELS && hBinRenderer->nInChannels != FOA_CHANNELS ) )
1649 : {
1650 83988 : ivas_sba2mc_cldfb( *( hBinRenderer->hInputSetup ), RealBuffer, ImagBuffer, hBinRenderer->nInChannels, hBinRenderer->conv_band, numTimeSlots, hBinRenderer->hoa_dec_mtx );
1651 : }
1652 :
1653 483522 : ivas_binRenderer_filterModule( Cldfb_RealBuffer_Binaural[0], Cldfb_ImagBuffer_Binaural[0], RealBuffer, ImagBuffer, numTimeSlots, hBinRenderer, 0 );
1654 :
1655 483522 : if ( pMultiBinPoseData != NULL )
1656 : {
1657 0 : if ( pMultiBinPoseData->num_poses > 1 )
1658 : {
1659 : IVAS_QUATERNION Quaternions_rel, Quaternions_abs, *Quaternions_ref;
1660 : float Rmat_local[3][3];
1661 :
1662 0 : if ( hCombinedOrientationData && hBinRenderer->rotInCldfb )
1663 : {
1664 0 : Quaternions_ref = &hCombinedOrientationData->Quaternions[0];
1665 0 : Quaternions_rel.w = -3.0f; /*euler*/
1666 0 : Quaternions_abs.w = -3.0f;
1667 :
1668 0 : if ( hCombinedOrientationData->shd_rot_max_order == 0 )
1669 : {
1670 : /*HOA signal already rotated by DirAC*/
1671 0 : Quaternions_abs.x = 0.0f;
1672 0 : Quaternions_abs.y = 0.0f;
1673 0 : Quaternions_abs.z = 0.0f;
1674 : }
1675 : else
1676 : {
1677 : /*euler*/
1678 0 : Quat2EulerDegree( *Quaternions_ref, &Quaternions_abs.z, &Quaternions_abs.y, &Quaternions_abs.x ); /*order in Quat2Euler seems to be reversed ?*/
1679 : }
1680 :
1681 0 : for ( pos_idx = 1; pos_idx < pMultiBinPoseData->num_poses; pos_idx++ )
1682 : {
1683 0 : for ( chIdx = 0; chIdx < hBinRenderer->hInputSetup->nchan_out_woLFE; chIdx++ )
1684 : {
1685 0 : for ( k = 0; k < numTimeSlots; k++ )
1686 : {
1687 0 : mvr2r( RealBuffer_local[chIdx][k], RealBuffer[chIdx][k], CLDFB_NO_CHANNELS_MAX );
1688 0 : mvr2r( ImagBuffer_local[chIdx][k], ImagBuffer[chIdx][k], CLDFB_NO_CHANNELS_MAX );
1689 : }
1690 : }
1691 0 : Quaternions_rel.x = pMultiBinPoseData->relative_head_poses[pos_idx][0] - pMultiBinPoseData->relative_head_poses[pos_idx - 1][0];
1692 0 : Quaternions_rel.y = pMultiBinPoseData->relative_head_poses[pos_idx][1] - pMultiBinPoseData->relative_head_poses[pos_idx - 1][1];
1693 0 : Quaternions_rel.z = pMultiBinPoseData->relative_head_poses[pos_idx][2] - pMultiBinPoseData->relative_head_poses[pos_idx - 1][2];
1694 0 : Quaternions_abs.x = Quaternions_abs.x + Quaternions_rel.x;
1695 0 : Quaternions_abs.y = Quaternions_abs.y + Quaternions_rel.y;
1696 0 : Quaternions_abs.z = Quaternions_abs.z + Quaternions_rel.z;
1697 :
1698 0 : QuatToRotMat( Quaternions_abs, Rmat_local );
1699 :
1700 0 : if ( hBinRenderer->hInputSetup->is_loudspeaker_setup )
1701 : {
1702 0 : rotateFrame_sd_cldfb( Rmat_local, RealBuffer, ImagBuffer, hBinRenderer->hInputSetup, hBinRenderer->hEFAPdata, numTimeSlots, hBinRenderer->conv_band );
1703 : }
1704 : else
1705 : {
1706 0 : rotateFrame_shd_cldfb( RealBuffer, ImagBuffer, Rmat_local, hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, hBinRenderer->hInputSetup->ambisonics_order );
1707 : }
1708 :
1709 0 : ivas_binRenderer_filterModule( Cldfb_RealBuffer_Binaural[pos_idx], Cldfb_ImagBuffer_Binaural[pos_idx], RealBuffer, ImagBuffer, numTimeSlots, hBinRenderer, pos_idx );
1710 : }
1711 : }
1712 : }
1713 : }
1714 :
1715 : /* Obtain the binaural dmx and compute the reverb */
1716 483522 : if ( hBinRenderer->hReverb != NULL )
1717 : {
1718 : float reverbRe[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX];
1719 : float reverbIm[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX];
1720 : float inRe[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX];
1721 : float inIm[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX];
1722 :
1723 302550 : ivas_binaural_obtain_DMX( numTimeSlots, hBinRenderer, RealBuffer, ImagBuffer, inRe, inIm );
1724 :
1725 907650 : for ( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ )
1726 : {
1727 3021894 : for ( k = 0; k < numTimeSlots; k++ )
1728 : {
1729 2416794 : set_zero( reverbRe[chIdx][k], hBinRenderer->max_band );
1730 2416794 : set_zero( reverbIm[chIdx][k], hBinRenderer->max_band );
1731 : }
1732 : }
1733 :
1734 302550 : ivas_binaural_reverb_processSubframe( hBinRenderer->hReverb, BINAURAL_CHANNELS, numTimeSlots, inRe, inIm, reverbRe, reverbIm );
1735 :
1736 : /* Add the conv module and reverb module output */
1737 907650 : for ( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ )
1738 : {
1739 3021894 : for ( k = 0; k < numTimeSlots; k++ )
1740 : {
1741 4833588 : for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ )
1742 : {
1743 : /* Combine first and second parts to generate binaural output signal with room effect */
1744 2416794 : v_add( Cldfb_RealBuffer_Binaural[pos_idx][chIdx][k], reverbRe[chIdx][k], Cldfb_RealBuffer_Binaural[pos_idx][chIdx][k], hBinRenderer->conv_band );
1745 2416794 : v_add( Cldfb_ImagBuffer_Binaural[pos_idx][chIdx][k], reverbIm[chIdx][k], Cldfb_ImagBuffer_Binaural[pos_idx][chIdx][k], hBinRenderer->conv_band );
1746 : }
1747 : }
1748 : }
1749 : }
1750 :
1751 483522 : pop_wmops();
1752 483522 : return;
1753 : }
1754 :
1755 :
1756 : /*-------------------------------------------------------------------------
1757 : * ivas_rend_CldfbMultiBinRendProcess()
1758 : *
1759 : *
1760 : *-------------------------------------------------------------------------*/
1761 :
1762 0 : void ivas_rend_CldfbMultiBinRendProcess(
1763 : const BINAURAL_RENDERER_HANDLE hCldfbRend,
1764 : const COMBINED_ORIENTATION_HANDLE *pCombinedOrientationData,
1765 : const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
1766 : float Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
1767 : float Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
1768 : float Cldfb_Out_Real[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */
1769 : float Cldfb_Out_Imag[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
1770 : const int16_t low_res_pre_rend_rot,
1771 : const int16_t num_subframes )
1772 : {
1773 : int16_t slot_idx, ch_idx, idx, pose_idx, i, j;
1774 : int16_t sf_idx;
1775 : float Cldfb_RealBuffer_sfIn[MAX_INPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
1776 : float Cldfb_ImagBuffer_sfIn[MAX_INPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
1777 : #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
1778 : HEAD_TRACK_DATA head_track_post;
1779 : float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES + 1][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
1780 : float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES + 1][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
1781 : #else
1782 : float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
1783 : float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
1784 : #endif
1785 :
1786 0 : for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
1787 : {
1788 0 : for ( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ )
1789 : {
1790 0 : idx = sf_idx * MAX_PARAM_SPATIAL_SUBFRAMES + slot_idx;
1791 0 : for ( ch_idx = 0; ch_idx < hCldfbRend->nInChannels; ch_idx++ )
1792 : {
1793 0 : mvr2r( &Cldfb_In_Real[ch_idx][idx][0], &Cldfb_RealBuffer_sfIn[ch_idx][slot_idx][0], hCldfbRend->max_band );
1794 0 : mvr2r( &Cldfb_In_Imag[ch_idx][idx][0], &Cldfb_ImagBuffer_sfIn[ch_idx][slot_idx][0], hCldfbRend->max_band );
1795 : }
1796 : }
1797 :
1798 0 : if ( ( *pCombinedOrientationData ) != NULL )
1799 : {
1800 0 : if ( ( low_res_pre_rend_rot ) && ( pMultiBinPoseData->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) )
1801 : {
1802 0 : ( *pCombinedOrientationData )->Quaternions[sf_idx] = ( *pCombinedOrientationData )->Quaternions[0];
1803 0 : for ( i = 0; i < 3; i++ )
1804 : {
1805 0 : for ( j = 0; j < 3; j++ )
1806 : {
1807 0 : ( *pCombinedOrientationData )->Rmat[sf_idx][i][j] = ( *pCombinedOrientationData )->Rmat[0][i][j];
1808 : }
1809 : }
1810 : }
1811 0 : ( *pCombinedOrientationData )->shd_rot_max_order = -1;
1812 : }
1813 :
1814 : #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
1815 : head_track_post.num_quaternions = 0;
1816 : head_track_post.shd_rot_max_order = -1;
1817 : head_track_post.Quaternions[0] = ivas_split_rend_get_sf_rot_data( pHeadRotData->headPositionsPostRend, sf_idx );
1818 :
1819 : #endif
1820 : #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG
1821 : ivas_binRenderer( hCldfbRend, pMultiBinPoseData, *pCombinedOrientationData, MAX_PARAM_SPATIAL_SUBFRAMES, &head_track_post, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer_sfIn, Cldfb_ImagBuffer_sfIn );
1822 : #else
1823 0 : ivas_binRenderer( hCldfbRend, pMultiBinPoseData, *pCombinedOrientationData, MAX_PARAM_SPATIAL_SUBFRAMES, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer_sfIn, Cldfb_ImagBuffer_sfIn );
1824 : #endif
1825 :
1826 0 : for ( pose_idx = 0; pose_idx < hCldfbRend->numPoses; pose_idx++ )
1827 : {
1828 0 : for ( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ )
1829 : {
1830 0 : idx = sf_idx * MAX_PARAM_SPATIAL_SUBFRAMES + slot_idx;
1831 0 : for ( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ )
1832 : {
1833 0 : mvr2r( &Cldfb_RealBuffer_Binaural[pose_idx][ch_idx][slot_idx][0], &Cldfb_Out_Real[( pose_idx * BINAURAL_CHANNELS ) + ch_idx][idx][0], hCldfbRend->max_band );
1834 0 : mvr2r( &Cldfb_ImagBuffer_Binaural[pose_idx][ch_idx][slot_idx][0], &Cldfb_Out_Imag[( pose_idx * BINAURAL_CHANNELS ) + ch_idx][idx][0], hCldfbRend->max_band );
1835 : }
1836 : }
1837 : }
1838 : }
1839 :
1840 0 : return;
1841 : }
|