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