aboutsummaryrefslogtreecommitdiffstats
path: root/mumd/src/audio.rs
diff options
context:
space:
mode:
authorRubens Brandao <git@rubens.io>2021-04-07 14:29:23 +0200
committerRubens Brandao <git@rubens.io>2021-04-07 14:29:23 +0200
commit12554b2f6cd89ad3cd3721bbc790d7772a21c3ae (patch)
tree03a289b3610eb5000ee3347c9a73d75da336808b /mumd/src/audio.rs
parent38270c4a2374c2ccc04597a28fb191af9d86b814 (diff)
downloadmum-12554b2f6cd89ad3cd3721bbc790d7772a21c3ae.tar.gz
Create a trait and default implementation for device audio input
Diffstat (limited to 'mumd/src/audio.rs')
-rw-r--r--mumd/src/audio.rs75
1 files changed, 9 insertions, 66 deletions
diff --git a/mumd/src/audio.rs b/mumd/src/audio.rs
index facca9c..5a839bc 100644
--- a/mumd/src/audio.rs
+++ b/mumd/src/audio.rs
@@ -2,6 +2,7 @@ pub mod input;
pub mod output;
mod noise_gate;
+use crate::audio::input::{DefaultAudioInputDevice, AudioInputDevice};
use crate::audio::output::SaturatingAdd;
use crate::audio::noise_gate::{from_interleaved_samples_stream, OpusEncoder, StreamingNoiseGate, StreamingSignalExt};
use crate::error::{AudioError, AudioStream};
@@ -68,80 +69,23 @@ impl TryFrom<&str> for NotificationEvents {
}
pub struct AudioInput {
- _stream: cpal::Stream,
+ _device: DefaultAudioInputDevice,
channel_receiver: Arc<tokio::sync::Mutex<Box<dyn Stream<Item = VoicePacket<Serverbound>> + Unpin>>>,
- volume_sender: watch::Sender<f32>,
}
impl AudioInput {
pub fn new(input_volume: f32, phase_watcher: watch::Receiver<StatePhase>) -> Result<Self, AudioError> {
+ let mut default = DefaultAudioInputDevice::new(input_volume, phase_watcher)?;
let sample_rate = SampleRate(SAMPLE_RATE);
- let host = cpal::default_host();
-
- let input_device = host
- .default_input_device()
- .ok_or(AudioError::NoDevice(AudioStream::Input))?;
- let input_supported_config = input_device
- .supported_input_configs()
- .map_err(|e| AudioError::NoConfigs(AudioStream::Input, 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::Input))?
- .with_sample_rate(sample_rate);
- let input_supported_sample_format = input_supported_config.sample_format();
- let input_config: StreamConfig = input_supported_config.into();
-
- let err_fn = |err| error!("An error occurred on the output audio stream: {}", err);
-
- let (sample_sender, sample_receiver) = futures_channel::mpsc::channel(1_000_000);
-
- let (input_volume_sender, input_volume_receiver) = watch::channel::<f32>(input_volume);
-
- let input_stream = match input_supported_sample_format {
- SampleFormat::F32 => input_device.build_input_stream(
- &input_config,
- input::callback::<f32>(
- sample_sender,
- input_volume_receiver,
- phase_watcher,
- ),
- err_fn,
- ),
- SampleFormat::I16 => input_device.build_input_stream(
- &input_config,
- input::callback::<i16>(
- sample_sender,
- input_volume_receiver,
- phase_watcher,
- ),
- err_fn,
- ),
- SampleFormat::U16 => input_device.build_input_stream(
- &input_config,
- input::callback::<u16>(
- sample_sender,
- input_volume_receiver,
- phase_watcher,
- ),
- err_fn,
- ),
- }
- .map_err(|e| AudioError::InvalidStream(AudioStream::Input, e))?;
-
let opus_stream = OpusEncoder::new(
4,
- input_config.sample_rate.0,
- input_config.channels as usize,
+ sample_rate.0,
+ default.get_num_channels(),
StreamingSignalExt::into_interleaved_samples(
StreamingNoiseGate::new(
- from_interleaved_samples_stream::<_, f32>(sample_receiver), //TODO group frames correctly
+ from_interleaved_samples_stream::<_, f32>(default.sample_receiver()), //TODO group frames correctly
10_000
)
)
@@ -156,11 +100,10 @@ impl AudioInput {
}
);
- input_stream.play().map_err(|e| AudioError::OutputPlayError(e))?;
+ default.play()?;
let res = Self {
- _stream: input_stream,
- volume_sender: input_volume_sender,
+ _device: default,
channel_receiver: Arc::new(tokio::sync::Mutex::new(Box::new(opus_stream))),
};
Ok(res)
@@ -171,7 +114,7 @@ impl AudioInput {
}
pub fn set_volume(&self, input_volume: f32) {
- self.volume_sender.send(input_volume).unwrap();
+ self._device.set_volume(input_volume);
}
}