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 "prot_fx.h"
36 : #include "ivas_prot_rend_fx.h"
37 : #include "ivas_rom_TdBinauralRenderer.h"
38 : #include "ivas_error.h"
39 : #include "wmc_auto.h"
40 : #include "ivas_rom_rend.h"
41 : #include "ivas_rom_binaural_crend_head.h"
42 : #include "ivas_prot_fx.h"
43 :
44 : /*-------------------------------------------------------------------*
45 : * Local constants
46 : *-------------------------------------------------------------------*/
47 :
48 : #define RESAMPLE_FACTOR_16_48 ( 16.0f / 48.0f )
49 : #define RESAMPLE_FACTOR_32_48 ( 32.0f / 48.0f )
50 :
51 : #define RESAMPLE_FACTOR_16_48_FX ( 5461 ) // Q14
52 : #define RESAMPLE_FACTOR_32_48_FX ( 10922 ) // Q14
53 :
54 :
55 : /*-------------------------------------------------------------------------
56 : * Local functions
57 : *-------------------------------------------------------------------------*/
58 : static ivas_error DefaultBSplineModel_fx( TDREND_HRFILT_FiltSet_t *HrFiltSet_p, const Word32 output_Fs );
59 :
60 : /*-------------------------------------------------------------------*
61 : * TDREND_MIX_LIST_SetPos()
62 : *
63 : * Sets the listener's position in the specified mixer unit.
64 : --------------------------------------------------------------------*/
65 :
66 685905 : void TDREND_MIX_LIST_SetPos_fx(
67 : BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */
68 : const Word32 *Pos_p /* i : Listener's position */ // Q Pos_fx->q_fact
69 : )
70 : {
71 : TDREND_MIX_Listener_t *Listener_p;
72 :
73 685905 : Listener_p = hBinRendererTd->Listener_p;
74 685905 : test();
75 685905 : test();
76 685905 : IF( NE_32( Pos_p[0], Listener_p->Pos_fx[0] ) || NE_32( Pos_p[1], Listener_p->Pos_fx[1] ) || NE_32( Pos_p[2], Listener_p->Pos_fx[2] ) )
77 : {
78 : /* Set position */
79 6688 : Copy32( Pos_p, Listener_p->Pos_fx, 3 ); // Q Pos_fx->q_fact
80 :
81 : /* Set pose update flag */
82 6688 : Listener_p->PoseUpdated = TRUE;
83 6688 : move16();
84 : }
85 :
86 685905 : return;
87 : }
88 :
89 :
90 : /*-------------------------------------------------------------------*
91 : * TDREND_MIX_LIST_SetOrient()
92 : *
93 : * Sets the listener's orientation vectors in the specified mixer unit.
94 : --------------------------------------------------------------------*/
95 :
96 685905 : ivas_error TDREND_MIX_LIST_SetOrient_fx(
97 : BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */
98 : const Word32 *FrontVec_p_fx,
99 : /* i : Listener's orientation front vector */ // orient_q
100 : const Word32 *UpVec_p_fx,
101 : /* i : Listener's orientation up vector */ // orient_q
102 : const Word16 orient_q /* i : Listener's orientation q-factor */
103 : )
104 : {
105 :
106 : TDREND_MIX_Listener_t *List_p;
107 : /* Value verification */
108 685905 : test();
109 685905 : test();
110 685905 : IF( ( FrontVec_p_fx[0] == 0 ) && ( FrontVec_p_fx[1] == 0 ) && ( FrontVec_p_fx[2] == 0 ) )
111 : {
112 0 : return ( IVAS_ERROR( IVAS_ERR_INTERNAL, "Zero front vector. Command is ignored!\n" ) );
113 : }
114 :
115 685905 : IF( ( UpVec_p_fx[0] == 0 ) && ( UpVec_p_fx[1] == 0 ) && ( UpVec_p_fx[2] == 0 ) )
116 : {
117 0 : return ( IVAS_ERROR( IVAS_ERR_INTERNAL, "Zero up vector. Command is ignored!\n" ) );
118 : }
119 :
120 685905 : test();
121 685905 : test();
122 : /* Get listener */
123 685905 : List_p = hBinRendererTd->Listener_p;
124 :
125 : /* Evaluate the normalized orientation vectors and set pose update flag */
126 685905 : List_p->PoseUpdated = TDREND_SPATIAL_EvalOrthonormOrient_fx( List_p->Front_fx, List_p->Up_fx, List_p->Right_fx, FrontVec_p_fx, UpVec_p_fx, orient_q ); // Q0
127 685905 : move16();
128 :
129 685905 : return IVAS_ERR_OK;
130 : }
131 :
132 :
133 : /*-------------------------------------------------------------------*
134 : * TDREND_MIX_Dealloc()
135 : *
136 : * Deallocates the TDREND_MIX_t variable
137 : --------------------------------------------------------------------*/
138 :
139 939 : void TDREND_MIX_Dealloc_fx(
140 : BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd /* i/o: TD renderer handle */
141 : )
142 : {
143 : Word16 i;
144 :
145 : /* Deallocate source list */
146 2578 : FOR( i = 0; i < hBinRendererTd->NumOfSrcs; i++ )
147 : {
148 1639 : TDREND_SRC_Dealloc( hBinRendererTd->Sources[i] );
149 : }
150 : /* Deallocate Listener and RendListener */
151 939 : IF( hBinRendererTd->Listener_p != NULL )
152 : {
153 939 : free( hBinRendererTd->Listener_p );
154 939 : hBinRendererTd->Listener_p = NULL;
155 : }
156 : /* Dealloc HR filter set */
157 939 : test();
158 939 : IF( ( *hBinRendererTd->pHrFiltSet_p != NULL ) && ( hBinRendererTd->HrFiltSet_p != NULL ) )
159 : {
160 405 : IF( EQ_16( hBinRendererTd->HrFiltSet_p->FilterMethod, TDREND_HRFILT_Method_BSplineModel ) )
161 : {
162 405 : BSplineModelEvalDealloc_fx( &hBinRendererTd->HrFiltSet_p->ModelParams, &hBinRendererTd->HrFiltSet_p->ModelEval );
163 : }
164 : ELSE
165 : {
166 0 : IF( hBinRendererTd->HrFiltSet_p->Elev_p_fx != NULL )
167 : {
168 0 : free( hBinRendererTd->HrFiltSet_p->Elev_p_fx );
169 0 : hBinRendererTd->HrFiltSet_p->Elev_p_fx = NULL;
170 : }
171 0 : IF( hBinRendererTd->HrFiltSet_p->Azim_p_fx != NULL )
172 : {
173 0 : free( hBinRendererTd->HrFiltSet_p->Azim_p_fx );
174 0 : hBinRendererTd->HrFiltSet_p->Azim_p_fx = NULL;
175 : }
176 0 : IF( hBinRendererTd->HrFiltSet_p->LeftFiltSet_p_fx != NULL )
177 : {
178 0 : free( hBinRendererTd->HrFiltSet_p->LeftFiltSet_p_fx );
179 0 : hBinRendererTd->HrFiltSet_p->LeftFiltSet_p_fx = NULL;
180 : }
181 0 : IF( hBinRendererTd->HrFiltSet_p->RightFiltSet_p_fx != NULL )
182 : {
183 0 : free( hBinRendererTd->HrFiltSet_p->RightFiltSet_p_fx );
184 0 : hBinRendererTd->HrFiltSet_p->RightFiltSet_p_fx = NULL;
185 : }
186 : }
187 :
188 405 : IF( EQ_16( hBinRendererTd->HrFiltSet_p->ModelParams.modelROM, 1 ) )
189 : {
190 358 : free( hBinRendererTd->HrFiltSet_p );
191 358 : hBinRendererTd->HrFiltSet_p = NULL;
192 358 : *hBinRendererTd->pHrFiltSet_p = NULL;
193 : }
194 : }
195 :
196 939 : return;
197 : }
198 :
199 :
200 : /*-------------------------------------------------------------------*
201 : * TDREND_MIX_Init()
202 : *
203 : * Initializes the mixer and sets HRTF
204 : --------------------------------------------------------------------*/
205 939 : ivas_error TDREND_MIX_Init_fx(
206 : BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */
207 : TDREND_HRFILT_FiltSet_t **hHrtfTD, /* i/o: HRTF data (initialized in case of NULL) */
208 : const TDREND_MixSpatSpec_t *MixSpatSpec_p, /* i : Mixer spatial specification */
209 : const Word32 output_Fs /* i : Output sampling rate */ // Q0
210 : )
211 : {
212 : ivas_error error;
213 939 : hBinRendererTd->Gain_fx = ONE_IN_Q14;
214 939 : move16();
215 : /* Init source list */
216 : /* Spatial settings */
217 939 : IF( MixSpatSpec_p != NULL )
218 : {
219 939 : hBinRendererTd->UseCommonDistAttenModel = MixSpatSpec_p->UseCommonDistAttenModel; // Q0
220 939 : move16();
221 939 : hBinRendererTd->DistAttenModel = MixSpatSpec_p->DistAttenModel; // Q0
222 939 : move16();
223 : }
224 : ELSE
225 : {
226 0 : hBinRendererTd->UseCommonDistAttenModel = TRUE; // Q0
227 0 : move16();
228 0 : hBinRendererTd->DistAttenModel = 0x0000; /* Distance attenuation not activated; */ // Q0
229 0 : move16();
230 : }
231 : /* Init virtual and rendering listeners for spatial mixers */
232 939 : TDREND_SPATIAL_VecInit_fx( hBinRendererTd->Listener_p->Pos_fx, 0, 0, 0 );
233 939 : hBinRendererTd->Listener_p->Pos_q = Q25;
234 939 : move16();
235 939 : TDREND_SPATIAL_VecInit_fx( hBinRendererTd->Listener_p->Vel_fx, 0, 0, 0 );
236 939 : TDREND_SPATIAL_VecInit_fx( hBinRendererTd->Listener_p->Front_fx, 0, 0, -ONE_IN_Q30 );
237 939 : TDREND_SPATIAL_VecInit_fx( hBinRendererTd->Listener_p->Up_fx, 0, ONE_IN_Q30, 0 );
238 939 : TDREND_SPATIAL_VecInit_fx( hBinRendererTd->Listener_p->Right_fx, ONE_IN_Q30, 0, 0 );
239 : /* Init HR filter set */
240 939 : IF( *hHrtfTD == NULL )
241 : {
242 358 : IF( ( hBinRendererTd->HrFiltSet_p = (TDREND_HRFILT_FiltSet_t *) malloc( sizeof( TDREND_HRFILT_FiltSet_t ) ) ) == NULL )
243 : {
244 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural TD renderer\n" ) );
245 : }
246 :
247 358 : IF( NE_32( ( error = DefaultBSplineModel_fx( hBinRendererTd->HrFiltSet_p, output_Fs ) ), IVAS_ERR_OK ) )
248 : {
249 0 : return error;
250 : }
251 358 : *hHrtfTD = hBinRendererTd->HrFiltSet_p;
252 : }
253 : ELSE
254 : {
255 581 : hBinRendererTd->HrFiltSet_p = *hHrtfTD;
256 : }
257 :
258 939 : hBinRendererTd->pHrFiltSet_p = hHrtfTD;
259 :
260 939 : IF( NE_32( hBinRendererTd->HrFiltSet_p->SampleRate, output_Fs ) )
261 : {
262 0 : return ( IVAS_ERROR( IVAS_ERR_INVALID_SAMPLING_RATE, "The sampling rate for the HR filter set does not match the output sampling rate.\n" ) );
263 : }
264 939 : return IVAS_ERR_OK;
265 : }
266 :
267 : /*-------------------------------------------------------------------*
268 : * TDREND_MIX_SetDistAttenModel()
269 : *
270 : * Set the distance attenuation model of the mixer
271 : --------------------------------------------------------------------*/
272 :
273 939 : ivas_error TDREND_MIX_SetDistAttenModel(
274 : BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */
275 : const TDREND_DistAttenModel_t DistAttenModel /* i : Distance attenuation model */
276 : )
277 : {
278 : /* Value validation */
279 939 : test();
280 939 : IF( LT_16( DistAttenModel, TDREND_DIST_ATTEN_MODEL_INV_DIST ) || GT_16( DistAttenModel, TDREND_DIST_ATTEN_MODEL_INV_DIST_CLAMPED ) )
281 : {
282 0 : return ( IVAS_ERROR( IVAS_ERR_INTERNAL, "Invalid distance attenuation model!\n" ) );
283 : }
284 : ELSE
285 : {
286 : /* Set the common distance attenuation model */
287 939 : hBinRendererTd->DistAttenModel = DistAttenModel; // Q0
288 939 : move32();
289 :
290 : /* If using common distance attenuation model, set it. */
291 939 : IF( hBinRendererTd->UseCommonDistAttenModel )
292 : {
293 939 : hBinRendererTd->DistAttenEnabled = TRUE; // Q0
294 939 : move16();
295 939 : hBinRendererTd->DistAttenModel = DistAttenModel; // Q0
296 939 : move32();
297 : }
298 : }
299 939 : return IVAS_ERR_OK;
300 : }
301 :
302 :
303 : /*-------------------------------------------------------------------*
304 : * TDREND_MIX_AddSrc()
305 : *
306 : * Adds the specified input source unit to the specified mixer unit.
307 : --------------------------------------------------------------------*/
308 1639 : ivas_error TDREND_MIX_AddSrc_fx(
309 : BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */
310 : Word16 *SrcInd,
311 : /* o : Source index */ // Q0
312 : const TDREND_PosType_t PosType /* i : Position type (absolute/relative) */
313 : )
314 : {
315 : TDREND_SRC_t *Src_p;
316 : ivas_error error;
317 :
318 1639 : error = IVAS_ERR_OK;
319 1639 : move32();
320 : /* Get unique source index */
321 1639 : *SrcInd = add( hBinRendererTd->MaxSrcInd, 1 ); // Q0
322 1639 : move16();
323 1639 : hBinRendererTd->MaxSrcInd = add( hBinRendererTd->MaxSrcInd, 1 ); // Q0
324 1639 : move16();
325 1639 : hBinRendererTd->NumOfSrcs = add( hBinRendererTd->NumOfSrcs, 1 ); // Q0
326 1639 : move16();
327 :
328 1639 : IF( GT_16( hBinRendererTd->NumOfSrcs, MAX_NUM_TDREND_CHANNELS ) )
329 : {
330 0 : return ( IVAS_ERROR( IVAS_ERR_INTERNAL, "Maximum number of sources exceeded!\n" ) );
331 : }
332 : ELSE
333 : {
334 1639 : test();
335 1639 : IF( LT_16( PosType, TDREND_POSTYPE_ABSOLUTE ) || GT_16( PosType, TDREND_POSTYPE_NON_DIEGETIC ) )
336 : {
337 0 : return ( IVAS_ERROR( IVAS_ERR_INTERNAL, "Invalid position type!\n" ) );
338 : }
339 : ELSE
340 : {
341 : /* Alloc and init a complete source: signal+spatial+rend components */
342 1639 : IF( NE_32( ( error = TDREND_SRC_Alloc( &Src_p ) ), IVAS_ERR_OK ) )
343 : {
344 0 : return error;
345 : }
346 :
347 1639 : TDREND_SRC_Init_fx( Src_p, PosType );
348 :
349 : /* Special OpenAL initialization due to a common distance attenuation model */
350 1639 : IF( NE_16( hBinRendererTd->DistAttenModel, 0 ) )
351 : {
352 1639 : Src_p->SrcSpatial_p->DistAttenEnabled = TRUE; // Q0
353 1639 : move16();
354 1639 : Src_p->SrcSpatial_p->DistAtten.DistAttenModel = hBinRendererTd->DistAttenModel; // Q0
355 1639 : move32();
356 : }
357 : /* Add source to mixer */
358 1639 : hBinRendererTd->Sources[*SrcInd] = Src_p;
359 : }
360 : }
361 :
362 1639 : return error;
363 : }
364 :
365 : /*-------------------------------------------------------------------*
366 : * BSplineModelEvalAlloc()
367 : *
368 : * Allocate the B Spline HR Filter model.
369 : --------------------------------------------------------------------*/
370 :
371 358 : static ivas_error BSplineModelEvalAlloc_fx(
372 : ModelParams_t *model, /* i : Model parameters */
373 : ModelEval_t *modelEval /* i/o: Model evaluation structure */
374 : )
375 : {
376 358 : IF( ( modelEval->hrfModL_fx = (Word32 *) malloc( model->K * sizeof( Word32 ) ) ) == NULL )
377 : {
378 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural TD renderer\n" ) );
379 : }
380 :
381 358 : IF( ( modelEval->hrfModR_fx = (Word32 *) malloc( model->K * sizeof( Word32 ) ) ) == NULL )
382 : {
383 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural TD renderer\n" ) );
384 : }
385 :
386 358 : return IVAS_ERR_OK;
387 : }
388 :
389 :
390 : /*-------------------------------------------------------------------*
391 : * DefaultBSplineModel()
392 : *
393 : * Init default HRTF model
394 : --------------------------------------------------------------------*/
395 :
396 358 : static ivas_error DefaultBSplineModel_fx(
397 : TDREND_HRFILT_FiltSet_t *HrFiltSet_p, /* o : Loaded HR filter set */
398 : const Word32 output_Fs /* i : Output sampling rate */ // Q0
399 : )
400 : {
401 : ModelParams_t *model;
402 : ModelParamsITD_t *modelITD;
403 : Word16 i, j;
404 : ivas_error error;
405 358 : HrFiltSet_p->FilterMethod = TDREND_HRFILT_Method_BSplineModel;
406 358 : move16();
407 358 : model = &( HrFiltSet_p->ModelParams );
408 358 : modelITD = &( HrFiltSet_p->ModelParamsITD );
409 :
410 :
411 : /* Set ROM flag for correct deallocation */
412 358 : model->modelROM = TRUE;
413 358 : move16();
414 :
415 : /* int16_t parameters */
416 358 : model->UseItdModel = 1; // Q0
417 358 : move16();
418 358 : model->SplineDegree = 4; // Q0
419 358 : move16();
420 358 : model->elevDim2 = 17; // Q0
421 358 : move16();
422 358 : model->elevDim3 = 15; // Q0
423 358 : move16();
424 358 : model->AlphaN = 470; // Q0
425 358 : move16();
426 358 : model->num_unique_azim_splines = 1; // Q0
427 358 : move16();
428 358 : model->elevSegSamples = 4; // Q0
429 358 : move16();
430 358 : model->elevBsLen[0] = 5; // Q0
431 358 : move16();
432 358 : model->elevBsLen[1] = 9; // Q0
433 358 : move16();
434 358 : model->elevBsLen[2] = 13; // Q0
435 358 : move16();
436 358 : model->elevBsLen[3] = 9; // Q0
437 358 : move16();
438 358 : model->elevBsStart[0] = 0; // Q0
439 358 : move16();
440 358 : model->elevBsStart[1] = 5; // Q0
441 358 : move16();
442 358 : model->elevBsStart[2] = 14; // Q0
443 358 : move16();
444 358 : model->elevBsStart[3] = 27; // Q0
445 358 : move16();
446 :
447 358 : model->azimDim2 = defaultHRIR_rom_azimDim2; // Q0
448 358 : model->azimDim3 = defaultHRIR_rom_azimDim3; // Q0
449 358 : model->azim_start_idx = defaultHRIR_rom_azim_start_idx; // Q0
450 358 : model->azimSegSamples = defaultHRIR_rom_azimSegSamples; // Q0
451 358 : model->azimShapeIdx = defaultHRIR_rom_azimShapeIdx; // Q0
452 358 : model->azimShapeSampFactor = defaultHRIR_rom_azimShapeSampFactor; // Q0
453 :
454 358 : model->elevKSeq_fx = defaultHRIR_rom_elevKSeq_fx; // Q22
455 358 : model->elevBsShape_fx = (const Word32 *) defaultHRIR_rom_elevBsShape_fx; // Q30
456 :
457 358 : IF( ( model->azimBsShape_fx = (const Word32 **) malloc( model->num_unique_azim_splines * sizeof( Word32 * ) ) ) == NULL )
458 : {
459 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural TD renderer\n" ) );
460 : }
461 358 : model->azimBsShape_fx[0] = defaultHRIR_rom_azimBsShape_fx; // Q30
462 358 : IF( ( model->azimKSeq_fx = (Word32 **) malloc( 18 * sizeof( Word32 * ) ) ) == NULL )
463 : {
464 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural TD renderer\n" ) );
465 : }
466 358 : IF( ( model->azimKSeq_fx[0] = (Word32 *) malloc( 2 * sizeof( Word32 * ) ) ) == NULL )
467 : {
468 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural TD renderer\n" ) );
469 : }
470 358 : IF( ( model->azimKSeq_fx[model->elevDim3 - 1] = (Word32 *) malloc( 2 * sizeof( Word32 * ) ) ) == NULL )
471 : {
472 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural TD renderer\n" ) );
473 : }
474 358 : model->azimKSeq_fx[0][0] = 0;
475 358 : model->azimKSeq_fx[model->elevDim3 - 1][0] = 0;
476 358 : model->azimKSeq_fx[0][1] = 360 << Q22; // Q22
477 358 : model->azimKSeq_fx[model->elevDim3 - 1][1] = 360 << Q22; // Q22
478 358 : move32();
479 358 : move32();
480 358 : move32();
481 358 : move32();
482 :
483 5012 : FOR( i = 1; i < sub( model->elevDim3, 1 ); i++ )
484 : {
485 4654 : IF( ( model->azimKSeq_fx[i] = (Word32 *) malloc( model->azimDim2[i] * sizeof( Word32 * ) ) ) == NULL ) /* azimDim2[i] = 91, i=2..15 */
486 : {
487 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural TD renderer\n" ) );
488 : }
489 176852 : FOR( j = 0; j < model->azimDim2[i]; j++ )
490 : {
491 172198 : model->azimKSeq_fx[i][j] = L_shl( L_mult0( defaultHRIR_rom_azimSegSamples[0], j ), Q22 ); // Q22
492 172198 : move32();
493 : }
494 : }
495 :
496 358 : SWITCH( output_Fs )
497 : {
498 327 : case 48000:
499 327 : model->AlphaL_fx = (const Word32 *) defaultHRIR_rom_AlphaL48_fx; // Q30
500 327 : model->AlphaL_e = 1;
501 327 : move16();
502 327 : model->AlphaR_fx = (const Word32 *) defaultHRIR_rom_AlphaR48_fx; // Q30
503 327 : model->AlphaR_e = 1;
504 327 : move16();
505 327 : model->EL_fx = (const Word32 *) defaultHRIR_rom_EL48_fx; // Q28
506 327 : model->EL_e = 3;
507 327 : move16();
508 327 : model->ER_fx = (const Word32 *) defaultHRIR_rom_ER48_fx; // Q28
509 327 : model->ER_e = 3;
510 327 : move16();
511 327 : model->K = 128; // Q0
512 327 : move16();
513 327 : IF( HrFiltSet_p->ModelParams.UseItdModel )
514 : {
515 327 : modelITD->resamp_factor_fx = ONE_IN_Q14; // Q14
516 327 : move16();
517 : }
518 327 : BREAK;
519 31 : case 32000:
520 31 : model->AlphaL_fx = (const Word32 *) defaultHRIR_rom_AlphaL32_fx; // Q30
521 31 : model->AlphaL_e = 1;
522 31 : move16();
523 31 : model->AlphaR_fx = (const Word32 *) defaultHRIR_rom_AlphaR32_fx; // Q30
524 31 : model->AlphaR_e = 1;
525 31 : move16();
526 31 : model->EL_fx = (const Word32 *) defaultHRIR_rom_EL32_fx; // Q28
527 31 : model->EL_e = 3;
528 31 : move16();
529 31 : model->ER_fx = (const Word32 *) defaultHRIR_rom_ER32_fx; // Q28
530 31 : model->ER_e = 3;
531 31 : move16();
532 31 : model->K = 86; // Q0
533 31 : move16();
534 31 : IF( HrFiltSet_p->ModelParams.UseItdModel )
535 : {
536 31 : modelITD->resamp_factor_fx = RESAMPLE_FACTOR_32_48_FX; // Q14
537 31 : move16();
538 : }
539 31 : BREAK;
540 0 : case 16000:
541 0 : model->AlphaL_fx = (const Word32 *) defaultHRIR_rom_AlphaL16_fx; // Q30
542 0 : model->AlphaL_e = 1;
543 0 : move16();
544 0 : model->AlphaR_fx = (const Word32 *) defaultHRIR_rom_AlphaR16_fx; // Q30
545 0 : model->AlphaR_e = 1;
546 0 : move16();
547 0 : model->EL_fx = (const Word32 *) defaultHRIR_rom_EL16_fx; // Q28
548 0 : model->EL_e = 3;
549 0 : move16();
550 0 : model->ER_fx = (const Word32 *) defaultHRIR_rom_ER16_fx; // Q28
551 0 : model->ER_e = 3;
552 0 : move16();
553 0 : model->K = 43; // Q0
554 0 : move16();
555 0 : IF( HrFiltSet_p->ModelParams.UseItdModel )
556 : {
557 0 : modelITD->resamp_factor_fx = RESAMPLE_FACTOR_16_48_FX; // Q14
558 0 : move16();
559 : }
560 0 : BREAK;
561 0 : default:
562 0 : BREAK;
563 : }
564 :
565 358 : modelITD->N = 4; // Q0
566 358 : move16();
567 358 : modelITD->elevDim2 = 20; // Q0
568 358 : move16();
569 358 : modelITD->elevDim3 = 18; // Q0
570 358 : move16();
571 358 : modelITD->azimDim2 = 41; // Q0
572 358 : move16();
573 358 : modelITD->azimDim3 = 41; // Q0
574 358 : move16();
575 358 : modelITD->elevSegSamples = 3; // Q0
576 358 : move16();
577 358 : modelITD->elevBsLen[0] = 4; // Q0
578 358 : move16();
579 358 : modelITD->elevBsLen[1] = 7; // Q0
580 358 : move16();
581 358 : modelITD->elevBsLen[2] = 10; // Q0
582 358 : move16();
583 358 : modelITD->elevBsLen[3] = 7; // Q0
584 358 : move16();
585 358 : modelITD->elevBsStart[0] = 0; // Q0
586 358 : move16();
587 358 : modelITD->elevBsStart[1] = 4; // Q0
588 358 : move16();
589 358 : modelITD->elevBsStart[2] = 11; // Q0
590 358 : move16();
591 358 : modelITD->elevBsStart[3] = 21; // Q0
592 358 : move16();
593 358 : modelITD->elevKSeq_fx = defaultHRIR_rom_ITD_elevKSeq_fx; // Q22
594 :
595 358 : modelITD->azimBsLen[0] = 11; // Q0
596 358 : move16();
597 358 : modelITD->azimBsLen[1] = 21; // Q0
598 358 : move16();
599 358 : modelITD->azimBsLen[2] = 31; // Q0
600 358 : move16();
601 358 : modelITD->azimBsLen[3] = 21; // Q0
602 358 : move16();
603 358 : modelITD->azimBsStart[0] = 0; // Q0
604 358 : move16();
605 358 : modelITD->azimBsStart[1] = 11; // Q0
606 358 : move16();
607 358 : modelITD->azimBsStart[2] = 32; // Q0
608 358 : move16();
609 358 : modelITD->azimBsStart[3] = 63; // Q0
610 358 : move16();
611 :
612 358 : modelITD->azimSegSamples = 10; // Q0
613 358 : move16();
614 358 : modelITD->azimKSeq_fx = defaultHRIR_rom_ITD_azimKSeq_fx; // Q22
615 358 : modelITD->W_fx = (const Word32 *) defaultHRIR_rom_ITD_W_fx; // Q25
616 358 : modelITD->W_e = 6;
617 358 : move16();
618 358 : modelITD->azimBsShape_fx = defaultHRIR_rom_ITD_azimBsShape_fx; // Q30
619 358 : modelITD->elevBsShape_fx = defaultHRIR_rom_ITD_elevBsShape_fx; // Q30
620 :
621 358 : HRTF_model_precalc( model );
622 :
623 358 : HrFiltSet_p->latency_s_fx = defaultHRIR_rom_latency_s_fx; // Q31
624 358 : move32();
625 358 : HrFiltSet_p->SampleRate = output_Fs; // Q0
626 358 : move32();
627 358 : HrFiltSet_p->FiltLength = HrFiltSet_p->ModelParams.K; // Q0
628 358 : move16();
629 :
630 358 : IF( NE_32( ( error = BSplineModelEvalAlloc_fx( &HrFiltSet_p->ModelParams, &HrFiltSet_p->ModelEval ) ), IVAS_ERR_OK ) )
631 : {
632 0 : return error;
633 : }
634 :
635 358 : return IVAS_ERR_OK;
636 : }
|