Add soundcache

Still getting the stuttering. Time to rethink channels
This commit is contained in:
Louis Pearson 2019-09-01 17:00:12 -06:00
parent 65008f7d54
commit 529cb40dc4
3 changed files with 79 additions and 19 deletions

View File

@ -1,4 +1,6 @@
use rodio::SpatialSink;
use rodio::{SpatialSink, Decoder, Device};
use std::io::BufReader;
use std::fs::File;
use crate::audio::fader::Fader;
use vek::*;
@ -10,6 +12,9 @@ pub enum AudioType {
#[derive(PartialEq, Clone, Copy)]
enum ChannelState {
Init,
ToPlay,
Loading,
Playing,
Stopping,
Stopped,
@ -22,10 +27,16 @@ pub struct Channel {
state: ChannelState,
fader: Fader,
pub pos: Vec3::<f32>,
// sound_cache: Option<&SoundCache>,
}
impl Channel {
pub fn music(id: usize, sink: SpatialSink) -> Self {
pub fn music(id: usize, device: &Device, bufr: BufReader<File>) -> Self {
let sink = SpatialSink::new(device, [0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [-1.0, 0.0, 0.0]);
let sound = Decoder::new(bufr).unwrap();
sink.append(sound);
Self {
id,
sink,
@ -33,6 +44,7 @@ impl Channel {
state: ChannelState::Playing,
fader: Fader::fade_in(0.0),
pos: Vec3::zero(),
// sound_cache: None,
}
}
@ -43,7 +55,8 @@ impl Channel {
audio_type: AudioType::Sfx,
state: ChannelState::Playing,
fader: Fader::fade_in(0.0),
pos
pos,
// sound_cache,
}
}
@ -82,6 +95,9 @@ impl Channel {
pub fn update(&mut self, dt: f32) {
match self.state {
ChannelState::Init | ChannelState::ToPlay | ChannelState::Loading => {
}
ChannelState::Playing => {},
ChannelState::Stopping => {
self.fader.update(dt);

View File

@ -1,18 +1,14 @@
pub mod fader;
pub mod channel;
pub mod soundcache;
use fader::Fader;
use channel::{AudioType, Channel};
use soundcache::SoundCache;
use common::assets;
use rodio::{Decoder, Device, SpatialSink};
use vek::*;
const LEFT_EAR : [f32; 3] = [1.0, 0.0, 0.0];
const RIGHT_EAR : [f32; 3] = [-1.0, 0.0, 0.0];
const EAR_LEFT : Vec3<f32> = Vec3::new(1.0, 0.0, 0.0);
const EAR_RIGHT : Vec3<f32> = Vec3::new(-1.0, 0.0, 0.0);
const FALLOFF : f32 = 0.13;
@ -20,6 +16,7 @@ pub struct AudioFrontend {
pub device: String,
pub device_list: Vec<String>,
audio_device: Option<Device>,
sound_cache: SoundCache,
channels: Vec<Channel>,
next_channel_id: usize,
@ -41,6 +38,7 @@ impl AudioFrontend {
device: device.clone(),
device_list: list_devices(),
audio_device: get_device_raw(device),
sound_cache: SoundCache::new(),
channels: Vec::new(),
next_channel_id: 0,
sfx_volume: 1.0,
@ -58,6 +56,7 @@ impl AudioFrontend {
device: "none".to_string(),
device_list: list_devices(),
audio_device: None,
sound_cache: SoundCache::new(),
channels: Vec::new(),
next_channel_id: 0,
sfx_volume: 1.0,
@ -101,8 +100,7 @@ impl AudioFrontend {
self.listener_pos_left,
self.listener_pos_right);
let file = assets::load_file(&sound, &["wav"]).unwrap();
let sound = Decoder::new(file).unwrap();
let sound = self.sound_cache.load_sound(sound);
sink.append(sound);
@ -119,9 +117,7 @@ impl AudioFrontend {
let up = Vec3::new(0.0, 0.0, 1.0);
let pos_left = up.cross(self.listener_ori.clone()).normalized();
dbg!(pos_left);
let pos_right = self.listener_ori.cross(up.clone()).normalized();
dbg!(pos_right);
self.listener_pos_left = pos_left.into_array();
self.listener_pos_right = pos_right.into_array();
@ -144,14 +140,9 @@ impl AudioFrontend {
self.next_channel_id += 1;
if let Some(device) = &self.audio_device {
let sink = SpatialSink::new(device, [0.0, 0.0, 0.0], LEFT_EAR, RIGHT_EAR);
let file = assets::load_file(&sound, &["ogg"]).unwrap();
let sound = Decoder::new(file).unwrap();
sink.append(sound);
self.channels.push(Channel::music(id, sink));
self.channels.push(Channel::music(id, device, file));
}
id

View File

@ -0,0 +1,53 @@
use rodio;
use hashbrown::HashMap;
use std::io;
use std::io::Read;
use std::convert::AsRef;
use common::assets;
use std::sync::Arc;
// Implementation of sound taken from this github issue:
// https://github.com/RustAudio/rodio/issues/141
pub struct Sound (Arc<Vec<u8>>);
impl AsRef<[u8]> for Sound {
fn as_ref(&self) -> &[u8] {
&self.0
}
}
impl Sound {
pub fn load(filename: &str) -> Result<Sound, assets::Error> {
let mut file = assets::load_file(filename, &["wav"])?;
let mut buf = Vec::new();
file.read_to_end(&mut buf)?;
Ok(Sound(Arc::new(buf)))
}
pub fn cursor(&self) -> io::Cursor<Sound> {
io::Cursor::new(Sound(self.0.clone()))
}
pub fn decoder(&self) -> rodio::Decoder<io::Cursor<Sound>> {
rodio::Decoder::new(self.cursor()).unwrap()
}
}
pub struct SoundCache {
sounds: HashMap<String, Sound>,
}
impl SoundCache {
pub fn new() -> Self {
Self {
sounds: HashMap::new()
}
}
pub fn load_sound(&mut self, name: String) -> rodio::Decoder<io::Cursor<Sound>> {
self.sounds
.entry(name.clone())
.or_insert(Sound::load(&name).unwrap())
.decoder()
}
}