SOUND(4) — UNIX Programmer’s Manual
NAME
sound − audio output device
DESCRIPTION
The device /dev/sound gives access to the sound output hardware. The hardware has a variable sampling rate and two separate audio output ports, allowing for stereo sound via an external socket, or monaural sound from the built-in loudspeaker. The number of channels of sound sample data can be varied over 1, 2, 4 or 8 and each channel is independently positionable to one of 7 different stereo positions (full left through full right). The hardware functionality is controllable by means of ioctl(2) commands on a open file descriptor for the device.
Sound output
Sound output is achieved using the write(2) system call to send sound data samples as a stream of bytes to the device. For hardware-related reasons, all write calls should specify a number of bytes which is a multiple of 16, otherwise the error EINVAL will be returned and no data output. In the present implementation of the system, the sound device driver uses a number of 4096-byte buffers to store the data to be output, and hence for maximum efficiency writes to the device should normally be of this size or an integer multiple of it (the block size returned by a stat(2) or fstat(2) call for the device is 4096).
The device may be operated in blocking or non-blocking mode: in blocking mode (the default), any attempt to write data will wait until all user data has been transferred to the driver’s buffers. In non-blocking mode, only as much data as can be accepted at the time will be transferred and the return value from the write call will indicate how much data was moved. If there is no room at all in the buffers, the error EWOULDBLOCK (or EAGAIN, they have the same value) will be returned. Non-blocking mode is selected either by using the O_NONBLOCK flag to the initial call of open(2), or by setting this flag on the file descriptor using the fcntl(2) call once the device has been opened.
Sample Format
Individual sound samples are presented to the device as 8-bit quantities in a signed, pseudo-logarithmic format shown below (bit 0 is the least significant bit, bit 7 the most significant):
bits 7..5- chord number
bits 4..1- position on chord
bit 0- sign (0: positive, 1: negative)
where a chord is a linear segment in which each successive position has a value a fixed step up from the previous one, and the step size in one chord is twice that in the previous chord. The input value 0 produces 0 on output; the step in chord 0 is 1, in chord 7 it is 128. Thus the range of input values 0..127 (viewing bits 7..1 of the sample as a single 7-bit binary number) will produce output values (as audio signal amplitudes) in the range 0..3952.
Sound system structure
The output sample rate (i.e. the rate at which individual byte samples are converted to analogue audio output values) is controllable in terms of the interval between samples, expressed in microseconds, where the available range is from 6 microseconds to 255 microseconds. For a simple single-channel configuration, this is the equivalent of a sample frequency range from 166.7 kHz down to 3.921 kHz.
In order to provide multi-channel operation, the hardware uses time-division multiplexing to break up the sequence of byte samples in the output stream into blocks of 8. Each of the 8 samples in a block has associated with it a register (numbered from 0 to 7) to control the positioning of that sample within the stereo stage; the register takes one out of seven different values representing from far left to far right. The data being fed to the hardware is viewable as representing 1, 2, 4 or 8 separate channels of sound, as follows. For single channel use, all 8 stereo position registers are set to the same value, and the output byte stream sample rate is the same as the effective channel sample rate. For two channels, the data in the output stream comprises pairs of bytes, one for each channel; all odd numbered stereo position registers are set to the desired position for the first channel, and all even numbered channel position registers are set to the desired position for the second channel (which might be the same as for the first channel). The output byte stream sample rate must then be set to twice the individual channel sample rate, e.g. for two channels of data, each sampled at 10kHz, the output sample rate is 20kHz. For four channels, stereo position registers 0 and 4 are set to the desired position for the first channel, registers 1 and 5 to that for the second channel, etc, and the output rate is 4 times the individual channel sample rate. Similarly for 8 channels, each individual stereo position register controls its corresponding channel position, and the output sample rate is 8 times the individual channel sample rate.
It is the responsibility of the program controlling the sound device to set up the 8 stereo position registers and the output sample rate as required for the application. The default setting of the device parameters is for single-channel mode, 20kHz output sample rate.
Parameter control
The parameters of the sound output system may be examined and modified by means of two ioctl commands, SNDIOCGETPARAMS and SNDIOCSETPARAMS, applied to a file descriptor for the sound device. These commands, the structure they operate on, and various other useful macros are given in the header file <dev/sndioctl.h>. The structure is defined as:
typedef struct snd_params
{
unsigned int period;/∗ output inter-sample time in usec ∗/
unsigned char image_pos[SND_MAX_CHANS];
} SNDParams, ∗SNDParamsRef;
A simplified example of use (no error checking, etc) is:
SNDParams sparams;
int fd, i;
fd = open ("/dev/sound", O_WRONLY);
ioctl (fd, SNDIOCGETPARAMS, &sparams);
printf ("Original sample period: %d0, sparams.period);
/∗
∗ Set up for two channel use, full-spread stereo, at
∗ 16.67 kHz sample rate. This implies an output sample
∗ rate of 33.33kHz, i.e. a period of 30 microseconds.
∗/
sparams.period = 30;
/∗ Position alternate channels to full left, full right.
for (i = 0; i < SND_MAX_CHANS; ++i)
sparams.image_pos[i] =
((i % 2) == 0) ? SND_LEFT_100 : SND_RIGHT_100;
/∗ Now set parameters into the device ∗/
ioctl (fd, SNDIOCSETPARAMS, &sparams);
/∗ Then start sending output data... ∗/
Loudspeaker control
In addition to controlling the hardware parameters, two further ioctl commands to the sound device allow the built-in loudspeaker to be enabled or disabled, and its state examined:
int state;
ioctl (fd, SNDIOCGETSPKR, &state);
writes into state the value 1 if the speaker is enabled, and 0 if it is not. Correspondingly,
int state;
..
ioctl (fd, SNDIOCGETSPKR, &state);
will turn the speaker off if state has the value 0 and on otherwise.
NOTES
Sound data samples may be either computed dynamically or derived from existing data, but in either case the program must arrange to provide data to the device at a rate in accordance with the output sample rate in use. If data is not supplied fast enough, audibly unpleasant effects can occur as the sample stream is interrupted by periods of silence.
FILES
/dev/sound
SEE ALSO
console(4), ioctl(2)
VIDC data sheet
4th Berkeley Distribution — Revision 1.2 of 10/08/90