andrew@0: /* andrew@0: * RecordedMultipleAudio.cpp andrew@0: * MultipleAudioMathcher andrew@0: * andrew@0: * Created by Andrew on 31/01/2012. andrew@0: * Copyright 2012 QMUL. All rights reserved. andrew@0: * andrew@0: */ andrew@0: andrew@0: #include "RecordedMultipleAudio.h" andrew@0: andrew@0: RecordedMultipleAudio::RecordedMultipleAudio(){ andrew@0: andrew@0: infoFilepath = "../../../data/errorData.txt"; andrew@0: //infoFilepath = "/Users/andrew/errorData.txt"; andrew@0: andrew@0: timingOffset = 0; andrew@0: } andrew@0: andrew@0: void RecordedMultipleAudio::loadTestAudio(){ andrew@0: andrew@0: andrew@0: numberOfAudioTracks = 2; andrew@0: andrew@0: printf("loaded max val is %f\n", loadedAudioFiles[0].fileLoader.onsetDetect.onsetDetector.maximumDetectionValue); andrew@0: andrew@0: int multitrackToLoad = 5; andrew@0: setDifferentMultitracks(multitrackToLoad);//command to load this set of audio files - see below andrew@0: andrew@0: drumTimingAnalyser.phaseCost = 1000;//v high - i.e. dont do phase andrew@0: andrew@0: drawWindow = 1; andrew@0: trackScreenHeight = 0.25; andrew@0: andrew@0: andrew@0: andrew@0: // printf("AFTER LOADING: \n"); andrew@0: // printInfo(); andrew@0: andrew@0: } andrew@0: #pragma mark -loadingPrerecordedTracks andrew@0: void RecordedMultipleAudio::setDifferentMultitracks(const int& setToLoad){ andrew@0: const char *kickfilename ;//= "../../../data/sound/LiveDues/kick_liveDues.wav"; andrew@0: const char *roomfilename ;//"../../../data/sound/LiveDues/bass_upsideLive.wav"; andrew@0: const char *snarefilename ; andrew@0: std::string sonicVizBeatsFilename ; andrew@0: andrew@0: switch (setToLoad) { andrew@0: case 0: andrew@0: kickfilename = "/Users/andrew/Documents/work/programming/MadMax/AudioFiles/futureHides/kickFuture.wav"; andrew@0: roomfilename = "/Users/andrew/Documents/work/programming/MadMax/AudioFiles/futureHides/roomFuture.wav"; andrew@0: snarefilename = "/Users/andrew/Documents/work/programming/MadMax/AudioFiles/futureHides/snareFuture.wav"; andrew@0: sonicVizBeatsFilename = "/Users/andrew/Documents/work/programming/MadMax/AudioFiles/futureHides/FutureHidesBeats.txt"; andrew@0: break; andrew@0: andrew@0: andrew@0: case 1: andrew@0: roomfilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcadeStudio14aMultitrack/Mixdown/PennyArcade_StudioMixdown.wav"; andrew@0: kickfilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcadeStudio14aMultitrack/kick.wav"; andrew@0: snarefilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcadeStudio14aMultitrack/snare.wav"; andrew@0: sonicVizBeatsFilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcadeStudio14aMultitrack/Mixdown/PennyArcade_StudioMixdown_beats.txt"; andrew@0: break; andrew@0: andrew@0: case 2: andrew@0: roomfilename = "/Users/andrew/Documents/work/programming/MadMax/AudioFiles/MattIngramGreenSection/colesL_bip.wav"; andrew@0: kickfilename = "/Users/andrew/Documents/work/programming/MadMax/AudioFiles/MattIngramGreenSection/Kick_bip.wav"; andrew@0: snarefilename = "/Users/andrew/Documents/work/programming/MadMax/AudioFiles/MattIngramGreenSection/Snare_bip.wav"; andrew@0: sonicVizBeatsFilename = "/Users/andrew/Documents/work/programming/MadMax/AudioFiles/MattIngramGreenSection/IngramGreenSectionBeats.txt"; andrew@0: break; andrew@0: andrew@0: case 3: andrew@0: roomfilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDiamondWhite/tractorsDiamondWhite/Bounces/diamondWhiteMultiTakeOne/coles_bip.wav"; andrew@0: kickfilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDiamondWhite/tractorsDiamondWhite/Bounces/diamondWhiteMultiTakeOne/kick d112_bip.wav"; andrew@0: snarefilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDiamondWhite/tractorsDiamondWhite/Bounces/diamondWhiteMultiTakeOne/snare bottom_bip.wav"; andrew@0: sonicVizBeatsFilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDiamondWhite/tractorsDiamondWhite/Bounces/diamondWhiteMultiTakeOne/TakeOneBeats.txt"; andrew@0: break; andrew@0: andrew@0: case 4: andrew@0: roomfilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeOne_4/neuamnn_bip.wav"; andrew@0: kickfilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeOne_4/kick_bip.wav"; andrew@0: snarefilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeOne_4/snare_bip.wav"; andrew@0: sonicVizBeatsFilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeOne_4/PennyArcade_take4_beats.txt"; andrew@0: break; andrew@0: andrew@0: case 5: andrew@0: roomfilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeTwo_5/neuamnn_bip.wav"; andrew@0: kickfilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeTwo_5/kick_bip.wav"; andrew@0: snarefilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeTwo_5/snare_bip.wav"; andrew@0: sonicVizBeatsFilename = "/Volumes/Supersaurus/TractorsAlbum/tractorsDemo/Bounces/PennyArcade_Multitracks/TakeTwo_5/PennyArcade_take5_beats.txt"; andrew@0: break; andrew@0: andrew@0: andrew@0: andrew@0: } andrew@0: if (kickfilename != NULL){ andrew@0: andrew@0: loadAudioTrack(kickfilename, 0); andrew@0: } andrew@0: andrew@0: if (roomfilename != NULL){ andrew@0: printf("roomfilename: %s\n", roomfilename); andrew@0: loadAudioTrack(roomfilename, 1); andrew@0: } andrew@0: andrew@0: if (snarefilename != NULL) andrew@0: loadAudioTrack(snarefilename, 2); andrew@0: andrew@0: if (sonicVizBeatsFilename.c_str() != NULL){ andrew@0: readInBeatsFile(sonicVizBeatsFilename); andrew@0: printBeatTimes(); andrew@0: checkFileErrors(0); andrew@0: checkFileErrors(2); andrew@0: findBeatOnsets(); andrew@0: } andrew@0: } andrew@0: andrew@0: void RecordedMultipleAudio::loadAudioTrack(std::string name, const int& channel){ andrew@0: //kick - track type 0 andrew@0: //bass - type 1 andrew@0: //snare type 2 andrew@0: //guitar type 3 andrew@0: if (channel >= 0 && channel <= numberOfAudioTracks){ andrew@0: loadedAudioPtr = new LoadedAudioHolder; andrew@0: //set tracktype before we do analysis andrew@0: //so we dont do unnecessary chroma and pitch calculations andrew@0: if (channel == 0 || channel == 2){ andrew@0: loadedAudioPtr->setTrackType(channel); andrew@0: } andrew@0: else{ andrew@0: loadedAudioPtr->setTrackType(0); andrew@0: } andrew@0: loadedAudioPtr->loadAudioFile(name); andrew@0: andrew@0: loadedAudioFiles[channel] = *loadedAudioPtr; andrew@0: loadedAudioFiles[channel].fileLoader.onsetDetect.window.setToRelativeSize(0, trackScreenHeight*channel, 1, trackScreenHeight); andrew@0: //loadedAudioFiles[channel].setTrackType(channel); andrew@0: } andrew@0: } andrew@0: andrew@0: andrew@0: andrew@0: void RecordedMultipleAudio::readInBeatsFile(std::string& pathName){ andrew@0: andrew@0: // "/Users/andrew/Documents/work/MuseScore/RWC/ANNOTATION/RM-C002_annotation+WavPos.csv" andrew@0: beatTimes.clear(); andrew@0: andrew@0: printf("- - - - \n\nREAD FILE %s\n", pathName.c_str()); andrew@0: ifstream file ( pathName.c_str()); andrew@0: string value, tmpLine; andrew@0: stringstream iss; andrew@0: int count = 0; andrew@0: andrew@0: while ( file.good() ) andrew@0: { andrew@0: getline(file, tmpLine); andrew@0: iss << tmpLine; andrew@0: int lineCount = 0; andrew@0: // printf("tmp line %s\n", tmpLine.c_str()); andrew@0: while(getline ( iss, value, '\t' )){ // read a string until next comma: http://www.cplusplus.com/reference/string/getline/ andrew@0: // cout << string( value, 1, value.length()-2 ); // display value removing the first and the last character from it andrew@0: // printf("line:%s\n", value.c_str()); andrew@0: string::size_type start = value.find_first_not_of(" ,\t\v\n"); andrew@0: andrew@0: string part = value.substr(start, string::npos); andrew@0: andrew@0: //printf("%s\n", firstpart.c_str()); andrew@0: if (lineCount == 0){ andrew@0: //printf("First part of line found '%s'\n", part.c_str()); andrew@0: double newBeatTime = atof(part.c_str()); andrew@0: beatTimes.push_back(newBeatTime); andrew@0: } andrew@0: lineCount++; andrew@0: andrew@0: }//end while reading line andrew@0: iss.clear(); andrew@0: andrew@0: andrew@0: }//end while andrew@0: andrew@0: // printBeatTimes(); andrew@0: printf("There are %i BEAT annotations\n", (int)beatTimes.size()); andrew@0: andrew@0: } andrew@0: andrew@0: void RecordedMultipleAudio::printBeatTimes(){ andrew@0: for (int i = 0;i < beatTimes.size();i++){ andrew@0: printf("Beat[%i] = %f\n", i, beatTimes[i]); andrew@0: } andrew@0: } andrew@0: andrew@0: andrew@0: void RecordedMultipleAudio::checkFileErrors(int channel){ andrew@0: int beatIndex = 0; andrew@0: int cutoff = 50;//ms width to check andrew@0: for (int i = 0;i < loadedAudioFiles[channel].onsetTimesMillis.size();i++){ andrew@0: while (beatIndex < beatTimes.size() && 1000.0*beatTimes[beatIndex] < loadedAudioFiles[channel].onsetTimesMillis[i] - cutoff) { andrew@0: beatIndex++; andrew@0: } andrew@0: double error = (1000.0*beatTimes[beatIndex] - loadedAudioFiles[channel].onsetTimesMillis[i]); andrew@0: if (fabs(error) < cutoff){ andrew@0: if (channel == 0) andrew@0: 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: else andrew@0: 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: andrew@0: }else{ andrew@0: if (channel == 0) andrew@0: printf("Out of Beat: Kick Time %f beat error %f\n", 1000.0*beatTimes[beatIndex], loadedAudioFiles[0].onsetTimesMillis[i], error); andrew@0: else andrew@0: printf("Out of Beat: %f Snare Time %f best error %f\n", 1000.0*beatTimes[beatIndex], loadedAudioFiles[0].onsetTimesMillis[i], error); andrew@0: andrew@0: } andrew@0: } andrew@0: } andrew@0: andrew@0: andrew@0: #pragma mark -labelExactOnsets andrew@0: andrew@0: void RecordedMultipleAudio::findBeatOnsets(){ andrew@0: //tries to find kicks on 1, 3; snares on 2,4 andrew@0: int beatIndex = 0; andrew@0: int kickIndex = 0; andrew@0: int snareIndex = 0; andrew@0: double kickTime, snareTime; andrew@0: int cutoff = 50;//ms width to check andrew@0: andrew@0: onsetInfo.clear(); andrew@0: andrew@0: // kickErrors.clear(); andrew@0: // snareErrors.clear(); andrew@0: andrew@0: bool beatFound; andrew@0: for (int k = 0;k < beatTimes.size();k++){ andrew@0: beatFound = false; andrew@0: double newBeatTime = beatTimes[k]*1000.0; andrew@0: int beatPosition = k % 4; andrew@0: OnsetInformation information; andrew@0: switch (beatPosition) { andrew@0: case 0: case 2://check for kick when it is on the `one' or 'three' (0 or 2 in our metrical position) andrew@0: // printf("check %i kindex %i\n", beatPosition, kickIndex); andrew@0: while (kickIndex < loadedAudioFiles[0].onsetTimesMillis.size() && loadedAudioFiles[0].onsetTimesMillis[kickIndex] < newBeatTime - cutoff){ andrew@0: kickIndex++; andrew@0: kickTime = loadedAudioFiles[0].onsetTimesMillis[kickIndex]; andrew@0: // printf("checking beat[%i] %f kick %f error %f\n", k, beatTimes[k]*1000.0, kickTime, (kickTime - beatTimes[k]*1000.0)); andrew@0: if (fabs(kickTime - beatTimes[k]*1000.0) < cutoff){ andrew@0: beatFound = true; andrew@0: printf("beat[%i] %f kick %f error %f\n", k, beatTimes[k]*1000.0, kickTime, (kickTime - beatTimes[k]*1000.0)); andrew@0: andrew@0: information.error = (kickTime - beatTimes[k]*1000.0);//FOR NOW ONLY andrew@0: information.metricalPosition = beatPosition; andrew@0: information.type = 0; andrew@0: information.exactOnsetTime = kickTime; andrew@0: // exactBeatPositions.push_back(kickTime); andrew@0: } andrew@0: } andrew@0: andrew@0: break; andrew@0: case 1: case 3://snare andrew@0: while (snareIndex < loadedAudioFiles[1].onsetTimesMillis.size() && loadedAudioFiles[1].onsetTimesMillis[snareIndex] < newBeatTime - cutoff ){ andrew@0: snareIndex++; andrew@0: snareTime = loadedAudioFiles[1].onsetTimesMillis[snareIndex]; andrew@0: if (fabs(snareTime - beatTimes[k]*1000.0) < cutoff){ andrew@0: beatFound = true; andrew@0: // snareErrors.push_back((beatTimes[k]*1000.0 - snareTime)); andrew@0: information.error = (snareTime - beatTimes[k]*1000.0); andrew@0: information.metricalPosition = beatPosition;//.push_back(beatPosition); andrew@0: information.type = 1; andrew@0: information.exactOnsetTime = snareTime; andrew@0: printf("beat[%i] %f snare %f error %f\n", k, beatTimes[k]*1000.0, snareTime, (snareTime - beatTimes[k]*1000.0)); andrew@0: // exactBeatPositions.push_back(snareTime); andrew@0: } andrew@0: } andrew@0: andrew@0: break; andrew@0: } andrew@0: if (!beatFound){ andrew@0: information.type = -1;//not a kick or snare andrew@0: information.exactOnsetTime = beatTimes[k]*1000.0; andrew@0: information.metricalPosition = beatPosition;//.push_ andrew@0: // exactBeatPositions.push_back(beatTimes[k]*1000.0);//have to go with the annotated beat instead (no matching kick or snare) andrew@0: andrew@0: printf("beat[%i] %f NOT FOUND, kicktime %f snaretime %f\n", k, beatTimes[k]*1000.0, kickTime, snareTime ); andrew@0: } andrew@0: andrew@0: onsetInfo.push_back(information); andrew@0: andrew@0: }//end for all beat annotations andrew@0: andrew@0: correctExactBeatTiming();//get rid of the first onset time andrew@0: andrew@0: calculateTimingAnalysis(); andrew@0: andrew@0: } andrew@0: andrew@0: #pragma mark -doTimingAnalysis andrew@0: void RecordedMultipleAudio::correctExactBeatTiming(){ andrew@0: //get rid of firtst onset time andrew@0: if (onsetInfo.size() > 0){ andrew@0: timingOffset = onsetInfo[0].exactOnsetTime;//s[0]; andrew@0: double tmpPosn; andrew@0: for (int i = 0;i < onsetInfo.size();i++){ andrew@0: onsetInfo[i].beatTimeToProcess = onsetInfo[i].exactOnsetTime - timingOffset; andrew@0: printf("exact [%i] type %i %f, corrected %f\n", i, onsetInfo[i].type, onsetInfo[i].exactOnsetTime, onsetInfo[i].beatTimeToProcess ); andrew@0: } andrew@0: } andrew@0: } andrew@0: andrew@0: void RecordedMultipleAudio::calculateTimingAnalysis(){ andrew@0: andrew@0: for (int i = 0;i < onsetInfo.size();i++){ andrew@0: drumTimingAnalyser.updateCostToPoint(onsetInfo[i].beatTimeToProcess, i); andrew@0: //updatecounter is the beat position for this note event - can be used to do other kinds of durations than just simple beats andrew@0: andrew@0: drumTimingAnalyser.beatPosition.push_back(onsetInfo[i].exactOnsetTime); andrew@0: } andrew@0: drumTimingAnalyser.processPathHistory(); andrew@0: drumTimingAnalyser.calculateTempoLimits(); andrew@0: andrew@0: getErrorTimesFromAnalysis(); andrew@0: andrew@0: alternativeKickRelativeAnalysis(); andrew@0: andrew@0: exportErrorInformation(); andrew@0: andrew@0: displayKickRelativeMedianErrors();//NB messes ther order of these andrew@0: andrew@0: //this was how we did it in multimatch program andrew@0: // timer.processPathHistory(); andrew@0: // timer.calculateTempoLimits(); andrew@0: // timer.exportTimingData(); andrew@0: // timer.exportProcessedBeatTimes(firstNoteTime); andrew@0: } andrew@0: andrew@0: void RecordedMultipleAudio::getErrorTimesFromAnalysis(){ andrew@0: printf("\nDrumTimingLoader: get error times from analysis!!!\n"); andrew@0: setUpErrorsByMetricalPosition(); andrew@0: //gets the errors from the drum timing analyser (i.e. ISMIR paper code) and attributes these to the onsets andrew@0: for (int i = 0;i < drumTimingAnalyser.timingData.size();i++){ andrew@0: onsetInfo[i].error = drumTimingAnalyser.timingData[i][5]; andrew@0: onsetInfo[i].clickTime = drumTimingAnalyser.timingData[i][1] + timingOffset;//this is where teh timing analyser placed the click times andrew@0: errorsByMetricalPosition[onsetInfo[i].metricalPosition].push_back(onsetInfo[i].error); andrew@0: 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: } andrew@0: displayMedianErrors(); andrew@0: } andrew@0: andrew@0: andrew@0: void RecordedMultipleAudio::alternativeKickRelativeAnalysis(){ andrew@0: printf("\n\nAnalysis Relative to the Kick Drum on the ONE\n"); andrew@0: //this sees kicks as ON the beat, looks at relative error of the three other beats if we chop the bar evenly andrew@0: andrew@0: double recentBeatTime, currentTempo; andrew@0: kickRelativeErrors.clear(); andrew@0: kickRelativeClickTimes.clear(); andrew@0: andrew@0: for (int i = 0;i < drumTimingAnalyser.timingData.size();i++){ andrew@0: int beatPosition = i%4; andrew@0: if (beatPosition == 0){ andrew@0: recentBeatTime = onsetInfo[i].exactOnsetTime; andrew@0: if (i+4 < onsetInfo.size()) andrew@0: currentTempo = (onsetInfo[i+4].exactOnsetTime - onsetInfo[i].exactOnsetTime)/4.0; andrew@0: printf("new beat time %f tempo %f\n", recentBeatTime, currentTempo); andrew@0: } andrew@0: double error = onsetInfo[i].exactOnsetTime - (recentBeatTime + beatPosition*currentTempo); andrew@0: 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: kickRelativeErrors.push_back(error); andrew@0: kickRelativeClickTimes.push_back(recentBeatTime + beatPosition*currentTempo); andrew@0: } andrew@0: } andrew@0: andrew@0: #pragma label -exportInfo andrew@0: void RecordedMultipleAudio::exportErrorInformation(){ andrew@0: printf("Export final timing information\n"); andrew@0: andrew@0: ofstream ofs(infoFilepath.c_str()); andrew@0: for (int i = 0;i < onsetInfo.size() && kickRelativeErrors.size();i++){// drumTimingAnalyser.timingData.size() andrew@0: ofs << i << "," << (i%4) << "," << onsetInfo[i].exactOnsetTime << ","; andrew@0: ofs << onsetInfo[i].clickTime << "," << onsetInfo[i].error << ",";//the error for the ISMIR timing analyser andrew@0: ofs << kickRelativeClickTimes[i] << "," << kickRelativeErrors[i];//the click and error for beats evenly between kicks andrew@0: ofs << endl; andrew@0: } andrew@0: andrew@0: } andrew@0: andrew@0: void RecordedMultipleAudio::printKickRelativeErrors(){ andrew@0: for (int i = 0;i < kickRelativeErrors.size();i++){ andrew@0: printf("KR error [%i] : %.1f\n", i, kickRelativeErrors[i]); andrew@0: } andrew@0: } andrew@0: andrew@0: void RecordedMultipleAudio::setUpErrorsByMetricalPosition(){ andrew@0: //clear this matrix andrew@0: errorsByMetricalPosition.clear(); andrew@0: for (int i = 0;i < 4;i++){ andrew@0: DoubleVector v; andrew@0: errorsByMetricalPosition.push_back(v); andrew@0: } andrew@0: andrew@0: } andrew@0: andrew@0: void RecordedMultipleAudio::displayMedianErrors(){ andrew@0: printf("Medians of the Decoded Tempo variations\n"); andrew@0: for (int i = 0;i < 4;i++){ andrew@0: //printErrorsForMetricalPosition(i); andrew@0: std::sort(errorsByMetricalPosition[i].begin(), errorsByMetricalPosition[i].end());//sort vector andrew@0: double median = errorsByMetricalPosition[i][(int)(errorsByMetricalPosition[i].size()/2)]; andrew@0: printf("median for metrical position %i is %f\n", i, median); andrew@0: } andrew@0: } andrew@0: andrew@0: andrew@0: void RecordedMultipleAudio::displayKickRelativeMedianErrors(){ andrew@0: printf("Medians of the KR variations\n"); andrew@0: andrew@0: DoubleVector tmpKRErrors; andrew@0: andrew@0: andrew@0: for (int i = 0;i < 4;i++){ andrew@0: andrew@0: tmpKRErrors.clear(); andrew@0: int index = 0; andrew@0: andrew@0: while (index+i < kickRelativeErrors.size()) { andrew@0: tmpKRErrors.push_back(kickRelativeErrors[index + i]); andrew@0: index += 4; andrew@0: } andrew@0: andrew@0: // for (int k = 0;k < tmpKRErrors.size();k++) andrew@0: // printf("kr %i [%i] = %f\n", i, k, tmpKRErrors[k]); andrew@0: andrew@0: //printErrorsForMetricalPosition(i); andrew@0: std::sort(tmpKRErrors.begin(), tmpKRErrors.end());//sort vector andrew@0: andrew@0: // for (int k = 0;k < tmpKRErrors.size();k++) andrew@0: // printf("sorted kr %i [%i] = %f\n", i, k, tmpKRErrors[k]); andrew@0: andrew@0: andrew@0: double median = tmpKRErrors[(int)(tmpKRErrors.size()/2)]; andrew@0: printf("median for metrical position %i is %f\n", i, median); andrew@0: } andrew@0: } andrew@0: andrew@0: void RecordedMultipleAudio::printErrorsForMetricalPosition(const int& i){ andrew@0: for (int k = 0;k < errorsByMetricalPosition[i].size();k++){ andrew@0: printf("metrical posn %i, [%i] = %f\n", i, k, errorsByMetricalPosition[i][k]); andrew@0: } andrew@0: } andrew@0: andrew@0: #pragma mark -drawTracks andrew@0: andrew@0: void RecordedMultipleAudio::drawTracks(){ andrew@0: if (drawWindow == 0){ andrew@0: for (int i = 0;i < numberOfAudioTracks;i++){ andrew@0: loadedAudioFiles[i].draw(); andrew@0: } andrew@0: } else { andrew@0: drumTimingAnalyser.drawTempoCurve(); andrew@0: } andrew@0: } andrew@0: andrew@0: #pragma mark -update andrew@0: void RecordedMultipleAudio::updatePosition(){ andrew@0: for (int i = 0;i < numberOfAudioTracks;i++) andrew@0: loadedAudioFiles[i].updateToPlayPosition(); andrew@0: } andrew@0: andrew@0: void RecordedMultipleAudio::updatePositionToMillis(const double& millis){ andrew@0: for (int i = 0;i < numberOfAudioTracks;i++) andrew@0: loadedAudioFiles[i].updateToMillisPosition(millis); andrew@0: } andrew@0: andrew@0: void RecordedMultipleAudio::updatePlaybackPositionToMillis(const double& millis){ andrew@0: for (int i = 0;i < numberOfAudioTracks;i++) andrew@0: loadedAudioFiles[i].updatePlaybackPositionToMillis(millis); andrew@0: } andrew@0: andrew@0: void RecordedMultipleAudio::switchScreens(){ andrew@0: for (int i = 0;i < numberOfAudioTracks;i++) andrew@0: loadedAudioFiles[i].switchScreens(); andrew@0: } andrew@0: andrew@0: andrew@0: void RecordedMultipleAudio::togglePlay(){ andrew@0: for (int i = 0;i < numberOfAudioTracks;i++) andrew@0: loadedAudioFiles[i].togglePlay(); andrew@0: } andrew@0: andrew@0: void RecordedMultipleAudio::stop(){ andrew@0: for (int i = 0;i < numberOfAudioTracks;i++) andrew@0: loadedAudioFiles[i].stop(); andrew@0: } andrew@0: andrew@0: andrew@0: void RecordedMultipleAudio::printInfo(){ andrew@0: loadedAudioFiles[0].fileLoader.onsetDetect.printChromaInfo(); andrew@0: loadedAudioFiles[0].printEvents(); andrew@0: } andrew@0: andrew@0: void RecordedMultipleAudio::windowResized(const int& w, const int& h){ andrew@0: for (int i = 0;i < numberOfAudioTracks;i++) andrew@0: loadedAudioFiles[i].windowResized(w, h); andrew@0: } andrew@0: andrew@0: void RecordedMultipleAudio::zoomIn(){ andrew@0: if (drawWindow == 0){ andrew@0: printf("zoom in\n"); andrew@0: for (int i = 0;i < numberOfAudioTracks;i++) andrew@0: loadedAudioFiles[i].fileLoader.zoomIn(); andrew@0: } andrew@0: andrew@0: if (drawWindow == 1) andrew@0: drumTimingAnalyser.zoomIn();//numberOfPointsPerPage /= 2; andrew@0: } andrew@0: andrew@0: void RecordedMultipleAudio::zoomOut(){ andrew@0: printf("zoom out\n"); andrew@0: for (int i = 0;i < numberOfAudioTracks;i++) andrew@0: loadedAudioFiles[i].fileLoader.zoomOut(); andrew@0: andrew@0: if (drawWindow == 1) andrew@0: drumTimingAnalyser.zoomOut();//numberOfPointsPerPage *= 2; andrew@0: andrew@0: } andrew@0: andrew@0: