SAF
Loading...
Searching...
No Matches
binauraliser_nf.c
Go to the documentation of this file.
1/*
2 * Copyright 2022 Michael McCrea, 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
40
41void binauraliserNF_create /* FREQUENCY DOMAIN version */
42(
43 void ** const phBin
44)
45{
47 *phBin = (void*)pData;
48 int nDim; // nDim not actually used
49
50 /* user parameters */
51 pData->useDefaultHRIRsFLAG = 1; /* pars->sofa_filepath must be valid to set this to 0 */
52 pData->enableHRIRsDiffuseEQ = 1;
53 pData->nSources = pData->new_nSources;
55 pData->yaw = 0.0f;
56 pData->pitch = 0.0f;
57 pData->roll = 0.0f;
58 pData->bFlipYaw = 0;
59 pData->bFlipPitch = 0;
60 pData->bFlipRoll = 0;
61 pData->useRollPitchYawFlag = 0;
62 pData->enableRotation = 0;
63
64 /* Near field DVF settings
65 * Head radius is set according to the linear combination of head width,
66 * height and depth from:
67 * Algazi VR, Avendano C, Duda RO. Estimation of a spherical-head model
68 * from anthropometry. J Audio Eng Soc 2001; 49(6):472-9.
69 * The far field threshold is set by rho (normalized distance) = 34, resulting
70 * in a ~3 m far field, where the max DVF filter response is about +/-0.5 dB.
71 * Near field limit set where filters are stable, in meters from head _center_.
72 */
73 pData->head_radius = 0.09096; /* Should match a_head in in saf_utility_dvf.c */
74 pData->head_radius_recip = 1.f / pData->head_radius;
75 pData->farfield_thresh_m = pData->head_radius * 34.f;
76 pData->farfield_headroom = 1.05f; /* 5% headroom above the far field threshold, for resetting to far field and UI range */
77 pData->nearfield_limit_m = 0.15f;
78
79 /* Set default source directions and distances */
80 binauraliser_loadPreset(SOURCE_CONFIG_PRESET_DEFAULT, pData->src_dirs_deg, &(pData->new_nSources), &nDim); /* check setStateInformation if you change default preset */
81 /* For now, any preset selected will reset sources to the far field */
82 binauraliserNF_resetSourceDistances(pData); /* Must be called after pData->farfield_thresh_m is set */
83
84 /* time-frequency transform + buffers */
85 pData->hSTFT = NULL;
86 /* hrir data */
87 pData->hrirs = NULL;
88 pData->hrir_dirs_deg = NULL;
89 pData->sofa_filepath = NULL;
90 pData->weights = NULL;
91 pData->N_hrir_dirs = pData->hrir_loaded_len = pData->hrir_runtime_len = 0;
92 pData->hrir_loaded_fs = pData->hrir_runtime_fs = -1; /* unknown */
93
94 /* time domain buffers */
95 pData->fs = 48000.0f;
96 pData->inputFrameTD = (float**)malloc2d(MAX_NUM_INPUTS, BINAURALISER_FRAME_SIZE, sizeof(float));
97 pData->outframeTD = (float**)malloc2d(NUM_EARS, BINAURALISER_FRAME_SIZE, sizeof(float));
98 pData->inputframeTF = (float_complex***)malloc3d(HYBRID_BANDS, MAX_NUM_INPUTS, TIME_SLOTS, sizeof(float_complex));
99 pData->outputframeTF = (float_complex***)malloc3d(HYBRID_BANDS, NUM_EARS, TIME_SLOTS, sizeof(float_complex));
100
101 /* vbap (amplitude normalised) */
102 pData->hrtf_vbap_gtableIdx = NULL;
103 pData->hrtf_vbap_gtableComp = NULL;
104 pData->nTriangles = pData->N_hrtf_vbap_gtable = 0;
105
106 /* HRTF filterbank coefficients */
107 pData->itds_s = NULL;
108 pData->hrtf_fb = NULL;
109 pData->hrtf_fb_mag = NULL;
110
111 /* Initialize DVF filter parameters */
112 memset(FLATTEN3D(pData->dvfmags), 1.f, MAX_NUM_INPUTS * NUM_EARS * HYBRID_BANDS * sizeof(float));
113 memset(FLATTEN3D(pData->dvfphases), 0.f, MAX_NUM_INPUTS * NUM_EARS * HYBRID_BANDS * sizeof(float));
114 memset(FLATTEN3D(pData->b_dvf), 0.f, MAX_NUM_INPUTS * NUM_EARS * 2 * sizeof(float));
115 memset(FLATTEN3D(pData->a_dvf), 0.f, MAX_NUM_INPUTS * NUM_EARS * 2 * sizeof(float));
116 for(int ch = 0; ch < MAX_NUM_INPUTS; ch++) {
117 for(int ear = 0; ear < NUM_EARS; ear++) {
118 pData->a_dvf[ch][ear][0] = 1.f; /* a_0 = 1.0, always */
119 }
120 }
121
122 /* flags/status */
123 pData->progressBar0_1 = 0.0f;
125 strcpy(pData->progressBarText, "");
128 pData->reInitHRTFsAndGainTables = 1;
129 for(int ch = 0; ch < MAX_NUM_INPUTS; ch++) {
130 pData->recalc_hrtf_interpFLAG[ch] = 1;
131 pData->recalc_dvfCoeffFLAG[ch] = 1;
132 pData->src_gains[ch] = 1.f;
133 }
134 pData->recalc_M_rotFLAG = 1;
135
136 pData->src_dirs_cur = pData->src_dirs_deg;
137}
138
140(
141 void ** const phBin
142)
143{
144 binauraliserNF_data *pData = (binauraliserNF_data*)(*phBin);
145
146 if (pData != NULL) {
147 /* not safe to free memory during intialisation/processing loop */
148 while (pData->codecStatus == CODEC_STATUS_INITIALISING ||
150 SAF_SLEEP(10);
151 }
152
153 if(pData->hSTFT !=NULL)
154 afSTFT_destroy(&(pData->hSTFT));
155 free(pData->inputFrameTD);
156 free(pData->outframeTD);
157 free(pData->inputframeTF);
158 free(pData->outputframeTF);
159 free(pData->hrtf_vbap_gtableComp);
160 free(pData->hrtf_vbap_gtableIdx);
161 free(pData->hrtf_fb);
162 free(pData->hrtf_fb_mag);
163 free(pData->itds_s);
164 free(pData->hrirs);
165 free(pData->hrir_dirs_deg);
166 free(pData->weights);
167 free(pData->progressBarText);
168
169 free(pData);
170 pData = NULL;
171 *phBin = NULL;
172 }
173}
174
176(
177 void * const hBin, int sampleRate
178)
179{
180 binauraliser_init(hBin, sampleRate);
181}
182
183/* NOTE: This function is a copy of binauraliser_initCodec.
184 * The only difference is that it calls binauraliserNF_initTFT, which needs
185 * new_nSources * NUM_EARS output channels in the afSTFT. This function could
186 * be omitted if binauraliser_initTFT could be refactored to set its number
187 * of outputs differently for the regular and NF version of the binauraliser,
188 * e.g. a member var afSTFT_nOuts, which changes when binauraliser_setNumSources
189 * is called. */
191(
192 void* const hBin
193)
194{
195 binauraliser_data *pData = (binauraliser_data*)(hBin);
196
198 return; /* re-init not required, or already happening */
199 while (pData->procStatus == PROC_STATUS_ONGOING){
200 /* re-init required, but we need to wait for the current processing loop to end */
201 pData->codecStatus = CODEC_STATUS_INITIALISING; /* indicate that we want to init */
202 SAF_SLEEP(10);
203 }
204
205 /* for progress bar */
207 strcpy(pData->progressBarText,"Initialising");
208 pData->progressBar0_1 = 0.0f;
209
210 /* check if TFT needs to be reinitialised */
211 // use binauraliser_initTFT() Freq-domain DVF, binauraliserNF_initTFT() for Time-domain DVF
213
214 /* reinit HRTFs and interpolation tables */
215 if(pData->reInitHRTFsAndGainTables){
217 pData->reInitHRTFsAndGainTables = 0;
218 }
219
220 /* done! */
221 strcpy(pData->progressBarText,"Done!");
222 pData->progressBar0_1 = 1.0f;
224}
225
226void binauraliserNF_process /* FREQ DOMAIN version */
227(
228 void * const hBin,
229 const float *const * inputs,
230 float* const* const outputs,
231 int nInputs,
232 int nOutputs,
233 int nSamples
234)
235{
237 int ch, ear, i, band, nSources, enableRotation;
238 float hypotxy, headRadiusRecip, fs, ffThresh, rho;
239 float Rxyz[3][3];
240 float alphaLR[2] = { 0.0, 0.0 };
241
242 /* copy user parameters to local variables */
243 nSources = pData->nSources;
244 enableRotation = pData->enableRotation;
245 headRadiusRecip = pData->head_radius_recip;
246 ffThresh = pData->farfield_thresh_m;
247 fs = (float)pData->fs;
248
249 /* apply binaural panner */
250 if ((nSamples == BINAURALISER_FRAME_SIZE) && (pData->hrtf_fb!=NULL) && (pData->codecStatus==CODEC_STATUS_INITIALISED) ) {
252
253 /* Load time-domain data */
254 for (i = 0; i < SAF_MIN(nSources, nInputs); i++)
256 for (; i < nSources; i++)
257 memset(pData->inputFrameTD[i], 0, BINAURALISER_FRAME_SIZE * sizeof(float));
258
259 /* Apply source gains */
260 for (ch = 0; ch < nSources; ch++) {
261 if(fabsf(pData->src_gains[ch] - 1.f) > 1e-6f)
262 utility_svsmul(pData->inputFrameTD[ch], &(pData->src_gains[ch]), BINAURALISER_FRAME_SIZE, NULL);
263 }
264
265 /* Apply time-frequency transform (TFT) */
267
268 /* Rotate source directions */
269 if (enableRotation && pData->recalc_M_rotFLAG) {
270 yawPitchRoll2Rzyx (pData->yaw, pData->pitch, pData->roll, pData->useRollPitchYawFlag, Rxyz);
271 for(i = 0; i < nSources; i++){
272 pData->src_dirs_xyz[i][0] = cosf(DEG2RAD(pData->src_dirs_deg[i][1])) * cosf(DEG2RAD(pData->src_dirs_deg[i][0]));
273 pData->src_dirs_xyz[i][1] = cosf(DEG2RAD(pData->src_dirs_deg[i][1])) * sinf(DEG2RAD(pData->src_dirs_deg[i][0]));
274 pData->src_dirs_xyz[i][2] = sinf(DEG2RAD(pData->src_dirs_deg[i][1]));
275 pData->recalc_hrtf_interpFLAG[i] = 1;
276 }
277 cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, nSources, 3, 3, 1.0f,
278 (float*)(pData->src_dirs_xyz), 3,
279 (float*)Rxyz, 3, 0.0f,
280 (float*)(pData->src_dirs_rot_xyz), 3);
281 for (i = 0; i < nSources; i++) {
282 hypotxy = sqrtf(powf(pData->src_dirs_rot_xyz[i][0], 2.0f) + powf(pData->src_dirs_rot_xyz[i][1], 2.0f));
283 pData->src_dirs_rot_deg[i][0] = RAD2DEG(atan2f(pData->src_dirs_rot_xyz[i][1], pData->src_dirs_rot_xyz[i][0]));
284 pData->src_dirs_rot_deg[i][1] = RAD2DEG(atan2f(pData->src_dirs_rot_xyz[i][2], hypotxy));
285 }
286 pData->recalc_M_rotFLAG = 0;
287 }
288
289 /* Interpolate and apply HRTFs, apply DVF magnitude filter */
290 /* Zero out TF summing bus */
291 memset(FLATTEN3D(pData->outputframeTF), 0, HYBRID_BANDS*NUM_EARS*TIME_SLOTS * sizeof(float_complex));
292
293 for (ch = 0; ch < nSources; ch++) {
294 /* Interpolate HRTFs */
295 if (pData->recalc_hrtf_interpFLAG[ch]) {
296 if (enableRotation) {
297 pData->src_dirs_cur = pData->src_dirs_rot_deg;
298 } else {
299 pData->src_dirs_cur = pData->src_dirs_deg;
300 }
301 binauraliser_interpHRTFs(hBin, pData->interpMode, pData->src_dirs_cur[ch][0], pData->src_dirs_cur[ch][1], pData->hrtf_interp[ch]);
302 pData->recalc_hrtf_interpFLAG[ch] = 0;
303 pData->recalc_dvfCoeffFLAG[ch] = 1;
304 }
305 /* Update DVF filters with change in direction and/or distance */
306 if (pData->recalc_dvfCoeffFLAG[ch]) {
307 rho = pData->src_dists_m[ch] * headRadiusRecip;
308 doaToIpsiInteraural(pData->src_dirs_cur[ch][0], pData->src_dirs_cur[ch][1], &alphaLR[0], NULL);
309 calcDVFCoeffs(alphaLR[0], rho, fs, pData->b_dvf[ch][0], pData->a_dvf[ch][0]);
310 calcDVFCoeffs(alphaLR[1], rho, fs, pData->b_dvf[ch][1], pData->a_dvf[ch][1]);
311 pData->recalc_dvfCoeffFLAG[ch] = 0;
312
313 evalIIRTransferFunctionf(pData->b_dvf[ch][0], pData->a_dvf[ch][0], 2,
314 pData->freqVector, HYBRID_BANDS, fs, 0,
315 pData->dvfmags[ch][0],
316 pData->dvfphases[ch][0]); // NULL to return magnitude only
317
318 evalIIRTransferFunctionf(pData->b_dvf[ch][1], pData->a_dvf[ch][1], 2,
319 pData->freqVector, HYBRID_BANDS, fs, 0,
320 pData->dvfmags[ch][1],
321 pData->dvfphases[ch][1]); // NULL to return magnitude only
322 pData->recalc_dvfCoeffFLAG[ch] = 0;
323 }
324
325 /* Convolve this channel with the interpolated HRTF, and add it to the binaural buffer */
326 if (pData->src_dists_m[ch] < ffThresh) {
327 /* Near field: convolve this channel with the HRTF & DVF filter */
328 float_complex dvfScale;
329 for (band = 0; band < HYBRID_BANDS; band++) {
330 for (ear = 0; ear < NUM_EARS; ear++) {
331 /* combine mag and phase response of HRTF and DVF */
332 /* apply magnitude & phase */
333 dvfScale = ccmulf(cmplxf(pData->dvfmags[ch][ear][band], pData->dvfphases[ch][ear][band]), pData->hrtf_interp[ch][band][ear]);
334 /* apply magnitude only, no phase */
335 // dvfScale = crmulf(pData->hrtf_interp[ch][band][ear], pData->dvfmags[ch][ear][band]);
336 /* bypass dvf */
337 // dvfScale = pData->hrtf_interp[ch][band][ear];
338
339 cblas_caxpy(TIME_SLOTS, &dvfScale,
340 pData->inputframeTF[band][ch], 1,
341 pData->outputframeTF[band][ear], 1);
342 }
343 }
344 } else {
345 /* Far field: convolve this channel with the HRTF filter only */
346 for (band = 0; band < HYBRID_BANDS; band++)
347 for (ear = 0; ear < NUM_EARS; ear++)
348 cblas_caxpy(TIME_SLOTS, &pData->hrtf_interp[ch][band][ear],
349 pData->inputframeTF[band][ch], 1,
350 pData->outputframeTF[band][ear], 1);
351 }
352 }
353
354 /* scale by number of sources */
355 cblas_sscal(/*re+im*/2*HYBRID_BANDS*NUM_EARS*TIME_SLOTS, 1.0f/sqrtf((float)nSources), (float*)FLATTEN3D(pData->outputframeTF), 1);
356
357 /* inverse-TFT */
359
360 /* Copy to output buffer */
361 for (ch = 0; ch < SAF_MIN(NUM_EARS, nOutputs); ch++)
362 utility_svvcopy(pData->outframeTD[ch], BINAURALISER_FRAME_SIZE, outputs[ch]);
363 for (; ch < nOutputs; ch++)
364 memset(outputs[ch], 0, BINAURALISER_FRAME_SIZE*sizeof(float));
365 }
366 else{
367 for (ch=0; ch < nOutputs; ch++)
368 memset(outputs[ch],0, BINAURALISER_FRAME_SIZE*sizeof(float));
369 }
370
372}
373
374
375/* Set Functions */
376
377void binauraliserNF_setSourceDist_m(void* const hBin, int index, float newDist_m)
378{
380 newDist_m = SAF_MAX(newDist_m, pData->nearfield_limit_m);
381 if(pData->src_dists_m[index] != newDist_m){
382 pData->src_dists_m[index] = newDist_m;
383 pData->recalc_dvfCoeffFLAG[index] = 1;
384 }
385}
386
387void binauraliserNF_setInputConfigPreset(void* const hBin, int newPresetID)
388{
390 int ch, nDim;
391
392 binauraliser_loadPreset(newPresetID, pData->src_dirs_deg, &(pData->new_nSources), &nDim);
393 // For now, any preset selected will reset sources to the far field
395
396 if(pData->nSources != pData->new_nSources)
398 for(ch=0; ch<MAX_NUM_INPUTS; ch++) {
399 pData->recalc_hrtf_interpFLAG[ch] = 1;
400 pData->recalc_dvfCoeffFLAG[ch] = 1;
401 }
402}
403
404float binauraliserNF_getSourceDist_m(void* const hBin, int index)
405{
407
408 return pData->src_dists_m[index];
409}
410
412{
414
415 return pData->farfield_thresh_m;
416}
417
419{
421
422 return pData->farfield_headroom;
423}
424
426{
428
429 return pData->nearfield_limit_m;
430}
#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_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_destroy(void **const phSTFT)
Destroys an instance of afSTFT.
Definition afSTFTlib.c:199
#define TIME_SLOTS
Number of STFT timeslots.
#define HYBRID_BANDS
Number of frequency bands.
void binauraliser_init(void *const hBin, int samplerate)
Initialises an instance of binauraliser with default settings.
@ 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.
#define BINAURALISER_FRAME_SIZE
Framesize, in time-domain samples.
void binauraliserNF_init(void *const hBin, int sampleRate)
Initialises an instance of binauraliser with default settings.
void binauraliserNF_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.
float binauraliserNF_getNearfieldLimit_m(void *const hBin)
Returns the minimum distance possible for near field filter, in METERS.
float binauraliserNF_getSourceDist_m(void *const hBin, int index)
Returns the source elevation for a given index, in METERS.
void binauraliserNF_create(void **const phBin)
Creates an instance of the binauraliser.
void binauraliserNF_destroy(void **const phBin)
Destroys an instance of the binauraliser.
void binauraliserNF_setInputConfigPreset(void *const hBin, int newPresetID)
Loads an input preset (see SOURCE_CONFIG_PRESETS enum)
float binauraliserNF_getFarfieldThresh_m(void *const hBin)
Returns the distance considered to be the far field (beyond which no near field filtering is applied)...
void binauraliserNF_setSourceDist_m(void *const hBin, int index, float newDist_m)
Sets the panning distance for a specific channel index, in METERS.
float binauraliserNF_getFarfieldHeadroom(void *const hBin)
Returns the scaling factor to give the far field threshold headroom (useful for UI range limits)
void binauraliserNF_initCodec(void *const hBin)
Intialises the codec variables, based on current global/user parameters.
void binauraliserNF_resetSourceDistances(void *const hBin)
Resets the source distances to the default far field distance.
Convolves input audio (up to 64 channels) with interpolated HRTFs in the time-frequency domain,...
void doaToIpsiInteraural(float azimuth, float elevation, float *alphaLR, float *betaLR)
Convert a frontal azimuth/elevation to a modified Interaural-Polar coordinate.
#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.
void evalIIRTransferFunctionf(float *b_coeff, float *a_coeff, int nCoeffs, float *freqs, int nFreqs, float fs, int mag2dB, float *magnitude, float *phase_rad)
Computes magnitude and phase response of an IIR filter from its coefficients (floats) at user-specifi...
#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 calcDVFCoeffs(float alpha, float rho, float fs, float *b, float *a)
Calculate the Distance Variation Function (DVF) filter coefficients, as described in [1].
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 *** 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.
PROC_STATUS procStatus
see PROC_STATUS
float progressBar0_1
Current (re)initialisation progress, between [0..1].
int reInitHRTFsAndGainTables
1: reinitialise the HRTFs and interpolation tables, 0: do not
CODEC_STATUS codecStatus
see CODEC_STATUS
char * progressBarText
Current (re)initialisation step, string.
Main structure for binauraliserNF.
float * itds_s
interaural-time differences for each HRIR (in seconds); nBands x 1
char * sofa_filepath
absolute/relevative file path for a sofa file
float * hrir_dirs_deg
directions of the HRIRs in degrees [azi elev]; FLAT: N_hrir_dirs x 2
float_complex *** outputframeTF
time-frequency domain input frame; HYBRID_BANDS x NUM_EARS x TIME_SLOTS
float_complex * hrtf_fb
hrtf filterbank coefficients; nBands x nCH x N_hrirs
int N_hrtf_vbap_gtable
Number of interpolation weights/directions.
int bFlipRoll
flag to flip the sign of the roll rotation angle
float pitch
pitch (Euler) rotation angle, in degrees
int useDefaultHRIRsFLAG
1: use default HRIRs in database, 0: use those from SOFA file
float src_dirs_rot_deg[MAX_NUM_INPUTS][2]
Intermediate rotated source directions, in degrees.
float * hrirs
time domain HRIRs; FLAT: N_hrir_dirs x NUM_EARS x hrir_len
int nTriangles
Number of triangles in the convex hull of the spherical arrangement of HRIR directions/points.
float(* src_dirs_cur)[2]
Pointer to assign to the current HRTF directions being operated on (non/rotated directions switch).
int enableRotation
1: enable rotation, 0: disable
CODEC_STATUS codecStatus
see CODEC_STATUS
float ** inputFrameTD
time-domain input frame; MAX_NUM_INPUTS x BINAURALISER_FRAME_SIZE
PROC_STATUS procStatus
see PROC_STATUS
char * progressBarText
Current (re)initialisation step, string.
float head_radius_recip
Reciprocal of head radius.
float src_dirs_deg[MAX_NUM_INPUTS][2]
Current source/panning directions, in degrees.
float dvfphases[MAX_NUM_INPUTS][NUM_EARS][HYBRID_BANDS]
DVF filter frequency band phases.
float a_dvf[MAX_NUM_INPUTS][NUM_EARS][2]
shelf IIR denominator coefficients for each input, left and right.
float * hrtf_fb_mag
magnitudes of the hrtf filterbank coefficients; nBands x nCH x N_hrirs
int hrir_loaded_len
length of the loaded HRIRs, in samples
float * weights
Integration weights for the HRIR measurement grid.
float farfield_thresh_m
Distance considered to be far field (no near field filtering), meters.
float freqVector[HYBRID_BANDS]
Frequency vector (filterbank centre frequencies)
INTERP_MODES interpMode
see INTERP_MODES
float_complex *** inputframeTF
time-frequency domain input frame; HYBRID_BANDS x MAX_NUM_INPUTS x TIME_SLOTS
int useRollPitchYawFlag
rotation order flag, 1: r-p-y, 0: y-p-r
int fs
Host sampling rate, in Hz.
int recalc_M_rotFLAG
1: re-calculate the rotation matrix, 0: do not
int * hrtf_vbap_gtableIdx
N_hrtf_vbap_gtable x 3.
int hrir_runtime_len
length of the HRIRs being used for processing (after any resampling), in samples
int enableHRIRsDiffuseEQ
flag to diffuse-field equalisation to the currently loaded HRTFs
float src_dirs_rot_xyz[MAX_NUM_INPUTS][3]
Intermediate rotated source directions, as unit-length Cartesian coordinates.
float roll
roll (Euler) rotation angle, in degrees
float dvfmags[MAX_NUM_INPUTS][NUM_EARS][HYBRID_BANDS]
DVF filter frequency band magnitudes.
float yaw
yaw (Euler) rotation angle, in degrees
int hrir_loaded_fs
sampling rate of the loaded HRIRs
float_complex hrtf_interp[MAX_NUM_INPUTS][HYBRID_BANDS][NUM_EARS]
Interpolated HRTFs.
float farfield_headroom
Scale factor applied to farfield_thresh_m when resetting to the far field, and for UI range,...
int nSources
Current number of input/source signals.
int N_hrir_dirs
number of HRIR directions in the current sofa file
float head_radius
Head radius, used calculate normalized source distance meters, def.
int hrir_runtime_fs
sampling rate of the HRIRs being used for processing (after any resampling)
int bFlipPitch
flag to flip the sign of the pitch rotation angle
int new_nSources
New number of input/source signals (current value will be replaced by this after next re-init)
float b_dvf[MAX_NUM_INPUTS][NUM_EARS][2]
shelf IIR numerator coefficients for each input, left and right.
float progressBar0_1
Current (re)initialisation progress, between [0..1].
int bFlipYaw
flag to flip the sign of the yaw rotation angle
float src_dists_m[MAX_NUM_INPUTS]
Source distance, meters.
int recalc_hrtf_interpFLAG[MAX_NUM_INPUTS]
1: re-calculate/interpolate the HRTF, 0: do not
float ** outframeTD
time-domain output frame; NUM_EARS x BINAURALISER_FRAME_SIZE
float nearfield_limit_m
Minimum distance allowed for near-field filtering, from head center, meters, def.
float src_dirs_xyz[MAX_NUM_INPUTS][3]
Intermediate source directions, as unit-length Cartesian coordinates
int reInitHRTFsAndGainTables
1: reinitialise the HRTFs and interpolation tables, 0: do not
float * hrtf_vbap_gtableComp
N_hrtf_vbap_gtable x 3.
float src_gains[MAX_NUM_INPUTS]
Gains applied per source.
int recalc_dvfCoeffFLAG[MAX_NUM_INPUTS]
1: re-calculate the DVF coefficients on change in distance, 0: do not.