Commit e22ef6c4 authored by Max Kellermann's avatar Max Kellermann

output/roar: convert to C++

parent 2bb01093
...@@ -825,8 +825,8 @@ endif ...@@ -825,8 +825,8 @@ endif
if HAVE_ROAR if HAVE_ROAR
liboutput_plugins_a_SOURCES += \ liboutput_plugins_a_SOURCES += \
src/output/roar_output_plugin.c src/output/roar_output_plugin.h src/output/RoarOutputPlugin.cxx src/output/RoarOutputPlugin.hxx
libmixer_plugins_a_SOURCES += src/mixer/roar_mixer_plugin.c libmixer_plugins_a_SOURCES += src/mixer/RoarMixerPlugin.cxx
endif endif
if ENABLE_FFADO_OUTPUT if ENABLE_FFADO_OUTPUT
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
#include "output/pipe_output_plugin.h" #include "output/pipe_output_plugin.h"
#include "output/pulse_output_plugin.h" #include "output/pulse_output_plugin.h"
#include "output/recorder_output_plugin.h" #include "output/recorder_output_plugin.h"
#include "output/roar_output_plugin.h" #include "output/RoarOutputPlugin.hxx"
#include "output/shout_output_plugin.h" #include "output/shout_output_plugin.h"
#include "output/solaris_output_plugin.h" #include "output/solaris_output_plugin.h"
#include "output/winmm_output_plugin.h" #include "output/winmm_output_plugin.h"
......
/* /*
* Copyright (C) 2003-2010 The Music Player Daemon Project * Copyright (C) 2003-2013 The Music Player Daemon Project
* Copyright (C) 2010-2011 Philipp 'ph3-der-loewe' Schafft * Copyright (C) 2010-2011 Philipp 'ph3-der-loewe' Schafft
* Copyright (C) 2010-2011 Hans-Kristian 'maister' Arntzen * Copyright (C) 2010-2011 Hans-Kristian 'maister' Arntzen
* *
...@@ -22,83 +22,55 @@ ...@@ -22,83 +22,55 @@
#include "config.h" #include "config.h"
#include "mixer_api.h" #include "mixer_api.h"
#include "output_api.h" #include "output_api.h"
#include "output/roar_output_plugin.h" #include "output/RoarOutputPlugin.hxx"
#include <glib.h> struct RoarMixer {
#include <assert.h>
#include <stdlib.h>
#include <unistd.h>
typedef struct roar_mpd_mixer
{
/** the base mixer class */ /** the base mixer class */
struct mixer base; struct mixer base;
struct roar *self; RoarOutput *self;
} roar_mixer_t;
/** RoarMixer(RoarOutput *_output):self(_output) {
* The quark used for GError.domain. mixer_init(&base, &roar_mixer_plugin);
*/ }
static inline GQuark };
roar_mixer_quark(void)
{
return g_quark_from_static_string("roar_mixer");
}
static struct mixer * static struct mixer *
roar_mixer_init(void *ao, G_GNUC_UNUSED const struct config_param *param, roar_mixer_init(void *ao, gcc_unused const struct config_param *param,
G_GNUC_UNUSED GError **error_r) gcc_unused GError **error_r)
{ {
roar_mixer_t *self = g_new(roar_mixer_t, 1); RoarMixer *self = new RoarMixer((RoarOutput *)ao);
self->self = ao;
mixer_init(&self->base, &roar_mixer_plugin);
return &self->base; return &self->base;
} }
static void static void
roar_mixer_finish(struct mixer *data) roar_mixer_finish(struct mixer *data)
{ {
roar_mixer_t *self = (roar_mixer_t *) data; RoarMixer *self = (RoarMixer *) data;
g_free(self); delete self;
}
static void
roar_mixer_close(G_GNUC_UNUSED struct mixer *data)
{
}
static bool
roar_mixer_open(G_GNUC_UNUSED struct mixer *data,
G_GNUC_UNUSED GError **error_r)
{
return true;
} }
static int static int
roar_mixer_get_volume(struct mixer *mixer, G_GNUC_UNUSED GError **error_r) roar_mixer_get_volume(struct mixer *mixer, gcc_unused GError **error_r)
{ {
roar_mixer_t *self = (roar_mixer_t *)mixer; RoarMixer *self = (RoarMixer *)mixer;
return roar_output_get_volume(self->self); return roar_output_get_volume(self->self);
} }
static bool static bool
roar_mixer_set_volume(struct mixer *mixer, unsigned volume, roar_mixer_set_volume(struct mixer *mixer, unsigned volume,
G_GNUC_UNUSED GError **error_r) gcc_unused GError **error_r)
{ {
roar_mixer_t *self = (roar_mixer_t *)mixer; RoarMixer *self = (RoarMixer *)mixer;
return roar_output_set_volume(self->self, volume); return roar_output_set_volume(self->self, volume);
} }
const struct mixer_plugin roar_mixer_plugin = { const struct mixer_plugin roar_mixer_plugin = {
.init = roar_mixer_init, roar_mixer_init,
.finish = roar_mixer_finish, roar_mixer_finish,
.open = roar_mixer_open, nullptr,
.close = roar_mixer_close, nullptr,
.get_volume = roar_mixer_get_volume, roar_mixer_get_volume,
.set_volume = roar_mixer_set_volume, roar_mixer_set_volume,
.global = false, false,
}; };
/* /*
* Copyright (C) 2003-2010 The Music Player Daemon Project * Copyright (C) 2003-2013 The Music Player Daemon Project
* Copyright (C) 2010-2011 Philipp 'ph3-der-loewe' Schafft * Copyright (C) 2010-2011 Philipp 'ph3-der-loewe' Schafft
* Copyright (C) 2010-2011 Hans-Kristian 'maister' Arntzen * Copyright (C) 2010-2011 Hans-Kristian 'maister' Arntzen
* *
...@@ -19,25 +19,19 @@ ...@@ -19,25 +19,19 @@
*/ */
#include "config.h" #include "config.h"
#include "roar_output_plugin.h" #include "RoarOutputPlugin.hxx"
#include "output_api.h" #include "output_api.h"
#include "mixer_list.h" #include "mixer_list.h"
#include "roar_output_plugin.h" #include "thread/Mutex.hxx"
#include <glib.h> #include <glib.h>
#include <stdint.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <roaraudio.h> #include <roaraudio.h>
#undef G_LOG_DOMAIN #undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "roaraudio" #define G_LOG_DOMAIN "roaraudio"
typedef struct roar struct RoarOutput {
{
struct audio_output base; struct audio_output base;
roar_vs_t * vss; roar_vs_t * vss;
...@@ -47,9 +41,18 @@ typedef struct roar ...@@ -47,9 +41,18 @@ typedef struct roar
int role; int role;
struct roar_connection con; struct roar_connection con;
struct roar_audio_info info; struct roar_audio_info info;
GMutex *lock; Mutex mutex;
volatile bool alive; volatile bool alive;
} roar_t;
RoarOutput()
:err(ROAR_ERROR_NONE),
host(nullptr), name(nullptr) {}
~RoarOutput() {
g_free(host);
g_free(name);
}
};
static inline GQuark static inline GQuark
roar_output_quark(void) roar_output_quark(void)
...@@ -58,9 +61,9 @@ roar_output_quark(void) ...@@ -58,9 +61,9 @@ roar_output_quark(void)
} }
static int static int
roar_output_get_volume_locked(struct roar *roar) roar_output_get_volume_locked(RoarOutput *roar)
{ {
if (roar->vss == NULL || !roar->alive) if (roar->vss == nullptr || !roar->alive)
return -1; return -1;
float l, r; float l, r;
...@@ -72,20 +75,18 @@ roar_output_get_volume_locked(struct roar *roar) ...@@ -72,20 +75,18 @@ roar_output_get_volume_locked(struct roar *roar)
} }
int int
roar_output_get_volume(struct roar *roar) roar_output_get_volume(RoarOutput *roar)
{ {
g_mutex_lock(roar->lock); const ScopeLock protect(roar->mutex);
int volume = roar_output_get_volume_locked(roar); return roar_output_get_volume_locked(roar);
g_mutex_unlock(roar->lock);
return volume;
} }
static bool static bool
roar_output_set_volume_locked(struct roar *roar, unsigned volume) roar_output_set_volume_locked(RoarOutput *roar, unsigned volume)
{ {
assert(volume <= 100); assert(volume <= 100);
if (roar->vss == NULL || !roar->alive) if (roar->vss == nullptr || !roar->alive)
return false; return false;
int error; int error;
...@@ -96,22 +97,20 @@ roar_output_set_volume_locked(struct roar *roar, unsigned volume) ...@@ -96,22 +97,20 @@ roar_output_set_volume_locked(struct roar *roar, unsigned volume)
} }
bool bool
roar_output_set_volume(struct roar *roar, unsigned volume) roar_output_set_volume(RoarOutput *roar, unsigned volume)
{ {
g_mutex_lock(roar->lock); const ScopeLock protect(roar->mutex);
bool success = roar_output_set_volume_locked(roar, volume); return roar_output_set_volume_locked(roar, volume);
g_mutex_unlock(roar->lock);
return success;
} }
static void static void
roar_configure(struct roar * self, const struct config_param *param) roar_configure(RoarOutput *self, const struct config_param *param)
{ {
self->host = config_dup_block_string(param, "server", NULL); self->host = config_dup_block_string(param, "server", nullptr);
self->name = config_dup_block_string(param, "name", "MPD"); self->name = config_dup_block_string(param, "name", "MPD");
const char *role = config_get_block_string(param, "role", "music"); const char *role = config_get_block_string(param, "role", "music");
self->role = role != NULL self->role = role != nullptr
? roar_str2role(role) ? roar_str2role(role)
: ROAR_ROLE_MUSIC; : ROAR_ROLE_MUSIC;
} }
...@@ -119,15 +118,13 @@ roar_configure(struct roar * self, const struct config_param *param) ...@@ -119,15 +118,13 @@ roar_configure(struct roar * self, const struct config_param *param)
static struct audio_output * static struct audio_output *
roar_init(const struct config_param *param, GError **error_r) roar_init(const struct config_param *param, GError **error_r)
{ {
struct roar *self = g_new0(struct roar, 1); RoarOutput *self = new RoarOutput();
if (!ao_base_init(&self->base, &roar_output_plugin, param, error_r)) { if (!ao_base_init(&self->base, &roar_output_plugin, param, error_r)) {
g_free(self); delete self;
return NULL; return nullptr;
} }
self->lock = g_mutex_new();
self->err = ROAR_ERROR_NONE;
roar_configure(self, param); roar_configure(self, param);
return &self->base; return &self->base;
} }
...@@ -135,14 +132,10 @@ roar_init(const struct config_param *param, GError **error_r) ...@@ -135,14 +132,10 @@ roar_init(const struct config_param *param, GError **error_r)
static void static void
roar_finish(struct audio_output *ao) roar_finish(struct audio_output *ao)
{ {
struct roar *self = (struct roar *)ao; RoarOutput *self = (RoarOutput *)ao;
g_free(self->host);
g_free(self->name);
g_mutex_free(self->lock);
ao_base_finish(&self->base); ao_base_finish(&self->base);
g_free(self); delete self;
} }
static void static void
...@@ -181,24 +174,22 @@ roar_use_audio_format(struct roar_audio_info *info, ...@@ -181,24 +174,22 @@ roar_use_audio_format(struct roar_audio_info *info,
static bool static bool
roar_open(struct audio_output *ao, struct audio_format *audio_format, GError **error) roar_open(struct audio_output *ao, struct audio_format *audio_format, GError **error)
{ {
struct roar *self = (struct roar *)ao; RoarOutput *self = (RoarOutput *)ao;
g_mutex_lock(self->lock); const ScopeLock protect(self->mutex);
if (roar_simple_connect(&(self->con), self->host, self->name) < 0) if (roar_simple_connect(&(self->con), self->host, self->name) < 0)
{ {
g_set_error(error, roar_output_quark(), 0, g_set_error(error, roar_output_quark(), 0,
"Failed to connect to Roar server"); "Failed to connect to Roar server");
g_mutex_unlock(self->lock);
return false; return false;
} }
self->vss = roar_vs_new_from_con(&(self->con), &(self->err)); self->vss = roar_vs_new_from_con(&(self->con), &(self->err));
if (self->vss == NULL || self->err != ROAR_ERROR_NONE) if (self->vss == nullptr || self->err != ROAR_ERROR_NONE)
{ {
g_set_error(error, roar_output_quark(), 0, g_set_error(error, roar_output_quark(), 0,
"Failed to connect to server"); "Failed to connect to server");
g_mutex_unlock(self->lock);
return false; return false;
} }
...@@ -208,43 +199,41 @@ roar_open(struct audio_output *ao, struct audio_format *audio_format, GError **e ...@@ -208,43 +199,41 @@ roar_open(struct audio_output *ao, struct audio_format *audio_format, GError **e
&(self->err)) < 0) &(self->err)) < 0)
{ {
g_set_error(error, roar_output_quark(), 0, "Failed to start stream"); g_set_error(error, roar_output_quark(), 0, "Failed to start stream");
g_mutex_unlock(self->lock);
return false; return false;
} }
roar_vs_role(self->vss, self->role, &(self->err)); roar_vs_role(self->vss, self->role, &(self->err));
self->alive = true; self->alive = true;
g_mutex_unlock(self->lock);
return true; return true;
} }
static void static void
roar_close(struct audio_output *ao) roar_close(struct audio_output *ao)
{ {
struct roar *self = (struct roar *)ao; RoarOutput *self = (RoarOutput *)ao;
g_mutex_lock(self->lock); const ScopeLock protect(self->mutex);
self->alive = false; self->alive = false;
if (self->vss != NULL) if (self->vss != nullptr)
roar_vs_close(self->vss, ROAR_VS_TRUE, &(self->err)); roar_vs_close(self->vss, ROAR_VS_TRUE, &(self->err));
self->vss = NULL; self->vss = nullptr;
roar_disconnect(&(self->con)); roar_disconnect(&(self->con));
g_mutex_unlock(self->lock);
} }
static void static void
roar_cancel_locked(struct roar *self) roar_cancel_locked(RoarOutput *self)
{ {
if (self->vss == NULL) if (self->vss == nullptr)
return; return;
roar_vs_t *vss = self->vss; roar_vs_t *vss = self->vss;
self->vss = NULL; self->vss = nullptr;
roar_vs_close(vss, ROAR_VS_TRUE, &(self->err)); roar_vs_close(vss, ROAR_VS_TRUE, &(self->err));
self->alive = false; self->alive = false;
vss = roar_vs_new_from_con(&(self->con), &(self->err)); vss = roar_vs_new_from_con(&(self->con), &(self->err));
if (vss == NULL) if (vss == nullptr)
return; return;
if (roar_vs_stream(vss, &(self->info), ROAR_DIR_PLAY, if (roar_vs_stream(vss, &(self->info), ROAR_DIR_PLAY,
...@@ -262,20 +251,19 @@ roar_cancel_locked(struct roar *self) ...@@ -262,20 +251,19 @@ roar_cancel_locked(struct roar *self)
static void static void
roar_cancel(struct audio_output *ao) roar_cancel(struct audio_output *ao)
{ {
struct roar *self = (struct roar *)ao; RoarOutput *self = (RoarOutput *)ao;
g_mutex_lock(self->lock); const ScopeLock protect(self->mutex);
roar_cancel_locked(self); roar_cancel_locked(self);
g_mutex_unlock(self->lock);
} }
static size_t static size_t
roar_play(struct audio_output *ao, const void *chunk, size_t size, GError **error) roar_play(struct audio_output *ao, const void *chunk, size_t size, GError **error)
{ {
struct roar *self = (struct roar *)ao; RoarOutput *self = (RoarOutput *)ao;
ssize_t rc; ssize_t rc;
if (self->vss == NULL) if (self->vss == nullptr)
{ {
g_set_error(error, roar_output_quark(), 0, "Connection is invalid"); g_set_error(error, roar_output_quark(), 0, "Connection is invalid");
return 0; return 0;
...@@ -332,19 +320,20 @@ roar_tag_convert(enum tag_type type, bool *is_uuid) ...@@ -332,19 +320,20 @@ roar_tag_convert(enum tag_type type, bool *is_uuid)
return "HASH"; return "HASH";
default: default:
return NULL; return nullptr;
} }
} }
static void static void
roar_send_tag(struct audio_output *ao, const struct tag *meta) roar_send_tag(struct audio_output *ao, const struct tag *meta)
{ {
struct roar *self = (struct roar *)ao; RoarOutput *self = (RoarOutput *)ao;
if (self->vss == NULL) if (self->vss == nullptr)
return; return;
g_mutex_lock(self->lock); const ScopeLock protect(self->mutex);
size_t cnt = 1; size_t cnt = 1;
struct roar_keyval vals[32]; struct roar_keyval vals[32];
memset(vals, 0, sizeof(vals)); memset(vals, 0, sizeof(vals));
...@@ -361,7 +350,7 @@ roar_send_tag(struct audio_output *ao, const struct tag *meta) ...@@ -361,7 +350,7 @@ roar_send_tag(struct audio_output *ao, const struct tag *meta)
{ {
bool is_uuid = false; bool is_uuid = false;
const char *key = roar_tag_convert(meta->items[i]->type, &is_uuid); const char *key = roar_tag_convert(meta->items[i]->type, &is_uuid);
if (key != NULL) if (key != nullptr)
{ {
if (is_uuid) if (is_uuid)
{ {
...@@ -383,19 +372,22 @@ roar_send_tag(struct audio_output *ao, const struct tag *meta) ...@@ -383,19 +372,22 @@ roar_send_tag(struct audio_output *ao, const struct tag *meta)
for (unsigned i = 0; i < 32; i++) for (unsigned i = 0; i < 32; i++)
g_free(vals[i].key); g_free(vals[i].key);
g_mutex_unlock(self->lock);
} }
const struct audio_output_plugin roar_output_plugin = { const struct audio_output_plugin roar_output_plugin = {
.name = "roar", "roar",
.init = roar_init, nullptr,
.finish = roar_finish, roar_init,
.open = roar_open, roar_finish,
.play = roar_play, nullptr,
.cancel = roar_cancel, nullptr,
.close = roar_close, roar_open,
.send_tag = roar_send_tag, roar_close,
nullptr,
.mixer_plugin = &roar_mixer_plugin roar_send_tag,
roar_play,
nullptr,
roar_cancel,
nullptr,
&roar_mixer_plugin,
}; };
/* /*
* Copyright (C) 2003-2011 The Music Player Daemon Project * Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -20,16 +20,14 @@ ...@@ -20,16 +20,14 @@
#ifndef MPD_ROAR_OUTPUT_PLUGIN_H #ifndef MPD_ROAR_OUTPUT_PLUGIN_H
#define MPD_ROAR_OUTPUT_PLUGIN_H #define MPD_ROAR_OUTPUT_PLUGIN_H
#include <stdbool.h> struct RoarOutput;
struct roar;
extern const struct audio_output_plugin roar_output_plugin; extern const struct audio_output_plugin roar_output_plugin;
int int
roar_output_get_volume(struct roar *roar); roar_output_get_volume(RoarOutput *roar);
bool bool
roar_output_set_volume(struct roar *roar, unsigned volume); roar_output_set_volume(RoarOutput *roar, unsigned volume);
#endif #endif
...@@ -74,16 +74,16 @@ pulse_output_set_volume(G_GNUC_UNUSED struct pulse_output *po, ...@@ -74,16 +74,16 @@ pulse_output_set_volume(G_GNUC_UNUSED struct pulse_output *po,
#endif #endif
#ifdef HAVE_ROAR #ifdef HAVE_ROAR
#include "output/roar_output_plugin.h" #include "output/RoarOutputPlugin.hxx"
int int
roar_output_get_volume(G_GNUC_UNUSED struct roar *roar) roar_output_get_volume(gcc_unused RoarOutput *roar)
{ {
return -1; return -1;
} }
bool bool
roar_output_set_volume(G_GNUC_UNUSED struct roar *roar, roar_output_set_volume(gcc_unused RoarOutput *roar,
G_GNUC_UNUSED unsigned volume) G_GNUC_UNUSED unsigned volume)
{ {
return true; return true;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment