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