diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/GlobalEvents.hxx | 3 | ||||
-rw-r--r-- | src/Main.cxx | 2 | ||||
-rw-r--r-- | src/Partition.cxx | 11 | ||||
-rw-r--r-- | src/Partition.hxx | 8 | ||||
-rw-r--r-- | src/mixer/Listener.hxx | 34 | ||||
-rw-r--r-- | src/mixer/MixerControl.cxx | 3 | ||||
-rw-r--r-- | src/mixer/MixerControl.hxx | 2 | ||||
-rw-r--r-- | src/mixer/MixerInternal.hxx | 8 | ||||
-rw-r--r-- | src/mixer/MixerPlugin.hxx | 2 | ||||
-rw-r--r-- | src/mixer/Volume.cxx | 16 | ||||
-rw-r--r-- | src/mixer/Volume.hxx | 3 | ||||
-rw-r--r-- | src/mixer/plugins/AlsaMixerPlugin.cxx | 22 | ||||
-rw-r--r-- | src/mixer/plugins/OssMixerPlugin.cxx | 6 | ||||
-rw-r--r-- | src/mixer/plugins/PulseMixerPlugin.cxx | 15 | ||||
-rw-r--r-- | src/mixer/plugins/RoarMixerPlugin.cxx | 9 | ||||
-rw-r--r-- | src/mixer/plugins/SoftwareMixerPlugin.cxx | 7 | ||||
-rw-r--r-- | src/mixer/plugins/WinmmMixerPlugin.cxx | 7 | ||||
-rw-r--r-- | src/output/Init.cxx | 14 | ||||
-rw-r--r-- | src/output/Internal.hxx | 5 | ||||
-rw-r--r-- | src/output/MultipleOutputs.cxx | 18 | ||||
-rw-r--r-- | src/output/MultipleOutputs.hxx | 5 |
21 files changed, 139 insertions, 61 deletions
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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m) static Mixer * alsa_mixer_init(EventLoop &event_loop, gcc_unused AudioOutput &ao, + MixerListener &listener, const config_param ¶m, 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 ¶m, Error &error); @@ -98,10 +99,11 @@ OssMixer::Configure(const config_param ¶m, Error &error) static Mixer * oss_mixer_init(gcc_unused EventLoop &event_loop, gcc_unused AudioOutput &ao, + MixerListener &listener, const config_param ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, Error &error) static bool audio_output_setup(EventLoop &event_loop, AudioOutput &ao, + MixerListener &mixer_listener, const config_param ¶m, 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 ¶m, + MixerListener &mixer_listener, PlayerControl &pc, Error &error) { @@ -317,7 +324,8 @@ audio_output_new(EventLoop &event_loop, const config_param ¶m, 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 ¶m, + 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 ¶m) +LoadOutput(EventLoop &event_loop, MixerListener &mixer_listener, + PlayerControl &pc, const config_param ¶m) { 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); |