Open Sound System
OSS 4.x Programmer's Guide

Do you have problems with sound/audio application development? Don't panic! Click here for help!


Return information about an audio device


oss_audioinfo ai; = The audio device number.
ioctl(fd, SNDCTL_AUDIOINFO, &ai);
ioctl(fd, SNDCTL_AUDIOINFO_EX, &ai);
ioctl(fd, SNDCTL_ENGINEINFO, &ai);

The above code fragment lacks all error checks for clarity. Real world applications must always check for the errors and handle them as described below. Also most OSS ioctl calls will return information in the argument variable and it's usually necessary to check it too.


These ioctl calls are supported by all OSS devices, including audio, mixer and MIDI devices. The device for which the information is returned is selected by the dev field of the argument. If dev is set to -1 then information for the current audio device pointed by the file descriptor (fd) will be returned. However the dev=-1 method works only with SNDCTL_ENGINEINFO because open file descriptors are bound directly to specific audio engines.

Applications must be very carefull when using these ioctl calls to see what is possible with the device and what is not. These calls will return information directly from the low level driver. Even the device itself doesn't support certain feature it's probaly supported by the upper levels of the audio core.

For example most sound cards support only mono and stereo (min_channels=1 and max_channels=2). It might seem to be a good idea to prevent the application from playing multichannel audio (say 5.1) with such devices. However this is not necessarily what the user wants. Future OSS versions will contain an 3D expander that makes it possible to play 5.1 channel audio streams with good results. If the application just tries to set the 6 channel mode using SNDCTL_DSP_CHANNELS it will work correctly both with the current and the future versions of OSS.

Audio engines and device files

OSS 4.0 has new audio device model. Instead of the earlier flat audio device numbering there are now two levels of audio devices. The higher level object is audio device file. Each audio device file has a visible device node in the /dev directory (actually there are two of them). Each audio device file has one or more audio engines. Audio device files that have multiple engines can be shared by multiple applications because each application (instance) will be directed to a different audio engine. In some cases these audio engines are real hardware level devices (hardware mixing). However in most cases these engines are software level virtual devices (virtual mixing).

Under some operating systems (older versions of FreeBSD at this moment) there is no difference between audio engines and device files. Since the operating system doesn't support device redirection OSS will create a device file for each audio engine. So both SNDCTL_AUDIOINFO and SNDCTL_ENGINEINFO will return the same information.

Audio device files

Audio device files are objects that applications can access directly by opening a device file located in /dev. The SNDCTL_AUDIOINFO ioctl call can be used to get information about the audio device files. Number of audio devices available in the system is returned by SNDCTL_SYSINFO in the numaudios field.

The device file entry returned by SNDCTL_AUDIOINFO contains information about the primary audio engine of this device. Each device file may have additional engines that are ordered in two chains. The next_play_engine field contains the engine number (see below) of the next playback engine and the next_rec_engine field in turn returns the next recording engine. If the engine numbers returned in these fields are the same then the additional engines are duplex engines and both chains will be identical (engine number 0 means that there are no addtional engines).

When an application opens an audio device files the engine that will actually be used depends on the device type. With devices that support hardware mixing the first application opening the device file will get the primary engine. Subsequent applications will get the next free engine from the play or record engine chain. However with devices using virtual mixing the primary engine will be used by the virtual mixer drivers and applications will be given the next free engine from the chain.

When an audio device file is opened normally it's likely that the application will get connected to one of the virtual mixer engines instead of the actual physical audio device itself. The virtual devices may have different capabilities than the actual physical device. For this reason SNDCTL_AUDIOINFO will return device capabilities that match the virtual engines.

Applications that use O_EXCL to open the physical device directly must use SNDCTL_AUDIOINFO_EX to check the device capabilities. This variation of SNDCTL_AUDIOINFO will report only the capabilities of the physical device itself. See the The open() system call section for more info.

Audio engines

Audio engines are the second level in the audio device hierarchy. The SNDCTL_ENGINEINFO ioctl call can be used to obtain information about the engines. The numaudioengines field returned by SNDCTL_SYSINFO will return the total number of audio engines currently in the system.

Applications cannot select the audio engine directly. Instead OSS will select the engine when the application opens some audio device file. For this reason some fields will return information about the parent device file object.

Information returned by these ioctl calls

The oss_audioinfo structure contains the following fields.

It's very important to realize that the device numbering may change every time when OSS is restarted.

dev The audio device number. Must be set prior the call (see above). Note that this field is just an arbitrary number between 0 and SNDCTL_SYSINFO.numaudios-1. It no longer matches the /dev/dsp# device number. For best results all applications written for OSS 4.0 and later should use the devnode field to find out which device to open.
name A string that contains the "full" description of the device.
busy Se to 0 if the device is not open by any applications. Other alternatives are OSS_OPEN_READ, OSS_OPEN_WRITE or OSS_OPEN_READWRITE.
pid The PID number of the process that is currently using this device. Value of -1 means that this information is not available or the device is currently not open. Just few operating systems support this field. See the cmd field.
caps Capabilities of the device. See the Audio device capabilities section for more info.
iformats Bitmask for the natively supported recording formats.
oformats Bitmask for the natively supported playback formats.
magic Reserved for internal use by OSS.
cmd The command (program) name of the process using this device or empty string if no command name is available. Only supported under Linux at this moment.
card_number Number of the sound card where this device belongs or -1 if this information is not available. Applications should normally not use this field for any purpose.
song_name Name of the current song this device is playing. Empty string means no song name is assigned. See the Application assigned metadata section for more info.
label Label attached to this device. Empty string means no label is assigned. See the Application assigned metadata section for more info.
port_number This field tells the port/device number within the device (card_number).
mixer_dev The mixer device number of the mixer that is related with this audio device or -1 if no mixer is available.
legacy_device *OBSOLETE* Use the devnode field instead. This field is the /dev/dsp# "legacy" device number. The device number for given device may change without notice. Applications that store the device numbers in their configuration files are likely to cause serious privacy problems when device numbers change. New applications written for OSS 4.0 or later should use the devnode field to find out which device file to open. Value of -1 means that this device doesn't have any legacy /dev/dsp# device (this alternative is used with certain special purpose devices).
devnode The device special file name associated with this audio device. Note that this field has been added to the oss_audioinfo structure recently and it will be empty with earlier OSS versions. In that case applications should use the legacy_device field as the /dev/dsp# number for this device.
enabled Usually 1. However it will be set to 0 if the device is (temporarily) unavailable. This may happen for example if an USB device is "hot" unplugged from the system.
flags Reserved for future use.
min_rate Minimum sampling rate supported by the device (see below).
max_rate Maximum sampling rate supported by the device (see below).
nrates Number of sampling rates supported by the device (see below).
rates Array containing the list of supported sampling rates (see below).
min_channels Minimum number of channels (see below).
max_channels Maximum number of channels (see below).
binding Reserved for future use.
rate_source Number of the sample rate group this device belongs to (see below). -1 means that the rate source is not known.
handle A short identifier (string) that uniquely identifies the physical hardware device/port. The device number (dev as well as the card_number fields may change if a new audio device is installed in the system. This field is designed to have the same value even after that (provided that the device is not moved to some other PCI slot or USB port. This is just an arbitrary character string that the applications should not try to interpret. The only permitted use is comparing against some previously stored handle in application's configuration files.
next_play_engine Next playback engine in the chain (0 means none).
next_rec_engine Next record engine in the chain (0 means none).

Recording and playback formats

OSS is designed to support any common sample formats by doing automatic conversions in the driver level. For this reason applications don't normally need to check which formats are supported in hardware level. Checking this is only necessary in rare special cases when no kind of conversions are allowed. Sample format conversions don't cause any quality loss so there is no need to be worried about.

Some devices support different formats during recording and playback. The iformats and oformats fields give the formats for both directions. If the device is opened with O_RDWR then the intersection of these two sets (iformats and oformats) gives the formats that are possible in this situation.

This also explains why some devices support more sample formats when opened with O_WRONLY than with O_RDWR.

Sampling rates

Normal applications don't need to know what sampling rates are really supported. OSS will do automatic sample rate conversions in driver level if they are necessay. There are just few special cases where checking this is necessary.

There are two kind of devices. Some of them support all sampling rates withing the min_rate to max_rate range. It's possible to identify such devices by checking if the PCM_CAP_FREERATE capability is reported in the caps field.

The remaining devices support one or few sampling rates. To find it out the application should look at the rates/nrates array. It's also necessary to check that the rates are within the min_rate to max_rate range (some of the rates given in the rates array may be outside this range in some situations.

Elements of the rates array are not necessarily sorted. Applications must not assume that they are in ascending or descending order.

Number of channels

Normal applications don't need to check how many channels the device really supports. OSS will do the necesary up and down sampling operations automatically in the driver level. All the application needs to do is trying to change the number of channels to the required value (using SNDCTL_DSP_CHANNELS) and the check how many channels were actually allocated. Please see the Using multiple channels with OSS section for more info.

The min_channels and max_channels fields define the limits for the number of channels. However some devices don't support all channels within this range. It's possible that the odd values (3, 5, 7, 9, etc). are not supported. There is currently no way to check for this other checking if SNDCTL_DSP_CHANNELS accepts the requested value. Another approach is trying to avoid using odd number of channels.

What does the rate source mean?

Most sound cards have several independednt audio recording and playback engines that are driven by a common crystal oscillator. Such engines are guaranteed to run excatly at the same rate (provided that they are programmed to the same sampling rate.

However in general audio engines that belong to different souncards will use slightly different sampling rates even the nominal rate is the same. This means that after few seconds or minutes the devices will be out of sync. In some applications such as digital audio workstations (DAW) this will cause serious problems in keeping the tracks in sync.

The rate_source field returned by this ioctl call can be used to find out if the devices are likely to be able to work in sync. If rate sources of two devices have the same value then this is guaranteed. However even the rate sources are different then it's still possible that the devices are synchronized to the same external clock signal (such as word clock or digital S/PDIF signal). So applications should accept devices with different rate sources. However it may be a good idea to show a warning about this.

Value of -1 in the rate_source field means that the OSS implementation or the driver doesn't support rate source management.

Logical and physical device numbers

Earlier the audio device numbering scheme used by OSS was completely flat. All devices are directly accessible and the dev and the legacy_device fields are set to the same value.

Starting from OSS 4.0 the dev and legacy_device fields are just arbitrary numbers that may change randomly when OSS configuration is changed. New applications should use the device special file name given in the devnode field to find out which device file to open.

To find the engine(s) for a given /dev/dsp# device you need to search the whole list of devices and pick the ones with the right value in the legacy_device field. The only difference between the engines is that some of them are in use while some others are free.

Related ioctl calls

You can use the SNDCTL_SYSINFO ioctl to find out how many audio devices there are in the system.

OSS ioctl return values

The return value from the OSS ioctl calls will be -1 if a fatal error occurred. Other values mean that the ioctl call was more or less successful. However in most cases the application must check the value returned in the argument to see what was the accepted value.

Please see the Possible error codes (errno) returned by OSS calls section for more info about the error codes returned by OSS.

Sample programs

osstest.cThe osstest program shipped with OSS
ossinfo.cThe ossinfo program that is included in the OSS package.
ossxmix.cThis is the ossxmix (GTK++ GUI) program shipped with OSS
ossmix.cSources for the ossmix command line mixer shipped with OSS
ossplay.cSources for the ossplay audio player and for the ossrecord
fulldup.cFull duplex sample program using the single device approach.
mmap_test.cA sample program for using mmap()

Copyright (C) 4Front Technologies, 2007. All rights reserved.
Back to index OSS web site