shout audioOutput will now connect and disconnect from icecast server
git-svn-id: https://svn.musicpd.org/mpd/trunk@2285 09075e82-0dd4-0310-85a5-a0d7c8717e4f
This commit is contained in:
		@@ -32,6 +32,7 @@ static AudioFormat audio_format;
 | 
				
			|||||||
static AudioFormat * audio_configFormat = NULL;
 | 
					static AudioFormat * audio_configFormat = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static AudioOutput * aoOutput = NULL;
 | 
					static AudioOutput * aoOutput = NULL;
 | 
				
			||||||
 | 
					static AudioOutput * shoutOutput = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void copyAudioFormat(AudioFormat * dest, AudioFormat * src) {
 | 
					static void copyAudioFormat(AudioFormat * dest, AudioFormat * src) {
 | 
				
			||||||
        dest->sampleRate = src->sampleRate;
 | 
					        dest->sampleRate = src->sampleRate;
 | 
				
			||||||
@@ -49,6 +50,7 @@ void initAudioDriver() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	aoOutput = newAudioOutput("ao");
 | 
						aoOutput = newAudioOutput("ao");
 | 
				
			||||||
	assert(aoOutput);
 | 
						assert(aoOutput);
 | 
				
			||||||
 | 
						shoutOutput = newAudioOutput("shout");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void getOutputAudioFormat(AudioFormat * inAudioFormat, 
 | 
					void getOutputAudioFormat(AudioFormat * inAudioFormat, 
 | 
				
			||||||
@@ -134,6 +136,7 @@ void finishAudioConfig() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void finishAudioDriver() {
 | 
					void finishAudioDriver() {
 | 
				
			||||||
	finishAudioOutput(aoOutput);
 | 
						finishAudioOutput(aoOutput);
 | 
				
			||||||
 | 
						if(shoutOutput) finishAudioOutput(shoutOutput);
 | 
				
			||||||
	aoOutput = NULL;
 | 
						aoOutput = NULL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -148,6 +151,7 @@ int isCurrentAudioFormat(AudioFormat * audioFormat) {
 | 
				
			|||||||
int openAudioDevice(AudioFormat * audioFormat) {
 | 
					int openAudioDevice(AudioFormat * audioFormat) {
 | 
				
			||||||
	if(!aoOutput->open || !isCurrentAudioFormat(audioFormat)) {
 | 
						if(!aoOutput->open || !isCurrentAudioFormat(audioFormat)) {
 | 
				
			||||||
		copyAudioFormat(&audio_format, audioFormat);
 | 
							copyAudioFormat(&audio_format, audioFormat);
 | 
				
			||||||
 | 
							if(shoutOutput) openAudioOutput(shoutOutput, audioFormat);
 | 
				
			||||||
		return openAudioOutput(aoOutput, audioFormat);
 | 
							return openAudioOutput(aoOutput, audioFormat);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -155,6 +159,7 @@ int openAudioDevice(AudioFormat * audioFormat) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int playAudio(char * playChunk, int size) {
 | 
					int playAudio(char * playChunk, int size) {
 | 
				
			||||||
 | 
						if(shoutOutput) playAudioOutput(shoutOutput, playChunk, size);
 | 
				
			||||||
	return playAudioOutput(aoOutput, playChunk, size);
 | 
						return playAudioOutput(aoOutput, playChunk, size);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -163,5 +168,6 @@ int isAudioDeviceOpen() {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void closeAudioDevice() {
 | 
					void closeAudioDevice() {
 | 
				
			||||||
 | 
						if(shoutOutput) closeAudioOutput(shoutOutput);
 | 
				
			||||||
	closeAudioOutput(aoOutput);
 | 
						closeAudioOutput(aoOutput);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,13 +28,16 @@ AudioOutput * newAudioOutput(char * name) {
 | 
				
			|||||||
	if(findInList(audioOutputPluginList, name, &data)) {
 | 
						if(findInList(audioOutputPluginList, name, &data)) {
 | 
				
			||||||
		AudioOutputPlugin * plugin = (AudioOutputPlugin *) data;
 | 
							AudioOutputPlugin * plugin = (AudioOutputPlugin *) data;
 | 
				
			||||||
		ret = malloc(sizeof(AudioOutput));
 | 
							ret = malloc(sizeof(AudioOutput));
 | 
				
			||||||
		ret->finishDriverFunc = plugin->initDriverFunc;
 | 
							ret->finishDriverFunc = plugin->finishDriverFunc;
 | 
				
			||||||
		ret->openDeviceFunc = plugin->openDeviceFunc;
 | 
							ret->openDeviceFunc = plugin->openDeviceFunc;
 | 
				
			||||||
		ret->playFunc = plugin->playFunc;
 | 
							ret->playFunc = plugin->playFunc;
 | 
				
			||||||
		ret->closeDeviceFunc = plugin->closeDeviceFunc;
 | 
							ret->closeDeviceFunc = plugin->closeDeviceFunc;
 | 
				
			||||||
		ret->open = 0;
 | 
							ret->open = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		plugin->initDriverFunc(ret);
 | 
							if(plugin->initDriverFunc(ret) != 0) {
 | 
				
			||||||
 | 
								free(ret);
 | 
				
			||||||
 | 
								ret = NULL;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,7 +28,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
typedef struct _AudioOutput AudioOutput;
 | 
					typedef struct _AudioOutput AudioOutput;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef void (* AudioOutputInitDriverFunc) (AudioOutput * audioOutput);
 | 
					typedef int (* AudioOutputInitDriverFunc) (AudioOutput * audioOutput);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef void (* AudioOutputFinishDriverFunc) (AudioOutput * audioOutput);
 | 
					typedef void (* AudioOutputFinishDriverFunc) (AudioOutput * audioOutput);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -56,7 +56,7 @@ static void audioOutputAo_error() {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void audioOutputAo_initDriver(AudioOutput * audioOutput) {
 | 
					static int audioOutputAo_initDriver(AudioOutput * audioOutput) {
 | 
				
			||||||
	ao_info * ai;
 | 
						ao_info * ai;
 | 
				
			||||||
	char * dup;
 | 
						char * dup;
 | 
				
			||||||
	char * stk1;
 | 
						char * stk1;
 | 
				
			||||||
@@ -71,7 +71,7 @@ static void audioOutputAo_initDriver(AudioOutput * audioOutput) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	ad->writeSize = strtol((getConf())[CONF_AUDIO_WRITE_SIZE],&test,10);
 | 
						ad->writeSize = strtol((getConf())[CONF_AUDIO_WRITE_SIZE],&test,10);
 | 
				
			||||||
	if (*test!='\0') {
 | 
						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]);
 | 
								(getConf())[CONF_AUDIO_WRITE_SIZE]);
 | 
				
			||||||
		exit(EXIT_FAILURE);
 | 
							exit(EXIT_FAILURE);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -133,6 +133,8 @@ static void audioOutputAo_initDriver(AudioOutput * audioOutput) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	free(dup);
 | 
						free(dup);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void freeAoData(AoData * ad) {
 | 
					static void freeAoData(AoData * ad) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,33 +26,127 @@
 | 
				
			|||||||
#include <assert.h>
 | 
					#include <assert.h>
 | 
				
			||||||
#include <signal.h>
 | 
					#include <signal.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <shout/shout.h>
 | 
				
			||||||
 | 
					#include <vorbis/vorbisenc.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int shoutInitCount = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct _ShoutData {
 | 
					typedef struct _ShoutData {
 | 
				
			||||||
 | 
						shout_t * shoutConn;
 | 
				
			||||||
} ShoutData;
 | 
					} ShoutData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static ShoutData * newShoutData() {
 | 
					static ShoutData * newShoutData() {
 | 
				
			||||||
	ShoutData * ret = malloc(sizeof(ShoutData));
 | 
						ShoutData * ret = malloc(sizeof(ShoutData));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret->shoutConn = shout_new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void freeShoutData(ShoutData * sd) {
 | 
					static void freeShoutData(ShoutData * sd) {
 | 
				
			||||||
 | 
						if(sd->shoutConn) shout_free(sd->shoutConn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	free(sd);
 | 
						free(sd);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void shout_initDriver(AudioOutput * audioOutput) {
 | 
					static int shout_initDriver(AudioOutput * audioOutput) {
 | 
				
			||||||
	ShoutData * sd  = newShoutData();
 | 
						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;
 | 
						audioOutput->data = sd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if(shoutInitCount == 0) shout_init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						shoutInitCount++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void shout_finishDriver(AudioOutput * audioOutput) {
 | 
					static void shout_finishDriver(AudioOutput * audioOutput) {
 | 
				
			||||||
	ShoutData * sd = (ShoutData *)audioOutput->data;
 | 
						ShoutData * sd = (ShoutData *)audioOutput->data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	freeShoutData(sd);
 | 
						freeShoutData(sd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						shoutInitCount--;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if(shoutInitCount == 0) shout_shutdown();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void shout_closeDevice(AudioOutput * audioOutput) {
 | 
					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;
 | 
						audioOutput->open = 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -60,7 +154,14 @@ static void shout_closeDevice(AudioOutput * audioOutput) {
 | 
				
			|||||||
static int shout_openDevice(AudioOutput * audioOutput,
 | 
					static int shout_openDevice(AudioOutput * audioOutput,
 | 
				
			||||||
		AudioFormat * audioFormat) 
 | 
							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;
 | 
						audioOutput->open = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user