diff options
| author | Eskil <eskilq@kth.se> | 2020-11-06 22:00:24 +0100 |
|---|---|---|
| committer | Eskil <eskilq@kth.se> | 2020-11-06 22:00:24 +0100 |
| commit | 1b3bcebc895bfa4b6f65697fafc31d482c74b2de (patch) | |
| tree | 8f3e8fa198747aa260128951eccd54994ca1fdb5 /mumd/src | |
| parent | d6496cb0f6abba855b04338fa8bc5aaa89487c29 (diff) | |
| parent | 0220f0372937ed179aa84fa6e2250933cd3e3896 (diff) | |
| download | mum-1b3bcebc895bfa4b6f65697fafc31d482c74b2de.tar.gz | |
Merge branch 'mute' into 'main'
Mute
Closes #43
See merge request gustav/mum!29
Diffstat (limited to 'mumd/src')
| -rw-r--r-- | mumd/src/audio.rs | 28 | ||||
| -rw-r--r-- | mumd/src/audio/output.rs | 16 | ||||
| -rw-r--r-- | mumd/src/state.rs | 99 | ||||
| -rw-r--r-- | mumd/src/state/server.rs | 20 | ||||
| -rw-r--r-- | mumd/src/state/user.rs | 8 |
5 files changed, 159 insertions, 12 deletions
diff --git a/mumd/src/audio.rs b/mumd/src/audio.rs index 9f837f7..05e3ff5 100644 --- a/mumd/src/audio.rs +++ b/mumd/src/audio.rs @@ -21,13 +21,13 @@ pub struct Audio { output_volume_sender: watch::Sender<f32>, - user_volumes: Arc<Mutex<HashMap<u32, f32>>>, + user_volumes: Arc<Mutex<HashMap<u32, (f32, bool)>>>, client_streams: Arc<Mutex<HashMap<u32, output::ClientStream>>>, } impl Audio { - pub fn new() -> Self { + pub fn new(input_volume: f32, output_volume: f32) -> Self { let sample_rate = SampleRate(48000); let host = cpal::default_host(); @@ -70,7 +70,7 @@ impl Audio { let err_fn = |err| error!("An error occurred on the output audio stream: {}", err); let user_volumes = Arc::new(Mutex::new(HashMap::new())); - let (output_volume_sender, output_volume_receiver) = watch::channel::<f32>(1.0); + let (output_volume_sender, output_volume_receiver) = watch::channel::<f32>(output_volume); let client_streams = Arc::new(Mutex::new(HashMap::new())); let output_stream = match output_supported_sample_format { @@ -119,7 +119,7 @@ impl Audio { .unwrap(); let (input_sender, input_receiver) = mpsc::channel(100); - let (input_volume_sender, input_volume_receiver) = watch::channel::<f32>(1.0); + 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( @@ -230,6 +230,24 @@ impl Audio { } pub fn set_user_volume(&self, id: u32, volume: f32) { - self.user_volumes.lock().unwrap().insert(id, volume); + match self.user_volumes.lock().unwrap().entry(id) { + Entry::Occupied(mut entry) => { + entry.get_mut().0 = volume; + } + Entry::Vacant(entry) => { + entry.insert((volume, false)); + } + } + } + + pub fn set_mute(&self, id: u32, mute: bool) { + match self.user_volumes.lock().unwrap().entry(id) { + Entry::Occupied(mut entry) => { + entry.get_mut().1 = mute; + } + Entry::Vacant(entry) => { + entry.insert((1.0, mute)); + } + } } } diff --git a/mumd/src/audio/output.rs b/mumd/src/audio/output.rs index 56da596..ce116a8 100644 --- a/mumd/src/audio/output.rs +++ b/mumd/src/audio/output.rs @@ -74,7 +74,7 @@ impl SaturatingAdd for u16 { pub fn curry_callback<T: Sample + AddAssign + SaturatingAdd>( buf: Arc<Mutex<HashMap<u32, ClientStream>>>, output_volume_receiver: watch::Receiver<f32>, - user_volumes: Arc<Mutex<HashMap<u32, f32>>>, + user_volumes: Arc<Mutex<HashMap<u32, (f32, bool)>>>, ) -> impl FnMut(&mut [T], &OutputCallbackInfo) + Send + 'static { move |data: &mut [T], _info: &OutputCallbackInfo| { for sample in data.iter_mut() { @@ -85,11 +85,17 @@ pub fn curry_callback<T: Sample + AddAssign + SaturatingAdd>( let mut lock = buf.lock().unwrap(); for (id, client_stream) in &mut *lock { - let user_volume = user_volumes.lock().unwrap().get(id).cloned().unwrap_or(1.0); + let (user_volume, muted) = user_volumes + .lock() + .unwrap() + .get(id) + .cloned() + .unwrap_or((1.0, false)); for sample in data.iter_mut() { - *sample = sample.saturating_add(Sample::from( - &(client_stream.buffer.pop_front().unwrap_or(0.0) * volume * user_volume), - )); + let s = client_stream.buffer.pop_front().unwrap_or(0.0) * volume * user_volume; + if !muted { + *sample = sample.saturating_add(Sample::from(&s)); + } } } } diff --git a/mumd/src/state.rs b/mumd/src/state.rs index 56ce030..a767d30 100644 --- a/mumd/src/state.rs +++ b/mumd/src/state.rs @@ -68,9 +68,13 @@ impl State { packet_sender: mpsc::UnboundedSender<ControlPacket<Serverbound>>, connection_info_sender: watch::Sender<Option<ConnectionInfo>>, ) -> Self { - let audio = Audio::new(); + let config = mumlib::config::read_default_cfg(); + let audio = Audio::new( + config.audio.input_volume.unwrap_or(1.0), + config.audio.output_volume.unwrap_or(1.0), + ); let mut state = Self { - config: mumlib::config::read_default_cfg(), + config, server: None, audio, packet_sender, @@ -229,6 +233,97 @@ impl State { self.audio.set_output_volume(volume); now!(Ok(None)) } + Command::DeafenSelf(toggle) => { + if !matches!(*self.phase_receiver().borrow(), StatePhase::Connected) { + return now!(Err(Error::DisconnectedError)); + } + + let action = match toggle { + Some(state) => { + if self.server().unwrap().deafened() != state { + Some(state) + } else { + None + } + } + None => Some(!self.server().unwrap().deafened()), + }; + + if let Some(action) = action { + if action { + self.server_mut().unwrap().set_muted(true); + } + let mut msg = msgs::UserState::new(); + msg.set_self_deaf(action); + self.packet_sender.send(msg.into()).unwrap(); + self.server_mut().unwrap().set_deafened(action); + } + + now!(Ok(None)) + } + Command::MuteSelf(toggle) => { + if !matches!(*self.phase_receiver().borrow(), StatePhase::Connected) { + return now!(Err(Error::DisconnectedError)); + } + + let action = match toggle { + Some(state) => { + if self.server().unwrap().muted() != state { + Some(state) + } else { + None + } + } + None => Some(!self.server().unwrap().muted()), + }; + + if let Some(action) = action { + if !action { + self.server_mut().unwrap().set_deafened(false); + } + let mut msg = msgs::UserState::new(); + msg.set_self_mute(action); + self.packet_sender.send(msg.into()).unwrap(); + self.server_mut().unwrap().set_muted(action); + } + + now!(Ok(None)) + } + Command::MuteOther(string, toggle) => { + if !matches!(*self.phase_receiver().borrow(), StatePhase::Connected) { + return now!(Err(Error::DisconnectedError)); + } + + let id = self + .server_mut() + .unwrap() + .users_mut() + .iter_mut() + .find(|(_, user)| user.name() == &string); + + let (id, user) = match id { + Some(id) => (*id.0, id.1), + None => return now!(Err(Error::InvalidUsernameError(string))), + }; + + let action = match toggle { + Some(state) => { + if user.suppressed() != state { + Some(state) + } else { + None + } + } + None => Some(!user.suppressed()), + }; + + if let Some(action) = action { + user.set_suppressed(action); + self.audio.set_mute(id, action); + } + + return now!(Ok(None)); + } Command::UserVolumeSet(string, volume) => { if !matches!(*self.phase_receiver().borrow(), StatePhase::Connected) { return now!(Err(Error::DisconnectedError)); diff --git a/mumd/src/state/server.rs b/mumd/src/state/server.rs index b99c7e6..a065df0 100644 --- a/mumd/src/state/server.rs +++ b/mumd/src/state/server.rs @@ -15,6 +15,8 @@ pub struct Server { username: Option<String>, session_id: Option<u32>, + muted: bool, + deafened: bool, host: Option<String>, } @@ -27,6 +29,8 @@ impl Server { welcome_text: None, username: None, session_id: None, + muted: false, + deafened: false, host: None, } } @@ -109,6 +113,22 @@ impl Server { pub fn username_mut(&mut self) -> &mut Option<String> { &mut self.username } + + pub fn muted(&self) -> bool { + self.muted + } + + pub fn deafened(&self) -> bool { + self.deafened + } + + pub fn set_muted(&mut self, value: bool) { + self.muted = value; + } + + pub fn set_deafened(&mut self, value: bool) { + self.deafened = value; + } } impl From<&Server> for mumlib::state::Server { diff --git a/mumd/src/state/user.rs b/mumd/src/state/user.rs index 848208c..913f91b 100644 --- a/mumd/src/state/user.rs +++ b/mumd/src/state/user.rs @@ -129,6 +129,14 @@ impl User { pub fn self_deaf(&self) -> bool { self.self_deaf } + + pub fn suppressed(&self) -> bool { + self.suppress + } + + pub fn set_suppressed(&mut self, value: bool) { + self.suppress = value; + } } impl From<&User> for mumlib::state::User { |
