bevy_mod_kira/sound/
static_sounds.rs1use anyhow::Result;
2use bevy::asset::io::Reader;
3use bevy::asset::{Asset, AssetLoader, LoadContext};
4use bevy::prelude::{Component, Handle, debug};
5use bevy::reflect::TypePath;
6use kira::sound::static_sound::StaticSoundData;
7use kira::sound::{FromFileError, SoundData};
8use std::io::Cursor;
9use thiserror::Error;
10
11#[derive(Debug, Error)]
12pub enum KiraError {
13    #[error("An error occurred while reading the file from the filesystem")]
14    IoError(#[from] std::io::Error),
15    #[error("An error occurred when parsing the file")]
16    FromFileError(#[from] FromFileError),
17}
18
19#[derive(TypePath, Clone, Asset)]
20pub struct SoundAsset<T>
21where
22    T: TypePath + Send + Sync + SoundData + Clone,
23{
24    pub sound: T,
25}
26
27#[derive(Clone, TypePath)]
28pub struct KiraStaticSoundData(pub StaticSoundData);
29
30impl SoundData for KiraStaticSoundData {
31    type Error = <StaticSoundData as SoundData>::Error;
32    type Handle = <StaticSoundData as SoundData>::Handle;
33    fn into_sound(
34        self,
35    ) -> std::result::Result<(Box<dyn kira::sound::Sound>, Self::Handle), Self::Error> {
36        self.0.into_sound()
37    }
38}
39
40pub type KiraStaticSoundAsset = SoundAsset<KiraStaticSoundData>;
50
51pub struct StaticSoundFileLoader;
52
53#[derive(Component)]
54pub struct KiraStaticSoundHandle(pub Handle<KiraStaticSoundAsset>);
55
56impl AssetLoader for StaticSoundFileLoader {
59    type Asset = KiraStaticSoundAsset;
60    type Settings = ();
61    type Error = KiraError;
62
63    async fn load(
64        &self,
65        reader: &mut dyn Reader,
66        _settings: &Self::Settings,
67        _load_context: &mut LoadContext<'_>,
68    ) -> Result<Self::Asset, KiraError> {
69        let mut sound_bytes = vec![];
70        reader.read_to_end(&mut sound_bytes).await?;
71        debug!("Loading sound with {} bytes", sound_bytes.len());
72        let sound = StaticSoundData::from_cursor(Cursor::new(sound_bytes))?;
73        let asset: KiraStaticSoundAsset = KiraStaticSoundAsset {
74            sound: KiraStaticSoundData(sound.clone()),
75        };
76        Ok(asset)
77    }
78
79    fn extensions(&self) -> &[&str] {
80        &[
81            #[cfg(feature = "ogg")]
82            "ogg",
83            "oga",
84            "spx",
85            #[cfg(feature = "flac")]
86            "flac",
87            #[cfg(feature = "mp3")]
88            "mp3",
89            #[cfg(feature = "wav")]
90            "wav",
91        ]
92    }
93}