Open Sound System |
Do you have problems with sound/audio application development? Don't panic! Click here for help! |
audio_buf_info bi;
ioctl(fd, SNDCTL_DSP_GETOSPACE, &bi);
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.
This ioctl call is out of fashion. Development of OSS has made it unnecessary in new applications. There is no need to avoid blocking in normal applications.
This ioctl call can be used to check how many bytes can be written to the device without blocking. See the Audio timing considerations section for more info about audio timing and syncronization.
Another purpose is to get the "optimal" fragment size to be used by the application. Please see the discussion about fragment sizes below.
It's very important to understand that this call is not designed to be used for syncronizing the screen content (video/visualizations/game) with audio. Other ioctl calls such as SNDCTL_DSP_GETODELAY or SNDCTL_DSP_GETOPTR are better suited for this purpose.
The audio_buf_info
field contains the following fields:
bytes
returns the number of bytes that can be written without blocking. fragments
(obsolete) returns the number of full fragments that can be written without blocking. fragsize
is the current fragment size in playback direction. fragstotal
is the number of buffer fragments allocated for playback. There is a big danger related with this ioctl call. Some applications wait until there is enough space before writing large block of data (several kilobytes). It is possible that under some OSS implementations this criteria is never met because the buffer allocated for the device is smaller than the the application expects. The result is that the application works under some OSS implementations but doesn't write anything under the others. The maximum amount of data the application can ever write is (fragments-1)*fragsize
bytes.
It's normally not desirable to avoid blocking. Using blocking writes and reads is the most optimal way of doing syncronization. Non-blocking operation is significantly more difficult to use and in many case just consumes more resources. In particular non-blocking operation must not be used if it results in a wait loop before read/write.
This ioctl must in no case be called before the device setup is finished.
Many applications check the actual fragment size being used by the device and partition the audio data to blocks of this size. This practice comes from very early Linux sound driver versions which cannot handle partitioning the data to fragments properly. With current OSS versions this is very rarely necessary. However there are few cases (see below) where using fragment size reads/writes may improve performance. In most cases applications may use any read/write size they like.
The concept of fragment size is rather problematic with current OSS versions that support sample rate and formatconversions. Because of this the real fragment size is not always an integer value. This means that the fragment size may sometimes be one less or one higher than the reported value.
Due to the sample rate conversions the fragment size seen by the application is not the same than the actual fragment size used by the device. For example if the application uses 44100 Hz smapling rate and the device is limited to 48000 Hz the ratio between these rates is 1.08843537415 or 0.91875 depending on the direction (read or write). For this reason the fragment sizes reported by SNDCTL_DSP_GETOSPACE and SNDCTL_DSP_GETISPACE will not match. For this reason the SNDCTL_DSP_GETBLKSIZE call will return the fragment size that is used by the device in the hardware level. The result is that in some cases there will be three different fragment sizes which makes it very difficult to the application to know which one to use. Fortunately most applications can use whatever fragment size (read/write count) they like with no performance problems.
There are few special applications that depend on very precise timing. In such cases it's recommended that the application disables all format and sample rate conversions by calling SNDCTL_DSP_COOKEDMODE after opening the device. In the "raw" mode OSS devices will behave in fully predictable manner. However the drawback is that the application itself needs to perform the format and rate conversions if necessary.
Possible sample rate and/or sample format conversions being made by the driver will affect the values returned by this call. In such case some of the fields may seem to be inconsistent with the information returned by some ofter calls. This is not an error but may break applications that use this call for purposes it's not designed for.
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.
mmap_test.c | A sample program for using mmap() |
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 |