#![cfg_attr(docsrs, feature(doc_cfg))]
#![warn(missing_docs)]
#![forbid(unsafe_code)]
const AVAILABLE_EXTENSIONS: &[&str] = &[
#[cfg(feature = "ogg")]
"ogg",
#[cfg(feature = "mp3")]
"mp3",
#[cfg(feature = "flac")]
"flac",
#[cfg(feature = "wav")]
"wav",
];
pub use static_sound::StaticSound;
pub use streaming::StreamingSound;
mod static_sound {
use assets_manager::{loader, Asset};
use kira::sound::static_sound::{StaticSoundData, StaticSoundSettings};
use std::io::Cursor;
#[derive(Clone)]
#[repr(transparent)]
pub struct StaticSound(pub StaticSoundData);
impl StaticSound {
pub fn duration(&self) -> std::time::Duration {
self.0.duration()
}
pub fn with_settings(&self, settings: StaticSoundSettings) -> Self {
Self(self.0.with_settings(settings))
}
}
impl loader::Loader<StaticSound> for loader::SoundLoader {
fn load(
content: std::borrow::Cow<[u8]>,
_: &str,
) -> Result<StaticSound, assets_manager::BoxedError> {
let sound = StaticSoundData::from_cursor(Cursor::new(content.into_owned()))?;
Ok(StaticSound(sound))
}
}
impl Asset for StaticSound {
const EXTENSIONS: &'static [&'static str] = crate::AVAILABLE_EXTENSIONS;
type Loader = loader::SoundLoader;
}
impl kira::sound::SoundData for StaticSound {
type Error = <StaticSoundData as kira::sound::SoundData>::Error;
type Handle = <StaticSoundData as kira::sound::SoundData>::Handle;
#[inline]
fn into_sound(self) -> Result<(Box<dyn kira::sound::Sound>, Self::Handle), Self::Error> {
self.0.into_sound()
}
}
impl From<StaticSound> for StaticSoundData {
#[inline]
fn from(sound: StaticSound) -> Self {
sound.0
}
}
impl std::fmt::Debug for StaticSound {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.fmt(f)
}
}
}
#[cfg(not(target_arch = "wasm32"))]
#[cfg_attr(docsrs, doc(cfg(not(target_arch = "wasm32"))))]
mod streaming {
use assets_manager::{loader, Asset};
use kira::sound::{
streaming::{StreamingSoundData, StreamingSoundSettings},
FromFileError,
};
use std::io::Cursor;
#[derive(Clone)]
pub struct StreamingSound {
pub settings: StreamingSoundSettings,
bytes: assets_manager::SharedBytes,
}
impl StreamingSound {
pub fn with_settings(&self, settings: StreamingSoundSettings) -> Self {
Self {
settings,
bytes: self.bytes.clone(),
}
}
fn try_into_kira(self) -> Result<StreamingSoundData<FromFileError>, FromFileError> {
let mut sound = StreamingSoundData::from_cursor(Cursor::new(self.bytes))?;
sound.settings = self.settings;
Ok(sound)
}
}
impl loader::Loader<StreamingSound> for loader::SoundLoader {
fn load(
content: std::borrow::Cow<[u8]>,
_: &str,
) -> Result<StreamingSound, assets_manager::BoxedError> {
let bytes = assets_manager::SharedBytes::from(content);
let settings = StreamingSoundSettings::default();
let _ = StreamingSoundData::from_cursor(Cursor::new(bytes.clone()))?;
Ok(StreamingSound { settings, bytes })
}
}
impl Asset for StreamingSound {
const EXTENSIONS: &'static [&'static str] = crate::AVAILABLE_EXTENSIONS;
type Loader = loader::SoundLoader;
}
impl kira::sound::SoundData for StreamingSound {
type Error = <StreamingSoundData<FromFileError> as kira::sound::SoundData>::Error;
type Handle = <StreamingSoundData<FromFileError> as kira::sound::SoundData>::Handle;
#[inline]
fn into_sound(self) -> Result<(Box<dyn kira::sound::Sound>, Self::Handle), Self::Error> {
self.try_into_kira()?.into_sound()
}
}
impl From<StreamingSound> for StreamingSoundData<FromFileError> {
fn from(sound: StreamingSound) -> Self {
sound.try_into_kira().expect("reading succeded earlier")
}
}
impl std::fmt::Debug for StreamingSound {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("StreamingSound")
.field("settings", &self.settings)
.finish_non_exhaustive()
}
}
}