if no audioOutput specified, we no attempt to detect if there exists a usable oss or alsa device
git-svn-id: https://svn.musicpd.org/mpd/trunk@3057 09075e82-0dd4-0310-85a5-a0d7c8717e4f
This commit is contained in:
parent
1865193575
commit
8583a3bc4e
@ -79,7 +79,9 @@ void initAudioDriver() {
|
||||
myAudioDevicesEnabled[i] = 1;
|
||||
}
|
||||
|
||||
while((param = getNextConfigParam(CONF_AUDIO_OUTPUT, param))) {
|
||||
param = getNextConfigParam(CONF_AUDIO_OUTPUT, param);
|
||||
|
||||
do {
|
||||
if(audioOutputArraySize == AUDIO_MAX_DEVICES) {
|
||||
ERROR("only up to 255 audio output devices are "
|
||||
"supported");
|
||||
@ -93,12 +95,12 @@ void initAudioDriver() {
|
||||
|
||||
audioOutputArray[i] = newAudioOutput(param);
|
||||
|
||||
if(!audioOutputArray[i]) {
|
||||
if(!audioOutputArray[i] && param) {
|
||||
ERROR("problems configuring output device defined at "
|
||||
"line %i\n", param->line);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
} while((param = getNextConfigParam(CONF_AUDIO_OUTPUT, param)));
|
||||
}
|
||||
|
||||
void getOutputAudioFormat(AudioFormat * inAudioFormat,
|
||||
|
@ -48,55 +48,87 @@ AudioOutput * newAudioOutput(ConfigParam * param) {
|
||||
char * name = NULL;
|
||||
char * format = NULL;
|
||||
char * type = NULL;
|
||||
BlockParam * bp;
|
||||
BlockParam * bp = NULL;
|
||||
AudioOutputPlugin * plugin = NULL;
|
||||
|
||||
getBlockParam(AUDIO_OUTPUT_NAME, name, 1);
|
||||
getBlockParam(AUDIO_OUTPUT_TYPE, type, 1);
|
||||
if(param) {
|
||||
getBlockParam(AUDIO_OUTPUT_NAME, name, 1);
|
||||
getBlockParam(AUDIO_OUTPUT_TYPE, type, 1);
|
||||
|
||||
if(findInList(audioOutputPluginList, type, &data)) {
|
||||
AudioOutputPlugin * plugin = (AudioOutputPlugin *) data;
|
||||
ret = malloc(sizeof(AudioOutput));
|
||||
ret->name = strdup(name);
|
||||
ret->type = strdup(type);
|
||||
ret->finishDriverFunc = plugin->finishDriverFunc;
|
||||
ret->openDeviceFunc = plugin->openDeviceFunc;
|
||||
ret->playFunc = plugin->playFunc;
|
||||
ret->dropBufferedAudioFunc = plugin->dropBufferedAudioFunc;
|
||||
ret->closeDeviceFunc = plugin->closeDeviceFunc;
|
||||
ret->sendMetdataFunc = plugin->sendMetdataFunc;
|
||||
ret->open = 0;
|
||||
|
||||
ret->convertAudioFormat = 0;
|
||||
ret->sameInAndOutFormats = 0;
|
||||
ret->convBuffer = NULL;
|
||||
ret->convBufferLen = 0;
|
||||
|
||||
memset(&ret->inAudioFormat, 0, sizeof(AudioFormat));
|
||||
memset(&ret->outAudioFormat, 0, sizeof(AudioFormat));
|
||||
memset(&ret->reqAudioFormat, 0, sizeof(AudioFormat));
|
||||
|
||||
getBlockParam(AUDIO_OUTPUT_FORMAT, format, 0);
|
||||
if(!findInList(audioOutputPluginList, type, &data)) {
|
||||
ERROR("couldn't find audio output plugin for type "
|
||||
"\"%s\" at line %i\n", type,
|
||||
param->line);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
plugin = (AudioOutputPlugin *) data;
|
||||
|
||||
if(format) {
|
||||
ret->convertAudioFormat = 1;
|
||||
|
||||
if(0 != parseAudioConfig(&ret->reqAudioFormat, format))
|
||||
{
|
||||
ERROR("error parsing format at line %i\n",
|
||||
ERROR("error parsing format at line %i\n",
|
||||
bp->line);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if(plugin->initDriverFunc(ret, param) != 0) {
|
||||
free(ret);
|
||||
ret = NULL;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
ERROR("couldn't find audio output plugin for type \"%s\" at "
|
||||
"line %i\n", type, param->line);
|
||||
exit(EXIT_FAILURE);
|
||||
ListNode * node = audioOutputPluginList->firstNode;
|
||||
|
||||
WARNING("No \"%s\" defined in config file\n",
|
||||
CONF_AUDIO_OUTPUT);
|
||||
WARNING("Attempt to detect audio output device\n");
|
||||
|
||||
while(node) {
|
||||
plugin = (AudioOutputPlugin *) node->data;
|
||||
if(plugin->testDefaultDeviceFunc) {
|
||||
WARNING("Attempting to detect a %s audio "
|
||||
"device\n", plugin->name);
|
||||
if(plugin->testDefaultDeviceFunc() == 0) {
|
||||
WARNING("Successfully detected a %s "
|
||||
"audio device\n",
|
||||
plugin->name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
node = node->nextNode;
|
||||
}
|
||||
|
||||
if(!node) {
|
||||
WARNING("Unable to detect an audio device\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
name = "default detected output";
|
||||
type = plugin->name;
|
||||
}
|
||||
|
||||
ret = malloc(sizeof(AudioOutput));
|
||||
ret->name = strdup(name);
|
||||
ret->type = strdup(type);
|
||||
ret->finishDriverFunc = plugin->finishDriverFunc;
|
||||
ret->openDeviceFunc = plugin->openDeviceFunc;
|
||||
ret->playFunc = plugin->playFunc;
|
||||
ret->dropBufferedAudioFunc = plugin->dropBufferedAudioFunc;
|
||||
ret->closeDeviceFunc = plugin->closeDeviceFunc;
|
||||
ret->sendMetdataFunc = plugin->sendMetdataFunc;
|
||||
ret->open = 0;
|
||||
|
||||
ret->convertAudioFormat = 0;
|
||||
ret->sameInAndOutFormats = 0;
|
||||
ret->convBuffer = NULL;
|
||||
ret->convBufferLen = 0;
|
||||
|
||||
memset(&ret->inAudioFormat, 0, sizeof(AudioFormat));
|
||||
memset(&ret->outAudioFormat, 0, sizeof(AudioFormat));
|
||||
memset(&ret->reqAudioFormat, 0, sizeof(AudioFormat));
|
||||
|
||||
if(plugin->initDriverFunc(ret, param) != 0) {
|
||||
free(ret);
|
||||
ret = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -28,6 +28,8 @@
|
||||
|
||||
typedef struct _AudioOutput AudioOutput;
|
||||
|
||||
typedef int (* AudioOutputTestDefaultDeviceFunc) ();
|
||||
|
||||
typedef int (* AudioOutputInitDriverFunc) (AudioOutput * audioOutput,
|
||||
ConfigParam * param);
|
||||
|
||||
@ -71,6 +73,7 @@ struct _AudioOutput {
|
||||
typedef struct _AudioOutputPlugin {
|
||||
char * name;
|
||||
|
||||
AudioOutputTestDefaultDeviceFunc testDefaultDeviceFunc;
|
||||
AudioOutputInitDriverFunc initDriverFunc;
|
||||
AudioOutputFinishDriverFunc finishDriverFunc;
|
||||
AudioOutputOpenDeviceFunc openDeviceFunc;
|
||||
|
@ -69,7 +69,10 @@ static void freeAlsaData(AlsaData * ad) {
|
||||
}
|
||||
|
||||
static int alsa_initDriver(AudioOutput * audioOutput, ConfigParam * param) {
|
||||
BlockParam * bp = getBlockParam(param, "device");
|
||||
BlockParam * bp = NULL;
|
||||
|
||||
if(param) bp = getBlockParam(param, "device");
|
||||
|
||||
AlsaData * ad = newAlsaData();
|
||||
|
||||
audioOutput->data = ad;
|
||||
@ -85,6 +88,23 @@ static void alsa_finishDriver(AudioOutput * audioOutput) {
|
||||
freeAlsaData(ad);
|
||||
}
|
||||
|
||||
static int alsa_testDefault()
|
||||
{
|
||||
snd_pcm_t * handle;
|
||||
|
||||
int ret = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK,
|
||||
SND_PCM_NONBLOCK);
|
||||
|
||||
if(ret) {
|
||||
WARNING("Error opening default alsa device: %s\n",
|
||||
snd_strerror(-ret));
|
||||
return -1;
|
||||
}
|
||||
else snd_pcm_close(handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int alsa_openDevice(AudioOutput * audioOutput)
|
||||
{
|
||||
AlsaData * ad = audioOutput->data;
|
||||
@ -313,6 +333,7 @@ static int alsa_playAudio(AudioOutput * audioOutput, char * playChunk,
|
||||
AudioOutputPlugin alsaPlugin =
|
||||
{
|
||||
"alsa",
|
||||
alsa_testDefault,
|
||||
alsa_initDriver,
|
||||
alsa_finishDriver,
|
||||
alsa_openDevice,
|
||||
@ -332,6 +353,7 @@ AudioOutputPlugin alsaPlugin =
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL /* sendMetadataFunc */
|
||||
};
|
||||
|
||||
|
@ -237,6 +237,7 @@ static int audioOutputAo_play(AudioOutput * audioOutput, char * playChunk,
|
||||
AudioOutputPlugin aoPlugin =
|
||||
{
|
||||
"ao",
|
||||
NULL,
|
||||
audioOutputAo_initDriver,
|
||||
audioOutputAo_finishDriver,
|
||||
audioOutputAo_openDevice,
|
||||
@ -259,6 +260,7 @@ AudioOutputPlugin aoPlugin =
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -291,10 +291,38 @@ static int oss_statDevice(char * device, int * stErrno) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int oss_testDefault() {
|
||||
int fd;
|
||||
|
||||
fd = open("/dev/sound/dsp", O_WRONLY);
|
||||
|
||||
if(fd) {
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
WARNING("Error opening OSS device \"/dev/sound/dsp\": %s\n",
|
||||
strerror(errno));
|
||||
|
||||
fd = open("/dev/dsp", O_WRONLY);
|
||||
|
||||
if(fd) {
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
WARNING("Error opening OSS device \"/dev/dsp\": %s\n",
|
||||
strerror(errno));
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int oss_initDriver(AudioOutput * audioOutput, ConfigParam * param) {
|
||||
BlockParam * bp = getBlockParam(param, "device");
|
||||
BlockParam * bp = NULL;
|
||||
|
||||
if(param) bp = getBlockParam(param, "device");
|
||||
|
||||
OssData * od = newOssData();
|
||||
|
||||
audioOutput->data = od;
|
||||
|
||||
if(!bp) {
|
||||
@ -307,8 +335,14 @@ static int oss_initDriver(AudioOutput * audioOutput, ConfigParam * param) {
|
||||
if(ret[0] == 0) od->device = strdup("/dev/sound/dsp");
|
||||
else if(ret[1] == 0) od->device = strdup("/dev/dsp");
|
||||
else {
|
||||
ERROR("Error trying to open default OSS device "
|
||||
"specified at line %i\n", param->line);
|
||||
if(param) {
|
||||
ERROR("Error trying to open default OSS device "
|
||||
"specified at line %i\n", param->line);
|
||||
}
|
||||
else {
|
||||
ERROR("Error trying to open default OSS "
|
||||
"device\n");
|
||||
}
|
||||
|
||||
if(ret[0] == ret[1] == OSS_STAT_DOESN_T_EXIST) {
|
||||
ERROR("Neither /dev/dsp nor /dev/sound/dsp "
|
||||
@ -501,6 +535,7 @@ static int oss_playAudio(AudioOutput * audioOutput, char * playChunk,
|
||||
AudioOutputPlugin ossPlugin =
|
||||
{
|
||||
"oss",
|
||||
oss_testDefault,
|
||||
oss_initDriver,
|
||||
oss_finishDriver,
|
||||
oss_openDevice,
|
||||
@ -521,6 +556,7 @@ AudioOutputPlugin ossPlugin =
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL /* sendMetadataFunc */
|
||||
};
|
||||
|
||||
|
@ -597,6 +597,7 @@ static void myShout_setTag(AudioOutput * audioOutput, MpdTag * tag) {
|
||||
AudioOutputPlugin shoutPlugin =
|
||||
{
|
||||
"shout",
|
||||
NULL,
|
||||
myShout_initDriver,
|
||||
myShout_finishDriver,
|
||||
myShout_openDevice,
|
||||
@ -617,6 +618,7 @@ AudioOutputPlugin shoutPlugin =
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -68,9 +68,12 @@ void bufferWarning(char * format, ... ) {
|
||||
|
||||
va_end(arglist);
|
||||
}
|
||||
|
||||
void flushWarningLog() {
|
||||
char * s;
|
||||
|
||||
DEBUG("flushing warning messages\n");
|
||||
|
||||
if(warningBuffer == NULL) return;
|
||||
|
||||
s = strtok(warningBuffer, "\n");
|
||||
|
@ -357,8 +357,8 @@ void setupLogOutput(Options * options, FILE * out, FILE * err) {
|
||||
}
|
||||
|
||||
myfprintfStdLogMode(out, err);
|
||||
flushWarningLog();
|
||||
}
|
||||
flushWarningLog();
|
||||
|
||||
/* lets redirect stdin to dev null as a work around for libao bug */
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user