aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGustav Sörnäs <gustav@sornas.net>2021-01-05 12:19:54 +0100
committerGustav Sörnäs <gustav@sornas.net>2021-01-05 12:20:21 +0100
commitba4aa72654f2d57d59f6e25151315213bec21192 (patch)
tree6ff7fe03e3ebbc4b351fae778fd1c02f2d6148de
parent531dc28e2c09a13336b057044bf8721d4b2c4c00 (diff)
parent2cef2e31a139e453474298b3278c98f18eba7203 (diff)
downloadmum-ba4aa72654f2d57d59f6e25151315213bec21192.tar.gz
Merge remote-tracking branch 'origin/choose-sfx' into main
-rw-r--r--Cargo.lock35
-rw-r--r--mumd/Cargo.toml2
-rw-r--r--mumd/src/audio.rs151
-rw-r--r--mumd/src/fallback_sfx.wav (renamed from mumd/src/resources/channel_join.wav)bin32002 -> 32002 bytes
-rw-r--r--mumd/src/resources/channel_leave.wavbin32002 -> 0 bytes
-rw-r--r--mumd/src/resources/connect.wavbin32002 -> 0 bytes
-rw-r--r--mumd/src/resources/deafen.wavbin32002 -> 0 bytes
-rw-r--r--mumd/src/resources/disconnect.wavbin303364 -> 0 bytes
-rw-r--r--mumd/src/resources/mute.wavbin32002 -> 0 bytes
-rw-r--r--mumd/src/resources/undeafen.wavbin32002 -> 0 bytes
-rw-r--r--mumd/src/resources/unmute.wavbin32002 -> 0 bytes
-rw-r--r--mumd/src/state.rs3
-rw-r--r--mumlib/src/config.rs7
13 files changed, 143 insertions, 55 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 904fe44..f732507 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -851,6 +851,15 @@ dependencies = [
]
[[package]]
+name = "heck"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87cbf45460356b7deeb5e3415b5563308c0a9b057c85e12b06ad551f98d0a6ac"
+dependencies = [
+ "unicode-segmentation",
+]
+
+[[package]]
name = "hermit-abi"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1208,6 +1217,8 @@ dependencies = [
"openssl",
"opus",
"serde",
+ "strum",
+ "strum_macros",
"tokio",
"tokio-native-tls",
"tokio-stream",
@@ -2002,6 +2013,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c"
[[package]]
+name = "strum"
+version = "0.20.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7318c509b5ba57f18533982607f24070a55d353e90d4cae30c467cdb2ad5ac5c"
+
+[[package]]
+name = "strum_macros"
+version = "0.20.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ee8bc6b87a5112aeeab1f4a9f7ab634fe6cbefc4850006df31267f4cfb9e3149"
+dependencies = [
+ "heck",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
name = "syn"
version = "1.0.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2221,6 +2250,12 @@ dependencies = [
]
[[package]]
+name = "unicode-segmentation"
+version = "1.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796"
+
+[[package]]
name = "unicode-width"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/mumd/Cargo.toml b/mumd/Cargo.toml
index 0f5edb1..4f0bc19 100644
--- a/mumd/Cargo.toml
+++ b/mumd/Cargo.toml
@@ -35,6 +35,8 @@ native-tls = "0.2"
openssl = { version = "0.10" }
opus = "0.2"
serde = { version = "1.0", features = ["derive"] }
+strum = "0.20"
+strum_macros = "0.20"
tokio = { version = "1.0", features = ["macros", "rt", "rt-multi-thread", "sync", "net", "time"] }
tokio-stream = "0.1.0"
tokio-native-tls = "0.3"
diff --git a/mumd/src/audio.rs b/mumd/src/audio.rs
index 83818d5..680433c 100644
--- a/mumd/src/audio.rs
+++ b/mumd/src/audio.rs
@@ -13,49 +13,28 @@ use futures::Stream;
use futures::stream::StreamExt;
use futures::task::{Context, Poll};
use log::*;
+use mumble_protocol::Serverbound;
use mumble_protocol::voice::{VoicePacketPayload, VoicePacket};
+use mumlib::config::SoundEffect;
use opus::Channels;
-use std::collections::hash_map::Entry;
-use std::collections::{HashMap, VecDeque};
-use std::fmt::Debug;
-use std::future::{Future};
-use std::pin::Pin;
-use std::sync::{Arc, Mutex};
+use std::{
+ borrow::Cow,
+ collections::{hash_map::Entry, HashMap, VecDeque},
+ convert::TryFrom,
+ fmt::Debug,
+ fs::File,
+ future::Future,
+ io::Read,
+ pin::Pin,
+ sync::{Arc, Mutex},
+};
+use strum::IntoEnumIterator;
+use strum_macros::EnumIter;
use tokio::sync::watch;
-use mumble_protocol::Serverbound;
-
-//TODO? move to mumlib
-pub const EVENT_SOUNDS: &[(&[u8], NotificationEvents)] = &[
- (include_bytes!("resources/connect.wav"), NotificationEvents::ServerConnect),
- (
- include_bytes!("resources/disconnect.wav"),
- NotificationEvents::ServerDisconnect,
- ),
- (
- include_bytes!("resources/channel_join.wav"),
- NotificationEvents::UserConnected,
- ),
- (
- include_bytes!("resources/channel_leave.wav"),
- NotificationEvents::UserDisconnected,
- ),
- (
- include_bytes!("resources/channel_join.wav"),
- NotificationEvents::UserJoinedChannel,
- ),
- (
- include_bytes!("resources/channel_leave.wav"),
- NotificationEvents::UserLeftChannel,
- ),
- (include_bytes!("resources/mute.wav"), NotificationEvents::Mute),
- (include_bytes!("resources/unmute.wav"), NotificationEvents::Unmute),
- (include_bytes!("resources/deafen.wav"), NotificationEvents::Deafen),
- (include_bytes!("resources/undeafen.wav"), NotificationEvents::Undeafen),
-];
const SAMPLE_RATE: u32 = 48000;
-#[derive(Debug, Eq, PartialEq, Clone, Copy, Hash)]
+#[derive(Debug, Eq, PartialEq, Clone, Copy, Hash, EnumIter)]
pub enum NotificationEvents {
ServerConnect,
ServerDisconnect,
@@ -69,6 +48,28 @@ pub enum NotificationEvents {
Undeafen,
}
+impl TryFrom<&str> for NotificationEvents {
+ type Error = ();
+ fn try_from(s: &str) -> Result<Self, Self::Error> {
+ match s {
+ "server_connect" => Ok(NotificationEvents::ServerConnect),
+ "server_disconnect" => Ok(NotificationEvents::ServerDisconnect),
+ "user_connected" => Ok(NotificationEvents::UserConnected),
+ "user_disconnected" => Ok(NotificationEvents::UserDisconnected),
+ "user_joined_channel" => Ok(NotificationEvents::UserJoinedChannel),
+ "user_left_channel" => Ok(NotificationEvents::UserLeftChannel),
+ "mute" => Ok(NotificationEvents::Mute),
+ "unmute" => Ok(NotificationEvents::Unmute),
+ "deafen" => Ok(NotificationEvents::Deafen),
+ "undeafen" => Ok(NotificationEvents::Undeafen),
+ _ => {
+ warn!("Unknown notification event '{}' in config", s);
+ Err(())
+ }
+ }
+ }
+}
+
pub struct Audio {
output_config: StreamConfig,
_output_stream: cpal::Stream,
@@ -220,10 +221,41 @@ impl Audio {
output_stream.play().unwrap();
- let sounds = EVENT_SOUNDS
+ let mut res = Self {
+ output_config,
+ _output_stream: output_stream,
+ _input_stream: input_stream,
+ input_volume_sender,
+ input_channel_receiver: Arc::new(Mutex::new(Box::new(opus_stream))),
+ client_streams,
+ sounds: HashMap::new(),
+ output_volume_sender,
+ user_volumes,
+ play_sounds,
+ };
+ res.load_sound_effects(&[]);
+ res
+ }
+
+ pub fn load_sound_effects(&mut self, sound_effects: &[SoundEffect]) {
+ let overrides: HashMap<_, _> = sound_effects
.iter()
- .map(|(bytes, event)| {
- let reader = hound::WavReader::new(*bytes).unwrap();
+ .filter_map(|sound_effect| {
+ let (event, file) = (&sound_effect.event, &sound_effect.file);
+ if let Ok(event) = NotificationEvents::try_from(event.as_str()) {
+ Some((event, file))
+ } else {
+ None
+ }
+ })
+ .collect();
+
+ self.sounds = NotificationEvents::iter()
+ .map(|event| {
+ let bytes = overrides.get(&event)
+ .map(|file| get_sfx(file))
+ .unwrap_or_else(get_default_sfx);
+ let reader = hound::WavReader::new(bytes.as_ref()).unwrap();
let spec = reader.spec();
let samples = match spec.sample_format {
hound::SampleFormat::Float => reader
@@ -246,24 +278,17 @@ impl Audio {
.from_hz_to_hz(interp, spec.sample_rate as f64, SAMPLE_RATE as f64)
.until_exhausted()
// if the source audio is stereo and is being played as mono, discard the right audio
- .flat_map(|e| if output_config.channels == 1 { vec![e[0]] } else { e.to_vec() })
+ .flat_map(
+ |e| if self.output_config.channels == 1 {
+ vec![e[0]]
+ } else {
+ e.to_vec()
+ }
+ )
.collect::<Vec<f32>>();
- (*event, samples)
+ (event, samples)
})
.collect();
-
- Self {
- output_config,
- _output_stream: output_stream,
- _input_stream: input_stream,
- input_volume_sender,
- input_channel_receiver: Arc::new(Mutex::new(Box::new(opus_stream))),
- client_streams,
- sounds,
- output_volume_sender,
- user_volumes,
- play_sounds,
- }
}
pub fn decode_packet(&self, session_id: u32, payload: VoicePacketPayload) {
@@ -359,6 +384,22 @@ impl Audio {
}
}
+// moo
+fn get_sfx(file: &str) -> Cow<'static, [u8]> {
+ let mut buf: Vec<u8> = Vec::new();
+ if let Ok(mut file) = File::open(file) {
+ file.read_to_end(&mut buf).unwrap();
+ Cow::from(buf)
+ } else {
+ warn!("File not found: '{}'", file);
+ get_default_sfx()
+ }
+}
+
+fn get_default_sfx() -> Cow<'static, [u8]> {
+ Cow::from(include_bytes!("fallback_sfx.wav").as_ref())
+}
+
struct StreamingNoiseGate<S: StreamingSignal> {
open: usize,
signal: S,
diff --git a/mumd/src/resources/channel_join.wav b/mumd/src/fallback_sfx.wav
index 82ee4d4..82ee4d4 100644
--- a/mumd/src/resources/channel_join.wav
+++ b/mumd/src/fallback_sfx.wav
Binary files differ
diff --git a/mumd/src/resources/channel_leave.wav b/mumd/src/resources/channel_leave.wav
deleted file mode 100644
index 82ee4d4..0000000
--- a/mumd/src/resources/channel_leave.wav
+++ /dev/null
Binary files differ
diff --git a/mumd/src/resources/connect.wav b/mumd/src/resources/connect.wav
deleted file mode 100644
index 82ee4d4..0000000
--- a/mumd/src/resources/connect.wav
+++ /dev/null
Binary files differ
diff --git a/mumd/src/resources/deafen.wav b/mumd/src/resources/deafen.wav
deleted file mode 100644
index 82ee4d4..0000000
--- a/mumd/src/resources/deafen.wav
+++ /dev/null
Binary files differ
diff --git a/mumd/src/resources/disconnect.wav b/mumd/src/resources/disconnect.wav
deleted file mode 100644
index fb2ca76..0000000
--- a/mumd/src/resources/disconnect.wav
+++ /dev/null
Binary files differ
diff --git a/mumd/src/resources/mute.wav b/mumd/src/resources/mute.wav
deleted file mode 100644
index 82ee4d4..0000000
--- a/mumd/src/resources/mute.wav
+++ /dev/null
Binary files differ
diff --git a/mumd/src/resources/undeafen.wav b/mumd/src/resources/undeafen.wav
deleted file mode 100644
index 82ee4d4..0000000
--- a/mumd/src/resources/undeafen.wav
+++ /dev/null
Binary files differ
diff --git a/mumd/src/resources/unmute.wav b/mumd/src/resources/unmute.wav
deleted file mode 100644
index 82ee4d4..0000000
--- a/mumd/src/resources/unmute.wav
+++ /dev/null
Binary files differ
diff --git a/mumd/src/state.rs b/mumd/src/state.rs
index d1f64a9..84247bc 100644
--- a/mumd/src/state.rs
+++ b/mumd/src/state.rs
@@ -573,6 +573,9 @@ impl State {
if let Some(output_volume) = self.config.audio.output_volume {
self.audio.set_output_volume(output_volume);
}
+ if let Some(sound_effects) = &self.config.audio.sound_effects {
+ self.audio.load_sound_effects(sound_effects);
+ }
}
pub fn initialized(&self) {
diff --git a/mumlib/src/config.rs b/mumlib/src/config.rs
index 5987ab9..0a43253 100644
--- a/mumlib/src/config.rs
+++ b/mumlib/src/config.rs
@@ -47,9 +47,16 @@ impl Config {
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
+pub struct SoundEffect {
+ pub event: String,
+ pub file: String,
+}
+
+#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct AudioConfig {
pub input_volume: Option<f32>,
pub output_volume: Option<f32>,
+ pub sound_effects: Option<Vec<SoundEffect>>,
}
#[derive(Clone, Debug, Deserialize, Serialize)]