aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/mixer/alsa_mixer.c1
-rw-r--r--src/mixer/oss_mixer.c1
-rw-r--r--src/mixer_api.c1
-rw-r--r--src/mixer_api.h5
-rw-r--r--src/mixer_control.c41
-rw-r--r--src/mixer_control.h7
-rw-r--r--src/mixer_plugin.h7
-rw-r--r--src/output_control.c3
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);