Open Sound System |
Do you have problems with sound/audio application development? Don't panic! Click here for help! |
int frag = (max_fragments << 16) | (size_selector);
ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &frag);
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.
Please see the Audio timing considerations section for more information about audio timing.
The argument value consists of two 16 bit fields 0xNNNNSSSS
(in hexadecimal). The upper part (NNNN
) is the maximum number of fragments to be allocated. It can be between 2 and 0x7fff (unlimited). The actual number of fragments may be less than requested if there is not enough memory available.
The lower part (SSSS
) selects the fragment size. Please see the following table for the possible values. The fragment size cannot be larger than half of the available buffer space.
selector | bytes |
4 | 16 |
5 | 32 |
6 | 64 |
7 | 128 |
8 | 256 |
9 | 512 |
10 | 1024 |
11 | 2048 |
12 | 4096 |
13 | 8192 |
14 | 16384 |
15 | 32768 |
16 | 65536 |
N | 1<<N |
It's important to understand that this call just sets the size hint. There is no guarantee that the requested size gets used. For example some devices always use fixed buffer size and there is no way to affect this.
It's very important to make this ioctl call as early as possible after opening the device since otherwise the call may not have any effect. In particular this call must be made before calling read, write or some other ioctl calls. It is not possible to use this call second time without closing and re-opening the device first.
This ioctl call will return an error only if the argument value is incorrect or if the call is made in a wrong place. Even if the call returned OK there is no guarantee that the requested buffer size will be used. This ioctl call sets just the size hint and the driver may or may not honor the request.
There is no need to limit the number of fragments when doing recording so OSS will always use as many fragments as possibe in recording direction. This prevents uncontrolled buffer overruns. The application can very easily discard too old samples simply by discarding the oldest ones. It just need to monitor the buffer usage with SNDCTL_DSP_GETISPACE and read all samples from the buffer.
Note that "minimal latencies" means something that is necessary only in special applications such as scientific tools and music production systems. Most applications like games and media players don't need anything more than the "stock" features provided by OSS. Using special techniques to reduce latencies may cause unwanted side effects that actually make the application less usable.
The method for getting minimal latencies in audio applications is to set the fragment size and number of fragments to a small enough values. However below certain level the latencies caused by the operating system will strike back. To push the latencies to the millisecond range may require use of special operating system specific features which are beyond the scope of this document.
OSS will prevent applications from using too short fragment sizes. To use very short fragments the max_intrate parameter must be changed in the configuration of the osscore module (in osscore.conf). By default the audio (fragment) interrupt rate is limited to 100 which means that the minimum fragment size is 1s/100=10ms or larger. It is probably necessary to set max_intrate to zero in systems that are used for applications requiring very low latencies. However higher interrupt rate will mean more system overhead which often decreases the overall performance of the system.
Use of virtual mixer will cause few milliseconds of additional latencies because of additional buffering. For this reason applications that require extremely low latencies should bypass vmix by opening the audio device with O_EXCL flag. However use of this flag will prevent the application from running if any other application is using the device. Also when an O_EXCL application is running it will be impossible for other applications to play critical anouncements using the same device.
Another OSS4 feature that causes slightly longer latencies are the automatic sample rate and format conversions. Applications doing timing critical processing should disable the conversions by using SNDCTL_DSP_COOKEDMODE. The drawback is that the application itself must be written to handle the sample rate/format used by the device. This will be rather different since future audio devices may use formats that were not known when the application was written.
The SNDCTL_DSP_POLICY ioctl is an easier to use version of this call. It permits selecting lower or higher latency modes without need to set the exact fragment size and count values. In most cases selecting just the policy will give better results because the driver can select the best buffer sizes depending on the device features.
If this call returns an error it means simply that the application is using it at a wrong moment or in otherwise wrong way.
Please look at the When OSS audio ioctl calls can be made section for information about DSP ioctl call ordering.
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.
fulldup.c | Full duplex sample program using the single device approach. |
mmap_duplex.c | A simple sample program for doing dull duplex using mmap |
morse3.c | Yet another morse code program that uses select |
morse2.c | Another morse code program that uses select |
seltest2.c | This program has been used to verify that the select() call works |
iosync.c | Measuring the hardware level latencies. |
ioctl_test.c | This program has been used to verify that some of the ioctl calls work |
softsynth_gtk.c | A simple software MIDI synthesizer program with GTK GUI. |
softsynth.c | A simple software MIDI synthesizer program. |