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.

Statistics Download as Zip
| Branch: | Revision:

root / mat_oct / onsetsds.c @ 6:55d7698f79f8

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
}