Commit f4d75d75 authored by Warren Dukes's avatar Warren Dukes

ok, now we're using some of the new audioOutput layer stuff, needs some serious…

ok, now we're using some of the new audioOutput layer stuff, needs some serious testing, and there maybe some serios BREAKAGE git-svn-id: https://svn.musicpd.org/mpd/trunk@2279 09075e82-0dd4-0310-85a5-a0d7c8717e4f
parent ce577384
...@@ -17,110 +17,36 @@ ...@@ -17,110 +17,36 @@
*/ */
#include "audio.h" #include "audio.h"
#include "audioOutput.h"
#include "conf.h" #include "conf.h"
#include "log.h" #include "log.h"
#include "sig_handlers.h" #include "sig_handlers.h"
#include <stdlib.h>
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
#include <signal.h> #include <signal.h>
#ifdef HAVE_AUDIO
#include <ao/ao.h>
static int audio_write_size;
static int audio_ao_driver_id;
static ao_option * audio_ao_options;
static AudioFormat audio_format; static AudioFormat audio_format;
static ao_device * audio_device = NULL;
#endif
static AudioFormat * audio_configFormat = NULL; static AudioFormat * audio_configFormat = NULL;
static AudioOutput * aoOutput = NULL;
static void copyAudioFormat(AudioFormat * dest, AudioFormat * src) { static void copyAudioFormat(AudioFormat * dest, AudioFormat * src) {
dest->sampleRate = src->sampleRate; dest->sampleRate = src->sampleRate;
dest->bits = src->bits; dest->bits = src->bits;
dest->channels = src->channels; dest->channels = src->channels;
} }
void initAudioDriver() { extern AudioOutputPlugin aoPlugin;
#ifdef HAVE_AUDIO
ao_info * ai;
char * dup;
char * stk1;
char * stk2;
char * n1;
char * key;
char * value;
char * test;
/*int found;
int i;*/
audio_write_size = 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(); void initAudioDriver() {
if(strcmp(AUDIO_AO_DRIVER_DEFAULT,(getConf())[CONF_AO_DRIVER])==0) { initAudioOutputPlugins();
audio_ao_driver_id = ao_default_driver_id(); loadAudioOutputPlugin(&aoPlugin);
}
else if((audio_ao_driver_id =
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) {
ERROR("problems getting ao_driver_info\n");
ERROR("you may not have permission to the audio device\n");
exit(EXIT_FAILURE);
}
dup = strdup((getConf())[CONF_AO_DRIVER_OPTIONS]); aoOutput = newAudioOutput("ao");
if(strlen(dup)) { assert(aoOutput);
stk1 = NULL;
n1 = strtok_r(dup,";",&stk1);
while(n1) {
stk2 = NULL;
key = strtok_r(n1,"=",&stk2);
if(!key) {
ERROR("problems parsing "
"ao_driver_options \"%s\"\n", n1);
exit(EXIT_FAILURE);
}
/*found = 0;
for(i=0;i<ai->option_count;i++) {
if(strcmp(ai->options[i],key)==0) {
found = 1;
break;
}
}
if(!found) {
ERROR("\"%s\" is not an option for "
"\"%s\" ao driver\n",key,
ai->short_name);
exit(EXIT_FAILURE);
}*/
value = strtok_r(NULL,"",&stk2);
if(!value) {
ERROR("problems parsing "
"ao_driver_options \"%s\"\n", n1);
exit(EXIT_FAILURE);
}
ao_append_option(&audio_ao_options,key,value);
n1 = strtok_r(NULL,";",&stk1);
}
}
free(dup);
#endif
} }
void getOutputAudioFormat(AudioFormat * inAudioFormat, void getOutputAudioFormat(AudioFormat * inAudioFormat,
...@@ -205,104 +131,44 @@ void finishAudioConfig() { ...@@ -205,104 +131,44 @@ void finishAudioConfig() {
} }
void finishAudioDriver() { void finishAudioDriver() {
#ifdef HAVE_AUDIO finishAudioOutput(aoOutput);
ao_free_options(audio_ao_options); aoOutput = NULL;
ao_shutdown();
#endif
} }
int isCurrentAudioFormat(AudioFormat * audioFormat) { int isCurrentAudioFormat(AudioFormat * audioFormat) {
#ifdef HAVE_AUDIO if(!aoOutput || !audioFormat) return 0;
if(!audio_device || !audioFormat) return 0;
if(memcmp(audioFormat,&audio_format,sizeof(AudioFormat)) != 0) return 0; if(memcmp(audioFormat,&audio_format,sizeof(AudioFormat)) != 0) return 0;
#endif
return 1; return 1;
} }
int openAudioDevice(AudioFormat * audioFormat) { int openAudioDevice(AudioFormat * audioFormat) {
#ifdef HAVE_AUDIO if(aoOutput->open && !isCurrentAudioFormat(audioFormat)) {
ao_sample_format format; closeAudioOutput(aoOutput);
if(audio_device && !isCurrentAudioFormat(audioFormat)) {
closeAudioDevice();
} }
if(!audio_device) { if(!aoOutput->open) {
if(audioFormat) { return openAudioOutput(aoOutput, audioFormat);
copyAudioFormat(&audio_format,audioFormat);
}
format.bits = audio_format.bits;
format.rate = audio_format.sampleRate;
format.byte_format = AO_FMT_NATIVE;
format.channels = audio_format.channels;
blockSignals();
audio_device = ao_open_live(audio_ao_driver_id, &format,
audio_ao_options);
unblockSignals();
if(audio_device==NULL) return -1;
} }
#endif
return 0;
}
void audioError() { return 0;
#ifdef HAVE_AUDIO
if(errno==AO_ENOTLIVE) {
ERROR("not a live ao device\n");
}
else if(errno==AO_EOPENDEVICE) {
ERROR("not able to open audio device\n");
}
else if(errno==AO_EBADOPTION) {
ERROR("bad driver option\n");
}
#endif
} }
int playAudio(char * playChunk, int size) { int playAudio(char * playChunk, int size) {
#ifdef HAVE_AUDIO if(!aoOutput->open) {
int send;
if(audio_device==NULL) {
ERROR("trying to play w/o the audio device being open!\n"); ERROR("trying to play w/o the audio device being open!\n");
return -1; return -1;
} }
while(size>0) {
send = audio_write_size>size?size:audio_write_size;
if(ao_play(audio_device,playChunk,send)==0) {
audioError();
ERROR("closing audio device due to write error\n");
closeAudioDevice();
return -1;
}
playChunk+=send; return playAudioOutput(aoOutput, playChunk, size);
size-=send;
}
#endif
return 0;
} }
int isAudioDeviceOpen() { int isAudioDeviceOpen() {
if(audio_device) return 1; return aoOutput->open;
return 0;
} }
void closeAudioDevice() { void closeAudioDevice() {
#ifdef HAVE_AUDIO if(aoOutput->open) {
if(audio_device) { closeAudioOutput(aoOutput);
blockSignals();
ao_close(audio_device);
audio_device = NULL;
unblockSignals();
} }
#endif
} }
...@@ -32,6 +32,7 @@ AudioOutput * newAudioOutput(char * name) { ...@@ -32,6 +32,7 @@ AudioOutput * newAudioOutput(char * name) {
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;
plugin->initDriverFunc(ret); plugin->initDriverFunc(ret);
} }
......
...@@ -41,7 +41,7 @@ typedef int (* AudioOutputPlayFunc) (AudioOutput * audioOutput, ...@@ -41,7 +41,7 @@ typedef int (* AudioOutputPlayFunc) (AudioOutput * audioOutput,
typedef void (* AudioOutputCloseDeviceFunc) (AudioOutput * audioOutput); typedef void (* AudioOutputCloseDeviceFunc) (AudioOutput * audioOutput);
struct _AudioOutput { struct _AudioOutput {
int error; int open;
AudioOutputFinishDriverFunc finishDriverFunc; AudioOutputFinishDriverFunc finishDriverFunc;
AudioOutputOpenDeviceFunc openDeviceFunc; AudioOutputOpenDeviceFunc openDeviceFunc;
...@@ -60,12 +60,15 @@ typedef struct _AudioOutputPlugin { ...@@ -60,12 +60,15 @@ typedef struct _AudioOutputPlugin {
AudioOutputCloseDeviceFunc closeDeviceFunc; AudioOutputCloseDeviceFunc closeDeviceFunc;
} AudioOutputPlugin; } AudioOutputPlugin;
void initAudioOutputPlugins();
void finishAudioOutputPlugins();
void loadAudioOutputPlugin(AudioOutputPlugin * audioOutputPlugin); void loadAudioOutputPlugin(AudioOutputPlugin * audioOutputPlugin);
void unloadAudioOutputPlugin(AudioOutputPlugin * audioOutputPlugin); void unloadAudioOutputPlugin(AudioOutputPlugin * audioOutputPlugin);
AudioOutput * newAudioOutput(char * name); AudioOutput * newAudioOutput(char * name);
int openAudioOutput(AudioOutput * audioOutput, AudioFormat * audioFormat); int openAudioOutput(AudioOutput * audioOutput, AudioFormat * audioFormat);
int audioOutputPlay(AudioOutput * audioOutput, char * playChunk, int size); int playAudioOutput(AudioOutput * audioOutput, char * playChunk, int size);
void closeAudioOutput(AudioOutput * audioOutput); void closeAudioOutput(AudioOutput * audioOutput);
void finishAudioOutput(AudioOutput * audioOutput); void finishAudioOutput(AudioOutput * audioOutput);
......
...@@ -150,6 +150,7 @@ static void audioOutputAo_closeDevice(AudioOutput * audioOutput) { ...@@ -150,6 +150,7 @@ static void audioOutputAo_closeDevice(AudioOutput * audioOutput) {
if(ad->device) { if(ad->device) {
blockSignals(); blockSignals();
ao_close(ad->device); ao_close(ad->device);
audioOutput->open = 0;
ad->device = NULL; ad->device = NULL;
unblockSignals(); unblockSignals();
} }
...@@ -176,6 +177,8 @@ static int audioOutputAo_openDevice(AudioOutput * audioOutput, ...@@ -176,6 +177,8 @@ static int audioOutputAo_openDevice(AudioOutput * audioOutput,
if(ad->device==NULL) return -1; if(ad->device==NULL) return -1;
audioOutput->open = 1;
return 0; return 0;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment