use std::time::Duration; use pitch_calc::{Letter, LetterOctave}; use rand::{prelude::*, Rng}; use rodio::{source::SineWave, OutputStream, Sink, Source}; fn main() { let (_stream, stream_handle) = OutputStream::try_default().unwrap(); let sink = Sink::try_new(&stream_handle).unwrap(); let bpm = 131.2; let seconds_per_beat = (1.0 / bpm) * 60.0; let mut rng = rand::thread_rng(); loop { // This is bad. let note = [2, 3] .iter() .flat_map(|&octave| { use Letter::*; [C, D, E, F, G, A, B] .iter() .map(move |&letter| LetterOctave(letter, octave)) }) .choose(&mut rng) .expect("how is there not a note"); let freq = note.hz(); let wave = SineWave::new(freq as u32); let length = (rng.gen_range(1..4) as f32) / 4.0 * seconds_per_beat; let source = wave .take_duration(Duration::from_secs_f32(length)) .amplify(0.10); sink.append(source); // The sound plays in a separate thread. This call will block the current thread until the sink // has finished playing all its queued sounds. sink.sleep_until_end(); } }