41#ifdef SAF_ENABLE_HADES_MODULE
68 float_complex *U, *E, *H_W;
69 const float_complex calpha = cmplxf(1.0f, 0.0f);
const float_complex cbeta = cmplxf(0.0f, 0.0f);
72 assert(blocksize % hopsize == 0);
82 memcpy(a->
h_array, h_array, nGrid*nMics*h_len*
sizeof(
float));
84 memcpy(a->
grid_dirs_deg, grid_dirs_deg, nGrid*2*
sizeof(
float));
95 cblas_sscal(nGrid*nMics*h_len, 1.0f/a->
h_array[idx_max], a->
h_array, 1);
124 for(i=0; i<a->
nGrid; i++)
125 a->
W[i*(a->
nGrid)+i] = cmplxf(1.0f, 0.0f);
130 for(i=0; i<a->
nGrid; i++)
131 a->
W[i*(a->
nGrid)+i] = cmplxf(w_tmp[i], 0.0f);
140 for(band=0; band<a->
nBands; band++){
142 cblas_cgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, a->
nMics, a->
nGrid, a->
nGrid, &calpha,
146 cblas_cgemm(CblasRowMajor, CblasNoTrans, CblasConjTrans, a->
nMics, a->
nMics, a->
nGrid, &calpha,
156 for(i=0; i<a->
nMics; i++)
157 E[i*a->
nMics+i] = cmplxf(sqrtf(1.0f/(crealf(E[i*a->
nMics+i])+2.23e-10f)), 0.0f);
158 cblas_cgemm(CblasRowMajor, CblasNoTrans, CblasConjTrans, a->
nMics, a->
nMics, a->
nMics, &calpha,
164 cblas_cgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, a->
nMics, a->
nGrid, a->
nMics, &calpha,
240 for(band=0; band<a->
nBands; band++)
257 int i, j, k, ch, band, est_idx;
259 CxMic Cx_new, T_Cx, T_Cx_TH;
260 const float_complex calpha = cmplxf(1.0f, 0.0f);
const float_complex cbeta = cmplxf(0.0f, 0.0f);
266 cblas_scopy(blocksize, input[ch], 1, a->
inputBlock[ch], 1);
267 for(; ch<a->
nMics; ch++)
268 memset(a->
inputBlock[ch], 0, blocksize*
sizeof(
float));
277 for(band=0; band<a->
nBands; band++){
278 cblas_cgemm(CblasRowMajor, CblasNoTrans, CblasConjTrans, a->
nMics, a->
nMics, a->
timeSlots, &calpha,
281 Cx_new.Cx, a->
nMics);
284 cblas_ccopy(a->
nMics*a->
nMics, (float_complex*)Cx_new.Cx, 1, (float_complex*)scon->
Cx[band].Cx, 1);
292 for (band = 0; band < a->
nBands; band++) {
294 cblas_cgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, a->
nMics, a->
nMics, a->
nMics, &calpha,
296 a->
Cx[band].Cx, a->
nMics, &cbeta,
298 cblas_cgemm(CblasRowMajor, CblasNoTrans, CblasConjTrans, a->
nMics, a->
nMics, a->
nMics, &calpha,
300 a->
T[band], a->
nMics, &cbeta,
301 T_Cx_TH.Cx, a->
nMics);
318 for(i=0; i<a->
nMics; i++)
319 for(j=0, k=1; j<a->
nMics-1; j++, k++)
388 *phPCon = (
void*)pcon;
432 *phSCon = (
void*)scon;
void afSTFT_FIRtoFilterbankCoeffs(float *hIR, int N_dirs, int nCH, int ir_len, int hopSize, int LDmode, int hybridmode, float_complex *hFB)
Converts FIR filters into Filterbank Coefficients by passing them through the afSTFT filterbank.
int afSTFT_getNBands(void *const hSTFT)
Returns number of frequency bands.
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.
int afSTFT_getProcDelay(void *const hSTFT)
Returns current processing delay, in samples.
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)
void afSTFT_getCentreFreqs(void *const hSTFT, float fs, int nBands, float *freqVector)
Returns current frequency vector.
void afSTFT_destroy(void **const phSTFT)
Destroys an instance of afSTFT.
@ AFSTFT_BANDS_CH_TIME
nBands x nChannels x nTimeHops
#define SAF_CLAMP(a, min, max)
Ensures value "a" is clamped between the "min" and "max" values.
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_cseig_destroy(void **const phWork)
De-allocate the working struct used by utility_cseig()
void utility_cseig(void *const hWork, const float_complex *A, const int dim, int sortDecFLAG, float_complex *V, float_complex *D, float *eig)
Eigenvalue decomposition of a SYMMETRIC/HERMITION matrix: single precision complex,...
void utility_cseig_create(void **const phWork, int maxDim)
(Optional) Pre-allocate the working struct used by utility_cseig()
#define SAF_MIN(a, b)
Returns the minimum of the two values.
void unitSph2cart(float *dirs, int nDirs, int anglesInDegreesFLAG, float *dirs_xyz)
Converts spherical coordinates to Cartesian coordinates of unit length.
void utility_simaxv(const float *a, const int len, int *index)
Single-precision, index of maximum absolute value in a vector, i.e.
void ** malloc2d(size_t dim1, size_t dim2, size_t data_size)
2-D malloc (contiguously allocated, so use free() as usual to deallocate)
void * malloc1d(size_t dim1_data_size)
1-D malloc (same as malloc, but with error checking)
void * calloc1d(size_t dim1, size_t data_size)
1-D calloc (same as calloc, 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 FLATTEN2D(A)
Use this macro when passing a 2-D dynamic multi-dimensional array to memset, memcpy or any other func...
void hades_analysis_reset(hades_analysis_handle const hAna)
Flushes run-time buffers with zeros.
const float * hades_analysis_getFrequencyVectorPtr(hades_analysis_handle const hAna, int *nBands)
Returns a pointer to the frequency vector (read-only)
int hades_analysis_getProcDelay(hades_analysis_handle const hAna)
Returns the analyser processing delay, in samples.
void hades_param_container_destroy(hades_param_container_handle *const phPCon)
Destroys an instance of a hades parameter container.
void hades_analysis_destroy(hades_analysis_handle *const phAna)
Destroys an instance of a hades analysis object.
void hades_signal_container_create(hades_signal_container_handle *const phSCon, hades_analysis_handle const hAna)
Creates an instance of a container used for storing the TF-domain audio returned by an analyser for o...
void hades_analysis_create(hades_analysis_handle *const phAna, float fs, HADES_FILTERBANKS fbOption, int hopsize, int blocksize, int hybridmode, float *h_array, float *grid_dirs_deg, int nGrid, int nMics, int h_len, HADES_DIFFUSENESS_ESTIMATORS diffOption, HADES_DOA_ESTIMATORS doaOption)
Creates and returns a handle to an instance of a hades analysis object.
void hades_param_container_create(hades_param_container_handle *const phPCon, hades_analysis_handle const hAna)
Creates an instance of a container used for storing the parameters estimated by an analyser for one '...
int hades_analysis_getNbands(hades_analysis_handle const hAna)
Returns number of frequency bands (0 if hAna is not initialised)
float * hades_analysis_getCovarianceAvagingCoeffPtr(hades_analysis_handle const hAna)
Returns a pointer to the covariance matrix averaging scalar [0..1], which can be changed at run-time.
void hades_analysis_apply(hades_analysis_handle const hAna, float **input, int nChannels, int blocksize, void *const hPCon, void *const hSCon)
Performs hades encoding: forward time-frequency transform, diffuseness and DoA estimation per band.
void hades_signal_container_destroy(hades_signal_container_handle *const phSCon)
Destroys an instance of a hades signal container.
Header for the HADES analysis (SAF_HADES_MODULE)
#define HADES_MAX_NMICS
Maximum number of microphones.
struct _hades_analysis_data * hades_analysis_handle
Handle for the hades analysis data.
struct _hades_param_container_data * hades_param_container_handle
Handle for the hades parameter container data.
struct _hades_signal_container_data * hades_signal_container_handle
Handle for the hades signal container data.
HADES_FILTERBANKS
Filterbank options.
@ HADES_USE_AFSTFT
Alias-free STFT filterbank.
@ HADES_USE_AFSTFT_LD
Alias-free STFT filterbank (low delay)
HADES_DOA_ESTIMATORS
Options for DoA estimation for hades_analysis.
@ HADES_USE_MUSIC
Use MUSIC.
HADES_DIFFUSENESS_ESTIMATORS
Options for diffuseness estimation for hades_analysis.
@ HADES_USE_COMEDIE
As in [1], after spatially whitening the array SCM.
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_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)
#define HADES_MAX_BLOCKSIZE
Maximum supported blocksize.
Helper struct for averaging covariance matrices (block-wise)
Main structure for hades analysis.
int nMics
Number of microphones.
float covAvgCoeff
Temporal averaging coefficient [0 1].
float_complex ** T
for covariance whitening; nBands x (nMics x nMics)
int blocksize
Number of samples to process at a time (note that 1 doa and diffuseness estimate is made per block)
int hybridmode
Optionally, the lowest TF bands may be subdivided to improve low-freq resolution.
void * hEig
handle for the eigen solver
float_complex * DCM_array
Diffuse covariance matrix (computed over all grid directions and weighted); FLAT: nBands x nMics x nM...
float * grid_dirs_xyz
Scanning grid coordinates (unit vectors and only used by grid-based estimators); FLAT: nGrid x 3.
float * h_array
Array impulse responses; FLAT: nGrid x nMics x h_len.
float * freqVector
Centre frequencies; nBands x 1.
HADES_DOA_ESTIMATORS doaOpt
see HADES_DOA_ESTIMATORS
float * grid_dirs_deg
Array grid dirs in degrees; FLAT: nGrid x 2.
float ** inputBlock
Input frame; nMics x blocksize.
int hopsize
Filterbank hop size (blocksize must be divisable by this.
float_complex * V
Eigen vectors; FLAT: nMics x nMics.
HADES_FILTERBANKS fbOpt
see HADES_FILTERBANKS
float_complex * H_array_w
Array IRs in the frequency domain spatially weightend; FLAT: nBands x nMics x nDirs.
void * hFB_enc
Time-frequency transform handle.
float_complex * W
Diffuse integration weighting matrix; FLAT: nGrid x nGrid.
int h_len
Length of impulse responses, in samples.
float * lambda
Eigenvalues; nMics x 1.
CxMic * Cx
Current (time-averaged) covariance matrix per band; nBands x 1.
float_complex * H_array
Array IRs in the frequency domain; FLAT: nBands x nMics x nDirs.
float fs
Host samplerate, Hz.
int filterbankDelay
Filterbank delay, in time-domain samples.
int nBands
Number of frequency bands.
void * hDoA
DoA estimator handle.
int timeSlots
Number of time slots.
float_complex * Vn
Noise subspace; FLAT: nMics x (nMics-1)
HADES_DIFFUSENESS_ESTIMATORS diffOpt
see HADES_DIFFUSENESS_ESTIMATORS
int nGrid
Number of grid/scanning directions.
Parameter container to store the data from an analyser for one blocksize of audio.
int * gains_idx
Reproduction direction index per band; nBands x 1.
int * doa_idx
Beamforming direction index per band; nBands x 1.
float * diffuseness
Diffuseness value per band; nBands x 1.
float * gains_diff
Extra diffuse reproduction gain per band (default=1.0f); nBands x 1
int nBands
Number of bands.
float * gains_dir
Extra direct reproduction gain per band (default=1.0f); nBands x 1
Signal container to store one block of TF-domain audio data.
int nBands
Number of bands in the time-frequency transform.
int nMics
Number of spherical harmonic components.
int timeSlots
Number of time frames in time-frequency transform.
CxMic * Cx
NON-time-averaged covariance matrix per band; nBands x .Cx(nMics x nMics)
float_complex *** inTF
Input frame in TF-domain; nBands x nMics x timeSlots.