Revision 0:a7c2bda0dfd9
| ChangeLog | ||
|---|---|---|
| 1 |
2011-02 Dan Stowell |
|
| 2 |
* Add matlab/octave wrapper |
|
| 3 |
|
|
| 4 | 1 |
2008-06 Dan Stowell |
| 5 | 2 |
* Fix bug in ODS_FFT_FFTW3_R2C case, thanks to both Wang Yue and Chris Cannam for spotting it |
| 6 | 3 |
|
| bundle.bash | ||
|---|---|---|
| 1 |
#!/bin/bash |
|
| 2 |
|
|
| 3 |
# Script to make a download bundle of the OnsetsDS code |
|
| 4 |
# Dan Stowell, June 2008 |
|
| 5 |
version=`date "+%Y-%m-%d"` |
|
| 6 |
|
|
| 7 |
# build the documentation |
|
| 8 |
cd doc |
|
| 9 |
doxygen |
|
| 10 |
cd .. |
|
| 11 |
|
|
| 12 |
rm -rf OnsetsDS |
|
| 13 |
|
|
| 14 |
svn export . OnsetsDS |
|
| 15 |
cp -R doc/html OnsetsDS/doc/html |
|
| 16 |
|
|
| 17 |
zip -r "OnsetsDS-$version" OnsetsDS |
|
| 18 |
tar -czvf "OnsetsDS-$version.tgz" OnsetsDS |
|
| 19 |
|
|
| doc/mainpage.dox | ||
|---|---|---|
| 1 | 1 |
/** \mainpage OnsetsDS - real time musical onset detection C/C++ library |
| 2 | 2 |
|
| 3 |
<small>Copyright (c) 2007 Dan Stowell (Published under the GNU Public License v2 or later).
|
|
| 3 |
<small>Copyright (c) 2007 Dan Stowell (Published under the GNU Public License v2). |
|
| 4 | 4 |
http://onsetsds.sourceforge.net/</small> |
| 5 | 5 |
|
| 6 | 6 |
<h2>Introduction</h2> |
| ... | ... | |
| 16 | 16 |
Its efficiency and fast reaction are designed with general real-time musical |
| 17 | 17 |
applications in mind. |
| 18 | 18 |
|
| 19 |
(Added Feb 2011: matlab/octave wrapper, an offline function onsetsds() which can |
|
| 20 |
be applied to a matrix of fft data) |
|
| 21 |
|
|
| 22 | 19 |
<h2>Download</h2> |
| 23 | 20 |
|
| 24 | 21 |
<ul> |
| 25 |
<li><a href="https://sourceforge.net/projects/onsetsds/files/onsetsds/OnsetsDS-source/">Download the sourcecode bundle</a></li>
|
|
| 22 |
<li><a href="http://sourceforge.net/">Download the sourcecode bundle</a></li>
|
|
| 26 | 23 |
<li>Or access the current development version using subversion [<small><a href="http://sourceforge.net/svn/?group_id=54622" title="What is subversion, and how to use it">info</a></small>]: <br /> |
| 27 | 24 |
<tt>svn co %https://onsetsds.svn.sourceforge.net/svnroot/onsetsds onsetsds</tt></li> |
| 28 | 25 |
</ul> |
| ... | ... | |
| 43 | 40 |
OnsetsDS ods; |
| 44 | 41 |
|
| 45 | 42 |
|
| 46 |
//-/////// (1) INITIALISATION: ///////-// |
|
| 43 |
///////// (1) INITIALISATION: ///////// |
|
| 44 |
|
|
| 45 |
// Allocate contiguous memory using malloc or whatever is reasonable. |
|
| 46 |
float* odsdata = (float*) malloc( onsetsds_memneeded(odftype, 512, 11) ); |
|
| 47 | 47 |
|
| 48 | 48 |
// There are various types of onset detector available, we must choose one |
| 49 | 49 |
odftype = ODS_ODF_RCOMPLEX; |
| 50 | 50 |
|
| 51 |
// Allocate contiguous memory using malloc or whatever is reasonable.
|
|
| 52 |
float* odsdata = (float*) malloc( onsetsds_memneeded(odftype, 512, 11) );
|
|
| 51 |
// Now initialise the OnsetsDS struct and its associated memory
|
|
| 52 |
onsetsds_init(ods, odsdata, ODS_FFT_FFTW3_HC, odftype, 512, 11);
|
|
| 53 | 53 |
|
| 54 |
// Now initialise the OnsetsDS struct and its associated memory |
|
| 55 |
onsetsds_init(&ods, odsdata, ODS_FFT_FFTW3_HC, odftype, 512, 11, 44100.f); |
|
| 56 | 54 |
|
| 57 |
|
|
| 58 |
//-/////// (2) EXECUTION: ///////-// |
|
| 55 |
///////// (2) EXECUTION: ///////// |
|
| 59 | 56 |
|
| 60 | 57 |
bool onset; |
| 61 | 58 |
while(running){
|
| 62 |
// Grab your 512- or 1024-point, 50%-overlap, nicely-windowed FFT data, into "fftdata"
|
|
| 59 |
// Grab your 512-point, 50%-overlap, nicely-windowed FFT data, into "fftdata" |
|
| 63 | 60 |
|
| 64 | 61 |
// Then detect. "onset" will be true when there's an onset, false otherwise |
| 65 |
onset = onsetsds_process(&ods, fftdata);
|
|
| 62 |
onset = onsetsds_process(ods, fftdata); |
|
| 66 | 63 |
} |
| 67 | 64 |
|
| 68 | 65 |
|
| 69 |
//-/////// (3) TIDYING UP: ///////-//
|
|
| 66 |
///////// (3) TIDYING UP: /////////
|
|
| 70 | 67 |
|
| 71 | 68 |
free(ods->data); // Or free(odsdata), they point to the same thing in this case |
| 72 | 69 |
|
| ... | ... | |
| 84 | 81 |
\li D. Stowell and M. D. Plumbley. |
| 85 | 82 |
<a href="http://www.elec.qmul.ac.uk/digitalmusic/papers/2007/StowellPlumbley07-icmc.pdf"> |
| 86 | 83 |
Adaptive whitening for improved real-time audio onset detection.</a> |
| 84 |
To appear in: |
|
| 87 | 85 |
Proceedings of the International Computer Music Conference (ICMC'07), |
| 88 | 86 |
Copenhagen, Denmark, August 2007. |
| 89 | 87 |
|
| 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 |
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 |
} |
|
| 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. |
|
| src/onsetsds.c | ||
|---|---|---|
| 24 | 24 |
#define ODS_DEBUG_POST_CSV 0 |
| 25 | 25 |
|
| 26 | 26 |
// Inline |
| 27 |
static inline float onsetsds_phase_rewrap(float phase){
|
|
| 27 |
inline float onsetsds_phase_rewrap(float phase); |
|
| 28 |
inline float onsetsds_phase_rewrap(float phase){
|
|
| 28 | 29 |
return (phase>MINUSPI && phase<PI) ? phase : phase + TWOPI * (1.f + floorf((MINUSPI - phase) * INV_TWOPI)); |
| 29 | 30 |
} |
| 30 | 31 |
|
| src/onsetsds.h | ||
|---|---|---|
| 59 | 59 |
* data comes from in order to interpret it correctly. |
| 60 | 60 |
*/ |
| 61 | 61 |
enum onsetsds_fft_types {
|
| 62 |
ODS_FFT_SC3_COMPLEX, ///< SuperCollider, cartesian co-ords ("SCComplexBuf") [dc, nyq, real[1], imag[1], real[2], imag[2]...] - NB it's more efficient to provide polar data from SC
|
|
| 63 |
ODS_FFT_SC3_POLAR, ///< SuperCollider, polar co-ords ("SCPolarBuf") [dc, nyq, mag[1], phase[1], mag[2], phase[2]...]
|
|
| 64 |
ODS_FFT_FFTW3_HC, ///< FFTW <a href="http://www.fftw.org/fftw3_doc/The-Halfcomplex_002dformat-DFT.html">"halfcomplex"</a> format - [dc, real[1], real[2] ... nyq, imag[nyq-1] ... imag[1]]
|
|
| 62 |
ODS_FFT_SC3_COMPLEX, ///< SuperCollider, cartesian co-ords ("SCComplexBuf") - NB it's more efficient to provide polar data from SC
|
|
| 63 |
ODS_FFT_SC3_POLAR, ///< SuperCollider, polar co-ords ("SCPolarBuf")
|
|
| 64 |
ODS_FFT_FFTW3_HC, ///< FFTW <a href="http://www.fftw.org/fftw3_doc/The-Halfcomplex_002dformat-DFT.html">"halfcomplex"</a> format |
|
| 65 | 65 |
ODS_FFT_FFTW3_R2C ///< FFTW regular format, typically produced using <a href="http://www.fftw.org/fftw3_doc/One_002dDimensional-DFTs-of-Real-Data.html#One_002dDimensional-DFTs-of-Real-Data">real-to-complex</a> transform |
| 66 | 66 |
}; |
| 67 | 67 |
|
| src/onsetsdshelpers.h | ||
|---|---|---|
| 36 | 36 |
#endif |
| 37 | 37 |
|
| 38 | 38 |
#include <fftw3.h> |
| 39 |
#include "onsetsds.h" |
|
| 39 |
#include "../onsetsds.h"
|
|
| 40 | 40 |
|
| 41 | 41 |
//////////////////////////////////////////////////////////////////////////////// |
| 42 | 42 |
|
Also available in: Unified diff