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 @@
*/
#include "audio.h"
#include "audioOutput.h"
#include "conf.h"
#include "log.h"
#include "sig_handlers.h"
#include <stdlib.h>
#include <string.h>
#include <assert.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 ao_device * audio_device = NULL;
#endif
static AudioFormat * audio_configFormat = NULL;
static AudioOutput * aoOutput = NULL;
static void copyAudioFormat(AudioFormat * dest, AudioFormat * src) {
dest->sampleRate = src->sampleRate;
dest->bits = src->bits;
dest->channels = src->channels;
}
void initAudioDriver() {
#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();
if(strcmp(AUDIO_AO_DRIVER_DEFAULT,(getConf())[CONF_AO_DRIVER])==0) {
audio_ao_driver_id = ao_default_driver_id();
}
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);
}
extern AudioOutputPlugin aoPlugin;
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);
}
void initAudioDriver() {
initAudioOutputPlugins();
loadAudioOutputPlugin(&aoPlugin);
dup = strdup((getConf())[CONF_AO_DRIVER_OPTIONS]);
if(strlen(dup)) {
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
aoOutput = newAudioOutput("ao");
assert(aoOutput);
}
void getOutputAudioFormat(AudioFormat * inAudioFormat,
......@@ -205,104 +131,44 @@ void finishAudioConfig() {
}
void finishAudioDriver() {
#ifdef HAVE_AUDIO
ao_free_options(audio_ao_options);
ao_shutdown();
#endif
finishAudioOutput(aoOutput);
aoOutput = NULL;
}
int isCurrentAudioFormat(AudioFormat * audioFormat) {
#ifdef HAVE_AUDIO
if(!audio_device || !audioFormat) return 0;
if(!aoOutput || !audioFormat) return 0;
if(memcmp(audioFormat,&audio_format,sizeof(AudioFormat)) != 0) return 0;
#endif
return 1;
}
int openAudioDevice(AudioFormat * audioFormat) {
#ifdef HAVE_AUDIO
ao_sample_format format;
if(audio_device && !isCurrentAudioFormat(audioFormat)) {
closeAudioDevice();
if(aoOutput->open && !isCurrentAudioFormat(audioFormat)) {
closeAudioOutput(aoOutput);
}
if(!audio_device) {
if(audioFormat) {
copyAudioFormat(&audio_format,audioFormat);
if(!aoOutput->open) {
return openAudioOutput(aoOutput, 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() {
#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) {
#ifdef HAVE_AUDIO
int send;
if(audio_device==NULL) {
if(!aoOutput->open) {
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;
if(ao_play(audio_device,playChunk,send)==0) {
audioError();
ERROR("closing audio device due to write error\n");
closeAudioDevice();
return -1;
}
playChunk+=send;
size-=send;
}
#endif
return 0;
return playAudioOutput(aoOutput, playChunk, size);
}
int isAudioDeviceOpen() {
if(audio_device) return 1;
return 0;
return aoOutput->open;
}
void closeAudioDevice() {
#ifdef HAVE_AUDIO
if(audio_device) {
blockSignals();
ao_close(audio_device);
audio_device = NULL;
unblockSignals();
if(aoOutput->open) {
closeAudioOutput(aoOutput);
}
#endif
}
......@@ -32,6 +32,7 @@ AudioOutput * newAudioOutput(char * name) {
ret->openDeviceFunc = plugin->openDeviceFunc;
ret->playFunc = plugin->playFunc;
ret->closeDeviceFunc = plugin->closeDeviceFunc;
ret->open = 0;
plugin->initDriverFunc(ret);
}
......
......@@ -41,7 +41,7 @@ typedef int (* AudioOutputPlayFunc) (AudioOutput * audioOutput,
typedef void (* AudioOutputCloseDeviceFunc) (AudioOutput * audioOutput);
struct _AudioOutput {
int error;
int open;
AudioOutputFinishDriverFunc finishDriverFunc;
AudioOutputOpenDeviceFunc openDeviceFunc;
......@@ -60,12 +60,15 @@ typedef struct _AudioOutputPlugin {
AudioOutputCloseDeviceFunc closeDeviceFunc;
} AudioOutputPlugin;
void initAudioOutputPlugins();
void finishAudioOutputPlugins();
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);
int playAudioOutput(AudioOutput * audioOutput, char * playChunk, int size);
void closeAudioOutput(AudioOutput * audioOutput);
void finishAudioOutput(AudioOutput * audioOutput);
......
......@@ -150,6 +150,7 @@ static void audioOutputAo_closeDevice(AudioOutput * audioOutput) {
if(ad->device) {
blockSignals();
ao_close(ad->device);
audioOutput->open = 0;
ad->device = NULL;
unblockSignals();
}
......@@ -176,6 +177,8 @@ static int audioOutputAo_openDevice(AudioOutput * audioOutput,
if(ad->device==NULL) return -1;
audioOutput->open = 1;
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