SAF
Loading...
Searching...
No Matches
ambi_dec.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
45
46#include "ambi_dec_internal.h"
47
49(
50 void ** const phAmbi
51)
52{
54 *phAmbi = (void*)pData;
55 int i, j, ch, band;
56
57 /* default user parameters */
58 loadLoudspeakerArrayPreset(LOUDSPEAKER_ARRAY_PRESET_T_DESIGN_24, pData->loudpkrs_dirs_deg, &(pData->new_nLoudpkrs), &(pData->loudpkrs_nDims));
59 pData->masterOrder = pData->new_masterOrder = 1;
60 for (band = 0; band<HYBRID_BANDS; band++)
61 pData->orderPerBand[band] = 1;
62 pData->useDefaultHRIRsFLAG = 1; /* pars->sofa_filepath must be valid to set this to 0 */
63 pData->enableHRIRsPreProc = 1;
64 pData->nLoudpkrs = pData->new_nLoudpkrs;
65 pData->chOrdering = CH_ACN;
66 pData->norm = NORM_SN3D;
69 pData->rE_WEIGHT[0] = 1;
70 pData->rE_WEIGHT[1] = 1;
71 pData->diffEQmode[0] = ENERGY_PRESERVING;
72 pData->diffEQmode[1] = ENERGY_PRESERVING;
73 pData->transitionFreq = 800.0f;
74
75 /* afSTFT stuff and audio buffers */
76 pData->fs = 48000.0f;
77 pData->hSTFT = NULL;
78 pData->SHFrameTD = (float**)malloc2d(MAX_NUM_SH_SIGNALS, AMBI_DEC_FRAME_SIZE, sizeof(float));
80 pData->SHframeTF = (float_complex***)malloc3d(HYBRID_BANDS, MAX_NUM_SH_SIGNALS, TIME_SLOTS, sizeof(float_complex));
81 pData->outputframeTF = (float_complex***)malloc3d(HYBRID_BANDS, MAX_NUM_LOUDSPEAKERS, TIME_SLOTS, sizeof(float_complex));
82 pData->binframeTF = (float_complex***)malloc3d(HYBRID_BANDS, NUM_EARS, TIME_SLOTS, sizeof(float_complex));
83
84 /* codec data */
85 pData->progressBar0_1 = 0.0f;
87 strcpy(pData->progressBarText,"");
90 ambi_dec_codecPars* pars = pData->pars;
91 for (i=0; i<NUM_DECODERS; i++){
92 for(j=0; j<MAX_SH_ORDER; j++){
93 pars->M_dec[i][j] = NULL;
94 pars->M_dec_cmplx[i][j] = NULL;
95 pars->M_dec_maxrE[i][j] = NULL;
96 pars->M_dec_cmplx_maxrE[i][j] = NULL;
97 }
98 }
99 pars->sofa_filepath = NULL;
100 pars->hrirs = NULL;
101 pars->hrir_dirs_deg = NULL;
102 pars->hrtf_vbap_gtableIdx = NULL;
103 pars->hrtf_vbap_gtableComp = NULL;
104 pars->itds_s = NULL;
105 pars->hrtf_fb = NULL;
106 pars->hrtf_fb_mag = NULL;
107 pars->weights = NULL;
108
109 /* internal parameters */
110 pData->binauraliseLS = pData->new_binauraliseLS = 0;
111
112 /* flags */
114 pData->reinit_hrtfsFLAG = 1;
115 for(ch=0; ch<MAX_NUM_LOUDSPEAKERS; ch++)
116 pData->recalc_hrtf_interpFLAG[ch] = 1;
117}
118
120(
121 void ** const phAmbi
122)
123{
124 ambi_dec_data *pData = (ambi_dec_data*)(*phAmbi);
125 ambi_dec_codecPars *pars;
126 int i, j;
127
128 if (pData != NULL) {
129 /* not safe to free memory during intialisation/processing loop */
130 while (pData->codecStatus == CODEC_STATUS_INITIALISING ||
132 SAF_SLEEP(10);
133 }
134
135 /* free afSTFT and buffers */
136 if(pData->hSTFT!=NULL)
137 afSTFT_destroy(&(pData->hSTFT));
138 free(pData->SHFrameTD);
139 free(pData->outputFrameTD);
140 free(pData->SHframeTF);
141 free(pData->outputframeTF);
142 free(pData->binframeTF);
143
144 /* free codec data */
145 pars = pData->pars;
146 free(pars->hrtf_vbap_gtableComp);
147 free(pars->hrtf_vbap_gtableIdx);
148 free(pars->hrtf_fb);
149 free(pars->hrtf_fb_mag);
150 free(pars->itds_s);
151 free(pars->sofa_filepath);
152 free(pars->hrirs);
153 free(pars->hrir_dirs_deg);
154 free(pars->weights);
155 for (i=0; i<NUM_DECODERS; i++){
156 for(j=0; j<MAX_SH_ORDER; j++){
157 free(pars->M_dec[i][j]);
158 free(pars->M_dec_cmplx[i][j]);
159 free(pars->M_dec_maxrE[i][j]);
160 free(pars->M_dec_cmplx_maxrE[i][j]);
161 }
162 }
163 free(pData->progressBarText);
164 free(pData);
165 pData = NULL;
166 *phAmbi = NULL;
167 }
168}
169
171(
172 void * const hAmbi,
173 int sampleRate
174)
175{
176 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
177
178 /* define frequency vector */
179 pData->fs = sampleRate;
181 afSTFT_getCentreFreqs(pData->hSTFT, (float)pData->fs, HYBRID_BANDS, pData->freqVector);
182}
183
185(
186 void* const hAmbi
187)
188{
189 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
190 ambi_dec_codecPars* pars = pData->pars;
191 int i, ch, d, j, n, ng, nGrid_dirs, masterOrder, nSH_order, max_nSH, nLoudspeakers;
192 float* grid_dirs_deg, *Y, *M_dec_tmp, *g, *a, *e, *a_n, *hrtf_vbap_gtable;;
193 float a_avg[MAX_SH_ORDER], e_avg[MAX_SH_ORDER], azi_incl[2], sum_elev;
194 float loudpkrs_dirs_deg_local[MAX_NUM_LOUDSPEAKERS][2];
195#ifdef SAF_ENABLE_SOFA_READER_MODULE
198#endif
199
201 return; /* re-init not required, or already happening */
202 while (pData->procStatus == PROC_STATUS_ONGOING){
203 /* re-init required, but we need to wait for the current processing loop to end */
204 pData->codecStatus = CODEC_STATUS_INITIALISING; /* indicate that we want to init */
205 SAF_SLEEP(10);
206 }
207
208 /* for progress bar */
210 strcpy(pData->progressBarText,"Initialising");
211 pData->progressBar0_1 = 0.0f;
212
213 /* reinit afSTFT */
214 masterOrder = pData->new_masterOrder;
215 max_nSH = (masterOrder+1)*(masterOrder+1);
216 nLoudspeakers = pData->new_nLoudpkrs;
217 if(pData->hSTFT==NULL){
218 if(pData->new_binauraliseLS)
219 afSTFT_create(&(pData->hSTFT), max_nSH, NUM_EARS, HOP_SIZE, 0, 1, AFSTFT_BANDS_CH_TIME);
220 else
221 afSTFT_create(&(pData->hSTFT), max_nSH, nLoudspeakers, HOP_SIZE, 0, 1, AFSTFT_BANDS_CH_TIME);
223 }
224 else{
225 if(pData->new_binauraliseLS)
226 afSTFT_channelChange(pData->hSTFT, max_nSH, NUM_EARS);
227 else
228 afSTFT_channelChange(pData->hSTFT, max_nSH, nLoudspeakers);
230 }
231 afSTFT_getCentreFreqs(pData->hSTFT, (float)pData->fs, HYBRID_BANDS, pData->freqVector);
232 pData->binauraliseLS = pData->new_binauraliseLS;
233 pData->nLoudpkrs = nLoudspeakers;
234
235 /* Grab local copy */
236 for(ch=0; ch < nLoudspeakers; ch++){
237 loudpkrs_dirs_deg_local[ch][0] = pData->loudpkrs_dirs_deg[ch][0];
238 loudpkrs_dirs_deg_local[ch][1] = pData->loudpkrs_dirs_deg[ch][1];
239 }
240
241 /* Quick and dirty check to find loudspeaker dimensionality */
242 strcpy(pData->progressBarText,"Computing decoder");
243 pData->progressBar0_1 = 0.2f;
244 sum_elev = 0.0f;
245 for(ch=0; ch < nLoudspeakers; ch++)
246 sum_elev += fabsf(loudpkrs_dirs_deg_local[ch][1]);
247 if( (((sum_elev < 5.0f) && (sum_elev > -5.0f))) || (nLoudspeakers < 4) )
248 pData->loudpkrs_nDims = 2;
249 else
250 pData->loudpkrs_nDims = 3;
251
252 /* add virtual loudspeakers for 2D case if using AllRAD, so that the triangulation cannot fail. */
253 if (pData->loudpkrs_nDims == 2 && (pData->dec_method[0]==DECODING_METHOD_ALLRAD || pData->dec_method[1]==DECODING_METHOD_ALLRAD)){
254 assert(nLoudspeakers<=MAX_NUM_LOUDSPEAKERS-2);
255 loudpkrs_dirs_deg_local[nLoudspeakers][0] = 0.0f;
256 loudpkrs_dirs_deg_local[nLoudspeakers][1] = -90.0f;
257 loudpkrs_dirs_deg_local[nLoudspeakers+1][0] = 0.0f;
258 loudpkrs_dirs_deg_local[nLoudspeakers+1][1] = 90.0f;
259 nLoudspeakers += 2;
260 }
261
262 /* prep */
263 nGrid_dirs = 480; /* Minimum t-design of degree 30, has 480 points */
264 g = malloc1d(nLoudspeakers*sizeof(float));
265 a = malloc1d(nGrid_dirs*sizeof(float));
266 e = malloc1d(nGrid_dirs*sizeof(float));
267
268 /* calculate loudspeaker decoding matrices */
269 for( d=0; d<NUM_DECODERS; d++){
270 M_dec_tmp = malloc1d(nLoudspeakers * max_nSH * sizeof(float));
271 switch(pData->dec_method[d]){
273 getLoudspeakerDecoderMtx((float*)loudpkrs_dirs_deg_local, nLoudspeakers, LOUDSPEAKER_DECODER_SAD, masterOrder, 0, M_dec_tmp);
274 break;
276 getLoudspeakerDecoderMtx((float*)loudpkrs_dirs_deg_local, nLoudspeakers, LOUDSPEAKER_DECODER_MMD, masterOrder, 0, M_dec_tmp);
277 break;
279 getLoudspeakerDecoderMtx((float*)loudpkrs_dirs_deg_local, nLoudspeakers, LOUDSPEAKER_DECODER_EPAD, masterOrder, 0, M_dec_tmp);
280 break;
282 getLoudspeakerDecoderMtx((float*)loudpkrs_dirs_deg_local, nLoudspeakers, LOUDSPEAKER_DECODER_ALLRAD, masterOrder, 0, M_dec_tmp);
283 break;
284 }
285
286 /* diffuse-field EQ for orders 1..masterOrder */
287 for( n=1; n<=masterOrder; n++){
288 /* truncate M_dec for each order */
289 nSH_order = (n+1)*(n+1);
290 free(pars->M_dec[d][n-1]);
291 pars->M_dec[d][n-1] = malloc1d(nLoudspeakers* nSH_order * sizeof(float));
292 free(pars->M_dec_cmplx[d][n-1]);
293 pars->M_dec_cmplx[d][n-1] = malloc1d(nLoudspeakers * nSH_order * sizeof(float_complex));
294 for(i=0; i<nLoudspeakers; i++){
295 for(j=0; j<nSH_order; j++){
296 pars->M_dec[d][n-1][i*nSH_order+j] = M_dec_tmp[i*max_nSH +j]; /* for applying in the time domain, and... */
297 pars->M_dec_cmplx[d][n-1][i*nSH_order+j] = cmplxf(pars->M_dec[d][n-1][i*nSH_order+j], 0.0f); /* for the time-frequency domain */
298 }
299 }
300
301 /* create dedicated maxrE weighted versions */
302 a_n = malloc1d(nSH_order*nSH_order*sizeof(float));
303 getMaxREweights(n, 1, a_n); /* weights returned as diagonal matrix */
304 free(pars->M_dec_maxrE[d][n-1]);
305 pars->M_dec_maxrE[d][n-1] = malloc1d(nLoudspeakers * nSH_order * sizeof(float));
306 free(pars->M_dec_cmplx_maxrE[d][n-1]);
307 pars->M_dec_cmplx_maxrE[d][n-1] = malloc1d(nLoudspeakers * nSH_order * sizeof(float_complex));
308 cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, nLoudspeakers, nSH_order, nSH_order, 1.0f,
309 pars->M_dec[d][n-1], nSH_order,
310 a_n, nSH_order, 0.0f,
311 pars->M_dec_maxrE[d][n-1], nSH_order); /* for applying in the time domain */
312 for(i=0; i<nLoudspeakers * nSH_order; i++)
313 pars->M_dec_cmplx_maxrE[d][n-1][i] = cmplxf(pars->M_dec_maxrE[d][n-1][i], 0.0f); /* for the time-frequency domain */
314
315 /* fire a plane-wave from each grid direction to find the total energy/amplitude (using non-maxrE weighted versions) */
316 Y = malloc1d(nSH_order*sizeof(float));
317 grid_dirs_deg = (float*)(&__Tdesign_degree_30_dirs_deg[0][0]);
318 for(ng=0; ng<nGrid_dirs; ng++){
319 azi_incl[0] = grid_dirs_deg[ng*2]*SAF_PI/180.0f;
320 azi_incl[1] = SAF_PI/2.0f-grid_dirs_deg[ng*2+1]*SAF_PI/180.0f;
321 getSHreal(n, (float*)azi_incl, 1, Y);
322 cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasTrans, nLoudspeakers, 1, nSH_order, 1.0f,
323 pars->M_dec[d][n-1], nSH_order,
324 Y, nSH_order, 0.0f,
325 g, 1);
326 a[ng] = e[ng] = 0.0f;
327 for(i=0; i<nLoudspeakers; i++){
328 a[ng] += g[i];
329 e[ng] += powf(g[i], 2.0f);
330 }
331 }
332
333 /* determine the order+decoder dependent normalisation factor for energy+amplitude preserving decoding */
334 a_avg[n-1] = e_avg[n-1] = 0.0f;
335 for(ng=0; ng<nGrid_dirs; ng++){
336 a_avg[n-1] += a[ng];
337 e_avg[n-1] += e[ng];
338 }
339 a_avg[n-1] /= (float)nGrid_dirs;
340 e_avg[n-1] /= (float)nGrid_dirs;
341 pars->M_norm[d][n-1][0] = 1.0f/(a_avg[n-1]+2.23e-6f); /* use this to preserve omni amplitude */
342 pars->M_norm[d][n-1][1] = sqrtf(1.0f/(e_avg[n-1]+2.23e-6f)); /* use this to preserve omni energy */
343 free(a_n);
344 free(Y);
345
346 /* remove virtual loudspeakers from the decoder (if needed) */
347 if (pData->loudpkrs_nDims == 2 && (pData->dec_method[0]==DECODING_METHOD_ALLRAD || pData->dec_method[1]==DECODING_METHOD_ALLRAD)){
348 pars->M_dec[d][n-1] = realloc1d(pars->M_dec[d][n-1], pData->nLoudpkrs * nSH_order * sizeof(float));
349 pars->M_dec_cmplx[d][n-1] = realloc1d(pars->M_dec_cmplx[d][n-1], pData->nLoudpkrs * nSH_order * sizeof(float_complex));
350 pars->M_dec_maxrE[d][n-1] = realloc1d(pars->M_dec_maxrE[d][n-1], pData->nLoudpkrs * nSH_order * sizeof(float));
351 pars->M_dec_cmplx_maxrE[d][n-1] = realloc1d(pars->M_dec_cmplx_maxrE[d][n-1], pData->nLoudpkrs * nSH_order * sizeof(float_complex));
352 }
353 }
354 free(M_dec_tmp);
355 }
356
357 /* update order */
358 pData->masterOrder = pData->new_masterOrder;
359
360 /* Binaural-related initialisations */
361 if(pData->reinit_hrtfsFLAG){
362 strcpy(pData->progressBarText,"Computing VBAP gain table");
363 pData->progressBar0_1 = 0.4f;
364
365 /* load sofa file or load default hrir data */
366#ifdef SAF_ENABLE_SOFA_READER_MODULE
367 if(!pData->useDefaultHRIRsFLAG && pars->sofa_filepath!=NULL){
368 /* Load SOFA file */
370
371 /* Load defaults instead */
372 if(error!=SAF_SOFA_OK || sofa.nReceivers!=NUM_EARS){
373 pData->useDefaultHRIRsFLAG = 1;
374 saf_print_warning("Unable to load the specified SOFA file, or it contained something other than 2 channels. Using default HRIR data instead.");
375 }
376 else{
377 /* Copy SOFA data */
378 pars->hrir_fs = (int)sofa.DataSamplingRate;
379 pars->hrir_len = sofa.DataLengthIR;
380 pars->N_hrir_dirs = sofa.nSources;
381 pars->hrirs = realloc1d(pars->hrirs, pars->N_hrir_dirs*NUM_EARS*(pars->hrir_len)*sizeof(float));
382 memcpy(pars->hrirs, sofa.DataIR, pars->N_hrir_dirs*NUM_EARS*(pars->hrir_len)*sizeof(float));
383 pars->hrir_dirs_deg = realloc1d(pars->hrir_dirs_deg, pars->N_hrir_dirs*2*sizeof(float));
384 cblas_scopy(pars->N_hrir_dirs, sofa.SourcePosition, 3, pars->hrir_dirs_deg, 2); /* azi */
385 cblas_scopy(pars->N_hrir_dirs, &sofa.SourcePosition[1], 3, &pars->hrir_dirs_deg[1], 2); /* elev */
386 }
387
388 /* Clean-up */
389 saf_sofa_close(&sofa);
390 }
391#else
392 pData->useDefaultHRIRsFLAG = 1; /* Can only load the default HRIR data */
393#endif
394 if(pData->useDefaultHRIRsFLAG){
395 /* Copy default HRIR data */
399 pars->hrirs = realloc1d(pars->hrirs, pars->N_hrir_dirs*NUM_EARS*(pars->hrir_len)*sizeof(float));
400 memcpy(pars->hrirs, (float*)__default_hrirs, pars->N_hrir_dirs*NUM_EARS*(pars->hrir_len)*sizeof(float));
401 pars->hrir_dirs_deg = realloc1d(pars->hrir_dirs_deg, pars->N_hrir_dirs*2*sizeof(float));
402 memcpy(pars->hrir_dirs_deg, (float*)__default_hrir_dirs_deg, pars->N_hrir_dirs*2*sizeof(float));
403 }
404
405 /* estimate the ITDs for each HRIR */
406 pars->itds_s = realloc1d(pars->itds_s, pars->N_hrir_dirs*sizeof(float));
407 estimateITDs(pars->hrirs, pars->N_hrir_dirs, pars->hrir_len, pars->hrir_fs, pars->itds_s);
408
409 /* generate VBAP gain table for the hrir_dirs */
410 hrtf_vbap_gtable = NULL;
411 pars->hrtf_vbapTableRes[0] = 2; /* azimuth resolution in degrees */
412 pars->hrtf_vbapTableRes[1] = 5; /* elevation resolution in degrees */
413 generateVBAPgainTable3D(pars->hrir_dirs_deg, pars->N_hrir_dirs, pars->hrtf_vbapTableRes[0], pars->hrtf_vbapTableRes[1], 1, 0, 0.0f,
414 &hrtf_vbap_gtable, &(pars->N_hrtf_vbap_gtable), &(pars->hrtf_nTriangles));
415 if(hrtf_vbap_gtable==NULL){
416 /* if generating vbap gain tabled failed, re-calculate with default HRIR set (which is known to triangulate correctly) */
417 pData->useDefaultHRIRsFLAG = 1;
418 ambi_dec_initCodec(hAmbi);
419 }
420
421 /* compress VBAP table (i.e. remove the zero elements) */
422 pars->hrtf_vbap_gtableComp = realloc1d(pars->hrtf_vbap_gtableComp, pars->N_hrtf_vbap_gtable * 3 * sizeof(float));
423 pars->hrtf_vbap_gtableIdx = realloc1d(pars->hrtf_vbap_gtableIdx, pars->N_hrtf_vbap_gtable * 3 * sizeof(int));
425
426 /* convert hrirs to filterbank coefficients */
427 strcpy(pData->progressBarText,"Preparing HRIRs");
428 pData->progressBar0_1 = 0.85f;
429 pars->hrtf_fb = realloc1d(pars->hrtf_fb, HYBRID_BANDS * NUM_EARS * (pars->N_hrir_dirs)*sizeof(float_complex));
430 HRIRs2HRTFs_afSTFT(pars->hrirs, pars->N_hrir_dirs, pars->hrir_len, HOP_SIZE, 0, 1, pars->hrtf_fb);
431 /* HRIR pre-processing */
432 if(pData->enableHRIRsPreProc){
433 /* get integration weights */
434 strcpy(pData->progressBarText,"Applying HRIR Pre-Processing");
435 pData->progressBar0_1 = 0.95f;
436 if(pars->N_hrir_dirs<=3600){
437 pars->weights = realloc1d(pars->weights, pars->N_hrir_dirs*sizeof(float));
438 //getVoronoiWeights(pars->hrir_dirs_deg, pars->N_hrir_dirs, 0, pars->weights);
439 float * hrir_dirs_rad = (float*) malloc1d(pars->N_hrir_dirs*2*sizeof(float));
440 memcpy(hrir_dirs_rad, pars->hrir_dirs_deg, pars->N_hrir_dirs*2*sizeof(float));
441 cblas_sscal(pars->N_hrir_dirs*2, SAF_PI/180.f, hrir_dirs_rad, 1);
442 sphElev2incl(hrir_dirs_rad, pars->N_hrir_dirs, 0, hrir_dirs_rad);
443 int supOrder = calculateGridWeights(hrir_dirs_rad, pars->N_hrir_dirs, -1, pars->weights);
444 if(supOrder < 1){
445 saf_print_warning("Could not calculate grid weights");
446 free(pars->weights);
447 pars->weights = NULL;
448 }
449 }
450 else{
451 saf_print_warning("Too many grid points");
452 free(pars->weights);
453 pars->weights = NULL;
454 }
455 diffuseFieldEqualiseHRTFs(pars->N_hrir_dirs, pars->itds_s, pData->freqVector, HYBRID_BANDS, pars->weights, 1, 0, pars->hrtf_fb);
456 }
457
458 /* calculate magnitude responses */
459 pars->hrtf_fb_mag = realloc1d(pars->hrtf_fb_mag, HYBRID_BANDS*NUM_EARS*(pars->N_hrir_dirs)*sizeof(float));
460 for(i=0; i<HYBRID_BANDS*NUM_EARS* (pars->N_hrir_dirs); i++)
461 pars->hrtf_fb_mag[i] = cabsf(pars->hrtf_fb[i]);
462
463 /* clean-up */
464 free(hrtf_vbap_gtable);
465 pData->reinit_hrtfsFLAG = 0;
466 }
467
468 /* HRTFs should be reinterpolated */
469 for(ch=0; ch<MAX_NUM_LOUDSPEAKERS; ch++)
470 pData->recalc_hrtf_interpFLAG[ch] = 1;
471
472 /* done! */
473 strcpy(pData->progressBarText,"Done!");
474 pData->progressBar0_1 = 1.0f;
476
477 free(g);
478 free(a);
479 free(e);
480}
481
483(
484 void * const hAmbi,
485 const float *const * inputs,
486 float* const* const outputs,
487 int nInputs,
488 int nOutputs,
489 int nSamples
490)
491{
492 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
493 ambi_dec_codecPars* pars = pData->pars;
494 int ch, ear, i, band, orderBand, nSH_band, decIdx, nSH;
495 const float_complex calpha = cmplxf(1.0f, 0.0f), cbeta = cmplxf(0.0f, 0.0f);
496
497 /* local copies of user parameters */
498 int nLoudspeakers, binauraliseLS, masterOrder;
499 int orderPerBand[HYBRID_BANDS], rE_WEIGHT[NUM_DECODERS];
500 float transitionFreq;
502 NORM_TYPES norm;
503 CH_ORDER chOrdering;
504 masterOrder = pData->masterOrder;
505 nSH = ORDER2NSH(masterOrder);
506 nLoudspeakers = pData->nLoudpkrs;
507 memcpy(orderPerBand, pData->orderPerBand, HYBRID_BANDS*sizeof(int));
508 transitionFreq = pData->transitionFreq;
509 memcpy(diffEQmode, pData->diffEQmode, NUM_DECODERS*sizeof(int));
510 binauraliseLS = pData->binauraliseLS;
511 norm = pData->norm;
512 chOrdering = pData->chOrdering;
513 memcpy(rE_WEIGHT, pData->rE_WEIGHT, NUM_DECODERS*sizeof(int));
514
515 /* Process frame */
516 if (nSamples == AMBI_DEC_FRAME_SIZE && (pData->codecStatus == CODEC_STATUS_INITIALISED) ) {
518
519 /* Load time-domain data */
520 for(i=0; i < SAF_MIN(nSH, nInputs); i++)
521 utility_svvcopy(inputs[i], AMBI_DEC_FRAME_SIZE, pData->SHFrameTD[i]);
522 for(; i<nSH; i++)
523 memset(pData->SHFrameTD[i], 0, AMBI_DEC_FRAME_SIZE * sizeof(float)); /* fill remaining channels with zeros */
524
525 /* account for channel order convention */
526 switch(chOrdering){
527 case CH_ACN: /* already ACN, do nothing */ break; /* Otherwise, convert to ACN... */
529 }
530
531 /* account for input normalisation scheme */
532 switch(norm){
533 case NORM_N3D: /* already in N3D, do nothing */ break; /* Otherwise, convert to N3D... */
536 }
537
538 /* Apply time-frequency transform (TFT) */
540
541 /* Decode to loudspeaker set-up */
542 memset(FLATTEN3D(pData->outputframeTF), 0, HYBRID_BANDS*MAX_NUM_LOUDSPEAKERS*TIME_SLOTS*sizeof(float_complex));
543 for(band=0; band<HYBRID_BANDS; band++){
544 orderBand = SAF_MAX(SAF_MIN(orderPerBand[band], masterOrder),1);
545 nSH_band = (orderBand+1)*(orderBand+1);
546
547 /* There is a different decoder for low (0) and high (1) frequencies, and for max_rE weights enabled/disabled */
548 decIdx = pData->freqVector[band] < transitionFreq ? 0 : 1;
549 if(rE_WEIGHT[decIdx]){
550 cblas_cgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, nLoudspeakers, TIME_SLOTS, nSH_band, &calpha,
551 pars->M_dec_cmplx_maxrE[decIdx][orderBand-1], nSH_band,
552 FLATTEN2D(pData->SHframeTF[band]), TIME_SLOTS, &cbeta,
553 FLATTEN2D(pData->outputframeTF[band]), TIME_SLOTS);
554 }
555 else{
556 cblas_cgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, nLoudspeakers, TIME_SLOTS, nSH_band, &calpha,
557 pars->M_dec_cmplx[decIdx][orderBand-1], nSH_band,
558 FLATTEN2D(pData->SHframeTF[band]), TIME_SLOTS, &cbeta,
559 FLATTEN2D(pData->outputframeTF[band]), TIME_SLOTS);
560 }
561
562 /* Apply scaling to preserve either the amplitude or energy when the decododing orders are different over frequency */
563 cblas_sscal(/*re+im*/2*nLoudspeakers*TIME_SLOTS, pars->M_norm[decIdx][orderBand-1][diffEQmode[decIdx]==AMPLITUDE_PRESERVING ? 0 : 1],
564 (float*)FLATTEN2D(pData->outputframeTF[band]), 1);
565 }
566
567 /* Binauralise the loudspeaker signals */
568 if(binauraliseLS){
569 /* Initialise the binaural buffer with zeros */
570 memset(FLATTEN3D(pData->binframeTF), 0, HYBRID_BANDS*NUM_EARS*TIME_SLOTS * sizeof(float_complex));
571
572 /* Convolve each loudspeaker signals with the respective HRTFs */
573 for (ch = 0; ch < nLoudspeakers; ch++) {
574 if(pData->recalc_hrtf_interpFLAG[ch]){
575 /* Re-compute the interpolated HRTF (only if loudspeaker direction changed) */
576 ambi_dec_interpHRTFs(hAmbi, pData->loudpkrs_dirs_deg[ch][0], pData->loudpkrs_dirs_deg[ch][1], pars->hrtf_interp[ch]);
577 pData->recalc_hrtf_interpFLAG[ch] = 0;
578 }
579
580 /* Convolve this loudspeaker channel with the interpolated HRTF, and add it to the binaural buffer */
581 for (band = 0; band < HYBRID_BANDS; band++)
582 for (ear = 0; ear < NUM_EARS; ear++)
583 cblas_caxpy(TIME_SLOTS, &pars->hrtf_interp[ch][band][ear], pData->outputframeTF[band][ch], 1, pData->binframeTF[band][ear], 1);
584 }
585
586 /* Scale by sqrt(number of loudspeakers) */
587 cblas_sscal(/*re+im*/2*HYBRID_BANDS*NUM_EARS*TIME_SLOTS, 1.0f/sqrtf((float)nLoudspeakers), (float*)FLATTEN3D(pData->binframeTF), 1);
588 }
589
590 /* inverse-TFT */
591 afSTFT_backward_knownDimensions(pData->hSTFT, binauraliseLS ? pData->binframeTF : pData->outputframeTF,
593
594 /* Copy to output buffer */
595 for(ch = 0; ch < SAF_MIN(binauraliseLS==1 ? NUM_EARS : nLoudspeakers, nOutputs); ch++)
596 utility_svvcopy(pData->outputFrameTD[ch], AMBI_DEC_FRAME_SIZE, outputs[ch]);
597 for (; ch < nOutputs; ch++)
598 memset(outputs[ch], 0, AMBI_DEC_FRAME_SIZE*sizeof(float));
599 }
600 else
601 for (ch=0; ch < nOutputs; ch++)
602 memset(outputs[ch], 0, AMBI_DEC_FRAME_SIZE*sizeof(float));
603
605}
606
607
608/* Set Functions */
609
610void ambi_dec_refreshSettings(void* const hAmbi)
611{
612 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
613 pData->reinit_hrtfsFLAG = 1;
615}
616
617void ambi_dec_setMasterDecOrder(void * const hAmbi, int newValue)
618{
619 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
620 pData->new_masterOrder = SAF_MIN(SAF_MAX(newValue,1), MAX_SH_ORDER);
622 /* FUMA only supports 1st order */
623 if(pData->new_masterOrder!=SH_ORDER_FIRST && pData->chOrdering == CH_FUMA)
624 pData->chOrdering = CH_ACN;
625 if(pData->new_masterOrder!=SH_ORDER_FIRST && pData->norm == NORM_FUMA)
626 pData->norm = NORM_SN3D;
627}
628
629void ambi_dec_setDecOrder(void * const hAmbi, int newValue, int bandIdx)
630{
631 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
632 pData->orderPerBand[bandIdx] = SAF_MIN(SAF_MAX(newValue,1), pData->new_masterOrder);
633}
634
635void ambi_dec_setDecOrderAllBands(void * const hAmbi, int newValue)
636{
637 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
638 int band;
639
640 for(band=0; band<HYBRID_BANDS; band++)
641 pData->orderPerBand[band] = SAF_MIN(SAF_MAX(newValue,1), pData->new_masterOrder);
642}
643
644void ambi_dec_setLoudspeakerAzi_deg(void* const hAmbi, int index, float newAzi_deg)
645{
646 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
647 if(newAzi_deg>180.0f)
648 newAzi_deg = -360.0f + newAzi_deg;
649 newAzi_deg = SAF_MAX(newAzi_deg, -180.0f);
650 newAzi_deg = SAF_MIN(newAzi_deg, 180.0f);
651 if(pData->loudpkrs_dirs_deg[index][0] != newAzi_deg){
652 pData->loudpkrs_dirs_deg[index][0] = newAzi_deg;
653 pData->recalc_hrtf_interpFLAG[index] = 1;
655 }
656}
657
658void ambi_dec_setLoudspeakerElev_deg(void* const hAmbi, int index, float newElev_deg)
659{
660 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
661 newElev_deg = SAF_MAX(newElev_deg, -90.0f);
662 newElev_deg = SAF_MIN(newElev_deg, 90.0f);
663 if(pData->loudpkrs_dirs_deg[index][1] != newElev_deg){
664 pData->loudpkrs_dirs_deg[index][1] = newElev_deg;
665 pData->recalc_hrtf_interpFLAG[index] = 1;
667 }
668}
669
670void ambi_dec_setNumLoudspeakers(void* const hAmbi, int new_nLoudspeakers)
671{
672 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
673 int ch;
674 pData->new_nLoudpkrs = new_nLoudspeakers > MAX_NUM_LOUDSPEAKERS ? MAX_NUM_LOUDSPEAKERS : new_nLoudspeakers;
676 if(pData->nLoudpkrs != pData->new_nLoudpkrs){
677 for(ch=0; ch<MAX_NUM_LOUDSPEAKERS; ch++)
678 pData->recalc_hrtf_interpFLAG[ch] = 1;
680 }
681}
682
683void ambi_dec_setBinauraliseLSflag(void* const hAmbi, int newState)
684{
685 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
686
687 pData->new_binauraliseLS = newState;
688 if(pData->new_binauraliseLS != pData->binauraliseLS)
690}
691
692void ambi_dec_setUseDefaultHRIRsflag(void* const hAmbi, int newState)
693{
694 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
695
696 if((!pData->useDefaultHRIRsFLAG) && (newState)){
697 pData->useDefaultHRIRsFLAG = newState;
698 ambi_dec_refreshSettings(hAmbi); // re-init and re-calc
699 }
700}
701
702void ambi_dec_setSofaFilePath(void* const hAmbi, const char* path)
703{
704 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
705 ambi_dec_codecPars* pars = pData->pars;
706
707 pars->sofa_filepath = realloc1d(pars->sofa_filepath, strlen(path) + 1);
708 strcpy(pars->sofa_filepath, path);
709 pData->useDefaultHRIRsFLAG = 0;
710 ambi_dec_refreshSettings(hAmbi); // re-init and re-calc
711}
712
713void ambi_dec_setEnableHRIRsPreProc(void* const hAmbi, int newState)
714{
715 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
716 if(newState!=pData->enableHRIRsPreProc){
717 pData->enableHRIRsPreProc = newState;
718 ambi_dec_refreshSettings(hAmbi); // re-init and re-calc
719 }
720}
721
722void ambi_dec_setOutputConfigPreset(void* const hAmbi, int newPresetID)
723{
724 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
725 int ch;
726
727 loadLoudspeakerArrayPreset(newPresetID, pData->loudpkrs_dirs_deg, &(pData->new_nLoudpkrs), &(pData->loudpkrs_nDims));
728 for(ch=0; ch<MAX_NUM_LOUDSPEAKERS; ch++)
729 pData->recalc_hrtf_interpFLAG[ch] = 1;
731}
732
733void ambi_dec_setSourcePreset(void* const hAmbi, int newPresetID)
734{
735 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
736 int band, rangeIdx, curOrder, reverse;
737
738 rangeIdx = 0;
739 curOrder = 1;
740 reverse = 0;
741 switch(newPresetID){
742 /* Ideal spherical harmonics will have SH_ORDER at all frequencies */
743 case MIC_PRESET_IDEAL:
744 for(band=0; band<HYBRID_BANDS; band++)
745 pData->orderPerBand[band] = pData->masterOrder;
746 break;
747
748 /* For real microphone arrays, the maximum usable spherical harmonic order will depend on frequency */
749 case MIC_PRESET_ZYLIA:
750 for(band=0; band<HYBRID_BANDS; band++){
751 if(rangeIdx<2*(__Zylia_maxOrder-1)){
752 if(pData->freqVector[band]>__Zylia_freqRange[rangeIdx]){
753 if(!reverse)
754 curOrder++;
755 else
756 curOrder--;
757 reverse = (curOrder == __Zylia_maxOrder) || (reverse) ? 1 : 0;
758 rangeIdx++;
759 }
760 }
761 pData->orderPerBand[band] = SAF_MIN(pData->masterOrder,curOrder);
762 }
763 break;
764
765 case MIC_PRESET_EIGENMIKE32:
766 for(band=0; band<HYBRID_BANDS; band++){
767 if(rangeIdx<2*(__Eigenmike32_maxOrder-1)){
768 if(pData->freqVector[band]>__Eigenmike32_freqRange[rangeIdx]){
769 if(!reverse)
770 curOrder++;
771 else
772 curOrder--;
773 reverse = (curOrder == __Eigenmike32_maxOrder) || (reverse) ? 1 : 0;
774 rangeIdx++;
775 }
776 }
777 pData->orderPerBand[band] = SAF_MIN(pData->masterOrder,curOrder);
778 }
779 break;
780
781 case MIC_PRESET_DTU_MIC:
782 for(band=0; band<HYBRID_BANDS; band++){
783 if(rangeIdx<2*(__DTU_mic_maxOrder-1)){
784 if(pData->freqVector[band]>__DTU_mic_freqRange[rangeIdx]){
785 if(!reverse)
786 curOrder++;
787 else
788 curOrder--;
789 reverse = (curOrder == __DTU_mic_maxOrder) || (reverse) ? 1 : 0;
790 rangeIdx++;
791 }
792 }
793 pData->orderPerBand[band] = SAF_MIN(pData->masterOrder,curOrder);
794 }
795 break;
796 }
797}
798
799void ambi_dec_setChOrder(void* const hAmbi, int newOrder)
800{
801 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
802 if((CH_ORDER)newOrder != CH_FUMA || pData->new_masterOrder==SH_ORDER_FIRST) /* FUMA only supports 1st order */
803 pData->chOrdering = (CH_ORDER)newOrder;
804}
805
806void ambi_dec_setNormType(void* const hAmbi, int newType)
807{
808 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
809 if((NORM_TYPES)newType != NORM_FUMA || pData->new_masterOrder==SH_ORDER_FIRST) /* FUMA only supports 1st order */
810 pData->norm = (NORM_TYPES)newType;
811}
812
813void ambi_dec_setDecMethod(void* const hAmbi, int index, int newID)
814{
815 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
816 pData->dec_method[index] = newID;
818}
819
820void ambi_dec_setDecEnableMaxrE(void* const hAmbi, int index, int newID)
821{
822 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
823 pData->rE_WEIGHT[index] = newID;
824}
825
826void ambi_dec_setDecNormType(void* const hAmbi, int index, int newID)
827{
828 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
829 pData->diffEQmode[index] = newID;
830}
831
832void ambi_dec_setTransitionFreq(void* const hAmbi, float newValue)
833{
834 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
836}
837
838
839/* Get Functions */
840
842{
843 return AMBI_DEC_FRAME_SIZE;
844}
845
847{
848 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
849 return pData->codecStatus;
850}
851
852float ambi_dec_getProgressBar0_1(void* const hAmbi)
853{
854 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
855 return pData->progressBar0_1;
856}
857
858void ambi_dec_getProgressBarText(void* const hAmbi, char* text)
859{
860 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
861 memcpy(text, pData->progressBarText, PROGRESSBARTEXT_CHAR_LENGTH*sizeof(char));
862}
863
864int ambi_dec_getMasterDecOrder(void * const hAmbi)
865{
866 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
867 return pData->new_masterOrder;
868}
869
870int ambi_dec_getDecOrder(void * const hAmbi, int bandIdx)
871{
872 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
873 return pData->orderPerBand[bandIdx];
874}
875
876int ambi_dec_getDecOrderAllBands(void * const hAmbi)
877{
878 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
879 return pData->orderPerBand[0];
880}
881
883(
884 void* const hAmbi,
885 float** pX_vector,
886 int** pY_values,
887 int* pNpoints
888)
889{
890 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
891 (*pX_vector) = &pData->freqVector[0];
892 (*pY_values) = (int*)&pData->orderPerBand[0];
893 (*pNpoints) = HYBRID_BANDS;
894}
895
897{
898 return HYBRID_BANDS;
899}
900
901float ambi_dec_getLoudspeakerAzi_deg(void* const hAmbi, int index)
902{
903 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
904 return pData->loudpkrs_dirs_deg[index][0];
905}
906
907float ambi_dec_getLoudspeakerElev_deg(void* const hAmbi, int index)
908{
909 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
910 return pData->loudpkrs_dirs_deg[index][1];
911}
912
913int ambi_dec_getNumLoudspeakers(void* const hAmbi)
914{
915 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
916 return pData->new_nLoudpkrs;
917}
918
923
924int ambi_dec_getNSHrequired(void* const hAmbi)
925{
926 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
927 return (pData->masterOrder+1)*(pData->masterOrder+1);
928}
929
930int ambi_dec_getBinauraliseLSflag(void* const hAmbi)
931{
932 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
933 return pData->new_binauraliseLS;
934}
935
937{
938 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
939 return pData->useDefaultHRIRsFLAG;
940}
941
942char* ambi_dec_getSofaFilePath(void* const hAmbi)
943{
944 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
945 ambi_dec_codecPars* pars = pData->pars;
946 if(pars->sofa_filepath!=NULL)
947 return pars->sofa_filepath;
948 else
949 return "/Spatial_Audio_Framework/Default";
950}
951
952int ambi_dec_getEnableHRIRsPreProc(void* const hAmbi)
953{
954 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
955 return pData->enableHRIRsPreProc;
956}
957
958int ambi_dec_getChOrder(void* const hAmbi)
959{
960 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
961 return (int)pData->chOrdering;
962}
963
964int ambi_dec_getNormType(void* const hAmbi)
965{
966 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
967 return (int)pData->norm;
968}
969
970int ambi_dec_getDecMethod(void* const hAmbi, int index)
971{
972 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
973 return pData->dec_method[index];
974}
975
976int ambi_dec_getDecEnableMaxrE(void* const hAmbi, int index)
977{
978 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
979 return pData->rE_WEIGHT[index];
980}
981
982int ambi_dec_getDecNormType(void* const hAmbi, int index)
983{
984 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
985 return pData->diffEQmode[index];
986}
987
988float ambi_dec_getTransitionFreq(void* const hAmbi)
989{
990 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
991 return pData->transitionFreq;
992}
993
994int ambi_dec_getHRIRsamplerate(void* const hAmbi)
995{
996 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
997 ambi_dec_codecPars* pars = pData->pars;
998 return pars->hrir_fs;
999}
1000
1001int ambi_dec_getDAWsamplerate(void* const hAmbi)
1002{
1003 ambi_dec_data *pData = (ambi_dec_data*)(hAmbi);
1004 return pData->fs;
1005}
1006
1008{
1009 return 12*HOP_SIZE;
1010}
1011
1012
1013
#define MAX_SH_ORDER
Maximum supported Ambisonic order.
Definition _common.h:56
#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
NORM_TYPES
Available Ambisonic normalisation conventions.
Definition _common.h:78
@ NORM_SN3D
Schmidt semi-normalisation (SN3D)
Definition _common.h:80
@ NORM_FUMA
(Legacy) Furse-Malham scaling
Definition _common.h:81
@ NORM_N3D
orthonormalised (N3D)
Definition _common.h:79
CH_ORDER
Available Ambisonic channel ordering conventions.
Definition _common.h:63
@ CH_ACN
Ambisonic Channel Numbering (ACN)
Definition _common.h:64
@ CH_FUMA
(Legacy) Furse-Malham/B-format (WXYZ)
Definition _common.h:65
#define MAX_NUM_SH_SIGNALS
Maximum number of spherical harmonic components/signals supported.
Definition _common.h:243
@ SH_ORDER_FIRST
First-order (4 channels)
Definition _common.h:43
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_clearBuffers(void *const hSTFT)
Flushes time-domain buffers with zeros.
Definition afSTFTlib.c:519
void afSTFT_create(void **const phSTFT, int nCHin, int nCHout, int hopsize, int lowDelayMode, int hybridmode, AFSTFT_FDDATA_FORMAT format)
Creates an instance of afSTFT.
Definition afSTFTlib.c:143
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
void afSTFT_channelChange(void *const hSTFT, int new_nCHin, int new_nCHout)
Re-allocates memory to support a change in the number of input/output channels.
Definition afSTFTlib.c:477
@ AFSTFT_BANDS_CH_TIME
nBands x nChannels x nTimeHops
Definition afSTFTlib.h:80
#define TIME_SLOTS
Number of STFT timeslots.
#define HOP_SIZE
STFT hop size.
#define HYBRID_BANDS
Number of frequency bands.
void ambi_dec_setDecOrderAllBands(void *const hAmbi, int newValue)
Sets the decoding order for all frequency bands.
Definition ambi_dec.c:635
void ambi_dec_create(void **const phAmbi)
Creates an instance of the ambi_dec.
Definition ambi_dec.c:49
int ambi_dec_getMaxNumLoudspeakers(void)
Returns the maximum number of loudspeakers supported by ambi_dec.
Definition ambi_dec.c:919
int ambi_dec_getNumLoudspeakers(void *const hAmbi)
Returns the number of loudspeakers in the current layout.
Definition ambi_dec.c:913
void ambi_dec_process(void *const hAmbi, const float *const *inputs, float *const *const outputs, int nInputs, int nOutputs, int nSamples)
Decodes input spherical harmonic signals to the loudspeaker channels.
Definition ambi_dec.c:483
int ambi_dec_getMasterDecOrder(void *const hAmbi)
Returns the master/maximum decoding order (see SH_ORDERS enum)
Definition ambi_dec.c:864
int ambi_dec_getNSHrequired(void *const hAmbi)
Returns the number of spherical harmonic signals required by the current decoding order: (current_ord...
Definition ambi_dec.c:924
void ambi_dec_setDecOrder(void *const hAmbi, int newValue, int bandIdx)
Sets the decoding order for a given frequency band.
Definition ambi_dec.c:629
float ambi_dec_getProgressBar0_1(void *const hAmbi)
(Optional) Returns current intialisation/processing progress, between 0..1
Definition ambi_dec.c:852
int ambi_dec_getEnableHRIRsPreProc(void *const hAmbi)
Returns the flag indicating whether the pre-processing applied to the HRTFs is enabled (1) or disable...
Definition ambi_dec.c:952
void ambi_dec_setBinauraliseLSflag(void *const hAmbi, int newState)
Sets flag to dictate whether the output loudspeaker signals should be binauralised.
Definition ambi_dec.c:683
float ambi_dec_getLoudspeakerElev_deg(void *const hAmbi, int index)
Returns the loudspeaker elevation in degrees for a given index.
Definition ambi_dec.c:907
void ambi_dec_setChOrder(void *const hAmbi, int newOrder)
Sets the Ambisonic channel ordering convention to decode with, in order to match the convention emplo...
Definition ambi_dec.c:799
int ambi_dec_getDecNormType(void *const hAmbi, int index)
Returns the current equalisation approach for one of the decoders (see AMBI_DEC_DIFFUSE_FIELD_EQ_APPR...
Definition ambi_dec.c:982
int ambi_dec_getDecOrder(void *const hAmbi, int bandIdx)
Returns the decoding order for a given frequency band index (see SH_ORDERS enum)
Definition ambi_dec.c:870
void ambi_dec_getProgressBarText(void *const hAmbi, char *text)
(Optional) Returns current intialisation/processing progress text
Definition ambi_dec.c:858
int ambi_dec_getFrameSize(void)
Returns the processing framesize (i.e., number of samples processed with every _process() call )
Definition ambi_dec.c:841
int ambi_dec_getNormType(void *const hAmbi)
Returns the Ambisonic normalisation convention currently being usedto decode with,...
Definition ambi_dec.c:964
int ambi_dec_getHRIRsamplerate(void *const hAmbi)
Returns the HRIR sample rate.
Definition ambi_dec.c:994
void ambi_dec_setDecEnableMaxrE(void *const hAmbi, int index, int newID)
Sets a flag to enable/disable (1 or 0) the max_rE weighting for one of the decoders.
Definition ambi_dec.c:820
void ambi_dec_initCodec(void *const hAmbi)
Intialises the codec variables, based on current global/user parameters.
Definition ambi_dec.c:185
void ambi_dec_setSofaFilePath(void *const hAmbi, const char *path)
Sets the file path for a .sofa file, in order to employ a custom HRIR set for the decoding.
Definition ambi_dec.c:702
int ambi_dec_getUseDefaultHRIRsflag(void *const hAmbi)
Returns the value of a flag used to dictate whether the default HRIRs in the Spatial_Audio_Framework ...
Definition ambi_dec.c:936
void ambi_dec_setSourcePreset(void *const hAmbi, int newPresetID)
Sets the source preset (ideal SH or SH signals derived from mic arrays)
Definition ambi_dec.c:733
void ambi_dec_refreshSettings(void *const hAmbi)
Sets all intialisation flags to 1.
Definition ambi_dec.c:610
void ambi_dec_getDecOrderHandle(void *const hAmbi, float **pX_vector, int **pY_values, int *pNpoints)
Returns handles for the decoding orders and frequency vector.
Definition ambi_dec.c:883
int ambi_dec_getDecOrderAllBands(void *const hAmbi)
Returns the decoding order for the first band (see SH_ORDERS enum)
Definition ambi_dec.c:876
void ambi_dec_setOutputConfigPreset(void *const hAmbi, int newPresetID)
Sets the output loudspeaker preset.
Definition ambi_dec.c:722
int ambi_dec_getProcessingDelay(void)
Returns the processing delay in samples; may be used for delay compensation features.
Definition ambi_dec.c:1007
void ambi_dec_setDecNormType(void *const hAmbi, int index, int newID)
Sets the equalisation approach for one of the decoders.
Definition ambi_dec.c:826
int ambi_dec_getNumberOfBands(void)
Returns the number of frequency bands employed by ambi_dec.
Definition ambi_dec.c:896
float ambi_dec_getTransitionFreq(void *const hAmbi)
Returns the frequency (in Hz) at which to transition from the low frequency decoder to the high frequ...
Definition ambi_dec.c:988
void ambi_dec_setDecMethod(void *const hAmbi, int index, int newID)
Sets the decoding method for a specific decoder.
Definition ambi_dec.c:813
char * ambi_dec_getSofaFilePath(void *const hAmbi)
Returns the file path for a .sofa file (WITH file extension)
Definition ambi_dec.c:942
void ambi_dec_setLoudspeakerElev_deg(void *const hAmbi, int index, float newElev_deg)
Sets the elevation of a specific loudspeaker.
Definition ambi_dec.c:658
CODEC_STATUS ambi_dec_getCodecStatus(void *const hAmbi)
Returns current codec status (see CODEC_STATUS enum)
Definition ambi_dec.c:846
void ambi_dec_setUseDefaultHRIRsflag(void *const hAmbi, int newState)
Sets flag to dictate whether the default HRIRs in the Spatial_Audio_Framework should be used (1),...
Definition ambi_dec.c:692
void ambi_dec_setMasterDecOrder(void *const hAmbi, int newValue)
Sets the master decoding order.
Definition ambi_dec.c:617
int ambi_dec_getDecMethod(void *const hAmbi, int index)
Returns the currently selected decoding method (see AMBI_DEC_DECODING_METHODS enum)
Definition ambi_dec.c:970
void ambi_dec_setEnableHRIRsPreProc(void *const hAmbi, int newState)
Enable (1) or disable (0) the pre-processing applied to the HRTFs.
Definition ambi_dec.c:713
int ambi_dec_getChOrder(void *const hAmbi)
Returns the Ambisonic channel ordering convention currently being used to decode with,...
Definition ambi_dec.c:958
void ambi_dec_init(void *const hAmbi, int sampleRate)
Initialises an instance of ambi_dec with default settings.
Definition ambi_dec.c:171
void ambi_dec_setTransitionFreq(void *const hAmbi, float newValue)
Sets the frequeny at which to transition from the low frequency decoder to the high frequency decoder...
Definition ambi_dec.c:832
void ambi_dec_setLoudspeakerAzi_deg(void *const hAmbi, int index, float newAzi_deg)
Sets the azimuth of a specific loudspeaker.
Definition ambi_dec.c:644
void ambi_dec_setNumLoudspeakers(void *const hAmbi, int new_nLoudspeakers)
Sets the number of loudspeakers to decode to.
Definition ambi_dec.c:670
void ambi_dec_setNormType(void *const hAmbi, int newType)
Sets the Ambisonic normalisation convention to decode with, in order to match with the convention emp...
Definition ambi_dec.c:806
int ambi_dec_getDecEnableMaxrE(void *const hAmbi, int index)
Returns the value of a flag used to dictate whether the max_rE weighting is being applied by a given ...
Definition ambi_dec.c:976
int ambi_dec_getBinauraliseLSflag(void *const hAmbi)
Returns the value of a flag used to dictate whether the loudspeaker signals should be binauralised (0...
Definition ambi_dec.c:930
void ambi_dec_destroy(void **const phAmbi)
Destroys an instance of the ambi_dec.
Definition ambi_dec.c:120
int ambi_dec_getDAWsamplerate(void *const hAmbi)
Returns the DAW/Host sample rate.
Definition ambi_dec.c:1001
float ambi_dec_getLoudspeakerAzi_deg(void *const hAmbi, int index)
Returns the loudspeaker azimuth in degrees for a given index.
Definition ambi_dec.c:901
#define AMBI_DEC_TRANSITION_MIN_VALUE
Minimum transition value between low/high frequency decoders, in Hz.
Definition ambi_dec.h:99
#define AMBI_DEC_TRANSITION_MAX_VALUE
Maximum transition value between low/high frequency decoders, in Hz.
Definition ambi_dec.h:102
AMBI_DEC_DIFFUSE_FIELD_EQ_APPROACH
When using mixed order decoding (i.e.
Definition ambi_dec.h:92
@ AMPLITUDE_PRESERVING
preserve omni amplitude
Definition ambi_dec.h:93
@ ENERGY_PRESERVING
preserve omni energy
Definition ambi_dec.h:94
@ DECODING_METHOD_SAD
Sampling Ambisonic Decoder (SAD)
Definition ambi_dec.h:74
@ DECODING_METHOD_MMD
Mode-Matching Decoder (MMD)
Definition ambi_dec.h:75
@ DECODING_METHOD_EPAD
Energy-Preserving Ambisonic Decoder (EPAD)
Definition ambi_dec.h:76
@ DECODING_METHOD_ALLRAD
All-Round Ambisonic Decoder (AllRAD)
Definition ambi_dec.h:77
void ambi_dec_setCodecStatus(void *const hAmbi, CODEC_STATUS newStatus)
Sets codec status (see CODEC_STATUS enum)
void ambi_dec_interpHRTFs(void *const hAmbi, float azimuth_deg, float elevation_deg, float_complex h_intrp[HYBRID_BANDS][NUM_EARS])
Interpolates between the 3 nearest HRTFs using amplitude-preserving VBAP gains.
void loadLoudspeakerArrayPreset(LOUDSPEAKER_ARRAY_PRESETS preset, _Atomic_FLOAT32 dirs_deg[MAX_NUM_LOUDSPEAKERS][2], _Atomic_INT32 *newNCH, int *nDims)
Returns the loudspeaker directions for a specified loudspeaker array preset.
A frequency-dependent Ambisonic decoder for reproducing Ambisonic sound scenes over loudspeakers.
#define MIN_NUM_LOUDSPEAKERS
To avoid triangulation errors when using AllRAD.
#define AMBI_DEC_FRAME_SIZE
Framesize, in time-domain samples.
#define MAX_NUM_LOUDSPEAKERS
Maximum permitted output channels.
#define NUM_DECODERS
One for low-frequencies and another for high-frequencies.
void convertHOAChannelConvention(float *insig, int order, int signalLength, HOA_CH_ORDER inConvention, HOA_CH_ORDER outConvention)
Converts an Ambisonic signal from one channel ordering convention to another.
Definition saf_hoa.c:41
void getLoudspeakerDecoderMtx(float *ls_dirs_deg, int nLS, LOUDSPEAKER_AMBI_DECODER_METHODS method, int order, int enableMaxReWeighting, float *decMtx)
Computes an ambisonic decoding matrix of a specific order, for a given loudspeaker layout.
Definition saf_hoa.c:327
void convertHOANormConvention(float *insig, int order, int signalLength, HOA_NORM inConvention, HOA_NORM outConvention)
Converts an Ambisonic signal from one normalisation convention to another.
Definition saf_hoa.c:73
void getMaxREweights(int order, int diagMtxFlag, float *a_n)
Computes the weights required to manipulate a hyper-cardioid beam-pattern, such that it has maximum e...
Definition saf_hoa.c:236
@ HOA_CH_ORDER_FUMA
Furse-Malham (FuMa) convention, often used by older recordings.
Definition saf_hoa.h:187
@ HOA_CH_ORDER_ACN
Ambisonic Channel numbering (ACN) convention, which is employed by all spherical harmonic related fun...
Definition saf_hoa.h:184
@ LOUDSPEAKER_DECODER_ALLRAD
All-Round Ambisonic Decoder (AllRAD): SAD decoding to a t-design, panned for the target loudspeaker d...
Definition saf_hoa.h:109
@ LOUDSPEAKER_DECODER_SAD
Sampling Ambisonic Decoder (SAD): transpose of the loudspeaker spherical harmonic matrix,...
Definition saf_hoa.h:76
@ LOUDSPEAKER_DECODER_EPAD
Energy-Preserving Ambisonic Decoder (EPAD) [1].
Definition saf_hoa.h:96
@ LOUDSPEAKER_DECODER_MMD
Mode-Matching Decoder (MMD): pseudo-inverse of the loudspeaker spherical harmonic matrix.
Definition saf_hoa.h:89
@ HOA_NORM_FUMA
Furse-Malham (FuMa) convention.
Definition saf_hoa.h:208
@ HOA_NORM_SN3D
Schmidt semi-normalisation (SN3D) convention, as used by the AmbiX standard.
Definition saf_hoa.h:206
@ HOA_NORM_N3D
Orthonormalised (N3D) convention, which is the default convention used by SAF.
Definition saf_hoa.h:204
const int __default_N_hrir_dirs
The number of directions/measurements in the default HRIR dataset.
const float __default_hrirs[836][2][256]
The default HRIR data for SAF.
const float __default_hrir_dirs_deg[836][2]
The measurement directions used for the default HRIR dataset.
const int __default_hrir_len
The length of the filters, in samples, for the default HRIR dataset.
const int __default_hrir_fs
The samplerate used to measure the default HRIR filters.
void diffuseFieldEqualiseHRTFs(int N_dirs, float *itds_s, float *centreFreq, int N_bands, float *weights, int applyEQ, int applyPhase, float_complex *hrtfs)
Applies pre-processing to a set of HRTFs, which can either be diffuse-field EQ of an (optionally weig...
Definition saf_hrir.c:174
void estimateITDs(float *hrirs, int N_dirs, int hrir_len, int fs, float *itds_s)
Estimates the interaural time-differences (ITDs) for each HRIR based on the cross-correlation between...
Definition saf_hrir.c:41
void HRIRs2HRTFs_afSTFT(float *hrirs, int N_dirs, int hrir_len, int hopsize, int LDmode, int hybridmode, float_complex *hrtf_fb)
Passes zero padded HRIRs through the afSTFT filterbank.
Definition saf_hrir.c:111
#define ORDER2NSH(order)
Converts spherical harmonic order to number of spherical harmonic components i.e: (order+1)^2.
Definition saf_sh.h:51
int calculateGridWeights(float *dirs_rad, int nDirs, int order, float *w)
Computes approximation of quadrature/integration weights for a given grid.
Definition saf_sh.c:1066
void getSHreal(int order, float *dirs_rad, int nDirs, float *Y)
Computes real-valued spherical harmonics [1] for each given direction on the unit sphere.
Definition saf_sh.c:191
void saf_sofa_close(saf_sofa_container *c)
Frees all SOFA data in a sofa_container.
SAF_SOFA_ERROR_CODES saf_sofa_open(saf_sofa_container *h, char *sofa_filepath, SAF_SOFA_READER_OPTIONS option)
Fills a 'sofa_container' with data found in a SOFA file (GeneralFIR or SimpleFreeFieldHRIR),...
SAF_SOFA_ERROR_CODES
SOFA loader error codes.
@ SAF_SOFA_READER_OPTION_DEFAULT
The default option is SAF_SOFA_READER_OPTION_LIBMYSOFA.
@ SAF_SOFA_OK
None of the error checks failed.
#define SAF_CLAMP(a, min, max)
Ensures value "a" is clamped between the "min" and "max" values.
#define SAF_PI
pi constant (single precision)
#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.
const float __Tdesign_degree_30_dirs_deg[480][2]
Directions [azimuth, Elevation] in degrees, for minimum Tdesign degree: 30.
#define SAF_MIN(a, b)
Returns the minimum of the two values.
void sphElev2incl(float *dirsElev, int nDirs, int degreesFlag, float *dirsIncl)
Converts spherical coordinates of unit length from elevation to inclination.
const float __Eigenmike32_freqRange[6]
Sensor array frequency ranges for each SH order, for the Eigenmike32 (should only be used as a rough ...
#define saf_print_warning(message)
Macro to print a warning message along with the filename and line number.
const int __Eigenmike32_maxOrder
Max spherical harmonic order for the Eigenmike32.
const float __Zylia_freqRange[4]
Sensor array frequency ranges for each SH order, for the Zylia array (should only be used as a rough ...
const int __DTU_mic_maxOrder
Max spherical harmonic order for the custom 52-sensor array built at the Technical University of Denm...
const float __DTU_mic_freqRange[10]
Sensor array frequency ranges for each SH order, for the DTU mic (should only be used as a rough esti...
const int __Zylia_maxOrder
Max spherical harmonic order for the Zylia mic.
void generateVBAPgainTable3D(float *ls_dirs_deg, int L, int az_res_deg, int el_res_deg, int omitLargeTriangles, int enableDummies, float spread, float **gtable, int *N_gtable, int *nTriangles)
Generates a 3-D VBAP gain table based on specified loudspeaker directions, with optional spreading [2...
Definition saf_vbap.c:172
void compressVBAPgainTable3D(float *vbap_gtable, int nTable, int nDirs, float *vbap_gtableComp, int *vbap_gtableIdx)
Compresses a VBAP gain table to use less memory and CPU (by removing the elements which are just zero...
Definition saf_vbap.c:313
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 FLATTEN2D(A)
Use this macro when passing a 2-D dynamic multi-dimensional array to memset, memcpy or any other func...
Definition md_malloc.h:65
#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
Contains variables for sofa file loading, HRTF interpolation, and the loudspeaker decoders.
_Atomic_INT32 N_hrir_dirs
number of HRIR directions in the current sofa file
float_complex hrtf_interp[MAX_NUM_LOUDSPEAKERS][HYBRID_BANDS][NUM_EARS]
interpolated HRTFs
_Atomic_INT32 hrir_len
length of the HRIRs, this can be truncated, see "saf_sofa_reader.h"
char * sofa_filepath
absolute/relevative file path for a sofa file
float * M_dec_maxrE[NUM_DECODERS][MAX_SH_ORDER]
ambisonic decoding matrices with maxrE weighting ([0] for low-freq, [1] for high-freq); FLAT: nLoudsp...
float * M_dec[NUM_DECODERS][MAX_SH_ORDER]
ambisonic decoding matrices ([0] for low-freq, [1] for high-freq); FLAT: nLoudspeakers x nSH
int hrtf_nTriangles
number of triangle groups after triangulation
float * itds_s
interaural-time differences for each HRIR (in seconds); N_hrirs x 1
int * hrtf_vbap_gtableIdx
N_hrtf_vbap_gtable x 3.
int hrtf_vbapTableRes[2]
[azi elev] step sizes in degrees
float_complex * hrtf_fb
HRTF filterbank coefficients; nBands x nCH x N_hrirs.
float_complex * M_dec_cmplx_maxrE[NUM_DECODERS][MAX_SH_ORDER]
complex ambisonic decoding matrices with maxrE weighting ([0] for low-freq, [1] for high-freq); FLAT:...
_Atomic_INT32 hrir_fs
sampling rate of the HRIRs, should ideally match the host sampling rate, although not required
float * hrtf_fb_mag
magnitudes of the HRTF filterbank coefficients; nBands x nCH x N_hrirs
int N_hrtf_vbap_gtable
number of interpolation directions
float_complex * M_dec_cmplx[NUM_DECODERS][MAX_SH_ORDER]
complex ambisonic decoding matrices ([0] for low-freq, [1] for high-freq); FLAT: nLoudspeakers x nSH
float * weights
grid integration weights of hrirs; N_hrirs x 1
float * hrtf_vbap_gtableComp
N_hrtf_vbap_gtable x 3.
float * hrirs
time domain HRIRs; N_hrir_dirs x 2 x hrir_len
float M_norm[NUM_DECODERS][MAX_SH_ORDER][2]
norm coefficients to preserve omni energy/amplitude between different orders and decoders
float * hrir_dirs_deg
directions of the HRIRs in degrees [azi elev]; N_hrir_dirs x 2
Main structure for ambi_dec.
_Atomic_AMBI_DEC_DIFFUSE_FIELD_EQ_APPROACH diffEQmode[NUM_DECODERS]
diffuse-field EQ approach; see AMBI_DEC_DIFFUSE_FIELD_EQ_APPROACH enum
_Atomic_INT32 masterOrder
Current maximum/master decoding order.
_Atomic_INT32 new_masterOrder
if new_masterOrder != masterOrder, ambi_dec is reinitialised (current value will be replaced by this ...
_Atomic_INT32 reinit_hrtfsFLAG
0: no init required, 1: init required
_Atomic_CH_ORDER chOrdering
Ambisonic channel order convention (see CH_ORDER)
_Atomic_INT32 nLoudpkrs
number of loudspeakers/virtual loudspeakers
int loudpkrs_nDims
dimensionality of the current loudspeaker set-up
float ** SHFrameTD
Input spherical harmonic (SH) signals in the time-domain; MAX_NUM_SH_SIGNALS x AMBI_DEC_FRAME_SIZE.
_Atomic_FLOAT32 transitionFreq
transition frequency for the 2 decoders, in Hz
float_complex *** binframeTF
Output binaural signals in the time-frequency domain; HYBRID_BANDS x NUM_EARS x TIME_SLOTS.
_Atomic_INT32 recalc_hrtf_interpFLAG[MAX_NUM_LOUDSPEAKERS]
0: no init required, 1: init required
_Atomic_INT32 enableHRIRsPreProc
flag to apply pre-processing to the currently loaded HRTFs
_Atomic_NORM_TYPES norm
Ambisonic normalisation convention (see NORM_TYPES)
_Atomic_FLOAT32 loudpkrs_dirs_deg[MAX_NUM_LOUDSPEAKERS][2]
loudspeaker directions in degrees [azi, elev]
_Atomic_INT32 orderPerBand[HYBRID_BANDS]
Ambisonic decoding order per frequency band 1..SH_ORDER.
_Atomic_AMBI_DEC_DECODING_METHODS dec_method[NUM_DECODERS]
decoding methods for each decoder, see AMBI_DEC_DECODING_METHODS enum
void * hSTFT
afSTFT handle
_Atomic_INT32 useDefaultHRIRsFLAG
1: use default HRIRs in database, 0: use those from SOFA file
float_complex *** SHframeTF
Input spherical harmonic (SH) signals in the time-frequency domain; HYBRID_BANDS x MAX_NUM_SH_SIGNALS...
float ** outputFrameTD
Output loudspeaker or binaural signals in the time-domain; MAX_NUM_LOUDSPEAKERS x AMBI_DEC_FRAME_SIZE...
_Atomic_INT32 new_binauraliseLS
if new_binauraliseLS != binauraliseLS, ambi_dec is reinitialised (current value will be replaced by t...
_Atomic_PROC_STATUS procStatus
see PROC_STATUS
_Atomic_INT32 binauraliseLS
1: convolve loudspeaker signals with HRTFs, 0: output loudspeaker signals
_Atomic_INT32 fs
host sampling rate
_Atomic_CODEC_STATUS codecStatus
see CODEC_STATUS
_Atomic_INT32 rE_WEIGHT[NUM_DECODERS]
0:disabled, 1: enable max_rE weight
float freqVector[HYBRID_BANDS]
frequency vector for time-frequency transform, in Hz
char * progressBarText
Current (re)initialisation step, string.
_Atomic_FLOAT32 progressBar0_1
Current (re)initialisation progress, between [0..1].
ambi_dec_codecPars * pars
codec parameters
float_complex *** outputframeTF
Output loudspeaker signals in the time-frequency domain; HYBRID_BANDS x MAX_NUM_LOUDSPEAKERS x TIME_S...
_Atomic_INT32 new_nLoudpkrs
if new_nLoudpkrs != nLoudpkrs, afSTFT is reinitialised (current value will be replaced by this after ...
SOFA container struct comprising all possible data that can be extracted from SOFA 1....
int DataLengthIR
Length of the IRs, in samples.
int nSources
Number of source/measurement positions.
float * SourcePosition
Source positions (refer to SourcePositionType & SourcePositionUnits for the convention and units); FL...
float DataSamplingRate
Sampling rate used to measure the IRs.
int nReceivers
Number of ears/number of mics etc.
float * DataIR
The impulse response (IR) Data; FLAT:nSources x nReceivers x DataLengthIR.