X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/disorder/blobdiff_plain/816e60886bca2caf8f33076bb90d97dacc53ffd0..bd8895a87731c72190ea2012f36583f796d4181a:/lib/mixer.c diff --git a/lib/mixer.c b/lib/mixer.c index 4fd4a9a..f674d68 100644 --- a/lib/mixer.c +++ b/lib/mixer.c @@ -1,6 +1,6 @@ /* * 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 @@ -35,81 +35,65 @@ #include "log.h" #include "syscalls.h" +static const struct mixer *mixers[] = { #if HAVE_SYS_SOUNDCARD_H -#include - -/* 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: