123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731 |
- <chapter id="state-requests">
- <title>State and State Requests</title>
- <para>
- The majority of &AL; state is associated with individual &AL; objects,
- and has to be set and queried referencing the objects. However, some
- state - e.g. processing errors - is
- defined context specific. &AL; has global state that affects all
- objects and processing equally. This state is set using a variety
- of functions, and
- can be queried using query functions. The majority of queries
- has to use the interface described in "Simple Queries".
- </para>
- <sect1 id="state-query">
- <title>Querying &AL; State</title>
- <sect2>
- <title>Simple Queries</title>
- <para>
- Like &OGL;, &AL; uses a simplified interface for querying global
- state. The following functions accept a set of enumerations.
- <funcsynopsis><funcprototype>
- <funcdef> void <function> GetBooleanv </function></funcdef>
- <paramdef> &enum; <parameter> paramName </parameter></paramdef>
- <paramdef> &bool;* <parameter> dest </parameter></paramdef>
- </funcprototype></funcsynopsis>
- <funcsynopsis><funcprototype>
- <funcdef> void <function> GetIntegerv </function></funcdef>
- <paramdef> &enum; <parameter> paramName </parameter></paramdef>
- <paramdef> ∫* <parameter> dest </parameter></paramdef>
- </funcprototype></funcsynopsis>
- <funcsynopsis><funcprototype>
- <funcdef> void <function> GetFloatv </function></funcdef>
- <paramdef> &enum; <parameter> paramName </parameter></paramdef>
- <paramdef> &float;* <parameter> dest </parameter></paramdef>
- </funcprototype></funcsynopsis>
- <funcsynopsis><funcprototype>
- <funcdef> void <function> GetDoublev </function></funcdef>
- <paramdef> &enum; <parameter> paramName </parameter></paramdef>
- <paramdef> &double;* <parameter> dest </parameter></paramdef>
- </funcprototype></funcsynopsis>
- Legal values are e.g. DOPPLER_FACTOR, DOPPLER_VELOCITY, DISTANCE_MODEL.
- </para>
- <para>
- NULL destinations are quietly ignored. INVALID_ENUM is the
- response to errors in specifying paramName. The amount of memory
- required in the destination depends on the actual state requested.
- Usually, state variables are returned in only one or some of the
- formats above.
- </para>
- <para>
- To query state controlled by Enable/Disable there is an additional
- IsEnabled function defined (see "Controlling &AL; Execution").
- </para>
- </sect2>
-
- <sect2>
- <title>Data Conversions</title>
- <para>
- If a Get command is issued that returns value types different from
- the type of the value being obtained, a type converswion is
- performed. If GetBooleanv is called, a floating-point or integer
- value converts to FALSE if and only if it is zero (otherwise
- it converts to TRUE). If GetIntegerv is called, a boolean value
- is interpreted as either 1 or 0, and a floating-point value is
- rounded to the nearest integer. If GetFloatv is called, a boolean
- value is interpreted as either 1.0 or 0.0, an integer is
- coerced to floating point, and a double-presicion foating-point
- value is converted to single precision. Analogous conversions are
- carried out in the case of GetDoublev. If a value is so large
- in magnitude that it cannot be represented with the requested
- type, then the nearest value is representable using the requested
- type is returned.
- </para>
- <![ %Annote [
- <note><title>Annotation (Query of Modes)</title><para>
- Modes (e.g. the current distance model) can be queried
- using the respective tokens. The recommended query
- command is GetIntegerv.
- </para></note>
- ]]>
- </sect2>
-
- <sect2>
- <title>String Queries</title>
- <para>
- The application can retrieve state information global to the current
- &AL; Context. GetString will return a pointer to a constant string.
- Valid values for param are VERSION, RENDERER, VENDOR, and EXTENSIONS,
- as well as the error codes defined by &AL;. The application can
- use GetString to retrieve a string for an error code.
- <funcsynopsis><funcprototype>
- <funcdef> const &ubyte;* <function> GetString </function></funcdef>
- <paramdef> &enum; <parameter> paramName</parameter></paramdef>
- </funcprototype></funcsynopsis>
- </para>
- </sect2>
- </sect1>
- <sect1 id="time">
- <title>Time and Frequency</title>
- <para>
- By default, &AL; uses seconds and Hertz as units for
- time and frequency, respectively.
- A float or integral value of one
- for a variable that specifies quantities like duration,
- latency, delay, or any other parameter measured as time,
- specifies 1 second.
- For frequency, the basic unit is 1/second, or Hertz.
- In other words, sample frequencies and frequency
- cut-offs or filter parameters specifying frequencies
- are expressed in units of Hertz.
- </para>
-
- <![ %RFC [
- <note id="rfc-bk000927-01"><title>RFC: Query and Factor?</title><para>
- Will time be an &AL; state that can be queried and scaled?
- &AL; usually (always) implements a real-time
- process with the constraint that it has to be
- synchronized with the time as experienced by the user.
- Do the units used with respect to time and frequency have
- a fixed meaning?
- </para></note>
- ]]>
- <![ %RFC [
- <note id="rfc-bk000803-03"><title>RFC: Setting Time/Long</title><para>
- Given a frequency range from a few Hz to 50kHz or more,
- we need a temporal resolution of 20 microseconds or less.
- For simplicity that means we either resolve Milliseconds
- and loose precision, or we resolve microseconds.
- Applications might run hours or days, which is 10E5 seconds
- or more. If we cover 12 orders of magnitude (10E6 to 10E-6)
- 32bit unsigned integer will not suffice. Do we introduce
- a 64 signed integer for the purpose of specifying time
- over a duration of several days at microseconds resolution,
- or do we use two 32bit integers, and how do we split them?
- </para></note>
- ]]>
- <![ %RFC [
- <note id="rfc-bk000806-03"><title>RFC: Duration Query</title>
- <para>
- The application might want to cull Sources based on
- how many milliseconds are left for their current buffer
- or queue (either to stop those that will stop soon
- anyway, or to stop those that will take too long,
- depending).
- </para>
- <para>
- We need to divorce sample (memory) count from duration,
- because of compression and differences between
- internal and external sample format.
- </para>
- <para>
- Duration can be queried in microsecond resolution in
- case we want to account for O(10Khz) sampling
- frequencies properly, or milliseconds if we
- do not anticipate the need to go beyond typical
- operating system time resolution.
- </para>
- <para>
- We need query as double, float, and possibly
- long (as of now an undefined data type).
- We might need an INVALID_RANGE error on the getter,
- especially if large reptition counters can be set.
- For paused source, the remainder will be the same
- as for playing sources. The application can query
- the Source State to find out the additional
- information. INFINITE is not needed,
- no is UNKNOWN as we operate on known
- queues.
- </para></note>
- ]]>
- <![ %Scratch [
- <![ %Annote [
- <note><title>Annotation (Buffer vs. Queue Duration)</title><para>
- Sourcel( sName , REMAINDER, &rem ) queries the remainder
- for the current buffer (zero if the Source is STOPPED,
- duration of the first buffer if the source is INITIAL).
- Sourcel( sName, REMAINDER_QUEUE, &rem ) queries the remainder
- of the entire queue.
- A STOPPED Source has remainder==0.
- An INITIAL Source has full remainder.
- </para></note>
- ]]>
- <![ %Annote [
- <note><title>Annotation (DURATION vs. REMAINDER)</title><para>
- DURATION is a buffer attribute independent of
- execution state. REMAINDER is a Source attribute
- that encapsulates part of the execution state.
- Sources and Buffers should not share these attributes:
- there is no Buffer REMAINDER and no Source DURATION.
- </para></note>
- ]]>
- ]]>
- </sect1>
-
-
- <sect1 id="scaling">
- <title>Space and Distance</title>
- <para>
- &AL; does not define the units of measurement for distances.
- The application is free to use meters, inches, or parsecs.
- &AL; provides means for simulating the natural attenuation
- of sound according to distance, and to exagerate or reduce
- this effect. However, the resulting effects do not depend on
- the distance unit used by the application to express source
- and listener coordinates. &AL; calculations are scale
- invariant.
- </para>
- <para>
- The specification assumes Euclidean calculation of
- distances, and mandates that if two Sources are
- sorted with respect to the Euclidean metric, the
- distance calculation used by the implementation has
- to preserve that order.
- </para>
- <![ %Annote [
- <note><title>Annotation (No DistanceFactor)</title><para>
- &AL; does not provide a global, per Context DISTANCE_FACTOR,
- as all calculations are scale invariant.
- </para></note>
- ]]>
-
- <![ %Annote [
- <note><title>Annotation (Distance Calculations)</title><para>
- The specification does not enforce that distances
- are calculated using the euclidean norm, to permit
- using computationally cheaper approximations.
- Implementations that opt to use approximations
- might cause audible artifacts. The specification does
- not enforce any upper limits on distance calculation
- errors yet.
- </para></note>
- ]]>
- <![ %RFC [
- <note id="rfc-bk000915-02"><title>RFC: Limiting Errors</title><para>
- Do we limit permissible errors on distance or gain
- calculations? How much quality
- and accuracy do we expect from conformant implementations?
- </para></note>
- ]]>
- <![ %Annote [
- <note><title>Annotation (DS3D DistanceFactor)</title><para>
- The DS3D documentation explicitely states that the default
- unit is 1 meter. &AL; does not specify any units.
- &AL; calculations are scale invariant. The main purpose
- of the DS3D DistanceFactor (modifying Doppler Shift
- by scaling velocity but not reference velocity) is
- accomplished using DOPPLER_VELOCITY in &AL;. &AL;
- does not have an equivalent to A3D's SetUnitsPerMeter
- either.
- <!-- http://msdn.microsoft.com/library/psdk/directx/dsover_6jj8.htm -->
- </para></note>
- ]]>
- </sect1>
- <sect1 id="attenuation-by-distance">
- <title>Attenuation By Distance</title>
- <para>
- 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.
- </para>
- <para>
- 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.0
- (amplification beyond the guaranteed dynamic range),
- distance and other attenuation might ultimately limit
- the overall GAIN to a value below 1.0.
- </para>
- <para>
- &AL; currently supports three modes of operation
- with respect to distance attenuation. It supports
- two distance-dependent attenuation models, including one
- that is similar to the IASIG I3DL2 (and DS3D) model.
- The application chooses one of these two models (or
- chooses to disable distance-dependent attenuation)
- on a per-context basis.
- <funcsynopsis><funcprototype>
- <funcdef> void <function> DistanceModel </function></funcdef>
- <paramdef> &enum; <parameter> modelName </parameter></paramdef>
- </funcprototype></funcsynopsis>
- Legal arguments are NONE, INVERSE_DISTANCE, and
- INVERSE_DISTANCE_CLAMPED. NONE bypasses all distance
- attenuation calculation for all Sources. The implementation
- is expected to optimize this situation. INVERSE_DISTANCE_CLAMPED
- is the DS3D model, with REFERENCE_DISTANCE indicating both the
- reference distance and the distance below which gain will
- be clamped. INVERSE_DISTANCE is equivalent to the DS3D model
- with the exception that REFERENCE_DISTANCE does not imply any
- clamping. The &AL; implementation is still free to apply
- any range clamping as necessary. The current distance model
- chosen can be queried using GetIntegerv and DISTANCE_MODEL.
- </para>
- <![ %Annote [
- <note><title>Annotation (Inverse Square Law)</title><para>
- The "inverse square law" used in physics applies to sound
- intensity (energy), which is proportional to the square
- of linear gain (amplitude). Thus the inverse distance model
- describes a physically correct inverse square behavior
- if ROLLOFF_FACTOR is set to 1.0.
- </para></note>
- ]]>
- <![ %Annote [
- <note><title>Annotation (Enable/Disable Attenuation)</title><para>
- As ROLLOFF_FACTOR is a per-Source attribute, setting it to zero
- can not be used to globally enable or disable distance
- attenuation, which (e.g. when using tables) can be resource
- intensive. Using Enable/Disable/IsEnabled with a DISTANCE_ATTENUATION
- token is redundant with respect to the possibility that support
- for different distance models might be desired at a later time.
- </para></note>
- ]]>
-
- <sect2>
- <title>Inverse Distance Rolloff Model</title>
- <para>
- The following formula describes the distance attenutation
- defined by the Rolloff Attenutation Model, as logarithmic
- calculation.
- <literallayout>
- G_dB = GAIN - 20*log10(1 + ROLLOFF_FACTOR*(dist-REFERENCE_DISTANCE)/REFERENCE_DISTANCE );
- G_dB = min(G_dB,MAX_GAIN);
- G_dB = max(G_dB,MIN_GAIN);
- </literallayout>
- The REFERENCE_DISTANCE parameter used here is a per-Source attribute
- that can be set and queried using the REFERENCE_DISTANCE token.
- REFERENCE_DISTANCE is the distance at which the Listener will
- experience GAIN (unless the implementation had to clamp effective
- GAIN to the available dynamic range).
- ROLLOFF_FACTOR is per-Source parameter the application can use
- to increase or decrease the range of a source by decreasing
- or increasing the attenuation, respectively. The default value
- is 1. The implementation is free to optimize for a
- ROLLOFF_FACTOR value of 0, which indicates that the application
- does not wish any distance attenuation on the respective Source.
- </para>
- <![ %Annote [
- <note><title>Annotation (Linear Calculation)</title><para>
- The logarithmic formula above is equivalent to
- <literallayout>
- G = gain_linear / ( 1 + ROLLOFF_FACTOR*((dist-REFERENCE_DISTANCE)/REFERENCE_DISTANCE) );
- G = min(G,max_gain_linear);
- G = max(G,min_gain_linear);
- </literallayout>
- with linear gains calculated from the logarithmic GAIN,
- MIN_GAIN, MAX_GAIN accordingly.
- By means of explanation: linear GAIN is applied to the sample, which describes
- an amplitude ultimately (DAC) converted into voltage. The actual power of the
- signal is proportional to the square of the amplitude (voltage). Logarithmic
- measurement is done by comparing the actual power with a reference value,
- i.e. the power (e.g in Watt) at the reference distance. The original Bel unit
- of measure (named after Alexander Graham Bell) was defined to account for the
- logarithmic response of the human ear: our subjective impression of "loudness"
- is not linear in the power of the acoustic signal. For practical purposes (range
- of volumes the human ear can handle) the deciBel (dB) is a better unit:
- <literallayout>
- dB = 10 * log( P/P0 ) = 10 * log( sqr(A/A0 ) = 20 * log( A/A0 )
- </literallayout>
- Common power/amplitude ratios and attenuations per distance are:
- <table>
- <title>Logarithmic Scale and Gain</title>
- <tgroup cols="4" align="left" colsep=1 rowsep=1>
- <thead>
- <row>
- <entry>Distance</>
- <entry>Attenuation</>
- <entry>Power Ratio</>
- <entry>Amplitude Ratio</>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>REF</>
- <entry> 0dB </>
- <entry> 1:1 </>
- <entry> 1:1 </>
- </row>
- <row>
- <entry> 2*REF </>
- <entry> -6dB </>
- <entry> 1:4 </>
- <entry> 1:2 </>
- </row>
- <row>
- <entry> 4*REF </>
- <entry> -12dB </>
- <entry> 1:16 </>
- <entry> 1:4 </>
- </row>
- <row>
- <entry> 8*REF </>
- <entry> -18dB </>
- <entry> 1:64 </>
- <entry> 1:8 </>
- </row>
- <row>
- <entry> 0.5*REF </>
- <entry> 6dB </>
- <entry> 2:1 </>
- <entry> 4:1 </>
- </row>
- <row>
- <entry> 0.25*REF </>
- <entry> 12dB </>
- <entry> 4:1 </>
- <entry> 16:1 </>
- </row>
- </tbody>
- </tgroup>
- </table>
- The logarithmic gain will drop from zero (linear gain 1) to negative infinity
- (approaching linear gain 0). A linear gain of zero can not be represented
- logarithmically. Any doubling of the reference distance will add another
- -6dB (i.e. 6dB of attenuation). This approximates an inverse square law falloff
- of signal power with distance, as long as the distance exceeds the reference
- distance.
- </para></note>
- ]]>
- <![ %Annote [
- <note><title>Annotation (Rolloff quantization)</title><para>
- Implementations that use lookup tables to speed up
- distance attenuation calculation may opt to map
- ROLLOFF_FACTOR to a limited set of internally used
- values, to minimize expense of per-Source calculations
- and setup/memory costs.
- </para></note>
- ]]>
- <![ %Annote [
- <note><title>Annotation (Gain Clamping)</title><para>
- In the absence of user MIN_GAIN and MAX_GAIN selections,
- clamping is implied by implementation constraints, and
- clamping behavior might change.
- The &AL; implementation should not clamp intermediate
- values of effective gain to unit range.
- Any clamping, if necessary, should be applied at the latest
- possible stage. In other words, GAIN>1 is perfectly
- valid as the implementation is free to clamp the value as
- needed for maximum mixing accuracy and to account for the
- actual dynamic range of the output device.
- </para></note>
- ]]>
- <![ %Annote [
- <note><title>Annotation (Extended Dynamic Range)</title><para>
- For applications that
- change GAIN but do not want to adjust ROLLOFF_FACTOR
- and REFERENCE_DISTANCE to account for different ranges,
- the separation in this distance model might allow for
- more intuitive adjustments:
- If we put a damper on the jet engine by lowering GAIN,
- we still want the listener to perceive the full volume,
- but now at a closer distance, without changing the
- reference distance.
- </para></note>
- ]]>
- </sect2>
- <sect2>
- <title>Inverse Distance Clamped Model</title>
- <para>
- This is essentially the Inverse Distance model,
- extended to guarantee that for distances below
- REFERENCE_DISTANCE, gain is clamped. This mode
- is equivalent to the IASIG I3DL2 (and DS3D) distance
- model.
- <literallayout>
- dist = max(dist,REFERENCE_DISTANCE);
- dist = min(dist,MAX_DISTANCE);
- G_dB = GAIN - 20*log10(1 + ROLLOFF_FACTOR*(dist-REFERENCE_DISTANCE)/REFERENCE_DISTANCE )
- G_dB = min(G_dB,MAX_GAIN);
- G_dB = max(G_dB,MIN_GAIN);
- </literallayout>
- </para>
-
- <![ %Annote [
- <note><title>Annotation (DS3D MIN_DISTANCE)</title><para>
- The DS3D attenuation model is extended by an explicit
- clamping mechanism. REFERENCE_DISTANCE is equivalent
- to DS3D MIN_DISTANCE if the INVERSE_DISTANCE_CLAMPED
- mode is used.
- </para></note>
- ]]>
- <![ %Annote [
- <note><title>Annotation (High Frequency Rolloff)</title><para>
- To simulate different atmospheric conditions, a frequency
- dependent attenuation is used in A3D and EAX.
- At this time &AL; does not have a mechanism to specify
- lowpass filtering parameterized by distance.
- </para></note>
- ]]>
- </sect2>
- </sect1>
- <sect1 id="order-distance">
- <title>Evaluation of Gain/Attenuation Related State</title>
- <para>
- While amplification/attenuation commute (mulplication 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 (REFERENCE_DISTANCE) and maximum (MAX_DISTANCE)
- thresholds. If the Source is directional (CONE_INNER_ANGLE
- less than CONE_OUTER_ANGLE), an angle-dependent attenuation
- is calculated depending on CONE_OUTER_GAIN, and multiplied
- with the distance dependent attenuation.
- The resulting attenuation factor for the given angle and
- distance between Listener and Source is multiplied
- with Source GAIN. The effective GAIN computed this way
- is compared against MIN_GAIN and MAX_GAIN thresholds.
- The result is guaranteed to be clamped to [MIN_GAIN, MAX_GAIN],
- 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.
- </para>
- </sect1>
-
- <sect1 id="culling-by-distance">
- <title>No Culling By Distance</title>
- <para>
- With the DS3D compatible Inverse Clamped Distance Model,
- &AL; provides a per-Source MAX_DISTANCE 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 proccessing,
- based on distance. However, &AL; does not
- support culling a Source from processing based on a distance
- threshold.
- </para>
- <para>
- At this time &AL; 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 &AL;. 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.
- </para>
- <![ %Annote [
- <note><title>Annotation (No MAX_DISTANCE plus MUTE)</title><para>
- &AL; does support the AUDIBLE mode with MAX_DISTANCE (clamping),
- but does not support culling. Applications that employ this
- DS3D feature will have to perform their own distance calculation
- and mute the source (Source GAIN equals zero) as desired.
- </para></note>
- ]]>
- <![ %RFC [
- <note id="rfc-bk000803-07"><title>RFC: DS3D-like Extension</title><para>
- For ease of portability, should we define an Extension that
- provides MAX_DISTANCE for MUTE mode?
- </para></note>
- ]]>
- </sect1>
-
- <![ %Scratch [
- <sect1 id="sound-speed">
- <title>NO Sound Propagation Speed</title>
- <para>
- &AL; implementations can choose to model sound propagation with
- limited speed for certain effects, e.g. early reflections.
- In addition, the Doppler Effect is defined with respect to the
- speed of sound in the predominant medium. The application can
- set the speed of sound as a scalar value. The speed is defined
- with respect to the scaled unit. If D I S T A N C E _ S C A L E is changed,
- this will affect both the distance and the propagation speed,
- leaving the propagation time unaffected.
- <funcsynopsis><funcprototype>
- <funcdef> void <function> PropagationSpeed </function></funcdef>
- <paramdef> &float; <parameter> propSpeed </parameter></paramdef>
- </funcprototype></funcsynopsis>
- </para>
- <para>
- A negative scale will result in an INVALID_VALUE error, the
- command is then ignored. The default value is 1. The current
- setting can be queried using GetFloatv and PROPAGATION_SPEED.
- </para>
- </sect1>
- ]]>
-
- <sect1 id="doppler-scale">
- <title>Velocity Dependent Doppler Effect</title>
- <para>
- The Doppler Effect depends on the velocities of Source and
- Listener relative to the medium, and the propagation speed
- of sound in that medium. The application might want to
- emphasize or de-emphasize the Doppler Effect as physically
- accurate calculation might not give the desired results. The
- amount of frequency shift (pitch change) is proportional
- to the speed of listener and source along their line of
- sight. The application can increase or decrease that
- frequency shift by specifying the scaling factor &AL;
- should apply to the result of the calculation.
- </para>
- <para>
- The Doppler Effect as implemented by &AL; is described
- by the formula below. Effects of the medium (air, water)
- moving with respect to listener and source are ignored.
- DOPPLER_VELOCITY is the propagation speed relative to
- which the Source velocities are interpreted.
- <literallayout>
- VD: DOPPLER_VELOCITY
- DF: DOPPLER_FACTOR
- vl: Listener velocity (scalar, projected on source-listener vector)
- vs: Source velocity (scalar, projected on source-listener vector)
- f: Frequency of sample
- f': effective Doppler shifted frequency
- f' = DF * f * (VD-vl)/(VD+vs)
- vl<0, vs>0 : source and listener approaching each other
- vl>0, vs<0 : source and listener moving away from each other
- </literallayout>
- The implementation has to clamp the projected Listener
- velocity vl, if abs(vl) is greater or equal to VD. It similarly has to
- clamp the projected Source velocity vs if abs(vs) is greater or equal
- to VD.
- </para>
- <para>
- There are two API calls global to the current context that provide
- control of the two related parameters. DOPPLER_FACTOR is a simple
- scaling to exaggerate or deemphasize the Doppler (pitch) shift
- resulting from the calculation.
- <funcsynopsis><funcprototype>
- <funcdef> void <function> DopplerFactor </function></funcdef>
- <paramdef> &float; <parameter> dopplerFactor </parameter></paramdef>
- </funcprototype></funcsynopsis>
- A negative value will result in an INVALID_VALUE error, the
- command is then ignored. The default value is 1. The current
- setting can be queried using GetFloatv and DOPPLER_FACTOR.
- The implementation is free to optimize the case of DOPPLER_FACTOR
- being set to zero, as this effectively disables the effect.
- </para>
- <![ %Annote [
- <note><title>Annotation (No Enable)</title><para>
- There is currently no mechanism to switch on/off Doppler
- calculation using e.g. a DOPPLER_SHIFT token and Enable/Disable.
- For the time being, DopplerFactor(0) may be used to signal
- to the implementation that no Doppler Effect calculation is
- required.
- </para></note>
- ]]>
-
- <para>
- DOPPLER_VELOCITY allows the application to change the
- reference (propagation) velocity used in the Doppler Effect
- calculation. This permits the application to use a velocity
- scale appropriate to its purposes.
- <funcsynopsis><funcprototype>
- <funcdef> void <function> DopplerVelocity </function></funcdef>
- <paramdef> &float; <parameter> dopplerVelocity</parameter></paramdef>
- </funcprototype></funcsynopsis>
- A negative or zero value will result in an INVALID_VALUE error, and the
- command is ignored. The default value is 1.
- The current setting can be queried using GetFloatv and DOPPLER_VELOCITY.
- </para>
-
- <![ %Annote [
- <note><title>Annotation (No Sideeffects on Delay)</title><para>
- To permit independent control of Doppler Effect as opposed
- to other, sound wave propagation related effects (delays,
- echos, reverberation), DOPPLER_VELOCITY is not taken into
- account for any other calculation than Doppler Shift.
- </para></note>
- ]]>
- <![ %Annote [
- <note><title>Annotation (SetUnitsPerMeter)</title><para>
- DOPPLER_VELOCITY accomplishes the purposes of DS3D
- scaling parameters in a straightforward way, without
- introducing the undesirable connotations of real world
- units.
- </para></note>
- ]]>
- </sect1>
- </chapter>
|