Sun SPARCstation audio observations

Generic Information

Gain settings

The recording gain rounds to the following values: 0 2 8 14 20 26 32 38 44 50 56 62 68 74 80 85 91 97 103 109 115 121 127 133 139 145 151 157 163 169 174 180 186 192 198 204 210 216 222 228 234 240 246 252 255

For some systems (SS20/Solaris, others?), the recording gains are: 15 31 47 63 79 95 111 127 143 159 175 191 207 223 239 255

Sensitivity

input sensitivity

For the microphone input with full gain (100), it takes a sine input with 2.5 mVrms to create a 0 dB digital output. For line input, it takes 168 mV. The gain-to-sensitivity curve is exactly logarithmic. Note that the microphone input sensitivity is not high enough for dynamic microphones and barely enough for standard condenser microphones a few inches away from the speaker's mouth.

Library functions

audio_u2s() translates mu-law into the range -32124 to 32124 (full 16 bits) rather than the actual 13-bit range.

The BSD (Berkeley) audio driver written by Van Jacobson does not have a control device. Thus, if we can't open the control device, we just use the regular audio device. If the control device is unavailable, the audio settings are stored until the audio device is opened and then set.

Control functionality

The sample_rate, channels, precision, and encoding fields are treated as read-only for /dev/audioctl, so that applications can be guaranteed that the existing audio format will stay in place until they relinquish the audio device. AUDIO_SETINFO will return EINVAL when the desired configuration is not possible, or EBUSY when another process has control of the audio device.

Once set, the following values persist through subsequent open() and close() calls of the device: play.gain, record.gain, play.balance, record.balance, output_muted, monitor_gain, play.port, and record.port. All other state is reset when the corresponding I/O stream of /dev/audio is closed.

SIGPOLL handling is slow and may lead to overflow cycles feeding on themselves; thus, we disable the SIGPOLL handling if 'track' is zero. Also, when there is a device error (over/underflow), we do not update the application state. The latter has the unfortunate consequence that once an error has occured, outside changes are no longer tracked. The ability to reset the error indicator is needed.

The .error flag needs to be explicitly reset with AUDIO_SETINFO.

Wiring

The microphone jack provides 5 V DC to both channels (tip and sleeve).

System-specific information

SPARC ELC, SLC with non-multicast 4.1.3

These systems will not read from the audio device if it is opened with O_RDWR. Thus, we need to maintain two separate file descriptors, one for reading and another for writing.

SPARCstation 5 with Solaris 2.3

The SPARCstation 5 has to open the audio device O_RDWR, otherwise setting values will yield an EINVAL error. For the first 400,000 samples (for PCMU), reading seems to happen in spurts of about 8192 bytes, but then the system 'catches itself' and continues normally. This is visible in a rather sluggish VU meter display.

SPARCstation 10 or higher with Solaris 2.x (SunOS 5.x) or SunOS 4.1.3

Precision=16 only works with AUDIO_ENCODING_LINEAR; otherwise precision=8 remains unchanged.

The following combinations of encodings, sampling rates and precision are possible:
encoding sample_rate precision channels
ALAW/ULAW 8000 8 1
LINEAR any 16 1 or 2
Play and record format must be the same. They cannot be changed (error EBUSY) if play and record are on separate file descriptors. Thus, we need to use a single descriptor.

sun/audioio.h is replaced by sys/audioio.h, which also needs <sys/types.h>. Use multimedia/audio_device.h instead. (Under /usr/demo/SOUND/include or /usr/demo/SOUND.)

The AUDIO_GETDEV return value differs: instead of an int, it is a structure of text fields.

Solaris 2.x

The audio_prinfo_t structure contains a new field buffer_size.

On Solaris, signal() has the property "the system first sets the signal's disposition to SIG_DFL before executing the signal handler" (signal(2)). In other words, SVR4 implementes old-style unreliable signals. This causes a small race condition, in that additional SIGPOLLs are not caught and trigger SIG_DFL (which for SIGPOLL is exit(), with the error message "Stream I/O possible"). Thus, we use sigaction() with the appropriate flags. See also Stevens, Advanced Programming in the UNIX Environment, p. 298.

#ifdef AUDIO_DIAG_LOOPBACK can be used to test for advanced features like 'buffer_size' and 'balance' fields.