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_fx.h"
37 : #include "ivas_prot_rend_fx.h"
38 : #include "cnst.h"
39 : #include "ivas_cnst.h"
40 : #include "ivas_rom_rend.h"
41 : #include "ivas_rom_dec.h"
42 : #include "ivas_rom_com.h"
43 : #include "ivas_rom_binauralRenderer.h"
44 : #include "wmc_auto.h"
45 : #include "ivas_prot_fx.h"
46 : #include "ivas_rom_com_fx.h"
47 : #include "debug.h"
48 : #define NUM_TAPS_F0_6 ( Word16 )( 58 ) // (Word16) ceil( 0.6f * hBinRenConvModule->numTaps )
49 : #define NUM_TAPS_F0_5 ( Word16 )( 48 ) // (Word16) ceil( 0.5f * hBinRenConvModule->numTaps )
50 : #define NUM_TAPS_F0_4 ( Word16 )( 39 ) // (Word16) ceil( 0.4f * hBinRenConvModule->numTaps )
51 : #define NUM_TAPS_F0_3 ( Word16 )( 29 ) // (Word16) ceil( 0.3f * hBinRenConvModule->numTaps )
52 :
53 : #ifdef FIX_1053_REVERB_RECONFIGURATION
54 : /*----------------------------------------------------------------------------------*
55 : * Local constants
56 : *----------------------------------------------------------------------------------*/
57 :
58 : #define REVERB_INPUT_DOWNMIX_CHANNELS ( 11 )
59 : /* Downmix table for sparse frequency domain reverberator*/
60 : const Word32 dmxmtx_table_fx[BINAURAL_CHANNELS][REVERB_INPUT_DOWNMIX_CHANNELS] = {
61 : // Q31
62 : { 0x7fffffff, 0, 1518485623, 0x7fffffff, 0, 0x7fffffff, 0, 0x7fffffff, 0, 0x7fffffff, 0 },
63 : { 0, 0x7fffffff, 1518485623, 0, 0x7fffffff, 0, 0x7fffffff, 0, 0x7fffffff, 0, 0x7fffffff },
64 : };
65 : #endif
66 :
67 : /*-------------------------------------------------------------------------
68 : * ivas_binRenderer_filterModule_fx()
69 : *
70 : *
71 : *-------------------------------------------------------------------------*/
72 155629 : static void ivas_binRenderer_filterModule_fx(
73 : Word32 out_Conv_CLDFB_real[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : real part of Binaural signals Q6 */
74 : Word32 out_Conv_CLDFB_imag[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : imag part of Binaural signals Q6 */
75 : Word32 CLDFB_real[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : real part of LS signals Q_curr*/
76 : Word32 CLDFB_imag[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : imag part of LS signals Q_curr*/
77 : const Word16 numTimeSlots, /* i : number of time slots to process */
78 : BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: fastconv binaural renderer handle */
79 : const Word16 pos_idx, /* i : pose index */
80 : Word16 Q_curr )
81 : {
82 : Word16 bandIdx, k, chIdx, tapIdx;
83 : Word32 *filterStatesLeftRealPtr_fx, *filterStatesLeftImagPtr_fx;
84 : Word16 Q_filterStates;
85 : const Word32 *filterTapsLeftRealPtr_fx, *filterTapsLeftImagPtr_fx, *filterTapsRightRealPtr_fx, *filterTapsRightImagPtr_fx;
86 : Word16 shift_q;
87 155629 : Word16 shift_q6 = sub( -29 + 6, Q_curr );
88 155629 : Q_filterStates = hBinRenderer->hBinRenConvModule->Q_filterStates[pos_idx];
89 155629 : move16();
90 :
91 155629 : shift_q = add( sub( Q_filterStates, Q_curr ), 1 );
92 155629 : hBinRenderer->hBinRenConvModule->Q_filterStates[pos_idx] = Q_curr;
93 :
94 7237689 : FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
95 : {
96 35307460 : FOR( k = 0; k < numTimeSlots; k++ )
97 : {
98 28225400 : Word64 outRealLeft_fx = 0, outRealRight_fx = 0, outImagLeft_fx = 0, outImagRight_fx = 0;
99 28225400 : move64();
100 28225400 : move64();
101 28225400 : move64();
102 28225400 : move64();
103 28225400 : Word64 outRealLeft = 0, outRealRight = 0, outImagLeft = 0, outImagRight = 0;
104 28225400 : move64();
105 28225400 : move64();
106 28225400 : move64();
107 28225400 : move64();
108 :
109 402693400 : FOR( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ )
110 : {
111 374468000 : filterStatesLeftRealPtr_fx = (Word32 *) &( hBinRenderer->hBinRenConvModule->filterStatesLeftReal_fx[pos_idx][bandIdx][chIdx][0] );
112 374468000 : filterStatesLeftImagPtr_fx = (Word32 *) &( hBinRenderer->hBinRenConvModule->filterStatesLeftImag_fx[pos_idx][bandIdx][chIdx][0] );
113 :
114 374468000 : filterTapsLeftRealPtr_fx = hBinRenderer->hBinRenConvModule->filterTapsLeftReal_fx[bandIdx][chIdx]; // Q29
115 374468000 : filterTapsLeftImagPtr_fx = hBinRenderer->hBinRenConvModule->filterTapsLeftImag_fx[bandIdx][chIdx]; // Q29
116 374468000 : filterTapsRightRealPtr_fx = hBinRenderer->hBinRenConvModule->filterTapsRightReal_fx[bandIdx][chIdx]; // Q29
117 374468000 : filterTapsRightImagPtr_fx = hBinRenderer->hBinRenConvModule->filterTapsRightImag_fx[bandIdx][chIdx]; // Q29
118 :
119 4837786400 : FOR( tapIdx = hBinRenderer->hBinRenConvModule->numTapsArray[bandIdx] - 1; tapIdx > 0; tapIdx-- )
120 : {
121 4463318400 : filterStatesLeftRealPtr_fx[tapIdx] = filterStatesLeftRealPtr_fx[tapIdx - 1];
122 4463318400 : move32();
123 4463318400 : filterStatesLeftImagPtr_fx[tapIdx] = filterStatesLeftImagPtr_fx[tapIdx - 1];
124 4463318400 : move32();
125 4463318400 : Word32 neg_filterStatesLeftImagPtr_fx = L_negate( filterStatesLeftImagPtr_fx[tapIdx] );
126 :
127 :
128 4463318400 : outRealLeft_fx = W_mac_32_32( outRealLeft_fx, filterStatesLeftRealPtr_fx[tapIdx], filterTapsLeftRealPtr_fx[tapIdx] ); // Q30 + Q_filterStates
129 4463318400 : outRealLeft_fx = W_mac_32_32( outRealLeft_fx, neg_filterStatesLeftImagPtr_fx, filterTapsLeftImagPtr_fx[tapIdx] ); // Q30 + Q_filterStates
130 :
131 4463318400 : outImagLeft_fx = W_mac_32_32( outImagLeft_fx, filterStatesLeftRealPtr_fx[tapIdx], filterTapsLeftImagPtr_fx[tapIdx] ); // Q30 + Q_filterStates
132 4463318400 : outImagLeft_fx = W_mac_32_32( outImagLeft_fx, filterStatesLeftImagPtr_fx[tapIdx], filterTapsLeftRealPtr_fx[tapIdx] ); // Q30 + Q_filterStates
133 :
134 4463318400 : outRealRight_fx = W_mac_32_32( outRealRight_fx, filterStatesLeftRealPtr_fx[tapIdx], filterTapsRightRealPtr_fx[tapIdx] ); // Q30 + Q_filterStates
135 4463318400 : outRealRight_fx = W_mac_32_32( outRealRight_fx, neg_filterStatesLeftImagPtr_fx, filterTapsRightImagPtr_fx[tapIdx] ); // Q30 + Q_filterStates
136 :
137 4463318400 : outImagRight_fx = W_mac_32_32( outImagRight_fx, filterStatesLeftRealPtr_fx[tapIdx], filterTapsRightImagPtr_fx[tapIdx] ); // Q30 + Q_filterStates
138 4463318400 : outImagRight_fx = W_mac_32_32( outImagRight_fx, filterStatesLeftImagPtr_fx[tapIdx], filterTapsRightRealPtr_fx[tapIdx] ); // Q30 + Q_filterStates
139 : }
140 :
141 374468000 : filterStatesLeftRealPtr_fx[0] = CLDFB_real[chIdx][k][bandIdx];
142 374468000 : move32();
143 374468000 : filterStatesLeftImagPtr_fx[0] = CLDFB_imag[chIdx][k][bandIdx];
144 374468000 : move32();
145 :
146 : /* Left Real and Imag */
147 374468000 : Word32 neg_temp2 = L_negate( filterStatesLeftImagPtr_fx[0] ); // Q_curr
148 :
149 374468000 : outRealLeft = W_mac_32_32( W_mac_32_32( outRealLeft, filterStatesLeftRealPtr_fx[0], filterTapsLeftRealPtr_fx[0] ), neg_temp2, filterTapsLeftImagPtr_fx[0] );
150 374468000 : outImagLeft = W_mac_32_32( W_mac_32_32( outImagLeft, filterStatesLeftImagPtr_fx[0], filterTapsLeftRealPtr_fx[0] ), filterStatesLeftRealPtr_fx[0], filterTapsLeftImagPtr_fx[0] );
151 :
152 : /* Right Real and Imag */
153 374468000 : outRealRight = W_mac_32_32( W_mac_32_32( outRealRight, neg_temp2, filterTapsRightImagPtr_fx[0] ), filterStatesLeftRealPtr_fx[0], filterTapsRightRealPtr_fx[0] );
154 374468000 : outImagRight = W_mac_32_32( W_mac_32_32( outImagRight, filterStatesLeftImagPtr_fx[0], filterTapsRightRealPtr_fx[0] ), filterStatesLeftRealPtr_fx[0], filterTapsRightImagPtr_fx[0] );
155 : }
156 28225400 : out_Conv_CLDFB_real[0][k][bandIdx] = W_shl_sat_l( W_add( W_shr( outRealLeft_fx, shift_q ), W_shr( outRealLeft, 1 ) ), shift_q6 );
157 28225400 : out_Conv_CLDFB_real[1][k][bandIdx] = W_shl_sat_l( W_add( W_shr( outRealRight_fx, shift_q ), W_shr( outRealRight, 1 ) ), shift_q6 );
158 28225400 : out_Conv_CLDFB_imag[0][k][bandIdx] = W_shl_sat_l( W_add( W_shr( outImagLeft_fx, shift_q ), W_shr( outImagLeft, 1 ) ), shift_q6 );
159 28225400 : out_Conv_CLDFB_imag[1][k][bandIdx] = W_shl_sat_l( W_add( W_shr( outImagRight_fx, shift_q ), W_shr( outImagRight, 1 ) ), shift_q6 );
160 28225400 : move32();
161 28225400 : move32();
162 28225400 : move32();
163 28225400 : move32();
164 : }
165 : }
166 :
167 :
168 155629 : return;
169 : }
170 :
171 : /*-------------------------------------------------------------------------
172 : * ivas_binRenderer_convModuleOpen()
173 : *
174 : * Open convolution module handle of fastconv binaural renderer
175 : *-------------------------------------------------------------------------*/
176 327 : static ivas_error ivas_binRenderer_convModuleOpen(
177 : BINAURAL_RENDERER_HANDLE hBinRenderer,
178 : const Word16 renderer_type,
179 : const Word16 isLoudspeaker,
180 : const AUDIO_CONFIG input_config,
181 : const HRTFS_FASTCONV_HANDLE hHrtf,
182 : const Word16 num_poses )
183 : {
184 : Word16 bandIdx, chIdx;
185 : Word16 pos_idx;
186 :
187 : BINRENDERER_CONV_MODULE_HANDLE_FX hBinRenConvModule;
188 :
189 : /*-----------------------------------------------------------------*
190 : * prepare library opening
191 : *-----------------------------------------------------------------*/
192 :
193 327 : IF( ( hBinRenConvModule = (BINRENDERER_CONV_MODULE_HANDLE_FX) malloc( sizeof( BINRENDERER_CONV_MODULE_FX ) ) ) == NULL )
194 : {
195 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
196 : }
197 :
198 327 : IF( !isLoudspeaker )
199 : {
200 174 : hBinRenderer->nInChannels = audioCfg2channels( input_config );
201 174 : move16();
202 : }
203 : ELSE
204 : {
205 : /* Note: needs to be revisited if multiple LFE support is required */
206 153 : hBinRenderer->nInChannels = sub( audioCfg2channels( input_config ), isLoudspeaker );
207 153 : move16();
208 : }
209 :
210 327 : IF( EQ_16( renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) )
211 : {
212 69 : hBinRenConvModule->numTaps = BINAURAL_NTAPS_MAX;
213 69 : move16();
214 :
215 : /* Use variable order filtering */
216 69 : bandIdx = 0;
217 69 : move16();
218 414 : FOR( ; bandIdx < 5; bandIdx++ )
219 : {
220 345 : hBinRenConvModule->numTapsArray[bandIdx] = hBinRenConvModule->numTaps;
221 345 : move16();
222 : }
223 414 : FOR( ; bandIdx < 10; bandIdx++ )
224 : {
225 345 : hBinRenConvModule->numTapsArray[bandIdx] = NUM_TAPS_F0_6;
226 345 : move16();
227 : }
228 759 : FOR( ; bandIdx < 20; bandIdx++ )
229 : {
230 690 : hBinRenConvModule->numTapsArray[bandIdx] = NUM_TAPS_F0_5;
231 690 : move16();
232 : }
233 759 : FOR( ; bandIdx < 30; bandIdx++ )
234 : {
235 690 : hBinRenConvModule->numTapsArray[bandIdx] = NUM_TAPS_F0_4;
236 690 : move16();
237 : }
238 1319 : FOR( ; bandIdx < hBinRenderer->conv_band; bandIdx++ )
239 : {
240 1250 : hBinRenConvModule->numTapsArray[bandIdx] = NUM_TAPS_F0_3;
241 1250 : move16();
242 : }
243 : }
244 : ELSE
245 : {
246 258 : IF( EQ_16( hBinRenderer->ivas_format, SBA_FORMAT ) )
247 : {
248 174 : hBinRenConvModule->numTaps = BINAURAL_NTAPS_SBA;
249 174 : move16();
250 : }
251 : ELSE
252 : {
253 84 : hBinRenConvModule->numTaps = BINAURAL_NTAPS;
254 84 : move16();
255 : }
256 :
257 : /* Use fixed order filtering */
258 258 : bandIdx = 0;
259 258 : move16();
260 10318 : FOR( ; bandIdx < hBinRenderer->conv_band; bandIdx++ )
261 : {
262 10060 : hBinRenConvModule->numTapsArray[bandIdx] = hBinRenConvModule->numTaps;
263 10060 : move16();
264 : }
265 : }
266 :
267 : /* allocate memory for filter states */
268 327 : IF( ( hBinRenConvModule->filterTapsLeftReal_fx = (Word32 ***) malloc( hBinRenderer->conv_band * sizeof( Word32 ** ) ) ) == NULL )
269 : {
270 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
271 : }
272 :
273 327 : IF( ( hBinRenConvModule->filterTapsLeftImag_fx = (Word32 ***) malloc( hBinRenderer->conv_band * sizeof( Word32 ** ) ) ) == NULL )
274 : {
275 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
276 : }
277 :
278 327 : IF( ( hBinRenConvModule->filterTapsRightReal_fx = (Word32 ***) malloc( hBinRenderer->conv_band * sizeof( Word32 ** ) ) ) == NULL )
279 : {
280 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
281 : }
282 :
283 327 : IF( ( hBinRenConvModule->filterTapsRightImag_fx = (Word32 ***) malloc( hBinRenderer->conv_band * sizeof( Word32 ** ) ) ) == NULL )
284 : {
285 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
286 : }
287 :
288 13677 : FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
289 : {
290 13350 : IF( ( hBinRenConvModule->filterTapsLeftReal_fx[bandIdx] = (Word32 **) malloc( hBinRenderer->nInChannels * sizeof( Word32 * ) ) ) == NULL )
291 : {
292 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
293 : }
294 :
295 13350 : IF( ( hBinRenConvModule->filterTapsLeftImag_fx[bandIdx] = (Word32 **) malloc( hBinRenderer->nInChannels * sizeof( Word32 * ) ) ) == NULL )
296 : {
297 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
298 : }
299 :
300 13350 : IF( ( hBinRenConvModule->filterTapsRightReal_fx[bandIdx] = (Word32 **) malloc( hBinRenderer->nInChannels * sizeof( Word32 * ) ) ) == NULL )
301 : {
302 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
303 : }
304 :
305 13350 : IF( ( hBinRenConvModule->filterTapsRightImag_fx[bandIdx] = (Word32 **) malloc( hBinRenderer->nInChannels * sizeof( Word32 * ) ) ) == NULL )
306 : {
307 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
308 : }
309 : }
310 :
311 327 : IF( ( hBinRenConvModule->filterStatesLeftReal_fx = (Word32 ****) malloc( num_poses * sizeof( Word32 *** ) ) ) == NULL )
312 : {
313 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
314 : }
315 :
316 327 : IF( ( hBinRenConvModule->filterStatesLeftImag_fx = (Word32 ****) malloc( num_poses * sizeof( Word32 *** ) ) ) == NULL )
317 : {
318 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
319 : }
320 :
321 327 : IF( ( hBinRenConvModule->Q_filterStates = (Word16 *) malloc( num_poses * sizeof( Word16 ) ) ) == NULL )
322 : {
323 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
324 : }
325 :
326 654 : FOR( pos_idx = 0; pos_idx < num_poses; pos_idx++ )
327 : {
328 327 : IF( ( hBinRenConvModule->filterStatesLeftReal_fx[pos_idx] = (Word32 ***) malloc( hBinRenderer->conv_band * sizeof( Word32 ** ) ) ) == NULL )
329 : {
330 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
331 : }
332 :
333 327 : IF( ( hBinRenConvModule->filterStatesLeftImag_fx[pos_idx] = (Word32 ***) malloc( hBinRenderer->conv_band * sizeof( Word32 ** ) ) ) == NULL )
334 : {
335 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
336 : }
337 :
338 :
339 13677 : FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
340 : {
341 13350 : IF( ( hBinRenConvModule->filterStatesLeftReal_fx[pos_idx][bandIdx] = (Word32 **) malloc( hBinRenderer->nInChannels * sizeof( Word32 * ) ) ) == NULL )
342 : {
343 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
344 : }
345 :
346 13350 : IF( ( hBinRenConvModule->filterStatesLeftImag_fx[pos_idx][bandIdx] = (Word32 **) malloc( hBinRenderer->nInChannels * sizeof( Word32 * ) ) ) == NULL )
347 : {
348 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
349 : }
350 :
351 :
352 167180 : FOR( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ )
353 : {
354 153830 : IF( ( hBinRenConvModule->filterStatesLeftReal_fx[pos_idx][bandIdx][chIdx] = (Word32 *) malloc( hBinRenConvModule->numTapsArray[bandIdx] * sizeof( Word32 ) ) ) == NULL )
355 : {
356 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
357 : }
358 :
359 153830 : IF( ( hBinRenConvModule->filterStatesLeftImag_fx[pos_idx][bandIdx][chIdx] = (Word32 *) malloc( hBinRenConvModule->numTapsArray[bandIdx] * sizeof( Word32 ) ) ) == NULL )
360 : {
361 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
362 : }
363 : }
364 : }
365 : }
366 :
367 : /* set memories */
368 13677 : FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
369 : {
370 167180 : FOR( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ )
371 : {
372 153830 : Word16 tmp = 0;
373 153830 : move16();
374 :
375 153830 : IF( isLoudspeaker )
376 : {
377 34150 : IF( EQ_16( input_config, IVAS_AUDIO_CONFIG_5_1 ) )
378 : {
379 25150 : tmp = channelIndex_CICP6[chIdx];
380 25150 : move16();
381 : }
382 9000 : ELSE IF( EQ_16( input_config, IVAS_AUDIO_CONFIG_7_1 ) )
383 : {
384 0 : tmp = channelIndex_CICP12[chIdx];
385 0 : move16();
386 : }
387 9000 : ELSE IF( EQ_16( input_config, IVAS_AUDIO_CONFIG_5_1_2 ) )
388 : {
389 420 : tmp = channelIndex_CICP14[chIdx];
390 420 : move16();
391 : }
392 8580 : ELSE IF( EQ_16( input_config, IVAS_AUDIO_CONFIG_5_1_4 ) )
393 : {
394 0 : tmp = channelIndex_CICP16[chIdx];
395 0 : move16();
396 : }
397 8580 : ELSE IF( EQ_16( input_config, IVAS_AUDIO_CONFIG_7_1_4 ) )
398 : {
399 8580 : tmp = channelIndex_CICP19[chIdx];
400 8580 : move16();
401 : }
402 : }
403 :
404 153830 : IF( EQ_16( renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) )
405 : {
406 : /* set the memories to zero */
407 19150 : IF( isLoudspeaker )
408 : {
409 19150 : hBinRenConvModule->filterTapsLeftReal_fx[bandIdx][chIdx] = hHrtf->leftBRIRReal_fx[bandIdx][tmp];
410 19150 : hBinRenConvModule->filterTapsLeftImag_fx[bandIdx][chIdx] = hHrtf->leftBRIRImag_fx[bandIdx][tmp];
411 19150 : hBinRenConvModule->filterTapsRightReal_fx[bandIdx][chIdx] = hHrtf->rightBRIRReal_fx[bandIdx][tmp];
412 19150 : hBinRenConvModule->filterTapsRightImag_fx[bandIdx][chIdx] = hHrtf->rightBRIRImag_fx[bandIdx][tmp];
413 : }
414 : }
415 : ELSE
416 : {
417 : /* set the memories to zero */
418 134680 : IF( isLoudspeaker )
419 : {
420 15000 : hBinRenConvModule->filterTapsLeftReal_fx[bandIdx][chIdx] = hHrtf->leftHRIRReal_fx[bandIdx][tmp];
421 15000 : hBinRenConvModule->filterTapsLeftImag_fx[bandIdx][chIdx] = hHrtf->leftHRIRImag_fx[bandIdx][tmp];
422 15000 : hBinRenConvModule->filterTapsRightReal_fx[bandIdx][chIdx] = hHrtf->rightHRIRReal_fx[bandIdx][tmp];
423 15000 : hBinRenConvModule->filterTapsRightImag_fx[bandIdx][chIdx] = hHrtf->rightHRIRImag_fx[bandIdx][tmp];
424 : }
425 : ELSE
426 : {
427 119680 : IF( EQ_16( input_config, IVAS_AUDIO_CONFIG_HOA3 ) )
428 : {
429 : /* HOA3 filter coefficients */
430 119680 : hBinRenConvModule->filterTapsLeftReal_fx[bandIdx][chIdx] = hHrtf->leftHRIRReal_HOA3_fx[bandIdx][chIdx];
431 119680 : hBinRenConvModule->filterTapsLeftImag_fx[bandIdx][chIdx] = hHrtf->leftHRIRImag_HOA3_fx[bandIdx][chIdx];
432 119680 : hBinRenConvModule->filterTapsRightReal_fx[bandIdx][chIdx] = hHrtf->rightHRIRReal_HOA3_fx[bandIdx][chIdx];
433 119680 : hBinRenConvModule->filterTapsRightImag_fx[bandIdx][chIdx] = hHrtf->rightHRIRImag_HOA3_fx[bandIdx][chIdx];
434 : }
435 0 : ELSE IF( EQ_16( input_config, IVAS_AUDIO_CONFIG_HOA2 ) )
436 : {
437 : /* HOA2 filter coefficients */
438 0 : hBinRenConvModule->filterTapsLeftReal_fx[bandIdx][chIdx] = hHrtf->leftHRIRReal_HOA2_fx[bandIdx][chIdx];
439 0 : hBinRenConvModule->filterTapsLeftImag_fx[bandIdx][chIdx] = hHrtf->leftHRIRImag_HOA2_fx[bandIdx][chIdx];
440 0 : hBinRenConvModule->filterTapsRightReal_fx[bandIdx][chIdx] = hHrtf->rightHRIRReal_HOA2_fx[bandIdx][chIdx];
441 0 : hBinRenConvModule->filterTapsRightImag_fx[bandIdx][chIdx] = hHrtf->rightHRIRImag_HOA2_fx[bandIdx][chIdx];
442 : }
443 0 : ELSE IF( EQ_16( input_config, IVAS_AUDIO_CONFIG_FOA ) )
444 : {
445 : /* FOA filter coefficients */
446 0 : hBinRenConvModule->filterTapsLeftReal_fx[bandIdx][chIdx] = hHrtf->leftHRIRReal_FOA_fx[bandIdx][chIdx];
447 0 : hBinRenConvModule->filterTapsLeftImag_fx[bandIdx][chIdx] = hHrtf->leftHRIRImag_FOA_fx[bandIdx][chIdx];
448 0 : hBinRenConvModule->filterTapsRightReal_fx[bandIdx][chIdx] = hHrtf->rightHRIRReal_FOA_fx[bandIdx][chIdx];
449 0 : hBinRenConvModule->filterTapsRightImag_fx[bandIdx][chIdx] = hHrtf->rightHRIRImag_FOA_fx[bandIdx][chIdx];
450 : }
451 : ELSE
452 : {
453 0 : return IVAS_ERR_INVALID_INPUT_FORMAT;
454 : }
455 : }
456 : }
457 : }
458 : }
459 :
460 327 : IF( EQ_16( renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) )
461 : {
462 138 : FOR( pos_idx = 0; pos_idx < num_poses; pos_idx++ )
463 : {
464 69 : hBinRenConvModule->Q_filterStates[pos_idx] = 31;
465 69 : move16();
466 3359 : FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
467 : {
468 22440 : FOR( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ )
469 : {
470 : /* set the memories to zero */
471 19150 : set32_fx( hBinRenConvModule->filterStatesLeftReal_fx[pos_idx][bandIdx][chIdx], 0, hBinRenConvModule->numTapsArray[bandIdx] );
472 19150 : set32_fx( hBinRenConvModule->filterStatesLeftImag_fx[pos_idx][bandIdx][chIdx], 0, hBinRenConvModule->numTapsArray[bandIdx] );
473 : }
474 : }
475 : }
476 : }
477 : ELSE
478 : {
479 516 : FOR( pos_idx = 0; pos_idx < num_poses; pos_idx++ )
480 : {
481 258 : hBinRenConvModule->Q_filterStates[pos_idx] = 31;
482 258 : move16();
483 10318 : FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
484 : {
485 144740 : FOR( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ )
486 : {
487 : /* set the memories to zero */
488 134680 : set32_fx( hBinRenConvModule->filterStatesLeftReal_fx[pos_idx][bandIdx][chIdx], 0, hBinRenConvModule->numTaps );
489 134680 : set32_fx( hBinRenConvModule->filterStatesLeftImag_fx[pos_idx][bandIdx][chIdx], 0, hBinRenConvModule->numTaps );
490 : }
491 : }
492 : }
493 : }
494 :
495 327 : hBinRenderer->hBinRenConvModule = hBinRenConvModule;
496 :
497 327 : return IVAS_ERR_OK;
498 : }
499 :
500 : /*-------------------------------------------------------------------------*
501 : * ivas_init_binaural_hrtf()
502 : *
503 : * initialize memory for HrtfFastConv structure elements
504 : *-------------------------------------------------------------------------*/
505 68 : void ivas_init_binaural_hrtf_fx(
506 : HRTFS_FASTCONV *HrtfFastConv /* i/o: FASTCONV HRTF structure */
507 : )
508 : {
509 : Word16 i;
510 :
511 68 : HrtfFastConv->leftHRIRReal_HOA3_fx = NULL;
512 68 : HrtfFastConv->leftHRIRImag_HOA3_fx = NULL;
513 68 : HrtfFastConv->rightHRIRReal_HOA3_fx = NULL;
514 68 : HrtfFastConv->rightHRIRImag_HOA3_fx = NULL;
515 68 : HrtfFastConv->FASTCONV_HOA3_latency_s_fx = 0;
516 68 : move32();
517 :
518 68 : HrtfFastConv->leftHRIRReal_fx = NULL;
519 68 : HrtfFastConv->leftHRIRImag_fx = NULL;
520 68 : HrtfFastConv->rightHRIRReal_fx = NULL;
521 68 : HrtfFastConv->rightHRIRImag_fx = NULL;
522 68 : HrtfFastConv->FASTCONV_HRIR_latency_s_fx = 0;
523 68 : move32();
524 :
525 68 : HrtfFastConv->leftBRIRReal_fx = NULL;
526 68 : HrtfFastConv->leftBRIRImag_fx = NULL;
527 68 : HrtfFastConv->rightBRIRReal_fx = NULL;
528 68 : HrtfFastConv->rightBRIRImag_fx = NULL;
529 68 : HrtfFastConv->FASTCONV_BRIR_latency_s_fx = 0;
530 68 : move32();
531 :
532 68 : HrtfFastConv->leftHRIRReal_HOA2_fx = NULL;
533 68 : HrtfFastConv->leftHRIRImag_HOA2_fx = NULL;
534 68 : HrtfFastConv->rightHRIRReal_HOA2_fx = NULL;
535 68 : HrtfFastConv->rightHRIRImag_HOA2_fx = NULL;
536 68 : HrtfFastConv->FASTCONV_HOA2_latency_s_fx = 0;
537 68 : move32();
538 :
539 68 : HrtfFastConv->leftHRIRReal_FOA_fx = NULL;
540 68 : HrtfFastConv->leftHRIRImag_FOA_fx = NULL;
541 68 : HrtfFastConv->rightHRIRReal_FOA_fx = NULL;
542 68 : HrtfFastConv->rightHRIRImag_FOA_fx = NULL;
543 68 : HrtfFastConv->FASTCONV_FOA_latency_s_fx = 0;
544 68 : move32();
545 :
546 68 : HrtfFastConv->allocate_init_flag = 0;
547 68 : move16();
548 :
549 4148 : FOR( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ )
550 : {
551 4080 : HrtfFastConv->fastconvReverberationTimes_fx[i] = 0;
552 4080 : move32();
553 4080 : HrtfFastConv->fastconvReverberationEneCorrections_fx[i] = 0;
554 4080 : move32();
555 : }
556 :
557 68 : return;
558 : }
559 :
560 : /*-------------------------------------------------------------------------*
561 : * ivas_alloc_pppMem()
562 : *
563 : * Allocate memory for tripple pointer elements
564 : *-------------------------------------------------------------------------*/
565 788 : static ivas_error ivas_alloc_pppMem_fx(
566 : Word32 ****pppMem, /*Qx*/
567 : const Word16 dim1,
568 : const Word16 dim2,
569 : const Word16 dim3,
570 : const Word16 allocate_init_flag )
571 : {
572 : Word16 i, j;
573 788 : Word32 ***localMem = NULL;
574 :
575 788 : IF( ( localMem = (Word32 ***) malloc( dim1 * sizeof( Word32 ** ) ) ) == NULL )
576 : {
577 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HRTF memory" );
578 : }
579 :
580 40188 : FOR( i = 0; i < dim1; i++ ){
581 39400 : IF( ( localMem[i] = (Word32 **) malloc( dim2 * sizeof( Word32 * ) ) ) == NULL ){
582 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HRTF memory" );
583 : }
584 39400 : IF( allocate_init_flag == 0 )
585 : {
586 307200 : FOR( j = 0; j < dim2; j++ )
587 : {
588 283200 : IF( ( localMem[i][j] = (Word32 *) malloc( dim3 * sizeof( Word32 ) ) ) == NULL )
589 : {
590 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HRTF memory" );
591 : }
592 : }
593 : }
594 : }
595 :
596 788 : *pppMem = localMem;
597 :
598 788 : return IVAS_ERR_OK;
599 : }
600 :
601 : /*-------------------------------------------------------------------------*
602 : * ivas_allocate_binaural_hrtf()
603 : *
604 : * Allocate memory for HrtfFastConv structure elements
605 : *-------------------------------------------------------------------------*/
606 164 : ivas_error ivas_allocate_binaural_hrtf_fx(
607 : HRTFS_FASTCONV *HrtfFastConv, /* i/o: FASTCONV HRTF structure */
608 : const AUDIO_CONFIG input_config, /* i : input audio configuration */
609 : const BINAURAL_INPUT_AUDIO_CONFIG bin_input_config, /* i : binaural input audio config */
610 : const RENDERER_TYPE renderer_type, /* i : renderer type */
611 : const Word16 allocate_init_flag /* i : Memory allocation flag */
612 : )
613 : {
614 164 : test();
615 164 : IF( EQ_32( input_config, IVAS_AUDIO_CONFIG_HOA3 ) || EQ_32( bin_input_config, BINAURAL_INPUT_AUDIO_CONFIG_HOA3 ) )
616 : {
617 57 : test();
618 57 : test();
619 57 : test();
620 57 : IF( ( HrtfFastConv->leftHRIRReal_HOA3_fx != NULL ) && ( HrtfFastConv->leftHRIRImag_HOA3_fx != NULL ) && ( HrtfFastConv->rightHRIRReal_HOA3_fx != NULL ) && ( HrtfFastConv->rightHRIRImag_HOA3_fx != NULL ) )
621 : {
622 0 : return IVAS_ERR_OK;
623 : }
624 : ELSE
625 : {
626 57 : IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->leftHRIRReal_HOA3_fx, BINAURAL_CONVBANDS, HOA3_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) )
627 : {
628 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftHRIRReal_HOA3" );
629 : }
630 57 : IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->leftHRIRImag_HOA3_fx, BINAURAL_CONVBANDS, HOA3_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) )
631 : {
632 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftHRIRImag_HOA3" );
633 : }
634 57 : IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->rightHRIRReal_HOA3_fx, BINAURAL_CONVBANDS, HOA3_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) )
635 : {
636 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRReal_HOA3" );
637 : }
638 57 : IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->rightHRIRImag_HOA3_fx, BINAURAL_CONVBANDS, HOA3_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) )
639 : {
640 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRImag_HOA3" );
641 : }
642 : }
643 : }
644 :
645 164 : test();
646 164 : IF( EQ_32( input_config, IVAS_AUDIO_CONFIG_HOA2 ) || EQ_32( bin_input_config, BINAURAL_INPUT_AUDIO_CONFIG_HOA2 ) )
647 : {
648 24 : test();
649 24 : test();
650 24 : test();
651 24 : IF( ( HrtfFastConv->leftHRIRReal_HOA2_fx != NULL ) && ( HrtfFastConv->leftHRIRImag_HOA2_fx != NULL ) && ( HrtfFastConv->rightHRIRReal_HOA2_fx != NULL ) && ( HrtfFastConv->rightHRIRImag_HOA2_fx != NULL ) )
652 : {
653 0 : return IVAS_ERR_OK;
654 : }
655 : ELSE
656 : {
657 24 : IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->leftHRIRReal_HOA2_fx, BINAURAL_CONVBANDS, HOA2_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) )
658 : {
659 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftHRIRReal_HOA2" );
660 : }
661 24 : IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->leftHRIRImag_HOA2_fx, BINAURAL_CONVBANDS, HOA2_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) )
662 : {
663 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftHRIRImag_HOA2" );
664 : }
665 24 : IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->rightHRIRReal_HOA2_fx, BINAURAL_CONVBANDS, HOA2_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) )
666 : {
667 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRReal_HOA2" );
668 : }
669 24 : IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->rightHRIRImag_HOA2_fx, BINAURAL_CONVBANDS, HOA2_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) )
670 : {
671 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRImag_HOA2" );
672 : }
673 : }
674 : }
675 :
676 164 : test();
677 164 : IF( EQ_32( input_config, IVAS_AUDIO_CONFIG_FOA ) || EQ_32( bin_input_config, BINAURAL_INPUT_AUDIO_CONFIG_FOA ) )
678 : {
679 24 : test();
680 24 : test();
681 24 : test();
682 24 : IF( ( HrtfFastConv->leftHRIRReal_FOA_fx != NULL ) && ( HrtfFastConv->leftHRIRImag_FOA_fx != NULL ) && ( HrtfFastConv->rightHRIRReal_FOA_fx != NULL ) && ( HrtfFastConv->rightHRIRImag_FOA_fx != NULL ) )
683 : {
684 0 : return IVAS_ERR_OK;
685 : }
686 : ELSE
687 : {
688 24 : IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->leftHRIRReal_FOA_fx, BINAURAL_CONVBANDS, FOA_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) )
689 : {
690 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftHRIRReal_FOA" );
691 : }
692 24 : IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->leftHRIRImag_FOA_fx, BINAURAL_CONVBANDS, FOA_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) )
693 : {
694 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftHRIRImag_FOA" );
695 : }
696 24 : IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->rightHRIRReal_FOA_fx, BINAURAL_CONVBANDS, FOA_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) )
697 : {
698 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRReal_FOA" );
699 : }
700 24 : IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->rightHRIRImag_FOA_fx, BINAURAL_CONVBANDS, FOA_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) )
701 : {
702 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRImag_FOA" );
703 : }
704 : }
705 : }
706 :
707 164 : test();
708 164 : IF( EQ_32( renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_32( bin_input_config, BINAURAL_INPUT_AUDIO_CONFIG_COMBINED ) )
709 : {
710 151 : test();
711 151 : test();
712 151 : test();
713 151 : IF( ( HrtfFastConv->leftHRIRReal_fx != NULL ) && ( HrtfFastConv->leftHRIRImag_fx != NULL ) && ( HrtfFastConv->rightHRIRReal_fx != NULL ) && ( HrtfFastConv->rightHRIRImag_fx != NULL ) )
714 : {
715 96 : return IVAS_ERR_OK;
716 : }
717 : ELSE
718 : {
719 55 : IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->leftHRIRReal_fx, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS, allocate_init_flag ) ) )
720 : {
721 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftHRIRReal" );
722 : }
723 55 : IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->leftHRIRImag_fx, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS, allocate_init_flag ) ) )
724 : {
725 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftHRIRImag" );
726 : }
727 55 : IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->rightHRIRReal_fx, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS, allocate_init_flag ) ) )
728 : {
729 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRReal" );
730 : }
731 55 : IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->rightHRIRImag_fx, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS, allocate_init_flag ) ) )
732 : {
733 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRImag" );
734 : }
735 : }
736 : }
737 :
738 68 : test();
739 68 : IF( EQ_32( renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) || EQ_32( bin_input_config, BINAURAL_INPUT_AUDIO_CONFIG_COMBINED ) )
740 : {
741 37 : test();
742 37 : test();
743 37 : test();
744 37 : IF( ( HrtfFastConv->leftBRIRReal_fx != NULL ) && ( HrtfFastConv->leftBRIRImag_fx != NULL ) && ( HrtfFastConv->rightBRIRReal_fx != NULL ) && ( HrtfFastConv->rightBRIRImag_fx != NULL ) )
745 : {
746 0 : return IVAS_ERR_OK;
747 : }
748 : ELSE
749 : {
750 37 : IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->leftBRIRReal_fx, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS_MAX, allocate_init_flag ) ) )
751 : {
752 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftBRIRReal" );
753 : }
754 37 : IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->leftBRIRImag_fx, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS_MAX, allocate_init_flag ) ) )
755 : {
756 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftBRIRImag" );
757 : }
758 37 : IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->rightBRIRReal_fx, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS_MAX, allocate_init_flag ) ) )
759 : {
760 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightBRIRReal" );
761 : }
762 37 : IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->rightBRIRImag_fx, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS_MAX, allocate_init_flag ) ) )
763 : {
764 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightBRIRImag" );
765 : }
766 : }
767 : }
768 :
769 68 : return IVAS_ERR_OK;
770 : }
771 :
772 : /*-------------------------------------------------------------------------*
773 : * ivas_binaural_HRTF_open()
774 : *
775 : *
776 : *-------------------------------------------------------------------------*/
777 327 : static ivas_error ivas_binaural_hrtf_open_fx(
778 : HRTFS_FASTCONV_HANDLE *hHrtfFastConv, /* i : fastconv HRTF handle */
779 : const AUDIO_CONFIG input_config, /* i : output configuration */
780 : const RENDERER_TYPE renderer_type /* i : renderer type */
781 : )
782 : {
783 : Word16 i, j;
784 : ivas_error error;
785 :
786 327 : test();
787 327 : IF( hHrtfFastConv != NULL && *hHrtfFastConv != NULL )
788 : {
789 : /* Tables already loaded from file */
790 283 : return IVAS_ERR_OK;
791 : }
792 : ELSE
793 : {
794 : /* Initialise tables from ROM */
795 : HRTFS_FASTCONV *HrtfFastConv;
796 :
797 44 : IF( ( HrtfFastConv = (HRTFS_FASTCONV *) malloc( sizeof( HRTFS_FASTCONV ) ) ) == NULL )
798 : {
799 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate memory for FastConv HRTF tables" );
800 : }
801 :
802 44 : ivas_init_binaural_hrtf_fx( HrtfFastConv );
803 :
804 44 : test();
805 44 : IF( EQ_32( input_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( renderer_type, RENDERER_BINAURAL_FASTCONV ) )
806 : {
807 31 : HrtfFastConv->FASTCONV_HRIR_latency_s_fx = FASTCONV_HRIR_latency_s_fx;
808 31 : move32();
809 : }
810 44 : if ( EQ_32( input_config, IVAS_AUDIO_CONFIG_HOA2 ) )
811 : {
812 0 : HrtfFastConv->FASTCONV_HOA2_latency_s_fx = FASTCONV_HOA2_latency_s_fx;
813 0 : move32();
814 : }
815 44 : if ( EQ_32( input_config, IVAS_AUDIO_CONFIG_HOA3 ) )
816 : {
817 33 : HrtfFastConv->FASTCONV_HOA3_latency_s_fx = FASTCONV_HOA3_latency_s_fx;
818 33 : move32();
819 : }
820 44 : if ( EQ_32( input_config, IVAS_AUDIO_CONFIG_FOA ) )
821 : {
822 0 : HrtfFastConv->FASTCONV_FOA_latency_s_fx = FASTCONV_FOA_latency_s_fx;
823 0 : move32();
824 : }
825 44 : test();
826 44 : IF( EQ_32( input_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) )
827 : {
828 13 : HrtfFastConv->FASTCONV_BRIR_latency_s_fx = FASTCONV_BRIR_latency_s_fx;
829 13 : move32();
830 : }
831 :
832 44 : HrtfFastConv->allocate_init_flag = 1;
833 44 : move16();
834 :
835 44 : IF( NE_32( ( error = ivas_allocate_binaural_hrtf_fx( HrtfFastConv, input_config, BINAURAL_INPUT_AUDIO_CONFIG_INVALID, renderer_type, HrtfFastConv->allocate_init_flag ) ), IVAS_ERR_OK ) )
836 : {
837 0 : return error;
838 : }
839 2244 : FOR( i = 0; i < BINAURAL_CONVBANDS; i++ )
840 : {
841 2200 : IF( EQ_32( renderer_type, RENDERER_BINAURAL_FASTCONV ) )
842 : {
843 24800 : FOR( j = 0; j < HRTF_LS_CHANNELS; j++ )
844 : {
845 23250 : HrtfFastConv->leftHRIRReal_fx[i][j] = leftHRIRReal_fx[i][j];
846 23250 : HrtfFastConv->leftHRIRImag_fx[i][j] = leftHRIRImag_fx[i][j];
847 23250 : HrtfFastConv->rightHRIRReal_fx[i][j] = rightHRIRReal_fx[i][j];
848 23250 : HrtfFastConv->rightHRIRImag_fx[i][j] = rightHRIRImag_fx[i][j];
849 : }
850 : }
851 650 : ELSE IF( EQ_32( renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) )
852 : {
853 10400 : FOR( j = 0; j < HRTF_LS_CHANNELS; j++ )
854 : {
855 9750 : HrtfFastConv->leftBRIRReal_fx[i][j] = leftBRIRReal_fx[i][j];
856 9750 : HrtfFastConv->leftBRIRImag_fx[i][j] = leftBRIRImag_fx[i][j];
857 9750 : HrtfFastConv->rightBRIRReal_fx[i][j] = rightBRIRReal_fx[i][j];
858 9750 : HrtfFastConv->rightBRIRImag_fx[i][j] = rightBRIRImag_fx[i][j];
859 : }
860 : }
861 2200 : IF( EQ_32( input_config, IVAS_AUDIO_CONFIG_HOA3 ) )
862 : {
863 28050 : FOR( j = 0; j < HOA3_CHANNELS; j++ )
864 : {
865 26400 : HrtfFastConv->leftHRIRReal_HOA3_fx[i][j] = leftHRIRReal_HOA3_fx[i][j];
866 26400 : HrtfFastConv->leftHRIRImag_HOA3_fx[i][j] = leftHRIRImag_HOA3_fx[i][j];
867 26400 : HrtfFastConv->rightHRIRReal_HOA3_fx[i][j] = rightHRIRReal_HOA3_fx[i][j];
868 26400 : HrtfFastConv->rightHRIRImag_HOA3_fx[i][j] = rightHRIRImag_HOA3_fx[i][j];
869 : }
870 : }
871 2200 : IF( EQ_32( input_config, IVAS_AUDIO_CONFIG_HOA2 ) )
872 : {
873 0 : FOR( j = 0; j < HOA2_CHANNELS; j++ )
874 : {
875 0 : HrtfFastConv->leftHRIRReal_HOA2_fx[i][j] = leftHRIRReal_HOA2_fx[i][j];
876 0 : HrtfFastConv->leftHRIRImag_HOA2_fx[i][j] = leftHRIRImag_HOA2_fx[i][j];
877 0 : HrtfFastConv->rightHRIRReal_HOA2_fx[i][j] = rightHRIRReal_HOA2_fx[i][j];
878 0 : HrtfFastConv->rightHRIRImag_HOA2_fx[i][j] = rightHRIRImag_HOA2_fx[i][j];
879 : }
880 : }
881 2200 : IF( EQ_32( input_config, IVAS_AUDIO_CONFIG_FOA ) )
882 : {
883 0 : FOR( j = 0; j < FOA_CHANNELS; j++ )
884 : {
885 0 : HrtfFastConv->leftHRIRReal_FOA_fx[i][j] = leftHRIRReal_FOA_fx[i][j];
886 0 : HrtfFastConv->leftHRIRImag_FOA_fx[i][j] = leftHRIRImag_FOA_fx[i][j];
887 0 : HrtfFastConv->rightHRIRReal_FOA_fx[i][j] = rightHRIRReal_FOA_fx[i][j];
888 0 : HrtfFastConv->rightHRIRImag_FOA_fx[i][j] = rightHRIRImag_FOA_fx[i][j];
889 : }
890 : }
891 : }
892 44 : Copy32( fastconvReverberationTimes_fx, HrtfFastConv->fastconvReverberationTimes_fx, CLDFB_NO_CHANNELS_MAX );
893 44 : Copy32( fastconvReverberationEneCorrections_fx, HrtfFastConv->fastconvReverberationEneCorrections_fx, CLDFB_NO_CHANNELS_MAX );
894 :
895 44 : *hHrtfFastConv = HrtfFastConv;
896 : }
897 :
898 44 : return IVAS_ERR_OK;
899 : }
900 : /*-------------------------------------------------------------------------*
901 : * ivas_binaural_obtain_DMX_fx()
902 : *
903 : *
904 : *-------------------------------------------------------------------------*/
905 : #ifdef FIX_1939_REVERB_DMX_OUT_Q
906 101201 : static void ivas_binaural_obtain_DMX_fx(
907 : const Word16 numTimeSlots,
908 : BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: fastconv binaural renderer handle */
909 : Word32 RealBuffer[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : Contains the LS signals Q_in_out */
910 : Word32 ImagBuffer[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : Contains the LS signals Q_in_out */
911 : Word32 realDMX[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /*Q_in_out*/
912 : Word32 imagDMX[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /*Q_in_out*/
913 : Word16 *Q_in_out ) /*i/o: input and output Q*/
914 : #else
915 : static void ivas_binaural_obtain_DMX_fx(
916 : const Word16 numTimeSlots,
917 : BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: fastconv binaural renderer handle */
918 : Word32 RealBuffer[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : Contains the LS signals Q_in */
919 : Word32 ImagBuffer[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : Contains the LS signals Q_in */
920 : Word32 realDMX[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /*Q_in-1*/
921 : Word32 imagDMX[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] ) /*Q_in-1*/
922 : #endif
923 : {
924 : Word16 chIdx, bandIdx, k;
925 :
926 101201 : test();
927 101201 : IF( EQ_32( hBinRenderer->ivas_format, MC_FORMAT ) )
928 : {
929 : /* Obtain the downmix */
930 : Word32 P_in_fx[CLDFB_NO_CHANNELS_MAX];
931 : Word32 P_out_fx, factEQ_fx;
932 : Word16 chOutIdx;
933 : Word32 temp1_fx, temp2_fx;
934 :
935 137200 : FOR( k = 0; k < numTimeSlots; k++ )
936 : {
937 329280 : FOR( chOutIdx = 0; chOutIdx < BINAURAL_CHANNELS; chOutIdx++ )
938 : {
939 219520 : set32_fx( realDMX[chOutIdx][k], 0, CLDFB_NO_CHANNELS_MAX );
940 219520 : set32_fx( imagDMX[chOutIdx][k], 0, CLDFB_NO_CHANNELS_MAX );
941 : }
942 : }
943 :
944 82320 : FOR( chOutIdx = 0; chOutIdx < BINAURAL_CHANNELS; chOutIdx++ )
945 : {
946 54880 : set32_fx( P_in_fx, 0, hBinRenderer->conv_band );
947 :
948 480960 : FOR( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ )
949 : {
950 : #ifdef FIX_1053_REVERB_RECONFIGURATION
951 426080 : Word32 dmxConst = dmxmtx_table_fx[chOutIdx][chIdx];
952 : #else
953 : Word32 dmxConst = hBinRenderer->hReverb->dmxmtx_fx[chOutIdx][chIdx];
954 : move32();
955 : #endif
956 :
957 20391680 : FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
958 : {
959 99828000 : FOR( k = 0; k < numTimeSlots; k++ )
960 : {
961 79862400 : temp1_fx = Mpy_32_32( RealBuffer[chIdx][k][bandIdx], dmxConst ); // Q_in_out
962 79862400 : temp2_fx = Mpy_32_32( ImagBuffer[chIdx][k][bandIdx], dmxConst ); // Q_in_out
963 79862400 : realDMX[chOutIdx][k][bandIdx] = L_add( realDMX[chOutIdx][k][bandIdx], temp1_fx ); // Q_in_out
964 79862400 : move32();
965 79862400 : imagDMX[chOutIdx][k][bandIdx] = L_add( imagDMX[chOutIdx][k][bandIdx], temp2_fx ); // Q_in_out
966 79862400 : move32();
967 79862400 : P_in_fx[bandIdx] = L_add( P_in_fx[bandIdx], L_add( Mpy_32_32( temp1_fx, temp1_fx ), Mpy_32_32( temp2_fx, temp2_fx ) ) ); // Q31-2*Q_in_out
968 79862400 : move32();
969 : }
970 : }
971 : }
972 :
973 2630080 : FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
974 : {
975 2575200 : P_out_fx = 0;
976 2575200 : move32();
977 12876000 : FOR( k = 0; k < numTimeSlots; k++ )
978 : {
979 10300800 : temp1_fx = realDMX[chOutIdx][k][bandIdx];
980 10300800 : move32();
981 10300800 : temp2_fx = imagDMX[chOutIdx][k][bandIdx];
982 10300800 : move32();
983 10300800 : P_out_fx = L_add( P_out_fx, L_add( Mpy_32_32( temp1_fx, temp1_fx ), Mpy_32_32( temp2_fx, temp2_fx ) ) ); // Q31-2*Q_in_out
984 : }
985 2575200 : test();
986 2575200 : IF( ( P_in_fx[bandIdx] <= 0 ) || ( P_out_fx <= 0 ) )
987 : {
988 1546810 : factEQ_fx = 0x40000000; // 1.0f in Q30
989 1546810 : move32();
990 : }
991 : ELSE
992 : {
993 1028390 : Word16 div = divide3232( P_in_fx[bandIdx], P_out_fx );
994 1028390 : Word16 exp = 16; // divide3232 returns Q15
995 1028390 : factEQ_fx = Sqrt32( div, &exp );
996 1028390 : factEQ_fx = L_shl( factEQ_fx, sub( exp, 1 ) ); // Q30
997 : }
998 2575200 : if ( factEQ_fx <= 0 )
999 : {
1000 0 : factEQ_fx = 0x40000000; // 1.0f in Q30
1001 0 : move32();
1002 : }
1003 :
1004 2575200 : factEQ_fx = L_max( L_min( factEQ_fx, 0x7fffffff ), 0x20000000 ); // Q30 , 0x7fffffff -> (1.0f in Q31)-1, 0x20000000 ->1.0f in Q29
1005 12876000 : FOR( k = 0; k < numTimeSlots; k++ )
1006 : {
1007 10300800 : realDMX[chOutIdx][k][bandIdx] = Mpy_32_32( realDMX[chOutIdx][k][bandIdx], factEQ_fx ); // Q_in_out - 1
1008 10300800 : move32();
1009 10300800 : imagDMX[chOutIdx][k][bandIdx] = Mpy_32_32( imagDMX[chOutIdx][k][bandIdx], factEQ_fx ); // Q_in_out - 1
1010 10300800 : move32();
1011 : }
1012 : }
1013 : }
1014 : #ifdef FIX_1939_REVERB_DMX_OUT_Q
1015 27440 : *Q_in_out = sub( *Q_in_out, 1 );
1016 : #endif
1017 : }
1018 73761 : ELSE IF( EQ_32( hBinRenderer->ivas_format, SBA_FORMAT ) || EQ_32( hBinRenderer->ivas_format, MASA_FORMAT ) )
1019 : {
1020 : Word32 *outRealLeftPtr_fx, *outImagLeftPtr_fx, *outRealRightPtr_fx, *outImagRightPtr_fx;
1021 : Word32 *inRealPtr_fx, *inImagPtr_fx;
1022 :
1023 : /*compute DMX */
1024 366724 : FOR( k = 0; k < numTimeSlots; k++ )
1025 : {
1026 292963 : outRealLeftPtr_fx = realDMX[0][k];
1027 292963 : outImagLeftPtr_fx = imagDMX[0][k];
1028 292963 : outRealRightPtr_fx = realDMX[1][k];
1029 292963 : outImagRightPtr_fx = imagDMX[1][k];
1030 292963 : set32_fx( outRealLeftPtr_fx, 0, CLDFB_NO_CHANNELS_MAX );
1031 292963 : set32_fx( outImagLeftPtr_fx, 0, CLDFB_NO_CHANNELS_MAX );
1032 292963 : set32_fx( outRealRightPtr_fx, 0, CLDFB_NO_CHANNELS_MAX );
1033 292963 : set32_fx( outImagRightPtr_fx, 0, CLDFB_NO_CHANNELS_MAX );
1034 :
1035 : /*Ambisonics input requires different processing*/
1036 292963 : IF( EQ_16( hBinRenderer->nInChannels, HOA3_CHANNELS ) )
1037 : {
1038 : Word32 *inRealPtr_W, *inImagPtr_W;
1039 : Word32 *inRealPtr_Y, *inImagPtr_Y;
1040 :
1041 180963 : inRealPtr_W = (Word32 *) &( RealBuffer[0][k][0] );
1042 180963 : inImagPtr_W = (Word32 *) &( ImagBuffer[0][k][0] );
1043 :
1044 180963 : inRealPtr_Y = (Word32 *) &( RealBuffer[1][k][0] );
1045 180963 : inImagPtr_Y = (Word32 *) &( ImagBuffer[1][k][0] );
1046 :
1047 8027483 : FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
1048 : {
1049 7846520 : outRealLeftPtr_fx[bandIdx] = L_add( inRealPtr_W[bandIdx], inRealPtr_Y[bandIdx] );
1050 7846520 : outImagLeftPtr_fx[bandIdx] = L_add( inImagPtr_W[bandIdx], inImagPtr_Y[bandIdx] );
1051 :
1052 7846520 : outRealRightPtr_fx[bandIdx] = L_sub( inRealPtr_W[bandIdx], inRealPtr_Y[bandIdx] );
1053 7846520 : outImagRightPtr_fx[bandIdx] = L_sub( inImagPtr_W[bandIdx], inImagPtr_Y[bandIdx] );
1054 : }
1055 : }
1056 : ELSE
1057 : {
1058 1344000 : FOR( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ )
1059 : {
1060 1232000 : Word32 foa_const_fx = L_shl( hBinRenderer->hReverb->foa_enc_fx[chIdx][1], 1 ); // Q30
1061 : Word32 one_add_foa_const, one_sub_foa_const;
1062 :
1063 1232000 : one_add_foa_const = L_add( ONE_IN_Q30, foa_const_fx ); // Q30
1064 1232000 : one_sub_foa_const = L_sub_sat( ONE_IN_Q30, foa_const_fx ); // Q30
1065 :
1066 1232000 : inRealPtr_fx = (Word32 *) &( RealBuffer[chIdx][k][0] );
1067 1232000 : inImagPtr_fx = (Word32 *) &( ImagBuffer[chIdx][k][0] );
1068 :
1069 52272000 : FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
1070 : {
1071 51040000 : outRealLeftPtr_fx[bandIdx] = L_add( outRealLeftPtr_fx[bandIdx], Mpy_32_32( inRealPtr_fx[bandIdx], one_add_foa_const ) ); // Q_in - 1
1072 51040000 : move32();
1073 51040000 : outImagLeftPtr_fx[bandIdx] = L_add( outImagLeftPtr_fx[bandIdx], Mpy_32_32( inImagPtr_fx[bandIdx], one_add_foa_const ) ); // Q_in - 1
1074 51040000 : move32();
1075 :
1076 51040000 : outRealRightPtr_fx[bandIdx] = L_add( outRealRightPtr_fx[bandIdx], Mpy_32_32( inRealPtr_fx[bandIdx], one_sub_foa_const ) ); // Q_in - 1
1077 51040000 : move32();
1078 51040000 : outImagRightPtr_fx[bandIdx] = L_add( outImagRightPtr_fx[bandIdx], Mpy_32_32( inImagPtr_fx[bandIdx], one_sub_foa_const ) ); // Q_in - 1
1079 51040000 : move32();
1080 : }
1081 : }
1082 : }
1083 : }
1084 : #ifdef FIX_1939_REVERB_DMX_OUT_Q
1085 73761 : IF( NE_16( hBinRenderer->nInChannels, HOA3_CHANNELS ) )
1086 : {
1087 28000 : *Q_in_out = sub( *Q_in_out, 1 );
1088 : }
1089 : #endif
1090 : }
1091 :
1092 101201 : return;
1093 : }
1094 :
1095 :
1096 : /*-------------------------------------------------------------------------
1097 : * ivas_rend_openCldfbRend()
1098 : *
1099 : * Allocate and initialize CLDFB fast conv renderer handle
1100 : *------------------------------------------------------------------------*/
1101 :
1102 0 : ivas_error ivas_rend_openCldfbRend(
1103 : CLDFB_REND_WRAPPER *pCldfbRend,
1104 : const AUDIO_CONFIG inConfig,
1105 : const AUDIO_CONFIG outConfig,
1106 : const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
1107 : const Word32 output_Fs )
1108 : {
1109 : BINAURAL_RENDERER_HANDLE hBinRenderer;
1110 : Word16 convBand;
1111 : ivas_error error;
1112 :
1113 0 : error = IVAS_ERR_OK;
1114 :
1115 : /*-----------------------------------------------------------------*
1116 : * prepare library opening
1117 : *-----------------------------------------------------------------*/
1118 :
1119 0 : IF( ( hBinRenderer = (BINAURAL_RENDERER_HANDLE) malloc( sizeof( BINAURAL_RENDERER ) ) ) == NULL )
1120 : {
1121 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural Renderer\n" ) );
1122 : }
1123 :
1124 0 : IF( ( hBinRenderer->hInputSetup = (IVAS_OUTPUT_SETUP_HANDLE) malloc( sizeof( IVAS_OUTPUT_SETUP ) ) ) == NULL )
1125 : {
1126 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for output setup Binaural Renderer\n" ) );
1127 : }
1128 :
1129 0 : hBinRenderer->rotInCldfb = 1;
1130 0 : hBinRenderer->ivas_format = SBA_FORMAT;
1131 :
1132 0 : hBinRenderer->max_band = extract_l( Mpy_32_32( Mpy_32_32( BINAURAL_MAXBANDS_Q25, L_shl( output_Fs, Q6 ) ), ONE_BY_48000_Q31 ) );
1133 0 : move16();
1134 :
1135 0 : convBand = hBinRenderer->max_band;
1136 0 : move16();
1137 :
1138 0 : hBinRenderer->timeSlots = MAX_PARAM_SPATIAL_SUBFRAMES; /* Corresponds to 5 msec sound to motion latency */
1139 0 : move16();
1140 :
1141 0 : IF( GT_16( convBand, BINAURAL_CONVBANDS ) )
1142 : {
1143 0 : hBinRenderer->conv_band = BINAURAL_CONVBANDS;
1144 0 : move16();
1145 : }
1146 : ELSE
1147 : {
1148 0 : hBinRenderer->conv_band = convBand;
1149 0 : move16();
1150 : }
1151 :
1152 0 : hBinRenderer->hInputSetup->is_loudspeaker_setup = 0;
1153 0 : hBinRenderer->hInputSetup->output_config = inConfig;
1154 0 : IF( ( error = getAudioConfigNumChannels( inConfig, &hBinRenderer->hInputSetup->nchan_out_woLFE ) ) != IVAS_ERR_OK )
1155 : {
1156 0 : return error;
1157 : }
1158 :
1159 0 : IF( EQ_32( outConfig, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( outConfig, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) )
1160 : {
1161 0 : hBinRenderer->numPoses = pMultiBinPoseData->num_poses;
1162 0 : move16();
1163 : }
1164 : ELSE
1165 : {
1166 0 : hBinRenderer->numPoses = 1;
1167 0 : move16();
1168 : }
1169 :
1170 : /*LFE rendering switched off by default*/
1171 0 : hBinRenderer->render_lfe = 0;
1172 0 : move16();
1173 :
1174 :
1175 : /* Load HRTF tables */
1176 0 : IF( NE_32( ( error = ivas_binaural_hrtf_open_fx( &pCldfbRend->hHrtfFastConv, hBinRenderer->hInputSetup->output_config, RENDERER_BINAURAL_FASTCONV ) ), IVAS_ERR_OK ) )
1177 : {
1178 0 : return error;
1179 : }
1180 :
1181 : /* Allocate memories and buffers needed for convolutional module in CICP19 */
1182 0 : IF( NE_32( ( error = ivas_binRenderer_convModuleOpen( hBinRenderer, RENDERER_BINAURAL_FASTCONV, hBinRenderer->hInputSetup->is_loudspeaker_setup, inConfig, pCldfbRend->hHrtfFastConv, hBinRenderer->numPoses ) ), IVAS_ERR_OK ) )
1183 : {
1184 0 : return error;
1185 : }
1186 :
1187 0 : pCldfbRend->binaural_latency_ns = (Word32) ( pCldfbRend->hHrtfFastConv->FASTCONV_HOA3_latency_s_fx * 1000000000 );
1188 0 : move32();
1189 0 : hBinRenderer->hReverb = NULL;
1190 0 : move32();
1191 0 : hBinRenderer->hEFAPdata = NULL;
1192 0 : move32();
1193 0 : pCldfbRend->hCldfbRend = hBinRenderer;
1194 0 : move32();
1195 :
1196 0 : return error;
1197 : }
1198 :
1199 : /*-------------------------------------------------------------------------
1200 : * ivas_binRenderer_open()
1201 : *
1202 : * Open fastconv binaural renderer handle
1203 : *-------------------------------------------------------------------------*/
1204 327 : ivas_error ivas_binRenderer_open_fx(
1205 : Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
1206 : )
1207 : {
1208 : BINAURAL_RENDERER_HANDLE hBinRenderer;
1209 : #ifdef FIX_1053_REVERB_RECONFIGURATION
1210 : Word16 convBand, k;
1211 : #else
1212 : Word16 convBand, chIdx, k;
1213 : #endif
1214 : ivas_error error;
1215 : #ifdef FIX_587_DEFAULT_REVERB
1216 : const IVAS_ROOM_ACOUSTICS_CONFIG_DATA *pRoomAcoustics;
1217 : #endif
1218 :
1219 327 : error = IVAS_ERR_OK;
1220 327 : move32();
1221 :
1222 : /*-----------------------------------------------------------------*
1223 : * prepare library opening
1224 : *-----------------------------------------------------------------*/
1225 :
1226 327 : IF( ( hBinRenderer = (BINAURAL_RENDERER_HANDLE) malloc( sizeof( BINAURAL_RENDERER ) ) ) == NULL )
1227 : {
1228 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural Renderer\n" ) );
1229 : }
1230 :
1231 327 : hBinRenderer->hInputSetup = &st_ivas->hIntSetup;
1232 :
1233 : /* Define of head rotation has to be done in binRendeder in CLDFB*/
1234 327 : hBinRenderer->rotInCldfb = 0;
1235 327 : move16();
1236 327 : test();
1237 327 : if ( EQ_32( st_ivas->ivas_format, MC_FORMAT ) || EQ_32( st_ivas->ivas_format, SBA_FORMAT ) || EQ_32( st_ivas->ivas_format, SBA_ISM_FORMAT ) )
1238 : {
1239 327 : hBinRenderer->rotInCldfb = 1;
1240 327 : move16();
1241 : }
1242 :
1243 327 : IF( EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || EQ_32( st_ivas->hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) )
1244 : {
1245 0 : hBinRenderer->numPoses = st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses;
1246 0 : move16();
1247 : }
1248 : else
1249 : {
1250 327 : hBinRenderer->numPoses = 1;
1251 327 : move16();
1252 : }
1253 :
1254 : /* Declare some common variables needed for renderer */
1255 : /* Which format used for binaural rendering (needed for late reverb) ? MC or SBA */
1256 327 : IF( st_ivas->hIntSetup.is_loudspeaker_setup )
1257 : {
1258 146 : hBinRenderer->ivas_format = MC_FORMAT;
1259 146 : move32();
1260 : }
1261 : ELSE
1262 : {
1263 181 : hBinRenderer->ivas_format = SBA_FORMAT;
1264 181 : move32();
1265 : }
1266 327 : hBinRenderer->max_band = extract_l( Mpy_32_32( Mpy_32_32( BINAURAL_MAXBANDS_Q25, L_shl( st_ivas->hDecoderConfig->output_Fs, Q6 ) ), ONE_BY_48000_Q31 ) );
1267 327 : move16();
1268 :
1269 327 : convBand = hBinRenderer->max_band;
1270 327 : move16();
1271 :
1272 327 : hBinRenderer->timeSlots = MAX_PARAM_SPATIAL_SUBFRAMES; /* Corresponds to 5 msec sound to motion latency */
1273 327 : move16();
1274 :
1275 327 : IF( GT_16( convBand, BINAURAL_CONVBANDS ) )
1276 : {
1277 199 : hBinRenderer->conv_band = BINAURAL_CONVBANDS;
1278 199 : move16();
1279 : }
1280 : ELSE
1281 : {
1282 128 : hBinRenderer->conv_band = convBand;
1283 128 : move16();
1284 : }
1285 :
1286 : /*LFE rendering switched off by default*/
1287 327 : hBinRenderer->render_lfe = 0;
1288 327 : move16();
1289 :
1290 327 : test();
1291 327 : if ( NE_32( st_ivas->ivas_format, ISM_FORMAT ) && st_ivas->hIntSetup.is_loudspeaker_setup )
1292 : {
1293 146 : hBinRenderer->render_lfe = 1;
1294 146 : move16();
1295 : }
1296 :
1297 : /* Load HRTF tables */
1298 327 : IF( NE_32( ( error = ivas_binaural_hrtf_open_fx( &st_ivas->hHrtfFastConv, st_ivas->hIntSetup.output_config, st_ivas->renderer_type ) ), IVAS_ERR_OK ) )
1299 : {
1300 0 : return error;
1301 : }
1302 :
1303 327 : test();
1304 327 : IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) && ( st_ivas->hIntSetup.is_loudspeaker_setup == 0 ) )
1305 7 : {
1306 : IVAS_OUTPUT_SETUP out_setup;
1307 :
1308 : /* Allocate memories and buffers needed for convolutional module in CICP19 */
1309 7 : IF( NE_32( ( error = ivas_binRenderer_convModuleOpen( hBinRenderer, st_ivas->renderer_type, 1, IVAS_AUDIO_CONFIG_7_1_4, st_ivas->hHrtfFastConv, hBinRenderer->numPoses ) ), IVAS_ERR_OK ) )
1310 : {
1311 0 : return error;
1312 : }
1313 7 : ivas_output_init( &out_setup, IVAS_AUDIO_CONFIG_7_1_4 );
1314 :
1315 7 : IF( st_ivas->hoa_dec_mtx == NULL )
1316 : {
1317 7 : IF( NE_32( ( error = ivas_sba_get_hoa_dec_matrix_fx( out_setup, &st_ivas->hoa_dec_mtx, st_ivas->hIntSetup.ambisonics_order ) ), IVAS_ERR_OK ) )
1318 : {
1319 0 : return error;
1320 : }
1321 : }
1322 :
1323 7 : hBinRenderer->hoa_dec_mtx = st_ivas->hoa_dec_mtx;
1324 7 : st_ivas->binaural_latency_ns = st_ivas->hHrtfFastConv->FASTCONV_BRIR_latency_s_fx;
1325 7 : move32();
1326 : }
1327 : ELSE
1328 : {
1329 : /* Allocate memories and buffers needed for convolutional module */
1330 320 : IF( NE_32( ( 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 ) )
1331 : {
1332 0 : return error;
1333 : }
1334 :
1335 320 : IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) )
1336 : {
1337 258 : IF( EQ_32( hBinRenderer->ivas_format, MC_FORMAT ) )
1338 : {
1339 84 : st_ivas->binaural_latency_ns = st_ivas->hHrtfFastConv->FASTCONV_HRIR_latency_s_fx;
1340 84 : move32();
1341 : }
1342 : ELSE
1343 : {
1344 174 : IF( EQ_16( hBinRenderer->nInChannels, 16 ) )
1345 : {
1346 174 : st_ivas->binaural_latency_ns = st_ivas->hHrtfFastConv->FASTCONV_HOA3_latency_s_fx;
1347 174 : move32();
1348 : }
1349 0 : ELSE IF( EQ_16( hBinRenderer->nInChannels, 9 ) )
1350 : {
1351 0 : st_ivas->binaural_latency_ns = st_ivas->hHrtfFastConv->FASTCONV_HOA2_latency_s_fx;
1352 0 : move32();
1353 : }
1354 0 : ELSE IF( EQ_16( hBinRenderer->nInChannels, 4 ) )
1355 : {
1356 0 : st_ivas->binaural_latency_ns = st_ivas->hHrtfFastConv->FASTCONV_FOA_latency_s_fx;
1357 0 : move32();
1358 : }
1359 : ELSE
1360 : {
1361 0 : return IVAS_ERR_INVALID_INPUT_FORMAT;
1362 : }
1363 : }
1364 : }
1365 : ELSE
1366 : {
1367 : /* same value for MC or HOA both use MC BRIR*/
1368 62 : st_ivas->binaural_latency_ns = st_ivas->hHrtfFastConv->FASTCONV_BRIR_latency_s_fx;
1369 62 : move32();
1370 : }
1371 : }
1372 :
1373 : /* Allocate memories needed for reverb module */
1374 327 : test();
1375 327 : IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) || ( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) && EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) )
1376 : {
1377 : #ifdef FIX_587_DEFAULT_REVERB
1378 192 : pRoomAcoustics = NULL;
1379 192 : IF( EQ_32( st_ivas->hOutSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) )
1380 : {
1381 123 : pRoomAcoustics = &( st_ivas->hRenderConfig->roomAcoustics );
1382 : }
1383 : #ifdef FIX_1139_REV_COLORATION_SHORT_T60
1384 192 : IF( NE_32( ( error = ivas_binaural_reverb_init( &( hBinRenderer->hReverb ), st_ivas->hHrtfStatistics, hBinRenderer->conv_band, hBinRenderer->timeSlots, pRoomAcoustics, st_ivas->hDecoderConfig->output_Fs, st_ivas->hHrtfFastConv->fastconvReverberationTimes_fx, st_ivas->hHrtfFastConv->fastconvReverberationEneCorrections_fx, NULL ) ), IVAS_ERR_OK ) )
1385 : #else
1386 : IF( NE_32( ( error = ivas_binaural_reverb_init( &( hBinRenderer->hReverb ), st_ivas->hHrtfStatistics, hBinRenderer->conv_band, hBinRenderer->timeSlots, pRoomAcoustics, st_ivas->hDecoderConfig->output_Fs, st_ivas->hHrtfFastConv->fastconvReverberationTimes_fx, st_ivas->hHrtfFastConv->fastconvReverberationEneCorrections_fx ) ), IVAS_ERR_OK ) )
1387 : #endif
1388 : #else
1389 : IF( NE_32( ( error = ivas_binaural_reverb_init( &( hBinRenderer->hReverb ), st_ivas->hHrtfStatistics, hBinRenderer->conv_band, hBinRenderer->timeSlots, &( st_ivas->hRenderConfig->roomAcoustics ), st_ivas->hDecoderConfig->output_Fs, st_ivas->hHrtfFastConv->fastconvReverberationTimes_fx, st_ivas->hHrtfFastConv->fastconvReverberationEneCorrections_fx ) ), IVAS_ERR_OK ) )
1390 : #endif
1391 : {
1392 0 : return error;
1393 : }
1394 :
1395 : /* initialize the dmx matrix */
1396 : #ifndef FIX_1053_REVERB_RECONFIGURATION
1397 : IF( NE_16( hBinRenderer->nInChannels, HOA3_CHANNELS ) )
1398 : {
1399 : FOR( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ )
1400 : {
1401 : FOR( k = 0; k < hBinRenderer->nInChannels; k++ )
1402 : {
1403 : hBinRenderer->hReverb->dmxmtx_fx[chIdx][k] = dmxmtx_table_fx[chIdx][k];
1404 : move32();
1405 : }
1406 : }
1407 : }
1408 : #endif
1409 : }
1410 : ELSE
1411 : {
1412 135 : hBinRenderer->hReverb = NULL;
1413 : }
1414 :
1415 327 : hBinRenderer->hEFAPdata = NULL;
1416 :
1417 327 : IF( hBinRenderer->hReverb != NULL && NE_16( hBinRenderer->nInChannels, HOA3_CHANNELS ) )
1418 : {
1419 125 : test();
1420 125 : test();
1421 125 : IF( hBinRenderer->hInputSetup->is_loudspeaker_setup == 0 )
1422 : {
1423 84 : FOR( k = 0; k < 11; k++ )
1424 : {
1425 77 : ivas_dirac_dec_get_response_fx( extract_l( L_shr_r( ls_azimuth_CICP19_fx[k], 22 ) ), extract_l( L_shr_r( ls_elevation_CICP19_fx[k], 22 ) ), hBinRenderer->hReverb->foa_enc_fx[k], 1, Q29 );
1426 : // Q29: hBinRenderer->hReverb->foa_enc_fx[k]
1427 : }
1428 : }
1429 118 : ELSE IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) && ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) )
1430 : {
1431 2 : IF( NE_32( ( error = efap_init_data_fx( &( st_ivas->hEFAPdata ), st_ivas->hIntSetup.ls_azimuth_fx, st_ivas->hIntSetup.ls_elevation_fx, st_ivas->hIntSetup.nchan_out_woLFE, EFAP_MODE_EFAP ) ), IVAS_ERR_OK ) )
1432 : {
1433 0 : return error;
1434 : }
1435 :
1436 : /* Copy handles to bin renderer handle*/
1437 2 : hBinRenderer->hEFAPdata = st_ivas->hEFAPdata;
1438 : }
1439 : }
1440 :
1441 : /* Copy the handles to main handle */
1442 327 : st_ivas->hBinRenderer = hBinRenderer;
1443 :
1444 327 : return error;
1445 : }
1446 :
1447 : /*-------------------------------------------------------------------------
1448 : * ivas_binRenderer_convModuleClose()
1449 : *
1450 : * Close convolution module handle of fastconv binaural renderer
1451 : *------------------------------------------------------------------------*/
1452 327 : static void ivas_binRenderer_convModuleClose_fx(
1453 : BINAURAL_RENDERER_HANDLE *hBinRenderer, /* i/o: fastconv binaural renderer handle */
1454 : const Word16 num_poses /* i : number of poses */
1455 : )
1456 : {
1457 : Word16 bandIdx, chIdx;
1458 : Word16 posIdx;
1459 :
1460 : BINRENDERER_CONV_MODULE_HANDLE_FX hBinRenConvModule;
1461 :
1462 327 : hBinRenConvModule = ( *hBinRenderer )->hBinRenConvModule;
1463 :
1464 327 : IF( hBinRenConvModule == NULL )
1465 : {
1466 0 : return;
1467 : }
1468 :
1469 13677 : FOR( bandIdx = 0; bandIdx < ( *hBinRenderer )->conv_band; bandIdx++ )
1470 : {
1471 13350 : free( hBinRenConvModule->filterTapsLeftReal_fx[bandIdx] );
1472 13350 : hBinRenConvModule->filterTapsLeftReal_fx[bandIdx] = NULL;
1473 :
1474 13350 : free( hBinRenConvModule->filterTapsLeftImag_fx[bandIdx] );
1475 13350 : hBinRenConvModule->filterTapsLeftImag_fx[bandIdx] = NULL;
1476 :
1477 13350 : free( hBinRenConvModule->filterTapsRightReal_fx[bandIdx] );
1478 13350 : hBinRenConvModule->filterTapsRightReal_fx[bandIdx] = NULL;
1479 :
1480 13350 : free( hBinRenConvModule->filterTapsRightImag_fx[bandIdx] );
1481 13350 : hBinRenConvModule->filterTapsRightImag_fx[bandIdx] = NULL;
1482 : }
1483 :
1484 327 : free( hBinRenConvModule->filterTapsLeftReal_fx );
1485 327 : hBinRenConvModule->filterTapsLeftReal_fx = NULL;
1486 :
1487 327 : free( hBinRenConvModule->filterTapsLeftImag_fx );
1488 327 : hBinRenConvModule->filterTapsLeftImag_fx = NULL;
1489 :
1490 327 : free( hBinRenConvModule->filterTapsRightReal_fx );
1491 327 : hBinRenConvModule->filterTapsRightReal_fx = NULL;
1492 :
1493 327 : free( hBinRenConvModule->filterTapsRightImag_fx );
1494 327 : hBinRenConvModule->filterTapsRightImag_fx = NULL;
1495 :
1496 654 : FOR( posIdx = 0; posIdx < num_poses; posIdx++ )
1497 : {
1498 13677 : FOR( bandIdx = 0; bandIdx < ( *hBinRenderer )->conv_band; bandIdx++ )
1499 : {
1500 167180 : FOR( chIdx = 0; chIdx < ( *hBinRenderer )->nInChannels; chIdx++ )
1501 : {
1502 153830 : free( hBinRenConvModule->filterStatesLeftReal_fx[posIdx][bandIdx][chIdx] );
1503 153830 : hBinRenConvModule->filterStatesLeftReal_fx[posIdx][bandIdx][chIdx] = NULL;
1504 :
1505 153830 : free( hBinRenConvModule->filterStatesLeftImag_fx[posIdx][bandIdx][chIdx] );
1506 153830 : hBinRenConvModule->filterStatesLeftImag_fx[posIdx][bandIdx][chIdx] = NULL;
1507 : }
1508 :
1509 13350 : free( hBinRenConvModule->filterStatesLeftReal_fx[posIdx][bandIdx] );
1510 13350 : hBinRenConvModule->filterStatesLeftReal_fx[posIdx][bandIdx] = NULL;
1511 :
1512 13350 : free( hBinRenConvModule->filterStatesLeftImag_fx[posIdx][bandIdx] );
1513 13350 : hBinRenConvModule->filterStatesLeftImag_fx[posIdx][bandIdx] = NULL;
1514 : }
1515 327 : free( hBinRenConvModule->filterStatesLeftReal_fx[posIdx] );
1516 327 : hBinRenConvModule->filterStatesLeftReal_fx[posIdx] = NULL;
1517 :
1518 327 : free( hBinRenConvModule->filterStatesLeftImag_fx[posIdx] );
1519 327 : hBinRenConvModule->filterStatesLeftImag_fx[posIdx] = NULL;
1520 : }
1521 327 : free( hBinRenConvModule->filterStatesLeftReal_fx );
1522 327 : hBinRenConvModule->filterStatesLeftReal_fx = NULL;
1523 :
1524 327 : free( hBinRenConvModule->filterStatesLeftImag_fx );
1525 327 : hBinRenConvModule->filterStatesLeftImag_fx = NULL;
1526 :
1527 327 : free( hBinRenConvModule->Q_filterStates );
1528 327 : hBinRenConvModule->Q_filterStates = NULL;
1529 :
1530 327 : free( ( *hBinRenderer )->hBinRenConvModule );
1531 327 : ( *hBinRenderer )->hBinRenConvModule = NULL;
1532 :
1533 327 : return;
1534 : }
1535 :
1536 : /*-------------------------------------------------------------------------
1537 : * ivas_binRenderer_close()
1538 : *
1539 : * Close fastconv binaural renderer memories
1540 : *------------------------------------------------------------------------*/
1541 895 : void ivas_binRenderer_close_fx(
1542 : BINAURAL_RENDERER_HANDLE *hBinRenderer /* i/o: fastconv binaural renderer handle */
1543 : )
1544 : {
1545 895 : test();
1546 895 : IF( hBinRenderer == NULL || *hBinRenderer == NULL )
1547 : {
1548 568 : return;
1549 : }
1550 :
1551 327 : IF( ( *hBinRenderer )->hBinRenConvModule != NULL )
1552 : {
1553 327 : ivas_binRenderer_convModuleClose_fx( hBinRenderer, ( *hBinRenderer )->numPoses );
1554 : }
1555 :
1556 327 : IF( ( *hBinRenderer )->hReverb != NULL )
1557 : {
1558 192 : ivas_binaural_reverb_close_fx( &( ( *hBinRenderer )->hReverb ) );
1559 : }
1560 :
1561 327 : free( *hBinRenderer );
1562 327 : *hBinRenderer = NULL;
1563 :
1564 327 : return;
1565 : }
1566 :
1567 : /*-------------------------------------------------------------------------
1568 : * ivas_free_pppHrtfMem()
1569 : *
1570 : * Free fastconv binaural renderer hrtf memories
1571 : *------------------------------------------------------------------------*/
1572 1360 : static void ivas_free_pppHrtfMem_fx(
1573 : Word32 ****ppppHRIR, /*Qx*/
1574 : const Word16 dim,
1575 : const Word16 alloc_init )
1576 : {
1577 : Word16 i, j;
1578 :
1579 1360 : IF( *ppppHRIR != NULL )
1580 : {
1581 40188 : FOR( i = 0; i < BINAURAL_CONVBANDS; i++ )
1582 : {
1583 39400 : IF( alloc_init == 0 )
1584 : {
1585 307200 : FOR( j = 0; j < dim; j++ )
1586 : {
1587 283200 : free( ( *ppppHRIR )[i][j] );
1588 283200 : ( *ppppHRIR )[i][j] = NULL;
1589 : }
1590 : }
1591 39400 : free( ( *ppppHRIR )[i] );
1592 39400 : ( *ppppHRIR )[i] = NULL;
1593 : }
1594 788 : free( *ppppHRIR );
1595 788 : *ppppHRIR = NULL;
1596 : }
1597 :
1598 1360 : return;
1599 : }
1600 :
1601 : /*-------------------------------------------------------------------------
1602 : * ivas_binaural_hrtf_close()
1603 : *
1604 : * Close fastconv binaural renderer hrtf memories
1605 : *------------------------------------------------------------------------*/
1606 1279 : void ivas_binaural_hrtf_close(
1607 : HRTFS_FASTCONV_HANDLE *hHrtfFastConv /* i : fastconv HRTF handle */
1608 : )
1609 : {
1610 : Word16 allocate_init_flag;
1611 :
1612 1279 : test();
1613 1279 : IF( hHrtfFastConv == NULL || *hHrtfFastConv == NULL )
1614 : {
1615 1211 : return;
1616 : }
1617 :
1618 68 : allocate_init_flag = ( *hHrtfFastConv )->allocate_init_flag;
1619 68 : move16();
1620 :
1621 68 : ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->leftHRIRReal_fx, HRTF_LS_CHANNELS, allocate_init_flag );
1622 68 : ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->leftHRIRImag_fx, HRTF_LS_CHANNELS, allocate_init_flag );
1623 68 : ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->rightHRIRReal_fx, HRTF_LS_CHANNELS, allocate_init_flag );
1624 68 : ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->rightHRIRImag_fx, HRTF_LS_CHANNELS, allocate_init_flag );
1625 :
1626 68 : ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->leftBRIRReal_fx, HRTF_LS_CHANNELS, allocate_init_flag );
1627 68 : ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->leftBRIRImag_fx, HRTF_LS_CHANNELS, allocate_init_flag );
1628 68 : ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->rightBRIRReal_fx, HRTF_LS_CHANNELS, allocate_init_flag );
1629 68 : ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->rightBRIRImag_fx, HRTF_LS_CHANNELS, allocate_init_flag );
1630 :
1631 68 : ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->leftHRIRReal_HOA3_fx, HOA3_CHANNELS, allocate_init_flag );
1632 68 : ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->leftHRIRImag_HOA3_fx, HOA3_CHANNELS, allocate_init_flag );
1633 68 : ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->rightHRIRReal_HOA3_fx, HOA3_CHANNELS, allocate_init_flag );
1634 68 : ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->rightHRIRImag_HOA3_fx, HOA3_CHANNELS, allocate_init_flag );
1635 :
1636 68 : ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->leftHRIRReal_HOA2_fx, HOA2_CHANNELS, allocate_init_flag );
1637 68 : ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->leftHRIRImag_HOA2_fx, HOA2_CHANNELS, allocate_init_flag );
1638 68 : ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->rightHRIRReal_HOA2_fx, HOA2_CHANNELS, allocate_init_flag );
1639 68 : ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->rightHRIRImag_HOA2_fx, HOA2_CHANNELS, allocate_init_flag );
1640 :
1641 68 : ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->leftHRIRReal_FOA_fx, FOA_CHANNELS, allocate_init_flag );
1642 68 : ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->leftHRIRImag_FOA_fx, FOA_CHANNELS, allocate_init_flag );
1643 68 : ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->rightHRIRReal_FOA_fx, FOA_CHANNELS, allocate_init_flag );
1644 68 : ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->rightHRIRImag_FOA_fx, FOA_CHANNELS, allocate_init_flag );
1645 :
1646 68 : return;
1647 : }
1648 :
1649 : /*-------------------------------------------------------------------------*
1650 : * ivas_binaural_add_LFE()
1651 : *
1652 : * The functions adds the LFE to the left and right channels after binaural rendering
1653 : *-------------------------------------------------------------------------*/
1654 16767 : void ivas_binaural_add_LFE_fx(
1655 : Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
1656 : Word16 output_frame, /* i : length of input frame */
1657 : Word32 *input_fx[], /* i : transport channels Q11*/
1658 : Word32 *output_fx[] /* o : synthesized core-coder transport channels/DirAC output Q11*/
1659 : )
1660 : {
1661 : Word16 render_lfe, idx_lfe, gain_fx, idx;
1662 : Word32 lfe_tc[L_FRAME48k];
1663 :
1664 16767 : IF( st_ivas->hBinRenderer != NULL )
1665 : {
1666 160 : render_lfe = st_ivas->hBinRenderer->render_lfe;
1667 160 : move16();
1668 : }
1669 : ELSE
1670 : {
1671 16607 : render_lfe = TRUE;
1672 16607 : move16();
1673 : }
1674 :
1675 :
1676 16767 : IF( render_lfe )
1677 : {
1678 16767 : IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_OBJECTS_TD ) )
1679 : {
1680 3144 : gain_fx = GAIN_LFE_FX;
1681 3144 : move16();
1682 : }
1683 : ELSE
1684 : {
1685 13623 : test();
1686 13623 : IF( ( st_ivas->hCrendWrapper != NULL ) && ( st_ivas->hCrendWrapper->hHrtfCrend != NULL ) )
1687 : {
1688 13462 : gain_fx = st_ivas->hCrendWrapper->hHrtfCrend->gain_lfe_fx;
1689 13462 : move16();
1690 : }
1691 : ELSE
1692 : {
1693 161 : gain_fx = GAIN_LFE_FX;
1694 161 : move16();
1695 : }
1696 : }
1697 33383 : FOR( idx_lfe = 0; idx_lfe < st_ivas->hIntSetup.num_lfe; idx_lfe++ )
1698 : {
1699 16616 : v_multc_fixed_16( input_fx[st_ivas->hIntSetup.index_lfe[idx_lfe]], gain_fx, lfe_tc, output_frame ); // q_input_fx - 1
1700 : /* copy LFE to left and right channels */
1701 14810856 : FOR( idx = 0; idx < output_frame; idx++ )
1702 : {
1703 14794240 : lfe_tc[idx] = L_shl_sat( lfe_tc[idx], 1 ); // saturating to keep same q
1704 14794240 : move32();
1705 14794240 : output_fx[0][idx] = L_add_sat( output_fx[0][idx], lfe_tc[idx] );
1706 14794240 : move32();
1707 14794240 : output_fx[1][idx] = L_add_sat( output_fx[1][idx], lfe_tc[idx] );
1708 14794240 : move32();
1709 : }
1710 : }
1711 : }
1712 :
1713 16767 : return;
1714 : }
1715 :
1716 : /*-------------------------------------------------------------------------
1717 : * ivas_binRenderer_fx()
1718 : *
1719 : * Fastconv binaural renderer main function
1720 : *-------------------------------------------------------------------------*/
1721 :
1722 155629 : void ivas_binRenderer_fx(
1723 : BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: binaural renderer handle */
1724 : const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
1725 : COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined head and external orientation handle*/
1726 : const Word16 numTimeSlots, /* i : number of time slots to render */
1727 : Word32 Cldfb_RealBuffer_Binaural_fx[][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Rotated Binaural signals */
1728 : Word32 Cldfb_ImagBuffer_Binaural_fx[][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Rotated Binaural signals */
1729 : Word32 RealBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals Q_in*/
1730 : Word32 ImagBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals Q_in*/
1731 : Word16 *Q_in /* i : LS signals exp */
1732 : )
1733 : {
1734 : Word16 chIdx, i, j, k;
1735 : Word16 pos_idx, num_poses;
1736 : Word32 RealBuffer_local[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
1737 : Word32 ImagBuffer_local[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
1738 :
1739 155629 : push_wmops( "fastconv_binaural_rendering" );
1740 :
1741 155629 : num_poses = hBinRenderer->numPoses;
1742 :
1743 : /* Compute Convolution */
1744 : /* memory reset for the binaural output */
1745 :
1746 : /* Note: on main, this nested for loop was removed under a "bit-exact optimization" under switch OPT_SBA_DEC_V2_BE */
1747 : /* this was found to clash with split rendering, so kept here. WMOPS impact should be assessed */
1748 2362377 : FOR( chIdx = 0; chIdx < hBinRenderer->hInputSetup->nchan_out_woLFE; chIdx++ )
1749 : {
1750 11000444 : FOR( k = 0; k < numTimeSlots; k++ )
1751 : {
1752 8793696 : Copy32( RealBuffer_fx[chIdx][k], RealBuffer_local[chIdx][k], CLDFB_NO_CHANNELS_MAX );
1753 8793696 : Copy32( ImagBuffer_fx[chIdx][k], ImagBuffer_local[chIdx][k], CLDFB_NO_CHANNELS_MAX );
1754 : }
1755 : }
1756 :
1757 : /* Head rotation in HOA3 or CICPx */
1758 155629 : test();
1759 155629 : test();
1760 155629 : IF( hCombinedOrientationData != NULL && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] && hBinRenderer->rotInCldfb )
1761 : {
1762 64111 : IF( hBinRenderer->hInputSetup->is_loudspeaker_setup == 0 )
1763 : {
1764 : /* Rotation in SHD (HOA3) */
1765 56111 : IF( EQ_16( hCombinedOrientationData->shd_rot_max_order, -1 ) )
1766 : {
1767 18911 : rotateFrame_shd_cldfb( RealBuffer_fx, ImagBuffer_fx, hCombinedOrientationData->Rmat_fx[hCombinedOrientationData->subframe_idx], hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, 3 );
1768 18911 : *Q_in = sub( *Q_in, 1 ); //( Q_in + 14 - 15 )
1769 18911 : move16();
1770 : }
1771 37200 : ELSE IF( hCombinedOrientationData->shd_rot_max_order > 0 )
1772 : {
1773 400 : rotateFrame_shd_cldfb( RealBuffer_fx, ImagBuffer_fx, hCombinedOrientationData->Rmat_fx[hCombinedOrientationData->subframe_idx], hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, hCombinedOrientationData->shd_rot_max_order );
1774 400 : *Q_in = sub( *Q_in, 1 ); //( Q_in + 14 - 15 )
1775 400 : move16();
1776 : }
1777 : }
1778 : ELSE
1779 : {
1780 : /* Rotation in SD (CICPx) */
1781 8000 : rotateFrame_sd_cldfb_fixed( hCombinedOrientationData->Rmat_fx[hCombinedOrientationData->subframe_idx], RealBuffer_fx, ImagBuffer_fx,
1782 8000 : hBinRenderer->hInputSetup, hBinRenderer->hEFAPdata, numTimeSlots, hBinRenderer->conv_band );
1783 : }
1784 : }
1785 :
1786 : /* HOA decoding to CICP19 if needed*/
1787 155629 : test();
1788 155629 : IF( hBinRenderer->hInputSetup->is_loudspeaker_setup == 0 && NE_16( hBinRenderer->nInChannels, 16 ) )
1789 : {
1790 28000 : ivas_sba2mc_cldfb_fixed( *( hBinRenderer->hInputSetup ), RealBuffer_fx, ImagBuffer_fx,
1791 28000 : hBinRenderer->nInChannels, hBinRenderer->conv_band, numTimeSlots, hBinRenderer->hoa_dec_mtx );
1792 : }
1793 :
1794 155629 : ivas_binRenderer_filterModule_fx( Cldfb_RealBuffer_Binaural_fx[0], Cldfb_ImagBuffer_Binaural_fx[0], RealBuffer_fx, ImagBuffer_fx, numTimeSlots, hBinRenderer, 0, *Q_in );
1795 :
1796 155629 : IF( pMultiBinPoseData != NULL )
1797 : {
1798 0 : IF( GT_16( pMultiBinPoseData->num_poses, 1 ) )
1799 : {
1800 : IVAS_QUATERNION Quaternions_abs, Quaternions_ref, Quaternions_ref2;
1801 : Word32 Rmat_local[3][3];
1802 : Word16 q_fact_orig;
1803 :
1804 0 : IF( hCombinedOrientationData && hBinRenderer->rotInCldfb )
1805 : {
1806 0 : Quaternions_ref = hCombinedOrientationData->Quaternions[0];
1807 0 : q_fact_orig = Quaternions_ref.q_fact;
1808 :
1809 0 : modify_Quat_q_fx( &Quaternions_ref, &Quaternions_ref, Q22 );
1810 :
1811 0 : Quaternions_ref2.w_fx = L_negate( 12582912 ); // Q22
1812 0 : IF( EQ_16( hCombinedOrientationData->shd_rot_max_order, 0 ) )
1813 : {
1814 : /*HOA signal already rotated by DirAC*/
1815 0 : Quaternions_ref2.x_fx = 0;
1816 0 : Quaternions_ref2.y_fx = 0;
1817 0 : Quaternions_ref2.z_fx = 0;
1818 0 : *Q_in = sub( *Q_in, 1 );
1819 : }
1820 : ELSE
1821 : {
1822 : /*euler*/
1823 0 : Quat2EulerDegree_fx( Quaternions_ref, &Quaternions_ref2.z_fx, &Quaternions_ref2.y_fx, &Quaternions_ref2.x_fx ); /*order in Quat2Euler seems to be reversed ?*/
1824 : }
1825 :
1826 0 : FOR( pos_idx = 1; pos_idx < pMultiBinPoseData->num_poses; pos_idx++ )
1827 : {
1828 0 : FOR( chIdx = 0; chIdx < hBinRenderer->hInputSetup->nchan_out_woLFE; chIdx++ )
1829 : {
1830 0 : FOR( k = 0; k < numTimeSlots; k++ )
1831 : {
1832 0 : Copy32( RealBuffer_local[chIdx][k], RealBuffer_fx[chIdx][k], CLDFB_NO_CHANNELS_MAX );
1833 0 : Copy32( ImagBuffer_local[chIdx][k], ImagBuffer_fx[chIdx][k], CLDFB_NO_CHANNELS_MAX );
1834 : }
1835 : }
1836 :
1837 0 : Quaternions_abs.x_fx = L_add( Quaternions_ref2.x_fx, pMultiBinPoseData->relative_head_poses_fx[pos_idx][0] );
1838 0 : Quaternions_abs.y_fx = L_add( Quaternions_ref2.y_fx, pMultiBinPoseData->relative_head_poses_fx[pos_idx][1] );
1839 0 : Quaternions_abs.z_fx = L_add( Quaternions_ref2.z_fx, pMultiBinPoseData->relative_head_poses_fx[pos_idx][2] );
1840 0 : Quaternions_abs.w_fx = L_negate( 12582912 ); // Q22
1841 :
1842 0 : Euler2Quat_fx( deg2rad_fx( Quaternions_abs.x_fx ), deg2rad_fx( Quaternions_abs.y_fx ), deg2rad_fx( Quaternions_abs.z_fx ), &Quaternions_abs );
1843 :
1844 0 : modify_Quat_q_fx( &Quaternions_abs, &Quaternions_abs, q_fact_orig );
1845 :
1846 0 : QuatToRotMat_fx( Quaternions_abs, Rmat_local );
1847 :
1848 0 : modify_Rmat_q_fx( Rmat_local, Rmat_local, sub( shl( q_fact_orig, 1 ), 32 ), Q30 );
1849 :
1850 0 : IF( hBinRenderer->hInputSetup->is_loudspeaker_setup )
1851 : {
1852 0 : rotateFrame_sd_cldfb_fixed( Rmat_local, RealBuffer_fx, ImagBuffer_fx, hBinRenderer->hInputSetup, hBinRenderer->hEFAPdata, numTimeSlots, hBinRenderer->conv_band );
1853 : }
1854 : ELSE
1855 : {
1856 0 : rotateFrame_shd_cldfb( RealBuffer_fx, ImagBuffer_fx, Rmat_local, hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, 3 );
1857 : }
1858 0 : ivas_binRenderer_filterModule_fx( Cldfb_RealBuffer_Binaural_fx[pos_idx], Cldfb_ImagBuffer_Binaural_fx[pos_idx], RealBuffer_fx, ImagBuffer_fx, numTimeSlots, hBinRenderer, pos_idx, *Q_in );
1859 : }
1860 : }
1861 : }
1862 : }
1863 :
1864 : /* Obtain the binaural dmx and compute the reverb */
1865 155629 : IF( hBinRenderer->hReverb != NULL )
1866 : {
1867 : Word32 reverbRe_fx[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX];
1868 : Word32 reverbIm_fx[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX];
1869 : Word32 inRe_fx[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX];
1870 : Word32 inIm_fx[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX];
1871 : Word16 shift_q;
1872 : #ifdef FIX_1939_REVERB_DMX_OUT_Q
1873 : Word16 q_in_out;
1874 101201 : q_in_out = *Q_in;
1875 : #endif
1876 :
1877 : #ifdef FIX_1939_REVERB_DMX_OUT_Q
1878 101201 : ivas_binaural_obtain_DMX_fx( numTimeSlots, hBinRenderer, RealBuffer_fx, ImagBuffer_fx, inRe_fx, inIm_fx, &q_in_out );
1879 : #else
1880 : ivas_binaural_obtain_DMX_fx( numTimeSlots, hBinRenderer, RealBuffer_fx, ImagBuffer_fx, inRe_fx, inIm_fx );
1881 : #endif
1882 :
1883 303603 : FOR( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ )
1884 : {
1885 1007848 : FOR( k = 0; k < numTimeSlots; k++ )
1886 : {
1887 805446 : set32_fx( reverbRe_fx[chIdx][k], 0, hBinRenderer->max_band );
1888 805446 : set32_fx( reverbIm_fx[chIdx][k], 0, hBinRenderer->max_band );
1889 : }
1890 : }
1891 :
1892 101201 : ivas_binaural_reverb_processSubframe_fx( hBinRenderer->hReverb, BINAURAL_CHANNELS, numTimeSlots, inRe_fx, inIm_fx, reverbRe_fx, reverbIm_fx );
1893 : #ifdef FIX_1939_REVERB_DMX_OUT_Q
1894 101201 : shift_q = sub( Q6, q_in_out );
1895 : #else
1896 : shift_q = sub( Q6, sub( *Q_in, 1 ) );
1897 : #endif
1898 303603 : FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
1899 : {
1900 1007848 : FOR( j = 0; j < numTimeSlots; j++ )
1901 : {
1902 36079286 : FOR( k = 0; k < hBinRenderer->hReverb->numBins; k++ )
1903 : {
1904 35273840 : reverbRe_fx[i][j][k] = L_shl( reverbRe_fx[i][j][k], shift_q ); // Q6
1905 35273840 : move32();
1906 35273840 : reverbIm_fx[i][j][k] = L_shl( reverbIm_fx[i][j][k], shift_q ); // Q6
1907 35273840 : move32();
1908 : }
1909 : }
1910 : }
1911 :
1912 : /* Add the conv module and reverb module output */
1913 303603 : FOR( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ )
1914 : {
1915 1007848 : FOR( k = 0; k < numTimeSlots; k++ )
1916 : {
1917 1610892 : FOR( pos_idx = 0; pos_idx < num_poses; pos_idx++ )
1918 : {
1919 : /* Combine first and second parts to generate binaural output signal with room effect */
1920 805446 : v_add_32( Cldfb_RealBuffer_Binaural_fx[pos_idx][chIdx][k], reverbRe_fx[chIdx][k], Cldfb_RealBuffer_Binaural_fx[pos_idx][chIdx][k], hBinRenderer->conv_band ); // Q6
1921 805446 : v_add_32( Cldfb_ImagBuffer_Binaural_fx[pos_idx][chIdx][k], reverbIm_fx[chIdx][k], Cldfb_ImagBuffer_Binaural_fx[pos_idx][chIdx][k], hBinRenderer->conv_band ); // Q6
1922 : }
1923 : }
1924 : }
1925 : }
1926 :
1927 155629 : Word16 len = sub( CLDFB_NO_CHANNELS_MAX, hBinRenderer->conv_band );
1928 :
1929 311258 : FOR( pos_idx = 0; pos_idx < num_poses; pos_idx++ )
1930 : {
1931 776064 : FOR( k = 0; k < numTimeSlots; k++ )
1932 : {
1933 620435 : set32_fx( &Cldfb_RealBuffer_Binaural_fx[pos_idx][0][k][hBinRenderer->conv_band], 0, len );
1934 620435 : set32_fx( &Cldfb_RealBuffer_Binaural_fx[pos_idx][1][k][hBinRenderer->conv_band], 0, len );
1935 620435 : set32_fx( &Cldfb_ImagBuffer_Binaural_fx[pos_idx][0][k][hBinRenderer->conv_band], 0, len );
1936 620435 : set32_fx( &Cldfb_ImagBuffer_Binaural_fx[pos_idx][1][k][hBinRenderer->conv_band], 0, len );
1937 : }
1938 : }
1939 :
1940 155629 : pop_wmops();
1941 155629 : return;
1942 : }
1943 :
1944 : /*-------------------------------------------------------------------------
1945 : * ivas_rend_CldfbMultiBinRendProcess()
1946 : *
1947 : *
1948 : *-------------------------------------------------------------------------*/
1949 :
1950 0 : void ivas_rend_CldfbMultiBinRendProcess(
1951 : const BINAURAL_RENDERER_HANDLE hCldfbRend,
1952 : const COMBINED_ORIENTATION_HANDLE *pCombinedOrientationData,
1953 : const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData,
1954 : Word32 Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
1955 : Word32 Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
1956 : Word32 Cldfb_Out_Real[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */
1957 : Word32 Cldfb_Out_Imag[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX],
1958 : const Word16 low_res_pre_rend_rot,
1959 : const Word16 num_subframes,
1960 : const Word16 Q_in /* i : LS signals exp */
1961 : )
1962 : {
1963 : int16_t slot_idx, ch_idx, idx, pose_idx, i, j;
1964 : int16_t sf_idx;
1965 : Word32 Cldfb_RealBuffer_sfIn[MAX_INPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
1966 : Word32 Cldfb_ImagBuffer_sfIn[MAX_INPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
1967 : Word32 Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
1968 : Word32 Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX];
1969 : Word16 Q_in_orig;
1970 :
1971 0 : FOR( sf_idx = 0; sf_idx < num_subframes; sf_idx++ )
1972 : {
1973 0 : Q_in_orig = Q_in;
1974 0 : move16();
1975 0 : FOR( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ )
1976 : {
1977 0 : idx = sf_idx * MAX_PARAM_SPATIAL_SUBFRAMES + slot_idx;
1978 0 : FOR( ch_idx = 0; ch_idx < hCldfbRend->nInChannels; ch_idx++ )
1979 : {
1980 0 : Copy32( &Cldfb_In_Real[ch_idx][idx][0], &Cldfb_RealBuffer_sfIn[ch_idx][slot_idx][0], hCldfbRend->max_band );
1981 0 : Copy32( &Cldfb_In_Imag[ch_idx][idx][0], &Cldfb_ImagBuffer_sfIn[ch_idx][slot_idx][0], hCldfbRend->max_band );
1982 : }
1983 : }
1984 :
1985 0 : IF( ( *pCombinedOrientationData ) != NULL )
1986 : {
1987 0 : IF( ( low_res_pre_rend_rot ) && ( EQ_32( pMultiBinPoseData->poseCorrectionMode, ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) ) )
1988 : {
1989 0 : Copy_Quat_fx( &( *pCombinedOrientationData )->Quaternions[0], &( *pCombinedOrientationData )->Quaternions[sf_idx] );
1990 :
1991 0 : FOR( i = 0; i < 3; i++ )
1992 : {
1993 0 : FOR( j = 0; j < 3; j++ )
1994 : {
1995 0 : ( *pCombinedOrientationData )->Rmat_fx[sf_idx][i][j] = ( *pCombinedOrientationData )->Rmat_fx[0][i][j];
1996 0 : move32();
1997 : }
1998 : }
1999 : }
2000 0 : ( *pCombinedOrientationData )->shd_rot_max_order = -1;
2001 0 : move16();
2002 : }
2003 :
2004 0 : ivas_binRenderer_fx( hCldfbRend, pMultiBinPoseData, *pCombinedOrientationData, MAX_PARAM_SPATIAL_SUBFRAMES, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer_sfIn, Cldfb_ImagBuffer_sfIn, &Q_in_orig );
2005 :
2006 0 : FOR( pose_idx = 0; pose_idx < hCldfbRend->numPoses; pose_idx++ )
2007 : {
2008 0 : FOR( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ )
2009 : {
2010 0 : idx = sf_idx * MAX_PARAM_SPATIAL_SUBFRAMES + slot_idx;
2011 0 : FOR( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ )
2012 : {
2013 0 : Copy32( &Cldfb_RealBuffer_Binaural[pose_idx][ch_idx][slot_idx][0], &Cldfb_Out_Real[( pose_idx * BINAURAL_CHANNELS ) + ch_idx][idx][0], hCldfbRend->max_band );
2014 0 : Copy32( &Cldfb_ImagBuffer_Binaural[pose_idx][ch_idx][slot_idx][0], &Cldfb_Out_Imag[( pose_idx * BINAURAL_CHANNELS ) + ch_idx][idx][0], hCldfbRend->max_band );
2015 :
2016 0 : Scale_sig32( &Cldfb_Out_Real[( pose_idx * BINAURAL_CHANNELS ) + ch_idx][idx][0], hCldfbRend->max_band, sub( Q_in, Q6 ) ); // Q_in
2017 0 : Scale_sig32( &Cldfb_Out_Imag[( pose_idx * BINAURAL_CHANNELS ) + ch_idx][idx][0], hCldfbRend->max_band, sub( Q_in, Q6 ) ); // Q_in
2018 : }
2019 : }
2020 : }
2021 : }
2022 :
2023 0 : return;
2024 : }
|