Make vol change more accurate
This commit is contained in:
parent
e51e53f4ea
commit
580e2630ea
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
67
src/audio.rs
67
src/audio.rs
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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: >k::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));
|
||||
}
|
||||
|
||||
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user