OpenAL-1.3.1.1: A binding to the OpenAL cross-platform 3D audio APISource codeContentsIndex
Sound.OpenAL.AL.Source
Portabilityportable
Stabilityprovisional
Maintainersven.panne@aedion.de
Contents
The Source Type
Source Attributes
Basic Source Attributes
Source Positioning
Source Type
Buffer Looping
Current Buffer
Queue State Queries
Bounds on Gain
Distance Model Attributes
Frequency Shift by Pitch
Direction and Cone
Offset
Queuing Buffers with a Source
Managing Source Execution
Description

This module corresponds to sections 4.1 (Basic Listener and Source Attributes) and 4.3 (Source Objects) of the OpenAL Specification and Reference (version 1.1).

Sources specify attributes like position, velocity, and a buffer with sample data. By controlling a source's attributes the application can modify and parameterize 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 additional functions to manipulate and query the execution state of sources: the current playing status of a source, including access to the current sampling position within the associated buffer.

Synopsis
data Source
sourcePosition :: Source -> StateVar (Vertex3 ALfloat)
sourceVelocity :: Source -> StateVar (Vector3 ALfloat)
sourceGain :: Source -> StateVar Gain
data SourceRelative
= World
| Listener
sourceRelative :: Source -> StateVar SourceRelative
data SourceType
= Undetermined
| Static
| Streaming
sourceType :: Source -> GettableStateVar SourceType
data LoopingMode
= OneShot
| Looping
loopingMode :: Source -> StateVar LoopingMode
buffer :: Source -> StateVar (Maybe Buffer)
buffersQueued :: Source -> GettableStateVar ALint
buffersProcessed :: Source -> GettableStateVar ALint
gainBounds :: Source -> StateVar (Gain, Gain)
referenceDistance :: Source -> StateVar ALfloat
rolloffFactor :: Source -> StateVar ALfloat
maxDistance :: Source -> StateVar ALfloat
pitch :: Source -> StateVar ALfloat
direction :: Source -> StateVar (Vector3 ALfloat)
coneAngles :: Source -> StateVar (ALfloat, ALfloat)
coneOuterGain :: Source -> StateVar Gain
secOffset :: Source -> StateVar ALfloat
sampleOffset :: Source -> StateVar ALint
byteOffset :: Source -> StateVar ALint
queueBuffers :: Source -> [Buffer] -> IO ()
unqueueBuffers :: Source -> [Buffer] -> IO ()
data SourceState
= Initial
| Playing
| Paused
| Stopped
sourceState :: Source -> GettableStateVar SourceState
play :: [Source] -> IO ()
pause :: [Source] -> IO ()
stop :: [Source] -> IO ()
rewind :: [Source] -> IO ()
The Source Type
data Source Source
The abstract buffer type.
show/hide Instances
Source Attributes
Basic Source Attributes
sourcePosition :: Source -> StateVar (Vertex3 ALfloat)Source
sourcePosition contains the current location of the source in the world coordinate system. Any 3-tuple of valid float values is allowed. Implementation behavior on encountering NaN and infinity is not defined. The initial position is (Vertex3 0 0 0).
sourceVelocity :: Source -> StateVar (Vector3 ALfloat)Source

sourceVelocity contains current velocity (speed and direction) of the source in the world coordinate system. Any 3-tuple of valid float values is allowed, and the initial velocity is (Vector3 0 0 0). sourceVelocity does not affect sourcePosition. OpenAL does not calculate the velocity from subsequent position updates, nor does it adjust the position over time based on the specified velocity. Any such calculation is left to the application. For the purposes of sound processing, position and velocity are independent parameters affecting different aspects of the sounds.

sourceVelocity is taken into account by the driver to synthesize the Doppler effect perceived by the listener for each source, based on the velocity of both source and listener, and the Doppler related parameters.

sourceGain :: Source -> StateVar GainSource

sourceGain contains a scalar amplitude multiplier for the given source. The initial value 1 means that the sound is unattenuated. A sourceGain value of 0.5 is equivalent to an attenuation of 6dB. The value zero equals silence (no output). Driver implementations are free to optimize this case and skip mixing and processing stages where applicable. The implementation is in charge of ensuring artifact-free (click-free) changes of gain values and is free to defer actual modification of the sound samples, within the limits of acceptable latencies.

A sourceGain larger than 1 (amplification) is permitted. However, the implementation is free to clamp the total gain (effective gain per source times listener gain) to 1 to prevent overflow.

Source Positioning
data SourceRelative Source
The entity to which the source attributes sourcePosition, sourceVelocity and direction are to be interpreted.
Constructors
World
Listener
show/hide Instances
sourceRelative :: Source -> StateVar SourceRelativeSource
If sourceRelative contains Listener, it indicates indicates that the values specified by sourcePosition, sourceVelocity and direction are to be interpreted relative to the listener position. The initial value is World, indicating that those source attributes are to be interpreted relative to the world, i.e. they are considered absolute.
Source Type
data SourceType Source
When first created, a source will be in the Undetermined state. If a buffer is then attached using buffer, then the source will enter the Static state. If the first buffer attached to a source is attached using queueBuffers, then the source will enter the Streaming state. A source of either state will be reset to state Undetermined by setting its buffer to Nothing, and attaching any buffer to a streaming source will change the state to Static. Attempting to queue a buffer on a static source will result in an ALInvalidOperation error.
Constructors
Undetermined
Static
Streaming
show/hide Instances
sourceType :: Source -> GettableStateVar SourceTypeSource
sourceType indicates whether a source is ready to queue buffers, ready to use a static buffer, or is in an undetermined state where it can be used for either streaming or static playback.
Buffer Looping
data LoopingMode Source
Specifies what should happen when the end of a buffer queue is reached.
Constructors
OneShot
Looping
show/hide Instances
loopingMode :: Source -> StateVar LoopingModeSource
If loopingMode contains Looping, it indicates that the source will not be in the Stopped state once it reaches the end of last buffer in the buffer queue. Instead, the source will immediately promote to Initial and Playing. The initial value is OneShot. loopingMode can be changed on a source in any execution state. In particular, it can be changed on a Playing source.
Current Buffer
buffer :: Source -> StateVar (Maybe Buffer)Source

buffer contains the current buffer object. Setting buffer to Just a buffer object makes it the head entry in the source's queue. Setting bufferfor a source in the Stopped or Initial state empties the entire queue, then appends the one buffer specified (or none at all if Nothing was specified).

For a source in the Playing or Paused state, setting buffer will result in the ALInvalidOperation error state being set. buffer can be applied only to sources in the Initial and Stopped states. Specifying an invalid buffer name (either because the buffer name doesn't exist or because that buffer can't be attached to the specified source) will result in an ALInvalidValue error while specifying an invalid source name results in an ALInvalidName error. Setting buffer to Nothing is a legal way to release the current buffer queue on a source in the Initial or Stopped state, whether the source has just one entry (current buffer) or more. Setting buffer to Nothing still causes an ALInvalidOperation for any source in the Playing or Paused state, consequently it cannot be used to mute or stop a source. The initial value is Nothing.

Queue State Queries
buffersQueued :: Source -> GettableStateVar ALintSource
buffersQueued contains 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. It will contain 0 if buffer has been set to Nothing.
buffersProcessed :: Source -> GettableStateVar ALintSource
buffersProcessed contains the number of buffers that have been played by a given source. Indirectly, this gives the index of the buffer currently playing. It can be used to determine how much slots are needed for unqueuing them. On a source in the Stopped state, all buffers are processed. On a source in the Initial state, no buffers are processed, all buffers are pending. It will contain 0 if buffer has been set to Nothing.
Bounds on Gain
gainBounds :: Source -> StateVar (Gain, Gain)Source

gainBounds contains two scalar amplitude thresholds between 0 and 1 (included): The minimum guaranteed gain for this source and the maximum gain permitted, with initial values 0 and 1, respectively At the end of the processing of various attenuation factors such as distance based attenuation and sourceGain, the effective gain calculated is compared to these values:

If the effective gain is lower than the minimum gain, the minimum gain is applied. This happens before the listenerGain is applied. If a zero minimum gain is set, then the effective gain will not be corrected.

If the effective gain is higher than the maximum gain, the maximum gain is applied. This happens before the listenerGain is applied. If the listenerGain times the maximum gain still exceeds the maximum gain the implementation can handle, the implementation is free to clamp. If a zero maximum gain is set, then the source is effectively muted. The implementation is free to optimize for this situation, but no optimization is required or recommended as setting sourceGain to zero is the proper way to mute a source.

Distance Model Attributes
referenceDistance :: Source -> StateVar ALfloatSource
referenceDistance is used for distance attenuation calculations based on inverse distance with rolloff. Depending on the distance model it will also act as a distance threshold below which gain is clamped. See Sound.OpenAL.AL.Attenuation for details. The initial value is 1.
rolloffFactor :: Source -> StateVar ALfloatSource

rolloffFactor is used for distance attenuation calculations based on inverse distance with rolloff. For distances smaller than maxDistance (and, depending on the distance model, larger than referenceDistance), this will scale the distance attenuation over the applicable range. See Sound.OpenAL.AL.Attenuation for details how the attenuation is computed as a function of the distance. The initial value is 1.

In particular, rolloffFactor can be set to zero for those sources that are supposed to be exempt from distance attenuation. The implementation is encouraged to optimize this case, bypassing distance attenuation calculation entirely on a persource basis.

maxDistance :: Source -> StateVar ALfloatSource
maxDistance is used for distance attenuation calculations based on inverse distance with rolloff, if the inverse clamped distance model is used. In this case, distances greater than maxDistance will be clamped to maxDistance. maxDistance based clamping is applied before minimum gain clamping (see gainBounds), so if the effective gain at maxDistance is larger than the minimum gain, the minimum gain will have no effect. No culling is supported. The initial value is the largest representable ALfloat.
Frequency Shift by Pitch
pitch :: Source -> StateVar ALfloatSource
pitch contains the desired pitch shift, where 1 (the initial value) equals identity. Each reduction by 50 percent equals a pitch shift of -12 semitones (one octave reduction). Each doubling equals a pitch shift of 12 semitones (one octave increase). Zero is not a legal value. Implementations may clamp the actual output pitch range to any values subject to the implementation's own limits.
Direction and Cone
Each source can be directional, depending on the settings for coneAngles. There are three zones defined: the inner cone, the outside zone, and the transitional zone in between. The angle-dependent gain for a directional source is constant inside the inner cone, and changes over the transitional zone to the value specified outside the outer cone. sourceGain is applied for the inner cone, with an application selectable coneOuterGain factor to define the gain in the outer zone. In the transitional zone implementation-dependent interpolation between sourceGain and sourceGain times coneOuterGain is applied.
direction :: Source -> StateVar (Vector3 ALfloat)Source

If direction does not contain the zero vector (Vector3 0 0 0), the source is directional. 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 the initial value, 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.

coneAngles :: Source -> StateVar (ALfloat, ALfloat)Source
coneAngles contains the inner and outer angles of the sound cone, in degrees. The default of 360 for the inner cone angle means that it covers the entire world, which is equivalent to an omni-directional source. The default of 360 for the outer cone angle means that it covers the entire world. If the inner angle is also 360, then the zone for angle-dependent attenuation is zero.
coneOuterGain :: Source -> StateVar GainSource
coneOuterGain contains the factor with which sourceGain is multiplied to determine the effective gain outside the cone defined by the outer angle. The effective gain applied outside the outer cone is sourceGain times coneOuterGain. Changing sourceGain affects all directions, i.e. the source is attenuated in all directions, for any position of the listener. The application has to change coneOuterGain as well if a different behavior is desired.
Offset
secOffset :: Source -> StateVar ALfloatSource

secOffset contains the playback position, expressed in seconds (the value will loop back to zero for looping sources).

When setting secOffset on a source which is already playing, the playback will jump to the new offset unless the new offset is out of range, in which case an ALInvalidValue error is set. If the source is not playing, then the offset will be applied on the next play call.

The position is relative to the beginning of all the queued buffers for the source, and any queued buffers traversed by a set call will be marked as processed.

This value is based on byte position, so a pitch-shifted source will have an exaggerated playback speed. For example, you can be 0.5 seconds into a buffer having taken only 0.25 seconds to get there if the pitch is set to 2.

sampleOffset :: Source -> StateVar ALintSource

sampleOffset contains the playback position, expressed in samples (the value will loop back to zero for looping sources). For a compressed format, this value will represent an exact offset within the uncompressed data.

When setting sampleOffset on a source which is already playing, the playback will jump to the new offset unless the new offset is out of range, in which case an ALInvalidValue error is set. If the source is not playing, then the offset will be applied on the next play call. A stop, rewind, or a second play call will reset the offset to the beginning of the buffer.

The position is relative to the beginning of all the queued buffers for the source, and any queued buffers traversed by a set call will be marked as processed.

byteOffset :: Source -> StateVar ALintSource

byteOffset contains the playback position, expressed in bytes (the value will loop back to zero for looping sources). For a compressed format, this value may represent an approximate offset within the compressed data buffer.

When setting byteOffset on a source which is already playing, the playback will jump to the new offset unless the new offset is out of range, in which case an ALInvalidValue error is set. If the source is not playing, then the offset will be applied on the next play call. A stop, rewind, or a second play call will reset the offset to the beginning of the buffer.

The position is relative to the beginning of all the queued buffers for the source, and any queued buffers traversed by a set call will be marked as processed.

Queuing Buffers with a Source

OpenAL does not specify a built-in streaming mechanism. There is no mechanism to stream data into a buffer object. Instead, the API has a more flexible and versatile mechanism to queue buffers for sources. There are many ways to use this feature, with streaming being only one of them.

Streaming is replaced by queuing static buffers. This effectively moves any multi-buffer caching into the application and allows the application to select how many buffers it wants to use, the size of the buffers, and whether these are re-used in cycle, pooled, or thrown away.

Looping (over a finite number of repetitions) can be implemented by explicitly repeating buffers in the queue. Infinite loops can (theoretically) be accomplished by sufficiently large repetition counters. If only a single buffer is supposed to be repeated infinitely, using the respective source attribute loopingMode is recommended.

Loop Points for restricted looping inside a buffer can in many cases be replaced by splitting the sample into several buffers and queuing the sample fragments (including repetitions) accordingly.

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 distinct advantages over approaches that require explicit management of samples and sample indices.

queueBuffers :: Source -> [Buffer] -> IO ()Source

The application can queue up one or multiple buffer names using queueBuffers. The buffers will be queued in the sequence in which they appear in the list.

This command is legal on a source in any playback state (to allow for streaming, queuing has to be possible on a Playing source).

All buffers in a queue must have the same format and attributes. An attempt to mix formats or other buffer attributes will result in a failure and an ALInvalidValue error will be thrown. If the queue operation fails, the source queue will remain unchanged (even if some of the buffers could have been queued).

unqueueBuffers :: Source -> [Buffer] -> IO ()Source

Once a queue entry for a buffer has been appended to a queue and is pending processing, it should not be changed. Removal of a given queue entry is not possible unless either the source is stopped (in which case then entire queue is considered processed), or if the queue entry has already been processed (Playing or Paused source). A playing source will enter the Stopped state if it completes playback of the last buffer in its queue (the same behavior as when a single buffer has been attached to a source and has finished playback).

The unqueueBuffers command removes a number of buffers entries that have finished processing, in the order of appearance, from the queue. The operation will fail with an ALInvalidValue error if more buffers are requested than available, leaving the destination arguments unchanged.

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.
data SourceState Source
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.
Constructors
Initial
Playing
Paused
Stopped
show/hide Instances
sourceState :: Source -> GettableStateVar SourceStateSource

Contains the current execution state of the given source. The initial state of any source is Initial.

Note that the Initial state is not necessarily identical to the initial state in which a source is created, because the other source attributes are not automatically reset to their initial values. Initial merely indicates that the source can be executed using the play command. A Stopped or Initial source can be reset into the default configuration by using a sequence of source commands as necessary. As the application has to specify all relevant state anyway to create a useful source configuration, no reset command is provided.

play :: [Source] -> IO ()Source
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 in Playing state, but reset the sampling offset to the beginning. 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 :: [Source] -> IO ()Source
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 :: [Source] -> IO ()Source
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 :: [Source] -> IO ()Source
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 an Stopped source promotes the source to Initial, resetting the sampling offset to the beginning.
Produced by Haddock version 0.8