aboutsummaryrefslogtreecommitdiffstats
path: root/src/volume.c
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2009-02-28 21:12:15 +0100
committerMax Kellermann <max@duempel.org>2009-02-28 21:12:15 +0100
commit82b081a6db88714aa2501e875e2e0f129f047d08 (patch)
treeded99fcd9427619469792ab9f600a322a778b7ca /src/volume.c
parentec4fd9fd88a10bfc88154e8e6791d5d69858a2e5 (diff)
downloadmpd-82b081a6db88714aa2501e875e2e0f129f047d08.tar.gz
mpd-82b081a6db88714aa2501e875e2e0f129f047d08.tar.xz
mpd-82b081a6db88714aa2501e875e2e0f129f047d08.zip
volume: throttle access to hardware mixers
On some hardware, reading the mixer value from hardware is an expensive operation, and MPD has to do it for every client. Throttle access to the hardware, cache the result for one second.
Diffstat (limited to 'src/volume.c')
-rw-r--r--src/volume.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/src/volume.c b/src/volume.c
index c5c1e83b2..3ff42b9be 100644
--- a/src/volume.c
+++ b/src/volume.c
@@ -27,6 +27,7 @@
#include <glib.h>
+#include <assert.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
@@ -45,8 +46,15 @@ const struct audio_output_plugin *default_mixer;
static int volume_mixer_type = VOLUME_MIXER_TYPE_HARDWARE;
static int volume_software_set = 100;
+/** the cached hardware mixer value; invalid if negative */
+static int last_hardware_volume = -1;
+/** the age of #last_hardware_volume */
+static GTimer *hardware_volume_timer;
+
void volume_finish(void)
{
+ if (volume_mixer_type == VOLUME_MIXER_TYPE_HARDWARE)
+ g_timer_destroy(hardware_volume_timer);
}
/**
@@ -148,6 +156,9 @@ void volume_init(void)
}
}
}
+
+ if (volume_mixer_type == VOLUME_MIXER_TYPE_HARDWARE)
+ hardware_volume_timer = g_timer_new();
}
static int hardware_volume_get(void)
@@ -155,6 +166,13 @@ static int hardware_volume_get(void)
int device, count;
int volume, volume_total, volume_ok;
+ assert(hardware_volume_timer != NULL);
+
+ if (last_hardware_volume >= 0 &&
+ g_timer_elapsed(hardware_volume_timer, NULL) < 1.0)
+ /* throttle access to hardware mixers */
+ return last_hardware_volume;
+
volume_total = 0;
volume_ok = 0;
@@ -168,7 +186,9 @@ static int hardware_volume_get(void)
}
if (volume_ok > 0) {
//return average
- return volume_total / volume_ok;
+ last_hardware_volume = volume_total / volume_ok;
+ g_timer_start(hardware_volume_timer);
+ return last_hardware_volume;
} else {
return -1;
}
@@ -224,6 +244,9 @@ static int hardware_volume_change(int change, int rel)
{
int device, count;
+ /* reset the cache */
+ last_hardware_volume = -1;
+
count = audio_output_count();
for (device=0; device<count ;device++) {
mixer_control_setvol(device, change, rel);