project restructure with Rust workspaces
This commit is contained in:
parent
3ffbe876f3
commit
09f72622bc
428 changed files with 19372 additions and 6061 deletions
62
crates/jarvis-core/src/audio/kira.rs
Normal file
62
crates/jarvis-core/src/audio/kira.rs
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
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<Mutex<AudioManager>> = 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::<DefaultBackend>::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);
|
||||
}
|
||||
}
|
||||
}
|
||||
65
crates/jarvis-core/src/audio/rodio.rs
Normal file
65
crates/jarvis-core/src/audio/rodio.rs
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
Abandoned temporary.
|
||||
Problems with blocking behaviour.
|
||||
Possible fixes are running rodio in a separate thread or smthng.
|
||||
*/
|
||||
|
||||
use once_cell::sync::OnceCell;
|
||||
use std::fs::File;
|
||||
use std::io::BufReader;
|
||||
use std::path::PathBuf;
|
||||
|
||||
// use rodio::{Decoder, OutputStream, OutputStreamHandle, Sink};
|
||||
use rodio::{Decoder, OutputStream, Sink};
|
||||
|
||||
// static STREAM: OnceCell<OutputStream> = OnceCell::new();
|
||||
static STREAM_HANDLE: OnceCell<OutputStream> = OnceCell::new();
|
||||
static SINK: OnceCell<Sink> = OnceCell::new();
|
||||
|
||||
pub fn init() -> Result<(), ()> {
|
||||
if !STREAM_HANDLE.get().is_none() {
|
||||
return Ok(());
|
||||
} // already initialized
|
||||
|
||||
// get output stream handle to the default physical sound device
|
||||
match rodio::OutputStreamBuilder::open_default_stream() {
|
||||
Ok(stream_handle) => {
|
||||
// create sink
|
||||
let sink = Sink::connect_new(&stream_handle.mixer());
|
||||
info!("Sink initialized.");
|
||||
|
||||
// store
|
||||
// STREAM.set(_stream).unwrap();
|
||||
STREAM_HANDLE.set(stream_handle);
|
||||
SINK.set(sink);
|
||||
|
||||
// success
|
||||
Ok(())
|
||||
}
|
||||
Err(msg) => {
|
||||
error!("Failed to initialize audio stream.\nError details: {}", msg);
|
||||
|
||||
// failed
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn play_sound(filename: &PathBuf, sleep: bool) {
|
||||
// Load a sound from a file, using a path relative to Cargo.toml
|
||||
// let filepath = format!("{PUBLIC_PATH}/sound/{filename}.wav");
|
||||
let file = BufReader::new(File::open(&filename).unwrap());
|
||||
|
||||
// Decode that sound file into a source
|
||||
let source = Decoder::new(file).unwrap();
|
||||
|
||||
// Play the sound directly on the device
|
||||
// STREAM_HANDLE.get().unwrap().play_raw(source.convert_samples());
|
||||
SINK.get().unwrap().append(source);
|
||||
|
||||
if sleep {
|
||||
// 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.get().unwrap().sleep_until_end();
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue