Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/lib/libossaudio/Attic/ossaudio.c,v rcsdiff: /ftp/cvs/cvsroot/src/lib/libossaudio/Attic/ossaudio.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.10 retrieving revision 1.11 diff -u -p -r1.10 -r1.11 --- src/lib/libossaudio/Attic/ossaudio.c 1999/11/16 23:56:41 1.10 +++ src/lib/libossaudio/Attic/ossaudio.c 2000/07/04 09:56:14 1.11 @@ -1,4 +1,4 @@ -/* $NetBSD: ossaudio.c,v 1.10 1999/11/16 23:56:41 augustss Exp $ */ +/* $NetBSD: ossaudio.c,v 1.11 2000/07/04 09:56:14 augustss Exp $ */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -55,7 +55,7 @@ #define GET_DEV(com) ((com) & 0xff) #define TO_OSSVOL(x) ((x) * 100 / 255) -#define FROM_OSSVOL(x) ((x) * 255 / 100) +#define FROM_OSSVOL(x) (((x) > 100 ? 100 : (x)) * 255 / 100) static struct audiodevinfo *getdevinfo(int); @@ -63,6 +63,9 @@ static void setblocksize(int, struct aud static int audio_ioctl(int, unsigned long, void *); static int mixer_ioctl(int, unsigned long, void *); +static int opaque_to_enum(struct audiodevinfo *di, audio_mixer_name_t *label, int opq); +static int enum_to_ord(struct audiodevinfo *di, int enm); +static int enum_to_mask(struct audiodevinfo *di, int enm); #define INTARG (*(int*)argp) @@ -266,7 +269,7 @@ audio_ioctl(int fd, unsigned long com, v if ((idat & 0xffff) < 4 || (idat & 0xffff) > 17) return EINVAL; tmpinfo.blocksize = 1 << (idat & 0xffff); - tmpinfo.hiwat = (idat >> 16) & 0x7fff; + tmpinfo.hiwat = ((unsigned)idat >> 16) & 0x7fff; if (tmpinfo.hiwat == 0) /* 0 means set to max */ tmpinfo.hiwat = 65536; (void) ioctl(fd, AUDIO_SETINFO, &tmpinfo); @@ -422,18 +425,65 @@ audio_ioctl(int fd, unsigned long com, v } -/* If the NetBSD mixer device should have more than 32 devices +/* If the NetBSD mixer device should have more than NETBSD_MAXDEVS devices * some will not be available to Linux */ -#define NETBSD_MAXDEVS 32 +#define NETBSD_MAXDEVS 64 struct audiodevinfo { int done; dev_t dev; int16_t devmap[SOUND_MIXER_NRDEVICES], rdevmap[NETBSD_MAXDEVS]; + char names[NETBSD_MAXDEVS][MAX_AUDIO_DEV_LEN]; + int enum2opaque[NETBSD_MAXDEVS]; u_long devmask, recmask, stereomask; u_long caps, source; }; +static int +opaque_to_enum(struct audiodevinfo *di, audio_mixer_name_t *label, int opq) +{ + int i, o; + + for (i = 0; i < NETBSD_MAXDEVS; i++) { + o = di->enum2opaque[i]; + if (o == opq) + break; + if (o == -1 && label != NULL && + !strncmp(di->names[i], label->name, sizeof di->names[i])) { + di->enum2opaque[i] = opq; + break; + } + } + if (i >= NETBSD_MAXDEVS) + i = -1; + /*printf("opq_to_enum %s %d -> %d\n", label->name, opq, i);*/ + return (i); +} + +static int +enum_to_ord(struct audiodevinfo *di, int enm) +{ + if (enm >= NETBSD_MAXDEVS) + return (-1); + + /*printf("enum_to_ord %d -> %d\n", enm, di->enum2opaque[enm]);*/ + return (di->enum2opaque[enm]); +} + +static int +enum_to_mask(struct audiodevinfo *di, int enm) +{ + int m; + if (enm >= NETBSD_MAXDEVS) + return (0); + + m = di->enum2opaque[enm]; + if (m == -1) + m = 0; + /*printf("enum_to_mask %d -> %d\n", enm, di->enum2opaque[enm]);*/ + return (m); +} + /* * Collect the audio device information to allow faster * emulation of the Linux mixer ioctls. Cache the information @@ -444,7 +494,7 @@ static struct audiodevinfo * getdevinfo(int fd) { mixer_devinfo_t mi; - int i; + int i, j, e; static struct { char *name; int code; @@ -487,12 +537,15 @@ getdevinfo(int fd) di->devmask = 0; di->recmask = 0; di->stereomask = 0; - di->source = -1; + di->source = ~0; di->caps = 0; for(i = 0; i < SOUND_MIXER_NRDEVICES; i++) di->devmap[i] = -1; - for(i = 0; i < NETBSD_MAXDEVS; i++) + for(i = 0; i < NETBSD_MAXDEVS; i++) { di->rdevmap[i] = -1; + di->names[i][0] = '\0'; + di->enum2opaque[i] = -1; + } for(i = 0; i < NETBSD_MAXDEVS; i++) { mi.index = i; if (ioctl(fd, AUDIO_MIXER_DEVINFO, &mi) < 0) @@ -508,29 +561,37 @@ getdevinfo(int fd) di->devmask |= 1 << dp->code; if (mi.un.v.num_channels == 2) di->stereomask |= 1 << dp->code; + strncpy(di->names[i], mi.label.name, + sizeof di->names[i]); } break; + } + } + for(i = 0; i < NETBSD_MAXDEVS; i++) { + mi.index = i; + if (ioctl(fd, AUDIO_MIXER_DEVINFO, &mi) < 0) + break; + if (strcmp(mi.label.name, AudioNsource) != 0) + continue; + di->source = i; + switch(mi.type) { case AUDIO_MIXER_ENUM: - if (strcmp(mi.label.name, AudioNsource) == 0) { - int j; - di->source = i; - for(j = 0; j < mi.un.e.num_mem; j++) - di->recmask |= 1 << di->rdevmap[mi.un.e.member[j].ord]; - di->caps = SOUND_CAP_EXCL_INPUT; + for(j = 0; j < mi.un.e.num_mem; j++) { + e = opaque_to_enum(di, + &mi.un.e.member[j].label, + mi.un.e.member[j].ord); + if (e >= 0) + di->recmask |= 1 << di->rdevmap[e]; } + di->caps = SOUND_CAP_EXCL_INPUT; break; case AUDIO_MIXER_SET: - if (strcmp(mi.label.name, AudioNsource) == 0) { - int j; - di->source = i; - for(j = 0; j < mi.un.s.num_mem; j++) { - int k, mask = mi.un.s.member[j].mask; - if (mask) { - for(k = 0; !(mask & 1); mask >>= 1, k++) - ; - di->recmask |= 1 << di->rdevmap[k]; - } - } + for(j = 0; j < mi.un.s.num_mem; j++) { + e = opaque_to_enum(di, + &mi.un.s.member[j].label, + mi.un.s.member[j].mask); + if (e >= 0) + di->recmask |= 1 << di->rdevmap[e]; } break; } @@ -548,13 +609,16 @@ mixer_ioctl(int fd, unsigned long com, v int idat; int i; int retval; - int l, r, n, error; + int l, r, n, error, e; di = getdevinfo(fd); if (di == 0) return -1; switch (com) { + case OSS_GETVERSION: + idat = SOUND_VERSION; + break; case SOUND_MIXER_INFO: case SOUND_OLD_MIXER_INFO: error = ioctl(fd, AUDIO_GETDEV, &adev); @@ -575,18 +639,17 @@ mixer_ioctl(int fd, unsigned long com, v retval = ioctl(fd, AUDIO_MIXER_READ, &mc); if (retval < 0) return retval; - idat = 1 << di->rdevmap[mc.un.ord]; + e = opaque_to_enum(di, NULL, mc.un.ord); + if (e >= 0) + idat = 1 << di->rdevmap[e]; } else { - int k; - unsigned int mask; mc.type = AUDIO_MIXER_SET; retval = ioctl(fd, AUDIO_MIXER_READ, &mc); if (retval < 0) return retval; - idat = 0; - for(mask = mc.un.mask, k = 0; mask; mask >>= 1, k++) - if (mask & 1) - idat |= 1 << di->rdevmap[k]; + e = opaque_to_enum(di, NULL, mc.un.mask); + if (e >= 0) + idat = 1 << di->rdevmap[e]; } break; case SOUND_MIXER_READ_DEVMASK: @@ -615,7 +678,7 @@ mixer_ioctl(int fd, unsigned long com, v if (i >= SOUND_MIXER_NRDEVICES || di->devmap[i] == -1) return EINVAL; - mc.un.ord = di->devmap[i]; + mc.un.ord = enum_to_ord(di, di->devmap[i]); } else { mc.type = AUDIO_MIXER_SET; mc.un.mask = 0; @@ -623,7 +686,7 @@ mixer_ioctl(int fd, unsigned long com, v if (idat & (1 << i)) { if (di->devmap[i] == -1) return EINVAL; - mc.un.mask |= 1 << di->devmap[i]; + mc.un.mask |= enum_to_mask(di, di->devmap[i]); } } }