NetBSD Problem Report #46611
From www@NetBSD.org Sun Jun 17 12:40:04 2012
Return-Path: <www@NetBSD.org>
Received: from mail.netbsd.org (mail.netbsd.org [149.20.53.66])
by www.NetBSD.org (Postfix) with ESMTP id 67AE463B955
for <gnats-bugs@gnats.NetBSD.org>; Sun, 17 Jun 2012 12:40:04 +0000 (UTC)
Message-Id: <20120617124002.124CA63B8CC@www.NetBSD.org>
Date: Sun, 17 Jun 2012 12:40:02 +0000 (UTC)
From: nathanialsloss@yahoo.com.au
Reply-To: nathanialsloss@yahoo.com.au
To: gnats-bugs@NetBSD.org
Subject: libossaudio: Support for OSSv4
X-Send-Pr-Version: www-1.0
>Number: 46611
>Category: lib
>Synopsis: libossaudio: Support for OSSv4
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: lib-bug-people
>State: closed
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Sun Jun 17 12:45:00 +0000 2012
>Closed-Date: Sat May 17 12:52:15 +0000 2014
>Last-Modified: Sat May 17 19:05:00 +0000 2014
>Originator: Nat Sloss
>Release: NetBSD 5.0.1
>Organization:
>Environment:
NetBSD beast 5.0.1 NetBSD 5.0.1 (LOCKDEBUG) #98: Sat Jun 16 19:50:55 EST 2012 build@beast:/usr/src/sys/arch/i386/compile/LOCKDEBUG i386
>Description:
Hi.
Wine-devel from pkgsrc requires ossv4 compatibility for sound. So do later versions of wine 1.4 and 1.56 they have no support for NetBSD's audio subsystem. Also I think the prerequisite for version 4 compatibility will be more common.
>How-To-Repeat:
Make configure on wine-devel from pkgsrc and you will receive a warning that there is no sound support as it requires oss v4 compatibility.
>Fix:
I implemented some of the required ioctls and redefined open and close to accommodate for the fact that wine devel would open an audio device and open it again in another function whilst it was previously open. If that open failed as it would normally no sound was produced.
So here are my patches I have as yet to port them to current:
Index: soundcard.h
===================================================================
RCS file: /cvsroot/src/lib/libossaudio/soundcard.h,v
retrieving revision 1.18
diff -u -r1.18 soundcard.h
--- soundcard.h 28 Apr 2008 20:23:01 -0000 1.18
+++ soundcard.h 17 Jun 2012 11:37:24 -0000
@@ -39,7 +39,7 @@
#ifndef _SOUNDCARD_H_
#define _SOUNDCARD_H_
-#define SOUND_VERSION 0x030001
+#define SOUND_VERSION 0x040001
#define SNDCTL_DSP_RESET _IO ('P', 0)
#define SNDCTL_DSP_SYNC _IO ('P', 1)
@@ -59,6 +59,10 @@
#define AFMT_U16_LE 0x00000080
#define AFMT_U16_BE 0x00000100
#define AFMT_MPEG 0x00000200
+#define AFMT_S24_LE 0x00000400
+#define AFMT_S24_BE 0x00000800
+#define AFMT_S32_LE 0x00001000
+#define AFMT_S32_BE 0x00002000
#define SNDCTL_DSP_SAMPLESIZE SNDCTL_DSP_SETFMT
#define SOUND_PCM_READ_BITS _IOR ('P', 5, int)
#define SNDCTL_DSP_CHANNELS _IOWR('P', 6, int)
@@ -81,6 +85,8 @@
# define DSP_CAP_COPROC 0x00000800
# define DSP_CAP_TRIGGER 0x00001000
# define DSP_CAP_MMAP 0x00002000
+# define PCM_CAP_INPUT 0x00004000
+# define PCM_CAP_OUTPUT 0x00008000
#define SNDCTL_DSP_GETTRIGGER _IOR ('P', 16, int)
#define SNDCTL_DSP_SETTRIGGER _IOW ('P', 16, int)
# define PCM_ENABLE_INPUT 0x00000001
@@ -290,6 +296,76 @@
int size;
} buffmem_desc;
+/* Some OSSv4 calls. */
+
+#define OSS_DEVNODE_SIZE 32
+#define OSS_LABEL_SIZE 16
+#define OSS_LONGNAME_SIZE 64
+#define OSS_MAX_AUDIO_DEVS 64
+
+#define SNDCTL_SYSINFO _IOR ('P',24, struct oss_sysinfo)
+#define SNDCTL_AUDIOINFO _IOWR ('P',25, struct oss_audioinfo)
+#define SNDCTL_ENGINEINFO _IOWR ('P',26, struct oss_audioinfo)
+#define SNDCTL_DSP_GETPLAYVOL _IOR ('P',27, uint)
+#define SNDCTL_DSP_SETPLAYVOL _IOW ('P',28, uint)
+#define SNDCTL_DSP_GETRECVOL _IOR ('P',29, uint)
+#define SNDCTL_DSP_SETRECVOL _IOW ('P',30, uint)
+#define SNDCTL_DSP_SKIP _IO ('P',31)
+
+typedef struct oss_sysinfo {
+ char product[32];
+ char version[32];
+ int versionnum;
+ char options[128]; /* Future use */
+ int numaudios;
+ int openedaudio[8]; /* Obsolete */
+ int numsynths; /* Obsolete */
+ int nummidis;
+ int numtimers;
+ int nummixers;
+ int openedmidi[8];
+ int numcards;
+ int numaudioengines;
+ char license[16];
+ char revision_info[256]; /* Internal Use */
+ int filler[172]; /* For expansion */
+} oss_sysinfo;
+
+typedef struct oss_audioinfo {
+ int dev; /* Set by caller */
+ char name[OSS_LONGNAME_SIZE];
+ int busy;
+ int pid;
+ int caps;
+ int iformats;
+ int oformats;
+ int magic; /* Unused */
+ char cmd[OSS_LONGNAME_SIZE];
+ int card_number;
+ int port_number;
+ int mixer_dev;
+ int legacy_device; /* Obsolete */
+ int enabled;
+ int flags; /* Reserved */
+ int min_rate;
+ int max_rate;
+ int min_channels;
+ int max_channels;
+ int binding; /* Reserved */
+ int rate_source;
+ char handle[32];
+#define OSS_MAX_SAMPLE_RATES 20
+ int nrates;
+ int rates[OSS_MAX_SAMPLE_RATES];
+ char song_name[OSS_LONGNAME_SIZE];
+ char label[OSS_LABEL_SIZE];
+ int latency; /* In usecs -1 = unknown */
+ char devnode[OSS_DEVNODE_SIZE]; /* device file name without /dev */
+ int next_play_engine;
+ int next_rec_engine;
+ int filler[184]; /* For expansion */
+} oss_audioinfo;
+
#if 0
/* This is what we'd like to have, but it causes prototype conflicts. */
#define ioctl _oss_ioctl
@@ -302,12 +378,18 @@
*/
#include <sys/ioctl.h>
#define ioctl(x,y,z) _oss_ioctl(x,y,z)
+#include <fcntl.h>
+#include <unistd.h>
+#define open(x,y,...) _oss_open(x,y,##__VA_ARGS__)
+#define close(x) _oss_close(x)
#endif
#include <sys/cdefs.h>
__BEGIN_DECLS
int _oss_ioctl(int fd, unsigned long com, void *argp);
+int _oss_open(char *path, int flags, ...);
+int _oss_close(int fd);
__END_DECLS
#endif /* !_SOUNDCARD_H_ */
Index: ossaudio.c
===================================================================
RCS file: /cvsroot/src/lib/libossaudio/ossaudio.c,v
retrieving revision 1.24
diff -u -r1.24 ossaudio.c
--- ossaudio.c 28 Apr 2008 20:23:01 -0000 1.24
+++ ossaudio.c 17 Jun 2012 11:37:40 -0000
@@ -44,17 +44,33 @@
#include <sys/audioio.h>
#include <sys/stat.h>
#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdarg.h>
#include "soundcard.h"
#undef ioctl
+#undef open
+#undef close
#define GET_DEV(com) ((com) & 0xff)
#define TO_OSSVOL(x) (((x) * 100 + 127) / 255)
#define FROM_OSSVOL(x) ((((x) > 100 ? 100 : (x)) * 255 + 50) / 100)
+static int initialised = 0;
+typedef struct openaudiofds {
+ int read;
+ int write;
+ int readwrite;
+ int count;
+} openaudiofds_t;
+
+static openaudiofds_t openedfds[64];
static struct audiodevinfo *getdevinfo(int);
+static void audioopeninit(void); /* Initialises fd structure */
static void setblocksize(int, struct audio_info *);
static int audio_ioctl(int, unsigned long, void *);
@@ -65,6 +81,134 @@
#define INTARG (*(int*)argp)
+static void
+audioopeninit()
+{
+ int i;
+
+ for (i = 0; i < 64; i++) {
+ openedfds[i].readwrite = -1;
+ openedfds[i].write = -1;
+ openedfds[i].read = -1;
+ openedfds[i].count = -1;
+ }
+ initialised = 1;
+
+ return;
+}
+
+int
+_oss_open(char *path, int flags, ...)
+{
+ int i, fd;
+ char checkpath[255];
+
+ va_list ap;
+ mode_t mode;
+
+ va_start(ap, flags);
+ mode = va_arg(ap, mode_t);
+ va_end(ap);
+
+ fd = -1;
+
+ if (initialised == 0)
+ audioopeninit();
+ if (strncmp("/dev/audio", path, 10) == 0) {
+ for (i=0; i < OSS_MAX_AUDIO_DEVS; i++) {
+ snprintf(checkpath, 255, "/dev/audio%d", i);
+ if (strcmp(checkpath, path) == 0)
+ break;
+ }
+
+ if (i == OSS_MAX_AUDIO_DEVS)
+ return -1;
+ if ((flags & O_ACCMODE) == O_RDWR) {
+ if (openedfds[i].readwrite == -1) {
+ fd = open(path, flags, mode);
+ if (fd < 0)
+ return fd;
+ else {
+ openedfds[i].readwrite = fd;
+ openedfds[i].count++;
+ }
+ } else {
+ fd = openedfds[i].readwrite;
+ openedfds[i].count++;
+ }
+ } else if ((flags & O_ACCMODE) == O_WRONLY) {
+ if (openedfds[i].write == -1) {
+ fd = open(path, flags, mode);
+ if (fd < 0)
+ return fd;
+ else {
+ openedfds[i].write = fd;
+ openedfds[i].count++;
+ }
+ } else {
+ fd = openedfds[i].write;
+ openedfds[i].count++;
+ }
+ } else if ((flags & O_ACCMODE) == O_RDONLY) {
+ if (openedfds[i].read == -1) {
+ fd = open(path, flags, mode);
+ if (fd < 0)
+ return fd;
+ else {
+ openedfds[i].read = fd;
+ openedfds[i].count++;
+ }
+ } else {
+ fd = openedfds[i].read;
+ openedfds[i].count++;
+ }
+ }
+ errno = 0;
+ /*printf("fd = %d openedcount[%d]: %d\n", fd, i,
+ * openedfds[i].count);
+ */
+ } else
+ fd = open(path, flags, mode);
+
+ return fd;
+}
+
+int
+_oss_close(int fd)
+{
+ int i;
+ for (i = 0; i < OSS_MAX_AUDIO_DEVS; i++) {
+ if (fd == openedfds[i].readwrite)
+ break;
+ if (fd == openedfds[i].write)
+ break;
+ if (fd == openedfds[i].read)
+ break;
+ }
+
+ if (i < OSS_MAX_AUDIO_DEVS) {
+ openedfds[i].count--;
+ if (openedfds[i].count < 0) {
+ if (openedfds[i].readwrite >= 0) {
+ close(openedfds[i].readwrite);
+ openedfds[i].readwrite = -1;
+ }
+ if (openedfds[i].write >= 0) {
+ close(openedfds[i].write);
+ openedfds[i].write = -1;
+ }
+ if (openedfds[i].read >= 0) {
+ close(openedfds[i].read);
+ openedfds[i].read = -1;
+ }
+ }
+ /*printf("oss_close count[%d]: %d\n",i, openedfds[i].count);*/
+
+ return 0;
+ } else
+ return (close(fd));
+}
+
int
_oss_ioctl(int fd, unsigned long com, void *argp)
{
@@ -85,9 +229,18 @@
struct audio_buf_info bufinfo;
struct count_info cntinfo;
struct audio_encoding tmpenc;
+ struct oss_sysinfo tmpsysinfo;
+ struct oss_audioinfo *tmpaudioinfo;
+ audio_device_t tmpaudiodev;
+ char audiodevpath[255];
+ struct stat tmpstat;
+ dev_t devno;
+ char version[32] = "4.01";
+ char license[16] = "NetBSD";
u_int u;
int idat, idata;
int retval;
+ int i, audiofd;
idat = 0;
@@ -299,13 +452,21 @@
idat |= AFMT_S8;
break;
case AUDIO_ENCODING_SLINEAR_LE:
- if (tmpenc.precision == 16)
+ if (tmpenc.precision == 32)
+ idat |= AFMT_S32_LE;
+ else if (tmpenc.precision == 24)
+ idat |= AFMT_S24_LE;
+ else if (tmpenc.precision == 16)
idat |= AFMT_S16_LE;
else
idat |= AFMT_S8;
break;
case AUDIO_ENCODING_SLINEAR_BE:
- if (tmpenc.precision == 16)
+ if (tmpenc.precision == 32)
+ idat |= AFMT_S32_BE;
+ else if (tmpenc.precision == 24)
+ idat |= AFMT_S24_BE;
+ else if (tmpenc.precision == 16)
idat |= AFMT_S16_BE;
else
idat |= AFMT_S8;
@@ -423,6 +584,133 @@
cntinfo.ptr = tmpoffs.offset;
*(struct count_info *)argp = cntinfo;
break;
+ case SNDCTL_SYSINFO:
+ strncpy(tmpsysinfo.product, "OSS/NetBSD", 31);
+ tmpsysinfo.product[31] = 0;
+ strncpy(tmpsysinfo.version, version, 31);
+ tmpsysinfo.version[31] = 0;
+ strncpy(tmpsysinfo.license, license, 15);
+ tmpsysinfo.license[15] = 0;
+ tmpsysinfo.versionnum = SOUND_VERSION;
+ memset(tmpsysinfo.options, 0, 8);
+ tmpsysinfo.numaudios = OSS_MAX_AUDIO_DEVS;
+ tmpsysinfo.numaudioengines = 1;
+ memset(tmpsysinfo.openedaudio, 0, 8);
+ tmpsysinfo.numsynths = 1;
+ tmpsysinfo.nummidis = -1;
+ tmpsysinfo.numtimers = -1;
+ tmpsysinfo.nummixers = 1;
+ tmpsysinfo.numcards = 1;
+ memset(tmpsysinfo.openedmidi, 0, 8);
+ *(struct oss_sysinfo *)argp = tmpsysinfo;
+ break;
+ case SNDCTL_ENGINEINFO:
+ case SNDCTL_AUDIOINFO:
+ devno = 0;
+ tmpaudioinfo = (struct oss_audioinfo*)argp;
+ if (tmpaudioinfo == NULL)
+ return EINVAL;
+ if (tmpaudioinfo->dev < 0) {
+ fstat(fd, &tmpstat);
+ if ((tmpstat.st_rdev & 0xff00) == 0x2a00)
+ devno = tmpstat.st_rdev & 0xff;
+ if (devno >= 0x80)
+ tmpaudioinfo->dev = devno & 0x7f;
+ }
+ if (tmpaudioinfo->dev < 0)
+ tmpaudioinfo->dev = 0;
+
+ snprintf(tmpaudioinfo->devnode, OSS_DEVNODE_SIZE,
+ "/dev/audio%d", tmpaudioinfo->dev);
+
+ snprintf(audiodevpath, 255, "%s", tmpaudioinfo->devnode);
+ audiofd = _oss_open(&audiodevpath[0], O_WRONLY);
+
+ retval = ioctl(audiofd, AUDIO_GETDEV, &tmpaudiodev);
+ if (retval < 0)
+ return retval;
+ retval = ioctl(audiofd, AUDIO_GETINFO, &tmpinfo);
+ if (retval < 0)
+ return retval;
+ retval = ioctl(audiofd, AUDIO_GETPROPS, &idata);
+ if (retval < 0)
+ return retval;
+ idat = DSP_CAP_TRIGGER; /* pretend we have trigger */
+ if (idata & AUDIO_PROP_FULLDUPLEX)
+ idat |= DSP_CAP_DUPLEX;
+ if (idata & AUDIO_PROP_MMAP)
+ idat |= DSP_CAP_MMAP;
+ idat = PCM_CAP_INPUT | PCM_CAP_OUTPUT;
+ strncpy(tmpaudioinfo->name, tmpaudiodev.name, 64);
+ tmpaudioinfo->name[63] = 0;
+ tmpaudioinfo->busy = tmpinfo.play.open;
+ tmpaudioinfo->pid = -1;
+ tmpaudioinfo->caps = idat;
+ ioctl(audiofd, SNDCTL_DSP_GETFMTS, &tmpaudioinfo->iformats);
+ tmpaudioinfo->oformats = tmpaudioinfo->iformats;
+ tmpaudioinfo->magic = -1;
+ memset(tmpaudioinfo->cmd, 0, 64);
+ tmpaudioinfo->card_number = -1;
+ memset(tmpaudioinfo->song_name, 0, 64);
+ memset(tmpaudioinfo->label, 0, 16);
+ tmpaudioinfo->port_number = tmpinfo.play.port;
+ tmpaudioinfo->mixer_dev = tmpaudioinfo->dev;
+ tmpaudioinfo->legacy_device = -1;
+ tmpaudioinfo->enabled = 1;
+ tmpaudioinfo->flags = -1;
+ tmpaudioinfo->min_rate = tmpinfo.play.sample_rate;
+ tmpaudioinfo->max_rate = tmpinfo.play.sample_rate;
+ tmpaudioinfo->nrates = 2;
+ for (i = 0; i < tmpaudioinfo->nrates; i++)
+ tmpaudioinfo->rates[i] = tmpinfo.play.sample_rate;
+ tmpaudioinfo->min_channels = tmpinfo.play.channels;
+ tmpaudioinfo->max_channels = tmpinfo.play.channels;
+ tmpaudioinfo->binding = -1;
+ tmpaudioinfo->rate_source = -1;
+ memset(tmpaudioinfo->handle, 0, 16);
+ tmpaudioinfo->next_play_engine = 0;
+ tmpaudioinfo->next_rec_engine = 0;
+ argp = tmpaudioinfo;
+ _oss_close(audiofd);
+ break;
+ case SNDCTL_DSP_GETPLAYVOL:
+ retval = ioctl(fd, AUDIO_GETBUFINFO, &tmpinfo);
+ if (retval < 0)
+ return retval;
+ *(uint *)argp = tmpinfo.play.gain;
+ break;
+ case SNDCTL_DSP_SETPLAYVOL:
+ retval = ioctl(fd, AUDIO_GETBUFINFO, &tmpinfo);
+ if (retval < 0)
+ return retval;
+ if (*(uint *)argp > 255)
+ tmpinfo.play.gain = 255;
+ else
+ tmpinfo.play.gain = *(uint *)argp;
+ retval = ioctl(fd, AUDIO_SETINFO, &tmpinfo);
+ if (retval < 0)
+ return retval;
+ break;
+ case SNDCTL_DSP_GETRECVOL:
+ retval = ioctl(fd, AUDIO_GETBUFINFO, &tmpinfo);
+ if (retval < 0)
+ return retval;
+ *(uint *)argp = tmpinfo.record.gain;
+ break;
+ case SNDCTL_DSP_SETRECVOL:
+ retval = ioctl(fd, AUDIO_GETBUFINFO, &tmpinfo);
+ if (retval < 0)
+ return retval;
+ if (*(uint *)argp > 255)
+ tmpinfo.record.gain = 255;
+ else
+ tmpinfo.record.gain = *(uint *)argp;
+ retval = ioctl(fd, AUDIO_SETINFO, &tmpinfo);
+ if (retval < 0)
+ return retval;
+ break;
+ case SNDCTL_DSP_SKIP:
+ return EINVAL;
case SNDCTL_DSP_SETDUPLEX:
idat = 1;
retval = ioctl(fd, AUDIO_SETFD, &idat);
Note: These patches are mostly my own work. The structures and ioctl definitions are from freebsd's soundcard.h as well as the OSS v4 api documentation. The implementation of the ioctls is my own work which I submit under the NetBSD license.
BUGS/TODO: The ioctl numbers for the ones I have implemented are probably not compatible with linux or oss v4 in general (I didn't look at ossv4 code from the ossv4 people due to concerns about their license). Also additional ioctls are missing.
However having said that these changes allow one to compile and run wine devel and later versions with sound support.
Regards,
Nat.
>Release-Note:
>Audit-Trail:
From: Nat Sloss <nathanialsloss@yahoo.com.au>
To: "gnats-bugs" <gnats-bugs@netbsd.org>
Cc: Thomas Klausner <wiz@netbsd.org>
Subject: Re: lib/46611
Date: Sat, 19 Apr 2014 12:32:28 +1000
Here is a better patch as it also supports SNDCTL_DSP_SILENCE and adds
additional missing defines (3 of them):
SNDCTL_DSP_SILENCE and SNDCTL_DSP_SKIP return EINVAL for now as they are
supposed to manipulate kernel sound buffers directly and I'm as yet to think of
a way of emulating this. On the packages I have tried so far retuning EINVAL
seems OK.
Index: libossaudio/soundcard.h
===================================================================
RCS file: /cvsroot/src/lib/libossaudio/soundcard.h,v
retrieving revision 1.22
diff -u -r1.22 soundcard.h
--- libossaudio/soundcard.h 5 May 2012 15:57:45 -0000 1.22
+++ libossaudio/soundcard.h 19 Apr 2014 02:02:18 -0000
@@ -39,7 +39,9 @@
#ifndef _SOUNDCARD_H_
#define _SOUNDCARD_H_
-#define SOUND_VERSION 0x030001
+#ifndef SOUND_VERSION
+#define SOUND_VERSION 0x030001
+#endif
#define SNDCTL_DSP_RESET _IO ('P', 0)
#define SNDCTL_DSP_SYNC _IO ('P', 1)
@@ -60,6 +62,11 @@
#define AFMT_U16_BE 0x00000100
#define AFMT_MPEG 0x00000200
#define AFMT_AC3 0x00000400
+#define AFMT_S24_LE 0x00000800
+#define AFMT_S24_BE 0x00001000
+#define AFMT_S32_LE 0x00002000
+#define AFMT_S32_BE 0x00004000
+#define AFMT_S32_NE 0x00008000
#define SNDCTL_DSP_SAMPLESIZE SNDCTL_DSP_SETFMT
#define SOUND_PCM_READ_BITS _IOR ('P', 5, int)
#define SNDCTL_DSP_CHANNELS _IOWR('P', 6, int)
@@ -82,6 +89,10 @@
# define DSP_CAP_COPROC 0x00000800
# define DSP_CAP_TRIGGER 0x00001000
# define DSP_CAP_MMAP 0x00002000
+# define PCM_CAP_INPUT 0x00004000
+# define PCM_CAP_OUTPUT 0x00008000
+# define PCM_CAP_MODEM 0x00010000
+# define PCM_CAP_HIDDEN 0x00020000
#define SNDCTL_DSP_GETTRIGGER _IOR ('P', 16, int)
#define SNDCTL_DSP_SETTRIGGER _IOW ('P', 16, int)
# define PCM_ENABLE_INPUT 0x00000001
@@ -291,6 +302,77 @@
int size;
} buffmem_desc;
+/* Some OSSv4 calls. */
+
+#define OSS_DEVNODE_SIZE 32
+#define OSS_LABEL_SIZE 16
+#define OSS_LONGNAME_SIZE 64
+#define OSS_MAX_AUDIO_DEVS 64
+
+#define SNDCTL_SYSINFO _IOR ('P',24, struct oss_sysinfo)
+#define SNDCTL_AUDIOINFO _IOWR ('P',25, struct oss_audioinfo)
+#define SNDCTL_ENGINEINFO _IOWR ('P',26, struct oss_audioinfo)
+#define SNDCTL_DSP_GETPLAYVOL _IOR ('P',27, uint)
+#define SNDCTL_DSP_SETPLAYVOL _IOW ('P',28, uint)
+#define SNDCTL_DSP_GETRECVOL _IOR ('P',29, uint)
+#define SNDCTL_DSP_SETRECVOL _IOW ('P',30, uint)
+#define SNDCTL_DSP_SKIP _IO ('P',31)
+#define SNDCTL_DSP_SILENCE _IO ('P',32)
+
+typedef struct oss_sysinfo {
+ char product[32];
+ char version[32];
+ int versionnum;
+ char options[128]; /* Future use */
+ int numaudios;
+ int openedaudio[8]; /* Obsolete */
+ int numsynths; /* Obsolete */
+ int nummidis;
+ int numtimers;
+ int nummixers;
+ int openedmidi[8];
+ int numcards;
+ int numaudioengines;
+ char license[16];
+ char revision_info[256]; /* Internal Use */
+ int filler[172]; /* For expansion */
+} oss_sysinfo;
+
+typedef struct oss_audioinfo {
+ int dev; /* Set by caller */
+ char name[OSS_LONGNAME_SIZE];
+ int busy;
+ int pid;
+ int caps;
+ int iformats;
+ int oformats;
+ int magic; /* Unused */
+ char cmd[OSS_LONGNAME_SIZE];
+ int card_number;
+ int port_number;
+ int mixer_dev;
+ int legacy_device; /* Obsolete */
+ int enabled;
+ int flags; /* Reserved */
+ int min_rate;
+ int max_rate;
+ int min_channels;
+ int max_channels;
+ int binding; /* Reserved */
+ int rate_source;
+ char handle[32];
+#define OSS_MAX_SAMPLE_RATES 20
+ int nrates;
+ int rates[OSS_MAX_SAMPLE_RATES];
+ char song_name[OSS_LONGNAME_SIZE];
+ char label[OSS_LABEL_SIZE];
+ int latency; /* In usecs -1 = unknown */
+ char devnode[OSS_DEVNODE_SIZE];
+ int next_play_engine;
+ int next_rec_engine;
+ int filler[184]; /* For expansion */
+} oss_audioinfo;
+
#define ioctl _oss_ioctl
/*
* If we already included <sys/ioctl.h>, then we define our own prototype,
@@ -302,6 +384,15 @@
#else
__BEGIN_DECLS
int _oss_ioctl(int, unsigned long, ...);
+#include <fcntl.h>
+#include <unistd.h>
+
+#ifdef OSS_OPEN_OVERLOAD
+#define open(x,y,...) _oss_open(x,y,##__VA_ARGS__)
+#define close(x) _oss_close(x)
+int _oss_open(char *path, int flags, ...);
+int _oss_close(int fd);
+#endif
__END_DECLS
#endif
Index: libossaudio/ossaudio.c
===================================================================
RCS file: /cvsroot/src/lib/libossaudio/ossaudio.c,v
retrieving revision 1.28
diff -u -r1.28 ossaudio.c
--- libossaudio/ossaudio.c 5 May 2012 15:57:45 -0000 1.28
+++ libossaudio/ossaudio.c 19 Apr 2014 02:03:49 -0000
@@ -44,6 +44,9 @@
#include <sys/audioio.h>
#include <sys/stat.h>
#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
#include <stdarg.h>
#include "soundcard.h"
@@ -93,9 +96,17 @@
struct audio_buf_info bufinfo;
struct count_info cntinfo;
struct audio_encoding tmpenc;
+ struct oss_sysinfo tmpsysinfo;
+ struct oss_audioinfo *tmpaudioinfo;
+ audio_device_t tmpaudiodev;
+ struct stat tmpstat;
+ dev_t devno;
+ char version[32] = "4.01";
+ char license[16] = "NetBSD";
u_int u;
int idat, idata;
int retval;
+ int i;
idat = 0;
@@ -316,13 +327,21 @@
idat |= AFMT_S8;
break;
case AUDIO_ENCODING_SLINEAR_LE:
- if (tmpenc.precision == 16)
+ if (tmpenc.precision == 32)
+ idat |= AFMT_S32_LE;
+ else if (tmpenc.precision == 24)
+ idat |= AFMT_S24_LE;
+ else if (tmpenc.precision == 16)
idat |= AFMT_S16_LE;
else
idat |= AFMT_S8;
break;
case AUDIO_ENCODING_SLINEAR_BE:
- if (tmpenc.precision == 16)
+ if (tmpenc.precision == 32)
+ idat |= AFMT_S32_BE;
+ else if (tmpenc.precision == 24)
+ idat |= AFMT_S24_BE;
+ else if (tmpenc.precision == 16)
idat |= AFMT_S16_BE;
else
idat |= AFMT_S8;
@@ -445,6 +464,130 @@
cntinfo.ptr = tmpoffs.offset;
*(struct count_info *)argp = cntinfo;
break;
+ case SNDCTL_SYSINFO:
+ strncpy(tmpsysinfo.product, "OSS/NetBSD", 31);
+ tmpsysinfo.product[31] = 0;
+ strncpy(tmpsysinfo.version, version, 31);
+ tmpsysinfo.version[31] = 0;
+ strncpy(tmpsysinfo.license, license, 15);
+ tmpsysinfo.license[15] = 0;
+ tmpsysinfo.versionnum = SOUND_VERSION;
+ memset(tmpsysinfo.options, 0, 8);
+ tmpsysinfo.numaudios = OSS_MAX_AUDIO_DEVS;
+ tmpsysinfo.numaudioengines = 1;
+ memset(tmpsysinfo.openedaudio, 0, 8);
+ tmpsysinfo.numsynths = 1;
+ tmpsysinfo.nummidis = -1;
+ tmpsysinfo.numtimers = -1;
+ tmpsysinfo.nummixers = 1;
+ tmpsysinfo.numcards = 1;
+ memset(tmpsysinfo.openedmidi, 0, 8);
+ *(struct oss_sysinfo *)argp = tmpsysinfo;
+ break;
+ case SNDCTL_ENGINEINFO:
+ case SNDCTL_AUDIOINFO:
+ devno = 0;
+ tmpaudioinfo = (struct oss_audioinfo*)argp;
+ if (tmpaudioinfo == NULL)
+ return EINVAL;
+ if (tmpaudioinfo->dev < 0) {
+ fstat(fd, &tmpstat);
+ if ((tmpstat.st_rdev & 0xff00) == 0x2a00)
+ devno = tmpstat.st_rdev & 0xff;
+ if (devno >= 0x80)
+ tmpaudioinfo->dev = devno & 0x7f;
+ }
+ if (tmpaudioinfo->dev < 0)
+ tmpaudioinfo->dev = 0;
+
+ snprintf(tmpaudioinfo->devnode, OSS_DEVNODE_SIZE,
+ "/dev/audio%d", tmpaudioinfo->dev);
+
+ retval = ioctl(fd, AUDIO_GETDEV, &tmpaudiodev);
+ if (retval < 0)
+ return retval;
+ retval = ioctl(fd, AUDIO_GETINFO, &tmpinfo);
+ if (retval < 0)
+ return retval;
+ retval = ioctl(fd, AUDIO_GETPROPS, &idata);
+ if (retval < 0)
+ return retval;
+ idat = DSP_CAP_TRIGGER; /* pretend we have trigger */
+ if (idata & AUDIO_PROP_FULLDUPLEX)
+ idat |= DSP_CAP_DUPLEX;
+ if (idata & AUDIO_PROP_MMAP)
+ idat |= DSP_CAP_MMAP;
+ idat = PCM_CAP_INPUT | PCM_CAP_OUTPUT;
+ strncpy(tmpaudioinfo->name, tmpaudiodev.name, 64);
+ tmpaudioinfo->name[63] = 0;
+ tmpaudioinfo->busy = tmpinfo.play.open;
+ tmpaudioinfo->pid = -1;
+ tmpaudioinfo->caps = idat;
+ ioctl(fd, SNDCTL_DSP_GETFMTS, &tmpaudioinfo->iformats);
+ tmpaudioinfo->oformats = tmpaudioinfo->iformats;
+ tmpaudioinfo->magic = -1;
+ memset(tmpaudioinfo->cmd, 0, 64);
+ tmpaudioinfo->card_number = -1;
+ memset(tmpaudioinfo->song_name, 0, 64);
+ memset(tmpaudioinfo->label, 0, 16);
+ tmpaudioinfo->port_number = tmpinfo.play.port;
+ tmpaudioinfo->mixer_dev = tmpaudioinfo->dev;
+ tmpaudioinfo->legacy_device = -1;
+ tmpaudioinfo->enabled = 1;
+ tmpaudioinfo->flags = -1;
+ tmpaudioinfo->min_rate = tmpinfo.play.sample_rate;
+ tmpaudioinfo->max_rate = tmpinfo.play.sample_rate;
+ tmpaudioinfo->nrates = 2;
+ for (i = 0; i < tmpaudioinfo->nrates; i++)
+ tmpaudioinfo->rates[i] = tmpinfo.play.sample_rate;
+ tmpaudioinfo->min_channels = tmpinfo.play.channels;
+ tmpaudioinfo->max_channels = tmpinfo.play.channels;
+ tmpaudioinfo->binding = -1;
+ tmpaudioinfo->rate_source = -1;
+ memset(tmpaudioinfo->handle, 0, 16);
+ tmpaudioinfo->next_play_engine = 0;
+ tmpaudioinfo->next_rec_engine = 0;
+ argp = tmpaudioinfo;
+ break;
+ case SNDCTL_DSP_GETPLAYVOL:
+ retval = ioctl(fd, AUDIO_GETBUFINFO, &tmpinfo);
+ if (retval < 0)
+ return retval;
+ *(uint *)argp = tmpinfo.play.gain;
+ break;
+ case SNDCTL_DSP_SETPLAYVOL:
+ retval = ioctl(fd, AUDIO_GETBUFINFO, &tmpinfo);
+ if (retval < 0)
+ return retval;
+ if (*(uint *)argp > 255)
+ tmpinfo.play.gain = 255;
+ else
+ tmpinfo.play.gain = *(uint *)argp;
+ retval = ioctl(fd, AUDIO_SETINFO, &tmpinfo);
+ if (retval < 0)
+ return retval;
+ break;
+ case SNDCTL_DSP_GETRECVOL:
+ retval = ioctl(fd, AUDIO_GETBUFINFO, &tmpinfo);
+ if (retval < 0)
+ return retval;
+ *(uint *)argp = tmpinfo.record.gain;
+ break;
+ case SNDCTL_DSP_SETRECVOL:
+ retval = ioctl(fd, AUDIO_GETBUFINFO, &tmpinfo);
+ if (retval < 0)
+ return retval;
+ if (*(uint *)argp > 255)
+ tmpinfo.record.gain = 255;
+ else
+ tmpinfo.record.gain = *(uint *)argp;
+ retval = ioctl(fd, AUDIO_SETINFO, &tmpinfo);
+ if (retval < 0)
+ return retval;
+ break;
+ case SNDCTL_DSP_SKIP:
+ case SNDCTL_DSP_SILENCE:
+ return EINVAL;
case SNDCTL_DSP_SETDUPLEX:
idat = 1;
retval = ioctl(fd, AUDIO_SETFD, &idat);
This allows wip/vlc21 to compile and run with oss but you have to specify the
audio device ie: vlc -Aoss -oss-audio-device=/dev/audio somefile
Regards,
Nat.
From: Nat Sloss <nathanialsloss@yahoo.com.au>
To: "gnats-bugs" <gnats-bugs@netbsd.org>
Cc: Thomas Klausner <wiz@netbsd.org>
Subject: Re: lib/46611
Date: Tue, 22 Apr 2014 08:30:21 +1000
Here is an updated soundcard.h as the one in the previous submission
contained defines for overloading open and close which has been removed
from my patch for ossaudio.c:
Index: src/lib/libossaudio/soundcard.h
===================================================================
RCS file: /cvsroot/src/lib/libossaudio/soundcard.h,v
retrieving revision 1.22
diff -u -r1.22 soundcard.h
--- src/lib/libossaudio/soundcard.h 5 May 2012 15:57:45 -0000 1.22
+++ src/lib/libossaudio/soundcard.h 21 Apr 2014 22:07:34 -0000
@@ -39,7 +39,9 @@
#ifndef _SOUNDCARD_H_
#define _SOUNDCARD_H_
-#define SOUND_VERSION 0x030001
+#ifndef SOUND_VERSION
+#define SOUND_VERSION 0x030001
+#endif
#define SNDCTL_DSP_RESET _IO ('P', 0)
#define SNDCTL_DSP_SYNC _IO ('P', 1)
@@ -60,6 +62,11 @@
#define AFMT_U16_BE 0x00000100
#define AFMT_MPEG 0x00000200
#define AFMT_AC3 0x00000400
+#define AFMT_S24_LE 0x00000800
+#define AFMT_S24_BE 0x00001000
+#define AFMT_S32_LE 0x00002000
+#define AFMT_S32_BE 0x00004000
+#define AFMT_S32_NE 0x00008000
#define SNDCTL_DSP_SAMPLESIZE SNDCTL_DSP_SETFMT
#define SOUND_PCM_READ_BITS _IOR ('P', 5, int)
#define SNDCTL_DSP_CHANNELS _IOWR('P', 6, int)
@@ -82,6 +89,10 @@
# define DSP_CAP_COPROC 0x00000800
# define DSP_CAP_TRIGGER 0x00001000
# define DSP_CAP_MMAP 0x00002000
+# define PCM_CAP_INPUT 0x00004000
+# define PCM_CAP_OUTPUT 0x00008000
+# define PCM_CAP_MODEM 0x00010000
+# define PCM_CAP_HIDDEN 0x00020000
#define SNDCTL_DSP_GETTRIGGER _IOR ('P', 16, int)
#define SNDCTL_DSP_SETTRIGGER _IOW ('P', 16, int)
# define PCM_ENABLE_INPUT 0x00000001
@@ -291,6 +302,77 @@
int size;
} buffmem_desc;
+/* Some OSSv4 calls. */
+
+#define OSS_DEVNODE_SIZE 32
+#define OSS_LABEL_SIZE 16
+#define OSS_LONGNAME_SIZE 64
+#define OSS_MAX_AUDIO_DEVS 64
+
+#define SNDCTL_SYSINFO _IOR ('P',24, struct oss_sysinfo)
+#define SNDCTL_AUDIOINFO _IOWR ('P',25, struct oss_audioinfo)
+#define SNDCTL_ENGINEINFO _IOWR ('P',26, struct oss_audioinfo)
+#define SNDCTL_DSP_GETPLAYVOL _IOR ('P',27, uint)
+#define SNDCTL_DSP_SETPLAYVOL _IOW ('P',28, uint)
+#define SNDCTL_DSP_GETRECVOL _IOR ('P',29, uint)
+#define SNDCTL_DSP_SETRECVOL _IOW ('P',30, uint)
+#define SNDCTL_DSP_SKIP _IO ('P',31)
+#define SNDCTL_DSP_SILENCE _IO ('P',32)
+
+typedef struct oss_sysinfo {
+ char product[32];
+ char version[32];
+ int versionnum;
+ char options[128]; /* Future use */
+ int numaudios;
+ int openedaudio[8]; /* Obsolete */
+ int numsynths; /* Obsolete */
+ int nummidis;
+ int numtimers;
+ int nummixers;
+ int openedmidi[8];
+ int numcards;
+ int numaudioengines;
+ char license[16];
+ char revision_info[256]; /* Internal Use */
+ int filler[172]; /* For expansion */
+} oss_sysinfo;
+
+typedef struct oss_audioinfo {
+ int dev; /* Set by caller */
+ char name[OSS_LONGNAME_SIZE];
+ int busy;
+ int pid;
+ int caps;
+ int iformats;
+ int oformats;
+ int magic; /* Unused */
+ char cmd[OSS_LONGNAME_SIZE];
+ int card_number;
+ int port_number;
+ int mixer_dev;
+ int legacy_device; /* Obsolete */
+ int enabled;
+ int flags; /* Reserved */
+ int min_rate;
+ int max_rate;
+ int min_channels;
+ int max_channels;
+ int binding; /* Reserved */
+ int rate_source;
+ char handle[32];
+#define OSS_MAX_SAMPLE_RATES 20
+ int nrates;
+ int rates[OSS_MAX_SAMPLE_RATES];
+ char song_name[OSS_LONGNAME_SIZE];
+ char label[OSS_LABEL_SIZE];
+ int latency; /* In usecs -1 = unknown */
+ char devnode[OSS_DEVNODE_SIZE];
+ int next_play_engine;
+ int next_rec_engine;
+ int filler[184]; /* For expansion */
+} oss_audioinfo;
+
#define ioctl _oss_ioctl
/*
* If we already included <sys/ioctl.h>, then we define our own prototype,
Regards,
Nat.
From: "Nathanial Sloss" <nat@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/46611 CVS commit: src/lib/libossaudio
Date: Sat, 17 May 2014 12:38:42 +0000
Module Name: src
Committed By: nat
Date: Sat May 17 12:38:42 UTC 2014
Modified Files:
src/lib/libossaudio: ossaudio.c soundcard.h
Log Message:
Adds ioctls and defines for OSSv4 compatibility.
The ioctl definitions and accompanying structures were
taken from FreeBSD's soundcard.h, hopefully providing
some binary compatibility.
The ioctls are as follows:
SNDCTL_SYSINFO: Returns a structure containing
details about the audio device.
SNDCTL_ENGINEINFO - SNDCTL_AUDIOINFO: Returns a
structure with playback/recording
characteristics.
SNDCTL_DSP_GETPLAYVOL, SNDCTL_DSP_SETPLAYVOL,
SNDCTL_DSP_GETRECVOL, SNDCTL_DSP_SETRECVOL:
Retrieves/Sets Playback/Recording volume.
SNDCTL_DSP_SKIP - SNDCTL_DSP_SILENCE: These ioctls
were intended to manipulate the underlying
audio buffer skip or insert silence. These
return EINVAL.
SOUND_VERSION is unchanged, but is definable, It will be
changed when the mixer OSSv4 ioctls are written.
Addresses PR 46611
This commit was approved by wiz@.
To generate a diff of this commit:
cvs rdiff -u -r1.28 -r1.29 src/lib/libossaudio/ossaudio.c
cvs rdiff -u -r1.22 -r1.23 src/lib/libossaudio/soundcard.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
State-Changed-From-To: open->closed
State-Changed-By: nat@NetBSD.org
State-Changed-When: Sat, 17 May 2014 12:52:15 +0000
State-Changed-Why:
Support for OSSv4 added.
From: matthew green <mrg@eterna.com.au>
To: gnats-bugs@NetBSD.org
Cc: lib-bug-people@netbsd.org, netbsd-bugs@netbsd.org,
gnats-admin@netbsd.org, nat@NetBSD.org, nathanialsloss@yahoo.com.au
Subject: re: lib/46611 (libossaudio: Support for OSSv4)
Date: Sun, 18 May 2014 05:04:33 +1000
nat@NetBSD.org writes:
> Synopsis: libossaudio: Support for OSSv4
>
> State-Changed-From-To: open->closed
> State-Changed-By: nat@NetBSD.org
> State-Changed-When: Sat, 17 May 2014 12:52:15 +0000
> State-Changed-Why:
> Support for OSSv4 added.
consider pullup to netbsd-6?
.mrg.
>Unformatted:
(Contact us)
$NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.