79 lines
2.2 KiB
Rust
79 lines
2.2 KiB
Rust
use rodio::{source::SineWave, OutputStream, Source};
|
|
use std::sync::atomic::{AtomicU8, Ordering};
|
|
use std::thread;
|
|
use std::time::{Duration, Instant};
|
|
|
|
static SOUND_TIMER: AtomicU8 = AtomicU8::new(0);
|
|
static DELAY_TIMER: AtomicU8 = AtomicU8::new(0);
|
|
|
|
pub enum Type {
|
|
Delay,
|
|
Sound,
|
|
}
|
|
|
|
pub struct Timer;
|
|
|
|
impl Timer {
|
|
pub fn start_thread() {
|
|
thread::spawn(|| {
|
|
let duration = Duration::from_nanos(1e+9 as u64 / 60);
|
|
let mut start = Instant::now();
|
|
let mut has_beeped = false;
|
|
loop {
|
|
if Instant::now().duration_since(start) > duration {
|
|
Timer::tick(&mut has_beeped);
|
|
start = Instant::now();
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
fn tick(has_beeped: &mut bool) {
|
|
// Sound Timer
|
|
let remaining = SOUND_TIMER.load(Ordering::Relaxed);
|
|
match (remaining, *has_beeped) {
|
|
(0, false) => {
|
|
Self::beep();
|
|
*has_beeped = true;
|
|
}
|
|
(0, true) => {}
|
|
_ => {
|
|
if *has_beeped {
|
|
*has_beeped = false;
|
|
}
|
|
|
|
SOUND_TIMER.store(remaining - 1, Ordering::Release)
|
|
}
|
|
}
|
|
|
|
// Delay Timer
|
|
let remaining = DELAY_TIMER.load(Ordering::Relaxed);
|
|
if remaining != 0 {
|
|
DELAY_TIMER.store(remaining - 1, Ordering::Release);
|
|
}
|
|
}
|
|
|
|
pub fn get(timer: Type) -> u8 {
|
|
match timer {
|
|
Type::Delay => DELAY_TIMER.load(Ordering::Acquire),
|
|
Type::Sound => SOUND_TIMER.load(Ordering::Acquire),
|
|
}
|
|
}
|
|
|
|
pub fn set(secs: u8, timer: Type) {
|
|
match timer {
|
|
Type::Delay => DELAY_TIMER.store(secs, Ordering::Relaxed),
|
|
Type::Sound => SOUND_TIMER.store(secs, Ordering::Relaxed),
|
|
}
|
|
}
|
|
|
|
fn beep() {
|
|
const BEEP_FREQ: f32 = 440.0; // Hz (Middle A)
|
|
const BEEP_LENGTH: u64 = 150; // ms
|
|
let beep = SineWave::new(BEEP_FREQ).take_duration(Duration::from_millis(BEEP_LENGTH));
|
|
|
|
let (_stream, stream_handle) = OutputStream::try_default().expect("find output stream");
|
|
stream_handle.play_raw(beep).expect("play sine wave");
|
|
}
|
|
}
|