diff --git a/Cargo.toml b/Cargo.toml index 42cca5f..0dc4444 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,7 @@ settings_loader = ["dep:ron", "dep:serde", "kira/serde"] bevy = { version = "0.15.0", default-features = false, features = ["bevy_asset"] } anyhow = "1.0" uuid = { version = "1", features = ["fast-rng"] } -kira = { version = "0.8.7", default-features = false, features = ["cpal"] } +kira = { version = "0.9", default-features = false, features = ["cpal"] } ron = { version = "0.8", optional = true } serde = { version = "1.0", features = ["derive"], optional = true } parking_lot = "0.12" diff --git a/src/audio.rs b/src/audio.rs index e65f632..2ff5e6f 100644 --- a/src/audio.rs +++ b/src/audio.rs @@ -11,7 +11,7 @@ use bevy::asset::{AssetId, Handle}; use bevy::ecs::system::Resource; use bevy::prelude::{default, IntoSystemConfigs, PostUpdate}; use kira::sound::static_sound::{StaticSoundData, StaticSoundHandle}; -use kira::sound::EndPosition; +use kira::sound::{EndPosition, PlaybackPosition}; use kira::tween::Value; use kira::Volume; use std::marker::PhantomData; @@ -133,11 +133,24 @@ impl PartialSoundSettings { sound.settings.playback_rate = playback_rate.into(); } if let Some(start) = self.start_position { - sound.settings.playback_region.start = start.into(); + sound.settings.start_position = PlaybackPosition::Seconds(start); } + if let Some(end) = self.end_position { - sound.settings.playback_region.end = EndPosition::Custom(end.into()); + let end_frame = (end * sound.sample_rate as f64).round() as usize; + + if let Some(start) = self.start_position { + let start_frame = (start * sound.sample_rate as f64).round() as usize; + + sound.slice = Some((start_frame, end_frame)); + } else { + sound.slice = Some((0, end_frame)); + } + } else if let Some(start) = self.start_position { + let start_frame = (start * sound.sample_rate as f64).round() as usize; + sound.slice = Some((start_frame, sound.frames.len())); } + if let Some(panning) = self.panning { sound.settings.panning = Value::Fixed(panning); } diff --git a/src/audio_output.rs b/src/audio_output.rs index 353861d..88281d7 100644 --- a/src/audio_output.rs +++ b/src/audio_output.rs @@ -14,10 +14,10 @@ use bevy::asset::{Assets, Handle}; use bevy::ecs::change_detection::{NonSendMut, ResMut}; use bevy::ecs::system::{NonSend, Res, Resource}; use bevy::ecs::world::{FromWorld, World}; -use bevy::log::{error, warn}; +use bevy::log::warn; use kira::manager::backend::{Backend, DefaultBackend}; use kira::manager::AudioManager; -use kira::{sound::PlaybackRate, CommandError, Volume}; +use kira::{sound::PlaybackRate, Volume}; use std::collections::HashMap; /// Non-send resource that acts as audio output @@ -57,15 +57,7 @@ impl AudioOutput { let tween = map_tween(tween); for instance in instances { if let Some(instance) = audio_instances.get_mut(instance.id()) { - match instance.handle.stop(tween) { - Err(CommandError::CommandQueueFull) => { - return AudioCommandResult::Retry; - } - Err(error) => { - error!("Failed to stop instance: {:?}", error); - } - _ => (), - } + instance.handle.stop(tween); } } } @@ -84,9 +76,7 @@ impl AudioOutput { for instance in instance_handles.iter_mut() { if let Some(instance) = audio_instances.get_mut(instance.id()) { if kira::sound::PlaybackState::Playing == instance.handle.state() { - if let Err(error) = instance.handle.pause(tween) { - error!("Failed to pause instance: {:?}", error); - } + instance.handle.pause(tween); } } } @@ -116,9 +106,7 @@ impl AudioOutput { || instance.handle.state() == kira::sound::PlaybackState::Pausing || instance.handle.state() == kira::sound::PlaybackState::Stopping { - if let Err(error) = instance.handle.resume(tween) { - error!("Failed to resume instance: {:?}", error); - } + instance.handle.resume(tween); } } } @@ -142,9 +130,7 @@ impl AudioOutput { let tween = map_tween(tween); for instance in instances.iter_mut() { if let Some(instance) = audio_instances.get_mut(instance.id()) { - if let Err(error) = instance.handle.set_volume(volume, tween) { - error!("Failed to set volume for instance: {:?}", error); - } + instance.handle.set_volume(volume, tween); } } } @@ -170,9 +156,7 @@ impl AudioOutput { let tween = map_tween(tween); for instance in instances.iter_mut() { if let Some(instance) = audio_instances.get_mut(instance.id()) { - if let Err(error) = instance.handle.set_panning(panning, tween) { - error!("Failed to set panning for instance: {:?}", error); - } + instance.handle.set_panning(panning, tween); } } } @@ -198,9 +182,7 @@ impl AudioOutput { let tween = map_tween(tween); for instance in instances.iter_mut() { if let Some(instance) = audio_instances.get_mut(instance.id()) { - if let Err(error) = instance.handle.set_playback_rate(playback_rate, tween) { - error!("Failed to set playback rate for instance: {:?}", error); - } + instance.handle.set_playback_rate(playback_rate, tween); } } } @@ -244,32 +226,17 @@ impl AudioOutput { let mut sound_handle = sound_handle.unwrap(); if let Some(channel_state) = self.channels.get(channel) { if channel_state.paused { - if let Err(error) = sound_handle.pause(kira::tween::Tween::default()) { - warn!( - "Failed to pause instance (channel was paused) due to {:?}", - error - ); - } + sound_handle.pause(kira::tween::Tween::default()); let playback_rate = partial_sound_settings .playback_rate .unwrap_or(channel_state.playback_rate); - if let Err(error) = - sound_handle.set_playback_rate(playback_rate, kira::tween::Tween::default()) - { - error!("Failed to set playback rate for instance: {:?}", error); - } + sound_handle.set_playback_rate(playback_rate, kira::tween::Tween::default()); } } if partial_sound_settings.paused { - if let Err(error) = sound_handle.pause(kira::tween::Tween::default()) { - warn!("Failed to pause instance due to {:?}", error); - } + sound_handle.pause(kira::tween::Tween::default()); let playback_rate = partial_sound_settings.playback_rate.unwrap_or(1.0); - if let Err(error) = - sound_handle.set_playback_rate(playback_rate, kira::tween::Tween::default()) - { - error!("Failed to set playback rate for instance: {:?}", error); - } + sound_handle.set_playback_rate(playback_rate, kira::tween::Tween::default()); } audio_instances.insert( &instance_handle, diff --git a/src/backend_settings.rs b/src/backend_settings.rs index aec4bc9..431c1b2 100644 --- a/src/backend_settings.rs +++ b/src/backend_settings.rs @@ -17,7 +17,7 @@ pub struct AudioSettings { /// Note that configuring a channel will cause one command per sound in the channel! pub command_capacity: usize, /// The maximum number of sounds that can be playing at a time. - pub sound_capacity: usize, + pub sound_capacity: u16, } impl Default for AudioSettings { diff --git a/src/instance.rs b/src/instance.rs index 05b7dbc..deeee90 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -2,8 +2,7 @@ use crate::{AudioTween, PlaybackState}; use bevy::asset::{Asset, Assets, Handle}; use kira::sound::static_sound::StaticSoundHandle; use kira::tween::Value; -use kira::{CommandError, Volume}; -use thiserror::Error; +use kira::Volume; #[derive(Asset, bevy::reflect::TypePath)] /// Asset for direct audio control @@ -11,50 +10,20 @@ pub struct AudioInstance { pub(crate) handle: StaticSoundHandle, } -/// Errors that can occur when directly controlling audio -#[derive(Error, Debug)] -pub enum AudioCommandError { - /// The audio command que of the audio manager is full - #[error("the audio thread could not handle the command, because its command que is full")] - CommandQueueFull, - - /// Something went wrong when handling the command in the audio thread - #[error("an error occurred while handling the command in the audio thread")] - AudioThreadError, -} - -impl From for AudioCommandError { - fn from(kira_error: CommandError) -> Self { - match kira_error { - CommandError::CommandQueueFull => AudioCommandError::CommandQueueFull, - _ => AudioCommandError::AudioThreadError, - } - } -} - impl AudioInstance { /// Pause the audio instance with the given easing - pub fn pause(&mut self, tween: AudioTween) -> Option { - self.handle - .pause(tween.into()) - .err() - .map(|kira_error| kira_error.into()) + pub fn pause(&mut self, tween: AudioTween) { + self.handle.pause(tween.into()); } /// Resume the audio instance with the given easing - pub fn resume(&mut self, tween: AudioTween) -> Option { - self.handle - .resume(tween.into()) - .err() - .map(|kira_error| kira_error.into()) + pub fn resume(&mut self, tween: AudioTween) { + self.handle.resume(tween.into()); } /// Stop the audio instance with the given easing - pub fn stop(&mut self, tween: AudioTween) -> Option { - self.handle - .stop(tween.into()) - .err() - .map(|kira_error| kira_error.into()) + pub fn stop(&mut self, tween: AudioTween) { + self.handle.stop(tween.into()); } /// Get the state of the audio instance @@ -65,30 +34,16 @@ impl AudioInstance { /// Set the volume of the audio instance /// /// Default is `1.0` - pub fn set_volume( - &mut self, - volume: impl Into>, - tween: AudioTween, - ) -> Option { - self.handle - .set_volume(volume, tween.into()) - .err() - .map(|kira_error| kira_error.into()) + pub fn set_volume(&mut self, volume: impl Into>, tween: AudioTween) { + self.handle.set_volume(volume, tween.into()); } /// Sets the playback rate of the sound. /// /// Changing the playback rate will change both the speed /// and pitch of the sound. - pub fn set_playback_rate( - &mut self, - playback_rate: f64, - tween: AudioTween, - ) -> Option { - self.handle - .set_playback_rate(playback_rate, tween.into()) - .err() - .map(|kira_error| kira_error.into()) + pub fn set_playback_rate(&mut self, playback_rate: f64, tween: AudioTween) { + self.handle.set_playback_rate(playback_rate, tween.into()); } /// Sets the panning of the sound @@ -96,27 +51,18 @@ impl AudioInstance { /// `0.0` is hard left, /// `0.5` is center (default) /// `1.0` is hard right. - pub fn set_panning(&mut self, panning: f64, tween: AudioTween) -> Option { - self.handle - .set_panning(panning, tween.into()) - .err() - .map(|kira_error| kira_error.into()) + pub fn set_panning(&mut self, panning: f64, tween: AudioTween) { + self.handle.set_panning(panning, tween.into()); } /// Sets the playback position to the specified time in seconds. - pub fn seek_to(&mut self, position: f64) -> Option { - self.handle - .seek_to(position) - .err() - .map(|kira_error| kira_error.into()) + pub fn seek_to(&mut self, position: f64) { + self.handle.seek_to(position); } /// Moves the playback position by the specified amount of time in seconds. - pub fn seek_by(&mut self, amount: f64) -> Option { - self.handle - .seek_by(amount) - .err() - .map(|kira_error| kira_error.into()) + pub fn seek_by(&mut self, amount: f64) { + self.handle.seek_by(amount); } } diff --git a/src/lib.rs b/src/lib.rs index d834260..288569b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -69,7 +69,7 @@ pub mod prelude { #[doc(hidden)] pub use crate::channel::AudioControl; #[doc(hidden)] - pub use crate::instance::{AudioCommandError, AudioInstance, AudioInstanceAssetsExt}; + pub use crate::instance::{AudioInstance, AudioInstanceAssetsExt}; #[doc(hidden)] #[cfg(feature = "flac")] pub use crate::source::flac_loader::*; @@ -92,12 +92,11 @@ pub mod prelude { #[doc(hidden)] pub use crate::{Audio, AudioPlugin, MainTrack}; pub use kira::{ - dsp::Frame, sound::{ static_sound::{StaticSoundData, StaticSoundSettings}, FromFileError, Sound, SoundData, }, - Volume, + Frame, Volume, }; } diff --git a/src/source/flac_loader.rs b/src/source/flac_loader.rs index 7a81beb..6de65b4 100644 --- a/src/source/flac_loader.rs +++ b/src/source/flac_loader.rs @@ -1,7 +1,7 @@ use anyhow::Result; use bevy::asset::io::Reader; +use kira::sound::static_sound::StaticSoundData; use bevy::asset::{AssetLoader, LoadContext}; -use kira::sound::static_sound::{StaticSoundData, StaticSoundSettings}; use kira::sound::FromFileError; use std::io::Cursor; use thiserror::Error; @@ -37,8 +37,7 @@ impl AssetLoader for FlacLoader { ) -> Result { let mut sound_bytes = vec![]; reader.read_to_end(&mut sound_bytes).await?; - let sound = - StaticSoundData::from_cursor(Cursor::new(sound_bytes), StaticSoundSettings::default())?; + let sound = StaticSoundData::from_cursor(Cursor::new(sound_bytes))?; Ok(AudioSource { sound }) } diff --git a/src/source/mp3_loader.rs b/src/source/mp3_loader.rs index 2c91c2f..4632df9 100644 --- a/src/source/mp3_loader.rs +++ b/src/source/mp3_loader.rs @@ -1,7 +1,7 @@ use anyhow::Result; use bevy::asset::io::Reader; +use kira::sound::static_sound::StaticSoundData; use bevy::asset::{AssetLoader, LoadContext}; -use kira::sound::static_sound::{StaticSoundData, StaticSoundSettings}; use kira::sound::FromFileError; use std::io::Cursor; use thiserror::Error; @@ -37,8 +37,7 @@ impl AssetLoader for Mp3Loader { ) -> Result { let mut sound_bytes = vec![]; reader.read_to_end(&mut sound_bytes).await?; - let sound = - StaticSoundData::from_cursor(Cursor::new(sound_bytes), StaticSoundSettings::default())?; + let sound = StaticSoundData::from_cursor(Cursor::new(sound_bytes))?; Ok(AudioSource { sound }) } diff --git a/src/source/ogg_loader.rs b/src/source/ogg_loader.rs index 2c17471..81f9aa6 100644 --- a/src/source/ogg_loader.rs +++ b/src/source/ogg_loader.rs @@ -1,7 +1,7 @@ use anyhow::Result; use bevy::asset::io::Reader; +use kira::sound::static_sound::StaticSoundData; use bevy::asset::{AssetLoader, LoadContext}; -use kira::sound::static_sound::{StaticSoundData, StaticSoundSettings}; use kira::sound::FromFileError; use std::io::Cursor; use thiserror::Error; @@ -37,8 +37,7 @@ impl AssetLoader for OggLoader { ) -> Result { let mut sound_bytes = vec![]; reader.read_to_end(&mut sound_bytes).await?; - let sound = - StaticSoundData::from_cursor(Cursor::new(sound_bytes), StaticSoundSettings::default())?; + let sound = StaticSoundData::from_cursor(Cursor::new(sound_bytes))?; Ok(AudioSource { sound }) } diff --git a/src/source/wav_loader.rs b/src/source/wav_loader.rs index b8130fb..ffd6409 100644 --- a/src/source/wav_loader.rs +++ b/src/source/wav_loader.rs @@ -1,7 +1,7 @@ use anyhow::Result; use bevy::asset::io::Reader; +use kira::sound::static_sound::StaticSoundData; use bevy::asset::{AssetLoader, LoadContext}; -use kira::sound::static_sound::{StaticSoundData, StaticSoundSettings}; use kira::sound::FromFileError; use std::io::Cursor; use thiserror::Error; @@ -37,8 +37,7 @@ impl AssetLoader for WavLoader { ) -> Result { let mut sound_bytes = vec![]; reader.read_to_end(&mut sound_bytes).await?; - let sound = - StaticSoundData::from_cursor(Cursor::new(sound_bytes), StaticSoundSettings::default())?; + let sound = StaticSoundData::from_cursor(Cursor::new(sound_bytes))?; Ok(AudioSource { sound }) } fn extensions(&self) -> &[&str] {