changeset 0:82352cfc0b23

Added files from ISMIR groove drum timing work
author Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk>
date Mon, 01 Oct 2012 22:24:32 +0100
parents
children 106bc2d4f702
files DrumTimingLoader_OF/DevNotes.txt DrumTimingLoader_OF/addTo->Bin->Data/Times New Roman.ttf DrumTimingLoader_OF/chromagramm/ChordDetect.cpp DrumTimingLoader_OF/chromagramm/ChordDetect.h DrumTimingLoader_OF/chromagramm/Chromagram.cpp DrumTimingLoader_OF/chromagramm/Chromagram.h DrumTimingLoader_OF/fftw/fftw3.h DrumTimingLoader_OF/fftw/libfftw3f.a DrumTimingLoader_OF/ofxAubioOnsetDetection/AubioOnsetDetector.cpp DrumTimingLoader_OF/ofxAubioOnsetDetection/AubioOnsetDetector.h DrumTimingLoader_OF/ofxAubioOnsetDetection/AubioPitch.cpp DrumTimingLoader_OF/ofxAubioOnsetDetection/AubioPitch.h DrumTimingLoader_OF/ofxAubioOnsetDetection/ChromaOnset.cpp DrumTimingLoader_OF/ofxAubioOnsetDetection/ChromaOnset.h DrumTimingLoader_OF/ofxAubioOnsetDetection/FrameHolder.cpp DrumTimingLoader_OF/ofxAubioOnsetDetection/FrameHolder.h DrumTimingLoader_OF/ofxAubioOnsetDetection/PreciseOnsetLocator.cpp DrumTimingLoader_OF/ofxAubioOnsetDetection/PreciseOnsetLocator.h DrumTimingLoader_OF/ofxAubioOnsetDetection/ofxAubioOnsetDetection.cpp DrumTimingLoader_OF/ofxAubioOnsetDetection/ofxAubioOnsetDetection.h DrumTimingLoader_OF/ofxAudioFileLoader/AudioAnalysis.cpp DrumTimingLoader_OF/ofxAudioFileLoader/AudioAnalysis.h DrumTimingLoader_OF/ofxAudioFileLoader/AudioFile.cpp DrumTimingLoader_OF/ofxAudioFileLoader/AudioFile.h DrumTimingLoader_OF/ofxAudioFileLoader/LoadedAudioHolder.cpp DrumTimingLoader_OF/ofxAudioFileLoader/LoadedAudioHolder.h DrumTimingLoader_OF/ofxAudioFileLoader/ofxSoundFileLoader.cpp DrumTimingLoader_OF/ofxAudioFileLoader/ofxSoundFileLoader.h DrumTimingLoader_OF/ofxAudioFileLoader/testApp.h DrumTimingLoader_OF/ofxWindowRegion/windowRegion/ofxPlotFunction.cpp DrumTimingLoader_OF/ofxWindowRegion/windowRegion/ofxPlotFunction.h DrumTimingLoader_OF/ofxWindowRegion/windowRegion/ofxWindowRegion.cpp DrumTimingLoader_OF/ofxWindowRegion/windowRegion/ofxWindowRegion.h DrumTimingLoader_OF/src/DrumTimingLoader.cpp DrumTimingLoader_OF/src/DrumTimingLoader.h DrumTimingLoader_OF/src/RecordedMultipleAudio.cpp DrumTimingLoader_OF/src/RecordedMultipleAudio.h DrumTimingLoader_OF/src/main.cpp DrumTimingLoader_OF/src/testApp.cpp DrumTimingLoader_OF/src/testApp.h
diffstat 40 files changed, 5766 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DrumTimingLoader_OF/DevNotes.txt	Mon Oct 01 22:24:32 2012 +0100
@@ -0,0 +1,12 @@
+
+
+load in 
+
+kick
+snare
+room
+
+recordedFileClass
+
+holds the three audio files
+loads each
Binary file DrumTimingLoader_OF/addTo->Bin->Data/Times New Roman.ttf has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DrumTimingLoader_OF/chromagramm/ChordDetect.cpp	Mon Oct 01 22:24:32 2012 +0100
@@ -0,0 +1,476 @@
+/*
+ *  ChordDetect.cpp
+ *  ChordDetect
+ *
+ *  Created by Adam Stark on 28/04/2008.
+ *  Copyright 2008 __MyCompanyName__. All rights reserved.
+ *
+ */
+
+#include "ChordDetect.h"
+#include <iostream>
+#include <math.h>
+using namespace std;
+
+ChordDetect :: ChordDetect()
+{
+	
+	bias = 1.06;
+	
+	makeprofiles();
+		
+}
+
+//--------------------------------------------------------------------------------------
+// destructor
+ChordDetect :: ~ChordDetect()
+{
+										
+}
+
+
+//--------------------------------------------------------------------------------------
+// main function to be called with 8192 sample frame at 11025 Hz
+void ChordDetect :: C_Detect(float c[],float c_low[])
+{
+	for (int i = 0;i < 12;i++)
+	{
+		chroma[i] = c[i];
+		chroma_low[i] = c_low[i];
+	}
+	
+	calculateweightings();
+	
+	classifychromagram();
+		
+	//cout << root << " " << quality << " " << intervals << endl;
+}
+
+//--------------------------------------------------------------------------------------
+// analyse the chromagram and assign it a root note, chord type and any features
+void ChordDetect :: classifychromagram()
+{
+	int i;
+	int j;
+	int fifth;
+	int chordindex;
+	
+	// remove some of the 5th note energy from chromagram
+	for (i = 0;i < 12;i++)
+	{
+		fifth = (i+7) % 12;
+		chroma[fifth] = chroma[fifth] - (0.1*chroma[i]);
+		
+		if (chroma[fifth] < 0)
+		{
+			chroma[fifth] = 0;
+		}
+		
+	}
+	
+	
+	// major chords
+	for (j=0;j < 12;j++)
+	{
+		chord[j] = calcchordvalue(chroma,profiles[j],bias,3);
+	}
+	
+	// minor chords
+	for (j=12;j < 24;j++)
+	{
+		chord[j] = calcchordvalue(chroma,profiles[j],bias,3);
+	}
+	
+	// diminished 5th chords
+	for (j=24;j < 36;j++)
+	{
+		chord[j] = calcchordvalue(chroma,profiles[j],bias,3);
+	}
+	
+	// augmented 5th chords
+	for (j=36;j < 48;j++)
+	{
+		chord[j] = calcchordvalue(chroma,profiles[j],bias,3);
+		
+		chord[j] = chord[j] / weight_aug[j-36];
+	}
+	
+	// sus2 chords
+	for (j=48;j < 60;j++)
+	{
+		chord[j] = calcchordvalue(chroma,profiles[j],1,3);
+		
+		chord[j] = chord[j] / weight_sus[j-48];
+	}
+	
+	// sus4 chords
+	for (j=60;j < 72;j++)
+	{
+		chord[j] = calcchordvalue(chroma,profiles[j],1,3);
+		
+		chord[j] = chord[j] / weight_sus[j-60];
+	}
+	
+	// major 7th chords
+	for (j=72;j < 84;j++)
+	{
+		chord[j] = calcchordvalue(chroma,profiles[j],1,4);
+	}
+	
+	// minor 7th chords
+	for (j=84;j < 96;j++)
+	{
+		chord[j] = calcchordvalue(chroma,profiles[j],bias,4);
+	}
+
+	// dominant 7th chords
+	for (j=96;j < 108;j++)
+	{
+		chord[j] = calcchordvalue(chroma,profiles[j],bias,4);
+	}
+	
+	chordindex = minindex(chord,108);
+	
+	// major
+	if (chordindex < 12)
+	{
+		root = chordindex;
+		quality = 1;
+		intervals = 0;
+	}
+	
+	// minor
+	if ((chordindex >= 12) && (chordindex < 24))
+	{
+		root = chordindex-12;
+		quality = 0;
+		intervals = 0;
+	}
+	
+	// diminished 5th
+	if ((chordindex >= 24) && (chordindex < 36))
+	{
+		root = chordindex-24;
+		quality = 4;
+		intervals = 0;
+	}
+	
+	// augmented 5th
+	if ((chordindex >= 36) && (chordindex < 48))
+	{
+		root = chordindex-36;
+		quality = 6;
+		intervals = 0;
+	}
+	
+	// sus2
+	if ((chordindex >= 48) && (chordindex < 60))
+	{
+		root = chordindex-48;
+		quality = 2;
+		intervals = 2;
+	}
+	
+	// sus4
+	if ((chordindex >= 60) && (chordindex < 72))
+	{
+		root = chordindex-60;
+		quality = 2;
+		intervals = 4;
+	}
+	
+	// major 7th
+	if ((chordindex >= 72) && (chordindex < 84))
+	{
+		root = chordindex-72;
+		quality = 1;
+		intervals = 7;
+	}
+	
+	// minor 7th
+	if ((chordindex >= 84) && (chordindex < 96))
+	{
+		root = chordindex-84;
+		quality = 0;
+		intervals = 7;
+	}
+	
+	// dominant 7th
+	if ((chordindex >= 96) && (chordindex < 108))
+	{
+		root = chordindex-96;
+		quality = 2;
+		intervals = 7;
+	}
+}
+
+//--------------------------------------------------------------------------------------
+// calculate weightings to help distinguish between sus2/sus4 and aug chords
+void ChordDetect :: calculateweightings()
+{
+	int i;
+	float maxval = 0;
+	int fifth;
+	int augfifth;
+	
+	maxval = max(chroma_low,12); 
+		
+	// normalise chroma low
+	for (i = 0;i < 12;i++)
+	{
+		chroma_low[i] = chroma_low[i] / maxval;
+	}
+	
+	// make weight for sus chords
+	for (i = 0;i < 12;i++)
+	{
+		fifth = i+7;
+		augfifth = i+8;
+		
+		if (fifth >= 12)
+		{
+			fifth = fifth-12;
+		}
+		
+		if (augfifth >= 12)
+		{
+			augfifth = augfifth-12;
+		}
+		
+		weight_sus[i] = chroma_low[i] + (chroma_low[fifth]/2);
+		weight_aug[i] = chroma_low[i] + (chroma_low[augfifth]/2);
+	}
+	
+	maxval = max(weight_sus,12);
+	// normalise weight_sus
+	for (i = 0;i < 12;i++)
+	{
+		weight_sus[i] = weight_sus[i] / maxval;
+	}
+	
+	maxval = max(weight_aug,12);
+	// normalise weight_aug
+	for (i = 0;i < 12;i++)
+	{
+		weight_aug[i] = weight_aug[i] / maxval;
+	}
+	
+	
+}
+
+
+//--------------------------------------------------------------------------------------
+// return delta value indicating how similar the chroma is to the chord template - lower value = more similar
+float ChordDetect :: calcchordvalue(float c[],float T[],float biasval, float N)
+{
+	float sum = 0;
+	float delta;
+
+	for (int i=0;i < 12;i++)
+	{
+		sum = sum + ((1-T[i])*(pow(c[i],2)));
+	}
+
+	delta = sqrt(sum) / ((12 - N)*biasval);
+	
+	return delta;
+}
+
+
+//--------------------------------------------------------------------------------------
+// returns max value of an array
+float ChordDetect :: max(float array[],int length)
+{
+	float max = 0;
+	
+	for (int i=0;i < length;i++)
+	{
+		if (array[i] > max)
+		{
+			max = array[i];
+		}
+	}
+	
+	return max;
+}
+
+//--------------------------------------------------------------------------------------
+// returns index of minimum value of array
+int ChordDetect :: minindex(float array[],int length)
+{
+	float min = 10000;
+	int minindex = 0;
+	int i;
+	
+	for (i = 0;i < length;i++)
+	{
+		if (array[i] < min)
+		{
+			min = array[i];
+			minindex = i;
+		}
+	}
+	
+	return minindex;
+}
+
+//--------------------------------------------------------------------------------------
+// calculates bit mask chord profiles
+void ChordDetect :: makeprofiles()
+{
+	int i;
+	int t;
+	int j = 0;
+	int root;
+	int third;
+	int fifth;
+	int seventh;
+	
+	float v1 = 1;
+	float v2 = 1;
+	float v3 = 1;
+	
+	// set profiles matrix to all zeros
+	for (j = 0;j < 108;j++)
+	{
+		for (t = 0;t < 12;t++)
+		{
+			profiles[j][t] = 0;
+		}
+	}
+	
+	// reset j to zero to begin creating profiles
+	j = 0;
+	
+	// major chords
+	for (i = 0;i < 12;i++)
+	{
+		root = i % 12;
+		third = (i+4) % 12;
+		fifth = (i+7) % 12;
+		
+		profiles[j][root] = v1;
+		profiles[j][third] = v2;
+		profiles[j][fifth] = v3;
+		
+		j++;				
+	}
+
+	// minor chords
+	for (i = 0;i < 12;i++)
+	{
+		root = i % 12;
+		third = (i+3) % 12;
+		fifth = (i+7) % 12;
+		
+		profiles[j][root] = v1;
+		profiles[j][third] = v2;
+		profiles[j][fifth] = v3;
+		
+		j++;				
+	}
+
+	// diminished chords
+	for (i = 0;i < 12;i++)
+	{
+		root = i % 12;
+		third = (i+3) % 12;
+		fifth = (i+6) % 12;
+		
+		profiles[j][root] = v1;
+		profiles[j][third] = v2;
+		profiles[j][fifth] = v3;
+		
+		j++;				
+	}	
+	
+	// augmented chords
+	for (i = 0;i < 12;i++)
+	{
+		root = i % 12;
+		third = (i+4) % 12;
+		fifth = (i+8) % 12;
+		
+		profiles[j][root] = v1;
+		profiles[j][third] = v2;
+		profiles[j][fifth] = v3;
+		
+		j++;				
+	}	
+	
+	// sus2 chords
+	for (i = 0;i < 12;i++)
+	{
+		root = i % 12;
+		third = (i+2) % 12;
+		fifth = (i+7) % 12;
+		
+		profiles[j][root] = v1;
+		profiles[j][third] = v2;
+		profiles[j][fifth] = v3;
+		
+		j++;				
+	}
+	
+	// sus4 chords
+	for (i = 0;i < 12;i++)
+	{
+		root = i % 12;
+		third = (i+5) % 12;
+		fifth = (i+7) % 12;
+		
+		profiles[j][root] = v1;
+		profiles[j][third] = v2;
+		profiles[j][fifth] = v3;
+		
+		j++;				
+	}		
+	
+	// major 7th chords
+	for (i = 0;i < 12;i++)
+	{
+		root = i % 12;
+		third = (i+4) % 12;
+		fifth = (i+7) % 12;
+		seventh = (i+11) % 12;
+		
+		profiles[j][root] = v1;
+		profiles[j][third] = v2;
+		profiles[j][fifth] = v3;
+		profiles[j][seventh] = v3;
+		
+		j++;				
+	}	
+	
+	// minor 7th chords
+	for (i = 0;i < 12;i++)
+	{
+		root = i % 12;
+		third = (i+3) % 12;
+		fifth = (i+7) % 12;
+		seventh = (i+10) % 12;
+		
+		profiles[j][root] = v1;
+		profiles[j][third] = v2;
+		profiles[j][fifth] = v3;
+		profiles[j][seventh] = v3;
+		
+		j++;				
+	}
+	
+	// dominant 7th chords
+	for (i = 0;i < 12;i++)
+	{
+		root = i % 12;
+		third = (i+4) % 12;
+		fifth = (i+7) % 12;
+		seventh = (i+10) % 12;
+		
+		profiles[j][root] = v1;
+		profiles[j][third] = v2;
+		profiles[j][fifth] = v3;
+		profiles[j][seventh] = v3;
+		
+		j++;				
+	}
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DrumTimingLoader_OF/chromagramm/ChordDetect.h	Mon Oct 01 22:24:32 2012 +0100
@@ -0,0 +1,49 @@
+/*
+ *  ChordDetect.h
+ *  ChordDetect
+ *
+ *  Created by Adam Stark on 28/04/2008.
+ *  Copyright 2008 __MyCompanyName__. All rights reserved.
+ *
+ */
+
+#ifndef CHORDDETECT_H
+#define CHORDDETECT_H
+
+#include "fftw3.h"
+
+class ChordDetect
+{
+public:		
+	ChordDetect();											// constructor
+	~ChordDetect();											// destructor
+	void C_Detect(float c[],float c_low[]);
+	
+	int root;
+	int quality;
+	int intervals;
+	
+private:
+	void makeprofiles();
+	void calculateweightings();
+	void classifychromagram();
+	
+	float calcchordvalue(float c[],float T[],float biasval, float N);
+	float max(float array[],int length);
+	int minindex(float array[],int length);
+
+	float chroma[12];
+	float chroma_low[12];
+	float weight_sus[12];
+	float weight_aug[12];
+	float profiles[108][12];
+	float w_profile[12];
+	
+	float chord[108];
+	
+	float bias;
+		
+
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DrumTimingLoader_OF/chromagramm/Chromagram.cpp	Mon Oct 01 22:24:32 2012 +0100
@@ -0,0 +1,427 @@
+
+
+#include "Chromagram.h"
+#include <iostream>
+#include <math.h>
+using namespace std;
+
+Chromagram :: Chromagram()
+{
+	pi = 3.14159265;
+	bsize = 8192;
+		
+	// array init
+	buffer = new float[8192]; // make audio buffer
+	wbuffer = new float[8192]; // to hold windowed audio buffer
+	win = new float[8192];
+	d_frame = new float[128];
+	hop = new float[1024];
+	mag = new float[(bsize/2)+1];
+	
+	maximumChromaValue = 1.0;
+	
+	float base = 130.81278265;
+	
+	for (int i = 0;i < 12;i++)
+	{
+		note[i] = base*pow(2,(((float) i)/12));
+	}
+	
+	harmonics = 2;
+	octaves = 2;
+	search = 2;  // p is number of bins either side of target to search for other peaks
+		
+	out = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * bsize);		// complex array to hold fft
+	p = fftwf_plan_dft_r2c_1d(bsize,wbuffer,out,FFTW_FORWARD*-1);	// plan for executing fft of wbuffer
+	
+	chromaready = 0;
+}
+
+//--------------------------------------------------------------------------------------
+// destructor
+Chromagram :: ~Chromagram()
+{
+	// destroy fft plan
+   // fftwf_destroy_plan(p); - causes problem - why? (Andrew R)
+	
+	// deallocate memory
+	win = NULL;	
+	delete [] win;	
+	buffer = NULL;	
+	delete [] buffer;										
+	wbuffer = NULL;	
+	delete [] wbuffer;
+	
+	//printf("delete chromogram\n");
+}
+
+//--------------------------------------------------------------------------------------
+// Initialises all framesize dependent variables. Should be called to properly initialise variables and anytime the frame size changes.
+void Chromagram :: initialise(int framesize,int hsize)
+{
+	fsize = framesize;
+	hopsize = hsize;
+	
+	d_frame = new float[fsize/4];
+	hop = new float[hopsize];
+
+
+	calcrate = (hopsize*4)/fsize;
+
+	count = 0;
+	
+	//fsize = framesize; // set frame size
+		
+	ratio = ((float) 11025) / ((float) 8192);	
+	hamming(bsize);		// define a hanning window offline	
+}
+
+//--------------------------------------------------------------------------------------
+// Processes a single frame
+void Chromagram :: processframe(float frame[])
+{
+	int i;
+	int j;
+	int c;
+
+	chromaready = 0; // default case that chroma isn't ready
+
+	// downsample frame
+	downsampleframe(frame);
+		
+	if (count < calcrate)
+	{
+        c = count*(fsize/4);
+		
+		j = 0;
+		for (i = c;i < c+(fsize/4);i++)
+		{
+			hop[i] = d_frame[j];//d_frame is downsampled
+			j++;
+		}
+		count++;// = count + 1;
+	}
+	    
+    if (count == calcrate)
+	{
+		for (i=0;i < 8192-hopsize;i++)
+		{
+			buffer[i] = buffer[i+hopsize];
+		}
+		
+		j = 0;
+		for (i=8192-hopsize;i < bsize;i++)
+		{
+			buffer[i] = hop[j];
+			j++;
+		}
+		        
+		chromacalc(buffer);
+		
+        count = 0;
+    }
+
+}
+/*
+// Processes a single frame
+void Chromagram :: processFrame(float* frame, int length){
+	if (length == 8192){
+	
+	int i;
+	int j;
+	int c;
+	
+	chromaready = 0; // default case that chroma isn't ready
+	
+	// downsample frame
+	downsampleframe(frame);
+	
+	if (count < calcrate)
+	{
+        c = count*(fsize/4);
+		
+		j = 0;
+		for (i = c;i < c+(fsize/4);i++)
+		{
+			hop[i] = d_frame[j];
+			j++;
+		}
+		count = count + 1;
+	}
+	
+    if (count == calcrate)
+	{
+		for (i=0;i < 8192-hopsize;i++)
+		{
+			buffer[i] = buffer[i+hopsize];
+		}
+		
+		j = 0;
+		for (i=8192-hopsize;i < bsize;i++)
+		{
+			buffer[i] = hop[j];
+			j++;
+		}
+		
+		chromacalc(buffer);
+		
+        count = 0;
+    }
+	}
+	
+}
+*/
+
+
+//--------------------------------------------------------------------------------------
+// Processes a single frame
+void Chromagram :: downsampleframe(float frame[])
+{
+	float filt_frame[fsize];
+	
+	float b0,b1,b2,a1,a2;
+	float x_1,x_2,y_1,y_2;
+	
+	b0 = 0.2929;
+	b1 = 0.5858;
+	b2 = 0.2929;   
+	a1 = -0.0000;
+	a2 = 0.1716;
+
+	x_1 = 0;
+	x_2 = 0;
+	y_1 = 0;
+	y_2 = 0;
+
+	for (int i=0;i < fsize;i++)
+	{
+		filt_frame[i] = frame[i]*b0 + x_1*b1 + x_2*b2 - y_1*a1 - y_2*a2;
+    
+		x_2 = x_1;
+		x_1 = frame[i];
+		y_2 = y_1;
+		y_1 = filt_frame[i];
+	}
+	
+	for (int i=0;i < (fsize/4);i++)
+	{
+		d_frame[i] = filt_frame[i*4];
+	}
+
+}
+
+//--------------------------------------------------------------------------------------
+// main function to be called with 8192 sample frame at 11025 Hz
+void Chromagram :: chromacalc(float frame[])
+{
+	int i;
+		
+	// apply hanning window to buffer
+	for (i = 0; i < bsize;i++)
+	{
+		wbuffer[i] = frame[i] * win[i];
+	}
+	
+	getmagspectrum();
+	
+	generatechromagram();
+		
+	chromaready = 1;	
+		
+//	for (i = 0;i < 12;i++)
+//	{
+//		cout << chroma[i] << " ";
+//	}	
+//	
+//	cout << endl;
+		
+	//cout << "root: " << root << "  type: " << type << "  features: " << features << endl;
+	
+	//cout << root << " " << quality << " " << intervals << endl;
+}
+
+//--------------------------------------------------------------------------------------
+// creates a chromagram from the magnitude spectrum of the input signal
+void Chromagram :: generatechromagram()
+{
+	int i;
+	float sum;
+	float notesum = 0;
+	float noteval;
+	int index;
+	float maxval = 0;
+	int searchlength;
+	
+	for (i = 0;i < 12;i++)
+	{
+		sum = 0;
+		
+		for (int oct = 1;oct <= octaves;oct++)
+		{
+			noteval = (note[i]/ratio)*((float) oct);
+			notesum = 0;
+			
+			for (int h = 1;h <= harmonics;h++)
+			{
+				index = round(noteval*((float) h));
+				
+				searchlength = search*h;
+				
+				maxval = 0;
+				for (int n = (index-searchlength);n <= index+searchlength;n++)
+				{
+					if (mag[n] > maxval)
+					{
+						maxval = mag[n];
+					}
+				}
+				
+				notesum = notesum+(maxval*(1/((float) h)));
+			}
+			sum = sum + notesum;
+			
+			if (oct == 1)
+			{
+				chroma_low[i] = notesum;
+			}
+		}
+		
+		chroma[i] = sum;
+		rawChroma[i] = sum;
+		
+		if (sum > maximumChromaValue)
+		maximumChromaValue = sum;
+		
+	}
+	
+	double L_One_Norm = 0;
+	for (i = 0;i < 12;i++){
+		L_One_Norm += chroma[i];
+	}
+	
+	if (L_One_Norm == 0)
+		L_One_Norm = 1;
+	
+	// normalise chromagram
+	maxval = max(chroma,12);
+	
+	maxval = L_One_Norm;
+	
+	for (i = 0;i < 12;i++)
+	{
+		chroma[i] = chroma[i] / maxval;
+		
+	}
+	
+	quantiseChromagram();
+	
+	
+}
+
+
+void Chromagram :: quantiseChromagram(){
+	for (int i = 0;i < 12;i++){
+		
+		quantisedChromagram[i] = 0;
+		
+		if (chroma[i] > 0.05)
+			quantisedChromagram[i]++;
+		
+		if (chroma[i] > 0.1)
+			quantisedChromagram[i]++;
+	
+		if (chroma[i] > 0.2)
+			quantisedChromagram[i]++;
+	
+		if (chroma[i] > 0.4)
+			quantisedChromagram[i]++;
+	
+	}
+}
+
+double Chromagram :: getQuantisedDistance(float secondQuantisedChroma[12]){
+	double cosineDistance = 0;
+	double quantLengthOne = 0;
+	double quantLengthTwo = 0;	
+	for (int i = 0;i < 12;i++){
+		
+		cosineDistance += quantisedChromagram[i] * secondQuantisedChroma[i];
+
+		quantLengthOne += quantisedChromagram[i] *quantisedChromagram[i];
+		quantLengthTwo += secondQuantisedChroma[i] * secondQuantisedChroma[i];
+	
+	}
+	
+	cosineDistance /= sqrt(quantLengthOne * quantLengthTwo);
+	
+	return cosineDistance;
+		
+}
+
+
+//--------------------------------------------------------------------------------------
+// main function to be called with 8192 sample frame at 11025 Hz
+void Chromagram :: hamming(int N)
+{
+	int n;
+		
+	// apply hanning window to buffer
+	for (n = 0; n < N;n++)
+	{
+		win[n] = 0.54 - 0.46*cos(2*pi*(((float) n)/((float) N)));
+	}
+}
+
+//--------------------------------------------------------------------------------------
+// finds mag spectrum of input
+void Chromagram :: getmagspectrum()
+{
+	int i = 0;	
+
+	// execute fft plan, i.e. compute fft of buffer
+    fftwf_execute(p);
+
+	// compute first (N/2)+1 mag values
+	for (i = 0;i < (bsize/2)+1;i++)
+	{
+		mag[i] = sqrt(pow(out[i][0],2) + pow(out[i][1],2));
+		mag[i] = sqrt(mag[i]);
+	}
+}
+
+//--------------------------------------------------------------------------------------
+// returns max value of an array
+float Chromagram :: max(float array[],int length)
+{
+	float max = 0;
+	
+	for (int i=0;i < length;i++)
+	{
+		if (array[i] > max)
+		{
+			max = array[i];
+		}
+	}
+	
+	return max;
+}
+
+//--------------------------------------------------------------------------------------
+// returns index of minimum value of array
+int Chromagram :: minindex(float array[],int length)
+{
+	float min = 10000;
+	int minindex = 0;
+	int i;
+	
+	for (i = 0;i < length;i++)
+	{
+		if (array[i] < min)
+		{
+			min = array[i];
+			minindex = i;
+		}
+	}
+	
+	return minindex;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DrumTimingLoader_OF/chromagramm/Chromagram.h	Mon Oct 01 22:24:32 2012 +0100
@@ -0,0 +1,70 @@
+
+
+#ifndef CHROMAGRAM_H
+#define CHROMAGRAM_H
+
+#include "fftw3.h"
+
+class Chromagram
+{
+public:		
+	Chromagram();											// constructor
+	~Chromagram();											// destructor
+	void chromacalc(float frame[]);
+	void initialise(int framesize,int hsize);
+	void processframe(float frame[]);
+//	void processFrame(float* frame, int length);	
+	
+	float rawChroma[12];	
+	float chroma[12];
+	float chroma_low[12];
+	int chromaready;	
+		
+	float maximumChromaValue;
+	
+	int quantisedChromagram[12];
+	double getQuantisedDistance(float secondQuantisedChroma[12]);
+	
+private:
+	void hamming(int N);
+	void makeprofiles();
+	void getmagspectrum();
+	void generatechromagram();
+	
+	void quantiseChromagram();//follows muller's method for quantising 
+	//taking L1 norm, normalising to that, then looking at the bins
+	
+	//float euclidean(float v1[],float v2[],int length);
+	float max(float array[],int length);
+	int minindex(float array[],int length);
+	void downsampleframe(float frame[]);
+
+	int bsize;
+	int count;
+	int hopsize;
+	int fsize;
+	int calcrate;
+	float ratio;
+	
+	float *buffer;											// audio buffer
+	float *wbuffer;											// windowed audio buffer
+	float *win;												// hanning window
+	float *mag;
+	float *d_frame;
+	float *hop;	
+	
+	
+	float note[12];
+	int harmonics;
+	int octaves;
+	int search;
+	
+	fftwf_plan p;											// create fft plan
+	fftwf_complex *out;										// to hold complex fft values
+	
+	float pi;
+	
+
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DrumTimingLoader_OF/fftw/fftw3.h	Mon Oct 01 22:24:32 2012 +0100
@@ -0,0 +1,381 @@
+/*
+ * Copyright (c) 2003, 2007-8 Matteo Frigo
+ * Copyright (c) 2003, 2007-8 Massachusetts Institute of Technology
+ *
+ * The following statement of license applies *only* to this header file,
+ * and *not* to the other files distributed with FFTW or derived therefrom:
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/***************************** NOTE TO USERS *********************************
+ *
+ *                 THIS IS A HEADER FILE, NOT A MANUAL
+ *
+ *    If you want to know how to use FFTW, please read the manual,
+ *    online at http://www.fftw.org/doc/ and also included with FFTW.
+ *    For a quick start, see the manual's tutorial section.
+ *
+ *   (Reading header files to learn how to use a library is a habit
+ *    stemming from code lacking a proper manual.  Arguably, it's a
+ *    *bad* habit in most cases, because header files can contain
+ *    interfaces that are not part of the public, stable API.)
+ *
+ ****************************************************************************/
+
+#ifndef FFTW3_H
+#define FFTW3_H
+
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+/* If <complex.h> is included, use the C99 complex type.  Otherwise
+   define a type bit-compatible with C99 complex */
+#if !defined(FFTW_NO_Complex) && defined(_Complex_I) && defined(complex) && defined(I)
+#  define FFTW_DEFINE_COMPLEX(R, C) typedef R _Complex C
+#else
+#  define FFTW_DEFINE_COMPLEX(R, C) typedef R C[2]
+#endif
+
+#define FFTW_CONCAT(prefix, name) prefix ## name
+#define FFTW_MANGLE_DOUBLE(name) FFTW_CONCAT(fftw_, name)
+#define FFTW_MANGLE_FLOAT(name) FFTW_CONCAT(fftwf_, name)
+#define FFTW_MANGLE_LONG_DOUBLE(name) FFTW_CONCAT(fftwl_, name)
+
+/* IMPORTANT: for Windows compilers, you should add a line
+        #define FFTW_DLL
+   here and in kernel/ifftw.h if you are compiling/using FFTW as a
+   DLL, in order to do the proper importing/exporting, or
+   alternatively compile with -DFFTW_DLL or the equivalent
+   command-line flag.  This is not necessary under MinGW/Cygwin, where
+   libtool does the imports/exports automatically. */
+#if defined(FFTW_DLL) && (defined(_WIN32) || defined(__WIN32__))
+   /* annoying Windows syntax for shared-library declarations */
+#  if defined(COMPILING_FFTW) /* defined in api.h when compiling FFTW */
+#    define FFTW_EXTERN extern __declspec(dllexport) 
+#  else /* user is calling FFTW; import symbol */
+#    define FFTW_EXTERN extern __declspec(dllimport) 
+#  endif
+#else
+#  define FFTW_EXTERN extern
+#endif
+
+enum fftw_r2r_kind_do_not_use_me {
+     FFTW_R2HC=0, FFTW_HC2R=1, FFTW_DHT=2,
+     FFTW_REDFT00=3, FFTW_REDFT01=4, FFTW_REDFT10=5, FFTW_REDFT11=6,
+     FFTW_RODFT00=7, FFTW_RODFT01=8, FFTW_RODFT10=9, FFTW_RODFT11=10
+};
+
+struct fftw_iodim_do_not_use_me {
+     int n;                     /* dimension size */
+     int is;			/* input stride */
+     int os;			/* output stride */
+};
+
+#include <stddef.h> /* for ptrdiff_t */
+struct fftw_iodim64_do_not_use_me {
+     ptrdiff_t n;                     /* dimension size */
+     ptrdiff_t is;			/* input stride */
+     ptrdiff_t os;			/* output stride */
+};
+
+/*
+  huge second-order macro that defines prototypes for all API
+  functions.  We expand this macro for each supported precision
+ 
+  X: name-mangling macro
+  R: real data type
+  C: complex data type
+*/
+
+#define FFTW_DEFINE_API(X, R, C)					   \
+									   \
+FFTW_DEFINE_COMPLEX(R, C);						   \
+									   \
+typedef struct X(plan_s) *X(plan);					   \
+									   \
+typedef struct fftw_iodim_do_not_use_me X(iodim);			   \
+typedef struct fftw_iodim64_do_not_use_me X(iodim64);			   \
+									   \
+typedef enum fftw_r2r_kind_do_not_use_me X(r2r_kind);			   \
+									   \
+FFTW_EXTERN void X(execute)(const X(plan) p);				   \
+									   \
+FFTW_EXTERN X(plan) X(plan_dft)(int rank, const int *n,			   \
+		    C *in, C *out, int sign, unsigned flags);		   \
+									   \
+FFTW_EXTERN X(plan) X(plan_dft_1d)(int n, C *in, C *out, int sign,	   \
+		       unsigned flags);					   \
+FFTW_EXTERN X(plan) X(plan_dft_2d)(int n0, int n1,			   \
+		       C *in, C *out, int sign, unsigned flags);	   \
+FFTW_EXTERN X(plan) X(plan_dft_3d)(int n0, int n1, int n2,		   \
+		       C *in, C *out, int sign, unsigned flags);	   \
+									   \
+FFTW_EXTERN X(plan) X(plan_many_dft)(int rank, const int *n,		   \
+                         int howmany,					   \
+                         C *in, const int *inembed,			   \
+                         int istride, int idist,			   \
+                         C *out, const int *onembed,			   \
+                         int ostride, int odist,			   \
+                         int sign, unsigned flags);			   \
+									   \
+FFTW_EXTERN X(plan) X(plan_guru_dft)(int rank, const X(iodim) *dims,	   \
+			 int howmany_rank,				   \
+			 const X(iodim) *howmany_dims,			   \
+			 C *in, C *out,					   \
+			 int sign, unsigned flags);			   \
+FFTW_EXTERN X(plan) X(plan_guru_split_dft)(int rank, const X(iodim) *dims, \
+			 int howmany_rank,				   \
+			 const X(iodim) *howmany_dims,			   \
+			 R *ri, R *ii, R *ro, R *io,			   \
+			 unsigned flags);				   \
+									   \
+FFTW_EXTERN X(plan) X(plan_guru64_dft)(int rank,			   \
+                         const X(iodim64) *dims,			   \
+			 int howmany_rank,				   \
+			 const X(iodim64) *howmany_dims,		   \
+			 C *in, C *out,					   \
+			 int sign, unsigned flags);			   \
+FFTW_EXTERN X(plan) X(plan_guru64_split_dft)(int rank,			   \
+                         const X(iodim64) *dims,			   \
+			 int howmany_rank,				   \
+			 const X(iodim64) *howmany_dims,		   \
+			 R *ri, R *ii, R *ro, R *io,			   \
+			 unsigned flags);				   \
+									   \
+FFTW_EXTERN void X(execute_dft)(const X(plan) p, C *in, C *out);	   \
+FFTW_EXTERN void X(execute_split_dft)(const X(plan) p, R *ri, R *ii,	   \
+                                      R *ro, R *io);			   \
+									   \
+FFTW_EXTERN X(plan) X(plan_many_dft_r2c)(int rank, const int *n,	   \
+                             int howmany,				   \
+                             R *in, const int *inembed,			   \
+                             int istride, int idist,			   \
+                             C *out, const int *onembed,		   \
+                             int ostride, int odist,			   \
+                             unsigned flags);				   \
+									   \
+FFTW_EXTERN X(plan) X(plan_dft_r2c)(int rank, const int *n,		   \
+                        R *in, C *out, unsigned flags);			   \
+									   \
+FFTW_EXTERN X(plan) X(plan_dft_r2c_1d)(int n,R *in,C *out,unsigned flags); \
+FFTW_EXTERN X(plan) X(plan_dft_r2c_2d)(int n0, int n1,			   \
+			   R *in, C *out, unsigned flags);		   \
+FFTW_EXTERN X(plan) X(plan_dft_r2c_3d)(int n0, int n1,			   \
+			   int n2,					   \
+			   R *in, C *out, unsigned flags);		   \
+									   \
+									   \
+FFTW_EXTERN X(plan) X(plan_many_dft_c2r)(int rank, const int *n,	   \
+			     int howmany,				   \
+			     C *in, const int *inembed,			   \
+			     int istride, int idist,			   \
+			     R *out, const int *onembed,		   \
+			     int ostride, int odist,			   \
+			     unsigned flags);				   \
+									   \
+FFTW_EXTERN X(plan) X(plan_dft_c2r)(int rank, const int *n,		   \
+                        C *in, R *out, unsigned flags);			   \
+									   \
+FFTW_EXTERN X(plan) X(plan_dft_c2r_1d)(int n,C *in,R *out,unsigned flags); \
+FFTW_EXTERN X(plan) X(plan_dft_c2r_2d)(int n0, int n1,			   \
+			   C *in, R *out, unsigned flags);		   \
+FFTW_EXTERN X(plan) X(plan_dft_c2r_3d)(int n0, int n1,			   \
+			   int n2,					   \
+			   C *in, R *out, unsigned flags);		   \
+									   \
+FFTW_EXTERN X(plan) X(plan_guru_dft_r2c)(int rank, const X(iodim) *dims,   \
+			     int howmany_rank,				   \
+			     const X(iodim) *howmany_dims,		   \
+			     R *in, C *out,				   \
+			     unsigned flags);				   \
+FFTW_EXTERN X(plan) X(plan_guru_dft_c2r)(int rank, const X(iodim) *dims,   \
+			     int howmany_rank,				   \
+			     const X(iodim) *howmany_dims,		   \
+			     C *in, R *out,				   \
+			     unsigned flags);				   \
+									   \
+FFTW_EXTERN X(plan) X(plan_guru_split_dft_r2c)(				   \
+                             int rank, const X(iodim) *dims,		   \
+			     int howmany_rank,				   \
+			     const X(iodim) *howmany_dims,		   \
+			     R *in, R *ro, R *io,			   \
+			     unsigned flags);				   \
+FFTW_EXTERN X(plan) X(plan_guru_split_dft_c2r)(				   \
+                             int rank, const X(iodim) *dims,		   \
+			     int howmany_rank,				   \
+			     const X(iodim) *howmany_dims,		   \
+			     R *ri, R *ii, R *out,			   \
+			     unsigned flags);				   \
+									   \
+FFTW_EXTERN X(plan) X(plan_guru64_dft_r2c)(int rank,			   \
+                             const X(iodim64) *dims,			   \
+			     int howmany_rank,				   \
+			     const X(iodim64) *howmany_dims,		   \
+			     R *in, C *out,				   \
+			     unsigned flags);				   \
+FFTW_EXTERN X(plan) X(plan_guru64_dft_c2r)(int rank,			   \
+                             const X(iodim64) *dims,			   \
+			     int howmany_rank,				   \
+			     const X(iodim64) *howmany_dims,		   \
+			     C *in, R *out,				   \
+			     unsigned flags);				   \
+									   \
+FFTW_EXTERN X(plan) X(plan_guru64_split_dft_r2c)(			   \
+                             int rank, const X(iodim64) *dims,		   \
+			     int howmany_rank,				   \
+			     const X(iodim64) *howmany_dims,		   \
+			     R *in, R *ro, R *io,			   \
+			     unsigned flags);				   \
+FFTW_EXTERN X(plan) X(plan_guru64_split_dft_c2r)(			   \
+                             int rank, const X(iodim64) *dims,		   \
+			     int howmany_rank,				   \
+			     const X(iodim64) *howmany_dims,		   \
+			     R *ri, R *ii, R *out,			   \
+			     unsigned flags);				   \
+									   \
+FFTW_EXTERN void X(execute_dft_r2c)(const X(plan) p, R *in, C *out);	   \
+FFTW_EXTERN void X(execute_dft_c2r)(const X(plan) p, C *in, R *out);	   \
+									   \
+FFTW_EXTERN void X(execute_split_dft_r2c)(const X(plan) p,		   \
+                                          R *in, R *ro, R *io);		   \
+FFTW_EXTERN void X(execute_split_dft_c2r)(const X(plan) p,		   \
+                                          R *ri, R *ii, R *out);	   \
+									   \
+FFTW_EXTERN X(plan) X(plan_many_r2r)(int rank, const int *n,		   \
+                         int howmany,					   \
+                         R *in, const int *inembed,			   \
+                         int istride, int idist,			   \
+                         R *out, const int *onembed,			   \
+                         int ostride, int odist,			   \
+                         const X(r2r_kind) *kind, unsigned flags);	   \
+									   \
+FFTW_EXTERN X(plan) X(plan_r2r)(int rank, const int *n, R *in, R *out,	   \
+                    const X(r2r_kind) *kind, unsigned flags);		   \
+									   \
+FFTW_EXTERN X(plan) X(plan_r2r_1d)(int n, R *in, R *out,		   \
+                       X(r2r_kind) kind, unsigned flags);		   \
+FFTW_EXTERN X(plan) X(plan_r2r_2d)(int n0, int n1, R *in, R *out,	   \
+                       X(r2r_kind) kind0, X(r2r_kind) kind1,		   \
+                       unsigned flags);					   \
+FFTW_EXTERN X(plan) X(plan_r2r_3d)(int n0, int n1, int n2,		   \
+                       R *in, R *out, X(r2r_kind) kind0,		   \
+                       X(r2r_kind) kind1, X(r2r_kind) kind2,		   \
+                       unsigned flags);					   \
+									   \
+FFTW_EXTERN X(plan) X(plan_guru_r2r)(int rank, const X(iodim) *dims,	   \
+                         int howmany_rank,				   \
+                         const X(iodim) *howmany_dims,			   \
+                         R *in, R *out,					   \
+                         const X(r2r_kind) *kind, unsigned flags);	   \
+									   \
+FFTW_EXTERN X(plan) X(plan_guru64_r2r)(int rank, const X(iodim64) *dims,   \
+                         int howmany_rank,				   \
+                         const X(iodim64) *howmany_dims,		   \
+                         R *in, R *out,					   \
+                         const X(r2r_kind) *kind, unsigned flags);	   \
+									   \
+FFTW_EXTERN void X(execute_r2r)(const X(plan) p, R *in, R *out);	   \
+									   \
+FFTW_EXTERN void X(destroy_plan)(X(plan) p);				   \
+FFTW_EXTERN void X(forget_wisdom)(void);				   \
+FFTW_EXTERN void X(cleanup)(void);					   \
+									   \
+FFTW_EXTERN void X(set_timelimit)(double);				   \
+									   \
+FFTW_EXTERN void X(plan_with_nthreads)(int nthreads);			   \
+FFTW_EXTERN int X(init_threads)(void);					   \
+FFTW_EXTERN void X(cleanup_threads)(void);				   \
+									   \
+FFTW_EXTERN void X(export_wisdom_to_file)(FILE *output_file);		   \
+FFTW_EXTERN char *X(export_wisdom_to_string)(void);			   \
+FFTW_EXTERN void X(export_wisdom)(void (*write_char)(char c, void *),	   \
+                                  void *data);				   \
+FFTW_EXTERN int X(import_system_wisdom)(void);				   \
+FFTW_EXTERN int X(import_wisdom_from_file)(FILE *input_file);		   \
+FFTW_EXTERN int X(import_wisdom_from_string)(const char *input_string);	   \
+FFTW_EXTERN int X(import_wisdom)(int (*read_char)(void *), void *data);	   \
+									   \
+FFTW_EXTERN void X(fprint_plan)(const X(plan) p, FILE *output_file);	   \
+FFTW_EXTERN void X(print_plan)(const X(plan) p);			   \
+									   \
+FFTW_EXTERN void *X(malloc)(size_t n);					   \
+FFTW_EXTERN void X(free)(void *p);					   \
+									   \
+FFTW_EXTERN void X(flops)(const X(plan) p,				   \
+                          double *add, double *mul, double *fmas);	   \
+FFTW_EXTERN double X(estimate_cost)(const X(plan) p);			   \
+									   \
+FFTW_EXTERN const char X(version)[];					   \
+FFTW_EXTERN const char X(cc)[];						   \
+FFTW_EXTERN const char X(codelet_optim)[];
+
+
+/* end of FFTW_DEFINE_API macro */
+
+FFTW_DEFINE_API(FFTW_MANGLE_DOUBLE, double, fftw_complex)
+FFTW_DEFINE_API(FFTW_MANGLE_FLOAT, float, fftwf_complex)
+FFTW_DEFINE_API(FFTW_MANGLE_LONG_DOUBLE, long double, fftwl_complex)
+
+#define FFTW_FORWARD (-1)
+#define FFTW_BACKWARD (+1)
+
+#define FFTW_NO_TIMELIMIT (-1.0)
+
+/* documented flags */
+#define FFTW_MEASURE (0U)
+#define FFTW_DESTROY_INPUT (1U << 0)
+#define FFTW_UNALIGNED (1U << 1)
+#define FFTW_CONSERVE_MEMORY (1U << 2)
+#define FFTW_EXHAUSTIVE (1U << 3) /* NO_EXHAUSTIVE is default */
+#define FFTW_PRESERVE_INPUT (1U << 4) /* cancels FFTW_DESTROY_INPUT */
+#define FFTW_PATIENT (1U << 5) /* IMPATIENT is default */
+#define FFTW_ESTIMATE (1U << 6)
+
+/* undocumented beyond-guru flags */
+#define FFTW_ESTIMATE_PATIENT (1U << 7)
+#define FFTW_BELIEVE_PCOST (1U << 8)
+#define FFTW_NO_DFT_R2HC (1U << 9)
+#define FFTW_NO_NONTHREADED (1U << 10)
+#define FFTW_NO_BUFFERING (1U << 11)
+#define FFTW_NO_INDIRECT_OP (1U << 12)
+#define FFTW_ALLOW_LARGE_GENERIC (1U << 13) /* NO_LARGE_GENERIC is default */
+#define FFTW_NO_RANK_SPLITS (1U << 14)
+#define FFTW_NO_VRANK_SPLITS (1U << 15)
+#define FFTW_NO_VRECURSE (1U << 16)
+#define FFTW_NO_SIMD (1U << 17)
+#define FFTW_NO_SLOW (1U << 18)
+#define FFTW_NO_FIXED_RADIX_LARGE_N (1U << 19)
+#define FFTW_ALLOW_PRUNING (1U << 20)
+#define FFTW_WISDOM_ONLY (1U << 21)
+
+#ifdef __cplusplus
+}  /* extern "C" */
+#endif /* __cplusplus */
+
+#endif /* FFTW3_H */
Binary file DrumTimingLoader_OF/fftw/libfftw3f.a has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DrumTimingLoader_OF/ofxAubioOnsetDetection/AubioOnsetDetector.cpp	Mon Oct 01 22:24:32 2012 +0100
@@ -0,0 +1,410 @@
+/*
+ *  AubioOnsetDetector.cpp
+ *  aubioonset~
+ *
+ *  Created by Andrew Robertson on 13/08/2010.
+ *  Copyright 2010 __MyCompanyName__. All rights reserved.
+ *
+ */
+
+#include "AubioOnsetDetector.h"
+
+AubioOnsetDetector :: AubioOnsetDetector(){
+	buffersize = 1024;
+	hopsize = 512;
+		//aubio related setup
+		o = new_aubio_onsetdetection(aubio_onset_complex, buffersize, 1);//initially in complex mode
+		pv = (aubio_pvoc_t *)new_aubio_pvoc(buffersize, hopsize, 1);
+		parms = new_aubio_peakpicker(threshold);
+		vec = (fvec_t *)new_fvec(hopsize,1);
+		
+		threshold = 1;
+		threshold2 = -70.;
+	
+	maximumDetectionValue = 10.0; 
+	resetValues();
+	thresholdRelativeToMedian = 1.1;
+	cutoffForRepeatOnsetsMillis = 100;
+	medianSpeed = 15;
+	pos = 0;
+	
+	detectionTriggerRatio = 0.5f;
+	detectionTriggerThreshold = 10;
+	
+	
+
+}
+
+AubioOnsetDetector :: ~AubioOnsetDetector(){
+		aubio_onsetdetection_free (o);
+		del_aubio_pvoc(pv);
+		del_aubio_peakpicker(parms);
+		del_fvec(vec);
+		aubio_cleanup();
+}
+
+void AubioOnsetDetector :: resetValues(){
+	printf("Aubio Onset RESET VALUES\n");
+	
+	rawDetectionValue = 1;
+	peakPickedDetectionValue = 1;
+	medianDetectionValue = 10.;
+	lastMedianOnsetFrame = 0;
+	currentFrame = 0;
+	aubioLongTermAverage = 10.;
+	lastDfValue = 0;
+	bestSlopeValue = 0;
+	recentValueIndex = 0;
+	lastSlopeOnsetFrame = 0;
+	bestSlopeMedian = 10;
+	slopeFallenBelowMedian = true;
+	maximumDetectionValue = 10.0;
+	
+	for (int i = 0;i< numberOfDetectionValues;i++)
+		recentRawDetectionValues[i] = 1;
+}
+
+
+void AubioOnsetDetector :: initialise(){
+	//reinitialises our object
+		o = new_aubio_onsetdetection(aubio_onset_complex, buffersize, 1);//initially in complex mode
+		pv = (aubio_pvoc_t *)new_aubio_pvoc(buffersize, hopsize, 1);
+		parms = new_aubio_peakpicker(threshold);
+		vec = (fvec_t *)new_fvec(hopsize,1);
+		pos = 0;
+				fvec_write_sample(vec, 0.234, 0, pos);
+				fftgrain  = (cvec_t *)new_cvec(buffersize,1);
+				onset = (fvec_t *)new_fvec(1,1);
+		}
+
+
+
+bool AubioOnsetDetector :: processframe(double* frame, const int& n){
+	bool newFrameResult = false;
+	//Paul Brossier's aubioonsetclass~ code ported from Pd
+		int j,isonset;
+	for (j=0;j<n;j++) {
+		
+		// write input to datanew 
+		fvec_write_sample(vec, frame[j], 0, pos);//vec->data[0][pos] = frame[j]
+		//time for fft
+	
+		if (pos == hopsize-1) {  //hopsize is 512       
+			newFrameResult = true;
+			aubioOnsetFound = false;
+		
+			 // block loop 
+			aubio_pvoc_do (pv,vec, fftgrain);
+		
+			fftgrain->norm[0][0] = fabs(fftgrain->norm[0][0]);
+			//added hack to solve bug that norm[0][0] is negative sometimes.
+			
+			aubio_onsetdetection(o, fftgrain, onset);
+			rawDetectionValue = onset->data[0][0];
+		//Paul Brossier's method to return value of peak picking process
+		
+				
+			postProcessing();
+				
+			//	smpl_t my_sample_value;
+			peakPickedDetectionValue = aubio_peakpick_pimrt_getval(parms); 
+			//peakPickedDetectionValue = my_sample_value;
+
+			isonset = aubio_peakpick_pimrt(onset,parms);
+			if (isonset) {
+				// test for silence 
+				if (aubio_silence_detection(vec, threshold2)==1){
+					isonset=0;
+					}
+				else{
+	//				outlet_bang(x->bangoutlet);
+					aubioOnsetFound = true;
+					}
+			}//end if (isonset)
+		
+			
+			
+			// end of block loop 
+			pos = -1; // so it will be zero next j loop 
+		}
+		pos++;
+	
+	}//end for j 
+//end of Paul's code
+
+return newFrameResult;
+		
+}
+
+
+bool AubioOnsetDetector :: processframe(float* frame, const int& n){
+	bool newFrameResult = false;
+	//Paul Brossier's aubioonsetclass~ code ported from Pd
+	int j,isonset;
+	for (j=0;j<n;j++) {
+		
+		// write input to datanew 
+		fvec_write_sample(vec, frame[j], 0, pos);//vec->data[0][pos] = frame[j]
+		//time for fft
+		
+		if (pos == hopsize-1) {  //hopsize is 512       
+			newFrameResult = true;
+			aubioOnsetFound = false;
+			
+			// block loop 
+			aubio_pvoc_do (pv,vec, fftgrain);
+			
+			fftgrain->norm[0][0] = fabs(fftgrain->norm[0][0]);
+			//added hack to solve bug that norm[0][0] is negative sometimes.
+			
+			aubio_onsetdetection(o, fftgrain, onset);
+			rawDetectionValue = onset->data[0][0];
+			//Paul Brossier's method to return value of peak picking process
+			
+			
+			postProcessing();
+			
+			//	smpl_t my_sample_value;
+			//peakPickedDetectionValue = aubio_peakpick_pimrt_getval(parms); 
+			//peakPickedDetectionValue = my_sample_value;
+			
+			//Paul Brossier's onset detection method
+			isonset = aubio_peakpick_pimrt(onset,parms);
+			if (isonset) {
+				// test for silence 
+				if (aubio_silence_detection(vec, threshold2)==1){
+					isonset=0;
+				}
+				else{
+					//				outlet_bang(x->bangoutlet);
+					aubioOnsetFound = true;
+				}
+			}//end if (isonset)
+			
+			
+			
+			// end of block loop 
+			pos = -1; // so it will be zero next j loop 
+		}
+		pos++;
+		
+	}//end for j 
+	//end of Paul's code
+	
+	return newFrameResult;
+	
+}
+
+
+ 
+ void AubioOnsetDetector :: postProcessing(){
+	 //anrMedia processed has conditions below
+	 anrMedianProcessedOnsetFound = checkForMedianOnset(rawDetectionValue);
+	 
+	 //the slope idea is we need both a high rise and a high / steep slope and we
+	 //look for both of these
+	 bestSlopeValue = getBestSlopeValue(rawDetectionValue); 
+	 anrBestSlopeOnset = checkForSlopeOnset(bestSlopeValue);
+ }
+ 
+bool AubioOnsetDetector :: checkForMedianOnset(const float& dfvalue){
+	 bool onsetDetected = false;
+	 //check for onset relative to our rising and falling median threshold
+	
+	 if (dfvalue > medianDetectionValue * thresholdRelativeToMedian && 
+		 dfvalue > aubioLongTermAverage &&
+		 //lastDfValue < medianDetectionValue &&
+		 1000*framesToSeconds(currentFrame - lastMedianOnsetFrame) > cutoffForRepeatOnsetsMillis){
+		
+		onsetDetected = true;
+		lastMedianOnsetFrame = currentFrame;
+		//printf("frame diff between onsets %6.1f", (1000*framesToSeconds(currentFrame - lastMedianOnsetFrame)) );
+	 }
+ 
+//	aubioLongTermAverage *= 0.995;
+	aubioLongTermAverage += 0.01*(dfvalue - aubioLongTermAverage);
+ 
+	if (dfvalue > medianDetectionValue)
+		medianDetectionValue = dfvalue;
+	else 
+		medianDetectionValue += 0.01*medianSpeed*(dfvalue - medianDetectionValue);
+ 
+	if (dfvalue > maximumDetectionValue){
+		maximumDetectionValue = dfvalue;
+		printf("DF value causes new max %f\n", maximumDetectionValue);
+	}
+ 
+ 
+ currentFrame++;
+ lastDfValue = dfvalue;
+ 
+ 
+return onsetDetected;
+}
+ 
+ 
+ 
+ double AubioOnsetDetector::getBestSlopeValue(const float& dfvalue){
+ //the idea is we want a high slope
+ recentRawDetectionValues[recentValueIndex] = dfvalue;
+ double bestValue = 0;
+ for (int i = 1;i < numberOfDetectionValues;i++){
+ double angle = 0;
+ int otherIndex = (recentValueIndex - i + numberOfDetectionValues)%numberOfDetectionValues;
+ double testValue = 0;
+ if (otherIndex > 0 && recentRawDetectionValues[otherIndex] > 0){
+ angle = atan((float)(i * dfvalue)/ (numberOfDetectionValues*(dfvalue-recentRawDetectionValues[otherIndex])) );
+ testValue = (dfvalue - recentRawDetectionValues[otherIndex]) * cos(angle);
+ }
+ 
+ if (testValue > bestValue)
+ bestValue = testValue;
+ }
+ 
+ recentValueIndex++;
+ 
+ if (recentValueIndex == numberOfDetectionValues)
+ recentValueIndex = 0;
+ 
+ 
+ return bestValue;
+ 
+ }
+ 
+ 
+ 
+ 
+ bool AubioOnsetDetector :: checkForSlopeOnset(const float& bestValue){
+ bool onsetDetected = false;
+ //check for onset relative to our processed slope function
+ //a mix between increase in value and the gradient of that increase
+ 
+ if (bestValue > bestSlopeMedian * thresholdRelativeToMedian && //better than recent average 
+ 1000*framesToSeconds(currentFrame - lastSlopeOnsetFrame) > cutoffForRepeatOnsetsMillis //after cutoff time
+ && slopeFallenBelowMedian // has had onset and fall away again
+ && bestValue > detectionTriggerThreshold * detectionTriggerRatio //longer term ratio of winning onsets 
+ ){
+ //	printf("frame diff between onsets %6.1f", (1000*framesToSeconds(currentFrame - lastMedianOnsetFrame)) );
+ onsetDetected = true;
+ lastSlopeOnsetFrame = currentFrame;
+ slopeFallenBelowMedian = false;
+ 
+ updateDetectionTriggerThreshold(bestValue);
+ }
+ 
+ 
+	 if (bestValue > bestSlopeMedian){
+		bestSlopeMedian += (bestValue - bestSlopeMedian)*0.04;//was 1.1
+	 }
+		else{
+			bestSlopeMedian *= 0.99;
+			slopeFallenBelowMedian = true;;
+		}
+	
+	 //bestSlopeMedian += 0.02* (bestValue - bestSlopeMedian);
+	 
+	 
+ return onsetDetected;
+ }
+ 
+ 
+ void AubioOnsetDetector::updateDetectionTriggerThreshold(const float& val){
+ float detectionAdaptSpeed = 0.05;//moving average, roughly last twenty onsets
+ detectionTriggerThreshold *= 1- detectionAdaptSpeed;
+ detectionTriggerThreshold += (val * detectionAdaptSpeed);
+ }
+ 
+
+double  AubioOnsetDetector::framesToSeconds(const float& frames){
+	double seconds = frames * buffersize / 44100.;
+	return seconds;
+}
+/*
+double  AubioOnsetDetector::framesToMillis(const float& frames){
+	double seconds = frames * buffersize * 1000.0 / 44100.;
+	return seconds;
+}
+*/
+float AubioOnsetDetector :: getRawDetectionFrame(){
+return rawDetectionValue;	
+}
+
+float AubioOnsetDetector :: getPeakPickedDetectionFrame(){
+return peakPickedDetectionValue;	
+}
+
+
+void AubioOnsetDetector :: onsetclass_energy(){
+		//aubio_onsetdetection_type
+		aubio_onsetdetection_free (o);
+		o = new_aubio_onsetdetection(aubio_onset_energy, buffersize, 1);
+}
+
+void AubioOnsetDetector :: onsetclass_hfc(){
+/** High Frequency Content onset detection function
+ 
+  This method computes the High Frequency Content (HFC) of the input spectral
+  frame. The resulting function is efficient at detecting percussive onsets.
+
+  Paul Masri. Computer modeling of Sound for Transformation and Synthesis of
+  Musical Signal. PhD dissertation, University of Bristol, UK, 1996.*/
+		aubio_onsetdetection_free (o);
+		o = new_aubio_onsetdetection(aubio_onset_hfc, buffersize, 1);
+}
+
+
+void AubioOnsetDetector :: onsetclass_complex(){
+		//aubio_onsetdetection_type
+		//Complex Domain Method onset detection function 
+		//Christopher Duxbury, Mike E. Davies, and Mark B. Sandler. Complex domain
+		//onset detection for musical signals. In Proceedings of the Digital Audio
+		//Effects Conference, DAFx-03, pages 90-93, London, UK, 2003.
+		aubio_onsetdetection_free (o);
+		o = new_aubio_onsetdetection(aubio_onset_complex, buffersize, 1);
+}
+
+void AubioOnsetDetector :: onsetclass_phase(){
+/** Phase Based Method onset detection function 
+
+  Juan-Pablo Bello, Mike P. Davies, and Mark B. Sandler. Phase-based note onset
+  detection for music signals. In Proceedings of the IEEE International
+  Conference on Acoustics Speech and Signal Processing, pages 441­444,
+  Hong-Kong, 2003.*/
+  		aubio_onsetdetection_free (o);
+		o = new_aubio_onsetdetection(aubio_onset_phase, buffersize, 1);
+		
+}
+
+void AubioOnsetDetector :: onsetclass_specdiff(){
+		/* Spectral difference method onset detection function 
+		Jonhatan Foote and Shingo Uchihashi. The beat spectrum: a new approach to
+		rhythm analysis. In IEEE International Conference on Multimedia and Expo
+		(ICME 2001), pages 881­884, Tokyo, Japan, August 2001.
+		*/
+		//aubio_onsetdetection_type
+		aubio_onsetdetection_free (o);
+		o = new_aubio_onsetdetection(aubio_onset_specdiff, buffersize, 1);
+}
+
+void AubioOnsetDetector :: onsetclass_kl(){
+		/** Kullback-Liebler onset detection function 
+  
+			Stephen Hainsworth and Malcom Macleod. Onset detection in music audio
+			signals. In Proceedings of the International Computer Music Conference
+			(ICMC), Singapore, 2003.
+		*/
+		aubio_onsetdetection_free (o);
+		o = new_aubio_onsetdetection(aubio_onset_kl, buffersize, 1);
+}
+
+void AubioOnsetDetector :: onsetclass_mkl(){
+
+		/** Modified Kullback-Liebler onset detection function 
+
+		Paul Brossier, ``Automatic annotation of musical audio for interactive
+		systems'', Chapter 2, Temporal segmentation, PhD thesis, Centre for Digital
+		music, Queen Mary University of London, London, UK, 2003.*/		
+		aubio_onsetdetection_free (o);
+		o = new_aubio_onsetdetection(aubio_onset_hfc, buffersize, 1);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DrumTimingLoader_OF/ofxAubioOnsetDetection/AubioOnsetDetector.h	Mon Oct 01 22:24:32 2012 +0100
@@ -0,0 +1,80 @@
+
+#ifndef AUBIOONSETDETECTOR_H
+#define AUBIOONSETDETECTOR_H
+
+#include "aubio.h"
+
+class AubioOnsetDetector
+{
+public:		
+	AubioOnsetDetector();
+	~AubioOnsetDetector();
+	void initialise();
+	void resetValues();
+	
+	bool processframe(double* frame, const int& n);
+	bool processframe(float* frame, const int& n);
+	
+	void onsetclass_energy();	
+	void onsetclass_complex();
+	void onsetclass_specdiff();
+	void onsetclass_kl();
+	void onsetclass_mkl();
+	void onsetclass_hfc();
+	void onsetclass_phase();
+		
+	bool checkForMedianOnset(const float& dfvalue);
+	void postProcessing();
+	
+	float getRawDetectionFrame();
+	float getPeakPickedDetectionFrame();
+	double framesToSeconds(const float& frames);
+//	double framesToMillis(const float& frames);
+//	boolean getIsOnset();
+	
+	
+	aubio_onsetdetection_t		*o;
+	aubio_pvoc_t				*pv;
+	aubio_pickpeak_t			*parms;
+	
+		
+	fvec_t						*vec;
+	fvec_t						*onset;
+	cvec_t						*fftgrain;//complex vector of buffersize, 1
+	
+	bool aubioOnsetFound;//method used by Paul Brossier
+	//see relevant papers - eg fast transients 2005
+	int buffersize, hopsize, pos;
+	float threshold,  threshold2;
+	float rawDetectionValue, peakPickedDetectionValue;
+
+	static const int numberOfDetectionValues = 16;
+	float recentRawDetectionValues[numberOfDetectionValues];
+	
+	int recentValueIndex;
+	
+	float medianDetectionValue, aubioLongTermAverage ;
+	bool anrMedianProcessedOnsetFound;//simple median method by Andrew Robertson
+	//requires a fast rise, slower fall
+	long lastMedianOnsetFrame, currentFrame;
+	float thresholdRelativeToMedian;
+	long cutoffForRepeatOnsetsMillis;
+	float medianSpeed;
+	float lastDfValue;
+	float bestSlopeValue;
+	double getBestSlopeValue(const float& dfvalue);
+	double bestSlopeMedian;
+	bool anrBestSlopeOnset;
+	long lastSlopeOnsetFrame;
+	bool slopeFallenBelowMedian;
+	bool checkForSlopeOnset(const float& bestValue);
+	
+	void updateDetectionTriggerThreshold(const float& val);
+	
+	float detectionTriggerThreshold, detectionTriggerRatio;
+	float maximumDetectionValue;
+	
+	
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DrumTimingLoader_OF/ofxAubioOnsetDetection/AubioPitch.cpp	Mon Oct 01 22:24:32 2012 +0100
@@ -0,0 +1,154 @@
+/*
+ *  AubioPitch.cpp
+ *  fileLoaderAndOnsetDetection
+ *
+ *  Created by Andrew on 24/01/2012.
+ *  Copyright 2012 QMUL. All rights reserved.
+ *
+ */
+
+#include "AubioPitch.h"
+
+
+
+//HERE I'm using doPitchDetection as it avoids the buffering problem
+//I just fill the buffer with what samples I want and get pitch returned.
+
+
+AubioPitch::AubioPitch(){
+	bufsize   = 4096;
+	hopsize   = bufsize / 2;
+	pitch = 0.0;
+	
+	aubio_pitchdetection_type type_pitch = aubio_pitch_yinfft;// now changed
+	aubio_pitchdetection_mode mode_pitch = aubio_pitchm_freq;
+//	bufsize*4 below
+	pitchDetect = new_aubio_pitchdetection(bufsize, hopsize, 1, 44100., type_pitch, mode_pitch);
+	
+	aubio_pitchdetection_set_yinthresh(pitchDetect, 0.85);
+	
+	vec = (fvec_t *)new_fvec(hopsize,1);//anr changed from hopsize
+	
+	pos = 0;
+}
+
+AubioPitch::~AubioPitch(){
+	del_aubio_pitchdetection(pitchDetect);
+	del_fvec(vec);
+	aubio_cleanup();
+	//delk fvec
+	
+}
+
+bool AubioPitch::processFrame(float* frame, int size){//
+	//note this no longer called
+	int j;
+	bool pitchDetected = false;
+	//smpl_t pitch;
+	
+	for (j=0;j<size;j++) {
+		
+		fvec_write_sample(vec, frame[j], 0, pos);
+
+		if (pos == hopsize-1) {  //anr recent change from hopsize       
+			// block loop /
+			
+			pitch = aubio_pitchdetection(pitchDetect, vec);
+			pitchDetected = true;
+			printf("PITCH IS %f\n", pitch);
+		
+			//			printf("Pitch detected %f\n", pitch);
+//			outlet_float(x->pitchOutlet, pitch);
+			
+			// end of block loop 
+			pos = -1; // so it will be zero next j loop //
+		}
+		pos++;
+		
+	}
+	return pitchDetected;
+	
+}
+
+//anr idea of adding to buffer
+void AubioPitch::addToBuffer(float* tmpFrame, const int& n){
+	for (int j=0;j < n;j++) {
+		fvec_write_sample(vec, tmpFrame[j], 0, pos);
+		
+		if (pos == hopsize - 1){
+			//pitch = aubio_pitchdetection(x->o,x->vec);
+			//outlet_float(x->pitchOutlet, pitch);
+			
+			pitch = aubio_pitchdetection(pitchDetect, vec);
+			pos = -1;
+		}
+		
+		pos++;
+	}
+}
+
+float AubioPitch::getPitch(){
+//float newPitch = aubio_pitchdetection(pitchDetect, vec);
+//	return newPitch;
+	return pitch;
+}
+
+//this function is more useful here
+//can process a frame - by converting it into an fvec_t type used by aubio
+//but since only do this once, better for our purposes than the more iterative method above
+//we just store the float frames and when needed, call this for our pitch calculation on the whole
+//buffer - checking that length below is in fact bufsize
+
+float AubioPitch::doPitchDetection(float* frame, const int& length){
+	//fn to do pitch detection without all the buffering etc
+	float newPitch = -1.0;
+	if (length == bufsize){
+		fvec_t* tmpVec;
+		tmpVec = new_fvec(bufsize,1);
+		for (int j =0;j < length;j++){
+			fvec_write_sample(tmpVec, frame[j], 0, j);
+		//	printf("vec[%i] = %.3f\n", j, frame[j]);
+		}
+		newPitch = aubio_pitchdetection(pitchDetect, tmpVec);
+	//	printf("NEW PITCH FOUND %f\n", newPitch);
+	}
+	return newPitch;
+}
+
+
+//float AubioPitch::getPitchDetectedFromBuffer(float* frame, const int& length){
+	
+//	smpl_t pitch = 0.;
+/*	fvec_t * buf;
+	for (int i = 0;i < length;i++){
+		buf[i] = frame[i];
+	}
+*/	
+
+/*	if (length == bufsize){
+		pitch = aubio_pitchyinfft_detect(pitchDetect->yinfft, buf, pitchDetect->yinthres);
+	
+		if (pitch > 0){
+			pitch = pitchDetect->srate/(pitch + 0.);
+		} else {
+			pitch = 0.;
+		}
+		
+	}//end if right size
+	*/
+//	return pitch;
+	
+//}
+
+
+
+
+
+
+/*This is the fvec_t defn from aubio:
+ AUBIO f_vec
+ struct _fvec_t {
+ ba_uint_t length;   /**< length of buffer 
+ ba_uint_t channels; /**< number of channels 
+ smpl_t **data;   /**< data array of size [length] * [channels] 
+ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DrumTimingLoader_OF/ofxAubioOnsetDetection/AubioPitch.h	Mon Oct 01 22:24:32 2012 +0100
@@ -0,0 +1,46 @@
+/*
+ *  AubioPitch.h
+ *  fileLoaderAndOnsetDetection
+ *
+ *  Created by Andrew on 24/01/2012.
+ *  Copyright 2012 QMUL. All rights reserved.
+ *
+ */
+
+
+#ifndef AUBIO_PITCH_H
+#define  AUBIO_PITCH_H
+
+#include "ofMain.h"
+#include "aubio.h"
+
+class AubioPitch {
+public:
+	AubioPitch();
+	~AubioPitch();
+	
+	bool processFrame(float* frame, int size);
+	
+	int bufsize, hopsize;
+	
+	aubio_pitchdetection_type type_pitch;
+	aubio_pitchdetection_mode mode_pitch;
+
+
+	float threshold;	
+	
+	smpl_t pitch;
+	
+	aubio_pitchdetection_t *pitchDetect;
+	fvec_t *vec;
+	int pos;
+	
+	float doPitchDetection(float* frame, const int& length);
+	
+	float getPitch();
+	void addToBuffer(float* tmpFrame, const int& n);
+	
+	//float getPitchDetectedFromBuffer(float* frame, const int& length);
+	
+};
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DrumTimingLoader_OF/ofxAubioOnsetDetection/ChromaOnset.cpp	Mon Oct 01 22:24:32 2012 +0100
@@ -0,0 +1,146 @@
+/*
+ *  ChromaOnset.cpp
+ *  fileLoaderAndOnsetDetection
+ *
+ *  Created by Andrew on 17/01/2012.
+ *  Copyright 2012 QMUL. All rights reserved.
+ *
+ */
+
+#include "ChromaOnset.h"
+
+//stores the information about our onset event
+//when it happened
+//what the chromagram was immeditaely after 
+//what the pitch was using AubioPitch class
+
+//FrameHolder holds the audio samples needed to do the harmonic analysis after the fact
+
+ChromaOnset::ChromaOnset(){
+	frameTime = 0;
+	millisTime = 0;
+	chromaCalculated = false;
+	chromaSize = 2048;
+	
+	cgramPtr = new Chromagram();
+	cgramPtr->initialise(512, chromaSize);
+	
+	onsetIndex = 0;
+
+	matched = false;
+	//we also store an aubio pitch result - using a Frameholder to hold the frames we need to calculate this on
+	aubioPitch = 0;
+	aubioPitchFound = false;
+	
+	pitchFrameCounter = 0;//counts til time to do pitch detection
+	
+	
+//	aubioPitchDetector = new AubioPitch();
+
+}
+
+void ChromaOnset::deleteChromagram(){
+	delete cgramPtr;
+	//printf("chromagram deleted\n");
+}
+
+
+bool ChromaOnset::processFrame(float* frame, const int& length){
+	bool newlyCalculated = false;
+	if (chromaCalculated == false){
+		
+		cgramPtr->processframe(frame);
+		
+		if (cgramPtr->chromaready){
+			
+			float tmpMax = max(cgramPtr->maximumChromaValue, 1.0f);
+
+			for (int i = 0;i < 12;i++){
+				chromaValues.push_back(cgramPtr->rawChroma[i]/tmpMax);
+				quantisedChromaValues.push_back(cgramPtr->quantisedChromagram[i]);
+			//	printf("chroma [%i] %f max %f quantised %i\n", i, cgramPtr->rawChroma[i], cgramPtr->chroma[i], cgramPtr->quantisedChromagram[i] );
+			}
+			chromaCalculated = true;
+			newlyCalculated = true;
+			//this would do chord detection
+			//			chord.C_Detect(chromoGramm.chroma,chromoGramm.chroma_low);
+			//			rootChord[chromaIndex] = chord.root;
+			
+		}
+		
+	}
+	
+	return newlyCalculated;
+}
+
+double ChromaOnset::timeDistanceMillis(const ChromaOnset& secondChromaOnset){
+	
+	return (abs(secondChromaOnset.millisTime - millisTime));
+}
+
+double ChromaOnset::pitchDistance(const ChromaOnset& secondChromaOnset){
+
+	return (abs(secondChromaOnset.aubioPitch - aubioPitch));
+}
+
+double ChromaOnset::getQuantisedDistance(ChromaOnset& secondChromaOnset){
+	
+	return getChromaQuantisedDistance(&secondChromaOnset.quantisedChromaValues[0]);
+	
+}
+
+double ChromaOnset::getChromaQuantisedDistance(float* quantisedChromagramTwo){
+	
+	double cosineDistance = 0;
+	double quantLengthOne = 0;
+	double quantLengthTwo = 0;	
+	for (int i = 0;i < 12;i++){
+		
+		cosineDistance += quantisedChromaValues[i] * quantisedChromagramTwo[i];
+		
+		quantLengthOne += quantisedChromaValues[i] * quantisedChromaValues[i];
+		quantLengthTwo += quantisedChromagramTwo[i] * quantisedChromagramTwo[i];
+		
+	}
+	
+	if (quantLengthOne > 0 && quantLengthTwo > 0)
+		cosineDistance /= sqrt(quantLengthOne * quantLengthTwo);
+	else 
+		cosineDistance = 0;
+	
+	return cosineDistance;
+	
+	
+}
+
+double ChromaOnset::chromaDotProductDistance(const ChromaOnset& secondChromaOnset){
+	double dotProductSum = 0;
+	double chromaOneSum = 0;
+	double chromaTwoSum = 0;
+	if (chromaValues.size() == 12 && secondChromaOnset.chromaValues.size() == 12){
+		for (int i = 0;i < 12;i++){
+			dotProductSum += chromaValues[i]*secondChromaOnset.chromaValues[i];
+			chromaOneSum += chromaValues[i]*chromaValues[i];
+			chromaTwoSum += secondChromaOnset.chromaValues[i]*secondChromaOnset.chromaValues[i];
+		}
+		chromaOneSum = sqrt(chromaOneSum);
+		chromaTwoSum = sqrt(chromaTwoSum);
+		if (chromaOneSum > 0 && chromaTwoSum > 0)
+			dotProductSum /= (chromaOneSum*chromaTwoSum);
+		else
+			dotProductSum = 0;
+	}
+	return (dotProductSum);
+}
+
+void ChromaOnset::printInfo(){
+
+	printf("ONSET : frametime %i, millis %f pitch %f\n", frameTime, millisTime, aubioPitch);
+	printf("chroma: ");
+	
+	for(int i = 0;i < chromaValues.size();i++)
+			printf("[%i] %1.3f, ", i, chromaValues[i]);
+	
+	printf(".\n");
+	
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DrumTimingLoader_OF/ofxAubioOnsetDetection/ChromaOnset.h	Mon Oct 01 22:24:32 2012 +0100
@@ -0,0 +1,77 @@
+/*
+ *  ChromaOnset.h
+ *  fileLoaderAndOnsetDetection
+ *
+ *  Created by Andrew on 17/01/2012.
+ *  Copyright 2012 QMUL. All rights reserved.
+ *
+ */
+
+#ifndef CHROMA_ONSET_H
+#define  CHROMA_ONSET_H
+
+#include "ofMain.h"
+#include "chromaGram.h"
+//#include "AubioPitch.h"
+#include "FrameHolder.h"
+
+/*
+//could switch to a struct to hold this?
+ 
+ struct OnsetEvent{
+	double millisTime;
+	int frameTime;
+	
+	bool chromaCalculated;
+	float chromaValues[12];
+	
+	bool aubioPitchFound;
+	float aubioPitch;
+};
+*/
+
+class ChromaOnset {
+	public:
+	ChromaOnset();
+	
+	double millisTime;
+	int frameTime;
+	//chromagram chroma;
+	bool chromaCalculated;
+	int chromaSize;
+	int pitchFrameCounter;
+	
+	//move chromagram out of this class 
+	//Chromagram cgram;
+	
+	typedef std::vector<float> FloatVector;
+	FloatVector chromaValues;
+	FloatVector quantisedChromaValues;
+	
+	double getQuantisedDistance(ChromaOnset& secondChromaOnset);
+	double getChromaQuantisedDistance(float* quantisedChromagramTwo);
+	//also do pitch detection using this class
+	//AubioPitch *aubioPitchDetector;
+	bool aubioPitchFound;
+	float aubioPitch;
+	
+	bool matched;//just for drawing
+
+	
+	bool processFrame(float* frame, const int& length);
+//	void calculateChroma(float* frame, const int& length);
+
+	double timeDistanceMillis(const ChromaOnset& secondChromaOnset);
+	double pitchDistance(const ChromaOnset& secondChromaOnset);
+	double chromaDotProductDistance(const ChromaOnset& secondChromaOnset);
+
+
+	Chromagram* cgramPtr;
+	void deleteChromagram();
+	
+	FrameHolder onsetFrame;
+	
+	int onsetIndex;//in terms of our onset detection fn - ofxAubioOnsetDetector
+	void printInfo();
+};
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DrumTimingLoader_OF/ofxAubioOnsetDetection/FrameHolder.cpp	Mon Oct 01 22:24:32 2012 +0100
@@ -0,0 +1,62 @@
+/*
+ *  FrameHolder.cpp
+ *  fileLoaderAndOnsetDetection
+ *
+ *  Created by Andrew on 25/01/2012.
+ *  Copyright 2012 QMUL. All rights reserved.
+ *
+ */
+
+#include "FrameHolder.h"
+
+FrameHolder::FrameHolder(){
+	sizeOfFrame = 0;
+	sizeOfFvec = 0;
+	frame.reserve(4096); 
+//	buffersize = 8192;
+	frameCounter = 0;
+//	vec = (fvec_t *)new_fvec(buffersize,1);
+	//printf("initialise frameholder\n");
+}
+
+
+void FrameHolder::deleteFrame(){
+	frame.clear();
+	//printf("clear frame\n");
+}
+
+
+void FrameHolder::addToFrame(float* newAudio, const int& length){
+	for (int i = 0;i < length;i++){
+	//	printf("new audio %i is %f\n", i, newAudio[i]);
+		frame.push_back(newAudio[i]);
+	}
+	
+	sizeOfFrame = frame.size();
+	//printf("framesize %i\n", sizeOfFrame);
+}
+
+bool FrameHolder::sizeEquals(const int& length){
+	if (sizeOfFrame == length)
+		return true;
+	else 
+		return false;
+}
+/*
+void FrameHolder::addToFvec(float* newAudio, const int& length){
+	//my way to write to fvec - hope it works!
+	for (int i =;i < length;i++)
+		vec->data[i+sizeOfFvec] = newAudio[i];
+	
+	sizeOfFvec += length;
+	
+//	fvec_write_sample(vec, frame[j], 0, pos);
+}
+
+void FrameHolder::addToFvec(float* newAudio, const int& length){
+	for (int i = 0;i < length;i++)
+		frame.push_back(newAudio[i]);
+	
+	size = frame.size();
+}
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DrumTimingLoader_OF/ofxAubioOnsetDetection/FrameHolder.h	Mon Oct 01 22:24:32 2012 +0100
@@ -0,0 +1,44 @@
+/*
+ *  FrameHolder.h
+ *  fileLoaderAndOnsetDetection
+ *
+ *  Created by Andrew on 25/01/2012.
+ *  Copyright 2012 QMUL. All rights reserved.
+ *
+ */
+
+
+#ifndef FRAME_HOLDER_H
+#define  FRAME_HOLDER_H
+
+#include "ofMain.h"
+//#include "chromaGram.h"
+//#include "AubioPitch.h"
+//#include "aubio.h"
+
+class FrameHolder {
+public:
+	FrameHolder();
+	
+	int sizeOfFrame, sizeOfFvec;
+	std::vector<float> frame;
+	
+	void deleteFrame();
+	void addToFrame(float* newAudio, const int& length);
+	
+	bool sizeEquals(const int& length);
+	
+	int frameCounter;
+	//_fvec_t aubioFvec;
+//	fvec_t *vec;
+	
+	/*
+	 struct _fvec_t {
+	 ba_uint_t length;   /**< length of buffer
+	ba_uint_t channels; /**< number of channels 
+	smpl_t **data;   /**< data array of size [length] * [channels] 
+	*/
+	
+};
+#endif
+	
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DrumTimingLoader_OF/ofxAubioOnsetDetection/PreciseOnsetLocator.cpp	Mon Oct 01 22:24:32 2012 +0100
@@ -0,0 +1,145 @@
+/*
+ *  PreciseOnsetLocator.cpp
+ *  peakOnsetDetector
+ *
+ *  Created by Andrew on 21/09/2012.
+ *  Copyright 2012 QMUL. All rights reserved.
+ *
+ */
+
+#include "PreciseOnsetLocator.h"
+
+PreciseOnsetLocator::PreciseOnsetLocator(){
+	setup(512);
+
+}
+
+PreciseOnsetLocator::~PreciseOnsetLocator(){
+	onsetSamples.clear();
+	recentBufferSamples.clear();
+}
+
+
+void PreciseOnsetLocator::setup(const int& size){
+	onsetSamples.clear();
+	recentBufferSamples.clear();
+	bufferSize = size;
+	onsetSamples.assign(bufferSize, 0.0);
+	recentBufferSamples.assign(bufferSize, 0.0);
+	printInfo = false;
+}
+
+void PreciseOnsetLocator::storeSamples(double* newSamples){
+	
+	for (int i = 0;i < bufferSize;i++)
+		recentBufferSamples[i] = newSamples[i];
+	
+}
+
+
+void PreciseOnsetLocator::storeSamples(float* newSamples){
+	
+	for (int i = 0;i < bufferSize;i++)
+		recentBufferSamples[i] = newSamples[i];
+	
+}
+
+
+int PreciseOnsetLocator::findExactOnset(double* frame, const int& framesize){
+	//store the samples - mainly for viewing actually
+	if (framesize == bufferSize){
+	onsetSamples.clear();
+	for (int i = 0; i < bufferSize;i++) {
+		onsetSamples.push_back(frame[i]);
+	}
+	
+	if (recentBufferSamples.size() == 0)
+		printf("Bad size onset vector\n");
+		
+	double energySum = 0;
+	double lastEnergySum, hopsizeLastEnergySum;
+	double energyDifference;
+	int bestEnergyIndex = 0;
+	double bestEnergyDifference = 0;
+	int endIndex = bufferSize;
+	int hopSize;
+
+	printInfo = false;
+	
+	for (int resolution = bufferSize/2;resolution > 1;resolution/=2){
+		if (printInfo)
+			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){
+				if (printInfo)
+					printf("index %i last energy %f hop energy %f ", startIndex, lastEnergySum, hopsizeLastEnergySum);
+			
+			//sum the energy for this new frame
+			energySum = 0;
+			for (int i = 0;i < resolution;i++){
+				energySum += onsetSamples[startIndex + i] * onsetSamples[startIndex + i];
+			}
+				if (printInfo)
+					printf("energysum %f\n", energySum);
+			//check if new max difference
+			energyDifference = energySum - lastEnergySum;
+			if (energyDifference > bestEnergyDifference){
+				bestEnergyDifference = energyDifference;
+				bestEnergyIndex = startIndex;
+			}
+			
+			//store the values for checking in two loops time (because proceeding at resolution/2 each step)
+			//eg 0_to_128 compared to -128_to_0, 64_to_196 compared to -64_to_64, then 128_256 compared with 0_to_128, 
+			lastEnergySum = hopsizeLastEnergySum;// energySum;
+			hopsizeLastEnergySum = energySum;
+			
+		}
+			if (printInfo)
+				printf("winning index is %i\n", bestEnergyIndex);
+		endIndex = bestEnergyIndex + resolution;
+		
+	}
+			if (printInfo)
+				printf("TOTAL WINNER %i\n", bestEnergyIndex);
+	return bestEnergyIndex;
+	}else{
+		printf("NOt same buffersize!\n");
+		return 0;
+	}
+	
+}
+
+
+
+int PreciseOnsetLocator::findExactOnset(float* frame, const int& framesize){
+
+	double tempOnsetSamples[framesize];
+	for (int i = 0;i < framesize;i++)
+		tempOnsetSamples[i] = frame[i];
+	
+	return findExactOnset(&tempOnsetSamples[0], framesize);
+}
+
+
+double PreciseOnsetLocator::getLastEnergySum(const int& startIndex, const int& vectorSize){
+	double lastEnergySum = 0;
+	
+	for (int i = startIndex - vectorSize;i < startIndex;i++){
+		if (i > 0)
+			lastEnergySum += onsetSamples[i] * onsetSamples[i];
+		else {
+			lastEnergySum += recentBufferSamples[bufferSize + i] * recentBufferSamples[bufferSize + i];
+		}
+	}
+	return lastEnergySum;
+	
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DrumTimingLoader_OF/ofxAubioOnsetDetection/PreciseOnsetLocator.h	Mon Oct 01 22:24:32 2012 +0100
@@ -0,0 +1,41 @@
+/*
+ *  PreciseOnsetLocator.h
+ *  peakOnsetDetector
+ *
+ *  Created by Andrew on 21/09/2012.
+ *  Copyright 2012 QMUL. All rights reserved.
+ *
+ */
+
+
+#ifndef PRECISE_ONSET_LOCATOR
+#define PRECISE_ONSET_LOCATOR
+
+#include <vector.h>
+
+class PreciseOnsetLocator{
+	public:
+	
+	PreciseOnsetLocator();
+	~PreciseOnsetLocator();
+	
+	int bufferSize;
+	bool printInfo;
+	
+	vector <double> onsetSamples;//holds the audio samples when onset is found
+	vector <double> recentBufferSamples;
+	
+	double getLastEnergySum(const int& startIndex, const int& vectorSize);
+	int findExactOnset(double* frame, const int& framesize);
+	int findExactOnset(float* frame, const int& framesize);
+
+	int exactOnsetIndex;
+	
+	void setup(const int& size);
+	
+	void storeSamples(double* newSamples);
+	void storeSamples(float* newSamples);
+
+		
+};
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DrumTimingLoader_OF/ofxAubioOnsetDetection/ofxAubioOnsetDetection.cpp	Mon Oct 01 22:24:32 2012 +0100
@@ -0,0 +1,906 @@
+/*
+ *  ofxAubioOnsetDetection.cpp
+ *  ofxOnsetDetection
+ *
+ *  Created by Andrew on 24/11/2011.
+ *  Copyright 2011 QMUL. All rights reserved.
+ *
+ */
+
+#include "ofxAubioOnsetDetection.h"
+
+
+//@ do: fix up reset - maybe think of using vectors
+
+//tracktypes:
+//there are three types
+//0 and 2 - the onset only type
+//1 - bass - ie.e uses aubio pitch
+//3 - harmonic - such as guitar represented by a chromagram following the onset
+
+//we calculate these by logging the time then filling up a window for the calculation.
+
+
+
+ofxAubioOnsetDetection::ofxAubioOnsetDetection(){
+	//onsetDetector = new AubioOnsetDetector();
+	onsetDetector.initialise();
+	
+	initialiseValues();
+	
+	printf("ofxAubioOnsetDetector made\n");
+	
+	amplitudeNumber = 256;//number of amplitudes shown on screen
+	maximumAubioPitch = 220;//max pitch shown inside window
+	minimumAubioPitch = 55.0/2.0;
+	trackType = 0;
+		
+
+	printf("max val on making is %f\n", onsetDetector.maximumDetectionValue);
+}
+
+
+ofxAubioOnsetDetection::~ofxAubioOnsetDetection(){
+//	delete onsetDetector;
+	printf("DELETE ONSET CALLED\n");
+//	delete qmOnsetDetector;
+}
+
+void ofxAubioOnsetDetection::initialiseValues(){
+	printf("ONSET DETECTOR INITIALISED\n");
+	//	useMedianOnsetDetection = true;
+	onsetIndex = 0;
+	frameCountIndex = 0;
+	playPositionFrames = 0;
+	playPosition = 0;
+	
+	screenWidth = ofGetWidth();
+	screenHeight = ofGetHeight();
+	
+	//each file has onset window to be displayed in
+	window.setToRelativeSize(0.1, 0.1, 0.8, 0.3);
+	//fullScreen.setToRelativeSize(0,0,1,1);
+	
+	drawParams.width = 5;
+	drawParams.maximumValue = 10;
+	drawParams.minimumValue = 0;
+	drawParams.difference = 10;
+	drawParams.scale_factor = 30;
+	
+	setDrawParams();
+}
+
+void ofxAubioOnsetDetection::reset(){
+	onsetIndex = 0;
+	frameCountIndex = 0;
+	
+	for (int i = 0;i < NUM_DETECTION_SAMPLES;i++){
+		onsetFunction[i] = 0;
+		medianOnsetFunction[i] = 0;
+		highSlopeOnsetFunction[i] = 0;
+		
+	}
+	
+	
+	highSlopeOnsetsFrames.clear();
+	highSlopeOnsetsMillis.clear();//The high slope onsets are the ones stored as chromaOnsets
+	//(i.e. have associated chroma and pitch to them)
+	chromaOnsets.clear();
+	
+	onsetDetector.resetValues();
+	
+	printf("Resetting the ofxAubioOnsetDetector\n");
+}
+
+
+void ofxAubioOnsetDetection::processFrame(double* frame, const int& n){
+	//bool onsetFound = false;
+	// aubio onset detector then processes current frame - returns bool true when new detection is output
+	//if buffer full and new result is processed (buffer is 1024 with hopsize 512 - can be set to other values)
+	
+	//for other class OnsetDetectionFunction : dfSample = qmonsetDetector.getDFsample(frame);
+		
+	//printf("process using double\n"); - NOT USING
+	
+	if (onsetDetector.processframe(frame, n)){
+
+		rawOnsetFunction[onsetIndex] = onsetDetector.rawDetectionValue;
+		medianOnsetFunction[onsetIndex] = onsetDetector.medianDetectionValue;
+//		aubioOnsetFunction[onsetIndex] = ??;
+		highSlopeOnsetFunction[onsetIndex] = onsetDetector.bestSlopeValue;
+		aubioLongTermAverage[onsetIndex] = onsetDetector.aubioLongTermAverage;
+		
+		//	outlet_float(x->detectionFunctionOutlet, x->onsetDetector.peakPickedDetectionValue);
+		
+		if (onsetDetector.aubioOnsetFound){
+			aubioOnsetRecorded[onsetIndex] = true;
+		}
+		else{
+			aubioOnsetRecorded[onsetIndex] = false;//anr chnage late on
+		}
+		
+		
+		if (onsetDetector.anrMedianProcessedOnsetFound){
+			onsetFound = true;
+			medianOnsetRecorded[onsetIndex] = true;
+		}else{
+			onsetFound = false;
+			medianOnsetRecorded[onsetIndex] = false;
+		}
+		
+		if (onsetDetector.anrBestSlopeOnset){
+			highSlopeOnsetRecorded[onsetIndex] = true;
+			highSlopeOnsetsFrames.push_back(frameCountIndex);
+			highSlopeOnsetsMillis.push_back(framesToMillis(frameCountIndex));
+			
+			printf("onset frame %i is time %f \n", frameCountIndex, framesToMillis(frameCountIndex));
+			
+			
+			chromaOnsetPtr = new ChromaOnset();
+			chromaOnsetPtr ->frameTime = frameCountIndex;
+			chromaOnsetPtr->millisTime = framesToMillis(frameCountIndex);
+			chromaOnsetPtr->onsetIndex = onsetIndex;
+			chromaOnsets.push_back(*chromaOnsetPtr);
+			
+			
+		}
+		else{
+			highSlopeOnsetRecorded[onsetIndex] = false;
+		}
+		
+		frameCountIndex++;//this one never loops
+		onsetIndex++;
+		if (onsetIndex == NUM_DETECTION_SAMPLES)
+			onsetIndex = 0;//this loops round
+		
+	}//end if new aubio onset detection result
+	
+	printf("N is %i\n", n);
+	float* tmpFrame;
+	vector<float> tmpFloatvector;
+	for (int i = 0;i < n;i++){
+		//tmpFrame[i] = frame[i];
+		tmpFloatvector.push_back(frame[i]);
+	}
+	
+	checkChromaAndPitch(&tmpFloatvector[0], n);
+	
+	
+ }
+
+void ofxAubioOnsetDetection::checkChromaAndPitch(float* tmpFrame, const int& n){
+	//new method for pitch
+	//calculate always
+	pitchDetector.addToBuffer(tmpFrame, n);
+	
+	//process frames into each onset's chromagram analyser
+	for (int i = 0;i < chromaOnsets.size();i++){
+		
+		//aubio pitch using yin
+		if (trackType == 1 && !chromaOnsets[i].aubioPitchFound ){//not yet done
+			
+			
+			//dont actually need to add this to the frame anymore!
+		//	chromaOnsets[i].onsetFrame.addToFrame(tmpFrame, n);//add to frame in the chromaOnset class
+		//	chromaOnsets[i].onsetFrame.frameCounter += n;
+			chromaOnsets[i].pitchFrameCounter += n;
+			
+			//used to use chromaOnsets[i].pitchFrameCounter
+		//	printf("adding to frame for onset %i at frametime %i\n", i, frameCountIndex);
+			if (chromaOnsets[i].pitchFrameCounter >= pitchDetector.bufsize){//enough to calculate yin with using aubio pitch detection
+				
+				printf("frame %i onset frame counter %i chromacounter %i\n", chromaOnsets[i].onsetFrame.sizeOfFrame, chromaOnsets[i].onsetFrame.frameCounter, chromaOnsets[i].pitchFrameCounter );
+				
+				
+				//float originalPitchMethod = pitchDetector.doPitchDetection(&chromaOnsets[i].onsetFrame.frame[0], pitchDetector.bufsize);
+				chromaOnsets[i].aubioPitch = pitchDetector.getPitch();//used to be originalPitchMethod;
+				
+				chromaOnsets[i].aubioPitchFound = true;
+				chromaOnsets[i].onsetFrame.deleteFrame();
+		//		printf("Aubio Pitch recieved for onset %i is %f\n", i, chromaOnsets[i].aubioPitch);
+				
+			
+				
+			
+			}
+				
+		}
+		
+		
+		//chroma
+		if (chromaOnsets[i].processFrame(tmpFrame, n) && trackType == 1){
+			//!= 3 : i.e. true when we dont need so we delete immediately
+			//printf("onset %i (frametime %i) chroma is newly calculated at frame %i\n", i, chromaOnsets[i].frameTime, frameCountIndex);
+			chromaOnsets[i].printInfo();
+			chromaOnsets[i].deleteChromagram();
+		}
+		
+	}//end for all onsets
+}
+
+void ofxAubioOnsetDetection::processFrame(float* frame, const int& n){
+	//bool onsetFound = false;
+	// aubio onset detector then processes current frame - returns bool true when new detection is output
+	//if buffer full and new result is processed (buffer is 1024 with hopsize 512 - can be set to other values)
+	
+	//for other class OnsetDetectionFunction : dfSample = qmonsetDetector.getDFsample(frame);
+	
+//	printf("process using float\n");
+	//THIS ONE IS USED!
+	
+	if (onsetDetector.processframe(frame, n)){
+		
+		rawOnsetFunction[onsetIndex] = onsetDetector.rawDetectionValue;
+		medianOnsetFunction[onsetIndex] = onsetDetector.medianDetectionValue;
+		//		aubioOnsetFunction[onsetIndex] = ??;
+		highSlopeOnsetFunction[onsetIndex] = onsetDetector.bestSlopeValue;
+		aubioLongTermAverage[onsetIndex] = onsetDetector.aubioLongTermAverage;
+		
+		//	outlet_float(x->detectionFunctionOutlet, x->onsetDetector.peakPickedDetectionValue);
+		
+		if (onsetDetector.aubioOnsetFound){
+			aubioOnsetRecorded[onsetIndex] = true;
+		}
+		else{
+			aubioOnsetRecorded[onsetIndex] = false;
+		}
+		
+		
+		if (onsetDetector.anrMedianProcessedOnsetFound){
+			onsetFound = true;
+			medianOnsetRecorded[onsetIndex] = true;
+		}else{
+			onsetFound = false;
+			medianOnsetRecorded[onsetIndex] = false;
+		}
+		
+		if (onsetDetector.anrBestSlopeOnset){
+			//do
+			highSlopeOnsetRecorded[onsetIndex] = true;
+			
+			printf("Frame index %i", frameCountIndex);
+			int exactOnsetIndex = precisionLocator.findExactOnset(&frame[0], n);//divide by 512.0 or bufferSize to get [0,1] value
+			printf("Exact index %i ", exactOnsetIndex);
+			
+			highSlopeOnsetsFrames.push_back(frameCountIndex);
+			float exactOffset = -1.0*framesToMillis((float)(n - exactOnsetIndex)/512.0);
+			
+			float millistime = framesToMillis(frameCountIndex);
+			float finalPreciseTime = millistime + exactOffset;//i.e. with offset due to energy analysis of frame
+			printf("exact offset %f millis %f final time %f\n", exactOffset, millistime, finalPreciseTime);
+			highSlopeOnsetsMillis.push_back(finalPreciseTime);
+			
+			
+			//did use the above but all info held in ChromaOnset class
+		
+			/*
+			 ChromaOnset c;
+			 c.frameTime = frameCountIndex;
+			 c.millisTime = framesToMillis(frameCountIndex);
+			 c.onsetIndex = onsetIndex;
+			 */
+			chromaOnsetPtr = new ChromaOnset();
+			chromaOnsetPtr->frameTime = frameCountIndex;
+			chromaOnsetPtr->onsetIndex = onsetIndex;
+			chromaOnsetPtr->millisTime = finalPreciseTime;//framesToMillis(frameCountIndex);
+			chromaOnsets.push_back(*chromaOnsetPtr);
+			
+		//	printf("frame %i is time %f \n", frameCountIndex, framesToMillis(frameCountIndex));
+		}
+		else{
+			highSlopeOnsetRecorded[onsetIndex] = false;
+		}
+		
+		frameCountIndex++;//this one never loops
+		onsetIndex++;
+		if (onsetIndex == NUM_DETECTION_SAMPLES)
+			onsetIndex = 0;//this loops round
+		
+	}//end if new aubio onset detection result
+	
+	//need to store these continually to help in location process
+	precisionLocator.storeSamples(&frame[0]);
+	
+	checkChromaAndPitch(frame, n);
+	
+}
+
+
+
+double ofxAubioOnsetDetection::framesToMillis(const double& frameCount){
+	return ((frameCount*onsetDetector.hopsize*1000.0)/44100.0);
+}
+
+
+void ofxAubioOnsetDetection::printOnsetList(){
+	printf("PRINT ONSET LIST\n");
+	for (int i = 0;i < chromaOnsets.size();i++){
+		printf("%i:", i);
+		chromaOnsets[i].printInfo();
+	}
+	printf("PRONT COMPLETE\n");
+}
+
+
+
+void ofxAubioOnsetDetection::drawOnsetDetection(){
+	
+	drawOnsetDetection(0, amplitudeNumber, window);
+//	ofDrawBitmapString("amp no"+ofToString(amplitudeNumber),40,40);
+	
+}//end draw onset fn
+
+void ofxAubioOnsetDetection::drawOnsetDetectionScrolling(){
+	
+	int startFrame = (int)(playPositionFrames/amplitudeNumber)* amplitudeNumber;
+	//setDrawParams();
+	
+	drawParams.windowStartFrame = startFrame;
+	
+	drawOutlineAndSetParams(window);
+	
+	if (trackType == 0 || trackType == 2)
+	drawOnsetDetection(startFrame, startFrame+amplitudeNumber, window);
+
+	setDrawParams(window);
+	drawChromaOnsetData(startFrame, startFrame+amplitudeNumber, window);
+	
+	drawScrollLine(startFrame, window);
+}//end draw onset fn
+
+
+void ofxAubioOnsetDetection::drawOutlineAndSetParams(const ofxWindowRegion& screenRegion){	
+	ofBackground(0);
+	setDrawParams(screenRegion);
+	ofSetColor(100,150,250);
+	screenRegion.drawOutline();
+}
+
+
+void ofxAubioOnsetDetection::drawOnsetDetection(int startIndex, int endIndex, const ofxWindowRegion& screenRegion){
+	
+
+	
+	int tmpIndex = onsetIndex;
+	float width = screenRegion.width / (float) amplitudeNumber;	
+	float maximumValue = onsetDetector.maximumDetectionValue;
+	float minimumValue = 0;//minimumDetectionFunction ;
+	float difference = maximumValue - minimumValue;
+	float scale_factor = screenRegion.height/ difference;
+	
+	endIndex = min(endIndex, startIndex+amplitudeNumber);
+	
+//	drawChromaOnsetData(startIndex, endIndex, screenRegion);
+	
+	for (int Xvalue = startIndex;Xvalue < endIndex; Xvalue++){
+		
+		int Xindex = Xvalue;//(endIndex - Xvalue) ;
+		
+		int previousIndex = (Xindex-1);
+		if (Xindex < 0){
+			Xindex += NUM_DETECTION_SAMPLES;
+			if (previousIndex < 0)
+				previousIndex += NUM_DETECTION_SAMPLES;
+		}
+		
+		//onsetFunction[] also processed	but not shown - Brossier's?
+		
+		
+		ofSetColor(155);//,200,55);
+		
+		
+		int previousXpos = (int) (screenRegion.x + (width*(Xvalue - startIndex - 1)));
+		int Xpos = (int) (screenRegion.x +(width*(Xvalue - startIndex)));		
+		
+		ofLine(previousXpos, screenRegion.y + screenRegion.height - (scale_factor*(rawOnsetFunction[previousIndex]- minimumValue)), 
+			   Xpos,  screenRegion.y + screenRegion.height - (scale_factor*(rawOnsetFunction[Xindex]- minimumValue)) );
+		
+		
+		
+		//median of Onset fn	
+		ofSetColor(0,105,0);		
+		ofLine(previousXpos, screenRegion.y + screenRegion.height - (scale_factor*(medianOnsetFunction[previousIndex]- minimumValue)), 
+			   Xpos,  screenRegion.y + screenRegion.height - (scale_factor*(medianOnsetFunction[Xindex]- minimumValue)) );
+		
+		
+		if (medianOnsetRecorded[Xindex] == true){
+			ofSetColor(0,255,0);
+			ofCircle(Xpos, screenRegion.y + screenRegion.height - (scale_factor*(medianOnsetFunction[Xindex]- minimumValue)) , 4);
+		}
+		
+		
+		ofSetColor(0,0,160);
+		ofLine(previousXpos, screenRegion.y + screenRegion.height - (scale_factor*(highSlopeOnsetFunction[previousIndex]- minimumValue)), 
+			   Xpos,  screenRegion.y + screenRegion.height - (scale_factor*(highSlopeOnsetFunction[Xindex]- minimumValue)) );
+		
+		//bright blue - slope based onsets
+		if (highSlopeOnsetRecorded[Xindex] == true){
+			ofSetColor(0,0,255);
+			ofCircle(Xpos, screenRegion.y + screenRegion.height - (scale_factor*(highSlopeOnsetFunction[Xindex]- minimumValue)) , 4);
+		}
+		
+		//long term average in dull grey
+		ofSetColor(100);
+		ofLine(previousXpos, screenRegion.y + screenRegion.height - (scale_factor*(aubioLongTermAverage[previousIndex]- minimumValue)), 
+			   Xpos,  screenRegion.y + screenRegion.height - (scale_factor*(aubioLongTermAverage[Xindex]- minimumValue)) );
+		
+		
+		ofSetColor(255,100,0);
+		
+	}//end for Xvalue (across the recent observations of osc data)
+	
+	
+	//some axis stuff deleted
+	
+	
+//	string tmpInfoString = "(windowed)max val "+ofToString(onsetDetector.maximumDetectionValue,2);
+//	tmpInfoString += " diff "+ofToString(difference);	
+//	ofDrawBitmapString(tmpInfoString, 100,200);
+	
+}//end draw onset fn
+
+void ofxAubioOnsetDetection::drawScrollLine(const int& startIndex, const ofxWindowRegion& screenRegion){
+	//play position
+	float width = screenRegion.width / (float) amplitudeNumber;	
+	ofSetColor(255,255,255);
+	playPositionFrames = playPosition * frameCountIndex;
+	ofLine(screenRegion.x + width*(playPositionFrames-startIndex), screenRegion.y , screenRegion.x + width*(playPositionFrames-startIndex), screenRegion.y + screenRegion.height);
+}
+
+
+void ofxAubioOnsetDetection::drawChromaOnsetData(const int& startIndex, const int& endIndex, const ofxWindowRegion& screenRegion){
+	
+	int chromaIndex = 0;//chromaOnsets.size()/2;
+	while (chromaIndex > 0 && chromaOnsets[chromaIndex].onsetIndex > startIndex)
+		chromaIndex--;
+	
+	while (chromaIndex < chromaOnsets.size() && chromaOnsets[chromaIndex].onsetIndex < startIndex)
+		chromaIndex++;
+	
+	switch (trackType) {
+		case 1:
+			drawPitchLines(chromaIndex, endIndex, screenRegion);
+			break;
+		case 3:
+				drawChromaStripes(chromaIndex, endIndex, screenRegion);
+			break;
+		case 0:
+			ofSetColor(100,0,0);
+			drawOnsetStripes(chromaIndex, endIndex, screenRegion);
+			break;
+		case 2:
+			ofSetColor(100,100,0);
+			drawOnsetStripes(chromaIndex, endIndex, screenRegion);
+			break;	
+	}//end switch
+	
+
+
+}//end draw chroma
+
+void ofxAubioOnsetDetection::drawOnsetStripes(int chromaIndex, const int& frameEndIndex, const ofxWindowRegion& screenRegion){
+			
+			
+	while (chromaIndex < chromaOnsets.size() && chromaOnsets[chromaIndex].chromaCalculated && chromaOnsets[chromaIndex].onsetIndex < frameEndIndex) {
+				
+				//ofSetColor(255,100,255);
+				
+				int Xindex = chromaOnsets[chromaIndex].onsetIndex;
+				int Xvalue = frameEndIndex - Xindex;
+				
+		//		for (int j = 0;j < 12;j++){
+					
+				//	if (!chromaOnsets[chromaIndex].matched)
+				//		ofSetColor(0,0,255*chromaOnsets[chromaIndex].chromaValues[11-j], 20);
+				//	else
+				//		ofSetColor(255*chromaOnsets[chromaIndex].chromaValues[11-j],0,0, 20);
+					
+					ofRect(screenRegion.x + drawParams.width*(amplitudeNumber - Xvalue), screenRegion.y, 4, screenRegion.height);
+		//		}
+				
+		//		ofCircle(screenRegion.x + drawParams.width*(amplitudeNumber - Xvalue), screenRegion.y + screenRegion.height - (drawParams.scale_factor*(highSlopeOnsetFunction[Xindex]- drawParams.minimumValue)) , 4);
+				
+				chromaIndex++;
+			}
+			
+}//end draw chroma		
+		
+void ofxAubioOnsetDetection::drawChromaStripes(int chromaIndex, const int& frameEndIndex, const ofxWindowRegion& screenRegion){
+	
+	
+	while (chromaIndex < chromaOnsets.size() && chromaOnsets[chromaIndex].chromaCalculated && chromaOnsets[chromaIndex].onsetIndex < frameEndIndex) {
+		
+		ofSetColor(255,100,255);
+		
+		int Xindex = chromaOnsets[chromaIndex].onsetIndex;
+		int Xvalue = frameEndIndex - Xindex;
+		
+		for (int j = 0;j < 12;j++){
+			
+			if (!chromaOnsets[chromaIndex].matched)
+				ofSetColor(0,0,255*chromaOnsets[chromaIndex].chromaValues[11-j], 20);
+			else
+				ofSetColor(255*chromaOnsets[chromaIndex].chromaValues[11-j],0,0, 20);
+			
+			ofRect(screenRegion.x + drawParams.width*(amplitudeNumber - Xvalue), screenRegion.y + screenRegion.height*j/12.0, 20, screenRegion.height/12);
+		}
+		
+		ofCircle(screenRegion.x + drawParams.width*(amplitudeNumber - Xvalue), screenRegion.y + screenRegion.height - (drawParams.scale_factor*(highSlopeOnsetFunction[Xindex]- drawParams.minimumValue)) , 4);
+		
+		chromaIndex++;
+	}
+	
+}//end draw chroma
+
+void ofxAubioOnsetDetection::drawPitchLines(int chromaIndex, const int& frameEndIndex, const ofxWindowRegion& screenRegion){
+	
+	ofSetLineWidth(2);
+	
+	while (chromaIndex < chromaOnsets.size() && chromaOnsets[chromaIndex].chromaCalculated && chromaOnsets[chromaIndex].onsetIndex < frameEndIndex) {
+		
+		int Xindex = chromaOnsets[chromaIndex].onsetIndex;
+		int Xvalue = frameEndIndex - Xindex;
+		
+		//now do pitch in log freq
+		float heightFactor = 0;
+		if (chromaOnsets[chromaIndex].aubioPitch > 0)
+			heightFactor = log(chromaOnsets[chromaIndex].aubioPitch/minimumAubioPitch) / log(maximumAubioPitch/minimumAubioPitch);
+		heightFactor = 1 - heightFactor;
+		//red lines for freq
+		ofSetColor(255,0,0);
+		//ofSetLineWidth(8);
+		ofLine(screenRegion.x + drawParams.width*(amplitudeNumber - Xvalue), screenRegion.y + screenRegion.height*heightFactor, 
+			   screenRegion.x + drawParams.width*(amplitudeNumber - Xvalue) + 50, screenRegion.y + screenRegion.height*heightFactor);
+		
+		ofSetColor(255,0,255);
+		ofDrawBitmapString(ofToString(chromaOnsets[chromaIndex].aubioPitch, 1) , screenRegion.x + drawParams.width*(amplitudeNumber - Xvalue) + 4, screenRegion.y + screenRegion.height*heightFactor - 4);
+		chromaIndex++;
+	}
+	
+	ofSetLineWidth(1);
+	
+	
+}//end draw pitch lines
+
+void ofxAubioOnsetDetection::setDrawParams(){
+	screenWidth = ofGetWidth();
+	screenHeight = ofGetHeight();//justin case
+	
+	drawParams.width = screenWidth / (float) amplitudeNumber;	
+	drawParams.maximumValue = onsetDetector.maximumDetectionValue;
+	drawParams.minimumValue = 0;//minimumDetectionFunction ;
+	drawParams.difference = drawParams.maximumValue - drawParams.minimumValue;
+	drawParams.scale_factor = screenHeight/ drawParams.difference;
+	
+}
+
+void ofxAubioOnsetDetection::setDrawParams(const ofxWindowRegion& screenRegion){
+	
+	drawParams.width = screenRegion.width / (float) amplitudeNumber;	
+	drawParams.maximumValue = onsetDetector.maximumDetectionValue;
+	drawParams.minimumValue = 0;//minimumDetectionFunction ;
+	drawParams.difference = drawParams.maximumValue - drawParams.minimumValue;
+	drawParams.scale_factor = screenRegion.height/ drawParams.difference;
+}
+
+
+void ofxAubioOnsetDetection::windowResized(const int& w, const int& h){
+	screenWidth = ofGetWidth();
+	screenHeight = ofGetHeight();
+	window.resized(w, h);
+	fullScreen.resized(w, h);
+}
+
+
+void ofxAubioOnsetDetection::printChromaInfo(){
+	for (int i = 0;i < chromaOnsets.size();i++)
+		chromaOnsets[i].printInfo();
+	
+	printf("max value on printing is %f\n", onsetDetector.maximumDetectionValue);
+}
+
+void ofxAubioOnsetDetection::aubioOnsetDetect_energy(){
+	onsetDetector.onsetclass_energy();
+	printf("Energy based onset detection now used by aubioOnsetDetect~.");
+}
+
+void ofxAubioOnsetDetection::aubioOnsetDetect_hfc(){
+	/** High Frequency Content onset detection function
+	 
+	 This method computes the High Frequency Content (HFC) of the input spectral
+	 frame. The resulting function is efficient at detecting percussive onsets.
+	 
+	 Paul Masri. Computer modeling of Sound for Transformation and Synthesis of
+	 Musical Signal. PhD dissertation, University of Bristol, UK, 1996.*/
+
+	onsetDetector.onsetclass_hfc();
+	printf("High Frequency Content (Masri '96) detection now used by aubioOnsetDetect~.");
+}
+
+
+void ofxAubioOnsetDetection::aubioOnsetDetect_complex(){
+	//Complex Domain Method onset detection function 
+	//Christopher Duxbury, Mike E. Davies, and Mark B. Sandler. Complex domain
+	//onset detection for musical signals. In Proceedings of the Digital Audio
+	//Effects Conference, DAFx-03, pages 90-93, London, UK, 2003.
+	onsetDetector.onsetclass_complex();
+	printf("Complex domain onset detection (Duxbury et al., DaFx '03) now used by aubioOnsetDetect~.");
+	
+}
+
+void ofxAubioOnsetDetection::aubioOnsetDetect_phase(){
+	/** Phase Based Method onset detection function 
+	 
+	 Juan-Pablo Bello, Mike P. Davies, and Mark B. Sandler. Phase-based note onset
+	 detection for music signals. In Proceedings of the IEEE International
+	 Conference on Acoustics Speech and Signal Processing, pages 441­444,
+	 Hong-Kong, 2003.*/
+
+	onsetDetector.onsetclass_phase();
+	printf("Phase-based detection (Bello et al., IEEE '03) now used by aubioOnsetDetect~.");
+}
+
+void ofxAubioOnsetDetection::aubioOnsetDetect_specdiff(){
+	/* Spectral difference method onset detection function 
+	 Jonhatan Foote and Shingo Uchihashi. The beat spectrum: a new approach to
+	 rhythm analysis. In IEEE International Conference on Multimedia and Expo
+	 (ICME 2001), pages 881­884, Tokyo, Japan, August 2001.
+	 */
+	//aubio_onsetdetection_type
+	//aubio_onsetdetection_free (x->o);
+	onsetDetector.onsetclass_specdiff();
+	printf("Spectral Difference (Foote and Shingo Uchihashi, ICME '01) detection now used by aubioOnsetDetect~.");
+	
+	
+}
+
+void ofxAubioOnsetDetection::aubioOnsetDetect_kl(){
+	//aubio_onsetdetection_type
+	//aubio_onsetdetection_free (x->o);
+	/** Kullback-Liebler onset detection function 
+	 
+	 Stephen Hainsworth and Malcom Macleod. Onset detection in music audio
+	 signals. In Proceedings of the International Computer Music Conference
+	 (ICMC), Singapore, 2003.
+	 */
+	
+	onsetDetector.onsetclass_kl();
+	printf("Kullback-Liebler (Hainsworth and McLeod, ICMC '03) detection now used by aubioOnsetDetect~.");
+}
+
+void ofxAubioOnsetDetection::aubioOnsetDetect_mkl(){
+	/** Modified Kullback-Liebler onset detection function 
+	 
+	 Paul Brossier, ``Automatic annotation of musical audio for interactive
+	 systems'', Chapter 2, Temporal segmentation, PhD thesis, Centre for Digital
+	 music, Queen Mary University of London, London, UK, 2003.*/		
+	onsetDetector.onsetclass_mkl();
+	printf("Modified Kullback-Liebler (Brossier, PhD thesis '03) detection now used by aubioOnsetDetect~.");
+}
+
+
+/*
+ axis stuff end
+ //label y axis
+ int axisHeight, stepSize;
+ ofSetColor(255,255,255);
+ stepSize = 1000;
+ 
+ while((difference / stepSize) < 3)
+ stepSize /= 2;
+ 
+ while ((difference / stepSize) > 7)// maximum 6 numbers to display
+ stepSize *= 2;
+ 
+ 
+ for (axisHeight = 0; axisHeight < maximumDetectionFunction; axisHeight += stepSize){
+ ofDrawBitmapString( ofToString((int)axisHeight), ofGetWidth()-50,
+ (int) ((TEXT_HEIGHT/2) +(screenHeight - (scale_factor*(axisHeight- minimumValue)))) );
+ }
+ 
+ for (axisHeight = max(0, (int)minimumDetectionFunction); axisHeight > min(0, (int)minimumDetectionFunction); axisHeight -= stepSize){
+ ofDrawBitmapString( ofToString((int)axisHeight), ofGetWidth()-50,
+ (int) ((TEXT_HEIGHT/2) +(screenHeight - (scale_factor*(axisHeight- minimumValue)))) );
+ }
+ 
+ //label x axis
+ stepSize = 20;//need to make sure not too many of these:
+ 
+ while((amplitudeNumber / stepSize) < 4)
+ stepSize /= 2;
+ 
+ while ((amplitudeNumber / stepSize) > 8)
+ stepSize *= 2;
+ 
+ int labelIndex = onsetIndex - (onsetIndex % stepSize);
+ for (int y = labelIndex; y > onsetIndex - amplitudeNumber; y -= stepSize){
+ ofDrawBitmapString( ofToString((int)y), (int) (width*(amplitudeNumber - (onsetIndex - y))), (int) ((TEXT_HEIGHT+2) + (screenHeight - (scale_factor*(0 - minimumValue)))) );
+ }
+ */
+
+
+
+
+
+
+void ofxAubioOnsetDetection::drawOnsetDetection(int startIndex, int endIndex){
+	ofBackground(0);
+	setDrawParams();
+	
+	int tmpIndex = onsetIndex;
+	float width = screenWidth / (float) amplitudeNumber;	
+	float maximumValue = onsetDetector.maximumDetectionValue;
+	float minimumValue = 0;//minimumDetectionFunction ;
+	float difference = maximumValue - minimumValue;
+	float scale_factor = screenHeight/ difference;
+	
+	//draw axis
+	ofSetColor(255,255,255);
+	ofDrawBitmapString(ofToString((startIndex)), 20, 20);
+	
+	ofLine(0, screenHeight - (scale_factor*(0 - minimumValue)), 
+		   (int) (width*(amplitudeNumber)),  screenHeight - (scale_factor*(0 - minimumValue)) );
+	
+	
+	
+	endIndex = min(endIndex, startIndex+amplitudeNumber);
+	
+	drawChromaOnsetData(startIndex, endIndex);
+	
+	for (int Xvalue = startIndex;Xvalue < endIndex; Xvalue++){
+		
+		int Xindex = Xvalue;//(endIndex - Xvalue) ;
+		
+		int previousIndex = (Xindex-1);
+		if (Xindex < 0){
+			Xindex += NUM_DETECTION_SAMPLES;
+			if (previousIndex < 0)
+				previousIndex += NUM_DETECTION_SAMPLES;
+		}
+		
+		//onsetFunction[] also processed	but not shown - Brossier's?
+		
+		
+		ofSetColor(155);//,200,55);
+		
+		
+		int previousXpos = (int) (width*(Xvalue - startIndex - 1));
+		int Xpos = (int) (width*(Xvalue - startIndex));		
+		
+		ofLine(previousXpos, screenHeight - (scale_factor*(rawOnsetFunction[previousIndex]- minimumValue)), 
+			   Xpos,  screenHeight - (scale_factor*(rawOnsetFunction[Xindex]- minimumValue)) );
+		
+		
+		
+		//median of Onset fn	
+		ofSetColor(0,105,0);		
+		ofLine(previousXpos, screenHeight - (scale_factor*(medianOnsetFunction[previousIndex]- minimumValue)), 
+			   Xpos,  screenHeight - (scale_factor*(medianOnsetFunction[Xindex]- minimumValue)) );
+		
+		
+		if (medianOnsetRecorded[Xindex] == true){
+			ofSetColor(0,255,0);
+			ofCircle(Xpos, screenHeight - (scale_factor*(medianOnsetFunction[Xindex]- minimumValue)) , 4);
+		}
+		
+		
+		ofSetColor(0,0,160);
+		ofLine(previousXpos, screenHeight - (scale_factor*(highSlopeOnsetFunction[previousIndex]- minimumValue)), 
+			   Xpos,  screenHeight - (scale_factor*(highSlopeOnsetFunction[Xindex]- minimumValue)) );
+		
+		//bright blue - slope based onsets
+		if (highSlopeOnsetRecorded[Xindex] == true){
+			ofSetColor(0,0,255);
+			ofCircle(Xpos, screenHeight - (scale_factor*(highSlopeOnsetFunction[Xindex]- minimumValue)) , 4);
+		}
+		
+		//long term average in dull grey
+		ofSetColor(100);
+		ofLine(previousXpos, screenHeight - (scale_factor*(aubioLongTermAverage[previousIndex]- minimumValue)), 
+			   Xpos,  screenHeight - (scale_factor*(aubioLongTermAverage[Xindex]- minimumValue)) );
+		
+		
+		ofSetColor(255,100,0);
+		
+	}//end for Xvalue (across the recent observations of osc data)
+	
+	//axis stuff at end
+	
+	//play position
+	ofSetColor(255,255,255);
+	playPositionFrames = playPosition * frameCountIndex;
+	ofLine(width*(playPositionFrames-startIndex), 0, width*(playPositionFrames-startIndex), screenHeight);
+	
+	
+	//ofDrawBitmapString("max val "+ofToString(onsetDetector.maximumDetectionValue,2), 100,200);
+}//end draw onset fn
+
+
+
+void ofxAubioOnsetDetection::drawChromaOnsetData(const int& startIndex, const int& endIndex){
+	
+	int chromaIndex = 0;//chromaOnsets.size()/2;
+	while (chromaIndex > 0 && chromaOnsets[chromaIndex].onsetIndex > startIndex)
+		chromaIndex--;
+	
+	while (chromaIndex < chromaOnsets.size() && chromaOnsets[chromaIndex].onsetIndex < startIndex)
+		chromaIndex++;
+	
+	
+	while (chromaIndex < chromaOnsets.size() && chromaOnsets[chromaIndex].chromaCalculated && chromaOnsets[chromaIndex].onsetIndex < endIndex) {
+		
+		ofSetColor(255,100,255);
+		
+		int Xindex = chromaOnsets[chromaIndex].onsetIndex;
+		int Xvalue = endIndex - Xindex;
+		
+		for (int j = 0;j < 12;j++){
+			ofSetColor(0,0,255*chromaOnsets[chromaIndex].chromaValues[11-j], 20);
+			ofRect(drawParams.width*(amplitudeNumber - Xvalue), screenHeight*j/12.0, 6, screenHeight/12);
+		}
+		
+		ofCircle(drawParams.width*(amplitudeNumber - Xvalue), screenHeight - (drawParams.scale_factor*(highSlopeOnsetFunction[Xindex]- drawParams.minimumValue)) , 4);
+		
+		//now do pitch in log freq
+		float heightFactor = 0;
+		if (chromaOnsets[chromaIndex].aubioPitch > 0)
+			heightFactor = log(chromaOnsets[chromaIndex].aubioPitch) / log(maximumAubioPitch);
+		heightFactor = 1 - heightFactor;
+		ofSetColor(255,0,0);
+		//ofSetLineWidth(8);
+		ofLine(drawParams.width*(amplitudeNumber - Xvalue), heightFactor*screenHeight, drawParams.width*(amplitudeNumber - Xvalue) + 50, heightFactor*screenHeight);
+		
+		ofSetColor(0,0,255);
+		ofDrawBitmapString(ofToString(chromaOnsets[chromaIndex].aubioPitch, 1) , drawParams.width*(amplitudeNumber - Xvalue), heightFactor*screenHeight-4);
+		chromaIndex++;
+	}
+	
+	ofSetColor(255,255,235);
+	ofDrawBitmapString("full drawparams width "+ofToString(drawParams.width), 100, 100);
+	ofDrawBitmapString("full x"+ofToString(fullScreen.x)+" width "+ofToString(fullScreen.width), 100, 120);
+}//end draw chroma
+
+
+
+/*
+ DRAW CHROMA JUNK
+ while (chromaIndex < chromaOnsets.size() && chromaOnsets[chromaIndex].chromaCalculated && chromaOnsets[chromaIndex].onsetIndex < endIndex) {
+ 
+ ofSetColor(255,100,255);
+ 
+ int Xindex = chromaOnsets[chromaIndex].onsetIndex;
+ int Xvalue = endIndex - Xindex;
+ 
+ for (int j = 0;j < 12;j++){
+ 
+ if (!chromaOnsets[chromaIndex].matched)
+ ofSetColor(0,0,255*chromaOnsets[chromaIndex].chromaValues[11-j], 20);
+ else
+ ofSetColor(255*chromaOnsets[chromaIndex].chromaValues[11-j],0,0, 20);
+ 
+ ofRect(screenRegion.x + drawParams.width*(amplitudeNumber - Xvalue), screenRegion.y + screenRegion.height*j/12.0, 6, screenRegion.height/12);
+ }
+ 
+ ofCircle(screenRegion.x + drawParams.width*(amplitudeNumber - Xvalue), screenRegion.y + screenRegion.height - (drawParams.scale_factor*(highSlopeOnsetFunction[Xindex]- drawParams.minimumValue)) , 4);
+ 
+ //now do pitch in log freq
+ float heightFactor = 0;
+ if (chromaOnsets[chromaIndex].aubioPitch > 0)
+ heightFactor = log(chromaOnsets[chromaIndex].aubioPitch) / log(maximumAubioPitch);
+ heightFactor = 1 - heightFactor;
+ //red lines for freq
+ ofSetColor(255,0,0);
+ //ofSetLineWidth(8);
+ ofLine(screenRegion.x + drawParams.width*(amplitudeNumber - Xvalue), screenRegion.y + screenRegion.height*heightFactor, 
+ screenRegion.x + drawParams.width*(amplitudeNumber - Xvalue) + 50, screenRegion.y + screenRegion.height*heightFactor);
+ 
+ ofSetColor(0,0,255);
+ ofDrawBitmapString(ofToString(chromaOnsets[chromaIndex].aubioPitch, 1) , screenRegion.x + drawParams.width*(amplitudeNumber - Xvalue) + 4, screenRegion.y + screenRegion.height*heightFactor - 4);
+ chromaIndex++;
+ }
+ */
+
+//	ofSetColor(255,255,235);
+//	ofDrawBitmapString("windowed drawparams width "+ofToString(drawParams.width), 100, 100);
+//	ofDrawBitmapString("windowed x"+ofToString(screenRegion.x)+" width "+ofToString(screenRegion.width), 100, 120);
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DrumTimingLoader_OF/ofxAubioOnsetDetection/ofxAubioOnsetDetection.h	Mon Oct 01 22:24:32 2012 +0100
@@ -0,0 +1,146 @@
+/*
+ *  ofxAubioOnsetDetection.h
+ *  ofxOnsetDetection
+ *
+ *  Created by Andrew Robertson on 24/11/2011.
+ *  Copyright 2011 Centre for Digital Music, QMUL. All rights reserved.
+ *
+ */
+
+
+#ifndef OFX_AUBDIO_ONSET_DETECTION_H_
+#define OFX_AUBIO_ONSET_DETECTION_H_
+
+#pragma once
+
+#define NUM_DETECTION_SAMPLES 24000
+#define TEXT_HEIGHT 16
+
+#include "ofMain.h"
+#include "AubioOnsetDetector.h"
+#include "ChromaOnset.h"
+#include "ofxWindowRegion.h"
+#include "AubioPitch.h"
+#include "Chromagram.h"
+#include "PreciseOnsetLocator.h"
+
+//#include "OnsetDetectionFunction.h"
+
+//this builds on aubioOsetDetector class
+//but that doesn't store any values
+//for drawing, perhpas we need to
+
+
+struct DrawOnsetParameters{
+	float width;//= screenWidth / (float) amplitudeNumber;	
+	float maximumValue;// = onsetDetector->maximumDetectionValue;
+	float minimumValue;// = 0;//minimumDetectionFunction ;
+	float difference;// = maximumValue - minimumValue;
+	float scale_factor;// = screenHeight/ difference;
+	int windowStartFrame;
+};
+
+class ofxAubioOnsetDetection{
+public:
+	ofxAubioOnsetDetection();
+	~ofxAubioOnsetDetection();
+	AubioOnsetDetector	onsetDetector;
+	//OnsetDetectionFunction *qmOnsetDetector;
+	
+	void reset();
+	void initialiseValues();
+	double dfSample;
+	
+	void processFrame(double* frame, const int& n);
+	void processFrame(float* frame, const int& n);
+	
+	void printOnsetList();//print the vector of chromaOnset times - onsets with timing and chroma info
+	
+	//switch between different onset methods
+	void aubioOnsetDetect_energy();
+	void aubioOnsetDetect_complex();
+	void aubioOnsetDetect_kl();
+	void aubioOnsetDetect_hfc();
+	void aubioOnsetDetect_specdiff();
+	void aubioOnsetDetect_phase();//this is pretty bad I think
+	void aubioOnsetDetect_mkl();
+
+	void drawOnsetDetection();
+	void drawOnsetDetectionScrolling();//float of how far thru file - e.g 0.6 60% through
+	void drawScrollLine(const int& startIndex, const ofxWindowRegion& screenRegion);
+	
+	void drawOnsetDetection(int startIndex, int endIndex);
+	void drawOnsetDetection(int startIndex, int endIndex, const ofxWindowRegion& screenRegion);//overloaded
+	int onsetIndex, frameCountIndex;
+	
+	
+	float			onsetFunction[NUM_DETECTION_SAMPLES];
+	bool			aubioOnsetRecorded[NUM_DETECTION_SAMPLES];
+	
+	float			rawOnsetFunction[NUM_DETECTION_SAMPLES];		
+	bool			highSlopeOnsetRecorded[NUM_DETECTION_SAMPLES];//true/false for onset
+
+	float			medianOnsetFunction[NUM_DETECTION_SAMPLES];		
+	bool			medianOnsetRecorded[NUM_DETECTION_SAMPLES];//true/false for onset
+	
+	float			highSlopeOnsetFunction[NUM_DETECTION_SAMPLES];
+	
+	float			aubioLongTermAverage[NUM_DETECTION_SAMPLES];
+	
+	float			maximumDetectionFunction;
+	float			minimumDetectionFunction;		
+	
+	float			maxValue;
+	
+	int				amplitudeNumber;
+	bool			onsetFound;
+	
+	typedef std::vector<double> DoubleVector;
+	DoubleVector highSlopeOnsetsFrames;
+	DoubleVector highSlopeOnsetsMillis;
+	double framesToMillis(const double& frameCount);
+	double playPosition, playPositionFrames;//play position is between 0 and 1 of the file 
+	
+	typedef std::vector<ChromaOnset> ChromaOnsetVector;
+	ChromaOnsetVector chromaOnsets;
+	
+	int trackType;
+	
+	void printChromaInfo();
+	
+	void checkChromaAndPitch(float* tmpFrame, const int& n);
+	
+	void drawChromaOnsetData(const int& startIndex, const int& endIndex);
+	void drawChromaOnsetData(const int& startIndex, const int& endIndex, const ofxWindowRegion& screenRegion);
+	
+	void drawOnsetStripes(int chromaIndex, const int& frameEndIndex, const ofxWindowRegion& screenRegion);
+	void drawChromaStripes(int chromaIndex, const int& frameEndIndex, const ofxWindowRegion& screenRegion);
+	void drawPitchLines(int chromaIndex, const int& frameEndIndex, const ofxWindowRegion& screenRegion);
+	
+	
+	DrawOnsetParameters drawParams ;
+	void setDrawParams();
+	void setDrawParams(const ofxWindowRegion& screenRegion);
+	void drawOutlineAndSetParams(const ofxWindowRegion& screenRegion);
+	
+	ChromaOnset* chromaOnsetPtr;
+	
+	AubioPitch pitchDetector;
+	//AubioPitch pitchDetectorTwo;
+	float	maximumAubioPitch, minimumAubioPitch;
+	
+	//basic screen stuff
+	float screenWidth;//= ofGetWidth();
+	float screenHeight;// = ofGetHeight();
+	void windowResized(const int& w, const int& h);
+	
+	ofxWindowRegion window;
+	ofxWindowRegion fullScreen;
+	
+	
+	PreciseOnsetLocator precisionLocator;
+
+};
+
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DrumTimingLoader_OF/ofxAudioFileLoader/AudioAnalysis.cpp	Mon Oct 01 22:24:32 2012 +0100
@@ -0,0 +1,226 @@
+/*
+ *  AudioAnalysis.cpp
+ *  audioFileLoader4
+ *
+ *  Created by Andrew on 14/08/2011.
+ *  Copyright 2011 QMUL. All rights reserved.
+ *
+ */
+
+#include "AudioAnalysis.h"
+
+
+AudioAnalysis::AudioAnalysis(){
+//	chromoGramm.initialise(FRAMESIZE,2048);
+
+	scrollWidth = 1600;
+	
+}
+
+
+
+void AudioAnalysis::drawEnergyVectorFromPointer(){
+	DoubleVector* energyVec;
+	energyVec = &energyVector;
+	//xxx above
+	
+	ofSetColor(0xFF0066);
+	float screenHeight = ofGetHeight() ;
+	float screenWidth = ofGetWidth();  
+	float heightFactor = 8;
+	int i, j, startingFrame;
+	startingFrame = currentPlayingFrame / scrollWidth;//i.e. number of scroll widths in
+	startingFrame *= scrollWidth;
+	
+	for (i = 0; i < scrollWidth - 1; i++){
+		j = i + startingFrame;
+		if (j < (*energyVec).size())
+			ofLine(i*screenWidth/scrollWidth, screenHeight - ((*energyVec)[j]*screenHeight/heightFactor),
+				   screenWidth*(i+1)/scrollWidth, screenHeight - ((*energyVec)[j+1]*screenHeight/heightFactor));
+		
+	}
+}
+
+void AudioAnalysis::drawSpectralDifference(){
+	DoubleMatrix* dMatrix;
+	dMatrix = &chromaMatrix;
+	//get rid of these!
+	
+	int matrixSize = (*dMatrix).size();
+	if (matrixSize > 0){
+		
+		float screenHeight = ofGetHeight() ;
+		float screenWidth = ofGetWidth();
+		float heightFactor = 8;
+		double difference;
+		int i, j, startingFrame;
+		startingFrame = currentPlayingFrame / scrollWidth;//i.e. number of scroll widths in
+		startingFrame *= scrollWidth;//starting frame in terms of energy frames
+		startingFrame /= CHROMA_CONVERSION_FACTOR; //in terms of chroma frames
+		
+		float chromoLength = scrollWidth/CHROMA_CONVERSION_FACTOR;
+		for (i = 1; i < chromoLength; i++){//changed to add 1
+			j = i + startingFrame;
+			for (int y = 0;y < 12;y++){			
+				
+				if (j < matrixSize)
+					difference = (*dMatrix)[j][11-y] - (*dMatrix)[j-1][11-y];
+				else 
+					difference = 0;
+				
+				if (difference < 0)
+					difference = 0;//half wave rectify
+				
+				ofSetColor(0,0,255 * difference);//, 0;
+				ofRect(i*screenWidth/chromoLength,y*screenHeight/12,screenWidth/chromoLength,screenHeight/12);
+			}//end y
+		}//end i
+		
+	}///end if matrix has content
+	else{
+		printf("Error - please load audio first");
+	}
+	
+}
+
+
+/*
+void testApp::initialiseVariables(){
+	
+	energyIndex = 0;
+	//	frameIndex = 0;
+	chromaIndex = 0;
+	chromoGramm.initialise(FRAMESIZE,2048);//framesize 512 and hopsize 2048
+}
+
+
+//--------------------------------------------------------------
+void testApp::draw(){
+	switch (screenToDraw){
+		case 0:
+			if (drawSpectralDifferenceFunction)
+				drawSpectralDifference(&chromaMatrix);
+			else
+				drawDoubleMatrix(&chromaMatrix);
+			
+			drawEnergyVectorFromPointer(&firstEnergyVector);
+			break;
+		case 1:
+			//	audioHolder.drawAudioVectorMillis(1000, 1000+audioScale);
+			audioHolder.drawAudioVectorSamples(audioHolder.playPosition, audioHolder.playPosition+audioHolder.audioScaleSamples);
+			break;
+	}
+	
+	
+	
+	//ofSetColor(255,0,0);
+	//drawEnergyVectorFromPointer(&audioVector);
+	
+	ofSetColor(0xFFFFFF);
+	ofLine(audioPosition*width, 0, audioPosition*width, height);
+	
+	ofDrawBitmapString(soundFileName,80,480);
+	
+}
+
+
+void testApp::drawEnergyVectorFromPointer(DoubleVector* energyVec){
+	
+	ofSetColor(0xFF0066);
+	float screenHeight = ofGetHeight() ;
+	float screenWidth = ofGetWidth();  
+	float heightFactor = 8;
+	int i, j, startingFrame;
+	startingFrame = currentPlayingFrame / scrollWidth;//i.e. number of scroll widths in
+	startingFrame *= scrollWidth;
+	
+	for (i = 0; i < scrollWidth - 1; i++){
+		j = i + startingFrame;
+		if (j < (*energyVec).size())
+			ofLine(i*screenWidth/scrollWidth, screenHeight - ((*energyVec)[j]*screenHeight/heightFactor),
+				   screenWidth*(i+1)/scrollWidth, screenHeight - ((*energyVec)[j+1]*screenHeight/heightFactor));
+		
+	}
+}
+
+void testApp::drawSpectralDifference(DoubleMatrix* dMatrix){
+	int matrixSize = (*dMatrix).size();
+	if (matrixSize > 0){
+		
+		float screenHeight = ofGetHeight() ;
+		float screenWidth = ofGetWidth();
+		float heightFactor = 8;
+		double difference;
+		int i, j, startingFrame;
+		startingFrame = currentPlayingFrame / scrollWidth;//i.e. number of scroll widths in
+		startingFrame *= scrollWidth;//starting frame in terms of energy frames
+		startingFrame /= CHROMA_CONVERSION_FACTOR; //in terms of chroma frames
+		
+		float chromoLength = scrollWidth/CHROMA_CONVERSION_FACTOR;
+		for (i = 1; i < chromoLength; i++){//changed to add 1
+			j = i + startingFrame;
+			for (int y = 0;y < 12;y++){			
+				
+				if (j < matrixSize)
+					difference = (*dMatrix)[j][11-y] - (*dMatrix)[j-1][11-y];
+				else 
+					difference = 0;
+				
+				if (difference < 0)
+					difference = 0;//half wave rectify
+				
+				ofSetColor(0,0,255 * difference);//, 0;
+				ofRect(i*screenWidth/chromoLength,y*screenHeight/12,screenWidth/chromoLength,screenHeight/12);
+			}//end y
+		}//end i
+		
+	}///end if matrix has content
+	else{
+		printf("Error - please load audio first");
+	}
+	
+}
+
+
+void testApp::drawDoubleMatrix(DoubleMatrix* dMatrix){
+	//used to draw the chromagram matrix
+	int matrixSize = (*dMatrix).size();
+	if (matrixSize > 0){
+		
+		float screenHeight = ofGetHeight() ;
+		float screenWidth = ofGetWidth();
+		float heightFactor = 8;
+		int i, j, startingFrame;
+		startingFrame = currentPlayingFrame / scrollWidth;//i.e. number of scroll widths in
+		startingFrame *= scrollWidth;//starting frame in terms of energy frames
+		startingFrame /= CHROMA_CONVERSION_FACTOR; //in terms of chroma frames
+		
+		float chromoLength = scrollWidth/CHROMA_CONVERSION_FACTOR;
+		for (i = 0; i < chromoLength; i++){
+			j = i + startingFrame;
+			for (int y = 0;y < 12;y++){
+				
+				if (j < matrixSize)
+					ofSetColor(0,0,255 * (*dMatrix)[j][11-y]);
+				else 
+					ofSetColor(0,0,0);
+				
+				ofRect(i*screenWidth/chromoLength,y*screenHeight/12,screenWidth/chromoLength,screenHeight/12);
+			}//end y
+		}//end i
+		
+	}///end if matrix has content
+	else{
+		printf("Error - please load audio first");
+	}
+	
+	
+}
+
+
+
+
+
+*/
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DrumTimingLoader_OF/ofxAudioFileLoader/AudioAnalysis.h	Mon Oct 01 22:24:32 2012 +0100
@@ -0,0 +1,91 @@
+/*
+ *  AudioAnalysis.h
+ *  audioFileLoader4
+ *
+ *  Created by Andrew on 14/08/2011.
+ *  Copyright 2011 QMUL. All rights reserved.
+ *
+ */
+
+#ifndef AUDIO_ANALYSIS_H
+#define AUDIO_ANALYSIS_H
+
+
+//#include "fftw3.h"
+#include "ofMain.h"
+//#include "chromaGram.h"
+//#include "ChordDetect.h"
+#include "sndfile.h"
+#include "ofxFileDialogOSX.h"
+#include "AudioFile.h"
+
+#define FRAMESIZE 512
+#define ENERGY_LENGTH 80000
+#define CHROMA_LENGTH 12000
+#define CHROMA_CONVERSION_FACTOR 16 //16 times as many frames in energy as in chroma
+
+
+//this does a chromagram analysis and aubio onset analysis
+//held in double matrix and doubleVector respectively
+//these are dynamic vectors, so size set by what's needed for the file
+
+class AudioAnalysis{
+
+public:
+	
+	AudioAnalysis();
+	
+	typedef std::vector<double> DoubleVector;
+	typedef std::vector<DoubleVector> DoubleMatrix;
+	
+	DoubleMatrix chromaMatrix;
+//	DoubleMatrix* matrixPtr;
+	DoubleVector energyVector;
+	
+	AudioFile* audioHolder;
+	void loadNewAudio(string soundFileName);//??
+	
+//	Chromagram chromoGramm;
+	int currentPlayingFrame;
+	
+//	ChordDetect chord;
+	
+	double getEnergyOfFrame();
+	int scrollWidth;
+	//int totalFrames;
+	void drawEnergyVectorFromPointer();
+	void drawSpectralDifference();
+	
+	/*
+	 double getEnergyOfFrame();
+	
+	 
+	 void initialiseVariables();
+	 
+	 	 
+	 void initialiseVariables();
+	 
+	 
+		 AudioFile audioHolder;
+	 
+	 void drawDoubleMatrix(DoubleMatrix* dMatrix);//DoubleMatrix* dMatrix); WOULD BE NICE TO USE POINTER BUT NOT WORKING YET
+	
+	 
+	 DoubleVector firstEnergyVector;
+	 
+	 void drawEnergyVectorFromPointer(DoubleVector* energyVec);
+	 
+	 void processAudioToDoubleMatrix(Chromagram* chromaG, DoubleMatrix* myDoubleMatrix, DoubleVector* energyVector);
+	 
+	 void loadNewAudio(string soundFileName);
+	 
+	 
+	 
+	 */
+	
+	
+};
+#endif
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DrumTimingLoader_OF/ofxAudioFileLoader/AudioFile.cpp	Mon Oct 01 22:24:32 2012 +0100
@@ -0,0 +1,123 @@
+/*
+ *  audioFile.cpp
+ *  audioFileLoader3
+ *
+ *  Created by Andrew on 31/07/2011.
+ *  Copyright 2011 QMUL. All rights reserved.
+ *
+ */
+
+#include "AudioFile.h"
+
+const double samplingFrequency = 44100.0;
+
+AudioFile::AudioFile(){
+	audioScaleSamples = 44100;
+	playPosition = 0;
+	
+}
+
+void AudioFile::drawAudioVectorMillis(double startTimeMillis, double endTimeMillis){
+	
+	ofBackground(255);
+	double startTimeSamples = startTimeMillis * samplingFrequency / 1000.0;
+	double endTimeSamples = endTimeMillis * samplingFrequency / 1000.0;
+	double screenHeight = ofGetHeight() ;
+	double screenWidth = ofGetWidth(); 
+	
+	ofSetColor(255,0,0);
+	double numberOfSamples = endTimeSamples - startTimeSamples;
+	double samplesPerPixel = numberOfSamples / screenWidth;
+	string samplesString = "millis : sps ";
+	samplesString += ofToString(samplesPerPixel, 2);
+	samplesString += " , \n";
+	
+	int lastSampleIndex = (int) startTimeSamples;
+	
+	for (int i = 1;i < screenWidth;i++){// && startTimeSamples + samplesPerPixel * i < endTimeSamples;i += 1){
+		int sampleIndex = (int) min((startTimeSamples + samplesPerPixel * i), (double) length-1);
+			//if (sampleIndex < 0)
+			//	sampleIndex = 0;
+		ofLine(i-1, screenHeight - (1-audioVector[sampleIndex])*screenHeight/2.0 , i, screenHeight - (1-audioVector[lastSampleIndex])*screenHeight/2.0);
+		samplesString += ofToString(audioVector[i])+"  , \n";
+		lastSampleIndex = sampleIndex;
+		
+	}
+	ofDrawBitmapString(samplesString, 20,20);	
+	
+	ofSetColor(100,100,100);
+	ofLine(screenWidth/2, 0, screenWidth/2, screenHeight);
+	
+	
+}
+
+
+
+void AudioFile::drawAudioVectorSamples(double startTimeSample, double endTimeSample){
+	
+	ofBackground(255);
+	screenHeight = ofGetHeight() ;
+	double screenWidth = ofGetWidth(); 
+	
+	ofSetColor(255,0,0);
+	double numberOfSamples = endTimeSample - startTimeSample;
+	double samplesPerPixel = numberOfSamples / screenWidth;
+	
+	double halfHeight = screenHeight/2;
+	
+	int lastSampleIndex = (int) startTimeSample;
+	/*
+	for (int i = 1;i < screenWidth;i++){// && startTimeSamples + samplesPerPixel * i < endTimeSamples;i += 1){
+		int sampleIndex = (int) (startTimeSample + samplesPerPixel * i);
+		ofLine(i-1, screenHeight - (1-audioVector[sampleIndex])*screenHeight/2.0 , i, screenHeight - (1-audioVector[lastSampleIndex])*screenHeight/2.0);
+		lastSampleIndex = sampleIndex;
+		
+	}
+	*/
+	double firstXpos = halfHeight;
+	double firstYpos = getPosition(startTimeSample);//screenHeight - ((1-audioVector[startTimeSample])*screenHeight/2.0);
+	
+	int stepSize = 1;//(int) samplesPerPixel); optimize !! XXX
+	for (int sampleIndex = startTimeSample+1;sampleIndex < min(endTimeSample, (double) length);sampleIndex+= stepSize){
+
+		double secondXpos = (sampleIndex - startTimeSample) * screenWidth/numberOfSamples;
+		double secondYpos = getPosition(sampleIndex);//screenHeight - ((1-audioVector[sampleIndex])*screenHeight/2.0);
+		ofLine(firstXpos, firstYpos, secondXpos, secondYpos);
+		
+			if (numberOfSamples < 100)
+				ofCircle(secondXpos, secondYpos, 2);
+		
+		firstXpos = secondXpos;
+		firstYpos = secondYpos;
+		
+		
+	}
+
+	string samplesString = "samples: sps " + ofToString(samplesPerPixel, 2);
+	samplesString += ", number of smaplers " + ofToString(numberOfSamples, 2);
+	samplesString += " , \n";
+	
+	
+	string textString;
+	textString = ofToString(playPosition, 1);
+	ofDrawBitmapString(textString, 20, 20);
+	ofDrawBitmapString(samplesString, 20, 60);
+
+	ofSetColor(0,0,255);
+	ofLine(0, halfHeight, screenWidth, halfHeight);
+	
+}
+/*
+double testApp::getXposition(int index, int startTimeSampleIndex){
+	if (index >= 0 && index < audioVector.size())
+		return (index - startTimeSampleIndex) * screenWidth/numberOfSamples;
+}
+*/
+double AudioFile::getPosition(int index){
+	if (index >= 0 && index < audioVector.size())
+		return screenHeight - ((1-audioVector[index])*screenHeight/2.0);
+	else
+		return screenHeight /2 ;
+}	
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DrumTimingLoader_OF/ofxAudioFileLoader/AudioFile.h	Mon Oct 01 22:24:32 2012 +0100
@@ -0,0 +1,44 @@
+/*
+ *  audioFile.h
+ *  audioFileLoader3
+ *
+ *  Created by Andrew on 31/07/2011.
+ *  Copyright 2011 QMUL. All rights reserved.
+ *
+ */
+
+//Holds the actual samples loaded in from the audio file
+//in a double matrix, so multilpe channels used
+
+
+#ifndef AUDIOFILE_H
+#define AUDIOFILE_H
+
+#include "ofMain.h"
+
+
+class AudioFile
+{
+public:		
+	AudioFile();											// constructor
+//	~AudioFile();
+	
+	
+	
+	void drawAudioVectorMillis(double startTimeMillis, double endTimeMillis);
+	void drawAudioVectorSamples(double startTimeSample, double endTimeSample);
+	double getPosition(int index);
+	
+	typedef std::vector<double> DoubleVector;
+	typedef std::vector<DoubleVector> DoubleMatrix;
+	DoubleVector audioVector;
+	DoubleMatrix audioMatrix;
+	
+	double screenHeight;
+	int length;
+	double audioScaleSamples;
+	double playPosition;//in samples
+	
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DrumTimingLoader_OF/ofxAudioFileLoader/LoadedAudioHolder.cpp	Mon Oct 01 22:24:32 2012 +0100
@@ -0,0 +1,93 @@
+/*
+ *  LoadedAudioHolder.cpp
+ *  fileLoaderAndOnsetDetection
+ *
+ *  Created by Andrew on 28/01/2012.
+ *  Copyright 2012 QMUL. All rights reserved.
+ *
+ */
+
+#include "LoadedAudioHolder.h"
+
+LoadedAudioHolder::LoadedAudioHolder(){
+	audioPaused = true;
+	audioPlaying = false;
+	trackType = 0;
+}
+
+void LoadedAudioHolder::updateToPlayPosition(){
+	fileLoader.updateToAudioPosition(loadedAudio.getPosition());
+}
+
+void LoadedAudioHolder::updateToMillisPosition(const double& millis){	
+	fileLoader.updateToMillisPosition(millis);
+}
+
+void LoadedAudioHolder::updatePlaybackPositionToMillis(const double& millis){
+	printf("updatePlay %f", millis * 44.1 / (double) fileLoader.totalNumberOfSamples );
+	
+	loadedAudio.setPosition(millis * 44.1 / (double) fileLoader.totalNumberOfSamples );
+}
+
+void LoadedAudioHolder::draw(){
+	fileLoader.drawFile();
+}
+
+void LoadedAudioHolder::loadAudioFile(string soundFileName){
+	loadedAudio.loadSound(soundFileName);
+	fileLoader.loadNewAudio(soundFileName);
+	audioPlaying = false;
+	loadedFileName = soundFileName;
+	copyOnsetTimes();
+	
+}
+
+void LoadedAudioHolder::copyOnsetTimes(){
+
+	onsetTimesMillis.clear();
+	
+	for (int i = 0;i < fileLoader.onsetDetect.chromaOnsets.size();i++)
+		onsetTimesMillis.push_back(fileLoader.onsetDetect.chromaOnsets[i].millisTime);
+	
+}
+
+void LoadedAudioHolder::setTrackType(const int& i){
+	fileLoader.onsetDetect.trackType = i;
+	trackType = i;
+}
+
+void LoadedAudioHolder::togglePlay(){
+	if (!audioPlaying) {
+		loadedAudio.play();
+		loadedAudio.setPaused(false);
+		audioPlaying = true;
+		audioPaused = false;
+		printf("playing %s\n", loadedFileName.c_str());
+	}
+	else{
+		audioPaused = !audioPaused;
+		loadedAudio.setPaused(audioPaused);
+	}
+}
+
+void LoadedAudioHolder::stop(){
+	audioPlaying = false;
+	loadedAudio.setPaused(true);
+	loadedAudio.setPosition(0.0);
+}
+
+void LoadedAudioHolder::switchScreens(){
+	fileLoader.screenToDraw = 1 - fileLoader.screenToDraw;
+}
+
+void LoadedAudioHolder::windowResized(const int& w, const int& h){
+	fileLoader.onsetDetect.windowResized(w, h);
+}
+
+
+void LoadedAudioHolder::printEvents(){
+	for (int i = 0;i < fileLoader.onsetDetect.chromaOnsets.size();i++){
+		printf("Event time %f millis %i frames pitch %f\n", fileLoader.onsetDetect.chromaOnsets[i].millisTime, 
+			   fileLoader.onsetDetect.chromaOnsets[i].frameTime, fileLoader.onsetDetect.chromaOnsets[i].aubioPitch);
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DrumTimingLoader_OF/ofxAudioFileLoader/LoadedAudioHolder.h	Mon Oct 01 22:24:32 2012 +0100
@@ -0,0 +1,62 @@
+/*
+ *  LoadedAudioHolder.h
+ *  fileLoaderAndOnsetDetection
+ *
+ *  Created by Andrew Robertson on 28/01/2012.
+ *  Copyright 2012 QMUL. All rights reserved.
+ *
+ */
+
+//Holds the player ofSoundplayer
+//and the analysis - ofxSoundFileLoader
+//latter consists of the audio samples - in AudioFile.h
+//and the onset detection, chroma and pitch analysis - in ofxAubioOnsetDetection
+
+
+#ifndef LOADED_AUDIO_HOLDER_H
+#define LOADED_AUDIO_HOLDER_H
+
+
+#include "ofMain.h"
+#include "ofxSoundFileLoader.h"
+
+class LoadedAudioHolder{
+	
+	public:
+
+	LoadedAudioHolder();
+
+	void updateToPlayPosition();
+	void updateToMillisPosition(const double& millis);
+	void updatePlaybackPositionToMillis(const double& millis);
+	
+	void draw();
+	void windowResized(const int& w, const int& h);
+	
+	void loadAudioFile(string soundFileName);
+
+	void togglePlay();//pauses if playing and vice-versa
+	void stop();
+	void switchScreens();
+	
+	void printEvents();
+	
+	//Samples to show or iterate through
+	ofxSoundFileLoader fileLoader;
+	ofSoundPlayer  loadedAudio;
+	std::string loadedFileName;
+	
+	int trackType;
+	void setTrackType(const int& type);
+	
+	typedef vector<double> DoubleVector;
+	DoubleVector onsetTimesMillis;
+	void copyOnsetTimes();
+	
+private:
+	
+	//Audio To PLay
+	bool audioPlaying, audioPaused;
+	
+};
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DrumTimingLoader_OF/ofxAudioFileLoader/ofxSoundFileLoader.cpp	Mon Oct 01 22:24:32 2012 +0100
@@ -0,0 +1,155 @@
+/*
+ *  ofxSoundFileLoader.cpp
+ *  audioFileLoaderSVN1
+ *
+ *  Created by Andrew on 04/09/2011.
+ *  Copyright 2011 QMUL. All rights reserved.
+ *
+ */
+
+#include "ofxSoundFileLoader.h"
+
+//NB zooming relies on screenToDraw - this needs to be 1
+
+ofxSoundFileLoader::ofxSoundFileLoader(){
+	sfinfo.format = 0;
+//	onsetDetect = new ofxAubioOnsetDetection();
+	//onsetDetect->reset();
+	
+	soundFileName = "";
+	screenToDraw = 1;
+}
+
+ofxSoundFileLoader::~ofxSoundFileLoader(){
+//	delete onsetDetect ;
+//	printf("file loader delete onset detect\n");
+	
+}
+
+void ofxSoundFileLoader::updateToAudioPosition(const float& audioPosition){
+	
+	audioHolder.playPosition = audioPosition * audioHolder.audioVector.size();
+	onsetDetect.playPosition = audioPosition;
+}
+
+void ofxSoundFileLoader::updateToMillisPosition(const double& millis){
+	
+//	audioHolder.playPosition = audioPosition * audioHolder.audioVector.size();
+	onsetDetect.playPosition = millis * 44.1 / (double)totalNumberOfSamples;
+	
+}
+
+void ofxSoundFileLoader::drawFile(){
+	if (screenToDraw == 0){
+		audioHolder.drawAudioVectorSamples(audioHolder.playPosition - audioHolder.audioScaleSamples*0.5, 
+													  audioHolder.playPosition + audioHolder.audioScaleSamples*0.5);
+	}else{
+		onsetDetect.drawOnsetDetectionScrolling();
+	}
+
+}
+
+#pragma mark -loadAudio
+void ofxSoundFileLoader::loadNewAudio(std::string filename){
+	loadLibSndFile(filename.c_str());
+}
+
+void ofxSoundFileLoader::loadLibSndFile(const char *infilename){
+	
+//	if (!sf_close(infile)){
+//		printf("closed sndfile okay \n");
+//	}
+	
+	// Open Input File with lib snd file
+    if (! (infile = sf_open (infilename, SFM_READ, &sfinfo)))
+    {   // Open failed
+        printf ("SF OPEN routine Not able to open input file %s.\n", infilename) ;
+        // Print the error message from libsndfile. 
+        puts (sf_strerror (NULL)) ;
+		
+	} else{
+		printf("SF OPEN : file %s okay, ", infilename);
+		printf("number of channels is %i\n", sfinfo.channels);
+		soundFileName = infilename;
+		//sndfileInfoString = "Opened okay ";
+		
+	};
+	
+	readAudio();
+	onsetDetect.printOnsetList();
+	printf("max val of onset det is %f\n", onsetDetect.onsetDetector.maximumDetectionValue);
+}
+
+void ofxSoundFileLoader::readAudio(){
+	
+	onsetDetect.reset();
+	//could add this in - check the stored github
+	
+	// HERE IS THE CLASSIC LOADING FILE CODE
+	//DEALS WITH MORE THAN MONO
+	int channels = sfinfo.channels;
+	int blocksize = FRAMESIZE;
+	
+	float buf [channels * blocksize] ;
+	int k, m, readcount ;
+	
+	DoubleVector d;
+	while ((readcount = sf_readf_float (infile, buf, blocksize)) > 0){
+		for (k = 0 ; k < readcount ; k++){	
+			//readcount is a chunk - eg 512 samples - of audio that is processed
+			d.clear();
+			for (m = 0 ; m < channels ; m++){
+				d.push_back(buf [k * channels + m]);
+				//		 fprintf (outfile, " % 12.10f", buf [k * channels + m]) ;
+				//		 fprintf (outfile, "\n") ;
+				if (m == 0){
+					//makes the vector hold the mono file - the left channel
+					audioHolder.audioVector.push_back(buf[k * channels + 0]);
+					frame[k] = buf[k*channels + 0];
+				}
+				
+			} 
+		audioHolder.audioMatrix.push_back(d);
+			//storing the full soundfile in multiple channels in the audioMatrix
+		}
+		//printf("processing at readcount %i\n", readcount);
+		//could call this here
+		onsetDetect.processFrame(&frame[0], blocksize);
+
+		
+	}//end readcount
+	
+	//printf("audio vector size is %i\n", (int) audioHolder.audioVector.size());
+	audioHolder.length = (int) audioHolder.audioVector.size();
+	totalNumberOfSamples = audioHolder.length;
+	
+	printf("Total number of samples %i onset frames %i\n", totalNumberOfSamples, onsetDetect.frameCountIndex);
+	
+	freeMemory();
+}
+
+
+void ofxSoundFileLoader::freeMemory(){
+	printf("FREE MEMORY in file loader\n");
+	audioHolder.audioMatrix.clear();
+	audioHolder.audioVector.clear();
+}
+
+void ofxSoundFileLoader::zoomOut(){
+	if (screenToDraw == 0){
+		audioHolder.audioScaleSamples *= 2.;
+	}
+	if (screenToDraw == 1){
+		onsetDetect.amplitudeNumber *= 2;
+	}
+}
+
+void ofxSoundFileLoader::zoomIn(){
+	if (screenToDraw == 0){
+		audioHolder.audioScaleSamples /= 2.;
+	}
+	if (screenToDraw == 1 && onsetDetect.amplitudeNumber > 2){
+		onsetDetect.amplitudeNumber /= 2;
+	}
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DrumTimingLoader_OF/ofxAudioFileLoader/ofxSoundFileLoader.h	Mon Oct 01 22:24:32 2012 +0100
@@ -0,0 +1,66 @@
+/*
+ *  ofxSoundFileLoader.h
+ *  audioFileLoaderSVN1
+ *
+ *  Created by Andrew on 04/09/2011.
+ *  Copyright 2011 QMUL. All rights reserved.
+ *
+ */
+
+#ifndef SOUND_FILE_LOADER_H
+#define SOUND_FILE_LOADER_H
+
+
+#include "ofMain.h"
+#include "sndfile.h"
+#include "AudioFile.h"
+#include "ofxAubioOnsetDetection.h"
+
+
+#define FRAMESIZE 512
+
+
+
+class ofxSoundFileLoader{
+	
+public:
+	ofxSoundFileLoader();
+	~ofxSoundFileLoader();
+	float frame[FRAMESIZE]; 
+	
+	void updateToAudioPosition(const float& audioPosition);
+	void updateToMillisPosition(const double& millis);
+	void drawFile();
+	void zoomOut();
+	void zoomIn();
+	
+	void loadLibSndFile(const char *infilename);
+
+//	void openNewFileWithDialogBox();
+	void loadNewAudio(std::string filename);
+	
+	typedef std::vector<double> DoubleVector;
+//	typedef std::vector<DoubleVector> DoubleMatrix;
+
+	//0 draws audio vector samples
+	//1 draws the onset fn, pitch and chroma data
+	int screenToDraw;
+	
+	AudioFile audioHolder;
+	
+	ofxAubioOnsetDetection onsetDetect;
+	//chromaOnsetHolder chromaHolder; - add in here
+	
+	int totalNumberOfSamples;
+	
+	void readAudio();
+	
+	string soundFileName;
+	SNDFILE *infile; // define input and output sound files
+	SF_INFO sfinfo ; // struct to hold info about sound file
+	
+	void freeMemory();
+	
+
+};
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DrumTimingLoader_OF/ofxAudioFileLoader/testApp.h	Mon Oct 01 22:24:32 2012 +0100
@@ -0,0 +1,62 @@
+#ifndef _TEST_APP
+#define _TEST_APP
+
+
+#include "ofMain.h"
+#include "sndfile.h"
+#include "ofxFileDialogOSX.h"
+#include "LoadedAudioHolder.h"
+//#include "ofxSoundFileLoader.h"
+#include "LoadedAudioHolder.h"
+
+//note the dependency on sndfile (libsndfile library needs to be accessible)
+//also the file dialogue addon
+
+//main commands:
+//O: open a new file
+//see the key pressed function for other bits - e.g. can view spectral difference
+
+//TO DO
+//Move all the soundfile stuff to the ofxSoundFileLoader
+//can hold the player, the audio samples and the onset class there
+
+//length in terms of frames (at 512 samples per frame - there are 90 per second) => 900: 10 seconds
+
+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 audioRequested 	(float * input, int bufferSize, int nChannels);
+
+	bool getFilenameFromDialogBox(string* fileNameToSave);
+	void openNewAudioFileWithdialogBox();		
+	void loadNewAudio(string soundFileName);
+	
+	LoadedAudioHolder audioFilePlayer;
+		
+
+//live audio input	
+		float 	pan;
+		int		sampleRate;
+		bool 	bNoise;
+		float 	volume;
+		float 	* lAudio;
+		float   * rAudio;
+
+		
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DrumTimingLoader_OF/ofxWindowRegion/windowRegion/ofxPlotFunction.cpp	Mon Oct 01 22:24:32 2012 +0100
@@ -0,0 +1,163 @@
+/*
+ *  ofxPlotFunction.cpp
+ * 
+ *
+ *  Created by Andrew on 14/11/2011.
+ *  Copyright 2011 QMUL. All rights reserved.
+ *
+ */
+
+#include "ofxPlotFunction.h"
+
+
+ofxPlotFunction :: ofxPlotFunction(){
+	fullScreen.resetToFullScreen();
+}
+
+ofxPlotFunction :: ~ofxPlotFunction(){
+
+}
+
+
+void ofxPlotFunction::drawVector(DoubleVector& energyVec, int minIndex, int maxIndex, const ofxWindowRegion& window, const double& maxNumberOfIndexPoints, const double& maxValue){
+
+	float screenHeight = window.height;
+	float screenWidth = window.width;  
+	
+	double  numberOfIndexPoints = min(maxNumberOfIndexPoints, (double) maxIndex - minIndex);
+	double indicesPerStep = (maxIndex - minIndex) / numberOfIndexPoints;
+	double pixelsPerStep = window.width / numberOfIndexPoints;
+	
+	int i, j;
+	
+	double heightScalar = window.height / (1.0*maxValue);
+	
+	int lastHeight = window.y + screenHeight - (energyVec[minIndex]*heightScalar);;
+	int newHeight;
+	int xPosition;
+	int lastXposition = window.x;
+	
+	double exactIndex;
+	for (exactIndex = minIndex; exactIndex < maxIndex; exactIndex += indicesPerStep){
+		j = round(exactIndex);
+		i = j - minIndex;
+		
+		if (j < energyVec.size()){
+			xPosition = window.x + i*pixelsPerStep;
+			newHeight =	window.y + screenHeight - (energyVec[j]*heightScalar);
+			
+			ofLine(lastXposition, lastHeight, xPosition, newHeight);
+			
+			lastHeight = newHeight;
+			lastXposition = xPosition;
+			
+		}
+	}
+}
+
+
+void ofxPlotFunction::drawVector(DoubleVector& energyVec, int minIndex, int maxIndex, const ofxWindowRegion& window, const double& maxResolution){
+	
+	
+	minIndex = max(0, minIndex);
+	maxIndex = min((int)energyVec.size()-1, maxIndex);
+	int tmpTwenty = 20;
+	double maximumValue = 1.1*getMaximum(energyVec, minIndex, maxIndex, tmpTwenty);
+	drawVector(energyVec, minIndex, maxIndex, window, maxResolution, maximumValue);
+
+}
+
+
+
+void ofxPlotFunction::drawArray(float* energyArray, int minIndex, int maxIndex, const ofxWindowRegion& window, const double& maxResolution){
+	
+	minIndex = max(0, minIndex);
+	//	maxIndex = min((int)sizeof(energyArray)-1, maxIndex);
+	int tmpStepVal = 100;
+	double maximumValue = 1;
+	if (maxIndex > minIndex)
+	maximumValue = getMaximumArray(energyArray, minIndex, maxIndex, tmpStepVal);
+	
+	drawArray(energyArray, minIndex, maxIndex, window, maxResolution, maximumValue);
+}
+
+void ofxPlotFunction::drawArray(float* energyArray, int minIndex, int maxIndex, const ofxWindowRegion& window, const double& maxNumberOfIndexPoints, const double& maximumValue){
+	
+	
+	float screenHeight = window.height;
+	float screenWidth = window.width;  
+	
+	double  numberOfIndexPoints= min(maxNumberOfIndexPoints, (double) maxIndex - minIndex);
+	int indicesPerStep = (int) round((maxIndex - minIndex) / numberOfIndexPoints);
+	indicesPerStep = max(1, indicesPerStep);
+	double pixelsPerStep = window.width / numberOfIndexPoints;
+	
+	string pixelstring = ofToString(indicesPerStep);
+	ofDrawBitmapString("max val "+pixelstring, 500,100);
+	
+	int i, j;
+	
+	double heightScalar = window.height / (1.2*maximumValue);
+	
+	int lastHeight = window.y + screenHeight - (energyArray[minIndex]*heightScalar);;
+	int newHeight;
+	int xPosition;
+	int lastXposition = window.x;
+	
+	int exactIndex;
+	for (exactIndex = minIndex - minIndex%indicesPerStep; exactIndex < maxIndex; exactIndex += indicesPerStep){
+		j = exactIndex;// - exactIndex % indicesPerStep ;
+		i = j - minIndex;
+
+			xPosition = window.x + i*pixelsPerStep;
+			if (j >= 0)
+			newHeight =	window.y + screenHeight - (energyArray[j]*heightScalar);
+
+			if (j < 16)
+				cout << "j is " << j << ", i is " << i << endl;
+		
+			ofLine(lastXposition, lastHeight, xPosition, newHeight);
+			//			   window.x+screenWidth*(i+1)/scrollWidth, window.y + screenHeight - (energyVec[j]*screenHeight/heightFactor));
+			
+			lastHeight = newHeight;
+			lastXposition = xPosition;
+			
+		
+	}
+	 
+	
+}
+
+
+double ofxPlotFunction::getMaximum(DoubleVector& energyVec, const int& minIndex, const int& maxIndex, int& numberOfSteps){
+	
+	int step = max(1, (int)((maxIndex - minIndex) / (float) numberOfSteps));
+	double maximumValue = energyVec[minIndex];
+	int index = minIndex;
+	while (index < maxIndex && index < energyVec.size()){
+		index += step;
+		if (energyVec[index] > maximumValue){
+			maximumValue = energyVec[index];
+		}
+	}
+	return maximumValue;
+	
+}
+
+
+
+double ofxPlotFunction::getMaximumArray(float* energyArray, const int& minIndex, const int& maxIndex, int& numberOfSteps){
+	
+	int step = max(1, (int)((maxIndex - minIndex) / (float) numberOfSteps));
+	double maximumValue = energyArray[minIndex];
+	int index = minIndex;
+	while (index < maxIndex ){//&& index < sizeof(energyArray)
+		index += step;
+		if (energyArray[index] > maximumValue){
+			maximumValue = energyArray[index];
+		}
+	}
+	return maximumValue;
+	
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DrumTimingLoader_OF/ofxWindowRegion/windowRegion/ofxPlotFunction.h	Mon Oct 01 22:24:32 2012 +0100
@@ -0,0 +1,40 @@
+/*
+ *  ofxPlotFunction.h
+ *  BTrackPortAudioMultipleAnalyser
+ *
+ *  Created by Andrew Robertson on 14/11/2011.
+ *  Copyright 2011 QMUL. All rights reserved.
+ *
+ */
+
+
+#ifndef PLOT_FUNCTION_H
+#define PLOT_FUNCTION_H
+
+#include "ofMain.h"
+#include "ofxWindowRegion.h"
+
+
+struct ofxPlotFunction {
+	public:
+
+	ofxPlotFunction();
+	~ofxPlotFunction();
+	
+	typedef std::vector<double> DoubleVector;
+	typedef std::vector<int> IntVector;
+	typedef std::vector<DoubleVector> DoubleMatrix;
+	
+	ofxWindowRegion fullScreen;
+	void drawVector(DoubleVector& energyVec, int minIndex, int maxIndex, const ofxWindowRegion& window, const double& maxResolution, const double& maxValue);
+	void drawVector(DoubleVector& energyVec, int minIndex, int maxIndex, const ofxWindowRegion& window, const double& maxResolution);
+	void drawArray(float* energyArray, int minIndex, int maxIndex, const ofxWindowRegion& window, const double& maxResolution);
+	void drawArray(float* energyArray, int minIndex, int maxIndex, const ofxWindowRegion& window, const double& maxResolution, const double& maximumValue);	
+
+	
+	double getMaximum(DoubleVector& energyVec, const int& minIndex, const int& maxIndex,  int& numberOfSteps);
+
+	double getMaximumArray(float* energyArray, const int& minIndex, const int& maxIndex, int& numberOfSteps);
+	
+};
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DrumTimingLoader_OF/ofxWindowRegion/windowRegion/ofxWindowRegion.cpp	Mon Oct 01 22:24:32 2012 +0100
@@ -0,0 +1,110 @@
+/*
+ *  ofxWindowRegion.cpp
+ *  BTrackPortAudioMultipleAnalyser
+ *
+ *  Created by Andrew Robertson on 13/10/2011.
+ *  Copyright 2011 QMUL. All rights reserved.
+ *
+ */
+
+//WARNING - if window is resized, you must make a manual check function in testApp that calls 
+//yourWindow.resize(w, h);
+//it does not use a listener (which would be preferable)
+
+#include "ofxWindowRegion.h"
+
+ofxWindowRegion::ofxWindowRegion(){
+	x = 0;
+	y = 0;
+	width = ofGetWidth();
+	height = ofGetHeight();
+	
+	fullScreenX = ofGetWidth();
+	fullScreenY = ofGetHeight();
+
+	getRelativeSize();//store in case we resize!
+	printf("set window with x %i, y %i, width %i, height %i\n", x, y, width, height);
+}
+
+ofxWindowRegion::ofxWindowRegion(int _x, int _y, int _width, int _height){
+	if (_x >= 0 && _x <= ofGetWidth())
+		x = _x;
+	
+	if (_y >= 0 && _y <= ofGetHeight())
+		y = _y;
+	
+	if (_width > 0)
+		width = _width;
+	
+	if (_height > 0)
+		height = _height;
+	
+	fullScreenX = ofGetWidth();
+	fullScreenY = ofGetHeight();
+	
+	getRelativeSize();
+	printf("set window with x %i, y %i, width %i, height %i\n", x, y, width, height);
+}
+
+void ofxWindowRegion::getRelativeSize(){
+	relativeX = (double)x / fullScreenX;
+	relativeY = (double)y / fullScreenY;
+	relativeWidth = (double)width / fullScreenX;
+	relativeHeight = (double)height / fullScreenY;
+}
+
+void ofxWindowRegion::setToRelativeSize(){
+	x = relativeX * fullScreenX;
+	y = relativeY * fullScreenY;
+	width = relativeWidth * fullScreenX;
+	height = relativeHeight * fullScreenY;
+}
+
+void ofxWindowRegion::setToRelativeSize(double _xr, double _yr, double _wr, double _hr){
+	relativeX = _xr;
+	relativeY = _yr;;
+	relativeWidth = _wr;;
+	relativeHeight = _hr;
+	setToRelativeSize();
+	printf("window set to relative size\n");
+}
+
+void ofxWindowRegion::resized(int w, int h){
+	fullScreenX = w;
+	fullScreenY = h;
+	setToRelativeSize();
+}
+
+
+void ofxWindowRegion::setWindowDimensions(int _x, int _y, int _width, int _height){
+	if (_x >= 0 && _x <= ofGetWidth())
+		x = _x;
+	
+	if (_y >= 0 && _y <= ofGetHeight())
+		y = _y;
+	
+	if (_width > 0)
+		width = _width;
+	
+	if (_height > 0)
+		height = _height;
+	
+	getRelativeSize();
+	printf("set window with x %i, y %i, width %i, height %i\n", x, y, width, height);
+}
+
+void ofxWindowRegion::resetToFullScreen(){
+	x = 0;
+	y = 0;
+	width = ofGetWidth();
+	height = ofGetHeight();
+}
+
+
+void ofxWindowRegion::drawOutline() const{
+	ofLine(x, y, x+width, y);
+	ofLine(x+width, y, x+width, y+height);
+	ofLine(x, y+height, x+width, y+height);
+	ofLine(x, y, x, y+height);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DrumTimingLoader_OF/ofxWindowRegion/windowRegion/ofxWindowRegion.h	Mon Oct 01 22:24:32 2012 +0100
@@ -0,0 +1,40 @@
+/*
+ *  ofxWindowRegion.h
+ *  BTrackPortAudioMultipleAnalyser
+ *
+ *  Created by Andrew on 13/10/2011.
+ *  Copyright 2011 QMUL. All rights reserved.
+ *
+ */
+
+
+#ifndef WINDOW_REGION_H
+#define WINDOW_REGION_H
+
+
+#include "ofMain.h"
+
+struct ofxWindowRegion {
+public:
+	ofxWindowRegion();
+	ofxWindowRegion(int _x, int _y, int _width, int _height);
+	void setWindowDimensions(int _x, int _y, int _width, int _height);
+	void resetToFullScreen();
+	void resized(int w, int h);
+	void getRelativeSize();
+	void setToRelativeSize();
+	void setToRelativeSize(double _xr, double _yr, double _wr, double _hr);
+	
+	int x;
+	int y;
+	int width; 
+	int height;
+	
+	double relativeX, relativeY, relativeWidth, relativeHeight;
+	double fullScreenX;
+	double fullScreenY;
+	
+	void drawOutline() const;
+	
+};
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DrumTimingLoader_OF/src/DrumTimingLoader.cpp	Mon Oct 01 22:24:32 2012 +0100
@@ -0,0 +1,44 @@
+/*
+ *  DrumTimingLoader.cpp
+ *  DrumTimingLoader
+ *
+ *  Created by Andrew on 09/08/2012.
+ *  Copyright 2012 QMUL. All rights reserved.
+ *
+ */
+
+#include "DrumTimingLoader.h"
+
+DrumTimingLoader::DrumTimingLoader(){
+
+}
+
+
+void DrumTimingLoader::initialise(){
+	
+	recordedTracks.loadTestAudio();
+	/*
+	calculateRecordedTempoData();
+	printf("\n audioeventmatcher\nFIRST PASS: FINAL recorded tempo is %f\n", recordedTempoData.playingTempo);
+	setTempoPrior(recordedTempoData.playingTempo);
+	calculateRecordedTempoData();//now calculate again using better prior
+	
+	printf("\n audioeventmatcher\nSECOND PASS: FINAL recorded tempo is %f\n", recordedTempoData.playingTempo);
+	printf("GLOBAL TEMPO of RECORDED FILES\n");
+	*/ 
+	
+}
+
+
+
+void DrumTimingLoader::draw(){
+	bool drawTracks = false;
+	if (drawTracks)
+		recordedTracks.drawTracks();
+	else 
+		recordedTracks.drumTimingAnalyser.drawTempoCurve();
+}
+
+void DrumTimingLoader::windowResized(int w, int h){
+	recordedTracks.windowResized(w, h);
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DrumTimingLoader_OF/src/DrumTimingLoader.h	Mon Oct 01 22:24:32 2012 +0100
@@ -0,0 +1,31 @@
+/*
+ *  DrumTimingLoader.h
+ *  DrumTimingLoader
+ *
+ *  Created by Andrew on 09/08/2012.
+ *  Copyright 2012 QMUL. All rights reserved.
+ *file://localhost/Users/andrew/Dropbox/DrumTiming/DrumTimingLoader_OF/PerformanceAnalyserSrc/
+ */
+
+#ifndef DRUM_TIMING_LOADER
+#define DRUM_TIMING_LOADER
+
+#include "RecordedMultipleAudio.h"
+
+// basic file operations for text file stuff
+#include <iostream>
+#include <fstream>
+using namespace std;
+
+
+class DrumTimingLoader{
+	
+	public:
+		DrumTimingLoader();
+		void initialise();
+		void draw();
+	void windowResized(int w, int h);
+	RecordedMultipleAudio recordedTracks;
+
+};
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DrumTimingLoader_OF/src/RecordedMultipleAudio.cpp	Mon Oct 01 22:24:32 2012 +0100
@@ -0,0 +1,525 @@
+/*
+ *  RecordedMultipleAudio.cpp
+ *  MultipleAudioMathcher
+ *
+ *  Created by Andrew on 31/01/2012.
+ *  Copyright 2012 QMUL. All rights reserved.
+ *
+ */
+
+#include "RecordedMultipleAudio.h"
+
+RecordedMultipleAudio::RecordedMultipleAudio(){
+	
+	infoFilepath = "../../../data/errorData.txt";
+	//infoFilepath = "/Users/andrew/errorData.txt";
+	
+	timingOffset = 0;
+}
+
+void RecordedMultipleAudio::loadTestAudio(){
+
+
+	numberOfAudioTracks = 2;
+	
+	printf("loaded max val  is %f\n", loadedAudioFiles[0].fileLoader.onsetDetect.onsetDetector.maximumDetectionValue);
+	
+	int multitrackToLoad = 5;
+	setDifferentMultitracks(multitrackToLoad);//command to load this set of audio files - see below
+
+	drumTimingAnalyser.phaseCost = 1000;//v high - i.e. dont do phase 
+	
+	drawWindow = 1;
+	trackScreenHeight = 0.25;
+	
+	
+	
+//	printf("AFTER LOADING: \n");
+//	printInfo();
+	
+}
+#pragma mark -loadingPrerecordedTracks
+void RecordedMultipleAudio::setDifferentMultitracks(const int& setToLoad){
+	const char	*kickfilename ;//= "../../../data/sound/LiveDues/kick_liveDues.wav";	
+	const char	*roomfilename ;//"../../../data/sound/LiveDues/bass_upsideLive.wav";	
+	const char	*snarefilename ;
+	std::string sonicVizBeatsFilename ;
+	
+	switch (setToLoad) {
+		case 0:
+				kickfilename = "/Users/andrew/Documents/work/programming/MadMax/AudioFiles/futureHides/kickFuture.wav";	
+				roomfilename = "/Users/andrew/Documents/work/programming/MadMax/AudioFiles/futureHides/roomFuture.wav";	
+				snarefilename = "/Users/andrew/Documents/work/programming/MadMax/AudioFiles/futureHides/snareFuture.wav";	
+				sonicVizBeatsFilename = "/Users/andrew/Documents/work/programming/MadMax/AudioFiles/futureHides/FutureHidesBeats.txt";
+			break;
+			
+			
+		case 1:
+			roomfilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcadeStudio14aMultitrack/Mixdown/PennyArcade_StudioMixdown.wav";
+			kickfilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcadeStudio14aMultitrack/kick.wav";
+			snarefilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcadeStudio14aMultitrack/snare.wav";
+			sonicVizBeatsFilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcadeStudio14aMultitrack/Mixdown/PennyArcade_StudioMixdown_beats.txt";
+			break;	
+	
+		case 2:
+			roomfilename = "/Users/andrew/Documents/work/programming/MadMax/AudioFiles/MattIngramGreenSection/colesL_bip.wav";
+			kickfilename = "/Users/andrew/Documents/work/programming/MadMax/AudioFiles/MattIngramGreenSection/Kick_bip.wav";
+			snarefilename = "/Users/andrew/Documents/work/programming/MadMax/AudioFiles/MattIngramGreenSection/Snare_bip.wav";
+			sonicVizBeatsFilename = "/Users/andrew/Documents/work/programming/MadMax/AudioFiles/MattIngramGreenSection/IngramGreenSectionBeats.txt";
+			break;		
+			
+		case 3:
+			roomfilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDiamondWhite/tractorsDiamondWhite/Bounces/diamondWhiteMultiTakeOne/coles_bip.wav";
+			kickfilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDiamondWhite/tractorsDiamondWhite/Bounces/diamondWhiteMultiTakeOne/kick d112_bip.wav";
+			snarefilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDiamondWhite/tractorsDiamondWhite/Bounces/diamondWhiteMultiTakeOne/snare bottom_bip.wav";
+			sonicVizBeatsFilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDiamondWhite/tractorsDiamondWhite/Bounces/diamondWhiteMultiTakeOne/TakeOneBeats.txt";
+			break;
+			
+		case 4:
+			roomfilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeOne_4/neuamnn_bip.wav";
+			kickfilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeOne_4/kick_bip.wav";
+			snarefilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeOne_4/snare_bip.wav";
+			sonicVizBeatsFilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeOne_4/PennyArcade_take4_beats.txt";
+			break;	
+			
+		case 5:
+			roomfilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeTwo_5/neuamnn_bip.wav";
+			kickfilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeTwo_5/kick_bip.wav";
+			snarefilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeTwo_5/snare_bip.wav";
+			sonicVizBeatsFilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeTwo_5/PennyArcade_take5_beats.txt";
+			break;	
+			
+			
+			
+	}
+	if (kickfilename != NULL){
+		
+		loadAudioTrack(kickfilename, 0);
+	}
+	
+	if (roomfilename != NULL){	
+		printf("roomfilename: %s\n", roomfilename);
+		loadAudioTrack(roomfilename, 1);
+	}
+	
+	if (snarefilename != NULL)
+		loadAudioTrack(snarefilename, 2);
+	
+	if (sonicVizBeatsFilename.c_str() != NULL){
+		readInBeatsFile(sonicVizBeatsFilename);
+		printBeatTimes();
+		checkFileErrors(0);
+		checkFileErrors(2);
+		findBeatOnsets();
+	}
+}
+
+void RecordedMultipleAudio::loadAudioTrack(std::string name, const int& channel){
+	//kick - track type 0
+	//bass - type 1
+	//snare type 2
+	//guitar type 3
+	if (channel >= 0 && channel <= numberOfAudioTracks){
+	loadedAudioPtr = new LoadedAudioHolder;
+	//set tracktype before we do analysis
+	//so we dont do unnecessary chroma and pitch calculations
+		if (channel == 0 || channel == 2){
+			loadedAudioPtr->setTrackType(channel);
+		}
+		else{
+			loadedAudioPtr->setTrackType(0);
+		}
+	loadedAudioPtr->loadAudioFile(name);
+		
+	loadedAudioFiles[channel] = *loadedAudioPtr;
+	loadedAudioFiles[channel].fileLoader.onsetDetect.window.setToRelativeSize(0, trackScreenHeight*channel, 1, trackScreenHeight);
+	//loadedAudioFiles[channel].setTrackType(channel);
+	}
+}
+
+
+
+void RecordedMultipleAudio::readInBeatsFile(std::string& pathName){
+	
+	// "/Users/andrew/Documents/work/MuseScore/RWC/ANNOTATION/RM-C002_annotation+WavPos.csv"
+	beatTimes.clear();
+	
+	printf("- - - - \n\nREAD FILE %s\n", pathName.c_str());
+	ifstream file ( pathName.c_str());
+	string value, tmpLine;
+	stringstream iss;
+	int count = 0;
+	
+	while ( file.good() )
+	{
+		getline(file, tmpLine);
+		iss << tmpLine;
+		int lineCount = 0;
+		//			printf("tmp line %s\n", tmpLine.c_str());
+		while(getline ( iss, value, '\t' )){ // read a string until next comma: http://www.cplusplus.com/reference/string/getline/
+			//	cout << string( value, 1, value.length()-2 ); // display value removing the first and the last character from it
+			//		printf("line:%s\n", value.c_str());
+			string::size_type start = value.find_first_not_of(" ,\t\v\n");
+			
+			string part = value.substr(start, string::npos);
+			
+			//printf("%s\n", firstpart.c_str());
+			if (lineCount == 0){
+				//printf("First part of line found '%s'\n", part.c_str());
+				double newBeatTime = atof(part.c_str());
+				beatTimes.push_back(newBeatTime);
+			}
+			lineCount++;
+			
+		}//end while reading line
+		iss.clear();
+		
+		
+	}//end while
+	
+	//	printBeatTimes();
+	printf("There are %i BEAT annotations\n", (int)beatTimes.size());
+	
+}
+
+void RecordedMultipleAudio::printBeatTimes(){
+	for (int i = 0;i < beatTimes.size();i++){
+		printf("Beat[%i] = %f\n", i, beatTimes[i]);
+	}
+}
+
+
+void RecordedMultipleAudio::checkFileErrors(int channel){
+	int beatIndex = 0;
+	int cutoff = 50;//ms width to check
+	for (int i = 0;i < loadedAudioFiles[channel].onsetTimesMillis.size();i++){
+		while (beatIndex < beatTimes.size() && 1000.0*beatTimes[beatIndex] < loadedAudioFiles[channel].onsetTimesMillis[i] - cutoff) {
+			beatIndex++;
+		}
+		double error = (1000.0*beatTimes[beatIndex] - loadedAudioFiles[channel].onsetTimesMillis[i]);
+		if (fabs(error) < cutoff){
+			if (channel == 0) 
+				printf("Pos: %i Beat Time %f Kick Time %f Error %f\n", beatIndex%4, 1000.0*beatTimes[beatIndex], loadedAudioFiles[0].onsetTimesMillis[i], error);
+			else 
+				printf("Pos: %i Beat Time %f Snare Time %f Error %f\n", beatIndex%4, 1000.0*beatTimes[beatIndex], loadedAudioFiles[0].onsetTimesMillis[i], error);
+			
+		}else{
+			if (channel == 0) 
+				printf("Out of Beat: Kick Time %f beat error %f\n", 1000.0*beatTimes[beatIndex], loadedAudioFiles[0].onsetTimesMillis[i], error);
+			else 
+				printf("Out of Beat: %f Snare Time %f best error %f\n", 1000.0*beatTimes[beatIndex], loadedAudioFiles[0].onsetTimesMillis[i], error);
+			
+		}
+	}
+}
+
+
+#pragma mark -labelExactOnsets
+
+void RecordedMultipleAudio::findBeatOnsets(){
+//tries to find kicks on 1, 3; snares on 2,4
+	int beatIndex = 0;
+	int kickIndex = 0;
+	int snareIndex = 0;
+	double kickTime, snareTime;
+	int cutoff = 50;//ms width to check
+	
+	onsetInfo.clear();
+	
+//	kickErrors.clear();
+//	snareErrors.clear();
+	
+	bool beatFound;
+	for (int k = 0;k < beatTimes.size();k++){
+		beatFound = false;
+		double newBeatTime = beatTimes[k]*1000.0;
+		int beatPosition = k % 4;
+		OnsetInformation information;
+		switch (beatPosition) {
+			case 0: case 2://check for kick when it is on the `one' or 'three' (0 or 2 in our metrical position)
+			//	printf("check %i kindex %i\n", beatPosition, kickIndex);
+				while (kickIndex < loadedAudioFiles[0].onsetTimesMillis.size() && loadedAudioFiles[0].onsetTimesMillis[kickIndex] < newBeatTime - cutoff){
+					kickIndex++;
+					kickTime = loadedAudioFiles[0].onsetTimesMillis[kickIndex];
+			//		printf("checking beat[%i] %f kick %f error %f\n", k, beatTimes[k]*1000.0, kickTime, (kickTime - beatTimes[k]*1000.0));
+					if (fabs(kickTime - beatTimes[k]*1000.0) < cutoff){
+						beatFound = true;
+						printf("beat[%i] %f kick %f error %f\n", k, beatTimes[k]*1000.0, kickTime, (kickTime - beatTimes[k]*1000.0));
+
+						information.error = (kickTime - beatTimes[k]*1000.0);//FOR NOW ONLY
+						information.metricalPosition = beatPosition;
+						information.type = 0;	
+						information.exactOnsetTime = kickTime;
+			//			exactBeatPositions.push_back(kickTime);
+					}
+				}
+				
+				break;
+			case 1: case 3://snare
+				while (snareIndex < loadedAudioFiles[1].onsetTimesMillis.size() && loadedAudioFiles[1].onsetTimesMillis[snareIndex] < newBeatTime - cutoff ){
+					snareIndex++;
+					snareTime = loadedAudioFiles[1].onsetTimesMillis[snareIndex];
+					if (fabs(snareTime - beatTimes[k]*1000.0) < cutoff){
+						beatFound = true;
+					//	snareErrors.push_back((beatTimes[k]*1000.0 - snareTime));
+						information.error = (snareTime - beatTimes[k]*1000.0);
+						information.metricalPosition = beatPosition;//.push_back(beatPosition);
+						information.type = 1;
+						information.exactOnsetTime = snareTime;
+						printf("beat[%i] %f snare %f error %f\n", k, beatTimes[k]*1000.0, snareTime, (snareTime - beatTimes[k]*1000.0));
+			//			exactBeatPositions.push_back(snareTime);
+					}
+				}
+				
+				break;
+		}
+		if (!beatFound){
+			information.type = -1;//not a kick or snare
+			information.exactOnsetTime = beatTimes[k]*1000.0;
+			information.metricalPosition = beatPosition;//.push_
+		//	exactBeatPositions.push_back(beatTimes[k]*1000.0);//have to go with the annotated beat instead (no matching kick or snare)
+			
+			printf("beat[%i] %f NOT FOUND, kicktime %f snaretime %f\n", k, beatTimes[k]*1000.0, kickTime, snareTime );
+		}
+		
+		onsetInfo.push_back(information);
+		
+	}//end for all beat annotations
+
+	correctExactBeatTiming();//get rid of the first onset time
+	
+	calculateTimingAnalysis();
+	
+}
+
+#pragma mark -doTimingAnalysis
+void RecordedMultipleAudio::correctExactBeatTiming(){
+	//get rid of firtst onset time
+	if (onsetInfo.size() > 0){
+		timingOffset = onsetInfo[0].exactOnsetTime;//s[0];
+		double tmpPosn;
+		for (int i = 0;i < onsetInfo.size();i++){
+			onsetInfo[i].beatTimeToProcess = onsetInfo[i].exactOnsetTime - timingOffset;
+			printf("exact [%i] type %i %f, corrected %f\n", i, onsetInfo[i].type, onsetInfo[i].exactOnsetTime, onsetInfo[i].beatTimeToProcess );
+		}
+	}
+}
+
+void RecordedMultipleAudio::calculateTimingAnalysis(){
+	
+	for (int i = 0;i < onsetInfo.size();i++){
+		drumTimingAnalyser.updateCostToPoint(onsetInfo[i].beatTimeToProcess, i);
+		//updatecounter is the beat position for this note event - can be used to do other kinds of durations than just simple beats
+		
+		drumTimingAnalyser.beatPosition.push_back(onsetInfo[i].exactOnsetTime);
+	}
+	drumTimingAnalyser.processPathHistory();
+	drumTimingAnalyser.calculateTempoLimits();
+
+	getErrorTimesFromAnalysis();
+	
+	alternativeKickRelativeAnalysis();
+	
+	exportErrorInformation();
+	
+	displayKickRelativeMedianErrors();//NB messes ther order of these
+	
+	//this was how we did it in multimatch program
+//	timer.processPathHistory();
+//	timer.calculateTempoLimits();
+//	timer.exportTimingData();
+//	timer.exportProcessedBeatTimes(firstNoteTime);
+}
+
+void RecordedMultipleAudio::getErrorTimesFromAnalysis(){
+	printf("\nDrumTimingLoader: get error times from analysis!!!\n");
+	setUpErrorsByMetricalPosition();
+	//gets the errors from the drum timing analyser (i.e. ISMIR paper code) and attributes these to the onsets
+	for (int i = 0;i < drumTimingAnalyser.timingData.size();i++){
+		onsetInfo[i].error = drumTimingAnalyser.timingData[i][5];
+		onsetInfo[i].clickTime = drumTimingAnalyser.timingData[i][1] + timingOffset;//this is where teh timing analyser placed the click times
+		errorsByMetricalPosition[onsetInfo[i].metricalPosition].push_back(onsetInfo[i].error);
+		printf("beat %i metrical posn %i exact beat time %f error %i\n", i, onsetInfo[i].metricalPosition, onsetInfo[i].exactOnsetTime, (int)onsetInfo[i].error);
+	}
+	displayMedianErrors();
+}
+
+
+void RecordedMultipleAudio::alternativeKickRelativeAnalysis(){
+	printf("\n\nAnalysis Relative to the Kick Drum on the ONE\n");
+	//this sees kicks as ON the beat, looks at relative error of the three other beats if we chop the bar evenly
+	
+	double recentBeatTime, currentTempo;	
+	kickRelativeErrors.clear();
+	kickRelativeClickTimes.clear();
+	
+	for (int i = 0;i < drumTimingAnalyser.timingData.size();i++){
+		int beatPosition = i%4;
+		if (beatPosition == 0){
+			recentBeatTime = onsetInfo[i].exactOnsetTime;
+			if (i+4 < onsetInfo.size())
+				currentTempo =  (onsetInfo[i+4].exactOnsetTime - onsetInfo[i].exactOnsetTime)/4.0;
+			printf("new beat time %f tempo %f\n", recentBeatTime, currentTempo);
+		}
+		double error = onsetInfo[i].exactOnsetTime - (recentBeatTime + beatPosition*currentTempo);
+		printf("Beat %i KR Predicted Beat %f Actual exact %f KRerror %f DTerror %i\n", beatPosition, (recentBeatTime + beatPosition*currentTempo), onsetInfo[i].exactOnsetTime, error, (int)onsetInfo[i].error); 
+		kickRelativeErrors.push_back(error);
+		kickRelativeClickTimes.push_back(recentBeatTime + beatPosition*currentTempo);
+	}
+}
+
+#pragma label -exportInfo
+void RecordedMultipleAudio::exportErrorInformation(){
+	printf("Export final timing information\n");
+	
+	ofstream ofs(infoFilepath.c_str());
+	for (int i = 0;i < onsetInfo.size() && kickRelativeErrors.size();i++){// drumTimingAnalyser.timingData.size()
+		ofs << i << "," << (i%4) << "," << onsetInfo[i].exactOnsetTime << ",";
+		ofs << onsetInfo[i].clickTime << "," << onsetInfo[i].error << ",";//the error for the ISMIR timing analyser
+		ofs << kickRelativeClickTimes[i] << "," << kickRelativeErrors[i];//the click and error for beats evenly between kicks
+		ofs << endl;
+	}
+	
+}
+
+void RecordedMultipleAudio::printKickRelativeErrors(){
+	for (int i = 0;i < kickRelativeErrors.size();i++){
+	printf("KR error [%i] : %.1f\n", i, kickRelativeErrors[i]);
+	}
+}
+
+void RecordedMultipleAudio::setUpErrorsByMetricalPosition(){
+	//clear this matrix
+	errorsByMetricalPosition.clear();
+	for (int i = 0;i < 4;i++){
+		DoubleVector v;
+		errorsByMetricalPosition.push_back(v);
+	}
+	
+}
+
+void RecordedMultipleAudio::displayMedianErrors(){
+	printf("Medians of the Decoded Tempo variations\n");
+	for (int i = 0;i < 4;i++){
+		//printErrorsForMetricalPosition(i);
+		std::sort(errorsByMetricalPosition[i].begin(), errorsByMetricalPosition[i].end());//sort vector
+		double median = errorsByMetricalPosition[i][(int)(errorsByMetricalPosition[i].size()/2)];
+		printf("median for metrical position %i is %f\n", i, median);
+	}
+}
+
+
+void RecordedMultipleAudio::displayKickRelativeMedianErrors(){
+	printf("Medians of the KR variations\n");
+	
+	DoubleVector tmpKRErrors;
+
+	
+	for (int i = 0;i < 4;i++){
+		
+		tmpKRErrors.clear();
+		int index = 0;
+		
+		while (index+i < kickRelativeErrors.size()) {
+			tmpKRErrors.push_back(kickRelativeErrors[index + i]);
+			index += 4;
+		}
+		
+//		for (int k = 0;k < tmpKRErrors.size();k++)
+//		printf("kr %i [%i] = %f\n", i, k, tmpKRErrors[k]);						  
+								  
+		//printErrorsForMetricalPosition(i);
+		std::sort(tmpKRErrors.begin(), tmpKRErrors.end());//sort vector
+		
+//		for (int k = 0;k < tmpKRErrors.size();k++)
+//			printf("sorted kr %i [%i] = %f\n", i, k, tmpKRErrors[k]);
+		
+		
+		double median = tmpKRErrors[(int)(tmpKRErrors.size()/2)];
+		printf("median for metrical position %i is %f\n", i, median);
+	}
+}
+
+void RecordedMultipleAudio::printErrorsForMetricalPosition(const int& i){
+	for (int k = 0;k < errorsByMetricalPosition[i].size();k++){
+		printf("metrical posn %i, [%i] = %f\n", i, k,  errorsByMetricalPosition[i][k]);
+	}
+}
+
+#pragma mark -drawTracks
+
+void RecordedMultipleAudio::drawTracks(){
+	if (drawWindow == 0){
+		for (int i = 0;i < numberOfAudioTracks;i++){		
+			loadedAudioFiles[i].draw();
+		}
+	} else {
+		drumTimingAnalyser.drawTempoCurve();
+	}
+}
+
+#pragma mark -update 
+void RecordedMultipleAudio::updatePosition(){
+	for (int i = 0;i < numberOfAudioTracks;i++)
+		loadedAudioFiles[i].updateToPlayPosition();
+}
+
+void RecordedMultipleAudio::updatePositionToMillis(const double& millis){
+	for (int i = 0;i < numberOfAudioTracks;i++)
+		loadedAudioFiles[i].updateToMillisPosition(millis);
+}
+
+void RecordedMultipleAudio::updatePlaybackPositionToMillis(const double& millis){
+	for (int i = 0;i < numberOfAudioTracks;i++)
+		loadedAudioFiles[i].updatePlaybackPositionToMillis(millis);
+}
+
+void RecordedMultipleAudio::switchScreens(){
+	for (int i = 0;i < numberOfAudioTracks;i++)
+		loadedAudioFiles[i].switchScreens();
+}
+
+
+void RecordedMultipleAudio::togglePlay(){
+	for (int i = 0;i < numberOfAudioTracks;i++)
+		loadedAudioFiles[i].togglePlay();
+}
+
+void RecordedMultipleAudio::stop(){
+	for (int i = 0;i < numberOfAudioTracks;i++)
+		loadedAudioFiles[i].stop();
+}
+
+
+void RecordedMultipleAudio::printInfo(){
+	loadedAudioFiles[0].fileLoader.onsetDetect.printChromaInfo();
+	loadedAudioFiles[0].printEvents();
+}
+
+void RecordedMultipleAudio::windowResized(const int& w, const int& h){
+	for (int i = 0;i < numberOfAudioTracks;i++)
+		loadedAudioFiles[i].windowResized(w, h);
+}
+
+void RecordedMultipleAudio::zoomIn(){
+	if (drawWindow == 0){
+		printf("zoom in\n");
+		for (int i = 0;i < numberOfAudioTracks;i++)
+			loadedAudioFiles[i].fileLoader.zoomIn();	
+	}
+	
+	if (drawWindow == 1)
+		drumTimingAnalyser.zoomIn();//numberOfPointsPerPage /= 2;
+}
+
+void RecordedMultipleAudio::zoomOut(){
+		printf("zoom out\n");
+	for (int i = 0;i < numberOfAudioTracks;i++)
+		loadedAudioFiles[i].fileLoader.zoomOut();
+	
+	if (drawWindow == 1)
+		drumTimingAnalyser.zoomOut();//numberOfPointsPerPage *= 2;
+	
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DrumTimingLoader_OF/src/RecordedMultipleAudio.h	Mon Oct 01 22:24:32 2012 +0100
@@ -0,0 +1,105 @@
+/*
+ *  RecordedMultipleAudio.h
+ *  MultipleAudioMathcher
+ *
+ *  Created by Andrew on 31/01/2012.
+ *  Copyright 2012 QMUL. All rights reserved.
+ *
+ */
+
+
+#ifndef RECORDED_MULTIPLE_AUDIO_H
+#define RECORDED_MULTIPLE_AUDIO_H
+
+
+#include "ofMain.h"
+#include "ChromaOnset.h"
+#include "LoadedAudioHolder.h"
+#include "TimingAnalyser.h"
+
+typedef std::vector<double> DoubleVector;
+typedef std::vector<int> IntVector;
+
+struct OnsetInformation{//stores all the beat positions, the onset type and metrical position
+	double error;
+	int metricalPosition;
+	double exactOnsetTime;
+	double beatTimeToProcess;
+	double clickTime;//from the Timing Analyser
+	int type;//0 for kick, 1 for snare
+};
+
+typedef std::vector<OnsetInformation> OnsetVector;
+
+class RecordedMultipleAudio{
+	
+	public:
+	RecordedMultipleAudio();
+	
+	void loadTestAudio();
+	void updatePosition();
+	void updatePositionToMillis(const double& millis);
+	void updatePlaybackPositionToMillis(const double& millis);
+	
+	void drawTracks();
+	void switchScreens();
+	void togglePlay();
+	
+	void stop();
+	void printInfo();
+	void windowResized(const int& w, const int& h);
+	void zoomIn();
+	void zoomOut();
+	void setDifferentMultitracks(const int& setToLoad);
+	void loadAudioTrack(std::string name, const int& channel);
+//	void matchNewPitchEvent(const int& channel, const double& pitchIn, const double& timeIn);
+
+//	bool checkMatch(const double& recordedPitch, const double& livePitch);
+	
+	//variables
+	int numberOfAudioTracks;
+	LoadedAudioHolder* loadedAudioPtr;
+	LoadedAudioHolder loadedAudioFiles[5];
+	
+	double trackScreenHeight;
+	
+	
+	//Sonic Vizualiser Beats code
+	void readInBeatsFile(std::string& pathName);
+	void printBeatTimes();
+
+	DoubleVector beatTimes;
+	void checkFileErrors(int channel);
+	void findBeatOnsets();
+
+//	OnsetInformation kickInformation, snareInformation;
+	
+	TimingAnalyser drumTimingAnalyser;
+	
+//	DoubleVector exactBeatPositions;
+	OnsetVector onsetInfo;
+	double timingOffset;
+	void correctExactBeatTiming();
+	void calculateTimingAnalysis();
+	void getErrorTimesFromAnalysis();
+	void setUpErrorsByMetricalPosition();
+	void displayMedianErrors();
+	void printErrorsForMetricalPosition(const int& i);
+	
+	DoubleMatrix errorsByMetricalPosition;
+//	DoubleVector kickErrors, snareErrors;
+	int drawWindow;
+	//plan is
+	//we get beats via the beatTimes vector
+	//then get new EXACT beat times by looking for the nearby kicks and snares
+	//these should go into
+	
+	DoubleVector kickRelativeErrors;
+	void printKickRelativeErrors();
+	void alternativeKickRelativeAnalysis();
+	DoubleVector kickRelativeClickTimes;
+	std::string infoFilepath;
+	void exportErrorInformation();
+	void displayKickRelativeMedianErrors();
+};
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DrumTimingLoader_OF/src/main.cpp	Mon Oct 01 22:24:32 2012 +0100
@@ -0,0 +1,16 @@
+#include "ofMain.h"
+#include "testApp.h"
+#include "ofAppGlutWindow.h"
+
+//========================================================================
+int main( ){
+
+    ofAppGlutWindow window;
+	ofSetupOpenGL(&window, 1024,768, OF_WINDOW);			// <-------- setup the GL context
+
+	// this kicks off the running of my app
+	// can be OF_WINDOW or OF_FULLSCREEN
+	// pass in width and height too:
+	ofRunApp( new testApp());
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DrumTimingLoader_OF/src/testApp.cpp	Mon Oct 01 22:24:32 2012 +0100
@@ -0,0 +1,71 @@
+#include "testApp.h"
+
+//--------------------------------------------------------------
+void testApp::setup(){
+	drumTimer.initialise();
+}
+
+//--------------------------------------------------------------
+void testApp::update(){
+
+}
+
+//--------------------------------------------------------------
+void testApp::draw(){
+	drumTimer.draw();
+}
+
+//--------------------------------------------------------------
+void testApp::keyPressed(int key){
+
+	
+	if (key == OF_KEY_UP){
+		drumTimer.recordedTracks.zoomOut();
+		
+	}
+	
+	if (key == OF_KEY_DOWN){
+		drumTimer.recordedTracks.zoomIn();
+	}
+	
+}
+
+//--------------------------------------------------------------
+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){
+
+}
+
+//--------------------------------------------------------------
+void testApp::mouseReleased(int x, int y, int button){
+
+}
+
+//--------------------------------------------------------------
+void testApp::windowResized(int w, int h){
+	drumTimer.windowResized(w, h);
+}
+
+//--------------------------------------------------------------
+void testApp::gotMessage(ofMessage msg){
+
+}
+
+//--------------------------------------------------------------
+void testApp::dragEvent(ofDragInfo dragInfo){ 
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DrumTimingLoader_OF/src/testApp.h	Mon Oct 01 22:24:32 2012 +0100
@@ -0,0 +1,27 @@
+#pragma once
+
+#include "ofMain.h"
+
+#include "DrumTimingLoader.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);
+		
+		DrumTimingLoader drumTimer;
+		
+	
+};