-.\" $OpenBSD: audio.4,v 1.71 2016/06/18 07:59:30 ratchov Exp $
+.\" $OpenBSD: audio.4,v 1.72 2016/08/31 07:22:43 ratchov Exp $
.\" $NetBSD: audio.4,v 1.20 1998/05/28 17:27:15 augustss Exp $
.\"
.\" Copyright (c) 1996 The NetBSD Foundation, Inc.
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd $Mdocdate: June 18 2016 $
+.Dd $Mdocdate: August 31 2016 $
.Dt AUDIO 4
.Os
.Sh NAME
commands are supported on the sample devices:
.Pp
.Bl -tag -width Ds -compact
-.It Dv AUDIO_RERROR Fa "int *"
-.It Dv AUDIO_PERROR Fa "int *"
-Obsolete.
-These commands fetch the count of dropped input or output samples into
-the
-.Vt int *
-argument, respectively.
-There is no information regarding when in the sample stream
-they were dropped.
-.Pp
.It Dv AUDIO_GETDEV Fa "audio_device_t *"
This command fetches the current hardware device information into the
.Vt audio_device_t *
} audio_device_t;
.Ed
.Pp
-.It Dv AUDIO_GETFD Fa "int *"
-This command returns 1 if in full-duplex mode, else 0.
-.Pp
-.It Dv AUDIO_GETENC Fa "audio_encoding_t *"
-This command is used iteratively to fetch sample encoding
-.Va name Ns s
-and
-.Va format_id Ns s
-into the input/output
-.Vt audio_encoding_t *
-argument.
-.Bd -literal
-typedef struct audio_encoding {
- int index; /* input: nth encoding */
- char name[MAX_AUDIO_DEV_LEN]; /* name of encoding */
- int encoding; /* value for encoding parameter */
- int precision; /* value for precision parameter */
- int bps; /* value for bps parameter */
- int msb; /* value for msb parameter */
-} audio_encoding_t;
-.Ed
-.Pp
-To query
-all the supported encodings, start with an index field of 0 and
-continue with successive encodings (1, 2, ...) until the command returns
-an error.
-.Pp
-.It Dv AUDIO_SETFD Fa "int *"
-Does nothing, left for compatibility; argument must point to a non-zero
-integer if the device is opened in read-write mode.
-.Pp
-.It Dv AUDIO_GETPROPS Fa "int *"
-This command gets a bit set of hardware properties.
-If the hardware
-has a certain property, the corresponding bit is set, otherwise it is not.
-The properties can have the following values:
-.Pp
-.Bl -tag -width AUDIO_PROP_INDEPENDENT -compact
-.It Dv AUDIO_PROP_FULLDUPLEX
-The device admits full-duplex operation.
-.It Dv AUDIO_PROP_INDEPENDENT
-The device can set playing and recording channel counts independently.
-.El
-.Pp
-.It Dv AUDIO_GETIOFFS Fa "audio_offset_t *"
-.It Dv AUDIO_GETOOFFS Fa "audio_offset_t *"
-Obsolete.
-These commands fetch the number of bytes played or recorded.
-The information is returned in the
-.Vt audio_offset
-structure.
-.Bd -literal
-typedef struct audio_offset {
- u_int samples; /* Total number of bytes transferred */
-} audio_offset_t;
-.Ed
-.Pp
-.It Dv AUDIO_GETINFO Fa "audio_info_t *"
-.It Dv AUDIO_SETINFO Fa "audio_info_t *"
-Get or set audio information as encoded in the
-.Vt audio_info
-structure.
-.Bd -literal
-typedef struct audio_info {
- struct audio_prinfo play; /* info for play (output) side */
- struct audio_prinfo record; /* info for record (input) side */
- u_int hiwat; /* blocks count in play buffer */
- u_int mode; /* current device mode */
-#define AUMODE_PLAY 0x01
-#define AUMODE_RECORD 0x02
-} audio_info_t;
-.Ed
-.Pp
-When setting the current state with
-.Dv AUDIO_SETINFO ,
-the
-.Vt audio_info
-structure should first be initialized with
-.Pp
-.Dl "AUDIO_INITINFO(&info);"
-.Pp
-and then the particular values to be changed should be set.
-This allows the audio driver to only set those things that you wish
-to change and eliminates the need to query the device with
-.Dv AUDIO_GETINFO
-first.
-.Pp
-The
-.Va mode
-field is read-only and set to
-.Dv AUMODE_PLAY ,
-.Dv AUMODE_RECORD ,
-or a bitwise OR combination of the three.
-Only full-duplex audio devices support
-simultaneous record and playback.
-.Pp
-.Va hiwat
-contains the number of blocks in the kernel play buffer.
-Writes to the audio devices will queue blocks until the play buffer
-is full, at which point any more write calls will block
-until space for at least one byte is available.
-.Bd -literal
-struct audio_prinfo {
- u_int sample_rate; /* sample rate in bit/s */
- u_int channels; /* number of channels, usually 1 or 2 */
- u_int precision; /* number of bits/sample */
- u_int bps; /* number of bytes/sample */
- u_int msb; /* data alignment */
- u_int encoding; /* data encoding (AUDIO_ENCODING_* below) */
- u_int block_size; /* size a block */
- /* Current state of device: */
- u_char pause; /* non-zero if paused, zero to resume */
- u_char active; /* non-zero if I/O is currently active */
-};
-.Ed
-.Pp
-The
-.Nm
-driver requires identical playback and
-recording sample rates, sample encodings, and block durations.
-.Pp
-The
-.Va encoding
-parameter can have the following values:
-.Pp
-.Bl -tag -width AUDIO_ENCODING_SLINEAR_BE -compact
-.It Dv AUDIO_ENCODING_ULAW
-mu-law encoding, 8 bits/sample
-.It Dv AUDIO_ENCODING_ALAW
-A-law encoding, 8 bits/sample
-.It Dv AUDIO_ENCODING_SLINEAR_LE
-two's complement signed linear encoding with little endian byte order
-.It Dv AUDIO_ENCODING_SLINEAR_BE
-two's complement signed linear encoding with big endian byte order
-.It Dv AUDIO_ENCODING_ULINEAR_LE
-unsigned linear encoding with little endian byte order
-.It Dv AUDIO_ENCODING_ULINEAR_BE
-unsigned linear encoding with big endian byte order
-.El
-.Pp
-The
-.Va precision
-parameter describes the number of bits of audio data per sample.
-The
-.Va bps
-parameter describes the number of bytes of audio data per sample.
-The
-.Va msb
-parameter describes the alignment of the data in the sample.
-It is only meaningful when
-.Va precision
-/ NBBY <
-.Va bps .
-A value of 1 means the data is aligned to the most significant bit.
-.Pp
-.Va block_size
-is the block size in bytes, which determines the frequency at which
-blocking
-.Xr read 2 ,
-.Xr write 2 ,
-or
-.Xr poll 2 ,
-wake up.
-The generic
-.Nm audio
-driver layer and the hardware driver have the
-opportunity to adjust this block size to get it within
-implementation-required limits.
-Normally the
-.Va block_size
-is recalculated
-when other parameters changes.
-.Pp
-It is recommended to set
-.Va block_size
-at the same time as, or after, all other parameters have been set.
-.Pp
-.Va pause
-returns the current pause/unpause state for recording or playback.
-For
-.Dv AUDIO_SETINFO ,
-if the pause value is specified it will either pause
-or unpause the particular direction.
-In full-duplex the pause values for both directions must
-be equal.
-.Pp
.It Dv AUDIO_SETPAR Fa "struct audio_swpar *"
.It Dv AUDIO_GETPAR Fa "struct audio_swpar *"
Set or get audio parameters as encoded in the
-/* $OpenBSD: audio.c,v 1.150 2016/06/21 06:38:28 ratchov Exp $ */
+/* $OpenBSD: audio.c,v 1.151 2016/08/31 07:22:43 ratchov Exp $ */
/*
* Copyright (c) 2015 Alexandre Ratchov <alex@caoua.org>
*
return 0;
}
-int
-audio_setinfo(struct audio_softc *sc, struct audio_info *ai)
-{
- struct audio_prinfo *r = &ai->record, *p = &ai->play;
- int error;
- int set;
-
- /*
- * stop the device if requested to stop
- */
- if (sc->mode != 0) {
- if (sc->mode & AUMODE_PLAY) {
- if (p->pause != (unsigned char)~0)
- sc->pause = p->pause;
- }
- if (sc->mode & AUMODE_RECORD) {
- if (r->pause != (unsigned char)~0)
- sc->pause = r->pause;
- }
- if (sc->pause) {
- if (sc->active)
- audio_stop(sc);
- }
- }
-
- /*
- * copy parameters into the softc structure
- */
- set = 0;
- if (ai->play.encoding != ~0) {
- sc->sw_enc = ai->play.encoding;
- set = 1;
- }
- if (ai->play.precision != ~0) {
- sc->bits = ai->play.precision;
- set = 1;
- }
- if (ai->play.bps != ~0) {
- sc->bps = ai->play.bps;
- set = 1;
- }
- if (ai->play.msb != ~0) {
- sc->msb = ai->play.msb;
- set = 1;
- }
- if (ai->play.sample_rate != ~0) {
- sc->rate = ai->play.sample_rate;
- set = 1;
- }
- if (ai->play.channels != ~0) {
- sc->pchan = ai->play.channels;
- set = 1;
- }
- if (ai->play.block_size != ~0) {
- sc->round = ai->play.block_size /
- (sc->bps * sc->pchan);
- set = 1;
- }
- if (ai->hiwat != ~0) {
- sc->nblks = ai->hiwat;
- set = 1;
- }
- if (ai->record.encoding != ~0) {
- sc->sw_enc = ai->record.encoding;
- set = 1;
- }
- if (ai->record.precision != ~0) {
- sc->bits = ai->record.precision;
- set = 1;
- }
- if (ai->record.bps != ~0) {
- sc->bps = ai->record.bps;
- set = 1;
- }
- if (ai->record.msb != ~0) {
- sc->msb = ai->record.msb;
- set = 1;
- }
- if (ai->record.sample_rate != ~0) {
- sc->rate = ai->record.sample_rate;
- set = 1;
- }
- if (ai->record.channels != ~0) {
- sc->rchan = ai->record.channels;
- set = 1;
- }
- if (ai->record.block_size != ~0) {
- sc->round = ai->record.block_size /
- (sc->bps * sc->rchan);
- set = 1;
- }
-
- DPRINTF("%s: setinfo: set = %d, mode = %d, pause = %d\n",
- DEVNAME(sc), set, sc->mode, sc->pause);
-
- /*
- * if the device not opened, we're done, don't touch the hardware
- */
- if (sc->mode == 0)
- return 0;
-
- /*
- * change parameters and recalculate buffer sizes
- */
- if (set) {
- if (sc->active) {
- DPRINTF("%s: can't change params during dma\n",
- DEVNAME(sc));
- return EBUSY;
- }
- error = audio_setpar(sc);
- if (error)
- return error;
- audio_clear(sc);
- if ((sc->mode & AUMODE_PLAY) && sc->ops->init_output) {
- error = sc->ops->init_output(sc->arg,
- sc->play.data, sc->play.len);
- if (error)
- return error;
- }
- if ((sc->mode & AUMODE_RECORD) && sc->ops->init_input) {
- error = sc->ops->init_input(sc->arg,
- sc->rec.data, sc->rec.len);
- if (error)
- return error;
- }
- }
-
- /*
- * if unpaused, start
- */
- if (!sc->pause && !sc->active) {
- error = audio_start(sc);
- if (error)
- return error;
- }
- return 0;
-}
-
-int
-audio_getinfo(struct audio_softc *sc, struct audio_info *ai)
-{
- ai->play.sample_rate = ai->record.sample_rate = sc->rate;
- ai->play.encoding = ai->record.encoding = sc->sw_enc;
- ai->play.precision = ai->record.precision = sc->bits;
- ai->play.bps = ai->record.bps = sc->bps;
- ai->play.msb = ai->record.msb = sc->msb;
- ai->play.channels = sc->pchan;
- ai->record.channels = sc->rchan;
-
- /*
- * XXX: this is used only to display counters through audioctl
- * and the pos counters are more useful
- */
- mtx_enter(&audio_lock);
- ai->play.samples = sc->play.pos - sc->play.xrun;
- ai->record.samples = sc->rec.pos - sc->rec.xrun;
- mtx_leave(&audio_lock);
-
- ai->play.pause = ai->record.pause = sc->pause;
- ai->play.active = ai->record.active = sc->active;
-
- ai->play.buffer_size = sc->play.datalen;
- ai->record.buffer_size = sc->rec.datalen;
-
- ai->play.block_size = sc->round * sc->bps * sc->pchan;
- ai->record.block_size = sc->round * sc->bps * sc->rchan;
-
- ai->hiwat = sc->nblks;
- ai->lowat = sc->nblks;
- ai->mode = sc->mode;
- return 0;
-}
-
int
audio_ioc_start(struct audio_softc *sc)
{
int
audio_ioctl(struct audio_softc *sc, unsigned long cmd, void *addr)
{
- struct audio_offset *ao;
struct audio_pos *ap;
- int error = 0, fd;
+ int error = 0;
/* block if quiesced */
while (sc->quiesce)
case FIONBIO:
/* All handled in the upper FS layer. */
break;
- case AUDIO_PERROR:
- mtx_enter(&audio_lock);
- *(int *)addr = sc->play.xrun / (sc->pchan * sc->bps);
- mtx_leave(&audio_lock);
- break;
- case AUDIO_RERROR:
- mtx_enter(&audio_lock);
- *(int *)addr = sc->rec.xrun / (sc->rchan * sc->bps);
- mtx_leave(&audio_lock);
- break;
- case AUDIO_GETOOFFS:
- mtx_enter(&audio_lock);
- ao = (struct audio_offset *)addr;
- ao->samples = sc->play.pos;
- mtx_leave(&audio_lock);
- break;
- case AUDIO_GETIOFFS:
- mtx_enter(&audio_lock);
- ao = (struct audio_offset *)addr;
- ao->samples = sc->rec.pos;
- mtx_leave(&audio_lock);
- break;
case AUDIO_GETPOS:
mtx_enter(&audio_lock);
ap = (struct audio_pos *)addr;
case AUDIO_GETSTATUS:
error = audio_ioc_getstatus(sc, (struct audio_status *)addr);
break;
- case AUDIO_SETINFO:
- error = audio_setinfo(sc, (struct audio_info *)addr);
- break;
- case AUDIO_GETINFO:
- error = audio_getinfo(sc, (struct audio_info *)addr);
- break;
case AUDIO_GETDEV:
error = audio_getdev(sc, (struct audio_device *)addr);
break;
- case AUDIO_GETENC:
- error = sc->ops->query_encoding(sc->arg,
- (struct audio_encoding *)addr);
- break;
- case AUDIO_GETFD:
- *(int *)addr = (sc->mode & (AUMODE_PLAY | AUMODE_RECORD)) ==
- (AUMODE_PLAY | AUMODE_RECORD);
- break;
- case AUDIO_SETFD:
- fd = *(int *)addr;
- if ((sc->mode & (AUMODE_PLAY | AUMODE_RECORD)) !=
- (AUMODE_PLAY | AUMODE_RECORD) || !fd)
- return EINVAL;
- break;
- case AUDIO_GETPROPS:
- *(int *)addr = sc->ops->get_props(sc->arg);
- break;
default:
DPRINTF("%s: unknown ioctl 0x%lx\n", DEVNAME(sc), cmd);
error = ENOTTY;
error = audio_ioctl(sc, cmd, addr);
break;
case AUDIO_DEV_AUDIOCTL:
- if (cmd == AUDIO_SETINFO && sc->mode != 0) {
- error = EBUSY;
- break;
- }
if (cmd == AUDIO_SETPAR && sc->mode != 0) {
error = EBUSY;
break;
-/* $OpenBSD: audio_if.h,v 1.30 2015/06/25 06:43:46 ratchov Exp $ */
+/* $OpenBSD: audio_if.h,v 1.31 2016/08/31 07:22:43 ratchov Exp $ */
/* $NetBSD: audio_if.h,v 1.24 1998/01/10 14:07:25 tv Exp $ */
/*
#include <sys/mutex.h>
+/*
+ * get_props
+ */
+#define AUDIO_PROP_FULLDUPLEX 0x01
+#define AUDIO_PROP_MMAP 0x02
+#define AUDIO_PROP_INDEPENDENT 0x04
+
#define AUDIO_BPS(bits) (bits) <= 8 ? 1 : ((bits) <= 16 ? 2 : 4)
/*
u_int channels; /* mono(1), stereo(2) */
};
+/*
+ * query_encoding argument
+ */
+typedef struct audio_encoding {
+ int index;
+#define MAX_AUDIO_DEV_LEN 16
+ char name[MAX_AUDIO_DEV_LEN];
+#define AUDIO_ENCODING_NONE 0 /* no encoding assigned */
+#define AUDIO_ENCODING_ULAW 1 /* ITU G.711 mu-law */
+#define AUDIO_ENCODING_ALAW 2 /* ITU G.711 A-law */
+#define AUDIO_ENCODING_ADPCM 5 /* adaptive differential PCM */
+#define AUDIO_ENCODING_SLINEAR_LE 6
+#define AUDIO_ENCODING_SLINEAR_BE 7
+#define AUDIO_ENCODING_ULINEAR_LE 8
+#define AUDIO_ENCODING_ULINEAR_BE 9
+#define AUDIO_ENCODING_SLINEAR 10
+#define AUDIO_ENCODING_ULINEAR 11
+ int encoding;
+ int precision;
+ int bps;
+ int msb;
+ int flags;
+#define AUDIO_ENCODINGFLAG_EMULATED 1 /* software emulation mode */
+} audio_encoding_t;
+
struct audio_hw_if {
int (*open)(void *, int); /* open hardware */
void (*close)(void *); /* close hardware */
-/* $OpenBSD: kern_pledge.c,v 1.180 2016/07/28 12:12:16 mikeb Exp $ */
+/* $OpenBSD: kern_pledge.c,v 1.181 2016/08/31 07:22:43 ratchov Exp $ */
/*
* Copyright (c) 2015 Nicholas Marriott <nicm@openbsd.org>
case AUDIO_SETPAR:
case AUDIO_START:
case AUDIO_STOP:
- case AUDIO_SETINFO:
- case AUDIO_GETINFO:
- case AUDIO_GETENC:
- case AUDIO_SETFD:
- case AUDIO_GETPROPS:
if (fp->f_type == DTYPE_VNODE &&
vp->v_type == VCHR &&
cdevsw[major(vp->v_rdev)].d_open == audioopen)
-/* $OpenBSD: audioio.h,v 1.25 2016/06/18 07:59:30 ratchov Exp $ */
+/* $OpenBSD: audioio.h,v 1.26 2016/08/31 07:22:43 ratchov Exp $ */
/* $NetBSD: audioio.h,v 1.24 1998/08/13 06:28:41 mrg Exp $ */
/*
#ifndef _SYS_AUDIOIO_H_
#define _SYS_AUDIOIO_H_
+#define AUMODE_PLAY 0x01
+#define AUMODE_RECORD 0x02
+
#define AUDIO_INITPAR(p) \
(void)memset((void *)(p), 0xff, sizeof(struct audio_swpar))
int _spare[5];
};
-/*
- * Audio device
- */
-struct audio_prinfo {
- u_int sample_rate; /* sample rate in bit/s */
- u_int channels; /* number of channels, usually 1 or 2 */
- u_int precision; /* number of bits/sample */
- u_int bps; /* number of bytes/sample */
- u_int msb; /* data alignment */
- u_int encoding; /* data encoding (AUDIO_ENCODING_* below) */
- u_int ispare2[4];
- u_int buffer_size; /* total size audio buffer */
- u_int block_size; /* size a block */
- /* Current state of device: */
- u_int samples; /* number of samples */
- u_int ispare[1];
- u_char pause; /* non-zero if paused, zero to resume */
- u_char cspare2[6];
- u_char active; /* non-zero if I/O is currently active */
-};
-typedef struct audio_prinfo audio_prinfo_t;
-
-struct audio_info {
- struct audio_prinfo play; /* Info for play (output) side */
- struct audio_prinfo record; /* Info for record (input) side */
- u_int ispare[2]; /* H/W read/write block size */
- u_int hiwat; /* output high water mark */
- u_int lowat; /* output low water mark */
- u_char cspare[4];
- u_int mode; /* current device mode */
-#define AUMODE_PLAY 0x01
-#define AUMODE_RECORD 0x02
-};
-typedef struct audio_info audio_info_t;
-
-#define AUDIO_INITINFO(p) \
- (void)memset((void *)(p), 0xff, sizeof(struct audio_info))
-
/*
* Parameter for the AUDIO_GETDEV ioctl to determine current
* audio devices.
char config[MAX_AUDIO_DEV_LEN];
} audio_device_t;
-typedef struct audio_offset {
- u_int samples; /* Total number of bytes transferred */
- u_int unused[2];
-} audio_offset_t;
-
struct audio_pos {
unsigned int play_pos; /* total bytes played */
unsigned int play_xrun; /* bytes of silence inserted */
unsigned int rec_xrun; /* bytes dropped */
};
-/*
- * Supported audio encodings
- */
-/* Encoding ID's */
-#define AUDIO_ENCODING_NONE 0 /* no encoding assigned */
-#define AUDIO_ENCODING_ULAW 1 /* ITU G.711 mu-law */
-#define AUDIO_ENCODING_ALAW 2 /* ITU G.711 A-law */
-#define AUDIO_ENCODING_ADPCM 5 /* adaptive differential PCM */
-#define AUDIO_ENCODING_SLINEAR_LE 6
-#define AUDIO_ENCODING_SLINEAR_BE 7
-#define AUDIO_ENCODING_ULINEAR_LE 8
-#define AUDIO_ENCODING_ULINEAR_BE 9
-#define AUDIO_ENCODING_SLINEAR 10
-#define AUDIO_ENCODING_ULINEAR 11
-
-typedef struct audio_encoding {
- int index;
- char name[MAX_AUDIO_DEV_LEN];
- int encoding;
- int precision;
- int bps;
- int msb;
- int flags;
-#define AUDIO_ENCODINGFLAG_EMULATED 1 /* software emulation mode */
-} audio_encoding_t;
-
-/*
- * Balance settings.
- */
-#define AUDIO_LEFT_BALANCE 0 /* left channel only */
-#define AUDIO_MID_BALANCE 32 /* equal left/right channel */
-#define AUDIO_RIGHT_BALANCE 64 /* right channel only */
-#define AUDIO_BALANCE_SHIFT 3
-
/*
* Audio device operations
*/
-#define AUDIO_GETINFO _IOR('A', 21, struct audio_info)
-#define AUDIO_SETINFO _IOWR('A', 22, struct audio_info)
-#define AUDIO_DRAIN _IO('A', 23)
-#define AUDIO_RERROR _IOR('A', 26, int)
#define AUDIO_GETDEV _IOR('A', 27, struct audio_device)
-#define AUDIO_GETENC _IOWR('A', 28, struct audio_encoding)
-#define AUDIO_GETFD _IOR('A', 29, int)
-#define AUDIO_SETFD _IOWR('A', 30, int)
-#define AUDIO_PERROR _IOR('A', 31, int)
-#define AUDIO_GETIOFFS _IOR('A', 32, struct audio_offset)
-#define AUDIO_GETOOFFS _IOR('A', 33, struct audio_offset)
-#define AUDIO_GETPROPS _IOR('A', 34, int)
#define AUDIO_GETPOS _IOR('A', 35, struct audio_pos)
#define AUDIO_GETPAR _IOR('A', 36, struct audio_swpar)
#define AUDIO_SETPAR _IOWR('A', 37, struct audio_swpar)
#define AUDIO_START _IO('A', 38)
#define AUDIO_STOP _IO('A', 39)
#define AUDIO_GETSTATUS _IOR('A', 40, struct audio_status)
-#define AUDIO_PROP_FULLDUPLEX 0x01
-#define AUDIO_PROP_MMAP 0x02
-#define AUDIO_PROP_INDEPENDENT 0x04
/*
* Mixer device