aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am3
-rw-r--r--src/audioOutput.c22
-rw-r--r--src/audioOutput.h16
-rw-r--r--src/audioOutput_ao.c181
4 files changed, 89 insertions, 133 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index bac83b8e4..c1ece1d97 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -14,6 +14,7 @@ mpd_inputPlugins = \
mpd_headers = \
ack.h \
audio.h \
+ audioOutput.h \
buffer2array.h \
charConv.h \
command.h \
@@ -55,6 +56,8 @@ mpd_SOURCES = \
$(mpd_headers) \
$(mpd_inputPlugins) \
audio.c \
+ audioOutput.c \
+ audioOutput_ao.c \
buffer2array.c \
charConv.c \
command.c \
diff --git a/src/audioOutput.c b/src/audioOutput.c
index aedfda59f..ff0c614a2 100644
--- a/src/audioOutput.c
+++ b/src/audioOutput.c
@@ -28,16 +28,30 @@ AudioOutput * newAudioOutput(char * name) {
if(findInList(audioOutputPluginList, name, &data)) {
AudioOutputPlugin * plugin = (AudioOutputPlugin *) data;
ret = malloc(sizeof(AudioOutput));
- ret->initConfigFunc = plugin->initConfigFunc;
- ret->finishConfigFunc = plugin->finishConfigFunc;
- ret->initDriverFunc = plugin->initDriverFunc;
ret->finishDriverFunc = plugin->initDriverFunc;
ret->openDeviceFunc = plugin->openDeviceFunc;
ret->playFunc = plugin->playFunc;
ret->closeDeviceFunc = plugin->closeDeviceFunc;
+
+ plugin->initDriverFunc(ret);
}
return ret;
}
-void closeAudioOutput(AudioOutput * audioOutput);
+int openAudioOutput(AudioOutput * audioOutput, AudioFormat * audioFormat) {
+ return audioOutput->openDeviceFunc(audioOutput, audioFormat);
+}
+
+int playAudioOutput(AudioOutput * audioOutput, char * playChunk, int size) {
+ return audioOutput->playFunc(audioOutput, playChunk, size);
+}
+
+void closeAudioOutput(AudioOutput * audioOutput) {
+ audioOutput->closeDeviceFunc(audioOutput);
+}
+
+void finishAudioOutput(AudioOutput * audioOutput) {
+ audioOutput->finishDriverFunc(audioOutput);
+ free(audioOutput);
+}
diff --git a/src/audioOutput.h b/src/audioOutput.h
index 1a01263b8..fd76e4772 100644
--- a/src/audioOutput.h
+++ b/src/audioOutput.h
@@ -28,10 +28,6 @@
typedef struct _AudioOutput AudioOutput;
-typedef void (* AudioOutputInitConfigFunc) (AudioOutput * audioOutput);
-
-typedef void (* AudioOutputFinishConfigFunc) (AudioOutput * audioOutput);
-
typedef void (* AudioOutputInitDriverFunc) (AudioOutput * audioOutput);
typedef void (* AudioOutputFinishDriverFunc) (AudioOutput * audioOutput);
@@ -47,32 +43,30 @@ typedef void (* AudioOutputCloseDeviceFunc) (AudioOutput * audioOutput);
struct _AudioOutput {
int error;
- AudioOutputInitConfigFunc initConfigFunc;
- AudioOutputFinishConfigFunc finishConfigFunc;
- AudioOutputInitDriverFunc initDriverFunc;
AudioOutputFinishDriverFunc finishDriverFunc;
AudioOutputOpenDeviceFunc openDeviceFunc;
AudioOutputPlayFunc playFunc;
- AudioOutputCloseDevicFunc closeDeviceFunc;
+ AudioOutputCloseDeviceFunc closeDeviceFunc;
void * data;
};
typedef struct _AudioOutputPlugin {
char * name;
- AudioOutputInitConfigFunc initConfigFunc;
- AudioOutputFinishConfigFunc finishConfigFunc;
AudioOutputInitDriverFunc initDriverFunc;
AudioOutputFinishDriverFunc finishDriverFunc;
AudioOutputOpenDeviceFunc openDeviceFunc;
AudioOutputPlayFunc playFunc;
- AudioOutputCloseDevicFunc closeDeviceFunc;
+ AudioOutputCloseDeviceFunc closeDeviceFunc;
} AudioOutputPlugin;
void loadAudioOutputPlugin(AudioOutputPlugin * audioOutputPlugin);
void unloadAudioOutputPlugin(AudioOutputPlugin * audioOutputPlugin);
AudioOutput * newAudioOutput(char * name);
+int openAudioOutput(AudioOutput * audioOutput, AudioFormat * audioFormat);
+int audioOutputPlay(AudioOutput * audioOutput, char * playChunk, int size);
void closeAudioOutput(AudioOutput * audioOutput);
+void finishAudioOutput(AudioOutput * audioOutput);
#endif
diff --git a/src/audioOutput_ao.c b/src/audioOutput_ao.c
index 385efe2ff..023b7f4a9 100644
--- a/src/audioOutput_ao.c
+++ b/src/audioOutput_ao.c
@@ -27,14 +27,24 @@
#include <ao/ao.h>
-static int audioOutputAo_write_size;
+static int driverInitCount = 0;
-static int audioOutputAo_driver_id;
-static ao_option * audioOutputAo_options;
+typedef struct _AoData {
+ int writeSize;
+ int driverId;
+ ao_option * options;
+ ao_device * device;
+} AoData;
-static ao_device * audioOutputAo_device = NULL;
+static AoData * newAoData() {
+ AoData * ret = malloc(sizeof(AoData));
+ ret->device = NULL;
+ ret->options = NULL;
-void audioOutputAo_initDriver() {
+ return ret;
+}
+
+static void audioOutputAo_initDriver(AudioOutput * audioOutput) {
ao_info * ai;
char * dup;
char * stk1;
@@ -43,28 +53,33 @@ void audioOutputAo_initDriver() {
char * key;
char * value;
char * test;
+ AoData * ad = newAoData();
- audio_write_size = strtol((getConf())[CONF_AUDIO_WRITE_SIZE],&test,10);
+ audioOutput->data = ad;
+
+ ad->writeSize = strtol((getConf())[CONF_AUDIO_WRITE_SIZE],&test,10);
if (*test!='\0') {
ERROR("\"%s\" is not a valid write size",
(getConf())[CONF_AUDIO_WRITE_SIZE]);
exit(EXIT_FAILURE);
}
- audio_ao_options = NULL;
-
- ao_initialize();
+ if(driverInitCount == 0) {
+ ao_initialize();
+ }
+ driverInitCount++;
+
if(strcmp(AUDIO_AO_DRIVER_DEFAULT,(getConf())[CONF_AO_DRIVER])==0) {
- audio_ao_driver_id = ao_default_driver_id();
+ ad->driverId = ao_default_driver_id();
}
- else if((audio_ao_driver_id =
+ else if((ad->driverId =
ao_driver_id((getConf())[CONF_AO_DRIVER]))<0) {
ERROR("\"%s\" is not a valid ao driver\n",
(getConf())[CONF_AO_DRIVER]);
exit(EXIT_FAILURE);
}
- if((ai = ao_driver_info(audio_ao_driver_id))==NULL) {
+ if((ai = ao_driver_info(ad->driverId))==NULL) {
ERROR("problems getting ao_driver_info\n");
ERROR("you may not have permission to the audio device\n");
exit(EXIT_FAILURE);
@@ -101,135 +116,76 @@ void audioOutputAo_initDriver() {
"ao_driver_options \"%s\"\n", n1);
exit(EXIT_FAILURE);
}
- ao_append_option(&audio_ao_options,key,value);
+ ao_append_option(&ad->options,key,value);
n1 = strtok_r(NULL,";",&stk1);
}
}
free(dup);
}
-void audioOutputAo_initConfig() {
- char * conf = getConf()[CONF_AUDIO_OUTPUT_FORMAT];
- char * test;
-
- if(NULL == conf) return;
-
- audio_configFormat = malloc(sizeof(AudioFormat));
+static void audioOutputAo_finishDriver(AudioOutput * audioOutput) {
+ AoData * ad = (AoData *)audioOutput->data;
+ ao_free_options(ad->options);
- memset(audio_configFormat,0,sizeof(AudioFormat));
-
- audio_configFormat->sampleRate = strtol(conf,&test,10);
-
- if(*test!=':') {
- ERROR("error parsing audio output format: %s\n",conf);
- exit(EXIT_FAILURE);
- }
-
- /*switch(audio_configFormat->sampleRate) {
- case 48000:
- case 44100:
- case 32000:
- case 16000:
- break;
- default:
- ERROR("sample rate %i can not be used for audio output\n",
- (int)audio_configFormat->sampleRate);
- exit(EXIT_FAILURE);
- }*/
-
- if(audio_configFormat->sampleRate <= 0) {
- ERROR("sample rate %i is not >= 0\n",
- (int)audio_configFormat->sampleRate);
- exit(EXIT_FAILURE);
- }
-
- audio_configFormat->bits = strtol(test+1,&test,10);
-
- if(*test!=':') {
- ERROR("error parsing audio output format: %s\n",conf);
- exit(EXIT_FAILURE);
- }
-
- switch(audio_configFormat->bits) {
- case 16:
- break;
- default:
- ERROR("bits %i can not be used for audio output\n",
- (int)audio_configFormat->bits);
- exit(EXIT_FAILURE);
- }
-
- audio_configFormat->channels = strtol(test+1,&test,10);
-
- if(*test!='\0') {
- ERROR("error parsing audio output format: %s\n",conf);
- exit(EXIT_FAILURE);
- }
-
- switch(audio_configFormat->channels) {
- case 2:
- break;
- default:
- ERROR("channels %i can not be used for audio output\n",
- (int)audio_configFormat->channels);
- exit(EXIT_FAILURE);
- }
-}
+ driverInitCount--;
-void audioOutputAo_finishConfig() {
- if(audio_configFormat) free(audio_configFormat);
+ if(driverInitCount == 0) ao_shutdown();
}
-void audioOutputAo_finishDriver() {
- ao_free_options(audio_ao_options);
+static void audioOutputAo_closeDevice(AudioOutput * audioOutput) {
+ AoData * ad = (AoData *) audioOutput->data;
- ao_shutdown();
+ if(ad->device) {
+ blockSignals();
+ ao_close(ad->device);
+ ad->device = NULL;
+ unblockSignals();
+ }
}
-int audioOutputAo_openDevice(AudioFormat * audioFormat) {
+static int audioOutputAo_openDevice(AudioOutput * audioOutput,
+ AudioFormat * audioFormat)
+{
ao_sample_format format;
+ AoData * ad = (AoData *)audioOutput->data;
- if(audio_device && !isCurrentAudioFormat(audioFormat)) {
- closeAudioDevice();
+ if(ad->device) {
+ audioOutputAo_closeDevice(audioOutput);
}
- if(!audio_device) {
- if(audioFormat) {
- copyAudioFormat(&audio_format,audioFormat);
- }
+ format.bits = audioFormat->bits;
+ format.rate = audioFormat->sampleRate;
+ format.byte_format = AO_FMT_NATIVE;
+ format.channels = audioFormat->channels;
- format.bits = audio_format.bits;
- format.rate = audio_format.sampleRate;
- format.byte_format = AO_FMT_NATIVE;
- format.channels = audio_format.channels;
+ blockSignals();
+ ad->device = ao_open_live(ad->driverId, &format, ad->options);
+ unblockSignals();
- blockSignals();
- audio_device = ao_open_live(audio_ao_driver_id, &format,
- audio_ao_options);
- unblockSignals();
-
- if(audio_device==NULL) return -1;
- }
+ if(ad->device==NULL) return -1;
return 0;
}
-int audioOutputAo_playAudio(char * playChunk, int size) {
+static int audioOutputAo_play(AudioOutput * audioOutput, char * playChunk,
+ int size)
+{
int send;
+ AoData * ad = (AoData *)audioOutput->data;
- if(audio_device==NULL) {
+ if(ad->device==NULL) {
ERROR("trying to play w/o the audio device being open!\n");
return -1;
}
while(size>0) {
- send = audio_write_size>size?size:audio_write_size;
+ send = ad->writeSize > size ? size : ad->writeSize;
- if(ao_play(audio_device,playChunk,send)==0) {
+ if(ao_play(ad->device, playChunk, send)==0) {
audioError();
ERROR("closing audio device due to write error\n");
- closeAudioDevice();
+ audioOutputAo_closeDevice(audioOutput);
return -1;
}
@@ -240,20 +196,9 @@ int audioOutputAo_playAudio(char * playChunk, int size) {
return 0;
}
-void audioOutputAo_closeAudioDevice() {
- if(audio_device) {
- blockSignals();
- ao_close(audio_device);
- audio_device = NULL;
- unblockSignals();
- }
-}
-
AudioOutputPlugin aoPlugin =
{
"ao",
- audioOutputAo_initConfig,
- audioOutputAo_finishConfig,
audioOutputAo_initDriver,
audioOutputAo_finishDriver,
audioOutputAo_openDevice,