output/roar: remove

Bugs in libroar which broke the MPD build have been annoying me for
quite some time, and the newest bug has now hit my main build machine:

 https://github.com/MusicPlayerDaemon/MPD/issues/377

Problem is the usage of the typedef `_IO_off64_t` in libroar's
`vio_stdio.h`:

 int roar_vio_to_stdio_lseek (void *__cookie, _IO_off64_t *__pos, int __w);

This `_IO_off64_t` is an internal implementation detail of glibc and
was removed in version 2.28.  Nobody must ever use it.  Why the ****
did the RoarAudio developers use it?  Not using internal typedefs
isn't exactly rocket science.

This annoys me enough to finally remove the plugin.  Anyway, I've
never heard of anybody using RoarAudio, so my best guess is that
nobody will notice.
This commit is contained in:
Max Kellermann 2018-10-31 15:03:28 +01:00
parent 9fc00a817b
commit 06ca08ce55
13 changed files with 2 additions and 485 deletions

1
NEWS
View File

@ -39,6 +39,7 @@ ver 0.21 (not yet released)
- shout: support the Shine encoder plugin
- sndio: remove support for the broken RoarAudio sndio emulation
- osx: initial support for DSD over PCM
- roar: removed
- httpd_output: support for unix sockets
* mixer
- sndio: new mixer plugin

View File

@ -936,21 +936,6 @@ The pulse plugin connects to a `PulseAudio <http://www.freedesktop.org/wiki/Soft
* - **sink NAME**
- Specifies the name of the PulseAudio sink :program:`MPD` should play on.
roar
~~~~
The roar plugin connects to a `RoarAudio <http://roaraudio.keep-cool.org/>`_ server.
.. list-table::
:widths: 20 80
:header-rows: 1
* - Setting
- Description
* - **server HOSTNAME**
- The host name of the RoarAudio server. If not specified, then :program:`MPD` will connect to the default locations.
* - **role ROLE**
- The "role" that :program:`MPD` registers itself as in the RoarAudio server. The default is "music".
recorder
~~~~~~~~
The recorder plugin writes the audio played by :program:`MPD` to a file. This may be useful for recording radio streams.

View File

@ -72,7 +72,7 @@ For example, the following installs a fairly complete list of build dependencies
libzzip-dev \
libcurl4-gnutls-dev libyajl-dev libexpat-dev \
libasound2-dev libao-dev libjack-jackd2-dev libopenal-dev \
libpulse-dev libroar-dev libshout3-dev \
libpulse-dev libshout3-dev \
libsndio-dev \
libmpdclient-dev \
libnfs-dev libsmbclient-dev \

View File

@ -309,7 +309,6 @@ subdir('src/lib/wrap')
subdir('src/lib/nfs')
subdir('src/lib/oss')
subdir('src/lib/pulse')
subdir('src/lib/roar')
subdir('src/lib/sndio')
subdir('src/lib/sqlite')
subdir('src/lib/systemd')

View File

@ -163,7 +163,6 @@ option('oss', type: 'feature', description: 'Open Sound System support')
option('pipe', type: 'boolean', value: true, description: 'Pipe output plugin')
option('pulse', type: 'feature', description: 'PulseAudio support')
option('recorder', type: 'boolean', value: true, description: 'Recorder output plugin')
option('roar', type: 'feature', description: 'Roar output plugin')
option('shout', type: 'feature', description: 'Shoutcast streaming support using libshout')
option('sndio', type: 'feature', description: 'sndio output plugin')
option('solaris_output', type: 'feature', description: 'Solaris /dev/audio support')

View File

@ -1,2 +0,0 @@
libroar_dep = dependency('libroar', version: '>= 0.4.0', required: get_option('roar'))
conf.set('ENABLE_ROAR', libroar_dep.found())

View File

@ -33,7 +33,6 @@ extern const MixerPlugin alsa_mixer_plugin;
extern const MixerPlugin haiku_mixer_plugin;
extern const MixerPlugin oss_mixer_plugin;
extern const MixerPlugin osx_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;

View File

@ -1,70 +0,0 @@
/*
* Copyright 2003-2017 The Music Player Daemon Project
* Copyright (C) 2010-2011 Philipp 'ph3-der-loewe' Schafft
* Copyright (C) 2010-2011 Hans-Kristian 'maister' Arntzen
*
* 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 "config.h"
#include "mixer/MixerInternal.hxx"
#include "output/plugins/RoarOutputPlugin.hxx"
#include "util/Compiler.h"
class RoarMixer final : public Mixer {
/** the base mixer class */
RoarOutput &self;
public:
RoarMixer(RoarOutput &_output, MixerListener &_listener)
:Mixer(roar_mixer_plugin, _listener),
self(_output) {}
/* virtual methods from class Mixer */
void Open() override {
}
void Close() noexcept override {
}
int GetVolume() override;
void SetVolume(unsigned volume) override;
};
static Mixer *
roar_mixer_init(gcc_unused EventLoop &event_loop, AudioOutput &ao,
MixerListener &listener,
gcc_unused const ConfigBlock &block)
{
return new RoarMixer((RoarOutput &)ao, listener);
}
int
RoarMixer::GetVolume()
{
return roar_output_get_volume(self);
}
void
RoarMixer::SetVolume(unsigned volume)
{
roar_output_set_volume(self, volume);
}
const MixerPlugin roar_mixer_plugin = {
roar_mixer_init,
false,
};

View File

@ -26,10 +26,6 @@ if pulse_dep.found()
mixer_plugins_sources += 'PulseMixerPlugin.cxx'
endif
if libroar_dep.found()
mixer_plugins_sources += 'RoarMixerPlugin.cxx'
endif
if libsndio_dep.found()
mixer_plugins_sources += 'SndioMixerPlugin.cxx'
endif
@ -45,7 +41,6 @@ mixer_plugins = static_library(
dependencies: [
alsa_dep,
pulse_dep,
libroar_dep,
libsndio_dep,
]
)

View File

@ -34,7 +34,6 @@
#include "plugins/PipeOutputPlugin.hxx"
#include "plugins/PulseOutputPlugin.hxx"
#include "plugins/RecorderOutputPlugin.hxx"
#include "plugins/RoarOutputPlugin.hxx"
#include "plugins/ShoutOutputPlugin.hxx"
#include "plugins/sles/SlesOutputPlugin.hxx"
#include "plugins/SolarisOutputPlugin.hxx"
@ -65,9 +64,6 @@ const AudioOutputPlugin *const audio_output_plugins[] = {
#ifdef ENABLE_ALSA
&alsa_output_plugin,
#endif
#ifdef ENABLE_ROAR
&roar_output_plugin,
#endif
#ifdef ENABLE_AO
&ao_output_plugin,
#endif

View File

@ -1,347 +0,0 @@
/*
* Copyright 2003-2017 The Music Player Daemon Project
* Copyright (C) 2010-2011 Philipp 'ph3-der-loewe' Schafft
* Copyright (C) 2010-2011 Hans-Kristian 'maister' Arntzen
*
* 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 "config.h"
#include "RoarOutputPlugin.hxx"
#include "../OutputAPI.hxx"
#include "mixer/MixerList.hxx"
#include "thread/Mutex.hxx"
#include "util/Domain.hxx"
#include "Log.hxx"
#include <string>
#include <stdexcept>
/* libroar/services.h declares roar_service_stream::new - work around
this C++ problem */
#define new _new
#include <roaraudio.h>
#undef new
#include <assert.h>
class RoarOutput final : AudioOutput {
const std::string host, name;
roar_vs_t * vss;
int err = ROAR_ERROR_NONE;
const int role;
struct roar_connection con;
struct roar_audio_info info;
mutable Mutex mutex;
bool alive;
public:
RoarOutput(const ConfigBlock &block);
static AudioOutput *Create(EventLoop &, const ConfigBlock &block) {
return new RoarOutput(block);
}
int GetVolume() const;
void SetVolume(unsigned volume);
private:
void Open(AudioFormat &audio_format) override;
void Close() noexcept override;
void SendTag(const Tag &tag) override;
size_t Play(const void *chunk, size_t size) override;
void Cancel() noexcept override;
};
static constexpr Domain roar_output_domain("roar_output");
gcc_pure
static int
GetConfiguredRole(const ConfigBlock &block) noexcept
{
const char *role = block.GetBlockValue("role");
return role != nullptr
? roar_str2role(role)
: ROAR_ROLE_MUSIC;
}
RoarOutput::RoarOutput(const ConfigBlock &block)
:AudioOutput(0),
host(block.GetBlockValue("server", "")),
name(block.GetBlockValue("name", "MPD")),
role(GetConfiguredRole(block))
{
}
inline int
RoarOutput::GetVolume() const
{
const std::lock_guard<Mutex> protect(mutex);
if (vss == nullptr || !alive)
return -1;
float l, r;
int error;
if (roar_vs_volume_get(vss, &l, &r, &error) < 0)
throw std::runtime_error(roar_vs_strerr(error));
return (l + r) * 50;
}
int
roar_output_get_volume(RoarOutput &roar)
{
return roar.GetVolume();
}
inline void
RoarOutput::SetVolume(unsigned volume)
{
assert(volume <= 100);
const std::lock_guard<Mutex> protect(mutex);
if (vss == nullptr || !alive)
throw std::runtime_error("closed");
int error;
float level = volume / 100.0;
if (roar_vs_volume_mono(vss, level, &error) < 0)
throw std::runtime_error(roar_vs_strerr(error));
}
void
roar_output_set_volume(RoarOutput &roar, unsigned volume)
{
roar.SetVolume(volume);
}
static void
roar_use_audio_format(struct roar_audio_info *info,
AudioFormat &audio_format)
{
info->rate = audio_format.sample_rate;
info->channels = audio_format.channels;
info->codec = ROAR_CODEC_PCM_S;
switch (audio_format.format) {
case SampleFormat::UNDEFINED:
case SampleFormat::FLOAT:
case SampleFormat::DSD:
info->bits = 16;
audio_format.format = SampleFormat::S16;
break;
case SampleFormat::S8:
info->bits = 8;
break;
case SampleFormat::S16:
info->bits = 16;
break;
case SampleFormat::S24_P32:
info->bits = 32;
audio_format.format = SampleFormat::S32;
break;
case SampleFormat::S32:
info->bits = 32;
break;
}
}
void
RoarOutput::Open(AudioFormat &audio_format)
{
const std::lock_guard<Mutex> protect(mutex);
if (roar_simple_connect(&con,
host.empty() ? nullptr : host.c_str(),
name.c_str()) < 0)
throw std::runtime_error("Failed to connect to Roar server");
vss = roar_vs_new_from_con(&con, &err);
if (vss == nullptr || err != ROAR_ERROR_NONE)
throw std::runtime_error("Failed to connect to server");
roar_use_audio_format(&info, audio_format);
if (roar_vs_stream(vss, &info, ROAR_DIR_PLAY, &err) < 0)
throw std::runtime_error("Failed to start stream");
roar_vs_role(vss, role, &err);
alive = true;
}
void
RoarOutput::Close() noexcept
{
const std::lock_guard<Mutex> protect(mutex);
alive = false;
if (vss != nullptr)
roar_vs_close(vss, ROAR_VS_TRUE, &err);
vss = nullptr;
roar_disconnect(&con);
}
void
RoarOutput::Cancel() noexcept
{
const std::lock_guard<Mutex> protect(mutex);
if (vss == nullptr)
return;
roar_vs_t *_vss = vss;
vss = nullptr;
roar_vs_close(_vss, ROAR_VS_TRUE, &err);
alive = false;
_vss = roar_vs_new_from_con(&con, &err);
if (_vss == nullptr)
return;
if (roar_vs_stream(_vss, &info, ROAR_DIR_PLAY, &err) < 0) {
roar_vs_close(_vss, ROAR_VS_TRUE, &err);
LogError(roar_output_domain, "Failed to start stream");
return;
}
roar_vs_role(_vss, role, &err);
vss = _vss;
alive = true;
}
size_t
RoarOutput::Play(const void *chunk, size_t size)
{
if (vss == nullptr)
throw std::runtime_error("Connection is invalid");
ssize_t nbytes = roar_vs_write(vss, chunk, size, &err);
if (nbytes <= 0)
throw std::runtime_error("Failed to play data");
return nbytes;
}
static const char*
roar_tag_convert(TagType type, bool *is_uuid)
{
*is_uuid = false;
switch (type)
{
case TAG_ARTIST:
case TAG_ALBUM_ARTIST:
return "AUTHOR";
case TAG_ALBUM:
return "ALBUM";
case TAG_TITLE:
return "TITLE";
case TAG_TRACK:
return "TRACK";
case TAG_NAME:
return "NAME";
case TAG_GENRE:
return "GENRE";
case TAG_DATE:
return "DATE";
case TAG_PERFORMER:
return "PERFORMER";
case TAG_COMMENT:
return "COMMENT";
case TAG_DISC:
return "DISCID";
case TAG_COMPOSER:
#ifdef ROAR_META_TYPE_COMPOSER
return "COMPOSER";
#else
return "AUTHOR";
#endif
case TAG_MUSICBRAINZ_ARTISTID:
case TAG_MUSICBRAINZ_ALBUMID:
case TAG_MUSICBRAINZ_ALBUMARTISTID:
case TAG_MUSICBRAINZ_TRACKID:
case TAG_MUSICBRAINZ_RELEASETRACKID:
case TAG_MUSICBRAINZ_WORKID:
*is_uuid = true;
return "HASH";
default:
return nullptr;
}
}
void
RoarOutput::SendTag(const Tag &tag)
{
if (vss == nullptr)
return;
const std::lock_guard<Mutex> protect(mutex);
size_t cnt = 0;
struct roar_keyval vals[32];
char uuid_buf[32][64];
char timebuf[16];
if (!tag.duration.IsNegative()) {
const unsigned seconds = tag.duration.ToS();
snprintf(timebuf, sizeof(timebuf), "%02d:%02d:%02d",
seconds / 3600, (seconds % 3600) / 60, seconds % 60);
vals[cnt].key = const_cast<char *>("LENGTH");
vals[cnt].value = timebuf;
++cnt;
}
for (const auto &item : tag) {
if (cnt >= 32)
break;
bool is_uuid = false;
const char *key = roar_tag_convert(item.type,
&is_uuid);
if (key != nullptr) {
vals[cnt].key = const_cast<char *>(key);
if (is_uuid) {
snprintf(uuid_buf[cnt], sizeof(uuid_buf[0]), "{UUID}%s",
item.value);
vals[cnt].value = uuid_buf[cnt];
} else {
vals[cnt].value = const_cast<char *>(item.value);
}
cnt++;
}
}
roar_vs_meta(vss, vals, cnt, &(err));
}
const struct AudioOutputPlugin roar_output_plugin = {
"roar",
nullptr,
&RoarOutput::Create,
&roar_mixer_plugin,
};

View File

@ -1,33 +0,0 @@
/*
* Copyright 2003-2017 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_ROAR_OUTPUT_PLUGIN_H
#define MPD_ROAR_OUTPUT_PLUGIN_H
class RoarOutput;
extern const struct AudioOutputPlugin roar_output_plugin;
int
roar_output_get_volume(RoarOutput &roar);
void
roar_output_set_volume(RoarOutput &roar, unsigned volume);
#endif

View File

@ -99,10 +99,6 @@ if get_option('recorder')
need_encoder = true
endif
if libroar_dep.found()
output_plugins_sources += 'RoarOutputPlugin.cxx'
endif
libshout_dep = dependency('shout', required: get_option('shout'))
conf.set('HAVE_SHOUT', libshout_dep.found())
if libshout_dep.found()
@ -150,7 +146,6 @@ output_plugins = static_library(
libao_dep,
libjack_dep,
pulse_dep,
libroar_dep,
libshout_dep,
libsndio_dep,
openal_dep,