diff options
author | Warren Dukes <warren.dukes@gmail.com> | 2004-11-02 17:05:27 +0000 |
---|---|---|
committer | Warren Dukes <warren.dukes@gmail.com> | 2004-11-02 17:05:27 +0000 |
commit | ee5d5d633016948f3ecf2d5f9875d7e8223f9a36 (patch) | |
tree | eb58a5f4ed032e6f28ff0e7f5bdaae29dd937e38 /src/audioOutput.c | |
parent | 02982397700a02cb095970023ff9e8618638cc0c (diff) | |
download | mpd-ee5d5d633016948f3ecf2d5f9875d7e8223f9a36.tar.gz mpd-ee5d5d633016948f3ecf2d5f9875d7e8223f9a36.tar.xz mpd-ee5d5d633016948f3ecf2d5f9875d7e8223f9a36.zip |
abstract out audioFormat conversion from shout plugin to the audioOutput layer,
now format can be specified for each different audioOutput device
git-svn-id: https://svn.musicpd.org/mpd/trunk@2474 09075e82-0dd4-0310-85a5-a0d7c8717e4f
Diffstat (limited to 'src/audioOutput.c')
-rw-r--r-- | src/audioOutput.c | 89 |
1 files changed, 82 insertions, 7 deletions
diff --git a/src/audioOutput.c b/src/audioOutput.c index 12f8c17b2..27a464ade 100644 --- a/src/audioOutput.c +++ b/src/audioOutput.c @@ -2,11 +2,13 @@ #include "list.h" #include "log.h" +#include "pcm_utils.h" #include <string.h> #define AUDIO_OUTPUT_TYPE "type" #define AUDIO_OUTPUT_NAME "name" +#define AUDIO_OUTPUT_FORMAT "format" static List * audioOutputPluginList; @@ -29,26 +31,27 @@ void finishAudioOutputPlugins() { freeList(audioOutputPluginList); } -#define getBlockParam(name, str) { \ - BlockParam * bp; \ +#define getBlockParam(name, str, force) { \ bp = getBlockParam(param, name); \ - if(bp == NULL) { \ + if(force && bp == NULL) { \ ERROR("couldn't find parameter \"%s\" in audio output " \ "definition begining at %i\n", \ name, param->line); \ exit(EXIT_FAILURE); \ } \ - str = bp->value; \ + if(bp) str = bp->value; \ } AudioOutput * newAudioOutput(ConfigParam * param) { AudioOutput * ret = NULL; void * data = NULL; char * name = NULL; + char * format = NULL; char * type = NULL; + BlockParam * bp; - getBlockParam(AUDIO_OUTPUT_NAME, name); - getBlockParam(AUDIO_OUTPUT_TYPE, type); + getBlockParam(AUDIO_OUTPUT_NAME, name, 1); + getBlockParam(AUDIO_OUTPUT_TYPE, type, 1); if(findInList(audioOutputPluginList, type, &data)) { AudioOutputPlugin * plugin = (AudioOutputPlugin *) data; @@ -62,6 +65,27 @@ AudioOutput * newAudioOutput(ConfigParam * param) { 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)); + + getBlockParam(AUDIO_OUTPUT_FORMAT, format, 0); + + if(format) { + ret->convertAudioFormat = 1; + + if(0 != parseAudioConfig(&ret->outAudioFormat, format)) + { + ERROR("error parsing format at line %i\n", + bp->line); + exit(EXIT_FAILURE); + } + } + if(plugin->initDriverFunc(ret, param) != 0) { free(ret); ret = NULL; @@ -77,12 +101,62 @@ AudioOutput * newAudioOutput(ConfigParam * param) { } int openAudioOutput(AudioOutput * audioOutput, AudioFormat * audioFormat) { - if(audioOutput->open) closeAudioOutput(audioOutput); + if(audioOutput->open) { + if(cmpAudioFormat(audioFormat, &audioOutput->inAudioFormat) + == 0) + { + return 0; + } + closeAudioOutput(audioOutput); + } + + copyAudioFormat(&audioOutput->inAudioFormat, audioFormat); + + if(audioOutput->convertAudioFormat) { + if(cmpAudioFormat(&audioOutput->inAudioFormat, + &audioOutput->outAudioFormat) == 0) + { + audioOutput->sameInAndOutFormats = 1; + } + else audioOutput->sameInAndOutFormats = 0; + } + else { + audioOutput->sameInAndOutFormats = 1; + copyAudioFormat(&audioOutput->outAudioFormat, + &audioOutput->inAudioFormat); + } + return audioOutput->openDeviceFunc(audioOutput, audioFormat); } +static void convertAudioFormat(AudioOutput * audioOutput, char ** chunkArgPtr, + int * sizeArgPtr) +{ + int size = pcm_sizeOfOutputBufferForAudioFormatConversion( + &(audioOutput->inAudioFormat), *sizeArgPtr, + &(audioOutput->outAudioFormat)); + + if(size > audioOutput->convBufferLen) { + audioOutput->convBuffer = + realloc(audioOutput->convBuffer, size); + audioOutput->convBufferLen = size; + } + + pcm_convertAudioFormat(&(audioOutput->inAudioFormat), *chunkArgPtr, + *sizeArgPtr, &(audioOutput->outAudioFormat), + audioOutput->convBuffer); + + *sizeArgPtr = size; + *chunkArgPtr = audioOutput->convBuffer; +} + int playAudioOutput(AudioOutput * audioOutput, char * playChunk, int size) { if(!audioOutput->open) return -1; + + if(!audioOutput->sameInAndOutFormats) { + convertAudioFormat(audioOutput, &playChunk, &size); + } + return audioOutput->playFunc(audioOutput, playChunk, size); } @@ -93,6 +167,7 @@ void closeAudioOutput(AudioOutput * audioOutput) { void finishAudioOutput(AudioOutput * audioOutput) { closeAudioOutput(audioOutput); audioOutput->finishDriverFunc(audioOutput); + if(audioOutput->convBuffer) free(audioOutput->convBuffer); free(audioOutput->type); free(audioOutput->name); free(audioOutput); |