diff options
-rw-r--r-- | src/mixer/alsa_mixer.c | 1 | ||||
-rw-r--r-- | src/mixer/oss_mixer.c | 1 | ||||
-rw-r--r-- | src/mixer_api.c | 1 | ||||
-rw-r--r-- | src/mixer_api.h | 5 | ||||
-rw-r--r-- | src/mixer_control.c | 41 | ||||
-rw-r--r-- | src/mixer_control.h | 7 | ||||
-rw-r--r-- | src/mixer_plugin.h | 7 | ||||
-rw-r--r-- | src/output_control.c | 3 |
8 files changed, 61 insertions, 5 deletions
diff --git a/src/mixer/alsa_mixer.c b/src/mixer/alsa_mixer.c index ea113b861..c5aac13d4 100644 --- a/src/mixer/alsa_mixer.c +++ b/src/mixer/alsa_mixer.c @@ -230,4 +230,5 @@ const struct mixer_plugin alsa_mixer = { .close = alsa_mixer_close, .get_volume = alsa_mixer_get_volume, .set_volume = alsa_mixer_set_volume, + .global = true, }; diff --git a/src/mixer/oss_mixer.c b/src/mixer/oss_mixer.c index 8789ac00c..13e325823 100644 --- a/src/mixer/oss_mixer.c +++ b/src/mixer/oss_mixer.c @@ -198,4 +198,5 @@ const struct mixer_plugin oss_mixer = { .close = oss_mixer_close, .get_volume = oss_mixer_get_volume, .set_volume = oss_mixer_set_volume, + .global = true, }; diff --git a/src/mixer_api.c b/src/mixer_api.c index aaa250d33..50bf8c1b1 100644 --- a/src/mixer_api.c +++ b/src/mixer_api.c @@ -27,4 +27,5 @@ mixer_init(struct mixer *mixer, const struct mixer_plugin *plugin) { mixer->plugin = plugin; mixer->mutex = g_mutex_new(); + mixer->open = false; } diff --git a/src/mixer_api.h b/src/mixer_api.h index 9af49cd87..344d04453 100644 --- a/src/mixer_api.h +++ b/src/mixer_api.h @@ -33,6 +33,11 @@ struct mixer { * implementation, so plugins don't have to deal with that. */ GMutex *mutex; + + /** + * Is the mixer device currently open? + */ + bool open; }; void diff --git a/src/mixer_control.c b/src/mixer_control.c index f1d67a078..4e86a9aa2 100644 --- a/src/mixer_control.c +++ b/src/mixer_control.c @@ -76,7 +76,12 @@ mixer_open(struct mixer *mixer) assert(mixer->plugin != NULL); g_mutex_lock(mixer->mutex); - success = mixer->plugin->open(mixer); + + if (mixer->open) + success = true; + else + success = mixer->open = mixer->plugin->open(mixer); + g_mutex_unlock(mixer->mutex); return success; @@ -89,10 +94,22 @@ mixer_close(struct mixer *mixer) assert(mixer->plugin != NULL); g_mutex_lock(mixer->mutex); - mixer->plugin->close(mixer); + + if (mixer->open) { + mixer->plugin->close(mixer); + mixer->open = false; + } + g_mutex_unlock(mixer->mutex); } +void +mixer_auto_close(struct mixer *mixer) +{ + if (!mixer->plugin->global) + mixer_close(mixer); +} + int mixer_get_volume(struct mixer *mixer) { @@ -100,8 +117,16 @@ mixer_get_volume(struct mixer *mixer) assert(mixer != NULL); + if (mixer->plugin->global && !mixer_open(mixer)) + return -1; + g_mutex_lock(mixer->mutex); - volume = mixer->plugin->get_volume(mixer); + + if (mixer->open) { + volume = mixer->plugin->get_volume(mixer); + } else + volume = -1; + g_mutex_unlock(mixer->mutex); return volume; @@ -114,8 +139,16 @@ mixer_set_volume(struct mixer *mixer, unsigned volume) assert(mixer != NULL); + if (mixer->plugin->global && !mixer_open(mixer)) + return false; + g_mutex_lock(mixer->mutex); - success = mixer->plugin->set_volume(mixer, volume); + + if (mixer->open) { + success = mixer->plugin->set_volume(mixer, volume); + } else + success = false; + g_mutex_unlock(mixer->mutex); return success; diff --git a/src/mixer_control.h b/src/mixer_control.h index b126d8c81..0f73e8f75 100644 --- a/src/mixer_control.h +++ b/src/mixer_control.h @@ -46,6 +46,13 @@ mixer_open(struct mixer *mixer); void mixer_close(struct mixer *mixer); +/** + * Close the mixer unless the plugin's "global" flag is set. This is + * called when the #audio_output is closed. + */ +void +mixer_auto_close(struct mixer *mixer); + int mixer_get_volume(struct mixer *mixer); diff --git a/src/mixer_plugin.h b/src/mixer_plugin.h index 8e9bb5804..2b9b440e5 100644 --- a/src/mixer_plugin.h +++ b/src/mixer_plugin.h @@ -68,6 +68,13 @@ struct mixer_plugin { * @return true on success */ bool (*set_volume)(struct mixer *mixer, unsigned volume); + + /** + * If true, then the mixer is automatically opened, even if + * its audio output is not open. If false, then the mixer is + * disabled as long as its audio output is closed. + */ + bool global; }; #endif diff --git a/src/output_control.c b/src/output_control.c index d19ce3583..4131594f0 100644 --- a/src/output_control.c +++ b/src/output_control.c @@ -22,6 +22,7 @@ #include "output_internal.h" #include "output_thread.h" #include "mixer_control.h" +#include "mixer_plugin.h" #include <assert.h> #include <stdlib.h> @@ -149,7 +150,7 @@ void audio_output_close(struct audio_output *ao) assert(!ao->open || ao->fail_timer == NULL); if (ao->mixer != NULL) - mixer_close(ao->mixer); + mixer_auto_close(ao->mixer); if (ao->open) ao_command(ao, AO_COMMAND_CLOSE); |