aboutsummaryrefslogtreecommitdiffstats
path: root/mumd/src/audio/input.rs
diff options
context:
space:
mode:
authorGustav Sörnäs <gustav@sornas.net>2020-10-21 03:37:22 +0200
committerGustav Sörnäs <gustav@sornas.net>2020-10-21 03:37:22 +0200
commitc9846394ac6cddd82442baadcabad653a28fed66 (patch)
treeb92afa32fa1e56f5542d921c8f9f1f3befa06648 /mumd/src/audio/input.rs
parent1c18f57afe3eae3d61ad44c899d57332e0f71e0c (diff)
downloadmum-c9846394ac6cddd82442baadcabad653a28fed66.tar.gz
refactor audio into input.rs and output.rs
Diffstat (limited to 'mumd/src/audio/input.rs')
-rw-r--r--mumd/src/audio/input.rs52
1 files changed, 52 insertions, 0 deletions
diff --git a/mumd/src/audio/input.rs b/mumd/src/audio/input.rs
new file mode 100644
index 0000000..4e95360
--- /dev/null
+++ b/mumd/src/audio/input.rs
@@ -0,0 +1,52 @@
+use bytes::Bytes;
+use cpal::{InputCallbackInfo, Sample};
+use mumble_protocol::voice::VoicePacketPayload;
+use std::collections::VecDeque;
+use std::sync::{Arc, Mutex};
+use tokio::sync::{mpsc, watch};
+
+pub fn callback<T: Sample>(
+ mut opus_encoder: opus::Encoder,
+ mut input_sender: mpsc::Sender<VoicePacketPayload>,
+ sample_rate: u32,
+ input_volume_receiver: watch::Receiver<f32>,
+ opus_frame_size_blocks: u32, // blocks of 2.5ms
+) -> impl FnMut(&[T], &InputCallbackInfo) + Send + 'static {
+ if !(opus_frame_size_blocks == 1
+ || opus_frame_size_blocks == 2
+ || opus_frame_size_blocks == 4
+ || opus_frame_size_blocks == 8)
+ {
+ panic!(
+ "Unsupported amount of opus frame blocks {}",
+ opus_frame_size_blocks
+ );
+ }
+ let opus_frame_size = opus_frame_size_blocks * sample_rate / 400;
+
+ let buf = Arc::new(Mutex::new(VecDeque::new()));
+ move |data: &[T], _info: &InputCallbackInfo| {
+ let mut buf = buf.lock().unwrap();
+ let input_volume = *input_volume_receiver.borrow();
+ let out: Vec<f32> = data.iter().map(|e| e.to_f32())
+ .map(|e| e * input_volume)
+ .collect();
+ buf.extend(out);
+ while buf.len() >= opus_frame_size as usize {
+ let tail = buf.split_off(opus_frame_size as usize);
+ let mut opus_buf: Vec<u8> = vec![0; opus_frame_size as usize];
+ let result = opus_encoder
+ .encode_float(&Vec::from(buf.clone()), &mut opus_buf)
+ .unwrap();
+ opus_buf.truncate(result);
+ let bytes = Bytes::copy_from_slice(&opus_buf);
+ match input_sender.try_send(VoicePacketPayload::Opus(bytes, false)) {
+ Ok(_) => {}
+ Err(_e) => {
+ //warn!("Error sending audio packet: {:?}", e);
+ }
+ }
+ *buf = tail;
+ }
+ }
+}