changeset 7:b1c13e8bec26

adding new files
author Venetian
date Thu, 14 Aug 2014 16:27:52 +0100
parents eb29c6b6dff8
children 184a7c232049
files ofxPreciseOnsetDetectorOffline/DetectionFunctions.cpp ofxPreciseOnsetDetectorOffline/DetectionFunctions.h ofxPreciseOnsetDetectorOffline/PointerOnsetVisualiser.cpp ofxPreciseOnsetDetectorOffline/PointerOnsetVisualiser.h ofxPreciseOnsetDetectorOffline/PreciseBassOnsetDetector.cpp ofxPreciseOnsetDetectorOffline/PreciseBassOnsetDetector.h ofxPreciseOnsetDetectorOffline/PreciseBassOnsetDetectorOffline.cpp ofxPreciseOnsetDetectorOffline/PreciseBassOnsetDetectorOffline.h ofxPreciseOnsetDetectorOffline/PreciseOnsetDetector.cpp ofxPreciseOnsetDetectorOffline/PreciseOnsetDetector.h ofxPreciseOnsetDetectorOffline/PreciseOnsetDetectorOffline.cpp ofxPreciseOnsetDetectorOffline/PreciseOnsetDetectorOffline.h ofxPreciseOnsetDetectorOffline/PreciseOnsetVisualiser.cpp ofxPreciseOnsetDetectorOffline/PreciseOnsetVisualiser.h ofxPreciseOnsetDetectorOffline/testApp.cpp ofxPreciseOnsetDetectorOffline/testApp.h
diffstat 16 files changed, 1711 insertions(+), 169 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ofxPreciseOnsetDetectorOffline/DetectionFunctions.cpp	Thu Aug 14 16:27:52 2014 +0100
@@ -0,0 +1,11 @@
+/*
+ *  DetectionFunctions.cpp
+ *  ofxPreciseOnsetDetectionOffline
+ *
+ *  Created by Andrew on 04/03/2014.
+ *  Copyright 2014 QMUL. All rights reserved.
+ *
+ */
+
+#include "DetectionFunctions.h"
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ofxPreciseOnsetDetectorOffline/DetectionFunctions.h	Thu Aug 14 16:27:52 2014 +0100
@@ -0,0 +1,21 @@
+/*
+ *  DetectionFunctions.h
+ *  ofxPreciseOnsetDetectionOffline
+ *
+ *  Created by Andrew Robertson on 04/03/2014.
+ *  Copyright 2014 QMUL. All rights reserved.
+ *
+ */
+
+
+#ifndef DETECTION_FUNCTIONS_H
+#define DETECTION_FUNCTIONS_H
+
+class DetectionFunctions{
+public:
+	DetectionFunctions();
+	~DetectionFunctions();
+	
+	
+};
+#endif
\ No newline at end of file
--- a/ofxPreciseOnsetDetectorOffline/PointerOnsetVisualiser.cpp	Sun Jan 19 23:07:13 2014 +0000
+++ b/ofxPreciseOnsetDetectorOffline/PointerOnsetVisualiser.cpp	Thu Aug 14 16:27:52 2014 +0100
@@ -27,7 +27,7 @@
 void PointerOnsetVisualiser::newFile(){
 	resetWindow();
 //	windowPress = 0;
-	
+	printf("loading sound %s\n", pod->loadedFilename.c_str());
 	soundPlay.loadSound(pod->loadedFilename, false);
 	paused = true;
 	soundPlay.play();
@@ -76,7 +76,8 @@
 	ofDrawBitmapString(ofToString(round(pod->secondsToFrameIndex((*windowEnd))), 1), window.x+window.width, window.y-10);
 	
 	ofSetColor(ofColor::blue);
-	plotter.drawBeatStripes(pod->onsetLocations, window, (*windowStart), (*windowEnd));
+	plotter.drawBeatStripes(pod->onsetList, window, (*windowStart), (*windowEnd));
+	//replaced above line with a plotter that can do our onset list
 	
 	//play position
 	ofSetColor(ofColor::red);
@@ -101,7 +102,7 @@
 	//	while ((*windowEnd) < pod->samples/44100.)
 	//		(*windowEnd) *= 2;
 	
-	(*windowEnd) = pod->samples/44100.;
+//	(*windowEnd) = pod->samples/44100.;
 	
 	printf("reset: start %.1f end %.1f\n", (*windowStart), (*windowEnd));
 }
--- a/ofxPreciseOnsetDetectorOffline/PointerOnsetVisualiser.h	Sun Jan 19 23:07:13 2014 +0000
+++ b/ofxPreciseOnsetDetectorOffline/PointerOnsetVisualiser.h	Thu Aug 14 16:27:52 2014 +0100
@@ -15,7 +15,7 @@
 #include "PreciseOnsetDetectorOffline.h"
 
 #include "ofxWindowRegion.h"
-#include "ofxPlotFunction.h"
+#include "ofxPlotOnsetFunction.h"
 
 class PointerOnsetVisualiser{
 public:
@@ -54,7 +54,7 @@
 	//	void drawOnsets(DoubleVector& onsetTimesSeconds, ofxWindowregion& window, double startTime, double endTime);
 	
 	ofxWindowRegion window;
-	ofxPlotFunction plotter;
+	ofxPlotOnsetFunction plotter;
 	
 	//this is the only change with pointer_onset_vis - it follows a NON-POINTER PreciseOnsetVisualiser
 	double *windowStart;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ofxPreciseOnsetDetectorOffline/PreciseBassOnsetDetector.cpp	Thu Aug 14 16:27:52 2014 +0100
@@ -0,0 +1,123 @@
+/*
+ *  PreciseBassOnsetDetector.cpp
+ *  BasslinePrediction
+ *
+ *  Created by Andrew N Robertson on 13/04/2014.
+ *  Copyright 2014 QMUL. All rights reserved.
+ *
+ */
+
+#include "PreciseBassOnsetDetector.h"
+
+
+PreciseBassOnsetDetector::PreciseBassOnsetDetector(){
+	pov.window.setToRelativeSize(0.1, 0.1, 0.8, 0.3);
+	pov.pod = &pod;//set up pointer if we want to visualise the onsets in a window
+	
+	//	std::string fileName;
+	//	fileName = "/Users/andrewrobertson/Music/audiowavs/Islamey/BachBWV846-2.wav";
+	//	loadNewFile(fileName);
+}
+
+PreciseBassOnsetDetector::~PreciseBassOnsetDetector(){
+	
+}
+
+void PreciseBassOnsetDetector::loadNewFile(std::string filename){
+	
+	pod.initialise();
+	pod.load(filename);	
+	pod.printOnsetLocations();
+	pov.newFile();//resets info in visualiser - could use pointer??
+}
+
+void PreciseBassOnsetDetector::update(){
+	pod.update();
+	pov.update();
+}
+
+void PreciseBassOnsetDetector::draw(){
+	pov.draw();
+}
+
+bool PreciseBassOnsetDetector::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;
+	
+	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;
+	}
+}
+
+void PreciseBassOnsetDetector::keyPressed(int key){
+	std::string loadName;
+	switch (key) {
+		case 'r':
+			pov.resetWindow();
+			break;
+		case 's':
+			pov.cropStart();
+			pod.cropStartTo(pov.windowStart);
+			break;
+		case 'e':
+			pov.cropEnd();
+			break;
+		case 'w':
+			printf("Exporting between %f and %f\n", pov.windowStart, pov.windowEnd);
+			pod.exportOnsetTimes(pov.windowStart, pov.windowEnd);
+			break;
+		case 'x':
+			printf("Exporting between %f and %f\n", 0., pov.lengthSeconds());
+			pod.exportOnsetTimes(0, pov.lengthSeconds());
+			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.stop();
+			
+			break;
+			
+		case OF_KEY_UP: case 'u':
+			pov.zoomIn();
+			break;
+		case OF_KEY_DOWN:
+			pov.zoomOut();
+			break;
+		case OF_KEY_RIGHT:
+			pov.scrollRight();
+			break;
+		case OF_KEY_LEFT:
+			pov.scrollLeft();
+			break;	
+			
+		default:
+			break;
+	}
+}
+
+void PreciseBassOnsetDetector::mousePressed(int x, int y, int button){
+	
+	pov.mousePressed(x, y);
+	
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ofxPreciseOnsetDetectorOffline/PreciseBassOnsetDetector.h	Thu Aug 14 16:27:52 2014 +0100
@@ -0,0 +1,45 @@
+/*
+ *  PreciseBassOnsetDetector.h
+ *  BasslinePrediction
+ *
+ *  Created by Andrew N Robertson on 13/04/2014.
+ *  Copyright 2014 QMUL. All rights reserved.
+ *
+ */
+
+#ifndef PRECISE_BASS_ONSET_DETECTOR
+#define PRECISE_BASS_ONSET_DETECTOR
+
+//#include "PreciseOnsetDetector.h"
+//#include "PreciseBassOnsetDetectorOffline.h"
+
+//#include "PreciseOnsetDetectorOffline.h"
+#include "PreciseOnsetVisualiser.h"
+
+#include "ofxWindowRegion.h"
+#include "ofxPlotFunction.h"
+
+#include "PreciseBassOnsetDetectorOffline.h"
+
+
+class PreciseBassOnsetDetector{
+public:
+	
+	PreciseBassOnsetDetector();
+	~PreciseBassOnsetDetector();
+	
+	void loadNewFile(std::string filename);
+	
+	void update();
+	void draw();
+	
+	void keyPressed(int key);
+	void mousePressed(int x, int y, int button);
+	
+	bool getFilenameFromDialogBox(std::string* fileNameToSave);
+	
+	PreciseBassOnsetDetectorOffline pod;
+	PreciseOnsetVisualiser pov;	
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ofxPreciseOnsetDetectorOffline/PreciseBassOnsetDetectorOffline.cpp	Thu Aug 14 16:27:52 2014 +0100
@@ -0,0 +1,692 @@
+/*
+ *  PreciseBassOnsetDetectorOffline.cpp
+ *  BasslinePrediction
+ *
+ *  Created by Andrew N Robertson on 11/04/2014.
+ *  Copyright 2014 QMUL. All rights reserved.
+ *
+ */
+
+#include "PreciseBassOnsetDetectorOffline.h"
+
+bool printingOn = false;//true;
+
+int PreciseBassOnsetDetectorOffline::processAudioFileForBeatTimes(std::string audiofile){
+	printf("PBODO: Process Function BASS OFFLINE VERSION\n");
+
+	//originally from BeatAnnotationViewer project
+	
+	initialise();// - needed but elsewhere
+	isBass = true;
+	
+	// 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);
+	
+	
+	
+    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);
+	
+	
+	int blocksize = hopSize;//FRAMESIZE;	
+	float buf [channels * blocksize] ;
+	float frame[blocksize];
+	
+	int k, m;
+	readcount = 1;
+	
+	
+	//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
+		}
+		
+		processAudioFrame(frame, blocksize);
+		processYinAudio(frame, blocksize);
+		//have now processed framecount samples
+		processBassPitches();
+		
+		//add to our buffer for pocessing
+		for (int i = 0; i< frameSize-hopSize;i++)
+		{
+			buffer[i] = buffer[i+hopSize];
+			buffer[i+hopSize] = frame[i];
+		}
+
+		//printf("read %i samples\n", readcount);
+		//was	sf_write_double(outfile, frame, readcount) ;
+		
+	}//end readcount
+	//END STEREO OKAY
+	
+	// Close input file
+    sf_close (infile);
+	
+	endProcessing();
+	
+	return 0;
+	
+}
+
+void PreciseBassOnsetDetectorOffline::processYinAudio(float* frame, int blocksize){
+	//continually update yin
+	yule.processBuffer(frame, (int)blocksize);
+}
+
+void PreciseBassOnsetDetectorOffline::processBassPitches(){
+	int tmpIndex = onsetList.size()-1;
+	int hsize = 1024;
+	while (tmpIndex >= 0 && onsetList[tmpIndex].positionSamples+8192+hsize>sampleCount){
+	//	printf("testing onset %i at %i, samplecount now %i diff %i\n", tmpIndex, onsetList[tmpIndex].positionSamples, sampleCount, sampleCount-onsetList[tmpIndex].positionSamples);
+		if (onsetList[tmpIndex].positionSamples+8192 <= sampleCount && !onsetList[tmpIndex].pitch){
+			//do yin value for this onset
+			onsetList[tmpIndex].pitch = yule.yinFrequency;
+			
+			float midiPitch = onsetList[tmpIndex].pitch/27.5;
+			if (midiPitch > 0){
+				midiPitch = 12.0*log(midiPitch)/log(2);
+				midiPitch += 24+9;
+			}
+			
+			onsetList[tmpIndex].midiPitch = midiPitch;
+			onsetList[tmpIndex].roundedPitch = round(midiPitch);
+			
+			setMidiNoteString(tmpIndex, midiPitch);//sets string eg C#4
+			
+			if (printingOn)
+				printf("PBODO: Yin Pitch %i, %f, %f, %s\n", tmpIndex, onsetList[tmpIndex].pitch, midiPitch, onsetList[tmpIndex].midiName.c_str());
+		}
+		
+		tmpIndex--;
+	}
+}
+
+void PreciseBassOnsetDetectorOffline::printOnsetLocations(){
+	for (int i = 0; i < (int)onsetList.size(); i++)
+		printf("PBODO: Onset[%i]: %.3f, samples %i pitch %f, %i\n", i, onsetList[i].onsetLocation, onsetList[i].positionSamples, onsetList[i].pitch, onsetList[i].roundedPitch);
+}
+
+void PreciseBassOnsetDetectorOffline::printPitchInfo(){
+	for (int i = 0; i < (int)onsetList.size(); i++)
+		printf("PBODO: Beat Position %i,%i: pitch %i\n", onsetList[i].beatPosition, onsetList[i].onsetType, onsetList[i].roundedPitch);
+}
+
+void PreciseBassOnsetDetectorOffline::setMidiNoteString(int index, float midiPitch){
+	std:string midiName = "";
+	if (midiPitch > 0){
+		midiPitch = round(midiPitch);
+		int midiLetter = (int)midiPitch%12;
+		int midiOctave = midiPitch - (int)midiPitch%12;
+		
+		switch (midiLetter) {
+			case 0:
+				midiName = "C ";
+				break;
+			case 1:
+				midiName = "C#";
+				break;
+			case 2:
+				midiName = "D";
+				break;
+			case 3:
+				midiName = "D#";
+				break;
+			case 4:
+				midiName = "E";
+				break;
+			case 5:
+				midiName = "F ";
+				break;
+			case 6:
+				midiName = "F#";
+				break;
+			case 7:
+				midiName = "G ";
+				break;
+			case 8:
+				midiName = "G#";
+				break;
+			case 9:
+				midiName = "A ";
+				break;
+			case 10:
+				midiName = "A#";
+				break;
+			case 11:
+				midiName = "B ";
+				break;
+			default:
+				break;
+		}
+		
+		midiName += ofToString(midiOctave/12);
+	}
+	if (index < onsetList.size())
+		onsetList[index].midiName = midiName;
+	
+}
+
+
+/*
+#pragma mark Quantisation
+void PreciseBassOnsetDetectorOffline::categoriseOnsets(std::vector<double> beatTimes){
+	double onsetTime;
+	for (int i = 0; i < onsetList.size(); i++){
+		
+		onsetTime = onsetList[i].onsetLocation;
+		
+		int beatIndex = 0;
+		while(beatIndex < beatTimes.size() && beatTimes[beatIndex] < onsetTime){
+			beatIndex++;
+		}
+		while(beatIndex > 0 && beatTimes[beatIndex] > onsetTime){
+			beatIndex--;
+		}
+		//beatIndex now either side of onset, or onset before first beat
+		
+		printf("beat %.2f, beat+1 %.2f, onset %.2f freq %.2f, ", beatAtIndex(beatTimes, beatIndex),
+			   beatAtIndex(beatTimes, beatIndex+1), onsetTime, onsetList[i].pitch);
+		
+		double beatTime =  beatAtIndex(beatTimes, beatIndex);//vampBeats.vampBeatAtIndex(beatIndex);
+		
+		
+		double diff = onsetTime - beatTime;
+		double nextBeat = beatAtIndex(beatTimes, beatIndex+1);
+		double period;
+		if (nextBeat){
+			period = nextBeat - beatAtIndex(beatTimes, beatIndex);
+		} else {
+			period = beatAtIndex(beatTimes, beatIndex) - beatAtIndex(beatTimes, beatIndex-1);
+		}
+		if (period > 0){
+			while (diff < 0){
+				diff += period;
+				//i.e. add the beat period to bring it in range
+			}
+			//now can look which point it is nearest
+			double ratio = diff/period;
+			ratio *= 12;
+			int beattype = round(ratio);
+			if (beattype == 12){
+				beattype = 0;
+				beatIndex++;//added need to test
+			}
+			
+			doCorrection(beattype, beatIndex);
+			
+			
+			
+			//	Onset newOnset;
+			//	newOnset.time = onsetTime;
+			//	newOnset.onsetType = beattype;
+			int position = beatIndex%4;
+			
+			//		if (onsetTime > beatTime + (period/2.))
+			//			pos++;
+			//		newOnset.position = pos%4;
+			
+			onsetList[i].beatPosition = beatIndex;
+			onsetList[i].onsetType = beattype;
+			
+			printf("Pitch %i, Position %i,%i\n", onsetList[i].roundedPitch, onsetList[i].beatPosition, beattype);
+		}
+		
+	}
+}
+ */
+
+#pragma mark PredictionProcess
+void PreciseBassOnsetDetectorOffline::predictionProcess(){
+
+
+	
+	//NOW do do precition
+	int optimalLag = getOptimalLag();
+	checkPrediction(optimalLag);
+	
+	checkPredictionFirstOrderMarkovCorrect(optimalLag);
+	
+	//checkBars(); - not quite sure what the idea here was
+	
+	/*
+	 beatInfo.clear();
+	 
+	 int tmpIndex = 0;
+	 double nearestOnset = preciseDetector.pod.onsetAtIndex(0);//start with first
+	 for (int beatIndex = 0; beatIndex < beatTimes.size(); beatIndex++){
+	 double newBeatTime =  beatTimes[beatIndex];
+	 printf("BEAT %i: %f, ", beatIndex, newBeatTime);
+	 double diff = pod.onsetAtIndex(tmpIndex) - newBeatTime;
+	 while (fabs(pod.onsetAtIndex(tmpIndex+1) - newBeatTime) < fabs(diff)){
+	 tmpIndex++;
+	 nearestOnset = pod.onsetAtIndex(tmpIndex);
+	 diff = pod.onsetAtIndex(tmpIndex) - newBeatTime;
+	 printf("testing %f, ", nearestOnset);
+	 }
+	 
+	 
+	 Beat newBeat(false);
+	 newBeat.onsetFound = false;
+	 if (fabs(nearestOnset - newBeatTime) < thresholdForBeat){
+	 newBeat.onsetFound = true;
+	 newBeat.onsetDifference = nearestOnset - newBeatTime;
+	 printf("nearest onset %f\n", nearestOnset);
+	 } else 
+	 printf("no onset %f\n", nearestOnset);
+	 //within 80 msec we say the onset is attributable to the beat location
+	 newBeat.onsetTime = nearestOnset;
+	 newBeat.time = newBeatTime;
+	 newBeat.errorFound = false;
+	 newBeat.period = nan(0);
+	 //find error
+	 int secondBeat = beatIndex-4;
+	 if (beatIndex%4 != 0)
+	 secondBeat = beatIndex - (beatIndex%4);
+	 int firstBeat = secondBeat - 4;
+	 
+	 //for the one use previous bar kicks
+	 //otherwise recent kicks on the one
+	 
+	 if (firstBeat >= 0 && secondBeat < beatInfo.size()){
+	 if (beatInfo[firstBeat].onsetFound && beatInfo[secondBeat].onsetFound){
+	 //can project
+	 double beatPeriod = beatInfo[secondBeat].onsetTime - beatInfo[firstBeat].onsetTime;
+	 beatPeriod /= 4.;
+	 printf("%i beat period %f, ", beatIndex, beatPeriod);
+	 double error = nearestOnset - (beatInfo[secondBeat].onsetTime + (beatIndex - secondBeat)*beatPeriod);
+	 printf("error %.1f, beat period %.1f\n", error*1000., beatPeriod*1000.);
+	 newBeat.errorFound = true;				
+	 newBeat.error = error;
+	 newBeat.period = beatPeriod;
+	 }
+	 
+	 }//end if  error
+	 
+	 beatInfo.push_back(newBeat);
+	 
+	 
+	 }
+	 */
+	
+	//dtwProcess();
+}
+
+int PreciseBassOnsetDetectorOffline::getOptimalLag(){
+	std::vector<double> correlationScores;
+	int maxCorr = 35;
+	
+	for (int i = 0; i < maxCorr; i++){
+		correlationScores.push_back(quantisedCorrelation(i));
+		printf("Lag[%i] %f\n", i, correlationScores[i]);
+	}
+	
+	int optimalLag = 8;
+	
+	BeatWriter newWriter;
+	newWriter.closeFile();
+	newWriter.openFile("/Users/andrewrobertson/corr_scores.txt");
+	
+	
+	//make rayligh
+	std::vector<double> wv;
+	float rayparam = 16;
+	for (int n = 0; n < maxCorr;n++){
+		wv.push_back(((float) n / pow(rayparam,2)) * exp((-1*pow((float)-n,2)) / (2*pow(rayparam,2))));
+		//wv.push_back(1.0 - fabs(n - 12.0)/64.0);
+		
+	}
+	
+	double maxScore = 0;
+	for (int i = 2; i < maxCorr; i++){
+		printf("Lag[%i] %f, rayleigh %f, weighted vec %f\n", i, correlationScores[i], wv[i], correlationScores[i]*wv[i]);
+		if (correlationScores[i]*wv[i] > maxScore){
+			maxScore = correlationScores[i]*wv[i];
+			optimalLag = i;
+		}
+		
+		newWriter.outputFile << i << "\t" << correlationScores[i] << std::endl;
+	}
+	
+	newWriter.closeFile();
+	
+	printf("Optimal lag %i\n", optimalLag);
+	
+	return optimalLag;
+}
+
+
+/*
+void PreciseBassOnsetDetectorOffline::doCorrection(int& beattype, int& beatPosition){
+	switch (beattype) {
+		case 1:
+			beattype = 0;//on beat
+			break;
+		case 2:
+			beattype = 3;//16th
+			break;
+		case 5: case 7:
+			beattype = 6;//8th note
+			break;
+		case 10:
+			beattype = 9;
+			break;
+		case 11:
+			beattype = 0;//on the beat
+			beatPosition++;
+			break;
+		default:
+			break;
+	}
+	
+}
+*/
+
+
+
+double PreciseBassOnsetDetectorOffline::quantisedCorrelation(int lag){
+	
+	double meanCorrelation = 0;
+	int count = 0;
+	
+	bool printResult = false;
+	
+	for (int index = 0; index < onsetList.size(); index++){
+		int midiPitch = 0;
+		if (printResult)
+			printf("testing %i,%i (%i): ", onsetList[index].beatPosition, onsetList[index].onsetType, onsetList[index].roundedPitch);
+		
+		getOnsetAtBeat(index, onsetList[index].beatPosition-lag, onsetList[index].onsetType, midiPitch);
+		
+		if (midiPitch){
+			count++;
+			if (midiPitch == onsetList[index].roundedPitch){
+				meanCorrelation++;
+			}
+			if (printResult){
+				printf("MIDI pitch found %i at lag %i\n", midiPitch, lag);
+			} else if (printResult){
+				printf("none\n");
+			}
+		}
+	}
+	
+	if (count > 0)
+		meanCorrelation /= count;
+	
+	return meanCorrelation;
+}
+
+
+void PreciseBassOnsetDetectorOffline::checkPrediction(int lag){
+	
+	//NAIVE METHOD - JUST LOOKING BACK FOR A BASS NOTE IN SAME POSITION AT SAME LAG
+	
+	int matches = 0;
+	int octaveErrors = 0;
+	int mismatches = 0;
+	
+	bool printResult = false;//true;
+	
+	for (int index = 0; index < onsetList.size(); index++){
+		onsetList[index].midiPrediction = 0;
+		
+		int midiPitch = 0;
+		if (printResult)
+			printf("prediction %i,%i (%i): ", onsetList[index].beatPosition, onsetList[index].onsetType, onsetList[index].roundedPitch);
+		
+		int k = 1;
+		while (onsetList[index].beatPosition - k *lag >= 0){
+				
+			int tmp = getOnsetAtBeat(index, onsetList[index].beatPosition-(k*lag), onsetList[index].onsetType, midiPitch);
+			
+		//	if (tmp == 0 && printResult)
+		//		printf("k %i, pos %i,%i : midi pred %i\n", k, onsetList[index].beatPosition-(k*lag), onsetList[index].onsetType, tmp);
+			
+			if (midiPitch)//i.e. non zero prediction made looking back k*lag beats
+				break;
+			
+			k++;//keep looking back
+		}
+		
+		if (midiPitch){
+			onsetList[index].midiPrediction = midiPitch;
+		
+			if (printResult)
+				printf(", pred %i, (lag %i) ", midiPitch, k);
+			
+			if (midiPitch == onsetList[index].roundedPitch){
+				onsetList[index].matchIndicator = 1;
+				matches++;
+				if (printResult)	
+					printf(", MATCH");
+				
+			}
+			
+			if (midiPitch && onsetList[index].roundedPitch && abs(midiPitch - onsetList[index].roundedPitch) == 12){
+				octaveErrors++;
+				if (printResult)
+					printf(", OCTAVE %i", onsetList[index].roundedPitch-midiPitch);
+			}
+			else if (midiPitch && onsetList[index].roundedPitch && midiPitch != onsetList[index].roundedPitch){
+				mismatches++;
+				if (printResult)
+					printf(", NOT");
+			}
+		}
+		
+		if (printResult)
+			printf("\n");
+		
+	}
+	double sum = matches+octaveErrors+mismatches;
+	printf("\nResult: naive method\noptimal lag %i, matches %.3f, octaves %.3f, wrong %.3f\n", lag, matches/sum, octaveErrors/sum, mismatches/sum);
+}
+
+
+int PreciseBassOnsetDetectorOffline::getOnsetAtBeat(int tmpIndex, int beatPosition, int beatType, int& midiPitch){
+	bool onsetFound = false;
+	while (tmpIndex >= 0 && onsetList[tmpIndex].beatPosition >= beatPosition){
+		if (onsetList[tmpIndex].beatPosition == beatPosition && onsetList[tmpIndex].onsetType == beatType){
+			midiPitch = onsetList[tmpIndex].roundedPitch;
+			//printf("beat pos %i,%i: pitch %i\n", beatPosition, beatType, midiPitch);
+			onsetFound = true;
+			break;
+		}
+		tmpIndex--;
+	}
+	return onsetFound;
+	
+}
+
+
+
+
+void PreciseBassOnsetDetectorOffline::checkPredictionFirstOrderMarkovCorrect(int lag){
+	
+	//LOOKING BACK, NOW REQUIRE ANOTHER CORRECT BASS NOTE RECENT BEAT POSITION
+	//hard to find 
+	printf("First Order check\n");
+	
+	
+	int matches = 0;
+	int octaveErrors = 0;
+	int mismatches = 0;
+	
+	bool printResult = false;//rue;
+	
+	if (printResult)
+		printPitchInfo();
+	
+	for (int index = 0; index < onsetList.size(); index++){
+		onsetList[index].midiPrediction = 0;
+		
+		int midiPitch = 0;
+		int previousMidiPitch = 0;
+		
+		if (printResult)
+			printf("\nBeat Position %i,%i:\n", onsetList[index].beatPosition, onsetList[index].onsetType);
+		
+		int k = 1;
+		
+		int previousOffset = 1;//the note before
+		while (index - previousOffset >= 0 && (onsetList[index-previousOffset].onsetType != 0 || !onsetList[index-previousOffset].roundedPitch)){
+			//printf("rejected: index %i offset %i onset type %i pitch %i\n", index, previousOffset, onsetList[index-previousOffset].onsetType, onsetList[index-previousOffset].roundedPitch);
+			previousOffset++;
+		}
+		
+		
+		if (printResult){
+			printf("\nBeat Position %i,%i (midi %i, prev %i,%i: %i):\n", onsetList[index].beatPosition, onsetList[index].onsetType, onsetList[index].roundedPitch, onsetList[index-previousOffset].beatPosition, onsetList[index-previousOffset].onsetType, onsetList[index-previousOffset].roundedPitch);
+			printf("Previous position is %i,%i offset %i, previous pitch %i\n", onsetList[index-previousOffset].beatPosition, onsetList[index-previousOffset].onsetType, previousOffset, onsetList[index-previousOffset].roundedPitch);
+		}
+		
+		bool printit = false;
+		//first try our new markov condition
+		while (onsetList[index].beatPosition - k *lag >= 0){
+			
+			if(getOnsetAtBeat(index, onsetList[index].beatPosition-(k*lag), onsetList[index].onsetType, midiPitch)
+			   && getOnsetAtBeat(index - previousOffset, onsetList[index - previousOffset].beatPosition - (k*lag), onsetList[index-previousOffset].onsetType, previousMidiPitch))
+			{
+				if (printit)
+					printf("k %i Predicted pitch %i Lag previous pitch %i \n", k, midiPitch, previousMidiPitch);
+				//midi picth is what we would do precition as, but require that the previous note also match our last observed note
+				
+				//onset found at beat pos - k*lag
+				//then is the same
+		
+				bool goodPrediction = false;
+				if (previousMidiPitch == onsetList[index-previousOffset].roundedPitch){
+					goodPrediction = true;
+					if (printit)
+							printf("Previous Found! Lag %i Lag previous pitch %i\nPrediction %i", k, onsetList[index-previousOffset].roundedPitch, previousMidiPitch, midiPitch); 
+				}
+					
+				
+				
+				if (midiPitch && goodPrediction)//i.e. non zero prediction made looking back k*lag beats
+				{
+					if (printit)
+						printf("MIDI PREDICTION IS %i\n", midiPitch);
+					break;
+				}
+			}
+			k++;//keep looking back
+		}
+		
+		
+		if (!midiPitch){
+			k = 1;
+			while (onsetList[index].beatPosition - k *lag >= 0){
+				
+				int tmp = getOnsetAtBeat(index, onsetList[index].beatPosition-(k*lag), onsetList[index].onsetType, midiPitch);
+				
+				if (midiPitch)//i.e. non zero prediction made looking back k*lag beats
+					break;
+				
+				k++;//keep looking back
+			}
+		}
+		
+		if (midiPitch){//only test non zero
+			onsetList[index].midiPrediction = midiPitch;
+			
+			if (printResult)
+				printf(", pred %i, (lag %i) ", midiPitch, k);
+			
+			if (midiPitch == onsetList[index].roundedPitch){
+				onsetList[index].matchIndicator = 1;
+				matches++;
+				if (printResult)	
+					printf(", MATCH");
+				
+			}
+			
+			if (midiPitch && onsetList[index].roundedPitch && abs(midiPitch - onsetList[index].roundedPitch) == 12){
+				octaveErrors++;
+				if (printResult)
+					printf(", OCTAVE %i", onsetList[index].roundedPitch-midiPitch);
+			}
+			else if (midiPitch && onsetList[index].roundedPitch && midiPitch != onsetList[index].roundedPitch){
+				mismatches++;
+				if (printResult)
+					printf(", NOT");
+			}
+		}
+		
+		if (printResult)
+			printf("\n");
+		
+	}
+	double sum = matches+octaveErrors+mismatches;
+	printf("Results : First Oreder Markov Correct\nOptimal lag %i, matches %.3f, octaves %.3f, wrong %.3f\n", lag, matches/sum, octaveErrors/sum, mismatches/sum);
+}
+
+
+
+void PreciseBassOnsetDetectorOffline::checkBars(){
+	int bar = 0;
+	double barScore = 0;
+	double barCount;
+	std::vector<double> scorePerBar;
+	for (int index = 0; index < onsetList.size(); index++){
+		while (bar*4 < onsetList[index].beatPosition){
+			if (barCount > 0)
+				barScore /= barCount;
+			scorePerBar.push_back(barScore);
+			//now going to next bar so reinitialise
+			bar++;
+			barScore = 0;
+			barCount = 0;
+		}
+		barScore += onsetList[index].matchIndicator;
+		barCount++;
+		
+	}
+	
+	for (int i = 0; i < scorePerBar.size(); i++)
+		printf("Score bar [%i] %f\n", i, scorePerBar[i]);
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ofxPreciseOnsetDetectorOffline/PreciseBassOnsetDetectorOffline.h	Thu Aug 14 16:27:52 2014 +0100
@@ -0,0 +1,53 @@
+/*
+ *  PreciseBassOnsetDetectorOffline.h
+ *  BasslinePrediction
+ *
+ *  Created by Andrew N Robertson on 11/04/2014.
+ *  Copyright 2014 QMUL. All rights reserved.
+ *
+ */
+
+#ifndef PRECISE_BASS_DETECTOR_OFFLINE
+#define PRECISE_BASS_DETECTOR_OFFLINE
+
+#include "PreciseOnsetDetectorOffline.h"
+#include "YuleBrinner.h"
+
+//here qwe extend the usual precise onset detector to run different process functin that will log 
+//the pitches of bass onsets using pyin
+
+//
+class PreciseBassOnsetDetectorOffline : public PreciseOnsetDetectorOffline{
+public: 
+	//this version we will also try and detect pitch
+	int processAudioFileForBeatTimes(std::string audiofile);
+
+	void processYinAudio(float* frame, int blocksize);
+	
+	
+	void processBassPitches();
+	
+	void setMidiNoteString(int index, float midiPitch);
+	
+	void printOnsetLocations();
+	void printPitchInfo();
+	
+	//void categoriseOnsets(std::vector<double> beatTimes);
+	//void doCorrection(int& beattype, int& beatPosition);
+	
+	void predictionProcess();
+	int getOptimalLag();
+	
+	double quantisedCorrelation(int lag);
+	int getOnsetAtBeat(int tmpIndex, int beatPosition, int beatType, int& midiPitch);
+	void checkPrediction(int lag);
+	void checkPredictionFirstOrderMarkovCorrect(int lag);
+	
+	void checkBars();
+	
+	
+	
+	YuleBrinner yule;
+	
+};
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ofxPreciseOnsetDetectorOffline/PreciseOnsetDetector.cpp	Thu Aug 14 16:27:52 2014 +0100
@@ -0,0 +1,125 @@
+/*
+ *  PreciseOnsetDetector.cpp
+ *  ofxPreciseOnsetDetectionOffline
+ *
+ *  Created by Andrew N Robertson on 11/04/2014.
+ *  Copyright 2014 QMUL. All rights reserved.
+ *
+ */
+
+#include "PreciseOnsetDetector.h"
+
+
+
+PreciseOnsetDetector::PreciseOnsetDetector(){
+	pov.window.setToRelativeSize(0.1, 0.1, 0.8, 0.3);
+	pov.pod = &pod;//set up pointer if we want to visualise the onsets in a window
+	
+//	std::string fileName;
+//	fileName = "/Users/andrewrobertson/Music/audiowavs/Islamey/BachBWV846-2.wav";
+//	loadNewFile(fileName);
+}
+
+PreciseOnsetDetector::~PreciseOnsetDetector(){
+	
+}
+
+void PreciseOnsetDetector::loadNewFile(std::string filename){
+
+	pod.initialise();
+	pod.load(filename);	
+	pod.printOnsetLocations();
+
+	pov.newFile();//resets info in visualiser - could use pointer??
+}
+
+void PreciseOnsetDetector::update(){
+	pod.update();
+	pov.update();
+}
+
+void PreciseOnsetDetector::draw(){
+	pov.draw();
+}
+
+bool PreciseOnsetDetector::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;
+
+	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;
+	}
+}
+
+void PreciseOnsetDetector::keyPressed(int key){
+	std::string loadName;
+	switch (key) {
+		case 'r':
+			pov.resetWindow();
+			break;
+		case 's':
+			pov.cropStart();
+			pod.cropStartTo(pov.windowStart);
+			break;
+		case 'e':
+			pov.cropEnd();
+			break;
+		case 'w':
+			printf("Exporting between %f and %f\n", pov.windowStart, pov.windowEnd);
+			pod.exportOnsetTimes(pov.windowStart, pov.windowEnd);
+			break;
+		case 'x':
+			printf("Exporting between %f and %f\n", 0., pov.lengthSeconds());
+			pod.exportOnsetTimes(0, pov.lengthSeconds());
+			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.stop();
+			
+			break;
+			
+		case OF_KEY_UP: case 'u':
+			pov.zoomIn();
+			break;
+		case OF_KEY_DOWN:
+			pov.zoomOut();
+			break;
+		case OF_KEY_RIGHT:
+			pov.scrollRight();
+			break;
+		case OF_KEY_LEFT:
+			pov.scrollLeft();
+			break;	
+			
+		default:
+			break;
+	}
+}
+
+void PreciseOnsetDetector::mousePressed(int x, int y, int button){
+
+	pov.mousePressed(x, y);
+	
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ofxPreciseOnsetDetectorOffline/PreciseOnsetDetector.h	Thu Aug 14 16:27:52 2014 +0100
@@ -0,0 +1,44 @@
+/*
+ *  PreciseOnsetDetector.h
+ *  ofxPreciseOnsetDetectionOffline
+ *
+ *  Created by Andrew N Robertson on 11/04/2014.
+ *  Copyright 2014 QMUL. All rights reserved.
+ *
+ */
+
+#ifndef PRECISE_ONSET_DETECTOR
+#define PRECISE_ONSET_DETECTOR
+
+
+#include "PreciseOnsetDetectorOffline.h"
+#include "PreciseOnsetVisualiser.h"
+
+#include "ofxWindowRegion.h"
+#include "ofxPlotFunction.h"
+
+#include "PreciseOnsetDetectorOffline.h"
+
+//this holds both the detection process and the visualiser for the result 
+//easy interfacing from OF
+
+class PreciseOnsetDetector{
+public:
+	PreciseOnsetDetector();
+	~PreciseOnsetDetector();
+	
+	void loadNewFile(std::string filename);
+	
+	void update();
+	void draw();
+	
+	void keyPressed(int key);
+	void mousePressed(int x, int y, int button);
+	
+	bool getFilenameFromDialogBox(std::string* fileNameToSave);
+	
+	//vars
+	PreciseOnsetDetectorOffline pod;
+	PreciseOnsetVisualiser pov;	
+};
+#endif
\ No newline at end of file
--- a/ofxPreciseOnsetDetectorOffline/PreciseOnsetDetectorOffline.cpp	Sun Jan 19 23:07:13 2014 +0000
+++ b/ofxPreciseOnsetDetectorOffline/PreciseOnsetDetectorOffline.cpp	Thu Aug 14 16:27:52 2014 +0100
@@ -12,36 +12,197 @@
 
 #include "PreciseOnsetDetectorOffline.h"
 
-const bool printingOn = false;
+const bool printingOn = false;//true
+
+//can work just by calling initialise, then recursive call to processAudioFrame(float* frame, in numSamples)
+//set the dfType - initialises to energy - good for bass and drums, not so good for harmonic instruments
 
 PreciseOnsetDetectorOffline::PreciseOnsetDetectorOffline(){
 	frameSize = 1024;
 	hopSize = 512;
 	preciseLocator.setup(frameSize);
 	writeOutput = true;//write output to txt when loading file - stored at sample location as file
+	
+	dfType = 5;//see onset detection class
+	//0 energy
+	//5 is csd
+	
+	ringbuffer = new AudioRingBuffer(frameSize, hopSize);
+	sampleCount = 0;
+	frameCount = 0;
+	
+	initialised = false;
+	
+	//some params for peak processing
+	peakProcess.cutoffForRepeatOnsetsFrames = 8;
+	peakProcess.detectionTriggerRatio = 0.5f;//was 0.5
+	peakProcess.bestSlopeMedian = 3;
+	peakProcess.thresholdRelativeToMedian = 1.81;
+	
+	isBass = false;
 }
 
 PreciseOnsetDetectorOffline::~PreciseOnsetDetectorOffline(){
-	//delete infile;
+	
+	if (initialised)
+		delete detectionFunction;
+	
+	delete ringbuffer;
+	
 }
 
+void PreciseOnsetDetectorOffline::initialise(){
+	clearAll();
+	sampleCount = 0;
+	frameCount = 0; 
+	// initialises with hopsize = 512, framesize = 1024, complex spectral difference DF and hanning window
+	detectionFunction = new OnsetDetectionFunction(hopSize, frameSize, dfType, 1);
+	
+	setDfType(5);//for csd
+	initialised = true;	
+	
+	peakProcess.reset();
+}
+
+void PreciseOnsetDetectorOffline::endProcessing(){
+	delete detectionFunction;
+	detectionFunction = NULL;
+	initialised = false;
+	
+	printf("frames in seconds %f\n", secondsToFrameIndex(samples/44100.));
+	printf("frames %i\n", (int) dfValues.size());
+
+}
+
+#pragma mark AudioProcessing
+void PreciseOnsetDetectorOffline::processAudioFrame(float* frame, int n){
+	//call initialise before starting here
+	assert(initialised);
+	
+	sampleCount += n;
+	
+	if (ringbuffer->addToBuffer(frame, n)){
+		//for (int i = 0; i < ringbuffer->buffersize; i++)
+		//	printf("ring[%i] %.6f\n", i, ringbuffer->audiobuffer[i]);
+	
+		
+		//needed to make sure df fn is same framesize as our ringbuffer
+		double dfval = detectionFunction->getDFsample(ringbuffer->audiobuffer);	// compute detection function sample
+		
+		dfValues.push_back(dfval);
+		
+		if (printingOn)
+			printf("det val %i: %f\n", frameCount, dfval);
+		
+		if (peakProcess.peakProcessing(dfval)){
+			
+			//onsetPositionFrames.push_back(frameCount);
+			
+			int precisesample = preciseLocator.findExactOnset(ringbuffer->audiobuffer);
+			
+			//printf("precise sample is %i\n", precisesample);
+			//so exact sample is
+			//int exactsample = (frameCount-1)*hopSize;//chunks in from beginning of frame
+			//as we have just added hopsize samples in, the beginning of the frame is -1 from counter
+			//exactsample += precisesample;
+			
+			//above was old way, but not as neat
+			
+			//number of samples in, but to beginning of frame, then precisesample in from there
+			int alternativePreciseSample = sampleCount - frameSize + precisesample;
+
+			//printf("PreciseSample %i, %i == %i\n", precisesample, exactsample, alternativePrecise);
+			
+			OnsetInfo newOnsetInfo;
+			newOnsetInfo.onsetLocation = alternativePreciseSample/44100.;
+			newOnsetInfo.positionSamples = alternativePreciseSample;
+			newOnsetInfo.positionFrames = frameCount;
+			newOnsetInfo.pitch = 0;
+			newOnsetInfo.matchIndicator = 0;
+			newOnsetInfo.onBeat = false;
+			newOnsetInfo.expressiveTiming = 0;
+//			onsetLocations.push_back(alternativePreciseSample/44100.);
+//			onsetPositionSamples.push_back(alternativePreciseSample);
+			onsetList.push_back(newOnsetInfo);
+			
+			
+			if (printingOn)
+				printf("BANG\n");
+		}
+		
+		frameCount++;
+		
+	}
+
+}
+
+
+void PreciseOnsetDetectorOffline::setDfType(int t){
+	if (t >= 0 && t <= 9)
+		dfType = t;
+	
+	/*
+	 switch (df_type){
+	 case 0:
+	 df_sample = energy_envelope();	// calculate energy envelope detection function sample
+	 break;	
+	 case 1:
+	 df_sample = energy_difference();	// calculate half-wave rectified energy difference detection function sample
+	 break;
+	 case 2:
+	 df_sample = spectral_difference();	// calculate spectral difference detection function sample
+	 break;
+	 case 3:
+	 df_sample = spectral_difference_hwr(); // calculate spectral difference detection function sample (half wave rectified)
+	 break;
+	 case 4:
+	 df_sample = phase_deviation();		// calculate phase deviation detection function sample (half wave rectified)
+	 break;
+	 case 5:
+	 df_sample = complex_spectral_difference(); // calcualte complex spectral difference detection function sample
+	 break;
+	 case 6:
+	 df_sample = complex_spectral_difference_hwr();  // calcualte complex spectral difference detection function sample (half-wave rectified)
+	 break;
+	 case 7:
+	 df_sample = high_frequency_content(); // calculate high frequency content detection function sample
+	 break;
+	 case 8:
+	 df_sample = high_frequency_spectral_difference(); // calculate high frequency spectral difference detection function sample
+	 break;
+	 case 9:
+	 df_sample = high_frequency_spectral_difference_hwr(); // calculate high frequency spectral difference detection function (half-wave rectified)
+	 break;
+	 */
+}
 
 int 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'
 	
-	return processAudioForBeatTimes(filename);
+	//printf("PODO: load '%s'\n", filename.c_str());
+	return processAudioFileForBeatTimes(filename);
 }
 
 
+void PreciseOnsetDetectorOffline::clearAll(){
+	
+	dfValues.clear();
+	onsetList.clear();
+//	onsetLocations.clear();
+//	onsetPositionFrames.clear();
+//	onsetPositionSamples.clear();
+}
 
-int PreciseOnsetDetectorOffline::processAudioForBeatTimes(std::string audiofile){
+
+int PreciseOnsetDetectorOffline::processAudioFileForBeatTimes(std::string audiofile){
 	//originally from BeatAnnotationViewer project
+	printf("PODO: ProcessFunction %s\n", audiofile.c_str());
+	
+	initialise();// - needed but elsewhere
+	
 
-	dfValues.clear();
-	onsetLocations.clear();
-	onsetPositionFrames.clear();
 	
 	// static double frame[FRAMESIZE]; // to hold a single frame
 	double buffer[frameSize];
@@ -54,8 +215,7 @@
 	
 	//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
 	
@@ -92,7 +252,7 @@
 	
 	int k, m;
 	readcount = 1;
-	int counter = 0;
+	
 	
 	//DoubleVector d;
 	while ((readcount = sf_readf_float (infile, buf, blocksize)) > 0){
@@ -108,41 +268,48 @@
 			frame[k] /= channels;//average of the channels
 		}
 		
+		processAudioFrame(frame, blocksize);
+		
 		//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]);
+		/*
+		for (int i = 0; i < frameSize; i++)
+			printf("buffer[%i] %.6f\n", i, buffer[i]);
 		
 		dfval = detectionFunction->getDFsample(buffer);	// compute detection function sample
 		
 		dfValues.push_back(dfval);
 		
-		if (printingOn)
-			printf("det val %i: %f\n", counter, dfval);
+	//	if (printingOn)
+	//		printf("det val %i: %f\n", counter, dfval);
 		
 		if (peakProcess.peakProcessing(dfval)){
 			
 			onsetPositionFrames.push_back(counter);
 			int precisesample = preciseLocator.findExactOnset(&buffer[0]);
+			printf("precise sample is %i\n", precisesample);
 			//so exact sample is
-			int exactsample = (counter-1)*hopSize;//chunks in from beginning
+			int exactsample = (counter-1)*hopSize;//chunks in from beginning of frame
 			//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);
 				
 			
 			onsetLocations.push_back(exactsample/44100.);
+			onsetPositionSamples.push_back(exactsample);
+
+			
 			
 			if (printingOn)
 				printf("BANG\n");
 		}
 		
 		counter++;
+		*/ 
 		//printf("read %i samples\n", readcount);
 		//was	sf_write_double(outfile, frame, readcount) ;
 		
@@ -152,10 +319,7 @@
 	// Close input file
     sf_close (infile);
 	
-	delete detectionFunction;
-	detectionFunction = NULL;
-	
-	printf("Number of samples%i\n", samples);
+	endProcessing();
 	
 	return 0;
 	
@@ -185,11 +349,11 @@
 	
 	
 	int index = 0;
-	while (index < onsetLocations.size() && onsetLocations[index] < startTime)
+	while (index < onsetList.size() && onsetList[index].onsetLocation < startTime)
 		index++;
 	
-	while (index < onsetLocations.size() && onsetLocations[index] <= endTime){
-		writer.writeBeatTime(onsetLocations[index]);
+	while (index < onsetList.size() && onsetList[index].onsetLocation <= endTime){
+		writer.writeBeatTime(onsetList[index].onsetLocation);
 		index++;
 	}
 	
@@ -207,8 +371,8 @@
 }
 
 void PreciseOnsetDetectorOffline::printOnsetLocations(){
-	for (int i = 0; i < (int)onsetLocations.size(); i++)
-		printf("Onset[%i]: %.3f\n", i, onsetLocations[i]);
+	for (int i = 0; i < (int)onsetList.size(); i++)
+		printf("Onset[%i]: %.3f, samples %i\n", i, onsetList[i].onsetLocation, onsetList[i].positionSamples);
 }
 
 double PreciseOnsetDetectorOffline::closestOnset(double& targetVal){
@@ -216,11 +380,11 @@
 	double bestDiff = 99999;
 	double bestVal = -1;
 	
-	for (int testIndex = 0; testIndex < (int)onsetLocations.size(); testIndex++){
-		double testDiff = (onsetLocations[testIndex] - targetVal);
+	for (int testIndex = 0; testIndex < (int)onsetList.size(); testIndex++){
+		double testDiff = (onsetList[testIndex].onsetLocation - targetVal);
 		if (fabs(testDiff) < bestDiff){
 			bestDiff = fabs(testDiff);
-			bestVal = onsetLocations[testIndex];
+			bestVal = onsetList[testIndex].onsetLocation;
 			bestIndex = testIndex;
 		}
 	}
@@ -229,8 +393,202 @@
 
 void PreciseOnsetDetectorOffline::loadOnsetLocations(DoubleVector& beats){
 	//replaces onset locations with new vector
-	onsetLocations.clear();
+	onsetList.clear();
+	
+	//onsetLocations.clear();
 	for (int i = 0; i < beats.size(); i++){
-		onsetLocations.push_back(beats[i]);
+		//onsetLocations.push_back(beats[i]);
+		OnsetInfo newInfo;
+		newInfo.onsetLocation = beats[i];
+		onsetList.push_back(newInfo);
 	}
-}
\ No newline at end of file
+}
+
+double PreciseOnsetDetectorOffline::onsetAtIndex(int index){
+	if (index < onsetList.size())
+		return onsetList[index].onsetLocation;
+	else 
+		return 0;
+	/*
+	if (index < onsetLocations.size())
+		return onsetLocations[index];
+	else 
+		return 0;
+	 */
+}
+
+void PreciseOnsetDetectorOffline::cropStartTo(double startTime){
+	int index = 0;
+	while (index < onsetList.size() && onsetList[index].onsetLocation < startTime){
+		onsetList.erase(onsetList.begin());
+//		onsetLocations.erase(onsetLocations.begin());
+//		onsetPositionSamples.erase(onsetPositionSamples.begin());
+//		onsetPositionFrames.erase(onsetPositionFrames.begin());
+	}
+/*	
+	int index = 0;
+	while (index < onsetLocations.size() && onsetLocations[index] < startTime){
+		onsetLocations.erase(onsetLocations.begin());
+		onsetPositionSamples.erase(onsetPositionSamples.begin());
+		onsetPositionFrames.erase(onsetPositionFrames.begin());
+	}
+ */
+}
+
+void PreciseOnsetDetectorOffline::setMinimumThreshold(float fVal){
+	peakProcess.minimumThreshold = fVal;
+}
+
+
+
+double PreciseOnsetDetectorOffline::beatAtIndex(std::vector<double> beatTimes, int beatIndex){
+	if (beatIndex >= 0 && beatIndex < beatTimes.size()){
+		return beatTimes[beatIndex];
+	} else {
+		printf("OUT OF RANGE\n");
+		return 0;
+	}
+}
+
+	
+	
+#pragma mark Quantisation
+void PreciseOnsetDetectorOffline::categoriseOnsets(std::vector<double> beatTimes){
+	double onsetTime;
+	double cutoff = 0.06;//seconds - is it within this range of given beat times
+	
+	for (int i = 0; i < onsetList.size(); i++){
+		
+		onsetTime = onsetList[i].onsetLocation;
+		
+		int beatIndex = 0;
+		while(beatIndex < beatTimes.size() && beatTimes[beatIndex] < onsetTime){
+			beatIndex++;
+		}
+		while(beatIndex > 0 && beatTimes[beatIndex] > onsetTime){
+			beatIndex--;
+		}
+		//beatIndex now either side of onset, or onset before first beat
+		
+		printf("beat %.2f, beat+1 %.2f, onset %.2f\n", beatAtIndex(beatTimes, beatIndex),
+			   beatAtIndex(beatTimes, beatIndex+1), onsetTime);
+		
+		double beatTime =  beatAtIndex(beatTimes, beatIndex);
+		double nextBeatTime =  beatAtIndex(beatTimes, beatIndex+1);
+		
+		//new cutoff part
+		onsetList[i].onBeat = false;
+
+		
+		
+		if (fabs(onsetTime-beatTime) < cutoff || fabs(onsetTime-nextBeatTime) < cutoff){
+			onsetList[i].onBeat = true;
+		}
+		//end cutoff part
+		
+		double diff = onsetTime - beatTime;
+		
+		double period;
+		if (nextBeatTime){
+			period = nextBeatTime - beatTime;
+		} else {
+			period = beatAtIndex(beatTimes, beatIndex) - beatAtIndex(beatTimes, beatIndex-1);
+		}
+		
+		while (onsetTime < beatTime){
+			//bug if onset is before th first beat
+			beatTime -= period;
+			nextBeatTime -= period;
+			beatIndex--;
+			printf("FIXING: beat index %i time %f onsest %f\n", beatIndex, beatTime, onsetTime);
+		}
+		
+		if (period > 0){
+			while (diff < 0){
+				diff += period;
+				//i.e. add the beat period to bring it in range
+			}
+			//now can look which point it is nearest
+			double ratio = diff/period;
+			ratio *= 12;
+			int beattype = round(ratio);
+			if (beattype == 12){
+				beattype = 0;
+				
+				beatIndex++;//added need to test
+			}
+			
+			doCorrection(beattype, beatIndex);
+			
+			
+			
+			//	Onset newOnset;
+			//	newOnset.time = onsetTime;
+			//	newOnset.onsetType = beattype;
+			//int position = beatIndex%4;
+			
+			//		if (onsetTime > beatTime + (period/2.))
+			//			pos++;
+			//		newOnset.position = pos%4;
+			
+			onsetList[i].beatPosition = beatIndex;
+			onsetList[i].onsetType = beattype;
+			
+			printf("Position %i,%i\n", onsetList[i].beatPosition, beattype);
+		}
+		
+	}
+
+}
+
+
+void PreciseOnsetDetectorOffline::doCorrection(int& beattype, int& beatPosition){
+	switch (beattype) {
+		case 1:
+			beattype = 0;//on beat
+			break;
+		case 2:
+			beattype = 3;//16th
+			break;
+		case 5: case 7:
+			beattype = 6;//8th note
+			break;
+		case 10:
+			beattype = 9;
+			break;
+		case 11:
+			beattype = 0;//on the beat
+			beatPosition++;
+			break;
+		default:
+			break;
+	}
+	
+}
+
+
+
+
+int PreciseOnsetDetectorOffline::onsetAtBeat(int testPosition){
+	//find onset bear at particular beat
+	int index = 0;
+	int foundIndex = 0;
+	bool found = false;
+	double tmpDiff = 10000;
+	while (index < onsetList.size() && onsetList[index].beatPosition <= testPosition){
+		
+		if (onsetList[index].beatPosition == testPosition && onsetList[index].onsetType == 0){
+			found = true;
+			foundIndex = index;
+			//tmpDiff = fabs(onsetList[index].onsetLocation - 
+			//break; - could break here - would find the first onset
+			//commented out finds the last one - really we'd just want the closest one to beat time
+		}
+		index++;
+	}
+	if (found)
+		return foundIndex;
+	else
+		return -1;
+}
+
--- a/ofxPreciseOnsetDetectorOffline/PreciseOnsetDetectorOffline.h	Sun Jan 19 23:07:13 2014 +0000
+++ b/ofxPreciseOnsetDetectorOffline/PreciseOnsetDetectorOffline.h	Thu Aug 14 16:27:52 2014 +0100
@@ -8,8 +8,8 @@
  */
 
 
-#ifndef PRECISE_ONSET_DETECTOR
-#define PRECISE_ONSET_DETECTOR
+#ifndef PRECISE_ONSET_DETECTOR_OFFLINE
+#define PRECISE_ONSET_DETECTOR_OFFLINE
 
 #include "OnsetDetectionFunction.h"
 #include "vector.h"
@@ -19,8 +19,37 @@
 #include "PeakProcessor.h"
 #include "PreciseOnsetLocator.h"
 
+#include "AudioRingBuffer.h"
+
 #include "BeatWriter.h"
 
+struct OnsetInfo{
+	//double dfValue;
+	double onsetLocation;//of exact time in seconds
+	int positionFrames;
+	int positionSamples;//exact time in samples
+	//this for bass onsets
+	float pitch;//freq in Hz
+	float midiPitch;//in Midi as float
+	int roundedPitch;//rounded to nearest MIDI
+	int midiPrediction;//prediction according to naive ICMC 2014 method at optimal lag (determined here)
+	int markovMidiPrediction;//prediction according to first markov ICMC 2014 method at optimal lag (determined here)
+	
+	
+	int barPosition;//ignore
+	int beatPosition;//in beats
+	int onsetType;//0-11 where 0 is on beat, 6 is halfbeat etc
+	
+	float matchIndicator;//?
+	
+	std::string midiName;//eg C#3
+	
+	bool onBeat;//is it near a beat - need to call testOnsetCloseToBeat and give a list of beat times in seconds
+	
+	float expressiveTiming;
+};
+
+
 class PreciseOnsetDetectorOffline{
 public:
 	PreciseOnsetDetectorOffline();
@@ -31,7 +60,16 @@
 	void update();
 	void draw();
 	
-	int processAudioForBeatTimes(std::string audiofile);
+	void initialise();
+	void processAudioFrame(float* frame, int n);
+	
+	void setDfType(int t);
+	
+	void clearAll();
+	virtual int processAudioFileForBeatTimes(std::string audiofile);
+	
+	void endProcessing();
+	
 	void exportOnsetTimes();
 	void exportOnsetTimes(double startTime, double endTime);
 
@@ -42,8 +80,21 @@
 	double secondsToFrameIndex(const double& seconds);
 	double closestOnset(double& targetVal);
 	
-	void printOnsetLocations();
+	virtual void printOnsetLocations();
+	double onsetAtIndex(int index);
 	
+	void cropStartTo(double startTime);
+	
+	void setMinimumThreshold(float fVal);
+	
+	double beatAtIndex(std::vector<double> beatTimes, int beatIndex);
+	
+	void categoriseOnsets(std::vector<double> beatTimes);
+	void doCorrection(int& beattype, int& beatPosition);
+	
+//	void testOnsetsCloseToBeats(std::vector<double> beatTimes);
+	int onsetAtBeat(int testPosition);
+					
 	//vars
 	int frameSize;
 	int hopSize;
@@ -60,9 +111,24 @@
 	PreciseOnsetLocator preciseLocator;
 	
 	std::vector<double> dfValues;
+	/*
 	std::vector<double> onsetLocations;//of exact time in seconds
 	std::vector<int> onsetPositionFrames;
+	std::vector<int> onsetPositionSamples;
+	*/
+	std::vector<OnsetInfo> onsetList;
 	
 	bool writeOutput;//write output to txt
+	
+	int dfType;
+	
+	AudioRingBuffer* ringbuffer;
+	
+	int sampleCount;
+	int frameCount;
+	bool isBass;
+private:	
+	bool initialised;
+
 };
 #endif
\ No newline at end of file
--- a/ofxPreciseOnsetDetectorOffline/PreciseOnsetVisualiser.cpp	Sun Jan 19 23:07:13 2014 +0000
+++ b/ofxPreciseOnsetDetectorOffline/PreciseOnsetVisualiser.cpp	Thu Aug 14 16:27:52 2014 +0100
@@ -22,13 +22,14 @@
 
 void PreciseOnsetVisualiser::newFile(){
 	resetWindow();
+	
+	//problem example
+	//soundPlay.loadSound("/Users/andrew/Music/Logic/GreenOnionsEvaluationThree/GreenOnionsEvaluationMetronome3/Audio Files/SM57_Metronome#13.aif");//.c_str());
+	
 	windowPress = 0;
-	
+	printf("Precise onset, loading...'%s'\n", pod->loadedFilename.c_str());
 	soundPlay.loadSound(pod->loadedFilename, false);
-	stop();
-//	paused = true;
-//	soundPlay.play();
-//	soundPlay.setPaused(true);
+	stop();//sets it not playing at beginning
 }
 
 double PreciseOnsetVisualiser::windowWidth(){
@@ -48,6 +49,7 @@
 
 
 void PreciseOnsetVisualiser::draw(){
+	ofSetLineWidth(1);
 	//if plotting use this, else comment out
 
 	ofSetColor(ofColor::white);
@@ -55,6 +57,8 @@
 	ofSetColor(ofColor::black);
 	window.drawOutline();
 	
+	ofDrawBitmapString(title, window.x+60, window.y - 10);
+	
 	//draw df function
 /*
 	int startIndex = 0;
@@ -68,12 +72,15 @@
 	ofSetColor(ofColor::tan);
 //	plotter.drawVector(pod->dfValues, startIndex, endIndex, window);
 	plotter.drawVector(pod->dfValues, round(pod->secondsToFrameIndex(windowStart)), round(pod->secondsToFrameIndex(windowEnd)), window);
+	
 	ofSetColor(ofColor::black);
 	ofDrawBitmapString(ofToString(round(pod->secondsToFrameIndex(windowStart)), 1), window.x, window.y-10);
 	ofDrawBitmapString(ofToString(round(pod->secondsToFrameIndex(windowEnd)), 1), window.x+window.width, window.y-10);
 	
 	ofSetColor(ofColor::blue);
-	plotter.drawBeatStripes(pod->onsetLocations, window, windowStart, windowEnd);
+//	plotter.drawBeatStripes(pod->onsetLocations, window, windowStart, windowEnd);
+	plotter.drawBeatStripes(pod->onsetList, window, windowStart, windowEnd);
+	drawOnsetInfo(pod->onsetList, window, windowStart, windowEnd);
 	
 	//play position
 	ofSetColor(ofColor::red);
@@ -85,6 +92,58 @@
 	
 }
 
+void PreciseOnsetVisualiser::drawOnsetInfo(std::vector<OnsetInfo> onsetList, ofxWindowRegion& window, double startTime, double endTime){
+	ofSetColor(ofColor::darkBlue);
+	if (endTime > startTime){
+		int index = 0;
+		while (index < onsetList.size() && onsetList[index].onsetLocation < startTime) {
+			index++;
+		}
+		
+		int pos = max(0, window.x - 45);
+		ofDrawBitmapString("onsetLocation", pos, window.y+window.height+10);
+		ofDrawBitmapString("beatPosition", pos, window.y+window.height+30);
+		ofDrawBitmapString("onsetType", pos, window.y+window.height+50);
+		if (pod->isBass){
+			ofDrawBitmapString("pitch", pos, window.y+window.height+70);
+			ofDrawBitmapString("midiPitch", pos, window.y+window.height+90);
+			ofDrawBitmapString("midiPrediction", pos, window.y+window.height+110);
+			ofDrawBitmapString("midiName", pos, window.y+window.height+130);
+			ofDrawBitmapString("exp timing", pos, window.y+window.height+150);	
+		}
+		
+		while (index < onsetList.size() && onsetList[index].onsetLocation <= endTime){
+			pos = window.width*((onsetList[index].onsetLocation - startTime)/(endTime - startTime));
+			pos += window.x;
+			int lineWidth = 20;
+			ofDrawBitmapString(ofToString(onsetList[index].onsetLocation, 2), pos, window.y+window.height+10);
+			ofDrawBitmapString(ofToString(onsetList[index].beatPosition, 0), pos, window.y+window.height+30);
+			ofDrawBitmapString(ofToString(onsetList[index].onsetType, 0), pos, window.y+window.height+50);
+			if (pod->isBass){
+				ofDrawBitmapString(ofToString(onsetList[index].pitch, 1), pos, window.y+window.height+70);
+				ofDrawBitmapString(ofToString(onsetList[index].midiPitch, 0), pos, window.y+window.height+90);
+				if (onsetList[index].midiPrediction == onsetList[index].roundedPitch)
+					ofSetColor(ofColor::darkGreen);
+				else if (abs(onsetList[index].midiPrediction - onsetList[index].roundedPitch) == 12)
+					ofSetColor(ofColor::orange);
+				else 
+					ofSetColor(ofColor::darkRed);
+				
+				ofDrawBitmapString(ofToString(onsetList[index].midiPrediction, 0), pos, window.y+window.height+110);
+				ofSetColor(ofColor::darkBlue);
+				ofDrawBitmapString(onsetList[index].midiName, pos, window.y+window.height+130);
+				if (onsetList[index].expressiveTiming)
+					ofDrawBitmapString(ofToString(1000.0*onsetList[index].expressiveTiming, 1), pos, window.y+window.height+150);	
+			}
+			
+//			ofLine(pos, window.y, pos, window.y+window.height);
+			index++;
+		}
+	}
+}
+
+
+
 double PreciseOnsetVisualiser::positionSeconds(){
 	return soundPlay.getPosition()*pod->samples/44100.;
 }
@@ -98,7 +157,7 @@
 //	while (windowEnd < pod->samples/44100.)
 //		windowEnd *= 2;
 	
-	windowEnd = pod->samples/44100.;
+//	windowEnd = pod->samples/44100.;
 		
 	printf("reset: start %.1f end %.1f\n", windowStart, windowEnd);
 }
@@ -145,12 +204,12 @@
 	if (!paused ){
 		soundPlay.setPaused(true);
 		paused = true;
-		printf("was playing\n");
+		//printf("was playing\n");
 	}
 	else {
 		soundPlay.setPaused(false);//
 		paused = false;
-		printf("was not playing\n");
+		//printf("was not playing\n");
 	}
 }
 
@@ -254,3 +313,41 @@
 double PreciseOnsetVisualiser::lengthSeconds(){
 	return pod->samples/44100.;
 }
+
+
+void PreciseOnsetVisualiser::keyPressed(int key){
+	switch (key) {
+		case 'r':
+			resetWindow();
+			break;
+		case 's':
+			cropStart();
+			break;
+		case 'e':
+			cropEnd();
+			break;
+		case ' ':
+			togglePlay();
+			break;
+		case OF_KEY_RETURN:
+			stop();
+			
+			break;
+			
+		case OF_KEY_UP: case 'u':
+			zoomIn();
+			break;
+		case OF_KEY_DOWN:
+			zoomOut();
+			break;
+		case OF_KEY_RIGHT:
+			scrollRight();
+			break;
+		case OF_KEY_LEFT:
+			scrollLeft();
+			break;	
+			
+		default:
+			break;
+	}
+}
--- a/ofxPreciseOnsetDetectorOffline/PreciseOnsetVisualiser.h	Sun Jan 19 23:07:13 2014 +0000
+++ b/ofxPreciseOnsetDetectorOffline/PreciseOnsetVisualiser.h	Thu Aug 14 16:27:52 2014 +0100
@@ -13,7 +13,7 @@
 #include "PreciseOnsetDetectorOffline.h"
 
 #include "ofxWindowRegion.h"
-#include "ofxPlotFunction.h"
+#include "ofxPlotOnsetFunction.h" 
 
 class PreciseOnsetVisualiser{
 public:
@@ -23,6 +23,9 @@
 	void newFile();
 	void update();
 	void draw();
+	
+	void drawOnsetInfo(std::vector<OnsetInfo> onsetList, ofxWindowRegion& window, double startTime, double endTime);
+	
 	double positionSeconds();
 	double windowWidth();
 	
@@ -49,6 +52,8 @@
 	
 	double lengthSeconds();
 	
+	void keyPressed(int key);
+	
 	//vars
 	PreciseOnsetDetectorOffline* pod;
 	ofSoundPlayer soundPlay;
@@ -56,10 +61,12 @@
 //	void drawOnsets(DoubleVector& onsetTimesSeconds, ofxWindowregion& window, double startTime, double endTime);
 
 	ofxWindowRegion window;
-	ofxPlotFunction plotter;
+	ofxPlotOnsetFunction plotter;
 	
 	double windowStart, windowEnd, windowPress;
 	
 	double currentPlayPosition;
+	
+	std::string title;
 };
 #endif
\ No newline at end of file
--- a/ofxPreciseOnsetDetectorOffline/testApp.cpp	Sun Jan 19 23:07:13 2014 +0000
+++ b/ofxPreciseOnsetDetectorOffline/testApp.cpp	Thu Aug 14 16:27:52 2014 +0100
@@ -2,95 +2,34 @@
 
 //possible to just omit the drawing (uses ofxWindowRegion for the screen and ofxPlotFunction to plot beat times)
 
+//w: export window
+//x:export whole file
+//o: open file
+
 //--------------------------------------------------------------
 void testApp::setup(){
-	pov.window.setToRelativeSize(0.1, 0.1, 0.8, 0.3);
-	pov.pod = &preciseOnsetDetect;//set up pointer if we want to visualise the onsets in a window
-	
-//	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");
-	
-	std::string fileName = "/Users/andrew/Music/Logic/GreenOnionsEvaluation/GreenOnionsEvaluationPlain/Audio Files/SongClickTrack#09.aif";
-//	fileName = "/Users/andrew/Music/Logic/GreenOnionsChichester/GreenOnionsChichester/Audio Files/Ride_SM58#08.aif";
-	loadNewFile(fileName);
+
 
 }
 
 
-void testApp::loadNewFile(std::string filename){
-	preciseOnsetDetect.load(filename);
-	preciseOnsetDetect.printOnsetLocations();
-	
-	pov.newFile();
-}
-
 //--------------------------------------------------------------
 void testApp::update(){
-	preciseOnsetDetect.update();
-	pov.update();
+	
+	onsetDetector.update();
 }
 
 //--------------------------------------------------------------
 void testApp::draw(){
 	
-	pov.draw();
+	onsetDetector.draw();
 
 }
 
 
 //--------------------------------------------------------------
 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 'w':
-			printf("Exporting between %f and %f\n", pov.windowStart, pov.windowEnd);
-			preciseOnsetDetect.exportOnsetTimes(pov.windowStart, pov.windowEnd);
-			break;
-		case 'x':
-			printf("Exporting between %f and %f\n", 0., pov.lengthSeconds());
-			preciseOnsetDetect.exportOnsetTimes(0, pov.lengthSeconds());
-			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;
-			
-		case OF_KEY_UP:
-			pov.zoomIn();
-			break;
-		case OF_KEY_DOWN:
-			pov.zoomOut();
-			break;
-		case OF_KEY_RIGHT:
-			pov.scrollRight();
-			break;
-		case OF_KEY_LEFT:
-			pov.scrollLeft();
-			break;	
-	
-		default:
-			break;
-	}
+	onsetDetector.keyPressed(key);
 }
 
 //--------------------------------------------------------------
@@ -110,13 +49,8 @@
 
 //--------------------------------------------------------------
 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);
 
+	onsetDetector.mousePressed(x,y,button);
 }
 
 //--------------------------------------------------------------
@@ -141,40 +75,4 @@
 
 
 
-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;
-	}
-}
 
--- a/ofxPreciseOnsetDetectorOffline/testApp.h	Sun Jan 19 23:07:13 2014 +0000
+++ b/ofxPreciseOnsetDetectorOffline/testApp.h	Thu Aug 14 16:27:52 2014 +0100
@@ -2,11 +2,11 @@
 
 #include "ofMain.h"
 
-#include "PreciseOnsetDetectorOffline.h"
-#include "PreciseOnsetVisualiser.h"
+#include "PreciseOnsetDetector.h"
 
-#include "ofxWindowRegion.h"
-#include "ofxPlotFunction.h"
+
+//#include "ofxWindowRegion.h"
+//#include "ofxPlotFunction.h"
 
 class testApp : public ofBaseApp{
 	public:
@@ -30,7 +30,8 @@
 	
 	
 	//vars
-	PreciseOnsetDetectorOffline preciseOnsetDetect;
+//	PreciseOnsetDetectorOffline preciseOnsetDetect;	
+//	PreciseOnsetVisualiser pov;
 	
-	PreciseOnsetVisualiser pov;
+	PreciseOnsetDetector onsetDetector;
 };