#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() : bpm(60), stopNext(false), enabled(false), currentBarIndex(0), currentBeatIndex(0), lastBeatTime(0), loopThread(&Loop::loop, this) { } ~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; } std::cout << "trigger bar#" << currentBarIndex << std::endl; currentBarIndex++; } lastBeatTime = getMillisecondsSinceEpoch(); } void loop() { while(!stopNext) { if(enabled && (getMillisecondsSinceEpoch() - lastBeatTime) >= getBeatDuration()) { beat(); } } } };