annotate DrumTimingLoader_OF/src/RecordedMultipleAudio.cpp @ 1:106bc2d4f702

added timing analyser file
author Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk>
date Sat, 23 Nov 2013 15:44:47 +0000
parents 82352cfc0b23
children 50ba55abea8c
rev   line source
andrew@0 1 /*
andrew@0 2 * RecordedMultipleAudio.cpp
andrew@0 3 * MultipleAudioMathcher
andrew@0 4 *
andrew@0 5 * Created by Andrew on 31/01/2012.
andrew@0 6 * Copyright 2012 QMUL. All rights reserved.
andrew@0 7 *
andrew@0 8 */
andrew@0 9
andrew@0 10 #include "RecordedMultipleAudio.h"
andrew@0 11
andrew@0 12 RecordedMultipleAudio::RecordedMultipleAudio(){
andrew@0 13
andrew@0 14 infoFilepath = "../../../data/errorData.txt";
andrew@0 15 //infoFilepath = "/Users/andrew/errorData.txt";
andrew@0 16
andrew@0 17 timingOffset = 0;
andrew@0 18 }
andrew@0 19
andrew@0 20 void RecordedMultipleAudio::loadTestAudio(){
andrew@0 21
andrew@0 22
andrew@0 23 numberOfAudioTracks = 2;
andrew@0 24
andrew@0 25 printf("loaded max val is %f\n", loadedAudioFiles[0].fileLoader.onsetDetect.onsetDetector.maximumDetectionValue);
andrew@0 26
andrew@0 27 int multitrackToLoad = 5;
andrew@0 28 setDifferentMultitracks(multitrackToLoad);//command to load this set of audio files - see below
andrew@0 29
andrew@0 30 drumTimingAnalyser.phaseCost = 1000;//v high - i.e. dont do phase
andrew@0 31
andrew@0 32 drawWindow = 1;
andrew@0 33 trackScreenHeight = 0.25;
andrew@0 34
andrew@0 35
andrew@0 36
andrew@0 37 // printf("AFTER LOADING: \n");
andrew@0 38 // printInfo();
andrew@0 39
andrew@0 40 }
andrew@0 41 #pragma mark -loadingPrerecordedTracks
andrew@0 42 void RecordedMultipleAudio::setDifferentMultitracks(const int& setToLoad){
andrew@0 43 const char *kickfilename ;//= "../../../data/sound/LiveDues/kick_liveDues.wav";
andrew@0 44 const char *roomfilename ;//"../../../data/sound/LiveDues/bass_upsideLive.wav";
andrew@0 45 const char *snarefilename ;
andrew@0 46 std::string sonicVizBeatsFilename ;
andrew@0 47
andrew@0 48 switch (setToLoad) {
andrew@0 49 case 0:
andrew@0 50 kickfilename = "/Users/andrew/Documents/work/programming/MadMax/AudioFiles/futureHides/kickFuture.wav";
andrew@0 51 roomfilename = "/Users/andrew/Documents/work/programming/MadMax/AudioFiles/futureHides/roomFuture.wav";
andrew@0 52 snarefilename = "/Users/andrew/Documents/work/programming/MadMax/AudioFiles/futureHides/snareFuture.wav";
andrew@0 53 sonicVizBeatsFilename = "/Users/andrew/Documents/work/programming/MadMax/AudioFiles/futureHides/FutureHidesBeats.txt";
andrew@0 54 break;
andrew@0 55
andrew@0 56
andrew@0 57 case 1:
andrew@0 58 roomfilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcadeStudio14aMultitrack/Mixdown/PennyArcade_StudioMixdown.wav";
andrew@0 59 kickfilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcadeStudio14aMultitrack/kick.wav";
andrew@0 60 snarefilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcadeStudio14aMultitrack/snare.wav";
andrew@0 61 sonicVizBeatsFilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcadeStudio14aMultitrack/Mixdown/PennyArcade_StudioMixdown_beats.txt";
andrew@0 62 break;
andrew@0 63
andrew@0 64 case 2:
andrew@0 65 roomfilename = "/Users/andrew/Documents/work/programming/MadMax/AudioFiles/MattIngramGreenSection/colesL_bip.wav";
andrew@0 66 kickfilename = "/Users/andrew/Documents/work/programming/MadMax/AudioFiles/MattIngramGreenSection/Kick_bip.wav";
andrew@0 67 snarefilename = "/Users/andrew/Documents/work/programming/MadMax/AudioFiles/MattIngramGreenSection/Snare_bip.wav";
andrew@0 68 sonicVizBeatsFilename = "/Users/andrew/Documents/work/programming/MadMax/AudioFiles/MattIngramGreenSection/IngramGreenSectionBeats.txt";
andrew@0 69 break;
andrew@0 70
andrew@0 71 case 3:
andrew@0 72 roomfilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDiamondWhite/tractorsDiamondWhite/Bounces/diamondWhiteMultiTakeOne/coles_bip.wav";
andrew@0 73 kickfilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDiamondWhite/tractorsDiamondWhite/Bounces/diamondWhiteMultiTakeOne/kick d112_bip.wav";
andrew@0 74 snarefilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDiamondWhite/tractorsDiamondWhite/Bounces/diamondWhiteMultiTakeOne/snare bottom_bip.wav";
andrew@0 75 sonicVizBeatsFilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDiamondWhite/tractorsDiamondWhite/Bounces/diamondWhiteMultiTakeOne/TakeOneBeats.txt";
andrew@0 76 break;
andrew@0 77
andrew@0 78 case 4:
andrew@0 79 roomfilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeOne_4/neuamnn_bip.wav";
andrew@0 80 kickfilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeOne_4/kick_bip.wav";
andrew@0 81 snarefilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeOne_4/snare_bip.wav";
andrew@0 82 sonicVizBeatsFilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeOne_4/PennyArcade_take4_beats.txt";
andrew@0 83 break;
andrew@0 84
andrew@0 85 case 5:
andrew@0 86 roomfilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeTwo_5/neuamnn_bip.wav";
andrew@0 87 kickfilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeTwo_5/kick_bip.wav";
andrew@0 88 snarefilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeTwo_5/snare_bip.wav";
andrew@0 89 sonicVizBeatsFilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeTwo_5/PennyArcade_take5_beats.txt";
andrew@0 90 break;
andrew@0 91
andrew@0 92
andrew@0 93
andrew@0 94 }
andrew@0 95 if (kickfilename != NULL){
andrew@0 96
andrew@0 97 loadAudioTrack(kickfilename, 0);
andrew@0 98 }
andrew@0 99
andrew@0 100 if (roomfilename != NULL){
andrew@0 101 printf("roomfilename: %s\n", roomfilename);
andrew@0 102 loadAudioTrack(roomfilename, 1);
andrew@0 103 }
andrew@0 104
andrew@0 105 if (snarefilename != NULL)
andrew@0 106 loadAudioTrack(snarefilename, 2);
andrew@0 107
andrew@0 108 if (sonicVizBeatsFilename.c_str() != NULL){
andrew@0 109 readInBeatsFile(sonicVizBeatsFilename);
andrew@0 110 printBeatTimes();
andrew@0 111 checkFileErrors(0);
andrew@0 112 checkFileErrors(2);
andrew@0 113 findBeatOnsets();
andrew@0 114 }
andrew@0 115 }
andrew@0 116
andrew@0 117 void RecordedMultipleAudio::loadAudioTrack(std::string name, const int& channel){
andrew@0 118 //kick - track type 0
andrew@0 119 //bass - type 1
andrew@0 120 //snare type 2
andrew@0 121 //guitar type 3
andrew@0 122 if (channel >= 0 && channel <= numberOfAudioTracks){
andrew@0 123 loadedAudioPtr = new LoadedAudioHolder;
andrew@0 124 //set tracktype before we do analysis
andrew@0 125 //so we dont do unnecessary chroma and pitch calculations
andrew@0 126 if (channel == 0 || channel == 2){
andrew@0 127 loadedAudioPtr->setTrackType(channel);
andrew@0 128 }
andrew@0 129 else{
andrew@0 130 loadedAudioPtr->setTrackType(0);
andrew@0 131 }
andrew@0 132 loadedAudioPtr->loadAudioFile(name);
andrew@0 133
andrew@0 134 loadedAudioFiles[channel] = *loadedAudioPtr;
andrew@0 135 loadedAudioFiles[channel].fileLoader.onsetDetect.window.setToRelativeSize(0, trackScreenHeight*channel, 1, trackScreenHeight);
andrew@0 136 //loadedAudioFiles[channel].setTrackType(channel);
andrew@0 137 }
andrew@0 138 }
andrew@0 139
andrew@0 140
andrew@0 141
andrew@0 142 void RecordedMultipleAudio::readInBeatsFile(std::string& pathName){
andrew@0 143
andrew@0 144 // "/Users/andrew/Documents/work/MuseScore/RWC/ANNOTATION/RM-C002_annotation+WavPos.csv"
andrew@0 145 beatTimes.clear();
andrew@0 146
andrew@0 147 printf("- - - - \n\nREAD FILE %s\n", pathName.c_str());
andrew@0 148 ifstream file ( pathName.c_str());
andrew@0 149 string value, tmpLine;
andrew@0 150 stringstream iss;
andrew@0 151 int count = 0;
andrew@0 152
andrew@0 153 while ( file.good() )
andrew@0 154 {
andrew@0 155 getline(file, tmpLine);
andrew@0 156 iss << tmpLine;
andrew@0 157 int lineCount = 0;
andrew@0 158 // printf("tmp line %s\n", tmpLine.c_str());
andrew@0 159 while(getline ( iss, value, '\t' )){ // read a string until next comma: http://www.cplusplus.com/reference/string/getline/
andrew@0 160 // cout << string( value, 1, value.length()-2 ); // display value removing the first and the last character from it
andrew@0 161 // printf("line:%s\n", value.c_str());
andrew@0 162 string::size_type start = value.find_first_not_of(" ,\t\v\n");
andrew@0 163
andrew@0 164 string part = value.substr(start, string::npos);
andrew@0 165
andrew@0 166 //printf("%s\n", firstpart.c_str());
andrew@0 167 if (lineCount == 0){
andrew@0 168 //printf("First part of line found '%s'\n", part.c_str());
andrew@0 169 double newBeatTime = atof(part.c_str());
andrew@0 170 beatTimes.push_back(newBeatTime);
andrew@0 171 }
andrew@0 172 lineCount++;
andrew@0 173
andrew@0 174 }//end while reading line
andrew@0 175 iss.clear();
andrew@0 176
andrew@0 177
andrew@0 178 }//end while
andrew@0 179
andrew@0 180 // printBeatTimes();
andrew@0 181 printf("There are %i BEAT annotations\n", (int)beatTimes.size());
andrew@0 182
andrew@0 183 }
andrew@0 184
andrew@0 185 void RecordedMultipleAudio::printBeatTimes(){
andrew@0 186 for (int i = 0;i < beatTimes.size();i++){
andrew@0 187 printf("Beat[%i] = %f\n", i, beatTimes[i]);
andrew@0 188 }
andrew@0 189 }
andrew@0 190
andrew@0 191
andrew@0 192 void RecordedMultipleAudio::checkFileErrors(int channel){
andrew@0 193 int beatIndex = 0;
andrew@0 194 int cutoff = 50;//ms width to check
andrew@0 195 for (int i = 0;i < loadedAudioFiles[channel].onsetTimesMillis.size();i++){
andrew@0 196 while (beatIndex < beatTimes.size() && 1000.0*beatTimes[beatIndex] < loadedAudioFiles[channel].onsetTimesMillis[i] - cutoff) {
andrew@0 197 beatIndex++;
andrew@0 198 }
andrew@0 199 double error = (1000.0*beatTimes[beatIndex] - loadedAudioFiles[channel].onsetTimesMillis[i]);
andrew@0 200 if (fabs(error) < cutoff){
andrew@0 201 if (channel == 0)
andrew@0 202 printf("Pos: %i Beat Time %f Kick Time %f Error %f\n", beatIndex%4, 1000.0*beatTimes[beatIndex], loadedAudioFiles[0].onsetTimesMillis[i], error);
andrew@0 203 else
andrew@0 204 printf("Pos: %i Beat Time %f Snare Time %f Error %f\n", beatIndex%4, 1000.0*beatTimes[beatIndex], loadedAudioFiles[0].onsetTimesMillis[i], error);
andrew@0 205
andrew@0 206 }else{
andrew@0 207 if (channel == 0)
andrew@0 208 printf("Out of Beat: Kick Time %f beat error %f\n", 1000.0*beatTimes[beatIndex], loadedAudioFiles[0].onsetTimesMillis[i], error);
andrew@0 209 else
andrew@0 210 printf("Out of Beat: %f Snare Time %f best error %f\n", 1000.0*beatTimes[beatIndex], loadedAudioFiles[0].onsetTimesMillis[i], error);
andrew@0 211
andrew@0 212 }
andrew@0 213 }
andrew@0 214 }
andrew@0 215
andrew@0 216
andrew@0 217 #pragma mark -labelExactOnsets
andrew@0 218
andrew@0 219 void RecordedMultipleAudio::findBeatOnsets(){
andrew@0 220 //tries to find kicks on 1, 3; snares on 2,4
andrew@0 221 int beatIndex = 0;
andrew@0 222 int kickIndex = 0;
andrew@0 223 int snareIndex = 0;
andrew@0 224 double kickTime, snareTime;
andrew@0 225 int cutoff = 50;//ms width to check
andrew@0 226
andrew@0 227 onsetInfo.clear();
andrew@0 228
andrew@0 229 // kickErrors.clear();
andrew@0 230 // snareErrors.clear();
andrew@0 231
andrew@0 232 bool beatFound;
andrew@0 233 for (int k = 0;k < beatTimes.size();k++){
andrew@0 234 beatFound = false;
andrew@0 235 double newBeatTime = beatTimes[k]*1000.0;
andrew@0 236 int beatPosition = k % 4;
andrew@0 237 OnsetInformation information;
andrew@0 238 switch (beatPosition) {
andrew@0 239 case 0: case 2://check for kick when it is on the `one' or 'three' (0 or 2 in our metrical position)
andrew@0 240 // printf("check %i kindex %i\n", beatPosition, kickIndex);
andrew@0 241 while (kickIndex < loadedAudioFiles[0].onsetTimesMillis.size() && loadedAudioFiles[0].onsetTimesMillis[kickIndex] < newBeatTime - cutoff){
andrew@0 242 kickIndex++;
andrew@0 243 kickTime = loadedAudioFiles[0].onsetTimesMillis[kickIndex];
andrew@0 244 // printf("checking beat[%i] %f kick %f error %f\n", k, beatTimes[k]*1000.0, kickTime, (kickTime - beatTimes[k]*1000.0));
andrew@0 245 if (fabs(kickTime - beatTimes[k]*1000.0) < cutoff){
andrew@0 246 beatFound = true;
andrew@0 247 printf("beat[%i] %f kick %f error %f\n", k, beatTimes[k]*1000.0, kickTime, (kickTime - beatTimes[k]*1000.0));
andrew@0 248
andrew@0 249 information.error = (kickTime - beatTimes[k]*1000.0);//FOR NOW ONLY
andrew@0 250 information.metricalPosition = beatPosition;
andrew@0 251 information.type = 0;
andrew@0 252 information.exactOnsetTime = kickTime;
andrew@0 253 // exactBeatPositions.push_back(kickTime);
andrew@0 254 }
andrew@0 255 }
andrew@0 256
andrew@0 257 break;
andrew@0 258 case 1: case 3://snare
andrew@0 259 while (snareIndex < loadedAudioFiles[1].onsetTimesMillis.size() && loadedAudioFiles[1].onsetTimesMillis[snareIndex] < newBeatTime - cutoff ){
andrew@0 260 snareIndex++;
andrew@0 261 snareTime = loadedAudioFiles[1].onsetTimesMillis[snareIndex];
andrew@0 262 if (fabs(snareTime - beatTimes[k]*1000.0) < cutoff){
andrew@0 263 beatFound = true;
andrew@0 264 // snareErrors.push_back((beatTimes[k]*1000.0 - snareTime));
andrew@0 265 information.error = (snareTime - beatTimes[k]*1000.0);
andrew@0 266 information.metricalPosition = beatPosition;//.push_back(beatPosition);
andrew@0 267 information.type = 1;
andrew@0 268 information.exactOnsetTime = snareTime;
andrew@0 269 printf("beat[%i] %f snare %f error %f\n", k, beatTimes[k]*1000.0, snareTime, (snareTime - beatTimes[k]*1000.0));
andrew@0 270 // exactBeatPositions.push_back(snareTime);
andrew@0 271 }
andrew@0 272 }
andrew@0 273
andrew@0 274 break;
andrew@0 275 }
andrew@0 276 if (!beatFound){
andrew@0 277 information.type = -1;//not a kick or snare
andrew@0 278 information.exactOnsetTime = beatTimes[k]*1000.0;
andrew@0 279 information.metricalPosition = beatPosition;//.push_
andrew@0 280 // exactBeatPositions.push_back(beatTimes[k]*1000.0);//have to go with the annotated beat instead (no matching kick or snare)
andrew@0 281
andrew@0 282 printf("beat[%i] %f NOT FOUND, kicktime %f snaretime %f\n", k, beatTimes[k]*1000.0, kickTime, snareTime );
andrew@0 283 }
andrew@0 284
andrew@0 285 onsetInfo.push_back(information);
andrew@0 286
andrew@0 287 }//end for all beat annotations
andrew@0 288
andrew@0 289 correctExactBeatTiming();//get rid of the first onset time
andrew@0 290
andrew@0 291 calculateTimingAnalysis();
andrew@0 292
andrew@0 293 }
andrew@0 294
andrew@0 295 #pragma mark -doTimingAnalysis
andrew@0 296 void RecordedMultipleAudio::correctExactBeatTiming(){
andrew@0 297 //get rid of firtst onset time
andrew@0 298 if (onsetInfo.size() > 0){
andrew@0 299 timingOffset = onsetInfo[0].exactOnsetTime;//s[0];
andrew@0 300 double tmpPosn;
andrew@0 301 for (int i = 0;i < onsetInfo.size();i++){
andrew@0 302 onsetInfo[i].beatTimeToProcess = onsetInfo[i].exactOnsetTime - timingOffset;
andrew@0 303 printf("exact [%i] type %i %f, corrected %f\n", i, onsetInfo[i].type, onsetInfo[i].exactOnsetTime, onsetInfo[i].beatTimeToProcess );
andrew@0 304 }
andrew@0 305 }
andrew@0 306 }
andrew@0 307
andrew@0 308 void RecordedMultipleAudio::calculateTimingAnalysis(){
andrew@0 309
andrew@0 310 for (int i = 0;i < onsetInfo.size();i++){
andrew@0 311 drumTimingAnalyser.updateCostToPoint(onsetInfo[i].beatTimeToProcess, i);
andrew@0 312 //updatecounter is the beat position for this note event - can be used to do other kinds of durations than just simple beats
andrew@0 313
andrew@0 314 drumTimingAnalyser.beatPosition.push_back(onsetInfo[i].exactOnsetTime);
andrew@0 315 }
andrew@0 316 drumTimingAnalyser.processPathHistory();
andrew@0 317 drumTimingAnalyser.calculateTempoLimits();
andrew@0 318
andrew@0 319 getErrorTimesFromAnalysis();
andrew@0 320
andrew@0 321 alternativeKickRelativeAnalysis();
andrew@0 322
andrew@0 323 exportErrorInformation();
andrew@0 324
andrew@0 325 displayKickRelativeMedianErrors();//NB messes ther order of these
andrew@0 326
andrew@0 327 //this was how we did it in multimatch program
andrew@0 328 // timer.processPathHistory();
andrew@0 329 // timer.calculateTempoLimits();
andrew@0 330 // timer.exportTimingData();
andrew@0 331 // timer.exportProcessedBeatTimes(firstNoteTime);
andrew@0 332 }
andrew@0 333
andrew@0 334 void RecordedMultipleAudio::getErrorTimesFromAnalysis(){
andrew@0 335 printf("\nDrumTimingLoader: get error times from analysis!!!\n");
andrew@0 336 setUpErrorsByMetricalPosition();
andrew@0 337 //gets the errors from the drum timing analyser (i.e. ISMIR paper code) and attributes these to the onsets
andrew@0 338 for (int i = 0;i < drumTimingAnalyser.timingData.size();i++){
andrew@0 339 onsetInfo[i].error = drumTimingAnalyser.timingData[i][5];
andrew@0 340 onsetInfo[i].clickTime = drumTimingAnalyser.timingData[i][1] + timingOffset;//this is where teh timing analyser placed the click times
andrew@0 341 errorsByMetricalPosition[onsetInfo[i].metricalPosition].push_back(onsetInfo[i].error);
andrew@0 342 printf("beat %i metrical posn %i exact beat time %f error %i\n", i, onsetInfo[i].metricalPosition, onsetInfo[i].exactOnsetTime, (int)onsetInfo[i].error);
andrew@0 343 }
andrew@0 344 displayMedianErrors();
andrew@0 345 }
andrew@0 346
andrew@0 347
andrew@0 348 void RecordedMultipleAudio::alternativeKickRelativeAnalysis(){
andrew@0 349 printf("\n\nAnalysis Relative to the Kick Drum on the ONE\n");
andrew@0 350 //this sees kicks as ON the beat, looks at relative error of the three other beats if we chop the bar evenly
andrew@0 351
andrew@0 352 double recentBeatTime, currentTempo;
andrew@0 353 kickRelativeErrors.clear();
andrew@0 354 kickRelativeClickTimes.clear();
andrew@0 355
andrew@0 356 for (int i = 0;i < drumTimingAnalyser.timingData.size();i++){
andrew@0 357 int beatPosition = i%4;
andrew@0 358 if (beatPosition == 0){
andrew@0 359 recentBeatTime = onsetInfo[i].exactOnsetTime;
andrew@0 360 if (i+4 < onsetInfo.size())
andrew@0 361 currentTempo = (onsetInfo[i+4].exactOnsetTime - onsetInfo[i].exactOnsetTime)/4.0;
andrew@0 362 printf("new beat time %f tempo %f\n", recentBeatTime, currentTempo);
andrew@0 363 }
andrew@0 364 double error = onsetInfo[i].exactOnsetTime - (recentBeatTime + beatPosition*currentTempo);
andrew@0 365 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);
andrew@0 366 kickRelativeErrors.push_back(error);
andrew@0 367 kickRelativeClickTimes.push_back(recentBeatTime + beatPosition*currentTempo);
andrew@0 368 }
andrew@0 369 }
andrew@0 370
andrew@0 371 #pragma label -exportInfo
andrew@0 372 void RecordedMultipleAudio::exportErrorInformation(){
andrew@0 373 printf("Export final timing information\n");
andrew@0 374
andrew@0 375 ofstream ofs(infoFilepath.c_str());
andrew@0 376 for (int i = 0;i < onsetInfo.size() && kickRelativeErrors.size();i++){// drumTimingAnalyser.timingData.size()
andrew@0 377 ofs << i << "," << (i%4) << "," << onsetInfo[i].exactOnsetTime << ",";
andrew@0 378 ofs << onsetInfo[i].clickTime << "," << onsetInfo[i].error << ",";//the error for the ISMIR timing analyser
andrew@0 379 ofs << kickRelativeClickTimes[i] << "," << kickRelativeErrors[i];//the click and error for beats evenly between kicks
andrew@0 380 ofs << endl;
andrew@0 381 }
andrew@0 382
andrew@0 383 }
andrew@0 384
andrew@0 385 void RecordedMultipleAudio::printKickRelativeErrors(){
andrew@0 386 for (int i = 0;i < kickRelativeErrors.size();i++){
andrew@0 387 printf("KR error [%i] : %.1f\n", i, kickRelativeErrors[i]);
andrew@0 388 }
andrew@0 389 }
andrew@0 390
andrew@0 391 void RecordedMultipleAudio::setUpErrorsByMetricalPosition(){
andrew@0 392 //clear this matrix
andrew@0 393 errorsByMetricalPosition.clear();
andrew@0 394 for (int i = 0;i < 4;i++){
andrew@0 395 DoubleVector v;
andrew@0 396 errorsByMetricalPosition.push_back(v);
andrew@0 397 }
andrew@0 398
andrew@0 399 }
andrew@0 400
andrew@0 401 void RecordedMultipleAudio::displayMedianErrors(){
andrew@0 402 printf("Medians of the Decoded Tempo variations\n");
andrew@0 403 for (int i = 0;i < 4;i++){
andrew@0 404 //printErrorsForMetricalPosition(i);
andrew@0 405 std::sort(errorsByMetricalPosition[i].begin(), errorsByMetricalPosition[i].end());//sort vector
andrew@0 406 double median = errorsByMetricalPosition[i][(int)(errorsByMetricalPosition[i].size()/2)];
andrew@0 407 printf("median for metrical position %i is %f\n", i, median);
andrew@0 408 }
andrew@0 409 }
andrew@0 410
andrew@0 411
andrew@0 412 void RecordedMultipleAudio::displayKickRelativeMedianErrors(){
andrew@0 413 printf("Medians of the KR variations\n");
andrew@0 414
andrew@0 415 DoubleVector tmpKRErrors;
andrew@0 416
andrew@0 417
andrew@0 418 for (int i = 0;i < 4;i++){
andrew@0 419
andrew@0 420 tmpKRErrors.clear();
andrew@0 421 int index = 0;
andrew@0 422
andrew@0 423 while (index+i < kickRelativeErrors.size()) {
andrew@0 424 tmpKRErrors.push_back(kickRelativeErrors[index + i]);
andrew@0 425 index += 4;
andrew@0 426 }
andrew@0 427
andrew@0 428 // for (int k = 0;k < tmpKRErrors.size();k++)
andrew@0 429 // printf("kr %i [%i] = %f\n", i, k, tmpKRErrors[k]);
andrew@0 430
andrew@0 431 //printErrorsForMetricalPosition(i);
andrew@0 432 std::sort(tmpKRErrors.begin(), tmpKRErrors.end());//sort vector
andrew@0 433
andrew@0 434 // for (int k = 0;k < tmpKRErrors.size();k++)
andrew@0 435 // printf("sorted kr %i [%i] = %f\n", i, k, tmpKRErrors[k]);
andrew@0 436
andrew@0 437
andrew@0 438 double median = tmpKRErrors[(int)(tmpKRErrors.size()/2)];
andrew@0 439 printf("median for metrical position %i is %f\n", i, median);
andrew@0 440 }
andrew@0 441 }
andrew@0 442
andrew@0 443 void RecordedMultipleAudio::printErrorsForMetricalPosition(const int& i){
andrew@0 444 for (int k = 0;k < errorsByMetricalPosition[i].size();k++){
andrew@0 445 printf("metrical posn %i, [%i] = %f\n", i, k, errorsByMetricalPosition[i][k]);
andrew@0 446 }
andrew@0 447 }
andrew@0 448
andrew@0 449 #pragma mark -drawTracks
andrew@0 450
andrew@0 451 void RecordedMultipleAudio::drawTracks(){
andrew@0 452 if (drawWindow == 0){
andrew@0 453 for (int i = 0;i < numberOfAudioTracks;i++){
andrew@0 454 loadedAudioFiles[i].draw();
andrew@0 455 }
andrew@0 456 } else {
andrew@0 457 drumTimingAnalyser.drawTempoCurve();
andrew@0 458 }
andrew@0 459 }
andrew@0 460
andrew@0 461 #pragma mark -update
andrew@0 462 void RecordedMultipleAudio::updatePosition(){
andrew@0 463 for (int i = 0;i < numberOfAudioTracks;i++)
andrew@0 464 loadedAudioFiles[i].updateToPlayPosition();
andrew@0 465 }
andrew@0 466
andrew@0 467 void RecordedMultipleAudio::updatePositionToMillis(const double& millis){
andrew@0 468 for (int i = 0;i < numberOfAudioTracks;i++)
andrew@0 469 loadedAudioFiles[i].updateToMillisPosition(millis);
andrew@0 470 }
andrew@0 471
andrew@0 472 void RecordedMultipleAudio::updatePlaybackPositionToMillis(const double& millis){
andrew@0 473 for (int i = 0;i < numberOfAudioTracks;i++)
andrew@0 474 loadedAudioFiles[i].updatePlaybackPositionToMillis(millis);
andrew@0 475 }
andrew@0 476
andrew@0 477 void RecordedMultipleAudio::switchScreens(){
andrew@0 478 for (int i = 0;i < numberOfAudioTracks;i++)
andrew@0 479 loadedAudioFiles[i].switchScreens();
andrew@0 480 }
andrew@0 481
andrew@0 482
andrew@0 483 void RecordedMultipleAudio::togglePlay(){
andrew@0 484 for (int i = 0;i < numberOfAudioTracks;i++)
andrew@0 485 loadedAudioFiles[i].togglePlay();
andrew@0 486 }
andrew@0 487
andrew@0 488 void RecordedMultipleAudio::stop(){
andrew@0 489 for (int i = 0;i < numberOfAudioTracks;i++)
andrew@0 490 loadedAudioFiles[i].stop();
andrew@0 491 }
andrew@0 492
andrew@0 493
andrew@0 494 void RecordedMultipleAudio::printInfo(){
andrew@0 495 loadedAudioFiles[0].fileLoader.onsetDetect.printChromaInfo();
andrew@0 496 loadedAudioFiles[0].printEvents();
andrew@0 497 }
andrew@0 498
andrew@0 499 void RecordedMultipleAudio::windowResized(const int& w, const int& h){
andrew@0 500 for (int i = 0;i < numberOfAudioTracks;i++)
andrew@0 501 loadedAudioFiles[i].windowResized(w, h);
andrew@0 502 }
andrew@0 503
andrew@0 504 void RecordedMultipleAudio::zoomIn(){
andrew@0 505 if (drawWindow == 0){
andrew@0 506 printf("zoom in\n");
andrew@0 507 for (int i = 0;i < numberOfAudioTracks;i++)
andrew@0 508 loadedAudioFiles[i].fileLoader.zoomIn();
andrew@0 509 }
andrew@0 510
andrew@0 511 if (drawWindow == 1)
andrew@0 512 drumTimingAnalyser.zoomIn();//numberOfPointsPerPage /= 2;
andrew@0 513 }
andrew@0 514
andrew@0 515 void RecordedMultipleAudio::zoomOut(){
andrew@0 516 printf("zoom out\n");
andrew@0 517 for (int i = 0;i < numberOfAudioTracks;i++)
andrew@0 518 loadedAudioFiles[i].fileLoader.zoomOut();
andrew@0 519
andrew@0 520 if (drawWindow == 1)
andrew@0 521 drumTimingAnalyser.zoomOut();//numberOfPointsPerPage *= 2;
andrew@0 522
andrew@0 523 }
andrew@0 524
andrew@0 525