git ssb

0+

dinoworm 🐛 / metronome



Commit de37e989827890621e4dbd2d5a5493b416130606

working interface

Michael Williams committed on 5/13/2018, 9:33:58 AM
Parent: 229b9f1cfc11b985c177c23edce4f274862be578

Files changed

src/clock.rschanged
src/control.rschanged
src/main.rschanged
src/interface.rsadded
src/clock.rsView
@@ -39,8 +39,16 @@
3939 beats_per_bar: DEFAULT_BEATS_PER_BAR
4040 }
4141 }
4242
43 + pub fn to_beats_per_minute (&self) -> f64 {
44 + let nanos_per_beat = self.nanos_per_beat;
45 + let beats_per_nano = 1_f64 / self.nanos_per_beat as f64;
46 + let beats_per_second = beats_per_nano * NANOS_PER_SECOND as f64;
47 + let beats_per_minute = beats_per_second * SECONDS_PER_MINUTE as f64;
48 + beats_per_minute
49 + }
50 +
4351 pub fn nanos_per_tick (&self) -> u64 {
4452 (self.nanos_per_beat / self.ticks_per_beat) as u64
4553 }
4654
@@ -85,58 +93,59 @@
8593 }
8694
8795 #[derive(Debug)]
8896 pub struct Clock {
89- control_tx: Sender<control::ControlMessage>,
90- start_instant: Instant,
91- tick_instant: Instant,
97 + start: Time,
98 + tick: Time,
9299 signature: ClockSignature
93100 }
94101
95102 pub enum ClockMessage {
96103 Time(ClockTime)
97104 }
98105
99106 impl Clock {
100- pub fn new (signature: ClockSignature, control: &control::Control) -> Self {
101- let start_instant = Instant::now();
107 + pub fn new (signature: ClockSignature) -> Self {
108 + let start = Time::now();
102109
103110 Self {
104- start_instant,
105- tick_instant: start_instant,
106- signature,
107- control_tx: control.tx.clone()
111 + start,
112 + tick: start,
113 + signature
108114 }
109115 }
110116
117 + pub fn start (signature: ClockSignature, control_tx: Sender<control::ControlMessage>) {
118 + let mut clock = Self::new(signature);
119 +
120 + spawn(move|| {
121 + loop {
122 + clock.tick();
123 +
124 + control_tx.send(control::ControlMessage::Time(clock.time())).unwrap();
125 + }
126 + });
127 + }
128 +
111129 pub fn time (&self) -> ClockTime {
112130 ClockTime::new(self.nanos_since_start(), self.signature)
113131 }
114132
115133 pub fn diff (&self) -> ClockTime {
116- ClockTime::new(self.nanos_since_tick(), self.signature)
134 + let nanos_since_tick = self.nanos_since_tick();
135 + let nanos_per_tick = self.signature.nanos_per_tick();
136 + let diff = nanos_per_tick - nanos_since_tick;
137 + ClockTime::new(diff, self.signature)
117138 }
118139
119140 pub fn nanos_since_start (&self) -> Nanos {
120- duration_to_nanos(self.start_instant.elapsed())
141 + duration_to_nanos(self.start.elapsed())
121142 }
122143
123144 pub fn nanos_since_tick (&self) -> Nanos {
124- duration_to_nanos(self.tick_instant.elapsed())
145 + duration_to_nanos(self.tick.elapsed())
125146 }
126147
127- pub fn start (&self) {
128- let control_tx = self.control_tx.clone();
129-
130- spawn(move|| {
131- loop {
132- self.tick();
133-
134- control_tx.send(control::ControlMessage::Time(self.time()));
135- }
136- });
137- }
138-
139148 // https://github.com/BookOwl/fps_clock/blob/master/src/lib.rs
140149 pub fn tick (&mut self) -> ClockTime {
141150 let diff = self.diff();
142151
@@ -144,9 +153,9 @@
144153 sleep(Duration::new(0, diff.nanos as u32))
145154 };
146155
147156
148- self.tick_instant = Instant::now();
157 + self.tick = Time::now();
149158
150159 diff
151160 }
152161 }
src/control.rsView
@@ -21,8 +21,9 @@
2121
2222 #[derive(Clone, Copy, Debug, Hash)]
2323 pub enum ControlMessage {
2424 Time(clock::ClockTime),
25 + Signature(clock::ClockSignature),
2526 Start,
2627 Stop,
2728 TapTempo,
2829 SetTempo,
src/main.rsView
@@ -1,125 +1,40 @@
11 extern crate ncurses;
22
3-use ncurses::{WchResult};
4-use std::char;
5-use std::sync::mpsc::{channel, Sender, Receiver};
6-use std::thread::{sleep, spawn};
7-use std::time::{Duration};
8-
93 mod clock;
104 mod control;
5 +mod interface;
116
12-// https://unicode.org/charts/PDF/U0000.pdf
13-static CHAR_SPACE: u32 = 0x0020;
14-static CHAR_RETURN: u32 = 0x000D;
15-static CHAR_NEWLINE: u32 = 0x000A;
16-
177 fn main () {
18- let control = control::Control::new();
8 + Metronome::run(60_f64);
9 +}
1910
20- let clock_signature = clock::ClockSignature::new(60_f64);
21- let mut clock = clock::Clock::new(clock_signature, &control);
2211
23- clock.start();
12 +pub type Bpm = f64;
2413
25- let terminal_interface = TerminalInterface::new(&control);
26-
27- terminal_interface.start();
28-
29- for control_message in control.rx {
30- match control_message {
31- control::ControlMessage::Time(time) => {
32- terminal_interface.tx.send(InterfaceMessage::Time(time));
33- }
34- }
35- }
14 +struct Metronome {
15 + pub bpm: Bpm
3616 }
3717
38-#[derive(Debug)]
39-pub struct TerminalInterface {
40- control_tx: Sender<control::ControlMessage>,
41- tx: Sender<InterfaceMessage>,
42- rx: Receiver<InterfaceMessage>
43-}
18 +impl Metronome {
19 + pub fn run (bpm: Bpm) {
20 + let control = control::Control::new();
4421
45-impl TerminalInterface {
46- pub fn new (control: &control::Control) -> Self {
47- let (tx, rx) = channel();
48-
49- Self {
50- control_tx: control.tx.clone(),
51- tx,
52- rx
53- }
54- }
22 + let clock_signature = clock::ClockSignature::new(bpm);
5523
56- pub fn start (&self) {
57- let control_tx = self.control_tx.clone();
24 + let clock = clock::Clock::start(clock_signature, control.tx.clone());
25 + let terminal_interface = interface::TerminalInterface::start(clock_signature, control.tx.clone());
5826
59- spawn(move|| {
60- /* Setup ncurses. */
61- ncurses::initscr();
62-
63- let locale_conf = ncurses::LcCategory::all;
64- ncurses::setlocale(locale_conf, "en_US.UTF-8");
65-
66- /* Enable mouse events. */
67- ncurses::mousemask(ncurses::ALL_MOUSE_EVENTS as ncurses::mmask_t, None);
68-
69- /* Allow for extended keyboard (like F1). */
70- ncurses::keypad(ncurses::stdscr(), true);
71- ncurses::noecho();
72-
73- loop {
74- let ch = ncurses::wget_wch(ncurses::stdscr());
75-
76- match ch {
77- Some(WchResult::KeyCode(ncurses::KEY_MOUSE)) => {
78- control_tx.send(control::ControlMessage::TapTempo).unwrap();
79- }
80-
81- // https://github.com/jeaye/ncurses-rs/blob/master/src/constants.rs
82- Some(WchResult::KeyCode(_)) => {}
83-
84- // Some(WchResult::KeyCode(KEY_ENTER)) => beat(),
85- Some(WchResult::Char(ch)) => {
86- if (ch == CHAR_SPACE || ch == CHAR_NEWLINE) {
87- control_tx.send(control::ControlMessage::TapTempo).unwrap();
88- }
89- }
90-
91- None => {}
92- }
93-
94- ncurses::refresh();
27 + for control_message in control.rx {
28 + match control_message {
29 + control::ControlMessage::Signature(signature) => {
30 + terminal_interface.tx.send(interface::InterfaceMessage::Signature(signature)).unwrap();
31 + },
32 + control::ControlMessage::Time(time) => {
33 + terminal_interface.tx.send(interface::InterfaceMessage::Time(time)).unwrap();
34 + },
35 + _ => {}
9536 }
96-
97- ncurses::endwin();
98- });
99-
100- spawn(move|| {
101- for interface_message in self.rx {
102- match interface_message {
103- InterfaceMessage::Time(time) => {
104- print_time(time);
105- }
106- }
107-
108- }
109- });
37 + }
11038 }
11139 }
11240
113-pub fn print_time (time: clock::ClockTime) {
114- ncurses::clear();
115- ncurses::mv(0, 0);
116- ncurses::printw("nanos: ");
117- ncurses::printw(format!("{}\n", time.nanos).as_ref());
118- ncurses::printw("\nticks: ");
119- ncurses::printw(format!("{}\n", time.ticks).as_ref());
120-}
121-
122-#[derive(Clone, Copy, Debug, Hash)]
123-pub enum InterfaceMessage {
124- Time(clock::ClockTime)
125-}
src/interface.rsView
@@ -1,0 +1,114 @@
1 +extern crate ncurses;
2 +
3 +use ncurses::{WchResult};
4 +use std::sync::mpsc::{channel, Sender, Receiver};
5 +use std::thread::{sleep, spawn};
6 +
7 +use clock;
8 +use control;
9 +
10 +// https://unicode.org/charts/PDF/U0000.pdf
11 +static CHAR_SPACE: u32 = 0x0020;
12 +static CHAR_RETURN: u32 = 0x000D;
13 +static CHAR_NEWLINE: u32 = 0x000A;
14 +
15 +#[derive(Debug)]
16 +pub struct TerminalInterface {
17 + pub tx: Sender<InterfaceMessage>
18 +}
19 +
20 +impl TerminalInterface {
21 + pub fn start (signature: clock::ClockSignature, control_tx: Sender<control::ControlMessage>) -> Self {
22 + let (tx, rx) = channel();
23 +
24 + let interface = Self {
25 + tx
26 + };
27 +
28 + spawn(move|| {
29 + /* Setup ncurses. */
30 + ncurses::initscr();
31 +
32 + let locale_conf = ncurses::LcCategory::all;
33 + ncurses::setlocale(locale_conf, "en_US.UTF-8");
34 +
35 + /* Enable mouse events. */
36 + ncurses::mousemask(ncurses::ALL_MOUSE_EVENTS as ncurses::mmask_t, None);
37 +
38 + /* Allow for extended keyboard (like F1). */
39 + ncurses::keypad(ncurses::stdscr(), true);
40 + ncurses::noecho();
41 +
42 + loop {
43 + let ch = ncurses::wget_wch(ncurses::stdscr());
44 +
45 + match ch {
46 + Some(WchResult::KeyCode(ncurses::KEY_MOUSE)) => {
47 + control_tx.send(control::ControlMessage::TapTempo).unwrap();
48 + }
49 +
50 + // https://github.com/jeaye/ncurses-rs/blob/master/src/constants.rs
51 + Some(WchResult::KeyCode(_)) => {}
52 +
53 + // Some(WchResult::KeyCode(KEY_ENTER)) => beat(),
54 + Some(WchResult::Char(ch)) => {
55 + if (ch == CHAR_SPACE || ch == CHAR_NEWLINE) {
56 + control_tx.send(control::ControlMessage::TapTempo).unwrap();
57 + }
58 + }
59 +
60 + None => {}
61 + }
62 +
63 + ncurses::refresh();
64 + }
65 +
66 + ncurses::endwin();
67 + });
68 +
69 + spawn(move|| {
70 + for interface_message in rx {
71 + match interface_message {
72 + InterfaceMessage::Time(time) => {
73 + ncurses::clear();
74 + ncurses::mv(0, 0);
75 + print_time(time);
76 + print_signature(signature);
77 + }
78 + InterfaceMessage::Signature(signature) => {
79 + }
80 + }
81 +
82 + ncurses::refresh();
83 + }
84 + });
85 +
86 + interface
87 + }
88 +}
89 +
90 +pub fn print_time (time: clock::ClockTime) {
91 + ncurses::printw("nanos: ");
92 + ncurses::printw(format!("{}\n", time.nanos).as_ref());
93 + ncurses::printw("ticks: ");
94 + ncurses::printw(format!("{}\n", time.ticks).as_ref());
95 + ncurses::printw("beats: ");
96 + ncurses::printw(format!("{}\n", time.beats).as_ref());
97 + ncurses::printw("bars: ");
98 + ncurses::printw(format!("{}\n", time.bars).as_ref());
99 +}
100 +
101 +pub fn print_signature (signature: clock::ClockSignature) {
102 + ncurses::printw("beats per minute: ");
103 + ncurses::printw(format!("{}\n", signature.to_beats_per_minute()).as_ref());
104 + ncurses::printw("ticks per beat: ");
105 + ncurses::printw(format!("{}\n", signature.ticks_per_beat).as_ref());
106 + ncurses::printw("beats per bar: ");
107 + ncurses::printw(format!("{}\n", signature.beats_per_bar).as_ref());
108 +}
109 +
110 +#[derive(Clone, Copy, Debug, Hash)]
111 +pub enum InterfaceMessage {
112 + Time(clock::ClockTime),
113 + Signature(clock::ClockSignature),
114 +}

Built with git-ssb-web