31#define NUM_INPUT_ARGS_CREATE  ( 7 ) 
   32const MEX_DATA_TYPES inputDataTypes_create[NUM_INPUT_ARGS_CREATE] = {
 
   41#define NUM_INPUT_ARGS_FWD ( 1 ) 
   42#define NUM_OUTPUT_ARGS_FWD ( 1 ) 
   43#define NUM_INPUT_ARGS_BKWD ( 1 ) 
   44#define NUM_OUTPUT_ARGS_BKWD ( 1 ) 
   75float* freqVector = NULL;
 
   79float** dataTD_in = NULL;
 
   80float** dataTD_out = NULL;
 
   81float_complex*** dataFD_in = NULL;
 
   82float_complex*** dataFD_out = NULL;
 
  104            mexPrintf(
"Destroying afSTFT filterbank.\n");
 
  106            free(freqVector); freqVector = NULL;
 
  107            free(dataTD_in);  dataTD_in = NULL;
 
  108            free(dataFD_in);  dataFD_in = NULL;
 
  109            free(dataTD_out); dataTD_out = NULL;
 
  110            free(dataFD_out); dataFD_out = NULL;
 
  114            mexPrintf(
"afSTFT filterbank is already dead!\n"); 
 
  118    else if(nrhs==NUM_INPUT_ARGS_CREATE && (nlhs==0 || nlhs==1 || nlhs==2)){
 
  120            mexErrMsgIdAndTxt(
"MyToolbox:inputError",
"safmex_afSTFT is already initialised! First destroy it if you want to change its configuration.");
 
  126        nCHin = (int)mxGetScalar(prhs[0]);
 
  127        nCHout = (int)mxGetScalar(prhs[1]);
 
  128        hopsize = (int)mxGetScalar(prhs[2]);
 
  129        blocksize = (int)mxGetScalar(prhs[3]); 
 
  130        hybridmode = (int)mxGetScalar(prhs[4]); 
 
  131        formatFlag = (int)mxGetScalar(prhs[5]); 
 
  132        fs = (float)mxGetScalar(prhs[6]); 
 
  137                mexErrMsgIdAndTxt(
"MyToolbox:inputError",
"the value of the fifth argument should be 0 or 1");
 
  141        if( !(hybridmode==0 || hybridmode==1) )
 
  142            mexErrMsgIdAndTxt(
"MyToolbox:inputError",
"'hybridmode' should be 0 (disabled) or 1 (enabled)");
 
  143        if( !(formatFlag==0 || formatFlag==1) )
 
  144            mexErrMsgIdAndTxt(
"MyToolbox:inputError",
"'formatFlag' should be 0 (bands x channels x time) or 1 (time x channels x bands)");
 
  145        if( !(hopsize==4 || hopsize==8 || hopsize==16 || hopsize==32 || hopsize==64 || hopsize==128) )
 
  146            mexErrMsgIdAndTxt(
"MyToolbox:inputError",
"the 'hopsize' should be 4, 8, 16, 32, 64, or 128");
 
  147        if( blocksize % hopsize != 0)
 
  148            mexErrMsgIdAndTxt(
"MyToolbox:inputError",
"'blocksize' must be a multiple of 'hopsize'");
 
  151        timeSlots = blocksize/hopsize;
 
  152        afSTFT_create(&hSTFT, nCHin, nCHout, hopsize, 0, hybridmode, format);
 
  155        freqVector = 
malloc1d(nBands*
sizeof(
float));
 
  159        dataTD_in = (
float**)
malloc2d(nCHin, blocksize, 
sizeof(
float)); 
 
  160        dataTD_out = (
float**)
malloc2d(nCHout, blocksize, 
sizeof(
float));
 
  163                dataFD_in = (float_complex***)
malloc3d(nBands, nCHin, timeSlots, 
sizeof(float_complex));
 
  164                dataFD_out = (float_complex***)
malloc3d(nBands, nCHout, timeSlots, 
sizeof(float_complex));
 
  167                dataFD_in = (float_complex***)
malloc3d(timeSlots, nCHin, nBands, 
sizeof(float_complex));
 
  168                dataFD_out = (float_complex***)
malloc3d(timeSlots, nCHout, nBands, 
sizeof(float_complex));
 
  181            plhs[1] = mxCreateDoubleScalar(procDelay); 
 
  185        mexPrintf(
"Creating afSTFT filterbank:");
 
  191            mexPrintf(
" hybrid mode enabled,");
 
  193            mexPrintf(
" hybrid mode disabled,");
 
  195            mexPrintf(
" format: time x channels x bands.\n");
 
  197            mexPrintf(
" format: bands x channels x time.\n");
 
  201    else if(nrhs == 1 && nlhs == 1){
 
  203            mexErrMsgIdAndTxt(
"MyToolbox:inputError",
"safmex_afSTFT is uninitialised!");
 
  207        const mwSize *pDims_mx;
 
  208        nDims_mx = mxGetNumberOfDimensions(prhs[0]);
 
  209        pDims_mx = mxGetDimensions(prhs[0]); 
 
  212        if(!mxIsComplex(prhs[0])){ 
 
  217            if( !(pDims_mx[0] == (mwSize)nCHin) ){
 
  219                mexErrMsgIdAndTxt(
"MyToolbox:inputError", 
message);
 
  221            if( !(pDims_mx[1] == (mwSize)blocksize) ){
 
  223                mexErrMsgIdAndTxt(
"MyToolbox:inputError", 
message);
 
  232            pDims = 
realloc1d(pDims, nDims*
sizeof(
int));
 
  234                case 0: pDims[0] = nBands; pDims[1] = nCHin; pDims[2] = timeSlots; 
break;
 
  235                case 1: pDims[0] = timeSlots; pDims[1] = nCHin; pDims[2] = nBands; 
break;
 
  244        else if(mxIsComplex(prhs[0])){
 
  249            if( !(pDims_mx[0] == (mwSize)nBands) && formatFlag==0 ){
 
  251                mexErrMsgIdAndTxt(
"MyToolbox:inputError", 
message);
 
  253            if( !(pDims_mx[0] == (mwSize)timeSlots) && formatFlag==1 ){
 
  255                mexErrMsgIdAndTxt(
"MyToolbox:inputError", 
message);
 
  257            if( !(pDims_mx[1] == (mwSize)nCHout) ){
 
  259                mexErrMsgIdAndTxt(
"MyToolbox:inputError", 
message);
 
  261            if( !(pDims_mx[2] == (mwSize)timeSlots) && formatFlag==0 ){
 
  263                mexErrMsgIdAndTxt(
"MyToolbox:inputError", 
message);
 
  265            if( !(pDims_mx[2] == (mwSize)nBands) && formatFlag==1 ){
 
  267                mexErrMsgIdAndTxt(
"MyToolbox:inputError", 
message);
 
  276            pDims = 
realloc1d(pDims, nDims*
sizeof(
int));
 
  278            pDims[1] = blocksize; 
 
  285            mexErrMsgIdAndTxt(
"MyToolbox:inputError",
"Unrecognised input/output configuration, refer to help instructions.");
 
  290        mexErrMsgIdAndTxt(
"MyToolbox:inputError",
"Unrecognised input/output configuration, refer to help instructions.");
 
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(void *const hSTFT, float **dataTD, int framesize, float_complex ***dataFD)
Performs forward afSTFT transform.
 
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.
 
void afSTFT_backward(void *const hSTFT, float_complex ***dataFD, int framesize, float **dataTD)
Performs backward afSTFT transform.
 
AFSTFT_FDDATA_FORMAT
Options for how the frequency domain data is permuted when using afSTFT.
 
@ AFSTFT_TIME_CH_BANDS
nTimeHops x nChannels x nBands
 
@ AFSTFT_BANDS_CH_TIME
nBands x nChannels x nTimeHops
 
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)
 
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...
 
#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.
 
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_1D_OR_2D
Real 2-D matrix or 1-D vector; N x M | N x 1.
 
@ SM_DOUBLE_COMPLEX_3D
Complex 3-D matrix; N x M x K.
 
void SAFsingle2MEXdouble(float *in, int nDims, int *dims, mxArray **out)
Convert a single precision array used by SAF to mex double-precision array.
 
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.