#include #include #include #include #include #include "Bar.h" class Loop { std::thread loopThread; std::chrono::milliseconds lastBeatTime; unsigned short bpm; std::mutex bpmLock; bool stopNext; public: bool enabled; unsigned short currentBarIndex; unsigned short currentBeatIndex; std::vector bars; Loop() : loopThread(&Loop::loop, this), bpm(60), stopNext(false), enabled(false), currentBarIndex(0), currentBeatIndex(0), lastBeatTime(0), bars(1) { } ~Loop() { stopNext = true; loopThread.join(); } void setBpm(unsigned short b) { bpmLock.lock(); bpm = b; bpmLock.unlock(); } unsigned short getBpm() { bpmLock.lock(); unsigned short r = bpm; bpmLock.unlock(); return r; } std::chrono::milliseconds getBeatDuration() { return std::chrono::milliseconds( (long long)((double)60 * 1000 / bpm) ); } void start() { enabled = true; } void stop() { enabled = false; } private: std::chrono::milliseconds getMillisecondsSinceEpoch() { std::chrono::system_clock::time_point now = std::chrono::system_clock::now(); std::chrono::system_clock::duration duration = now.time_since_epoch(); return std::chrono::duration_cast(duration); } void beat() { // std::cout << "\a" << lastBeatTime.count() << std::endl; if(bars.size() > 0) { if(currentBarIndex >= bars.size()) { currentBarIndex = 0; } if(currentBeatIndex >= bars[currentBarIndex].beatsCount) { currentBeatIndex = 0; currentBarIndex++; if(currentBarIndex >= bars.size()) { currentBarIndex = 0; } } std::cout << "trigger bar#" << currentBarIndex << " beat#" << currentBeatIndex << std::endl; bars[currentBarIndex].beats[currentBeatIndex].trigger(); currentBeatIndex++; } lastBeatTime = getMillisecondsSinceEpoch(); } void loop() { while(!stopNext) { if(enabled && (getMillisecondsSinceEpoch() - lastBeatTime) >= getBeatDuration()) { beat(); } } } };