570 lines
19 KiB
Groff
570 lines
19 KiB
Groff
.\" $NetBSD: audio.4,v 1.14 1997/10/08 21:59:52 jtc Exp $
|
|
.\"
|
|
.\" Copyright (c) 1996 The NetBSD Foundation, Inc.
|
|
.\" All rights reserved.
|
|
.\"
|
|
.\" This code is derived from software contributed to The NetBSD Foundation
|
|
.\" by John T. Kohl.
|
|
.\"
|
|
.\" Redistribution and use in source and binary forms, with or without
|
|
.\" modification, are permitted provided that the following conditions
|
|
.\" are met:
|
|
.\" 1. Redistributions of source code must retain the above copyright
|
|
.\" notice, this list of conditions and the following disclaimer.
|
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
|
.\" notice, this list of conditions and the following disclaimer in the
|
|
.\" documentation and/or other materials provided with the distribution.
|
|
.\" 3. All advertising materials mentioning features or use of this software
|
|
.\" must display the following acknowledgement:
|
|
.\" This product includes software developed by the NetBSD
|
|
.\" Foundation, Inc. and its contributors.
|
|
.\" 4. Neither the name of The NetBSD Foundation nor the names of its
|
|
.\" contributors may be used to endorse or promote products derived
|
|
.\" from this software without specific prior written permission.
|
|
.\"
|
|
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
|
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
|
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
.\" POSSIBILITY OF SUCH DAMAGE.
|
|
.\"
|
|
.Dd March 11, 1997
|
|
.Dt AUDIO 4
|
|
.Os NetBSD
|
|
.Sh NAME
|
|
.Nm audio
|
|
.Nd device-independent audio driver layer
|
|
.Sh SYNOPSIS
|
|
.Fd #include <sys/types.h>
|
|
.Fd #include <sys/audioio.h>
|
|
.Sh DESCRIPTION
|
|
The
|
|
.Nm
|
|
driver provides support for various audio peripherals. It provides a
|
|
uniform programming interface layer above different underlying audio
|
|
hardware drivers. The audio layer provides full-duplex operation if the
|
|
underlying hardware configuration supports it.
|
|
.Pp
|
|
There are four device files available for audio operation:
|
|
.Pa /dev/audio ,
|
|
.Pa /dev/sound ,
|
|
.Pa /dev/audioctl ,
|
|
and
|
|
.Pa /dev/mixer .
|
|
.Pa /dev/audio
|
|
and
|
|
.Pa /dev/sound
|
|
are used for recording or playback of digital samples.
|
|
.Pa /dev/mixer
|
|
is used to manipulate volume, recording source, or other audio mixer
|
|
functions.
|
|
.Pa /dev/audioctl
|
|
accepts the same
|
|
.Xr ioctl 2
|
|
operations as
|
|
.Pa /dev/sound ,
|
|
but no other operations. In contrast to
|
|
.Pa /dev/sound
|
|
which has the exclusive open property
|
|
.Pa /dev/audioctl
|
|
can be opened at any time and can be used to manipulate the audio device
|
|
while it is in use.
|
|
.Sh SAMPLING DEVICES
|
|
When
|
|
.Pa /dev/audio
|
|
is opened, it automatically directs the underlying driver to manipulate
|
|
monaural 8-bit mulaw samples. In addition, if it is opened read-only
|
|
(write-only) the device is set to half-duplex record (play) mode with
|
|
recording (playing) unpaused and playing (recording) paused.
|
|
When
|
|
.Pa /dev/sound
|
|
is opened, it maintains the previous audio sample mode and
|
|
record/playback mode. In all other respects
|
|
.Pa /dev/audio
|
|
and
|
|
.Pa /dev/sound
|
|
are identical.
|
|
.Pp
|
|
Only one process may hold open a sampling device at a given time
|
|
(although file descriptors may be shared between processes once the
|
|
first open completes).
|
|
.Pp
|
|
On a half-duplex device, writes while recording is in progress will be
|
|
immediately discarded. Similarly, reads while playback is in progress
|
|
will be filled with silence but delayed to return at the current
|
|
sampling rate. If both playback and recording are requested on a half-duplex
|
|
device, playback mode takes precedence and recordings will get silence.
|
|
On a full-duplex device, reads and writes may operate
|
|
concurrently without interference.
|
|
If a full-duplex capable audio device is opened for both reading and writing
|
|
it will start in half-duplex play mode; full-duplex mode has to be set
|
|
explicitely.
|
|
On either type of device, if the playback mode is paused then silence is
|
|
played instead of the provided samples, and if recording is paused then
|
|
the process blocks in
|
|
.Xr read 2
|
|
until recording is unpaused.
|
|
.Pp
|
|
If a writing process does not call
|
|
.Xr write 2
|
|
frequently enough to provide samples at the pace the hardware
|
|
consumes them silence is inserted.
|
|
If the
|
|
.Dv AUMODE_PLAY_ALL
|
|
mode is not set the writing process must
|
|
provide enough data via
|
|
subsequent write calls to ``catch up'' in time to the current audio
|
|
block before any more process-provided samples will be played.
|
|
If a reading process does not call
|
|
.Xr read 2
|
|
frequently enough, it will simply miss samples.
|
|
.Pp
|
|
The audio device is normally accessed with
|
|
.Xr read 2
|
|
or
|
|
.Xr write 2
|
|
calls, but it can also be mapped into user memory with
|
|
.Xr mmap 2
|
|
(when supported by the device).
|
|
Once the device has been mapped it can no longer be accessed
|
|
by read or write; all access is by reading and writing to
|
|
the mapped memory. The device appears as a block of memory
|
|
of size
|
|
.Va buffersize
|
|
available via
|
|
.Dv AUDIO_GETINFO .
|
|
The device driver will continuously move data from this buffer
|
|
from/to the audio hardware, wrapping around at the end of the
|
|
buffer. To find out where the hardware is currently accessing
|
|
data in the buffer the
|
|
.Dv AUDIO_GETIOFFS
|
|
and
|
|
.Dv AUDIO_GETOOFFS
|
|
calls can be used.
|
|
The playing and recording buffers are distinct and must be
|
|
mapped separately if both are to be used.
|
|
Only encodings that are not emulated (i.e. where
|
|
.Dv AUDIO_ENCODINGFLAG_EMULATED
|
|
is not set) work properly for a mapped device.
|
|
.Pp
|
|
The following
|
|
.Xr ioctl 2
|
|
commands are supported on the sample devices:
|
|
.Pp
|
|
.Bl -tag -width indent -compact
|
|
.It Dv AUDIO_FLUSH
|
|
This command stops all playback and recording, clears all queued
|
|
buffers, resets error counters, and restarts recording and playback as
|
|
appropriate for the current sampling mode.
|
|
.It Dv AUDIO_RERROR (int)
|
|
This command fetches the count of dropped input samples into its integer
|
|
argument. There is no information regarding when in the sample stream
|
|
they were dropped.
|
|
.It Dv AUDIO_WSEEK (int)
|
|
This command fetches the count of samples are queued ahead of the
|
|
first sample in the most recent sample block written into its integer argument.
|
|
.It Dv AUDIO_DRAIN
|
|
This command suspends the calling process until all queued playback
|
|
samples have been played by the hardware.
|
|
.It Dv AUDIO_GETDEV (audio_device_t)
|
|
This command fetches the current hardware device information into the
|
|
audio_device_t argument.
|
|
.Bd -literal
|
|
typedef struct audio_device {
|
|
char name[MAX_AUDIO_DEV_LEN];
|
|
char version[MAX_AUDIO_DEV_LEN];
|
|
char config[MAX_AUDIO_DEV_LEN];
|
|
} audio_device_t;
|
|
.Ed
|
|
.It Dv AUDIO_GETENC (audio_encoding_t)
|
|
This command is used iteratively to fetch sample encoding names and
|
|
format_ids into the input/output 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 flags;
|
|
#define AUDIO_ENCODINGFLAG_EMULATED 1 /* software emulation mode */
|
|
} audio_encoding_t;
|
|
.Ed
|
|
To query
|
|
all the supported encodings, start with an index field of zero and
|
|
continue with successive encodings (1, 2, ...) until the command returns
|
|
an error.
|
|
.It Dv AUDIO_SETFD (int)
|
|
This command sets the device into full-duplex operation if its integer
|
|
argument has a non-zero value, or into half-duplex operation if it
|
|
contains a zero value. If the device does not support full-duplex
|
|
operation, attempting to set full-duplex mode returns an error.
|
|
.It Dv AUDIO_GETPROPS (int)
|
|
This command gets a bit set of hardware properties. If the hardware
|
|
has a certain property a bit is set, otherwise it is not.
|
|
The properties can have the following values:
|
|
.Bl -tag -width indent -compact
|
|
.It Dv AUDIO_PROP_FULLDUPLEX
|
|
the device admits full duplex operation.
|
|
.It Dv AUDIO_PROP_MMAP
|
|
the device can be used with
|
|
.Xr mmap 2 .
|
|
.It Dv AUDIO_PROP_INDEPENDENT
|
|
the device can set the playing and recording encoding parameters
|
|
independently.
|
|
.El
|
|
.It Dv AUDIO_GETIOFFS (audio_offset_t)
|
|
.It Dv AUDIO_GETOOFFS (audio_offset_t)
|
|
This command fetches the current offset in the input(output) buffer where
|
|
the hardware is putting(getting) data. It mostly useful when the device
|
|
buffer is available in user space via the
|
|
.Xr mmap 2
|
|
call.
|
|
The information is returned in the audio_offset structure.
|
|
.Bd -literal
|
|
typedef struct audio_offset {
|
|
u_int samples; /* Total number of bytes transferred */
|
|
u_int deltablks; /* Blocks transferred since last checked */
|
|
u_int offset; /* Physical transfer offset in buffer */
|
|
} audio_offset_t;
|
|
.Ed
|
|
.It Dv AUDIO_GETINFO (audio_info_t)
|
|
.It Dv AUDIO_SETINFO (audio_info_t)
|
|
Get or set audio information as encoded in the 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 buffersize; /* total size of audio buffer */
|
|
/* BSD extensions */
|
|
u_int blocksize; /* H/W read/write block size */
|
|
u_int hiwat; /* output high water mark */
|
|
u_int lowat; /* output low water mark */
|
|
u_int backlog; /* samples of output backlog to gen. */
|
|
u_int mode; /* current device mode */
|
|
#define AUMODE_PLAY 0x01
|
|
#define AUMODE_RECORD 0x02
|
|
#define AUMODE_PLAY_ALL 0x04 /* do not do real-time correction */
|
|
};
|
|
.Ed
|
|
.Pp
|
|
When setting the current state with
|
|
.Dv AUDIO_SETINFO ,
|
|
the audio_info structure should first be initialized with
|
|
.Li Dv AUDIO_INITINFO Po &info Pc
|
|
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 should be set to
|
|
.Dv AUMODE_PLAY ,
|
|
.Dv AUMODE_RECORD ,
|
|
.Dv AUMODE_PLAY_ALL ,
|
|
or a bitwise OR combination of the three.
|
|
Only full-duplex audio devices support
|
|
simultaneous record and playback.
|
|
.Pp
|
|
.Va hiwat
|
|
and
|
|
.Va lowat
|
|
are used to control write behavior. Writes to the audio devices will
|
|
queue up blocks until the high-water mark is reached, at which point any
|
|
more write calls will block until the queue is drained to the low-water
|
|
mark.
|
|
.Va hiwat
|
|
and
|
|
.Va lowat
|
|
set those high- and low-water marks (in audio blocks).
|
|
.Pp
|
|
.Va buffersize
|
|
is the total size of the audio buffer. The buffer size divided
|
|
by the
|
|
.Va blocksize
|
|
gives the maximum value for
|
|
.Va hiwat .
|
|
Currently the
|
|
.Va blocksize
|
|
can only be read and not set.
|
|
.Pp
|
|
.Va blocksize
|
|
sets the current audio blocksize. The generic audio driver layer and
|
|
the hardware driver have the opportunity to adjust this block size to
|
|
get it within implementation-required limits. Upon return from an
|
|
.Dv AUDIO_SETINFO
|
|
call, the actual blocksize set is returned in this field.
|
|
Normally the
|
|
.Va blocksize
|
|
is calculated to correspond to 50ms of sound and it is recalculated
|
|
when the encoding parameter changes, but if the
|
|
.Va blocksize
|
|
is set explicitely this value becomes sticky, i.e., it is remains
|
|
even when the encoding is changed. The stickyness can be cleared
|
|
by reopening the device or setting the
|
|
.Va blocksize
|
|
to 0.
|
|
.Pp
|
|
.Va backlog
|
|
is currently unused.
|
|
.Bd -literal
|
|
struct audio_prinfo {
|
|
u_int sample_rate; /* sample rate in samples/s */
|
|
u_int channels; /* number of channels, usually 1 or 2 */
|
|
u_int precision; /* number of bits/sample */
|
|
u_int encoding; /* data encoding (AUDIO_ENCODING_* above) */
|
|
u_int gain; /* volume level */
|
|
u_int port; /* selected I/O port */
|
|
u_long seek; /* BSD extension */
|
|
u_int ispare[3];
|
|
/* Current state of device: */
|
|
u_int samples; /* number of samples */
|
|
u_int eof; /* End Of File (zero-size writes) counter */
|
|
u_char pause; /* non-zero if paused, zero to resume */
|
|
u_char error; /* non-zero if underflow/overflow ocurred */
|
|
u_char waiting; /* non-zero if another process hangs in open */
|
|
u_char cspare[3];
|
|
u_char open; /* non-zero if currently open */
|
|
u_char active; /* non-zero if I/O is currently active */
|
|
};
|
|
.Ed
|
|
.Pp
|
|
Note: many hardware audio drivers require identical playback and
|
|
recording sample rates, sample encodings, and channel counts. The
|
|
playing information is always set last and will prevail on such hardware.
|
|
If the hardware can handle different settings the
|
|
.It Dv AUDIO_PROP_INDEPENDENT
|
|
property is set.
|
|
.Pp
|
|
The encoding parameter can have the following values:
|
|
.Bl -tag -width indent -compact
|
|
.It Dv AUDIO_ENCODING_ULAW
|
|
mulaw encoding, 8 bits/sample
|
|
.It Dv AUDIO_ENCODING_ALAW
|
|
alaw encoding, 8 bits/sample
|
|
.It Dv AUDIO_ENCODING_SLINEAR
|
|
two's complement signed linear encoding with the platform byte order
|
|
.It Dv AUDIO_ENCODING_ULINEAR
|
|
unsigned linear encoding with the platform byte order
|
|
.It Dv AUDIO_ENCODING_ADPCM
|
|
ADPCM 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 little big byte order
|
|
.El
|
|
.Pp
|
|
The gain and port settings provide simple shortcuts to the richer mixer
|
|
interface described below. The gain should be in the range
|
|
.Bq Dv AUDIO_MIN_GAIN , Dv AUDIO_MAX_GAIN .
|
|
The port value is hardware-dependent
|
|
and should be selected (if setting with
|
|
.Dv AUDIO_SETINFO )
|
|
based upon return values from the mixer query functions below or from
|
|
a prior
|
|
.Dv AUDIO_GETINFO .
|
|
.Pp
|
|
The
|
|
.Va seek
|
|
and
|
|
.Va samples
|
|
fields are only used for
|
|
.Dv AUDIO_GETINFO .
|
|
.Va seek
|
|
represents the count of
|
|
samples pending;
|
|
.Va samples
|
|
represents the total number of bytes recorded or played, less those
|
|
that were dropped due to inadequate consumption/production rates.
|
|
.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.
|
|
.El
|
|
.Sh MIXER DEVICE
|
|
The mixer device,
|
|
.Pa /dev/mixer ,
|
|
may be manipulated with
|
|
.Xr ioctl 2
|
|
but does not support
|
|
.Xr read 2
|
|
or
|
|
.Xr write 2 .
|
|
It supports the following
|
|
.Xr ioctl 2
|
|
commands:
|
|
.Bl -tag -width indent -compact
|
|
.It Dv AUDIO_GETDEV (audio_device_t)
|
|
This command is the same as described above for the sampling devices.
|
|
.It Dv AUDIO_MIXER_READ (mixer_ctrl_t)
|
|
.It Dv AUDIO_MIXER_WRITE (mixer_ctrl_t)
|
|
.Bd -literal
|
|
#define AUDIO_MIXER_CLASS 0
|
|
#define AUDIO_MIXER_ENUM 1
|
|
#define AUDIO_MIXER_SET 2
|
|
#define AUDIO_MIXER_VALUE 3
|
|
typedef struct mixer_ctrl {
|
|
int dev; /* input: nth device */
|
|
int type;
|
|
union {
|
|
int ord; /* enum */
|
|
int mask; /* set */
|
|
mixer_level_t value; /* value */
|
|
} un;
|
|
} mixer_ctrl_t;
|
|
.Ed
|
|
These commands read the current mixer state or set new mixer state for
|
|
the specified device
|
|
.Va dev .
|
|
.Va type
|
|
identifies which type of value is supplied in the mixer_ctrl_t
|
|
argument.
|
|
For a mixer value, the
|
|
.Va value
|
|
field specifies both the number of channels and the values for each of
|
|
the channels. If the channel count does not match the current channel
|
|
count, the attempt to change the setting may fail (depending on the
|
|
hardware device driver implementation).
|
|
For an enumeration value, the
|
|
.Va ord
|
|
field should be set to one of the possible values as returned by a prior
|
|
.Dv AUDIO_MIXER_DEVINFO
|
|
command. The type
|
|
.Dv AUDIO_MIXER_CLASS
|
|
is only used for classifying particular mixer device
|
|
types and is not used for
|
|
.Dv AUDIO_MIXER_READ
|
|
or
|
|
.Dv AUDIO_MIXER_WRITE .
|
|
.It Dv AUDIO_MIXER_DEVINFO (mixer_devinfo_t)
|
|
This command is used iteratively to fetch audio mixer device information
|
|
into the input/output mixer_devinfo_t argument. To query all the
|
|
supported encodings, start with an index field of zero and continue with
|
|
successive encodings (1, 2, ...) until the command returns an error.
|
|
.Bd -literal
|
|
typedef struct mixer_devinfo {
|
|
int index; /* input: nth mixer device */
|
|
audio_mixer_name_t label;
|
|
int type;
|
|
int mixer_class;
|
|
int next, prev;
|
|
#define AUDIO_MIXER_LAST -1
|
|
union {
|
|
struct audio_mixer_enum {
|
|
int num_mem;
|
|
struct {
|
|
audio_mixer_name_t label;
|
|
int ord;
|
|
} member[32];
|
|
} e;
|
|
struct audio_mixer_set {
|
|
int num_mem;
|
|
struct {
|
|
audio_mixer_name_t label;
|
|
int mask;
|
|
} member[32];
|
|
} s;
|
|
struct audio_mixer_value {
|
|
audio_mixer_name_t units;
|
|
int num_channels;
|
|
} v;
|
|
} un;
|
|
} mixer_devinfo_t;
|
|
.Ed
|
|
The
|
|
.Va label
|
|
field identifies the name of this particular mixer control. The
|
|
.Va index
|
|
field may be used as the
|
|
.Va dev
|
|
field in
|
|
.Dv AUDIO_MIXER_READ
|
|
and
|
|
.Dv AUDIO_MIXER_WRITE
|
|
commands. The
|
|
.Va type
|
|
field identifies the type of this mixer control.
|
|
Enumeration types are typically used for on/off style controls (e.g. a
|
|
mute control) or for input/output device selection (e.g. select
|
|
recording input source from CD, line in, or microphone).
|
|
.Pp
|
|
The
|
|
.Va mixer_class
|
|
field identifies what class of control this is. This value is set to
|
|
the index value used to query the class itself. For example, a mixer
|
|
level controlling the input gain on the ``line in'' circuit would be a
|
|
class that matches an input class device with the name ``Inputs''
|
|
(AudioCInputs).
|
|
Mixer controls which control audio circuitry for a particular audio
|
|
source (e.g. line-in, CD in, DAC output) are collected under the input class,
|
|
while those which control all audio sources (e.g. master volume,
|
|
equalization controls) are under the output class.
|
|
.Pp
|
|
The
|
|
.Va next
|
|
and
|
|
.Va prev
|
|
may be used by the hardware device driver to provide hints for the next
|
|
and previous devices in a related set (for example, the line in level
|
|
control would have the line in mute as its "next" value). If there is
|
|
no relevant next or previous value,
|
|
.Dv AUDIO_MIXER_LAST
|
|
is specified.
|
|
.Pp
|
|
For
|
|
.Dv AUDIO_MIXER_ENUM
|
|
mixer control types,
|
|
the enumeration values and their corresponding names are filled in. For
|
|
example, a mute control would return appropriate values paired with
|
|
AudioNon and AudioNoff.
|
|
For
|
|
.Dv AUDIO_MIXER_VALUE
|
|
mixer control types, the channel count is
|
|
returned; the units name specifies what the level controls (typical
|
|
values are AudioNvolume, AudioNtreble, AudioNbass).
|
|
.\" For AUDIO_MIXER_SET mixer control types, what is what?
|
|
.El
|
|
.Pp
|
|
By convention, all the mixer device indices for generic
|
|
class grouping are at the end of the index number space for a particular
|
|
hardware device, and can be distinguished from other mixer controls
|
|
because they use a name from one of the AudioC* string values.
|
|
.Sh FILES
|
|
.Bl -tag -width /dev/audio -compact
|
|
.It Pa /dev/audio
|
|
.It Pa /dev/sound
|
|
.It Pa /dev/mixer
|
|
.El
|
|
.Sh SEE ALSO
|
|
.Xr ioctl 2 .
|
|
.br
|
|
For ports using the ISA bus:
|
|
.Xr gus 4 ,
|
|
.Xr guspnp 4 ,
|
|
.Xr pas 4 ,
|
|
.Xr pss 4 ,
|
|
.Xr sb 4 ,
|
|
.Xr wss 4 .
|
|
.Sh BUGS
|
|
The device class conventions are just a wish and not yet reality.
|
|
.Pp
|
|
If the device is used in
|
|
.Xr mmap 2
|
|
it is currently always mapped for writing (playing) due to
|
|
VM system weirdness.
|
|
.Pp
|