diff DrumTimingLoader_OF/src/RecordedMultipleAudio.cpp @ 2:50ba55abea8c

updating files to newer version
author Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk>
date Sat, 23 Nov 2013 15:49:27 +0000
parents 82352cfc0b23
children
line wrap: on
line diff
--- a/DrumTimingLoader_OF/src/RecordedMultipleAudio.cpp	Sat Nov 23 15:44:47 2013 +0000
+++ b/DrumTimingLoader_OF/src/RecordedMultipleAudio.cpp	Sat Nov 23 15:49:27 2013 +0000
@@ -1,6 +1,6 @@
 /*
  *  RecordedMultipleAudio.cpp
- *  MultipleAudioMathcher
+ *  Drum Timing Analyser
  *
  *  Created by Andrew on 31/01/2012.
  *  Copyright 2012 QMUL. All rights reserved.
@@ -9,26 +9,42 @@
 
 #include "RecordedMultipleAudio.h"
 
+const bool printExportInfo = false;
+
 RecordedMultipleAudio::RecordedMultipleAudio(){
 	
 	infoFilepath = "../../../data/errorData.txt";
+	
+	exactOnsetFilePath = "../../../data/exactOnsetTimes.txt";
+	kickRelativeTempoFilePath = "../../../data/kickRelativeTempoTimes.txt";
+	kickRelativeErrorsFilePath = "../../../data/kickRelativeErrorTimes.txt";	
+	kickRelativeClickFilePath = "../../../data/kickRelativeClickTimes.txt";
+	
+	drumTimerTempoFilePath = "../../../data/drummerTimerTempoTimes.txt";
+	drumTimerErrorsFilePath = "../../../data/drummerTimerErrorTimes.txt";
+	drumTimerClickFilePath = "../../../data/drummerTimerClickTimes.txt";
+	
 	//infoFilepath = "/Users/andrew/errorData.txt";
 	
 	timingOffset = 0;
+	playPositionSeconds = 3.4;
 }
 
 void RecordedMultipleAudio::loadTestAudio(){
 
+	int multitrackToLoad = 7;
 
 	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;
 	
@@ -82,35 +98,71 @@
 			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;	
+		*/	
+		case 5:
+			roomfilename = "/Volumes/MiniSaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeTwo_5/neuamnn_bip.wav";
+			kickfilename = "/Volumes/MiniSaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeTwo_5/kick_bip.wav";
+			snarefilename = "/Volumes/MiniSaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeTwo_5/snare_bip.wav";
+			sonicVizBeatsFilename = "/Volumes/MiniSaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeTwo_5/PennyArcade_take5_beats.txt";
+			break;		
 			
 			
+		case 6:
+			roomfilename = "/Users/andrew/Documents/work/Alignment/FunkyDrummerAnalysis/FunkyDrummerBreak.wav";
+			kickfilename = "/Users/andrew/Documents/work/Alignment/FunkyDrummerAnalysis/FunkyDrummerBreak.wav";
+			snarefilename = "/Users/andrew/Documents/work/Alignment/FunkyDrummerAnalysis/FunkyDrummerBreak.wav";
+			sonicVizBeatsFilename = "/Users/andrew/Documents/work/Alignment/FunkyDrummerAnalysis/FunkyDrummerBeats.txt";
+			break;		
+			
+		case 7:
+			roomfilename = "/Users/andrew/Music/Logic/Tractors_April13/tractorIsaak2/Bounces/Take23_mono.wav";
+			kickfilename = "/Users/andrew/Music/Logic/Tractors_April13/tractorIsaak2/Bounces/Take23_mono.wav";
+			snarefilename = "/Users/andrew/Music/Logic/Tractors_April13/tractorIsaak2/Bounces/Take23_mono.wav";
+			sonicVizBeatsFilename = "/Users/andrew/Music/Logic/Tractors_April13/tractorIsaak2/Bounces/IsaakTake23MonoBeats.txt";
+			break;		
+			
 			
 	}
 	if (kickfilename != NULL){
-		
+		printf("Loading Kick file: %s\n", kickfilename);
 		loadAudioTrack(kickfilename, 0);
 	}
 	
 	if (roomfilename != NULL){	
-		printf("roomfilename: %s\n", roomfilename);
+		printf("loading room: %s\n", roomfilename);
 		loadAudioTrack(roomfilename, 1);
 	}
 	
-	if (snarefilename != NULL)
+	if (snarefilename != NULL){
+		printf("Loading Snare file: %s\n", kickfilename);
 		loadAudioTrack(snarefilename, 2);
+	}
 	
 	if (sonicVizBeatsFilename.c_str() != NULL){
+		printf("Reading sonic viz beats: %s\n", sonicVizBeatsFilename.c_str());
 		readInBeatsFile(sonicVizBeatsFilename);
 		printBeatTimes();
 		checkFileErrors(0);
 		checkFileErrors(2);
 		findBeatOnsets();
+		
+		exportErrorInformation();
+		exportExactOnsetTimes();
+		
+		exportKickRelativeTempoTimes();
+		exportKickRelativeErrorTimes();
+		exportKickRelativeClickTimes();
+		
+		exportDrumTimerTempoTimes();
+		exportDrumTimerErrorTimes();
+		exportDrumTimerClickTimes();
 	}
 }
 
@@ -177,7 +229,7 @@
 		
 	}//end while
 	
-	//	printBeatTimes();
+		
 	printf("There are %i BEAT annotations\n", (int)beatTimes.size());
 	
 }
@@ -191,8 +243,11 @@
 
 void RecordedMultipleAudio::checkFileErrors(int channel){
 	int beatIndex = 0;
-	int cutoff = 50;//ms width to check
+	int cutoff = 60;//ms width to check
 	for (int i = 0;i < loadedAudioFiles[channel].onsetTimesMillis.size();i++){
+		
+		printf("onset time %i ms %i frames ", (int)loadedAudioFiles[channel].onsetTimesMillis[i], (int)loadedAudioFiles[channel].onsetTimesFrames[i]);
+		
 		while (beatIndex < beatTimes.size() && 1000.0*beatTimes[beatIndex] < loadedAudioFiles[channel].onsetTimesMillis[i] - cutoff) {
 			beatIndex++;
 		}
@@ -205,9 +260,9 @@
 			
 		}else{
 			if (channel == 0) 
-				printf("Out of Beat: Kick Time %f beat error %f\n", 1000.0*beatTimes[beatIndex], loadedAudioFiles[0].onsetTimesMillis[i], error);
+				printf("Ch.0 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);
+				printf("Ch.2 Out of Beat: %f Snare Time %f best error %f\n", 1000.0*beatTimes[beatIndex], loadedAudioFiles[0].onsetTimesMillis[i], error);
 			
 		}
 	}
@@ -235,6 +290,7 @@
 		double newBeatTime = beatTimes[k]*1000.0;
 		int beatPosition = k % 4;
 		OnsetInformation information;
+		double bestBeatDifference = 1000;//i.e. high
 		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);
@@ -242,14 +298,15 @@
 					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){
+					if (fabs(kickTime - beatTimes[k]*1000.0) < cutoff && fabs(kickTime - beatTimes[k]*1000.0) < bestBeatDifference){
 						beatFound = true;
-						printf("beat[%i] %f kick %f error %f\n", k, beatTimes[k]*1000.0, kickTime, (kickTime - beatTimes[k]*1000.0));
+						printf("beat[%i] pos %i time %f kick %f error %f\n", k, beatPosition, 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;
+						bestBeatDifference = fabs(kickTime - beatTimes[k]*1000.0);
 			//			exactBeatPositions.push_back(kickTime);
 					}
 				}
@@ -259,14 +316,15 @@
 				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){
+					if (fabs(snareTime - beatTimes[k]*1000.0) < cutoff && fabs(snareTime - beatTimes[k]*1000.0) < bestBeatDifference){
 						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));
+						bestBeatDifference = fabs(snareTime - beatTimes[k]*1000.0);
+						printf("beat[%i] pos %i tim e%f snare %f error %f\n", k, beatPosition, beatTimes[k]*1000.0, snareTime, (snareTime - beatTimes[k]*1000.0));
 			//			exactBeatPositions.push_back(snareTime);
 					}
 				}
@@ -290,6 +348,9 @@
 	
 	calculateTimingAnalysis();
 	
+	
+	//so our exact beat times are then information.exactOnsetTime
+	
 }
 
 #pragma mark -doTimingAnalysis
@@ -320,8 +381,6 @@
 	
 	alternativeKickRelativeAnalysis();
 	
-	exportErrorInformation();
-	
 	displayKickRelativeMedianErrors();//NB messes ther order of these
 	
 	//this was how we did it in multimatch program
@@ -339,7 +398,8 @@
 		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);
+		printf("beat %i metrical posn %i exact onset time %f click time %i error %i\n", i, onsetInfo[i].metricalPosition, onsetInfo[i].exactOnsetTime, 
+			   onsetInfo[i].clickTime, (int)onsetInfo[i].error);
 	}
 	displayMedianErrors();
 }
@@ -352,23 +412,25 @@
 	double recentBeatTime, currentTempo;	
 	kickRelativeErrors.clear();
 	kickRelativeClickTimes.clear();
+	kickRelativeTempo.clear();
 	
 	for (int i = 0;i < drumTimingAnalyser.timingData.size();i++){
 		int beatPosition = i%4;
-		if (beatPosition == 0){
+		if (beatPosition == 0){//then divide kicks and get even division
 			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); 
+		printf("Beat %i KR Predicted Beat: %f Onset: %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);
+		kickRelativeTempo.push_back(currentTempo);
 	}
 }
 
-#pragma label -exportInfo
+#pragma mark -exportInfo
 void RecordedMultipleAudio::exportErrorInformation(){
 	printf("Export final timing information\n");
 	
@@ -382,6 +444,93 @@
 	
 }
 
+
+void RecordedMultipleAudio::exportExactOnsetTimes(){
+	printf("Export exact beat times\n");
+	
+	ofstream ofs(exactOnsetFilePath.c_str());
+	for (int i = 0;i < onsetInfo.size();i++){// drumTimingAnalyser.timingData.size()
+		ofs << onsetInfo[i].exactOnsetTime/1000.0 << endl;
+		if (printExportInfo)
+			printf("exporting exact beat times %f\n", onsetInfo[i].exactOnsetTime);
+	}
+}
+
+void RecordedMultipleAudio::exportKickRelativeTempoTimes(){
+	printf("Export kick relative Tempo times\n");
+	
+	ofstream ofs(kickRelativeTempoFilePath.c_str());
+	for (int i = 0;i < kickRelativeTempo.size() && i < onsetInfo.size();i++){
+		ofs << onsetInfo[i].exactOnsetTime << "\t" << kickRelativeTempo[i] << endl;
+		if (printExportInfo)
+			printf("exporting tempo[%i]: onset %f %f\n", i, onsetInfo[i].exactOnsetTime, kickRelativeTempo[i]);
+	}	
+}
+
+void RecordedMultipleAudio::exportKickRelativeErrorTimes(){
+	printf("Export kick relative Error times\n");
+	
+	ofstream ofs(kickRelativeErrorsFilePath.c_str());
+	for (int i = 0;i < kickRelativeErrors.size() && i < onsetInfo.size();i++){
+		ofs << onsetInfo[i].exactOnsetTime << "\t" << kickRelativeErrors[i] << endl;
+		if (printExportInfo)
+			printf("exporting tempo[%i]: onset %f %f\n", i, onsetInfo[i].exactOnsetTime, kickRelativeErrors[i]);
+	}	
+}
+
+void RecordedMultipleAudio::exportKickRelativeClickTimes(){
+	printf("Export kick relative click times\n");
+	
+	ofstream ofs(kickRelativeClickFilePath.c_str());
+	for (int i = 0;i < kickRelativeClickTimes.size();i++){
+		ofs << kickRelativeClickTimes[i]/1000.0 << endl;
+		if (printExportInfo)
+			printf("exporting KD click [%i]:%f\n", i,kickRelativeClickTimes[i]);
+	}	
+}
+
+
+void RecordedMultipleAudio::exportDrumTimerTempoTimes(){
+	printf("Export drum timing tempo times\n");
+	
+	ofstream ofs(drumTimerTempoFilePath.c_str());
+	for (int i = 0;i < drumTimingAnalyser.timingData.size() && i < onsetInfo.size();i++){
+		ofs << onsetInfo[i].exactOnsetTime << "\t" << drumTimingAnalyser.timingData[i][0] << endl;
+		if (printExportInfo)
+			printf("exporting tempo[%i]: onset %f tempo %i\n", i, onsetInfo[i].exactOnsetTime, drumTimingAnalyser.timingData[i][0]);
+	}	
+}
+
+
+void RecordedMultipleAudio::exportDrumTimerErrorTimes(){
+	printf("Export drum timing Error times\n");
+	
+	ofstream ofs(drumTimerErrorsFilePath.c_str());
+	for (int i = 0;i < drumTimingAnalyser.timingData.size() && i < onsetInfo.size();i++){
+		ofs << onsetInfo[i].exactOnsetTime << "\t" << drumTimingAnalyser.timingData[i][5] << endl;
+		if (printExportInfo)
+			printf("exporting [%i]: onset %f error %i\n", i, onsetInfo[i].exactOnsetTime, drumTimingAnalyser.timingData[i][5]);
+	}	
+}
+
+
+void RecordedMultipleAudio::exportDrumTimerClickTimes(){
+	printf("Export drum timing Click times\n");
+	
+	ofstream ofs(drumTimerClickFilePath.c_str());
+	for (int i = 0;i < onsetInfo.size();i++){
+		ofs << onsetInfo[i].clickTime/1000.0 << endl;
+		if (printExportInfo)
+			printf("exporting click[%i] %i\n", i, onsetInfo[i].clickTime);
+	}	
+}
+
+
+
+
+
+
+
 void RecordedMultipleAudio::printKickRelativeErrors(){
 	for (int i = 0;i < kickRelativeErrors.size();i++){
 	printf("KR error [%i] : %.1f\n", i, kickRelativeErrors[i]);
@@ -456,12 +605,23 @@
 	} else {
 		drumTimingAnalyser.drawTempoCurve();
 	}
+	
+//	ofDrawBitmapString(ofToString(playPositionSeconds),20, 40);
 }
 
 #pragma mark -update 
 void RecordedMultipleAudio::updatePosition(){
 	for (int i = 0;i < numberOfAudioTracks;i++)
 		loadedAudioFiles[i].updateToPlayPosition();
+	
+	playPositionSeconds = samplesToSeconds(loadedAudioFiles[0].fileLoader.audioHolder.playPosition);
+	drumTimingAnalyser.updatePlayIndex(playPositionSeconds);
+	
+	
+}
+
+double RecordedMultipleAudio::samplesToSeconds(const double& samples){
+	return samples/44100.0;
 }
 
 void RecordedMultipleAudio::updatePositionToMillis(const double& millis){
@@ -474,12 +634,6 @@
 		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();
@@ -496,6 +650,7 @@
 	loadedAudioFiles[0].printEvents();
 }
 
+#pragma mark -ScreenFunctions
 void RecordedMultipleAudio::windowResized(const int& w, const int& h){
 	for (int i = 0;i < numberOfAudioTracks;i++)
 		loadedAudioFiles[i].windowResized(w, h);
@@ -522,4 +677,8 @@
 	
 }
 
+void RecordedMultipleAudio::switchScreens(){
+	for (int i = 0;i < numberOfAudioTracks;i++)
+		loadedAudioFiles[i].switchScreens();
+}