Line data Source code
1 : /******************************************************************************************************
2 :
3 : (C) 2022-2026 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.h"
36 : #include "ivas_prot_rend.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 <math.h>
43 : #ifdef DEBUGGING
44 : #include "debug.h"
45 : #endif
46 :
47 :
48 : /*-------------------------------------------------------------------------
49 : * Local functions declaration
50 : *-------------------------------------------------------------------------*/
51 :
52 : static ivas_error DefaultBSplineModel( TDREND_HRFILT_FiltSet_t *HrFiltSet_p, const int32_t output_Fs );
53 :
54 :
55 : /*-------------------------------------------------------------------*
56 : * TDREND_MIX_LIST_SetPos()
57 : *
58 : * Sets the listener's position in the specified mixer unit.
59 : --------------------------------------------------------------------*/
60 :
61 14372997 : void TDREND_MIX_LIST_SetPos(
62 : BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */
63 : const float *Pos_p /* i : Listener's position */
64 : )
65 : {
66 : TDREND_MIX_Listener_t *Listener_p;
67 :
68 14372997 : Listener_p = hBinRendererTd->Listener_p;
69 :
70 14372997 : if ( ( Pos_p[0] != Listener_p->Pos[0] ) || ( Pos_p[1] != Listener_p->Pos[1] ) || ( Pos_p[2] != Listener_p->Pos[2] ) )
71 : {
72 : /* Set position */
73 20058 : mvr2r( Pos_p, Listener_p->Pos, 3 );
74 :
75 : /* Set pose update flag */
76 20058 : Listener_p->PoseUpdated = TRUE;
77 : }
78 :
79 14372997 : return;
80 : }
81 :
82 :
83 : /*-------------------------------------------------------------------*
84 : * TDREND_MIX_LIST_SetOrient()
85 : *
86 : * Sets the listener's orientation vectors in the specified mixer unit.
87 : --------------------------------------------------------------------*/
88 :
89 14372997 : ivas_error TDREND_MIX_LIST_SetOrient(
90 : BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */
91 : const float *FrontVec_p, /* i : Listener's orientation front vector */
92 : const float *UpVec_p /* i : Listener's orientation up vector */
93 : )
94 : {
95 : TDREND_MIX_Listener_t *List_p;
96 : /* Value verification */
97 14372997 : if ( ( FrontVec_p[0] == 0.0f ) && ( FrontVec_p[1] == 0.0f ) && ( FrontVec_p[2] == 0.0f ) )
98 : {
99 0 : return ( IVAS_ERROR( IVAS_ERR_INTERNAL, "Zero front vector. Command is ignored!\n" ) );
100 : }
101 :
102 14372997 : if ( ( UpVec_p[0] == 0.0f ) && ( UpVec_p[1] == 0.0f ) && ( UpVec_p[2] == 0.0f ) )
103 : {
104 0 : return ( IVAS_ERROR( IVAS_ERR_INTERNAL, "Zero up vector. Command is ignored!\n" ) );
105 : }
106 :
107 : /* Get listener */
108 14372997 : List_p = hBinRendererTd->Listener_p;
109 :
110 : /* Evaluate the normalized orientation vectors and set pose update flag */
111 14372997 : List_p->PoseUpdated = TDREND_SPATIAL_EvalOrthonormOrient( List_p->Front, List_p->Up, List_p->Right, FrontVec_p, UpVec_p );
112 :
113 14372997 : return IVAS_ERR_OK;
114 : }
115 :
116 :
117 : /*-------------------------------------------------------------------*
118 : * TDREND_MIX_Dealloc()
119 : *
120 : * Deallocates the TDREND_MIX_t variable
121 : --------------------------------------------------------------------*/
122 :
123 42931 : void TDREND_MIX_Dealloc(
124 : BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd /* i/o: TD renderer handle */
125 : )
126 : {
127 : int16_t i;
128 :
129 : /* Deallocate source list */
130 113301 : for ( i = 0; i < hBinRendererTd->NumOfSrcs; i++ )
131 : {
132 70370 : TDREND_SRC_Dealloc( hBinRendererTd->Sources[i] );
133 : }
134 : /* Deallocate Listener and RendListener */
135 42931 : if ( hBinRendererTd->Listener_p != NULL )
136 : {
137 42931 : free( hBinRendererTd->Listener_p );
138 42931 : hBinRendererTd->Listener_p = NULL;
139 : }
140 : /* Dealloc HR filter set */
141 42931 : if ( ( *hBinRendererTd->pHrFiltSet_p != NULL ) && ( hBinRendererTd->HrFiltSet_p != NULL ) )
142 : {
143 16029 : if ( hBinRendererTd->HrFiltSet_p->FilterMethod == TDREND_HRFILT_Method_BSplineModel )
144 : {
145 16029 : BSplineModelEvalDealloc( &hBinRendererTd->HrFiltSet_p->ModelParams, &hBinRendererTd->HrFiltSet_p->ModelEval );
146 : }
147 :
148 16029 : if ( hBinRendererTd->HrFiltSet_p->ModelParams.modelROM == 1 )
149 : {
150 :
151 14107 : free( hBinRendererTd->HrFiltSet_p );
152 14107 : hBinRendererTd->HrFiltSet_p = NULL;
153 14107 : *hBinRendererTd->pHrFiltSet_p = NULL;
154 : }
155 : }
156 :
157 42931 : return;
158 : }
159 :
160 :
161 : /*-------------------------------------------------------------------*
162 : * TDREND_MIX_Init()
163 : *
164 : * Initializes the mixer and sets HRTF
165 : --------------------------------------------------------------------*/
166 :
167 42931 : ivas_error TDREND_MIX_Init(
168 : BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */
169 : TDREND_HRFILT_FiltSet_t **hHrtfTD, /* i/o: HRTF data (initialized in case of NULL) */
170 : const TDREND_MixSpatSpec_t *MixSpatSpec_p, /* i : Mixer spatial specification */
171 : const int32_t output_Fs /* i : Output sampling rate */
172 : )
173 : {
174 : ivas_error error;
175 :
176 42931 : hBinRendererTd->Gain = 1.0f;
177 :
178 : /* Init source list */
179 :
180 : /* Spatial settings */
181 42931 : if ( MixSpatSpec_p != NULL )
182 : {
183 42931 : hBinRendererTd->UseCommonDistAttenModel = MixSpatSpec_p->UseCommonDistAttenModel;
184 42931 : hBinRendererTd->DistAttenModel = MixSpatSpec_p->DistAttenModel;
185 : }
186 : else
187 : {
188 0 : hBinRendererTd->UseCommonDistAttenModel = TRUE;
189 0 : hBinRendererTd->DistAttenModel = 0x0000; /* Distance attenuation not activated; */
190 : }
191 :
192 : /* Init virtual and rendering listeners for spatial mixers */
193 42931 : TDREND_SPATIAL_VecInit( hBinRendererTd->Listener_p->Pos, 0.0f, 0.0f, 0.0f );
194 42931 : TDREND_SPATIAL_VecInit( hBinRendererTd->Listener_p->Vel, 0.0f, 0.0f, 0.0f );
195 42931 : TDREND_SPATIAL_VecInit( hBinRendererTd->Listener_p->Front, 0.0f, 0.0f, -1.0f );
196 42931 : TDREND_SPATIAL_VecInit( hBinRendererTd->Listener_p->Up, 0.0f, 1.0f, 0.0f );
197 42931 : TDREND_SPATIAL_VecInit( hBinRendererTd->Listener_p->Right, 1.0f, 0.0f, 0.0f );
198 :
199 : /* Init HR filter set */
200 42931 : if ( *hHrtfTD == NULL )
201 : {
202 14107 : if ( ( hBinRendererTd->HrFiltSet_p = (TDREND_HRFILT_FiltSet_t *) malloc( sizeof( TDREND_HRFILT_FiltSet_t ) ) ) == NULL )
203 : {
204 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural TD renderer\n" ) );
205 : }
206 :
207 14107 : if ( ( error = DefaultBSplineModel( hBinRendererTd->HrFiltSet_p, output_Fs ) ) != IVAS_ERR_OK )
208 : {
209 0 : return error;
210 : }
211 14107 : *hHrtfTD = hBinRendererTd->HrFiltSet_p;
212 : }
213 : else
214 : {
215 28824 : hBinRendererTd->HrFiltSet_p = *hHrtfTD;
216 : }
217 :
218 42931 : hBinRendererTd->pHrFiltSet_p = hHrtfTD;
219 :
220 42931 : if ( hBinRendererTd->HrFiltSet_p->SampleRate != output_Fs )
221 : {
222 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" ) );
223 : }
224 :
225 42931 : return IVAS_ERR_OK;
226 : }
227 :
228 :
229 : /*-------------------------------------------------------------------*
230 : * TDREND_MIX_SetDistAttenModel()
231 : *
232 : * Set the distance attenuation model of the mixer
233 : --------------------------------------------------------------------*/
234 :
235 42931 : ivas_error TDREND_MIX_SetDistAttenModel(
236 : BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */
237 : const TDREND_DistAttenModel_t DistAttenModel /* i : Distance attenuation model */
238 : )
239 : {
240 :
241 : /* Value validation */
242 42931 : if ( ( DistAttenModel < TDREND_DIST_ATTEN_MODEL_INV_DIST ) || ( DistAttenModel > TDREND_DIST_ATTEN_MODEL_INV_DIST_CLAMPED ) )
243 : {
244 0 : return ( IVAS_ERROR( IVAS_ERR_INTERNAL, "Invalid distance attenuation model!\n" ) );
245 : }
246 : else
247 : {
248 : /* Set the common distance attenuation model */
249 42931 : hBinRendererTd->DistAttenModel = DistAttenModel;
250 :
251 : /* If using common distance attenuation model, set it. */
252 42931 : if ( hBinRendererTd->UseCommonDistAttenModel )
253 : {
254 42931 : hBinRendererTd->DistAttenEnabled = TRUE;
255 42931 : hBinRendererTd->DistAttenModel = DistAttenModel;
256 : }
257 : }
258 :
259 42931 : return IVAS_ERR_OK;
260 : }
261 :
262 :
263 : /*-------------------------------------------------------------------*
264 : * TDREND_MIX_AddSrc()
265 : *
266 : * Adds the specified input source unit to the specified mixer unit.
267 : --------------------------------------------------------------------*/
268 :
269 70370 : ivas_error TDREND_MIX_AddSrc(
270 : BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */
271 : int16_t *SrcInd, /* o : Source index */
272 : const TDREND_PosType_t PosType /* i : Position type (absolute/relative) */
273 : )
274 : {
275 : TDREND_SRC_t *Src_p;
276 : ivas_error error;
277 :
278 : /* Get unique source index */
279 70370 : *SrcInd = hBinRendererTd->MaxSrcInd + 1;
280 70370 : hBinRendererTd->MaxSrcInd++;
281 70370 : hBinRendererTd->NumOfSrcs++;
282 :
283 70370 : if ( hBinRendererTd->NumOfSrcs > MAX_NUM_TDREND_CHANNELS )
284 : {
285 0 : return ( IVAS_ERROR( IVAS_ERR_INTERNAL, "Maximum number of sources exceeded!\n" ) );
286 : }
287 : else
288 : {
289 70370 : if ( ( PosType < TDREND_POSTYPE_ABSOLUTE ) || ( PosType > TDREND_POSTYPE_NON_DIEGETIC ) )
290 : {
291 0 : return ( IVAS_ERROR( IVAS_ERR_INTERNAL, "Invalid position type!\n" ) );
292 : }
293 : else
294 : {
295 : /* Alloc and init a complete source: signal+spatial+rend components */
296 70370 : if ( ( error = TDREND_SRC_Alloc( &Src_p ) ) != IVAS_ERR_OK )
297 : {
298 0 : return error;
299 : }
300 :
301 70370 : TDREND_SRC_Init( Src_p, PosType );
302 :
303 : /* Special OpenAL initialization due to a common distance attenuation model */
304 70370 : if ( hBinRendererTd->DistAttenModel != 0 )
305 : {
306 70370 : Src_p->SrcSpatial_p->DistAttenEnabled = TRUE;
307 70370 : Src_p->SrcSpatial_p->DistAtten.DistAttenModel = hBinRendererTd->DistAttenModel;
308 : }
309 : /* Add source to mixer */
310 70370 : hBinRendererTd->Sources[*SrcInd] = Src_p;
311 : }
312 : }
313 :
314 70370 : return IVAS_ERR_OK;
315 : }
316 :
317 :
318 : /*-------------------------------------------------------------------*
319 : * BSplineModelEvalAlloc()
320 : *
321 : * Allocate the B Spline HR Filter model.
322 : --------------------------------------------------------------------*/
323 :
324 14107 : static ivas_error BSplineModelEvalAlloc(
325 : ModelParams_t *model, /* i : Model parameters */
326 : ModelEval_t *modelEval /* i/o: Model evaluation structure */
327 : )
328 : {
329 14107 : if ( ( modelEval->hrfModL = (float *) malloc( model->K * sizeof( float ) ) ) == NULL )
330 : {
331 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural TD renderer\n" ) );
332 : }
333 :
334 14107 : if ( ( modelEval->hrfModR = (float *) malloc( model->K * sizeof( float ) ) ) == NULL )
335 : {
336 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural TD renderer\n" ) );
337 : }
338 :
339 14107 : return IVAS_ERR_OK;
340 : }
341 :
342 :
343 : /*-------------------------------------------------------------------*
344 : * DefaultBSplineModel()
345 : *
346 : * Init default HRTF model
347 : --------------------------------------------------------------------*/
348 :
349 14107 : static ivas_error DefaultBSplineModel(
350 : TDREND_HRFILT_FiltSet_t *HrFiltSet_p, /* o : Loaded HR filter set */
351 : const int32_t output_Fs /* i : Output sampling rate */
352 : )
353 : {
354 : ModelParams_t *model;
355 : ModelParamsITD_t *modelITD;
356 : int16_t i, j;
357 : ivas_error error;
358 : float azimSegSamples;
359 :
360 14107 : HrFiltSet_p->FilterMethod = TDREND_HRFILT_Method_BSplineModel;
361 14107 : model = &( HrFiltSet_p->ModelParams );
362 14107 : modelITD = &( HrFiltSet_p->ModelParamsITD );
363 :
364 : /* Set ROM flag for correct deallocation */
365 14107 : model->modelROM = TRUE;
366 :
367 : /* int16_t parameters */
368 14107 : model->UseItdModel = defaultHRIR_rom_model_configuration[0];
369 14107 : model->elevDim3 = defaultHRIR_rom_model_configuration[1];
370 14107 : model->AlphaN = defaultHRIR_rom_model_configuration[2];
371 14107 : model->num_unique_azim_splines = defaultHRIR_rom_model_configuration[3];
372 14107 : model->elevSegSamples = defaultHRIR_rom_model_configuration[4];
373 14107 : model->elevBsLen = defaultHRIR_rom_elevBsLen;
374 14107 : model->elevBsStart = defaultHRIR_rom_elevBsStart;
375 14107 : model->azimDim3 = defaultHRIR_rom_azimDim3;
376 14107 : model->azim_start_idx = defaultHRIR_rom_azim_start_idx;
377 14107 : model->azimSegSamples = defaultHRIR_rom_azimSegSamples;
378 14107 : model->azimShapeIdx = defaultHRIR_rom_azimShapeIdx;
379 14107 : model->azimShapeSampFactor = defaultHRIR_rom_azimShapeSampFactor;
380 :
381 : /* float parameters */
382 14107 : model->elevKSeq = (const float *) defaultHRIR_rom_elevKSeq;
383 14107 : model->elevBsShape = (const float *) defaultHRIR_rom_elevBsShape;
384 :
385 14107 : if ( ( model->azimBsShape = (const float **) malloc( model->num_unique_azim_splines * sizeof( float * ) ) ) == NULL )
386 : {
387 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural TD renderer\n" ) );
388 : }
389 :
390 14107 : model->azimBsShape[0] = (const float *) defaultHRIR_rom_azimBsShape;
391 :
392 14107 : if ( ( model->azimKSeq = (float **) malloc( model->elevDim3 * sizeof( float * ) ) ) == NULL )
393 : {
394 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural TD renderer\n" ) );
395 : }
396 :
397 225712 : for ( i = 0; i < model->elevDim3; i++ )
398 : {
399 211605 : if ( ( model->azimKSeq[i] = (float *) malloc( ( model->azimDim3[i] + 1 ) * sizeof( float * ) ) ) == NULL )
400 : {
401 0 : return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural TD renderer\n" ) );
402 : }
403 :
404 211605 : if ( model->azimShapeIdx[i] < 0 )
405 : {
406 28214 : azimSegSamples = 360.0f;
407 : }
408 : else
409 : {
410 183391 : azimSegSamples = defaultHRIR_rom_azimSegSamples[model->azimShapeIdx[i]];
411 : }
412 :
413 211605 : assert( azimSegSamples == 360.0f / model->azimDim3[i] );
414 7053500 : for ( j = 0; j < model->azimDim3[i] + 1; j++ )
415 : {
416 6841895 : model->azimKSeq[i][j] = azimSegSamples * j;
417 : }
418 : }
419 :
420 14107 : switch ( output_Fs )
421 : {
422 6978 : case 48000:
423 6978 : model->AlphaL = (const float *) defaultHRIR_rom_AlphaL48;
424 6978 : model->AlphaR = (const float *) defaultHRIR_rom_AlphaR48;
425 6978 : model->EL = (const float *) defaultHRIR_rom_EL48;
426 6978 : model->ER = (const float *) defaultHRIR_rom_ER48;
427 6978 : model->K = defaultHRIR_rom_model_configuration[5];
428 6978 : if ( HrFiltSet_p->ModelParams.UseItdModel )
429 : {
430 6978 : modelITD->resamp_factor = 1.0f;
431 : }
432 6978 : break;
433 3611 : case 32000:
434 3611 : model->AlphaL = (const float *) defaultHRIR_rom_AlphaL32;
435 3611 : model->AlphaR = (const float *) defaultHRIR_rom_AlphaR32;
436 3611 : model->EL = (const float *) defaultHRIR_rom_EL32;
437 3611 : model->ER = (const float *) defaultHRIR_rom_ER32;
438 3611 : model->K = (int16_t) ceilf( RESAMPLE_FACTOR_32_48 * defaultHRIR_rom_model_configuration[5] );
439 3611 : if ( HrFiltSet_p->ModelParams.UseItdModel )
440 : {
441 3611 : modelITD->resamp_factor = RESAMPLE_FACTOR_32_48;
442 : }
443 3611 : break;
444 3518 : case 16000:
445 3518 : model->AlphaL = (const float *) defaultHRIR_rom_AlphaL16;
446 3518 : model->AlphaR = (const float *) defaultHRIR_rom_AlphaR16;
447 3518 : model->EL = (const float *) defaultHRIR_rom_EL16;
448 3518 : model->ER = (const float *) defaultHRIR_rom_ER16;
449 3518 : model->K = (int16_t) ceilf( RESAMPLE_FACTOR_16_48 * defaultHRIR_rom_model_configuration[5] );
450 3518 : if ( HrFiltSet_p->ModelParams.UseItdModel )
451 : {
452 3518 : modelITD->resamp_factor = RESAMPLE_FACTOR_16_48;
453 : }
454 3518 : break;
455 0 : default:
456 0 : break;
457 : }
458 :
459 14107 : modelITD->elevDim3 = defaultHRIR_rom_ITD_model_configuration[0];
460 14107 : modelITD->azimDim3 = defaultHRIR_rom_ITD_model_configuration[1];
461 14107 : modelITD->elevSegSamples = defaultHRIR_rom_ITD_model_configuration[2];
462 14107 : modelITD->azimSegSamples = defaultHRIR_rom_ITD_model_configuration[3];
463 14107 : modelITD->elevBsLen = defaultHRIR_rom_ITD_elevBsLen;
464 14107 : modelITD->elevBsStart = defaultHRIR_rom_ITD_elevBsStart;
465 :
466 14107 : modelITD->elevKSeq = defaultHRIR_rom_ITD_elevKSeq;
467 :
468 14107 : modelITD->azimBsLen = defaultHRIR_rom_ITD_azimBsLen;
469 14107 : modelITD->azimBsStart = defaultHRIR_rom_ITD_azimBsStart;
470 :
471 14107 : modelITD->azimKSeq = defaultHRIR_rom_ITD_azimKSeq;
472 14107 : modelITD->W = (const float *) defaultHRIR_rom_ITD_W;
473 14107 : modelITD->azimBsShape = (const float *) defaultHRIR_rom_ITD_azimBsShape;
474 14107 : modelITD->elevBsShape = (const float *) defaultHRIR_rom_ITD_elevBsShape;
475 :
476 14107 : HRTF_model_precalc( model );
477 :
478 14107 : HrFiltSet_p->latency_s = defaultHRIR_rom_latency_s;
479 :
480 14107 : HrFiltSet_p->SampleRate = output_Fs;
481 14107 : HrFiltSet_p->FiltLength = HrFiltSet_p->ModelParams.K;
482 :
483 14107 : if ( ( error = BSplineModelEvalAlloc( &HrFiltSet_p->ModelParams, &HrFiltSet_p->ModelEval ) ) != IVAS_ERR_OK )
484 : {
485 0 : return error;
486 : }
487 :
488 14107 : return IVAS_ERR_OK;
489 : }
|