Hi,

I use mpd on OpenBSD. Here is a patch I use to build the OpenBSD port
of mpd.

* adds sndio mixer support
* increments the glibc++ version quirk in CommandError.cxx to a date
  that includes the OpenBSD glibc++ (gcc 4.9.4).

It would be nice to have this included upstream.
I'm not subscribed to the list, so please CC me.


Thanks,
Christopher


-- 
http://gmerlin.de
OpenPGP: http://gmerlin.de/christopher.pub
2779 7F73 44FD 0736 B67A  C410 69EC 7922 34B4 2566
From 4ba990da805cb01c4cae5fbf6615a2b7d8416241 Mon Sep 17 00:00:00 2001
From: Christopher Zimmermann <madro...@gmerlin.de>
Date: Tue, 31 Jan 2017 14:24:00 +0100
Subject: [PATCH 1/2] Add sndio mixer plugin

---
 Makefile.am                              |  1 +
 doc/mpdconf.example                      |  2 +-
 src/mixer/MixerList.hxx                  |  1 +
 src/mixer/plugins/SndioMixerPlugin.cxx   | 68 ++++++++++++++++++++++++++++++++
 src/output/plugins/SndioOutputPlugin.cxx | 55 ++++++++++++++++----------
 src/output/plugins/SndioOutputPlugin.hxx | 30 ++++++++++++++
 6 files changed, 136 insertions(+), 21 deletions(-)
 create mode 100644 src/mixer/plugins/SndioMixerPlugin.cxx

diff --git Makefile.am Makefile.am
index 898abba82..3dc078657 100644
--- Makefile.am
+++ Makefile.am
@@ -1449,6 +1449,7 @@ if ENABLE_SNDIO
 liboutput_plugins_a_SOURCES += \
 	src/output/plugins/SndioOutputPlugin.cxx \
 	src/output/plugins/SndioOutputPlugin.hxx
+libmixer_plugins_a_SOURCES += src/mixer/plugins/SndioMixerPlugin.cxx
 endif
 
 if ENABLE_HAIKU
diff --git doc/mpdconf.example doc/mpdconf.example
index 2609c38c1..504ecd825 100644
--- doc/mpdconf.example
+++ doc/mpdconf.example
@@ -310,7 +310,7 @@ input {
 #audio_output {
 #	type		"sndio"
 #	name		"sndio output"
-#	mixer_type	"software"
+#	mixer_type	"hardware"
 #}
 #
 # An example of an OS X output:
diff --git src/mixer/MixerList.hxx src/mixer/MixerList.hxx
index b1a8cf11a..21edb9d17 100644
--- src/mixer/MixerList.hxx
+++ src/mixer/MixerList.hxx
@@ -35,5 +35,6 @@ extern const MixerPlugin oss_mixer_plugin;
 extern const MixerPlugin roar_mixer_plugin;
 extern const MixerPlugin pulse_mixer_plugin;
 extern const MixerPlugin winmm_mixer_plugin;
+extern const MixerPlugin sndio_mixer_plugin;
 
 #endif
diff --git src/mixer/plugins/SndioMixerPlugin.cxx src/mixer/plugins/SndioMixerPlugin.cxx
new file mode 100644
index 000000000..9ba3ab42e
--- /dev/null
+++ src/mixer/plugins/SndioMixerPlugin.cxx
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2017 Christopher Zimmermann <christop...@gmerlin.de>
+ *
+ * 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.
+ */
+
+#include <sndio.h>
+
+#include "config.h"
+#include "mixer/Listener.hxx"
+#include "mixer/MixerInternal.hxx"
+#include "output/plugins/SndioOutputPlugin.hxx"
+
+class SndioMixer;
+
+class SndioMixer final : public Mixer {
+	/**
+	 * The current volume in percent (0..100).
+	 */
+	SndioOutput &output;
+
+public:
+	SndioMixer(SndioOutput &output, MixerListener &listener)
+		:Mixer(sndio_mixer_plugin, listener), output(output)
+	{
+		output.RegisterMixerListener(this, &listener);
+	}
+
+	/* virtual methods from class Mixer */
+	void Open() override {}
+
+	void Close() override {}
+
+	int GetVolume() override {
+		return output.GetVolume();
+	}
+
+	void SetVolume(unsigned volume) override {
+		output.SetVolume(volume);
+	}
+
+};
+
+static Mixer *
+sndio_mixer_init(gcc_unused EventLoop &event_loop,
+		AudioOutput &ao,
+		MixerListener &listener,
+		gcc_unused const ConfigBlock &block)
+{
+	return new SndioMixer((SndioOutput &)ao, listener);
+}
+
+const MixerPlugin sndio_mixer_plugin = {
+	sndio_mixer_init,
+	false,
+};
diff --git src/output/plugins/SndioOutputPlugin.cxx src/output/plugins/SndioOutputPlugin.cxx
index 8c4a7327e..73a68f9b4 100644
--- src/output/plugins/SndioOutputPlugin.cxx
+++ src/output/plugins/SndioOutputPlugin.cxx
@@ -21,6 +21,7 @@
 #include "SndioOutputPlugin.hxx"
 #include "../OutputAPI.hxx"
 #include "../Wrapper.hxx"
+#include "mixer/MixerList.hxx"
 #include "util/Domain.hxx"
 #include "Log.hxx"
 
@@ -37,30 +38,16 @@ static constexpr unsigned MPD_SNDIO_BUFFER_TIME_MS = 250;
 
 static constexpr Domain sndio_output_domain("sndio_output");
 
-class SndioOutput {
-	friend struct AudioOutputWrapper<SndioOutput>;
-	AudioOutput base;
-	const char *const device;
-	const unsigned buffer_time; /* in ms */
-	struct sio_hdl *sio_hdl;
-
-public:
-	SndioOutput(const ConfigBlock &block);
-
-	static SndioOutput *Create(EventLoop &event_loop,
-				   const ConfigBlock &block);
-
-	void Open(AudioFormat &audio_format);
-	void Close();
-	size_t Play(const void *chunk, size_t size);
-	void Cancel();
-};
+void SndioMixerCallback(void *arg, unsigned int volume) {
+	((SndioOutput *)arg)->VolumeChanged(volume);
+}
 
 SndioOutput::SndioOutput(const ConfigBlock &block)
 	:base(sndio_output_plugin, block),
 	 device(block.GetBlockValue("device", SIO_DEVANY)),
 	 buffer_time(block.GetBlockValue("buffer_time",
-					 MPD_SNDIO_BUFFER_TIME_MS))
+					 MPD_SNDIO_BUFFER_TIME_MS)),
+	 raw_volume(SIO_MAXVOL)
 {
 }
 
@@ -139,6 +126,9 @@ SndioOutput::Open(AudioFormat &audio_format)
 		throw std::runtime_error("Requested audio params cannot be satisfied");
 	}
 
+	sio_setvol(sio_hdl, raw_volume);
+	sio_onvol(sio_hdl, SndioMixerCallback, this);
+
 	if (!sio_start(sio_hdl)) {
 		sio_close(sio_hdl);
 		throw std::runtime_error("Failed to start audio device");
@@ -162,6 +152,31 @@ SndioOutput::Play(const void *chunk, size_t size)
 	return n;
 }
 
+void
+SndioOutput::SetVolume(unsigned int volume) {
+	sio_setvol(sio_hdl, volume * SIO_MAXVOL / 100);
+}
+
+void
+SndioOutput::VolumeChanged(unsigned int _raw_volume) {
+	raw_volume = _raw_volume;
+	if (listener != NULL && mixer != NULL) {
+		listener->OnMixerVolumeChanged(*mixer,
+		    _raw_volume * 100 / SIO_MAXVOL);
+	}
+}
+
+unsigned int
+SndioOutput::GetVolume() {
+	return (raw_volume * 100 / SIO_MAXVOL);
+}
+
+void
+SndioOutput::RegisterMixerListener(Mixer *_mixer, MixerListener *_listener) {
+	mixer = _mixer;
+	listener = _listener;
+}
+
 typedef AudioOutputWrapper<SndioOutput> Wrapper;
 
 const struct AudioOutputPlugin sndio_output_plugin = {
@@ -179,5 +194,5 @@ const struct AudioOutputPlugin sndio_output_plugin = {
 	nullptr,
 	nullptr,
 	nullptr,
-	nullptr,
+	&sndio_mixer_plugin,
 };
diff --git src/output/plugins/SndioOutputPlugin.hxx src/output/plugins/SndioOutputPlugin.hxx
index 5ad43f0f6..47416b058 100644
--- src/output/plugins/SndioOutputPlugin.hxx
+++ src/output/plugins/SndioOutputPlugin.hxx
@@ -20,6 +20,36 @@
 #ifndef MPD_SNDIO_OUTPUT_PLUGIN_HXX
 #define MPD_SNDIO_OUTPUT_PLUGIN_HXX
 
+#include "../OutputAPI.hxx"
+#include "../Wrapper.hxx"
+#include "mixer/Listener.hxx"
+
 extern const struct AudioOutputPlugin sndio_output_plugin;
 
+class SndioOutput {
+	friend struct AudioOutputWrapper<SndioOutput>;
+	AudioOutput base;
+	Mixer *mixer = NULL;
+	MixerListener *listener = NULL;
+	const char *const device;
+	const unsigned buffer_time; /* in ms */
+	struct sio_hdl *sio_hdl;
+	unsigned int raw_volume;
+
+public:
+	SndioOutput(const ConfigBlock &block);
+
+	static SndioOutput *Create(EventLoop &event_loop,
+				   const ConfigBlock &block);
+
+	void Open(AudioFormat &audio_format);
+	void Close();
+	size_t Play(const void *chunk, size_t size);
+	void Cancel();
+	void SetVolume(unsigned int _volume);
+	unsigned int GetVolume();
+	void RegisterMixerListener(Mixer *_mixer, MixerListener *_listener);
+	void VolumeChanged(unsigned int _volume);
+};
+
 #endif
-- 
2.11.0

From 4d0a8f8ce03eaa0199eb39a34a96a942eb80af3d Mon Sep 17 00:00:00 2001
From: Christopher Zimmermann <madro...@gmerlin.de>
Date: Tue, 31 Jan 2017 14:24:53 +0100
Subject: [PATCH 2/2] Fix building for gcc 4.9, too.

---
 src/command/CommandError.cxx | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git src/command/CommandError.cxx src/command/CommandError.cxx
index 7d8878c61..a720e6745 100644
--- src/command/CommandError.cxx
+++ src/command/CommandError.cxx
@@ -100,13 +100,13 @@ ToAck(std::exception_ptr ep)
 		return ACK_ERROR_SYSTEM;
 	} catch (const std::invalid_argument &e) {
 		return ACK_ERROR_ARG;
-#if defined(__GLIBCXX__) && __GLIBCXX__ < 20151204
+#if defined(__GLIBCXX__) && __GLIBCXX__ < 20160727
 	} catch (const std::exception &e) {
 #else
 	} catch (...) {
 #endif
 		try {
-#if defined(__GLIBCXX__) && __GLIBCXX__ < 20151204
+#if defined(__GLIBCXX__) && __GLIBCXX__ < 20160727
 			/* workaround for g++ 4.x: no overload for
 			   rethrow_exception(exception_ptr) */
 			std::rethrow_if_nested(e);
-- 
2.11.0

Attachment: pgp83nkXE9r_3.pgp
Description: OpenPGP digital signature

_______________________________________________
mpd-devel mailing list
mpd-devel@musicpd.org
http://mailman.blarg.de/listinfo/mpd-devel

Reply via email to