SAF
Loading...
Searching...
No Matches
binauraliser.c
Go to the documentation of this file.
1/*
2 * Copyright 2017-2018 Leo McCormack
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
13 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14 * PERFORMANCE OF THIS SOFTWARE.
15 */
16
34
36(
37 void ** const phBin
38)
39{
41 *phBin = (void*)pData;
42 int ch, dummy;
43
44 /* user parameters */
45 binauraliser_loadPreset(SOURCE_CONFIG_PRESET_DEFAULT, pData->src_dirs_deg, &(pData->new_nSources), &(dummy)); /*check setStateInformation if you change default preset*/
46 pData->useDefaultHRIRsFLAG = 1; /* pars->sofa_filepath must be valid to set this to 0 */
47 pData->enableHRIRsDiffuseEQ = 1;
48 pData->nSources = pData->new_nSources;
50 pData->yaw = 0.0f;
51 pData->pitch = 0.0f;
52 pData->roll = 0.0f;
53 pData->bFlipYaw = 0;
54 pData->bFlipPitch = 0;
55 pData->bFlipRoll = 0;
56 pData->useRollPitchYawFlag = 0;
57 pData->enableRotation = 0;
58
59 /* time-frequency transform + buffers */
60 pData->hSTFT = NULL;
61 pData->fs = 48000.0f;
62 pData->inputFrameTD = (float**)malloc2d(MAX_NUM_INPUTS, BINAURALISER_FRAME_SIZE, sizeof(float));
63 pData->outframeTD = (float**)malloc2d(NUM_EARS, BINAURALISER_FRAME_SIZE, sizeof(float));
64 pData->inputframeTF = (float_complex***)malloc3d(HYBRID_BANDS, MAX_NUM_INPUTS, TIME_SLOTS, sizeof(float_complex));
65 pData->outputframeTF = (float_complex***)malloc3d(HYBRID_BANDS, NUM_EARS, TIME_SLOTS, sizeof(float_complex));
66
67 /* hrir data */
68 pData->hrirs = NULL;
69 pData->hrir_dirs_deg = NULL;
70 pData->sofa_filepath = NULL;
71 pData->weights = NULL;
72 pData->N_hrir_dirs = pData->hrir_loaded_len = pData->hrir_runtime_len = 0;
73 pData->hrir_loaded_fs = pData->hrir_runtime_fs = -1; /* unknown */
74
75 /* vbap (amplitude normalised) */
76 pData->hrtf_vbap_gtableIdx = NULL;
77 pData->hrtf_vbap_gtableComp = NULL;
78 pData->nTriangles = pData->N_hrtf_vbap_gtable = 0;
79
80 /* HRTF filterbank coefficients */
81 pData->itds_s = NULL;
82 pData->hrtf_fb = NULL;
83 pData->hrtf_fb_mag = NULL;
84
85 /* flags/status */
86 pData->progressBar0_1 = 0.0f;
88 strcpy(pData->progressBarText,"");
91 pData->reInitHRTFsAndGainTables = 1;
92 for(ch=0; ch<MAX_NUM_INPUTS; ch++) {
93 pData->recalc_hrtf_interpFLAG[ch] = 1;
94 pData->src_gains[ch] = 1.f;
95 }
96 pData->recalc_M_rotFLAG = 1;
97}
98
100(
101 void ** const phBin
102)
103{
104 binauraliser_data *pData = (binauraliser_data*)(*phBin);
105
106 if (pData != NULL) {
107 /* not safe to free memory during intialisation/processing loop */
108 while (pData->codecStatus == CODEC_STATUS_INITIALISING ||
110 SAF_SLEEP(10);
111 }
112
113 /* free afSTFT and buffers */
114 if(pData->hSTFT !=NULL)
115 afSTFT_destroy(&(pData->hSTFT));
116 free(pData->inputFrameTD);
117 free(pData->outframeTD);
118 free(pData->inputframeTF);
119 free(pData->outputframeTF);
120 free(pData->hrtf_vbap_gtableComp);
121 free(pData->hrtf_vbap_gtableIdx);
122 free(pData->hrtf_fb);
123 free(pData->hrtf_fb_mag);
124 free(pData->itds_s);
125 free(pData->sofa_filepath);
126 free(pData->hrirs);
127 free(pData->hrir_dirs_deg);
128 free(pData->weights);
129 free(pData->progressBarText);
130
131 free(pData);
132 pData = NULL;
133 *phBin = NULL;
134 }
135}
136
138(
139 void * const hBin,
140 int sampleRate
141)
142{
143 binauraliser_data *pData = (binauraliser_data*)(hBin);
144
145 /* define frequency vector */
146 pData->fs = sampleRate;
147 afSTFT_getCentreFreqs(pData->hSTFT, (float)sampleRate, HYBRID_BANDS, pData->freqVector);
148 if(pData->hrir_runtime_fs!=pData->fs){
149 pData->reInitHRTFsAndGainTables = 1;
151 }
152
153 /* defaults */
154 pData->recalc_M_rotFLAG = 1;
155}
156
158(
159 void* const hBin
160)
161{
162 binauraliser_data *pData = (binauraliser_data*)(hBin);
163
165 return; /* re-init not required, or already happening */
166 while (pData->procStatus == PROC_STATUS_ONGOING){
167 /* re-init required, but we need to wait for the current processing loop to end */
168 pData->codecStatus = CODEC_STATUS_INITIALISING; /* indicate that we want to init */
169 SAF_SLEEP(10);
170 }
171
172 /* for progress bar */
174 strcpy(pData->progressBarText,"Initialising");
175 pData->progressBar0_1 = 0.0f;
176
177 /* check if TFT needs to be reinitialised */
179
180 /* reinit HRTFs and interpolation tables */
181 if(pData->reInitHRTFsAndGainTables){
183 pData->reInitHRTFsAndGainTables = 0;
184 }
185
186 /* done! */
187 strcpy(pData->progressBarText,"Done!");
188 pData->progressBar0_1 = 1.0f;
190
191}
192
194(
195 void * const hBin,
196 const float *const * inputs,
197 float* const* const outputs,
198 int nInputs,
199 int nOutputs,
200 int nSamples
201)
202{
203 binauraliser_data *pData = (binauraliser_data*)(hBin);
204 int ch, ear, i, band, nSources;
205 float Rxyz[3][3], hypotxy;
206 int enableRotation;
207
208 /* copy user parameters to local variables */
209 nSources = pData->nSources;
210 enableRotation = pData->enableRotation;
211
212 /* apply binaural panner */
213 if ((nSamples == BINAURALISER_FRAME_SIZE) && (pData->hrtf_fb!=NULL) && (pData->codecStatus==CODEC_STATUS_INITIALISED) ){
215
216 /* Load time-domain data */
217 for(i=0; i < SAF_MIN(nSources,nInputs); i++)
219 for(; i<nSources; i++)
220 memset(pData->inputFrameTD[i], 0, BINAURALISER_FRAME_SIZE * sizeof(float));
221
222 /* Apply source gains */
223 for (ch = 0; ch < nSources; ch++) {
224 if(fabsf(pData->src_gains[ch] - 1.f) > 1e-6f)
225 utility_svsmul(pData->inputFrameTD[ch], &(pData->src_gains[ch]), BINAURALISER_FRAME_SIZE, NULL);
226 }
227
228 /* Apply time-frequency transform (TFT) */
230
231 /* Rotate source directions */
232 if(enableRotation && pData->recalc_M_rotFLAG){
233 yawPitchRoll2Rzyx (pData->yaw, pData->pitch, pData->roll, pData->useRollPitchYawFlag, Rxyz);
234 for(i=0; i<nSources; i++){
235 pData->src_dirs_xyz[i][0] = cosf(DEG2RAD(pData->src_dirs_deg[i][1])) * cosf(DEG2RAD(pData->src_dirs_deg[i][0]));
236 pData->src_dirs_xyz[i][1] = cosf(DEG2RAD(pData->src_dirs_deg[i][1])) * sinf(DEG2RAD(pData->src_dirs_deg[i][0]));
237 pData->src_dirs_xyz[i][2] = sinf(DEG2RAD(pData->src_dirs_deg[i][1]));
238 pData->recalc_hrtf_interpFLAG[i] = 1;
239 }
240 cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, nSources, 3, 3, 1.0f,
241 (float*)(pData->src_dirs_xyz), 3,
242 (float*)Rxyz, 3, 0.0f,
243 (float*)(pData->src_dirs_rot_xyz), 3);
244 for(i=0; i<nSources; i++){
245 hypotxy = sqrtf(powf(pData->src_dirs_rot_xyz[i][0], 2.0f) + powf(pData->src_dirs_rot_xyz[i][1], 2.0f));
246 pData->src_dirs_rot_deg[i][0] = RAD2DEG(atan2f(pData->src_dirs_rot_xyz[i][1], pData->src_dirs_rot_xyz[i][0]));
247 pData->src_dirs_rot_deg[i][1] = RAD2DEG(atan2f(pData->src_dirs_rot_xyz[i][2], hypotxy));
248 }
249 pData->recalc_M_rotFLAG = 0;
250 }
251
252 /* interpolate hrtfs and apply to each source */
253 memset(FLATTEN3D(pData->outputframeTF), 0, HYBRID_BANDS*NUM_EARS*TIME_SLOTS * sizeof(float_complex));
254 for (ch = 0; ch < nSources; ch++) {
255 if(pData->recalc_hrtf_interpFLAG[ch]){
256 if(enableRotation)
257 binauraliser_interpHRTFs(hBin, pData->interpMode, pData->src_dirs_rot_deg[ch][0], pData->src_dirs_rot_deg[ch][1], pData->hrtf_interp[ch]);
258 else
259 binauraliser_interpHRTFs(hBin, pData->interpMode, pData->src_dirs_deg[ch][0], pData->src_dirs_deg[ch][1], pData->hrtf_interp[ch]);
260 pData->recalc_hrtf_interpFLAG[ch] = 0;
261 }
262
263 /* Convolve this channel with the interpolated HRTF, and add it to the binaural buffer */
264 for (band = 0; band < HYBRID_BANDS; band++)
265 for (ear = 0; ear < NUM_EARS; ear++)
266 cblas_caxpy(TIME_SLOTS, &pData->hrtf_interp[ch][band][ear], pData->inputframeTF[band][ch], 1, pData->outputframeTF[band][ear], 1);
267 }
268
269 /* scale by number of sources */
270 cblas_sscal(/*re+im*/2*HYBRID_BANDS*NUM_EARS*TIME_SLOTS, 1.0f/sqrtf((float)nSources), (float*)FLATTEN3D(pData->outputframeTF), 1);
271
272 /* inverse-TFT */
274
275 /* Copy to output buffer */
276 for (ch = 0; ch < SAF_MIN(NUM_EARS, nOutputs); ch++)
277 utility_svvcopy(pData->outframeTD[ch], BINAURALISER_FRAME_SIZE, outputs[ch]);
278 for (; ch < nOutputs; ch++)
279 memset(outputs[ch], 0, BINAURALISER_FRAME_SIZE*sizeof(float));
280 }
281 else{
282 for (ch=0; ch < nOutputs; ch++)
283 memset(outputs[ch],0, BINAURALISER_FRAME_SIZE*sizeof(float));
284 }
285
287}
288
289/* Set Functions */
290
291void binauraliser_refreshSettings(void* const hBin)
292{
293 binauraliser_data *pData = (binauraliser_data*)(hBin);
294 int ch;
295 pData->reInitHRTFsAndGainTables = 1;
296 for(ch=0; ch<MAX_NUM_INPUTS; ch++)
297 pData->recalc_hrtf_interpFLAG[ch] = 1;
299}
300
301void binauraliser_setSourceAzi_deg(void* const hBin, int index, float newAzi_deg)
302{
303 binauraliser_data *pData = (binauraliser_data*)(hBin);
304 if(newAzi_deg>180.0f)
305 newAzi_deg = -360.0f + newAzi_deg;
306 newAzi_deg = SAF_MAX(newAzi_deg, -180.0f);
307 newAzi_deg = SAF_MIN(newAzi_deg, 180.0f);
308 if(pData->src_dirs_deg[index][0]!=newAzi_deg){
309 pData->src_dirs_deg[index][0] = newAzi_deg;
310 pData->recalc_hrtf_interpFLAG[index] = 1;
311 pData->recalc_M_rotFLAG = 1;
312 }
313}
314
315void binauraliser_setSourceElev_deg(void* const hBin, int index, float newElev_deg)
316{
317 binauraliser_data *pData = (binauraliser_data*)(hBin);
318 newElev_deg = SAF_MAX(newElev_deg, -90.0f);
319 newElev_deg = SAF_MIN(newElev_deg, 90.0f);
320 if(pData->src_dirs_deg[index][1] != newElev_deg){
321 pData->src_dirs_deg[index][1] = newElev_deg;
322 pData->recalc_hrtf_interpFLAG[index] = 1;
323 pData->recalc_M_rotFLAG = 1;
324 }
325}
326
327void binauraliser_setNumSources(void* const hBin, int new_nSources)
328{
329 binauraliser_data *pData = (binauraliser_data*)(hBin);
330 pData->new_nSources = SAF_CLAMP(new_nSources, 1, MAX_NUM_INPUTS);
331 pData->recalc_M_rotFLAG = 1;
333}
334
335void binauraliser_setUseDefaultHRIRsflag(void* const hBin, int newState)
336{
337 binauraliser_data *pData = (binauraliser_data*)(hBin);
338 if((!pData->useDefaultHRIRsFLAG) && (newState)){
339 pData->useDefaultHRIRsFLAG = newState;
340 binauraliser_refreshSettings(hBin); // re-init and re-calc
341 }
342}
343
344void binauraliser_setSofaFilePath(void* const hBin, const char* path)
345{
346 binauraliser_data *pData = (binauraliser_data*)(hBin);
347
348 pData->sofa_filepath = realloc1d(pData->sofa_filepath, strlen(path) + 1);
349 strcpy(pData->sofa_filepath, path);
350 pData->useDefaultHRIRsFLAG = 0;
351 binauraliser_refreshSettings(hBin); // re-init and re-calc
352}
353
354void binauraliser_setEnableHRIRsDiffuseEQ(void* const hBin, int newState)
355{
356 binauraliser_data *pData = (binauraliser_data*)(hBin);
357 if(newState!=pData->enableHRIRsDiffuseEQ){
358 pData->enableHRIRsDiffuseEQ = newState;
359 binauraliser_refreshSettings(hBin); // re-init and re-calc
360 }
361}
362
363void binauraliser_setInputConfigPreset(void* const hBin, int newPresetID)
364{
365 binauraliser_data *pData = (binauraliser_data*)(hBin);
366 int ch, dummy;
367
368 binauraliser_loadPreset(newPresetID, pData->src_dirs_deg, &(pData->new_nSources), &(dummy));
369 if(pData->nSources != pData->new_nSources)
371 for(ch=0; ch<MAX_NUM_INPUTS; ch++)
372 pData->recalc_hrtf_interpFLAG[ch] = 1;
373 pData->recalc_M_rotFLAG = 1;
374}
375
376void binauraliser_setEnableRotation(void* const hBin, int newState)
377{
378 binauraliser_data *pData = (binauraliser_data*)(hBin);
379 int ch;
380
381 pData->enableRotation = newState;
382 if(!pData->enableRotation)
383 for (ch = 0; ch<MAX_NUM_INPUTS; ch++)
384 pData->recalc_hrtf_interpFLAG[ch] = 1;
385 pData->recalc_M_rotFLAG = 1;
386}
387
388void binauraliser_setYaw(void * const hBin, float newYaw)
389{
390 binauraliser_data *pData = (binauraliser_data*)(hBin);
391 pData->yaw = pData->bFlipYaw == 1 ? -DEG2RAD(newYaw) : DEG2RAD(newYaw);
392 pData->recalc_M_rotFLAG = 1;
393}
394
395void binauraliser_setPitch(void* const hBin, float newPitch)
396{
397 binauraliser_data *pData = (binauraliser_data*)(hBin);
398 pData->pitch = pData->bFlipPitch == 1 ? -DEG2RAD(newPitch) : DEG2RAD(newPitch);
399 pData->recalc_M_rotFLAG = 1;
400}
401
402void binauraliser_setRoll(void* const hBin, float newRoll)
403{
404 binauraliser_data *pData = (binauraliser_data*)(hBin);
405 pData->roll = pData->bFlipRoll == 1 ? -DEG2RAD(newRoll) : DEG2RAD(newRoll);
406 pData->recalc_M_rotFLAG = 1;
407}
408
409void binauraliser_setFlipYaw(void* const hBin, int newState)
410{
411 binauraliser_data *pData = (binauraliser_data*)(hBin);
412 if(newState !=pData->bFlipYaw ){
413 pData->bFlipYaw = newState;
415 }
416}
417
418void binauraliser_setFlipPitch(void* const hBin, int newState)
419{
420 binauraliser_data *pData = (binauraliser_data*)(hBin);
421 if(newState !=pData->bFlipPitch ){
422 pData->bFlipPitch = newState;
424 }
425}
426
427void binauraliser_setFlipRoll(void* const hBin, int newState)
428{
429 binauraliser_data *pData = (binauraliser_data*)(hBin);
430 if(newState !=pData->bFlipRoll ){
431 pData->bFlipRoll = newState;
433 }
434}
435
436void binauraliser_setRPYflag(void* const hBin, int newState)
437{
438 binauraliser_data *pData = (binauraliser_data*)(hBin);
439 pData->useRollPitchYawFlag = newState;
440 pData->recalc_M_rotFLAG = 1;
441}
442
443void binauraliser_setInterpMode(void* const hBin, int newMode)
444{
445 binauraliser_data *pData = (binauraliser_data*)(hBin);
446 int ch;
447 pData->interpMode = newMode;
448 for(ch=0; ch<MAX_NUM_INPUTS; ch++)
449 pData->recalc_hrtf_interpFLAG[ch] = 1;
450}
451
452void binauraliser_setSourceGain(void* const hAmbi, int srcIdx, float newGain)
453{
454 binauraliser_data *pData = (binauraliser_data*)(hAmbi);
455 pData->src_gains[srcIdx] = newGain;
456}
457
458void binauraliser_setSourceSolo(void* const hAmbi, int srcIdx)
459{
460 binauraliser_data *pData = (binauraliser_data*)(hAmbi);
461 int i;
462 for(i=0; i<pData->nSources; i++){
463 if(i==srcIdx)
464 pData->src_gains[i] = 1.f;
465 else
466 pData->src_gains[i] = 0.f;
467 }
468}
469
470void binauraliser_setUnSolo(void* const hAmbi)
471{
472 binauraliser_data *pData = (binauraliser_data*)(hAmbi);
473 for(int i=0; i<pData->nSources; i++)
474 pData->src_gains[i] = 1.f;
475}
476
477
478/* Get Functions */
479
484
486{
487 binauraliser_data *pData = (binauraliser_data*)(hBin);
488 return pData->codecStatus;
489}
490
491float binauraliser_getProgressBar0_1(void* const hBin)
492{
493 binauraliser_data *pData = (binauraliser_data*)(hBin);
494 return pData->progressBar0_1;
495}
496
497void binauraliser_getProgressBarText(void* const hBin, char* text)
498{
499 binauraliser_data *pData = (binauraliser_data*)(hBin);
500 memcpy(text, pData->progressBarText, PROGRESSBARTEXT_CHAR_LENGTH*sizeof(char));
501}
502
503float binauraliser_getSourceAzi_deg(void* const hBin, int index)
504{
505 binauraliser_data *pData = (binauraliser_data*)(hBin);
506 return pData->src_dirs_deg[index][0];
507}
508
509float binauraliser_getSourceElev_deg(void* const hBin, int index)
510{
511 binauraliser_data *pData = (binauraliser_data*)(hBin);
512 return pData->src_dirs_deg[index][1];
513}
514
515int binauraliser_getNumSources(void* const hBin)
516{
517 binauraliser_data *pData = (binauraliser_data*)(hBin);
518 return pData->new_nSources;
519}
520
525
527{
528 return NUM_EARS;
529}
530
531int binauraliser_getNDirs(void* const hBin)
532{
533 binauraliser_data *pData = (binauraliser_data*)(hBin);
534 return pData->N_hrir_dirs;
535}
536
537int binauraliser_getNTriangles(void* const hBin)
538{
539 binauraliser_data *pData = (binauraliser_data*)(hBin);
540 return pData->nTriangles;
541}
542
543float binauraliser_getHRIRAzi_deg(void* const hBin, int index)
544{
545 binauraliser_data *pData = (binauraliser_data*)(hBin);
546 if(pData->hrir_dirs_deg!=NULL)
547 return pData->hrir_dirs_deg[index*2+0];
548 else
549 return 0.0f;
550}
551
552float binauraliser_getHRIRElev_deg(void* const hBin, int index)
553{
554 binauraliser_data *pData = (binauraliser_data*)(hBin);
555 if(pData->hrir_dirs_deg!=NULL)
556 return pData->hrir_dirs_deg[index*2+1];
557 else
558 return 0.0f;
559}
560
561int binauraliser_getHRIRlength(void* const hBin)
562{
563 binauraliser_data *pData = (binauraliser_data*)(hBin);
564 return pData->hrir_loaded_len;
565}
566
568{
569 binauraliser_data *pData = (binauraliser_data*)(hBin);
570 return pData->hrir_loaded_fs;
571}
572
574{
575 binauraliser_data *pData = (binauraliser_data*)(hBin);
576 return pData->useDefaultHRIRsFLAG;
577}
578
579char* binauraliser_getSofaFilePath(void* const hBin)
580{
581 binauraliser_data *pData = (binauraliser_data*)(hBin);
582 if(pData->sofa_filepath!=NULL)
583 return pData->sofa_filepath;
584 else
585 return "no_file";
586}
587
589{
590 binauraliser_data *pData = (binauraliser_data*)(hBin);
591 return pData->enableHRIRsDiffuseEQ;
592}
593
594int binauraliser_getDAWsamplerate(void* const hBin)
595{
596 binauraliser_data *pData = (binauraliser_data*)(hBin);
597 return pData->fs;
598}
599
601{
602 binauraliser_data *pData = (binauraliser_data*)(hBin);
603 return pData->enableRotation;
604}
605
606float binauraliser_getYaw(void* const hBin)
607{
608 binauraliser_data *pData = (binauraliser_data*)(hBin);
609 return pData->bFlipYaw == 1 ? -RAD2DEG(pData->yaw) : RAD2DEG(pData->yaw);
610}
611
612float binauraliser_getPitch(void* const hBin)
613{
614 binauraliser_data *pData = (binauraliser_data*)(hBin);
615 return pData->bFlipPitch == 1 ? -RAD2DEG(pData->pitch) : RAD2DEG(pData->pitch);
616}
617
618float binauraliser_getRoll(void* const hBin)
619{
620 binauraliser_data *pData = (binauraliser_data*)(hBin);
621 return pData->bFlipRoll == 1 ? -RAD2DEG(pData->roll) : RAD2DEG(pData->roll);
622}
623
624int binauraliser_getFlipYaw(void* const hBin)
625{
626 binauraliser_data *pData = (binauraliser_data*)(hBin);
627 return pData->bFlipYaw;
628}
629
630int binauraliser_getFlipPitch(void* const hBin)
631{
632 binauraliser_data *pData = (binauraliser_data*)(hBin);
633 return pData->bFlipPitch;
634}
635
636int binauraliser_getFlipRoll(void* const hBin)
637{
638 binauraliser_data *pData = (binauraliser_data*)(hBin);
639 return pData->bFlipRoll;
640}
641
642int binauraliser_getRPYflag(void* const hBin)
643{
644 binauraliser_data *pData = (binauraliser_data*)(hBin);
645 return pData->useRollPitchYawFlag;
646}
647
648int binauraliser_getInterpMode(void* const hBin)
649{
650 binauraliser_data *pData = (binauraliser_data*)(hBin);
651 return (int)pData->interpMode;
652}
653
655{
656 return 12*HOP_SIZE;
657}
#define MAX_NUM_INPUTS
Maximum number of input channels supported.
Definition _common.h:233
#define PROGRESSBARTEXT_CHAR_LENGTH
Length of progress bar string.
Definition _common.h:227
@ PROC_STATUS_ONGOING
Codec is processing input audio, and should not be reinitialised at this time.
Definition _common.h:220
@ PROC_STATUS_NOT_ONGOING
Codec is not processing input audio, and may be reinitialised if needed.
Definition _common.h:222
CODEC_STATUS
Current status of the codec.
Definition _common.h:201
@ CODEC_STATUS_NOT_INITIALISED
Codec has not yet been initialised, or the codec configuration has changed.
Definition _common.h:204
@ CODEC_STATUS_INITIALISED
Codec is initialised and ready to process input audio.
Definition _common.h:202
@ CODEC_STATUS_INITIALISING
Codec is currently being initialised, input audio should not be processed.
Definition _common.h:207
void afSTFT_backward_knownDimensions(void *const hSTFT, float_complex ***dataFD, int framesize, int dataFD_nCH, int dataFD_nHops, float **dataTD)
Performs backward afSTFT transform (dataFD dimensions are known)
Definition afSTFTlib.c:391
void afSTFT_forward_knownDimensions(void *const hSTFT, float **dataTD, int framesize, int dataFD_nCH, int dataFD_nHops, float_complex ***dataFD)
Performs forward afSTFT transform (dataFD dimensions are known)
Definition afSTFTlib.c:268
void afSTFT_getCentreFreqs(void *const hSTFT, float fs, int nBands, float *freqVector)
Returns current frequency vector.
Definition afSTFTlib.c:546
void afSTFT_destroy(void **const phSTFT)
Destroys an instance of afSTFT.
Definition afSTFTlib.c:199
#define TIME_SLOTS
Number of STFT timeslots.
#define HOP_SIZE
STFT hop size.
#define HYBRID_BANDS
Number of frequency bands.
int binauraliser_getMaxNumSources()
Returns the maximum number of input sources supported by binauraliser.
int binauraliser_getNTriangles(void *const hBin)
Returns the number of triangular groupings (faces) returned by the Convex Hull.
void binauraliser_setSofaFilePath(void *const hBin, const char *path)
Sets the file path for a .sofa file, in order to employ a custom HRIR set for the decoding.
void binauraliser_refreshSettings(void *const hBin)
Sets all intialisation flags to 1; re-initialising all settings/variables as binauraliser is currentl...
char * binauraliser_getSofaFilePath(void *const hBin)
Returns the file path for a .sofa file.
void binauraliser_setEnableHRIRsDiffuseEQ(void *const hBin, int newState)
Enable (1) or disable (0) the diffuse-field EQ applied to the HRTFs.
int binauraliser_getFlipPitch(void *const hBin)
Returns a flag as to whether to "flip" the sign of the current 'pitch' angle (0: do not flip sign,...
int binauraliser_getNDirs(void *const hBin)
Returns the number of directions in the currently used HRIR set.
void binauraliser_init(void *const hBin, int sampleRate)
Initialises an instance of binauraliser with default settings.
void binauraliser_destroy(void **const phBin)
Destroys an instance of the binauraliser.
int binauraliser_getUseDefaultHRIRsflag(void *const hBin)
Returns the value of a flag used to dictate whether the default HRIRs in the Spatial_Audio_Framework ...
void binauraliser_setRoll(void *const hBin, float newRoll)
Sets the 'roll' rotation angle, in DEGREES.
void binauraliser_initCodec(void *const hBin)
Intialises the codec variables, based on current global/user parameters.
int binauraliser_getFlipRoll(void *const hBin)
Returns a flag as to whether to "flip" the sign of the current 'roll' angle (0: do not flip sign,...
void binauraliser_setSourceAzi_deg(void *const hBin, int index, float newAzi_deg)
Sets the panning azimuth for a specific channel index, in DEGREES.
void binauraliser_setPitch(void *const hBin, float newPitch)
Sets the 'pitch' rotation angle, in DEGREES.
void binauraliser_process(void *const hBin, const float *const *inputs, float *const *const outputs, int nInputs, int nOutputs, int nSamples)
Binauralises the input signals at the user specified directions.
void binauraliser_setSourceSolo(void *const hAmbi, int srcIdx)
Set a source to solo.
int binauraliser_getEnableHRIRsDiffuseEQ(void *const hBin)
Returns the flag indicating whether the diffuse-field EQ applied to the HRTFs is enabled (1) or disab...
void binauraliser_setSourceElev_deg(void *const hBin, int index, float newElev_deg)
Sets the panning elevation for a specific channel index, in DEGREES.
float binauraliser_getProgressBar0_1(void *const hBin)
(Optional) Returns current intialisation/processing progress, between 0..1
CODEC_STATUS binauraliser_getCodecStatus(void *const hBin)
Returns current codec status codec status (see CODEC_STATUS enum)
void binauraliser_create(void **const phBin)
Creates an instance of the binauraliser.
int binauraliser_getRPYflag(void *const hBin)
Returns a flag as to whether to use "yaw-pitch-roll" (0) or "roll-pitch-yaw" (1) rotation order.
float binauraliser_getPitch(void *const hBin)
Returns the 'pitch' rotation angle, in DEGREES.
int binauraliser_getFrameSize(void)
Returns the processing framesize (i.e., number of samples processed with every _process() call )
int binauraliser_getEnableRotation(void *const hBin)
Returns the flag value which dictates whether to enable/disable sound-field rotation (0: disabled,...
void binauraliser_setRPYflag(void *const hBin, int newState)
Sets a flag as to whether to use "yaw-pitch-roll" (0) or "roll-pitch-yaw" (1) rotation order.
int binauraliser_getNumEars(void)
Returns the number of ears possessed by the average homo sapien.
void binauraliser_getProgressBarText(void *const hBin, char *text)
(Optional) Returns current intialisation/processing progress text
int binauraliser_getDAWsamplerate(void *const hBin)
Returns the DAW/Host sample rate.
int binauraliser_getHRIRsamplerate(void *const hBin)
Returns the HRIR sample rate.
float binauraliser_getYaw(void *const hBin)
Returns the 'yaw' rotation angle, in DEGREES.
float binauraliser_getSourceElev_deg(void *const hBin, int index)
Returns the source elevation for a given index, in DEGREES.
void binauraliser_setFlipPitch(void *const hBin, int newState)
Sets a flag as to whether to "flip" the sign of the current 'pitch' angle (0: do not flip sign,...
void binauraliser_setEnableRotation(void *const hBin, int newState)
Sets the flag to enable/disable (1 or 0) rotation.
void binauraliser_setFlipYaw(void *const hBin, int newState)
Sets a flag as to whether to "flip" the sign of the current 'yaw' angle (0: do not flip sign,...
int binauraliser_getProcessingDelay()
Returns the processing delay in samples (may be used for delay compensation purposes)
void binauraliser_setYaw(void *const hBin, float newYaw)
Sets the 'yaw' rotation angle, in DEGREES.
void binauraliser_setInputConfigPreset(void *const hBin, int newPresetID)
Loads an input preset (see SOURCE_CONFIG_PRESETS enum)
void binauraliser_setInterpMode(void *const hBin, int newMode)
NOT IMPLEMENTED YET.
void binauraliser_setUseDefaultHRIRsflag(void *const hBin, int newState)
Sets flag to dictate whether the default HRIRs in the Spatial_Audio_Framework should be used (1),...
void binauraliser_setUnSolo(void *const hAmbi)
Unsolo / unmute all sources.
float binauraliser_getHRIRElev_deg(void *const hBin, int index)
Returns the HRIR/HRTF elevation for a given index, in DEGREES.
float binauraliser_getSourceAzi_deg(void *const hBin, int index)
Returns the source azimuth for a given index, in DEGREES.
float binauraliser_getRoll(void *const hBin)
Returns the 'roll' rotation angle, in DEGREES.
void binauraliser_setFlipRoll(void *const hBin, int newState)
Sets a flag as to whether to "flip" the sign of the current 'roll' angle (0: do not flip sign,...
int binauraliser_getFlipYaw(void *const hBin)
Returns a flag as to whether to "flip" the sign of the current 'yaw' angle (0: do not flip sign,...
int binauraliser_getInterpMode(void *const hBin)
NOT IMPLEMENTED YET.
int binauraliser_getHRIRlength(void *const hBin)
Returns the length of HRIRs in time-domain samples.
float binauraliser_getHRIRAzi_deg(void *const hBin, int index)
Returns the HRIR/HRTF azimuth for a given index, in DEGREES.
void binauraliser_setSourceGain(void *const hAmbi, int srcIdx, float newGain)
Sets gain factor for an input source.
void binauraliser_setNumSources(void *const hBin, int new_nSources)
Sets the number of input channels/sources to binauralise.
int binauraliser_getNumSources(void *const hBin)
Returns the number of inputs/sources in the current layout.
@ INTERP_TRI_PS
Triangular interpolation (with phase-simplification)
void binauraliser_initHRTFsAndGainTables(void *const hBin)
Initialise the HRTFs: either loading the default set or loading from a SOFA file; and then generate a...
void binauraliser_setCodecStatus(void *const hBin, CODEC_STATUS newStatus)
Sets codec status (see CODEC_STATUS enum)
void binauraliser_loadPreset(SOURCE_CONFIG_PRESETS preset, float dirs_deg[MAX_NUM_INPUTS][2], int *newNCH, int *nDims)
Returns the source directions for a specified source config preset.
void binauraliser_initTFT(void *const hBin)
Initialise the filterbank used by binauraliser.
void binauraliser_interpHRTFs(void *const hBin, INTERP_MODES mode, float azimuth_deg, float elevation_deg, float_complex h_intrp[HYBRID_BANDS][NUM_EARS])
Interpolates between (up to) 3 HRTFs via amplitude-normalised VBAP gains.
Convolves input audio (up to 64 channels) with interpolated HRTFs in the time-frequency domain.
#define BINAURALISER_FRAME_SIZE
Framesize, in time-domain samples.
#define SAF_CLAMP(a, min, max)
Ensures value "a" is clamped between the "min" and "max" values.
#define DEG2RAD(x)
Converts degrees to radians.
#define SAF_MAX(a, b)
Returns the maximum of the two values.
#define NUM_EARS
2 (true for most humans)
void utility_svvcopy(const float *a, const int len, float *c)
Single-precision, vector-vector copy, i.e.
#define SAF_MIN(a, b)
Returns the minimum of the two values.
void yawPitchRoll2Rzyx(float yaw, float pitch, float roll, int rollPitchYawFLAG, float R[3][3])
Constructs a 3x3 rotation matrix from the Euler angles, using the yaw-pitch-roll (zyx) convention.
void utility_svsmul(float *a, const float *s, const int len, float *c)
Single-precision, multiplies each element in vector 'a' with a scalar 's', i.e.
#define RAD2DEG(x)
Converts radians to degrees
void ** malloc2d(size_t dim1, size_t dim2, size_t data_size)
2-D malloc (contiguously allocated, so use free() as usual to deallocate)
Definition md_malloc.c:89
void * malloc1d(size_t dim1_data_size)
1-D malloc (same as malloc, but with error checking)
Definition md_malloc.c:59
void * realloc1d(void *ptr, size_t dim1_data_size)
1-D realloc (same as realloc, but with error checking)
Definition md_malloc.c:79
void *** malloc3d(size_t dim1, size_t dim2, size_t dim3, size_t data_size)
3-D malloc (contiguously allocated, so use free() as usual to deallocate)
Definition md_malloc.c:151
#define FLATTEN3D(A)
Use this macro when passing a 3-D dynamic multi-dimensional array to memset, memcpy or any other func...
Definition md_malloc.h:72
Main structure for binauraliser.
float ** inputFrameTD
time-domain input frame; MAX_NUM_INPUTS x BINAURALISER_FRAME_SIZE
int hrir_runtime_len
length of the HRIRs being used for processing (after any resampling), in samples
int enableRotation
1: enable rotation, 0: disable
int fs
Host sampling rate, in Hz.
float roll
roll (Euler) rotation angle, in degrees
PROC_STATUS procStatus
see PROC_STATUS
int bFlipYaw
flag to flip the sign of the yaw rotation angle
int recalc_M_rotFLAG
1: re-calculate the rotation matrix, 0: do not
float_complex *** outputframeTF
time-frequency domain input frame; HYBRID_BANDS x NUM_EARS x TIME_SLOTS
int nSources
Current number of input/source signals.
float * hrtf_vbap_gtableComp
N_hrtf_vbap_gtable x 3.
int N_hrir_dirs
number of HRIR directions in the current sofa file
float src_dirs_rot_xyz[MAX_NUM_INPUTS][3]
Intermediate rotated source directions, as unit-length Cartesian coordinates.
float * hrirs
time domain HRIRs; FLAT: N_hrir_dirs x NUM_EARS x hrir_len
float src_dirs_rot_deg[MAX_NUM_INPUTS][2]
Intermediate rotated source directions, in degrees.
float_complex * hrtf_fb
hrtf filterbank coefficients; nBands x nCH x N_hrirs
int N_hrtf_vbap_gtable
Number of interpolation weights/directions.
float progressBar0_1
Current (re)initialisation progress, between [0..1].
float_complex hrtf_interp[MAX_NUM_INPUTS][HYBRID_BANDS][NUM_EARS]
Interpolated HRTFs.
int hrir_runtime_fs
sampling rate of the HRIRs being used for processing (after any resampling)
float * hrir_dirs_deg
directions of the HRIRs in degrees [azi elev]; FLAT: N_hrir_dirs x 2
int reInitHRTFsAndGainTables
1: reinitialise the HRTFs and interpolation tables, 0: do not
float pitch
pitch (Euler) rotation angle, in degrees
float * weights
Integration weights for the HRIR measurement grid.
int useRollPitchYawFlag
rotation order flag, 1: r-p-y, 0: y-p-r
float src_gains[MAX_NUM_INPUTS]
Gains applied per source.
float src_dirs_xyz[MAX_NUM_INPUTS][3]
Intermediate source directions, as unit-length Cartesian coordinates
float_complex *** inputframeTF
time-frequency domain input frame; HYBRID_BANDS x MAX_NUM_INPUTS x TIME_SLOTS
float * itds_s
interaural-time differences for each HRIR (in seconds); nBands x 1
int * hrtf_vbap_gtableIdx
N_hrtf_vbap_gtable x 3.
int hrir_loaded_len
length of the loaded HRIRs, in samples
CODEC_STATUS codecStatus
see CODEC_STATUS
char * progressBarText
Current (re)initialisation step, string.
void * hSTFT
afSTFT handle
float src_dirs_deg[MAX_NUM_INPUTS][2]
Current source/panning directions, in degrees.
float * hrtf_fb_mag
magnitudes of the hrtf filterbank coefficients; nBands x nCH x N_hrirs
int new_nSources
New number of input/source signals (current value will be replaced by this after next re-init)
int enableHRIRsDiffuseEQ
flag to diffuse-field equalisation to the currently loaded HRTFs
float yaw
yaw (Euler) rotation angle, in degrees
int recalc_hrtf_interpFLAG[MAX_NUM_INPUTS]
1: re-calculate/interpolate the HRTF, 0: do not
int hrir_loaded_fs
sampling rate of the loaded HRIRs
int useDefaultHRIRsFLAG
1: use default HRIRs in database, 0: use those from SOFA file
int bFlipRoll
flag to flip the sign of the roll rotation angle
char * sofa_filepath
absolute/relevative file path for a sofa file
int nTriangles
Number of triangles in the convex hull of the spherical arrangement of HRIR directions/points.
int bFlipPitch
flag to flip the sign of the pitch rotation angle
INTERP_MODES interpMode
see INTERP_MODES
float ** outframeTD
time-domain output frame; NUM_EARS x BINAURALISER_FRAME_SIZE
float freqVector[HYBRID_BANDS]
Frequency vector (filterbank centre frequencies)