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
32
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, temp_gain;
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->codecStatus==CODEC_STATUS_INITIALISED) && (pData->hrtf_fb!=NULL) ){
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 temp_gain = pData->src_gains[ch];
226 utility_svsmul(pData->inputFrameTD[ch], &temp_gain, BINAURALISER_FRAME_SIZE, NULL);
227 }
228 }
229
230 /* Apply time-frequency transform (TFT) */
232
233 /* Rotate source directions */
234 if(enableRotation && pData->recalc_M_rotFLAG){
235 yawPitchRoll2Rzyx (pData->yaw, pData->pitch, pData->roll, pData->useRollPitchYawFlag, Rxyz);
236 for(i=0; i<nSources; i++){
237 pData->src_dirs_xyz[i][0] = cosf(DEG2RAD(pData->src_dirs_deg[i][1])) * cosf(DEG2RAD(pData->src_dirs_deg[i][0]));
238 pData->src_dirs_xyz[i][1] = cosf(DEG2RAD(pData->src_dirs_deg[i][1])) * sinf(DEG2RAD(pData->src_dirs_deg[i][0]));
239 pData->src_dirs_xyz[i][2] = sinf(DEG2RAD(pData->src_dirs_deg[i][1]));
240 pData->recalc_hrtf_interpFLAG[i] = 1;
241 }
242 cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, nSources, 3, 3, 1.0f,
243 (float*)(pData->src_dirs_xyz), 3,
244 (float*)Rxyz, 3, 0.0f,
245 (float*)(pData->src_dirs_rot_xyz), 3);
246 for(i=0; i<nSources; i++){
247 hypotxy = sqrtf(powf(pData->src_dirs_rot_xyz[i][0], 2.0f) + powf(pData->src_dirs_rot_xyz[i][1], 2.0f));
248 pData->src_dirs_rot_deg[i][0] = RAD2DEG(atan2f(pData->src_dirs_rot_xyz[i][1], pData->src_dirs_rot_xyz[i][0]));
249 pData->src_dirs_rot_deg[i][1] = RAD2DEG(atan2f(pData->src_dirs_rot_xyz[i][2], hypotxy));
250 }
251 pData->recalc_M_rotFLAG = 0;
252 }
253
254 /* interpolate hrtfs and apply to each source */
255 memset(FLATTEN3D(pData->outputframeTF), 0, HYBRID_BANDS*NUM_EARS*TIME_SLOTS * sizeof(float_complex));
256 for (ch = 0; ch < nSources; ch++) {
257 if(pData->recalc_hrtf_interpFLAG[ch]){
258 if(enableRotation)
259 binauraliser_interpHRTFs(hBin, pData->interpMode, pData->src_dirs_rot_deg[ch][0], pData->src_dirs_rot_deg[ch][1], pData->hrtf_interp[ch]);
260 else
261 binauraliser_interpHRTFs(hBin, pData->interpMode, pData->src_dirs_deg[ch][0], pData->src_dirs_deg[ch][1], pData->hrtf_interp[ch]);
262 pData->recalc_hrtf_interpFLAG[ch] = 0;
263 }
264
265 /* Convolve this channel with the interpolated HRTF, and add it to the binaural buffer */
266 for (band = 0; band < HYBRID_BANDS; band++)
267 for (ear = 0; ear < NUM_EARS; ear++)
268 cblas_caxpy(TIME_SLOTS, &pData->hrtf_interp[ch][band][ear], pData->inputframeTF[band][ch], 1, pData->outputframeTF[band][ear], 1);
269 }
270
271 /* scale by number of sources */
272 cblas_sscal(/*re+im*/2*HYBRID_BANDS*NUM_EARS*TIME_SLOTS, 1.0f/sqrtf((float)nSources), (float*)FLATTEN3D(pData->outputframeTF), 1);
273
274 /* inverse-TFT */
276
277 /* Copy to output buffer */
278 for (ch = 0; ch < SAF_MIN(NUM_EARS, nOutputs); ch++)
279 utility_svvcopy(pData->outframeTD[ch], BINAURALISER_FRAME_SIZE, outputs[ch]);
280 for (; ch < nOutputs; ch++)
281 memset(outputs[ch], 0, BINAURALISER_FRAME_SIZE*sizeof(float));
282 }
283 else{
284 for (ch=0; ch < nOutputs; ch++)
285 memset(outputs[ch],0, BINAURALISER_FRAME_SIZE*sizeof(float));
286 }
287
289}
290
291/* Set Functions */
292
293void binauraliser_refreshSettings(void* const hBin)
294{
295 binauraliser_data *pData = (binauraliser_data*)(hBin);
296 int ch;
297 pData->reInitHRTFsAndGainTables = 1;
298 for(ch=0; ch<MAX_NUM_INPUTS; ch++)
299 pData->recalc_hrtf_interpFLAG[ch] = 1;
301}
302
303void binauraliser_setSourceAzi_deg(void* const hBin, int index, float newAzi_deg)
304{
305 binauraliser_data *pData = (binauraliser_data*)(hBin);
306 if(newAzi_deg>180.0f)
307 newAzi_deg = -360.0f + newAzi_deg;
308 newAzi_deg = SAF_MAX(newAzi_deg, -180.0f);
309 newAzi_deg = SAF_MIN(newAzi_deg, 180.0f);
310 if(pData->src_dirs_deg[index][0]!=newAzi_deg){
311 pData->src_dirs_deg[index][0] = newAzi_deg;
312 pData->recalc_hrtf_interpFLAG[index] = 1;
313 pData->recalc_M_rotFLAG = 1;
314 }
315}
316
317void binauraliser_setSourceElev_deg(void* const hBin, int index, float newElev_deg)
318{
319 binauraliser_data *pData = (binauraliser_data*)(hBin);
320 newElev_deg = SAF_MAX(newElev_deg, -90.0f);
321 newElev_deg = SAF_MIN(newElev_deg, 90.0f);
322 if(pData->src_dirs_deg[index][1] != newElev_deg){
323 pData->src_dirs_deg[index][1] = newElev_deg;
324 pData->recalc_hrtf_interpFLAG[index] = 1;
325 pData->recalc_M_rotFLAG = 1;
326 }
327}
328
329void binauraliser_setNumSources(void* const hBin, int new_nSources)
330{
331 binauraliser_data *pData = (binauraliser_data*)(hBin);
332 pData->new_nSources = SAF_CLAMP(new_nSources, 1, MAX_NUM_INPUTS);
333 pData->recalc_M_rotFLAG = 1;
335}
336
337void binauraliser_setUseDefaultHRIRsflag(void* const hBin, int newState)
338{
339 binauraliser_data *pData = (binauraliser_data*)(hBin);
340 if((!pData->useDefaultHRIRsFLAG) && (newState)){
341 pData->useDefaultHRIRsFLAG = newState;
342 binauraliser_refreshSettings(hBin); // re-init and re-calc
343 }
344}
345
346void binauraliser_setSofaFilePath(void* const hBin, const char* path)
347{
348 binauraliser_data *pData = (binauraliser_data*)(hBin);
349
350 pData->sofa_filepath = realloc1d(pData->sofa_filepath, strlen(path) + 1);
351 strcpy(pData->sofa_filepath, path);
352 pData->useDefaultHRIRsFLAG = 0;
353 binauraliser_refreshSettings(hBin); // re-init and re-calc
354}
355
356void binauraliser_setEnableHRIRsDiffuseEQ(void* const hBin, int newState)
357{
358 binauraliser_data *pData = (binauraliser_data*)(hBin);
359 if(newState!=pData->enableHRIRsDiffuseEQ){
360 pData->enableHRIRsDiffuseEQ = newState;
361 binauraliser_refreshSettings(hBin); // re-init and re-calc
362 }
363}
364
365void binauraliser_setInputConfigPreset(void* const hBin, int newPresetID)
366{
367 binauraliser_data *pData = (binauraliser_data*)(hBin);
368 int ch, dummy;
369
370 binauraliser_loadPreset(newPresetID, pData->src_dirs_deg, &(pData->new_nSources), &(dummy));
371 if(pData->nSources != pData->new_nSources)
373 for(ch=0; ch<MAX_NUM_INPUTS; ch++)
374 pData->recalc_hrtf_interpFLAG[ch] = 1;
375 pData->recalc_M_rotFLAG = 1;
376}
377
378void binauraliser_setEnableRotation(void* const hBin, int newState)
379{
380 binauraliser_data *pData = (binauraliser_data*)(hBin);
381 int ch;
382
383 pData->enableRotation = newState;
384 if(!pData->enableRotation)
385 for (ch = 0; ch<MAX_NUM_INPUTS; ch++)
386 pData->recalc_hrtf_interpFLAG[ch] = 1;
387 pData->recalc_M_rotFLAG = 1;
388}
389
390void binauraliser_setYaw(void * const hBin, float newYaw)
391{
392 binauraliser_data *pData = (binauraliser_data*)(hBin);
393 pData->yaw = pData->bFlipYaw == 1 ? -DEG2RAD(newYaw) : DEG2RAD(newYaw);
394 pData->recalc_M_rotFLAG = 1;
395}
396
397void binauraliser_setPitch(void* const hBin, float newPitch)
398{
399 binauraliser_data *pData = (binauraliser_data*)(hBin);
400 pData->pitch = pData->bFlipPitch == 1 ? -DEG2RAD(newPitch) : DEG2RAD(newPitch);
401 pData->recalc_M_rotFLAG = 1;
402}
403
404void binauraliser_setRoll(void* const hBin, float newRoll)
405{
406 binauraliser_data *pData = (binauraliser_data*)(hBin);
407 pData->roll = pData->bFlipRoll == 1 ? -DEG2RAD(newRoll) : DEG2RAD(newRoll);
408 pData->recalc_M_rotFLAG = 1;
409}
410
411void binauraliser_setFlipYaw(void* const hBin, int newState)
412{
413 binauraliser_data *pData = (binauraliser_data*)(hBin);
414 if(newState !=pData->bFlipYaw ){
415 pData->bFlipYaw = newState;
417 }
418}
419
420void binauraliser_setFlipPitch(void* const hBin, int newState)
421{
422 binauraliser_data *pData = (binauraliser_data*)(hBin);
423 if(newState !=pData->bFlipPitch ){
424 pData->bFlipPitch = newState;
426 }
427}
428
429void binauraliser_setFlipRoll(void* const hBin, int newState)
430{
431 binauraliser_data *pData = (binauraliser_data*)(hBin);
432 if(newState !=pData->bFlipRoll ){
433 pData->bFlipRoll = newState;
435 }
436}
437
438void binauraliser_setRPYflag(void* const hBin, int newState)
439{
440 binauraliser_data *pData = (binauraliser_data*)(hBin);
441 pData->useRollPitchYawFlag = newState;
442 pData->recalc_M_rotFLAG = 1;
443}
444
445void binauraliser_setInterpMode(void* const hBin, int newMode)
446{
447 binauraliser_data *pData = (binauraliser_data*)(hBin);
448 int ch;
449 pData->interpMode = newMode;
450 for(ch=0; ch<MAX_NUM_INPUTS; ch++)
451 pData->recalc_hrtf_interpFLAG[ch] = 1;
452}
453
454void binauraliser_setSourceGain(void* const hAmbi, int srcIdx, float newGain)
455{
456 binauraliser_data *pData = (binauraliser_data*)(hAmbi);
457 pData->src_gains[srcIdx] = newGain;
458}
459
460void binauraliser_setSourceSolo(void* const hAmbi, int srcIdx)
461{
462 binauraliser_data *pData = (binauraliser_data*)(hAmbi);
463 int i;
464 for(i=0; i<pData->nSources; i++){
465 if(i==srcIdx)
466 pData->src_gains[i] = 1.f;
467 else
468 pData->src_gains[i] = 0.f;
469 }
470}
471
472void binauraliser_setUnSolo(void* const hAmbi)
473{
474 binauraliser_data *pData = (binauraliser_data*)(hAmbi);
475 for(int i=0; i<pData->nSources; i++)
476 pData->src_gains[i] = 1.f;
477}
478
479
480/* Get Functions */
481
486
488{
489 binauraliser_data *pData = (binauraliser_data*)(hBin);
490 return pData->codecStatus;
491}
492
493float binauraliser_getProgressBar0_1(void* const hBin)
494{
495 binauraliser_data *pData = (binauraliser_data*)(hBin);
496 return pData->progressBar0_1;
497}
498
499void binauraliser_getProgressBarText(void* const hBin, char* text)
500{
501 binauraliser_data *pData = (binauraliser_data*)(hBin);
502 memcpy(text, pData->progressBarText, PROGRESSBARTEXT_CHAR_LENGTH*sizeof(char));
503}
504
505float binauraliser_getSourceAzi_deg(void* const hBin, int index)
506{
507 binauraliser_data *pData = (binauraliser_data*)(hBin);
508 return pData->src_dirs_deg[index][0];
509}
510
511float binauraliser_getSourceElev_deg(void* const hBin, int index)
512{
513 binauraliser_data *pData = (binauraliser_data*)(hBin);
514 return pData->src_dirs_deg[index][1];
515}
516
517int binauraliser_getNumSources(void* const hBin)
518{
519 binauraliser_data *pData = (binauraliser_data*)(hBin);
520 return pData->new_nSources;
521}
522
524{
525 return MAX_NUM_INPUTS;
526}
527
529{
530 return NUM_EARS;
531}
532
533int binauraliser_getNDirs(void* const hBin)
534{
535 binauraliser_data *pData = (binauraliser_data*)(hBin);
536 return pData->N_hrir_dirs;
537}
538
539int binauraliser_getNTriangles(void* const hBin)
540{
541 binauraliser_data *pData = (binauraliser_data*)(hBin);
542 return pData->nTriangles;
543}
544
545float binauraliser_getHRIRAzi_deg(void* const hBin, int index)
546{
547 binauraliser_data *pData = (binauraliser_data*)(hBin);
548 if(!pData->reInitHRTFsAndGainTables && pData->hrir_dirs_deg!=NULL)
549 return pData->hrir_dirs_deg[index*2+0];
550 else
551 return 0.0f;
552}
553
554float binauraliser_getHRIRElev_deg(void* const hBin, int index)
555{
556 binauraliser_data *pData = (binauraliser_data*)(hBin);
557 if(!pData->reInitHRTFsAndGainTables && pData->hrir_dirs_deg!=NULL)
558 return pData->hrir_dirs_deg[index*2+1];
559 else
560 return 0.0f;
561}
562
563int binauraliser_getHRIRlength(void* const hBin)
564{
565 binauraliser_data *pData = (binauraliser_data*)(hBin);
566 return pData->hrir_loaded_len;
567}
568
570{
571 binauraliser_data *pData = (binauraliser_data*)(hBin);
572 return pData->hrir_loaded_fs;
573}
574
576{
577 binauraliser_data *pData = (binauraliser_data*)(hBin);
578 return pData->useDefaultHRIRsFLAG;
579}
580
581char* binauraliser_getSofaFilePath(void* const hBin)
582{
583 binauraliser_data *pData = (binauraliser_data*)(hBin);
584 if(pData->sofa_filepath!=NULL)
585 return pData->sofa_filepath;
586 else
587 return "/Spatial_Audio_Framework/Default";
588}
589
591{
592 binauraliser_data *pData = (binauraliser_data*)(hBin);
593 return pData->enableHRIRsDiffuseEQ;
594}
595
596int binauraliser_getDAWsamplerate(void* const hBin)
597{
598 binauraliser_data *pData = (binauraliser_data*)(hBin);
599 return pData->fs;
600}
601
603{
604 binauraliser_data *pData = (binauraliser_data*)(hBin);
605 return pData->enableRotation;
606}
607
608float binauraliser_getYaw(void* const hBin)
609{
610 binauraliser_data *pData = (binauraliser_data*)(hBin);
611 return pData->bFlipYaw == 1 ? -RAD2DEG(pData->yaw) : RAD2DEG(pData->yaw);
612}
613
614float binauraliser_getPitch(void* const hBin)
615{
616 binauraliser_data *pData = (binauraliser_data*)(hBin);
617 return pData->bFlipPitch == 1 ? -RAD2DEG(pData->pitch) : RAD2DEG(pData->pitch);
618}
619
620float binauraliser_getRoll(void* const hBin)
621{
622 binauraliser_data *pData = (binauraliser_data*)(hBin);
623 return pData->bFlipRoll == 1 ? -RAD2DEG(pData->roll) : RAD2DEG(pData->roll);
624}
625
626int binauraliser_getFlipYaw(void* const hBin)
627{
628 binauraliser_data *pData = (binauraliser_data*)(hBin);
629 return pData->bFlipYaw;
630}
631
632int binauraliser_getFlipPitch(void* const hBin)
633{
634 binauraliser_data *pData = (binauraliser_data*)(hBin);
635 return pData->bFlipPitch;
636}
637
638int binauraliser_getFlipRoll(void* const hBin)
639{
640 binauraliser_data *pData = (binauraliser_data*)(hBin);
641 return pData->bFlipRoll;
642}
643
644int binauraliser_getRPYflag(void* const hBin)
645{
646 binauraliser_data *pData = (binauraliser_data*)(hBin);
647 return pData->useRollPitchYawFlag;
648}
649
650int binauraliser_getInterpMode(void* const hBin)
651{
652 binauraliser_data *pData = (binauraliser_data*)(hBin);
653 return (int)pData->interpMode;
654}
655
657{
658 return 12*HOP_SIZE;
659}
#define MAX_NUM_INPUTS
Maximum number of input channels supported.
Definition _common.h:237
#define PROGRESSBARTEXT_CHAR_LENGTH
Length of progress bar string.
Definition _common.h:231
@ PROC_STATUS_ONGOING
Codec is processing input audio, and should not be reinitialised at this time.
Definition _common.h:224
@ PROC_STATUS_NOT_ONGOING
Codec is not processing input audio, and may be reinitialised if needed.
Definition _common.h:226
CODEC_STATUS
Current status of the codec.
Definition _common.h:205
@ CODEC_STATUS_NOT_INITIALISED
Codec has not yet been initialised, or the codec configuration has changed.
Definition _common.h:208
@ CODEC_STATUS_INITIALISED
Codec is initialised and ready to process input audio.
Definition _common.h:206
@ CODEC_STATUS_INITIALISING
Codec is currently being initialised, input audio should not be processed.
Definition _common.h:211
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_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)
int binauraliser_getMaxNumSources(void)
Returns the maximum number of input sources supported by binauraliser.
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_getProcessingDelay(void)
Returns the processing delay in samples (may be used for delay compensation purposes)
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,...
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_loadPreset(SOURCE_CONFIG_PRESETS preset, _Atomic_FLOAT32 dirs_deg[MAX_NUM_INPUTS][2], _Atomic_INT32 *newNCH, int *nDims)
Returns the source directions for a specified source config preset.
void binauraliser_setCodecStatus(void *const hBin, CODEC_STATUS newStatus)
Sets codec status (see CODEC_STATUS enum)
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
_Atomic_INT32 hrir_loaded_fs
sampling rate of the loaded HRIRs
_Atomic_INT32 reInitHRTFsAndGainTables
1: reinitialise the HRTFs and interpolation tables, 0: do not
_Atomic_FLOAT32 yaw
yaw (Euler) rotation angle, in degrees
_Atomic_FLOAT32 src_gains[MAX_NUM_INPUTS]
Gains applied per source.
_Atomic_INT32 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
float * hrtf_vbap_gtableComp
N_hrtf_vbap_gtable x 3.
_Atomic_INT32 enableHRIRsDiffuseEQ
flag to diffuse-field equalisation to the currently loaded HRTFs
_Atomic_INT32 bFlipPitch
flag to flip the sign of the pitch rotation angle
_Atomic_INT32 useRollPitchYawFlag
rotation order flag, 1: r-p-y, 0: y-p-r
float src_dirs_rot_xyz[MAX_NUM_INPUTS][3]
Intermediate rotated source directions, as unit-length Cartesian coordinates.
_Atomic_INT32 hrir_runtime_fs
sampling rate of the HRIRs being used for processing (after any resampling)
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_complex hrtf_interp[MAX_NUM_INPUTS][HYBRID_BANDS][NUM_EARS]
Interpolated HRTFs.
_Atomic_INTERP_MODES interpMode
see INTERP_MODES
float * hrir_dirs_deg
directions of the HRIRs in degrees [azi elev]; FLAT: N_hrir_dirs x 2
_Atomic_FLOAT32 src_dirs_deg[MAX_NUM_INPUTS][2]
Current source/panning directions, in degrees.
_Atomic_FLOAT32 fs
Host sampling rate, in Hz.
float * weights
Integration weights for the HRIR measurement grid; N_hrir_dirs x 1.
_Atomic_INT32 bFlipYaw
flag to flip the sign of the yaw rotation angle
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
_Atomic_INT32 hrir_loaded_len
length of the loaded HRIRs, in samples
int * hrtf_vbap_gtableIdx
N_hrtf_vbap_gtable x 3.
_Atomic_FLOAT32 pitch
pitch (Euler) rotation angle, in degrees
_Atomic_FLOAT32 roll
roll (Euler) rotation angle, in degrees
_Atomic_INT32 enableRotation
1: enable rotation, 0: disable
char * progressBarText
Current (re)initialisation step, string.
void * hSTFT
afSTFT handle
_Atomic_INT32 recalc_hrtf_interpFLAG[MAX_NUM_INPUTS]
1: re-calculate/interpolate the HRTF, 0: do not
float * hrtf_fb_mag
magnitudes of the hrtf filterbank coefficients; nBands x nCH x N_hrirs
_Atomic_PROC_STATUS procStatus
see PROC_STATUS
_Atomic_FLOAT32 progressBar0_1
Current (re)initialisation progress, between [0..1].
_Atomic_INT32 bFlipRoll
flag to flip the sign of the roll rotation angle
_Atomic_INT32 N_hrir_dirs
number of HRIR directions in the current sofa file
_Atomic_INT32 hrir_runtime_len
length of the HRIRs being used for processing (after any resampling), in samples
_Atomic_INT32 useDefaultHRIRsFLAG
1: use default HRIRs in database, 0: use those from SOFA file
char * sofa_filepath
absolute/relevative file path for a sofa file
_Atomic_CODEC_STATUS codecStatus
see CODEC_STATUS
int nTriangles
Number of triangles in the convex hull of the spherical arrangement of HRIR directions/points.
float ** outframeTD
time-domain output frame; NUM_EARS x BINAURALISER_FRAME_SIZE
float freqVector[HYBRID_BANDS]
Frequency vector (filterbank centre frequencies)
_Atomic_INT32 new_nSources
New number of input/source signals (current value will be replaced by this after next re-init)
_Atomic_INT32 nSources
Current number of input/source signals.