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 #include +#include +#include + +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;