Revision 4:747075e72e54

View differences:

mat_oct/mexme.m
1
mex                    -I../src  onsetsds.c ../src/onsetsds.c
mat_oct/onsetsds.c
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
//		printf("%i ", onset);
83
//		printf("[%i] %i", i, onset);
84
		results[i] = (onset ? 1.0 : 0.0);
85
//		printf("[%i] %g", i, results[i]);
86
	}	
87
	
88
	// Copy the results from double-array into matlab format
89
//	mwSize *dims = (mwSize*) mxCalloc(2, sizeof(mwSize));
90
//	dims[0] = 1;
91
//	dims[1] = numframes;
92
//	mxArray *resultsM = mxCreateNumericArray(2, dims, mxINT8_CLASS, mxREAL);
93
	mxArray *resultsM = mxCreateDoubleMatrix(1,numframes,mxREAL);
94
//	mxSetPr(resultsM, results);
95
	memcpy(mxGetPr(resultsM), results, numframes * sizeof(double));
96
	plhs[0] = resultsM;
97
	
98
	// destroy the ods correctly, and any matlabby things that need to go too.
99
	free(ods.data);
100
	free(packeddata);
101
//	mxFree(dims);
102
	mxFree(results);
103
	// *resultsM ? no I think that lives on in matlabworld
104
}
mat_oct/onsetsds.m
1
function onsets = onsetsds(fftdata, odftype, medspan, srate)
2
% function onsets = onsetsds(fftdata)
3
% function onsets = onsetsds(fftdata, odftype)
4
% function onsets = onsetsds(fftdata, odftype, medspan)
5
% function onsets = onsetsds(fftdata, odftype, medspan, srate)
6
%
7
% Musical onset detector using adaptive whitening 
8
%     -- see http://onsetsds.sourceforge.net/
9
%
10
%  "fftdata": a matrix of FFT frames (1 per column) derived from an audio 
11
%             file. The common case (used for testing the code) is 44.1 kHz 
12
%             audio with 50% overlap and Hann windowing.
13
%
14
%  "odftype": integer specifying onset detection function to use:
15
%              0 'power', 
16
%              1 'magsum', 
17
%              2 'complex',
18
%              3 'rcomplex',  <-- default
19
%              4 'phase', 
20
%              5 'wphase', 
21
%              6 'mkl'.
22
%  "medspan": length of median-filter in frames, default is 11.
23
%  "srate": sampling rate of audio, default is 44100.
24
%
25
% For more info see D. Stowell and M. D. Plumbley, 
26
%         "Adaptive whitening for improved real-time audio onset detection", 
27
%         Proceedings of the International Computer Music Conference (ICMC'07), 
28
%         Copenhagen, Denmark, August 2007.
29
%
30
%   onsetsds is free software: you can redistribute it and/or modify
31
%   it under the terms of the GNU General Public License as published by
32
%   the Free Software Foundation, either version 2 of the License, or
33
%   (at your option) any later version.

Also available in: Unified diff