From 967af603270246f1c97e11b8bad6a0eb65c81318 Mon Sep 17 00:00:00 2001
From: Stefano Miccoli <stefano.miccoli@polimi.it>
Date: Tue, 12 Dec 2017 23:42:42 +0100
Subject: [PATCH] =?UTF-8?q?rounds=20alsa=20HW=20mixer=20volume=20towards?=
 =?UTF-8?q?=20=C2=B1=E2=88=9E=20depending=20on=20sgn(=E2=88=86=20vol)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This alleviates a problem in which 'volume +1' cannot be undo by
'volume -1' when using alsa hw mixer.

Closes #104
---
 NEWS                                  | 2 ++
 src/mixer/plugins/AlsaMixerPlugin.cxx | 4 +++-
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/NEWS b/NEWS
index 6f72320dc..5b7c83cfb 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,8 @@
 ver 0.20.13 (not yet released)
 * output
   - osx: set up ring buffer to hold at least 100ms
+* mixer
+  - alsa: fix rounding errors
 * database
   - simple: don't purge mount points on update/rescan
   - simple: fix "mount" bug caused by bad compiler optimization
diff --git a/src/mixer/plugins/AlsaMixerPlugin.cxx b/src/mixer/plugins/AlsaMixerPlugin.cxx
index 8012ca2fb..c5ef0dcef 100644
--- a/src/mixer/plugins/AlsaMixerPlugin.cxx
+++ b/src/mixer/plugins/AlsaMixerPlugin.cxx
@@ -292,7 +292,9 @@ AlsaMixer::SetVolume(unsigned volume)
 {
 	assert(handle != nullptr);
 
-	int err = set_normalized_playback_volume(elem, 0.01*volume, 1);
+	double cur = get_normalized_playback_volume(elem, SND_MIXER_SCHN_FRONT_LEFT);
+	int delta = volume - lrint(100.*cur);
+	int err = set_normalized_playback_volume(elem, cur + 0.01*delta, delta);
 	if (err < 0)
 		throw FormatRuntimeError("failed to set ALSA volume: %s",
 					 snd_strerror(err));