Add --progressive-volume option. Increase volume slowly at low level, faster at higher level

This commit is contained in:
Robert 2018-01-25 23:37:28 +01:00
parent b6a38780df
commit 4870acd572
3 changed files with 48 additions and 13 deletions

View file

@ -122,4 +122,5 @@ pub struct ConnectConfig {
pub name: String, pub name: String,
pub device_type: DeviceType, pub device_type: DeviceType,
pub volume: i32, pub volume: i32,
pub progressive_volume: bool,
} }

View file

@ -101,7 +101,8 @@ fn setup(args: &[String]) -> Setup {
.optopt("", "backend", "Audio backend to use. Use '?' to list options", "BACKEND") .optopt("", "backend", "Audio backend to use. Use '?' to list options", "BACKEND")
.optopt("", "device", "Audio device to use. Use '?' to list options", "DEVICE") .optopt("", "device", "Audio device to use. Use '?' to list options", "DEVICE")
.optopt("", "mixer", "Mixer to use", "MIXER") .optopt("", "mixer", "Mixer to use", "MIXER")
.optopt("", "initial-volume", "Initial volume in %, once connected (must be from 0 to 100)", "VOLUME"); .optopt("", "initial-volume", "Initial volume in %, once connected (must be from 0 to 100)", "VOLUME")
.optflag("", "progressive-volume", "Increase volume slowly at low level, faster at high level");
let matches = match opts.parse(&args[1..]) { let matches = match opts.parse(&args[1..]) {
Ok(m) => m, Ok(m) => m,
@ -159,8 +160,11 @@ fn setup(args: &[String]) -> Setup {
// if argument not present use default values (50%) // if argument not present use default values (50%)
else{ else{
initial_volume = 0x8000 as i32; initial_volume = 0x8000 as i32;
} }
debug!("Volume \"{}\" !", initial_volume);
let progressive_volume = matches.opt_present("progressive-volume");
info!("Volume:{}, progressive_volume: {}.", initial_volume, progressive_volume);
let name = matches.opt_str("name").unwrap(); let name = matches.opt_str("name").unwrap();
let use_audio_cache = !matches.opt_present("disable-audio-cache"); let use_audio_cache = !matches.opt_present("disable-audio-cache");
@ -209,6 +213,7 @@ fn setup(args: &[String]) -> Setup {
name: name, name: name,
device_type: device_type, device_type: device_type,
volume: initial_volume, volume: initial_volume,
progressive_volume,
} }
}; };

View file

@ -17,12 +17,14 @@ use protocol::spirc::{PlayStatus, State, MessageType, Frame, DeviceState};
use mixer::Mixer; use mixer::Mixer;
use player::Player; use player::Player;
use std;
use rand; use rand;
use rand::Rng; use rand::Rng;
pub struct SpircTask { pub struct SpircTask {
player: Player, player: Player,
mixer: Box<Mixer>, mixer: Box<Mixer>,
progressive_volume:bool,
sequence: SeqGenerator<u32>, sequence: SeqGenerator<u32>,
@ -122,6 +124,33 @@ fn initial_device_state(config: ConnectConfig, volume: u16) -> DeviceState {
}) })
} }
fn volume_to_mixer(volume: u16, progressive: bool) -> u16 {
if progressive {
// Some by trail determined volume calculation algorithm. Start increasing slowly,
// then after 50% increase in bigger steps.
let d = volume / (std::u16::MAX / 100);
let mut v:u32 = 0;
let mut incr:u32 = 0;
for i in 0..d {
v += incr;
incr +=3;
if i > 50 {
// Increase faster to reach max volume
incr += 42;
}
}
// Clip the vulume to the max
if v > std::u16::MAX as u32 {v = std::u16::MAX as u32;}
debug!("volume_to_mixer {} {}", volume, v);
return v as u16;
} else {
debug!("volume_to_mixer {}", volume);
return volume;
}
}
impl Spirc { impl Spirc {
pub fn new(config: ConnectConfig, session: Session, player: Player, mixer: Box<Mixer>) pub fn new(config: ConnectConfig, session: Session, player: Player, mixer: Box<Mixer>)
-> (Spirc, SpircTask) -> (Spirc, SpircTask)
@ -144,15 +173,15 @@ impl Spirc {
})); }));
let (cmd_tx, cmd_rx) = mpsc::unbounded(); let (cmd_tx, cmd_rx) = mpsc::unbounded();
let progressive_volume = config.progressive_volume;
let volume = config.volume as u16; let volume = config.volume as u16;
let device = initial_device_state(config, volume); let device = initial_device_state(config, volume);
mixer.set_volume(volume as u16); mixer.set_volume(volume_to_mixer(volume as u16, progressive_volume));
let mut task = SpircTask { let mut task = SpircTask {
player: player, player: player,
mixer: mixer, mixer: mixer,
progressive_volume,
sequence: SeqGenerator::new(1), sequence: SeqGenerator::new(1),
ident: ident, ident: ident,
@ -439,9 +468,9 @@ impl SpircTask {
} }
MessageType::kMessageTypeVolume => { MessageType::kMessageTypeVolume => {
let volume = frame.get_volume(); self.device.set_volume(frame.get_volume());
self.device.set_volume(volume); self.mixer.set_volume(
self.mixer.set_volume(frame.get_volume() as u16); volume_to_mixer(frame.get_volume() as u16, self.progressive_volume));
self.notify(None); self.notify(None);
} }
@ -536,21 +565,21 @@ impl SpircTask {
} }
fn handle_volume_up(&mut self) { fn handle_volume_up(&mut self) {
let mut volume: u32 = self.mixer.volume() as u32 + 4096; let mut volume: u32 = self.device.get_volume() as u32 + 4096;
if volume > 0xFFFF { if volume > 0xFFFF {
volume = 0xFFFF; volume = 0xFFFF;
} }
self.device.set_volume(volume); self.device.set_volume(volume);
self.mixer.set_volume(volume as u16); self.mixer.set_volume(volume_to_mixer(volume as u16, self.progressive_volume));
} }
fn handle_volume_down(&mut self) { fn handle_volume_down(&mut self) {
let mut volume: i32 = self.mixer.volume() as i32 - 4096; let mut volume: i32 = self.device.get_volume() as i32 - 4096;
if volume < 0 { if volume < 0 {
volume = 0; volume = 0;
} }
self.device.set_volume(volume as u32); self.device.set_volume(volume as u32);
self.mixer.set_volume(volume as u16); self.mixer.set_volume(volume_to_mixer(volume as u16, self.progressive_volume));
} }
fn handle_end_of_track(&mut self) { fn handle_end_of_track(&mut self) {