130 lines
3.4 KiB
Rust
130 lines
3.4 KiB
Rust
use super::sys::{tone, TONE_PULSE1, TONE_PULSE2};
|
|
|
|
pub struct Note {
|
|
pub freq: u32,
|
|
pub dur: u32,
|
|
pub volume: u32,
|
|
pub flags: u32,
|
|
}
|
|
|
|
impl Note {
|
|
pub fn play(&self) {
|
|
tone(self.freq, self.dur, self.volume, self.flags);
|
|
}
|
|
}
|
|
|
|
impl From<(u32, u32, u32, u32)> for Note {
|
|
fn from((freq, dur, volume, flags): (u32, u32, u32, u32)) -> Self {
|
|
Note {freq, dur, volume, flags}
|
|
}
|
|
}
|
|
|
|
pub enum Quantum {
|
|
Rest(u8),
|
|
Notes([(u32, u32, u32, u32); 2]),
|
|
}
|
|
pub use Quantum::*;
|
|
|
|
pub const CHOPSTICKS: [Quantum; 48] = [
|
|
// G7
|
|
Notes([(196, 14, 25, TONE_PULSE1), (175, 14, 25, TONE_PULSE2)]),
|
|
Rest(15),
|
|
Notes([(196, 14, 25, TONE_PULSE1), (175, 14, 25, TONE_PULSE2)]),
|
|
Rest(15),
|
|
Notes([(196, 14, 25, TONE_PULSE1), (175, 14, 25, TONE_PULSE2)]),
|
|
Rest(15),
|
|
// G7
|
|
Notes([(196, 15, 25, TONE_PULSE1), (175, 15, 25, TONE_PULSE2)]),
|
|
Rest(15),
|
|
Notes([(196, 15, 25, TONE_PULSE1), (175, 15, 25, TONE_PULSE2)]),
|
|
Rest(15),
|
|
Notes([(196, 15, 25, TONE_PULSE1), (175, 15, 25, TONE_PULSE2)]),
|
|
Rest(15),
|
|
// C
|
|
Notes([(196, 15, 25, TONE_PULSE1), (164, 15, 25, TONE_PULSE2)]),
|
|
Rest(15),
|
|
Notes([(196, 15, 25, TONE_PULSE1), (175, 15, 25, TONE_PULSE2)]),
|
|
Rest(15),
|
|
Notes([(196, 15, 25, TONE_PULSE1), (175, 15, 25, TONE_PULSE2)]),
|
|
Rest(15),
|
|
// C
|
|
Notes([(196, 15, 25, TONE_PULSE1), (164, 15, 25, TONE_PULSE2)]),
|
|
Rest(15),
|
|
Notes([(246, 15, 25, TONE_PULSE1), (164, 15, 25, TONE_PULSE2)]),
|
|
Rest(15),
|
|
Notes([(246, 15, 25, TONE_PULSE1), (164, 15, 25, TONE_PULSE2)]),
|
|
Rest(15),
|
|
// G7
|
|
Notes([(246, 15, 25, TONE_PULSE1), (164, 15, 25, TONE_PULSE2)]),
|
|
Rest(15),
|
|
Notes([(246, 15, 25, TONE_PULSE1), (164, 15, 25, TONE_PULSE2)]),
|
|
Rest(15),
|
|
Notes([(246, 15, 25, TONE_PULSE1), (164, 15, 25, TONE_PULSE2)]),
|
|
Rest(15),
|
|
// G7
|
|
Notes([(246, 15, 25, TONE_PULSE1), (164, 15, 25, TONE_PULSE2)]),
|
|
Rest(15),
|
|
Notes([(261, 15, 25, TONE_PULSE1), (130, 15, 25, TONE_PULSE2)]),
|
|
Rest(15),
|
|
Notes([(261, 15, 25, TONE_PULSE1), (130, 15, 25, TONE_PULSE2)]),
|
|
Rest(15),
|
|
// C
|
|
Notes([(261, 15, 25, TONE_PULSE1), (130, 15, 25, TONE_PULSE2)]),
|
|
Rest(15),
|
|
Notes([(261, 15, 25, TONE_PULSE1), (130, 15, 25, TONE_PULSE2)]),
|
|
Rest(15),
|
|
Notes([(261, 15, 25, TONE_PULSE1), (130, 15, 25, TONE_PULSE2)]),
|
|
Rest(15),
|
|
// C
|
|
Notes([(261, 15, 25, TONE_PULSE1), (130, 15, 25, TONE_PULSE2)]),
|
|
Rest(15),
|
|
Notes([(246, 15, 25, TONE_PULSE1), (146, 15, 25, TONE_PULSE2)]),
|
|
Rest(15),
|
|
Notes([(220, 15, 25, TONE_PULSE1), (164, 15, 25, TONE_PULSE2)]),
|
|
Rest(15),
|
|
];
|
|
|
|
pub struct Song<const N: usize> {
|
|
position: usize,
|
|
sleep_timer: u8,
|
|
song: [Quantum; N],
|
|
paused: bool,
|
|
}
|
|
|
|
impl<const N: usize> Song<N> {
|
|
pub const fn new(song: [Quantum;N]) -> Self {
|
|
Self{
|
|
position: 0,
|
|
sleep_timer: 0,
|
|
song,
|
|
paused: false,
|
|
}
|
|
}
|
|
|
|
pub fn pause(&mut self) {
|
|
self.paused = !self.paused;
|
|
}
|
|
|
|
pub fn update(&mut self) {
|
|
if self.paused {
|
|
return;
|
|
}
|
|
|
|
if self.sleep_timer != 0 {
|
|
self.sleep_timer -= 1;
|
|
return;
|
|
}
|
|
|
|
match self.song[self.position % self.song.len()] {
|
|
Rest(n) => self.sleep_timer = n,
|
|
Notes(notes) => {
|
|
for note in notes {
|
|
Note::from(note).play();
|
|
}
|
|
},
|
|
}
|
|
|
|
self.position += 1;
|
|
}
|
|
}
|