# HG changeset patch # User Andrew N Robertson # Date 1388412522 0 # Node ID 7ec1ed0b2eb041bf051be5405c0d8a1f43873d99 # Parent 5a94f002e5ef6456c7d0e13f3b75e9cbde620756 Added offline precise onset detection, outputting precise locations in seconds to text file diff -r 5a94f002e5ef -r 7ec1ed0b2eb0 ofxPreciseOnsetDetectorOffline/PreciseOnsetDetectorOffline.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ofxPreciseOnsetDetectorOffline/PreciseOnsetDetectorOffline.cpp Mon Dec 30 14:08:42 2013 +0000 @@ -0,0 +1,182 @@ +/* + * PreciseOnsetDetectorOffline.cpp + * ofxPreciseOnsetDetectionOffline + * + * Created by Andrew Robertson on 25/12/2013. + * Copyright 2013 QMUL. All rights reserved. + * + */ + + +//add a retrigger threshold + +#include "PreciseOnsetDetectorOffline.h" + +PreciseOnsetDetectorOffline::PreciseOnsetDetectorOffline(){ + frameSize = 1024; + hopSize = 512; + preciseLocator.setup(frameSize); + writeOutput = true;//write output to txt when loading file - stored at sample location as file +} + +PreciseOnsetDetectorOffline::~PreciseOnsetDetectorOffline(){ + +} + + +void PreciseOnsetDetectorOffline::load(std::string filename){ + + //name for output file is same dir and filename as aif/wav but with _preciseOnsets.txt added + //eg 'song.wav' is 'song.wav_preciseOnsets.txt' + + processAudioForBeatTimes(filename); +} + + + +int PreciseOnsetDetectorOffline::processAudioForBeatTimes(std::string audiofile){ + //originally from BeatAnnotationViewer project + + BeatWriter writer; + dfValues.clear(); + onsetLocations.clear(); + onsetPositionFrames.clear(); + + // static double frame[FRAMESIZE]; // to hold a single frame + double buffer[frameSize]; + double dfval; + + for (int i = 0;i < frameSize;i++) + { + buffer[i] = 0; + } + + //detfun = new df(1,(FRAMESIZE*2),0); + + // initialises with hopsize = 512, framesize = 1024, complex spectral difference DF and hanning window + detectionFunction = new OnsetDetectionFunction(); + + SNDFILE *infile, *outfile ; // define input and output sound files + + SF_INFO sfinfo ; // struct to hold info about sound file + int readcount ; // counts number of samples read from sound file + const char *infilename = audiofile.c_str(); + //"/Users/andrew/Music/Station To Station 2/3-03 Panic In Detroit (Live Nassau Coliseum '76).wav";//"ledzep.wav" ; // input file name + // const char *outfilename = "output.wav" ; // output file name + + + // Open Input File + if (! (infile = sf_open (infilename, SFM_READ, &sfinfo))) + { // Open failed + printf ("Not able to open input file %s.\n", infilename) ; + // Print the error message from libsndfile. + puts (sf_strerror (NULL)) ; + return 1; + } ; + + printf("opened '%s'\n", audiofile.c_str()); + loadedFilename = audiofile; + //STEREO OKAY + + //HERE IS THE CLASSIC LOADING FILE CODE + //DEALS WITH MORE THAN MONO + int channels = sfinfo.channels; + samples = sfinfo.frames; + printf("Number of channels %i, samples %i\n", channels, samples); + + //for writing output + std::string outputFilename = audiofile+"_preciseOnsets.txt"; + + if (writeOutput) + writer.openFile(outputFilename); + + + int blocksize = hopSize;//FRAMESIZE; + float buf [channels * blocksize] ; + float frame[blocksize]; + + int k, m; + readcount = 1; + int counter = 0; + + //DoubleVector d; + while ((readcount = sf_readf_float (infile, buf, blocksize)) > 0){ + for (k = 0 ; k < readcount ; k++){ + //d.clear(); + frame[k] = 0; + + for (m = 0 ; m < channels ; m++){ + frame[k] += buf[k*channels + 0];//sum the channels together + //d.push_back(buf [k * channels + m]); + } + + frame[k] /= channels;//average of the channels + } + + //add to our buffer for pocessing + for (int i = 0; i< frameSize-hopSize;i++) + { + buffer[i] = buffer[i+hopSize]; + buffer[i+hopSize] = frame[i]; + } + + // for (int i = 0; i < frameSize; i++) + // printf("buffer[%i] %.5f\n", i, buffer[i]); + + dfval = detectionFunction->getDFsample(buffer); // compute detection function sample + + dfValues.push_back(dfval); + + printf("det val %i: %f\n", counter, dfval); + + if (peakProcess.peakProcessing(dfval)){ + printf("BANG\n"); + onsetPositionFrames.push_back(counter); + int precisesample = preciseLocator.findExactOnset(&buffer[0]); + //so exact sample is + int exactsample = (counter-1)*hopSize;//chunks in from beginning + //as we have just added hopsize samples in, the beginning of the frame is -1 from counter + exactsample += precisesample; + //printf("PreciseSample %i, %i\n", precisesample, exactsample); + if (writeOutput) + writer.writeBeatTime(exactsample/44100.); + + onsetLocations.push_back(exactsample/44100.); + } + + counter++; + printf("read %i samples\n", readcount); + //was sf_write_double(outfile, frame, readcount) ; + + }//end readcount + //END STEREO OKAY + + // Close input file + sf_close (infile); + + if (writeOutput) + writer.closeFile(); + + delete detectionFunction; + detectionFunction = NULL; + + return 0; + +} + + + + +void PreciseOnsetDetectorOffline::update(){ + +} + + +void PreciseOnsetDetectorOffline::draw(){ + //do vizualisation in a specialised class +} + +void PreciseOnsetDetectorOffline::printOnsetLocations(){ + for (int i = 0; i < (int)onsetLocations.size(); i++) + printf("Onset[%i]: %.3f\n", i, onsetLocations[i]); +} diff -r 5a94f002e5ef -r 7ec1ed0b2eb0 ofxPreciseOnsetDetectorOffline/PreciseOnsetDetectorOffline.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ofxPreciseOnsetDetectorOffline/PreciseOnsetDetectorOffline.h Mon Dec 30 14:08:42 2013 +0000 @@ -0,0 +1,59 @@ +/* + * PreciseOnsetDetectorOffline.h + * ofxPreciseOnsetDetectionOffline + * + * Created by Andrew Robertson on 25/12/2013. + * Copyright 2013 QMUL. All rights reserved. + * + */ + + +#ifndef PRECISE_ONSET_DETECTOR +#define PRECISE_ONSET_DETECTOR + +#include "OnsetDetectionFunction.h" +#include "vector.h" +#include "ofMain.h" +#include "sndfile.h" + +#include "PeakProcessor.h" +#include "PreciseOnsetLocator.h" + +#include "BeatWriter.h" + +class PreciseOnsetDetectorOffline{ +public: + PreciseOnsetDetectorOffline(); + ~PreciseOnsetDetectorOffline(); + + + void load(std::string filename); + void update(); + void draw(); + + int processAudioForBeatTimes(std::string audiofile); + + void printOnsetLocations(); + + //vars + int frameSize; + int hopSize; + int samples;//number of samples + + SNDFILE *infile; // define input and output sound files + SF_INFO sfinfo ; // struct to hold info about sound file + + std::string loadedFilename; + + OnsetDetectionFunction* detectionFunction; + + PeakProcessor peakProcess; + PreciseOnsetLocator preciseLocator; + + std::vector dfValues; + std::vector onsetLocations;//of exact time in seconds + std::vector onsetPositionFrames; + + bool writeOutput;//write output to txt +}; +#endif \ No newline at end of file diff -r 5a94f002e5ef -r 7ec1ed0b2eb0 ofxPreciseOnsetDetectorOffline/PreciseOnsetVisualiser.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ofxPreciseOnsetDetectorOffline/PreciseOnsetVisualiser.cpp Mon Dec 30 14:08:42 2013 +0000 @@ -0,0 +1,92 @@ +/* + * PreciseOnsetVisualiser.cpp + * ofxPreciseOnsetDetectionOffline + * + * Created by Andrew Robertson on 28/12/2013. + * Copyright 2013 QMUL. All rights reserved. + * + */ + +#include "PreciseOnsetVisualiser.h" + +PreciseOnsetVisualiser::PreciseOnsetVisualiser(){ + +} + +PreciseOnsetVisualiser::~PreciseOnsetVisualiser(){ + delete pod; + pod = NULL; +} + +void PreciseOnsetVisualiser::newFile(){ + resetWindow(); + windowPress = 0; + + soundPlay.loadSound(pod->loadedFilename, false); + paused = true; + soundPlay.play(); + soundPlay.setPaused(true); +} + +void PreciseOnsetVisualiser::update(){ + +} + +void PreciseOnsetVisualiser::draw(){ + //if plotting use this, else comment out + + ofSetColor(ofColor::white); + window.drawBackground(); + ofSetColor(ofColor::black); + window.drawOutline(); + ofSetColor(ofColor::blue); + plotter.drawBeatStripes(pod->onsetLocations, window, windowStart, windowEnd); + + ofSetColor(ofColor::red); + plotter.drawStripe(soundPlay.getPosition()*pod->samples/44100., window, windowStart, windowEnd); + +} + +//void PreciseOnsetVisualiser::drawOnsets(DoubleVector& onsetTimesSeconds, ofxWindowregion& window, double startTime, double endTime){ +//} + +void PreciseOnsetVisualiser::resetWindow(){ + windowStart = 0; + windowEnd = pod->samples/44100.; + printf("reset: start %.1f end %.1f\n", windowStart, windowEnd); +} + +void PreciseOnsetVisualiser::cropStart(){ + windowStart = windowPress; + printf("s: start %.1f end %.1f\n", windowStart, windowEnd); +} + +void PreciseOnsetVisualiser::cropEnd(){ + if (windowPress > windowStart) + windowEnd = windowPress; + + printf("crop end: start %.1f end %.1f\n", windowStart, windowEnd); +} + + +void PreciseOnsetVisualiser::mousePressed(int& x, int& y){ + if (window.tapped(x, y)){ + windowPress = windowStart + (windowEnd-windowStart)*(x - window.x)/window.width; + + printf("window position is %f\n", windowPress); + } +} + +void PreciseOnsetVisualiser::togglePlay(){ + if (!paused ){ + soundPlay.setPaused(true); + paused = true; + printf("was playing\n"); + } + else { + soundPlay.setPaused(false);// + paused = false; + printf("was not playing\n"); + } + +} \ No newline at end of file diff -r 5a94f002e5ef -r 7ec1ed0b2eb0 ofxPreciseOnsetDetectorOffline/PreciseOnsetVisualiser.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ofxPreciseOnsetDetectorOffline/PreciseOnsetVisualiser.h Mon Dec 30 14:08:42 2013 +0000 @@ -0,0 +1,45 @@ +/* + * PreciseOnsetVisualiser.h + * ofxPreciseOnsetDetectionOffline + * + * Created by Andrew Robertson on 28/12/2013. + * Copyright 2013 QMUL. All rights reserved. + * + */ + +#ifndef PRECISE_ONSET_VISUALISER +#define PRECISE_ONSET_VISUALISER + +#include "PreciseOnsetDetectorOffline.h" + +#include "ofxWindowRegion.h" +#include "ofxPlotFunction.h" + +class PreciseOnsetVisualiser{ +public: + PreciseOnsetVisualiser(); + ~PreciseOnsetVisualiser(); + + void newFile(); + void update(); + void draw(); + + void mousePressed(int& x, int& y); + void togglePlay(); + + void resetWindow(); + void cropStart(); + void cropEnd(); + + //vars + PreciseOnsetDetectorOffline* pod; + ofSoundPlayer soundPlay; + bool paused; +// void drawOnsets(DoubleVector& onsetTimesSeconds, ofxWindowregion& window, double startTime, double endTime); + + ofxWindowRegion window; + ofxPlotFunction plotter; + + double windowStart, windowEnd, windowPress; +}; +#endif \ No newline at end of file diff -r 5a94f002e5ef -r 7ec1ed0b2eb0 ofxPreciseOnsetDetectorOffline/main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ofxPreciseOnsetDetectorOffline/main.cpp Mon Dec 30 14:08:42 2013 +0000 @@ -0,0 +1,10 @@ +#include "testApp.h" +#include "ofAppGlutWindow.h" + +//-------------------------------------------------------------- +int main(){ + ofAppGlutWindow window; // create a window + // set width, height, mode (OF_WINDOW or OF_FULLSCREEN) + ofSetupOpenGL(&window, 1024, 768, OF_WINDOW); + ofRunApp(new testApp()); // start the app +} diff -r 5a94f002e5ef -r 7ec1ed0b2eb0 ofxPreciseOnsetDetectorOffline/testApp.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ofxPreciseOnsetDetectorOffline/testApp.cpp Mon Dec 30 14:08:42 2013 +0000 @@ -0,0 +1,167 @@ +#include "testApp.h" + +//possible to just omit the drawing (uses ofxWindowRegion for the screen and ofxPlotFunction to plot beat times) + +//-------------------------------------------------------------- +void testApp::setup(){ + pov.window.setToRelativeSize(0.1, 0.1, 0.8, 0.3); + pov.pod = &preciseOnsetDetect; + +// preciseOnsetDetect.load("/Users/andrew/Documents/work/programming/MadMax/AudioFiles/AdamBetts/AdamBetss_1_Swing_Kick.wav"); +// preciseOnsetDetect.load("/Users/andrew/Music/Logic/GreenOnionsChichester/GreenOnionsChichester/Bouncing/Snare_Sontronics#08edit.aif"); + loadNewFile("/Users/andrew/Music/Logic/GreenOnionsChichester/GreenOnionsChichester/Audio Files/Ride_SM58#08.aif"); + +} + + +void testApp::loadNewFile(std::string filename){ + preciseOnsetDetect.load(filename); + preciseOnsetDetect.printOnsetLocations(); + + //windowStart = 0; + //windowEnd = preciseOnsetDetect.samples/44100.; + //windowPress = 0; + + pov.newFile(); +} + +//-------------------------------------------------------------- +void testApp::update(){ + preciseOnsetDetect.update(); + pov.update(); +} + +//-------------------------------------------------------------- +void testApp::draw(){ + + pov.draw(); + /* + //if plotting use this, else comment out + ofSetColor(ofColor::white); + window.drawBackground(); + ofSetColor(ofColor::black); + window.drawOutline(); + ofSetColor(ofColor::blue); + plotter.drawBeatStripes(preciseOnsetDetect.onsetLocations, window, windowStart, windowEnd); +*/ + +} + +//-------------------------------------------------------------- +void testApp::keyPressed(int key){ + std::string loadName; + switch (key) { + case 'r': + pov.resetWindow(); + break; + case 's': + pov.cropStart(); + break; + case 'e': + pov.cropEnd(); + break; + case 'o': + if (getFilenameFromDialogBox(&loadName)){ + printf("loading %s\n", (loadName).c_str()); + loadNewFile(loadName); + }; + + //delete testName; + break; + case ' ': + pov.togglePlay(); + break; + case OF_KEY_RETURN: + pov.soundPlay.stop(); + break; + + default: + break; + } +} + +//-------------------------------------------------------------- +void testApp::keyReleased(int key){ + +} + +//-------------------------------------------------------------- +void testApp::mouseMoved(int x, int y){ + +} + +//-------------------------------------------------------------- +void testApp::mouseDragged(int x, int y, int button){ + +} + +//-------------------------------------------------------------- +void testApp::mousePressed(int x, int y, int button){ +// if (window.tapped(x, y)){ +// windowPress = windowStart + (windowEnd-windowStart)*(x - window.x)/window.width; +// +// printf("window position is %f\n", windowPress); +// } + pov.mousePressed(x, y); + +} + +//-------------------------------------------------------------- +void testApp::mouseReleased(int x, int y, int button){ + +} + +//-------------------------------------------------------------- +void testApp::windowResized(int w, int h){ + +} + +//-------------------------------------------------------------- +void testApp::gotMessage(ofMessage msg){ + +} + +//-------------------------------------------------------------- +void testApp::dragEvent(ofDragInfo dragInfo){ + +} + + + +bool testApp::getFilenameFromDialogBox(std::string* fileNameToSave){ + //this uses a pointer structure within the loader and returns true if the dialogue box was used successfully + // first, create a string that will hold the URL + string URL; + + // // openFile(string& URL) returns 1 if a file was picked + // // returns 0 when something went wrong or the user pressed 'cancel' + // int response = ofxFileDialogOSX::openFile(URL); + // if(response){ + // // now you can use the URL + // *fileNameToSave = URL; + // //printf("\n filename is %s \n", soundFileName.c_str()); + // return true; + // } + // else { + // // soundFileName = "OPEN canceled. "; + // printf("\n open file cancelled \n"); + // return false; + // } + + // openFile(string& URL) returns 1 if a file was picked + // returns 0 when something went wrong or the user pressed 'cancel' + ofFileDialogResult fileResult = ofSystemLoadDialog("Choose audio file to load"); + + if(fileResult.bSuccess){ + // now you can use the URL + *fileNameToSave = fileResult.filePath; + //printf("\n filename is %s \n", soundFileName.c_str()); + return true; + } + else { + // soundFileName = "OPEN canceled. "; + printf("\n open file cancelled \n"); + return false; + } +} + diff -r 5a94f002e5ef -r 7ec1ed0b2eb0 ofxPreciseOnsetDetectorOffline/testApp.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ofxPreciseOnsetDetectorOffline/testApp.h Mon Dec 30 14:08:42 2013 +0000 @@ -0,0 +1,38 @@ +#pragma once + +#include "ofMain.h" + +#include "PreciseOnsetDetectorOffline.h" +#include "PreciseOnsetVisualiser.h" + +#include "ofxWindowRegion.h" +#include "ofxPlotFunction.h" + +class testApp : public ofBaseApp{ + public: + void setup(); + void update(); + void draw(); + + void keyPressed(int key); + void keyReleased(int key); + void mouseMoved(int x, int y); + void mouseDragged(int x, int y, int button); + void mousePressed(int x, int y, int button); + void mouseReleased(int x, int y, int button); + void windowResized(int w, int h); + void dragEvent(ofDragInfo dragInfo); + void gotMessage(ofMessage msg); + + void loadNewFile(std::string filename); + bool getFilenameFromDialogBox(string* fileNameToSave); + + + //vars + PreciseOnsetDetectorOffline preciseOnsetDetect; +// ofxWindowRegion window; +// ofxPlotFunction plotter; +// double windowStart, windowEnd, windowPress; + + PreciseOnsetVisualiser pov; +}; diff -r 5a94f002e5ef -r 7ec1ed0b2eb0 src/BeatWriter.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/BeatWriter.cpp Mon Dec 30 14:08:42 2013 +0000 @@ -0,0 +1,65 @@ +/* + * BeatWriter.cpp + * BTrack + * + * Created by Andrew on 31/10/2013. + * Copyright 2013 QMUL. All rights reserved. + * + */ + +#include "BeatWriter.h" + +/* + * BeatWriter.cpp + * MultipleAudioMathcher + * + * Created by Andrew on 25/04/2012. + * Copyright 2012 QMUL. All rights reserved. + * + */ + +#include "BeatWriter.h" + +BeatWriter::BeatWriter(){ + filepath = "output.txt"; + //openFile(); +} + +BeatWriter::~BeatWriter(){ + closeFile(); +} + +void BeatWriter::writeBeatTime(const double& beatTime){ + + if (outputFile.is_open()){ + outputFile << beatTime << endl; + } else{ + printf("trying to write value but file closed\n"); + } +} + +void BeatWriter::openFile(std::string pathname){ + // closeFile(); + filepath = pathname; + printf("Writer: opening file '%s'\n", pathname.c_str()); + //filepath = "/Users/andrew/Ride_SM58#08.aif.txt"; + openFile(); +} + +void BeatWriter::openFile(){ + if (!outputFile.is_open()){ + outputFile.open(filepath.c_str()); + //printf("opening file %s\n", filepath.c_str()); + }else{ + printf("file already open! %s\n", filepath.c_str()); + } +} + +void BeatWriter::closeFile(){ + if (outputFile.is_open()){ + outputFile.close(); + printf("closing file '%s'\n", filepath.c_str()); + }else { + printf("Writer: file is not open to be closed\n"); + } +} \ No newline at end of file diff -r 5a94f002e5ef -r 7ec1ed0b2eb0 src/BeatWriter.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/BeatWriter.h Mon Dec 30 14:08:42 2013 +0000 @@ -0,0 +1,46 @@ +/* + * BeatWriter.h + * BTrack + * + * Created by Andrew on 31/10/2013. + * Copyright 2013 QMUL. All rights reserved. + * + */ + +/* + * BeatWriter.h + * MultipleAudioMathcher + * + * Created by Andrew on 25/04/2012. + * Copyright 2012 QMUL. All rights reserved. + * + */ + + + + +#ifndef BEAT_WRITER_H +#define BEAT_WRITER_H + + +// basic file operations for text file stuff +#include +#include +using namespace std; + +class BeatWriter{ + +public: + BeatWriter(); + ~BeatWriter(); + + std::string filepath; + ofstream outputFile; + + void openFile(); + void openFile(std::string pathname); + void closeFile(); + void writeBeatTime(const double& beatTime); + +}; +#endif \ No newline at end of file diff -r 5a94f002e5ef -r 7ec1ed0b2eb0 src/PeakProcessor.cpp --- a/src/PeakProcessor.cpp Sat Sep 22 01:11:31 2012 +0100 +++ b/src/PeakProcessor.cpp Mon Dec 30 14:08:42 2013 +0000 @@ -2,13 +2,15 @@ * PeakProcessor.cpp * peakOnsetDetector * - * Created by Andrew on 07/09/2012. + * Created by Andrew Robertson on 07/09/2012. * Copyright 2012 QMUL. All rights reserved. * */ #include "PeakProcessor.h" +const bool printingOn = true;//false; + PeakProcessor::PeakProcessor(){ recentDFsamples.assign(vectorSize, 0.0); @@ -19,8 +21,8 @@ currentFrame = 0; cutoffForRepeatOnsetsFrames = 4; detectionTriggerRatio = 0.5f; - detectionTriggerThreshold = 0.1; - bestSlopeMedian = 1; + detectionTriggerThreshold = 5;//0.1; + bestSlopeMedian = 8; thresholdRelativeToMedian = 1.1; slopeFallenBelowMedian = true; lastSlopeOnsetFrame = 0; @@ -42,11 +44,11 @@ newOnsetFound = checkForSlopeOnset(slopeVal); + if (printingOn) + printf("PeakProcessor: slope %f best slope median %f det trigger thresh median %f\n", slopeVal, bestSlopeMedian, detectionTriggerThreshold); - printf("slope %f median %f det median %f\n", slopeVal, bestSlopeMedian, detectionTriggerThreshold); - if (newOnsetFound){ - printf("BANG!\n"); - + if (newOnsetFound && printingOn){ + printf("PeakProcessor: BANG!\n"); } recentDFslopeValues.erase (recentDFslopeValues.begin(), recentDFslopeValues.begin()+1);//erase first val diff -r 5a94f002e5ef -r 7ec1ed0b2eb0 src/PeakProcessor.h --- a/src/PeakProcessor.h Sat Sep 22 01:11:31 2012 +0100 +++ b/src/PeakProcessor.h Mon Dec 30 14:08:42 2013 +0000 @@ -2,7 +2,7 @@ * PeakProcessor.h * peakOnsetDetector * - * Created by Andrew on 07/09/2012. + * Created by Andrew Robertson on 07/09/2012. * Copyright 2012 QMUL. All rights reserved. * */ diff -r 5a94f002e5ef -r 7ec1ed0b2eb0 src/PreciseOnsetLocator.cpp --- a/src/PreciseOnsetLocator.cpp Sat Sep 22 01:11:31 2012 +0100 +++ b/src/PreciseOnsetLocator.cpp Mon Dec 30 14:08:42 2013 +0000 @@ -2,13 +2,15 @@ * PreciseOnsetLocator.cpp * peakOnsetDetector * - * Created by Andrew on 21/09/2012. + * Created by Andrew Robertson on 21/09/2012. * Copyright 2012 QMUL. All rights reserved. * */ #include "PreciseOnsetLocator.h" +const bool printingOn = true; + PreciseOnsetLocator::PreciseOnsetLocator(){ setup(512); } @@ -25,6 +27,8 @@ bufferSize = size; onsetSamples.assign(bufferSize, 0.0); recentBufferSamples.assign(bufferSize, 0.0); + if (printingOn) + printf("Precise onset locator - using %i samples as framesize\n", size); } void PreciseOnsetLocator::storeSamples(double* newSamples){ @@ -37,7 +41,7 @@ int PreciseOnsetLocator::findExactOnset(double* frame){ //store the samples - mainly for viewing actually onsetSamples.clear(); - for (int i = 0; i < bufferSize;i++) { + for (int i = 0; i < bufferSize;i++){ onsetSamples.push_back(frame[i]); } @@ -49,20 +53,21 @@ int endIndex = bufferSize; int hopSize; - for (int resolution = bufferSize/2;resolution > 1;resolution/=2){ - printf("resolution %i\n", resolution); + for (int resolution = bufferSize/2; resolution > 1; resolution/=2){ + if (printingOn) + printf("resolution %i\n", resolution); bestEnergyDifference = 0; // printf("previous energy %f", lastEnergySum); //initialise last energySum hopSize = resolution/2; - lastEnergySum = getLastEnergySum(bestEnergyIndex, resolution); hopsizeLastEnergySum = getLastEnergySum(bestEnergyIndex + hopSize, resolution); for (int startIndex = bestEnergyIndex;startIndex + resolution <= endIndex;startIndex += hopSize){ - printf("index %i last energy %f hop energy %f ", startIndex, lastEnergySum, hopsizeLastEnergySum); + if (printingOn) + printf("index %i last energy %f hop energy %f ", startIndex, lastEnergySum, hopsizeLastEnergySum); //sum the energy for this new frame energySum = 0; @@ -70,7 +75,8 @@ energySum += onsetSamples[startIndex + i] * onsetSamples[startIndex + i]; } - printf("energysum %f\n", energySum); + if (printingOn) + printf("energysum %f\n", energySum); //check if new max difference energyDifference = energySum - lastEnergySum; if (energyDifference > bestEnergyDifference){ @@ -84,11 +90,13 @@ hopsizeLastEnergySum = energySum; } - printf("winning index is %i\n", bestEnergyIndex); + if (printingOn) + printf("winning index is %i\n", bestEnergyIndex); endIndex = bestEnergyIndex + resolution; } - printf("TOTAL WINNER %i\n", bestEnergyIndex); + if (printingOn) + printf("TOTAL WINNER %i\n", bestEnergyIndex); return bestEnergyIndex; } diff -r 5a94f002e5ef -r 7ec1ed0b2eb0 src/PreciseOnsetLocator.h --- a/src/PreciseOnsetLocator.h Sat Sep 22 01:11:31 2012 +0100 +++ b/src/PreciseOnsetLocator.h Mon Dec 30 14:08:42 2013 +0000 @@ -2,7 +2,7 @@ * PreciseOnsetLocator.h * peakOnsetDetector * - * Created by Andrew on 21/09/2012. + * Created by Andrew Robertson on 21/09/2012. * Copyright 2012 QMUL. All rights reserved. * */ diff -r 5a94f002e5ef -r 7ec1ed0b2eb0 src/testApp.cpp --- a/src/testApp.cpp Sat Sep 22 01:11:31 2012 +0100 +++ b/src/testApp.cpp Mon Dec 30 14:08:42 2013 +0000 @@ -62,7 +62,7 @@ void testApp::draw(){ ofSetColor(225); - ofDrawBitmapString("AUDIO INPUT EXAMPLE " + ofToString(exactOnsetIndex), 32, 32); + ofDrawBitmapString("AUDIO INPUT :: PRECISE ONSET DETECTION " + ofToString(exactOnsetIndex), 32, 32); ofDrawBitmapString("press 's' to unpause the audio\n'e' to pause the audio", 31, 92); ofNoFill(); @@ -100,13 +100,16 @@ ofSetLineWidth(1); ofRect(0, 0, 512, 200); - + + //param + float heightFactor = 0.15; + ofSetColor(245, 58, 135); ofSetLineWidth(3); ofBeginShape(); for (int i = 0; i < peakProcess.recentDFsamples.size(); i++){ - int height = 100 - peakProcess.recentDFsamples[i]*10; + int height = 200 - peakProcess.recentDFsamples[i]*heightFactor; ofVertex(i*6, height); // if (recentDFonsetFound[i]){ // ofCircle(32+i*6, 376+height , 10); @@ -130,7 +133,7 @@ ofBeginShape(); for (int i = 0; i < peakProcess.recentDFsamples.size(); i++){ - int height = 100 - peakProcess.recentDFslopeValues[i]*10; + int height = 200 - peakProcess.recentDFslopeValues[i]*heightFactor; ofVertex(i*6, height); } @@ -146,6 +149,7 @@ ofTranslate(32, 320, 0); ofSetColor(25, 224, 135); + ofSetLineWidth(3); ofBeginShape(); @@ -153,7 +157,7 @@ if (peakProcess.recentDFonsetFound[i]) ofVertex(i*6, 0); else { - ofVertex(i*6, 100); + ofVertex(i*6, 200); } } ofEndShape(false); @@ -161,12 +165,16 @@ ofPopMatrix(); ofPopStyle(); + + //ONSET Samples ofPushStyle(); ofPushMatrix(); ofTranslate(32, 520, 0); ofSetColor(245, 224, 235); + ofDrawBitmapString("exact onset index (in buffer) "+ofToString(exactOnsetIndex), 0, 20); + ofSetLineWidth(3); ofBeginShape();