AUDIO(4) — DEVICES AND NETWORK INTERFACES
NAME
audio − telephone quality audio device
CONFIG
device-driver audio
AVAILABILITY
SPARCstation 1 systems only.
DESCRIPTION
The audio device is a SPARCstation 1 specific device that implements telephone quality sound using the AM79C30 Digital Subscriber Controller chip. The chip uses a sampling rate of 8192 samples per second, with each sample being 8-bits. The chip has a built-in analog to digital converter (ADC) and digital to analog converter (DAC). The chip uses either u-law or A-law compression, and will drive either the built-in speaker or an external headphone jack.
The simplest way to record and play sound is to use the read(2V) and write(2V) system calls. By default, u-law encoding is used, output goes to the internal speaker, and the chip’s registers are set to reasonable values. However, by setting the chip’s registers and using other ioctl(2) requests, the user has more control over the device.
The device starts converting sound to digital form when:
• read() is called, or
• the AUDIOREADSTART ioctl is issued.
The signal is converted and stored in an internal buffer. Conversion stops:
• the AUDIOSTOP, AUDIOPAUSE, or AUDIOSETQSIZE ioctl is issued, or
• write() is called, or
• the device is closed, or
• the internal buffer fills up.
The device starts converting samples to sound when the write() system call is issued. Conversion stops when:
• the AUDIOSTOP, AUDIOPAUSE, or AUDIOSETQSIZE ioctl is issued, or
• the device is closed, or
• the internal buffer is exhausted.
Several processes can have the device open at one time. This is useful if you wish to have separate processes for reading and writing. It is possible (but probably not useful) to have several processes reading or writing at the same time. The driver randomly selects one of the outstanding requests when the current request is finished. Thus, if two processes call write() at the same time, one of them will be selected at random and run to completion before the other one starts. Data from the two write() calls will not be interspersed.
The AUDIOREADSTART, AUDIOPAUSE, AUDIORESUME, and AUDIOSTOP ioctl calls have the same form:
ioctl(fd,cmd,value)
intfd
intcmd;
intvalue;
AUDIOSTARTREAD makes the device start recording without calling read(). AUDIOPAUSE stops both read() and write() calls, but does not empty the buffers. You can pause at any time, regardless of whether there are any outstanding read() or write() calls. AUDIORESUME resumes I/O after a pause. AUDIOSTOP stops the currently active read() or write() call. Only the current operations are stopped — queued I/O calls are not affected.
The driver uses separate buffers internally for reads and writes. The four ioctl() requests that are useful for manipulating the buffers all have the same form:
ioctl(fd,cmd,ptr);
intfd;
intcmd;
int∗ptr;
The AUDIOGETQSIZE ioctl returns the size of the buffers (currently the read and write buffers have the same length). The AUDIOSETQSIZE ioctl sets the size of the buffers. The buffer length must be a power of two between AUDIO_MIN_RING_SIZE (1024) and AUDIO_MAX_RING_SIZE (1048576), inclusive. Changing the length stops any audio i/o that is currently active and destroys the contents of the buffers. The amount of data currently currently available to a read() can be determined with the AUDIOREADQ ioctl, and the amount that has been written but not converted can be determine with the AUDIOWRITEQ ioctl. Note: these ioctl() requests can be used to keep adequate amounts of data in the buffers. An application can look at the amount of data in the queue and decide whether it can take the time to do something before it services the device. The application can also increase the size of the buffer to reduce the frequency at which the device must be serviced.
Sound may be produced by opening the device and writing data using the write() system call. Similarly, sound may be recorded by using the read() system call. In the simplest case, the contents of a file can be directed to /dev/audio.
The device has a number of registers that may be used to alter the behavior of the chip. For example, you can vary the gain of the chip’s amplifiers and switch the output between the built-in speaker and external jack. All access to the chip’s registers is through two ioctl() calls which have the form:
#include <sun/audioio.h>
structaudio_ioctl {
shortcontrol;
unsigned char data[46];
};
ioctl(fd,cmd,ptr)
intfd;
intcmd;
structaudio_ioctl∗ptr;
The control member specifies the register and the number of bytes to be read or written, while the data member contains the data to be read or written. The defined macros AUDIO_PACK, AUDIO_UNPACK_REG, and AUDIO_UNPACK_LENGTH can be used to assemble and disassemble the control values. AUDIOGETREQ reads the register and AUDIOSETREQ writes to it. The AM79C30 data sheet describes the values used for each register.
The chip’s registers are reset to their default values when the device is not being used. If several processes open the device at the same time, the registers will be reset when all of the processes close the device. For example, if you set the volume in one process, all other processes will use the same volume setting. When the final process closes the device, the registers will be reinitialized.
The chip has a number of special purpose functions designed for telephone applications. For example, it can generate ringer, DTMF (touch-tone), and single frequency tones. It also has a number of specialized filtering capabilities that are designed primarily to compensate for different types of external speakers and microphones. All of these capabilities can be accessed through ioctl() calls. However, there is no external access to the ISDN capabilities of the chip.
A-law and u-law are two forms of encoding which compress a signal with a wide dynamic range into one with a smaller range. This produces a more consistent signal to noise ratio (s/n) for signals of different amplitudes, at the expense of a lower maximum s/n.
ERRORS
An open() will fail if:
ENODEV A non-zero minor device is opened
EBUSY The device is already opened.
ENOMEM There is no memory to use for the driver’s buffer.
An ioctl() will fail if:
EINVAL An invalid cmd is used, or an invalid length for the buffer is specified.
ENOMEM The request to allocate a new buffer can not be honored.
EFAULT arg points outside the allocated address space.
FILES
/usr/include/sun/audioio.h
/usr/include/sbusdev/audioreg.h
/usr/include/sbusdev/audiovar.h
/dev/audio
SEE ALSO
ioctl(2), read(2V), open(2V), write(2V)
AMD data sheet for the AM79C30A Digital Subscriber Controller, Publication number 09893.
BUGS
The interface to this device is preliminary and subject to change in future releases. You are encouraged to write your programs in a modular fashion so that you can easily incorporate future changes.
Sun Release 4.0 — Last change: 20 April 1989