use once_cell::sync::OnceCell; use std::path::PathBuf; use std::sync::Mutex; // use kira::{ // manager::{backend::DefaultBackend, AudioManager, AudioManagerSettings}, // sound::static_sound::{StaticSoundData, StaticSoundSettings}, // }; use kira::{ AudioManager, AudioManagerSettings, DefaultBackend, sound::static_sound::StaticSoundData, }; static MANAGER: OnceCell> = OnceCell::new(); pub fn init() -> Result<(), ()> { if MANAGER.get().is_some() { return Ok(()); } // already initialized // Create an audio manager. This plays sounds and manages resources. match AudioManager::::new(AudioManagerSettings::default()) { Ok(manager) => { // store MANAGER.set(Mutex::new(manager)).ok(); // success Ok(()) } Err(msg) => { error!("Failed to initialize audio stream.\nError details: {}", msg); // failed Err(()) } } } // @TODO. Cache sounds in memory? With a pool of a certain size, for instance. pub fn play_sound(filename: &PathBuf) { // load the file match StaticSoundData::from_file(filename) { Ok(sound_data) => { // sound_data.duration() can be used in order to sleep, if (for some reason) blocking behaviour is required // play it (non-blocking) if let Some(manager) = MANAGER.get() { if let Ok(mut audio_manager) = manager.lock() { if let Err(e) = audio_manager.play(sound_data) { warn!("Failed to play sound: {}", e); } } } else { warn!("Audio manager not initialized"); } } Err(err) => { warn!("Cannot find sound file: {} (err: {})", filename.display(), err); } } }