-
Notifications
You must be signed in to change notification settings - Fork 26
/
Copy pathsound.rs
75 lines (72 loc) · 1.81 KB
/
sound.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
use pwm_speaker::{songs, Speaker};
struct IterNb<I> {
iter: I,
cur: I,
nb: usize,
}
impl<I: Clone> IterNb<I> {
fn new(nb: usize, iter: I) -> Self {
Self {
cur: iter.clone(),
iter,
nb,
}
}
}
impl<I: Iterator + Clone> Iterator for IterNb<I> {
type Item = I::Item;
fn next(&mut self) -> Option<Self::Item> {
loop {
match (self.cur.next(), self.nb) {
(Some(i), _) => return Some(i),
(None, 0) => return None,
(None, _) => {
self.nb -= 1;
self.cur = self.iter.clone();
}
}
}
}
}
pub struct Sound {
speaker: Speaker,
playing: bool,
song: IterNb<songs::MsEvents>,
}
impl Sound {
pub fn new(speaker: Speaker) -> Self {
Self {
speaker,
playing: false,
song: IterNb::new(0, songs::MARIO_THEME_INTRO.ms_events()),
}
}
pub fn play(&mut self, song: &'static songs::Score, nb_sec: u32) {
let song_ms = song.ms_duration();
let nb = if song_ms == 0 {
0
} else {
nb_sec * 1000 / song_ms
};
self.song = IterNb::new(nb as usize, song.ms_events());
self.playing = true;
self.speaker.unmute();
}
pub fn stop(&mut self) {
self.playing = false;
self.speaker.rest();
self.speaker.mute();
}
pub fn poll(&mut self) {
if !self.playing {
return;
}
use pwm_speaker::songs::MsEvent::*;
match self.song.next() {
Some(BeginNote { pitch }) => self.speaker.play(pitch),
Some(EndNote) => self.speaker.rest(),
Some(Wait) => (),
None => self.stop(),
}
}
}