Add positional audio

Orientation needs to be set now
This commit is contained in:
Louis Pearson 2019-08-31 21:18:03 -06:00
parent fcb141a160
commit 00830108e9
3 changed files with 44 additions and 3 deletions

View File

@ -64,6 +64,14 @@ impl Channel {
self.sink.set_volume(volume);
}
pub fn set_left_ear_position(&mut self, pos: [f32; 3]) {
self.sink.set_left_ear_position(pos);
}
pub fn set_right_ear_position(&mut self, pos: [f32; 3]) {
self.sink.set_right_ear_position(pos);
}
pub fn update(&mut self, dt: f32) {
match self.state {
ChannelState::Playing => {},

View File

@ -5,10 +5,16 @@ use channel::{AudioType, Channel};
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 LISTEN_DISTANCE : f32 = 25.0;
pub struct AudioFrontend {
pub device: String,
@ -20,6 +26,8 @@ pub struct AudioFrontend {
sfx_volume: f32,
music_volume: f32,
listener_pos_left: Vec3::<f32>,
listener_pos_right: Vec3::<f32>,
}
impl AudioFrontend {
@ -33,6 +41,8 @@ impl AudioFrontend {
next_channel_id: 0,
sfx_volume: 1.0,
music_volume: 1.0,
listener_pos_left: Vec3::from_slice(&LEFT_EAR),
listener_pos_right: Vec3::from_slice(&RIGHT_EAR),
}
}
@ -46,6 +56,8 @@ impl AudioFrontend {
next_channel_id: 0,
sfx_volume: 1.0,
music_volume: 1.0,
listener_pos_left: Vec3::from_slice(&LEFT_EAR),
listener_pos_right: Vec3::from_slice(&RIGHT_EAR),
}
}
@ -67,12 +79,15 @@ impl AudioFrontend {
///```ignore
///audio.play_sound("voxygen.audio.sfx.step");
///```
pub fn play_sound(&mut self, sound: String) -> usize {
pub fn play_sound(&mut self, sound: String, pos: Vec3::<f32>) -> usize {
let id = self.next_channel_id;
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 pos = pos / LISTEN_DISTANCE;
let sink = SpatialSink::new(device, pos.into_array(),
self.listener_pos_left.into_array(),
self.listener_pos_right.into_array());
let file = assets::load_file(&sound, &["wav"]).unwrap();
let sound = Decoder::new(file).unwrap();
@ -85,6 +100,21 @@ impl AudioFrontend {
id
}
pub fn set_listener_pos(&mut self, pos: &Vec3::<f32>) {
let pos_left = (pos.clone() + EAR_LEFT) / LISTEN_DISTANCE;
let pos_right = (pos.clone() + EAR_RIGHT) / LISTEN_DISTANCE;
self.listener_pos_left = pos_left.clone();
self.listener_pos_right = pos_right.clone();
for channel in self.channels.iter_mut() {
if channel.get_audio_type() == AudioType::Sfx {
channel.set_left_ear_position(pos_left.into_array());
channel.set_right_ear_position(pos_right.into_array());
}
}
}
pub fn play_music(&mut self, sound: String) -> usize {
let id = self.next_channel_id;
self.next_channel_id += 1;
@ -138,6 +168,7 @@ impl AudioFrontend {
}
}
// TODO: figure out how badly this will break things when it is called
pub fn set_device(&mut self, name: String) {
self.device = name.clone();
self.audio_device = get_device_raw(name);

View File

@ -39,6 +39,8 @@ impl SoundMgr {
.get(client.entity())
.map_or(Vec3::zero(), |pos| pos.0);
audio.set_listener_pos(&player_pos);
for (entity, pos, body, character) in (
&ecs.entities(),
&ecs.read_storage::<Pos>(),
@ -60,7 +62,7 @@ impl SoundMgr {
if let Run = &character.movement {
if state.last_step_sound.elapsed().as_secs_f64() > 0.5 {
let rand_step = (rand::random::<usize>() % 7) + 1;
audio.play_sound(format!("voxygen.audio.footsteps.stepdirt_{}", rand_step));
audio.play_sound(format!("voxygen.audio.footsteps.stepdirt_{}", rand_step), pos.0);
state.last_step_sound = Instant::now();
}
}