Source Objects

Sources specify attributes like position, velocity, and a buffer with sample data. By controlling a Source's attributes the application can modify and parametrize the static sample data provided by the Buffer referenced by the Source. Sources define a localized sound, and encapsulate a set of attributes applied to a sound at its origin, i.e. in the very first stage of the processing on the way to the listener. Source related effects have to be applied before Listener related effects unless the output is invariant to any collapse or reversal of order.

OpenAL also provides additonal functions to manipulate and query the execution state of Sources: the current playing status of a source (started, stopped, paused), including access to the current sampling position within the associated Buffer.

Managing Source Names

OpenAL provides calls to request and release Source Names handles. Calls to control Source Execution State are also provided.

Requesting a Source Name

The application requests a number of Sources using GenSources.

sizei GenSources ( sizei n , uint * sources );

Releasing Source Names

The application requests deletion of a number of Sources by DeleteSources.

void DeleteSources ( sizei n , uint * sources );

Validating a Source Name

The application can verify whether a source name is valid using the IsSource query.

boolean IsSource ( uint sourceName );

Source Attributes

This section lists the attributes that are set per Source, affecting the processing of the current buffer. Some of these attributes can also be set for buffer queue entries.

NoteAnnotation (No Priorities)
 

There are no per Source priorities, and no explicit priority handling, defined at this point. A mechanism that lets the application express preferences in case that the implementation provides culling and prioritization mechanisms might be added at some later time. This topic is under discussion for GL as well, which already has one exlicit priority API along with internally used MRU heuristics (for resident texture memory).

Buffer Looping

Table 5. Source LOOP_COUNT Attribute

NameSignatureValuesDefault
LOOP_COUNT ui [0, any ] 0
Description: LOOP_COUNT gets and sets the number of times a Source will traverse a buffer in the specified direction. The token can legally be used for a Source in any state, applying to the current buffer (NONE for a STOPPED, the first queue entry for INITIAL), and also legal for buffer queue commands. Setting to 0 or NONE will cause a playing Source to stop playing the current buffer following the completion of the current traversal.

NoteAnnotation (Looping as Reptition)
 

To play infinitely, a sufficiently large number of repetitions will work. There is no INFINITE (== MAXINT) enum. If it turns out that an explicit enum is needed, it can be added in a later revision. Applications are free to define their own INFINITE value.

NoteAnnotation (Separarte direction and counter)
 

An interface like Queue( sname, LOOP, rep ) would require two additional tokens for query. The current API does not invite specifying multiple arguments in a single command. In this case, such a combination would be cumbersome, as the counter can be reset for the current buffer, but the direction can not, so a separate token for Source( sname, LOOP_COUNT, rep ) would be required anyway.

Current Buffer

Table 6. Source BUFFER Attribute

NameSignatureValuesDefault
BUFFER ui any valid bufferName NONE
Description: Specify the current Buffer object, which means the head entry in its queue. Using this command empties the entire queue, then appends the one Buffer specified. NONE i.e. 0 is a valid buffer Name.

For a PLAYING or PAUSED Source this will yield an ILLEGAL_OPERATIOM. It does not cause a buffer to be queued if used with the Source command. It can be applied to INITIAL and STOPPED Sources only. Specifying an invalid bufferName will result in an INVALID_VALUE error while specifying an invalid sourceName results in an INVALID_NAME error.

NoteAnnotation/ repeated BUFFER does not queue
 

Using repeated BUFFER calls to queue a buffer on an active source would imply that there is no way to release the current buffer e.g. by setting it to 0. On the other hand read-only queues do not allow for releasing a buffer without releasing the entire queue. We can not require BUFFER state to be transient and lost as soon as a Source is implicitely or explicitely stopped. This contradicts queue state being part of the Source's configuration state that is preserved through Stop() operations and available for Play().

Queue State Queries

Table 7. Buffer BUFFERS_QUEUED Attribute

NameSignatureValuesDefault
BUFFERS_QUEUED uint [0, any] none
Query only. Query the number of buffers in the queue of a given Source. This includes those not yet played, the one currently playing, and the ones that have been played already. This will return 0 if the current and only bufferName is 0.

Table 8. Buffer BUFFERS_USED Attribute

NameSignatureValuesDefault
BUFFERS_QUEUED uint [0, any] none
Query only. Query the number of buffers that have been played by a given Source. Indirectly, this gives the index of the buffer currently playing. Used to determine how much slots are needed for unqueueing them. On an STOPPED Source, all buffers are used. On an INITIAL Source, all buffers are unused. This will return 0 if the current and only bufferName is 0.

Bounds on Gain

Table 9. Source Minimal Gain

NameSignatureValuesDefault
MIN_GAINf0.0f, (0.0f, 1.0f]0.0f
Description: MIN_GAIN is a scalar amplitude threshold. It indicates the minimal GAIN which is always guaranteed for this Source. At the end of the processing of various attenuation factors such as distance based attenuation and Source GAIN, the effective gain calculated is compared to this value. If the effective gain is lower than MIN_GAIN, MIN_GAIN is applied. This happens before the Listener GAIN is applied. If a zero MIN_GAIN is set, then the effective gain will not be corrected.

Table 10. Source Maximal Gain

NameSignatureValuesDefault
MAX_GAINf0.0f, (0.0f, 1.0f]1.0f
Description: MAX_GAIN is a scalar amplitude threshold. It indicates the maximal GAIN permitted for this Source. At the end of the processing of various attenuation factors such as distance based attenuation and Source GAIN, the effective gain calculated is compared to this value. If the effective gain is higher than MAX_GAIN, MAX_GAIN is applied. This happens before the Listener GAIN is applied. If the Listener gain times MAX_GAIN still exceeds the maximum gain the implementation can handle, the implementation is free to clamp. If a zero MAX_GAIN is set, then the Source is effectively mute. The implementation is free to omptimize this beahvior, but no optimization is required or recommended as setting GAIN to zero is the proper way to mute a Source.

NoteAnnotation/ Un-attenuated Source
 

Setting MIN_GAIN and MAX_GAIN to the GAIN value will effectively make the Source independend of distance. The implementation is free to optimize for this situation.

NoteAnnotation/ Effective Maximal Distance
 

By setting MIN_GAIN, the application implicitely defines a maximum distance for a given distance attenuation model and Source GAIN. The distance at which the effective gain is MIN_GAIN is equivalent to the DirectSound3D MAX_DISTANCE parameter. Once the effective gain has reached the MIN_GAIN value, it will no longer decrease with increasing distance.

NoteAnnotation/ Internal GAIN threshold
 

The OpenAL implementation is free to use an internally chosen threshold level below which a Source is ignored for mixing. Reasonable choices would set this threshold low enough so that the user will not perceive a difference. Setting MIN_GAIN for a source will circumvent this test.

Frequency Shift by Pitch

Table 11. Source PITCH Attribute

NameSignatureValuesDefault
PITCHf (0.0f, 1.0f] 1.0f
Description: Desired pitch shift, where 1.0 equals identity. Each reduction by 50 percent equals a pitch shift of -12 semitones (one octave reduction). Zero is not a legal value. RFC: is this used?

Direction and Cone

Table 12. Source DIRECTION Attribute

NameSignatureValuesDefault
DIRECTION3fv, 3f any except NaN { 0.0f, 0.0f, 0.0f }
Description: DIRECTION specifies that a Source is a directional source, and specifies the current direction. The sound emission is presumed to be symmetric around the direction vector (cylinder symmetry). Sources are not oriented in full 3 degrees of freedom, only two angles are effectively needed.

The zero vector is default, indicating that a Source is not directional. Specifying a non-zero vector will make the Source directional. Specifying a zero vector for a directional Source will effectively mark it as nondirectional. RFC: AZIMUTH/ALTITUDE ? RFC: ORIENTATION later? Superimposable - mix both? RFC: change directional to nondirectional on the fly?

NoteAnnotation/ All Sources Directional
 

From the point of view of the OpenAL implementation, all Sources are directional. Certain choices for cone angles as well as a direction vector with zero length are treated equivalent to an omnidirectional source. The OpenAL implementation is free to flag and optimize these cases.

Table 13. Source CONE_INNER_ANGLE Attribute

NameSignatureValuesDefault
CONE_INNER_ANGLEi,fany except NaN360.0f
Description: Inside angle of the sound cone, in degrees. The default of 360 means that the inner angle covers the entire world, which is equivalent to an omnidirectional source. RFC: (inner <= outer) required? Shouldn't this be a CONE_ANGLES 2f call specifying both angles at once?

Table 14. Source CONE_OUTER_ANGLE Attribute

NameSignatureValuesDefault
CONE_OUTER_ANGLEi,fany except NaN360.0f
Description: Outer angle of the sound cone, in degrees. The default of 360 means that the outer angle covers the entire world. If the inner angle is also 360, then the zone for angle-dependend attenuation is zero.

Table 15. Source CONE_OUTER_GAIN Attribute

NameSignatureValuesDefault
CONE_OUTER_GAINi,f[0.0f, 1.0f]0.0f
Description: the gain outside the outer angle. The angle dependend gain for a directional source is constant inside the inner cone (at the Source GAIN selected), and changes over the outer cone to the value specified here.

NoteAnnotation/ CONE_OUTER_GAIN > GAIN
 

The specification does not probibit using a Source GAIN smaller than the CONE_OUTER_GAIN for a directional source. The OpenAL implementation has to account for this possibility to occur.

Changing Source Attributes

The Source specifies the position and properties for the first sound processing stage. By controlling the Source parameters the application controls the way sound is modified before fed into the processing stage at the listener position. See...

void Source{n}{sifd} ( uint sourceName , enum paramName , T value );

void Source{n}{sifd}v ( uint sourceName , enum paramName , T * values );

Querying Source Attributes

Source state is maintained inside the OpenAL implementation, and the current attributes can be queried. The performance of such queries is implementation dependent, no performance guarantees are made. The valid values for the paramName parameter are identical to the ones for Source*.

void GetSource{n}{sifd}{v} ( uint sourceName , enum paramName , T * values );

Managing Source Execution

The execution state of a source can be queried. OpenAL provides a set of functions that initiate state transitions causing Sources to start and stop execution.

TBA: State Transition Diagram.

NoteAnnotation/ Source Config/Exec State
 

Sources have configuration state and execution state. Configuration state is directly set by the application using AL commands, starting with the INITIAL configuration. Execution state is not under direct application control and not exposed: most notably this is the offset to the current sample.

Source State Query

The application can query the current state of any Source using GetSource with the parameter Name SOURCE_STATE. Each Source can be in one of four possible execution states: INITIAL, PLAYING, PAUSED, STOPPED. Sources that are either PLAYING or PAUSED are considered active. Sources that are STOPPED or INITIAL are considered inactive. Only PLAYING Sources are included in the processing. The implementation is free to skip those processing stages for Sources that have no effect on the output (e.g. mixing for a Source muted by zero GAIN, but not sample offset increments). Depending on the current state of a Source certain (e.g. repeated) state transition commands are legal NOPs: they will be ignored, no error is generated.

State Transition Commands

The default state of any Source is INITIAL. From this state it can be propagated to any other state by appropriate use of the commands below. There are no irreversible state transitions.

void SourceStart ( uint sName );

void SourcePause ( uint sName );

void SourceStop ( uint sName );

void SourceRewind ( uint sName );

The functions are also available as a vector variant, which guarantees synchronized operation on a set of Sources.

void SourceStartv ( sizei n , uint * sNames );

void SourcePausev ( sizei n , uint * sNames );

void SourceStopv ( sizei n , uint * sNames );

void SourceRewindv ( sizei n , uint * sNames );

The following state/command/state transitions are defined:

  • Play() applied to an INITIAL Source will promote the Source to PLAYING, thus the data found in the Buffer will be fed into the processing, starting at the beginning. Play() applied to a PLAYING Source will restart the Source from the beginning. It will not affect the configuration, and will leave the Source its PLAYING state, but reset the sampling offset immediately. Play() applied to a PAUSED Source will resume processing using the Source state as preserved at the Pause() operation. Play() applied to a STOPPED Source will propagate it to INITIAL then to PLAYING immediately.

  • Pause() applied to an INITIAL Source is a legal NOP. Pause() applied to a PLAYING Source will change its state to PAUSED. The Source is exempt from processing, its current state is preserved. Pause() applied to a PAUSED Source is a legal NOP. Pause() applied to a STOPPED Source is a legal NOP.

  • Stop() applied to an INITIAL Source is a legal NOP. Stop() applied to a PLAYING Source will change its state to STOPPED. The Source is exempt from processing, its current state is preserved. Stop() applied to a PAUSED Source will change its state to STOPPED, with the same consequences as on a PLAYING Source. Stop() applied to a STOPPED Source is a legal NOP.

  • Rewind() applied to an INITIAL Source is a legal NOP. Rewind() applied to a PLAYING Source will change its state to STOPPED then INITIAL. The Source is exempt from processing, its current state is preserved, with the exception of the sampling offset which is reset to the beginning. Rewind() applied to a PAUSED Source will change its state to INITIAL, with the same consequences as on a PLAYING Source. Rewind() applied to a STOPPED Source promotes the Source to INITIAL, resetting the sampling offset to the beginning.

NoteAnnotation (SourceNext)
 

The specification does not provide any means to immediately skip from the current Buffer to the next in the queue. A conditional stop (following the next complete traversal) is available. In necessary an additonal entry point could be provided in future revisions.

NoteAnnotation (Rewind() optional)
 

The INITIAL state is not identical to the STOPPED state. Applications that want to verify whether a Source has indeed been PLAYING before becoming STOPPED can use Rewind() to reset the Source state to INITIAL. This is an optional operation that can safely be omitted by application without this constraint. Applications that want to guard against Play() on a Source that is INITIAL can query the Source state first.

NoteAnnotation (Play() on a PLAYING Source)
 

Repeated Play() commands applied a PLAYING Source are interpreted as an (atomic) sequence to stop and restart a Source. This can be used by applications that want to restart a sound but do not care whether the Source has finished or not, and do not want an audible pause. One example is the DOOM chaingun repeatedly abbreviating the pistol sound. To guard against redundant Play() commands, an application can query the current state before executing Play().

NoteAnnotation (redundant commands)
 

The simple variant (e.g. SourcePlay) is redundant to the vector variant (e.g. SourcePlayv). However, these calls will be used frequently, and the simple variant is provided for convenience. However, OpenAL does not enable applications to use literals as source names.

Resetting Configuration

The INITIAL state is not necessarily identical to the default state in which Source is created. INITIAL merely indicates that the Source can be executed using the SourcePlay command. A STOPPED or INITIAL Source can be reset into the default configuration by using a sequence alSource commands as necessary. As the application has to specify all relevant state anyway to create a useful Source configuration, not reset command is provided.

NoteAnnotation (illegal NOPs)
 

In the current specification there are no illegal NOPs. In other words, no sequence of commands affecting the execution state will generate an INVALID_OPERATION error.