In lesson #10 we looked into how buffer can be queed on a source. Now we take that technique a step further and stream a large sound file through it. For that we use a technique called double buffering.
First we need to set up the buffers and sources properly:
As you see i specified i want to generate 2 buffers. For this to work buffers need to be specified as an array[0..1] of TALUint .
Now both buffers must be filled and placed in the que for an source:
alSourceQueueBuffers(Source, 2, @Buffers);
In this case the Stream function fills an buffer with a part of an mp3 file decoded. This funtions looks like this:
mpg123_read(Fhandle, data, BufferSize, @d);
alBufferData(Buffer, Format, data, BufferSize, FRate);
Now if we play this we only the 2 buffers are played and nothing. So with a regurar interval the source and its buffers need to be checked and updated. For this example everything is written as an TThread descendant but you can also use a timer if you want.
That goes like this:
alGetSourcei(Source, AL_BUFFERS_PROCESSED, @Processed);
if Processed > 0 then
alSourceUnqueueBuffers(source, 1, @Buffer);
alSourceQueueBuffers(source, 1, @Buffer);
until Processed <= 0;
With alGetSource together with AL_BUFFERS_PROCESSED we can check what buffers i currently playing on the source. If the first buffer is playing there is nothing to do. However if the second buffer is playing it is time to update the first buffer.
Before we can update the buffer it needs to be detached from the source. So the source is left with one buffer that is currently playing. Now we can fill the detached buffer with data from the mp3. Next we attach it again to the source. Now it has become the second buffer on the source. And the buffer stil playing has become the first. buffer. So when the previous second buffers and now first buffer finished our freshly filled buffer continous playing and we are ready to start all over.
And that is all there is to it. With this technique we can stream mp3, ogg, and even use bass or fmod.