ncmixer

ncurses audio mixer for DJ'ing
git clone git://git.2f30.org/ncmixer.git
Log | Files | Refs | README | LICENSE

0001-output-plugins-Add-UNIX-domain-socket-output.patch (8843B)


      1 From 73246507075f772c40e717a741459d31b5a3a784 Mon Sep 17 00:00:00 2001
      2 From: Dimitris Papastamos <sin@2f30.org>
      3 Date: Sun, 12 Jun 2016 15:06:55 +0100
      4 Subject: [PATCH] output/plugins: Add UNIX domain socket output
      5 
      6 Signed-off-by: Dimitris Papastamos <sin@2f30.org>
      7 Tested-by: Lazaros Koromilas <lostd@2f30.org>
      8 ---
      9  Makefile.am                             |   6 +
     10  configure.ac                            |  16 +++
     11  src/output/Registry.cxx                 |   4 +
     12  src/output/plugins/UnixOutputPlugin.cxx | 188 ++++++++++++++++++++++++++++++++
     13  src/output/plugins/UnixOutputPlugin.hxx |  26 +++++
     14  5 files changed, 240 insertions(+)
     15  create mode 100644 src/output/plugins/UnixOutputPlugin.cxx
     16  create mode 100644 src/output/plugins/UnixOutputPlugin.hxx
     17 
     18 diff --git a/Makefile.am b/Makefile.am
     19 index 2cf8e05..bd94ae1 100644
     20 --- a/Makefile.am
     21 +++ b/Makefile.am
     22 @@ -1409,6 +1409,12 @@ liboutput_plugins_a_SOURCES += \
     23  	src/output/plugins/SndioOutputPlugin.hxx
     24  endif
     25  
     26 +if HAVE_UNIX
     27 +liboutput_plugins_a_SOURCES += \
     28 +	src/output/plugins/UnixOutputPlugin.cxx \
     29 +	src/output/plugins/UnixOutputPlugin.hxx
     30 +endif
     31 +
     32  if HAVE_HAIKU
     33  liboutput_plugins_a_SOURCES += \
     34  	src/output/plugins/HaikuOutputPlugin.cxx \
     35 diff --git a/configure.ac b/configure.ac
     36 index 51ab2e0..51f99a2 100644
     37 --- a/configure.ac
     38 +++ b/configure.ac
     39 @@ -339,6 +339,11 @@ AC_ARG_ENABLE(sndio,
     40  		[enable support for sndio output plugin (default: auto)]),,
     41  	enable_sndio=auto)
     42  
     43 +AC_ARG_ENABLE(unix,
     44 +	AS_HELP_STRING([--disable-unix],
     45 +		[disable support for UNIX domain socket output (default: enable)]),,
     46 +	enable_unix=yes)
     47 +
     48  AC_ARG_ENABLE(haiku,
     49  	AS_HELP_STRING([--enable-haiku],
     50  		[enable the Haiku output plugin (default: auto)]),,
     51 @@ -1128,6 +1133,16 @@ fi
     52  
     53  AM_CONDITIONAL(HAVE_SNDIO, test x$enable_sndio = xyes)
     54  
     55 +dnl ----------------------------------- UNIX ----------------------------------
     56 +if test x$enable_unix = xyes; then
     57 +	AC_CHECK_HEADER(sys/un.h,
     58 +		[enable_unix=yes],
     59 +		[enable_unix=no;AC_MSG_WARN([sys/un.h not found -- disabling support for UNIX domain socket output])])
     60 +fi
     61 +
     62 +MPD_DEFINE_CONDITIONAL(enable_unix, HAVE_UNIX,
     63 +	[support for UNIX domain socket output])
     64 +
     65  dnl ----------------------------------- Haiku ---------------------------------
     66  if test x$enable_haiku = xauto; then
     67  	AC_CHECK_HEADER(media/MediaDefs.h,
     68 @@ -1449,6 +1464,7 @@ printf '\nPlayback support:\n\t'
     69  results(alsa,ALSA)
     70  results(fifo,FIFO)
     71  results(sndio,[SNDIO])
     72 +results(unix,[UNIX domain socket])
     73  results(recorder_output,[File Recorder])
     74  results(haiku,[Haiku])
     75  results(httpd_output,[HTTP Daemon])
     76 diff --git a/src/output/Registry.cxx b/src/output/Registry.cxx
     77 index 9d8d826..3961710 100644
     78 --- a/src/output/Registry.cxx
     79 +++ b/src/output/Registry.cxx
     80 @@ -24,6 +24,7 @@
     81  #include "plugins/AoOutputPlugin.hxx"
     82  #include "plugins/FifoOutputPlugin.hxx"
     83  #include "plugins/SndioOutputPlugin.hxx"
     84 +#include "plugins/UnixOutputPlugin.hxx"
     85  #include "plugins/httpd/HttpdOutputPlugin.hxx"
     86  #include "plugins/HaikuOutputPlugin.hxx"
     87  #include "plugins/JackOutputPlugin.hxx"
     88 @@ -56,6 +57,9 @@ const AudioOutputPlugin *const audio_output_plugins[] = {
     89  #ifdef HAVE_SNDIO
     90  	&sndio_output_plugin,
     91  #endif
     92 +#ifdef HAVE_UNIX
     93 +	&unix_output_plugin,
     94 +#endif
     95  #ifdef HAVE_HAIKU
     96  	&haiku_output_plugin,
     97  #endif
     98 diff --git a/src/output/plugins/UnixOutputPlugin.cxx b/src/output/plugins/UnixOutputPlugin.cxx
     99 new file mode 100644
    100 index 0000000..2b85d64
    101 --- /dev/null
    102 +++ b/src/output/plugins/UnixOutputPlugin.cxx
    103 @@ -0,0 +1,188 @@
    104 +/*
    105 + * Copyright (C) 2016 The Music Player Daemon Project
    106 + * http://www.musicpd.org
    107 + *
    108 + * This program is free software; you can redistribute it and/or modify
    109 + * it under the terms of the GNU General Public License as published by
    110 + * the Free Software Foundation; either version 2 of the License, or
    111 + * (at your option) any later version.
    112 + *
    113 + * This program is distributed in the hope that it will be useful,
    114 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    115 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    116 + * GNU General Public License for more details.
    117 + *
    118 + * You should have received a copy of the GNU General Public License along
    119 + * with this program; if not, write to the Free Software Foundation, Inc.,
    120 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
    121 + */
    122 +
    123 +#include <sys/socket.h>
    124 +#include <sys/stat.h>
    125 +#include <sys/un.h>
    126 +
    127 +#include <errno.h>
    128 +#include <string.h>
    129 +#include <unistd.h>
    130 +
    131 +#include "config.h"
    132 +#include "UnixOutputPlugin.hxx"
    133 +#include "config/ConfigError.hxx"
    134 +#include "../OutputAPI.hxx"
    135 +#include "../Wrapper.hxx"
    136 +#include "fs/AllocatedPath.hxx"
    137 +#include "util/Error.hxx"
    138 +#include "util/Domain.hxx"
    139 +#include "Log.hxx"
    140 +
    141 +class UnixOutput {
    142 +	friend struct AudioOutputWrapper<UnixOutput>;
    143 +	AudioOutput base;
    144 +	AllocatedPath path;
    145 +	std::string path_utf8;
    146 +	int sock;
    147 +
    148 +	bool Connect(Error &error);
    149 +	void Disconnect();
    150 +public:
    151 +	UnixOutput()
    152 +		:base(unix_output_plugin),
    153 +		 path(AllocatedPath::Null()), sock(-1) {}
    154 +	~UnixOutput() {
    155 +		Disconnect();
    156 +	}
    157 +
    158 +	bool Initialize(const ConfigBlock &block, Error &error) {
    159 +		return base.Configure(block, error);
    160 +	}
    161 +
    162 +	static UnixOutput *Create(const ConfigBlock &block, Error &error);
    163 +
    164 +	bool Open(AudioFormat &audio_format, Error &error);
    165 +	void Close();
    166 +	size_t Play(const void *chunk, size_t size, Error &error);
    167 +};
    168 +
    169 +static constexpr Domain unix_output_domain("unix_output");
    170 +
    171 +bool
    172 +UnixOutput::Connect(Error &error)
    173 +{
    174 +	struct sockaddr_un sun;
    175 +	socklen_t len;
    176 +	int ret;
    177 +
    178 +	sock = socket(AF_UNIX, SOCK_STREAM, 0);
    179 +	if (sock == -1) {
    180 +		error.FormatErrno("Could not create UNIX socket");
    181 +		return false;
    182 +	}
    183 +
    184 +	memset(&sun, 0, sizeof(sun));
    185 +	sun.sun_family = AF_UNIX;
    186 +	snprintf(sun.sun_path, sizeof(sun.sun_path), "%s", path_utf8.c_str());
    187 +	len = sizeof(sun);
    188 +	ret = connect(sock, (struct sockaddr *)&sun, len);
    189 +	if (ret == -1) {
    190 +		error.FormatErrno("Could not connect to UNIX socket \"%s\"",
    191 +		                  path_utf8.c_str());
    192 +		Disconnect();
    193 +		return false;
    194 +	}
    195 +
    196 +	return true;
    197 +}
    198 +
    199 +void
    200 +UnixOutput::Disconnect()
    201 +{
    202 +	if (sock >= 0) {
    203 +		close(sock);
    204 +		sock = -1;
    205 +	}
    206 +}
    207 +
    208 +UnixOutput *
    209 +UnixOutput::Create(const ConfigBlock &block, Error &error)
    210 +{
    211 +	UnixOutput *ao = new UnixOutput();
    212 +
    213 +	ao->path = block.GetBlockPath("path", error);
    214 +	if (ao->path.IsNull()) {
    215 +		delete ao;
    216 +
    217 +		if (!error.IsDefined())
    218 +			error.Set(config_domain,
    219 +				  "No \"path\" parameter specified");
    220 +		return nullptr;
    221 +	}
    222 +
    223 +	ao->path_utf8 = ao->path.ToUTF8();
    224 +
    225 +	if (!ao->Initialize(block, error)) {
    226 +		delete ao;
    227 +		return nullptr;
    228 +	}
    229 +
    230 +	return ao;
    231 +}
    232 +
    233 +bool
    234 +UnixOutput::Open(gcc_unused AudioFormat &audio_format,
    235 +		 gcc_unused Error &error)
    236 +{
    237 +	if (sock == -1 && !Connect(error))
    238 +		return false;
    239 +	audio_format.sample_rate = 44100;
    240 +	audio_format.format = SampleFormat::S16;
    241 +	audio_format.channels = 2;
    242 +	return true;
    243 +}
    244 +
    245 +void
    246 +UnixOutput::Close()
    247 +{
    248 +	Disconnect();
    249 +}
    250 +
    251 +size_t
    252 +UnixOutput::Play(const void *chunk, size_t size, Error &error)
    253 +{
    254 +	ssize_t bytes;
    255 +
    256 +	while (true) {
    257 +		bytes = write(sock, chunk, size);
    258 +		if (bytes > 0)
    259 +			return (size_t)bytes;
    260 +		if (bytes < 0) {
    261 +			switch (errno) {
    262 +			case EAGAIN:
    263 +			case EINTR:
    264 +				continue;
    265 +			}
    266 +			error.FormatErrno("Failed to write to UNIX socket%s",
    267 +					  path_utf8.c_str());
    268 +			return 0;
    269 +		}
    270 +	}
    271 +}
    272 +
    273 +typedef AudioOutputWrapper<UnixOutput> Wrapper;
    274 +
    275 +const struct AudioOutputPlugin unix_output_plugin = {
    276 +	"unix",
    277 +	nullptr,
    278 +	&Wrapper::Init,
    279 +	&Wrapper::Finish,
    280 +	nullptr,
    281 +	nullptr,
    282 +	&Wrapper::Open,
    283 +	&Wrapper::Close,
    284 +	nullptr,
    285 +	nullptr,
    286 +	&Wrapper::Play,
    287 +	nullptr,
    288 +	nullptr,
    289 +	nullptr,
    290 +	nullptr,
    291 +};
    292 diff --git a/src/output/plugins/UnixOutputPlugin.hxx b/src/output/plugins/UnixOutputPlugin.hxx
    293 new file mode 100644
    294 index 0000000..3fda10b
    295 --- /dev/null
    296 +++ b/src/output/plugins/UnixOutputPlugin.hxx
    297 @@ -0,0 +1,26 @@
    298 +/*
    299 + * Copyright (C) 2016 The Music Player Daemon Project
    300 + * http://www.musicpd.org
    301 + *
    302 + * This program is free software; you can redistribute it and/or modify
    303 + * it under the terms of the GNU General Public License as published by
    304 + * the Free Software Foundation; either version 2 of the License, or
    305 + * (at your option) any later version.
    306 + *
    307 + * This program is distributed in the hope that it will be useful,
    308 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    309 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    310 + * GNU General Public License for more details.
    311 + *
    312 + * You should have received a copy of the GNU General Public License along
    313 + * with this program; if not, write to the Free Software Foundation, Inc.,
    314 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
    315 + */
    316 +
    317 +#ifndef MPD_UNIX_OUTPUT_PLUGIN_HXX
    318 +#define MPD_UNIX_OUTPUT_PLUGIN_HXX
    319 +
    320 +extern const struct AudioOutputPlugin unix_output_plugin;
    321 +
    322 +#endif
    323 +
    324 -- 
    325 2.9.0
    326