A multiplayer VR framework w/voice chat
at main 2.2 kB view raw
1use bevy::transform::components::Transform; 2use kira::{Decibels, Easing, Mapping, Tween, Value, effect::{filter::FilterBuilder}, track::{SendTrackBuilder, SendTrackHandle, SpatialTrackBuilder, SpatialTrackHandle}}; 3 4use crate::{FelixAudioComponent, source::{AudioSource, stream_source::sound_data::StreamAudioSourceSoundData}}; 5 6mod sound_data; 7 8pub struct StreamAudioSource{ 9 saturate_cb: Option<Box<dyn FnMut(usize) -> Vec<f32> + 'static + Sync + Send>>, 10 sample_rate: usize, 11 12 send_track: Option<SendTrackHandle>, 13 spatial_track: Option<SpatialTrackHandle> 14} 15 16impl StreamAudioSource{ 17 pub fn new<T>( sample_rate: usize, saturate: T ) -> Self 18 where 19 T: FnMut(usize) -> Vec<f32> + 'static + Sync + Send 20 { 21 Self { 22 saturate_cb: Some(Box::new(saturate)), 23 sample_rate, 24 25 send_track: None, 26 spatial_track: None 27 } 28 } 29} 30 31impl AudioSource for StreamAudioSource{ 32 fn init( &mut self, audio_system: &mut FelixAudioComponent ) { 33 let sound_data = StreamAudioSourceSoundData::new(self.sample_rate.clone(), self.saturate_cb.take().unwrap()); 34 let send_track = audio_system.manager.add_send_track(SendTrackBuilder::new()).unwrap(); 35 36 let mut spatial_track = audio_system.manager.add_spatial_sub_track( 37 &audio_system.main_listener, 38 [ 39 0.0, 40 0.0, 41 0.0 42 ], 43 SpatialTrackBuilder::new() 44 .with_effect(FilterBuilder::new().cutoff(Value::FromListenerDistance(Mapping { 45 input_range: ( 0.0, 20.0 ), 46 output_range: ( 18000.0, 2000.0 ), 47 easing: Easing::Linear 48 }))) 49 .with_send(&send_track, Value::FromListenerDistance(Mapping { 50 input_range: ( 0.0, 1.0 ), 51 output_range: ( Decibels(12.0), Decibels(-100.0) ), 52 easing: Easing::Linear 53 })) 54 ).unwrap(); 55 56 spatial_track.play(sound_data).unwrap(); 57 58 self.send_track = Some(send_track); 59 self.spatial_track = Some(spatial_track); 60 } 61 62 fn needs_init( &self ) -> bool { 63 self.spatial_track.is_none() 64 } 65 66 fn update( &mut self, transform: &Transform ) { 67 let track = self.spatial_track.as_mut().unwrap(); 68 track.set_position(transform.translation, Tween::default()); 69 } 70}