63 int i, n, j, k, order, nSectors, nSH, grid_N_vbap_gtable, grid_nGroups, maxOrder;
64 float* sec_dirs_deg, *grid_vbap_gtable, *w_SG, *pinv_Y, *grid_vbap_gtable_T;
67 secPatterns = (
float**)
calloc2d(4, pData->
nGrid,
sizeof(
float));
73 for(i=0, order=2; order<=maxOrder; i++,order++){
75 nSH = (order+1)*(order+1);
78 sec_dirs_deg =
malloc1d(nSectors*2*
sizeof(
float));
83 &(grid_vbap_gtable), &(grid_N_vbap_gtable), &(grid_nGroups));
89 for(n=0; n<nSectors; n++)
90 for(j=0; j<pData->
nGrid; j++)
91 grid_vbap_gtable_T[n*pData->
nGrid+j] = grid_vbap_gtable[j*nSectors+n];
97 w_SG =
malloc1d(4 * (nSH) *
sizeof(
float));
99 for(n=0; n<nSectors; n++){
104 cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, 4, nSH, pData->
nGrid, 1.0f,
105 &(secPatterns[0][0]), pData->
nGrid,
112 pData->
secCoeffs[i][j*(nSectors*nSH)+n*nSH+k] = cmplxf(w_SG[j*nSH+k], 0.0f);
116 free(grid_vbap_gtable);
120 free(grid_vbap_gtable_T);
137 if(pData->
hSTFT==NULL)
139 else if(nSH!=new_nSH){
147 float_complex** SHframeTF,
149 float_complex* secCoeffs,
154 int n, ch, i, j, nSectors, analysisOrder, nSH;
156 float_complex* sec_c;
158 const float_complex calpha = cmplxf(1.0f, 0.0f);
const float_complex cbeta = cmplxf(0.0f, 0.0f);
165 nSH = (analysisOrder+1)*(analysisOrder+1);
166 sec_c =
malloc1d(4*nSH*
sizeof(float_complex));
169 for( n=0; n<nSectors; n++){
170 if(anaOrder==1 || secCoeffs == NULL)
172 memcpy(secSig[i], SHframeTF[i],
TIME_SLOTS *
sizeof(float_complex));
175 for (j=0; j<nSH; j++)
176 sec_c[i*nSH+j] = secCoeffs[i*(nSectors*nSH)+n*nSH+j];
177 cblas_cgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, 4,
TIME_SLOTS, nSH, &calpha,
184 for (ch = 1; ch<4; ch++)
186 secSig[ch][i] = crmulf(secSig[ch][i], 1.0f/sqrtf(3.0f));
189 memset(secEnergy, 0,
TIME_SLOTS*
sizeof(
float));
192 secEnergy[j] += 0.5f*powf(cabsf(secSig[i][j]), 2.0f);
195 secIntensity[i][j] = crealf(ccmulf(conjf(secSig[0][j]), secSig[1+i][j]));
199 secAzi[j] = atan2f( secIntensity[0][j], secIntensity[2][j] );
200 secElev[j] = atan2f( secIntensity[1][j], sqrtf( powf(secIntensity[2][j], 2.0f) + powf(secIntensity[0][j], 2.0f)) );
205 doa[n][j][0] = secAzi[j];
206 doa[n][j][1] = secElev[j];
207 energy[n][j] = secEnergy[j]*1e6f;
#define MAX_SH_ORDER
Maximum supported Ambisonic order.
CODEC_STATUS
Current status of the codec.
@ CODEC_STATUS_NOT_INITIALISED
Codec has not yet been initialised, or the codec configuration has changed.
@ CODEC_STATUS_INITIALISING
Codec is currently being initialised, input audio should not be processed.
void afSTFT_clearBuffers(void *const hSTFT)
Flushes time-domain buffers with zeros.
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.
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.
@ AFSTFT_BANDS_CH_TIME
nBands x nChannels x nTimeHops
#define TIME_SLOTS
Number of STFT timeslots.
#define HOP_SIZE
STFT hop size.
const float * __HANDLES_SphCovering_dirs_deg[64]
Sphere covering handles ( between 4..64 points only)
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.
void utility_spinv(void *const hWork, const float *inM, const int dim1, const int dim2, float *outM)
General matrix pseudo-inverse (the svd way): single precision, i.e.
#define SAF_MIN(a, b)
Returns the minimum of the two values.
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 ** calloc2d(size_t dim1, size_t dim2, size_t data_size)
2-D calloc (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...
A spatially-localised active-intensity (SLAI) based direction-of- arrival estimator (SLDoA)
void sldoa_setCodecStatus(void *const hSld, CODEC_STATUS newStatus)
Sets codec status (see CODEC_STATUS enum)
void sldoa_initAna(void *const hSld)
Intialises the codec variables, based on current global/user parameters.
void sldoa_initTFT(void *const hSld)
Initialise the filterbank used by sldoa.
void sldoa_estimateDoA(float_complex **SHframeTF, int anaOrder, float_complex *secCoeffs, float doa[MAX_NUM_SECTORS][TIME_SLOTS][2], float energy[MAX_NUM_SECTORS][TIME_SLOTS])
Estimates the DoA using the active intensity vectors derived from spatially localised sectors,...
A spatially-localised active-intensity (SLAI) based direction-of- arrival estimator (SLDoA)
#define MAX_NUM_SECTORS
maximum number of sectors, TODO: expand beyond 64 (which is the max possible in the spherecovering gr...
#define ORDER2NUMSECTORS(L)
Macro to convert SH order to number of sectors.
int new_masterOrder
New master/maximum analysis order (current value will be replaced by this after next re-init)
void * hSTFT
afSTFT handle
float_complex * secCoeffs[MAX_SH_ORDER-1]
Sector beamforming weights/coefficients.
CODEC_STATUS codecStatus
see CODEC_STATUS
float ** grid_Y_dipoles_norm
SH basis.
float ** grid_dirs_deg
Grid directions, in degrees.
int masterOrder
Current master/maximum analysis order.
int nGrid
Number of grid directions.