Skip to content

Commit

Permalink
Merge pull request #123 from mum-rs/typestate
Browse files Browse the repository at this point in the history
Typestate
  • Loading branch information
default-username-852 authored Aug 24, 2021
2 parents 455c09c + 5b48c3b commit 719bb19
Show file tree
Hide file tree
Showing 18 changed files with 808 additions and 753 deletions.
5 changes: 4 additions & 1 deletion mum/src/audio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,9 @@ impl AudioOutput {
/// Queues a sound effect.
pub fn play_effect(&self, effect: NotificationEvents) {
let samples = self.sounds.get(&effect).unwrap();
self.client_streams.lock().unwrap().add_sound_effect(samples);
self.client_streams
.lock()
.unwrap()
.add_sound_effect(samples);
}
}
28 changes: 15 additions & 13 deletions mum/src/audio/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use log::*;
use std::fmt::Debug;
use tokio::sync::watch;

use crate::audio::SAMPLE_RATE;
use crate::audio::transformers::{NoiseGate, Transformer};
use crate::audio::SAMPLE_RATE;
use crate::error::{AudioError, AudioStream};
use crate::state::StatePhase;

Expand All @@ -32,7 +32,9 @@ pub fn callback<T: Sample>(
buffer.extend(data.by_ref().take(buffer_size - buffer.len()));
let encoded = transformers
.iter_mut()
.try_fold((opus::Channels::Mono, &mut buffer[..]), |acc, e| e.transform(acc))
.try_fold((opus::Channels::Mono, &mut buffer[..]), |acc, e| {
e.transform(acc)
})
.map(|buf| opus_encoder.encode_vec_float(&*buf.1, buffer_size).unwrap());

if let Some(encoded) = encoded {
Expand Down Expand Up @@ -109,14 +111,18 @@ impl DefaultAudioInputDevice {
match input_config.channels {
1 => opus::Channels::Mono,
2 => opus::Channels::Stereo,
_ => unimplemented!("Only 1 or 2 channels supported, got {}", input_config.channels),
_ => unimplemented!(
"Only 1 or 2 channels supported, got {}",
input_config.channels
),
},
opus::Application::Voip,
)
.unwrap();
let buffer_size = (sample_rate.0 * frame_size / 400) as usize;

let transformers = vec![Box::new(NoiseGate::new(50)) as Box<dyn Transformer + Send + 'static>];
let transformers =
vec![Box::new(NoiseGate::new(50)) as Box<dyn Transformer + Send + 'static>];

let input_stream = match input_supported_sample_format {
SampleFormat::F32 => input_device.build_input_stream(
Expand All @@ -127,7 +133,7 @@ impl DefaultAudioInputDevice {
opus_encoder,
buffer_size,
input_volume_receiver,
phase_watcher
phase_watcher,
),
err_fn,
),
Expand All @@ -139,7 +145,7 @@ impl DefaultAudioInputDevice {
opus_encoder,
buffer_size,
input_volume_receiver,
phase_watcher
phase_watcher,
),
err_fn,
),
Expand All @@ -151,7 +157,7 @@ impl DefaultAudioInputDevice {
opus_encoder,
buffer_size,
input_volume_receiver,
phase_watcher
phase_watcher,
),
err_fn,
),
Expand All @@ -170,15 +176,11 @@ impl DefaultAudioInputDevice {

impl AudioInputDevice for DefaultAudioInputDevice {
fn play(&self) -> Result<(), AudioError> {
self.stream
.play()
.map_err(AudioError::InputPlayError)
self.stream.play().map_err(AudioError::InputPlayError)
}

fn pause(&self) -> Result<(), AudioError> {
self.stream
.pause()
.map_err(AudioError::InputPauseError)
self.stream.pause().map_err(AudioError::InputPauseError)
}

fn set_volume(&self, volume: f32) {
Expand Down
52 changes: 28 additions & 24 deletions mum/src/audio/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,23 @@ impl ClientAudioData {
.expect("Error decoding");
out.truncate(parsed);
match (packet_channels, self.output_channels) {
(opus::Channels::Mono, opus::Channels::Mono) | (opus::Channels::Stereo, opus::Channels::Stereo) => for sample in out {
self.buf.push(sample);
},
(opus::Channels::Mono, opus::Channels::Stereo) => for sample in out {
self.buf.push(sample);
self.buf.push(sample);
},
(opus::Channels::Stereo, opus::Channels::Mono) => for sample in out.into_iter().step_by(2) {
self.buf.push(sample);
},
(opus::Channels::Mono, opus::Channels::Mono)
| (opus::Channels::Stereo, opus::Channels::Stereo) => {
for sample in out {
self.buf.push(sample);
}
}
(opus::Channels::Mono, opus::Channels::Stereo) => {
for sample in out {
self.buf.push(sample);
self.buf.push(sample);
}
}
(opus::Channels::Stereo, opus::Channels::Mono) => {
for sample in out.into_iter().step_by(2) {
self.buf.push(sample);
}
}
}
}
}
Expand Down Expand Up @@ -92,9 +99,9 @@ impl ClientStream {
}

fn get_client(&mut self, client: ClientStreamKey) -> &mut ClientAudioData {
self.buffer_clients.entry(client).or_insert(
ClientAudioData::new(self.sample_rate, self.output_channels)
)
self.buffer_clients
.entry(client)
.or_insert(ClientAudioData::new(self.sample_rate, self.output_channels))
}

/// Decodes a voice packet.
Expand All @@ -116,7 +123,7 @@ impl ClientStream {
}

/// Adds two values in some saturating way.
///
///
/// Since we support [f32], [i16] and [u16] we need some way of adding two values
/// without peaking above/below the edge values. This trait ensures that we can
/// use all three primitive types as a generic parameter.
Expand Down Expand Up @@ -183,7 +190,10 @@ impl DefaultAudioOutputDevice {
.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 && c.channels() == 2 {
if c.min_sample_rate() <= sample_rate
&& c.max_sample_rate() >= sample_rate
&& c.channels() == 2
{
Some(c)
} else {
None
Expand Down Expand Up @@ -244,15 +254,11 @@ impl DefaultAudioOutputDevice {

impl AudioOutputDevice for DefaultAudioOutputDevice {
fn play(&self) -> Result<(), AudioError> {
self.stream
.play()
.map_err(AudioError::OutputPlayError)
self.stream.play().map_err(AudioError::OutputPlayError)
}

fn pause(&self) -> Result<(), AudioError> {
self.stream
.pause()
.map_err(AudioError::OutputPauseError)
self.stream.pause().map_err(AudioError::OutputPauseError)
}

fn set_volume(&self, volume: f32) {
Expand Down Expand Up @@ -288,9 +294,7 @@ pub fn callback<T: Sample + AddAssign + SaturatingAdd + std::fmt::Display>(
let (user_volume, muted) = user_volumes.get(&k.1).cloned().unwrap_or((1.0, false));
if !muted {
for (sample, val) in data.iter_mut().zip(v.buf.drain().chain(iter::repeat(0.0))) {
*sample = sample.saturating_add(Sample::from(
&(val * volume * user_volume),
));
*sample = sample.saturating_add(Sample::from(&(val * volume * user_volume)));
}
}
}
Expand Down
9 changes: 5 additions & 4 deletions mum/src/audio/sound_effects.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,16 +69,17 @@ impl TryFrom<&str> for NotificationEvents {
"unmute" => Ok(NotificationEvents::Unmute),
"deafen" => Ok(NotificationEvents::Deafen),
"undeafen" => Ok(NotificationEvents::Undeafen),
_ => {
Err(())
}
_ => Err(()),
}
}
}

/// Loads files into an "event -> data"-map, with support for overriding
/// specific events with another sound file.
pub fn load_sound_effects(overrides: &[SoundEffect], num_channels: usize) -> HashMap<NotificationEvents, Vec<f32>> {
pub fn load_sound_effects(
overrides: &[SoundEffect],
num_channels: usize,
) -> HashMap<NotificationEvents, Vec<f32>> {
let overrides: HashMap<_, _> = overrides
.iter()
.filter_map(|sound_effect| {
Expand Down
16 changes: 13 additions & 3 deletions mum/src/audio/transformers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
pub trait Transformer {
/// Do the transform. Returning `None` is interpreted as "the buffer is unwanted".
/// The implementor is free to modify the buffer however it wants to.
fn transform<'a>(&mut self, buf: (opus::Channels, &'a mut [f32])) -> Option<(opus::Channels, &'a mut [f32])>;
fn transform<'a>(
&mut self,
buf: (opus::Channels, &'a mut [f32]),
) -> Option<(opus::Channels, &'a mut [f32])>;
}

/// A struct representing a noise gate transform.
Expand All @@ -26,10 +29,17 @@ impl NoiseGate {
}

impl Transformer for NoiseGate {
fn transform<'a>(&mut self, (channels, buf): (opus::Channels, &'a mut [f32])) -> Option<(opus::Channels, &'a mut [f32])> {
fn transform<'a>(
&mut self,
(channels, buf): (opus::Channels, &'a mut [f32]),
) -> Option<(opus::Channels, &'a mut [f32])> {
const MUTE_PERCENTAGE: f32 = 0.1;

let max = buf.iter().map(|e| e.abs()).max_by(|a, b| a.partial_cmp(b).unwrap()).unwrap();
let max = buf
.iter()
.map(|e| e.abs())
.max_by(|a, b| a.partial_cmp(b).unwrap())
.unwrap();

if max > self.alltime_high {
self.alltime_high = max;
Expand Down
8 changes: 7 additions & 1 deletion mum/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@ use crate::state::{ExecutionContext, State};
use log::*;
use mumble_protocol::{control::ControlPacket, Serverbound};
use mumlib::command::{Command, CommandResponse};
use std::{rc::Rc, sync::{Arc, RwLock, atomic::{AtomicBool, AtomicU64, Ordering}}};
use std::{
rc::Rc,
sync::{
atomic::{AtomicBool, AtomicU64, Ordering},
Arc, RwLock,
},
};
use tokio::sync::{mpsc, watch};

pub async fn handle(
Expand Down
Loading

0 comments on commit 719bb19

Please sign in to comment.