40#ifdef SAF_ENABLE_HADES_MODULE
47 float* target_dirs_deg,
49 float_complex* hrtf_interp
53 int band, i, j, ntable, ntri;
55 float* itds_s, *interpTable, *w;
56 float_complex*** hrtf_fb;
66 if (cblas_sasum(nTargetDirs, target_dirs_deg+1, 2)/(
float)nTargetDirs<0.0001)
69 w =
malloc1d(nTargetDirs*
sizeof(
float));
81 idx =
malloc1d(nTargetDirs*
sizeof(
int));
83 for(band=0; band<a->
nBands; band++)
85 for(j=0; j<nTargetDirs; j++)
86 hrtf_interp[band*
NUM_EARS*nTargetDirs + i*nTargetDirs + j] = hrtf_fb[band][i][idx[j]];
117typedef struct _hades_sdMUSIC_data {
120 float* grid_dirs_xyz;
131 void **
const phMUSIC,
133 float* grid_dirs_deg,
144 h->grid_dirs_xyz =
malloc1d(h->nDirs * 3 *
sizeof(
float));
145 unitSph2cart(grid_dirs_deg, h->nDirs, 1, h->grid_dirs_xyz);
148 h->VnA =
malloc1d(h->nMics * (h->nDirs) *
sizeof(float_complex));
149 h->abs_VnA =
malloc1d(h->nMics * (h->nDirs) *
sizeof(
float));
150 h->pSpec =
malloc1d(h->nDirs*
sizeof(
float));
151 h->pSpecInv =
malloc1d(h->nDirs*
sizeof(
float));
152 h->P_minus_peak =
malloc1d(h->nDirs*
sizeof(
float));
153 h->VM_mask =
malloc1d(h->nDirs*
sizeof(
float));
158 void **
const phMUSIC
164 free(h->grid_dirs_xyz);
169 free(h->P_minus_peak);
180 float_complex* A_grid,
188 int i, k, VnD2, peak_idx;
191 const float_complex calpha = cmplxf(1.0f, 0.0f);
const float_complex cbeta = cmplxf(0.0f, 0.0f);
193 VnD2 = h->nMics - nSrcs;
196 cblas_cgemm(CblasRowMajor, CblasConjTrans, CblasNoTrans, h->nDirs, VnD2, h->nMics, &calpha,
201 for (i = 0; i < (h->nDirs); i++)
202 h->pSpecInv[i] = cblas_sdot(VnD2, &(h->abs_VnA[i*VnD2]), 1, &(h->abs_VnA[i*VnD2]), 1);
208 cblas_scopy(h->nDirs, h->pSpec, 1, P_music, 1);
213 scale = kappa/(2.0f*
SAF_PI*expf(kappa)-expf(-kappa));
214 cblas_scopy(h->nDirs, h->pSpec, 1, h->P_minus_peak, 1);
217 for(k=0; k<nSrcs; k++){
219 peak_inds[k] = peak_idx;
222 VM_mean[0] = h->grid_dirs_xyz[peak_idx*3];
223 VM_mean[1] = h->grid_dirs_xyz[peak_idx*3+1];
224 VM_mean[2] = h->grid_dirs_xyz[peak_idx*3+2];
227 cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasTrans, h->nDirs, 1, 3, 1.0f,
229 (
const float*)VM_mean, 3, 0.0f,
231 cblas_sscal(h->nDirs, kappa, h->VM_mask, 1);
232 for(i=0; i<h->nDirs; i++)
233 h->VM_mask[i] = expf(h->VM_mask[i]);
234 cblas_sscal(h->nDirs, scale, h->VM_mask, 1);
235 for(i=0; i<h->nDirs; i++)
236 h->VM_mask[i] = 1.0f/(0.00001f+(h->VM_mask[i]));
237 utility_svvmul(h->P_minus_peak, h->VM_mask, h->nDirs, h->P_minus_peak);
249 float Nord, sum, g_0, mean_ev, g, sumAbsDiff;
251 Nord = sqrtf((
float)N)-1.0f;
258 g_0 = 2.0f*(powf(Nord+1.0f,2.0f)-1.0f);
259 mean_ev = (1.0f/(powf(Nord+1.0f,2.0f)))*sum;
262 sumAbsDiff += fabsf(lambda[i]-mean_ev);
263 g = (1.0f/mean_ev)*sumAbsDiff;
266 return SAF_MAX(1.0f-g/g_0, 0.0f);
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...
void interpHRTFs(float_complex *hrtfs, float *itds, float *freqVector, float *interp_table, int N_hrtf_dirs, int N_bands, int N_interp_dirs, float_complex *hrtfs_interp)
Interpolates a set of HRTFs based on a specified interpolation table.
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...
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.
#define SAF_PI
pi constant (single precision)
void utility_svvmul(const float *a, const float *b, const int len, float *c)
Single-precision, element-wise vector-vector multiplication i.e.
#define SAF_MAX(a, b)
Returns the maximum of the two values.
#define NUM_EARS
2 (true for most humans)
void getVoronoiWeights(float *dirs_deg, int nDirs, int diagFLAG, float *weights)
Computes the integration weights, based on the areas of each face of the corresponding Voronoi diagra...
void utility_cvabs(const float_complex *a, const int len, float *c)
Single-precision, complex, absolute values of vector elements, i.e.
void unitSph2cart(float *dirs, int nDirs, int anglesInDegreesFLAG, float *dirs_xyz)
Converts spherical coordinates to Cartesian coordinates of unit length.
void utility_svrecip(const float *a, const int len, float *c)
Single-precision, vector-reciprocal/inversion, i.e.
void findClosestGridPoints(float *grid_dirs, int nGrid, float *target_dirs, int nTarget, int degFLAG, int *idx_closest, float *dirs_closest, float *angle_diff)
Finds indicies into "grid_dirs" that are the closest to "target dirs".
void utility_simaxv(const float *a, const int len, int *index)
Single-precision, index of maximum absolute value in a vector, i.e.
void generateVBAPgainTable3D_srcs(float *src_dirs_deg, int S, float *ls_dirs_deg, int L, int omitLargeTriangles, int enableDummies, float spread, float **gtable, int *N_gtable, int *nTriangles)
Generates a 3-D VBAP [1] gain table based on specified source and loudspeaker directions,...
void VBAPgainTable2InterpTable(float *vbap_gtable, int nTable, int nDirs)
Renormalises a VBAP gain table (in-place) so it may be utilised for interpolation of data (for exampl...
void * malloc1d(size_t dim1_data_size)
1-D malloc (same as malloc, but with error checking)
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)
#define FLATTEN3D(A)
Use this macro when passing a 3-D dynamic multi-dimensional array to memset, memcpy or any other func...
struct _hades_analysis_data * hades_analysis_handle
Handle for the hades analysis data.
@ HADES_USE_AFSTFT
Alias-free STFT filterbank.
@ HADES_USE_AFSTFT_LD
Alias-free STFT filterbank (low delay)
void hades_sdMUSIC_destroy(void **const phMUSIC)
Destroys an instance of the spherical harmonic domain MUSIC implementation, which may be used for com...
void hades_sdMUSIC_create(void **const phMUSIC, int nMics, float *grid_dirs_deg, int nDirs)
Creates an instance of the space-domain MUSIC implementation.
void hades_getInterpolatedHRTFs(hades_analysis_handle const hAna, HADES_HRTF_INTERP_OPTIONS interpOption, hades_binaural_config *binConfig, float *target_dirs_deg, int nTargetDirs, float_complex *hrtf_interp)
Binaural filter interpolator.
void hades_sdMUSIC_compute(void *const hMUSIC, float_complex *A_grid, float_complex *Vn, int nSrcs, float *P_music, int *peak_inds)
Computes a pseudo-spectrum based on the MUSIC algorithm optionally returning the grid indices corresp...
float hades_comedie(float *lambda, int N)
Returns an estimate of the diffuseness, based on [1].
Internal header for the HADES module (SAF_HADES_MODULE)
HADES_HRTF_INTERP_OPTIONS
HRTF interpolation options for hades_synthesis.
@ HADES_HRTF_INTERP_NEAREST
Quantise to nearest measurement.
@ HADES_HRTF_INTERP_TRIANGULAR
Triangular interpolation.
Main structure for hades analysis.
int hybridmode
Optionally, the lowest TF bands may be subdivided to improve low-freq resolution.
float * freqVector
Centre frequencies; nBands x 1.
int hopsize
Filterbank hop size (blocksize must be divisable by this.
HADES_FILTERBANKS fbOpt
see HADES_FILTERBANKS
int nBands
Number of frequency bands.
Binaural configuration struct.
int nHRIR
Number of HRIRs.
int hrir_fs
HRIR sample rate.
int lHRIR
Length of HRIRs in samples.
float * hrir_dirs_deg
HRTF directions in [azimuth elevation] format, in degrees; FLAT: nHRIR x 2.
float * hrirs
Matrix of HRIR data; FLAT: nHRIR x NUM_EARS x lHRIR.
Internal data structure for sdMUSIC.