MixerAll.cxx 3.65 KB
Newer Older
1
/*
Max Kellermann's avatar
Max Kellermann committed
2
 * Copyright (C) 2003-2014 The Music Player Daemon Project
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
 * http://www.musicpd.org
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

20
#include "config.h"
21
#include "MixerAll.hxx"
22 23 24
#include "MixerControl.hxx"
#include "MixerInternal.hxx"
#include "MixerList.hxx"
25
#include "OutputAll.hxx"
26
#include "pcm/Volume.hxx"
Max Kellermann's avatar
Max Kellermann committed
27
#include "OutputInternal.hxx"
28
#include "util/Error.hxx"
29 30
#include "util/Domain.hxx"
#include "Log.hxx"
31

32 33
#include <assert.h>

34
static constexpr Domain mixer_domain("mixer");
35

36 37 38 39
static int
output_mixer_get_volume(unsigned i)
{
	struct audio_output *output;
40
	int volume;
41 42 43 44 45 46 47

	assert(i < audio_output_count());

	output = audio_output_get(i);
	if (!output->enabled)
		return -1;

48
	Mixer *mixer = output->mixer;
49
	if (mixer == nullptr)
50 51
		return -1;

52 53 54
	Error error;
	volume = mixer_get_volume(mixer, error);
	if (volume < 0 && error.IsDefined())
55 56 57
		FormatError(error,
			    "Failed to read mixer for '%s'",
			    output->name);
58 59

	return volume;
60 61
}

62 63 64 65 66 67 68
int
mixer_all_get_volume(void)
{
	unsigned count = audio_output_count(), ok = 0;
	int volume, total = 0;

	for (unsigned i = 0; i < count; i++) {
69 70
		volume = output_mixer_get_volume(i);
		if (volume >= 0) {
71 72 73 74 75 76 77 78 79 80 81
			total += volume;
			++ok;
		}
	}

	if (ok == 0)
		return -1;

	return total / ok;
}

82
static bool
83
output_mixer_set_volume(unsigned i, unsigned volume)
84 85
{
	struct audio_output *output;
86
	bool success;
87 88

	assert(i < audio_output_count());
89
	assert(volume <= 100);
90 91 92 93 94

	output = audio_output_get(i);
	if (!output->enabled)
		return false;

95
	Mixer *mixer = output->mixer;
96
	if (mixer == nullptr)
97 98
		return false;

99 100 101
	Error error;
	success = mixer_set_volume(mixer, volume, error);
	if (!success && error.IsDefined())
102 103 104
		FormatError(error,
			    "Failed to set mixer for '%s'",
			    output->name);
105 106

	return success;
107 108
}

109
bool
110
mixer_all_set_volume(unsigned volume)
111 112 113 114
{
	bool success = false;
	unsigned count = audio_output_count();

115 116
	assert(volume <= 100);

117
	for (unsigned i = 0; i < count; i++)
118
		success = output_mixer_set_volume(i, volume)
119
			|| success;
120 121 122

	return success;
}
123 124 125 126 127 128 129 130 131 132 133 134

static int
output_mixer_get_software_volume(unsigned i)
{
	struct audio_output *output;

	assert(i < audio_output_count());

	output = audio_output_get(i);
	if (!output->enabled)
		return -1;

135
	Mixer *mixer = output->mixer;
136
	if (mixer == nullptr || !mixer->IsPlugin(software_mixer_plugin))
137 138
		return -1;

139
	return mixer_get_volume(mixer, IgnoreError());
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
}

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);
171
		if (output->mixer != nullptr &&
172
		    output->mixer->plugin == &software_mixer_plugin)
173
			mixer_set_volume(output->mixer, volume, IgnoreError());
174 175
	}
}