mirror of
https://github.com/librespot-org/librespot.git
synced 2024-12-18 17:11:53 +00:00
Merge pull request #10 from thekr1s/progressive-voume-control
Change volume control to implement logarithmic scaling.
This commit is contained in:
commit
91647ab2dd
1 changed files with 31 additions and 8 deletions
39
src/spirc.rs
39
src/spirc.rs
|
@ -15,6 +15,7 @@ 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;
|
||||||
|
|
||||||
|
@ -120,6 +121,29 @@ fn initial_device_state(config: ConnectConfig, volume: u16) -> DeviceState {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn volume_to_mixer(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.
|
||||||
|
// Use the equatation: a * exp(b * x)
|
||||||
|
// in which a = IDEAL_FACTOR, b = 1/1000
|
||||||
|
const IDEAL_FACTOR: f64 = 6.908;
|
||||||
|
let normalized_volume = volume as f64 / std::u16::MAX as f64; // To get a value between 0 and 1
|
||||||
|
|
||||||
|
let mut val = std::u16::MAX;
|
||||||
|
// Prevent val > std::u16::MAX due to rounding errors
|
||||||
|
if normalized_volume < 0.999 {
|
||||||
|
let new_volume = (normalized_volume * IDEAL_FACTOR).exp() / 1000.0;
|
||||||
|
val = (new_volume * std::u16::MAX as f64) as u16;
|
||||||
|
}
|
||||||
|
|
||||||
|
debug!("input volume:{} to mixer: {}", volume, val);
|
||||||
|
|
||||||
|
// return the scale factor (0..0xffff) (equivalent to a voltage multiplier).
|
||||||
|
val
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
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)
|
||||||
|
@ -145,7 +169,7 @@ impl Spirc {
|
||||||
|
|
||||||
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));
|
||||||
|
|
||||||
let mut task = SpircTask {
|
let mut task = SpircTask {
|
||||||
player: player,
|
player: player,
|
||||||
|
@ -437,9 +461,8 @@ 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(volume_to_mixer(frame.get_volume() as u16));
|
||||||
self.mixer.set_volume(frame.get_volume() as u16);
|
|
||||||
self.notify(None);
|
self.notify(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -534,21 +557,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));
|
||||||
}
|
}
|
||||||
|
|
||||||
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_end_of_track(&mut self) {
|
fn handle_end_of_track(&mut self) {
|
||||||
|
|
Loading…
Reference in a new issue