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.
This commit is contained in:
parent
df9fc8fe01
commit
5d7326fb2a
@ -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)
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user