veloren/voxygen/src/audio/soundcache.rs

85 lines
2.4 KiB
Rust
Raw Normal View History

//! Handles caching and retrieval of decoded `.wav` sfx sound data, eliminating
//! the need to decode files on each playback
2019-09-05 09:11:18 +00:00
use common::assets;
2020-12-12 22:14:24 +00:00
use std::{borrow::Cow, io, sync::Arc};
use tracing::warn;
// Implementation of sound taken from this github issue:
// https://github.com/RustAudio/rodio/issues/141
2020-12-12 22:14:24 +00:00
#[derive(Clone)]
pub struct WavSound(Arc<Vec<u8>>);
2020-12-12 22:14:24 +00:00
impl AsRef<[u8]> for WavSound {
fn as_ref(&self) -> &[u8] { &self.0 }
}
2020-12-12 22:14:24 +00:00
pub struct SoundLoader;
impl assets::Loader<WavSound> for SoundLoader {
fn load(content: Cow<[u8]>, _: &str) -> Result<WavSound, assets::BoxedError> {
let arc = Arc::new(content.into_owned());
Ok(WavSound(arc))
}
2020-12-12 22:14:24 +00:00
}
impl assets::Asset for WavSound {
type Loader = SoundLoader;
2020-12-13 01:09:57 +00:00
const EXTENSION: &'static str = "wav";
2020-12-12 22:14:24 +00:00
fn default_value(specifier: &str, error: assets::Error) -> Result<Self, assets::Error> {
warn!(?specifier, ?error, "Failed to load sound");
2020-12-12 22:14:24 +00:00
Ok(WavSound::empty())
}
}
/// Wrapper for decoded audio data
impl WavSound {
pub fn decoder(self) -> rodio::Decoder<io::Cursor<WavSound>> {
let cursor = io::Cursor::new(self);
rodio::Decoder::new(cursor).unwrap()
}
2020-12-13 01:09:57 +00:00
/// Returns a `WavSound` containing empty .wav data. This intentionally
/// doesn't load from the filesystem so we have a reliable fallback when
/// there is a failure to read a file.
///
/// The data below is the result of passing a very short, silent .wav file
/// to `Sound::load()`.
2020-12-12 22:14:24 +00:00
pub fn empty() -> WavSound {
WavSound(Arc::new(vec![
82, 73, 70, 70, 40, 0, 0, 0, 87, 65, 86, 69, 102, 109, 116, 32, 16, 0, 0, 0, 1, 0, 1,
0, 68, 172, 0, 0, 136, 88, 1, 0, 2, 0, 16, 0, 100, 97, 116, 97, 4, 0, 0, 0, 0, 0, 0, 0,
]))
}
}
2020-12-12 22:14:24 +00:00
#[derive(Clone)]
pub struct OggSound(Arc<Vec<u8>>);
impl AsRef<[u8]> for OggSound {
fn as_ref(&self) -> &[u8] { &self.0 }
}
2020-12-12 22:14:24 +00:00
impl assets::Loader<OggSound> for SoundLoader {
fn load(content: Cow<[u8]>, _: &str) -> Result<OggSound, assets::BoxedError> {
let arc = Arc::new(content.into_owned());
Ok(OggSound(arc))
}
}
2020-12-12 22:14:24 +00:00
impl assets::Asset for OggSound {
type Loader = SoundLoader;
2020-12-13 01:09:57 +00:00
const EXTENSION: &'static str = "ogg";
2020-12-12 22:14:24 +00:00
}
/// Wrapper for decoded audio data
impl OggSound {
pub fn decoder(self) -> rodio::Decoder<io::Cursor<OggSound>> {
let cursor = io::Cursor::new(self);
rodio::Decoder::new(cursor).unwrap()
}
2020-12-13 01:09:57 +00:00
}