Commit a2de68cc1a716fedcf010549ceed0b77aebe92f1
tap tempo
Michael Williams committed on 5/13/2018, 1:28:40 PMParent: 2431efbc25dadc7996fc6ca2d7748bc2f467b4e9
Files changed
src/clock.rs | changed |
src/clock.rs | ||
---|---|---|
@@ -1,7 +1,8 @@ | ||
1 | 1 … | // inspired by https://github.com/mmckegg/rust-loop-drop/blob/master/src/midi_time.rs |
2 | 2 … | // http://www.deluge.co/?q=midi-tempo-bpm |
3 | 3 … | |
4 … | +use std::u64; | |
4 | 5 … | use std::time::{Duration, Instant}; |
5 | 6 … | use std::thread::{sleep, spawn}; |
6 | 7 … | use std::sync::mpsc::{channel, Sender, Receiver, TryRecvError}; |
7 | 8 … | |
@@ -134,10 +135,11 @@ | ||
134 | 135 … | } |
135 | 136 … | |
136 | 137 … | |
137 | 138 … | pub struct Clock { |
139 … | + tick: Instant, | |
140 … | + tap: Option<Instant>, | |
138 | 141 … | nanos: Nanos, |
139 | - instant: Instant, | |
140 | 142 … | signature: ClockSignature |
141 | 143 … | } |
142 | 144 … | |
143 | 145 … | pub enum ClockMessage { |
@@ -148,14 +150,15 @@ | ||
148 | 150 … | } |
149 | 151 … | |
150 | 152 … | impl Clock { |
151 | 153 … | pub fn new () -> Self { |
152 | - let instant = Instant::now(); | |
154 … | + let tick = Instant::now(); | |
153 | 155 … | let signature = ClockSignature::default(); |
154 | 156 … | |
155 | 157 … | Self { |
156 | 158 … | nanos: 0, |
157 | - instant, | |
159 … | + tap: None, | |
160 … | + tick, | |
158 | 161 … | signature |
159 | 162 … | } |
160 | 163 … | } |
161 | 164 … | |
@@ -196,8 +199,22 @@ | ||
196 | 199 … | } else { |
197 | 200 … | // nudge to the next beat |
198 | 201 … | clock.nanos = time.nanos + nanos_per_beat - nanos_since_beat |
199 | 202 … | } |
203 … | + | |
204 … | + // if second tap on beat, adjust tempo | |
205 … | + match clock.tap { | |
206 … | + Some(tap) => { | |
207 … | + let tap_diff = duration_to_nanos(tap.elapsed()); | |
208 … | + if tap_diff < (nanos_per_beat * 2) { | |
209 … | + let next_signature = ClockSignature::new(tap_diff); | |
210 … | + control_tx.send(control::ControlMessage::Signature(next_signature)); | |
211 … | + } | |
212 … | + }, | |
213 … | + None => {} | |
214 … | + } | |
215 … | + | |
216 … | + clock.tap = Some(Instant::now()); | |
200 | 217 … | }, |
201 | 218 … | Ok(ClockMessage::NudgeTempo(nudge)) => { |
202 | 219 … | let old_beats_per_minute = clock.signature.to_beats_per_minute(); |
203 | 220 … | let new_beats_per_minute = old_beats_per_minute + nudge; |
@@ -216,9 +233,10 @@ | ||
216 | 233 … | } |
217 | 234 … | |
218 | 235 … | pub fn reset (&mut self) { |
219 | 236 … | self.nanos = 0; |
220 | - self.instant = Instant::now(); | |
237 … | + self.tick = Instant::now(); | |
238 … | + self.tap = None; | |
221 | 239 … | } |
222 | 240 … | |
223 | 241 … | pub fn time (&self) -> ClockTime { |
224 | 242 … | ClockTime::new(self.nanos_since_loop(), self.signature) |
@@ -228,9 +246,9 @@ | ||
228 | 246 … | self.nanos % self.signature.nanos_per_loop() |
229 | 247 … | } |
230 | 248 … | |
231 | 249 … | pub fn nanos_since_tick (&self) -> Nanos { |
232 | - duration_to_nanos(self.instant.elapsed()) % self.signature.nanos_per_tick() | |
250 … | + duration_to_nanos(self.tick.elapsed()) % self.signature.nanos_per_tick() | |
233 | 251 … | } |
234 | 252 … | |
235 | 253 … | pub fn nanos_until_tick (&self) -> Nanos { |
236 | 254 … | let nanos_since_tick = self.nanos_since_tick(); |
@@ -244,9 +262,9 @@ | ||
244 | 262 … | |
245 | 263 … | sleep(Duration::new(0, nanos_until_tick as u32)); |
246 | 264 … | |
247 | 265 … | self.nanos = self.nanos + nanos_until_tick; |
248 | - self.instant = Instant::now(); | |
266 … | + self.tick = Instant::now(); | |
249 | 267 … | |
250 | 268 … | nanos_until_tick |
251 | 269 … | } |
252 | 270 … | } |
Built with git-ssb-web