git ssb

0+

dinoworm 🐛 / metronome



Commit a2de68cc1a716fedcf010549ceed0b77aebe92f1

tap tempo

Michael Williams committed on 5/13/2018, 1:28:40 PM
Parent: 2431efbc25dadc7996fc6ca2d7748bc2f467b4e9

Files changed

src/clock.rschanged
src/clock.rsView
@@ -1,7 +1,8 @@
11 // inspired by https://github.com/mmckegg/rust-loop-drop/blob/master/src/midi_time.rs
22 // http://www.deluge.co/?q=midi-tempo-bpm
33
4 +use std::u64;
45 use std::time::{Duration, Instant};
56 use std::thread::{sleep, spawn};
67 use std::sync::mpsc::{channel, Sender, Receiver, TryRecvError};
78
@@ -134,10 +135,11 @@
134135 }
135136
136137 #[derive(Debug)]
137138 pub struct Clock {
139 + tick: Instant,
140 + tap: Option<Instant>,
138141 nanos: Nanos,
139- instant: Instant,
140142 signature: ClockSignature
141143 }
142144
143145 pub enum ClockMessage {
@@ -148,14 +150,15 @@
148150 }
149151
150152 impl Clock {
151153 pub fn new () -> Self {
152- let instant = Instant::now();
154 + let tick = Instant::now();
153155 let signature = ClockSignature::default();
154156
155157 Self {
156158 nanos: 0,
157- instant,
159 + tap: None,
160 + tick,
158161 signature
159162 }
160163 }
161164
@@ -196,8 +199,22 @@
196199 } else {
197200 // nudge to the next beat
198201 clock.nanos = time.nanos + nanos_per_beat - nanos_since_beat
199202 }
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());
200217 },
201218 Ok(ClockMessage::NudgeTempo(nudge)) => {
202219 let old_beats_per_minute = clock.signature.to_beats_per_minute();
203220 let new_beats_per_minute = old_beats_per_minute + nudge;
@@ -216,9 +233,10 @@
216233 }
217234
218235 pub fn reset (&mut self) {
219236 self.nanos = 0;
220- self.instant = Instant::now();
237 + self.tick = Instant::now();
238 + self.tap = None;
221239 }
222240
223241 pub fn time (&self) -> ClockTime {
224242 ClockTime::new(self.nanos_since_loop(), self.signature)
@@ -228,9 +246,9 @@
228246 self.nanos % self.signature.nanos_per_loop()
229247 }
230248
231249 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()
233251 }
234252
235253 pub fn nanos_until_tick (&self) -> Nanos {
236254 let nanos_since_tick = self.nanos_since_tick();
@@ -244,9 +262,9 @@
244262
245263 sleep(Duration::new(0, nanos_until_tick as u32));
246264
247265 self.nanos = self.nanos + nanos_until_tick;
248- self.instant = Instant::now();
266 + self.tick = Instant::now();
249267
250268 nanos_until_tick
251269 }
252270 }

Built with git-ssb-web