aboutsummaryrefslogtreecommitdiffstats
path: root/mumd/src/audio.rs
diff options
context:
space:
mode:
authorRubens Brandao <git@rubens.io>2021-04-05 18:39:55 +0200
committerRubens Brandao <git@rubens.io>2021-04-05 18:39:55 +0200
commite431ecb6c5c8406bde6a54f40ee2f648cc0cec05 (patch)
tree93a227ab5f3ceac27286a1c2c36b79c12c72f95f /mumd/src/audio.rs
parent1734a72d3caff4f8831f4b366fdb818fddecf32f (diff)
downloadmum-e431ecb6c5c8406bde6a54f40ee2f648cc0cec05.tar.gz
Separate the input and output audio
Diffstat (limited to 'mumd/src/audio.rs')
-rw-r--r--mumd/src/audio.rs181
1 files changed, 99 insertions, 82 deletions
diff --git a/mumd/src/audio.rs b/mumd/src/audio.rs
index fdbeaee..0aac68c 100644
--- a/mumd/src/audio.rs
+++ b/mumd/src/audio.rs
@@ -67,46 +67,18 @@ impl TryFrom<&str> for NotificationEvents {
}
}
-pub struct Audio {
- output_config: StreamConfig,
- _output_stream: cpal::Stream,
+pub struct AudioInput {
_input_stream: cpal::Stream,
input_channel_receiver: Arc<tokio::sync::Mutex<Box<dyn Stream<Item = VoicePacket<Serverbound>> + Unpin>>>,
input_volume_sender: watch::Sender<f32>,
-
- output_volume_sender: watch::Sender<f32>,
-
- user_volumes: Arc<Mutex<HashMap<u32, (f32, bool)>>>,
-
- client_streams: Arc<Mutex<HashMap<(VoiceStreamType, u32), output::ClientStream>>>,
-
- sounds: HashMap<NotificationEvents, Vec<f32>>,
- play_sounds: Arc<Mutex<VecDeque<f32>>>,
}
-impl Audio {
- pub fn new(input_volume: f32, output_volume: f32, phase_watcher: watch::Receiver<StatePhase>) -> Result<Self, AudioError> {
+impl AudioInput {
+ pub fn new(input_volume: f32, phase_watcher: watch::Receiver<StatePhase>) -> Result<Self, AudioError> {
let sample_rate = SampleRate(SAMPLE_RATE);
let host = cpal::default_host();
- let output_device = host
- .default_output_device()
- .ok_or(AudioError::NoDevice(AudioStream::Output))?;
- let output_supported_config = output_device
- .supported_output_configs()
- .map_err(|e| AudioError::NoConfigs(AudioStream::Output, e))?
- .find_map(|c| {
- if c.min_sample_rate() <= sample_rate && c.max_sample_rate() >= sample_rate {
- Some(c)
- } else {
- None
- }
- })
- .ok_or(AudioError::NoSupportedConfig(AudioStream::Output))?
- .with_sample_rate(sample_rate);
- let output_supported_sample_format = output_supported_config.sample_format();
- let output_config: StreamConfig = output_supported_config.into();
let input_device = host
.default_input_device()
@@ -128,45 +100,6 @@ impl Audio {
let err_fn = |err| error!("An error occurred on the output audio stream: {}", err);
- let user_volumes = Arc::new(std::sync::Mutex::new(HashMap::new()));
- let (output_volume_sender, output_volume_receiver) = watch::channel::<f32>(output_volume);
- let play_sounds = Arc::new(std::sync::Mutex::new(VecDeque::new()));
-
- let client_streams = Arc::new(std::sync::Mutex::new(HashMap::new()));
- let output_stream = match output_supported_sample_format {
- SampleFormat::F32 => output_device.build_output_stream(
- &output_config,
- output::curry_callback::<f32>(
- Arc::clone(&play_sounds),
- Arc::clone(&client_streams),
- output_volume_receiver,
- Arc::clone(&user_volumes),
- ),
- err_fn,
- ),
- SampleFormat::I16 => output_device.build_output_stream(
- &output_config,
- output::curry_callback::<i16>(
- Arc::clone(&play_sounds),
- Arc::clone(&client_streams),
- output_volume_receiver,
- Arc::clone(&user_volumes),
- ),
- err_fn,
- ),
- SampleFormat::U16 => output_device.build_output_stream(
- &output_config,
- output::curry_callback::<u16>(
- Arc::clone(&play_sounds),
- Arc::clone(&client_streams),
- output_volume_receiver,
- Arc::clone(&user_volumes),
- ),
- err_fn,
- ),
- }
- .map_err(|e| AudioError::InvalidStream(AudioStream::Output, e))?;
-
let (sample_sender, sample_receiver) = futures_channel::mpsc::channel(1_000_000);
let (input_volume_sender, input_volume_receiver) = watch::channel::<f32>(input_volume);
@@ -218,14 +151,106 @@ impl Audio {
position_info: None,
});
- output_stream.play().map_err(|e| AudioError::OutputPlayError(e))?;
+ input_stream.play().map_err(|e| AudioError::OutputPlayError(e))?;
- let mut res = Self {
- output_config,
- _output_stream: output_stream,
+ let res = Self {
_input_stream: input_stream,
input_volume_sender,
input_channel_receiver: Arc::new(tokio::sync::Mutex::new(Box::new(opus_stream))),
+ };
+ Ok(res)
+ }
+
+ pub fn input_receiver(&self) -> Arc<tokio::sync::Mutex<Box<dyn Stream<Item = VoicePacket<Serverbound>> + Unpin>>> {
+ Arc::clone(&self.input_channel_receiver)
+ }
+
+ pub fn set_input_volume(&self, input_volume: f32) {
+ self.input_volume_sender.send(input_volume).unwrap();
+ }
+}
+
+pub struct AudioOutput {
+ output_config: StreamConfig,
+ _output_stream: cpal::Stream,
+
+ output_volume_sender: watch::Sender<f32>,
+
+ user_volumes: Arc<Mutex<HashMap<u32, (f32, bool)>>>,
+
+ client_streams: Arc<Mutex<HashMap<(VoiceStreamType, u32), output::ClientStream>>>,
+
+ sounds: HashMap<NotificationEvents, Vec<f32>>,
+ play_sounds: Arc<Mutex<VecDeque<f32>>>,
+}
+
+impl AudioOutput {
+ pub fn new(output_volume: f32) -> Result<Self, AudioError> {
+ let sample_rate = SampleRate(SAMPLE_RATE);
+
+ let host = cpal::default_host();
+ let output_device = host
+ .default_output_device()
+ .ok_or(AudioError::NoDevice(AudioStream::Output))?;
+ let output_supported_config = output_device
+ .supported_output_configs()
+ .map_err(|e| AudioError::NoConfigs(AudioStream::Output, e))?
+ .find_map(|c| {
+ if c.min_sample_rate() <= sample_rate && c.max_sample_rate() >= sample_rate {
+ Some(c)
+ } else {
+ None
+ }
+ })
+ .ok_or(AudioError::NoSupportedConfig(AudioStream::Output))?
+ .with_sample_rate(sample_rate);
+ let output_supported_sample_format = output_supported_config.sample_format();
+ let output_config: StreamConfig = output_supported_config.into();
+
+ let err_fn = |err| error!("An error occurred on the output audio stream: {}", err);
+
+ let user_volumes = Arc::new(std::sync::Mutex::new(HashMap::new()));
+ let (output_volume_sender, output_volume_receiver) = watch::channel::<f32>(output_volume);
+ let play_sounds = Arc::new(std::sync::Mutex::new(VecDeque::new()));
+
+ let client_streams = Arc::new(std::sync::Mutex::new(HashMap::new()));
+ let output_stream = match output_supported_sample_format {
+ SampleFormat::F32 => output_device.build_output_stream(
+ &output_config,
+ output::curry_callback::<f32>(
+ Arc::clone(&play_sounds),
+ Arc::clone(&client_streams),
+ output_volume_receiver,
+ Arc::clone(&user_volumes),
+ ),
+ err_fn,
+ ),
+ SampleFormat::I16 => output_device.build_output_stream(
+ &output_config,
+ output::curry_callback::<i16>(
+ Arc::clone(&play_sounds),
+ Arc::clone(&client_streams),
+ output_volume_receiver,
+ Arc::clone(&user_volumes),
+ ),
+ err_fn,
+ ),
+ SampleFormat::U16 => output_device.build_output_stream(
+ &output_config,
+ output::curry_callback::<u16>(
+ Arc::clone(&play_sounds),
+ Arc::clone(&client_streams),
+ output_volume_receiver,
+ Arc::clone(&user_volumes),
+ ),
+ err_fn,
+ ),
+ }
+ .map_err(|e| AudioError::InvalidStream(AudioStream::Output, e))?;
+
+ let mut res = Self {
+ output_config,
+ _output_stream: output_stream,
client_streams,
sounds: HashMap::new(),
output_volume_sender,
@@ -335,18 +360,10 @@ impl Audio {
}
}
- pub fn input_receiver(&self) -> Arc<tokio::sync::Mutex<Box<dyn Stream<Item = VoicePacket<Serverbound>> + Unpin>>> {
- Arc::clone(&self.input_channel_receiver)
- }
-
pub fn clear_clients(&mut self) {
self.client_streams.lock().unwrap().clear();
}
- pub fn set_input_volume(&self, input_volume: f32) {
- self.input_volume_sender.send(input_volume).unwrap();
- }
-
pub fn set_output_volume(&self, output_volume: f32) {
self.output_volume_sender.send(output_volume).unwrap();
}