summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am1
-rw-r--r--src/GlobalEvents.hxx3
-rw-r--r--src/Main.cxx2
-rw-r--r--src/Partition.cxx11
-rw-r--r--src/Partition.hxx8
-rw-r--r--src/mixer/Listener.hxx34
-rw-r--r--src/mixer/MixerControl.cxx3
-rw-r--r--src/mixer/MixerControl.hxx2
-rw-r--r--src/mixer/MixerInternal.hxx8
-rw-r--r--src/mixer/MixerPlugin.hxx2
-rw-r--r--src/mixer/Volume.cxx16
-rw-r--r--src/mixer/Volume.hxx3
-rw-r--r--src/mixer/plugins/AlsaMixerPlugin.cxx22
-rw-r--r--src/mixer/plugins/OssMixerPlugin.cxx6
-rw-r--r--src/mixer/plugins/PulseMixerPlugin.cxx15
-rw-r--r--src/mixer/plugins/RoarMixerPlugin.cxx9
-rw-r--r--src/mixer/plugins/SoftwareMixerPlugin.cxx7
-rw-r--r--src/mixer/plugins/WinmmMixerPlugin.cxx7
-rw-r--r--src/output/Init.cxx14
-rw-r--r--src/output/Internal.hxx5
-rw-r--r--src/output/MultipleOutputs.cxx18
-rw-r--r--src/output/MultipleOutputs.hxx5
-rw-r--r--test/read_mixer.cxx7
-rw-r--r--test/run_output.cxx10
24 files changed, 144 insertions, 74 deletions
diff --git a/Makefile.am b/Makefile.am
index 6a985e76f..8e70ff290 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1033,6 +1033,7 @@ MIXER_LIBS = \
$(PULSE_LIBS)
MIXER_API_SRC = \
+ src/mixer/Listener.hxx \
src/mixer/MixerPlugin.hxx \
src/mixer/MixerList.hxx \
src/mixer/MixerControl.cxx src/mixer/MixerControl.hxx \
diff --git a/src/GlobalEvents.hxx b/src/GlobalEvents.hxx
index 9b678a4f6..a9df03724 100644
--- a/src/GlobalEvents.hxx
+++ b/src/GlobalEvents.hxx
@@ -42,9 +42,6 @@ namespace GlobalEvents {
/** the current song's tag has changed */
TAG,
- /** a hardware mixer plugin has detected a change */
- MIXER,
-
#ifdef WIN32
/** shutdown requested */
SHUTDOWN,
diff --git a/src/Main.cxx b/src/Main.cxx
index de74925e5..e52b40d58 100644
--- a/src/Main.cxx
+++ b/src/Main.cxx
@@ -33,7 +33,6 @@
#include "client/ClientList.hxx"
#include "command/AllCommands.hxx"
#include "Partition.hxx"
-#include "mixer/Volume.hxx"
#include "tag/TagConfig.hxx"
#include "ReplayGainConfig.hxx"
#include "Idle.hxx"
@@ -469,7 +468,6 @@ int mpd_main(int argc, char *argv[])
command_init();
initialize_decoder_and_player();
- volume_init();
initAudioConfig();
instance->partition->outputs.Configure(*instance->event_loop,
instance->partition->pc);
diff --git a/src/Partition.cxx b/src/Partition.cxx
index 4d4504338..512912f96 100644
--- a/src/Partition.cxx
+++ b/src/Partition.cxx
@@ -21,6 +21,8 @@
#include "Partition.hxx"
#include "DetachedSong.hxx"
#include "output/MultipleOutputs.hxx"
+#include "mixer/Volume.hxx"
+#include "Idle.hxx"
#ifdef ENABLE_DATABASE
@@ -47,3 +49,12 @@ Partition::SyncWithPlayer()
{
playlist.SyncWithPlayer(pc);
}
+
+void
+Partition::OnMixerVolumeChanged(gcc_unused Mixer &mixer, gcc_unused int volume)
+{
+ InvalidateHardwareVolume();
+
+ /* notify clients */
+ idle_add(IDLE_MIXER);
+}
diff --git a/src/Partition.hxx b/src/Partition.hxx
index 57dc9a5f4..cbdce2e86 100644
--- a/src/Partition.hxx
+++ b/src/Partition.hxx
@@ -22,6 +22,7 @@
#include "Playlist.hxx"
#include "output/MultipleOutputs.hxx"
+#include "mixer/Listener.hxx"
#include "PlayerControl.hxx"
struct Instance;
@@ -32,7 +33,7 @@ class SongLoader;
* A partition of the Music Player Daemon. It is a separate unit with
* a playlist, a player, outputs etc.
*/
-struct Partition {
+struct Partition final : private MixerListener {
Instance &instance;
struct playlist playlist;
@@ -46,6 +47,7 @@ struct Partition {
unsigned buffer_chunks,
unsigned buffered_before_play)
:instance(_instance), playlist(max_length),
+ outputs(*this),
pc(outputs, buffer_chunks, buffered_before_play) {}
void ClearQueue() {
@@ -188,6 +190,10 @@ struct Partition {
* Synchronize the player with the play queue.
*/
void SyncWithPlayer();
+
+private:
+ /* virtual methods from class MixerListener */
+ virtual void OnMixerVolumeChanged(Mixer &mixer, int volume) override;
};
#endif
diff --git a/src/mixer/Listener.hxx b/src/mixer/Listener.hxx
new file mode 100644
index 000000000..6f48fbd4d
--- /dev/null
+++ b/src/mixer/Listener.hxx
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2003-2014 The Music Player Daemon Project
+ * 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.
+ */
+
+#ifndef MPD_MIXER_LISTENER_HXX
+#define MPD_MIXER_LISTENER_HXX
+
+class Mixer;
+
+/**
+ * An interface that listens on events from mixer plugins. The
+ * methods must be thread-safe and non-blocking.
+ */
+class MixerListener {
+public:
+ virtual void OnMixerVolumeChanged(Mixer &mixer, int volume) = 0;
+};
+
+#endif
diff --git a/src/mixer/MixerControl.cxx b/src/mixer/MixerControl.cxx
index 568fad058..6d08140db 100644
--- a/src/mixer/MixerControl.cxx
+++ b/src/mixer/MixerControl.cxx
@@ -27,10 +27,11 @@
Mixer *
mixer_new(EventLoop &event_loop,
const MixerPlugin &plugin, AudioOutput &ao,
+ MixerListener &listener,
const config_param &param,
Error &error)
{
- Mixer *mixer = plugin.init(event_loop, ao, param, error);
+ Mixer *mixer = plugin.init(event_loop, ao, listener, param, error);
assert(mixer == nullptr || mixer->IsPlugin(plugin));
diff --git a/src/mixer/MixerControl.hxx b/src/mixer/MixerControl.hxx
index 46a9138e6..75255d98c 100644
--- a/src/mixer/MixerControl.hxx
+++ b/src/mixer/MixerControl.hxx
@@ -30,10 +30,12 @@ class Mixer;
class EventLoop;
struct AudioOutput;
struct MixerPlugin;
+class MixerListener;
struct config_param;
Mixer *
mixer_new(EventLoop &event_loop, const MixerPlugin &plugin, AudioOutput &ao,
+ MixerListener &listener,
const config_param &param,
Error &error);
diff --git a/src/mixer/MixerInternal.hxx b/src/mixer/MixerInternal.hxx
index 2c6282ebb..7b2cf2b32 100644
--- a/src/mixer/MixerInternal.hxx
+++ b/src/mixer/MixerInternal.hxx
@@ -25,10 +25,14 @@
#include "thread/Mutex.hxx"
#include "Compiler.h"
+class MixerListener;
+
class Mixer {
public:
const MixerPlugin &plugin;
+ MixerListener &listener;
+
/**
* This mutex protects all of the mixer struct, including its
* implementation, so plugins don't have to deal with that.
@@ -47,8 +51,8 @@ public:
bool failed;
public:
- explicit Mixer(const MixerPlugin &_plugin)
- :plugin(_plugin),
+ explicit Mixer(const MixerPlugin &_plugin, MixerListener &_listener)
+ :plugin(_plugin), listener(_listener),
open(false),
failed(false) {}
diff --git a/src/mixer/MixerPlugin.hxx b/src/mixer/MixerPlugin.hxx
index bf9af14e3..02bae844e 100644
--- a/src/mixer/MixerPlugin.hxx
+++ b/src/mixer/MixerPlugin.hxx
@@ -30,6 +30,7 @@
struct config_param;
struct AudioOutput;
class Mixer;
+class MixerListener;
class EventLoop;
class Error;
@@ -44,6 +45,7 @@ struct MixerPlugin {
* @return a mixer object, or nullptr on error
*/
Mixer *(*init)(EventLoop &event_loop, AudioOutput &ao,
+ MixerListener &listener,
const config_param &param,
Error &error);
diff --git a/src/mixer/Volume.cxx b/src/mixer/Volume.cxx
index aaae5d9ee..596b3c12a 100644
--- a/src/mixer/Volume.cxx
+++ b/src/mixer/Volume.cxx
@@ -21,7 +21,6 @@
#include "Volume.hxx"
#include "output/MultipleOutputs.hxx"
#include "Idle.hxx"
-#include "GlobalEvents.hxx"
#include "util/StringUtil.hxx"
#include "util/Domain.hxx"
#include "system/PeriodClock.hxx"
@@ -41,22 +40,11 @@ static int last_hardware_volume = -1;
/** the age of #last_hardware_volume */
static PeriodClock hardware_volume_clock;
-/**
- * Handler for #GlobalEvents::MIXER.
- */
-static void
-mixer_event_callback(void)
+void
+InvalidateHardwareVolume()
{
/* flush the hardware volume cache */
last_hardware_volume = -1;
-
- /* notify clients */
- idle_add(IDLE_MIXER);
-}
-
-void volume_init(void)
-{
- GlobalEvents::Register(GlobalEvents::MIXER, mixer_event_callback);
}
int
diff --git a/src/mixer/Volume.hxx b/src/mixer/Volume.hxx
index b86328d88..a02c21a21 100644
--- a/src/mixer/Volume.hxx
+++ b/src/mixer/Volume.hxx
@@ -26,7 +26,8 @@
class MultipleOutputs;
-void volume_init(void);
+void
+InvalidateHardwareVolume();
gcc_pure
int
diff --git a/src/mixer/plugins/AlsaMixerPlugin.cxx b/src/mixer/plugins/AlsaMixerPlugin.cxx
index 26007fef3..cd787182a 100644
--- a/src/mixer/plugins/AlsaMixerPlugin.cxx
+++ b/src/mixer/plugins/AlsaMixerPlugin.cxx
@@ -19,8 +19,8 @@
#include "config.h"
#include "mixer/MixerInternal.hxx"
+#include "mixer/Listener.hxx"
#include "output/OutputAPI.hxx"
-#include "GlobalEvents.hxx"
#include "event/MultiSocketMonitor.hxx"
#include "event/DeferredMonitor.hxx"
#include "event/Loop.hxx"
@@ -76,8 +76,9 @@ class AlsaMixer final : public Mixer {
AlsaMixerMonitor *monitor;
public:
- AlsaMixer(EventLoop &_event_loop)
- :Mixer(alsa_mixer_plugin), event_loop(_event_loop) {}
+ AlsaMixer(EventLoop &_event_loop, MixerListener &_listener)
+ :Mixer(alsa_mixer_plugin, _listener),
+ event_loop(_event_loop) {}
virtual ~AlsaMixer();
@@ -142,10 +143,15 @@ AlsaMixerMonitor::DispatchSockets()
*/
static int
-alsa_mixer_elem_callback(gcc_unused snd_mixer_elem_t *elem, unsigned mask)
+alsa_mixer_elem_callback(snd_mixer_elem_t *elem, unsigned mask)
{
- if (mask & SND_CTL_EVENT_MASK_VALUE)
- GlobalEvents::Emit(GlobalEvents::MIXER);
+ AlsaMixer &mixer = *(AlsaMixer *)
+ snd_mixer_elem_get_callback_private(elem);
+
+ if (mask & SND_CTL_EVENT_MASK_VALUE) {
+ int volume = mixer.GetVolume(IgnoreError());
+ mixer.listener.OnMixerVolumeChanged(mixer, volume);
+ }
return 0;
}
@@ -168,10 +174,11 @@ AlsaMixer::Configure(const config_param &param)
static Mixer *
alsa_mixer_init(EventLoop &event_loop, gcc_unused AudioOutput &ao,
+ MixerListener &listener,
const config_param &param,
gcc_unused Error &error)
{
- AlsaMixer *am = new AlsaMixer(event_loop);
+ AlsaMixer *am = new AlsaMixer(event_loop, listener);
am->Configure(param);
return am;
@@ -236,6 +243,7 @@ AlsaMixer::Setup(Error &error)
snd_mixer_selem_get_playback_volume_range(elem, &volume_min,
&volume_max);
+ snd_mixer_elem_set_callback_private(elem, this);
snd_mixer_elem_set_callback(elem, alsa_mixer_elem_callback);
monitor = new AlsaMixerMonitor(event_loop, handle);
diff --git a/src/mixer/plugins/OssMixerPlugin.cxx b/src/mixer/plugins/OssMixerPlugin.cxx
index 939fe0824..6615c7022 100644
--- a/src/mixer/plugins/OssMixerPlugin.cxx
+++ b/src/mixer/plugins/OssMixerPlugin.cxx
@@ -49,7 +49,8 @@ class OssMixer final : public Mixer {
int volume_control;
public:
- OssMixer():Mixer(oss_mixer_plugin) {}
+ OssMixer(MixerListener &_listener)
+ :Mixer(oss_mixer_plugin, _listener) {}
bool Configure(const config_param &param, Error &error);
@@ -98,10 +99,11 @@ OssMixer::Configure(const config_param &param, Error &error)
static Mixer *
oss_mixer_init(gcc_unused EventLoop &event_loop, gcc_unused AudioOutput &ao,
+ MixerListener &listener,
const config_param &param,
Error &error)
{
- OssMixer *om = new OssMixer();
+ OssMixer *om = new OssMixer(listener);
if (!om->Configure(param, error)) {
delete om;
diff --git a/src/mixer/plugins/PulseMixerPlugin.cxx b/src/mixer/plugins/PulseMixerPlugin.cxx
index b838de689..0a765bf68 100644
--- a/src/mixer/plugins/PulseMixerPlugin.cxx
+++ b/src/mixer/plugins/PulseMixerPlugin.cxx
@@ -20,8 +20,8 @@
#include "config.h"
#include "PulseMixerPlugin.hxx"
#include "mixer/MixerInternal.hxx"
+#include "mixer/Listener.hxx"
#include "output/plugins/PulseOutputPlugin.hxx"
-#include "GlobalEvents.hxx"
#include "util/Error.hxx"
#include "util/Domain.hxx"
#include "Log.hxx"
@@ -41,9 +41,9 @@ class PulseMixer final : public Mixer {
struct pa_cvolume volume;
public:
- PulseMixer(PulseOutput &_output)
- :Mixer(pulse_mixer_plugin),
- output(_output), online(false)
+ PulseMixer(PulseOutput &_output, MixerListener &_listener)
+ :Mixer(pulse_mixer_plugin, _listener),
+ output(_output), online(false)
{
}
@@ -75,7 +75,7 @@ PulseMixer::Offline()
online = false;
- GlobalEvents::Emit(GlobalEvents::MIXER);
+ listener.OnMixerVolumeChanged(*this, -1);
}
inline void
@@ -92,7 +92,7 @@ PulseMixer::VolumeCallback(const pa_sink_input_info *i, int eol)
online = true;
volume = i->volume;
- GlobalEvents::Emit(GlobalEvents::MIXER);
+ listener.OnMixerVolumeChanged(*this, GetVolume(IgnoreError()));
}
/**
@@ -165,11 +165,12 @@ pulse_mixer_on_change(PulseMixer &pm,
static Mixer *
pulse_mixer_init(gcc_unused EventLoop &event_loop, AudioOutput &ao,
+ MixerListener &listener,
gcc_unused const config_param &param,
gcc_unused Error &error)
{
PulseOutput &po = (PulseOutput &)ao;
- PulseMixer *pm = new PulseMixer(po);
+ PulseMixer *pm = new PulseMixer(po, listener);
pulse_output_set_mixer(po, *pm);
diff --git a/src/mixer/plugins/RoarMixerPlugin.cxx b/src/mixer/plugins/RoarMixerPlugin.cxx
index 7c2a25dfb..8e198478d 100644
--- a/src/mixer/plugins/RoarMixerPlugin.cxx
+++ b/src/mixer/plugins/RoarMixerPlugin.cxx
@@ -29,9 +29,9 @@ class RoarMixer final : public Mixer {
RoarOutput &self;
public:
- RoarMixer(RoarOutput &_output)
- :Mixer(roar_mixer_plugin),
- self(_output) {}
+ RoarMixer(RoarOutput &_output, MixerListener &_listener)
+ :Mixer(roar_mixer_plugin, _listener),
+ self(_output) {}
/* virtual methods from class Mixer */
virtual bool Open(gcc_unused Error &error) override {
@@ -47,10 +47,11 @@ public:
static Mixer *
roar_mixer_init(gcc_unused EventLoop &event_loop, AudioOutput &ao,
+ MixerListener &listener,
gcc_unused const config_param &param,
gcc_unused Error &error)
{
- return new RoarMixer((RoarOutput &)ao);
+ return new RoarMixer((RoarOutput &)ao, listener);
}
int
diff --git a/src/mixer/plugins/SoftwareMixerPlugin.cxx b/src/mixer/plugins/SoftwareMixerPlugin.cxx
index 78f0769ab..0cde682f6 100644
--- a/src/mixer/plugins/SoftwareMixerPlugin.cxx
+++ b/src/mixer/plugins/SoftwareMixerPlugin.cxx
@@ -52,8 +52,8 @@ class SoftwareMixer final : public Mixer {
unsigned volume;
public:
- SoftwareMixer()
- :Mixer(software_mixer_plugin),
+ SoftwareMixer(MixerListener &_listener)
+ :Mixer(software_mixer_plugin, _listener),
filter(CreateVolumeFilter()),
owns_filter(true),
volume(100)
@@ -86,10 +86,11 @@ public:
static Mixer *
software_mixer_init(gcc_unused EventLoop &event_loop,
gcc_unused AudioOutput &ao,
+ MixerListener &listener,
gcc_unused const config_param &param,
gcc_unused Error &error)
{
- return new SoftwareMixer();
+ return new SoftwareMixer(listener);
}
bool
diff --git a/src/mixer/plugins/WinmmMixerPlugin.cxx b/src/mixer/plugins/WinmmMixerPlugin.cxx
index 6b81fa095..e0436011a 100644
--- a/src/mixer/plugins/WinmmMixerPlugin.cxx
+++ b/src/mixer/plugins/WinmmMixerPlugin.cxx
@@ -34,8 +34,8 @@ class WinmmMixer final : public Mixer {
WinmmOutput &output;
public:
- WinmmMixer(WinmmOutput &_output)
- :Mixer(winmm_mixer_plugin),
+ WinmmMixer(WinmmOutput &_output, MixerListener &_listener)
+ :Mixer(winmm_mixer_plugin, _listener),
output(_output) {
}
@@ -68,10 +68,11 @@ winmm_volume_encode(int volume)
static Mixer *
winmm_mixer_init(gcc_unused EventLoop &event_loop, AudioOutput &ao,
+ MixerListener &listener,
gcc_unused const config_param &param,
gcc_unused Error &error)
{
- return new WinmmMixer((WinmmOutput &)ao);
+ return new WinmmMixer((WinmmOutput &)ao, listener);
}
int
diff --git a/src/output/Init.cxx b/src/output/Init.cxx
index 69ee12b35..eafcec432 100644
--- a/src/output/Init.cxx
+++ b/src/output/Init.cxx
@@ -116,6 +116,7 @@ audio_output_load_mixer(EventLoop &event_loop, AudioOutput &ao,
const config_param &param,
const MixerPlugin *plugin,
Filter &filter_chain,
+ MixerListener &listener,
Error &error)
{
Mixer *mixer;
@@ -129,10 +130,12 @@ audio_output_load_mixer(EventLoop &event_loop, AudioOutput &ao,
if (plugin == nullptr)
return nullptr;
- return mixer_new(event_loop, *plugin, ao, param, error);
+ return mixer_new(event_loop, *plugin, ao, listener,
+ param, error);
case MIXER_TYPE_SOFTWARE:
mixer = mixer_new(event_loop, software_mixer_plugin, ao,
+ listener,
config_param(),
IgnoreError());
assert(mixer != nullptr);
@@ -212,6 +215,7 @@ AudioOutput::Configure(const config_param &param, Error &error)
static bool
audio_output_setup(EventLoop &event_loop, AudioOutput &ao,
+ MixerListener &mixer_listener,
const config_param &param,
Error &error)
{
@@ -244,7 +248,9 @@ audio_output_setup(EventLoop &event_loop, AudioOutput &ao,
Error mixer_error;
ao.mixer = audio_output_load_mixer(event_loop, ao, param,
ao.plugin.mixer_plugin,
- *ao.filter, mixer_error);
+ *ao.filter,
+ mixer_listener,
+ mixer_error);
if (ao.mixer == nullptr && mixer_error.IsDefined())
FormatError(mixer_error,
"Failed to initialize hardware mixer for '%s'",
@@ -279,6 +285,7 @@ audio_output_setup(EventLoop &event_loop, AudioOutput &ao,
AudioOutput *
audio_output_new(EventLoop &event_loop, const config_param &param,
+ MixerListener &mixer_listener,
PlayerControl &pc,
Error &error)
{
@@ -317,7 +324,8 @@ audio_output_new(EventLoop &event_loop, const config_param &param,
if (ao == nullptr)
return nullptr;
- if (!audio_output_setup(event_loop, *ao, param, error)) {
+ if (!audio_output_setup(event_loop, *ao, mixer_listener,
+ param, error)) {
ao_plugin_finish(ao);
return nullptr;
}
diff --git a/src/output/Internal.hxx b/src/output/Internal.hxx
index 9b08a9228..266930448 100644
--- a/src/output/Internal.hxx
+++ b/src/output/Internal.hxx
@@ -33,6 +33,8 @@ class Error;
class Filter;
class MusicPipe;
class EventLoop;
+class Mixer;
+class MixerListener;
struct music_chunk;
struct config_param;
struct PlayerControl;
@@ -79,7 +81,7 @@ struct AudioOutput {
* May be nullptr if none is available, or if software volume is
* configured.
*/
- class Mixer *mixer;
+ Mixer *mixer;
/**
* Will this output receive tags from the decoder? The
@@ -424,6 +426,7 @@ extern struct notify audio_output_client_notify;
AudioOutput *
audio_output_new(EventLoop &event_loop, const config_param &param,
+ MixerListener &mixer_listener,
PlayerControl &pc,
Error &error);
diff --git a/src/output/MultipleOutputs.cxx b/src/output/MultipleOutputs.cxx
index a65fb73c0..10e3e3bd5 100644
--- a/src/output/MultipleOutputs.cxx
+++ b/src/output/MultipleOutputs.cxx
@@ -35,8 +35,9 @@
#include <assert.h>
#include <string.h>
-MultipleOutputs::MultipleOutputs()
- :buffer(nullptr), pipe(nullptr),
+MultipleOutputs::MultipleOutputs(MixerListener &_mixer_listener)
+ :mixer_listener(_mixer_listener),
+ buffer(nullptr), pipe(nullptr),
elapsed_time(-1)
{
}
@@ -50,10 +51,13 @@ MultipleOutputs::~MultipleOutputs()
}
static AudioOutput *
-LoadOutput(EventLoop &event_loop, PlayerControl &pc, const config_param &param)
+LoadOutput(EventLoop &event_loop, MixerListener &mixer_listener,
+ PlayerControl &pc, const config_param &param)
{
Error error;
- AudioOutput *output = audio_output_new(event_loop, param, pc, error);
+ AudioOutput *output = audio_output_new(event_loop, param,
+ mixer_listener,
+ pc, error);
if (output == nullptr) {
if (param.line > 0)
FormatFatalError("line %i: %s",
@@ -72,7 +76,8 @@ MultipleOutputs::Configure(EventLoop &event_loop, PlayerControl &pc)
const config_param *param = nullptr;
while ((param = config_get_next_param(CONF_AUDIO_OUTPUT,
param)) != nullptr) {
- auto output = LoadOutput(event_loop, pc, *param);
+ auto output = LoadOutput(event_loop, mixer_listener,
+ pc, *param);
if (FindByName(output->name) != nullptr)
FormatFatalError("output devices with identical "
"names: %s", output->name);
@@ -83,7 +88,8 @@ MultipleOutputs::Configure(EventLoop &event_loop, PlayerControl &pc)
if (outputs.empty()) {
/* auto-detect device */
const config_param empty;
- auto output = LoadOutput(event_loop, pc, empty);
+ auto output = LoadOutput(event_loop, mixer_listener,
+ pc, empty);
outputs.push_back(output);
}
}
diff --git a/src/output/MultipleOutputs.hxx b/src/output/MultipleOutputs.hxx
index 4fe1aa4f1..296b9815e 100644
--- a/src/output/MultipleOutputs.hxx
+++ b/src/output/MultipleOutputs.hxx
@@ -38,12 +38,15 @@ struct AudioFormat;
class MusicBuffer;
class MusicPipe;
class EventLoop;
+class MixerListener;
struct music_chunk;
struct PlayerControl;
struct AudioOutput;
class Error;
class MultipleOutputs {
+ MixerListener &mixer_listener;
+
std::vector<AudioOutput *> outputs;
AudioFormat input_audio_format;
@@ -70,7 +73,7 @@ public:
* Load audio outputs from the configuration file and
* initialize them.
*/
- MultipleOutputs();
+ MultipleOutputs(MixerListener &_mixer_listener);
~MultipleOutputs();
void Configure(EventLoop &event_loop, PlayerControl &pc);
diff --git a/test/read_mixer.cxx b/test/read_mixer.cxx
index 881f517c7..97529057f 100644
--- a/test/read_mixer.cxx
+++ b/test/read_mixer.cxx
@@ -22,7 +22,6 @@
#include "mixer/MixerList.hxx"
#include "filter/FilterRegistry.hxx"
#include "pcm/Volume.hxx"
-#include "GlobalEvents.hxx"
#include "Main.hxx"
#include "event/Loop.hxx"
#include "config/ConfigData.hxx"
@@ -35,11 +34,6 @@
#include <string.h>
#include <unistd.h>
-void
-GlobalEvents::Emit(gcc_unused Event event)
-{
-}
-
const struct filter_plugin *
filter_plugin_by_name(gcc_unused const char *name)
{
@@ -65,6 +59,7 @@ int main(int argc, gcc_unused char **argv)
Error error;
Mixer *mixer = mixer_new(event_loop, alsa_mixer_plugin,
*(AudioOutput *)nullptr,
+ *(MixerListener *)nullptr,
config_param(), error);
if (mixer == NULL) {
LogError(error, "mixer_new() failed");
diff --git a/test/run_output.cxx b/test/run_output.cxx
index 374a0ceca..8aac5e555 100644
--- a/test/run_output.cxx
+++ b/test/run_output.cxx
@@ -26,7 +26,6 @@
#include "Idle.hxx"
#include "Main.hxx"
#include "event/Loop.hxx"
-#include "GlobalEvents.hxx"
#include "IOThread.hxx"
#include "fs/Path.hxx"
#include "AudioParser.hxx"
@@ -47,11 +46,6 @@
#include <stdlib.h>
#include <stdio.h>
-void
-GlobalEvents::Emit(gcc_unused Event event)
-{
-}
-
const struct filter_plugin *
filter_plugin_by_name(gcc_unused const char *name)
{
@@ -95,7 +89,9 @@ load_audio_output(EventLoop &event_loop, const char *name)
Error error;
AudioOutput *ao =
- audio_output_new(event_loop, *param, dummy_player_control,
+ audio_output_new(event_loop, *param,
+ *(MixerListener *)nullptr,
+ dummy_player_control,
error);
if (ao == nullptr)
LogError(error);