aboutsummaryrefslogtreecommitdiffstats
path: root/src/audio.c
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2006-03-18 03:58:31 +0000
committerEric Wong <normalperson@yhbt.net>2006-03-18 03:58:31 +0000
commita25acbc94fb6e139c4484c3c93d3030a19494b2f (patch)
treefd23fef78584a66ca6852895ecbd827ab8de68ab /src/audio.c
parent6dadabea214a46d303e2c9a4d92cb0073492821e (diff)
downloadmpd-a25acbc94fb6e139c4484c3c93d3030a19494b2f.tar.gz
mpd-a25acbc94fb6e139c4484c3c93d3030a19494b2f.tar.xz
mpd-a25acbc94fb6e139c4484c3c93d3030a19494b2f.zip
rewrite statefile code for audio devices
In the words of the original author, it was 'crappy'. I tend to agree :) The code has also been broken for at least the past few months, and nobody bothered fixing it The previous format it was overly complex: 5 lines to describe each device. The new format is one-line per-device: audio_device_state:%d:%s %d - 0 for disabled, any integer for enabled %s - name of the device as specified in the config file, whitespace and all Incompatibilities: * Output names are now _required_ to be unique. This is required because the new format relies solely on the name of the audio device. Relying on the device IDs internal to MPD was a bad idea anyways since the user usually has none or very little idea how they're generated, and adding a new device or removing one from a config would throw things off completely. This is also just a Good Idea(TM) because it makes things less confusing to users when they see it in their clients. * Output states are not preserved from the previous format. Not a big deal, since the previous code was never officially released. Also, it's been broken for months now, so I doubt anybody would notice :) git-svn-id: https://svn.musicpd.org/mpd/trunk@3928 09075e82-0dd4-0310-85a5-a0d7c8717e4f
Diffstat (limited to 'src/audio.c')
-rw-r--r--src/audio.c193
1 files changed, 91 insertions, 102 deletions
diff --git a/src/audio.c b/src/audio.c
index 8f7200d46..dfc209b32 100644
--- a/src/audio.c
+++ b/src/audio.c
@@ -34,18 +34,10 @@
#include <errno.h>
#include <unistd.h>
-
-/* crappy code by qball */
-#define AUDIO_STATE_FILE_DEVICE_START "audio_device_start"
-#define AUDIO_STATE_FILE_DEVICE_ID "audio_device_id: "
-#define AUDIO_STATE_FILE_DEVICE_ENABLED "audio_device_enabled: "
-#define AUDIO_STATE_FILE_DEVICE_NAME "audio_device_name: "
-#define AUDIO_STATE_FILE_DEVICE_END "audio_device_end"
-
+#define AUDIO_DEVICE_STATE "audio_device_state:"
+#define AUDIO_DEVICE_STATE_LEN 19 /* strlen(AUDIO_DEVICE_STATE) */
#define AUDIO_BUFFER_SIZE 2*MAXPATHLEN
-/* /crappy code */
-
-
+static void saveAudioDevicesState();
static AudioFormat audio_format;
@@ -104,6 +96,9 @@ void initAudioDriver() {
param = getNextConfigParam(CONF_AUDIO_OUTPUT, param);
do {
+ AudioOutput *output;
+ int j;
+
if(audioOutputArraySize == AUDIO_MAX_DEVICES) {
ERROR("only up to 255 audio output devices are "
"supported");
@@ -114,14 +109,25 @@ void initAudioDriver() {
audioOutputArray = realloc(audioOutputArray,
audioOutputArraySize*sizeof(AudioOutput *));
-
- audioOutputArray[i] = newAudioOutput(param);
- if(!audioOutputArray[i] && param) {
+ output = newAudioOutput(param);
+ if(!output && param) {
ERROR("problems configuring output device defined at "
"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) ) {
+ ERROR("output devices with identical "
+ "names: %s\n",
+ output->name);
+ exit(EXIT_FAILURE);
+ }
+ }
+ audioOutputArray[i] = output;
} while((param = getNextConfigParam(CONF_AUDIO_OUTPUT, param)));
}
@@ -221,6 +227,7 @@ void finishAudioConfig() {
void finishAudioDriver() {
int i;
+ saveAudioDevicesState();
for(i = 0; i < audioOutputArraySize; i++) {
finishAudioOutput(audioOutputArray[i]);
}
@@ -415,115 +422,97 @@ void printAudioDevices(FILE * fp) {
}
}
-
-/* more qball crappy code */
-
static char * getStateFile() {
ConfigParam * param = parseConfigFilePath(CONF_STATE_FILE, 0);
-
+
if(!param) return NULL;
return param->value;
}
+static void saveAudioDevicesState() {
+ char *stateFile;
+ FILE *fp;
+ int i;
+ if (!(stateFile = getStateFile()))
+ return;
-void saveAudioDevicesState() {
- int i;
- char * stateFile = getStateFile();
-
- if(stateFile) {
- FILE * fp;
-
- while(!(fp = fopen(stateFile,"a")) && errno==EINTR);
- if(!fp) {
- ERROR("problems opening state file \"%s\" for "
- "writing: %s\n", stateFile,
- strerror(errno));
- return;
- }
- for(i = 0; i < audioOutputArraySize; i++) {
- myfprintf(fp, "%s\n", AUDIO_STATE_FILE_DEVICE_START);
- myfprintf(fp, "%s%i\n", AUDIO_STATE_FILE_DEVICE_ID, i);
- myfprintf(fp, "%s%s\n", AUDIO_STATE_FILE_DEVICE_NAME, audioOutputArray[i]->name);
- myfprintf(fp, "%s%i\n", AUDIO_STATE_FILE_DEVICE_ENABLED,(int)pdAudioDevicesEnabled[i]);
- myfprintf(fp, "%s\n", AUDIO_STATE_FILE_DEVICE_END);
- }
- while(fclose(fp) && errno==EINTR);
+ while(!(fp = fopen(stateFile,"a")) && errno==EINTR);
+ if(!fp) {
+ ERROR("problems opening state file \"%s\" for "
+ "writing: %s\n", stateFile, strerror(errno));
+ return;
+ }
+
+ assert(audioOutputArraySize != 0);
+ for (i = audioOutputArraySize - 1; i >= 0; --i) {
+ myfprintf(fp, AUDIO_DEVICE_STATE "%d:%s\n",
+ (int)pdAudioDevicesEnabled[i],
+ audioOutputArray[i]->name);
}
+ while(fclose(fp) && errno==EINTR);
}
-void readAudioDevicesState() {
- char * stateFile = getStateFile();
- FILE *fp;
- struct stat st;
- if(stateFile) {
- char buffer[AUDIO_BUFFER_SIZE];
+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)) {
+ char *c, *name;
+ if (strncmp(buffer,AUDIO_DEVICE_STATE,AUDIO_DEVICE_STATE_LEN))
+ continue;
- 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);
- exit(EXIT_FAILURE);
- }
+ c = strchr(buffer,':');
+ if (!c || !(++c))
+ goto errline;
- fp = fopen(stateFile,"r");
- if(!fp) {
- ERROR("problems opening state file \"%s\" for "
- "reading: %s\n", stateFile,
- strerror(errno));
- exit(EXIT_FAILURE);
- }
+ name = strchr(c,':');
+ if (!name || !(++name))
+ goto errline;
- while(myFgets(buffer,AUDIO_BUFFER_SIZE,fp)) {
- if(strncmp(buffer,AUDIO_STATE_FILE_DEVICE_START, strlen(AUDIO_STATE_FILE_DEVICE_START))==0) {
- char *name = NULL;
- int id = -1;
- int enabled = 1;
- if(!myFgets(buffer,AUDIO_BUFFER_SIZE,fp)) {
- ERROR("error parsing state file \"%s\"\n", stateFile);
- exit(EXIT_FAILURE);
- }
- while(strcmp(buffer,AUDIO_STATE_FILE_DEVICE_END)) {
- if(strncmp(buffer,AUDIO_STATE_FILE_DEVICE_ID, strlen(AUDIO_STATE_FILE_DEVICE_ID)) == 0 ) {
- if(strlen(buffer) > strlen(AUDIO_STATE_FILE_DEVICE_ID))
- {
- id = atoi(&buffer[strlen(AUDIO_STATE_FILE_DEVICE_ID)]);
- }
- }
- if(strncmp(buffer,AUDIO_STATE_FILE_DEVICE_ENABLED, strlen(AUDIO_STATE_FILE_DEVICE_ENABLED)) == 0 ) {
- if(strlen(buffer) > strlen(AUDIO_STATE_FILE_DEVICE_ENABLED))
- {
- enabled = atoi(&buffer[strlen(AUDIO_STATE_FILE_DEVICE_ENABLED)]);
- }
- }
- if(!myFgets(buffer,AUDIO_BUFFER_SIZE,fp)) {
- ERROR("error parsing state file \"%s\"\n", stateFile);
- exit(EXIT_FAILURE);
- }
- }
- if(id != -1)
- {
- /* search for same name here, can we trust id? */
- if(id < audioOutputArraySize)
- {
- pdAudioDevicesEnabled[id] = enabled;
- }
- }
- if(name != NULL)
- {
- free(name);
- }
+ for (i = audioOutputArraySize - 1; i >= 0; --i) {
+ if (!strcmp(name, audioOutputArray[i]->name)) {
+ pdAudioDevicesEnabled[i] = atoi(c);
+ break;
}
}
+ continue;
+errline:
+ /* nonfatal */
+ ERROR("invalid line in state_file: %s\n", buffer);
+ }
+}
+
+void readAudioDevicesState() {
+ char *stateFile;
+ FILE *fp;
+ struct stat st;
- fclose(fp);
+ if (!(stateFile = getStateFile()))
+ return;
+ 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);
+ exit(EXIT_FAILURE);
+ }
+
+ fp = fopen(stateFile,"r");
+ if(!fp) {
+ ERROR("problems opening state file \"%s\" for "
+ "reading: %s\n", stateFile,
+ strerror(errno));
+ exit(EXIT_FAILURE);
}
+ parse_audio_device_state(fp);
+ fclose(fp);
}