use common::Name; use embassy_rp::clocks::RoscRng; use embassy_rp::uart; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::channel::Channel; use embassy_time::Timer; use embedded_io_async::Read; use embedded_io_async::Write; use rand::RngCore; use serde::Deserialize; use serde::Serialize; use crate::server::NAMES; use crate::wiggle::WAGS; use crate::Irqs; use embassy_rp::uart::BufferedUart; use embassy_rp::peripherals::PIN_21; use embassy_rp::peripherals::PIN_20; use embassy_rp::peripherals::UART1; use log::*; pub static COMMANDS: Channel = Channel::new(); pub trait Tracks { fn tracks(&self) -> u8; fn prefix(&self) -> &'static str; } impl Tracks for Name { fn tracks(&self) -> u8 { match self { Name::Andy => 7, Name::Evan => 7, Name::Felix => 12, Name::Phil => 6, Name::Tess => 4, Name::Amaia => 5, Name::Prueky => 1, Name::David => 2, Name::Nathaniel => 1, Name::Thia => 7, Name::Michael => 0, Name::Zoey => 1, Name::Unknown => 0, } } fn prefix(&self) -> &'static str { match self { Name::Andy => "andy", Name::Evan => "evan", Name::Felix => "felix", Name::Phil => "phil", Name::Tess => "tess", Name::Amaia => "amaia", Name::Prueky => "prueky", Name::David => "david", Name::Nathaniel => "nathaniel1", Name::Thia => "thia", Name::Michael => "michael", Name::Zoey => "zoey", Name::Unknown => "", } } } static ACCEPTED_SUFFIXABLE: [bool; 6] = [false, false, false, false, false, true]; static DENIED_SUFFIXABLE: [bool; 6] = [false, false, false, false, false, true]; pub enum MusicCommand { /// play a random clip for name, accepted if true Introduce(Name, bool), /// 0-30 SetVolume(u8), Play(&'static str), Button(), } #[embassy_executor::task] pub async fn music_manager(uart: UART1, irqs: Irqs, txp: PIN_20, rxp: PIN_21) -> ! { let mut config = uart::Config::default(); config.baudrate = 115200; let mut rx = [0; 2048]; let mut tx = [0; 2048]; let mut uart = BufferedUart::new(uart, irqs, txp, rxp, &mut tx, &mut rx, config); let mut rng = RoscRng; loop { let command = COMMANDS.receive().await; match command { MusicCommand::Introduce(name, accepted) => { let call: bool; if accepted { let index = rng.next_u32() % ACCEPTED_SUFFIXABLE.len() as u32; play_song("a", Some((index+1) as u8), &mut uart).await; call = ACCEPTED_SUFFIXABLE[index as usize]; } else { let index = rng.next_u32() % DENIED_SUFFIXABLE.len() as u32; play_song("d", Some((index+1) as u8), &mut uart).await; call = DENIED_SUFFIXABLE[index as usize]; } if call { match name.tracks() { 0 => {}, 1 => { play_song(&name.prefix(), None, &mut uart).await; }, tracks => { let index = rng.next_u32() % tracks as u32; play_song(&name.prefix(), Some((index+1) as u8), &mut uart).await; } } } }, MusicCommand::Button() => { let index = rng.next_u32() % 12 as u32; play_song("b", Some((index+1) as u8), &mut uart).await; }, MusicCommand::Play(song) => { play_song(song, None, &mut uart).await }, MusicCommand::SetVolume(vol) => { uart.write_all(b"AT+VOL=").await.unwrap(); uart.write_all(itoa::Buffer::new().format(vol).as_bytes()).await.unwrap(); uart.write_all(b"\r\n").await.unwrap(); let mut buffer = [0;512]; info!("set volume to {vol}, returned: {}",read_line(&mut buffer, &mut uart).await.trim()); }, } } } async fn play_song<'a>(prefix: &str, index: Option, uart: &mut BufferedUart<'a, UART1>) { info!("playing: {}{}.mp3",prefix,index.unwrap_or(0)); uart.write_all(b"AT+PLAYFILE=/").await.unwrap(); uart.write_all(prefix.as_bytes()).await.unwrap(); if let Some(index) = index { uart.write_all(itoa::Buffer::new().format(index).as_bytes()).await.unwrap(); } uart.write_all(b".mp3\r\n").await.unwrap(); let mut buffer = [0;512]; info!("returned: {}",read_line(&mut buffer, uart).await.trim()); uart.write_all(b"AT+QUERY=4\r\n").await.unwrap(); let mut buffer = [0;512]; let output = read_line(&mut buffer, uart).await; if let Ok(length) = output.trim().parse::() { WAGS.store((length as u8) * 2 + 1, core::sync::atomic::Ordering::SeqCst); Timer::after_secs(length).await; } } async fn read_line<'a, 'b>(buffer: &'b mut [u8], uart: &mut BufferedUart<'a, UART1>) -> &'b str { let mut pos = 0; loop { if let Ok(len) = uart.read(&mut buffer[pos..]).await { let to_print = unsafe { core::str::from_utf8_unchecked(&buffer[..(pos + len)]) }; if to_print.contains("\r\n") { //info!("{}", to_print); pos += len; break; } pos += len; } else { break; } } return unsafe { core::str::from_utf8_unchecked(&buffer[..(pos)]) }; }