Copyright | (c) Sven Panne 2003-2016 |
---|---|
License | BSD3 |
Maintainer | Sven Panne <svenpanne@gmail.com> |
Stability | stable |
Portability | portable |
Safe Haskell | Safe |
Language | Haskell2010 |
This module corresponds to section 3.4 (Attenuation By Distance) of the OpenAL Specification and Reference (version 1.1).
Introduction
Samples usually use the entire dynamic range of the chosen format/encoding, independent of their real world intensity. In other words, a jet engine and a clockwork both will have samples with full amplitude. The application will then have to adjust source gain accordingly to account for relative differences.
Source gain is then attenuated by distance. The effective attenuation of a source depends on many factors, among which distance attenuation and source and listener gain are only some of the contributing factors. Even if the source and listener gain exceed 1 (amplification beyond the guaranteed dynamic range), distance and other attenuation might ultimately limit the overall gain to a value below 1.
Handling the Distance Model
data DistanceModel Source
OpenAL currently supports six modes of operation with respect to distance attenuation, including one that is similar to the IASIG I3DL2 model. The application chooses one of these models (or chooses to disable distance-dependent attenuation) on a per-context basis.
The distance used in the formulas for the "clamped" modes below is clamped
to be in the range between referenceDistance
and maxDistance
:
clamped distance =
max(referenceDistance
, min(distance, maxDistance
))
The linear models are not physically realistic, but do allow full attenuation of a source beyond a specified distance. The OpenAL implementation is still free to apply any range clamping as necessary.
With all the distance models, if the formula can not be evaluated then the
source will not be attenuated. For example, if a linear model is being used
with referenceDistance
equal to maxDistance
, then the gain equation will
have a divide-by-zero error in it. In this case, there is no attenuation for
that source.
NoAttenuation | Bypass all distance attenuation calculation for all sources. The implementation is expected to optimize this situation. |
InverseDistance | Inverse distance rolloff model, which is equivalent to the IASIG I3DL2
model with the exception that gain = The |
InverseDistanceClamped | Inverse Distance clamped model, which is essentially the inverse
distance rolloff model, extended to guarantee that for distances below
|
LinearDistance | Linear distance rolloff model, modeling a linear dropoff in gain as distance increases between the source and listener. gain = (1 - |
LinearDistanceClamped | Linear Distance clamped model, which is the linear model, extended to
guarantee that for distances below |
ExponentDistance | Exponential distance rolloff model, modeling an exponential dropoff in gain as distance increases between the source and listener. gain = (distance / |
ExponentDistanceClamped | Exponential Distance clamped model, which is the exponential model,
extended to guarantee that for distances below |
distanceModel :: StateVar DistanceModel Source
Contains the current per-context distance model.
Evaluation of Gain/Attenuation Related State
While amplification/attenuation commute (multiplication of scaling factors), clamping operations do not. The order in which various gain related operations are applied is:
- Distance attenuation is calculated first, including minimum
(
referenceDistance
) and maximum (maxDistance
) thresholds. - The result is then multiplied by source gain.
- If the source is directional (the inner cone angle is less than the outer
cone angle, see
coneAngles
), an angle-dependent attenuation is calculated depending onconeOuterGain
, and multiplied with the distance-dependent attenuation. The resulting attenuation factor for the given angle and distance between listener and source is multiplied withsourceGain
. - The effective gain computed this way is compared against
gainBounds
. - The result is guaranteed to be clamped to
gainBounds
, and subsequently multiplied by listener gain which serves as an overall volume control.
The implementation is free to clamp listener gain if necessary due to hardware or implementation constraints.
No Culling By Distance
With the DS3D compatible inverse clamped distance model, OpenAL provides a
per-source maxDistance
attribute that can be used to define a distance
beyond which the source will not be further attenuated by distance. The DS3D
distance attenuation model and its clamping of volume is also extended by a
mechanism to cull (mute) sources from processing, based on distance. However,
the OpenAL does not support culling a source from processing based on a
distance threshold.
At this time OpenAL is not meant to support culling at all. Culling based on distance, or bounding volumes, or other criteria, is best left to the application. For example, the application might employ sophisticated techniques to determine whether sources are audible that are beyond the scope of OpenAL. In particular, rule based culling inevitably introduces acoustic artifacts. E.g. if the listener-source distance is nearly equal to the culling threshold distance, but varies above and below, there will be popping artifacts in the absence of hysteresis.