| 
					
				 | 
			
			
				@@ -0,0 +1,87 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#include "Clock.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+namespace midi { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+Clock::Clock() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    : bpm(60), running(false) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+unsigned int Clock::getBpm() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    bpm_mutex.lock(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    bpm_type b = bpm; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    bpm_mutex.unlock(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return b; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void Clock::setBpm(bpm_type b) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(b == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        throw "bpm may not be 0."; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    bpm_mutex.lock(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    bpm = b; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    bpm_mutex.unlock(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+Clock::duration Clock::getTickInterval() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Clock::duration minute = std::chrono::duration_cast<Clock::duration>( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        std::chrono::minutes(1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return minute / getBpm(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void Clock::start() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(isRunning()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        throw "already running"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    setRunning(true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    stopTickThread = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    lastTickTime = time_point(); // epoch 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tickThread = std::thread(&Clock::run, this); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void Clock::stop() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(!isRunning()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        throw "not running"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tickThread.detach(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    stopTickThread = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+bool Clock::isRunning() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    running_mutex.lock(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    bool r = running; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    running_mutex.unlock(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return r; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void Clock::tick() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void Clock::run() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    while(!stopTickThread) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if((now() - lastTickTime) >= getTickInterval()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            lastTickTime = now(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            tick(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        std::this_thread::sleep_for(std::chrono::microseconds(1000)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    setRunning(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void Clock::setRunning(bool r) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    running_mutex.lock(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    running = r; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    running_mutex.unlock(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}; 
			 |