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 selem = self.selem();
|
||||||
let range = self.get_volume_range();
|
let volume = selem.get_playback_volume(FrontRight);
|
||||||
let volume = selem.get_playback_volume(FrontRight).map(|v| {
|
|
||||||
return vol_to_percent(v, range);
|
|
||||||
});
|
|
||||||
|
|
||||||
return volume.from_err();
|
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 selem = self.selem();
|
||||||
|
return selem.set_playback_volume_all(new_vol).from_err();
|
||||||
let range = self.get_volume_range();
|
|
||||||
selem.set_playback_volume_all(percent_to_vol(new_vol, range))?;
|
|
||||||
|
|
||||||
return Ok(());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
67
src/audio.rs
67
src/audio.rs
@ -6,6 +6,7 @@ use std::cell::Ref;
|
|||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::f64;
|
use std::f64;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use support_audio::*;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -152,7 +153,9 @@ impl Audio {
|
|||||||
|
|
||||||
|
|
||||||
pub fn vol(&self) -> Result<f64> {
|
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();
|
let mut rc = self.last_action_timestamp.borrow_mut();
|
||||||
*rc = glib::get_monotonic_time();
|
*rc = glib::get_monotonic_time();
|
||||||
@ -194,10 +197,15 @@ impl Audio {
|
|||||||
.unwrap(),
|
.unwrap(),
|
||||||
new_vol,
|
new_vol,
|
||||||
user);
|
user);
|
||||||
|
|
||||||
|
let alsa_vol = percent_to_vol(new_vol,
|
||||||
|
self.acard.borrow().get_volume_range(),
|
||||||
|
dir)?;
|
||||||
self.acard
|
self.acard
|
||||||
.borrow()
|
.borrow()
|
||||||
.set_vol(new_vol)?;
|
.set_vol(alsa_vol)?;
|
||||||
|
|
||||||
|
// TODO: only invoke handlers if volume did not change
|
||||||
invoke_handlers(&self.handlers.borrow(),
|
invoke_handlers(&self.handlers.borrow(),
|
||||||
AudioSignal::ValuesChanged,
|
AudioSignal::ValuesChanged,
|
||||||
user);
|
user);
|
||||||
@ -205,64 +213,19 @@ impl Audio {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO: refactor with decrease_vol
|
|
||||||
pub fn increase_vol(&self, user: AudioUser) -> Result<()> {
|
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 old_vol = self.vol()?;
|
||||||
let (min, max) = self.acard.borrow().get_volume_range();
|
let new_vol = old_vol + (self.scroll_step.get() as f64);
|
||||||
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;
|
|
||||||
|
|
||||||
debug!("Increase vol on card {:?} and chan {:?} by {:?} to {:?}",
|
return self.set_vol(new_vol, user, VolDir::Up);
|
||||||
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(());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn decrease_vol(&self, user: AudioUser) -> Result<()> {
|
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 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 {:?}",
|
return self.set_vol(new_vol, user, VolDir::Down);
|
||||||
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(());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -147,16 +147,3 @@ pub fn selem_is_playable(selem: &Selem) -> bool {
|
|||||||
return selem.has_playback_volume();
|
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::*;
|
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,
|
pub fn audio_reload(audio: &Audio,
|
||||||
prefs: &Prefs,
|
prefs: &Prefs,
|
||||||
@ -13,3 +38,20 @@ pub fn audio_reload(audio: &Audio,
|
|||||||
// TODO: is this clone safe?
|
// TODO: is this clone safe?
|
||||||
return audio.switch_acard(Some(card.clone()), Some(channel.clone()), user);
|
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 prefs::*;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use support_audio::*;
|
||||||
use support_cmd::*;
|
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) {
|
fn on_vol_scale_value_changed(appstate: &AppS) {
|
||||||
let audio = &appstate.audio;
|
let audio = &appstate.audio;
|
||||||
|
let old_vol = try_w!(audio.vol());
|
||||||
|
|
||||||
let val = appstate.gui
|
let val = appstate.gui
|
||||||
.popup_window
|
.popup_window
|
||||||
.vol_scale
|
.vol_scale
|
||||||
.get_value();
|
.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")),
|
.unwrap_or(String::from("Master")),
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO don't convert like that
|
// TODO save raw values?
|
||||||
let vol_meter_color = VolColor {
|
let vol_meter_color = VolColor {
|
||||||
red: (self.vol_meter_color_button.get_rgba().red * 255.0) as u8,
|
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,
|
green: (self.vol_meter_color_button.get_rgba().green * 255.0) as u8,
|
||||||
|
Loading…
Reference in New Issue
Block a user