To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.
The primary repository for this project is hosted at svn://svn.code.sf.net/p/onsetsds/code/ .
This repository is a read-only copy which is updated automatically every hour.
root / mat_oct / onsetsds.c
History | View | Annotate | Download (3.39 KB)
| 1 |
/**
|
|---|---|
| 2 |
This file is part of "onsetsds".
|
| 3 |
(c) 2011 Dan Stowell and Queen Mary University of London
|
| 4 |
All rights reserved.
|
| 5 |
|
| 6 |
onsetsds is free software: you can redistribute it and/or modify
|
| 7 |
it under the terms of the GNU General Public License as published by
|
| 8 |
the Free Software Foundation, either version 3 of the License, or
|
| 9 |
(at your option) any later version.
|
| 10 |
|
| 11 |
onsetsds is distributed in the hope that it will be useful,
|
| 12 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 13 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| 14 |
GNU General Public License for more details.
|
| 15 |
|
| 16 |
You should have received a copy of the GNU General Public License
|
| 17 |
along with kdpee. If not, see <http://www.gnu.org/licenses/>.
|
| 18 |
*/
|
| 19 |
|
| 20 |
#include "math.h" |
| 21 |
#include "mex.h" |
| 22 |
#include "onsetsds.h" |
| 23 |
|
| 24 |
////////////////////////////////////////////////////////////////////////
|
| 25 |
// MATLAB ENTRY FUNCTION:
|
| 26 |
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) |
| 27 |
{
|
| 28 |
// implementation of: onsetsds(fftdata, odftype, medspan, srate)
|
| 29 |
|
| 30 |
// Get the star of the show, the fft data
|
| 31 |
const mxArray *fftdata;
|
| 32 |
fftdata = prhs[0];
|
| 33 |
if(!mxIsComplex(fftdata)){
|
| 34 |
mexErrMsgTxt("onsetsds expects a matrix of complex data (e.g. from fft()).\n");
|
| 35 |
} |
| 36 |
const size_t fftframesize = mxGetM(fftdata);
|
| 37 |
const size_t numframes = mxGetN(fftdata);
|
| 38 |
|
| 39 |
const double* real = mxGetPr(fftdata); |
| 40 |
const double* imag = mxGetPi(fftdata); |
| 41 |
|
| 42 |
// optional args
|
| 43 |
int odftype = ODS_ODF_RCOMPLEX;
|
| 44 |
if(nrhs>1){ |
| 45 |
odftype = mxGetScalar(prhs[1]);
|
| 46 |
if((odftype < 0) || (newodftype > 6)) |
| 47 |
mexErrMsgTxt("onsetsds: unrecognised ODF type.\n");
|
| 48 |
} |
| 49 |
const unsigned int medspan |
| 50 |
= (nrhs<3) ? 11 : (unsigned int) mxGetScalar(prhs[2]); |
| 51 |
const float srate = (nrhs<4) ? 44100.f : (float) mxGetScalar(prhs[3]); |
| 52 |
|
| 53 |
// set up the ods
|
| 54 |
OnsetsDS ods; |
| 55 |
float* odsdata = (float*) malloc( onsetsds_memneeded(odftype, fftframesize, medspan) ); |
| 56 |
onsetsds_init(&ods, odsdata, ODS_FFT_SC3_COMPLEX, odftype, fftframesize, medspan, srate); |
| 57 |
|
| 58 |
// This is where we'll repack an individual frame
|
| 59 |
float* packeddata = malloc(fftframesize * sizeof(float)); |
| 60 |
|
| 61 |
// set up the output array, size numframes
|
| 62 |
double *results = (double*) mxCalloc(numframes, sizeof(double)); |
| 63 |
if(!results){
|
| 64 |
mexErrMsgTxt("onsetsds error, could not create results array (out of memory?).\n");
|
| 65 |
} |
| 66 |
|
| 67 |
////////////////////////////////////////////////////////////////////////////
|
| 68 |
// iterate the frames, converting to expected format and onset-detecting
|
| 69 |
size_t i; |
| 70 |
for(i=0; i<numframes; ++i){ |
| 71 |
// copy the data into an array in ODS_FFT_SC3_COMPLEX format.
|
| 72 |
// note that here we're discarding stuff above nyquist, since assuming real-valued input.
|
| 73 |
size_t frameoffset = fftframesize * i; |
| 74 |
packeddata[0] = (float) real[frameoffset]; |
| 75 |
packeddata[1] = (float) real[frameoffset + fftframesize / 2]; |
| 76 |
size_t j; |
| 77 |
for(j=1; j< fftframesize/2; ++j){ |
| 78 |
packeddata[j+j] = (float) real[frameoffset + j];
|
| 79 |
packeddata[j+j+1] = (float) imag[frameoffset + j]; |
| 80 |
} |
| 81 |
bool onset = onsetsds_process(&ods, packeddata);
|
| 82 |
results[i] = (onset ? 1.0 : 0.0); |
| 83 |
} |
| 84 |
|
| 85 |
// Copy the results from double-array into matlab format
|
| 86 |
mxArray *resultsM = mxCreateDoubleMatrix(1,numframes,mxREAL);
|
| 87 |
memcpy(mxGetPr(resultsM), results, numframes * sizeof(double)); |
| 88 |
plhs[0] = resultsM;
|
| 89 |
|
| 90 |
// destroy the ods correctly, and any matlabby things that need to go too.
|
| 91 |
free(ods.data); |
| 92 |
free(packeddata); |
| 93 |
mxFree(results); |
| 94 |
} |