Processing Queue

OpenAL does not specify a builtin streaming mechanism. There are no mechanism to stream data e.g. into a Buffer object. Instead, the API introduces a more flexible and versatile mechanism to queue up Buffers for Sources.

There are many ways to use this feature, with streaming being only one of them.

Buffers can be queued, unqueued after they have been used, and either be deleted, or refilled and queued again. Splitting large samples over several buffers maintained in a queue has a distinct advantages over approaches that require explicit management of samples and sample indices.

Queueing command

To distinguish between commands affecting the Source immediately, i.e. setting attributes affecting the processing of the current buffer, and those that are meant to create a new queue entry, a different entry point is used:

void alQueue{if} ( uint sourceName , enum paramName , T value );

In other words

         alSource*( sname, paramName, value )
       

is an immediate command and executed immediately, affecting the current processing but not changing the queue entry. If a Source is STOPPED, then started again, the attributes specified in the queue will be the same as initially queued, unaffected by any commands issued this way. paramNames legal for Source* are not always legal for alQueue*, and vice versa. Queues are read-only with exception of the unqueue operation.

All commands between two subsequent

      alQueue*( sname, AL_BUFFER, bName )
     

commands apply to the queue entry created first. If multiple calls for the same state are issued, the last value is used. The second call to alQueue closes the open queue entry and opens a new one.

Any use of Source( sname, BUFFER, bName ) on an inactive Source closes the open queue entry, and causes it to be removed along with all other existing entries, to be replaced by the specified buffer Name. The application is still obliged to delete all buffers as were contained in the queue. The immediate use of BUFFER destroys all queue information. It is recommended to Stop() the Source first, retrieve the queued bnames next, and then set a buffer (implicitely head of the queue).

The Buffer Name NONE (i.e. 0) can be queued at any time. Thus Source( sname, BUFFER, NONE ) is a legal command, effectively wiping the queue without specifying an actually playable buffer. Similarly, Queue( sname, BUFFER, NONE ) is a legal call which will case a 0 entry to be queued.

NoteAnnotation (Backwards Compatiblity)
 

alSource( AL_WHATEVER, ... ) affects the current queue entry. Some but not all of these commands are legal on a PLAYING source (GAIN, REPEAT), others (BUFFER) are not. None of the legal ones can be used to queue parameters. For clarity (and to account for possible future changes that make currently illegal commands legal) the remaining ones should not be used either.

We can not make the semantics of BUFFER dependend on source state (queuing if PLAYING, immediate else) for clarity reasons either. Queueing using BUFFER this way would require a PLAYING Source (which in turn might require an atomic PlayAndPause() command).

For that reason alSource( AL_BUFFER ) has been rejected as a queueing command, as we neither interpret all nor some alSource(..) commands as queueing instead of immediate depending in context. It is not a legal immediate command on a PLAYING or PAUSED Source either.

NoteAnnotation (No QUEUE_BUFFER)
 

Duplication of one entry point is preferable to duplicating an entire set of enums.