diff --git a/connect/src/spirc.rs b/connect/src/spirc.rs old mode 100644 new mode 100755 index f9c692cc..f95e1778 --- a/connect/src/spirc.rs +++ b/connect/src/spirc.rs @@ -24,6 +24,7 @@ use std::time::{SystemTime, UNIX_EPOCH}; pub struct SpircTask { player: Player, mixer: Box, + linear_volume: bool, sequence: SeqGenerator, @@ -170,7 +171,9 @@ fn initial_device_state(config: ConnectConfig, volume: u16) -> DeviceState { } } -fn volume_to_mixer(volume: u16) -> u16 { + + +fn calc_logarithmic_volume(volume: u16) -> u16 { // Volume conversion taken from https://www.dr-lex.be/info-stuff/volumecontrols.html#ideal2 // Convert the given volume [0..0xffff] to a dB gain // We assume a dB range of 60dB. @@ -192,6 +195,15 @@ fn volume_to_mixer(volume: u16) -> u16 { val } +fn volume_to_mixer(volume: u16, linear_volume: bool) -> u16 { + if linear_volume { + debug!("linear volume: {}", volume); + volume + } else { + calc_logarithmic_volume(volume) + } +} + impl Spirc { pub fn new( config: ConnectConfig, @@ -224,12 +236,15 @@ impl Spirc { let (cmd_tx, cmd_rx) = mpsc::unbounded(); let volume = config.volume as u16; + let linear_volume = config.linear_volume; + let device = initial_device_state(config, volume); - mixer.set_volume(volume_to_mixer(volume as u16)); + mixer.set_volume(volume_to_mixer(volume as u16, linear_volume)); let mut task = SpircTask { player: player, mixer: mixer, + linear_volume: linear_volume, sequence: SeqGenerator::new(1), @@ -518,7 +533,7 @@ impl SpircTask { MessageType::kMessageTypeVolume => { self.device.set_volume(frame.get_volume()); self.mixer - .set_volume(volume_to_mixer(frame.get_volume() as u16)); + .set_volume(volume_to_mixer(frame.get_volume() as u16, self.linear_volume)); self.notify(None); } @@ -642,7 +657,7 @@ impl SpircTask { volume = 0xFFFF; } self.device.set_volume(volume); - self.mixer.set_volume(volume_to_mixer(volume as u16)); + self.mixer.set_volume(volume_to_mixer(volume as u16, self.linear_volume)); } fn handle_volume_down(&mut self) { @@ -651,7 +666,7 @@ impl SpircTask { volume = 0; } self.device.set_volume(volume as u32); - self.mixer.set_volume(volume_to_mixer(volume as u16)); + self.mixer.set_volume(volume_to_mixer(volume as u16, self.linear_volume)); } fn handle_end_of_track(&mut self) { diff --git a/core/src/config.rs b/core/src/config.rs old mode 100644 new mode 100755 index 7d3a5aea..1e7ec9a7 --- a/core/src/config.rs +++ b/core/src/config.rs @@ -79,4 +79,5 @@ pub struct ConnectConfig { pub name: String, pub device_type: DeviceType, pub volume: i32, + pub linear_volume: bool, } diff --git a/src/main.rs b/src/main.rs old mode 100644 new mode 100755 index b71566d0..6a39544f --- a/src/main.rs +++ b/src/main.rs @@ -166,6 +166,11 @@ fn setup(args: &[String]) -> Setup { "normalisation-pregain", "Pregain (dB) applied by volume normalisation", "PREGAIN", + ) + .optflag( + "", + "linear-volume", + "increase volume linear instead of logarithmic.", ); let matches = match opts.parse(&args[1..]) { @@ -282,6 +287,7 @@ fn setup(args: &[String]) -> Setup { name: name, device_type: device_type, volume: initial_volume, + linear_volume: matches.opt_present("linear-volume") } };