summaryrefslogtreecommitdiff
path: root/lib/libossaudio
diff options
context:
space:
mode:
authornia <nia@NetBSD.org>2021-05-09 11:28:25 +0000
committernia <nia@NetBSD.org>2021-05-09 11:28:25 +0000
commit295b047adf7ee29bac2f832699402227ee8a0737 (patch)
tree175691f83a655249addb95ae5df330bc2e82a1c4 /lib/libossaudio
parente269f57b202160047d5feb4e1f2373974daa78d4 (diff)
libossaudio: Various OSSv4 fixes to allow reference programs to compile
- Define various new AFMT_*. These are not returned as supported formats by SNDCTL_DSP_GETFMTS, because it would be very silly to have Vorbis in the kernel. - Implement PLAYTGT and RECSRC. For each NetBSD audio device we only return one playback and recording source, "primary". - Return preferred channel configuration in capabilities. Either DSP_CH_STEREO, DSP_CH_MONO, or DSP_CH_MULTI depending on the current hardware format. - SNDCTL_DSP_HALT_* simply flushes the audio device.
Diffstat (limited to 'lib/libossaudio')
-rw-r--r--lib/libossaudio/ossaudio.c60
-rw-r--r--lib/libossaudio/soundcard.h41
2 files changed, 86 insertions, 15 deletions
diff --git a/lib/libossaudio/ossaudio.c b/lib/libossaudio/ossaudio.c
index d6882d64e1e..6b1e4f8b968 100644
--- a/lib/libossaudio/ossaudio.c
+++ b/lib/libossaudio/ossaudio.c
@@ -1,7 +1,7 @@
-/* $NetBSD: ossaudio.c,v 1.66 2021/03/15 10:58:05 nia Exp $ */
+/* $NetBSD: ossaudio.c,v 1.67 2021/05/09 11:28:25 nia Exp $ */
/*-
- * Copyright (c) 1997, 2020 The NetBSD Foundation, Inc.
+ * Copyright (c) 1997-2021 The NetBSD Foundation, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: ossaudio.c,v 1.66 2021/03/15 10:58:05 nia Exp $");
+__RCSID("$NetBSD: ossaudio.c,v 1.67 2021/05/09 11:28:25 nia Exp $");
/*
* This is an Open Sound System compatibility layer, which provides
@@ -127,6 +127,7 @@ audio_ioctl(int fd, unsigned long com, void *argp)
int perrors, rerrors;
static int totalperrors = 0;
static int totalrerrors = 0;
+ oss_mixer_enuminfo *ei;
oss_count_t osscount;
int idat;
int retval;
@@ -134,6 +135,8 @@ audio_ioctl(int fd, unsigned long com, void *argp)
idat = 0;
switch (com) {
+ case SNDCTL_DSP_HALT_INPUT:
+ case SNDCTL_DSP_HALT_OUTPUT:
case SNDCTL_DSP_RESET:
retval = ioctl(fd, AUDIO_FLUSH, 0);
if (retval < 0)
@@ -293,6 +296,7 @@ audio_ioctl(int fd, unsigned long com, void *argp)
* the 24-bit formats should be handled properly instead
* of falling back to 32 bits.
*/
+ case AFMT_S24_PACKED:
case AFMT_S24_LE:
case AFMT_S32_LE:
tmpinfo.play.precision =
@@ -434,10 +438,6 @@ audio_ioctl(int fd, unsigned long com, void *argp)
case SNDCTL_DSP_SETFRAGMENT:
AUDIO_INITINFO(&tmpinfo);
idat = INTARG;
- if ((idat & 0xffff) < 4 || (idat & 0xffff) > 17) {
- errno = EINVAL;
- return -1;
- }
tmpinfo.blocksize = 1 << (idat & 0xffff);
tmpinfo.hiwat = ((unsigned)idat >> 16) & 0x7fff;
if (tmpinfo.hiwat == 0) /* 0 means set to max */
@@ -662,6 +662,21 @@ audio_ioctl(int fd, unsigned long com, void *argp)
case SNDCTL_DSP_SETSYNCRO:
errno = EINVAL;
return -1; /* XXX unimplemented */
+ case SNDCTL_DSP_GET_PLAYTGT_NAMES:
+ case SNDCTL_DSP_GET_RECSRC_NAMES:
+ ei = (oss_mixer_enuminfo *)argp;
+ ei->nvalues = 1;
+ ei->version = 0;
+ ei->strindex[0] = 0;
+ strlcpy(ei->strings, "primary", OSS_ENUM_STRINGSIZE);
+ break;
+ case SNDCTL_DSP_SET_PLAYTGT:
+ case SNDCTL_DSP_SET_RECSRC:
+ case SNDCTL_DSP_GET_PLAYTGT:
+ case SNDCTL_DSP_GET_RECSRC:
+ /* We have one recording source and play target. */
+ INTARG = 0;
+ break;
default:
errno = EINVAL;
return -1;
@@ -1114,7 +1129,7 @@ mixer_oss4_ioctl(int fd, unsigned long com, void *argp)
"%s %s", dev.name, dev.version);
tmpai->busy = 0;
tmpai->pid = -1;
- ioctl(newfd, SNDCTL_DSP_GETFMTS, &tmpai->iformats);
+ audio_ioctl(newfd, SNDCTL_DSP_GETFMTS, &tmpai->iformats);
tmpai->oformats = tmpai->iformats;
tmpai->magic = -1; /* reserved for "internal use" */
memset(tmpai->cmd, 0, sizeof(tmpai->cmd));
@@ -1603,17 +1618,40 @@ global_oss4_ioctl(int fd, unsigned long com, void *argp)
static int
getcaps(int fd, int *out)
{
+ struct audio_info info;
int props, caps;
+ int nchannels;
if (ioctl(fd, AUDIO_GETPROPS, &props) < 0)
return -1;
- caps = DSP_CAP_TRIGGER;
+ if (ioctl(fd, AUDIO_GETFORMAT, &info) < 0)
+ return -1;
+
+ caps = 0;
+ caps |= PCM_CAP_TRIGGER;
+ caps |= PCM_CAP_MULTI;
+ caps |= PCM_CAP_FREERATE;
+
+ nchannels = (props & AUDIO_PROP_PLAYBACK) ?
+ info.play.channels : info.record.channels;
+
+ switch (nchannels) {
+ case 2:
+ caps |= DSP_CH_STEREO;
+ break;
+ case 1:
+ caps |= DSP_CH_MONO;
+ break;
+ default:
+ caps |= DSP_CH_MULTI;
+ break;
+ }
if (props & AUDIO_PROP_FULLDUPLEX)
- caps |= DSP_CAP_DUPLEX;
+ caps |= PCM_CAP_DUPLEX;
if (props & AUDIO_PROP_MMAP)
- caps |= DSP_CAP_MMAP;
+ caps |= PCM_CAP_MMAP;
if (props & AUDIO_PROP_CAPTURE)
caps |= PCM_CAP_INPUT;
if (props & AUDIO_PROP_PLAYBACK)
diff --git a/lib/libossaudio/soundcard.h b/lib/libossaudio/soundcard.h
index f14591be969..58229d078aa 100644
--- a/lib/libossaudio/soundcard.h
+++ b/lib/libossaudio/soundcard.h
@@ -1,4 +1,4 @@
-/* $NetBSD: soundcard.h,v 1.33 2020/12/03 22:10:21 nia Exp $ */
+/* $NetBSD: soundcard.h,v 1.34 2021/05/09 11:28:25 nia Exp $ */
/*-
* Copyright (c) 1997, 2020 The NetBSD Foundation, Inc.
@@ -60,12 +60,16 @@
#define AFMT_S8 0x00000040
#define AFMT_U16_LE 0x00000080
#define AFMT_U16_BE 0x00000100
-#define AFMT_MPEG 0x00000200
+#define AFMT_MPEG 0x00000200 /* Not supported */
#define AFMT_AC3 0x00000400
-#define AFMT_S24_LE 0x00000800
-#define AFMT_S24_BE 0x00001000
+#define AFMT_S24_LE 0x00000800 /* Not supported */
+#define AFMT_S24_BE 0x00001000 /* Not supported */
#define AFMT_S32_LE 0x00002000
#define AFMT_S32_BE 0x00004000
+#define AFMT_FLOAT 0x00010000 /* Not supported */
+#define AFMT_SPDIF_RAW 0x00020000 /* Not supported */
+#define AFMT_S24_PACKED 0x00040000 /* Not supported */
+#define AFMT_VORBIS 0x00080000 /* Not supported */
#define SNDCTL_DSP_SAMPLESIZE SNDCTL_DSP_SETFMT
#define SOUND_PCM_READ_BITS _IOR ('P', 5, int)
#define SNDCTL_DSP_CHANNELS _IOWR('P', 6, int)
@@ -99,6 +103,10 @@
# define DSP_CAP_DIGITALOUT PCM_CAP_DIGITALOUT
# define DSP_CAP_DIGITALIN PCM_CAP_DIGITALIN
# define DSP_CAP_ADMASK PCM_CAP_ADMASK
+# define DSP_CAP_FREERATE PCM_CAP_FREERATE
+# define DSP_CAP_MULTI PCM_CAP_MULTI
+# define DSP_CAP_BIND PCM_CAP_BIND
+# define DSP_CAP_SHADOW PCM_CAP_SHADOW
# define PCM_CAP_REVISION 0x000000ff /* Unused in NetBSD */
# define PCM_CAP_DUPLEX 0x00000100 /* Full duplex */
# define PCM_CAP_REALTIME 0x00000200 /* Unused in NetBSD */
@@ -111,12 +119,21 @@
# define PCM_CAP_MODEM 0x00010000 /* Unused in NetBSD */
# define PCM_CAP_HIDDEN 0x00020000 /* Unused in NetBSD */
# define PCM_CAP_VIRTUAL 0x00040000 /* Unused in NetBSD */
+# define PCM_CAP_MULTI 0x00080000 /* Simultaneous open() */
# define PCM_CAP_ANALOGOUT 0x00100000 /* Unused in NetBSD */
# define PCM_CAP_ANALOGIN 0x00200000 /* Unused in NetBSD */
# define PCM_CAP_DIGITALOUT 0x00400000 /* Unused in NetBSD */
# define PCM_CAP_DIGITALIN 0x00800000 /* Unused in NetBSD */
# define PCM_CAP_ADMASK 0x00f00000 /* Unused in NetBSD */
# define PCM_CAP_SPECIAL 0x01000000 /* Unused in NetBSD */
+# define PCM_CAP_FREERATE 0x10000000 /* Freely set rate */
+# define PCM_CAP_SHADOW 0x40000000 /* Unused in NetBSD */
+# define PCM_CAP_BIND 0x80000000 /* Unused in NetBSD */
+# define DSP_CH_ANY 0x00000000 /* No preferred mode */
+# define DSP_CH_MONO 0x02000000
+# define DSP_CH_STEREO 0x04000000
+# define DSP_CH_MULTI 0x06000000
+# define DSP_CH_MASK 0x06000000
#define SNDCTL_DSP_GETTRIGGER _IOR ('P', 16, int)
#define SNDCTL_DSP_SETTRIGGER _IOW ('P', 16, int)
# define PCM_ENABLE_INPUT 0x00000001
@@ -342,6 +359,11 @@ typedef struct buffmem_desc {
/* Some OSSv4 calls. */
+/* Why is yet more duplication necessary? Sigh. */
+#define OSS_OPEN_READ PCM_ENABLE_INPUT
+#define OSS_OPEN_WRITE PCM_ENABLE_OUTPUT
+#define OSS_OPEN_READWRITE (OSS_OPEN_READ|OSS_OPEN_WRITE)
+
#define OSS_DEVNODE_SIZE 32
#define OSS_LABEL_SIZE 16
#define OSS_LONGNAME_SIZE 64
@@ -357,10 +379,21 @@ typedef struct buffmem_desc {
#define SNDCTL_DSP_GETERROR _IOR ('P',34, struct audio_errinfo)
#define SNDCTL_DSP_CURRENT_IPTR _IOR ('P',35, oss_count_t)
#define SNDCTL_DSP_CURRENT_OPTR _IOR ('P',36, oss_count_t)
+#define SNDCTL_DSP_GET_RECSRC_NAMES _IOR ('P',37, oss_mixer_enuminfo)
+#define SNDCTL_DSP_GET_RECSRC _IOR ('P',38, int)
+#define SNDCTL_DSP_SET_RECSRC _IOWR ('P',38, int)
+#define SNDCTL_DSP_GET_PLAYTGT_NAMES _IOR ('P',39, oss_mixer_enuminfo)
+#define SNDCTL_DSP_GET_PLAYTGT _IOR ('P',40, int)
+#define SNDCTL_DSP_SET_PLAYTGT _IOWR ('P',40, int)
#define SNDCTL_DSP_GET_CHNORDER _IOR ('P',42, unsigned long long)
#define SNDCTL_DSP_SET_CHNORDER _IOWR ('P',42, unsigned long long)
+#define SNDCTL_DSP_HALT_OUTPUT _IO ('P',70)
+#define SNDCTL_DSP_RESET_OUTPUT SNDCTL_DSP_HALT_OUTPUT /* Old name */
+#define SNDCTL_DSP_HALT_INPUT _IO ('P',71)
+#define SNDCTL_DSP_RESET_INPUT SNDCTL_DSP_HALT_INPUT /* Old name */
+
#define CHID_UNDEF 0
#define CHID_L 1
#define CHID_R 2