diff options
author | Max Kellermann <max@duempel.org> | 2009-02-28 21:12:15 +0100 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2009-02-28 21:12:15 +0100 |
commit | 82b081a6db88714aa2501e875e2e0f129f047d08 (patch) | |
tree | ded99fcd9427619469792ab9f600a322a778b7ca /src/volume.c | |
parent | ec4fd9fd88a10bfc88154e8e6791d5d69858a2e5 (diff) | |
download | mpd-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.c | 25 |
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); |