Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src Implement OSS_GETVERSION.
details: https://anonhg.NetBSD.org/src/rev/40e602fafea9
branches: trunk
changeset: 494238:40e602fafea9
user: augustss <augustss%NetBSD.org@localhost>
date: Tue Jul 04 09:56:14 2000 +0000
description:
Implement OSS_GETVERSION.
Accept mixer values above max (100).
Handle the info from AUDIO_MIXER_DEVINFO properly, parts of it is opaque.
diffstat:
lib/libossaudio/ossaudio.c | 133 ++++++++++++++++++++++++++---------
sys/compat/ossaudio/ossaudio.c | 142 +++++++++++++++++++++++++++----------
sys/compat/ossaudio/ossaudiovar.h | 5 +-
3 files changed, 203 insertions(+), 77 deletions(-)
diffs (truncated from 512 to 300 lines):
diff -r 27013dfa1d02 -r 40e602fafea9 lib/libossaudio/ossaudio.c
--- a/lib/libossaudio/ossaudio.c Tue Jul 04 09:33:55 2000 +0000
+++ b/lib/libossaudio/ossaudio.c Tue Jul 04 09:56:14 2000 +0000
@@ -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 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 @@
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 @@
}
-/* 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 @@
getdevinfo(int fd)
{
mixer_devinfo_t mi;
- int i;
+ int i, j, e;
static struct {
char *name;
int code;
@@ -487,12 +537,15 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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]);
}
}
}
diff -r 27013dfa1d02 -r 40e602fafea9 sys/compat/ossaudio/ossaudio.c
--- a/sys/compat/ossaudio/ossaudio.c Tue Jul 04 09:33:55 2000 +0000
+++ b/sys/compat/ossaudio/ossaudio.c Tue Jul 04 09:56:14 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ossaudio.c,v 1.30 1999/11/17 00:06:38 augustss Exp $ */
+/* $NetBSD: ossaudio.c,v 1.31 2000/07/04 09:59:31 augustss Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -58,9 +58,12 @@
#endif
#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 __P((struct file *, struct proc *));
+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);
static void setblocksize __P((struct file *, struct audio_info *, struct proc *));
@@ -508,10 +511,57 @@
dev_t dev;
int16_t devmap[OSS_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);
Home |
Main Index |
Thread Index |
Old Index