aboutsummaryrefslogtreecommitdiffstats
path: root/mumd/src/audio.rs
diff options
context:
space:
mode:
authorEskil Queseth <eskilq@kth.se>2020-10-14 19:48:05 +0200
committerEskil Queseth <eskilq@kth.se>2020-10-14 19:48:05 +0200
commita40d365aacf118b33c07f3353f277eb96c4536a8 (patch)
tree1a5e623da01745b3d2a2d1b1d5958a22cd0e382a /mumd/src/audio.rs
parentc0855405832ce47f75fa6e1ff7a33e51a8b36903 (diff)
parent6ac72067a75d5e1904226efb5c45bcf0e54a0ae5 (diff)
downloadmum-a40d365aacf118b33c07f3353f277eb96c4536a8.tar.gz
Merge remote-tracking branch 'origin/commands' into main
Diffstat (limited to 'mumd/src/audio.rs')
-rw-r--r--mumd/src/audio.rs71
1 files changed, 43 insertions, 28 deletions
diff --git a/mumd/src/audio.rs b/mumd/src/audio.rs
index 9b794a6..1445415 100644
--- a/mumd/src/audio.rs
+++ b/mumd/src/audio.rs
@@ -1,6 +1,5 @@
use bytes::Bytes;
-use cpal::traits::DeviceTrait;
-use cpal::traits::HostTrait;
+use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
use cpal::{
InputCallbackInfo, OutputCallbackInfo, Sample, SampleFormat, SampleRate, Stream, StreamConfig,
};
@@ -28,9 +27,9 @@ pub struct Audio {
pub input_config: StreamConfig,
pub input_stream: Stream,
pub input_buffer: Arc<Mutex<VecDeque<f32>>>,
- input_channel_receiver: Option<Receiver<VoicePacketPayload>>,
+ input_channel_receiver: Option<Receiver<VoicePacketPayload>>, //TODO unbounded? mbe ring buffer and drop the first packet
- client_streams: Arc<Mutex<HashMap<u32, ClientStream>>>,
+ client_streams: Arc<Mutex<HashMap<u32, ClientStream>>>, //TODO move to user state
}
//TODO split into input/output
@@ -104,31 +103,39 @@ impl Audio {
let input_stream = match input_supported_sample_format {
SampleFormat::F32 => input_device.build_input_stream(
&input_config,
- input_callback::<f32>(input_encoder,
- input_sender,
- input_config.sample_rate.0,
- 10.0),
+ input_callback::<f32>(
+ input_encoder,
+ input_sender,
+ input_config.sample_rate.0,
+ 4, // 10 ms
+ ),
err_fn,
),
SampleFormat::I16 => input_device.build_input_stream(
&input_config,
- input_callback::<i16>(input_encoder,
- input_sender,
- input_config.sample_rate.0,
- 10.0),
+ input_callback::<i16>(
+ input_encoder,
+ input_sender,
+ input_config.sample_rate.0,
+ 4, // 10 ms
+ ),
err_fn,
),
SampleFormat::U16 => input_device.build_input_stream(
&input_config,
- input_callback::<u16>(input_encoder,
- input_sender,
- input_config.sample_rate.0,
- 10.0),
+ input_callback::<u16>(
+ input_encoder,
+ input_sender,
+ input_config.sample_rate.0,
+ 4, // 10 ms
+ ),
err_fn,
),
}
.unwrap();
+ output_stream.play().unwrap();
+
Self {
output_config,
output_stream,
@@ -206,7 +213,8 @@ impl ClientStream {
match payload {
VoicePacketPayload::Opus(bytes, _eot) => {
let mut out: Vec<f32> = vec![0.0; 720 * channels * 4]; //720 is because that is the max size of packet we can get that we want to decode
- let parsed = self.opus_decoder
+ let parsed = self
+ .opus_decoder
.decode_float(&bytes, &mut out, false)
.expect("Error decoding");
out.truncate(parsed);
@@ -268,16 +276,19 @@ fn input_callback<T: Sample>(
mut opus_encoder: opus::Encoder,
mut input_sender: Sender<VoicePacketPayload>,
sample_rate: u32,
- opus_frame_size_ms: f32,
+ opus_frame_size_blocks: u32, // blocks of 2.5ms
) -> impl FnMut(&[T], &InputCallbackInfo) + Send + 'static {
- if ! ( opus_frame_size_ms == 2.5
- || opus_frame_size_ms == 5.0
- || opus_frame_size_ms == 10.0
- || opus_frame_size_ms == 20.0) {
- panic!("Unsupported opus frame size {}", opus_frame_size_ms);
+ 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_ms * sample_rate as f32) as u32 / 1000;
-
+ let opus_frame_size = opus_frame_size_blocks * sample_rate / 400;
let buf = Arc::new(Mutex::new(VecDeque::new()));
move |data: &[T], _info: &InputCallbackInfo| {
@@ -292,9 +303,13 @@ fn input_callback<T: Sample>(
.unwrap();
opus_buf.truncate(result);
let bytes = Bytes::copy_from_slice(&opus_buf);
- input_sender
- .try_send(VoicePacketPayload::Opus(bytes, false))
- .unwrap(); //TODO handle full buffer / disconnect
+ match input_sender.try_send(VoicePacketPayload::Opus(bytes, false)) {
+ //TODO handle full buffer / disconnect
+ Ok(_) => {}
+ Err(_e) => {
+ //warn!("Error sending audio packet: {:?}", e);
+ }
+ }
*buf = tail;
}
}