|
Thanks a lot for that Rune. I'm only just starting with C/Mex so it's probably a stupid coding error, but of course my lack of experience makes tracking it down 10 times harder. I've included it below, maybe you'll be able to spot a silly mistake just at a glance!
//begin C code
#include "math.h"
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
//function martin_xcorr(hc_L,hc_R,frameCount,numchans,frame_length,maxlag,window,inhib,noverlap,maxdeg,sd,warpers)
// declarations
double *hc_L,*hc_R,*frameCount_in,*frame_length_in,*maxlag_in,*window,*inhib,*noverlap_in,*ccg_out,\
*maxdeg_in,*sd,*warpers_in,*ccg_azi_out,*sccg_out,*tau,*ccg_warp_in,*warp_data,*warp_result,\
*conv_data_in,*conv_in_gauss,*conv_result,maxlag_temp,*ccg_raw,*ccg_r,*gaussian;
int numchans,frameCount,frame_length,maxlag,noverlap,numsamples,offset,sample,sample_late,\
lengthCCG,leftn,rightn,ccg_index,ccg_r_index,ccg_raw_index,\
firstFrame,maxdeg,newLengthCCG;
mwSize ccg_r_dims[3],ccg_raw_dims[3],ccg_dims[3],sccg_dims[3];
mwIndex i,j,n,m,o;
mxArray *warp_out[1],*warp_in[3],*conv_out[1],*conv_in[2],*ccg_raw_mx[1],*ccg_r_mx[1],*gaussian_mx[1];
// inputs
hc_L = mxGetPr(prhs[0]);
hc_R = mxGetPr(prhs[1]);
frameCount_in = mxGetPr(prhs[2]);
frame_length_in = mxGetPr(prhs[3]);
maxlag_in = mxGetPr(prhs[4]);
window = mxGetPr(prhs[5]);
inhib = mxGetPr(prhs[6]);
noverlap_in = mxGetPr(prhs[7]);
maxdeg_in = mxGetPr(prhs[8]);
sd = mxGetPr(prhs[9]);
warpers_in = mxGetPr(prhs[10]);
numsamples = mxGetM(prhs[0]);
numchans = mxGetN(prhs[0]);
// derive variables
frameCount = (int) *frameCount_in;
frame_length = (int) *frame_length_in;
maxlag = (int) *maxlag_in;
noverlap = (int) *noverlap_in;
maxdeg = (int) *maxdeg_in;
offset = (int) noverlap*frame_length;
lengthCCG = (int) (2*maxlag)+1;
newLengthCCG = (int) (2*maxdeg)+1;
firstFrame = (int) 1;
// matrix dimensions
ccg_r_dims[0] = frame_length;
ccg_r_dims[1] = lengthCCG;
ccg_r_dims[2] = numchans;
ccg_raw_dims[0] = (noverlap+1)*frame_length;
ccg_raw_dims[1] = lengthCCG;
ccg_raw_dims[2] = numchans;
ccg_dims[0] = numchans;
ccg_dims[1] = lengthCCG;
ccg_dims[2] = frameCount;
sccg_dims[0] = numchans;
sccg_dims[1] = newLengthCCG;
sccg_dims[2] = frameCount;
// temp variables
ccg_raw_mx[0] = mxCreateNumericArray((mwSize)3,ccg_raw_dims,mxDOUBLE_CLASS,mxREAL);
ccg_raw = mxGetPr(ccg_raw_mx[0]);
ccg_r_mx[0] = mxCreateNumericArray((mwSize)3,ccg_r_dims,mxDOUBLE_CLASS,mxREAL);
ccg_r = mxGetPr(ccg_r_mx[0]);
gaussian_mx[0] = mxCreateDoubleMatrix((mwSize)newLengthCCG,(mwSize)numchans,mxREAL);
gaussian = mxGetPr(gaussian_mx[0]);
// outputs
plhs[0] = mxCreateNumericArray((mwSize)3,ccg_dims,mxDOUBLE_CLASS,mxREAL);
plhs[1] = mxCreateNumericArray((mwSize)3,sccg_dims,mxDOUBLE_CLASS,mxREAL);
plhs[2] = mxCreateNumericArray((mwSize)3,sccg_dims,mxDOUBLE_CLASS,mxREAL);
//mexPrintf("frameCount: %d \n",frameCount);
ccg_out = mxGetPr(plhs[0]);
ccg_azi_out = mxGetPr(plhs[1]);
sccg_out = mxGetPr(plhs[2]);
// initiate tau for warping
warp_in[0] = mxCreateDoubleMatrix((mwSize)lengthCCG,(mwSize)1,mxREAL);
tau = mxGetPr(warp_in[0]);
maxlag_temp = (double) maxlag;
for ( m = 0; m < lengthCCG; m++ ) {
tau[m] = (((double) m - maxlag_temp)/maxlag_temp);
}
// initiate ccg input to warping
warp_in[1] = mxCreateDoubleMatrix((mwSize)lengthCCG,1,mxREAL);
ccg_warp_in = mxGetPr(warp_in[1]);
// initiate warping array
warp_in[2] = mxCreateDoubleMatrix((mwSize)newLengthCCG,1,mxREAL);
warp_data = mxGetPr(warp_in[2]);
warp_result = mxGetPr(warp_out[0]);
//warp_in[3] = mxCreateString("spline");
// initiate gaussians for skeleton ccg
conv_in[0] = mxCreateDoubleMatrix((mwSize)newLengthCCG,(mwSize)1,mxREAL);
conv_in[1] = mxCreateDoubleMatrix((mwSize)newLengthCCG,(mwSize)1,mxREAL);
conv_data_in = mxGetPr(conv_in[0]);
conv_in_gauss = mxGetPr(conv_in[1]);
conv_result = mxGetPr(conv_out[0]);
for ( i = 0; i < numchans; i++ ) {
for ( m = 0; m < newLengthCCG; m++ ) {
gaussian[i*newLengthCCG+m] = exp((-pow(m-(*maxdeg_in),2))/(2*(pow(sd[i],2))));
}
}
// Do the calculations
for ( j = 0; j < frameCount; j++ ) {
for ( i = 0; i < numchans; i++ ) {
if ( firstFrame==1 ) {
for ( n = 0; n < frame_length*(noverlap+1); n++ ) {
sample = i*numsamples+n;
for ( m = 0; m < lengthCCG; m++ ) { // raw cross-correlations
ccg_raw_index = n+((m+(i*lengthCCG))*((noverlap+1)*frame_length));
leftn = fmax(sample-maxlag+m,sample);
rightn = fmax(sample+maxlag-m,sample);
ccg_raw[ccg_raw_index] = hc_L[leftn]*hc_R[rightn];
}
}
for ( n = 0; n < frame_length; n++ ) {
sample = i*numsamples+n;
for ( m = 0; m < lengthCCG; m++ ) { // integrate
ccg_raw_index = n+((m+(i*lengthCCG))*((noverlap+1)*frame_length));
ccg_r_index = n+((m+(i*lengthCCG))*frame_length);
ccg_index = i+((m+(j*lengthCCG))*numchans);
ccg_r[ccg_r_index] = window[0]*ccg_raw[ccg_raw_index];
for ( o = 1; o < noverlap*frame_length; o++ ) {
ccg_r[ccg_r_index] += window[o]*ccg_raw[ccg_raw_index+o];
}
ccg_r[ccg_r_index] /= (frame_length*noverlap); // running ccg
ccg_r[ccg_r_index] *= inhib[sample];
ccg_out[ccg_index] += ccg_r[ccg_r_index]/frame_length; // write to o/p
}
}
}
else { // if not first frame (firstFrame = 0)
for ( n = 0; n < noverlap*frame_length; n++ ) { // move ccgs
for ( m = 0; m < lengthCCG; m++ ) {
ccg_raw_index = n+((m+(i*lengthCCG))*((noverlap+1)*frame_length));
ccg_raw[ccg_raw_index] = ccg_raw[ccg_raw_index+frame_length];
}
}
for ( n = 0; n < frame_length; n++ ) {
sample_late = (i*numsamples)+(j*frame_length)+n+offset;
sample = (i*numsamples)+(j*frame_length)+n;
for ( m = 0; m < lengthCCG; m++ ) {
// indices
ccg_r_index = n+((m+(i*lengthCCG))*frame_length);
ccg_raw_index = n+((m+(i*lengthCCG))*((noverlap+1)*frame_length));
ccg_index = i+((m+(j*lengthCCG))*numchans);
leftn = fmax(sample_late-maxlag+m,sample_late);
rightn = fmax(sample_late+maxlag-m,sample_late);
// calculations
ccg_raw[ccg_raw_index+offset] = hc_L[leftn]*hc_R[rightn];
ccg_r[ccg_r_index] = window[0]*ccg_raw[ccg_raw_index];
for ( o = 1; o < noverlap*frame_length; o++ ) { // integrate
ccg_r[ccg_r_index] += window[o]*ccg_raw[ccg_raw_index+o];
}
ccg_r[ccg_r_index] /= (frame_length*noverlap); // running ccg
ccg_r[ccg_r_index] *= inhib[sample];
ccg_out[ccg_index] += ccg_r[ccg_r_index]/frame_length; // write to o/p
}
}
}
} // end frequency loop
firstFrame = 0;
} // end frame loop
mxDestroyArray(*warp_out);
mxDestroyArray(*warp_in);
mxDestroyArray(*conv_out);
mxDestroyArray(*conv_in);
mxDestroyArray(*ccg_raw_mx);
mxDestroyArray(*ccg_r_mx);
mxDestroyArray(*gaussian_mx);
return;
}
//end C code
|