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 : * ivas_binRenderer_filterModule_fx()
54 : *
55 : *
56 : *-------------------------------------------------------------------------*/
57 136305 : static void ivas_binRenderer_filterModule_fx(
58 : Word32 out_Conv_CLDFB_real[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : real part of Binaural signals Q6 */
59 : Word32 out_Conv_CLDFB_imag[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : imag part of Binaural signals Q6 */
60 : Word32 CLDFB_real[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : real part of LS signals Q_curr*/
61 : Word32 CLDFB_imag[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : imag part of LS signals Q_curr*/
62 : const Word16 numTimeSlots, /* i : number of time slots to process */
63 : BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: fastconv binaural renderer handle */
64 : Word16 Q_curr )
65 : {
66 : Word16 bandIdx, k, chIdx, tapIdx;
67 : Word32 *filterStatesLeftRealPtr_fx, *filterStatesLeftImagPtr_fx;
68 : Word16 Q_filterStates;
69 : const Word32 *filterTapsLeftRealPtr_fx, *filterTapsLeftImagPtr_fx, *filterTapsRightRealPtr_fx, *filterTapsRightImagPtr_fx;
70 : Word16 shift_q;
71 136305 : Word16 shift_q6 = sub( -29 + 6, Q_curr );
72 136305 : Q_filterStates = hBinRenderer->hBinRenConvModule->Q_filterStatesLeft;
73 136305 : move16();
74 :
75 : // to be checked: feasibility with 32 bit buffers
76 : Word64 Cldfb_RealBuffer_64fx[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES];
77 : Word64 Cldfb_ImagBuffer_64fx[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES];
78 :
79 6310355 : FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
80 : {
81 6174050 : set64_fx( &Cldfb_RealBuffer_64fx[0][0], 0, BINAURAL_CHANNELS * MAX_PARAM_SPATIAL_SUBFRAMES );
82 6174050 : set64_fx( &Cldfb_ImagBuffer_64fx[0][0], 0, BINAURAL_CHANNELS * MAX_PARAM_SPATIAL_SUBFRAMES );
83 :
84 88510050 : FOR( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ )
85 : {
86 82336000 : filterStatesLeftRealPtr_fx = (Word32 *) &( hBinRenderer->hBinRenConvModule->filterStatesLeftReal_fx[bandIdx][chIdx][0] );
87 82336000 : filterStatesLeftImagPtr_fx = (Word32 *) &( hBinRenderer->hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx][0] );
88 :
89 82336000 : filterTapsLeftRealPtr_fx = hBinRenderer->hBinRenConvModule->filterTapsLeftReal_fx[bandIdx][chIdx]; // Q29
90 82336000 : filterTapsLeftImagPtr_fx = hBinRenderer->hBinRenConvModule->filterTapsLeftImag_fx[bandIdx][chIdx]; // Q29
91 82336000 : filterTapsRightRealPtr_fx = hBinRenderer->hBinRenConvModule->filterTapsRightReal_fx[bandIdx][chIdx]; // Q29
92 82336000 : filterTapsRightImagPtr_fx = hBinRenderer->hBinRenConvModule->filterTapsRightImag_fx[bandIdx][chIdx]; // Q29
93 :
94 410464000 : FOR( k = 0; k < numTimeSlots; k++ )
95 : {
96 328128000 : Word64 outRealLeft_fx = 0, outRealRight_fx = 0, outImagLeft_fx = 0, outImagRight_fx = 0;
97 328128000 : move64();
98 328128000 : move64();
99 328128000 : move64();
100 328128000 : move64();
101 :
102 4698766400 : FOR( tapIdx = hBinRenderer->hBinRenConvModule->numTapsArray[bandIdx] - 1; tapIdx > 0; tapIdx-- )
103 : {
104 4370638400 : filterStatesLeftRealPtr_fx[tapIdx] = filterStatesLeftRealPtr_fx[tapIdx - 1];
105 4370638400 : move32();
106 4370638400 : filterStatesLeftImagPtr_fx[tapIdx] = filterStatesLeftImagPtr_fx[tapIdx - 1];
107 4370638400 : move32();
108 4370638400 : Word32 neg_filterStatesLeftImagPtr_fx = L_negate( filterStatesLeftImagPtr_fx[tapIdx] );
109 :
110 :
111 4370638400 : outRealLeft_fx = W_mac_32_32( outRealLeft_fx, filterStatesLeftRealPtr_fx[tapIdx], filterTapsLeftRealPtr_fx[tapIdx] ); // Q30 + Q_filterStates
112 4370638400 : outRealLeft_fx = W_mac_32_32( outRealLeft_fx, neg_filterStatesLeftImagPtr_fx, filterTapsLeftImagPtr_fx[tapIdx] ); // Q30 + Q_filterStates
113 :
114 4370638400 : outImagLeft_fx = W_mac_32_32( outImagLeft_fx, filterStatesLeftRealPtr_fx[tapIdx], filterTapsLeftImagPtr_fx[tapIdx] ); // Q30 + Q_filterStates
115 4370638400 : outImagLeft_fx = W_mac_32_32( outImagLeft_fx, filterStatesLeftImagPtr_fx[tapIdx], filterTapsLeftRealPtr_fx[tapIdx] ); // Q30 + Q_filterStates
116 :
117 4370638400 : outRealRight_fx = W_mac_32_32( outRealRight_fx, filterStatesLeftRealPtr_fx[tapIdx], filterTapsRightRealPtr_fx[tapIdx] ); // Q30 + Q_filterStates
118 4370638400 : outRealRight_fx = W_mac_32_32( outRealRight_fx, neg_filterStatesLeftImagPtr_fx, filterTapsRightImagPtr_fx[tapIdx] ); // Q30 + Q_filterStates
119 :
120 4370638400 : outImagRight_fx = W_mac_32_32( outImagRight_fx, filterStatesLeftRealPtr_fx[tapIdx], filterTapsRightImagPtr_fx[tapIdx] ); // Q30 + Q_filterStates
121 4370638400 : outImagRight_fx = W_mac_32_32( outImagRight_fx, filterStatesLeftImagPtr_fx[tapIdx], filterTapsRightRealPtr_fx[tapIdx] ); // Q30 + Q_filterStates
122 : }
123 :
124 328128000 : shift_q = add( sub( Q_filterStates, Q_curr ), 1 );
125 :
126 328128000 : IF( shift_q != 0 )
127 : {
128 328128000 : outRealLeft_fx = W_shr( outRealLeft_fx, shift_q ); // Q_curr + Q29
129 328128000 : outImagLeft_fx = W_shr( outImagLeft_fx, shift_q ); // Q_curr + Q29
130 328128000 : outRealRight_fx = W_shr( outRealRight_fx, shift_q ); // Q_curr + Q29
131 328128000 : outImagRight_fx = W_shr( outImagRight_fx, shift_q ); // Q_curr + Q29
132 328128000 : hBinRenderer->hBinRenConvModule->Q_filterStatesLeft = Q_curr;
133 328128000 : move16();
134 : }
135 :
136 328128000 : filterStatesLeftRealPtr_fx[0] = CLDFB_real[chIdx][k][bandIdx];
137 328128000 : move32();
138 328128000 : filterStatesLeftImagPtr_fx[0] = CLDFB_imag[chIdx][k][bandIdx];
139 328128000 : move32();
140 :
141 :
142 : /* Left Real and Imag */
143 :
144 328128000 : Word32 temp1 = L_shr( filterStatesLeftRealPtr_fx[0], 1 ); // Q_curr -1
145 328128000 : Word32 temp2 = L_shr( filterStatesLeftImagPtr_fx[0], 1 ); // Q_curr -1
146 328128000 : Word32 neg_temp2 = L_negate( temp2 ); // Q_curr -1
147 :
148 :
149 328128000 : outRealLeft_fx = W_mac_32_32( outRealLeft_fx, temp1, filterTapsLeftRealPtr_fx[0] );
150 328128000 : outRealLeft_fx = W_mac_32_32( outRealLeft_fx, neg_temp2, filterTapsLeftImagPtr_fx[0] );
151 328128000 : Cldfb_RealBuffer_64fx[0][k] = W_add( Cldfb_RealBuffer_64fx[0][k], outRealLeft_fx ); // Q29 + Q_curr
152 328128000 : move64();
153 :
154 328128000 : outImagLeft_fx = W_mac_32_32( outImagLeft_fx, temp1, filterTapsLeftImagPtr_fx[0] );
155 328128000 : outImagLeft_fx = W_mac_32_32( outImagLeft_fx, temp2, filterTapsLeftRealPtr_fx[0] );
156 328128000 : Cldfb_ImagBuffer_64fx[0][k] = W_add( Cldfb_ImagBuffer_64fx[0][k], outImagLeft_fx ); // Q29 + Q_curr
157 328128000 : move64();
158 :
159 : /* Right Real and Imag */
160 328128000 : outRealRight_fx = W_mac_32_32( outRealRight_fx, temp1, filterTapsRightRealPtr_fx[0] );
161 328128000 : outRealRight_fx = W_mac_32_32( outRealRight_fx, neg_temp2, filterTapsRightImagPtr_fx[0] );
162 328128000 : Cldfb_RealBuffer_64fx[1][k] = W_add( Cldfb_RealBuffer_64fx[1][k], outRealRight_fx ); // Q29 + Q_curr
163 328128000 : move64();
164 :
165 328128000 : outImagRight_fx = W_mac_32_32( outImagRight_fx, temp1, filterTapsRightImagPtr_fx[0] );
166 328128000 : outImagRight_fx = W_mac_32_32( outImagRight_fx, temp2, filterTapsRightRealPtr_fx[0] );
167 328128000 : Cldfb_ImagBuffer_64fx[1][k] = W_add( Cldfb_ImagBuffer_64fx[1][k], outImagRight_fx ); // Q29 + Q_curr
168 328128000 : move64();
169 : }
170 : }
171 18522150 : FOR( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ )
172 : {
173 61740500 : FOR( k = 0; k < MAX_PARAM_SPATIAL_SUBFRAMES; k++ )
174 : {
175 49392400 : out_Conv_CLDFB_real[chIdx][k][bandIdx] = W_shl_sat_l( Cldfb_RealBuffer_64fx[chIdx][k], shift_q6 ); // Q6
176 49392400 : move32();
177 49392400 : out_Conv_CLDFB_imag[chIdx][k][bandIdx] = W_shl_sat_l( Cldfb_ImagBuffer_64fx[chIdx][k], shift_q6 ); // Q6
178 49392400 : move32();
179 : }
180 : }
181 : }
182 :
183 :
184 136305 : return;
185 : }
186 :
187 : /*-------------------------------------------------------------------------
188 : * ivas_binRenderer_convModuleOpen()
189 : *
190 : * Open convolution module handle of fastconv binaural renderer
191 : *-------------------------------------------------------------------------*/
192 271 : static ivas_error ivas_binRenderer_convModuleOpen(
193 : BINAURAL_RENDERER_HANDLE hBinRenderer,
194 : const Word16 renderer_type,
195 : const Word16 isLoudspeaker,
196 : const AUDIO_CONFIG input_config,
197 : const HRTFS_FASTCONV_HANDLE hHrtf )
198 : {
199 : Word16 bandIdx, chIdx;
200 :
201 : BINRENDERER_CONV_MODULE_HANDLE_FX hBinRenConvModule;
202 :
203 : /*-----------------------------------------------------------------*
204 : * prepare library opening
205 : *-----------------------------------------------------------------*/
206 :
207 271 : IF( ( hBinRenConvModule = (BINRENDERER_CONV_MODULE_HANDLE_FX) malloc( sizeof( BINRENDERER_CONV_MODULE_FX ) ) ) == NULL )
208 : {
209 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
210 : }
211 :
212 271 : IF( !isLoudspeaker )
213 : {
214 140 : hBinRenderer->nInChannels = audioCfg2channels( input_config );
215 140 : move16();
216 : }
217 : ELSE
218 : {
219 : /* Note: needs to be revisited if multiple LFE support is required */
220 131 : hBinRenderer->nInChannels = sub( audioCfg2channels( input_config ), isLoudspeaker );
221 131 : move16();
222 : }
223 :
224 271 : IF( EQ_16( renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) )
225 : {
226 69 : hBinRenConvModule->numTaps = BINAURAL_NTAPS_MAX;
227 69 : move16();
228 :
229 : /* Use variable order filtering */
230 69 : bandIdx = 0;
231 69 : move16();
232 414 : FOR( ; bandIdx < 5; bandIdx++ )
233 : {
234 345 : hBinRenConvModule->numTapsArray[bandIdx] = hBinRenConvModule->numTaps;
235 345 : move16();
236 : }
237 414 : FOR( ; bandIdx < 10; bandIdx++ )
238 : {
239 345 : hBinRenConvModule->numTapsArray[bandIdx] = NUM_TAPS_F0_6;
240 345 : move16();
241 : }
242 759 : FOR( ; bandIdx < 20; bandIdx++ )
243 : {
244 690 : hBinRenConvModule->numTapsArray[bandIdx] = NUM_TAPS_F0_5;
245 690 : move16();
246 : }
247 759 : FOR( ; bandIdx < 30; bandIdx++ )
248 : {
249 690 : hBinRenConvModule->numTapsArray[bandIdx] = NUM_TAPS_F0_4;
250 690 : move16();
251 : }
252 1319 : FOR( ; bandIdx < hBinRenderer->conv_band; bandIdx++ )
253 : {
254 1250 : hBinRenConvModule->numTapsArray[bandIdx] = NUM_TAPS_F0_3;
255 1250 : move16();
256 : }
257 : }
258 : ELSE
259 : {
260 202 : IF( EQ_16( hBinRenderer->ivas_format, SBA_FORMAT ) )
261 : {
262 140 : hBinRenConvModule->numTaps = BINAURAL_NTAPS_SBA;
263 140 : move16();
264 : }
265 : ELSE
266 : {
267 62 : hBinRenConvModule->numTaps = BINAURAL_NTAPS;
268 62 : move16();
269 : }
270 :
271 : /* Use fixed order filtering */
272 202 : bandIdx = 0;
273 202 : move16();
274 8312 : FOR( ; bandIdx < hBinRenderer->conv_band; bandIdx++ )
275 : {
276 8110 : hBinRenConvModule->numTapsArray[bandIdx] = hBinRenConvModule->numTaps;
277 8110 : move16();
278 : }
279 : }
280 :
281 : /* allocate memory for filter states */
282 271 : IF( ( hBinRenConvModule->filterTapsLeftReal_fx = (Word32 ***) malloc( hBinRenderer->conv_band * sizeof( Word32 ** ) ) ) == NULL )
283 : {
284 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
285 : }
286 :
287 271 : IF( ( hBinRenConvModule->filterTapsLeftImag_fx = (Word32 ***) malloc( hBinRenderer->conv_band * sizeof( Word32 ** ) ) ) == NULL )
288 : {
289 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
290 : }
291 :
292 271 : IF( ( hBinRenConvModule->filterTapsRightReal_fx = (Word32 ***) malloc( hBinRenderer->conv_band * sizeof( Word32 ** ) ) ) == NULL )
293 : {
294 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
295 : }
296 :
297 271 : IF( ( hBinRenConvModule->filterTapsRightImag_fx = (Word32 ***) malloc( hBinRenderer->conv_band * sizeof( Word32 ** ) ) ) == NULL )
298 : {
299 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
300 : }
301 :
302 11671 : FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
303 : {
304 11400 : IF( ( hBinRenConvModule->filterTapsLeftReal_fx[bandIdx] = (Word32 **) malloc( hBinRenderer->nInChannels * sizeof( Word32 * ) ) ) == NULL )
305 : {
306 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
307 : }
308 :
309 11400 : IF( ( hBinRenConvModule->filterTapsLeftImag_fx[bandIdx] = (Word32 **) malloc( hBinRenderer->nInChannels * sizeof( Word32 * ) ) ) == NULL )
310 : {
311 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
312 : }
313 :
314 11400 : IF( ( hBinRenConvModule->filterTapsRightReal_fx[bandIdx] = (Word32 **) malloc( hBinRenderer->nInChannels * sizeof( Word32 * ) ) ) == NULL )
315 : {
316 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
317 : }
318 :
319 11400 : IF( ( hBinRenConvModule->filterTapsRightImag_fx[bandIdx] = (Word32 **) malloc( hBinRenderer->nInChannels * sizeof( Word32 * ) ) ) == NULL )
320 : {
321 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
322 : }
323 : }
324 :
325 :
326 271 : IF( ( hBinRenConvModule->filterStatesLeftReal_fx = (Word32 ***) malloc( hBinRenderer->conv_band * sizeof( Word32 ** ) ) ) == NULL )
327 : {
328 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
329 : }
330 :
331 271 : IF( ( hBinRenConvModule->filterStatesLeftImag_fx = (Word32 ***) malloc( hBinRenderer->conv_band * sizeof( Word32 ** ) ) ) == NULL )
332 : {
333 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
334 : }
335 :
336 :
337 11671 : FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
338 : {
339 11400 : IF( ( hBinRenConvModule->filterStatesLeftReal_fx[bandIdx] = (Word32 **) malloc( hBinRenderer->nInChannels * sizeof( Word32 * ) ) ) == NULL )
340 : {
341 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
342 : }
343 :
344 11400 : IF( ( hBinRenConvModule->filterStatesLeftImag_fx[bandIdx] = (Word32 **) malloc( hBinRenderer->nInChannels * sizeof( Word32 * ) ) ) == NULL )
345 : {
346 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
347 : }
348 :
349 :
350 146130 : FOR( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ )
351 : {
352 134730 : IF( ( hBinRenConvModule->filterStatesLeftReal_fx[bandIdx][chIdx] = (Word32 *) malloc( hBinRenConvModule->numTapsArray[bandIdx] * sizeof( Word32 ) ) ) == NULL )
353 : {
354 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
355 : }
356 :
357 134730 : IF( ( hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx] = (Word32 *) malloc( hBinRenConvModule->numTapsArray[bandIdx] * sizeof( Word32 ) ) ) == NULL )
358 : {
359 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) );
360 : }
361 : }
362 : }
363 : /* set memories */
364 11671 : FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
365 : {
366 146130 : FOR( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ )
367 : {
368 134730 : Word16 tmp = 0;
369 134730 : move16();
370 :
371 134730 : IF( isLoudspeaker )
372 : {
373 28650 : IF( EQ_16( input_config, IVAS_AUDIO_CONFIG_5_1 ) )
374 : {
375 19650 : tmp = channelIndex_CICP6[chIdx];
376 19650 : move16();
377 : }
378 9000 : ELSE IF( EQ_16( input_config, IVAS_AUDIO_CONFIG_7_1 ) )
379 : {
380 0 : tmp = channelIndex_CICP12[chIdx];
381 0 : move16();
382 : }
383 9000 : ELSE IF( EQ_16( input_config, IVAS_AUDIO_CONFIG_5_1_2 ) )
384 : {
385 420 : tmp = channelIndex_CICP14[chIdx];
386 420 : move16();
387 : }
388 8580 : ELSE IF( EQ_16( input_config, IVAS_AUDIO_CONFIG_5_1_4 ) )
389 : {
390 0 : tmp = channelIndex_CICP16[chIdx];
391 0 : move16();
392 : }
393 8580 : ELSE IF( EQ_16( input_config, IVAS_AUDIO_CONFIG_7_1_4 ) )
394 : {
395 8580 : tmp = channelIndex_CICP19[chIdx];
396 8580 : move16();
397 : }
398 : }
399 :
400 134730 : IF( EQ_16( renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) )
401 : {
402 : /* set the memories to zero */
403 19150 : set32_fx( hBinRenConvModule->filterStatesLeftReal_fx[bandIdx][chIdx], 0, hBinRenConvModule->numTapsArray[bandIdx] );
404 19150 : set32_fx( hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx], 0, hBinRenConvModule->numTapsArray[bandIdx] );
405 19150 : hBinRenConvModule->Q_filterStatesLeft = 31;
406 19150 : move16();
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 115580 : set32_fx( hBinRenConvModule->filterStatesLeftReal_fx[bandIdx][chIdx], 0, hBinRenConvModule->numTaps );
419 115580 : set32_fx( hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx], 0, hBinRenConvModule->numTaps );
420 115580 : hBinRenConvModule->Q_filterStatesLeft = 31;
421 115580 : move16();
422 115580 : IF( isLoudspeaker )
423 : {
424 9500 : hBinRenConvModule->filterTapsLeftReal_fx[bandIdx][chIdx] = hHrtf->leftHRIRReal_fx[bandIdx][tmp];
425 9500 : hBinRenConvModule->filterTapsLeftImag_fx[bandIdx][chIdx] = hHrtf->leftHRIRImag_fx[bandIdx][tmp];
426 9500 : hBinRenConvModule->filterTapsRightReal_fx[bandIdx][chIdx] = hHrtf->rightHRIRReal_fx[bandIdx][tmp];
427 9500 : hBinRenConvModule->filterTapsRightImag_fx[bandIdx][chIdx] = hHrtf->rightHRIRImag_fx[bandIdx][tmp];
428 : }
429 : ELSE
430 : {
431 106080 : IF( EQ_16( input_config, IVAS_AUDIO_CONFIG_HOA3 ) )
432 : {
433 : /* HOA3 filter coefficients */
434 106080 : hBinRenConvModule->filterTapsLeftReal_fx[bandIdx][chIdx] = hHrtf->leftHRIRReal_HOA3_fx[bandIdx][chIdx];
435 106080 : hBinRenConvModule->filterTapsLeftImag_fx[bandIdx][chIdx] = hHrtf->leftHRIRImag_HOA3_fx[bandIdx][chIdx];
436 106080 : hBinRenConvModule->filterTapsRightReal_fx[bandIdx][chIdx] = hHrtf->rightHRIRReal_HOA3_fx[bandIdx][chIdx];
437 106080 : hBinRenConvModule->filterTapsRightImag_fx[bandIdx][chIdx] = hHrtf->rightHRIRImag_HOA3_fx[bandIdx][chIdx];
438 : }
439 0 : ELSE IF( EQ_16( input_config, IVAS_AUDIO_CONFIG_HOA2 ) )
440 : {
441 : /* HOA2 filter coefficients */
442 0 : hBinRenConvModule->filterTapsLeftReal_fx[bandIdx][chIdx] = hHrtf->leftHRIRReal_HOA2_fx[bandIdx][chIdx];
443 0 : hBinRenConvModule->filterTapsLeftImag_fx[bandIdx][chIdx] = hHrtf->leftHRIRImag_HOA2_fx[bandIdx][chIdx];
444 0 : hBinRenConvModule->filterTapsRightReal_fx[bandIdx][chIdx] = hHrtf->rightHRIRReal_HOA2_fx[bandIdx][chIdx];
445 0 : hBinRenConvModule->filterTapsRightImag_fx[bandIdx][chIdx] = hHrtf->rightHRIRImag_HOA2_fx[bandIdx][chIdx];
446 : }
447 0 : ELSE IF( EQ_16( input_config, IVAS_AUDIO_CONFIG_FOA ) )
448 : {
449 : /* FOA filter coefficients */
450 0 : hBinRenConvModule->filterTapsLeftReal_fx[bandIdx][chIdx] = hHrtf->leftHRIRReal_FOA_fx[bandIdx][chIdx];
451 0 : hBinRenConvModule->filterTapsLeftImag_fx[bandIdx][chIdx] = hHrtf->leftHRIRImag_FOA_fx[bandIdx][chIdx];
452 0 : hBinRenConvModule->filterTapsRightReal_fx[bandIdx][chIdx] = hHrtf->rightHRIRReal_FOA_fx[bandIdx][chIdx];
453 0 : hBinRenConvModule->filterTapsRightImag_fx[bandIdx][chIdx] = hHrtf->rightHRIRImag_FOA_fx[bandIdx][chIdx];
454 : }
455 : ELSE
456 : {
457 0 : return IVAS_ERR_INVALID_INPUT_FORMAT;
458 : }
459 : }
460 : }
461 : }
462 : }
463 :
464 :
465 271 : hBinRenderer->hBinRenConvModule = hBinRenConvModule;
466 :
467 271 : return IVAS_ERR_OK;
468 : }
469 :
470 : /*-------------------------------------------------------------------------*
471 : * ivas_init_binaural_hrtf()
472 : *
473 : * initialize memory for HrtfFastConv structure elements
474 : *-------------------------------------------------------------------------*/
475 61 : void ivas_init_binaural_hrtf_fx(
476 : HRTFS_FASTCONV *HrtfFastConv /* i/o: FASTCONV HRTF structure */
477 : )
478 : {
479 : Word16 i;
480 :
481 61 : HrtfFastConv->leftHRIRReal_HOA3_fx = NULL;
482 61 : HrtfFastConv->leftHRIRImag_HOA3_fx = NULL;
483 61 : HrtfFastConv->rightHRIRReal_HOA3_fx = NULL;
484 61 : HrtfFastConv->rightHRIRImag_HOA3_fx = NULL;
485 61 : HrtfFastConv->FASTCONV_HOA3_latency_s_fx = 0;
486 61 : move32();
487 :
488 61 : HrtfFastConv->leftHRIRReal_fx = NULL;
489 61 : HrtfFastConv->leftHRIRImag_fx = NULL;
490 61 : HrtfFastConv->rightHRIRReal_fx = NULL;
491 61 : HrtfFastConv->rightHRIRImag_fx = NULL;
492 61 : HrtfFastConv->FASTCONV_HRIR_latency_s_fx = 0;
493 61 : move32();
494 :
495 61 : HrtfFastConv->leftBRIRReal_fx = NULL;
496 61 : HrtfFastConv->leftBRIRImag_fx = NULL;
497 61 : HrtfFastConv->rightBRIRReal_fx = NULL;
498 61 : HrtfFastConv->rightBRIRImag_fx = NULL;
499 61 : HrtfFastConv->FASTCONV_BRIR_latency_s_fx = 0;
500 61 : move32();
501 :
502 61 : HrtfFastConv->leftHRIRReal_HOA2_fx = NULL;
503 61 : HrtfFastConv->leftHRIRImag_HOA2_fx = NULL;
504 61 : HrtfFastConv->rightHRIRReal_HOA2_fx = NULL;
505 61 : HrtfFastConv->rightHRIRImag_HOA2_fx = NULL;
506 61 : HrtfFastConv->FASTCONV_HOA2_latency_s_fx = 0;
507 61 : move32();
508 :
509 61 : HrtfFastConv->leftHRIRReal_FOA_fx = NULL;
510 61 : HrtfFastConv->leftHRIRImag_FOA_fx = NULL;
511 61 : HrtfFastConv->rightHRIRReal_FOA_fx = NULL;
512 61 : HrtfFastConv->rightHRIRImag_FOA_fx = NULL;
513 61 : HrtfFastConv->FASTCONV_FOA_latency_s_fx = 0;
514 61 : move32();
515 :
516 61 : HrtfFastConv->allocate_init_flag = 0;
517 61 : move16();
518 :
519 3721 : FOR( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ )
520 : {
521 3660 : HrtfFastConv->fastconvReverberationTimes_fx[i] = 0;
522 3660 : move32();
523 3660 : HrtfFastConv->fastconvReverberationEneCorrections_fx[i] = 0;
524 3660 : move32();
525 : }
526 :
527 61 : return;
528 : }
529 :
530 : /*-------------------------------------------------------------------------*
531 : * ivas_alloc_pppMem()
532 : *
533 : * Allocate memory for tripple pointer elements
534 : *-------------------------------------------------------------------------*/
535 728 : static ivas_error ivas_alloc_pppMem_fx(
536 : Word32 ****pppMem, /*Qx*/
537 : const Word16 dim1,
538 : const Word16 dim2,
539 : const Word16 dim3,
540 : const Word16 allocate_init_flag )
541 : {
542 : Word16 i, j;
543 728 : Word32 ***localMem = NULL;
544 :
545 728 : IF( ( localMem = (Word32 ***) malloc( dim1 * sizeof( Word32 ** ) ) ) == NULL )
546 : {
547 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HRTF memory" );
548 : }
549 :
550 37128 : FOR( i = 0; i < dim1; i++ ){
551 36400 : IF( ( localMem[i] = (Word32 **) malloc( dim2 * sizeof( Word32 * ) ) ) == NULL ){
552 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HRTF memory" );
553 : }
554 36400 : IF( allocate_init_flag == 0 )
555 : {
556 294400 : FOR( j = 0; j < dim2; j++ )
557 : {
558 271400 : IF( ( localMem[i][j] = (Word32 *) malloc( dim3 * sizeof( Word32 ) ) ) == NULL )
559 : {
560 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HRTF memory" );
561 : }
562 : }
563 : }
564 : }
565 :
566 728 : *pppMem = localMem;
567 :
568 728 : return IVAS_ERR_OK;
569 : }
570 :
571 : /*-------------------------------------------------------------------------*
572 : * ivas_allocate_binaural_hrtf()
573 : *
574 : * Allocate memory for HrtfFastConv structure elements
575 : *-------------------------------------------------------------------------*/
576 153 : ivas_error ivas_allocate_binaural_hrtf_fx(
577 : HRTFS_FASTCONV *HrtfFastConv, /* i/o: FASTCONV HRTF structure */
578 : const AUDIO_CONFIG input_config, /* i : input audio configuration */
579 : const BINAURAL_INPUT_AUDIO_CONFIG bin_input_config, /* i : binaural input audio config */
580 : const RENDERER_TYPE renderer_type, /* i : renderer type */
581 : const Word16 allocate_init_flag /* i : Memory allocation flag */
582 : )
583 : {
584 153 : test();
585 153 : IF( EQ_32( input_config, IVAS_AUDIO_CONFIG_HOA3 ) || EQ_32( bin_input_config, BINAURAL_INPUT_AUDIO_CONFIG_HOA3 ) )
586 : {
587 52 : test();
588 52 : test();
589 52 : test();
590 52 : IF( ( HrtfFastConv->leftHRIRReal_HOA3_fx != NULL ) && ( HrtfFastConv->leftHRIRImag_HOA3_fx != NULL ) && ( HrtfFastConv->rightHRIRReal_HOA3_fx != NULL ) && ( HrtfFastConv->rightHRIRImag_HOA3_fx != NULL ) )
591 : {
592 0 : return IVAS_ERR_OK;
593 : }
594 : ELSE
595 : {
596 52 : IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->leftHRIRReal_HOA3_fx, BINAURAL_CONVBANDS, HOA3_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) )
597 : {
598 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftHRIRReal_HOA3" );
599 : }
600 52 : IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->leftHRIRImag_HOA3_fx, BINAURAL_CONVBANDS, HOA3_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) )
601 : {
602 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftHRIRImag_HOA3" );
603 : }
604 52 : IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->rightHRIRReal_HOA3_fx, BINAURAL_CONVBANDS, HOA3_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) )
605 : {
606 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRReal_HOA3" );
607 : }
608 52 : IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->rightHRIRImag_HOA3_fx, BINAURAL_CONVBANDS, HOA3_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) )
609 : {
610 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRImag_HOA3" );
611 : }
612 : }
613 : }
614 :
615 153 : test();
616 153 : IF( EQ_32( input_config, IVAS_AUDIO_CONFIG_HOA2 ) || EQ_32( bin_input_config, BINAURAL_INPUT_AUDIO_CONFIG_HOA2 ) )
617 : {
618 23 : test();
619 23 : test();
620 23 : test();
621 23 : IF( ( HrtfFastConv->leftHRIRReal_HOA2_fx != NULL ) && ( HrtfFastConv->leftHRIRImag_HOA2_fx != NULL ) && ( HrtfFastConv->rightHRIRReal_HOA2_fx != NULL ) && ( HrtfFastConv->rightHRIRImag_HOA2_fx != NULL ) )
622 : {
623 0 : return IVAS_ERR_OK;
624 : }
625 : ELSE
626 : {
627 23 : IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->leftHRIRReal_HOA2_fx, BINAURAL_CONVBANDS, HOA2_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) )
628 : {
629 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftHRIRReal_HOA2" );
630 : }
631 23 : IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->leftHRIRImag_HOA2_fx, BINAURAL_CONVBANDS, HOA2_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) )
632 : {
633 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftHRIRImag_HOA2" );
634 : }
635 23 : IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->rightHRIRReal_HOA2_fx, BINAURAL_CONVBANDS, HOA2_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) )
636 : {
637 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRReal_HOA2" );
638 : }
639 23 : IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->rightHRIRImag_HOA2_fx, BINAURAL_CONVBANDS, HOA2_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) )
640 : {
641 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRImag_HOA2" );
642 : }
643 : }
644 : }
645 :
646 153 : test();
647 153 : IF( EQ_32( input_config, IVAS_AUDIO_CONFIG_FOA ) || EQ_32( bin_input_config, BINAURAL_INPUT_AUDIO_CONFIG_FOA ) )
648 : {
649 23 : test();
650 23 : test();
651 23 : test();
652 23 : IF( ( HrtfFastConv->leftHRIRReal_FOA_fx != NULL ) && ( HrtfFastConv->leftHRIRImag_FOA_fx != NULL ) && ( HrtfFastConv->rightHRIRReal_FOA_fx != NULL ) && ( HrtfFastConv->rightHRIRImag_FOA_fx != NULL ) )
653 : {
654 0 : return IVAS_ERR_OK;
655 : }
656 : ELSE
657 : {
658 23 : IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->leftHRIRReal_FOA_fx, BINAURAL_CONVBANDS, FOA_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) )
659 : {
660 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftHRIRReal_FOA" );
661 : }
662 23 : IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->leftHRIRImag_FOA_fx, BINAURAL_CONVBANDS, FOA_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) )
663 : {
664 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftHRIRImag_FOA" );
665 : }
666 23 : IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->rightHRIRReal_FOA_fx, BINAURAL_CONVBANDS, FOA_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) )
667 : {
668 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRReal_FOA" );
669 : }
670 23 : IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->rightHRIRImag_FOA_fx, BINAURAL_CONVBANDS, FOA_CHANNELS, BINAURAL_NTAPS_SBA, allocate_init_flag ) ) )
671 : {
672 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRImag_FOA" );
673 : }
674 : }
675 : }
676 :
677 153 : test();
678 153 : IF( EQ_32( renderer_type, RENDERER_BINAURAL_FASTCONV ) || EQ_32( bin_input_config, BINAURAL_INPUT_AUDIO_CONFIG_COMBINED ) )
679 : {
680 140 : test();
681 140 : test();
682 140 : test();
683 140 : IF( ( HrtfFastConv->leftHRIRReal_fx != NULL ) && ( HrtfFastConv->leftHRIRImag_fx != NULL ) && ( HrtfFastConv->rightHRIRReal_fx != NULL ) && ( HrtfFastConv->rightHRIRImag_fx != NULL ) )
684 : {
685 92 : return IVAS_ERR_OK;
686 : }
687 : ELSE
688 : {
689 48 : IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->leftHRIRReal_fx, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS, allocate_init_flag ) ) )
690 : {
691 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftHRIRReal" );
692 : }
693 48 : IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->leftHRIRImag_fx, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS, allocate_init_flag ) ) )
694 : {
695 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftHRIRImag" );
696 : }
697 48 : IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->rightHRIRReal_fx, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS, allocate_init_flag ) ) )
698 : {
699 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRReal" );
700 : }
701 48 : IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->rightHRIRImag_fx, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS, allocate_init_flag ) ) )
702 : {
703 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightHRIRImag" );
704 : }
705 : }
706 : }
707 :
708 61 : test();
709 61 : IF( EQ_32( renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) || EQ_32( bin_input_config, BINAURAL_INPUT_AUDIO_CONFIG_COMBINED ) )
710 : {
711 36 : test();
712 36 : test();
713 36 : test();
714 36 : IF( ( HrtfFastConv->leftBRIRReal_fx != NULL ) && ( HrtfFastConv->leftBRIRImag_fx != NULL ) && ( HrtfFastConv->rightBRIRReal_fx != NULL ) && ( HrtfFastConv->rightBRIRImag_fx != NULL ) )
715 : {
716 0 : return IVAS_ERR_OK;
717 : }
718 : ELSE
719 : {
720 36 : IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->leftBRIRReal_fx, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS_MAX, allocate_init_flag ) ) )
721 : {
722 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftBRIRReal" );
723 : }
724 36 : IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->leftBRIRImag_fx, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS_MAX, allocate_init_flag ) ) )
725 : {
726 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for leftBRIRImag" );
727 : }
728 36 : IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->rightBRIRReal_fx, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS_MAX, allocate_init_flag ) ) )
729 : {
730 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightBRIRReal" );
731 : }
732 36 : IF( NE_32( IVAS_ERR_OK, ivas_alloc_pppMem_fx( &HrtfFastConv->rightBRIRImag_fx, BINAURAL_CONVBANDS, HRTF_LS_CHANNELS, BINAURAL_NTAPS_MAX, allocate_init_flag ) ) )
733 : {
734 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for rightBRIRImag" );
735 : }
736 : }
737 : }
738 :
739 61 : return IVAS_ERR_OK;
740 : }
741 :
742 : /*-------------------------------------------------------------------------*
743 : * ivas_binaural_HRTF_open()
744 : *
745 : *
746 : *-------------------------------------------------------------------------*/
747 271 : static ivas_error ivas_binaural_hrtf_open_fx(
748 : HRTFS_FASTCONV_HANDLE *hHrtfFastConv, /* i : fastconv HRTF handle */
749 : const AUDIO_CONFIG input_config, /* i : output configuration */
750 : const RENDERER_TYPE renderer_type /* i : renderer type */
751 : )
752 : {
753 : Word16 i, j;
754 : ivas_error error;
755 :
756 271 : test();
757 271 : IF( hHrtfFastConv != NULL && *hHrtfFastConv != NULL )
758 : {
759 : /* Tables already loaded from file */
760 233 : return IVAS_ERR_OK;
761 : }
762 : ELSE
763 : {
764 : /* Initialise tables from ROM */
765 : HRTFS_FASTCONV *HrtfFastConv;
766 :
767 38 : IF( ( HrtfFastConv = (HRTFS_FASTCONV *) malloc( sizeof( HRTFS_FASTCONV ) ) ) == NULL )
768 : {
769 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate memory for FastConv HRTF tables" );
770 : }
771 :
772 38 : ivas_init_binaural_hrtf_fx( HrtfFastConv );
773 :
774 38 : test();
775 38 : IF( EQ_32( input_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( renderer_type, RENDERER_BINAURAL_FASTCONV ) )
776 : {
777 25 : HrtfFastConv->FASTCONV_HRIR_latency_s_fx = FASTCONV_HRIR_latency_s_fx;
778 25 : move32();
779 : }
780 38 : if ( EQ_32( input_config, IVAS_AUDIO_CONFIG_HOA2 ) )
781 : {
782 0 : HrtfFastConv->FASTCONV_HOA2_latency_s_fx = FASTCONV_HOA2_latency_s_fx;
783 0 : move32();
784 : }
785 38 : if ( EQ_32( input_config, IVAS_AUDIO_CONFIG_HOA3 ) )
786 : {
787 29 : HrtfFastConv->FASTCONV_HOA3_latency_s_fx = FASTCONV_HOA3_latency_s_fx;
788 29 : move32();
789 : }
790 38 : if ( EQ_32( input_config, IVAS_AUDIO_CONFIG_FOA ) )
791 : {
792 0 : HrtfFastConv->FASTCONV_FOA_latency_s_fx = FASTCONV_FOA_latency_s_fx;
793 0 : move32();
794 : }
795 38 : test();
796 38 : IF( EQ_32( input_config, IVAS_AUDIO_CONFIG_BINAURAL ) || EQ_32( renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) )
797 : {
798 13 : HrtfFastConv->FASTCONV_BRIR_latency_s_fx = FASTCONV_BRIR_latency_s_fx;
799 13 : move32();
800 : }
801 :
802 38 : HrtfFastConv->allocate_init_flag = 1;
803 38 : move16();
804 :
805 38 : 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 ) )
806 : {
807 0 : return error;
808 : }
809 1938 : FOR( i = 0; i < BINAURAL_CONVBANDS; i++ )
810 : {
811 1900 : IF( EQ_32( renderer_type, RENDERER_BINAURAL_FASTCONV ) )
812 : {
813 20000 : FOR( j = 0; j < HRTF_LS_CHANNELS; j++ )
814 : {
815 18750 : HrtfFastConv->leftHRIRReal_fx[i][j] = leftHRIRReal_fx[i][j];
816 18750 : HrtfFastConv->leftHRIRImag_fx[i][j] = leftHRIRImag_fx[i][j];
817 18750 : HrtfFastConv->rightHRIRReal_fx[i][j] = rightHRIRReal_fx[i][j];
818 18750 : HrtfFastConv->rightHRIRImag_fx[i][j] = rightHRIRImag_fx[i][j];
819 : }
820 : }
821 650 : ELSE IF( EQ_32( renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) )
822 : {
823 10400 : FOR( j = 0; j < HRTF_LS_CHANNELS; j++ )
824 : {
825 9750 : HrtfFastConv->leftBRIRReal_fx[i][j] = leftBRIRReal_fx[i][j];
826 9750 : HrtfFastConv->leftBRIRImag_fx[i][j] = leftBRIRImag_fx[i][j];
827 9750 : HrtfFastConv->rightBRIRReal_fx[i][j] = rightBRIRReal_fx[i][j];
828 9750 : HrtfFastConv->rightBRIRImag_fx[i][j] = rightBRIRImag_fx[i][j];
829 : }
830 : }
831 1900 : IF( EQ_32( input_config, IVAS_AUDIO_CONFIG_HOA3 ) )
832 : {
833 24650 : FOR( j = 0; j < HOA3_CHANNELS; j++ )
834 : {
835 23200 : HrtfFastConv->leftHRIRReal_HOA3_fx[i][j] = leftHRIRReal_HOA3_fx[i][j];
836 23200 : HrtfFastConv->leftHRIRImag_HOA3_fx[i][j] = leftHRIRImag_HOA3_fx[i][j];
837 23200 : HrtfFastConv->rightHRIRReal_HOA3_fx[i][j] = rightHRIRReal_HOA3_fx[i][j];
838 23200 : HrtfFastConv->rightHRIRImag_HOA3_fx[i][j] = rightHRIRImag_HOA3_fx[i][j];
839 : }
840 : }
841 1900 : IF( EQ_32( input_config, IVAS_AUDIO_CONFIG_HOA2 ) )
842 : {
843 0 : FOR( j = 0; j < HOA2_CHANNELS; j++ )
844 : {
845 0 : HrtfFastConv->leftHRIRReal_HOA2_fx[i][j] = leftHRIRReal_HOA2_fx[i][j];
846 0 : HrtfFastConv->leftHRIRImag_HOA2_fx[i][j] = leftHRIRImag_HOA2_fx[i][j];
847 0 : HrtfFastConv->rightHRIRReal_HOA2_fx[i][j] = rightHRIRReal_HOA2_fx[i][j];
848 0 : HrtfFastConv->rightHRIRImag_HOA2_fx[i][j] = rightHRIRImag_HOA2_fx[i][j];
849 : }
850 : }
851 1900 : IF( EQ_32( input_config, IVAS_AUDIO_CONFIG_FOA ) )
852 : {
853 0 : FOR( j = 0; j < FOA_CHANNELS; j++ )
854 : {
855 0 : HrtfFastConv->leftHRIRReal_FOA_fx[i][j] = leftHRIRReal_FOA_fx[i][j];
856 0 : HrtfFastConv->leftHRIRImag_FOA_fx[i][j] = leftHRIRImag_FOA_fx[i][j];
857 0 : HrtfFastConv->rightHRIRReal_FOA_fx[i][j] = rightHRIRReal_FOA_fx[i][j];
858 0 : HrtfFastConv->rightHRIRImag_FOA_fx[i][j] = rightHRIRImag_FOA_fx[i][j];
859 : }
860 : }
861 : }
862 38 : Copy32( fastconvReverberationTimes_fx, HrtfFastConv->fastconvReverberationTimes_fx, CLDFB_NO_CHANNELS_MAX );
863 38 : Copy32( fastconvReverberationEneCorrections_fx, HrtfFastConv->fastconvReverberationEneCorrections_fx, CLDFB_NO_CHANNELS_MAX );
864 :
865 38 : *hHrtfFastConv = HrtfFastConv;
866 : }
867 :
868 38 : return IVAS_ERR_OK;
869 : }
870 : /*-------------------------------------------------------------------------*
871 : * ivas_binaural_obtain_DMX_fx()
872 : *
873 : *
874 : *-------------------------------------------------------------------------*/
875 :
876 0 : static void ivas_binaural_obtain_DMX_fx(
877 : const Word16 numTimeSlots,
878 : BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: fastconv binaural renderer handle */
879 : Word32 RealBuffer[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : Contains the LS signals Q_in */
880 : Word32 ImagBuffer[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i : Contains the LS signals Q_in */
881 : Word32 realDMX[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /*Q_in-1*/
882 : Word32 imagDMX[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX] ) /*Q_in-1*/
883 : {
884 : Word16 chIdx, bandIdx, k;
885 :
886 0 : test();
887 0 : IF( EQ_32( hBinRenderer->ivas_format, MC_FORMAT ) )
888 : {
889 : /* Obtain the downmix */
890 : Word32 P_in_fx[CLDFB_NO_CHANNELS_MAX];
891 : Word32 P_out_fx, factEQ_fx;
892 : Word16 chOutIdx;
893 : Word32 temp1_fx, temp2_fx;
894 :
895 0 : FOR( k = 0; k < numTimeSlots; k++ )
896 : {
897 0 : FOR( chOutIdx = 0; chOutIdx < BINAURAL_CHANNELS; chOutIdx++ )
898 : {
899 0 : set32_fx( realDMX[chOutIdx][k], 0, CLDFB_NO_CHANNELS_MAX );
900 0 : set32_fx( imagDMX[chOutIdx][k], 0, CLDFB_NO_CHANNELS_MAX );
901 : }
902 : }
903 :
904 0 : FOR( chOutIdx = 0; chOutIdx < BINAURAL_CHANNELS; chOutIdx++ )
905 : {
906 0 : set32_fx( P_in_fx, 0, hBinRenderer->conv_band );
907 :
908 0 : FOR( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ )
909 : {
910 0 : Word32 dmxConst = hBinRenderer->hReverb->dmxmtx_fx[chOutIdx][chIdx];
911 0 : move32();
912 :
913 0 : FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
914 : {
915 0 : FOR( k = 0; k < numTimeSlots; k++ )
916 : {
917 0 : temp1_fx = Mpy_32_32( RealBuffer[chIdx][k][bandIdx], dmxConst ); // Q_in
918 0 : temp2_fx = Mpy_32_32( ImagBuffer[chIdx][k][bandIdx], dmxConst ); // Q_in
919 0 : realDMX[chOutIdx][k][bandIdx] = L_add( realDMX[chOutIdx][k][bandIdx], temp1_fx ); // Q_in
920 0 : move32();
921 0 : imagDMX[chOutIdx][k][bandIdx] = L_add( imagDMX[chOutIdx][k][bandIdx], temp2_fx ); // Q_in
922 0 : move32();
923 :
924 0 : 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
925 0 : move32();
926 : }
927 : }
928 : }
929 :
930 0 : FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
931 : {
932 0 : P_out_fx = 0;
933 0 : move32();
934 0 : FOR( k = 0; k < numTimeSlots; k++ )
935 : {
936 0 : temp1_fx = realDMX[chOutIdx][k][bandIdx];
937 0 : move32();
938 0 : temp2_fx = imagDMX[chOutIdx][k][bandIdx];
939 0 : move32();
940 0 : 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
941 : }
942 0 : test();
943 0 : IF( ( P_in_fx[bandIdx] <= 0 ) || ( P_out_fx <= 0 ) )
944 : {
945 0 : factEQ_fx = 0x40000000; // 1.0f in Q30
946 0 : move32();
947 : }
948 : ELSE
949 : {
950 0 : Word16 div = divide3232( P_in_fx[bandIdx], P_out_fx );
951 0 : Word16 exp = norm_l( div );
952 0 : factEQ_fx = Sqrt32( L_shl( div, Q16 ), &exp );
953 0 : factEQ_fx = L_shl( factEQ_fx, sub( exp, 1 ) ); // Q30
954 : }
955 0 : if ( factEQ_fx <= 0 )
956 : {
957 0 : factEQ_fx = 0x40000000; // 1.0f in Q30
958 0 : move32();
959 : }
960 :
961 0 : factEQ_fx = L_max( L_min( factEQ_fx, 0x7fffffff ), 0x20000000 ); // Q30 , 0x7fffffff -> (1.0f in Q31)-1, 0x20000000 ->1.0f in Q29
962 0 : FOR( k = 0; k < numTimeSlots; k++ )
963 : {
964 0 : realDMX[chOutIdx][k][bandIdx] = Mpy_32_32( realDMX[chOutIdx][k][bandIdx], factEQ_fx ); // Q_in - 1
965 0 : move32();
966 0 : imagDMX[chOutIdx][k][bandIdx] = Mpy_32_32( imagDMX[chOutIdx][k][bandIdx], factEQ_fx ); // Q_in - 1
967 0 : move32();
968 : }
969 : }
970 : }
971 : }
972 0 : ELSE IF( EQ_32( hBinRenderer->ivas_format, SBA_FORMAT ) || EQ_32( hBinRenderer->ivas_format, MASA_FORMAT ) )
973 : {
974 : Word32 *outRealLeftPtr_fx, *outImagLeftPtr_fx, *outRealRightPtr_fx, *outImagRightPtr_fx;
975 : Word32 *inRealPtr_fx, *inImagPtr_fx;
976 :
977 : /*compute DMX */
978 0 : FOR( k = 0; k < numTimeSlots; k++ )
979 : {
980 0 : outRealLeftPtr_fx = realDMX[0][k];
981 0 : outImagLeftPtr_fx = imagDMX[0][k];
982 0 : outRealRightPtr_fx = realDMX[1][k];
983 0 : outImagRightPtr_fx = imagDMX[1][k];
984 0 : set32_fx( outRealLeftPtr_fx, 0, CLDFB_NO_CHANNELS_MAX );
985 0 : set32_fx( outImagLeftPtr_fx, 0, CLDFB_NO_CHANNELS_MAX );
986 0 : set32_fx( outRealRightPtr_fx, 0, CLDFB_NO_CHANNELS_MAX );
987 0 : set32_fx( outImagRightPtr_fx, 0, CLDFB_NO_CHANNELS_MAX );
988 :
989 0 : FOR( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ )
990 : {
991 0 : Word32 foa_const_fx = L_shl( hBinRenderer->hReverb->foa_enc_fx[chIdx][1], 1 ); // Q30
992 :
993 0 : inRealPtr_fx = (Word32 *) &( RealBuffer[chIdx][k][0] );
994 0 : inImagPtr_fx = (Word32 *) &( ImagBuffer[chIdx][k][0] );
995 :
996 0 : FOR( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ )
997 : {
998 0 : outRealLeftPtr_fx[bandIdx] = L_add( outRealLeftPtr_fx[bandIdx], Mpy_32_32( inRealPtr_fx[bandIdx], L_add( ONE_IN_Q30, foa_const_fx ) ) ); // Q_in - 1
999 0 : move32();
1000 0 : outImagLeftPtr_fx[bandIdx] = L_add( outImagLeftPtr_fx[bandIdx], Mpy_32_32( inImagPtr_fx[bandIdx], L_add( ONE_IN_Q30, foa_const_fx ) ) ); // Q_in - 1
1001 0 : move32();
1002 :
1003 0 : outRealRightPtr_fx[bandIdx] = L_add( outRealRightPtr_fx[bandIdx], Mpy_32_32( inRealPtr_fx[bandIdx], L_sub( ONE_IN_Q30, foa_const_fx ) ) ); // Q_in - 1
1004 0 : move32();
1005 0 : outImagRightPtr_fx[bandIdx] = L_add( outImagRightPtr_fx[bandIdx], Mpy_32_32( inImagPtr_fx[bandIdx], L_sub( ONE_IN_Q30, foa_const_fx ) ) ); // Q_in - 1
1006 0 : move32();
1007 : }
1008 : }
1009 : }
1010 : }
1011 :
1012 0 : return;
1013 : }
1014 :
1015 : /*-------------------------------------------------------------------------
1016 : * ivas_binRenderer_open()
1017 : *
1018 : * Open fastconv binaural renderer handle
1019 : *-------------------------------------------------------------------------*/
1020 271 : ivas_error ivas_binRenderer_open_fx(
1021 : Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */
1022 : )
1023 : {
1024 : BINAURAL_RENDERER_HANDLE hBinRenderer;
1025 : Word16 convBand, chIdx, k;
1026 : ivas_error error;
1027 :
1028 271 : error = IVAS_ERR_OK;
1029 271 : move32();
1030 :
1031 : /*-----------------------------------------------------------------*
1032 : * prepare library opening
1033 : *-----------------------------------------------------------------*/
1034 :
1035 271 : IF( ( hBinRenderer = (BINAURAL_RENDERER_HANDLE) malloc( sizeof( BINAURAL_RENDERER ) ) ) == NULL )
1036 : {
1037 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural Renderer\n" ) );
1038 : }
1039 :
1040 271 : hBinRenderer->hInputSetup = &st_ivas->hIntSetup;
1041 :
1042 : /* Define of head rotation has to be done in binRendeder in CLDFB*/
1043 271 : hBinRenderer->rotInCldfb = 0;
1044 271 : move16();
1045 271 : test();
1046 271 : if ( EQ_32( st_ivas->ivas_format, MC_FORMAT ) || EQ_32( st_ivas->ivas_format, SBA_FORMAT ) )
1047 : {
1048 178 : hBinRenderer->rotInCldfb = 1;
1049 178 : move16();
1050 : }
1051 :
1052 :
1053 : /* Declare some common variables needed for renderer */
1054 : /* Which format used for binaural rendering (needed for late reverb) ? MC or SBA */
1055 271 : IF( st_ivas->hIntSetup.is_loudspeaker_setup )
1056 : {
1057 124 : hBinRenderer->ivas_format = MC_FORMAT;
1058 124 : move32();
1059 : }
1060 : ELSE
1061 : {
1062 147 : hBinRenderer->ivas_format = SBA_FORMAT;
1063 147 : move32();
1064 : }
1065 271 : 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 ) );
1066 271 : move16();
1067 :
1068 271 : convBand = hBinRenderer->max_band;
1069 271 : move16();
1070 :
1071 271 : hBinRenderer->timeSlots = MAX_PARAM_SPATIAL_SUBFRAMES; /* Corresponds to 5 msec sound to motion latency */
1072 271 : move16();
1073 :
1074 271 : IF( GT_16( convBand, BINAURAL_CONVBANDS ) )
1075 : {
1076 174 : hBinRenderer->conv_band = BINAURAL_CONVBANDS;
1077 174 : move16();
1078 : }
1079 : ELSE
1080 : {
1081 97 : hBinRenderer->conv_band = convBand;
1082 97 : move16();
1083 : }
1084 :
1085 : /*LFE rendering switched off by default*/
1086 271 : hBinRenderer->render_lfe = 0;
1087 271 : move16();
1088 :
1089 271 : test();
1090 271 : if ( NE_32( st_ivas->ivas_format, ISM_FORMAT ) && st_ivas->hIntSetup.is_loudspeaker_setup )
1091 : {
1092 124 : hBinRenderer->render_lfe = 1;
1093 124 : move16();
1094 : }
1095 :
1096 : /* Load HRTF tables */
1097 271 : IF( NE_32( ( error = ivas_binaural_hrtf_open_fx( &st_ivas->hHrtfFastConv, st_ivas->hIntSetup.output_config, st_ivas->renderer_type ) ), IVAS_ERR_OK ) )
1098 : {
1099 0 : return error;
1100 : }
1101 :
1102 271 : test();
1103 271 : IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV_ROOM ) && ( st_ivas->hIntSetup.is_loudspeaker_setup == 0 ) )
1104 7 : {
1105 : IVAS_OUTPUT_SETUP out_setup;
1106 :
1107 : /* Allocate memories and buffers needed for convolutional module in CICP19 */
1108 7 : IF( NE_32( ( error = ivas_binRenderer_convModuleOpen( hBinRenderer, st_ivas->renderer_type, 1, IVAS_AUDIO_CONFIG_7_1_4, st_ivas->hHrtfFastConv ) ), IVAS_ERR_OK ) )
1109 : {
1110 0 : return error;
1111 : }
1112 :
1113 7 : ivas_output_init( &out_setup, IVAS_AUDIO_CONFIG_7_1_4 );
1114 :
1115 7 : IF( st_ivas->hoa_dec_mtx == NULL )
1116 : {
1117 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 ) )
1118 : {
1119 0 : return error;
1120 : }
1121 : }
1122 :
1123 7 : hBinRenderer->hoa_dec_mtx = st_ivas->hoa_dec_mtx;
1124 7 : st_ivas->binaural_latency_ns = st_ivas->hHrtfFastConv->FASTCONV_BRIR_latency_s_fx;
1125 7 : move32();
1126 : }
1127 : ELSE
1128 : {
1129 : /* Allocate memories and buffers needed for convolutional module */
1130 264 : 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 ) ), IVAS_ERR_OK ) )
1131 : {
1132 0 : return error;
1133 : }
1134 :
1135 264 : IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) )
1136 : {
1137 202 : IF( EQ_32( hBinRenderer->ivas_format, MC_FORMAT ) )
1138 : {
1139 62 : st_ivas->binaural_latency_ns = st_ivas->hHrtfFastConv->FASTCONV_HRIR_latency_s_fx;
1140 62 : move32();
1141 : }
1142 : ELSE
1143 : {
1144 140 : IF( EQ_16( hBinRenderer->nInChannels, 16 ) )
1145 : {
1146 140 : st_ivas->binaural_latency_ns = st_ivas->hHrtfFastConv->FASTCONV_HOA3_latency_s_fx;
1147 140 : move32();
1148 : }
1149 0 : ELSE IF( EQ_16( hBinRenderer->nInChannels, 9 ) )
1150 : {
1151 0 : st_ivas->binaural_latency_ns = st_ivas->hHrtfFastConv->FASTCONV_HOA2_latency_s_fx;
1152 0 : move32();
1153 : }
1154 0 : ELSE IF( EQ_16( hBinRenderer->nInChannels, 4 ) )
1155 : {
1156 0 : st_ivas->binaural_latency_ns = st_ivas->hHrtfFastConv->FASTCONV_FOA_latency_s_fx;
1157 0 : move32();
1158 : }
1159 : ELSE
1160 : {
1161 0 : return IVAS_ERR_INVALID_INPUT_FORMAT;
1162 : }
1163 : }
1164 : }
1165 : ELSE
1166 : {
1167 : /* same value for MC or HOA both use MC BRIR*/
1168 62 : st_ivas->binaural_latency_ns = st_ivas->hHrtfFastConv->FASTCONV_BRIR_latency_s_fx;
1169 62 : move32();
1170 : }
1171 : }
1172 :
1173 : /* Allocate memories needed for reverb module */
1174 271 : test();
1175 271 : IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_FASTCONV ) && EQ_32( st_ivas->hIntSetup.output_config, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) )
1176 : {
1177 0 : IF( NE_32( ( error = ivas_binaural_reverb_open_fastconv_fx( &( hBinRenderer->hReverb ), hBinRenderer->conv_band, hBinRenderer->timeSlots, &( st_ivas->hRenderConfig->roomAcoustics ), st_ivas->hIntSetup.output_config, st_ivas->hDecoderConfig->output_Fs, st_ivas->hHrtfFastConv ) ), IVAS_ERR_OK ) )
1178 : {
1179 0 : return error;
1180 : }
1181 :
1182 : /* initialize the dmx matrix */
1183 0 : FOR( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ )
1184 : {
1185 0 : FOR( k = 0; k < hBinRenderer->nInChannels; k++ )
1186 : {
1187 0 : hBinRenderer->hReverb->dmxmtx_fx[chIdx][k] = dmxmtx_table_fx[chIdx][k];
1188 0 : move32();
1189 : }
1190 : }
1191 : }
1192 : ELSE
1193 : {
1194 271 : hBinRenderer->hReverb = NULL;
1195 : }
1196 :
1197 271 : hBinRenderer->hEFAPdata = NULL;
1198 :
1199 271 : IF( hBinRenderer->hReverb != NULL )
1200 : {
1201 0 : test();
1202 0 : test();
1203 0 : IF( hBinRenderer->hInputSetup->is_loudspeaker_setup == 0 )
1204 : {
1205 0 : FOR( k = 0; k < 11; k++ )
1206 : {
1207 0 : 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 );
1208 : // Q29: hBinRenderer->hReverb->foa_enc_fx[k]
1209 : }
1210 : }
1211 0 : ELSE IF( EQ_32( st_ivas->ivas_format, MC_FORMAT ) && ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) )
1212 : {
1213 0 : 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 ) )
1214 : {
1215 0 : return error;
1216 : }
1217 :
1218 : /* Copy handles to bin renderer handle*/
1219 0 : hBinRenderer->hEFAPdata = st_ivas->hEFAPdata;
1220 : }
1221 : }
1222 :
1223 : /* Copy the handles to main handle */
1224 271 : st_ivas->hBinRenderer = hBinRenderer;
1225 :
1226 271 : return error;
1227 : }
1228 :
1229 : /*-------------------------------------------------------------------------
1230 : * ivas_binRenderer_convModuleClose()
1231 : *
1232 : * Close convolution module handle of fastconv binaural renderer
1233 : *------------------------------------------------------------------------*/
1234 271 : static void ivas_binRenderer_convModuleClose_fx(
1235 : BINAURAL_RENDERER_HANDLE *hBinRenderer /* i/o: fastconv binaural renderer handle */
1236 : )
1237 : {
1238 : Word16 bandIdx, chIdx;
1239 :
1240 : BINRENDERER_CONV_MODULE_HANDLE_FX hBinRenConvModule;
1241 :
1242 271 : hBinRenConvModule = ( *hBinRenderer )->hBinRenConvModule;
1243 :
1244 271 : IF( hBinRenConvModule == NULL )
1245 : {
1246 0 : return;
1247 : }
1248 :
1249 11671 : FOR( bandIdx = 0; bandIdx < ( *hBinRenderer )->conv_band; bandIdx++ )
1250 : {
1251 11400 : free( hBinRenConvModule->filterTapsLeftReal_fx[bandIdx] );
1252 11400 : hBinRenConvModule->filterTapsLeftReal_fx[bandIdx] = NULL;
1253 :
1254 11400 : free( hBinRenConvModule->filterTapsLeftImag_fx[bandIdx] );
1255 11400 : hBinRenConvModule->filterTapsLeftImag_fx[bandIdx] = NULL;
1256 :
1257 11400 : free( hBinRenConvModule->filterTapsRightReal_fx[bandIdx] );
1258 11400 : hBinRenConvModule->filterTapsRightReal_fx[bandIdx] = NULL;
1259 :
1260 11400 : free( hBinRenConvModule->filterTapsRightImag_fx[bandIdx] );
1261 11400 : hBinRenConvModule->filterTapsRightImag_fx[bandIdx] = NULL;
1262 : }
1263 :
1264 271 : free( hBinRenConvModule->filterTapsLeftReal_fx );
1265 271 : hBinRenConvModule->filterTapsLeftReal_fx = NULL;
1266 :
1267 271 : free( hBinRenConvModule->filterTapsLeftImag_fx );
1268 271 : hBinRenConvModule->filterTapsLeftImag_fx = NULL;
1269 :
1270 271 : free( hBinRenConvModule->filterTapsRightReal_fx );
1271 271 : hBinRenConvModule->filterTapsRightReal_fx = NULL;
1272 :
1273 271 : free( hBinRenConvModule->filterTapsRightImag_fx );
1274 271 : hBinRenConvModule->filterTapsRightImag_fx = NULL;
1275 :
1276 11671 : FOR( bandIdx = 0; bandIdx < ( *hBinRenderer )->conv_band; bandIdx++ )
1277 : {
1278 146130 : FOR( chIdx = 0; chIdx < ( *hBinRenderer )->nInChannels; chIdx++ )
1279 : {
1280 134730 : free( hBinRenConvModule->filterStatesLeftReal_fx[bandIdx][chIdx] );
1281 134730 : hBinRenConvModule->filterStatesLeftReal_fx[bandIdx][chIdx] = NULL;
1282 :
1283 134730 : free( hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx] );
1284 134730 : hBinRenConvModule->filterStatesLeftImag_fx[bandIdx][chIdx] = NULL;
1285 : }
1286 :
1287 11400 : free( hBinRenConvModule->filterStatesLeftReal_fx[bandIdx] );
1288 11400 : hBinRenConvModule->filterStatesLeftReal_fx[bandIdx] = NULL;
1289 :
1290 11400 : free( hBinRenConvModule->filterStatesLeftImag_fx[bandIdx] );
1291 11400 : hBinRenConvModule->filterStatesLeftImag_fx[bandIdx] = NULL;
1292 : }
1293 :
1294 271 : free( hBinRenConvModule->filterStatesLeftReal_fx );
1295 271 : hBinRenConvModule->filterStatesLeftReal_fx = NULL;
1296 :
1297 271 : free( hBinRenConvModule->filterStatesLeftImag_fx );
1298 271 : hBinRenConvModule->filterStatesLeftImag_fx = NULL;
1299 :
1300 :
1301 271 : free( ( *hBinRenderer )->hBinRenConvModule );
1302 271 : ( *hBinRenderer )->hBinRenConvModule = NULL;
1303 :
1304 271 : return;
1305 : }
1306 :
1307 : /*-------------------------------------------------------------------------
1308 : * ivas_binRenderer_close()
1309 : *
1310 : * Close fastconv binaural renderer memories
1311 : *------------------------------------------------------------------------*/
1312 836 : void ivas_binRenderer_close_fx(
1313 : BINAURAL_RENDERER_HANDLE *hBinRenderer /* i/o: fastconv binaural renderer handle */
1314 : )
1315 : {
1316 836 : test();
1317 836 : IF( hBinRenderer == NULL || *hBinRenderer == NULL )
1318 : {
1319 565 : return;
1320 : }
1321 :
1322 271 : IF( ( *hBinRenderer )->hBinRenConvModule != NULL )
1323 : {
1324 271 : ivas_binRenderer_convModuleClose_fx( hBinRenderer );
1325 : }
1326 :
1327 271 : IF( ( *hBinRenderer )->hReverb != NULL )
1328 : {
1329 0 : ivas_binaural_reverb_close_fx( &( ( *hBinRenderer )->hReverb ) );
1330 : }
1331 :
1332 271 : free( *hBinRenderer );
1333 271 : *hBinRenderer = NULL;
1334 :
1335 271 : return;
1336 : }
1337 :
1338 : /*-------------------------------------------------------------------------
1339 : * ivas_free_pppHrtfMem()
1340 : *
1341 : * Free fastconv binaural renderer hrtf memories
1342 : *------------------------------------------------------------------------*/
1343 1220 : static void ivas_free_pppHrtfMem_fx(
1344 : Word32 ****ppppHRIR, /*Qx*/
1345 : const Word16 dim,
1346 : const Word16 alloc_init )
1347 : {
1348 : Word16 i, j;
1349 :
1350 1220 : IF( *ppppHRIR != NULL )
1351 : {
1352 37128 : FOR( i = 0; i < BINAURAL_CONVBANDS; i++ )
1353 : {
1354 36400 : IF( alloc_init == 0 )
1355 : {
1356 294400 : FOR( j = 0; j < dim; j++ )
1357 : {
1358 271400 : free( ( *ppppHRIR )[i][j] );
1359 271400 : ( *ppppHRIR )[i][j] = NULL;
1360 : }
1361 : }
1362 36400 : free( ( *ppppHRIR )[i] );
1363 36400 : ( *ppppHRIR )[i] = NULL;
1364 : }
1365 728 : free( *ppppHRIR );
1366 728 : *ppppHRIR = NULL;
1367 : }
1368 :
1369 1220 : return;
1370 : }
1371 :
1372 : /*-------------------------------------------------------------------------
1373 : * ivas_binaural_hrtf_close()
1374 : *
1375 : * Close fastconv binaural renderer hrtf memories
1376 : *------------------------------------------------------------------------*/
1377 604 : void ivas_binaural_hrtf_close(
1378 : HRTFS_FASTCONV_HANDLE *hHrtfFastConv /* i : fastconv HRTF handle */
1379 : )
1380 : {
1381 : Word16 allocate_init_flag;
1382 :
1383 604 : test();
1384 604 : IF( hHrtfFastConv == NULL || *hHrtfFastConv == NULL )
1385 : {
1386 543 : return;
1387 : }
1388 :
1389 61 : allocate_init_flag = ( *hHrtfFastConv )->allocate_init_flag;
1390 61 : move16();
1391 :
1392 61 : ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->leftHRIRReal_fx, HRTF_LS_CHANNELS, allocate_init_flag );
1393 61 : ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->leftHRIRImag_fx, HRTF_LS_CHANNELS, allocate_init_flag );
1394 61 : ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->rightHRIRReal_fx, HRTF_LS_CHANNELS, allocate_init_flag );
1395 61 : ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->rightHRIRImag_fx, HRTF_LS_CHANNELS, allocate_init_flag );
1396 :
1397 61 : ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->leftBRIRReal_fx, HRTF_LS_CHANNELS, allocate_init_flag );
1398 61 : ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->leftBRIRImag_fx, HRTF_LS_CHANNELS, allocate_init_flag );
1399 61 : ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->rightBRIRReal_fx, HRTF_LS_CHANNELS, allocate_init_flag );
1400 61 : ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->rightBRIRImag_fx, HRTF_LS_CHANNELS, allocate_init_flag );
1401 :
1402 61 : ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->leftHRIRReal_HOA3_fx, HOA3_CHANNELS, allocate_init_flag );
1403 61 : ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->leftHRIRImag_HOA3_fx, HOA3_CHANNELS, allocate_init_flag );
1404 61 : ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->rightHRIRReal_HOA3_fx, HOA3_CHANNELS, allocate_init_flag );
1405 61 : ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->rightHRIRImag_HOA3_fx, HOA3_CHANNELS, allocate_init_flag );
1406 :
1407 61 : ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->leftHRIRReal_HOA2_fx, HOA2_CHANNELS, allocate_init_flag );
1408 61 : ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->leftHRIRImag_HOA2_fx, HOA2_CHANNELS, allocate_init_flag );
1409 61 : ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->rightHRIRReal_HOA2_fx, HOA2_CHANNELS, allocate_init_flag );
1410 61 : ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->rightHRIRImag_HOA2_fx, HOA2_CHANNELS, allocate_init_flag );
1411 :
1412 61 : ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->leftHRIRReal_FOA_fx, FOA_CHANNELS, allocate_init_flag );
1413 61 : ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->leftHRIRImag_FOA_fx, FOA_CHANNELS, allocate_init_flag );
1414 61 : ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->rightHRIRReal_FOA_fx, FOA_CHANNELS, allocate_init_flag );
1415 61 : ivas_free_pppHrtfMem_fx( &( *hHrtfFastConv )->rightHRIRImag_FOA_fx, FOA_CHANNELS, allocate_init_flag );
1416 :
1417 61 : return;
1418 : }
1419 :
1420 : /*-------------------------------------------------------------------------*
1421 : * ivas_binaural_add_LFE()
1422 : *
1423 : * The functions adds the LFE to the left and right channels after binaural rendering
1424 : *-------------------------------------------------------------------------*/
1425 15180 : void ivas_binaural_add_LFE_fx(
1426 : Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */
1427 : Word16 output_frame, /* i : length of input frame */
1428 : Word32 *input_fx[], /* i : transport channels Q11*/
1429 : Word32 *output_fx[] /* o : synthesized core-coder transport channels/DirAC output Q11*/
1430 : )
1431 : {
1432 : Word16 render_lfe, idx_lfe, gain_fx, idx;
1433 :
1434 15180 : IF( st_ivas->hBinRenderer != NULL )
1435 : {
1436 160 : render_lfe = st_ivas->hBinRenderer->render_lfe;
1437 160 : move16();
1438 : }
1439 : ELSE
1440 : {
1441 15020 : render_lfe = TRUE;
1442 15020 : move16();
1443 : }
1444 :
1445 :
1446 15180 : IF( render_lfe )
1447 : {
1448 15180 : IF( EQ_32( st_ivas->renderer_type, RENDERER_BINAURAL_OBJECTS_TD ) )
1449 : {
1450 3060 : gain_fx = GAIN_LFE_FX;
1451 3060 : move16();
1452 : }
1453 : ELSE
1454 : {
1455 12120 : test();
1456 12120 : IF( ( st_ivas->hCrendWrapper != NULL ) && ( st_ivas->hCrendWrapper->hHrtfCrend != NULL ) )
1457 : {
1458 11960 : gain_fx = st_ivas->hCrendWrapper->hHrtfCrend->gain_lfe_fx;
1459 11960 : move16();
1460 : }
1461 : ELSE
1462 : {
1463 160 : gain_fx = GAIN_LFE_FX;
1464 160 : move16();
1465 : }
1466 : }
1467 30210 : FOR( idx_lfe = 0; idx_lfe < st_ivas->hIntSetup.num_lfe; idx_lfe++ )
1468 : {
1469 15030 : v_multc_fixed_16( input_fx[st_ivas->hIntSetup.index_lfe[idx_lfe]], gain_fx, input_fx[st_ivas->hIntSetup.index_lfe[idx_lfe]], output_frame ); // q_input_fx - 1
1470 : /* copy LFE to left and right channels */
1471 13327030 : FOR( idx = 0; idx < output_frame; idx++ )
1472 : {
1473 13312000 : input_fx[st_ivas->hIntSetup.index_lfe[idx_lfe]][idx] = L_shl_sat( input_fx[st_ivas->hIntSetup.index_lfe[idx_lfe]][idx], 1 ); // saturating to keep same q
1474 13312000 : move32();
1475 13312000 : output_fx[0][idx] = L_add_sat( output_fx[0][idx], input_fx[st_ivas->hIntSetup.index_lfe[idx_lfe]][idx] );
1476 13312000 : move32();
1477 13312000 : output_fx[1][idx] = L_add_sat( output_fx[1][idx], input_fx[st_ivas->hIntSetup.index_lfe[idx_lfe]][idx] );
1478 13312000 : move32();
1479 : }
1480 : }
1481 : }
1482 :
1483 15180 : return;
1484 : }
1485 :
1486 : /*-------------------------------------------------------------------------
1487 : * ivas_binRenderer()
1488 : *
1489 : * Fastconv binaural renderer main function
1490 : *-------------------------------------------------------------------------*/
1491 :
1492 136305 : void ivas_binRenderer_fx(
1493 : BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: binaural renderer handle */
1494 : COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined head and external orientation handle*/
1495 : const Word16 numTimeSlots, /* i : number of time slots to render */
1496 : Word32 Cldfb_RealBuffer_Binaural_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals Q_in*/
1497 : Word32 Cldfb_ImagBuffer_Binaural_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals Q_in*/
1498 : Word32 RealBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals Q_in*/
1499 : Word32 ImagBuffer_fx[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals Q_in*/
1500 : Word16 *Q_in /* i : LS signals exp */
1501 : )
1502 : {
1503 : Word16 chIdx, i, j, k;
1504 136305 : push_wmops( "fastconv_binaural_rendering" );
1505 :
1506 : /* Compute Convolution */
1507 : /* memory reset for the binaural output */
1508 : #ifndef OPT_SBA_DEC_V2_BE
1509 : FOR( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ )
1510 : {
1511 : FOR( k = 0; k < numTimeSlots; k++ )
1512 : {
1513 : set32_fx( Cldfb_RealBuffer_Binaural_fx[chIdx][k], 0, CLDFB_NO_CHANNELS_MAX );
1514 : set32_fx( Cldfb_ImagBuffer_Binaural_fx[chIdx][k], 0, CLDFB_NO_CHANNELS_MAX );
1515 : }
1516 : }
1517 : #endif /* OPT_SBA_DEC_V2_BE */
1518 :
1519 : /* Head rotation in HOA3 or CICPx */
1520 136305 : test();
1521 136305 : test();
1522 136305 : IF( hCombinedOrientationData != NULL && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] && hBinRenderer->rotInCldfb )
1523 : {
1524 62520 : IF( hBinRenderer->hInputSetup->is_loudspeaker_setup == 0 )
1525 : {
1526 : /* Rotation in SHD (HOA3) */
1527 54520 : IF( EQ_16( hCombinedOrientationData->shd_rot_max_order, -1 ) )
1528 : {
1529 18520 : rotateFrame_shd_cldfb( RealBuffer_fx, ImagBuffer_fx, hCombinedOrientationData->Rmat_fx[hCombinedOrientationData->subframe_idx], hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, 3 );
1530 18520 : *Q_in = sub( *Q_in, 1 ); //( Q_in + 14 - 15 )
1531 18520 : move16();
1532 : }
1533 36000 : ELSE IF( hCombinedOrientationData->shd_rot_max_order > 0 )
1534 : {
1535 0 : rotateFrame_shd_cldfb( RealBuffer_fx, ImagBuffer_fx, hCombinedOrientationData->Rmat_fx[hCombinedOrientationData->subframe_idx], hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, hCombinedOrientationData->shd_rot_max_order );
1536 0 : *Q_in = sub( *Q_in, 1 ); //( Q_in + 14 - 15 )
1537 0 : move16();
1538 : }
1539 : }
1540 : ELSE
1541 : {
1542 : /* Rotation in SD (CICPx) */
1543 8000 : rotateFrame_sd_cldfb_fixed( hCombinedOrientationData->Rmat_fx[hCombinedOrientationData->subframe_idx], RealBuffer_fx, ImagBuffer_fx,
1544 8000 : hBinRenderer->hInputSetup, hBinRenderer->hEFAPdata, numTimeSlots, hBinRenderer->conv_band );
1545 : }
1546 : }
1547 :
1548 : /* HOA decoding to CICP19 if needed*/
1549 136305 : test();
1550 136305 : IF( hBinRenderer->hInputSetup->is_loudspeaker_setup == 0 && NE_16( hBinRenderer->nInChannels, 16 ) )
1551 : {
1552 28000 : ivas_sba2mc_cldfb_fixed( *( hBinRenderer->hInputSetup ), RealBuffer_fx, ImagBuffer_fx,
1553 28000 : hBinRenderer->nInChannels, hBinRenderer->conv_band, numTimeSlots, hBinRenderer->hoa_dec_mtx );
1554 : }
1555 136305 : ivas_binRenderer_filterModule_fx( Cldfb_RealBuffer_Binaural_fx, Cldfb_ImagBuffer_Binaural_fx, RealBuffer_fx, ImagBuffer_fx, numTimeSlots, hBinRenderer, *Q_in );
1556 : /* Obtain the binaural dmx and compute the reverb */
1557 136305 : IF( hBinRenderer->hReverb != NULL )
1558 : {
1559 : Word32 reverbRe_fx[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX];
1560 : Word32 reverbIm_fx[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX];
1561 : Word32 inRe_fx[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX];
1562 : Word32 inIm_fx[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX];
1563 :
1564 0 : ivas_binaural_obtain_DMX_fx( numTimeSlots, hBinRenderer, RealBuffer_fx, ImagBuffer_fx, inRe_fx, inIm_fx );
1565 :
1566 0 : FOR( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ )
1567 : {
1568 0 : FOR( k = 0; k < numTimeSlots; k++ )
1569 : {
1570 0 : set32_fx( reverbRe_fx[chIdx][k], 0, hBinRenderer->max_band );
1571 0 : set32_fx( reverbIm_fx[chIdx][k], 0, hBinRenderer->max_band );
1572 : }
1573 : }
1574 :
1575 0 : ivas_binaural_reverb_processSubframe_fx( hBinRenderer->hReverb, BINAURAL_CHANNELS, numTimeSlots, inRe_fx, inIm_fx, reverbRe_fx, reverbIm_fx );
1576 :
1577 0 : FOR( i = 0; i < BINAURAL_CHANNELS; i++ )
1578 : {
1579 0 : FOR( j = 0; j < numTimeSlots; j++ )
1580 : {
1581 0 : FOR( k = 0; k < hBinRenderer->hReverb->numBins; k++ )
1582 : {
1583 0 : reverbRe_fx[i][j][k] = L_shl( reverbRe_fx[i][j][k], 1 ); //*Q_in
1584 0 : move32();
1585 0 : reverbIm_fx[i][j][k] = L_shl( reverbIm_fx[i][j][k], 1 ); //*Q_in
1586 0 : move32();
1587 : }
1588 : }
1589 : }
1590 :
1591 : /* Add the conv module and reverb module output */
1592 0 : FOR( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ )
1593 : {
1594 0 : FOR( k = 0; k < numTimeSlots; k++ )
1595 : {
1596 : /* Combine first and second parts to generate binaural output signal with room effect */
1597 0 : v_add_32( Cldfb_RealBuffer_Binaural_fx[chIdx][k], reverbRe_fx[chIdx][k], Cldfb_RealBuffer_Binaural_fx[chIdx][k], hBinRenderer->conv_band ); // Q_in
1598 0 : v_add_32( Cldfb_ImagBuffer_Binaural_fx[chIdx][k], reverbIm_fx[chIdx][k], Cldfb_ImagBuffer_Binaural_fx[chIdx][k], hBinRenderer->conv_band ); // Q_in
1599 : }
1600 : }
1601 : }
1602 :
1603 : #ifdef OPT_SBA_DEC_V2_BE
1604 136305 : Word16 len = sub( CLDFB_NO_CHANNELS_MAX, hBinRenderer->conv_band );
1605 :
1606 680005 : FOR( k = 0; k < numTimeSlots; k++ )
1607 : {
1608 543700 : set32_fx( &Cldfb_RealBuffer_Binaural_fx[0][k][hBinRenderer->conv_band], 0, len );
1609 543700 : set32_fx( &Cldfb_RealBuffer_Binaural_fx[1][k][hBinRenderer->conv_band], 0, len );
1610 543700 : set32_fx( &Cldfb_ImagBuffer_Binaural_fx[0][k][hBinRenderer->conv_band], 0, len );
1611 543700 : set32_fx( &Cldfb_ImagBuffer_Binaural_fx[1][k][hBinRenderer->conv_band], 0, len );
1612 : }
1613 : #endif /* OPT_SBA_DEC_V2_BE */
1614 :
1615 136305 : pop_wmops();
1616 136305 : return;
1617 : }
|