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:

NetBSD Home
NetBSD PR Database Search

(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.