diff options
Diffstat (limited to 'src/audioOutput_ao.c')
-rw-r--r-- | src/audioOutput_ao.c | 181 |
1 files changed, 63 insertions, 118 deletions
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, |