aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGustav Sörnäs <gustav@sornas.net>2020-10-17 01:10:04 +0200
committerGustav Sörnäs <gustav@sornas.net>2020-10-17 01:10:04 +0200
commitc614c117dc9fb40fe6565321dceb0c758766fef7 (patch)
tree2107ec186d80b3d8a2160db9608918eefc757e93
parente2f5c15e17d0ddcde88830194410c387793c045f (diff)
downloadmum-c614c117dc9fb40fe6565321dceb0c758766fef7.tar.gz
Set input volume via mumctl
-rw-r--r--mumctl/src/main.rs19
-rw-r--r--mumd/src/audio.rs18
-rw-r--r--mumd/src/state.rs4
-rw-r--r--mumlib/src/command.rs1
-rw-r--r--usage.org8
5 files changed, 48 insertions, 2 deletions
diff --git a/mumctl/src/main.rs b/mumctl/src/main.rs
index ae4acc5..5c07f7b 100644
--- a/mumctl/src/main.rs
+++ b/mumctl/src/main.rs
@@ -1,4 +1,5 @@
use clap::{App, AppSettings, Arg, Shell, SubCommand};
+use colored::Colorize;
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
use log::*;
use mumlib::command::{Command, CommandResponse};
@@ -41,6 +42,11 @@ fn main() {
.arg(Arg::with_name("channel")
.required(true))))
.subcommand(SubCommand::with_name("status"))
+ .subcommand(SubCommand::with_name("config")
+ .arg(Arg::with_name("name")
+ .required(true))
+ .arg(Arg::with_name("value")
+ .required(true)))
.subcommand(SubCommand::with_name("completions")
.arg(Arg::with_name("zsh")
.long("zsh"))
@@ -86,6 +92,19 @@ fn main() {
}
let res = send_command(Command::Status).unwrap().unwrap();
println!("{:#?}", res);
+ } else if let Some(matches) = matches.subcommand_matches("config") {
+ let name = matches.value_of("name").unwrap();
+ let value = matches.value_of("value").unwrap();
+ match name {
+ "audio.input_volume" => {
+ if let Ok(volume) = value.parse() {
+ send_command(Command::InputVolumeSet(volume)).unwrap();
+ }
+ },
+ _ => {
+ println!("{} Unknown config value {}", "error:".red(), name);
+ }
+ }
} else if let Some(matches) = matches.subcommand_matches("completions") {
app.gen_completions_to("mumctl",
match matches.value_of("shell").unwrap_or("zsh") {
diff --git a/mumd/src/audio.rs b/mumd/src/audio.rs
index edc2f7f..a63e0cc 100644
--- a/mumd/src/audio.rs
+++ b/mumd/src/audio.rs
@@ -13,6 +13,7 @@ use std::ops::AddAssign;
use std::sync::Arc;
use std::sync::Mutex;
use tokio::sync::mpsc::{self, Receiver, Sender};
+use tokio::sync::watch;
struct ClientStream {
buffer: VecDeque<f32>, //TODO ring buffer?
@@ -28,6 +29,7 @@ pub struct Audio {
pub input_stream: Stream,
pub input_buffer: Arc<Mutex<VecDeque<f32>>>,
input_channel_receiver: Option<Receiver<VoicePacketPayload>>, //TODO unbounded? mbe ring buffer and drop the first packet
+ input_volume_sender: watch::Sender<f32>,
client_streams: Arc<Mutex<HashMap<u32, ClientStream>>>, //TODO move to user state
}
@@ -99,6 +101,8 @@ 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_buffer = Arc::new(Mutex::new(VecDeque::new()));
let input_stream = match input_supported_sample_format {
SampleFormat::F32 => input_device.build_input_stream(
@@ -107,6 +111,7 @@ impl Audio {
input_encoder,
input_sender,
input_config.sample_rate.0,
+ input_volume_receiver.clone(),
4, // 10 ms
),
err_fn,
@@ -117,6 +122,7 @@ impl Audio {
input_encoder,
input_sender,
input_config.sample_rate.0,
+ input_volume_receiver.clone(),
4, // 10 ms
),
err_fn,
@@ -127,6 +133,7 @@ impl Audio {
input_encoder,
input_sender,
input_config.sample_rate.0,
+ input_volume_receiver.clone(),
4, // 10 ms
),
err_fn,
@@ -142,6 +149,7 @@ impl Audio {
input_config,
input_stream,
input_buffer,
+ input_volume_sender,
input_channel_receiver: Some(input_receiver),
client_streams,
}
@@ -195,6 +203,10 @@ impl Audio {
pub fn clear_clients(&mut self) {
self.client_streams.lock().unwrap().clear();
}
+
+ pub fn set_input_volume(&self, input_volume: f32) {
+ self.input_volume_sender.broadcast(input_volume).unwrap();
+ }
}
impl ClientStream {
@@ -280,6 +292,7 @@ fn input_callback<T: Sample>(
mut opus_encoder: opus::Encoder,
mut input_sender: Sender<VoicePacketPayload>,
sample_rate: u32,
+ input_volume_receiver: watch::Receiver<f32>,
opus_frame_size_blocks: u32, // blocks of 2.5ms
) -> impl FnMut(&[T], &InputCallbackInfo) + Send + 'static {
if !(opus_frame_size_blocks == 1
@@ -297,7 +310,10 @@ fn input_callback<T: Sample>(
let buf = Arc::new(Mutex::new(VecDeque::new()));
move |data: &[T], _info: &InputCallbackInfo| {
let mut buf = buf.lock().unwrap();
- let out: Vec<f32> = data.iter().map(|e| e.to_f32()).collect();
+ let input_volume = *input_volume_receiver.borrow();
+ let out: Vec<f32> = data.iter().map(|e| e.to_f32())
+ .map(|e| e * input_volume)
+ .collect();
buf.extend(out);
while buf.len() >= opus_frame_size as usize {
let tail = buf.split_off(opus_frame_size as usize);
diff --git a/mumd/src/state.rs b/mumd/src/state.rs
index 82d671e..b50c34c 100644
--- a/mumd/src/state.rs
+++ b/mumd/src/state.rs
@@ -137,6 +137,10 @@ impl State {
.unwrap();
(false, Ok(None))
}
+ Command::InputVolumeSet(volume) => {
+ self.audio.set_input_volume(volume);
+ (false, Ok(None))
+ }
}
}
diff --git a/mumlib/src/command.rs b/mumlib/src/command.rs
index b2ac321..9211656 100644
--- a/mumlib/src/command.rs
+++ b/mumlib/src/command.rs
@@ -9,6 +9,7 @@ pub enum Command {
channel_id: u32,
},
ChannelList,
+ InputVolumeSet(f32),
ServerConnect {
host: String,
port: u16,
diff --git a/usage.org b/usage.org
index e340165..8746014 100644
--- a/usage.org
+++ b/usage.org
@@ -50,7 +50,7 @@ root [3](4)
someone eating food
#+END_SRC
-**** TODO --short
+**** DONE --short
#+BEGIN_SRC bash
$ mumctl channel list --short
root [3](4)
@@ -139,3 +139,9 @@ server offered invalid key. what do you want to do?
#+BEGIN_SRC bash
$ mumctl server rename loopback my_server
#+END_SRC
+** config
+#+BEGIN_SRC bash
+$ mumctl config audio.input_volume 1.1
+$ mumctl config audio.input_volume
+$ mumctl config audio.input_volume --help
+#+END_SRC