/*
* This file is part of DisOrder
- * Copyright (C) 2004 Richard Kettlewell
+ * Copyright (C) 2007 Richard Kettlewell
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#include "log.h"
#include "syscalls.h"
+static const struct mixer *mixers[] = {
#if HAVE_SYS_SOUNDCARD_H
-#include <sys/soundcard.h>
-
-/* documentation does not match implementation! */
-#ifndef SOUND_MIXER_READ
-# define SOUND_MIXER_READ(x) MIXER_READ(x)
-#endif
-#ifndef SOUND_MIXER_WRITE
-# define SOUND_MIXER_WRITE(x) MIXER_WRITE(x)
+ &mixer_oss
#endif
+};
-static const char *channels[] = SOUND_DEVICE_NAMES;
-
-int mixer_channel(const char *c) {
- unsigned n;
-
- if(!c[strspn(c, "0123456789")])
- return atoi(c);
- else {
- for(n = 0; n < sizeof channels / sizeof *channels; ++n)
- if(!strcmp(channels[n], c))
- return n;
- return -1;
- }
+#define NMIXERS (sizeof mixers / sizeof *mixers)
+
+static const struct mixer *find_mixer(int api) {
+ size_t n;
+
+ for(n = 0; n < NMIXERS; ++n)
+ if(mixers[n]->api == api)
+ return mixers[n];
+ return 0;
+}
+
+int mixer_valid_channel(int api, const char *c) {
+ const struct mixer *const m = find_mixer(api);
+
+ return m ? m->validate_channel(c) : 1;
+}
+
+int mixer_valid_device(int api, const char *d) {
+ const struct mixer *const m = find_mixer(api);
+
+ return m ? m->validate_device(d) : 1;
}
int mixer_control(int *left, int *right, int set) {
- int fd, ch, r;
-
- if(config->mixer
- && config->channel
- && (ch = mixer_channel(config->channel)) != -1) {
- if((fd = open(config->mixer, O_RDWR, 0)) < 0) {
- error(errno, "error opening %s", config->mixer);
- return -1;
- }
- if(set) {
- r = (*left & 0xff) + (*right & 0xff) * 256;
- if(ioctl(fd, SOUND_MIXER_WRITE(ch), &r) == -1) {
- error(errno, "error changing %s channel %s",
- config->mixer, config->channel);
- xclose(fd);
- return -1;
- }
- }
- if(ioctl(fd, SOUND_MIXER_READ(ch), &r) == -1) {
- error(errno, "error reading %s channel %s",
- config->mixer, config->channel);
- xclose(fd);
- return -1;
+ const struct mixer *const m = find_mixer(config->api);
+
+ if(m) {
+ if(set)
+ return m->set(left, right);
+ else
+ return m->get(left, right);
+ } else {
+ static int reported;
+
+ if(!reported) {
+ error(0, "don't know how to get/set volume with this api");
+ reported = 1;
}
- *left = r & 0xff;
- *right = (r >> 8) & 0xff;
- xclose(fd);
- return 0;
- } else
return -1;
+ }
}
-#else
-int mixer_channel(const char attribute((unused)) *c) {
- return 0;
+
+const char *mixer_default_device(int api) {
+ const struct mixer *const m = find_mixer(api);
+
+ return m ? m->device : "";
}
-int mixer_control(int attribute((unused)) *left,
- int attribute((unused)) *right,
- int attribute((unused)) set) {
- static int reported;
+const char *mixer_default_channel(int api) {
+ const struct mixer *const m = find_mixer(api);
- if(!reported) {
- error(0, "don't know how to set volume on this platform");
- reported = 1;
- }
- return -1;
+ return m ? m->channel : "";
}
-#endif
/*
Local Variables: