changeset 4:747075e72e54

Add matlab/octave wrapper (tested in octave)
author danstowell
date Thu, 10 Feb 2011 16:08:20 +0000
parents 15345ae708d6
children 422c0871839f
files mat_oct/mexme.m mat_oct/onsetsds.c mat_oct/onsetsds.m
diffstat 3 files changed, 138 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mat_oct/mexme.m	Thu Feb 10 16:08:20 2011 +0000
@@ -0,0 +1,1 @@
+mex                    -I../src  onsetsds.c ../src/onsetsds.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mat_oct/onsetsds.c	Thu Feb 10 16:08:20 2011 +0000
@@ -0,0 +1,104 @@
+/**
+    This file is part of "onsetsds".
+    (c) 2011 Dan Stowell and Queen Mary University of London
+    All rights reserved.
+
+    onsetsds is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    onsetsds is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with kdpee.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "math.h"
+#include "mex.h"
+#include "onsetsds.h"
+
+////////////////////////////////////////////////////////////////////////
+// MATLAB ENTRY FUNCTION:
+void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
+{
+	// implementation of: onsetsds(fftdata, odftype, medspan, srate)
+	
+	// Get the star of the show, the fft data
+	const mxArray *fftdata;	
+	fftdata = prhs[0];
+	if(!mxIsComplex(fftdata)){
+    	mexErrMsgTxt("onsetsds expects a matrix of complex data (e.g. from fft()).\n");
+	}
+	const size_t fftframesize = mxGetM(fftdata);
+	const size_t numframes    = mxGetN(fftdata);
+	
+	const double* real = mxGetPr(fftdata);
+	const double* imag = mxGetPi(fftdata);
+	
+	// optional args
+	int odftype = ODS_ODF_RCOMPLEX;
+	if(nrhs>1){
+		odftype = mxGetScalar(prhs[1]);
+		if((odftype < 0) || (newodftype > 6))
+    		mexErrMsgTxt("onsetsds: unrecognised ODF type.\n");
+	}
+	const unsigned int medspan
+	                  = (nrhs<3) ? 11 : (unsigned int) mxGetScalar(prhs[2]);
+	const float srate = (nrhs<4) ? 44100.f : (float) mxGetScalar(prhs[3]);
+	
+	// set up the ods
+	OnsetsDS ods;
+	float* odsdata = (float*) malloc( onsetsds_memneeded(odftype, fftframesize, medspan) );
+	onsetsds_init(&ods, odsdata, ODS_FFT_SC3_COMPLEX, odftype, fftframesize, medspan, srate);
+	
+	// This is where we'll repack an individual frame
+	float* packeddata = malloc(fftframesize * sizeof(float));
+	
+	// set up the output array, size numframes
+	double *results = (double*) mxCalloc(numframes, sizeof(double));
+	if(!results){
+    	mexErrMsgTxt("onsetsds error, could not create results array (out of memory?).\n");
+	}
+	
+	////////////////////////////////////////////////////////////////////////////
+	// iterate the frames, converting to expected format and onset-detecting
+	size_t i;
+	for(i=0; i<numframes; ++i){
+		// copy the data into an array in ODS_FFT_SC3_COMPLEX format.
+		// note that here we're discarding stuff above nyquist, since assuming real-valued input.
+		size_t frameoffset = fftframesize * i;
+		packeddata[0] = (float) real[frameoffset];
+		packeddata[1] = (float) real[frameoffset + fftframesize / 2];
+		size_t j;
+		for(j=1; j< fftframesize/2; ++j){
+			packeddata[j+j]   = (float) real[frameoffset + j];
+			packeddata[j+j+1] = (float) imag[frameoffset + j];
+		}
+		bool onset = onsetsds_process(&ods, packeddata);
+//		printf("%i ", onset);
+//		printf("[%i] %i", i, onset);
+		results[i] = (onset ? 1.0 : 0.0);
+//		printf("[%i] %g", i, results[i]);
+	}	
+	
+	// Copy the results from double-array into matlab format
+//	mwSize *dims = (mwSize*) mxCalloc(2, sizeof(mwSize));
+//	dims[0] = 1;
+//	dims[1] = numframes;
+//	mxArray *resultsM = mxCreateNumericArray(2, dims, mxINT8_CLASS, mxREAL);
+	mxArray *resultsM = mxCreateDoubleMatrix(1,numframes,mxREAL);
+//	mxSetPr(resultsM, results);
+	memcpy(mxGetPr(resultsM), results, numframes * sizeof(double));
+	plhs[0] = resultsM;
+	
+	// destroy the ods correctly, and any matlabby things that need to go too.
+	free(ods.data);
+	free(packeddata);
+//	mxFree(dims);
+	mxFree(results);
+	// *resultsM ? no I think that lives on in matlabworld
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mat_oct/onsetsds.m	Thu Feb 10 16:08:20 2011 +0000
@@ -0,0 +1,33 @@
+function onsets = onsetsds(fftdata, odftype, medspan, srate)
+% function onsets = onsetsds(fftdata)
+% function onsets = onsetsds(fftdata, odftype)
+% function onsets = onsetsds(fftdata, odftype, medspan)
+% function onsets = onsetsds(fftdata, odftype, medspan, srate)
+%
+% Musical onset detector using adaptive whitening 
+%     -- see http://onsetsds.sourceforge.net/
+%
+%  "fftdata": a matrix of FFT frames (1 per column) derived from an audio 
+%             file. The common case (used for testing the code) is 44.1 kHz 
+%             audio with 50% overlap and Hann windowing.
+%
+%  "odftype": integer specifying onset detection function to use:
+%              0 'power', 
+%              1 'magsum', 
+%              2 'complex',
+%              3 'rcomplex',  <-- default
+%              4 'phase', 
+%              5 'wphase', 
+%              6 'mkl'.
+%  "medspan": length of median-filter in frames, default is 11.
+%  "srate": sampling rate of audio, default is 44100.
+%
+% For more info see D. Stowell and M. D. Plumbley, 
+%         "Adaptive whitening for improved real-time audio onset detection", 
+%         Proceedings of the International Computer Music Conference (ICMC'07), 
+%         Copenhagen, Denmark, August 2007.
+%
+%   onsetsds is free software: you can redistribute it and/or modify
+%   it under the terms of the GNU General Public License as published by
+%   the Free Software Foundation, either version 2 of the License, or
+%   (at your option) any later version.