aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/mixer/MixerControl.cxx18
-rw-r--r--src/mixer/MixerInternal.hxx32
-rw-r--r--src/mixer/MixerPlugin.hxx40
-rw-r--r--src/mixer/plugins/AlsaMixerPlugin.cxx52
-rw-r--r--src/mixer/plugins/OssMixerPlugin.cxx59
-rw-r--r--src/mixer/plugins/PulseMixerPlugin.cxx130
-rw-r--r--src/mixer/plugins/PulseMixerPlugin.hxx2
-rw-r--r--src/mixer/plugins/RoarMixerPlugin.cxx42
-rw-r--r--src/mixer/plugins/SoftwareMixerPlugin.cxx80
-rw-r--r--src/mixer/plugins/WinmmMixerPlugin.cxx41
-rw-r--r--src/output/plugins/PulseOutputPlugin.hxx2
11 files changed, 200 insertions, 298 deletions
diff --git a/src/mixer/MixerControl.cxx b/src/mixer/MixerControl.cxx
index 2c030cdfd..e7b6e8395 100644
--- a/src/mixer/MixerControl.cxx
+++ b/src/mixer/MixerControl.cxx
@@ -46,7 +46,7 @@ mixer_free(Mixer *mixer)
this point (see mixer_auto_close()) */
mixer_close(mixer);
- mixer->plugin.finish(mixer);
+ delete mixer;
}
bool
@@ -58,12 +58,7 @@ mixer_open(Mixer *mixer, Error &error)
const ScopeLock protect(mixer->mutex);
- if (mixer->open)
- success = true;
- else if (mixer->plugin.open == nullptr)
- success = mixer->open = true;
- else
- success = mixer->open = mixer->plugin.open(mixer, error);
+ success = mixer->open || (mixer->open = mixer->Open(error));
mixer->failed = !success;
@@ -76,9 +71,7 @@ mixer_close_internal(Mixer *mixer)
assert(mixer != nullptr);
assert(mixer->open);
- if (mixer->plugin.close != nullptr)
- mixer->plugin.close(mixer);
-
+ mixer->Close();
mixer->open = false;
}
@@ -128,7 +121,7 @@ mixer_get_volume(Mixer *mixer, Error &error)
const ScopeLock protect(mixer->mutex);
if (mixer->open) {
- volume = mixer->plugin.get_volume(mixer, error);
+ volume = mixer->GetVolume(error);
if (volume < 0 && error.IsDefined())
mixer_failed(mixer);
} else
@@ -149,6 +142,5 @@ mixer_set_volume(Mixer *mixer, unsigned volume, Error &error)
const ScopeLock protect(mixer->mutex);
- return mixer->open &&
- mixer->plugin.set_volume(mixer, volume, error);
+ return mixer->open && mixer->SetVolume(volume, error);
}
diff --git a/src/mixer/MixerInternal.hxx b/src/mixer/MixerInternal.hxx
index 5d1ad1362..2c6282ebb 100644
--- a/src/mixer/MixerInternal.hxx
+++ b/src/mixer/MixerInternal.hxx
@@ -23,6 +23,7 @@
#include "MixerPlugin.hxx"
#include "MixerList.hxx"
#include "thread/Mutex.hxx"
+#include "Compiler.h"
class Mixer {
public:
@@ -53,9 +54,40 @@ public:
Mixer(const Mixer &) = delete;
+ virtual ~Mixer() {}
+
bool IsPlugin(const MixerPlugin &other) const {
return &plugin == &other;
}
+
+ /**
+ * Open mixer device
+ *
+ * @return true on success, false on error
+ */
+ virtual bool Open(Error &error) = 0;
+
+ /**
+ * Close mixer device
+ */
+ virtual void Close() = 0;
+
+ /**
+ * Reads the current volume.
+ *
+ * @return the current volume (0..100 including) or -1 if
+ * unavailable or on error (error set, mixer will be closed)
+ */
+ gcc_pure
+ virtual int GetVolume(Error &error) = 0;
+
+ /**
+ * Sets the volume.
+ *
+ * @param volume the new volume (0..100 including) @return
+ * true on success, false on error
+ */
+ virtual bool SetVolume(unsigned volume, Error &error) = 0;
};
#endif
diff --git a/src/mixer/MixerPlugin.hxx b/src/mixer/MixerPlugin.hxx
index d342ba1a7..27e59accf 100644
--- a/src/mixer/MixerPlugin.hxx
+++ b/src/mixer/MixerPlugin.hxx
@@ -47,46 +47,6 @@ struct MixerPlugin {
Error &error);
/**
- * Finish and free mixer data
- */
- void (*finish)(Mixer *data);
-
- /**
- * Open mixer device
- *
- * @param error_r location to store the error occurring, or
- * nullptr to ignore errors
- * @return true on success, false on error
- */
- bool (*open)(Mixer *data, Error &error);
-
- /**
- * Close mixer device
- */
- void (*close)(Mixer *data);
-
- /**
- * Reads the current volume.
- *
- * @param error_r location to store the error occurring, or
- * nullptr to ignore errors
- * @return the current volume (0..100 including) or -1 if
- * unavailable or on error (error set, mixer will be closed)
- */
- int (*get_volume)(Mixer *mixer, Error &error);
-
- /**
- * Sets the volume.
- *
- * @param error_r location to store the error occurring, or
- * nullptr to ignore errors
- * @param volume the new volume (0..100 including)
- * @return true on success, false on error
- */
- bool (*set_volume)(Mixer *mixer, unsigned volume,
- Error &error);
-
- /**
* 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.
diff --git a/src/mixer/plugins/AlsaMixerPlugin.cxx b/src/mixer/plugins/AlsaMixerPlugin.cxx
index 6fb669c54..3a520725f 100644
--- a/src/mixer/plugins/AlsaMixerPlugin.cxx
+++ b/src/mixer/plugins/AlsaMixerPlugin.cxx
@@ -79,13 +79,16 @@ public:
AlsaMixer(EventLoop &_event_loop)
:Mixer(alsa_mixer_plugin), event_loop(_event_loop) {}
+ virtual ~AlsaMixer();
+
void Configure(const config_param &param);
bool Setup(Error &error);
- bool Open(Error &error);
- void Close();
- int GetVolume(Error &error);
- bool SetVolume(unsigned volume, Error &error);
+ /* virtual methods from class Mixer */
+ virtual bool Open(Error &error) override;
+ virtual void Close() override;
+ virtual int GetVolume(Error &error) override;
+ virtual bool SetVolume(unsigned volume, Error &error) override;
};
static constexpr Domain alsa_mixer_domain("alsa_mixer");
@@ -174,13 +177,8 @@ alsa_mixer_init(EventLoop &event_loop, gcc_unused void *ao,
return am;
}
-static void
-alsa_mixer_finish(Mixer *data)
+AlsaMixer::~AlsaMixer()
{
- AlsaMixer *am = (AlsaMixer *)data;
-
- delete am;
-
/* free libasound's config cache */
snd_config_update_free_global();
}
@@ -267,14 +265,6 @@ AlsaMixer::Open(Error &error)
return true;
}
-static bool
-alsa_mixer_open(Mixer *data, Error &error)
-{
- AlsaMixer *am = (AlsaMixer *)data;
-
- return am->Open(error);
-}
-
inline void
AlsaMixer::Close()
{
@@ -286,13 +276,6 @@ AlsaMixer::Close()
snd_mixer_close(handle);
}
-static void
-alsa_mixer_close(Mixer *data)
-{
- AlsaMixer *am = (AlsaMixer *)data;
- am->Close();
-}
-
inline int
AlsaMixer::GetVolume(Error &error)
{
@@ -332,13 +315,6 @@ AlsaMixer::GetVolume(Error &error)
return ret;
}
-static int
-alsa_mixer_get_volume(Mixer *mixer, Error &error)
-{
- AlsaMixer *am = (AlsaMixer *)mixer;
- return am->GetVolume(error);
-}
-
inline bool
AlsaMixer::SetVolume(unsigned volume, Error &error)
{
@@ -367,19 +343,7 @@ AlsaMixer::SetVolume(unsigned volume, Error &error)
return true;
}
-static bool
-alsa_mixer_set_volume(Mixer *mixer, unsigned volume, Error &error)
-{
- AlsaMixer *am = (AlsaMixer *)mixer;
- return am->SetVolume(volume, error);
-}
-
const MixerPlugin alsa_mixer_plugin = {
alsa_mixer_init,
- alsa_mixer_finish,
- alsa_mixer_open,
- alsa_mixer_close,
- alsa_mixer_get_volume,
- alsa_mixer_set_volume,
true,
};
diff --git a/src/mixer/plugins/OssMixerPlugin.cxx b/src/mixer/plugins/OssMixerPlugin.cxx
index 7e8d96ca8..fc86f292e 100644
--- a/src/mixer/plugins/OssMixerPlugin.cxx
+++ b/src/mixer/plugins/OssMixerPlugin.cxx
@@ -41,7 +41,7 @@
#define VOLUME_MIXER_OSS_DEFAULT "/dev/mixer"
-class OssMixer : public Mixer {
+class OssMixer final : public Mixer {
const char *device;
const char *control;
@@ -52,11 +52,12 @@ public:
OssMixer():Mixer(oss_mixer_plugin) {}
bool Configure(const config_param &param, Error &error);
- bool Open(Error &error);
- void Close();
- int GetVolume(Error &error);
- bool SetVolume(unsigned volume, Error &error);
+ /* virtual methods from class Mixer */
+ virtual bool Open(Error &error) override;
+ virtual void Close() override;
+ virtual int GetVolume(Error &error) override;
+ virtual bool SetVolume(unsigned volume, Error &error) override;
};
static constexpr Domain oss_mixer_domain("oss_mixer");
@@ -110,14 +111,6 @@ oss_mixer_init(gcc_unused EventLoop &event_loop, gcc_unused void *ao,
return om;
}
-static void
-oss_mixer_finish(Mixer *data)
-{
- OssMixer *om = (OssMixer *) data;
-
- delete om;
-}
-
void
OssMixer::Close()
{
@@ -126,14 +119,7 @@ OssMixer::Close()
close(device_fd);
}
-static void
-oss_mixer_close(Mixer *data)
-{
- OssMixer *om = (OssMixer *) data;
- om->Close();
-}
-
-inline bool
+bool
OssMixer::Open(Error &error)
{
device_fd = open_cloexec(device, O_RDONLY, 0);
@@ -163,15 +149,7 @@ OssMixer::Open(Error &error)
return true;
}
-static bool
-oss_mixer_open(Mixer *data, Error &error)
-{
- OssMixer *om = (OssMixer *) data;
-
- return om->Open(error);
-}
-
-inline int
+int
OssMixer::GetVolume(Error &error)
{
int left, right, level;
@@ -197,14 +175,7 @@ OssMixer::GetVolume(Error &error)
return left;
}
-static int
-oss_mixer_get_volume(Mixer *mixer, Error &error)
-{
- OssMixer *om = (OssMixer *)mixer;
- return om->GetVolume(error);
-}
-
-inline bool
+bool
OssMixer::SetVolume(unsigned volume, Error &error)
{
int level;
@@ -224,19 +195,7 @@ OssMixer::SetVolume(unsigned volume, Error &error)
return true;
}
-static bool
-oss_mixer_set_volume(Mixer *mixer, unsigned volume, Error &error)
-{
- OssMixer *om = (OssMixer *)mixer;
- return om->SetVolume(volume, error);
-}
-
const MixerPlugin oss_mixer_plugin = {
oss_mixer_init,
- oss_mixer_finish,
- oss_mixer_open,
- oss_mixer_close,
- oss_mixer_get_volume,
- oss_mixer_set_volume,
true,
};
diff --git a/src/mixer/plugins/PulseMixerPlugin.cxx b/src/mixer/plugins/PulseMixerPlugin.cxx
index 7c6076bb2..10aa6a93a 100644
--- a/src/mixer/plugins/PulseMixerPlugin.cxx
+++ b/src/mixer/plugins/PulseMixerPlugin.cxx
@@ -34,74 +34,95 @@
#include <assert.h>
-struct PulseMixer final : public Mixer {
+class PulseMixer final : public Mixer {
PulseOutput *output;
bool online;
struct pa_cvolume volume;
+public:
PulseMixer(PulseOutput *_output)
:Mixer(pulse_mixer_plugin),
output(_output), online(false)
{
}
+
+ virtual ~PulseMixer();
+
+ void Offline();
+ void VolumeCallback(const pa_sink_input_info *i, int eol);
+ void Update(pa_context *context, pa_stream *stream);
+
+ /* virtual methods from class Mixer */
+ virtual bool Open(gcc_unused Error &error) override {
+ return true;
+ }
+
+ virtual void Close() override {
+ }
+
+ virtual int GetVolume(Error &error) override;
+ virtual bool SetVolume(unsigned volume, Error &error) override;
};
static constexpr Domain pulse_mixer_domain("pulse_mixer");
-static void
-pulse_mixer_offline(PulseMixer *pm)
+void
+PulseMixer::Offline()
{
- if (!pm->online)
+ if (!online)
return;
- pm->online = false;
+ online = false;
GlobalEvents::Emit(GlobalEvents::MIXER);
}
-/**
- * Callback invoked by pulse_mixer_update(). Receives the new mixer
- * value.
- */
-static void
-pulse_mixer_volume_cb(gcc_unused pa_context *context, const pa_sink_input_info *i,
- int eol, void *userdata)
+inline void
+PulseMixer::VolumeCallback(const pa_sink_input_info *i, int eol)
{
- PulseMixer *pm = (PulseMixer *)userdata;
-
if (eol)
return;
if (i == nullptr) {
- pulse_mixer_offline(pm);
+ Offline();
return;
}
- pm->online = true;
- pm->volume = i->volume;
+ online = true;
+ volume = i->volume;
GlobalEvents::Emit(GlobalEvents::MIXER);
}
+/**
+ * Callback invoked by pulse_mixer_update(). Receives the new mixer
+ * value.
+ */
static void
-pulse_mixer_update(PulseMixer *pm,
- struct pa_context *context, struct pa_stream *stream)
+pulse_mixer_volume_cb(gcc_unused pa_context *context, const pa_sink_input_info *i,
+ int eol, void *userdata)
{
- pa_operation *o;
+ PulseMixer *pm = (PulseMixer *)userdata;
+ pm->VolumeCallback(i, eol);
+}
+inline void
+PulseMixer::Update(pa_context *context, pa_stream *stream)
+{
assert(context != nullptr);
assert(stream != nullptr);
assert(pa_stream_get_state(stream) == PA_STREAM_READY);
- o = pa_context_get_sink_input_info(context,
- pa_stream_get_index(stream),
- pulse_mixer_volume_cb, pm);
+ pa_operation *o =
+ pa_context_get_sink_input_info(context,
+ pa_stream_get_index(stream),
+ pulse_mixer_volume_cb, this);
if (o == nullptr) {
FormatError(pulse_mixer_domain,
"pa_context_get_sink_input_info() failed: %s",
pa_strerror(pa_context_errno(context)));
- pulse_mixer_offline(pm);
+ Offline();
return;
}
@@ -132,14 +153,14 @@ pulse_mixer_on_connect(gcc_unused PulseMixer *pm,
void
pulse_mixer_on_disconnect(PulseMixer *pm)
{
- pulse_mixer_offline(pm);
+ pm->Offline();
}
void
pulse_mixer_on_change(PulseMixer *pm,
struct pa_context *context, struct pa_stream *stream)
{
- pulse_mixer_update(pm, context, stream);
+ pm->Update(context, stream);
}
static Mixer *
@@ -162,65 +183,48 @@ pulse_mixer_init(gcc_unused EventLoop &event_loop, void *ao,
return pm;
}
-static void
-pulse_mixer_finish(Mixer *data)
+PulseMixer::~PulseMixer()
{
- PulseMixer *pm = (PulseMixer *) data;
-
- pulse_output_clear_mixer(pm->output, pm);
-
- delete pm;
+ pulse_output_clear_mixer(output, this);
}
-static int
-pulse_mixer_get_volume(Mixer *mixer, gcc_unused Error &error)
+int
+PulseMixer::GetVolume(gcc_unused Error &error)
{
- PulseMixer *pm = (PulseMixer *) mixer;
- int ret;
-
- pulse_output_lock(pm->output);
+ pulse_output_lock(output);
- ret = pm->online
- ? (int)((100*(pa_cvolume_avg(&pm->volume)+1))/PA_VOLUME_NORM)
+ int result = online
+ ? (int)((100 * (pa_cvolume_avg(&volume) + 1)) / PA_VOLUME_NORM)
: -1;
- pulse_output_unlock(pm->output);
+ pulse_output_unlock(output);
- return ret;
+ return result;
}
-static bool
-pulse_mixer_set_volume(Mixer *mixer, unsigned volume, Error &error)
+bool
+PulseMixer::SetVolume(unsigned new_volume, Error &error)
{
- PulseMixer *pm = (PulseMixer *) mixer;
- struct pa_cvolume cvolume;
- bool success;
-
- pulse_output_lock(pm->output);
+ pulse_output_lock(output);
- if (!pm->online) {
- pulse_output_unlock(pm->output);
+ if (!online) {
+ pulse_output_unlock(output);
error.Set(pulse_mixer_domain, "disconnected");
return false;
}
- pa_cvolume_set(&cvolume, pm->volume.channels,
- (pa_volume_t)volume * PA_VOLUME_NORM / 100 + 0.5);
- success = pulse_output_set_volume(pm->output, &cvolume, error);
+ struct pa_cvolume cvolume;
+ pa_cvolume_set(&cvolume, volume.channels,
+ (pa_volume_t)new_volume * PA_VOLUME_NORM / 100 + 0.5);
+ bool success = pulse_output_set_volume(output, &cvolume, error);
if (success)
- pm->volume = cvolume;
-
- pulse_output_unlock(pm->output);
+ volume = cvolume;
+ pulse_output_unlock(output);
return success;
}
const MixerPlugin pulse_mixer_plugin = {
pulse_mixer_init,
- pulse_mixer_finish,
- nullptr,
- nullptr,
- pulse_mixer_get_volume,
- pulse_mixer_set_volume,
false,
};
diff --git a/src/mixer/plugins/PulseMixerPlugin.hxx b/src/mixer/plugins/PulseMixerPlugin.hxx
index 993945e9b..23cf03566 100644
--- a/src/mixer/plugins/PulseMixerPlugin.hxx
+++ b/src/mixer/plugins/PulseMixerPlugin.hxx
@@ -20,7 +20,7 @@
#ifndef MPD_PULSE_MIXER_PLUGIN_HXX
#define MPD_PULSE_MIXER_PLUGIN_HXX
-struct PulseMixer;
+class PulseMixer;
struct pa_context;
struct pa_stream;
diff --git a/src/mixer/plugins/RoarMixerPlugin.cxx b/src/mixer/plugins/RoarMixerPlugin.cxx
index f03c82c04..d1ac8a6e3 100644
--- a/src/mixer/plugins/RoarMixerPlugin.cxx
+++ b/src/mixer/plugins/RoarMixerPlugin.cxx
@@ -24,13 +24,25 @@
#include "output/plugins/RoarOutputPlugin.hxx"
#include "Compiler.h"
-struct RoarMixer final : public Mixer {
+class RoarMixer final : public Mixer {
/** the base mixer class */
RoarOutput *self;
+public:
RoarMixer(RoarOutput *_output)
:Mixer(roar_mixer_plugin),
self(_output) {}
+
+ /* virtual methods from class Mixer */
+ virtual bool Open(gcc_unused Error &error) override {
+ return true;
+ }
+
+ virtual void Close() override {
+ }
+
+ virtual int GetVolume(Error &error) override;
+ virtual bool SetVolume(unsigned volume, Error &error) override;
};
static Mixer *
@@ -41,35 +53,19 @@ roar_mixer_init(gcc_unused EventLoop &event_loop, void *ao,
return new RoarMixer((RoarOutput *)ao);
}
-static void
-roar_mixer_finish(Mixer *data)
-{
- RoarMixer *self = (RoarMixer *) data;
-
- delete self;
-}
-
-static int
-roar_mixer_get_volume(Mixer *mixer, gcc_unused Error &error)
+int
+RoarMixer::GetVolume(gcc_unused Error &error)
{
- RoarMixer *self = (RoarMixer *)mixer;
- return roar_output_get_volume(self->self);
+ return roar_output_get_volume(self);
}
-static bool
-roar_mixer_set_volume(Mixer *mixer, unsigned volume,
- gcc_unused Error &error)
+bool
+RoarMixer::SetVolume(unsigned volume, gcc_unused Error &error)
{
- RoarMixer *self = (RoarMixer *)mixer;
- return roar_output_set_volume(self->self, volume);
+ return roar_output_set_volume(self, volume);
}
const MixerPlugin roar_mixer_plugin = {
roar_mixer_init,
- roar_mixer_finish,
- nullptr,
- nullptr,
- roar_mixer_get_volume,
- roar_mixer_set_volume,
false,
};
diff --git a/src/mixer/plugins/SoftwareMixerPlugin.cxx b/src/mixer/plugins/SoftwareMixerPlugin.cxx
index ec7aa197b..7dba2ee5e 100644
--- a/src/mixer/plugins/SoftwareMixerPlugin.cxx
+++ b/src/mixer/plugins/SoftwareMixerPlugin.cxx
@@ -38,7 +38,7 @@ CreateVolumeFilter()
IgnoreError());
}
-struct SoftwareMixer final : public Mixer {
+class SoftwareMixer final : public Mixer {
Filter *filter;
/**
@@ -51,6 +51,7 @@ struct SoftwareMixer final : public Mixer {
unsigned volume;
+public:
SoftwareMixer()
:Mixer(software_mixer_plugin),
filter(CreateVolumeFilter()),
@@ -60,10 +61,26 @@ struct SoftwareMixer final : public Mixer {
assert(filter != nullptr);
}
- ~SoftwareMixer() {
+ virtual ~SoftwareMixer() {
if (owns_filter)
delete filter;
}
+
+ Filter *GetFilter();
+
+ /* virtual methods from class Mixer */
+ virtual bool Open(gcc_unused Error &error) override {
+ return true;
+ }
+
+ virtual void Close() override {
+ }
+
+ virtual int GetVolume(gcc_unused Error &error) override {
+ return volume;
+ }
+
+ virtual bool SetVolume(unsigned volume, Error &error) override;
};
static Mixer *
@@ -74,59 +91,40 @@ software_mixer_init(gcc_unused EventLoop &event_loop, gcc_unused void *ao,
return new SoftwareMixer();
}
-static void
-software_mixer_finish(Mixer *data)
+bool
+SoftwareMixer::SetVolume(unsigned new_volume, gcc_unused Error &error)
{
- SoftwareMixer *sm = (SoftwareMixer *)data;
-
- delete sm;
-}
+ assert(new_volume <= 100);
-static int
-software_mixer_get_volume(Mixer *mixer, gcc_unused Error &error)
-{
- SoftwareMixer *sm = (SoftwareMixer *)mixer;
+ if (new_volume >= 100)
+ new_volume = PCM_VOLUME_1;
+ else if (new_volume > 0)
+ new_volume = pcm_float_to_volume((exp(new_volume / 25.0) - 1) /
+ (54.5981500331F - 1));
- return sm->volume;
-}
-
-static bool
-software_mixer_set_volume(Mixer *mixer, unsigned volume,
- gcc_unused Error &error)
-{
- SoftwareMixer *sm = (SoftwareMixer *)mixer;
-
- assert(volume <= 100);
-
- sm->volume = volume;
-
- if (volume >= 100)
- volume = PCM_VOLUME_1;
- else if (volume > 0)
- volume = pcm_float_to_volume((exp(volume / 25.0) - 1) /
- (54.5981500331F - 1));
-
- volume_filter_set(sm->filter, volume);
+ volume = new_volume;
+ volume_filter_set(filter, new_volume);
return true;
}
const MixerPlugin software_mixer_plugin = {
software_mixer_init,
- software_mixer_finish,
- nullptr,
- nullptr,
- software_mixer_get_volume,
- software_mixer_set_volume,
true,
};
+inline Filter *
+SoftwareMixer::GetFilter()
+{
+ assert(owns_filter);
+
+ owns_filter = false;
+ return filter;
+}
+
Filter *
software_mixer_get_filter(Mixer *mixer)
{
SoftwareMixer *sm = (SoftwareMixer *)mixer;
assert(sm->IsPlugin(software_mixer_plugin));
- assert(sm->owns_filter);
-
- sm->owns_filter = false;
- return sm->filter;
+ return sm->GetFilter();
}
diff --git a/src/mixer/plugins/WinmmMixerPlugin.cxx b/src/mixer/plugins/WinmmMixerPlugin.cxx
index 5e5a84637..d69480264 100644
--- a/src/mixer/plugins/WinmmMixerPlugin.cxx
+++ b/src/mixer/plugins/WinmmMixerPlugin.cxx
@@ -30,13 +30,25 @@
#include <math.h>
#include <windows.h>
-struct WinmmMixer final : public Mixer {
+class WinmmMixer final : public Mixer {
WinmmOutput *output;
+public:
WinmmMixer(WinmmOutput *_output)
:Mixer(winmm_mixer_plugin),
output(_output) {
}
+
+ /* virtual methods from class Mixer */
+ virtual bool Open(gcc_unused Error &error) override {
+ return true;
+ }
+
+ virtual void Close() override {
+ }
+
+ virtual int GetVolume(Error &error) override;
+ virtual bool SetVolume(unsigned volume, Error &error) override;
};
static constexpr Domain winmm_mixer_domain("winmm_mixer");
@@ -64,20 +76,11 @@ winmm_mixer_init(gcc_unused EventLoop &event_loop, void *ao,
return new WinmmMixer((WinmmOutput *)ao);
}
-static void
-winmm_mixer_finish(Mixer *data)
-{
- WinmmMixer *wm = (WinmmMixer *)data;
-
- delete wm;
-}
-
-static int
-winmm_mixer_get_volume(Mixer *mixer, Error &error)
+int
+WinmmMixer::GetVolume(Error &error)
{
- WinmmMixer *wm = (WinmmMixer *) mixer;
DWORD volume;
- HWAVEOUT handle = winmm_output_get_handle(wm->output);
+ HWAVEOUT handle = winmm_output_get_handle(output);
MMRESULT result = waveOutGetVolume(handle, &volume);
if (result != MMSYSERR_NOERROR) {
@@ -88,12 +91,11 @@ winmm_mixer_get_volume(Mixer *mixer, Error &error)
return winmm_volume_decode(volume);
}
-static bool
-winmm_mixer_set_volume(Mixer *mixer, unsigned volume, Error &error)
+bool
+WinmmMixer::SetVolume(unsigned volume, Error &error)
{
- WinmmMixer *wm = (WinmmMixer *) mixer;
DWORD value = winmm_volume_encode(volume);
- HWAVEOUT handle = winmm_output_get_handle(wm->output);
+ HWAVEOUT handle = winmm_output_get_handle(output);
MMRESULT result = waveOutSetVolume(handle, value);
if (result != MMSYSERR_NOERROR) {
@@ -106,10 +108,5 @@ winmm_mixer_set_volume(Mixer *mixer, unsigned volume, Error &error)
const MixerPlugin winmm_mixer_plugin = {
winmm_mixer_init,
- winmm_mixer_finish,
- nullptr,
- nullptr,
- winmm_mixer_get_volume,
- winmm_mixer_set_volume,
false,
};
diff --git a/src/output/plugins/PulseOutputPlugin.hxx b/src/output/plugins/PulseOutputPlugin.hxx
index 4982256fc..4d8bf4b59 100644
--- a/src/output/plugins/PulseOutputPlugin.hxx
+++ b/src/output/plugins/PulseOutputPlugin.hxx
@@ -21,7 +21,7 @@
#define MPD_PULSE_OUTPUT_PLUGIN_HXX
struct PulseOutput;
-struct PulseMixer;
+class PulseMixer;
struct pa_cvolume;
class Error;