git ssb

0+

dinoworm 🐛 / metronome



Commit 229b9f1cfc11b985c177c23edce4f274862be578

close but no

Michael Williams committed on 5/13/2018, 8:15:18 AM
Parent: 9cf1052d129942a85af116c81a7f960330143ad6

Files changed

src/clock.rschanged
src/control.rschanged
src/main.rschanged
src/clock.rsView
@@ -1,10 +1,13 @@
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
44 use std::time::{Duration, Instant};
5-use std::thread::{sleep};
5 +use std::thread::{sleep, spawn};
6 +use std::sync::mpsc::{channel, Sender, Receiver};
67
8 +use control;
9 +
710 pub type Time = Instant;
811
912 pub type Nanos = u64;
1013 pub type Ticks = u64;
@@ -18,11 +21,11 @@
1821 static DEFAULT_BEATS_PER_BAR: u64 = 4;
1922
2023 #[derive(Clone, Copy, Debug, Hash)]
2124 pub struct ClockSignature {
22- nanos_per_beat: u64, // tempo
23- ticks_per_beat: u64, // meter
24- beats_per_bar: u64 // meter
25 + pub nanos_per_beat: u64, // tempo
26 + pub ticks_per_beat: u64, // meter
27 + pub beats_per_bar: u64 // meter
2528 }
2629
2730 impl ClockSignature {
2831 pub fn new (beats_per_minute: f64) -> Self {
@@ -63,12 +66,12 @@
6366 }
6467
6568 #[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
6669 pub struct ClockTime {
67- nanos: Nanos,
68- ticks: Ticks,
69- beats: Beats,
70- bars: Bars
70 + pub nanos: Nanos,
71 + pub ticks: Ticks,
72 + pub beats: Beats,
73 + pub bars: Bars
7174 }
7275
7376 impl ClockTime {
7477 pub fn new (nanos: Nanos, signature: ClockSignature) -> Self {
@@ -80,26 +83,29 @@
8083 }
8184 }
8285 }
8386
84-#[derive(Clone, Copy, Debug, Hash)]
87 +#[derive(Debug)]
8588 pub struct Clock {
89 + control_tx: Sender<control::ControlMessage>,
8690 start_instant: Instant,
8791 tick_instant: Instant,
8892 signature: ClockSignature
8993 }
9094
91-pub struct ClockMessage {
95 +pub enum ClockMessage {
96 + Time(ClockTime)
9297 }
9398
9499 impl Clock {
95- pub fn new (signature: ClockSignature) -> Self {
100 + pub fn new (signature: ClockSignature, control: &control::Control) -> Self {
96101 let start_instant = Instant::now();
97102
98103 Self {
99104 start_instant,
100105 tick_instant: start_instant,
101- signature
106 + signature,
107 + control_tx: control.tx.clone()
102108 }
103109 }
104110
105111 pub fn time (&self) -> ClockTime {
@@ -117,8 +123,20 @@
117123 pub fn nanos_since_tick (&self) -> Nanos {
118124 duration_to_nanos(self.tick_instant.elapsed())
119125 }
120126
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 +
121139 // https://github.com/BookOwl/fps_clock/blob/master/src/lib.rs
122140 pub fn tick (&mut self) -> ClockTime {
123141 let diff = self.diff();
124142
src/control.rsView
@@ -1,40 +1,32 @@
1-use std::thread;
21 use std::sync::mpsc::{channel, Sender, Receiver};
32
4-pub type Time = f32;
3 +use clock;
54
6-pub enum ChangeMode {
7- Start,
8- Continue,
9- Stop
5 +#[derive(Debug)]
6 +pub struct Control {
7 + pub tx: Sender<ControlMessage>,
8 + pub rx: Receiver<ControlMessage>
109 }
1110
12-pub
11 +impl Control {
12 + pub fn new() -> Self {
13 + let (tx, rx) = channel();
14 +
15 + Self {
16 + tx,
17 + rx
18 + }
19 + }
20 +}
1321
14-
15-pub enum Control {
16- Time(Time),
17- ChangeMode(ChangeMode),
22 +#[derive(Clone, Copy, Debug, Hash)]
23 +pub enum ControlMessage {
24 + Time(clock::ClockTime),
25 + Start,
26 + Stop,
1827 TapTempo,
19- SetTempo(),
20- Nudge(
21- Configure(ChangeMode)
28 + SetTempo,
29 + NudgeClock,
30 + Configure
2231 }
2332
24-pub fn create_control_channel() -> (Sender<Control>, Receiver<Control>) {
25- return channel();
26-}
27-
28-pub fn connect_clock(fps: u32, control_tx: Sender<Control>) {
29- thread::spawn(move|| {
30- let mut fps_clock = fps_clock::FpsClock::new(fps);
31- let mut nanosecs_since_start = 0.0;
32- let mut nanosecs_since_last_tick;
33- loop {
34- nanosecs_since_last_tick = fps_clock.tick();
35- nanosecs_since_start += nanosecs_since_last_tick;
36- let clock_time = Control::Time(nanosecs_since_start);
37- control_tx.send(clock_time).unwrap();
38- }
39- });
40-}
src/main.rsView
@@ -1,127 +1,125 @@
1-/*
2-use std::io;
3-use std::io::prelude::*;
4-
5-use std::sync::mpsc;
6-use std::thread::sleep;
7-use std::time::{Duration};
8-
9-fn main () {
10- let metronome = Metronone::new();
11- metronome().unwrap();
12-}
13-
14-pub struct Metronone {}
15-
16-impl Metronome () {
17- pub fn new () -> <()> {
18- let stdin = io::stdin();
19- let mut buffer = vec![0_u8; 2_usize.pow(8)];
20-
21- loop {
22- let mut handle = stdin.lock();
23- match handle.read(&mut buffer) {
24- Ok(num_bytes) => {
25- println!("{} bytes read", num_bytes);
26- let string = String::from_utf8(buffer.clone()).unwrap();
27- },
28- Err(error) => println!("error: {}", error),
29- }
30-
31- sleep(Duration::new(0, 30 * 1000 * 1000));
32- }
33- }
34-*/
35-
36-/*
37- Copyright © 2013 Free Software Foundation, Inc
38- See licensing in LICENSE file
39- File: examples/ex_7.rs
40- Author: Jesse 'Jeaye' Wilkerson
41- Description:
42- Basic input and attribute example, using the Unicode-aware get_wch functions.
43-*/
44-
451 extern crate ncurses;
46-// extern crate ctrlc;
472
3 +use ncurses::{WchResult};
484 use std::char;
49-use ncurses::{WchResult};
50-use std::thread::{sleep,spawn};
5 +use std::sync::mpsc::{channel, Sender, Receiver};
6 +use std::thread::{sleep, spawn};
517 use std::time::{Duration};
528
539 mod clock;
10 +mod control;
5411
5512 // https://unicode.org/charts/PDF/U0000.pdf
5613 static CHAR_SPACE: u32 = 0x0020;
5714 static CHAR_RETURN: u32 = 0x000D;
5815 static CHAR_NEWLINE: u32 = 0x000A;
5916
6017 fn main () {
61- clock();
62- // terminal_interface();
18 + let control = control::Control::new();
19 +
20 + let clock_signature = clock::ClockSignature::new(60_f64);
21 + let mut clock = clock::Clock::new(clock_signature, &control);
22 +
23 + clock.start();
24 +
25 + let terminal_interface = TerminalInterface::new(&control);
6326
64- loop {
65- sleep(Duration::new(10, 0));
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 + }
6635 }
6736 }
6837
69-fn clock () {
70- spawn(move|| {
71- let signature = clock::ClockSignature::new(60_f64);
72- let mut clock = clock::Clock::new(signature);
73- loop {
74- clock.tick();
75- println!("{:?}", clock.time());
76- }
77- });
38 +#[derive(Debug)]
39 +pub struct TerminalInterface {
40 + control_tx: Sender<control::ControlMessage>,
41 + tx: Sender<InterfaceMessage>,
42 + rx: Receiver<InterfaceMessage>
7843 }
7944
80-fn terminal_interface () {
81- spawn(move|| {
82- let locale_conf = ncurses::LcCategory::all;
83- ncurses::setlocale(locale_conf, "en_US.UTF-8");
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 + }
8455
85- /* Setup ncurses. */
86- ncurses::initscr();
56 + pub fn start (&self) {
57 + let control_tx = self.control_tx.clone();
8758
88- /* Enable mouse events. */
89- ncurses::mousemask(ncurses::ALL_MOUSE_EVENTS as ncurses::mmask_t, None);
59 + spawn(move|| {
60 + /* Setup ncurses. */
61 + ncurses::initscr();
9062
91- /* Allow for extended keyboard (like F1). */
92- ncurses::keypad(ncurses::stdscr(), true);
93- ncurses::noecho();
63 + let locale_conf = ncurses::LcCategory::all;
64 + ncurses::setlocale(locale_conf, "en_US.UTF-8");
9465
95- loop {
96- let ch = ncurses::wget_wch(ncurses::stdscr());
66 + /* Enable mouse events. */
67 + ncurses::mousemask(ncurses::ALL_MOUSE_EVENTS as ncurses::mmask_t, None);
9768
98- match ch {
99- Some(WchResult::KeyCode(ncurses::KEY_MOUSE)) => {
100- tap();
101- }
69 + /* Allow for extended keyboard (like F1). */
70 + ncurses::keypad(ncurses::stdscr(), true);
71 + ncurses::noecho();
10272
103- // https://github.com/jeaye/ncurses-rs/blob/master/src/constants.rs
104- Some(WchResult::KeyCode(_)) => {}
73 + loop {
74 + let ch = ncurses::wget_wch(ncurses::stdscr());
10575
106- // Some(WchResult::KeyCode(KEY_ENTER)) => beat(),
107- Some(WchResult::Char(ch)) => {
108- if (ch == CHAR_SPACE || ch == CHAR_NEWLINE) {
109- tap();
76 + match ch {
77 + Some(WchResult::KeyCode(ncurses::KEY_MOUSE)) => {
78 + control_tx.send(control::ControlMessage::TapTempo).unwrap();
11079 }
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 => {}
11192 }
11293
113- None => {}
94 + ncurses::refresh();
11495 }
11596
116- ncurses::refresh();
117- }
97 + ncurses::endwin();
98 + });
11899
119- ncurses::endwin();
120- });
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 + });
110 + }
121111 }
122112
123-fn tap () {
124- ncurses::attron(ncurses::A_BOLD());
125- ncurses::printw("\nBeat");
126- ncurses::attroff(ncurses::A_BOLD());
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());
127120 }
121 +
122 +#[derive(Clone, Copy, Debug, Hash)]
123 +pub enum InterfaceMessage {
124 + Time(clock::ClockTime)
125 +}

Built with git-ssb-web