aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/audio.c6
-rw-r--r--src/audioOutput.c7
-rw-r--r--src/audioOutput.h2
-rw-r--r--src/audioOutput_ao.c6
-rw-r--r--src/audioOutput_shout.c109
5 files changed, 121 insertions, 9 deletions
diff --git a/src/audio.c b/src/audio.c
index dbc5273f1..b897d8bc9 100644
--- a/src/audio.c
+++ b/src/audio.c
@@ -32,6 +32,7 @@ static AudioFormat audio_format;
static AudioFormat * audio_configFormat = NULL;
static AudioOutput * aoOutput = NULL;
+static AudioOutput * shoutOutput = NULL;
static void copyAudioFormat(AudioFormat * dest, AudioFormat * src) {
dest->sampleRate = src->sampleRate;
@@ -49,6 +50,7 @@ void initAudioDriver() {
aoOutput = newAudioOutput("ao");
assert(aoOutput);
+ shoutOutput = newAudioOutput("shout");
}
void getOutputAudioFormat(AudioFormat * inAudioFormat,
@@ -134,6 +136,7 @@ void finishAudioConfig() {
void finishAudioDriver() {
finishAudioOutput(aoOutput);
+ if(shoutOutput) finishAudioOutput(shoutOutput);
aoOutput = NULL;
}
@@ -148,6 +151,7 @@ int isCurrentAudioFormat(AudioFormat * audioFormat) {
int openAudioDevice(AudioFormat * audioFormat) {
if(!aoOutput->open || !isCurrentAudioFormat(audioFormat)) {
copyAudioFormat(&audio_format, audioFormat);
+ if(shoutOutput) openAudioOutput(shoutOutput, audioFormat);
return openAudioOutput(aoOutput, audioFormat);
}
@@ -155,6 +159,7 @@ int openAudioDevice(AudioFormat * audioFormat) {
}
int playAudio(char * playChunk, int size) {
+ if(shoutOutput) playAudioOutput(shoutOutput, playChunk, size);
return playAudioOutput(aoOutput, playChunk, size);
}
@@ -163,5 +168,6 @@ int isAudioDeviceOpen() {
}
void closeAudioDevice() {
+ if(shoutOutput) closeAudioOutput(shoutOutput);
closeAudioOutput(aoOutput);
}
diff --git a/src/audioOutput.c b/src/audioOutput.c
index 5352be012..24899e814 100644
--- a/src/audioOutput.c
+++ b/src/audioOutput.c
@@ -28,13 +28,16 @@ AudioOutput * newAudioOutput(char * name) {
if(findInList(audioOutputPluginList, name, &data)) {
AudioOutputPlugin * plugin = (AudioOutputPlugin *) data;
ret = malloc(sizeof(AudioOutput));
- ret->finishDriverFunc = plugin->initDriverFunc;
+ ret->finishDriverFunc = plugin->finishDriverFunc;
ret->openDeviceFunc = plugin->openDeviceFunc;
ret->playFunc = plugin->playFunc;
ret->closeDeviceFunc = plugin->closeDeviceFunc;
ret->open = 0;
- plugin->initDriverFunc(ret);
+ if(plugin->initDriverFunc(ret) != 0) {
+ free(ret);
+ ret = NULL;
+ }
}
return ret;
diff --git a/src/audioOutput.h b/src/audioOutput.h
index 8fec7e503..985b57797 100644
--- a/src/audioOutput.h
+++ b/src/audioOutput.h
@@ -28,7 +28,7 @@
typedef struct _AudioOutput AudioOutput;
-typedef void (* AudioOutputInitDriverFunc) (AudioOutput * audioOutput);
+typedef int (* AudioOutputInitDriverFunc) (AudioOutput * audioOutput);
typedef void (* AudioOutputFinishDriverFunc) (AudioOutput * audioOutput);
diff --git a/src/audioOutput_ao.c b/src/audioOutput_ao.c
index 3dafc8e89..95f0f1a98 100644
--- a/src/audioOutput_ao.c
+++ b/src/audioOutput_ao.c
@@ -56,7 +56,7 @@ static void audioOutputAo_error() {
}
}
-static void audioOutputAo_initDriver(AudioOutput * audioOutput) {
+static int audioOutputAo_initDriver(AudioOutput * audioOutput) {
ao_info * ai;
char * dup;
char * stk1;
@@ -71,7 +71,7 @@ static void audioOutputAo_initDriver(AudioOutput * audioOutput) {
ad->writeSize = strtol((getConf())[CONF_AUDIO_WRITE_SIZE],&test,10);
if (*test!='\0') {
- ERROR("\"%s\" is not a valid write size",
+ ERROR("\"%s\" is not a valid write size\n",
(getConf())[CONF_AUDIO_WRITE_SIZE]);
exit(EXIT_FAILURE);
}
@@ -133,6 +133,8 @@ static void audioOutputAo_initDriver(AudioOutput * audioOutput) {
}
}
free(dup);
+
+ return 0;
}
static void freeAoData(AoData * ad) {
diff --git a/src/audioOutput_shout.c b/src/audioOutput_shout.c
index a895b63ae..5e14b0467 100644
--- a/src/audioOutput_shout.c
+++ b/src/audioOutput_shout.c
@@ -26,33 +26,127 @@
#include <assert.h>
#include <signal.h>
+#include <shout/shout.h>
+#include <vorbis/vorbisenc.h>
+
+static int shoutInitCount = 0;
+
typedef struct _ShoutData {
+ shout_t * shoutConn;
} ShoutData;
static ShoutData * newShoutData() {
ShoutData * ret = malloc(sizeof(ShoutData));
+ ret->shoutConn = shout_new();
+
return ret;
}
static void freeShoutData(ShoutData * sd) {
+ if(sd->shoutConn) shout_free(sd->shoutConn);
+
free(sd);
}
-static void shout_initDriver(AudioOutput * audioOutput) {
- ShoutData * sd = newShoutData();
+static int shout_initDriver(AudioOutput * audioOutput) {
+ ShoutData * sd;
+ char * test;
+ int port;
+ char * host;
+ char * mount;
+ char * passwd;
+ char * user;
+ char * name;
+
+ if(!getConf()[CONF_SHOUT_HOST]) {
+ return -1;
+ }
+
+ sd = newShoutData();
+
+ if(!getConf()[CONF_SHOUT_MOUNT]) {
+ ERROR("shout host defined but not shout mount point\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if(!getConf()[CONF_SHOUT_PORT]) {
+ ERROR("shout host defined but not shout port\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if(!getConf()[CONF_SHOUT_PASSWD]) {
+ ERROR("shout host defined but not shout password\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if(!getConf()[CONF_SHOUT_NAME]) {
+ ERROR("shout host defined but not shout name\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if(!getConf()[CONF_SHOUT_USER]) {
+ ERROR("shout host defined but not shout user\n");
+ exit(EXIT_FAILURE);
+ }
+
+ host = getConf()[CONF_SHOUT_HOST];
+ passwd = getConf()[CONF_SHOUT_PASSWD];
+ user = getConf()[CONF_SHOUT_USER];
+ mount = getConf()[CONF_SHOUT_MOUNT];
+ name = getConf()[CONF_SHOUT_NAME];
+
+ port = strtol(getConf()[CONF_SHOUT_PORT], &test, 10);
+
+ if(*test != '\0' || port <= 0) {
+ ERROR("shout port \"%s\" is not a positive integer\n",
+ getConf()[CONF_SHOUT_PORT]);
+ exit(EXIT_FAILURE);
+ }
+
+ if(shout_set_host(sd->shoutConn, host) != SHOUTERR_SUCCESS ||
+ shout_set_port(sd->shoutConn, port) != SHOUTERR_SUCCESS ||
+ shout_set_password(sd->shoutConn, passwd) != SHOUTERR_SUCCESS ||
+ shout_set_mount(sd->shoutConn, mount) != SHOUTERR_SUCCESS ||
+ shout_set_name(sd->shoutConn, name) != SHOUTERR_SUCCESS ||
+ shout_set_user(sd->shoutConn, user) != SHOUTERR_SUCCESS ||
+ shout_set_format(sd->shoutConn, SHOUT_FORMAT_VORBIS)
+ != SHOUTERR_SUCCESS ||
+ shout_set_protocol(sd->shoutConn, SHOUT_PROTOCOL_HTTP)
+ != SHOUTERR_SUCCESS)
+ {
+ ERROR("error configuring shout: %s\n",
+ shout_get_error(sd->shoutConn));
+ exit(EXIT_FAILURE);
+ }
audioOutput->data = sd;
+
+ if(shoutInitCount == 0) shout_init();
+
+ shoutInitCount++;
+
+ return 0;
}
static void shout_finishDriver(AudioOutput * audioOutput) {
ShoutData * sd = (ShoutData *)audioOutput->data;
freeShoutData(sd);
+
+ shoutInitCount--;
+
+ if(shoutInitCount == 0) shout_shutdown();
}
static void shout_closeDevice(AudioOutput * audioOutput) {
- /*ShoutData * sd = (ShoutData *) audioOutput->data;*/
+ ShoutData * sd = (ShoutData *) audioOutput->data;
+
+ if(shout_close(sd->shoutConn) != SHOUTERR_SUCCESS)
+ {
+ ERROR("problem closing connection to shout server: %s\n",
+ shout_get_error(sd->shoutConn));
+ }
audioOutput->open = 0;
}
@@ -60,7 +154,14 @@ static void shout_closeDevice(AudioOutput * audioOutput) {
static int shout_openDevice(AudioOutput * audioOutput,
AudioFormat * audioFormat)
{
- /*ShoutData * sd = (ShoutData *)audioOutput->data;*/
+ ShoutData * sd = (ShoutData *)audioOutput->data;
+
+ if(shout_open(sd->shoutConn) != SHOUTERR_SUCCESS)
+ {
+ ERROR("problem opening connection to shout server: %s\n",
+ shout_get_error(sd->shoutConn));
+ return -1;
+ }
audioOutput->open = 1;