Open Sound System |
Do you have problems with sound/audio application development? Don't panic! Click here for help! |
OSS is designed to take care of all timing automatically. There is actually not much need to care about timing. Unfortunately many programmers like to use more or less "advanced" methods to improve timing which usually just causes troubles.
OSS uses driver level buffering which makes it possible to the application to continue it's operation at the same time when audio recording and/or playback is being performed by the device. The application needs to write new data to the device before the previously content of the buffer has been completely played (underrun). During recording the application needs to read data from the device buffer before it becomes full (overrurn). If the application calls read/write at the moment there is not enough space in the buffer the write call will automatically wait until the device has played/or recorded some more data. This automatic waiting is called "blocking".
To save processor time the device and the application/driver don't communicate with each other all the time. Instead the device will handle the audio data in fixed size blocks that are called "fragments". OSS will select the length of the fragment automatically but the application has some control on that.
The fragment size has been a key audio parameter in some of the earliest OSS versions. However OSS 4.0 no longer uses fragments for anything important so there is no need any more to write applications so that they care about the fragment sizes.
The fragment size determines the general responsiveness of the application. If the fragment size is lowered then the application will respond quicker to events like keyboard input. However this will increase the CPU overhead caused by the device because the number of hardware interrupts/second increases. Please see the buffering policies subsection (below) for more info.
As mentioned above the "blocking" mechanism of the read and write system calls is an automatic way to keep the application in sync with audio. If the buffering policy is selected properly the blocking doesn't cause any feel of unresponsiveness.
There are some rare special cases where this blocking is must be avoided. An example of this is an application that needs to respond to some input events within few milliseconds. For this kind of purposes the application can use the select system call and some of the ioctl calls such as SNDCTL_DSP_GETOSPACE and SNDCTL_DSP_GETISPACE.
Obtaining low latencies is for some reason the number one design goal for most novice audio programmers. They use all possible documented and undocumented methods to push the latencies to as close to zero as possible. The result is application that works just in computers dedicated for the application and with all possible low latency patches installed in the operating system.
What does "low latency" actually mean? An urban legent is that all delays must be few milliseconds or less for low latencies. Is this the truth?
The answer is yes and no. Low latency usually means that audio output doesn't lag behind the input or some other parallel events so much that anybody notices it. There are some situations when even a delay of one sample causes phase errors that are audible. However this is just a rare special case.
For example games and (DVD) video players are applications that most programmer believe requiring low latencies. However in reality the requirement is that the latencies are low enough to maintain "lip sync". In movie industry the frame rate is 24 fps which means that the latencies must be 1/24th of second or maybe bit less. This is about 30 to 40 milliseconds. At 48 kHz it equals to about 2000 samples which in turn matches fragment size of 8k (assuming 16 bit stereo format). We at 4Front Technologies don't call this as low latencies but just normal latencies. Practically nothing special is needed for this. The application doesn't need to use any special programming tricks such as mmap.
The latencies are largely determined by the amount of buffer memory allocated for the device. The application can control this by changing the buffering policy (see below). However after certain (system dependent) limit the audio signal will start to break and the result may be just terrible noise. What happened? Is this a bug in OSS? The answer is no. One purpose of the driver level buffering mechanism is that smoothens the timing randomness typical to multitasking general purpose operating systems. The application doing audio is not the only process that needs CPU time. The other concurrent programs will prevent the audio application from running immediately when the device needs attention. When the buffer size is decreased the tolerance against this randomness also decreases. After certain limit everything just bresks. This is no way a feature or bug of OSS (or any other audio driver implemntation). It's characteristic of the underlaying operating system and hardware environment. It is possible to improbe things by stopping unnecessary programs in the system and by using highest possible priorities. The operating system/version and it's configuration parameters affect too. Sometimes even the sound card capabilities may prevent using extremely low buffer sizes.
To get extremely low latencies you will have to use special hardware and specially designed operating systems. This is the reason why professionally designed audio/music/effect units use dedicated DSP and microcontroller based designs instead of cheap PC hardware and sound cards bought from a corner shop.
There are two alternative ways for changing the buffering policy. The traditional way has been setting the fragment/buffer size directly using SNDCTL_DSP_SETFRAGMENT. However this method is very difficult to use properly. For this reason OSS 4.0 has a new ioctl call SNDCTL_DSP_POLICY. With it the application simply tells what kind of buffering policy it needs. The OSS software will then automatically fine tune the bufering to match the application needs.
Please take a look at the Some common types of audio programs section which contains sample programs for some typical audio programming problems.