Merge pull request #188 from thekr1s/linear-volume-control

Add optional linear volume contol
This commit is contained in:
Sasha Hilton 2018-03-15 23:43:44 +01:00 committed by GitHub
commit 085f76162f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 30 additions and 6 deletions

View file

@ -24,6 +24,7 @@ use std::time::{SystemTime, UNIX_EPOCH};
pub struct SpircTask {
player: Player,
mixer: Box<Mixer>,
linear_volume: bool,
sequence: SeqGenerator<u32>,
@ -170,7 +171,7 @@ 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 +193,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 +234,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),
@ -517,8 +530,10 @@ impl SpircTask {
MessageType::kMessageTypeVolume => {
self.device.set_volume(frame.get_volume());
self.mixer
.set_volume(volume_to_mixer(frame.get_volume() as u16));
self.mixer.set_volume(volume_to_mixer(
frame.get_volume() as u16,
self.linear_volume,
));
self.notify(None);
}
@ -642,7 +657,8 @@ 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 +667,8 @@ 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) {

View file

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

View file

@ -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"),
}
};