From 580e2630eaf3f0552543b7967c30e8d0ee76af39 Mon Sep 17 00:00:00 2001 From: Julian Ospald Date: Tue, 11 Jul 2017 21:48:40 +0200 Subject: [PATCH] Make vol change more accurate --- src/alsa_card.rs | 15 +++------- src/audio.rs | 67 ++++++++++-------------------------------- src/support_alsa.rs | 13 -------- src/support_audio.rs | 42 ++++++++++++++++++++++++++ src/ui_popup_window.rs | 6 +++- src/ui_prefs_dialog.rs | 2 +- 6 files changed, 67 insertions(+), 78 deletions(-) diff --git a/src/alsa_card.rs b/src/alsa_card.rs index ee1952f8a..81c0b8a22 100644 --- a/src/alsa_card.rs +++ b/src/alsa_card.rs @@ -121,24 +121,17 @@ impl AlsaCard { } - pub fn get_vol(&self) -> Result { + pub fn get_vol(&self) -> Result { 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(); } diff --git a/src/audio.rs b/src/audio.rs index 14af81807..b5709b905 100644 --- a/src/audio.rs +++ b/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 { - 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); } diff --git a/src/support_alsa.rs b/src/support_alsa.rs index 046678658..c249308d1 100644 --- a/src/support_alsa.rs +++ b/src/support_alsa.rs @@ -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; -} diff --git a/src/support_audio.rs b/src/support_audio.rs index 25abeb0ff..9458b75b3 100644 --- a/src/support_audio.rs +++ b/src/support_audio.rs @@ -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 { + 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 { + 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); +} diff --git a/src/ui_popup_window.rs b/src/ui_popup_window.rs index 64c52edb5..9fb95ef9f 100644 --- a/src/ui_popup_window.rs +++ b/src/ui_popup_window.rs @@ -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)); } diff --git a/src/ui_prefs_dialog.rs b/src/ui_prefs_dialog.rs index 7d2a476c8..14f5d2fcf 100644 --- a/src/ui_prefs_dialog.rs +++ b/src/ui_prefs_dialog.rs @@ -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,