andrew@2: /* andrew@2: * PreciseOnsetVisualiser.cpp andrew@2: * ofxPreciseOnsetDetectionOffline andrew@2: * andrew@2: * Created by Andrew Robertson on 28/12/2013. andrew@2: * Copyright 2013 QMUL. All rights reserved. andrew@2: * andrew@2: */ andrew@2: andrew@2: #include "PreciseOnsetVisualiser.h" andrew@2: andrew@2: PreciseOnsetVisualiser::PreciseOnsetVisualiser(){ andrew@2: andrew@2: } andrew@2: andrew@2: PreciseOnsetVisualiser::~PreciseOnsetVisualiser(){ andrew@3: printf("deleting pointer in visualiser\n"); andrew@6: pod = NULL; andrew@2: delete pod; andrew@6: andrew@2: } andrew@2: andrew@2: void PreciseOnsetVisualiser::newFile(){ andrew@2: resetWindow(); Venetian@7: Venetian@7: //problem example Venetian@7: //soundPlay.loadSound("/Users/andrew/Music/Logic/GreenOnionsEvaluationThree/GreenOnionsEvaluationMetronome3/Audio Files/SM57_Metronome#13.aif");//.c_str()); Venetian@7: andrew@2: windowPress = 0; Venetian@7: printf("Precise onset, loading...'%s'\n", pod->loadedFilename.c_str()); andrew@2: soundPlay.loadSound(pod->loadedFilename, false); Venetian@7: stop();//sets it not playing at beginning andrew@2: } andrew@2: andrew@4: double PreciseOnsetVisualiser::windowWidth(){ andrew@4: return windowEnd - windowStart; andrew@4: } andrew@4: andrew@2: void PreciseOnsetVisualiser::update(){ andrew@6: currentPlayPosition = positionSeconds(); andrew@6: if (currentPlayPosition > windowEnd){ andrew@4: double tmp = windowWidth(); andrew@4: windowEnd += tmp; andrew@4: windowStart += tmp; andrew@4: //printf("Scrolling\n"); andrew@4: } andrew@2: andrew@2: } andrew@2: andrew@4: andrew@2: void PreciseOnsetVisualiser::draw(){ Venetian@7: ofSetLineWidth(1); andrew@2: //if plotting use this, else comment out andrew@2: andrew@2: ofSetColor(ofColor::white); andrew@2: window.drawBackground(); andrew@2: ofSetColor(ofColor::black); andrew@2: window.drawOutline(); andrew@4: Venetian@7: ofDrawBitmapString(title, window.x+60, window.y - 10); Venetian@7: andrew@4: //draw df function andrew@4: /* andrew@4: int startIndex = 0; andrew@4: while (startIndex < (int)pod->dfValues.size() && pod->frameIndexToSeconds(startIndex) < windowStart) andrew@4: startIndex++; andrew@4: andrew@4: int endIndex = 0; andrew@4: while (endIndex < (int)pod->dfValues.size()-1 && pod->frameIndexToSeconds(endIndex) < windowEnd) andrew@4: endIndex++; andrew@4: */ andrew@4: ofSetColor(ofColor::tan); andrew@4: // plotter.drawVector(pod->dfValues, startIndex, endIndex, window); andrew@4: plotter.drawVector(pod->dfValues, round(pod->secondsToFrameIndex(windowStart)), round(pod->secondsToFrameIndex(windowEnd)), window); Venetian@7: andrew@4: ofSetColor(ofColor::black); andrew@4: ofDrawBitmapString(ofToString(round(pod->secondsToFrameIndex(windowStart)), 1), window.x, window.y-10); andrew@4: ofDrawBitmapString(ofToString(round(pod->secondsToFrameIndex(windowEnd)), 1), window.x+window.width, window.y-10); andrew@4: andrew@2: ofSetColor(ofColor::blue); Venetian@7: // plotter.drawBeatStripes(pod->onsetLocations, window, windowStart, windowEnd); Venetian@7: plotter.drawBeatStripes(pod->onsetList, window, windowStart, windowEnd); Venetian@7: drawOnsetInfo(pod->onsetList, window, windowStart, windowEnd); andrew@2: andrew@4: //play position andrew@2: ofSetColor(ofColor::red); andrew@3: plotter.drawStripe(positionSeconds(), window, windowStart, windowEnd); andrew@2: andrew@4: ofSetColor(ofColor::black); andrew@4: ofDrawBitmapString(ofToString(windowStart, 1), window.x, window.y+window.height+10); andrew@4: ofDrawBitmapString(ofToString(windowEnd, 1), window.x+window.width, window.y+window.height+10); andrew@4: andrew@2: } andrew@2: Venetian@7: void PreciseOnsetVisualiser::drawOnsetInfo(std::vector onsetList, ofxWindowRegion& window, double startTime, double endTime){ Venetian@7: ofSetColor(ofColor::darkBlue); Venetian@7: if (endTime > startTime){ Venetian@7: int index = 0; Venetian@7: while (index < onsetList.size() && onsetList[index].onsetLocation < startTime) { Venetian@7: index++; Venetian@7: } Venetian@7: Venetian@7: int pos = max(0, window.x - 45); Venetian@7: ofDrawBitmapString("onsetLocation", pos, window.y+window.height+10); Venetian@7: ofDrawBitmapString("beatPosition", pos, window.y+window.height+30); Venetian@7: ofDrawBitmapString("onsetType", pos, window.y+window.height+50); Venetian@7: if (pod->isBass){ Venetian@7: ofDrawBitmapString("pitch", pos, window.y+window.height+70); Venetian@7: ofDrawBitmapString("midiPitch", pos, window.y+window.height+90); Venetian@7: ofDrawBitmapString("midiPrediction", pos, window.y+window.height+110); Venetian@7: ofDrawBitmapString("midiName", pos, window.y+window.height+130); Venetian@7: ofDrawBitmapString("exp timing", pos, window.y+window.height+150); Venetian@7: } Venetian@7: Venetian@7: while (index < onsetList.size() && onsetList[index].onsetLocation <= endTime){ Venetian@7: pos = window.width*((onsetList[index].onsetLocation - startTime)/(endTime - startTime)); Venetian@7: pos += window.x; Venetian@7: int lineWidth = 20; Venetian@7: ofDrawBitmapString(ofToString(onsetList[index].onsetLocation, 2), pos, window.y+window.height+10); Venetian@7: ofDrawBitmapString(ofToString(onsetList[index].beatPosition, 0), pos, window.y+window.height+30); Venetian@7: ofDrawBitmapString(ofToString(onsetList[index].onsetType, 0), pos, window.y+window.height+50); Venetian@7: if (pod->isBass){ Venetian@7: ofDrawBitmapString(ofToString(onsetList[index].pitch, 1), pos, window.y+window.height+70); Venetian@7: ofDrawBitmapString(ofToString(onsetList[index].midiPitch, 0), pos, window.y+window.height+90); Venetian@7: if (onsetList[index].midiPrediction == onsetList[index].roundedPitch) Venetian@7: ofSetColor(ofColor::darkGreen); Venetian@7: else if (abs(onsetList[index].midiPrediction - onsetList[index].roundedPitch) == 12) Venetian@7: ofSetColor(ofColor::orange); Venetian@7: else Venetian@7: ofSetColor(ofColor::darkRed); Venetian@7: Venetian@7: ofDrawBitmapString(ofToString(onsetList[index].midiPrediction, 0), pos, window.y+window.height+110); Venetian@7: ofSetColor(ofColor::darkBlue); Venetian@7: ofDrawBitmapString(onsetList[index].midiName, pos, window.y+window.height+130); Venetian@7: if (onsetList[index].expressiveTiming) Venetian@7: ofDrawBitmapString(ofToString(1000.0*onsetList[index].expressiveTiming, 1), pos, window.y+window.height+150); Venetian@7: } Venetian@7: Venetian@7: // ofLine(pos, window.y, pos, window.y+window.height); Venetian@7: index++; Venetian@7: } Venetian@7: } Venetian@7: } Venetian@7: Venetian@7: Venetian@7: andrew@3: double PreciseOnsetVisualiser::positionSeconds(){ andrew@3: return soundPlay.getPosition()*pod->samples/44100.; andrew@3: } andrew@3: andrew@2: //void PreciseOnsetVisualiser::drawOnsets(DoubleVector& onsetTimesSeconds, ofxWindowregion& window, double startTime, double endTime){ andrew@2: //} andrew@2: andrew@2: void PreciseOnsetVisualiser::resetWindow(){ andrew@2: windowStart = 0; andrew@3: windowEnd = 8; andrew@3: // while (windowEnd < pod->samples/44100.) andrew@3: // windowEnd *= 2; andrew@3: Venetian@7: // windowEnd = pod->samples/44100.; andrew@3: andrew@2: printf("reset: start %.1f end %.1f\n", windowStart, windowEnd); andrew@2: } andrew@2: andrew@2: void PreciseOnsetVisualiser::cropStart(){ andrew@3: if (soundPlay.getPositionMS()/1000. < windowEnd){ andrew@3: windowStart = soundPlay.getPositionMS()/1000.; andrew@3: printf("s: start %.1f end %.1f\n", windowStart, windowEnd); andrew@3: } andrew@2: } andrew@2: andrew@3: void PreciseOnsetVisualiser::cropStartSeconds(double& val){ andrew@3: if (val < windowEnd) andrew@3: windowStart = val; andrew@3: } andrew@3: andrew@3: void PreciseOnsetVisualiser::cropEnd(){//crops to play position andrew@3: andrew@3: if (soundPlay.getPositionMS()/1000. > windowStart){ andrew@3: windowEnd = soundPlay.getPositionMS()/1000.; andrew@3: printf("crop end: start %.1f end %.1f\n", windowStart, windowEnd); andrew@3: } andrew@3: } andrew@3: andrew@3: andrew@3: void PreciseOnsetVisualiser::cropEndSeconds(double& val){ andrew@3: if (val > windowStart) andrew@3: windowEnd = val; andrew@2: andrew@2: printf("crop end: start %.1f end %.1f\n", windowStart, windowEnd); andrew@2: } andrew@2: andrew@2: andrew@2: void PreciseOnsetVisualiser::mousePressed(int& x, int& y){ andrew@2: if (window.tapped(x, y)){ andrew@2: windowPress = windowStart + (windowEnd-windowStart)*(x - window.x)/window.width; andrew@3: double newPos = windowPress/(double)(pod->samples/44100.); andrew@3: printf("window position is %.1f new pos %f\n", windowPress, newPos); andrew@3: soundPlay.setPositionMS(windowPress*1000.0); andrew@2: } andrew@2: } andrew@2: andrew@2: void PreciseOnsetVisualiser::togglePlay(){ andrew@2: if (!paused ){ andrew@2: soundPlay.setPaused(true); andrew@2: paused = true; Venetian@7: //printf("was playing\n"); andrew@2: } andrew@2: else { andrew@2: soundPlay.setPaused(false);// andrew@2: paused = false; Venetian@7: //printf("was not playing\n"); andrew@2: } andrew@3: } andrew@2: andrew@3: void PreciseOnsetVisualiser::stop(){ andrew@3: soundPlay.stop(); andrew@3: //then get set to be played andrew@3: soundPlay.play(); andrew@3: soundPlay.setPaused(true); andrew@3: soundPlay.setPositionMS(windowStart*1000.0); andrew@3: paused = true; andrew@4: } andrew@4: andrew@4: void PreciseOnsetVisualiser::zoomIn(){ andrew@4: double positionNow = positionSeconds(); andrew@4: if (positionNow > windowEnd){ andrew@4: double tmp = windowWidth(); andrew@4: windowEnd += windowWidth(); andrew@4: windowStart += tmp; andrew@4: } andrew@4: andrew@4: windowStart = positionNow - (windowEnd-windowStart)/4; andrew@4: if (windowStart < 0) andrew@4: windowStart = 0; andrew@4: windowEnd = positionNow + (windowEnd-windowStart)/4; andrew@4: } andrew@4: andrew@4: andrew@4: void PreciseOnsetVisualiser::zoomOut(){ andrew@4: double positionNow = positionSeconds(); andrew@4: if (positionNow > windowEnd){ andrew@4: double tmp = windowWidth(); andrew@4: windowEnd += tmp; andrew@4: windowStart += tmp; andrew@4: } andrew@4: andrew@4: windowStart = positionNow - (windowEnd-windowStart); andrew@4: windowEnd = positionNow + (windowEnd-windowStart); andrew@4: if (windowStart < 0) andrew@4: windowStart = 0; andrew@4: } andrew@4: andrew@4: void PreciseOnsetVisualiser::scrollLeft(){ andrew@4: double tmp = windowWidth(); andrew@4: windowStart = max(0., windowStart - windowWidth()/2.); andrew@4: windowEnd = windowStart + tmp; andrew@4: checkPosition(); andrew@4: } andrew@4: andrew@4: andrew@4: void PreciseOnsetVisualiser::scrollRight(){ andrew@4: double tmp = windowWidth(); andrew@4: windowStart = min( windowStart+tmp/2., pod->samples/44100.); andrew@4: windowEnd = windowStart + tmp; andrew@4: checkPosition(); andrew@4: } andrew@4: andrew@6: void PreciseOnsetVisualiser::scrollRightSecs(double secs){ andrew@6: double positionNow = positionSeconds(); andrew@6: double newPosition = min(positionNow+secs, pod->samples/44100.); andrew@6: soundPlay.setPositionMS(newPosition*1000.); andrew@6: double tmp = windowWidth()/2.; andrew@6: while (windowEnd < newPosition){ andrew@6: windowEnd += tmp; andrew@6: windowStart += tmp; andrew@6: } andrew@6: } andrew@6: andrew@6: andrew@6: void PreciseOnsetVisualiser::scrollLeftSecs(double secs){ andrew@6: double positionNow = positionSeconds(); andrew@6: double newPosition = max(positionNow-secs, 0.); andrew@6: soundPlay.setPositionMS(newPosition*1000.); andrew@6: double tmp = windowWidth()/2.; andrew@6: while (windowStart > newPosition){ andrew@6: windowEnd -= tmp; andrew@6: windowStart -= tmp; andrew@6: } andrew@6: } andrew@6: andrew@6: andrew@4: void PreciseOnsetVisualiser::checkPosition(){ andrew@4: double positionNow = positionSeconds(); andrew@4: if (positionNow < windowStart || positionNow > windowEnd) andrew@6: soundPlay.setPositionMS(windowStart*1000.); andrew@6: } andrew@6: andrew@6: andrew@6: void PreciseOnsetVisualiser::setPositionSeconds(double secs){ andrew@6: soundPlay.setPositionMS(secs*1000.); andrew@6: double tmp = windowEnd - windowStart; andrew@6: while (windowStart > max(0. , secs)){ andrew@6: windowStart -= tmp; andrew@6: windowEnd -= tmp; andrew@6: } andrew@6: while (windowEnd < min(pod->samples/44100. , secs)){ andrew@6: windowStart += tmp; andrew@6: windowEnd += tmp; andrew@6: } andrew@6: } andrew@6: andrew@6: double PreciseOnsetVisualiser::lengthSeconds(){ andrew@6: return pod->samples/44100.; andrew@6: } Venetian@7: Venetian@7: Venetian@7: void PreciseOnsetVisualiser::keyPressed(int key){ Venetian@7: switch (key) { Venetian@7: case 'r': Venetian@7: resetWindow(); Venetian@7: break; Venetian@7: case 's': Venetian@7: cropStart(); Venetian@7: break; Venetian@7: case 'e': Venetian@7: cropEnd(); Venetian@7: break; Venetian@7: case ' ': Venetian@7: togglePlay(); Venetian@7: break; Venetian@7: case OF_KEY_RETURN: Venetian@7: stop(); Venetian@7: Venetian@7: break; Venetian@7: Venetian@7: case OF_KEY_UP: case 'u': Venetian@7: zoomIn(); Venetian@7: break; Venetian@7: case OF_KEY_DOWN: Venetian@7: zoomOut(); Venetian@7: break; Venetian@7: case OF_KEY_RIGHT: Venetian@7: scrollRight(); Venetian@7: break; Venetian@7: case OF_KEY_LEFT: Venetian@7: scrollLeft(); Venetian@7: break; Venetian@7: Venetian@7: default: Venetian@7: break; Venetian@7: } Venetian@7: }