git ssb

0+

dinoworm 🐛 / metronome



Commit 2431efbc25dadc7996fc6ca2d7748bc2f467b4e9

tap tap

Michael Williams committed on 5/13/2018, 1:00:28 PM
Parent: fca343292fb72c697c29294488b5b36397ac1dc5

Files changed

src/clock.rschanged
src/control.rschanged
src/interface.rschanged
src/main.rschanged
src/clock.rsView
@@ -6,10 +6,8 @@
66 use std::sync::mpsc::{channel, Sender, Receiver, TryRecvError};
77
88 use control;
99
10-pub type Time = Instant;
11-
1210 pub type Nanos = u64;
1311 pub type Ticks = u64;
1412 pub type Beats = u64;
1513 pub type Bars = u64;
@@ -21,34 +19,37 @@
2119 static DEFAULT_BEATS_PER_BAR: u64 = 4;
2220 static DEFAULT_BARS_PER_LOOP: u64 = 4;
2321 static DEFAULT_BEATS_PER_MINUTE: f64 = 60_f64;
2422
25-#[derive(Clone, Copy, Debug, Hash)]
23 +#[derive(Clone, Copy, Debug)]
2624 pub struct ClockSignature {
2725 pub nanos_per_beat: u64, // tempo
2826 pub ticks_per_beat: u64, // meter
2927 pub beats_per_bar: u64, // meter
3028 pub bars_per_loop: u64,
3129 }
3230
3331 impl ClockSignature {
34- pub fn new (beats_per_minute: f64) -> Self {
35- let minutes_per_beat = 1_f64 / beats_per_minute;
36- let seconds_per_beat = minutes_per_beat * SECONDS_PER_MINUTE as f64;
37- let nanos_per_beat = seconds_per_beat * NANOS_PER_SECOND as f64;
38-
32 + pub fn new (nanos_per_beat: u64) -> Self {
3933 Self {
40- nanos_per_beat: nanos_per_beat as u64,
34 + nanos_per_beat: nanos_per_beat,
4135 ticks_per_beat: DEFAULT_TICKS_PER_BEAT,
4236 beats_per_bar: DEFAULT_BEATS_PER_BAR,
4337 bars_per_loop: DEFAULT_BARS_PER_LOOP,
4438 }
4539 }
4640
4741 pub fn default () -> Self {
48- Self::new(DEFAULT_BEATS_PER_MINUTE)
42 + Self::from_beats_per_minute(DEFAULT_BEATS_PER_MINUTE)
4943 }
5044
45 + pub fn from_beats_per_minute (beats_per_minute: f64) -> Self {
46 + let minutes_per_beat = 1_f64 / beats_per_minute;
47 + let seconds_per_beat = minutes_per_beat * SECONDS_PER_MINUTE as f64;
48 + let nanos_per_beat = seconds_per_beat * NANOS_PER_SECOND as f64;
49 + Self::new(nanos_per_beat as u64)
50 + }
51 +
5152 pub fn to_beats_per_minute (&self) -> f64 {
5253 let nanos_per_beat = self.nanos_per_beat;
5354 let beats_per_nano = 1_f64 / self.nanos_per_beat as f64;
5455 let beats_per_second = beats_per_nano * NANOS_PER_SECOND as f64;
@@ -67,8 +68,12 @@
6768 pub fn nanos_per_bar (&self) -> u64 {
6869 self.nanos_per_beat() * self.beats_per_bar
6970 }
7071
72 + pub fn nanos_per_loop (&self) -> u64 {
73 + self.nanos_per_bar() * self.bars_per_loop
74 + }
75 +
7176 pub fn nanos_to_ticks (&self, nanos: Nanos) -> u64 {
7277 (nanos / self.nanos_per_tick()) % self.ticks_per_beat
7378 }
7479
@@ -80,50 +85,77 @@
8085 nanos / self.nanos_per_bar() % self.bars_per_loop
8186 }
8287 }
8388
84-#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
89 +#[derive(Clone, Copy, Debug)]
8590 pub struct ClockTime {
86- pub nanos: Nanos,
87- pub ticks: Ticks,
88- pub beats: Beats,
89- pub bars: Bars
91 + nanos: Nanos,
92 + signature: ClockSignature
9093 }
9194
9295 impl ClockTime {
9396 pub fn new (nanos: Nanos, signature: ClockSignature) -> Self {
9497 Self {
9598 nanos,
96- ticks: signature.nanos_to_ticks(nanos),
97- beats: signature.nanos_to_beats(nanos),
98- bars: signature.nanos_to_bars(nanos),
99- // ticks_til_beat: signature.ticks_til_beat(nanos),
100- // beats_til_bar: signature.beats_til_bar(nanos)
99 + signature
101100 }
102101 }
102 +
103 + pub fn nanos (&self) -> Nanos {
104 + self.nanos
105 + }
106 +
107 + pub fn ticks (&self) -> Ticks {
108 + self.signature.nanos_to_ticks(self.nanos)
109 + }
110 +
111 + pub fn beats (&self) -> Beats {
112 + self.signature.nanos_to_beats(self.nanos)
113 + }
114 +
115 + pub fn bars (&self) -> Bars {
116 + self.signature.nanos_to_bars(self.nanos)
117 + }
118 +
119 + pub fn nanos_since_loop (&self) -> Nanos {
120 + self.nanos % self.signature.nanos_per_loop()
121 + }
122 +
123 + pub fn nanos_since_tick (&self) -> Nanos {
124 + self.nanos % self.signature.nanos_per_tick()
125 + }
126 +
127 + pub fn nanos_since_beat (&self) -> Nanos {
128 + self.nanos % self.signature.nanos_per_beat()
129 + }
130 +
131 + pub fn nanos_since_bar (&self) -> Nanos {
132 + self.nanos % self.signature.nanos_per_bar()
133 + }
103134 }
104135
105136 #[derive(Debug)]
106137 pub struct Clock {
107- start: Time,
108- tick: Time,
138 + nanos: Nanos,
139 + instant: Instant,
109140 signature: ClockSignature
110141 }
111142
112143 pub enum ClockMessage {
144 + NudgeTempo(f64),
113145 Reset,
114- NudgeTempo(f64),
115- Signature(ClockSignature)
146 + Signature(ClockSignature),
147 + Tap,
116148 }
117149
118150 impl Clock {
119151 pub fn new () -> Self {
120- let start = Time::now();
152 + let instant = Instant::now();
121153 let signature = ClockSignature::default();
122154
123155 Self {
124- start,
125- tick: start,
156 + nanos: 0,
157 + instant,
126158 signature
127159 }
128160 }
129161
@@ -131,9 +163,9 @@
131163 let mut clock = Self::new();
132164
133165 let (tx, rx) = channel();
134166
135- control_tx.send(control::ControlMessage::Signature(ClockSignature::new(DEFAULT_BEATS_PER_MINUTE))).unwrap();
167 + control_tx.send(control::ControlMessage::Signature(ClockSignature::from_beats_per_minute(DEFAULT_BEATS_PER_MINUTE))).unwrap();
136168
137169 spawn(move|| {
138170 loop {
139171 // wait a tick
@@ -150,12 +182,27 @@
150182 },
151183 Ok(ClockMessage::Signature(signature)) => {
152184 clock.signature = signature;
153185 },
186 + Ok(ClockMessage::Tap) => {
187 + // find how far off the beat we are
188 + let time = clock.time();
189 + let nanos_since_beat = time.nanos_since_beat();
190 + let nanos_per_beat = time.signature.nanos_per_beat();
191 + let nanos_per_half_beat = time.signature.nanos_per_beat() / 2;
192 + // if the beat happened recently
193 + if nanos_since_beat < nanos_per_half_beat {
194 + // nudge back to the beat
195 + clock.nanos = time.nanos - nanos_since_beat
196 + } else {
197 + // nudge to the next beat
198 + clock.nanos = time.nanos + nanos_per_beat - nanos_since_beat
199 + }
200 + },
154201 Ok(ClockMessage::NudgeTempo(nudge)) => {
155202 let old_beats_per_minute = clock.signature.to_beats_per_minute();
156- let new_beats_per_minute = old_beats_per_minute - nudge;
157- let next_signature = ClockSignature::new(new_beats_per_minute);
203 + let new_beats_per_minute = old_beats_per_minute + nudge;
204 + let next_signature = ClockSignature::from_beats_per_minute(new_beats_per_minute);
158205 control_tx.send(control::ControlMessage::Signature(next_signature));
159206 },
160207 Err(TryRecvError::Empty) => {},
161208 Err(TryRecvError::Disconnected) => {
@@ -168,41 +215,40 @@
168215 tx
169216 }
170217
171218 pub fn reset (&mut self) {
172- self.start = Time::now();
219 + self.nanos = 0;
220 + self.instant = Instant::now();
173221 }
174222
175223 pub fn time (&self) -> ClockTime {
176- ClockTime::new(self.nanos_since_start(), self.signature)
224 + ClockTime::new(self.nanos_since_loop(), self.signature)
177225 }
178226
179- pub fn diff (&self) -> ClockTime {
180- let nanos_since_tick = self.nanos_since_tick();
181- let nanos_per_tick = self.signature.nanos_per_tick();
182- let diff = nanos_per_tick - nanos_since_tick;
183- ClockTime::new(diff, self.signature)
227 + pub fn nanos_since_loop (&self) -> Nanos {
228 + self.nanos % self.signature.nanos_per_loop()
184229 }
185-
186- pub fn nanos_since_start (&self) -> Nanos {
187- duration_to_nanos(self.start.elapsed())
188- }
189230
190231 pub fn nanos_since_tick (&self) -> Nanos {
191- duration_to_nanos(self.tick.elapsed())
232 + duration_to_nanos(self.instant.elapsed()) % self.signature.nanos_per_tick()
192233 }
193234
235 + pub fn nanos_until_tick (&self) -> Nanos {
236 + let nanos_since_tick = self.nanos_since_tick();
237 + let nanos_per_tick = self.signature.nanos_per_tick();
238 + nanos_per_tick - nanos_since_tick
239 + }
240 +
194241 // https://github.com/BookOwl/fps_clock/blob/master/src/lib.rs
195- pub fn tick (&mut self) -> ClockTime {
196- let diff = self.diff();
242 + pub fn tick (&mut self) -> Nanos {
243 + let nanos_until_tick = self.nanos_until_tick();
197244
198- if diff.nanos > 0 {
199- sleep(Duration::new(0, diff.nanos as u32))
200- };
245 + sleep(Duration::new(0, nanos_until_tick as u32));
201246
202- self.tick = Time::now();
247 + self.nanos = self.nanos + nanos_until_tick;
248 + self.instant = Instant::now();
203249
204- diff
250 + nanos_until_tick
205251 }
206252 }
207253
208254 fn duration_to_nanos (duration: Duration) -> Nanos {
src/control.rsView
@@ -24,12 +24,11 @@
2424 Time(clock::ClockTime),
2525 Signature(clock::ClockSignature),
2626 Reset,
2727 NudgeTempo(f64),
28- TapTempo
28 + Tap,
2929 /*
3030 Stop,
31- SetTempo,
3231 NudgeClock,
3332 Configure
3433 */
3534 }
src/interface.rsView
@@ -41,14 +41,14 @@
4141 match ch {
4242 Some(WchResult::KeyCode(ncurses::KEY_MOUSE)) => {
4343 }
4444
45- Some(WchResult::KeyCode(ncurses::KEY_UP)) => { // why is up down?
46- control_tx.send(control::ControlMessage::NudgeTempo(-1_f64)).unwrap();
45 + Some(WchResult::KeyCode(ncurses::KEY_UP)) => {
46 + control_tx.send(control::ControlMessage::NudgeTempo(1_f64)).unwrap();
4747 }
4848
49- Some(WchResult::KeyCode(ncurses::KEY_DOWN)) => { // why is down up?
50- control_tx.send(control::ControlMessage::NudgeTempo(1_f64)).unwrap();
49 + Some(WchResult::KeyCode(ncurses::KEY_DOWN)) => {
50 + control_tx.send(control::ControlMessage::NudgeTempo(-1_f64)).unwrap();
5151 }
5252
5353 // https://github.com/jeaye/ncurses-rs/blob/master/src/constants.rs
5454 Some(WchResult::KeyCode(_)) => {
@@ -56,9 +56,9 @@
5656
5757 // Some(WchResult::KeyCode(KEY_ENTER)) => beat(),
5858 Some(WchResult::Char(ch)) => {
5959 if (ch == CHAR_SPACE) {
60- control_tx.send(control::ControlMessage::TapTempo).unwrap();
60 + control_tx.send(control::ControlMessage::Tap).unwrap();
6161 }
6262
6363 if (ch == CHAR_NEWLINE) {
6464 control_tx.send(control::ControlMessage::Reset).unwrap();
@@ -98,33 +98,33 @@
9898 }
9999 }
100100
101101 pub fn print_beat (time: clock::ClockTime) {
102- if time.ticks == 0 {
103- if time.beats == 0 {
102 + if time.ticks() == 0 {
103 + if time.beats() == 0 {
104104 ncurses::printw("SUPER ");
105105 }
106106 ncurses::printw("BEAT");
107107 }
108108 ncurses::printw("\n");
109109 }
110110
111111 pub fn print_bar (time: clock::ClockTime) {
112- if time.bars == 0 {
112 + if time.bars() == 0 {
113113 ncurses::printw("YAY YAY YAY");
114114 }
115115 ncurses::printw("\n");
116116 }
117117
118118 pub fn print_time (time: clock::ClockTime) {
119119 ncurses::printw("nanos: ");
120- ncurses::printw(format!("{}\n", time.nanos).as_ref());
120 + ncurses::printw(format!("{}\n", time.nanos()).as_ref());
121121 ncurses::printw("ticks: ");
122- ncurses::printw(format!("{}\n", time.ticks + 1).as_ref());
122 + ncurses::printw(format!("{}\n", time.ticks() + 1).as_ref());
123123 ncurses::printw("beats: ");
124- ncurses::printw(format!("{}\n", time.beats + 1).as_ref());
124 + ncurses::printw(format!("{}\n", time.beats() + 1).as_ref());
125125 ncurses::printw("bars: ");
126- ncurses::printw(format!("{}\n", time.bars + 1).as_ref());
126 + ncurses::printw(format!("{}\n", time.bars() + 1).as_ref());
127127 }
128128
129129 pub fn print_signature (signature: clock::ClockSignature) {
130130 ncurses::printw("beats per minute: ");
@@ -136,9 +136,9 @@
136136 ncurses::printw("bars per loop: ");
137137 ncurses::printw(format!("{}\n", signature.bars_per_loop).as_ref());
138138 }
139139
140-#[derive(Clone, Copy, Debug, Hash)]
140 +#[derive(Clone, Copy, Debug)]
141141 pub enum InterfaceMessage {
142142 Time(clock::ClockTime),
143143 Signature(clock::ClockSignature),
144144 }
src/main.rsView
@@ -29,8 +29,12 @@
2929 // sent by interface
3030 control::ControlMessage::NudgeTempo(nudge) => {
3131 clock_tx.send(clock::ClockMessage::NudgeTempo(nudge)).unwrap();
3232 },
33 + // sent by interface
34 + control::ControlMessage::Tap => {
35 + clock_tx.send(clock::ClockMessage::Tap).unwrap();
36 + },
3337 // sent by clock
3438 control::ControlMessage::Signature(signature) => {
3539 clock_tx.send(clock::ClockMessage::Signature(signature)).unwrap();
3640 terminal_tx.send(interface::InterfaceMessage::Signature(signature)).unwrap();

Built with git-ssb-web