Sophie

Sophie

distrib > Mandriva > 10.0 > i586 > by-pkgid > 7f05d609815afe07559d02c744017379 > files > 30

libopenal0-devel-0.0.6-13mdk.i586.rpm


    <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> &int;* <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, &amp;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, &amp;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&gt;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>