From 89944f0f56935dfd4c3adca6ff8f1fd52212ee03 Mon Sep 17 00:00:00 2001 From: Eskil Queseth Date: Fri, 13 Nov 2020 23:37:54 +0100 Subject: add mvp for playing sound when stuff happens --- Cargo.lock | 157 +++++++++++++++++++++++++++++++++++++++++++---- mumd/Cargo.toml | 2 + mumd/src/audio.rs | 63 ++++++++++++++++++- mumd/src/audio/output.rs | 14 +++-- mumd/src/state.rs | 4 +- 5 files changed, 221 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 806bc91..00f5586 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,14 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +[[package]] +name = "aho-corasick" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5" +dependencies = [ + "memchr", +] + [[package]] name = "alsa" version = "0.4.2" @@ -72,9 +81,32 @@ dependencies = [ [[package]] name = "bindgen" -version = "0.53.3" +version = "0.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c72a978d268b1d70b0e963217e60fdabd9523a941457a6c42a7315d15c7e89e5" +checksum = "ebd71393f1ec0509b553aa012b9b58e81dadbdff7130bd3b8cba576e69b32f75" +dependencies = [ + "bitflags", + "cexpr", + "cfg-if", + "clang-sys", + "clap", + "env_logger", + "lazy_static", + "log", + "peeking_take_while", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "which", +] + +[[package]] +name = "bindgen" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99de13bb6361e01e493b3db7928085dcc474b7ba4f5481818e53a89d76b8393f" dependencies = [ "bitflags", "cexpr", @@ -122,9 +154,9 @@ checksum = "ed67cbde08356238e75fc4656be4749481eeffb09e19f320a25237d5221c985d" [[package]] name = "cexpr" -version = "0.4.0" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27" +checksum = "fce5b5fb86b0c57c20c834c1b412fd09c77c8a59b9473f86272709e78874cd1d" dependencies = [ "nom", ] @@ -150,9 +182,9 @@ dependencies = [ [[package]] name = "clang-sys" -version = "0.29.3" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe6837df1d5cba2397b835c8530f51723267e16abbf83892e9e5af4f0e5dd10a" +checksum = "81de550971c976f176130da4b2978d3b524eaa0fd9ac31f3ceb5ae1231fb4853" dependencies = [ "glob", "libc", @@ -184,6 +216,15 @@ dependencies = [ "bitflags", ] +[[package]] +name = "cmake" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e56268c17a6248366d66d4a47a3381369d068cce8409bb1716ed77ea32163bb" +dependencies = [ + "cc", +] + [[package]] name = "colored" version = "2.0.0" @@ -233,7 +274,7 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6570ee6e089131e928d5ec9236db9e818aa3cf850f48b0eec6ef700571271d4" dependencies = [ - "bindgen", + "bindgen 0.53.1", ] [[package]] @@ -277,6 +318,19 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "env_logger" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + [[package]] name = "fern" version = "0.5.9" @@ -521,6 +575,21 @@ dependencies = [ "libc", ] +[[package]] +name = "hound" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a164bb2ceaeff4f42542bdb847c41517c78a60f5649671b2a07312b6e117549" + +[[package]] +name = "humantime" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" +dependencies = [ + "quick-error", +] + [[package]] name = "iovec" version = "0.1.4" @@ -623,6 +692,16 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "libsamplerate-sys" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66575d1d489214f8767f90de2b1e115626d8277ca09d7c39549652a9602309eb" +dependencies = [ + "bindgen 0.51.1", + "cmake", +] + [[package]] name = "lock_api" version = "0.3.4" @@ -760,6 +839,7 @@ dependencies = [ "cpal", "futures", "futures-util", + "hound", "ipc-channel", "libnotify", "log", @@ -768,6 +848,7 @@ dependencies = [ "native-tls", "openssl", "opus", + "samplerate", "serde", "tokio", "tokio-tls", @@ -830,9 +911,9 @@ dependencies = [ [[package]] name = "nom" -version = "5.1.2" +version = "4.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af" +checksum = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" dependencies = [ "memchr", "version_check", @@ -1048,6 +1129,12 @@ dependencies = [ "protobuf-codegen", ] +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + [[package]] name = "quote" version = "1.0.7" @@ -1110,7 +1197,10 @@ version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8963b85b8ce3074fecffde43b4b0dded83ce2f367dc8d363afc56679f3ee820b" dependencies = [ + "aho-corasick", + "memchr", "regex-syntax", + "thread_local", ] [[package]] @@ -1143,6 +1233,15 @@ dependencies = [ "semver", ] +[[package]] +name = "samplerate" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6913e9f2ad7d0aa9528523f7e4385e160d690c66d43bb8bd7559f1be705aee8" +dependencies = [ + "libsamplerate-sys", +] + [[package]] name = "schannel" version = "0.1.19" @@ -1297,6 +1396,15 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "termcolor" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f" +dependencies = [ + "winapi-util", +] + [[package]] name = "textwrap" version = "0.11.0" @@ -1326,6 +1434,15 @@ dependencies = [ "syn", ] +[[package]] +name = "thread_local" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" +dependencies = [ + "lazy_static", +] + [[package]] name = "time" version = "0.1.44" @@ -1440,9 +1557,9 @@ checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "version_check" -version = "0.9.2" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" +checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" [[package]] name = "void" @@ -1526,6 +1643,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "which" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724" +dependencies = [ + "libc", +] + [[package]] name = "winapi" version = "0.2.8" @@ -1554,6 +1680,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi 0.3.9", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" diff --git a/mumd/Cargo.toml b/mumd/Cargo.toml index 3dfc82c..a7a5ef8 100644 --- a/mumd/Cargo.toml +++ b/mumd/Cargo.toml @@ -29,6 +29,8 @@ serde = { version = "1.0", features = ["derive"] } tokio = { version = "0.2", features = ["full"] } tokio-tls = "0.3" tokio-util = { version = "0.3", features = ["codec", "udp"] } +hound = "3.4.0" +samplerate = "0.2.2" libnotify = { version = "1.0", optional = true } diff --git a/mumd/src/audio.rs b/mumd/src/audio.rs index 05e3ff5..65da656 100644 --- a/mumd/src/audio.rs +++ b/mumd/src/audio.rs @@ -7,9 +7,25 @@ use log::*; use mumble_protocol::voice::VoicePacketPayload; use opus::Channels; use std::collections::hash_map::Entry; -use std::collections::HashMap; +use std::collections::{HashMap, VecDeque}; use std::sync::{Arc, Mutex}; use tokio::sync::{mpsc, watch}; +use samplerate::ConverterType; +use crate::audio::output::SaturatingAdd; + +//TODO? move to mumlib +pub const EVENT_SOUNDS: &[(&str, NotificationEvents)] = &[ + ("resources/connect.wav", NotificationEvents::ServerConnect), + ("resources/disconnect.wav", NotificationEvents::ServerDisconnect), +]; + +const SAMPLE_RATE: u32 = 48000; + +#[derive(Debug, Eq, PartialEq, Clone, Copy, Hash)] +pub enum NotificationEvents { + ServerConnect, + ServerDisconnect, +} pub struct Audio { output_config: StreamConfig, @@ -24,11 +40,15 @@ pub struct Audio { user_volumes: Arc>>, client_streams: Arc>>, + + sounds: HashMap>, + + play_sounds: Arc>>, } impl Audio { pub fn new(input_volume: f32, output_volume: f32) -> Self { - let sample_rate = SampleRate(48000); + let sample_rate = SampleRate(SAMPLE_RATE); let host = cpal::default_host(); let output_device = host @@ -71,12 +91,14 @@ impl Audio { let user_volumes = Arc::new(Mutex::new(HashMap::new())); let (output_volume_sender, output_volume_receiver) = watch::channel::(output_volume); + let play_sounds = Arc::new(Mutex::new(VecDeque::new())); let client_streams = Arc::new(Mutex::new(HashMap::new())); let output_stream = match output_supported_sample_format { SampleFormat::F32 => output_device.build_output_stream( &output_config, output::curry_callback::( + Arc::clone(&play_sounds), Arc::clone(&client_streams), output_volume_receiver, Arc::clone(&user_volumes), @@ -86,6 +108,7 @@ impl Audio { SampleFormat::I16 => output_device.build_output_stream( &output_config, output::curry_callback::( + Arc::clone(&play_sounds), Arc::clone(&client_streams), output_volume_receiver, Arc::clone(&user_volumes), @@ -95,6 +118,7 @@ impl Audio { SampleFormat::U16 => output_device.build_output_stream( &output_config, output::curry_callback::( + Arc::clone(&play_sounds), Arc::clone(&client_streams), output_volume_receiver, Arc::clone(&user_volumes), @@ -160,6 +184,26 @@ impl Audio { output_stream.play().unwrap(); + let sounds = EVENT_SOUNDS.iter() + .map(|(path, event)| { + let reader = hound::WavReader::open(path).unwrap(); + let spec = reader.spec(); + debug!("{:?}", spec); + let samples = match spec.sample_format { + hound::SampleFormat::Float => reader.into_samples::().map(|e| e.unwrap()).collect::>(), + hound::SampleFormat::Int => reader.into_samples::().map(|e| cpal::Sample::to_f32(&e.unwrap())).collect::>(), + }; + let samples = samplerate::convert( + spec.sample_rate, + SAMPLE_RATE, + spec.channels as usize, + ConverterType::SincBestQuality, + &samples) + .unwrap(); + (*event, samples) + }) + .collect(); + Self { output_config, _output_stream: output_stream, @@ -167,8 +211,10 @@ impl Audio { input_volume_sender, input_channel_receiver: Some(input_receiver), client_streams, + sounds, output_volume_sender, user_volumes, + play_sounds, } } @@ -250,4 +296,17 @@ impl Audio { } } } + + pub fn play_effect(&mut self, effect: NotificationEvents) { + let samples = self.sounds.get(&effect).unwrap(); + + let mut play_sounds = self.play_sounds.lock().unwrap(); + + for (val, e) in play_sounds.iter_mut().zip(samples.iter()) { + *val = val.saturating_add(*e); + } + + let l = play_sounds.len(); + play_sounds.extend(samples.iter().skip(l)); + } } diff --git a/mumd/src/audio/output.rs b/mumd/src/audio/output.rs index ce116a8..2b58d5b 100644 --- a/mumd/src/audio/output.rs +++ b/mumd/src/audio/output.rs @@ -71,8 +71,9 @@ impl SaturatingAdd for u16 { } } -pub fn curry_callback( - buf: Arc>>, +pub fn curry_callback( + effect_sound: Arc>>, + user_bufs: Arc>>, output_volume_receiver: watch::Receiver, user_volumes: Arc>>, ) -> impl FnMut(&mut [T], &OutputCallbackInfo) + Send + 'static { @@ -83,8 +84,9 @@ pub fn curry_callback( let volume = *output_volume_receiver.borrow(); - let mut lock = buf.lock().unwrap(); - for (id, client_stream) in &mut *lock { + let mut effects_sound = effect_sound.lock().unwrap(); + let mut user_bufs = user_bufs.lock().unwrap(); + for (id, client_stream) in &mut *user_bufs { let (user_volume, muted) = user_volumes .lock() .unwrap() @@ -98,5 +100,9 @@ pub fn curry_callback( } } } + + for sample in data.iter_mut() { + *sample = sample.saturating_add(Sample::from(&(effects_sound.pop_front().unwrap_or(0.0) * volume))); + } } } diff --git a/mumd/src/state.rs b/mumd/src/state.rs index 8fe5e36..2c90b7c 100644 --- a/mumd/src/state.rs +++ b/mumd/src/state.rs @@ -2,7 +2,7 @@ pub mod channel; pub mod server; pub mod user; -use crate::audio::Audio; +use crate::audio::{Audio, NotificationEvents}; use crate::network::ConnectionInfo; use crate::notify; use crate::state::server::Server; @@ -85,7 +85,6 @@ impl State { state } - //TODO? move bool inside Result pub fn handle_command(&mut self, command: Command) -> ExecutionContext { match command { Command::ChannelJoin { channel_identifier } => { @@ -423,6 +422,7 @@ impl State { &msg.get_name(), channel.name() )); + self.audio.play_effect(NotificationEvents::ServerConnect); } } } -- cgit v1.2.1 From 7391abb102cd9724e0cc2d843ccbcaa3b74a42c7 Mon Sep 17 00:00:00 2001 From: Eskil Queseth Date: Fri, 13 Nov 2020 23:38:23 +0100 Subject: add sound files --- resources/connect.wav | Bin 0 -> 32002 bytes resources/disconnect.wav | Bin 0 -> 303364 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 resources/connect.wav create mode 100644 resources/disconnect.wav diff --git a/resources/connect.wav b/resources/connect.wav new file mode 100644 index 0000000..82ee4d4 Binary files /dev/null and b/resources/connect.wav differ diff --git a/resources/disconnect.wav b/resources/disconnect.wav new file mode 100644 index 0000000..fb2ca76 Binary files /dev/null and b/resources/disconnect.wav differ -- cgit v1.2.1 From 8b942cffeb81dbf068dbe7c76584bf68e74e7f17 Mon Sep 17 00:00:00 2001 From: Eskil Queseth Date: Sun, 15 Nov 2020 00:32:20 +0100 Subject: refactor of parsing user state --- mumd/src/audio.rs | 1 - mumd/src/network/tcp.rs | 8 +--- mumd/src/state.rs | 102 +++++++++++++++++++++++++----------------------- 3 files changed, 54 insertions(+), 57 deletions(-) diff --git a/mumd/src/audio.rs b/mumd/src/audio.rs index 65da656..53ec2d4 100644 --- a/mumd/src/audio.rs +++ b/mumd/src/audio.rs @@ -188,7 +188,6 @@ impl Audio { .map(|(path, event)| { let reader = hound::WavReader::open(path).unwrap(); let spec = reader.spec(); - debug!("{:?}", spec); let samples = match spec.sample_format { hound::SampleFormat::Float => reader.into_samples::().map(|e| e.unwrap()).collect::>(), hound::SampleFormat::Int => reader.into_samples::().map(|e| cpal::Sample::to_f32(&e.unwrap())).collect::>(), diff --git a/mumd/src/network/tcp.rs b/mumd/src/network/tcp.rs index 131f066..2a0d01e 100644 --- a/mumd/src/network/tcp.rs +++ b/mumd/src/network/tcp.rs @@ -247,13 +247,7 @@ async fn listen( warn!("Login rejected: {:?}", msg); } ControlPacket::UserState(msg) => { - let mut state = state.lock().unwrap(); - if *state.phase_receiver().borrow() == StatePhase::Connecting { - state.audio_mut().add_client(msg.get_session()); - state.parse_user_state(*msg); - } else { - state.parse_user_state(*msg); - } + state.lock().unwrap().parse_user_state(*msg); } ControlPacket::UserRemove(msg) => { state.lock().unwrap().remove_client(*msg); diff --git a/mumd/src/state.rs b/mumd/src/state.rs index 2c90b7c..e7c16ec 100644 --- a/mumd/src/state.rs +++ b/mumd/src/state.rs @@ -384,25 +384,29 @@ impl State { } } - pub fn parse_user_state(&mut self, msg: msgs::UserState) -> Option { + pub fn parse_user_state(&mut self, msg: msgs::UserState) { if !msg.has_session() { warn!("Can't parse user state without session"); - return None; + return; } let session = msg.get_session(); // check if this is initial state if !self.server().unwrap().users().contains_key(&session) { - self.parse_initial_user_state(session, msg); - None + self.create_user(msg); } else { - Some(self.parse_updated_user_state(session, msg)) + self.update_user(msg); } } - fn parse_initial_user_state(&mut self, session: u32, msg: msgs::UserState) { + fn create_user(&mut self, msg: msgs::UserState) { if !msg.has_name() { warn!("Missing name in initial user state"); - } else if msg.get_name() == self.server().unwrap().username().unwrap() { + return; + } + + let session = msg.get_session(); + + if msg.get_name() == self.server().unwrap().username().unwrap() { // this is us *self.server_mut().unwrap().session_id_mut() = Some(session); } else { @@ -411,31 +415,28 @@ impl State { // send notification only if we've passed the connecting phase if *self.phase_receiver().borrow() == StatePhase::Connected { - let channel_id = if msg.has_channel_id() { - msg.get_channel_id() - } else { - 0 - }; + let channel_id = msg.get_channel_id(); if let Some(channel) = self.server().unwrap().channels().get(&channel_id) { notify::send(format!( "{} connected and joined {}", &msg.get_name(), channel.name() )); - self.audio.play_effect(NotificationEvents::ServerConnect); } } } + self.server_mut() .unwrap() .users_mut() .insert(session, user::User::new(msg)); } - fn parse_updated_user_state(&mut self, session: u32, msg: msgs::UserState) -> UserDiff { - let user = self - .server_mut() - .unwrap() + fn update_user(&mut self, msg: msgs::UserState) { + let session = msg.get_session(); + let server = self.server_mut().unwrap(); + + let user = server .users_mut() .get_mut(&session) .unwrap(); @@ -453,40 +454,42 @@ impl State { let diff = UserDiff::from(msg); user.apply_user_diff(&diff); - let user = self.server().unwrap().users().get(&session).unwrap(); - - // send notification if the user moved to or from any channel - //TODO our channel only - if let Some(channel_id) = diff.channel_id { - if let Some(channel) = self.server().unwrap().channels().get(&channel_id) { - notify::send(format!( - "{} moved to channel {}", - &user.name(), - channel.name() - )); - } else { - warn!("{} moved to invalid channel {}", &user.name(), channel_id); + + let user = server + .users() + .get(&session) + .unwrap(); + + if Some(session) != server.session_id() { + //send notification if the user moved to or from any channel + if let Some(channel_id) = diff.channel_id { + if let Some(channel) = server.channels().get(&channel_id) { + notify::send(format!( + "{} moved to channel {}", + user.name(), + channel.name() + )); + } else { + warn!("{} moved to invalid channel {}", user.name(), channel_id); + } } - } - // send notification if a user muted/unmuted - //TODO our channel only - let notify_desc = match (mute, deaf) { - (Some(true), Some(true)) => Some(format!("{} muted and deafend themselves", &user.name())), - (Some(false), Some(false)) => Some(format!("{} unmuted and undeafend themselves", &user.name())), - (None, Some(true)) => Some(format!("{} deafend themselves", &user.name())), - (None, Some(false)) => Some(format!("{} undeafend themselves", &user.name())), - (Some(true), None) => Some(format!("{} muted themselves", &user.name())), - (Some(false), None) => Some(format!("{} unmuted themselves", &user.name())), - (Some(true), Some(false)) => Some(format!("{} muted and undeafened themselves", &user.name())), - (Some(false), Some(true)) => Some(format!("{} unmuted and deafened themselves", &user.name())), - (None, None) => None, - }; - if let Some(notify_desc) = notify_desc { - notify::send(notify_desc); + //send notification if a user muted/unmuted + let notify_desc = match (mute, deaf) { + (Some(true), Some(true)) => Some(format!("{} muted and deafend themselves", &user.name())), + (Some(false), Some(false)) => Some(format!("{} unmuted and undeafend themselves", &user.name())), + (None, Some(true)) => Some(format!("{} deafend themselves", &user.name())), + (None, Some(false)) => Some(format!("{} undeafend themselves", &user.name())), + (Some(true), None) => Some(format!("{} muted themselves", &user.name())), + (Some(false), None) => Some(format!("{} unmuted themselves", &user.name())), + (Some(true), Some(false)) => Some(format!("{} muted and undeafened themselves", &user.name())), + (Some(false), Some(true)) => Some(format!("{} unmuted and deafened themselves", &user.name())), + (None, None) => None, + }; + if let Some(notify_desc) = notify_desc { + notify::send(notify_desc); + } } - - diff } pub fn remove_client(&mut self, msg: msgs::UserRemove) { @@ -516,11 +519,12 @@ impl State { } } - pub fn initialized(&self) { + pub fn initialized(&mut self) { self.phase_watcher .0 .broadcast(StatePhase::Connected) .unwrap(); + self.audio.play_effect(NotificationEvents::ServerConnect); } pub fn audio(&self) -> &Audio { -- cgit v1.2.1 From c3fabb1f9224cdf8fd68ad186baeffc93c96ce5c Mon Sep 17 00:00:00 2001 From: Eskil Queseth Date: Mon, 16 Nov 2020 02:02:46 +0100 Subject: add sound on users moving --- mumd/src/audio.rs | 10 ++++++- mumd/src/state.rs | 64 +++++++++++++++++++++++++++++--------------- resources/channel_join.wav | Bin 0 -> 32002 bytes resources/channel_leave.wav | Bin 0 -> 32002 bytes 4 files changed, 52 insertions(+), 22 deletions(-) create mode 100644 resources/channel_join.wav create mode 100644 resources/channel_leave.wav diff --git a/mumd/src/audio.rs b/mumd/src/audio.rs index 53ec2d4..d1ef106 100644 --- a/mumd/src/audio.rs +++ b/mumd/src/audio.rs @@ -17,6 +17,10 @@ use crate::audio::output::SaturatingAdd; pub const EVENT_SOUNDS: &[(&str, NotificationEvents)] = &[ ("resources/connect.wav", NotificationEvents::ServerConnect), ("resources/disconnect.wav", NotificationEvents::ServerDisconnect), + ("resources/channel_join.wav", NotificationEvents::UserConnected), + ("resources/channel_leave.wav", NotificationEvents::UserDisconnected), + ("resources/channel_join.wav", NotificationEvents::UserJoinedChannel), + ("resources/channel_leave.wav", NotificationEvents::UserLeftChannel), ]; const SAMPLE_RATE: u32 = 48000; @@ -25,6 +29,10 @@ const SAMPLE_RATE: u32 = 48000; pub enum NotificationEvents { ServerConnect, ServerDisconnect, + UserConnected, + UserDisconnected, + UserJoinedChannel, + UserLeftChannel, } pub struct Audio { @@ -296,7 +304,7 @@ impl Audio { } } - pub fn play_effect(&mut self, effect: NotificationEvents) { + pub fn play_effect(&self, effect: NotificationEvents) { let samples = self.sounds.get(&effect).unwrap(); let mut play_sounds = self.play_sounds.lock().unwrap(); diff --git a/mumd/src/state.rs b/mumd/src/state.rs index e7c16ec..69bf4df 100644 --- a/mumd/src/state.rs +++ b/mumd/src/state.rs @@ -218,6 +218,7 @@ impl State { .0 .broadcast(StatePhase::Disconnected) .unwrap(); + self.audio.play_effect(NotificationEvents::ServerDisconnect); now!(Ok(None)) } Command::ConfigReload => { @@ -416,12 +417,17 @@ impl State { // send notification only if we've passed the connecting phase if *self.phase_receiver().borrow() == StatePhase::Connected { let channel_id = msg.get_channel_id(); - if let Some(channel) = self.server().unwrap().channels().get(&channel_id) { - notify::send(format!( - "{} connected and joined {}", - &msg.get_name(), - channel.name() - )); + + if channel_id == self.get_users_channel(self.server().unwrap().session_id().unwrap()) { + if let Some(channel) = self.server().unwrap().channels().get(&channel_id) { + notify::send(format!( + "{} connected and joined {}", + &msg.get_name(), + channel.name() + )); + } + + self.audio.play_effect(NotificationEvents::UserConnected); } } } @@ -434,9 +440,11 @@ impl State { fn update_user(&mut self, msg: msgs::UserState) { let session = msg.get_session(); - let server = self.server_mut().unwrap(); - let user = server + let from_channel = self.get_users_channel(session); + + let user = self.server_mut() + .unwrap() .users_mut() .get_mut(&session) .unwrap(); @@ -455,22 +463,27 @@ impl State { let diff = UserDiff::from(msg); user.apply_user_diff(&diff); - let user = server + let user = self.server() + .unwrap() .users() .get(&session) .unwrap(); - if Some(session) != server.session_id() { + if Some(session) != self.server().unwrap().session_id() { //send notification if the user moved to or from any channel - if let Some(channel_id) = diff.channel_id { - if let Some(channel) = server.channels().get(&channel_id) { - notify::send(format!( - "{} moved to channel {}", - user.name(), - channel.name() - )); - } else { - warn!("{} moved to invalid channel {}", user.name(), channel_id); + if let Some(to_channel) = diff.channel_id { + let this_channel = self.get_users_channel(self.server().unwrap().session_id().unwrap()); + if from_channel == this_channel || to_channel == this_channel { + if let Some(channel) = self.server().unwrap().channels().get(&to_channel) { + notify::send(format!( + "{} moved to channel {}", + user.name(), + channel.name() + )); + } else { + warn!("{} moved to invalid channel {}", user.name(), to_channel); + } + self.audio.play_effect(if from_channel == this_channel { NotificationEvents::UserJoinedChannel } else { NotificationEvents::UserLeftChannel }); } } @@ -497,8 +510,14 @@ impl State { warn!("Tried to remove user state without session"); return; } - if let Some(user) = self.server().unwrap().users().get(&msg.get_session()) { - notify::send(format!("{} disconnected", &user.name())); + + let this_channel = self.get_users_channel(self.server().unwrap().session_id().unwrap()); + let other_channel = self.get_users_channel(msg.get_session()); + if this_channel == other_channel { + self.audio.play_effect(NotificationEvents::UserDisconnected); + if let Some(user) = self.server().unwrap().users().get(&msg.get_session()) { + notify::send(format!("{} disconnected", &user.name())); + } } self.audio().remove_client(msg.get_session()); @@ -548,4 +567,7 @@ impl State { pub fn username(&self) -> Option<&str> { self.server.as_ref().map(|e| e.username()).flatten() } + fn get_users_channel(&self, user_id: u32) -> u32 { + self.server().unwrap().users().iter().find(|e| *e.0 == user_id).unwrap().1.channel() + } } diff --git a/resources/channel_join.wav b/resources/channel_join.wav new file mode 100644 index 0000000..82ee4d4 Binary files /dev/null and b/resources/channel_join.wav differ diff --git a/resources/channel_leave.wav b/resources/channel_leave.wav new file mode 100644 index 0000000..82ee4d4 Binary files /dev/null and b/resources/channel_leave.wav differ -- cgit v1.2.1 From 1bf223de5aca7d39347efa468558e14c02fe8d6a Mon Sep 17 00:00:00 2001 From: Eskil Queseth Date: Mon, 16 Nov 2020 02:13:25 +0100 Subject: add sound for muting and unmuting self --- mumd/src/audio.rs | 8 ++++++++ mumd/src/state.rs | 10 ++++++++-- resources/deafen.wav | Bin 0 -> 32002 bytes resources/mute.wav | Bin 0 -> 32002 bytes resources/undeafen.wav | Bin 0 -> 32002 bytes resources/unmute.wav | Bin 0 -> 32002 bytes 6 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 resources/deafen.wav create mode 100644 resources/mute.wav create mode 100644 resources/undeafen.wav create mode 100644 resources/unmute.wav diff --git a/mumd/src/audio.rs b/mumd/src/audio.rs index d1ef106..7f6dd51 100644 --- a/mumd/src/audio.rs +++ b/mumd/src/audio.rs @@ -21,6 +21,10 @@ pub const EVENT_SOUNDS: &[(&str, NotificationEvents)] = &[ ("resources/channel_leave.wav", NotificationEvents::UserDisconnected), ("resources/channel_join.wav", NotificationEvents::UserJoinedChannel), ("resources/channel_leave.wav", NotificationEvents::UserLeftChannel), + ("resources/mute.wav", NotificationEvents::Mute), + ("resources/unmute.wav", NotificationEvents::Unmute), + ("resources/deafen.wav", NotificationEvents::Deafen), + ("resources/undeafen.wav", NotificationEvents::Undeafen), ]; const SAMPLE_RATE: u32 = 48000; @@ -33,6 +37,10 @@ pub enum NotificationEvents { UserDisconnected, UserJoinedChannel, UserLeftChannel, + Mute, + Unmute, + Deafen, + Undeafen, } pub struct Audio { diff --git a/mumd/src/state.rs b/mumd/src/state.rs index 69bf4df..d719851 100644 --- a/mumd/src/state.rs +++ b/mumd/src/state.rs @@ -238,7 +238,7 @@ impl State { return now!(Err(Error::DisconnectedError)); } - let server = self.server_mut().unwrap(); + let server = self.server().unwrap(); let action = match (toggle, server.muted(), server.deafened()) { (Some(false), false, false) => None, (Some(false), false, true) => Some((false, false)), @@ -258,12 +258,15 @@ impl State { let mut msg = msgs::UserState::new(); if server.muted() != mute { msg.set_self_mute(mute); + self.audio.play_effect(if mute { NotificationEvents::Mute } else { NotificationEvents::Unmute }); } else if !mute && !deafen && server.deafened() { msg.set_self_mute(false); } if server.deafened() != deafen { msg.set_self_deaf(deafen); + self.audio.play_effect(if deafen { NotificationEvents::Deafen } else { NotificationEvents::Undeafen }); } + let server = self.server_mut().unwrap(); server.set_muted(mute); server.set_deafened(deafen); self.packet_sender.send(msg.into()).unwrap(); @@ -276,7 +279,7 @@ impl State { return now!(Err(Error::DisconnectedError)); } - let server = self.server_mut().unwrap(); + let server = self.server().unwrap(); let action = match (toggle, server.muted(), server.deafened()) { (Some(false), false, false) => None, (Some(false), false, true) => Some((false, false)), @@ -296,12 +299,15 @@ impl State { let mut msg = msgs::UserState::new(); if server.muted() != mute { msg.set_self_mute(mute); + self.audio.play_effect(if mute { NotificationEvents::Mute } else { NotificationEvents::Unmute }); } else if !mute && !deafen && server.deafened() { msg.set_self_mute(false); } if server.deafened() != deafen { msg.set_self_deaf(deafen); + self.audio.play_effect(if deafen { NotificationEvents::Deafen } else { NotificationEvents::Undeafen }); } + let server = self.server_mut().unwrap(); server.set_muted(mute); server.set_deafened(deafen); self.packet_sender.send(msg.into()).unwrap(); diff --git a/resources/deafen.wav b/resources/deafen.wav new file mode 100644 index 0000000..82ee4d4 Binary files /dev/null and b/resources/deafen.wav differ diff --git a/resources/mute.wav b/resources/mute.wav new file mode 100644 index 0000000..82ee4d4 Binary files /dev/null and b/resources/mute.wav differ diff --git a/resources/undeafen.wav b/resources/undeafen.wav new file mode 100644 index 0000000..82ee4d4 Binary files /dev/null and b/resources/undeafen.wav differ diff --git a/resources/unmute.wav b/resources/unmute.wav new file mode 100644 index 0000000..82ee4d4 Binary files /dev/null and b/resources/unmute.wav differ -- cgit v1.2.1 From f9c1001b540348670feb64675699a7cd4f4401ea Mon Sep 17 00:00:00 2001 From: Eskil Queseth Date: Mon, 16 Nov 2020 02:20:00 +0100 Subject: fix on how sound is played when muting --- mumd/src/state.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/mumd/src/state.rs b/mumd/src/state.rs index d719851..640a839 100644 --- a/mumd/src/state.rs +++ b/mumd/src/state.rs @@ -255,16 +255,19 @@ impl State { }; if let Some((mute, deafen)) = action { + if server.deafened() != deafen { + self.audio.play_effect(if deafen { NotificationEvents::Deafen } else { NotificationEvents::Undeafen }); + } else if server.muted() != mute { + self.audio.play_effect(if mute { NotificationEvents::Mute } else { NotificationEvents::Unmute }); + } let mut msg = msgs::UserState::new(); if server.muted() != mute { msg.set_self_mute(mute); - self.audio.play_effect(if mute { NotificationEvents::Mute } else { NotificationEvents::Unmute }); } else if !mute && !deafen && server.deafened() { msg.set_self_mute(false); } if server.deafened() != deafen { msg.set_self_deaf(deafen); - self.audio.play_effect(if deafen { NotificationEvents::Deafen } else { NotificationEvents::Undeafen }); } let server = self.server_mut().unwrap(); server.set_muted(mute); @@ -296,16 +299,19 @@ impl State { }; if let Some((mute, deafen)) = action { + if server.deafened() != deafen { + self.audio.play_effect(if deafen { NotificationEvents::Deafen } else { NotificationEvents::Undeafen }); + } else if server.muted() != mute { + self.audio.play_effect(if mute { NotificationEvents::Mute } else { NotificationEvents::Unmute }); + } let mut msg = msgs::UserState::new(); if server.muted() != mute { msg.set_self_mute(mute); - self.audio.play_effect(if mute { NotificationEvents::Mute } else { NotificationEvents::Unmute }); } else if !mute && !deafen && server.deafened() { msg.set_self_mute(false); } if server.deafened() != deafen { msg.set_self_deaf(deafen); - self.audio.play_effect(if deafen { NotificationEvents::Deafen } else { NotificationEvents::Undeafen }); } let server = self.server_mut().unwrap(); server.set_muted(mute); -- cgit v1.2.1 From c6cb3fc95bb00e66b66e0638cae8a036073bdeb4 Mon Sep 17 00:00:00 2001 From: Eskil Queseth Date: Mon, 16 Nov 2020 02:22:59 +0100 Subject: remove a mut --- mumd/src/state.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mumd/src/state.rs b/mumd/src/state.rs index 640a839..6bb78c5 100644 --- a/mumd/src/state.rs +++ b/mumd/src/state.rs @@ -550,7 +550,7 @@ impl State { } } - pub fn initialized(&mut self) { + pub fn initialized(&self) { self.phase_watcher .0 .broadcast(StatePhase::Connected) -- cgit v1.2.1 From 3b0d0f7aee5b6d8dc4ab59c1c16315c2c80347b3 Mon Sep 17 00:00:00 2001 From: Eskil Queseth Date: Mon, 16 Nov 2020 02:23:28 +0100 Subject: cargo fmt --- mumd/src/audio.rs | 49 ++++++++++++++++++++++++--------- mumd/src/audio/output.rs | 4 ++- mumd/src/state.rs | 71 ++++++++++++++++++++++++++++++++++++------------ 3 files changed, 92 insertions(+), 32 deletions(-) diff --git a/mumd/src/audio.rs b/mumd/src/audio.rs index 7f6dd51..a51c2f2 100644 --- a/mumd/src/audio.rs +++ b/mumd/src/audio.rs @@ -1,26 +1,41 @@ pub mod input; pub mod output; +use crate::audio::output::SaturatingAdd; use cpal::traits::{DeviceTrait, HostTrait, StreamTrait}; use cpal::{SampleFormat, SampleRate, Stream, StreamConfig}; use log::*; use mumble_protocol::voice::VoicePacketPayload; use opus::Channels; +use samplerate::ConverterType; use std::collections::hash_map::Entry; use std::collections::{HashMap, VecDeque}; use std::sync::{Arc, Mutex}; use tokio::sync::{mpsc, watch}; -use samplerate::ConverterType; -use crate::audio::output::SaturatingAdd; //TODO? move to mumlib pub const EVENT_SOUNDS: &[(&str, NotificationEvents)] = &[ ("resources/connect.wav", NotificationEvents::ServerConnect), - ("resources/disconnect.wav", NotificationEvents::ServerDisconnect), - ("resources/channel_join.wav", NotificationEvents::UserConnected), - ("resources/channel_leave.wav", NotificationEvents::UserDisconnected), - ("resources/channel_join.wav", NotificationEvents::UserJoinedChannel), - ("resources/channel_leave.wav", NotificationEvents::UserLeftChannel), + ( + "resources/disconnect.wav", + NotificationEvents::ServerDisconnect, + ), + ( + "resources/channel_join.wav", + NotificationEvents::UserConnected, + ), + ( + "resources/channel_leave.wav", + NotificationEvents::UserDisconnected, + ), + ( + "resources/channel_join.wav", + NotificationEvents::UserJoinedChannel, + ), + ( + "resources/channel_leave.wav", + NotificationEvents::UserLeftChannel, + ), ("resources/mute.wav", NotificationEvents::Mute), ("resources/unmute.wav", NotificationEvents::Unmute), ("resources/deafen.wav", NotificationEvents::Deafen), @@ -200,21 +215,29 @@ impl Audio { output_stream.play().unwrap(); - let sounds = EVENT_SOUNDS.iter() + let sounds = EVENT_SOUNDS + .iter() .map(|(path, event)| { - let reader = hound::WavReader::open(path).unwrap(); + let reader = hound::WavReader::open(path).unwrap(); let spec = reader.spec(); let samples = match spec.sample_format { - hound::SampleFormat::Float => reader.into_samples::().map(|e| e.unwrap()).collect::>(), - hound::SampleFormat::Int => reader.into_samples::().map(|e| cpal::Sample::to_f32(&e.unwrap())).collect::>(), + hound::SampleFormat::Float => reader + .into_samples::() + .map(|e| e.unwrap()) + .collect::>(), + hound::SampleFormat::Int => reader + .into_samples::() + .map(|e| cpal::Sample::to_f32(&e.unwrap())) + .collect::>(), }; let samples = samplerate::convert( spec.sample_rate, SAMPLE_RATE, spec.channels as usize, ConverterType::SincBestQuality, - &samples) - .unwrap(); + &samples, + ) + .unwrap(); (*event, samples) }) .collect(); diff --git a/mumd/src/audio/output.rs b/mumd/src/audio/output.rs index 2b58d5b..5e0cb8d 100644 --- a/mumd/src/audio/output.rs +++ b/mumd/src/audio/output.rs @@ -102,7 +102,9 @@ pub fn curry_callback } for sample in data.iter_mut() { - *sample = sample.saturating_add(Sample::from(&(effects_sound.pop_front().unwrap_or(0.0) * volume))); + *sample = sample.saturating_add(Sample::from( + &(effects_sound.pop_front().unwrap_or(0.0) * volume), + )); } } } diff --git a/mumd/src/state.rs b/mumd/src/state.rs index 6bb78c5..d3c793e 100644 --- a/mumd/src/state.rs +++ b/mumd/src/state.rs @@ -256,9 +256,17 @@ impl State { if let Some((mute, deafen)) = action { if server.deafened() != deafen { - self.audio.play_effect(if deafen { NotificationEvents::Deafen } else { NotificationEvents::Undeafen }); + self.audio.play_effect(if deafen { + NotificationEvents::Deafen + } else { + NotificationEvents::Undeafen + }); } else if server.muted() != mute { - self.audio.play_effect(if mute { NotificationEvents::Mute } else { NotificationEvents::Unmute }); + self.audio.play_effect(if mute { + NotificationEvents::Mute + } else { + NotificationEvents::Unmute + }); } let mut msg = msgs::UserState::new(); if server.muted() != mute { @@ -300,9 +308,17 @@ impl State { if let Some((mute, deafen)) = action { if server.deafened() != deafen { - self.audio.play_effect(if deafen { NotificationEvents::Deafen } else { NotificationEvents::Undeafen }); + self.audio.play_effect(if deafen { + NotificationEvents::Deafen + } else { + NotificationEvents::Undeafen + }); } else if server.muted() != mute { - self.audio.play_effect(if mute { NotificationEvents::Mute } else { NotificationEvents::Unmute }); + self.audio.play_effect(if mute { + NotificationEvents::Mute + } else { + NotificationEvents::Unmute + }); } let mut msg = msgs::UserState::new(); if server.muted() != mute { @@ -430,7 +446,9 @@ impl State { if *self.phase_receiver().borrow() == StatePhase::Connected { let channel_id = msg.get_channel_id(); - if channel_id == self.get_users_channel(self.server().unwrap().session_id().unwrap()) { + if channel_id + == self.get_users_channel(self.server().unwrap().session_id().unwrap()) + { if let Some(channel) = self.server().unwrap().channels().get(&channel_id) { notify::send(format!( "{} connected and joined {}", @@ -455,7 +473,8 @@ impl State { let from_channel = self.get_users_channel(session); - let user = self.server_mut() + let user = self + .server_mut() .unwrap() .users_mut() .get_mut(&session) @@ -475,16 +494,13 @@ impl State { let diff = UserDiff::from(msg); user.apply_user_diff(&diff); - let user = self.server() - .unwrap() - .users() - .get(&session) - .unwrap(); + let user = self.server().unwrap().users().get(&session).unwrap(); if Some(session) != self.server().unwrap().session_id() { //send notification if the user moved to or from any channel if let Some(to_channel) = diff.channel_id { - let this_channel = self.get_users_channel(self.server().unwrap().session_id().unwrap()); + let this_channel = + self.get_users_channel(self.server().unwrap().session_id().unwrap()); if from_channel == this_channel || to_channel == this_channel { if let Some(channel) = self.server().unwrap().channels().get(&to_channel) { notify::send(format!( @@ -495,20 +511,32 @@ impl State { } else { warn!("{} moved to invalid channel {}", user.name(), to_channel); } - self.audio.play_effect(if from_channel == this_channel { NotificationEvents::UserJoinedChannel } else { NotificationEvents::UserLeftChannel }); + self.audio.play_effect(if from_channel == this_channel { + NotificationEvents::UserJoinedChannel + } else { + NotificationEvents::UserLeftChannel + }); } } //send notification if a user muted/unmuted let notify_desc = match (mute, deaf) { - (Some(true), Some(true)) => Some(format!("{} muted and deafend themselves", &user.name())), - (Some(false), Some(false)) => Some(format!("{} unmuted and undeafend themselves", &user.name())), + (Some(true), Some(true)) => { + Some(format!("{} muted and deafend themselves", &user.name())) + } + (Some(false), Some(false)) => { + Some(format!("{} unmuted and undeafend themselves", &user.name())) + } (None, Some(true)) => Some(format!("{} deafend themselves", &user.name())), (None, Some(false)) => Some(format!("{} undeafend themselves", &user.name())), (Some(true), None) => Some(format!("{} muted themselves", &user.name())), (Some(false), None) => Some(format!("{} unmuted themselves", &user.name())), - (Some(true), Some(false)) => Some(format!("{} muted and undeafened themselves", &user.name())), - (Some(false), Some(true)) => Some(format!("{} unmuted and deafened themselves", &user.name())), + (Some(true), Some(false)) => { + Some(format!("{} muted and undeafened themselves", &user.name())) + } + (Some(false), Some(true)) => { + Some(format!("{} unmuted and deafened themselves", &user.name())) + } (None, None) => None, }; if let Some(notify_desc) = notify_desc { @@ -580,6 +608,13 @@ impl State { self.server.as_ref().map(|e| e.username()).flatten() } fn get_users_channel(&self, user_id: u32) -> u32 { - self.server().unwrap().users().iter().find(|e| *e.0 == user_id).unwrap().1.channel() + self.server() + .unwrap() + .users() + .iter() + .find(|e| *e.0 == user_id) + .unwrap() + .1 + .channel() } } -- cgit v1.2.1 From ac6b6e462f8dd7b6ab73e12b55de07b5019f232d Mon Sep 17 00:00:00 2001 From: Eskil Queseth Date: Mon, 16 Nov 2020 16:33:07 +0100 Subject: clean up mute notification code --- mumd/src/state.rs | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/mumd/src/state.rs b/mumd/src/state.rs index d3c793e..91cf734 100644 --- a/mumd/src/state.rs +++ b/mumd/src/state.rs @@ -520,27 +520,19 @@ impl State { } //send notification if a user muted/unmuted - let notify_desc = match (mute, deaf) { - (Some(true), Some(true)) => { - Some(format!("{} muted and deafend themselves", &user.name())) + if mute != None || deaf != None { + let mut s = user.name().to_string(); + if let Some(mute) = mute { + s += if mute { " muted" } else { " unmuted" }; } - (Some(false), Some(false)) => { - Some(format!("{} unmuted and undeafend themselves", &user.name())) + if mute.is_some() && deaf.is_some() { + s += " and"; } - (None, Some(true)) => Some(format!("{} deafend themselves", &user.name())), - (None, Some(false)) => Some(format!("{} undeafend themselves", &user.name())), - (Some(true), None) => Some(format!("{} muted themselves", &user.name())), - (Some(false), None) => Some(format!("{} unmuted themselves", &user.name())), - (Some(true), Some(false)) => { - Some(format!("{} muted and undeafened themselves", &user.name())) + if let Some(deaf) = deaf { + s += if deaf { " deafened" } else { " undeafened" }; } - (Some(false), Some(true)) => { - Some(format!("{} unmuted and deafened themselves", &user.name())) - } - (None, None) => None, - }; - if let Some(notify_desc) = notify_desc { - notify::send(notify_desc); + s += " themselves"; + notify::send(s); } } } -- cgit v1.2.1 From 292ba0307ebcf14ab8362f8f8f276a67d38a93ea Mon Sep 17 00:00:00 2001 From: Eskil Queseth Date: Mon, 16 Nov 2020 19:48:27 +0100 Subject: change some things with extra features --- mumd/Cargo.toml | 15 +++++++++++---- mumd/src/audio.rs | 12 ++++++++++++ mumd/src/notify.rs | 6 +++--- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/mumd/Cargo.toml b/mumd/Cargo.toml index a7a5ef8..1096041 100644 --- a/mumd/Cargo.toml +++ b/mumd/Cargo.toml @@ -9,7 +9,13 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [features] -default = ["libnotify"] +default = [] + +all = ["libnotify", "hound", "samplerate"] + +notifications = ["libnotify"] + +sounds = ["hound", "samplerate"] [dependencies] mumlib = { path = "../mumlib" } @@ -23,16 +29,17 @@ ipc-channel = "0.14" log = "0.4" mumble-protocol = "0.3" native-tls = "0.2" -openssl = { version = "0.10", optional = true } +openssl = { version = "0.10" } opus = "0.2" serde = { version = "1.0", features = ["derive"] } tokio = { version = "0.2", features = ["full"] } tokio-tls = "0.3" tokio-util = { version = "0.3", features = ["codec", "udp"] } -hound = "3.4.0" -samplerate = "0.2.2" libnotify = { version = "1.0", optional = true } +hound = { version = "3.4.0", optional = true } +samplerate = { version = "0.2.2", optional = true } + #compressor = "0.3" #daemonize = "0.4" diff --git a/mumd/src/audio.rs b/mumd/src/audio.rs index a51c2f2..316d66b 100644 --- a/mumd/src/audio.rs +++ b/mumd/src/audio.rs @@ -1,12 +1,14 @@ pub mod input; pub mod output; +#[cfg(any(feature = "sounds", feature = "all"))] use crate::audio::output::SaturatingAdd; use cpal::traits::{DeviceTrait, HostTrait, StreamTrait}; use cpal::{SampleFormat, SampleRate, Stream, StreamConfig}; use log::*; use mumble_protocol::voice::VoicePacketPayload; use opus::Channels; +#[cfg(any(feature = "sounds", feature = "all"))] use samplerate::ConverterType; use std::collections::hash_map::Entry; use std::collections::{HashMap, VecDeque}; @@ -14,6 +16,7 @@ use std::sync::{Arc, Mutex}; use tokio::sync::{mpsc, watch}; //TODO? move to mumlib +#[cfg(any(feature = "sounds", feature = "all"))] pub const EVENT_SOUNDS: &[(&str, NotificationEvents)] = &[ ("resources/connect.wav", NotificationEvents::ServerConnect), ( @@ -72,8 +75,10 @@ pub struct Audio { client_streams: Arc>>, + #[cfg(any(feature = "sounds", feature = "all"))] sounds: HashMap>, + #[cfg(any(feature = "sounds", feature = "all"))] play_sounds: Arc>>, } @@ -215,6 +220,7 @@ impl Audio { output_stream.play().unwrap(); + #[cfg(any(feature = "sounds", feature = "all"))] let sounds = EVENT_SOUNDS .iter() .map(|(path, event)| { @@ -249,9 +255,11 @@ impl Audio { input_volume_sender, input_channel_receiver: Some(input_receiver), client_streams, + #[cfg(any(feature = "sounds", feature = "all"))] sounds, output_volume_sender, user_volumes, + #[cfg(any(feature = "sounds", feature = "all"))] play_sounds, } } @@ -335,6 +343,7 @@ impl Audio { } } + #[cfg(any(feature = "sounds", feature = "all"))] pub fn play_effect(&self, effect: NotificationEvents) { let samples = self.sounds.get(&effect).unwrap(); @@ -347,4 +356,7 @@ impl Audio { let l = play_sounds.len(); play_sounds.extend(samples.iter().skip(l)); } + + #[cfg(not(any(feature = "sounds", feature = "all")))] + pub fn play_effect(&self, _: NotificationEvents) {} } diff --git a/mumd/src/notify.rs b/mumd/src/notify.rs index 0739c58..eaed3dc 100644 --- a/mumd/src/notify.rs +++ b/mumd/src/notify.rs @@ -1,9 +1,9 @@ pub fn init() { - #[cfg(feature = "libnotify")] + #[cfg(any(feature = "notifications", feature = "all"))] libnotify::init("mumd").unwrap(); } -#[cfg(feature = "libnotify")] +#[cfg(any(feature = "notifications", feature = "all"))] pub fn send(msg: String) -> Option { match libnotify::Notification::new("mumd", Some(msg.as_str()), None).show() { Ok(_) => Some(true), @@ -14,7 +14,7 @@ pub fn send(msg: String) -> Option { } } -#[cfg(not(feature = "libnotify"))] +#[cfg(not(any(feature = "notifications", feature = "all")))] pub fn send(_: String) -> Option { None } -- cgit v1.2.1 From 505e850afab903797eba40bdc6c852f09dfa186f Mon Sep 17 00:00:00 2001 From: Eskil Queseth Date: Mon, 16 Nov 2020 21:14:29 +0100 Subject: clean up conditional compilation --- mumd/Cargo.toml | 6 ++---- mumd/src/audio.rs | 20 ++++++++++---------- mumd/src/notify.rs | 6 +++--- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/mumd/Cargo.toml b/mumd/Cargo.toml index 1096041..e124eb4 100644 --- a/mumd/Cargo.toml +++ b/mumd/Cargo.toml @@ -9,13 +9,11 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [features] -default = [] - -all = ["libnotify", "hound", "samplerate"] +default = ["notifications", "sound_effects"] notifications = ["libnotify"] -sounds = ["hound", "samplerate"] +sound_effects = ["hound", "samplerate"] [dependencies] mumlib = { path = "../mumlib" } diff --git a/mumd/src/audio.rs b/mumd/src/audio.rs index 316d66b..2e9d1bd 100644 --- a/mumd/src/audio.rs +++ b/mumd/src/audio.rs @@ -1,14 +1,14 @@ pub mod input; pub mod output; -#[cfg(any(feature = "sounds", feature = "all"))] +#[cfg(feature = "sound_effects")] use crate::audio::output::SaturatingAdd; use cpal::traits::{DeviceTrait, HostTrait, StreamTrait}; use cpal::{SampleFormat, SampleRate, Stream, StreamConfig}; use log::*; use mumble_protocol::voice::VoicePacketPayload; use opus::Channels; -#[cfg(any(feature = "sounds", feature = "all"))] +#[cfg(feature = "sound_effects")] use samplerate::ConverterType; use std::collections::hash_map::Entry; use std::collections::{HashMap, VecDeque}; @@ -16,7 +16,7 @@ use std::sync::{Arc, Mutex}; use tokio::sync::{mpsc, watch}; //TODO? move to mumlib -#[cfg(any(feature = "sounds", feature = "all"))] +#[cfg(feature = "sound_effects")] pub const EVENT_SOUNDS: &[(&str, NotificationEvents)] = &[ ("resources/connect.wav", NotificationEvents::ServerConnect), ( @@ -75,10 +75,10 @@ pub struct Audio { client_streams: Arc>>, - #[cfg(any(feature = "sounds", feature = "all"))] + #[cfg(feature = "sound_effects")] sounds: HashMap>, - #[cfg(any(feature = "sounds", feature = "all"))] + #[cfg(feature = "sound_effects")] play_sounds: Arc>>, } @@ -220,7 +220,7 @@ impl Audio { output_stream.play().unwrap(); - #[cfg(any(feature = "sounds", feature = "all"))] + #[cfg(feature = "sound_effects")] let sounds = EVENT_SOUNDS .iter() .map(|(path, event)| { @@ -255,11 +255,11 @@ impl Audio { input_volume_sender, input_channel_receiver: Some(input_receiver), client_streams, - #[cfg(any(feature = "sounds", feature = "all"))] + #[cfg(feature = "sound_effects")] sounds, output_volume_sender, user_volumes, - #[cfg(any(feature = "sounds", feature = "all"))] + #[cfg(feature = "sound_effects")] play_sounds, } } @@ -343,7 +343,7 @@ impl Audio { } } - #[cfg(any(feature = "sounds", feature = "all"))] + #[cfg(feature = "sound_effects")] pub fn play_effect(&self, effect: NotificationEvents) { let samples = self.sounds.get(&effect).unwrap(); @@ -357,6 +357,6 @@ impl Audio { play_sounds.extend(samples.iter().skip(l)); } - #[cfg(not(any(feature = "sounds", feature = "all")))] + #[cfg(not(feature = "sound_effects"))] pub fn play_effect(&self, _: NotificationEvents) {} } diff --git a/mumd/src/notify.rs b/mumd/src/notify.rs index eaed3dc..ee387cc 100644 --- a/mumd/src/notify.rs +++ b/mumd/src/notify.rs @@ -1,9 +1,9 @@ pub fn init() { - #[cfg(any(feature = "notifications", feature = "all"))] + #[cfg(feature = "notifications")] libnotify::init("mumd").unwrap(); } -#[cfg(any(feature = "notifications", feature = "all"))] +#[cfg(feature = "notifications")] pub fn send(msg: String) -> Option { match libnotify::Notification::new("mumd", Some(msg.as_str()), None).show() { Ok(_) => Some(true), @@ -14,7 +14,7 @@ pub fn send(msg: String) -> Option { } } -#[cfg(not(any(feature = "notifications", feature = "all")))] +#[cfg(not(feature = "notifications"))] pub fn send(_: String) -> Option { None } -- cgit v1.2.1 From be4d273fa8778ec87ad4a34502d0f3c75657fbbc Mon Sep 17 00:00:00 2001 From: Eskil Queseth Date: Mon, 16 Nov 2020 23:26:11 +0100 Subject: change sound_effects to sound-effects --- mumd/Cargo.toml | 4 ++-- mumd/src/audio.rs | 20 ++++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/mumd/Cargo.toml b/mumd/Cargo.toml index e124eb4..15aaed5 100644 --- a/mumd/Cargo.toml +++ b/mumd/Cargo.toml @@ -9,11 +9,11 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [features] -default = ["notifications", "sound_effects"] +default = ["notifications", "sound-effects"] notifications = ["libnotify"] -sound_effects = ["hound", "samplerate"] +sound-effects = ["hound", "samplerate"] [dependencies] mumlib = { path = "../mumlib" } diff --git a/mumd/src/audio.rs b/mumd/src/audio.rs index 2e9d1bd..d5617fc 100644 --- a/mumd/src/audio.rs +++ b/mumd/src/audio.rs @@ -1,14 +1,14 @@ pub mod input; pub mod output; -#[cfg(feature = "sound_effects")] +#[cfg(feature = "sound-effects")] use crate::audio::output::SaturatingAdd; use cpal::traits::{DeviceTrait, HostTrait, StreamTrait}; use cpal::{SampleFormat, SampleRate, Stream, StreamConfig}; use log::*; use mumble_protocol::voice::VoicePacketPayload; use opus::Channels; -#[cfg(feature = "sound_effects")] +#[cfg(feature = "sound-effects")] use samplerate::ConverterType; use std::collections::hash_map::Entry; use std::collections::{HashMap, VecDeque}; @@ -16,7 +16,7 @@ use std::sync::{Arc, Mutex}; use tokio::sync::{mpsc, watch}; //TODO? move to mumlib -#[cfg(feature = "sound_effects")] +#[cfg(feature = "sound-effects")] pub const EVENT_SOUNDS: &[(&str, NotificationEvents)] = &[ ("resources/connect.wav", NotificationEvents::ServerConnect), ( @@ -75,10 +75,10 @@ pub struct Audio { client_streams: Arc>>, - #[cfg(feature = "sound_effects")] + #[cfg(feature = "sound-effects")] sounds: HashMap>, - #[cfg(feature = "sound_effects")] + #[cfg(feature = "sound-effects")] play_sounds: Arc>>, } @@ -220,7 +220,7 @@ impl Audio { output_stream.play().unwrap(); - #[cfg(feature = "sound_effects")] + #[cfg(feature = "sound-effects")] let sounds = EVENT_SOUNDS .iter() .map(|(path, event)| { @@ -255,11 +255,11 @@ impl Audio { input_volume_sender, input_channel_receiver: Some(input_receiver), client_streams, - #[cfg(feature = "sound_effects")] + #[cfg(feature = "sound-effects")] sounds, output_volume_sender, user_volumes, - #[cfg(feature = "sound_effects")] + #[cfg(feature = "sound-effects")] play_sounds, } } @@ -343,7 +343,7 @@ impl Audio { } } - #[cfg(feature = "sound_effects")] + #[cfg(feature = "sound-effects")] pub fn play_effect(&self, effect: NotificationEvents) { let samples = self.sounds.get(&effect).unwrap(); @@ -357,6 +357,6 @@ impl Audio { play_sounds.extend(samples.iter().skip(l)); } - #[cfg(not(feature = "sound_effects"))] + #[cfg(not(feature = "sound-effects"))] pub fn play_effect(&self, _: NotificationEvents) {} } -- cgit v1.2.1