Make vol change more accurate

This commit is contained in:
Julian Ospald 2017-07-11 21:48:40 +02:00
parent e51e53f4ea
commit 580e2630ea
No known key found for this signature in database
GPG Key ID: 511B62C09D50CD28
6 changed files with 67 additions and 78 deletions

View File

@ -121,24 +121,17 @@ impl AlsaCard {
}
pub fn get_vol(&self) -> Result<f64> {
pub fn get_vol(&self) -> Result<i64> {
let selem = self.selem();
let range = self.get_volume_range();
let volume = selem.get_playback_volume(FrontRight).map(|v| {
return vol_to_percent(v, range);
});
let volume = selem.get_playback_volume(FrontRight);
return volume.from_err();
}
pub fn set_vol(&self, new_vol: f64) -> Result<()> {
pub fn set_vol(&self, new_vol: i64) -> Result<()> {
let selem = self.selem();
let range = self.get_volume_range();
selem.set_playback_volume_all(percent_to_vol(new_vol, range))?;
return Ok(());
return selem.set_playback_volume_all(new_vol).from_err();
}

View File

@ -6,6 +6,7 @@ use std::cell::Ref;
use std::cell::RefCell;
use std::f64;
use std::rc::Rc;
use support_audio::*;
@ -152,7 +153,9 @@ impl Audio {
pub fn vol(&self) -> Result<f64> {
return self.acard.borrow().get_vol();
let alsa_vol = self.acard.borrow().get_vol()?;
return vol_to_percent(alsa_vol,
self.acard.borrow().get_volume_range());
}
@ -172,7 +175,7 @@ impl Audio {
}
pub fn set_vol(&self, new_vol: f64, user: AudioUser) -> Result<()> {
pub fn set_vol(&self, new_vol: f64, user: AudioUser, dir: VolDir) -> Result<()> {
{
let mut rc = self.last_action_timestamp.borrow_mut();
*rc = glib::get_monotonic_time();
@ -194,10 +197,15 @@ impl Audio {
.unwrap(),
new_vol,
user);
let alsa_vol = percent_to_vol(new_vol,
self.acard.borrow().get_volume_range(),
dir)?;
self.acard
.borrow()
.set_vol(new_vol)?;
.set_vol(alsa_vol)?;
// TODO: only invoke handlers if volume did not change
invoke_handlers(&self.handlers.borrow(),
AudioSignal::ValuesChanged,
user);
@ -205,64 +213,19 @@ impl Audio {
}
// TODO: refactor with decrease_vol
pub fn increase_vol(&self, user: AudioUser) -> Result<()> {
{
let mut rc = self.last_action_timestamp.borrow_mut();
*rc = glib::get_monotonic_time();
}
let old_vol = self.vol()?;
let (min, max) = self.acard.borrow().get_volume_range();
ensure!(mn >= max, "Invalid playback volume range: [{} - {}]",
min,
max);
let new_vol = f64::ceil(old_vol + (self.scroll_step.get() as f64)) + min as f64;
let new_vol = old_vol + (self.scroll_step.get() as f64);
debug!("Increase vol on card {:?} and chan {:?} by {:?} to {:?}",
self.acard
.borrow()
.card_name()
.unwrap(),
self.acard
.borrow()
.chan_name()
.unwrap(),
(new_vol - old_vol),
new_vol);
self.set_vol(new_vol, user)?;
return Ok(());
return self.set_vol(new_vol, user, VolDir::Up);
}
pub fn decrease_vol(&self, user: AudioUser) -> Result<()> {
{
let mut rc = self.last_action_timestamp.borrow_mut();
*rc = glib::get_monotonic_time();
}
let (min, max) = self.acard.borrow().get_volume_range();
ensure!(min >= max, "Invalid playback volume range: [{} - {}]",
mn,
max);
let old_vol = self.vol()?;
let new_vol = old_vol - (self.scroll_step.get() as f64) + min as f64;
let new_vol = old_vol - (self.scroll_step.get() as f64);
debug!("Decrease vol on card {:?} and chan {:?} by {:?} to {:?}",
self.acard
.borrow()
.card_name()
.unwrap(),
self.acard
.borrow()
.chan_name()
.unwrap(),
(new_vol - old_vol),
new_vol);
self.set_vol(new_vol, user)?;
return Ok(());
return self.set_vol(new_vol, user, VolDir::Down);
}

View File

@ -147,16 +147,3 @@ pub fn selem_is_playable(selem: &Selem) -> bool {
return selem.has_playback_volume();
}
pub fn vol_to_percent(vol: i64, range: (i64, i64)) -> f64 {
let (min, max) = range;
return ((vol - min) as f64) / ((max - min) as f64) * 100.0;
}
pub fn percent_to_vol(vol: f64, range: (i64, i64)) -> i64 {
let (min, max) = range;
let _v = vol / 100.0 * ((max - min) as f64) + (min as f64);
/* TODO: precision? Use direction. */
return _v as i64;
}

View File

@ -3,6 +3,31 @@ use errors::*;
use prefs::*;
pub enum VolDir {
Up,
Down,
Unknown,
}
pub fn vol_change_to_voldir(old: f64, new: f64) -> VolDir {
if old < new {
return VolDir::Up;
} else if old > new {
return VolDir::Down;
} else {
return VolDir::Unknown;
}
}
pub fn lrint(v: f64, dir: VolDir) -> f64 {
match dir {
VolDir::Up => v.ceil(),
VolDir::Down => v.floor(),
_ => v,
}
}
pub fn audio_reload(audio: &Audio,
prefs: &Prefs,
@ -13,3 +38,20 @@ pub fn audio_reload(audio: &Audio,
// TODO: is this clone safe?
return audio.switch_acard(Some(card.clone()), Some(channel.clone()), user);
}
pub fn vol_to_percent(vol: i64, range: (i64, i64)) -> Result<f64> {
let (min, max) = range;
ensure!(min < max, "Invalid playback volume range [{} - {}]", min, max);
let perc = ((vol - min) as f64) / ((max - min) as f64) * 100.0;
return Ok(perc);
}
pub fn percent_to_vol(vol: f64, range: (i64, i64), dir: VolDir) -> Result<i64> {
let (min, max) = range;
ensure!(min < max, "Invalid playback volume range [{} - {}]", min, max);
let _v = lrint(vol / 100.0 * ((max - min) as f64), dir) + (min as f64);
return Ok(_v as i64);
}

View File

@ -12,6 +12,7 @@ use gtk;
use prefs::*;
use std::cell::Cell;
use std::rc::Rc;
use support_audio::*;
use support_cmd::*;
@ -232,13 +233,16 @@ fn on_popup_window_event(w: &gtk::Window, e: &gdk::Event) -> gtk::Inhibit {
fn on_vol_scale_value_changed(appstate: &AppS) {
let audio = &appstate.audio;
let old_vol = try_w!(audio.vol());
let val = appstate.gui
.popup_window
.vol_scale
.get_value();
try_w!(audio.set_vol(val, AudioUser::Popup));
let dir = vol_change_to_voldir(old_vol, val);
try_w!(audio.set_vol(val, AudioUser::Popup, dir));
}

View File

@ -173,7 +173,7 @@ impl PrefsDialog {
.unwrap_or(String::from("Master")),
};
// TODO don't convert like that
// TODO save raw values?
let vol_meter_color = VolColor {
red: (self.vol_meter_color_button.get_rgba().red * 255.0) as u8,
green: (self.vol_meter_color_button.get_rgba().green * 255.0) as u8,