31#define NUM_INPUT_ARGS_CREATE ( 4 )
32const MEX_DATA_TYPES inputDataTypes_create[NUM_INPUT_ARGS_CREATE] = {
38#define NUM_INPUT_ARGS_APPLY ( 1 )
39#define NUM_OUTPUT_ARGS_APPLY ( 1 )
43const MEX_DATA_TYPES outputDataTypes_apply[NUM_OUTPUT_ARGS_APPLY] = {
61float** data_out = NULL;
84 mexPrintf(
"Destroying FaF filterbank.\n");
87 free(data_in); data_in = NULL;
88 free(data_out); data_out = NULL;
92 mexPrintf(
"FaF filterbank is already dead!\n");
96 else if( nrhs==NUM_INPUT_ARGS_CREATE && nlhs==0 ){
98 mexErrMsgIdAndTxt(
"MyToolbox:inputError",
"safmex_faf_IIRFilterbank is already initialised! First destroy it if you want to change its configuration.");
104 order = (int)mxGetScalar(prhs[0]);
105 lSig = (int)mxGetScalar(prhs[2]);
106 fs = (float)mxGetScalar(prhs[3]);
110 nCutoffFreqs = pDims[0];
111 if( !((order==1) || (order==3)) )
112 mexErrMsgIdAndTxt(
"MyToolbox:inputError",
"'order' must be either 1 or 3.");
113 if( nCutoffFreqs<=1 )
114 mexErrMsgIdAndTxt(
"MyToolbox:inputError",
"cut-off frequency vector must be longer than 1 element.");
120 data_in =
malloc1d(lSig *
sizeof(
float));
121 data_out = (
float**)
malloc2d(nCutoffFreqs+1, lSig,
sizeof(
float));
124 mexPrintf(
"Creating FaF filterbank:");
127 mexPrintf(
" filter cut-off frequencies = [");
128 for(i=0; i<nCutoffFreqs; i++){
136 else if(nrhs == 1 && nlhs == 1){
138 mexErrMsgIdAndTxt(
"MyToolbox:inputError",
"safmex_faf_IIRFilterbank is uninitialised!");
145 const mwSize *pDims_mx;
146 nDims_mx = mxGetNumberOfDimensions(prhs[0]);
147 pDims_mx = mxGetDimensions(prhs[0]);
150 if( pDims_mx[0] != (mwSize)lSig ){
152 mexErrMsgIdAndTxt(
"MyToolbox:inputError",
message);
155 if(pDims_mx[1] != 1 || nDims_mx>2 )
156 mexErrMsgIdAndTxt(
"MyToolbox:inputError",
"Was expecting just one input channel.");
164 pDims =
realloc1d(pDims, nDims*
sizeof(
int));
165 pDims[0] = nCutoffFreqs+1; pDims[1] = lSig;
174 mexErrMsgIdAndTxt(
"MyToolbox:inputError",
"Unrecognised input/output configuration, refer to help instructions.");
void faf_IIRFilterbank_destroy(void **phFaF)
Destroys an instance of the Favrot & Faller filterbank.
void faf_IIRFilterbank_create(void **phFaF, int order, float *fc, int nCutoffFreq, float sampleRate, int maxNumSamples)
Computes a bank of IIR filter coefficients required to divide a signal into frequency bands,...
void faf_IIRFilterbank_apply(void *hFaF, float *inSig, float **outBands, int nSamples)
Applies the Favrot & Faller filterbank.
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 * realloc1d(void *ptr, size_t dim1_data_size)
1-D realloc (same as realloc, but with error checking)
#define FLATTEN2D(A)
Use this macro when passing a 2-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.
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_REAL_2D
Real 2-D matrix; N x M.
@ SM_DOUBLE_REAL_1D
Real 1-D vector; N x 1.
void SAFsingle2MEXdouble(float *in, int nDims, int *dims, mxArray **out)
Convert a single precision array used by SAF to mex double-precision array.
void checkArgDataTypes(mxArray **hData, MEX_DATA_TYPES *dataTypes, int nArgs)
Helper function to check the format of the input/output arguments are as expected.