SAF
Loading...
Searching...
No Matches
saf_hades_analysis.c
Go to the documentation of this file.
1/*
2 * This file is part of the saf_hades module.
3 * Copyright (c) 2021 - Leo McCormack & Janani Fernandez
4 *
5 * The saf_hades module is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * The saf_hades module is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * See <http://www.gnu.org/licenses/> for a copy of the GNU General Public
16 * License.
17 */
18
38#include "saf_hades_analysis.h"
39#include "saf_hades_internal.h"
40
41#ifdef SAF_ENABLE_HADES_MODULE
42
43/* ========================================================================== */
44/* HADES Analysis */
45/* ========================================================================== */
46
48(
49 hades_analysis_handle* const phAna,
50 float fs,
51 HADES_FILTERBANKS fbOption,
52 int hopsize,
53 int blocksize,
54 int hybridmode,
55 float* h_array,
56 float* grid_dirs_deg,
57 int nGrid,
58 int nMics,
59 int h_len,
61 HADES_DOA_ESTIMATORS doaOption
62)
63{
65 *phAna = (void*)a;
66 int band, i, idx_max;
67 float* w_tmp;
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); /* blas */
70
71 nMics = SAF_MIN(nMics, HADES_MAX_NMICS);
72 assert(blocksize % hopsize == 0); /* Must be a multiple of hopsize */
73 assert(blocksize<=HADES_MAX_BLOCKSIZE);
74
75 /* User parameters */
76 a->fs = fs;
77 a->fbOpt = fbOption;
78 a->hopsize = hopsize;
79 a->blocksize = blocksize;
80 a->hybridmode = hybridmode;
81 a->h_array = malloc1d(nGrid*nMics*h_len*sizeof(float));
82 memcpy(a->h_array, h_array, nGrid*nMics*h_len*sizeof(float));
83 a->grid_dirs_deg = malloc1d(nGrid*2*sizeof(float));
84 memcpy(a->grid_dirs_deg, grid_dirs_deg, nGrid*2*sizeof(float));
85 a->nGrid = nGrid;
86 a->nMics = nMics;
87 a->h_len = h_len;
88 a->diffOpt = diffOption;
89 a->doaOpt = doaOption;
90 a->covAvgCoeff = 1.0f - 1.0f/(4096.0f/a->blocksize);
91 a->covAvgCoeff = SAF_CLAMP(a->covAvgCoeff, 0.0f, 0.99999f);
92
93 /* Scale steering vectors so that the peak of loudest measurement is 1 */
94 utility_simaxv(a->h_array, nGrid*nMics*h_len, &idx_max);
95 cblas_sscal(nGrid*nMics*h_len, 1.0f/a->h_array[idx_max], a->h_array, 1);
96
97 /* Initialise time-frequency transform */
98 a->timeSlots = a->blocksize/a->hopsize;
99 switch(a->fbOpt){
100 case HADES_USE_AFSTFT_LD: /* fall through */
101 case HADES_USE_AFSTFT:
104 a->freqVector = malloc1d(a->nBands*sizeof(float));
107 a->H_array = malloc1d(a->nBands*(a->nMics)*(a->nGrid)*sizeof(float_complex));
108 a->H_array_w = malloc1d(a->nBands*(a->nMics)*(a->nGrid)*sizeof(float_complex));
110 break;
111 }
112
113 /* Initialise DoA estimator */
115 a->grid_dirs_xyz = malloc1d(a->nGrid*3*sizeof(float));
117 switch(a->doaOpt){
118 case HADES_USE_MUSIC: hades_sdMUSIC_create(&(a->hDoA), a->nMics, a->grid_dirs_deg, a->nGrid); break;
119 }
120
121 /* Integration weights */
122 a->W = calloc1d(a->nGrid*a->nGrid,sizeof(float_complex));
123 if (cblas_sasum(a->nGrid, a->grid_dirs_deg+1, 2)/(float)a->nGrid<0.0001){
124 for(i=0; i<a->nGrid; i++)
125 a->W[i*(a->nGrid)+i] = cmplxf(1.0f, 0.0f);
126 }
127 else{
128 w_tmp = malloc1d(a->nGrid*sizeof(float));
129 getVoronoiWeights(a->grid_dirs_deg, a->nGrid, 0, w_tmp);
130 for(i=0; i<a->nGrid; i++)
131 a->W[i*(a->nGrid)+i] = cmplxf(w_tmp[i], 0.0f);
132 }
133
134 /* For spatial whitening of the spatial covariance matrix, such that it has an identity structure under diffuse-field conditions */
135 a->T = (float_complex**)malloc2d(a->nBands, a->nMics*(a->nMics), sizeof(float_complex));
136 a->DCM_array = malloc1d(a->nBands*(a->nMics)*(a->nMics)*sizeof(float_complex));
137 U = malloc1d(a->nMics*(a->nMics)*sizeof(float_complex));
138 E = malloc1d(a->nMics*(a->nMics)*sizeof(float_complex));
139 H_W = malloc1d(a->nMics*(a->nGrid)*sizeof(float_complex));
140 for(band=0; band<a->nBands; band++){
141 /* Diffuse covariance matrix */
142 cblas_cgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, a->nMics, a->nGrid, a->nGrid, &calpha,
143 &(a->H_array[band*(a->nMics)*(a->nGrid)]), a->nGrid,
144 a->W, a->nGrid, &cbeta,
145 H_W, a->nGrid);
146 cblas_cgemm(CblasRowMajor, CblasNoTrans, CblasConjTrans, a->nMics, a->nMics, a->nGrid, &calpha,
147 H_W, a->nGrid,
148 &(a->H_array[band*(a->nMics)*(a->nGrid)]), a->nGrid, &cbeta,
149 &(a->DCM_array[band*(a->nMics)*(a->nMics)]), a->nMics);
150 cblas_sscal(/*re+im*/2*(a->nMics)*(a->nMics), 1.0f/(float)a->nGrid, (float*)&(a->DCM_array[band*(a->nMics)*(a->nMics)]), 1);
151
152 /* Decomposition of the diffuse covariance matrix */
153 utility_cseig(a->hEig, &(a->DCM_array[band*(a->nMics)*(a->nMics)]), a->nMics, 1, U, E, NULL);
154
155 /* Compute spatial whitening matrix */
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,
159 E, a->nMics,
160 U, a->nMics, &cbeta,
161 a->T[band], a->nMics);
162
163 /* Whiten the array steering vectors / anechoic relative transfer functions (RTFs) */
164 cblas_cgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, a->nMics, a->nGrid, a->nMics, &calpha,
165 a->T[band], a->nMics,
166 &(a->H_array[band*(a->nMics)*(a->nGrid)]), a->nGrid, &cbeta,
167 &(a->H_array_w[band*(a->nMics)*(a->nGrid)]), a->nGrid);
168 }
169 free(U);
170 free(E);
171 free(H_W);
172
173 /* Run-time variables */
174 a->inputBlock = (float**)malloc2d(a->nMics, a->blocksize, sizeof(float));
175 a->Cx = malloc1d(a->nBands*sizeof(CxMic));
176 a->V = malloc1d((a->nMics)*(a->nMics)*sizeof(float_complex));
177 a->Vn = malloc1d((a->nMics)*(a->nMics)*sizeof(float_complex));
178 a->lambda = malloc1d((a->nMics)*sizeof(float));
179
180 /* Flush run-time buffers with zeros */
181 hades_analysis_reset((*phAna));
182}
183
185(
186 hades_analysis_handle* const phAna
187)
188{
190
191 if (a != NULL) {
192 free(a->h_array);
193 free(a->H_array);
194 free(a->H_array_w);
195 free(a->DCM_array);
196 free(a->W);
197 free(a->T);
198 free(a->grid_dirs_xyz);
199 free(a->grid_dirs_deg);
200
201 /* Destroy time-frequency transform */
202 switch(a->fbOpt){
203 case HADES_USE_AFSTFT_LD: /* fall through */
204 case HADES_USE_AFSTFT: afSTFT_destroy(&(a->hFB_enc)); break;
205 }
206 free(a->freqVector);
207
208 /* Destroy DoA estimator */
210 switch(a->doaOpt){
211 case HADES_USE_MUSIC:
213 break;
214 }
215
216 /* Free run-time variables */
217 free(a->inputBlock);
218 free(a->Cx);
219 free(a->V);
220 free(a->Vn);
221 free(a->lambda);
222
223 free(a);
224 a = NULL;
225 (*phAna) = NULL;
226 }
227}
228
230(
231 hades_analysis_handle const hAna
232)
233{
235 int band;
236 if(hAna==NULL)
237 return;
238 a = (hades_analysis_data*)(hAna);
239
240 for(band=0; band<a->nBands; band++)
241 memset(a->Cx[band].Cx, 0, HADES_MAX_NMICS*HADES_MAX_NMICS*sizeof(float_complex));
242}
243
245(
246 hades_analysis_handle const hAna,
247 float** input,
248 int nChannels,
249 int blocksize,
250 void* const hPCon,
251 void* const hSCon
252)
253{
257 int i, j, k, ch, band, est_idx;
258 float diffuseness;
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); /* blas */
261
262 assert(blocksize==a->blocksize);
263
264 /* Load time-domain data */
265 for(ch=0; ch<SAF_MIN(nChannels, a->nMics); ch++)
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));
269
270 /* Forward time-frequency transform */
271 switch(a->fbOpt){
272 case HADES_USE_AFSTFT_LD: /* fall through */
273 case HADES_USE_AFSTFT: afSTFT_forward_knownDimensions(a->hFB_enc, a->inputBlock, blocksize, a->nMics, a->timeSlots, scon->inTF); break;
274 }
275
276 /* Update covarience matrix per band */
277 for(band=0; band<a->nBands; band++){
278 cblas_cgemm(CblasRowMajor, CblasNoTrans, CblasConjTrans, a->nMics, a->nMics, a->timeSlots, &calpha,
279 FLATTEN2D(scon->inTF[band]), a->timeSlots,
280 FLATTEN2D(scon->inTF[band]), a->timeSlots, &cbeta,
281 Cx_new.Cx, a->nMics);
282
283 /* Make a copy for the signal container */
284 cblas_ccopy(a->nMics*a->nMics, (float_complex*)Cx_new.Cx, 1, (float_complex*)scon->Cx[band].Cx, 1);
285
286 /* Apply temporal averaging */
287 cblas_sscal(/*re+im*/2*(a->nMics) * (a->nMics), SAF_CLAMP(a->covAvgCoeff, 0.0f, 0.999f), (float*)a->Cx[band].Cx, 1);
288 cblas_saxpy(/*re+im*/2*(a->nMics) * (a->nMics), 1.0f-SAF_CLAMP(a->covAvgCoeff, 0.0f, 0.999f), (float*)Cx_new.Cx, 1, (float*)a->Cx[band].Cx, 1);
289 }
290
291 /* Spatial parameter estimation per band */
292 for (band = 0; band < a->nBands; band++) {
293 /* Apply diffuse whitening process */
294 cblas_cgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, a->nMics, a->nMics, a->nMics, &calpha,
295 a->T[band], a->nMics,
296 a->Cx[band].Cx, a->nMics, &cbeta,
297 T_Cx.Cx, a->nMics);
298 cblas_cgemm(CblasRowMajor, CblasNoTrans, CblasConjTrans, a->nMics, a->nMics, a->nMics, &calpha,
299 T_Cx.Cx, a->nMics,
300 a->T[band], a->nMics, &cbeta,
301 T_Cx_TH.Cx, a->nMics);
302 utility_cseig(a->hEig, T_Cx_TH.Cx, a->nMics, 1, a->V, NULL, a->lambda);
303
304 /* Estimate diffuseness */
305 diffuseness = 0.0f;
306 switch(a->diffOpt){
307 case HADES_USE_COMEDIE: diffuseness = hades_comedie(a->lambda, a->nMics); break;
308 }
309
310 /* Store diffuseness and source number estimates */
311 pcon->diffuseness[band] = diffuseness;
312 pcon->gains_dir[band] = pcon->gains_diff[band] = 1.0f; /* Default gains per band */
313
314 /* Apply DoA estimator */
315 switch(a->doaOpt){
316 case HADES_USE_MUSIC:
317 /* perform sphMUSIC on the noise subspace */
318 for(i=0; i<a->nMics; i++)
319 for(j=0, k=1; j<a->nMics-1; j++, k++)
320 a->Vn[i*(a->nMics-1)+j] = a->V[i*(a->nMics)+k];
321 hades_sdMUSIC_compute(a->hDoA, &(a->H_array_w[band*(a->nMics)*(a->nGrid)]), a->Vn, 1, NULL, &est_idx);
322 break;
323 }
324
325 /* Store */
326 pcon->doa_idx[band] = pcon->gains_idx[band] = est_idx;
327 }
328}
329
331(
332 hades_analysis_handle const hAna,
333 int* nBands
334)
335{
337 if(hAna==NULL){
338 if(nBands!=NULL)
339 (*nBands) = 0;
340 return NULL;
341 }
342 a = (hades_analysis_data*)(hAna);
343 if(nBands!=NULL)
344 (*nBands) = a->nBands;
345 return (const float*)a->freqVector;
346}
347
349(
350 hades_analysis_handle const hAna
351)
352{
353 return hAna == NULL ? 0 : ((hades_analysis_data*)(hAna))->nBands;
354}
355
357(
358 hades_analysis_handle const hAna
359)
360{
362 if(hAna==NULL)
363 return NULL;
364 a = (hades_analysis_data*)(hAna);
365 return &(a->covAvgCoeff);
366}
367
369(
370 hades_analysis_handle const hAna
371)
372{
373 return hAna == NULL ? 0 : ((hades_analysis_data*)(hAna))->filterbankDelay;
374}
375
376
377/* ========================================================================== */
378/* Parameter and Signal Containers */
379/* ========================================================================== */
380
382(
383 hades_param_container_handle* const phPCon,
384 hades_analysis_handle const hAna
385)
386{
388 *phPCon = (void*)pcon;
390
391 /* Copy data that is relevant to the container */
392 pcon->nBands = a->nBands;
393
394 /* Allocate parameter storage */
395 pcon->diffuseness = malloc1d(pcon->nBands*sizeof(float));
396 pcon->doa_idx = malloc1d(pcon->nBands*sizeof(int));
397 pcon->gains_idx = malloc1d(pcon->nBands*sizeof(int));
398
399 /* Allocate the optional parameter storage */
400 pcon->gains_dir = calloc1d(pcon->nBands, sizeof(float));
401 pcon->gains_diff = calloc1d(pcon->nBands, sizeof(float));
402}
403
405(
406 hades_param_container_handle* const phPCon
407)
408{
410
411 if (pcon != NULL) {
412 /* Free parameter storage */
413 free(pcon->diffuseness);
414 free(pcon->doa_idx);
415 free(pcon->gains_idx);
416 free(pcon->gains_dir);
417 free(pcon->gains_diff);
418
419 free(pcon);
420 pcon = NULL;
421 (*phPCon) = NULL;
422 }
423}
424
426(
427 hades_signal_container_handle* const phSCon,
428 hades_analysis_handle const hAna
429)
430{
432 *phSCon = (void*)scon;
434
435 /* Copy data that is relevant to the container */
436 scon->nMics = a->nMics;
437 scon->nBands = a->nBands;
438 scon->timeSlots = a->timeSlots;
439
440 /* Copy of the NON-time-averaged covariance matrix per band */
441 scon->Cx = malloc1d(a->nBands*sizeof(CxMic));
442
443 /* Time-frequency frame */
444 scon->inTF = (float_complex***)malloc3d(scon->nBands, scon->nMics, scon->timeSlots, sizeof(float_complex));
445}
446
448(
450)
451{
453
454 if (scon != NULL) {
455 /* Free time-frequency frame */
456 free(scon->Cx);
457 free(scon->inTF);
458
459 free(scon);
460 scon = NULL;
461 (*phSCon) = NULL;
462 }
463}
464
465#endif /* SAF_ENABLE_HADES_MODULE */
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.
Definition afSTFTlib.c:593
int afSTFT_getNBands(void *const hSTFT)
Returns number of frequency bands.
Definition afSTFTlib.c:528
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
int afSTFT_getProcDelay(void *const hSTFT)
Returns current processing delay, in samples.
Definition afSTFTlib.c:537
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
@ AFSTFT_BANDS_CH_TIME
nBands x nChannels x nTimeHops
Definition afSTFTlib.h:80
#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)
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 * calloc1d(size_t dim1, size_t data_size)
1-D calloc (same as calloc, but with error checking)
Definition md_malloc.c:69
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
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
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.