aboutsummaryrefslogtreecommitdiffstats
path: root/src/audio.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/audio.c366
1 files changed, 195 insertions, 171 deletions
diff --git a/src/audio.c b/src/audio.c
index 4d4889b6c..2e8645882 100644
--- a/src/audio.c
+++ b/src/audio.c
@@ -41,23 +41,25 @@
static AudioFormat audio_format;
-static AudioFormat * audio_configFormat = NULL;
+static AudioFormat *audio_configFormat = NULL;
-static AudioOutput ** audioOutputArray = NULL;
+static AudioOutput **audioOutputArray = NULL;
static mpd_uint8 audioOutputArraySize = 0;
/* the audioEnabledArray should be stuck into shared memory, and then disable
and enable in playAudio() routine */
-static mpd_sint8 * pdAudioDevicesEnabled = NULL;
+static mpd_sint8 *pdAudioDevicesEnabled = NULL;
static mpd_sint8 myAudioDevicesEnabled[AUDIO_MAX_DEVICES];
static mpd_uint8 audioOpened = 0;
static mpd_sint32 audioBufferSize = 0;
-static char * audioBuffer = NULL;
+static char *audioBuffer = NULL;
static mpd_sint32 audioBufferPos = 0;
-void copyAudioFormat(AudioFormat * dest, AudioFormat * src) {
- if(!src) return;
+void copyAudioFormat(AudioFormat * dest, AudioFormat * src)
+{
+ if (!src)
+ return;
memcpy(dest, src, sizeof(AudioFormat));
}
@@ -65,8 +67,7 @@ void copyAudioFormat(AudioFormat * dest, AudioFormat * src) {
int cmpAudioFormat(AudioFormat * f1, AudioFormat * f2)
{
if (f1 && f2 && (f1->sampleRate == f2->sampleRate) &&
- (f1->bits == f2->bits) &&
- (f1->channels == f2->channels))
+ (f1->bits == f2->bits) && (f1->channels == f2->channels))
return 0;
return 1;
}
@@ -79,8 +80,8 @@ extern AudioOutputPlugin pulsePlugin;
extern AudioOutputPlugin mvpPlugin;
extern AudioOutputPlugin shoutPlugin;
-
-void loadAudioDrivers(void) {
+void loadAudioDrivers(void)
+{
initAudioOutputPlugins();
loadAudioOutputPlugin(&alsaPlugin);
loadAudioOutputPlugin(&aoPlugin);
@@ -92,15 +93,16 @@ void loadAudioDrivers(void) {
}
/* make sure initPlayerData is called before this function!! */
-void initAudioDriver(void) {
- ConfigParam * param = NULL;
+void initAudioDriver(void)
+{
+ ConfigParam *param = NULL;
int i;
loadAudioDrivers();
pdAudioDevicesEnabled = (getPlayerData())->audioDeviceEnabled;
- for(i = 0; i < AUDIO_MAX_DEVICES; i++) {
+ for (i = 0; i < AUDIO_MAX_DEVICES; i++) {
pdAudioDevicesEnabled[i] = 1;
myAudioDevicesEnabled[i] = 1;
}
@@ -111,135 +113,140 @@ void initAudioDriver(void) {
AudioOutput *output;
int j;
- if(audioOutputArraySize == AUDIO_MAX_DEVICES) {
+ if (audioOutputArraySize == AUDIO_MAX_DEVICES) {
ERROR("only up to 255 audio output devices are "
- "supported");
+ "supported");
exit(EXIT_FAILURE);
}
i = audioOutputArraySize++;
audioOutputArray = realloc(audioOutputArray,
- audioOutputArraySize*sizeof(AudioOutput *));
+ audioOutputArraySize *
+ sizeof(AudioOutput *));
output = newAudioOutput(param);
- if(!output && param) {
+ if (!output && param) {
ERROR("problems configuring output device defined at "
- "line %i\n", param->line);
+ "line %i\n", param->line);
exit(EXIT_FAILURE);
}
/* require output names to be unique: */
for (j = i - 1; j >= 0; --j) {
- if ( !strcmp( output->name,
- audioOutputArray[j]->name) ) {
+ if (!strcmp(output->name, audioOutputArray[j]->name)) {
ERROR("output devices with identical "
- "names: %s\n",
- output->name);
+ "names: %s\n", output->name);
exit(EXIT_FAILURE);
}
}
audioOutputArray[i] = output;
- } while((param = getNextConfigParam(CONF_AUDIO_OUTPUT, param)));
+ } while ((param = getNextConfigParam(CONF_AUDIO_OUTPUT, param)));
}
-void getOutputAudioFormat(AudioFormat * inAudioFormat,
- AudioFormat * outAudioFormat)
+void getOutputAudioFormat(AudioFormat * inAudioFormat,
+ AudioFormat * outAudioFormat)
{
- if(audio_configFormat) {
- copyAudioFormat(outAudioFormat,audio_configFormat);
- }
- else copyAudioFormat(outAudioFormat,inAudioFormat);
+ if (audio_configFormat) {
+ copyAudioFormat(outAudioFormat, audio_configFormat);
+ } else
+ copyAudioFormat(outAudioFormat, inAudioFormat);
}
-void initAudioConfig(void) {
- ConfigParam * param = getConfigParam(CONF_AUDIO_OUTPUT_FORMAT);
+void initAudioConfig(void)
+{
+ ConfigParam *param = getConfigParam(CONF_AUDIO_OUTPUT_FORMAT);
- if(NULL == param || NULL == param->value) return;
+ if (NULL == param || NULL == param->value)
+ return;
- audio_configFormat = malloc(sizeof(AudioFormat));
+ audio_configFormat = malloc(sizeof(AudioFormat));
- if(0 != parseAudioConfig(audio_configFormat, param->value)) {
- ERROR("error parsing \"%s\" at line %i\n",
- CONF_AUDIO_OUTPUT_FORMAT, param->line);
+ if (0 != parseAudioConfig(audio_configFormat, param->value)) {
+ ERROR("error parsing \"%s\" at line %i\n",
+ CONF_AUDIO_OUTPUT_FORMAT, param->line);
exit(EXIT_FAILURE);
}
}
-int parseAudioConfig(AudioFormat * audioFormat, char * conf) {
- char * test;
+int parseAudioConfig(AudioFormat * audioFormat, char *conf)
+{
+ char *test;
+
+ memset(audioFormat, 0, sizeof(AudioFormat));
- memset(audioFormat,0,sizeof(AudioFormat));
+ audioFormat->sampleRate = strtol(conf, &test, 10);
- audioFormat->sampleRate = strtol(conf,&test,10);
-
- if(*test!=':') {
- ERROR("error parsing audio output format: %s\n",conf);
+ if (*test != ':') {
+ ERROR("error parsing audio output format: %s\n", conf);
return -1;
- }
-
- /*switch(audioFormat->sampleRate) {
- case 48000:
- case 44100:
- case 32000:
- case 16000:
- break;
- default:
- ERROR("sample rate %i can not be used for audio output\n",
- (int)audioFormat->sampleRate);
- return -1
- }*/
-
- if(audioFormat->sampleRate <= 0) {
- ERROR("sample rate %i is not >= 0\n",
- (int)audioFormat->sampleRate);
+ }
+
+ /*switch(audioFormat->sampleRate) {
+ case 48000:
+ case 44100:
+ case 32000:
+ case 16000:
+ break;
+ default:
+ ERROR("sample rate %i can not be used for audio output\n",
+ (int)audioFormat->sampleRate);
+ return -1
+ } */
+
+ if (audioFormat->sampleRate <= 0) {
+ ERROR("sample rate %i is not >= 0\n",
+ (int)audioFormat->sampleRate);
return -1;
- }
+ }
+
+ audioFormat->bits = strtol(test + 1, &test, 10);
- audioFormat->bits = strtol(test+1,&test,10);
-
- if(*test!=':') {
- ERROR("error parsing audio output format: %s\n",conf);
+ if (*test != ':') {
+ ERROR("error parsing audio output format: %s\n", conf);
return -1;
- }
-
- switch(audioFormat->bits) {
- case 16:
- break;
- default:
- ERROR("bits %i can not be used for audio output\n",
- (int)audioFormat->bits);
+ }
+
+ switch (audioFormat->bits) {
+ case 16:
+ break;
+ default:
+ ERROR("bits %i can not be used for audio output\n",
+ (int)audioFormat->bits);
return -1;
- }
+ }
- audioFormat->channels = strtol(test+1,&test,10);
-
- if(*test!='\0') {
- ERROR("error parsing audio output format: %s\n",conf);
+ audioFormat->channels = strtol(test + 1, &test, 10);
+
+ if (*test != '\0') {
+ ERROR("error parsing audio output format: %s\n", conf);
return -1;
- }
+ }
- switch(audioFormat->channels) {
+ switch (audioFormat->channels) {
case 1:
- case 2:
- break;
- default:
- ERROR("channels %i can not be used for audio output\n",
- (int)audioFormat->channels);
+ case 2:
+ break;
+ default:
+ ERROR("channels %i can not be used for audio output\n",
+ (int)audioFormat->channels);
return -1;
- }
+ }
return 0;
}
-void finishAudioConfig(void) {
- if(audio_configFormat) free(audio_configFormat);
+void finishAudioConfig(void)
+{
+ if (audio_configFormat)
+ free(audio_configFormat);
}
-void finishAudioDriver(void) {
+void finishAudioDriver(void)
+{
int i;
- for(i = 0; i < audioOutputArraySize; i++) {
+ for (i = 0; i < audioOutputArraySize; i++) {
finishAudioOutput(audioOutputArray[i]);
}
@@ -248,46 +255,51 @@ void finishAudioDriver(void) {
audioOutputArraySize = 0;
}
-int isCurrentAudioFormat(AudioFormat * audioFormat) {
- if(!audioFormat) return 1;
+int isCurrentAudioFormat(AudioFormat * audioFormat)
+{
+ if (!audioFormat)
+ return 1;
- if(cmpAudioFormat(audioFormat, &audio_format) != 0) return 0;
+ if (cmpAudioFormat(audioFormat, &audio_format) != 0)
+ return 0;
return 1;
}
-static void syncAudioDevicesEnabledArrays(void) {
+static void syncAudioDevicesEnabledArrays(void)
+{
int i;
- memcpy(myAudioDevicesEnabled, pdAudioDevicesEnabled,AUDIO_MAX_DEVICES);
-
- for(i = 0; i < audioOutputArraySize; i++) {
- if(myAudioDevicesEnabled[i]) {
+ memcpy(myAudioDevicesEnabled, pdAudioDevicesEnabled, AUDIO_MAX_DEVICES);
+
+ for (i = 0; i < audioOutputArraySize; i++) {
+ if (myAudioDevicesEnabled[i]) {
openAudioOutput(audioOutputArray[i], &audio_format);
- }
- else {
+ } else {
dropBufferedAudioOutput(audioOutputArray[i]);
closeAudioOutput(audioOutputArray[i]);
}
}
}
-static int flushAudioBuffer(void) {
+static int flushAudioBuffer(void)
+{
int ret = -1;
int i, err;
- if(audioBufferPos == 0) return 0;
+ if (audioBufferPos == 0)
+ return 0;
- if(0 != memcmp(pdAudioDevicesEnabled, myAudioDevicesEnabled,
- AUDIO_MAX_DEVICES))
- {
+ if (0 != memcmp(pdAudioDevicesEnabled, myAudioDevicesEnabled,
+ AUDIO_MAX_DEVICES)) {
syncAudioDevicesEnabledArrays();
}
- for(i = 0; i < audioOutputArraySize; i++) {
- if(!myAudioDevicesEnabled[i]) continue;
+ for (i = 0; i < audioOutputArraySize; i++) {
+ if (!myAudioDevicesEnabled[i])
+ continue;
err = playAudioOutput(audioOutputArray[i], audioBuffer,
- audioBufferPos);
+ audioBufferPos);
if (!err)
ret = 0;
else if (err < 0)
@@ -301,32 +313,36 @@ static int flushAudioBuffer(void) {
return ret;
}
-int openAudioDevice(AudioFormat * audioFormat) {
+int openAudioDevice(AudioFormat * audioFormat)
+{
int isCurrentFormat = isCurrentAudioFormat(audioFormat);
int ret = -1;
int i;
- if(!audioOutputArray) return -1;
+ if (!audioOutputArray)
+ return -1;
- if(!audioOpened || !isCurrentFormat) {
+ if (!audioOpened || !isCurrentFormat) {
flushAudioBuffer();
copyAudioFormat(&audio_format, audioFormat);
- audioBufferSize = (audio_format.bits >> 3)*
- audio_format.channels;
- audioBufferSize*= audio_format.sampleRate >> 5;
+ audioBufferSize = (audio_format.bits >> 3) *
+ audio_format.channels;
+ audioBufferSize *= audio_format.sampleRate >> 5;
audioBuffer = realloc(audioBuffer, audioBufferSize);
}
syncAudioDevicesEnabledArrays();
-
- for(i = 0; i < audioOutputArraySize; i++) {
- if(audioOutputArray[i]->open) ret = 0;
+
+ for (i = 0; i < audioOutputArraySize; i++) {
+ if (audioOutputArray[i]->open)
+ ret = 0;
}
- if(ret == 0) audioOpened = 1;
+ if (ret == 0)
+ audioOpened = 1;
else {
/* close all devices if there was an error */
- for(i = 0; i < audioOutputArraySize; i++) {
+ for (i = 0; i < audioOutputArraySize; i++) {
closeAudioOutput(audioOutputArray[i]);
}
@@ -336,48 +352,53 @@ int openAudioDevice(AudioFormat * audioFormat) {
return ret;
}
-int playAudio(char * playChunk, int size) {
+int playAudio(char *playChunk, int size)
+{
int send;
-
- while(size > 0) {
- send = audioBufferSize-audioBufferPos;
+
+ while (size > 0) {
+ send = audioBufferSize - audioBufferPos;
send = send < size ? send : size;
- memcpy(audioBuffer+audioBufferPos, playChunk, send);
+ memcpy(audioBuffer + audioBufferPos, playChunk, send);
audioBufferPos += send;
size -= send;
- playChunk+= send;
+ playChunk += send;
- if(audioBufferPos == audioBufferSize) {
- if( flushAudioBuffer() < 0 ) return -1;
+ if (audioBufferPos == audioBufferSize) {
+ if (flushAudioBuffer() < 0)
+ return -1;
}
}
return 0;
}
-int isAudioDeviceOpen(void) {
+int isAudioDeviceOpen(void)
+{
return audioOpened;
}
-void dropBufferedAudio(void) {
+void dropBufferedAudio(void)
+{
int i;
- if(0 != memcmp(pdAudioDevicesEnabled, myAudioDevicesEnabled,
- AUDIO_MAX_DEVICES))
- {
+ if (0 != memcmp(pdAudioDevicesEnabled, myAudioDevicesEnabled,
+ AUDIO_MAX_DEVICES)) {
syncAudioDevicesEnabledArrays();
}
audioBufferPos = 0;
- for(i = 0; i < audioOutputArraySize; i++) {
- if(!myAudioDevicesEnabled[i]) continue;
+ for (i = 0; i < audioOutputArraySize; i++) {
+ if (!myAudioDevicesEnabled[i])
+ continue;
dropBufferedAudioOutput(audioOutputArray[i]);
}
}
-void closeAudioDevice(void) {
+void closeAudioDevice(void)
+{
int i;
flushAudioBuffer();
@@ -386,25 +407,27 @@ void closeAudioDevice(void) {
audioBuffer = NULL;
audioBufferSize = 0;
- for(i = 0; i < audioOutputArraySize; i++) {
+ for (i = 0; i < audioOutputArraySize; i++) {
closeAudioOutput(audioOutputArray[i]);
}
audioOpened = 0;
}
-void sendMetadataToAudioDevice(MpdTag * tag) {
+void sendMetadataToAudioDevice(MpdTag * tag)
+{
int i;
- for(i = 0; i < audioOutputArraySize; i++) {
+ for (i = 0; i < audioOutputArraySize; i++) {
sendMetadataToAudioOutput(audioOutputArray[i], tag);
}
}
-int enableAudioDevice(FILE * fp, int device) {
- if(device < 0 || device >= audioOutputArraySize) {
+int enableAudioDevice(FILE * fp, int device)
+{
+ if (device < 0 || device >= audioOutputArraySize) {
commandError(fp, ACK_ERROR_ARG, "audio output device id %i "
- "doesn't exist\n", device);
+ "doesn't exist\n", device);
return -1;
}
@@ -413,10 +436,11 @@ int enableAudioDevice(FILE * fp, int device) {
return 0;
}
-int disableAudioDevice(FILE * fp, int device) {
- if(device < 0 || device >= audioOutputArraySize) {
+int disableAudioDevice(FILE * fp, int device)
+{
+ if (device < 0 || device >= audioOutputArraySize) {
commandError(fp, ACK_ERROR_ARG, "audio output device id %i "
- "doesn't exist\n", device);
+ "doesn't exist\n", device);
return -1;
}
@@ -425,18 +449,20 @@ int disableAudioDevice(FILE * fp, int device) {
return 0;
}
-void printAudioDevices(FILE * fp) {
+void printAudioDevices(FILE * fp)
+{
int i;
- for(i = 0; i < audioOutputArraySize; i++) {
+ for (i = 0; i < audioOutputArraySize; i++) {
myfprintf(fp, "outputid: %i\n", i);
myfprintf(fp, "outputname: %s\n", audioOutputArray[i]->name);
- myfprintf(fp, "outputenabled: %i\n",
- (int)pdAudioDevicesEnabled[i]);
+ myfprintf(fp, "outputenabled: %i\n",
+ (int)pdAudioDevicesEnabled[i]);
}
}
-void saveAudioDevicesState(void) {
+void saveAudioDevicesState(void)
+{
char *stateFile;
FILE *fp;
int i;
@@ -444,40 +470,40 @@ void saveAudioDevicesState(void) {
if (!(stateFile = getStateFile()))
return;
- while(!(fp = fopen(stateFile,"a")) && errno==EINTR);
- if(!fp) {
+ while (!(fp = fopen(stateFile, "a")) && errno == EINTR) ;
+ if (!fp) {
ERROR("problems opening state file \"%s\" for "
- "writing: %s\n", stateFile, strerror(errno));
+ "writing: %s\n", stateFile, strerror(errno));
return;
}
assert(audioOutputArraySize != 0);
for (i = 0; i < audioOutputArraySize; i++) {
myfprintf(fp, AUDIO_DEVICE_STATE "%d:%s\n",
- (int)pdAudioDevicesEnabled[i],
- audioOutputArray[i]->name);
+ (int)pdAudioDevicesEnabled[i],
+ audioOutputArray[i]->name);
}
- while(fclose(fp) && errno==EINTR);
+ while (fclose(fp) && errno == EINTR) ;
}
-static void parse_audio_device_state(FILE *fp)
+static void parse_audio_device_state(FILE * fp)
{
char buffer[AUDIO_BUFFER_SIZE];
int i;
assert(audioOutputArraySize != 0);
- while (myFgets(buffer,AUDIO_BUFFER_SIZE,fp)) {
+ while (myFgets(buffer, AUDIO_BUFFER_SIZE, fp)) {
char *c, *name;
- if (strncmp(buffer,AUDIO_DEVICE_STATE,AUDIO_DEVICE_STATE_LEN))
+ if (strncmp(buffer, AUDIO_DEVICE_STATE, AUDIO_DEVICE_STATE_LEN))
continue;
- c = strchr(buffer,':');
+ c = strchr(buffer, ':');
if (!c || !(++c))
goto errline;
- name = strchr(c,':');
+ name = strchr(c, ':');
if (!name || !(++name))
goto errline;
@@ -488,37 +514,35 @@ static void parse_audio_device_state(FILE *fp)
}
}
continue;
-errline:
+ errline:
/* nonfatal */
ERROR("invalid line in state_file: %s\n", buffer);
}
}
-void readAudioDevicesState(void) {
+void readAudioDevicesState(void)
+{
char *stateFile;
FILE *fp;
struct stat st;
if (!(stateFile = getStateFile()))
return;
- if(stat(stateFile,&st)<0) {
+ if (stat(stateFile, &st) < 0) {
DEBUG("failed to stat state file\n");
return;
}
- if(!S_ISREG(st.st_mode)) {
- ERROR("state file \"%s\" is not a regular file\n",
- stateFile);
+ if (!S_ISREG(st.st_mode)) {
+ ERROR("state file \"%s\" is not a regular file\n", stateFile);
exit(EXIT_FAILURE);
}
- fp = fopen(stateFile,"r");
- if(!fp) {
+ fp = fopen(stateFile, "r");
+ if (!fp) {
ERROR("problems opening state file \"%s\" for "
- "reading: %s\n", stateFile,
- strerror(errno));
+ "reading: %s\n", stateFile, strerror(errno));
exit(EXIT_FAILURE);
}
parse_audio_device_state(fp);
fclose(fp);
}
-