aboutsummaryrefslogtreecommitdiffstats
path: root/src/mixer_all.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mixer_all.c')
-rw-r--r--src/mixer_all.c100
1 files changed, 83 insertions, 17 deletions
diff --git a/src/mixer_all.c b/src/mixer_all.c
index 252cb61ab..ffe610b91 100644
--- a/src/mixer_all.c
+++ b/src/mixer_all.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2009 The Music Player Daemon Project
+ * Copyright (C) 2003-2010 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -17,11 +17,15 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#include "config.h"
#include "mixer_all.h"
#include "mixer_control.h"
#include "output_all.h"
#include "output_plugin.h"
#include "output_internal.h"
+#include "pcm_volume.h"
+#include "mixer_api.h"
+#include "mixer_list.h"
#include <glib.h>
@@ -35,6 +39,8 @@ output_mixer_get_volume(unsigned i)
{
struct audio_output *output;
struct mixer *mixer;
+ int volume;
+ GError *error = NULL;
assert(i < audio_output_count());
@@ -46,7 +52,14 @@ output_mixer_get_volume(unsigned i)
if (mixer == NULL)
return -1;
- return mixer_get_volume(mixer);
+ volume = mixer_get_volume(mixer, &error);
+ if (volume < 0 && error != NULL) {
+ g_warning("Failed to read mixer for '%s': %s",
+ output->name, error->message);
+ g_error_free(error);
+ }
+
+ return volume;
}
int
@@ -70,12 +83,15 @@ mixer_all_get_volume(void)
}
static bool
-output_mixer_set_volume(unsigned i, int volume, bool relative)
+output_mixer_set_volume(unsigned i, unsigned volume)
{
struct audio_output *output;
struct mixer *mixer;
+ bool success;
+ GError *error = NULL;
assert(i < audio_output_count());
+ assert(volume <= 100);
output = audio_output_get(i);
if (!output->enabled)
@@ -85,31 +101,81 @@ output_mixer_set_volume(unsigned i, int volume, bool relative)
if (mixer == NULL)
return false;
- if (relative) {
- int prev = mixer_get_volume(mixer);
- if (prev < 0)
- return false;
-
- volume += prev;
+ success = mixer_set_volume(mixer, volume, &error);
+ if (!success && error != NULL) {
+ g_warning("Failed to set mixer for '%s': %s",
+ output->name, error->message);
+ g_error_free(error);
}
- if (volume > 100)
- volume = 100;
- else if (volume < 0)
- volume = 0;
-
- return mixer_set_volume(mixer, volume);
+ return success;
}
bool
-mixer_all_set_volume(int volume, bool relative)
+mixer_all_set_volume(unsigned volume)
{
bool success = false;
unsigned count = audio_output_count();
+ assert(volume <= 100);
+
for (unsigned i = 0; i < count; i++)
- success = output_mixer_set_volume(i, volume, relative)
+ success = output_mixer_set_volume(i, volume)
|| success;
return success;
}
+
+static int
+output_mixer_get_software_volume(unsigned i)
+{
+ struct audio_output *output;
+ struct mixer *mixer;
+
+ assert(i < audio_output_count());
+
+ output = audio_output_get(i);
+ if (!output->enabled)
+ return -1;
+
+ mixer = output->mixer;
+ if (mixer == NULL || mixer->plugin != &software_mixer_plugin)
+ return -1;
+
+ return mixer_get_volume(mixer, NULL);
+}
+
+int
+mixer_all_get_software_volume(void)
+{
+ unsigned count = audio_output_count(), ok = 0;
+ int volume, total = 0;
+
+ for (unsigned i = 0; i < count; i++) {
+ volume = output_mixer_get_software_volume(i);
+ if (volume >= 0) {
+ total += volume;
+ ++ok;
+ }
+ }
+
+ if (ok == 0)
+ return -1;
+
+ return total / ok;
+}
+
+void
+mixer_all_set_software_volume(unsigned volume)
+{
+ unsigned count = audio_output_count();
+
+ assert(volume <= PCM_VOLUME_1);
+
+ for (unsigned i = 0; i < count; i++) {
+ struct audio_output *output = audio_output_get(i);
+ if (output->mixer != NULL &&
+ output->mixer->plugin == &software_mixer_plugin)
+ mixer_set_volume(output->mixer, volume, NULL);
+ }
+}