On Mon, 7 Nov 2005 09:52:35 +0100 Molle Bestefich molle.bestefich@gmail.com wrote:
Great explanation, thanks!!! Greatly appreciated by me and I'm sure a lot others.
Good :-)
I'm missing a point from your explanation here: Why do you even need the hardware play position? It seems that the ALSA folks went to some length to hide it from you..
In short, you need it to know how much data in the buffer the hardware has already read, and therefore, up to which point in the buffer it is safe to overwrite.
Because some sounds are longer than the buffer (including continuous sound which is actually composed of multiple seperate sounds), you need to load the buffer full of data for the first part of the sound, then wait until that portion has played, and then store the next part of the sound in the buffer.
In practice the buffer is divided into several periods, let's say 10 for example. Also, we might not fill the whole buffer before we tell the hardware to start playing the sound (to reduce latency, among other reasons). So say we fill the buffer with 4 periods worth of sound data. In general the software mixer likes to stay a specific number of periods in front of the hardware (4 in this case). It doesn't want to get too far ahead (mainly because sounds are often dynamic and if you store too much into the buffer, you might need to cancel or alter it later which consumes processing capacity). Neither does it want to get little ahead, or the hardware might overtake the software (buffer underrun).
So, after the first period has been played, we want to fill in the next period (number 5 in the buffer) with data, and also to clear the period that has just played. Then when the next period (#2) plays we fill in another one (#6), and so one. We only know what periods have played be checking the hardware pointer.
Alsa tries to abstract this away somewhat. The good thing about the way Alsa does it is that the interface is (at least in theory) consistent regardless of whether you are using the hardware directly or you using Alsa's plug layer (or other virtual device). The problem is that at the moment, Wine's direct sound implementation (and Alsa driver) do not support the buffer locking interface for the primary buffer (the Alsa buffer, which may or may not also be the mapped hardware buffer).
The locking interface provides a mechanism for direct sound to signal to the driver which parts of the buffer it has changed. This would allow committing only as much as was actually ready. Alsa also provides a "rewind" function for cases where changes occur to the buffer between the current hardware and application pointers.
Davin