31#define NUM_INPUT_ARGS_CREATE ( 8 )
32const MEX_DATA_TYPES inputDataTypes_create[NUM_INPUT_ARGS_CREATE] = {
42#define NUM_INPUT_ARGS_APPLY ( 1 )
43#define NUM_OUTPUT_ARGS_APPLY ( 1 )
47const MEX_DATA_TYPES outputDataTypes_apply[NUM_OUTPUT_ARGS_APPLY] = {
62float* freqCutoffs = NULL;
65float* freqVector = NULL;
72float_complex*** dataFD_in = NULL;
73float_complex*** dataFD_out = NULL;
75const int nSupportedOrders = 12;
76const int supportedOrders[12] = {2,3,4,6,8,10,12,14,15,16,18,20};
98 mexPrintf(
"Destroying latticeDecorrelator.\n");
100 free(orders); orders = NULL;
101 free(freqCutoffs); freqCutoffs = NULL;
102 free(freqVector); freqVector = NULL;
103 free(dataFD_in); dataFD_in = NULL;
104 free(dataFD_out); dataFD_out = NULL;
108 mexPrintf(
"latticeDecorrelator is already dead!\n");
112 else if(nrhs==NUM_INPUT_ARGS_CREATE){
114 mexErrMsgIdAndTxt(
"MyToolbox:inputError",
"safmex_latticeDecorrelator is already initialised! First destroy it if you want to change its configuration.");
120 fs = (float)mxGetScalar(prhs[0]);
121 hopsize = (int)mxGetScalar(prhs[1]);
122 nCH = (int)mxGetScalar(prhs[2]);
127 mexErrMsgIdAndTxt(
"MyToolbox:inputError",
"freqCutoffs vector must be longer than 1 element.");
128 for(i=0; i<nCutoffs; i++){
129 int supportedOrder = 0;
130 for(j=0; j<nSupportedOrders; j++)
131 if(orders[i] == supportedOrders[j])
135 mexErrMsgIdAndTxt(
"MyToolbox:inputError",
"Supported 'orders' are: 2,3,4,6,8,10,12,14,15,16,18,20.");
139 if(pDims[0] != nCutoffs )
140 mexErrMsgIdAndTxt(
"MyToolbox:inputError",
"freqCutoffs vector must be the same length as orders vector.");
142 maxDelay = (int)mxGetScalar(prhs[5]);
146 nTimeSlots = (int)mxGetScalar(prhs[7]);
149 latticeDecorrelator_create(&hDecor, fs, hopsize, freqVector, nBands, nCH, orders, freqCutoffs, nCutoffs, maxDelay, 0, 0.75f);
152 dataFD_in = (float_complex***)
malloc3d(nBands, nCH, nTimeSlots,
sizeof(float_complex));
153 dataFD_out = (float_complex***)
malloc3d(nBands, nCH, nTimeSlots,
sizeof(float_complex));
156 mexPrintf(
"Creating latticeDecorrelator:");
158 mexPrintf(
" filter orders = [");
159 for(i=0; i<nCutoffs; i++){
164 mexPrintf(
" cut-offs = [");
165 for(i=0; i<nCutoffs; i++){
175 else if(nrhs == 1 && nlhs == 1){
177 mexErrMsgIdAndTxt(
"MyToolbox:inputError",
"safmex_latticeDecorrelator is uninitialised!");
181 const mwSize *pDims_mx;
182 nDims_mx = mxGetNumberOfDimensions(prhs[0]);
183 pDims_mx = mxGetDimensions(prhs[0]);
189 if( !(pDims_mx[0] == (mwSize)nBands) ){
191 mexErrMsgIdAndTxt(
"MyToolbox:inputError",
message);
193 if( !(pDims_mx[1] == (mwSize)nCH) ){
195 mexErrMsgIdAndTxt(
"MyToolbox:inputError",
message);
197 if( !(pDims_mx[2] == (mwSize)nTimeSlots) ){
199 mexErrMsgIdAndTxt(
"MyToolbox:inputError",
message);
208 pDims =
realloc1d(pDims, nDims*
sizeof(
int));
209 pDims[0] = nBands; pDims[1] = nCH; pDims[2] = nTimeSlots;
218 mexErrMsgIdAndTxt(
"MyToolbox:inputError",
"Unrecognised input/output configuration, refer to help instructions.");
void latticeDecorrelator_apply(void *hDecor, float_complex ***inFrame, int nTimeSlots, float_complex ***decorFrame)
Applies the lattice all-pass-filter-based multi-channel signal decorrelator.
void latticeDecorrelator_create(void **phDecor, float fs, int hopsize, float *freqVector, int nBands, int nCH, int *orders, float *freqCutoffs, int nCutoffs, int maxDelay, int lookupOffset, float enComp_coeff)
Creates an instance of the lattice all-pass-filter-based multi-channel signal decorrelator.
void latticeDecorrelator_destroy(void **phDecor)
Destroys an instance of the lattice all-pass-filter-based multi-channel signal decorrelator.
void * realloc1d(void *ptr, size_t dim1_data_size)
1-D realloc (same as realloc, 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...
Main include header for safmex.
void MEXdouble2SAFsingle(const mxArray *in, float **out, int *nDims, int **pDims)
Convert a mex double-precision array into single precision array for SAF.
#define MSG_STR_LENGTH
Warning/error message character length.
char message[MSG_STR_LENGTH]
Current warning/error message.
void MEXdouble2SAFsingle_int(const mxArray *in, int **out, int *nDims, int **pDims)
Convert a mex double-precision array into single precision array for SAF (integers)
MEX_DATA_TYPES
Supported SAF/MEX data conversions.
@ SM_DOUBLE_REAL
Scalar, real valued; 1 x 1.
@ SM_INT32
Integer; 1 x 1.
@ SM_DOUBLE_COMPLEX_3D
Complex 3-D matrix; N x M x K.
@ SM_DOUBLE_REAL_1D
Real 1-D vector; N x 1.
void MEXdouble2SAFsingle_complex(const mxArray *in, float_complex **out, int *nDims, int **pDims)
Convert a mex double-precision array into single precision array for SAF (complex-valued)
void SAFsingle2MEXdouble_complex(float_complex *in, int nDims, int *dims, mxArray **out)
Convert a single precision array used by SAF to mex double-precision array (complex valued)
void checkArgDataTypes(mxArray **hData, MEX_DATA_TYPES *dataTypes, int nArgs)
Helper function to check the format of the input/output arguments are as expected.