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)); /* must match binauraliser_defaultSourceDirections */
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;
49 pData->interpMode = INTERP_TRI;
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->firstInit = 1;
63 pData->inputFrameTD = (float**)malloc2d(MAX_NUM_INPUTS, BINAURALISER_FRAME_SIZE, sizeof(float));
64 pData->outframeTD = (float**)malloc2d(NUM_EARS, BINAURALISER_FRAME_SIZE, sizeof(float));
65 pData->inputframeTF = (float_complex***)malloc3d(HYBRID_BANDS, MAX_NUM_INPUTS, TIME_SLOTS, sizeof(float_complex));
66 pData->outputframeTF = (float_complex***)malloc3d(HYBRID_BANDS, NUM_EARS, TIME_SLOTS, sizeof(float_complex));
67
68 /* hrir data */
69 pData->hrirs = NULL;
70 pData->hrir_dirs_deg = NULL;
71 pData->sofa_filepath = NULL;
72 pData->weights = NULL;
73 pData->N_hrir_dirs = pData->hrir_len = 0;
75
76 /* vbap (amplitude normalised) */
77 pData->hrtf_vbap_gtableIdx = NULL;
78 pData->hrtf_vbap_gtableComp = NULL;
79 pData->nTriangles = pData->N_hrtf_vbap_gtable = 0;
80
81 /* HRTF filterbank coefficients */
82 pData->itds_s = NULL;
83 pData->hrtf_fb = NULL;
84 pData->hrtf_fb_mag = NULL;
85
86 /* flags/status */
87 pData->progressBar0_1 = 0.0f;
89 strcpy(pData->progressBarText,"");
92 pData->reInitHRTFsAndGainTables = 1;
93 for(ch=0; ch<MAX_NUM_INPUTS; ch++) {
94 pData->recalc_hrtf_interpFLAG[ch] = 1;
95 pData->src_gains[ch] = 1.f;
96 }
97 pData->recalc_M_rotFLAG = 1;
98}
99
101(
102 void ** const phBin
103)
104{
105 binauraliser_data *pData = (binauraliser_data*)(*phBin);
106
107 if (pData != NULL) {
108 /* not safe to free memory during intialisation/processing loop */
109 while (pData->codecStatus == CODEC_STATUS_INITIALISING ||
111 SAF_SLEEP(10);
112 }
113
114 /* free afSTFT and buffers */
115 if(pData->hSTFT !=NULL)
116 afSTFT_destroy(&(pData->hSTFT));
117 free(pData->inputFrameTD);
118 free(pData->outframeTD);
119 free(pData->inputframeTF);
120 free(pData->outputframeTF);
121 free(pData->hrtf_vbap_gtableComp);
122 free(pData->hrtf_vbap_gtableIdx);
123 free(pData->hrtf_fb);
124 free(pData->hrtf_fb_mag);
125 free(pData->itds_s);
126 free(pData->sofa_filepath);
127 free(pData->hrirs);
128 free(pData->hrir_dirs_deg);
129 free(pData->weights);
130 free(pData->progressBarText);
131
132 free(pData);
133 pData = NULL;
134 *phBin = NULL;
135 }
136}
137
139(
140 void * const hBin,
141 int sampleRate
142)
143{
144 binauraliser_data *pData = (binauraliser_data*)(hBin);
145
146 /* define frequency vector */
147 pData->fs = sampleRate;
148 if(pData->fs != sampleRate || pData->firstInit){
149 pData->fs = sampleRate;
150 pData->reInitHRTFsAndGainTables = 1;
152 pData->firstInit = 0;
153 }
155 afSTFT_getCentreFreqs(pData->hSTFT, (float)sampleRate, HYBRID_BANDS, pData->freqVector);
156
157 /* defaults */
158 pData->recalc_M_rotFLAG = 1;
159}
160
162(
163 void* const hBin
164)
165{
166 binauraliser_data *pData = (binauraliser_data*)(hBin);
167
169 return; /* re-init not required, or already happening */
170 while (pData->procStatus == PROC_STATUS_ONGOING){
171 /* re-init required, but we need to wait for the current processing loop to end */
172 pData->codecStatus = CODEC_STATUS_INITIALISING; /* indicate that we want to init */
173 SAF_SLEEP(10);
174 }
175
176 /* for progress bar */
178 strcpy(pData->progressBarText,"Initialising");
179 pData->progressBar0_1 = 0.0f;
180
181 /* check if TFT needs to be reinitialised */
183
184 /* reinit HRTFs and interpolation tables */
185 if(pData->reInitHRTFsAndGainTables){
187 pData->reInitHRTFsAndGainTables = 0;
188 }
189
190 /* done! */
191 strcpy(pData->progressBarText,"Done!");
192 pData->progressBar0_1 = 1.0f;
194
195}
196
198(
199 void * const hBin,
200 const float *const * inputs,
201 float* const* const outputs,
202 int nInputs,
203 int nOutputs,
204 int nSamples
205)
206{
207 binauraliser_data *pData = (binauraliser_data*)(hBin);
208 int ch, ear, i, band, nSources;
209 float Rxyz[3][3], hypotxy, temp_gain;
210 int enableRotation;
211
212 /* copy user parameters to local variables */
213 nSources = pData->nSources;
214 enableRotation = pData->enableRotation;
215
216 /* apply binaural panner */
217 if ((nSamples == BINAURALISER_FRAME_SIZE) && (pData->codecStatus==CODEC_STATUS_INITIALISED) && (pData->hrtf_fb!=NULL) ){
219
220 /* Load time-domain data */
221 for(i=0; i < SAF_MIN(nSources,nInputs); i++)
223 for(; i<nSources; i++)
224 memset(pData->inputFrameTD[i], 0, BINAURALISER_FRAME_SIZE * sizeof(float));
225
226 /* Apply source gains */
227 for (ch = 0; ch < nSources; ch++) {
228 if(fabsf(pData->src_gains[ch] - 1.f) > 1e-6f){
229 temp_gain = pData->src_gains[ch];
230 utility_svsmul(pData->inputFrameTD[ch], &temp_gain, BINAURALISER_FRAME_SIZE, NULL);
231 }
232 }
233
234 /* Apply time-frequency transform (TFT) */
236
237 /* Rotate source directions */
238 if(enableRotation && pData->recalc_M_rotFLAG){
239 yawPitchRoll2Rzyx (pData->yaw, pData->pitch, pData->roll, pData->useRollPitchYawFlag, Rxyz);
240 for(i=0; i<nSources; i++){
241 pData->src_dirs_xyz[i][0] = cosf(DEG2RAD(pData->src_dirs_deg[i][1])) * cosf(DEG2RAD(pData->src_dirs_deg[i][0]));
242 pData->src_dirs_xyz[i][1] = cosf(DEG2RAD(pData->src_dirs_deg[i][1])) * sinf(DEG2RAD(pData->src_dirs_deg[i][0]));
243 pData->src_dirs_xyz[i][2] = sinf(DEG2RAD(pData->src_dirs_deg[i][1]));
244 pData->recalc_hrtf_interpFLAG[i] = 1;
245 }
246 cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, nSources, 3, 3, 1.0f,
247 (float*)(pData->src_dirs_xyz), 3,
248 (float*)Rxyz, 3, 0.0f,
249 (float*)(pData->src_dirs_rot_xyz), 3);
250 for(i=0; i<nSources; i++){
251 hypotxy = sqrtf(powf(pData->src_dirs_rot_xyz[i][0], 2.0f) + powf(pData->src_dirs_rot_xyz[i][1], 2.0f));
252 pData->src_dirs_rot_deg[i][0] = RAD2DEG(atan2f(pData->src_dirs_rot_xyz[i][1], pData->src_dirs_rot_xyz[i][0]));
253 pData->src_dirs_rot_deg[i][1] = RAD2DEG(atan2f(pData->src_dirs_rot_xyz[i][2], hypotxy));
254 }
255 pData->recalc_M_rotFLAG = 0;
256 }
257
258 /* interpolate hrtfs and apply to each source */
259 memset(FLATTEN3D(pData->outputframeTF), 0, HYBRID_BANDS*NUM_EARS*TIME_SLOTS * sizeof(float_complex));
260 for (ch = 0; ch < nSources; ch++) {
261 if(pData->recalc_hrtf_interpFLAG[ch]){
262 if(enableRotation)
263 binauraliser_interpHRTFs(hBin, pData->interpMode, pData->src_dirs_rot_deg[ch][0], pData->src_dirs_rot_deg[ch][1], pData->hrtf_interp[ch]);
264 else
265 binauraliser_interpHRTFs(hBin, pData->interpMode, pData->src_dirs_deg[ch][0], pData->src_dirs_deg[ch][1], pData->hrtf_interp[ch]);
266 pData->recalc_hrtf_interpFLAG[ch] = 0;
267 }
268
269 /* Convolve this channel with the interpolated HRTF, and add it to the binaural buffer */
270 for (band = 0; band < HYBRID_BANDS; band++)
271 for (ear = 0; ear < NUM_EARS; ear++)
272 cblas_caxpy(TIME_SLOTS, &pData->hrtf_interp[ch][band][ear], pData->inputframeTF[band][ch], 1, pData->outputframeTF[band][ear], 1);
273 }
274
275 /* scale by number of sources */
276 cblas_sscal(/*re+im*/2*HYBRID_BANDS*NUM_EARS*TIME_SLOTS, 1.0f/sqrtf((float)nSources), (float*)FLATTEN3D(pData->outputframeTF), 1);
277
278 /* inverse-TFT */
280
281 /* Copy to output buffer */
282 for (ch = 0; ch < SAF_MIN(NUM_EARS, nOutputs); ch++)
283 utility_svvcopy(pData->outframeTD[ch], BINAURALISER_FRAME_SIZE, outputs[ch]);
284 for (; ch < nOutputs; ch++)
285 memset(outputs[ch], 0, BINAURALISER_FRAME_SIZE*sizeof(float));
286 }
287 else{
288 for (ch=0; ch < nOutputs; ch++)
289 memset(outputs[ch],0, BINAURALISER_FRAME_SIZE*sizeof(float));
290 }
291
293}
294
295/* Set Functions */
296
297void binauraliser_refreshSettings(void* const hBin)
298{
299 binauraliser_data *pData = (binauraliser_data*)(hBin);
300 int ch;
301 pData->reInitHRTFsAndGainTables = 1;
302 for(ch=0; ch<MAX_NUM_INPUTS; ch++)
303 pData->recalc_hrtf_interpFLAG[ch] = 1;
305}
306
307void binauraliser_setSourceAzi_deg(void* const hBin, int index, float newAzi_deg)
308{
309 binauraliser_data *pData = (binauraliser_data*)(hBin);
310 if(newAzi_deg>180.0f)
311 newAzi_deg = -360.0f + newAzi_deg;
312 newAzi_deg = SAF_MAX(newAzi_deg, -180.0f);
313 newAzi_deg = SAF_MIN(newAzi_deg, 180.0f);
314 if(pData->src_dirs_deg[index][0]!=newAzi_deg){
315 pData->src_dirs_deg[index][0] = newAzi_deg;
316 pData->recalc_hrtf_interpFLAG[index] = 1;
317 pData->recalc_M_rotFLAG = 1;
318 }
319}
320
321void binauraliser_setSourceElev_deg(void* const hBin, int index, float newElev_deg)
322{
323 binauraliser_data *pData = (binauraliser_data*)(hBin);
324 newElev_deg = SAF_MAX(newElev_deg, -90.0f);
325 newElev_deg = SAF_MIN(newElev_deg, 90.0f);
326 if(pData->src_dirs_deg[index][1] != newElev_deg){
327 pData->src_dirs_deg[index][1] = newElev_deg;
328 pData->recalc_hrtf_interpFLAG[index] = 1;
329 pData->recalc_M_rotFLAG = 1;
330 }
331}
332
333void binauraliser_setNumSources(void* const hBin, int new_nSources)
334{
335 binauraliser_data *pData = (binauraliser_data*)(hBin);
336 pData->new_nSources = SAF_CLAMP(new_nSources, 1, MAX_NUM_INPUTS);
337 pData->recalc_M_rotFLAG = 1;
339}
340
341void binauraliser_setUseDefaultHRIRsflag(void* const hBin, int newState)
342{
343 binauraliser_data *pData = (binauraliser_data*)(hBin);
344 if((!pData->useDefaultHRIRsFLAG) && (newState)){
345 pData->useDefaultHRIRsFLAG = newState;
346 binauraliser_refreshSettings(hBin); // re-init and re-calc
347 }
348}
349
350void binauraliser_setSofaFilePath(void* const hBin, const char* path)
351{
352 binauraliser_data *pData = (binauraliser_data*)(hBin);
353
354 pData->sofa_filepath = realloc1d(pData->sofa_filepath, strlen(path) + 1);
355 strcpy(pData->sofa_filepath, path);
356 pData->useDefaultHRIRsFLAG = 0;
357 binauraliser_refreshSettings(hBin); // re-init and re-calc
358}
359
360void binauraliser_setEnableHRIRsDiffuseEQ(void* const hBin, int newState)
361{
362 binauraliser_data *pData = (binauraliser_data*)(hBin);
363 if(newState!=pData->enableHRIRsDiffuseEQ){
364 pData->enableHRIRsDiffuseEQ = newState;
365 binauraliser_refreshSettings(hBin); // re-init and re-calc
366 }
367}
368
369void binauraliser_setInputConfigPreset(void* const hBin, int newPresetID)
370{
371 binauraliser_data *pData = (binauraliser_data*)(hBin);
372 int ch, dummy;
373
374 binauraliser_loadPreset(newPresetID, pData->src_dirs_deg, &(pData->new_nSources), &(dummy));
375 if(pData->nSources != pData->new_nSources)
377 for(ch=0; ch<MAX_NUM_INPUTS; ch++)
378 pData->recalc_hrtf_interpFLAG[ch] = 1;
379 pData->recalc_M_rotFLAG = 1;
380}
381
382void binauraliser_setEnableRotation(void* const hBin, int newState)
383{
384 binauraliser_data *pData = (binauraliser_data*)(hBin);
385 int ch;
386
387 pData->enableRotation = newState;
388 if(!pData->enableRotation)
389 for (ch = 0; ch<MAX_NUM_INPUTS; ch++)
390 pData->recalc_hrtf_interpFLAG[ch] = 1;
391 pData->recalc_M_rotFLAG = 1;
392}
393
394void binauraliser_setYaw(void * const hBin, float newYaw)
395{
396 binauraliser_data *pData = (binauraliser_data*)(hBin);
397 pData->yaw = pData->bFlipYaw == 1 ? -DEG2RAD(newYaw) : DEG2RAD(newYaw);
398 pData->recalc_M_rotFLAG = 1;
399}
400
401void binauraliser_setPitch(void* const hBin, float newPitch)
402{
403 binauraliser_data *pData = (binauraliser_data*)(hBin);
404 pData->pitch = pData->bFlipPitch == 1 ? -DEG2RAD(newPitch) : DEG2RAD(newPitch);
405 pData->recalc_M_rotFLAG = 1;
406}
407
408void binauraliser_setRoll(void* const hBin, float newRoll)
409{
410 binauraliser_data *pData = (binauraliser_data*)(hBin);
411 pData->roll = pData->bFlipRoll == 1 ? -DEG2RAD(newRoll) : DEG2RAD(newRoll);
412 pData->recalc_M_rotFLAG = 1;
413}
414
415void binauraliser_setFlipYaw(void* const hBin, int newState)
416{
417 binauraliser_data *pData = (binauraliser_data*)(hBin);
418 if(newState !=pData->bFlipYaw ){
419 pData->bFlipYaw = newState;
421 }
422}
423
424void binauraliser_setFlipPitch(void* const hBin, int newState)
425{
426 binauraliser_data *pData = (binauraliser_data*)(hBin);
427 if(newState !=pData->bFlipPitch ){
428 pData->bFlipPitch = newState;
430 }
431}
432
433void binauraliser_setFlipRoll(void* const hBin, int newState)
434{
435 binauraliser_data *pData = (binauraliser_data*)(hBin);
436 if(newState !=pData->bFlipRoll ){
437 pData->bFlipRoll = newState;
439 }
440}
441
442void binauraliser_setRPYflag(void* const hBin, int newState)
443{
444 binauraliser_data *pData = (binauraliser_data*)(hBin);
445 pData->useRollPitchYawFlag = newState;
446 pData->recalc_M_rotFLAG = 1;
447}
448
449void binauraliser_setInterpMode(void* const hBin, int newMode)
450{
451 binauraliser_data *pData = (binauraliser_data*)(hBin);
452 int ch;
453 pData->interpMode = newMode;
454 for(ch=0; ch<MAX_NUM_INPUTS; ch++)
455 pData->recalc_hrtf_interpFLAG[ch] = 1;
456}
457
458void binauraliser_setSourceGain(void* const hAmbi, int srcIdx, float newGain)
459{
460 binauraliser_data *pData = (binauraliser_data*)(hAmbi);
461 pData->src_gains[srcIdx] = newGain;
462}
463
464void binauraliser_setSourceSolo(void* const hAmbi, int srcIdx)
465{
466 binauraliser_data *pData = (binauraliser_data*)(hAmbi);
467 int i;
468 for(i=0; i<pData->nSources; i++){
469 if(i==srcIdx)
470 pData->src_gains[i] = 1.f;
471 else
472 pData->src_gains[i] = 0.f;
473 }
474}
475
476void binauraliser_setUnSolo(void* const hAmbi)
477{
478 binauraliser_data *pData = (binauraliser_data*)(hAmbi);
479 for(int i=0; i<pData->nSources; i++)
480 pData->src_gains[i] = 1.f;
481}
482
483
484/* Get Functions */
485
490
492{
493 binauraliser_data *pData = (binauraliser_data*)(hBin);
494 return pData->codecStatus;
495}
496
497float binauraliser_getProgressBar0_1(void* const hBin)
498{
499 binauraliser_data *pData = (binauraliser_data*)(hBin);
500 return pData->progressBar0_1;
501}
502
503void binauraliser_getProgressBarText(void* const hBin, char* text)
504{
505 binauraliser_data *pData = (binauraliser_data*)(hBin);
506 memcpy(text, pData->progressBarText, PROGRESSBARTEXT_CHAR_LENGTH*sizeof(char));
507}
508
509float binauraliser_getSourceAzi_deg(void* const hBin, int index)
510{
511 binauraliser_data *pData = (binauraliser_data*)(hBin);
512 return pData->src_dirs_deg[index][0];
513}
514
515float binauraliser_getSourceElev_deg(void* const hBin, int index)
516{
517 binauraliser_data *pData = (binauraliser_data*)(hBin);
518 return pData->src_dirs_deg[index][1];
519}
520
521int binauraliser_getNumSources(void* const hBin)
522{
523 binauraliser_data *pData = (binauraliser_data*)(hBin);
524 return pData->new_nSources;
525}
526
528{
529 return MAX_NUM_INPUTS;
530}
531
533{
534 return NUM_EARS;
535}
536
537int binauraliser_getNDirs(void* const hBin)
538{
539 binauraliser_data *pData = (binauraliser_data*)(hBin);
540 return pData->N_hrir_dirs;
541}
542
543int binauraliser_getNTriangles(void* const hBin)
544{
545 binauraliser_data *pData = (binauraliser_data*)(hBin);
546 return pData->nTriangles;
547}
548
549float binauraliser_getHRIRAzi_deg(void* const hBin, int index)
550{
551 binauraliser_data *pData = (binauraliser_data*)(hBin);
552 if(!pData->reInitHRTFsAndGainTables && pData->hrir_dirs_deg!=NULL)
553 return pData->hrir_dirs_deg[index*2+0];
554 else
555 return 0.0f;
556}
557
558float binauraliser_getHRIRElev_deg(void* const hBin, int index)
559{
560 binauraliser_data *pData = (binauraliser_data*)(hBin);
561 if(!pData->reInitHRTFsAndGainTables && pData->hrir_dirs_deg!=NULL)
562 return pData->hrir_dirs_deg[index*2+1];
563 else
564 return 0.0f;
565}
566
567int binauraliser_getHRIRlength(void* const hBin)
568{
569 binauraliser_data *pData = (binauraliser_data*)(hBin);
570 return pData->hrir_len;
571}
572
574{
575 binauraliser_data *pData = (binauraliser_data*)(hBin);
576 return pData->hrir_orig_fs;
577}
578
580{
581 binauraliser_data *pData = (binauraliser_data*)(hBin);
582 return pData->useDefaultHRIRsFLAG;
583}
584
585char* binauraliser_getSofaFilePath(void* const hBin)
586{
587 binauraliser_data *pData = (binauraliser_data*)(hBin);
588 if(pData->sofa_filepath!=NULL)
589 return pData->sofa_filepath;
590 else
591 return "/Spatial_Audio_Framework/Default";
592}
593
595{
596 binauraliser_data *pData = (binauraliser_data*)(hBin);
597 return pData->enableHRIRsDiffuseEQ;
598}
599
600int binauraliser_getDAWsamplerate(void* const hBin)
601{
602 binauraliser_data *pData = (binauraliser_data*)(hBin);
603 return pData->fs;
604}
605
607{
608 binauraliser_data *pData = (binauraliser_data*)(hBin);
609 return pData->enableRotation;
610}
611
612float binauraliser_getYaw(void* const hBin)
613{
614 binauraliser_data *pData = (binauraliser_data*)(hBin);
615 return pData->bFlipYaw == 1 ? -RAD2DEG(pData->yaw) : RAD2DEG(pData->yaw);
616}
617
618float binauraliser_getPitch(void* const hBin)
619{
620 binauraliser_data *pData = (binauraliser_data*)(hBin);
621 return pData->bFlipPitch == 1 ? -RAD2DEG(pData->pitch) : RAD2DEG(pData->pitch);
622}
623
624float binauraliser_getRoll(void* const hBin)
625{
626 binauraliser_data *pData = (binauraliser_data*)(hBin);
627 return pData->bFlipRoll == 1 ? -RAD2DEG(pData->roll) : RAD2DEG(pData->roll);
628}
629
630int binauraliser_getFlipYaw(void* const hBin)
631{
632 binauraliser_data *pData = (binauraliser_data*)(hBin);
633 return pData->bFlipYaw;
634}
635
636int binauraliser_getFlipPitch(void* const hBin)
637{
638 binauraliser_data *pData = (binauraliser_data*)(hBin);
639 return pData->bFlipPitch;
640}
641
642int binauraliser_getFlipRoll(void* const hBin)
643{
644 binauraliser_data *pData = (binauraliser_data*)(hBin);
645 return pData->bFlipRoll;
646}
647
648int binauraliser_getRPYflag(void* const hBin)
649{
650 binauraliser_data *pData = (binauraliser_data*)(hBin);
651 return pData->useRollPitchYawFlag;
652}
653
654int binauraliser_getInterpMode(void* const hBin)
655{
656 binauraliser_data *pData = (binauraliser_data*)(hBin);
657 return (int)pData->interpMode;
658}
659
661{
662 return 12*HOP_SIZE;
663}
#define MAX_NUM_INPUTS
Maximum number of input channels supported.
Definition _common.h:261
#define PROGRESSBARTEXT_CHAR_LENGTH
Length of progress bar string.
Definition _common.h:255
@ PROC_STATUS_ONGOING
Codec is processing input audio, and should not be reinitialised at this time.
Definition _common.h:248
@ PROC_STATUS_NOT_ONGOING
Codec is not processing input audio, and may be reinitialised if needed.
Definition _common.h:250
CODEC_STATUS
Current status of the codec.
Definition _common.h:229
@ CODEC_STATUS_NOT_INITIALISED
Codec has not yet been initialised, or the codec configuration has changed.
Definition _common.h:232
@ CODEC_STATUS_INITIALISED
Codec is initialised and ready to process input audio.
Definition _common.h:230
@ CODEC_STATUS_INITIALISING
Codec is currently being initialised, input audio should not be processed.
Definition _common.h:235
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
Triangular interpolation.
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.
const int __default_hrir_fs
The samplerate used to measure the default HRIR filters.
#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 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
_Atomic_INT32 hrir_len
length of the loaded HRIRs, in samples
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.
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
int * hrtf_vbap_gtableIdx
N_hrtf_vbap_gtable x 3.
_Atomic_FLOAT32 pitch
pitch (Euler) rotation angle, in degrees
int firstInit
flag, 1: _init() function has never been called, 0: _init() function has been called
_Atomic_FLOAT32 roll
roll (Euler) rotation angle, in degrees
_Atomic_INT32 enableRotation
1: enable rotation, 0: disable
_Atomic_INT32 hrir_orig_fs
Can be different from hrir_fs if HRIRs were resampled.
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 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.