SunOS man pages : mixer (7)
Ioctl Requests mixer(7I)
NAME
mixer - audio mixer audio personality module interface
SYNOPSIS
#include <sys/mixer.h>
OVERVIEW
The audio mixer extends the audio(7I) interface, allowing
more then one process to play or record audio at the same
time. Understanding the audio(7I) interface thoroughly is a
prerequisite to understanding the mixer(7I) interface.
Backward Compatibility
It is possible to disable the mixing function and return to
100% backward compatibility with the audio(7I) interface.
These two modes of operation are referred to as the mixer
mode and the compatible mode. This is done by using either
the mixerctl(1) or sdtaudiocontrol(1) applications, or by
editing the audio driver.conf file and then unloading and
reloading the driver.
Multi-Stream Codecs
The audio mixer supports multi-stream Codecs. Examples of
these Codecs are the Crystal Semiconductor 4410/4422 and the
Aureal 8820/8830. These devices have DSP engines that pro-
vide sample rate conversion and other features. Each
play/record channel is mapped to an individual channel
straight into the Codec. The audio mixer does not perform
sample rate or encoding conversion. (See below). However,
the programming interfaces remain the same and applications
cannot distinguish between multi-stream Codec and tradi-
tional Codec.
Buffer Size
An application can use the audio_info_t structure to set the
size of the play/record buffers. As with the audio(7i)
interface, the audio mixer does not support changing of the
play buffer. (The audio driver takes sound samples as they
are needed, regardless of how many are delivered with each
write.)
The audio mixer does support changing of the record buffer.
When captured by the audio driver, buffer size bytes are
sent to the application to read.
AUDIO FORMATS
See the audio(7I) manual page for a brief discussion of
audio formats. To mix the various audio streams, the audio
mixer must convert all audio formats to a common format. The
following describes how the audio mixer deals with these
different components.
SunOS 5.8 Last change: 26 January 2000 1
Ioctl Requests mixer(7I)
Sample Rate
When /dev/audio is opened, the initial sample rate
is 8KHz, as defined in audio(7I).
In mixer mode, the audio mixer
always configures the Codec for the highest possible sample
rate for both play and record. This ensures that none of the
audio streams require compute-intensive low pass filtering.
The result is that high sample rate audio streams are not
degraded by filtering.
Sample rate conversion can be a compute-intensive operation,
depending on the number of channels and a device's sample
rate. For example, an 8KHz signal can be easily converted to
48KHz, requiring a low cost up sampling by 6. However, con-
verting from 44.1KHz to 48KHz is compute intensive because
it must be up sampled by 160 and then down sampled by 147.
(This is only done using integer multipliers.)
Applications can greatly reduce the impact of sample rate
conversion by carefully picking the sample rate. Applica-
tions should always use the highest sample rate the device
supports. An application can also do its own sample rate
conversion (to take advantage of floating point and
accelerated instruction) or use small integers for up and
down sampling.
In compatible mode, the audio mixer
programs the Codec to the sample rate set by the applica-
tion to avoid incurring any sample rate conversion overhead.
If the Codec cannot support different play and record sample
rates, the AUDIO_SETINFO ioctl(2) will fail.
Encodings and Precision
When /dev/audio is opened, initial encoding and precision is
8-bit u-Law (as in the Greek letter mu) . (As defined in
audio(7I.))
In mixer mode, the audio mixer supports formats in the fol-
lowing precisions:
SunOS 5.8 Last change: 26 January 2000 2
Ioctl Requests mixer(7I)
_______________________________________________________________
| Encoding | Precision | Channels |
| Signed Linear PCM | 16-bit | Mono or Stereo |
| Signed Linear PCM | 8-bit | Mono or Stereo |
| u-Law | 8-bit | Mono or Stereo |
| A-Law | 8-bit | Mono or Stereo |
|____________________|____________________|____________________|
The audio mixer converts all audio streams to 16-bit Linear
PCM before mixing. After mixing, conversion is made to the
best possible Codec format. The conversion process is not
compute intensive and audio applications can choose the
encoding format the best meets its needs.
In compatibility mode, the audio mixer sets the Codec to the
encoding and precision set by the application. If the Codec
cannot support different play and record encodings or preci-
sions, the AUDIO_SETINFO ioctl(2) will fail.
Channels
When /dev/audio is opened, the number of initial channels
is 1, left channel mono. (As defined in audio(7I)). Most
Codecs play or record mono audio on the left channel.
In mixer mode, the audio mixer sets the Codec to the maximum
number of channels supported. If a mono signal is played or
recorded, it is mixed on the first (usually the left) chan-
nel only. Silence is mixed on the remaining channels.
In compatible mode, the audio mixer sets the Codec to the
number of channels set by the application. If the Codec can-
not support a different number of play and record channels,
the AUDIO_SETINFO ioctl(2) will fail.
DESCRIPTION
The device /dev/audio is a device driver that dispatches
audio requests to the appropriate underlying audio personal-
ity module. The audio driver is implemented as a STREAMS
driver. To record audio input, applications open(2) the
/dev/audio device and read data from it using the read(2)
system call. Similarly, sound data is queued to the audio
output port by using the write(2) system call. Device confi-
guration is performed using the ioctl(2) interface.
Opening the Audio Device
In mixer mode, the the audio device is no longer treated as
an exclusive resource. Each process may open the audio dev-
ice once unless the process has made an
AUDIO_MIXER_MULTIPLE_OPEN ioctl(2). See below for details.
SunOS 5.8 Last change: 26 January 2000 3
Ioctl Requests mixer(7I)
Each open() will complete as long as there are channels
available to be allocated. If no channels are available to
be allocated:
o if either the O_NDELAY or O_NONBLOCK flags are set in
the open() oflag argument, -1 is immediately
returned, with errno set to EBUSY.
o if neither the O_NDELAY nor the O_NONBLOCK flags are
set, then open() hangs until a channel becomes avail-
able or a signal is delivered to the process. In this
case, a -1 is returned with errno set to EINTR.
Upon the initial open() of the audio channel, the audio
mixer sets the data format of the audio channel to the
default state of 8-bit, 8Khz, mono u-Law data. If the audio
device does not support this configuration, it informs the
audio mixer of the initial configuration. Audio applications
should explicitly set the encoding characteristics to match
the audio data requirements, and not depend on the default
configuration. See the audio(7I) manual page for details on
how the audio mixer behaves when in
compatible mode.
Recording Audio Data
The read(2) system call copies data from the system buffers
to the application. Ordinarily, read() blocks until the user
buffer is filled. The I_NREAD ioctl (see streamio(7I)) may
be used to determine the amount of data that may be read
without blocking. The device may also be set to a non-
blocking mode, where read() completes immediately but may
return fewer bytes than requested. See the read(2) manual
page for a complete description of this behavior.
When the audio device is opened with read access, the device
driver immediately starts buffering audio input data.
Because this consumes system resources, processes that do
not record audio data should open the device write-only
(O_WRONLY).
The transfer of input data to STREAMS buffers may be paused
(or resumed) by using the AUDIO_SETINFO ioctl to set (or
clear) the record.pause flag in the audio_info_t information
structure. (See audio(7)). All unread input data in the
STREAMS queue may be discarded by using the I_FLUSH STREAMS
ioctl (see streamio(7I)). When changing record parameters,
the input stream should first be paused and flushed before
the change. Otherwise, subsequent reads may return samples
in the old format, followed by samples in the new format.
Input data accumulates in STREAMS buffers rapidly. For 8-
bit, 8 KHz, mono u-Law data, it accumulates at 8000 bytes
SunOS 5.8 Last change: 26 January 2000 4
Ioctl Requests mixer(7I)
per second . If a device is configured for 16-bit linear or
higher sample rates, it accumulates even faster. If the
application that consumes the data is unable to meet the
input data rate, the STREAMS queue may become full. When
this happens, the record.error flag is set in the
audio_info_t information structure and input sampling ceases
until there is room for additional data, resulting in a data
stream discontinuity. To prevent this, audio recording
applications should open the audio device when they are
ready to begin reading data and not at the start of exten-
sive initialization.
Playing Audio Data
The write(2) system call copies data from an application's
buffer to the STREAMS output queue. Ordinarily, write()
blocks until the entire user buffer is transferred. The dev-
ice may alternatively be set to a non-blocking mode, in
which case write() completes immediately, but may transfer
fewer bytes than requested. (See the write(2) manual page
for a complete description of this behavior).
Although write() returns when the data is successfully
queued, the actual completion of audio output may take con-
siderably longer. The AUDIO_DRAIN ioctl may be issued to
allow an application to block until all of the queued output
data has been played. Alternatively, a process may request
asynchronous notification of output completion by writing a
zero-length buffer (end-of-file record) to the output
stream. When such a buffer has been processed, the play.eof
flag in the audio_info_t information structure (see below)
is incremented.
The final close(2) of the audio device file descriptor hangs
until all of the process' remaining audio output has
drained. If a signal interrupts the close(), or if the pro-
cess exits without closing the audio device, any remaining
data queued for audio output is flushed and the audio device
is closed immediately.
The conversion of output data may be paused (or resumed) by
using the AUDIO_SETINFO ioctl to set (or clear) the
play.pause flag in the audio_info_t structure. Queued out-
put data may be discarded by using the I_FLUSH STREAMS
ioctl. (See streamio(7I).)
Output data will be played from the STREAMS buffers at a
default rate of 8000 bytes per second for u-Law, A-Law, or
8-bit PCM dat. (And at a faster rate for 16-bit linear data
or higher sampling rates). If the output queue becomes
empty, the play.error flag is set in the audio_info_t
structure and output is stopped until additional data is
queued. If an application attempts to write a number of
SunOS 5.8 Last change: 26 January 2000 5
Ioctl Requests mixer(7I)
bytes that is not a multiple of the current sample frame
size, an error will be generated and the bad data will be
thrown away. Additional writes are allowed.
Asynchronous I/O
The I_SETSIG STREAMS ioctl (see streamio(7I)) enables asyn-
chronous notification through the SIGPOLL signal of input
and output ready conditions. The O_NONBLOCK flag may be set
using the F_SETFL fcntl(2) to enable non-blocking read() and
write() requests. This is normally sufficient for applica-
tions to maintain a background audio stream.
Audio Control Pseudo-Device
The /dev/audioctl pseudo-device enables an application to
modify characteristics of the audio device while it is being
used by an unrelated process. Any number of processes may
open /dev/audioctl pseudo device simultaneously. However,
read() and write() system calls are ignored.
Note: The audio control device name is constructed by
appending the letters "ctl" to the path name of the audio
device.
Audio Status Change Notification
Applications that open the audio control pseudo-device may
request asynchronous notification of changes in the state of
the audio device by setting the S_MSG flag in an I_SETSIG
STREAMS ioctl. (See streamio(7I)). Such processes receive a
SIGPOLL signal when any of the following events occur:
o AUDIO_SETINFO, AUDIO_MIXERCTL_SETINFO,
AUDIO_MIXERCTL_SET_CHINFO, or AUDIO_MIXERCTL_SET_MODE
ioctl () has altered the device state.
o Iinput overflow or output underflow has occurred.
o End-of-file record (zero-length buffer) has been pro-
cessed on output.
o open() or close() of /dev/audio has altered the dev-
ice state.
o External event (such as speakerbox volume control) has
altered the device state.
IOCTLS
The audio mixer implements all the ioctl()s defined in
audio(7I) and uses the audio_prinfo_t, audio_info_t, and
audio_device_t structures. See the audio(7I) manual page for
details on these ioctl()s and structures. The audio mixer
also uses the data structures described below.
SunOS 5.8 Last change: 26 January 2000 6
Ioctl Requests mixer(7I)
Audio Mixer Control Structure
The state of the audio device may be polled or modified
using the AUDIO_MIXERCTL_GETINFO and AUDIO_MIXERCTL_SETINFO
ioctl commands.
typedef struct am_control {
audio_info_t dev_info; / *the audio device's state */
int8_t ch_open[1]; / *variable sized array of open chs */
} am_control_t;
See CODE EXAMPLES for sample code on how to use this struc-
ture and the related
macroAUDIO_MIXER_CTL_STRUCT_SIZE(num_ch).
Audio Mixer Sample Rates Structure
The following structure is used by the
AUDIO_MIXER_GET_SAMPLE_RATES ioctl to get a list of all the
supported sample rates.
typedef struct am_sample_rates {
uint_t type; /* play or capture */
uint_t flags;
uint_t num_samp_rates; /* number of elements in samp_rates[] */
uint_t samp_rates[1]; /*variable sized array of sample rates */
} am_sample_rates_t;
#define AUDIO_PLAY 0 /*type */
#define AUDIO_RECORD 1
#define MIXER_SR_LIMITS 0x00000001 /* flags */
See CODE EXAMPLES for example code on how to use this
structure and the related
macroAUDIO_MIXER_SAMP_RATES_STRUCT_SIZE(num_srs).
Audio Info Structure
When in mixer mode the audio_info_t structure's
sw_features_enabled field will have AM_MIXER set. When in
compatibility mode, the AM_MIXER bit will be cleared.
The defines for the sw_features and the sw_features_enabled
fields are:
#define AM_MIXER 0x00000001 /* mixer is present/enabled */
Streamio IOCTLS
All of the streamio(7I) ioctl commands may be issued for the
/dev/audio and /dev/audioctl devices. I_SETSIG ioctl may be
issued for /dev/audioctl to enable the notification of audio
status changes as described above.
SunOS 5.8 Last change: 26 January 2000 7
Ioctl Requests mixer(7I)
Audio Mixer IOCTLS
Except for AUDIO_MIXER_GET_SAMPLE_RATE,
AUDIO_MIXERCTL_GET_MODE, and AUDIO_MIXERCTL_SET_MODE, these
ioctl()s are valid only in mixer mode. Using them in compa-
tible mode will cause an EINVAL error to be returned.
AUDIO_MIXER_MULTIPLE_OPEN
The argument is ignored. This command allows an indi-
vidual process to open /dev/audio more then once for
play or record. This feature is useful for mixing
panels that may be controlling multiple audio streams.
AUDIO_MIXER_SINGLE_OPEN
The argument is ignored. This command returns
/dev/audio back to an exclusive access device on per
process basis after an AUDIO_MIXER_MULTIPLE_OPEN
ioctl() has been executed. This ioctl() will fail if
more than one play or record stream is open.
AUDIO_MIXER_GET_SAMPLE_RATES
The argument is a pointer to an am_sample_rates_t
structure. This command gets a list of supported sam-
ple rates for either play or record for the audio
mixer's current mode. It is legal for the supported
sample rates to be different for mixer mode vs compa-
tible mode. The type field must be set to either
AUDIO_PLAY or AUDIO_RECORD to get a list of either
play or record sample rates, respectively. Setting
both or neither is an error. The num_samp_rates field
is set to the number of sample rates that the
samp_rates[] array may hold. When the ioctl returns,
num_samp_rates will be set either to the number of
sample rates in the array samp_rates[], or the total
number of sample rates available if there are more
then the array can hold. In the former case, there are
num_samp_rates valid sample rates in the array. In the
later case, all the elements of the array have valid
sample rates, but there are more available. The size
of the array should be increased to get all available
sample rates. If the flags field has MIXER_SR_LIMITS
flag set, the return sample rates are the lowest and
the highest rates possible, with all sample rates in-
between being legal. Some Codecs that have DSP engines
on them have this capability.
AUDIO_MIXERCTL_GETINFO
The argument is a pointer to an am_control_t struc-
ture. This command gets device and channel state
information. The dev_info field contains the state of
the hardware device. It provides a convenient way to
determine the hardware's state. The ch_open array is
used to specify which channels are open and which are
SunOS 5.8 Last change: 26 January 2000 8
Ioctl Requests mixer(7I)
closed. Open channels are non-zero, closed channels
are set to zero, (where the channel number corresponds
to the array index). The number of elements in the
ch_open array may change over time and a macro is pro-
vided to allocate the correct amount of space. The
MACROS section below provides more information.
AUDIO_MIXERCTL_SETINFO
The argument is a pointer to an am_control_t struc-
ture. This command sets the device state but cannot
modify any channel's state. The dev_info field is used
to set the device state. However, there are several
limitations. Only the gain, balance, port and pause
for play and record and monitor_gain and output_muted
fields may be modified. (Modifying other fields would
interfere with how the audio mixer programs the audio
device.) The ch_open array is not used when setting
the audio device and may be set to a size of one.
AUDIO_MIXERCTL_GET_CHINFO
The argument is a pointer to an audio_channel_t struc-
ture. This command gets a channel's state information.
To enable the audio mixer to determine
channel information, set the ch_number field before
making the ioctl() call. The info_size field must be
set to the size of the audio_info_t structure. The
*info field must point to an audio_info_t structure.
When the ioctl() returns, the pid field should be
checked. If it is set to 0, the remaining data in the
audio_channel_t structure is invalid because the chan-
nel has not been allocated. The dev_type field
describes the type of channel; the *info pointer
points to a buffer where the audio_info_t structure
for the audio channel is populated.
AUDIO_MIXERCTL_SET_CHINFO
The argument is a pointer to an audio_channel_t struc-
ture. This command sets a channel's state information.
To enable the audio mixer to determine which channel
to set, set the ch_number field before making the
ioctl() call. The info_size field must be set to the
size of the audio_info_t structure. The *info field
must point to an audio_info_t structure. When the
ioctl() returns, the pid will contain the process ID
of the process that has the channel open and dev_type
will contain the type of the device. If pid is 0
(zero), then the channel is not open. The *info
pointer points to an audio_info_t structure which is
used to program the state of the channel.
AUDIO_MIXERCTL_GET_MODE
The argument is a pointer to an integer that contains
SunOS 5.8 Last change: 26 January 2000 9
Ioctl Requests mixer(7I)
the audio mixer mode when it returns. It will be set
to either AM_MIXER_MODE for mixer mode or
AM_COMPAT_MODE for compatibility mode.
AUDIO_MIXERCTL_SET_MODE
The argument is a pointer to an integer that contains
the audio mixer mode to be set. It must be set to
either AM_MIXER_MODE or AM_COMPAT_MODE. The audio
mixer may be set to mixer mode at any time, but can
only be set to compatible mode when there is a single
read/write open within one process, or a single read
process and a single write process. Otherwise the
ioctl() will fail. Because the Codec is being repro-
grammed to a different data format, there may be brief
pause or burst of noise when the mode changes. This
can be eliminated by pausing the input and output or
by closing all streams before changing modes. The mixerctl(1)
command may be used to change the audio
mixer's mode.
MACROS
The following macro is used to determine how large an
am_control_t structure is when it points to an audio_info_t
structure.
AUDIO_MIXER_CTL_STRUCT_SIZE(num_ch)
Where num_ch is the number of channels the device supports.
The number of channels can be determined using the
AUDIO_GET_NUM_CHS ioctl().
This macro is used when allocating an am_sample_rates_t
structure.
AUDIO_MIXER_SAMP_RATES_STRUCT_SIZE(num_srs)
Where num_srs is the number of samples rates requested.
CODE EXAMPLES
The following examples illustrate how these new data struc-
tures and ioctls can be used.
Example 1
The following code demonstrates how to use the audio support
and the audio mixer ioctl()s to get state information on
/dev/audio.
audio_channel_t ch;
audio_info_t info;
am_control_t *ctl;
int num;
err = ioctl(audio_fd, AUDIO_GET_NUM_CHS, &num);
SunOS 5.8 Last change: 26 January 2000 10
Ioctl Requests mixer(7I)
ctl = (am_control_t *)malloc(AUDIO_MIXER_CTL_STRUCT_SIZE(num));
err = ioctl(audio_fd, AUDIO_MIXERCTL_GETINFO, ctl);
ch.info = &info;
ch.info_size = sizeof (audio_info_t);
for (i = 0; i < num; i++) {
if (ctl->ch_open[i] != 0) {
ch.ch_number = i;
if (ioctl(audio_fd, AUDIO_MIXERCTL_GET_CHINFO, &ch) < 0) {
printf("Channel #%d isn't an audio/audioctl device", i);
} else {
printf("Ch# %d, PID = %d, Type = %d0, i, ch.pid, ch.dev_type);
}
}
}
Example 2
The following code demonstrates how to use the
AUDIO_MIXER_GET_SAMPLE_RATES ioctl to get the number of sup-
ported play sample rates. It also shows how to deal with
allocating a samp_rates[] array that is too small.
#define LARGE_NUMBER 10000;
am_sample_rates_t *sr;
int num;
for (num = 4; num < LARGE_NUMBER; num += 2) {
sr = (am_sample_rates_t *)malloc(AUDIO_MIXER_SAMP_RATES_STRUCT_SIZE(num));
sr->num_samp_rates = num;
sr->type = AUDIO_PLAY;
err = ioctl(audio_fd, AUDIO_MIXER_GET_SAMPLE_RATES, sr);
if (sr->num_samp_rates <= num) {
break;
}
free(sr);
}
(void) printf("Supported play sample rates:0);
for (i = 0; i < sr->num_samp_rates; i++) {
(void) printf(" %d0, sr->samp_rates[i]);
}
ERRORS
An open() will fail if:
EBUSY The requested play or record access is busy and either
SunOS 5.8 Last change: 26 January 2000 11
Ioctl Requests mixer(7I)
the O_NDELAY or O_NONBLOCK flag was set in the open()
request.
ENOMEM
Memory was not available to be allocated for the chan-
nel.
EINTR The requested play or record access is busy and a sig-
nal interrupted the open() request.
EIO There has been an error opening the device. An error
message is printed on the console explaining the
failure.
An ioctl() will fail if:
EBUSY The parameter changes requested in the AUDIO_SETINFO
ioctl could not be made because another process has
the device open and is using a different format.
EINTR The ioctl() was interrupted by a signal.
EINVAL
The parameter changes requested in the AUDIO_SETINFO
ioctl are invalid or are not supported by the device.
EIO There has been an error with the ioctl(). An error
message is printed on the console explaining the
failure.
ENOMEM
The ioctl() failed because memory couldn't be allo-
cated.
EPERM The audio mixer is in compatible mode and one of the
new ioctl()s was used. They are supported only in
mixer mode.
FILES
The physical audio device names are system dependent and are
rarely
used by programmers. The programmer should use the generic
device names listed below.
/dev/audio
symbolic link to the system's primary audio device
/dev/audioctl
symbolic link to the control device for /dev/audio
/dev/sound/0
first audio device in the system
SunOS 5.8 Last change: 26 January 2000 12
Ioctl Requests mixer(7I)
/dev/sound/0ctl
audio control device for /dev/sound/0
/dev/sound/x
additional audio devices
/dev/sound/xctl
audio control device for /dev/sound/x
ATTRIBUTES
See attributes(5) for a description of the following attri-
butes:
_____________________________________________________________
| ATTRIBUTE TYPE | ATTRIBUTE VALUE |
| Architecture | SPARC |
| Availability | SUNWaudd, SUNWauddx, SUNWaudh|
| Stability Level | Evolving |
|_____________________________|______________________________|
SEE ALSO
mixerctl(1), close(2), fcntl(2), ioctl(2), open(2), poll(2),
read(2), write(2), system(4), audiocs(7D), usb_ac(7D),
audio_support(7I), streamio(7I)
BUGS
Due to a feature of the STREAMS implementation, programs
that are terminated or exit without closing the audio device
may hang for a short period while audio output drains. In
general, programs that produce audio output should catch the
SIGINT signal and flush the output stream before exiting.
SunOS 5.8 Last change: 26 January 2000 13
|
 |
|
|