aboutsummaryrefslogtreecommitdiffstats
path: root/src/audio.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-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);
}