]> icculus.org git repositories - icculus/iodoom3.git/blob - neo/openal/docs/chp-rendering.sgml
hello world
[icculus/iodoom3.git] / neo / openal / docs / chp-rendering.sgml
1
2
3     <chapter id="rendering">
4      <title>Listener and Sources</title>
5
6     <sect1 id="object-state">
7      <title>Basic Listener and Source Attributes</title>
8     <para>
9        This section introduces basic attributes that can be set both for 
10        the Listener object and for Source objects.
11     </para>
12
13     <![ %RFC [
14      <note id="rfc-bk000619-02"><title>RFC: attribute grouping</title><para>
15        JM: "These attributes are of
16        two types:  non-positional and positional.
17        Non-positional properties include gain control and Environment Name."
18      </para><para>
19       I said: (low pass) Filters are applied to the sound during processing 
20       at various stages. The exact sequence in which Filters are applied is 
21       determined based on the location of the Objects they are 
22       set for - spatial arrangement of Objects determines the
23       sequence unless invariance is guaranteed, or invariance
24      violation is permitted by the specification and current &AL;
25      configuration state.
26       </para><para>
27       Is there a required order of application, i.e. a pipeline? 
28       </para><para>
29       Filter Parameters vs. Non-positional properties.
30       Spatialization vs. Positional properties.
31       Spatial attributes?
32       Let's postpone grouping of attributes. 
33       </para></note>
34      ]]>
35
36    
37     <para>
38       The &AL; Listener and Sources have attributes to describe 
39       their position, velocity and orientation in three dimensional space.
40       &AL; like &OGL;, uses a right-handed Cartesian coordinate system (RHS), 
41       where in a frontal default view X (thumb) points right,
42       Y (index finger) points up, and Z (middle finger) points towards 
43       the viewer/camera. To switch from a left handed coordinate system (LHS)
44       to a right handed coordinate systems, flip the sign on the Z coordinate.
45     </para>
46
47     <para>
48     <table>
49     <title>Listener/Source Position</title>
50     <tgroup cols="4" align="left" colsep=1 rowsep=1>
51     <thead>
52     <row>
53        <entry>&Par;</>
54        <entry>&Sig;</>
55        <entry>&Val</>
56        <entry>&Def;</>        
57     </row>
58     </thead>
59     <tbody>
60     <row>
61        <entry>POSITION</>
62        <entry>3fv, 3f</>
63        <entry> any except NaN </>
64        <entry> { 0.0f, 0.0f, 0.0f } </>        
65     </row>
66     </tbody>
67     </tgroup>
68     </table>
69     Description:
70         POSITION specifies the current location of the Object in the
71         world coordinate system. Any 3-tuple of valid float/double values 
72         is allowed. Implementation behavior on encountering &NaN; and &Infty; 
73         is not defined. The Object position is always defined in the
74         world coordinate system.
75     </para>
76
77     <![ %Annote [
78       <note><title>Annotation (No Transformation)</title><para>
79         &AL; does not support transformation operations on Objects.
80         Support for transformation matrices is not planned.
81        </para></note>
82     ]]>
83
84
85     <para>
86     <table>
87     <title>Listener/Source Velocity</title>
88     <tgroup cols="4" align="left" colsep=1 rowsep=1>
89     <thead>
90     <row>
91        <entry>&Par;</>
92        <entry>&Sig;</>
93        <entry>&Val</>
94        <entry>&Def;</>        
95     </row>
96     </thead>
97     <tbody>
98     <row>
99        <entry>VELOCITY</>
100        <entry>3fv, 3f</>
101        <entry> any except NaN </>
102        <entry> { 0.0f, 0.0f, 0.0f } </>        
103     </row>
104     </tbody>
105     </tgroup>
106     </table>     
107     Description:
108         VELOCITY specifies the current velocity (speed and direction) of
109         the Object, in the world coordinate system. Any 3-tuple of valid 
110         float/double values is allowed. The Object VELOCITY does not affect 
111         its position.
112         &AL; does not calculate the velocity from subsequent position
113         updates, nor does it adjust the position over time based on
114         the specified velocity. Any such calculation is left to the
115         application. For the purposes of sound processing, position and
116         velocity are independent parameters affecting different aspects
117         of the sounds. 
118        </para><para>
119         VELOCITY is taken into account by the driver to synthesize the 
120         Doppler effect perceived by the Listener for each source, based 
121         on the velocity of both Source and Listener, and the Doppler
122         related parameters.
123     </para>
124
125
126
127
128     <para>
129     <table>
130     <title>Listener/Source Gain (logarithmic)</title>
131     <tgroup cols="4" align="left" colsep=1 rowsep=1>
132     <thead>
133     <row>
134        <entry>&Par;</>
135        <entry>&Sig;</>
136        <entry>&Val</>
137        <entry>&Def;</>        
138     </row>
139     </thead>
140     <tbody>
141     <row>
142        <entry>GAIN</>
143        <entry>f</>
144        <entry>0.0f, (0.0f, any</>
145        <entry> 1.0f</>        
146     </row>
147     </tbody>
148     </tgroup>
149     </table>
150      Description:
151         GAIN defines a scalar amplitude multiplier. As a Source attribute, it applies
152         to that particular source only. As a Listener attribute, it effectively
153         applies to all Sources in the current Context. The default 1.0 means 
154         that the sound is un-attenuated. A GAIN value of 0.5 is equivalent to 
155         an attenuation of 6 dB. The value zero equals silence (no output). Driver 
156         implementations are free to optimize this case and skip mixing and 
157         processing stages where applicable. The implementation is in charge of 
158         ensuring artifact-free (click-free) changes of gain values and is free 
159         to defer actual modification of the sound samples, within the limits of 
160         acceptable latencies.
161     </para>
162     <para>
163         GAIN larger than 1 (amplification) is permitted for Source and
164         Listener. However, the implementation is free to clamp the
165         total gain (effective gain per source times listener gain)
166         to 1 to prevent overflow.
167     </para>
168
169
170     <![ %Annote [
171       <note><title>Annotation/ Effective Minimal Distance</title><para>
172          Presuming that the sample uses the entire dynamic range of
173          the encoding format, an effective gain of 1 represents the 
174          maximum volume at which a source can reasonably be played.
175          During processing, the implementation combines the Source
176          GAIN (or MIN_GAIN, if set and larger) with distance based
177          attenuation. The distance at which the effective gain is 1
178          is equivalent to the DirectSound3D MIN_DISTANCE parameter.  
179          Once the effective gain has reached the maximum possible
180          value, it will not increase with decreasing distance anymore.
181       </para></note>
182     ]]>
183
184    
185     <![ %Annote [
186       <note><title>Annotation (Muting a Context)</title><para>
187          To mute the current context, simply set Listener GAIN to zero.
188          The implementation is expected to optimize for this case,
189          calculating necessary (offset) updates but bypassing the 
190          mixing and releasing hardware resources.
191          The specification does not guarantee that the implementation
192          will release hardware resources used by a muted context.
193        </para></note>
194     ]]>
195
196     <![ %Annote [
197       <note><title>Annotation (Muting a Source)</title><para>
198         To mute a Source, set Source GAIN to zero. The &AL; implementation
199         is encouraged to optimize for this case. 
200        </para></note>
201     ]]>
202
203     <![ %RFC [
204     <para>
205         <note id="rf-bk000503-01"><title>RFC: GAIN &gt; 1?</title><para>       
206         GAIN could exceed 1 (to compensate attenuation elsewhere, or to account 
207         for grater dynamic range of the hardware? No guarantees are made with 
208         respect to range overflows? Precision loss? Culling by effective gain?
209         Does &AL; clip values during processing, and when/at what stages?
210         </para></note>
211
212         <note id="rfc-bk000619-01"><title>RFC: Doppler</title><para>
213         JM wrote: "VELOCITY is used by the driver
214         to synthesize the Doppler effect perceived by the listener for each
215         source, based on the relative velocity of this source with respect
216         to the listener."
217         Doppler is calculated using Source and Listener velocities measured 
218         with respect to the medium. Do we have to account for the medium
219         to move (offsetting listener/source) in later revisions (air/water currents)?
220         </para></note>
221    
222         <note id="rfc-bk000619-03"><title>RFC: </title><para>
223         JM removed: "For the purposes of sound processing, position and
224         velocity are independent parameters affecting different paths
225         in the sound synthesis." I think the "different aspects of sounds"
226         is ambiguous. Is there a problem with describing &AL; as a
227         multichannel processing machine?
228         </para></note>
229     </para>
230      ]]>
231
232     </sect1>
233
234
235     <sect1 id="object-listener">
236      <title>Listener Object</title>
237
238     <para>
239      The Listener Object defines various properties that affect processing of
240      the sound for the actual output. The Listener is unique for an &AL; Context,
241      and has no Name. By controlling the listener, the application controls
242      the way the user experiences the virtual world, as the listener defines
243      the sampling/pickup point and orientation, and other parameters that
244      affect the output stream.
245     </para>
246     <para>
247       It is entirely up to the driver and hardware configuration, i.e.
248       the installation of &AL; as part of the operating system and
249       hardware setup, whether the output stream is generated for
250       headphones or 2 speakers, 4.1 speakers, or other arrangements,
251       whether (and which) HRTF's are applied, etc..
252     </para>
253     
254     <![ %Annote [
255       <note><title>Annotation (Listener Anatomy)</title><para>
256        The API is ignorant with respect to the real world 
257        listener, it does not need to make assumptions on the 
258        listening capabilities of the user, its species or its 
259        number of ears. It only describes a scene and the position 
260        of the listener in this scene.  It is the &AL; implementation
261        that is designed for humans with ears on either side of the 
262        head.
263        </para></note>
264     ]]>
265
266  
267     <![ %Annote [
268       <note><title>Annotation (Listener State Evaluation)</title><para>
269        Some Listener state (GAIN) affects only the very last
270        stage of sound synthesis, and is thus applied to the sound stream 
271        as sampled at the Listener position. Other Listener state is
272        applied earlier. One example is Listener velocity as used to 
273        compute the amount of Doppler pitch-shifting applied to each source:
274        In a typical implementation, pitch-shifting (sample-rate conversion) 
275        might be the first stage of the audio processing for each source.
276        </para></note>
277     ]]>
278
279
280     <sect2>
281     <title>Listener Attributes</title>
282
283     <para>
284       Several Source attributes also apply to Listener: e.g. POSITION, VELOCITY,
285       GAIN. In addition, some attributes are listener specific.
286     <table>
287     <title>Listener Orientation</title>
288     <tgroup cols="4" align="left" colsep=1 rowsep=1>
289     <thead>
290     <row>
291        <entry>&Par;</>
292        <entry>&Sig;</>
293        <entry>&Val</>
294        <entry>&Def;</>        
295     </row>
296     </thead>
297     <tbody>
298     <row>
299        <entry>ORIENTATION</>
300        <entry> fv </>
301        <entry> any except NaN </>
302        <entry>  { { 0.0f, 0.0f, -1.0f },       { 0.0f, 1.0f, 0.0f } } </>        
303     </row>
304     </tbody>
305     </tgroup>
306     </table>
307       Description:
308         ORIENTATION is a pair of 3-tuples representing the 'at' direction vector  
309         and 'up' direction of the Object in Cartesian space. &AL; expects two
310         vectors that are orthogonal to each other. These
311         vectors are not expected to be normalized. If one or more vectors 
312         have zero length, implementation behavior is undefined. If the two
313         vectors are linearly dependent, behavior is undefined.
314      </para>
315      <![ %RFC [
316       <note id="rfc-bk000503-01"><title>RFC: Orientation Paranoia</title><para>
317         Watch LHS vs. RHS (sign on 'at'). 
318         Confirm sequence is (up, at) not vice versa.
319         Do we want to allow for different representations down the road?
320       </para></note>
321      ]]>
322     </sect2>
323
324     <sect2>
325     <title>Changing Listener Attributes</title>
326     <para>
327       Listener attributes are changed using the Listener group of commands.
328       <funcsynopsis><funcprototype> 
329       <funcdef> void <function> Listener{n}{sifd}{v} </function></funcdef>
330       <paramdef> &enum; <parameter> paramName </parameter></paramdef>
331       <paramdef> &type; <parameter> values </parameter></paramdef>
332       </funcprototype></funcsynopsis>
333     </para>
334     </sect2>
335
336     <sect2>
337     <title>Querying Listener Attributes</title>
338     <para>
339       Listener state is maintained inside the &AL; implementation and can be
340       queried in full. See Querying Object Attributes. The valid values for 
341       paramName are identical to the ones for the Listener* command.
342       <funcsynopsis><funcprototype> 
343       <funcdef> void <function> GetListener{sifd}v </function></funcdef>
344       <paramdef> &enum; <parameter> paramName </parameter></paramdef>
345       <paramdef> &type;* <parameter> values </parameter></paramdef>
346       </funcprototype></funcsynopsis>
347     </para>
348     </sect2>
349    </sect1>
350
351
352
353   <sect1 id="object-sources">
354      <title>Source Objects</title>
355      <para>
356        Sources specify attributes like position, velocity, and a buffer with
357        sample data. By controlling a Source's attributes the
358        application can modify and parameterize the static sample data provided
359        by the Buffer referenced by the Source.
360        Sources define a localized sound, and encapsulate 
361        a set of attributes applied to a sound at its origin, i.e. in the 
362        very first stage of the processing on the way to the listener. 
363        Source related effects have to be applied 
364        before Listener related effects unless the output is invariant
365        to any collapse or reversal of order. 
366      </para>
367      <para>
368       &AL; also provides additional functions to manipulate and query the
369       execution state of Sources: the current playing status of a 
370       source (started, stopped, paused), including access to the current
371       sampling position within the associated Buffer. 
372      </para>
373   
374     <![ %RFC [
375       <note id="rfc-briareos000629-01"><title>RFC: Mike on Source Types</title><para>  
376         AL_SOURCE_ABSOLUTE and AL_SOURCE_AMBIENT have been
377         deprecated. AL_SOURCE_ABSOLUTE was simply the converse of the
378         AL_SOURCE_RELATIVE pname, and as such was unnecessary. The
379         effect of AL_SOURCE_AMBIENT is trivially emulated by either
380         querying the Listener position and setting the Source position
381         accordingly, or setting the Source position to (0,0,0) and the
382         type to AL_SOURCE_RELATIVE, and is therefore also unnecessary.
383       </para></note>
384    ]]>
385  
386
387    <![ %RFC [
388      <note id="rfc-bk000721-02"><title>RFC: Bernd on Source Types</title><para>
389        Mike seems to miss a few problems here. W/o a converse we can't
390        reset source attributes to ABSOLUTE. Ambient sounds are not 
391        necessarily trivial. A3D manual suggested some magic number
392        to fake the effect of ambient (i.e. sound that ideally
393        can't be localized by listener). If we can get away with such magic 
394        numbers in a tutorial in a driver-independent way, fine. If there is any
395        risk that the impression of ambient sound requires driver specific
396        hacks, then we need AMBIENT. As soon as we have a third localization
397        type, ABSOLUTE and RELATIVE are needed as there is no unambiguous
398        converse.
399
400        From the A3D 2.0 Optimize.doc: 
401        "Adding some ambient background noise is a great way to fill in the gaps 
402         when the audio content is reduced.  A great way to make an ambient sound 
403         seem like it is coming from everywhere is to load up two buffers with the 
404         same sound, and position them about 2 meters behind the listener at 
405         about 4 and 8 o\rquote clock.  The waves have to be looping (make sure
406         there is no beating when you play them back).  Starting the sounds 180 
407         degrees out of phase can help, as will playing them with slightly different 
408         pitch-shift values." 
409      </para></note>
410    ]]>
411
412    <![ %RFC [
413      <note id="rfc-bk000721-03"><title>RFC: Bernd on Source Types (2)</title><para>
414        There is a point to be made in using POSITION_RELATIVE and
415        VELOCITY_RELATIVE iff we do not have AMBIENT to consider.
416        This makes it a call-by-call choice when setting Source3f{v} 
417        vectors, as it is applied when dereferencing.
418    </para></note>
419    ]]>
420
421    <![ %RFC [
422      <note id="rfc-bk000721-04"><title>RFC: Bernd on Source Types (3)</title><para>
423        Semantically, AMBIENT has nothing to do with coordinate systems, 
424        it is a qualifier just like multichannel direct passthru.
425    </para></note>
426    ]]>
427
428     <![ %RFC [
429       <note id="rfc-bk000721-05"><title>RFC:  Source Attenuation Clamping</title><para>  
430          Using AL_SOURCE_ATTENUATION_MIN and AL_SOURCE_ATTENUATION_MAX
431          to specify the clamping values for the normalized attenuation
432          factor (which is a function of distance) is in contradiction
433          to the distance based model that Creative is pushing for
434          (DirectSound). As driver-interall culling of source and other
435          processing might be based on the effective (overall, ultimate)
436          gain composed of amplifications and attenuations accumulated
437          over the entire processing, I raise the question whether a sound
438          designer might not want to control the effective GAIN ranges
439          instead of the distance attenuation itself. Samples commonly
440          use the entire dynamic range provided by the format, which is
441          mapped to the entire dynamic range of the output device. An
442          effective gain exceeding 1 does not make sense, an amplification
443          during processing might.
444       </para></note>
445     ]]>
446     
447
448
449
450
451     <sect2>
452     <title>Managing Source Names</title>
453     <para> 
454      &AL; provides calls to request and release Source Names handles.
455      Calls to control Source Execution State are also provided.
456     </para>
457
458     <sect3>
459     <title>Requesting a Source Name</title>
460     <para>
461      The application requests a number of Sources using GenSources.
462       <funcsynopsis><funcprototype> 
463       <funcdef> &void; <function> GenSources </function></funcdef>
464       <paramdef> &sizei; <parameter> n </parameter></paramdef>
465       <paramdef> &uint;* <parameter> sources </parameter></paramdef>
466       </funcprototype></funcsynopsis>
467     </para>
468    </sect3>
469
470
471    <sect3>
472    <title>Releasing Source Names</title>
473    <para>
474      The application requests deletion of a number of Sources
475      by DeleteSources.
476       <funcsynopsis><funcprototype> 
477       <funcdef> &void; <function> DeleteSources </function></funcdef>
478       <paramdef> &sizei; <parameter> n </parameter></paramdef>
479       <paramdef> &uint;* <parameter> sources </parameter></paramdef>
480       </funcprototype></funcsynopsis>
481     </para>
482    </sect3>
483
484    <sect3>
485    <title>Validating a Source Name</title>
486    <para>
487      The application can verify whether a source name is valid
488      using the IsSource query.
489       <funcsynopsis><funcprototype> 
490       <funcdef> &bool; <function> IsSource </function></funcdef>
491       <paramdef> &uint; <parameter> sourceName </parameter></paramdef>
492       </funcprototype></funcsynopsis>
493     </para>
494    </sect3>
495    </sect2>
496
497
498     <sect2>
499     <title>Source Attributes</title>
500     <para>
501         This section lists the attributes that are set per Source,
502         affecting the processing of the current buffer. Some of
503         these attributes can also be set for buffer queue entries.
504     </para> 
505     <![ %Annote [
506       <note><title>Annotation (No Priorities)</title><para>
507          There are no per Source priorities, and no explicit priority
508          handling, defined at this point. A mechanism that lets the
509          application express preferences in case that the implementation
510          provides culling and prioritization mechanisms might be added
511          at some later time. This topic is under discussion for GL as
512          well, which already has one exlicit priority API along with 
513          internally used MRU heuristics (for resident texture memory). 
514        </para></note>
515     ]]>
516  
517
518
519
520     <sect3>
521     <title>Source Positioning</title>
522     <para>
523     <table>
524     <title>SOURCE_RELATIVE Attribute</title>
525     <tgroup cols="4" align="left" colsep=1 rowsep=1>
526     <thead>
527     <row>
528        <entry>&Par;</>
529        <entry>&Sig;</>
530        <entry>&Val</>
531        <entry>&Def;</>        
532     </row>
533     </thead>
534     <tbody>
535     <row>
536        <entry> SOURCE_RELATIVE </>
537        <entry> &bool; </>
538        <entry> FALSE, TRUE</>
539        <entry> FALSE </>        
540     </row>
541     </tbody>
542     </tgroup>
543     </table>
544        SOURCE_RELATIVE set to TRUE indicates that the values
545        specified by POSITION are to be interpreted relative 
546        to the listener position.
547     </para>
548
549
550     <![ %Annote [
551       <note><title>Annotation (Position only)</title><para>
552         SOURCE_RELATIVE does not affect velocity or orientation
553         calculation.
554        </para></note>
555     ]]>
556
557     </sect3>
558
559     <sect3>
560     <title>Buffer Looping</title>
561     <para>
562     <table>
563     <title>Source LOOPING  Attribute</title>
564     <tgroup cols="4" align="left" colsep=1 rowsep=1>
565     <colspec colname=c1>
566     <colspec colname=c2>
567     <colspec colname=c3>
568     <colspec colname=c4>
569     <spanspec spanname=hspan namest=c1 nameend=c4 align=left>
570     <thead>
571     <row>
572        <entry>&Par;</>
573        <entry>&Sig;</>
574        <entry>&Val</>
575        <entry>&Def;</>        
576     </row>
577     </thead>
578     <tbody>
579     <row>
580        <entry> LOOPING </>
581        <entry> &uint; </>
582        <entry> TURE, FALSE</>
583        <entry> FALSE </>        
584     </row>
585     </tbody>
586     </tgroup>
587     </table>
588      Description:
589        LOOPING is a flag that indicates that the Source will not 
590        be in STOPPED state once it reaches the end of last buffer
591        in the buffer queue. Instead, the Source will immediately
592        promote to INITIAL and PLAYING. The default value is FALSE.
593        LOOPING can be changed on a Source in any execution state.
594        In particular, it can be changed on a PLAYING Source.
595     </para>
596
597     <![ %Annote [
598       <note><title>Annotation (Finite Repetition)</title><para>
599         Finite reptition is implemented by buffer queueing.
600        </para></note>
601     ]]>
602
603     <![ %Annote [
604       <note><title>Annotation (Loop Control)</title><para>
605         To implement a 3 stage "loop point" solution, the
606         application has to queue the FadeIn buffer first,
607         then queue the buffer it wants to loop, and set 
608         LOOPING to TRUE once the FadeIn buffer has been
609         processed and unqueued. To fade from looping, the 
610         application can queue a FadeOut buffer, then
611         set LOOPING to false on the PLAYING source. Alternatively,
612         the application can decide to not use the LOOPING
613         attribute at all, and just continue to queue the buffer
614         it wants repeated. 
615        </para></note>
616     ]]>
617
618     <![ %Annote [
619       <note><title>Annotation (Rejected alternatives)</title><para>
620         A finite loop counter was rejected because it is
621         ambiguous with respect to persistent (initial counter) 
622         vs. transient (current counter). For similar reasons,
623         a Play-equivalent command with a (transient) loop counter
624         was rejected.  
625       </para></note>
626     ]]>
627     </sect3>
628
629     <sect3>
630     <title>Current Buffer</title>
631     <para>
632     <table>
633     <title>Source BUFFER Attribute</title>
634     <tgroup cols="4" align="left" colsep=1 rowsep=1>
635     <thead>
636     <row>
637        <entry>&Par;</>
638        <entry>&Sig;</>
639        <entry>&Val</>
640        <entry>&Def;</>        
641     </row>
642     </thead>
643     <tbody>
644     <row>
645        <entry>BUFFER</>
646        <entry> &uint; </>
647        <entry> any valid bufferName </>
648        <entry> &NONE; </>        
649     </row>
650     </tbody>
651     </tgroup>
652     </table>
653      Description: 
654         Specifies the current Buffer object, making it the
655         head entry in the Source's queue.  Using BUFFER on a 
656         STOPPED or INITIAL Source empties the entire queue,
657         then appends the one Buffer specified.
658     </para>
659     <para>
660        For a PLAYING or PAUSED Source, using the Source command 
661        with BUFFER is an INVALID_OPERATION. 
662        It can be applied to INITIAL and STOPPED Sources only.
663        Specifying an invalid bufferName will
664        result in an INVALID_VALUE error while specifying an
665        invalid sourceName results in an INVALID_NAME error.
666     </para>
667     <para>
668         NONE, i.e. 0, is a valid buffer Name.
669         Source( sName, BUFFER, 0 ) is a legal way to release the
670         current buffer queue on an INITIAL or STOPPED Source,
671         whether it has just one entry (current buffer) or more.
672         The Source( sName, BUFFER, NONE) call still causes an 
673         INVALID_OPERATION for any source PLAYING or PAUSED, 
674         consequently it cannot be abused to mute or stop a source.
675     </para>
676
677     <![ %Annote [
678       <note><title>Annotation (repeated Source+BUFFER does not queue) </title><para>
679             Using repeated Source(BUFFER) calls to queue a buffer on
680             an active source would imply that there is no way to
681             release the current buffer e.g. by setting it to 0.
682             On the other hand read-only queues do not allow for
683             releasing a buffer without releasing the entire queue.
684
685             We can not require BUFFER state to be transient and lost 
686             as soon as a Source is implicitely or explicitely stopped. 
687             This contradicts queue state being part of the Source's 
688             configuration state that is preserved through Stop() 
689             operations and available for Play().
690        </para></note>
691     ]]>
692
693   
694     </sect3>
695
696
697     <sect3>
698     <title>Queue State Queries</title>
699     <para>
700     <table>
701     <title>BUFFERS_QUEUED Attribute</title>
702     <tgroup cols="4" align="left" colsep=1 rowsep=1>
703     <thead>
704     <row>
705        <entry>&Par;</>
706        <entry>&Sig;</>
707        <entry>&Val</>
708        <entry>&Def;</>        
709     </row>
710     </thead>
711     <tbody>
712     <row>
713        <entry> BUFFERS_QUEUED </>
714        <entry> &uint; </>
715        <entry> [0, any]</>
716        <entry> none </>        
717     </row>
718     </tbody>
719     </tgroup>
720     </table>
721        Query only. Query the number of buffers in the queue
722        of a given Source. This includes those not yet played,
723        the one currently playing, and the ones that have been 
724        played already. This will return 0 if the current and 
725        only bufferName is 0.
726     </para>
727
728
729     <para>
730     <table>
731     <title>BUFFERS_PROCESSED Attribute</title>
732     <tgroup cols="4" align="left" colsep=1 rowsep=1>
733     <thead>
734     <row>
735        <entry>&Par;</>
736        <entry>&Sig;</>
737        <entry>&Val</>
738        <entry>&Def;</>        
739     </row>
740     </thead>
741     <tbody>
742     <row>
743        <entry> BUFFERS_PROCESSED </>
744        <entry> &uint; </>
745        <entry> [0, any]</>
746        <entry> none </>        
747     </row>
748     </tbody>
749     </tgroup>
750     </table>
751        Query only. Query the number of buffers that have
752        been played by a given Source. 
753        Indirectly, this gives the index of the buffer
754        currently playing. Used to determine how much
755        slots are needed for unqueueing them.
756        On an STOPPED Source, all buffers are processed.
757        On an INITIAL Source, no buffers are processed,
758        all buffers are pending.
759        This will return 0 if the current and 
760        only bufferName is 0.
761     </para>
762
763     <![ %Annote [
764       <note><title>Annotation (per-Source vs. Buffer State)</title><para>
765        BUFFERS_PROCESSED is only defined within the scope of a given
766        Source's queue. It indicates that the given number of buffer names
767        can be unqueued for this Source. It does not guarantee that the
768        buffers can safely be deleted or refilled, as they might still be
769        queued with other Sources. One way to keep track of this is to
770        store, per buffer, the Source for which a given buffer was most
771        recently scheduled (this will not work if Sources sharing buffers
772        might be paused by the application). If necessary an explicit
773        query for a given buffer name can be added in later revisions.
774       </para></note>
775     ]]>
776
777     <![ %Annote [
778       <note><title>Annotation (No Looping Queues)</title><para>
779          Unqueueing requires nonzero BUFFERS_PROCESSED,
780          which necessitates no looping on entire queues,
781          unless we accept that no unqueueing is possible
782          from Source looping over the entire queue.
783          Currently not supported, as queueing is 
784          primarily meant for streaming, which implies
785          unqueue-refill-requeue operations.
786       </para></note>
787     ]]>
788
789
790     </sect3>
791
792     <sect3>
793     <title>Bounds on Gain</title>
794     <para>
795     <table>
796     <title>Source Minimal Gain</title>
797     <tgroup cols="4" align="left" colsep=1 rowsep=1>
798     <thead>
799     <row>
800        <entry>&Par;</>
801        <entry>&Sig;</>
802        <entry>&Val</>
803        <entry>&Def;</>        
804     </row>
805     </thead>
806     <tbody>
807     <row>
808        <entry>MIN_GAIN</>
809        <entry>f</>
810        <entry>0.0f, (0.0f, 1.0f]</>
811        <entry>0.0f</>        
812     </row>
813     </tbody>
814     </tgroup>
815     </table>
816      Description:
817         MIN_GAIN is a scalar amplitude threshold. It indicates the minimal GAIN 
818         that is always guaranteed for this Source. At the end of the processing
819         of various attenuation factors such as distance based attenuation and
820         Source GAIN, the effective gain calculated is compared to this value.
821         If the effective gain is lower than MIN_GAIN, MIN_GAIN is applied.
822         This happens before the Listener GAIN is applied. If a zero MIN_GAIN 
823         is set, then the effective gain will not be corrected.
824     </para>
825
826
827     <![ %Annote [
828       <note><title>Annotation (Effective Maximal Distance)</title><para>
829          By setting MIN_GAIN, the application implicitely defines a
830          maximum distance for a given distance attenuation model and
831          Source GAIN. The distance at which the effective gain is MIN_GAIN
832          can be used as a replacement to the DirectSound3D MAX_DISTANCE parameter.  
833          Once the effective gain has reached the MIN_GAIN value, it will 
834          no longer decrease with increasing distance.
835       </para></note>
836     ]]>
837
838    
839     <para>
840     <table>
841     <title>Source Maximal Gain (logarithmic)</title>
842     <tgroup cols="4" align="left" colsep=1 rowsep=1>
843     <thead>
844     <row>
845        <entry>&Par;</>
846        <entry>&Sig;</>
847        <entry>&Val</>
848        <entry>&Def;</>        
849     </row>
850     </thead>
851     <tbody>
852     <row>
853        <entry>MAX_GAIN</>
854        <entry>f</>
855        <entry>0.0f, (0.0f, 1.0f]</>
856        <entry>1.0f</>        
857     </row>
858     </tbody>
859     </tgroup>
860     </table>
861      Description:
862         MAX_GAIN defines a scalar amplitude threshold. It indicates the maximal 
863         GAIN permitted for this Source. At the end of the processing
864         of various attenuation factors such as distance based attenuation and
865         Source GAIN, the effective gain calculated is compared to this value.
866         If the effective gain is higher than MAX_GAIN, MAX_GAIN is applied.
867         This happens before the Listener GAIN is applied. If the Listener gain
868         times MAX_GAIN still exceeds the maximum gain the implementation can
869         handle, the implementation is free to clamp. If a zero MAX_GAIN 
870         is set, then the Source is effectively muted. The implementation is free
871         to optimize for this situation, but no optimization is required or
872         recommended as setting GAIN to zero is the proper way to mute a Source.
873     </para>
874
875     <![ %Annote [
876       <note><title>Annotation (Un-attenuated Source)</title><para>
877          Setting MIN_GAIN and MAX_GAIN to the GAIN value will effectively
878          make the Source amplitude independent of distance. The 
879          implementation is free to optimize for this situation. However, the
880          recommended way to accomplish this effect is using a ROLLOFF_FACTOR 
881          of zero.
882        </para></note>
883     ]]>
884
885
886
887     <![ %Annote [
888       <note><title>Annotation (Internal GAIN threshold)</title><para>
889         The &AL; implementation is free to use an internally chosen 
890         threshold level below which a Source is ignored for mixing. 
891         Reasonable choices would set this threshold low enough so 
892         that the user will not perceive a difference.  Setting MIN_GAIN
893         for a source will override any implementation defined test.     
894        </para></note>
895     ]]>
896     </sect3>
897
898
899
900     <sect3>
901     <title>Distance Model Attributes</title>
902     <para>
903     <table>
904     <title> REFERENCE_DISTANCE Attribute</title>
905     <tgroup cols="4" align="left" colsep=1 rowsep=1>
906     <thead>
907     <row>
908        <entry>&Par;</>
909        <entry>&Sig;</>
910        <entry>&Val</>
911        <entry>&Def;</>        
912     </row>
913     </thead>
914     <tbody>
915     <row>
916        <entry> REFERENCE_DISTANCE </>
917        <entry> &float; </>
918        <entry> [0, any]</>
919        <entry> 1.0f </>        
920     </row>
921     </tbody>
922     </tgroup>
923     </table>
924        This is used for distance attenuation calculations
925        based on inverse distance with rolloff. Depending
926        on the distance model it will also act as a distance
927        threshold below which gain is clamped. See the
928        section on distance models for details.
929     </para>
930
931
932     <para>
933     <table>
934     <title> ROLLOFF_FACTOR Attribute</title>
935     <tgroup cols="4" align="left" colsep=1 rowsep=1>
936     <thead>
937     <row>
938        <entry>&Par;</>
939        <entry>&Sig;</>
940        <entry>&Val</>
941        <entry>&Def;</>        
942     </row>
943     </thead>
944     <tbody>
945     <row>
946        <entry> ROLLOFF_FACTOR </>
947        <entry> &float; </>
948        <entry> [0, any]</>
949        <entry> 1.0f </>        
950     </row>
951     </tbody>
952     </tgroup>
953     </table>
954        This is used for distance attenuation calculations
955        based on inverse distance with rolloff. For
956        distances smaller than MAX_DISTANCE (and, depending
957        on the distance model, larger than REFERENCE_DISTANCE), 
958        this will scale the distance attenuation over the
959        applicable range. See section on distance models for
960        details how the attenuation is computed as a function
961        of the distance.
962     </para>   
963     <para>
964        In particular, ROLLOFF_FACTOR can be set to zero for
965        those Sources that are supposed to be exempt from
966        distance attenuation. The implementation is encouraged
967        to optimize this case, bypassing distance attenuation
968        calculation entirely on a per-Source basis.
969     </para>
970
971     <para>
972     <table>
973     <title> MAX_DISTANCE Attribute</title>
974     <tgroup cols="4" align="left" colsep=1 rowsep=1>
975     <thead>
976     <row>
977        <entry>&Par;</>
978        <entry>&Sig;</>
979        <entry>&Val</>
980        <entry>&Def;</>        
981     </row>
982     </thead>
983     <tbody>
984     <row>
985        <entry> MAX_DISTANCE </>
986        <entry> &float; </>
987        <entry> [0, any]</>
988        <entry> MAX_FLOAT </>        
989     </row>
990     </tbody>
991     </tgroup>
992     </table>
993        This is used for distance attenuation calculations
994        based on inverse distance with rolloff, if the
995        Inverse Clamped Distance Model is used. In this case,
996        distances greater than MAX_DISTANCE will
997        be clamped to MAX_DISTANCE.
998        MAX_DISTANCE based clamping is applied before MIN_GAIN clamping,
999        so if the effective gain at MAX_DISTANCE is larger than MIN_GAIN,
1000        MIN_GAIN will have no effect. No culling is supported.     
1001     </para>
1002
1003     <![ %Annote [
1004       <note><title>Annotation (No Culling)</title><para>
1005       This is a per-Source attribute supported for DS3D compatibility
1006       only. Other API features might suffer from side effects due to 
1007       the clamping of distance (instead of e.g. clamping to an effective
1008       gain at MAX_DISTANCE). 
1009       </para></note>
1010     ]]>
1011
1012     </sect3>
1013
1014
1015
1016
1017     <sect3>
1018     <title>Frequency Shift by Pitch</title>
1019     <para>
1020     <table>
1021     <title>Source PITCH Attribute</title>
1022     <tgroup cols="4" align="left" colsep=1 rowsep=1>
1023     <thead>
1024     <row>
1025        <entry>&Par;</>
1026        <entry>&Sig;</>
1027        <entry>&Val</>
1028        <entry>&Def;</>        
1029     </row>
1030     </thead>
1031     <tbody>
1032     <row>
1033        <entry>PITCH</>
1034        <entry>f</>
1035        <entry> (0.0f, 2.0f]</>
1036        <entry> 1.0f</>        
1037     </row>
1038     </tbody>
1039     </tgroup>
1040     </table>
1041      Description: 
1042         Desired pitch shift, where 1.0 equals identity. Each reduction by 50 percent 
1043         equals a pitch shift of -12 semitones (one octave reduction). Zero is not
1044         a legal value.
1045     </para>
1046     </sect3>
1047
1048
1049     <sect3>
1050     <title>Direction and Cone</title>
1051     <para>
1052        Each Source can be directional, depending on the settings for
1053        CONE_INNER_ANGLE and CONE_OUTER_ANGLE. There are three zones
1054        defined: the inner cone, the outside zone, and the transitional
1055        zone in between. 
1056        The angle-dependent gain for a directional source is constant 
1057        inside the inner cone, and changes over the transitional zone
1058        to the value specified outside the outer cone.
1059        Source GAIN is applied for the inner cone,
1060        with an application selectable CONE_OUTER_GAIN factor to
1061        define the gain in the outer zone. In the transitional
1062        zone implementation-dependent interpolation between
1063        GAIN and GAIN times CONE_OUTER_GAIN is applied.
1064
1065
1066     </para>
1067     <![ %Annote [
1068       <note><title>Annotation (Interpolation Restrictions)</title><para>
1069          The specification does not specify the exact interpolation
1070          applied in the transitional zone, to calculate gain as a 
1071          function of angle. The implementation is free to use
1072          linear or other interpolation, as long as the values
1073          are monotonically decreasing from GAIN to GAIN times CONE_OUTER_GAIN.
1074        </para></note>
1075     ]]>
1076
1077
1078     <para>
1079     <table>
1080     <title>Source DIRECTION Attribute</title>
1081     <tgroup cols="4" align="left" colsep=1 rowsep=1>
1082     <thead>
1083     <row>
1084        <entry>&Par;</>
1085        <entry>&Sig;</>
1086        <entry>&Val</>
1087        <entry>&Def;</>        
1088     </row>
1089     </thead>
1090     <tbody>
1091     <row>
1092        <entry>DIRECTION</>
1093        <entry>3fv, 3f</>
1094        <entry> any except NaN </>
1095        <entry> { 0.0f, 0.0f, 0.0f } </>        
1096     </row>
1097     </tbody>
1098     </tgroup>
1099     </table>
1100      Description: 
1101         If DIRECTION does not equal the zero vector, the Source is directional. 
1102         The sound emission is presumed to be symmetric
1103         around the direction vector (cylinder symmetry). Sources are not
1104         oriented in full 3 degrees of freedom, only two angles are effectively
1105         needed.
1106        </para><para>
1107         The zero vector is default, indicating that a Source is not directional.
1108         Specifying a non-zero vector will make the Source directional. 
1109         Specifying a zero vector for a directional Source will effectively
1110         mark it as nondirectional. 
1111     </para>
1112
1113     <![ %RFC [
1114        <note id="rfc-bk000821-01"><title>RFC: Oriented Sources </title><para>  
1115          Do we want an alternative AZIMUTH/ALTITUDE parametrization?
1116          Do we need ORIENTATION later? Is this superimposable? Can we mix both?
1117       </para></note>
1118     ]]>
1119
1120     <![ %Annote [
1121       <note><title>Annotation (All Sources Directional)</title><para>
1122          From the point of view of the &AL; implementation, all
1123          Sources are directional. Certain choices for cone angles
1124          as well as a direction vector with zero length are treated
1125          equivalent to an omnidirectional source. The &AL; 
1126          implementation is free to flag and optimize these cases. 
1127        </para></note>
1128     ]]>
1129
1130     <![ %RFC [
1131        <note id="rfc-bk000803-05"><title>RFC: Separate GenDirectionSource?</title><para>  
1132          Is there any risk that directional sources require different
1133          resources that have to be allocated from the beginning, and
1134          that we can not change an omnidirectional source to a
1135          bidirectional source at runtime?
1136       </para></note>
1137     ]]>
1138
1139
1140     <para>
1141     <table>
1142     <title>Source CONE_INNER_ANGLE Attribute</title>
1143     <tgroup cols="4" align="left" colsep=1 rowsep=1>
1144     <thead>
1145     <row>
1146        <entry>&Par;</>
1147        <entry>&Sig;</>
1148        <entry>&Val</>
1149        <entry>&Def;</>        
1150     </row>
1151     </thead>
1152     <tbody>
1153     <row>
1154        <entry>CONE_INNER_ANGLE</>
1155        <entry>i,f</>
1156        <entry>any except NaN</>
1157        <entry>360.0f</>        
1158     </row>
1159     </tbody>
1160     </tgroup>
1161     </table>
1162      Description: 
1163        Inside angle of the sound cone, in degrees. The default of 360 means that the
1164        inner angle covers the entire world, which is equivalent to an omnidirectional 
1165        source.
1166     </para>
1167     <![ %RFC [
1168        <note id="rfc-bk000926-01"><title>RFC: inconsistent cone angles? </title><para>  
1169         Is (inner &lt;= outer) required? Do we generate an error?
1170         Shouldn't this be a CONE_ANGLES 2f call specifying both angles at once?      
1171       </para></note>
1172     ]]>
1173
1174
1175
1176
1177     <para>
1178     <table>
1179     <title>Source CONE_OUTER_ANGLE Attribute</title>
1180     <tgroup cols="4" align="left" colsep=1 rowsep=1>
1181     <thead>
1182     <row>
1183        <entry>&Par;</>
1184        <entry>&Sig;</>
1185        <entry>&Val</>
1186        <entry>&Def;</>        
1187     </row>
1188     </thead>
1189     <tbody>
1190     <row>
1191        <entry>CONE_OUTER_ANGLE</>
1192        <entry>i,f</>
1193        <entry>any except NaN</>
1194        <entry>360.0f</>        
1195     </row>
1196     </tbody>
1197     </tgroup>
1198     </table>
1199      Description: Outer angle of the sound cone, in degrees. The default of 360 means that the
1200        outer angle covers the entire world. If the inner angle is also 360, then
1201        the zone for angle-dependent attenuation is zero.
1202     </para>
1203   
1204     <![ %RFC [
1205        <note id="rfc-bk000926-02"><title>RFC: addition? </title><para>  
1206      More generally, we could specify: 
1207       "If the sum of inner and outer angles is larger than 360,
1208       CONE_OUTER_ANGLE is clamped to (360-CONE_INNER_ANGLE) and
1209       there is no transition zone."
1210       </para></note>
1211     ]]>
1212
1213     <para>
1214     <table>
1215     <title>Source CONE_OUTER_GAIN Attribute</title>
1216     <tgroup cols="4" align="left" colsep=1 rowsep=1>
1217     <thead>
1218     <row>
1219        <entry>&Par;</>
1220        <entry>&Sig;</>
1221        <entry>&Val</>
1222        <entry>&Def;</>        
1223     </row>
1224     </thead>
1225     <tbody>
1226     <row>
1227        <entry>CONE_OUTER_GAIN</>
1228        <entry>i,f</>
1229        <entry>[0.0f, 1.0f]</>
1230        <entry>0.0f</>        
1231     </row>
1232     </tbody>
1233     </tgroup>
1234     </table>
1235         Description: the factor with which GAIN is multiplied to 
1236         determine the effective gain outside the cone defined by
1237         the outer angle. The effective gain applied outside the
1238         outer cone is GAIN times CONE_OUTER_GAIN. Changing
1239         GAIN affects all directions, i.e. the source is attenuated 
1240         in all directions, for any position of the listener.
1241         The application has to change CONE_OUTER_GAIN as well if
1242         a different behavior is desired.
1243     </para>
1244    
1245   
1246     <![ %Annote [
1247       <note><title>Annotation (GAIN calculation)</title><para>
1248          The angle-dependend gain DGAIN is multiplied with the
1249          gain determined by the source's GAIN and any distance
1250          attenuation as applicable. Let theta be the angle
1251          between the source's direction vector, and the vector
1252          connection the source and the listener. This multiplier 
1253          DGAIN is calculated as:
1254         <literallayout>
1255           OUTER = CONE_OUTER_ANGLE/2;
1256           INNER = CONE_INNER_ANGLE/2;
1257           if      ( theta less/equal INNER )
1258               DGAIN = 1               
1259           else if ( theta greater/equal OUTER )
1260              DGAIN = CONE_OUTER_GAIN
1261           else
1262              DGAIN = 1 - (1-CONE_OUTER_GAIN)*((theta-INNER)/(OUTER-INNER))
1263           GAIN *= DGAIN
1264         </literallayout>
1265          in the case of linear interpolation. The implementation
1266          is free to use a different interplation across the (INNER,OUTER)
1267          range as long as it is monotone. 
1268        </para></note>
1269     ]]>
1270
1271     <![ %Annote [
1272       <note><title>Annotation (CONE_OUTER_GAIN always less than GAIN)</title><para>
1273          CONE_OUTER_GAIN is not an absolute value, but (like all GAIN
1274          parameters) a scaling factor. This avoids a possible error 
1275          case (implementations can count on effective gain outside the
1276          outer cone being smaller than GAIN), and ensures the common
1277          case in which changing GAIN should affect inner, transitional, 
1278          and outer zone simultaneously.
1279       </para><para>
1280          In case that the application desires to have an outer zone
1281          volume exceeding that of the inner cone, the mapping to
1282          &AL; will require to rotate the Source direction to the
1283          opposite direction (negate vector), and swapping
1284          inner and outer angle.
1285       </para></note>
1286     ]]>
1287     </sect3>
1288    </sect2>
1289
1290
1291     <sect2>
1292     <title>Changing Source Attributes</title>
1293     <para>
1294       The Source specifies the position and other properties as
1295       taken into account during sound processing. 
1296       <funcsynopsis><funcprototype> 
1297       <funcdef> void <function> Source{n}{sifd} </function></funcdef>
1298       <paramdef> &uint; <parameter> sourceName </parameter></paramdef>
1299       <paramdef> &enum; <parameter> paramName </parameter></paramdef>
1300       <paramdef> &type; <parameter> value </parameter></paramdef>
1301       </funcprototype></funcsynopsis>
1302       <funcsynopsis><funcprototype> 
1303       <funcdef> void <function> Source{n}{sifd}v </function></funcdef>
1304       <paramdef> &uint; <parameter> sourceName </parameter></paramdef>
1305       <paramdef> &enum; <parameter> paramName </parameter></paramdef>
1306       <paramdef> &type;* <parameter> values </parameter></paramdef>
1307       </funcprototype></funcsynopsis>
1308     </para>
1309    </sect2>
1310
1311    <sect2>
1312     <title>Querying Source Attributes</title>
1313     <para>
1314       Source state is maintained inside the &AL; implementation, and the
1315       current attributes can be queried. The performance of such queries is 
1316       implementation dependent, no performance guarantees are made. The 
1317       valid values for the paramName parameter are identical to the ones 
1318       for Source*.
1319       <funcsynopsis><funcprototype> 
1320       <funcdef> void <function> GetSource{n}{sifd}{v} </function></funcdef>
1321       <paramdef> &uint; <parameter> sourceName </parameter></paramdef>
1322       <paramdef> &enum; <parameter> paramName </parameter></paramdef>
1323       <paramdef> &type;* <parameter> values </parameter></paramdef>
1324       </funcprototype></funcsynopsis>
1325     </para>
1326
1327     <![ %Scratch [
1328      <warning><para>
1329       Old signature: T GetSource{sifd}{v}( uint id, enum param );
1330      </para></warning>
1331      ]]>
1332  
1333     </sect2>
1334
1335
1336
1337   <sect2 id="queueing">
1338    <title>Queueing Buffers with a Source</title>
1339    <para>
1340      &AL; does not specify a built-in streaming mechanism. There
1341      is no mechanism to stream data e.g. into a Buffer object.
1342      Instead, the API introduces a more flexible and versatile
1343      mechanism to queue Buffers for Sources.
1344    </para>
1345    <para>
1346      There are many ways to use this feature, with
1347      streaming being only one of them. 
1348     <itemizedlist>
1349     <listitem>
1350     <para>
1351       Streaming is replaced by queuing static
1352       buffers. This effectively moves any multi-buffer
1353       caching into the application and allows the
1354       application to select how many buffers it wants
1355       to use, whether these are re-used in cycle,
1356       pooled, or thrown away. 
1357    </para>
1358    </listitem>
1359    <listitem>
1360    <para>
1361       Looping (over a finite number of repititions) can be 
1362       implemented by explicitely repeating buffers
1363       in the queue. Infinite loops can (theoretically)
1364       be accomplished by sufficiently large repetition counters.
1365       If only a single buffer is supposed to be repeated
1366       infinitely, using the respective Source attribute is
1367       recommended.
1368    </para>
1369    </listitem>
1370    <listitem>
1371    <para>
1372       Loop Points for restricted looping inside a buffer
1373       can in many cases be replaced by splitting the 
1374       sample into several buffers, queueing the sample
1375       fragments (including repetitions) accordingly.
1376    </para>
1377    </listitem>
1378    </itemizedlist>
1379    Buffers can be queued, unqueued after they have been
1380    used, and either be deleted, or refilled and queued again.
1381    Splitting large samples over several buffers maintained
1382    in a queue has a distinct advantages over approaches that
1383    require explicit management of samples and sample indices.
1384    </para>
1385
1386     <![ %RFC [
1387       <note id="bk000626-01"><title>RFC: Unified Handling</title><para>  
1388        Jonathan Blow has proposed removing the distinction between
1389        streaming and non-streaming buffers. An existing example is
1390        the unified for directional and omnidirectional sources, where
1391        all sources are treated as directional.
1392       </para></note>
1393     ]]>
1394
1395
1396    <sect3>
1397    <title>Queueing command</title>
1398    <para>
1399      The application can queue up one or multiple buffer names 
1400      using SourceQueueBuffers. The buffers will be queued in the sequence
1401      in which they appear in the array.
1402       <funcsynopsis><funcprototype> 
1403       <funcdef> &void; <function> alSourceQueueBuffers </function></funcdef>
1404       <paramdef> &uint; <parameter> sourceName </parameter></paramdef>
1405       <paramdef> &sizei; <parameter> numBuffers </parameter></paramdef>
1406       <paramdef> &uint; * <parameter> bufferNames </parameter></paramdef>
1407       </funcprototype></funcsynopsis>
1408      This command is legal on a Source in any state (to allow for
1409      streaming, queueing has to be possible on a PLAYING Source).
1410      Queues are read-only with exception of the unqueue operation. 
1411      The Buffer Name NONE (i.e. 0) can be queued.
1412     </para>
1413   
1414     <![ %Annote [
1415       <note><title>Annotation (BUFFER vs. SourceQueueBuffers)</title><para>
1416        A Sourcei( sname, BUFFER, bname ) command is an immediate
1417        command, and executed immediately. It effectively unqueues
1418        all buffers, and then adds the specified buffer to the
1419        then empty queue as its single entry. Consequently, this
1420        call is only legal if SourceUnqueueBuffers is legal.
1421        In particular, the Source has to be STOPPED or INITIAL.
1422        The application is still obliged to delete all
1423        buffers as were contained in the queue.  
1424        Sourcei( sname, BUFFER, NONE ) is a legal command,
1425        effectively wiping the queue without specifying an
1426        actually playable buffer.
1427        </para></note>
1428     ]]>
1429
1430
1431     <![ %Annote [
1432       <note><title>Annotation (Buffer Repetition)</title><para>
1433         To accomplish a finite number of repetitions of a buffer name multiple times,
1434         the buffer has to be queued multiple times. If the need occurs, the
1435         API could be extended by SourceQueueBuffer( sname, bname, repetitions )
1436         call for brevity.
1437       </para></note>
1438     ]]>
1439
1440     <![ %RFC [
1441        <note id="rfc-bk000806-04"><title>RFC: Duration of bName==0? </title><para>  
1442           The buffer is considered empty, it should have zero length,
1443           thus zero duration for consistency. If an application wants to
1444           schedule a pause, specifying duration for a gain==0 queue entry
1445           might be a cleaner solution.     
1446       </para></note>
1447     ]]>
1448
1449
1450     <![ %Annote [
1451       <note><title>Annotation (Backwards Compatiblity)</title><para>
1452          Sourcei( sname, BUFFER, bname ) has been rejected as
1453          a queueing command, as it would make semantics dependent on
1454          source state (queueing if PLAYING, immediate else).
1455          The command is not legal on a PLAYING or PAUSED Source.
1456        </para></note>
1457     ]]>
1458
1459     <![ %Annote [
1460       <note><title>Annotation (No BUFFER_QUEUE)</title><para>
1461           Duplication of one entry point is preferable to
1462           duplicating token enums, and tokens do not express
1463           commands, but specify the attribute/state affected.
1464           From the same reason, there is no BUFFER_UNQUEUE
1465           token-as-command.
1466        </para></note>
1467     ]]>
1468
1469     </sect3>
1470
1471    <sect3>
1472    <title>Unqueueing command</title>
1473    <para>
1474      Once a queue entry for a buffer has been appended to a queue 
1475      and is pending processing, it should not be changed.
1476      Removal of a given queue entry is not possible unless 
1477      either the Source is STOPPED (in which case then entire queue
1478      is considered processed), or if the queue entry has already
1479      been processed (PLAYING or PAUSED Source).
1480    </para>
1481    <para>
1482      The Unqueue command removes a number of buffers entries that 
1483      have finished processing, in the order of appearance, from 
1484      the queue. The operation will fail if more buffers are
1485      requested than available, leaving the destination arguments 
1486      unchanged. An INVALID_VALUE error will be thrown.  
1487      If no error, the destination argument will have been updated 
1488      accordingly.
1489       <funcsynopsis><funcprototype> 
1490       <funcdef> void <function>  SourceUnqueueBuffers </function></funcdef>
1491       <paramdef> &uint;    <parameter> sourceName </parameter></paramdef>
1492       <paramdef> &sizei;    <parameter> numEntries </parameter></paramdef>
1493       <paramdef> &uint;*    <parameter> bufferNames </parameter></paramdef>
1494       </funcprototype></funcsynopsis>
1495     </para>
1496
1497     <![ %Annote [
1498       <note><title>Annotation (Unqueueing shared buffers)</title><para>
1499          If a buffer is queued with more than one source, it might have
1500          been processed for some not all of them. With the current
1501          interface, the application is forced to maintain its own list
1502          of consumers (Sources) for a buffer it wishes to unqueue.
1503          For groups of Sources that are never individually PAUSED 
1504          nor STOPPED, the application can save the MRU Source for 
1505          which the buffer was scheduled last.
1506        </para></note>
1507     ]]>
1508
1509     <![ %Annote [
1510       <note><title>Annotation (Looping a Queue vs. Unqueue):</title><para>
1511           If a Source is playing repeatedly, it will traverse
1512           the entire Queue repeatedly. Consequently, no buffer
1513           in the queue can be considered processed until 
1514           there is no further repetition scheduled.
1515        </para></note>
1516     ]]>
1517
1518     <![ %Annote [
1519       <note><title>Annotation (No Name based access)</title><para>
1520          No interface is provided to access a queue entry by name,
1521          due to ambiguity (same buffer name scheduled several times
1522          in a sequence).
1523        </para></note>
1524     ]]>
1525
1526     <![ %Annote [
1527       <note><title>Annotation (No Index based access)</title><para>
1528          No interface is provided for random access to a queue entry 
1529          by index.
1530        </para></note>
1531     ]]>
1532     </sect3>
1533
1534
1535
1536    <![ %Annote [
1537      <sect3>
1538      <title>More Annotation on Queueing</title>
1539
1540     <![ %Annote [
1541       <note><title>Annotation (No Queue Copying)</title><para>
1542           The current queue of a source could be copied to another source, 
1543          as repetition and traversal parameters are stored unless the 
1544          queue entry is unqueued, or the queue is replaced using 
1545          AL_BUFFER.  Copying a queue is a special case of
1546          copying Source state in one sense, and a special case of
1547          a synching problem in another. Due to these unresolved issues
1548          no such command is included in the current specification.
1549          To share queues, the application can keep buffer names
1550          and the selected attributes that define the queue entries
1551          in an array or other lookup table.
1552        </para></note>
1553     ]]>
1554
1555     <![ %Annote [
1556       <note><title>Annotation (No Explicit QueueClear)</title><para>
1557         Sourcei( sname, BUFFER, NONE ) serves the 
1558         same purpose. The operation is also redundant
1559         with respect to Unqueue for a STOPPED Source.
1560        </para></note>
1561     ]]>
1562
1563     <![ %Annote [
1564       <note><title>Annotation (Queueing vs. AppendData):</title><para>
1565          Buffer queueing does not solve the synchronization and timing 
1566          issues raised by possible underflow, as these are inherent
1567          to application-driven (pushed) streaming. However, it turns 
1568          an internal AL error condition (offset exceeds valid data)
1569          into an audible artifact (Source stops).
1570          Its main advantage is that it allows the application coder
1571          to operate at a scale of her own choice, selecting the
1572          number and size of buffers used for caching the stream,
1573          and to schedule buffer refill and queueing according to 
1574          preferences and constraints. Queueing effectively moves 
1575          all problems related to replacing or appending Buffer data 
1576          to the scale of entire arrays istead of single samples and 
1577          indices.
1578        </para></note>
1579     ]]>
1580
1581     <![ %Annote [
1582       <note><title>Annotation (Multiple Sources on a stream)</title><para>
1583          Queueing allows for the application to determine how much of
1584          a backlog of the data stream is preserved. The application can
1585          keep buffers, and queue them with other Sources after they have
1586          been used already by the original Source. Unlike the mechanism
1587          for appending data to a buffer, the backlog is visible to the
1588          application and under its control, and no synchronization of
1589          Sources using the stream is required.
1590        </para></note>
1591     ]]>
1592
1593
1594
1595     <![ %Annote [
1596       <note><title>Annotation (Loop Points and Compressed Data)</title><para>
1597         For compressed data, uncompression by the application might be
1598          impossible or undesireable. In consequence, splitting the sample
1599          into several buffers is not possible without explicit support
1600          by the API. Buffer-Buffer operations will be added as needed,
1601          for the time being applications should not try to use compressed
1602          samples if more than full looping is required.
1603        </para></note>
1604     ]]>
1605
1606
1607
1608     <![ %Annote [
1609       <note><title>Annotation (No Explicit Queue Objects)</title><para>
1610         Explicit Queue objects have been considered and rejected,
1611         as they introduce another producer-consumer dependency with
1612         another level of indirection. Further, e.g. QUEUE would 
1613         also require deprecating BUFFER (breaking backwards 
1614         compatibility) as an alSource argument, or would introduce
1615         a confusing set of precedence and overide rules if both
1616         are used in sequence. However, in the absence of explicit
1617         queue objects the application will be forced to keep track
1618         where buffers have been queued in case it intends to 
1619         unqueue them for refill or deletion. If several sources
1620         use the same buffers (e.g. for synchronous or 
1621         asynchronous streaming) the buffer will have to be
1622         unqueued from each single one.
1623       </para></note>
1624     ]]>
1625
1626
1627     <![ %Scratch [
1628       <note><title>Annotation (Queue no Display List)</title><para>
1629          An interface resembling &OGL; display-lists has been 
1630          considered and rejected. The problem with this approach 
1631          is that not only commands would have to be prohibited 
1632          (similarly, not all GL calls are legal within a display 
1633          list), but also parameters (enumerations).
1634
1635          In particular, only a small set of operations is meant
1636          to be legal for a queue at this point, and appending
1637          to a queue has to be possible at any time.
1638          Within a hypothetical AL display list, only relative
1639          timing/conditionals are allowed as arguments. This
1640          might necessitate to have multiple forms for deferred
1641          commands, or to not allow for absolute timing.
1642
1643          Example:
1644          <literallayout>
1645          // lock this queue for overwriting/appending
1646          alBeginQueue( qname, APPEND | REPLACE );  
1647
1648          // queue a buffer in sequence, with parameters
1649          // boolean: never skip? never bail?
1650          alQueue( AL_BUFFER, bid, loopdir, repetitions );
1651          ...
1652
1653          // end lock. 
1654          // Existing  queue content will be replaced
1655          //  or appended at this point.
1656          alEndQueue();
1657        </literallayout>
1658        </para></note>
1659     ]]>
1660
1661
1662     <![ %Example [
1663       <example>
1664       <title>Queue Then Delete </title>
1665       <programlisting>
1666
1667          create source
1668          queue buffer1
1669          queue buffer2
1670          queue buffer3
1671          play
1672          request deletion of buffer1,2,3
1673        
1674        </programlisting>
1675        </example>
1676     ]]>
1677
1678     <![ %Example [
1679       <example>
1680       <title> Queue and Refill with Dual Buffering</title>
1681       <programlisting>
1682
1683         create source
1684         fill buffer1
1685         queue buffer1
1686         play
1687         fill buffer2
1688         queue buffer2
1689         check for unused buffers
1690           unqueue buffer1
1691           fill buffer1
1692           queue buffer1
1693           ...
1694        
1695        </programlisting>
1696        </example>
1697     ]]>
1698
1699     <![ %Example [
1700       <example>
1701       <title> Queue for Loop Points</title>
1702       <programlisting>
1703
1704          create source
1705          read sample data
1706          split sample data into pre/main/post
1707          queue pre
1708          queue main with repetitions
1709          queue post
1710          play
1711          set repetitions to 0 on main when needed
1712          wait till post has been played
1713        
1714        </programlisting>
1715        </example>
1716     ]]>
1717  
1718    </sect3>
1719 ]]>
1720
1721 <![ %Scratch [
1722   <sect3>
1723     <title>Attributes Specific to Queueing</title>
1724
1725      <section>
1726     <title>Buffer Traversal</title>
1727     <para>
1728        The Buffer traversal attribute specifies the direction
1729        in which the sample in the buffer is supposed to be
1730        processed. To account for the 3 basic modes of traversal that
1731        can be implemented in software and hardware, the following
1732        tokens are defined:
1733        <literallayout>
1734          LOOP_DIRECTION     /* traversal direction */
1735
1736          FORWARD            /* linear forward   (increment) */
1737          BACKWARD           /* linear backward  (decrement) */
1738          FORWARD_AND_BACK   /* RESERVED: ping-pong-looping  */
1739  
1740        </literallayout>
1741        The first and the next two tokens are legal with a buffer queue command. 
1742        They are not legal for a Source command, in any possible
1743        Source state. The last token is reserved, but not yet legal to use.
1744     </para>  
1745
1746
1747     <![ %Annote [
1748       <note><title>Annotation (Ping-Pong postponed)</title><para>
1749         Definition and implementation of ping-pong looping
1750         has been postponed. Applications can fake it at doubling
1751         memory expense by reverse copying the buffer (2nd buffer queued 
1752         or in a double size single buffer). If there is hardware support
1753         for this feature, AL will have to support it eventually. A boolean
1754         flag is not acceptable because of this possibility.
1755        </para></note>
1756     ]]>
1757     </sect3> 
1758 ]]> <!-- SCRATCH -->
1759  
1760   
1761    </sect2>
1762  
1763
1764
1765
1766
1767
1768     <sect2>
1769     <title>Managing Source Execution</title>
1770     <para>
1771        The execution state of a source can be queried. &AL; provides
1772        a set of functions that initiate state transitions causing
1773        Sources to start and stop execution.
1774     </para>
1775     <para>
1776        TBA: State Transition Diagram.
1777     </para>
1778
1779     <![ %Annote [
1780       <note><title>Annotation/ Source Config/Exec State</title><para>
1781        Sources have configuration state and execution state.
1782        Configuration state is directly set by the application using 
1783        AL commands, starting with the INITIAL configuration. Execution 
1784        state (e.g. the offset to the current sample) is not under direct 
1785        application control and not exposed. 
1786        </para></note>
1787     ]]>
1788
1789     <sect3>
1790     <title>Source State Query</title>
1791     <para>
1792       The application can query the current state of any Source 
1793       using GetSource with the parameter Name SOURCE_STATE. 
1794       Each Source can be in one of four possible execution states: 
1795       INITIAL, PLAYING, PAUSED, STOPPED. Sources that are either
1796       PLAYING or PAUSED are considered active. Sources that are
1797       STOPPED or INITIAL are considered inactive. Only PLAYING
1798       Sources are included in the processing. The implementation 
1799       is free to skip those processing stages for Sources that 
1800       have no effect on the output (e.g. mixing for a Source 
1801       muted by zero GAIN, but not sample offset increments). 
1802       Depending on the current state of a Source certain (e.g. repeated)
1803       state transition commands are legal NOPs: they will be ignored, 
1804       no error is generated.
1805     </para>
1806     </sect3>
1807
1808     <sect3>
1809     <title>State Transition Commands</title>
1810     <para>
1811       The default state of any Source is INITIAL. From this state
1812       it can be propagated to any other state by appropriate use
1813       of the commands below. There are no irreversible state
1814       transitions. 
1815       <funcsynopsis><funcprototype> 
1816       <funcdef> void <function> SourcePlay </function></funcdef>
1817       <paramdef> &uint; <parameter> sName </parameter></paramdef>
1818       </funcprototype></funcsynopsis>
1819       <funcsynopsis><funcprototype> 
1820       <funcdef> void <function> SourcePause </function></funcdef>
1821       <paramdef> &uint; <parameter> sName </parameter></paramdef>
1822       </funcprototype></funcsynopsis>
1823       <funcsynopsis><funcprototype> 
1824       <funcdef> void <function> SourceStop </function></funcdef>
1825       <paramdef> &uint; <parameter> sName </parameter></paramdef>
1826       </funcprototype></funcsynopsis>
1827       <funcsynopsis><funcprototype> 
1828       <funcdef> void <function> SourceRewind </function></funcdef>
1829       <paramdef> &uint; <parameter> sName </parameter></paramdef>
1830       </funcprototype></funcsynopsis>
1831
1832
1833     </para>
1834     <para>
1835       The functions are also available as a vector variant,
1836       which guarantees synchronized operation on a set of 
1837       Sources.
1838       <funcsynopsis><funcprototype> 
1839       <funcdef> void <function> SourcePlayv </function></funcdef>
1840       <paramdef> &sizei; <parameter> n </parameter></paramdef>
1841       <paramdef> &uint;* <parameter> sNames </parameter></paramdef>
1842       </funcprototype></funcsynopsis>
1843       <funcsynopsis><funcprototype> 
1844       <funcdef> void <function> SourcePausev </function></funcdef>
1845       <paramdef> &sizei; <parameter> n </parameter></paramdef>
1846       <paramdef> &uint;* <parameter> sNames </parameter></paramdef>
1847       </funcprototype></funcsynopsis>
1848       <funcsynopsis><funcprototype> 
1849       <funcdef> void <function> SourceStopv </function></funcdef>
1850       <paramdef> &sizei; <parameter> n </parameter></paramdef>
1851       <paramdef> &uint;* <parameter> sNames </parameter></paramdef>
1852       </funcprototype></funcsynopsis>
1853
1854       <funcsynopsis><funcprototype> 
1855       <funcdef> void <function> SourceRewindv </function></funcdef>
1856       <paramdef> &sizei; <parameter> n </parameter></paramdef>
1857       <paramdef> &uint;* <parameter> sNames </parameter></paramdef>
1858       </funcprototype></funcsynopsis>
1859
1860     </para>
1861     <para>
1862       The following state/command/state transitions are defined:
1863       <itemizedlist>
1864        <listitem>
1865        <para>
1866         Play() applied to an INITIAL Source will promote the Source
1867         to PLAYING, thus the data found in the Buffer will be fed 
1868         into the processing, starting at the beginning.
1869         Play() applied to a PLAYING Source will restart the Source
1870         from the beginning. It will not affect the configuration,
1871         and will leave the Source in PLAYING state, but reset the
1872         sampling offset to the beginning.
1873         Play() applied to a PAUSED Source will 
1874         resume processing using the Source state 
1875         as preserved at the Pause() operation.
1876         Play() applied to a STOPPED Source will propagate it
1877         to INITIAL then to PLAYING immediately.
1878        </para> 
1879        </listitem>
1880        <listitem>
1881        <para>
1882         Pause() applied to an INITIAL Source is a legal NOP.
1883         Pause() applied to a PLAYING Source will change its state to
1884         PAUSED. The Source is exempt from processing, its current
1885         state is preserved.
1886         Pause() applied to a PAUSED Source is a legal NOP.
1887         Pause() applied to a STOPPED Source is a legal NOP.
1888        </para>
1889        </listitem>
1890        <listitem>
1891        <para>
1892         Stop() applied to an INITIAL Source is a legal NOP.
1893         Stop() applied to a PLAYING Source will change its state to
1894         STOPPED. The Source is exempt from processing, its current
1895         state is preserved.
1896         Stop() applied to a PAUSED Source will change its state
1897         to STOPPED, with the same consequences as on a PLAYING
1898         Source.
1899         Stop() applied to a STOPPED Source is a legal NOP.
1900        </para>
1901        </listitem>
1902        <listitem>
1903        <para>
1904         Rewind() applied to an INITIAL Source is a legal NOP.
1905         Rewind() applied to a PLAYING Source will change its state to
1906         STOPPED then INITIAL. The Source is exempt from processing:
1907         its current state is preserved, with the exception of the 
1908         sampling offset, which is reset to the beginning.
1909         Rewind() applied to a PAUSED Source will change its state
1910         to INITIAL, with the same consequences as on a PLAYING
1911         Source.
1912         Rewind() applied to a STOPPED Source promotes the Source
1913         to INITIAL, resetting the sampling offset to the beginning.
1914        </para>
1915        </listitem>
1916     </itemizedlist>
1917     </para>
1918
1919     <![ %Annote [
1920       <note><title>Annotation (SourceNext)</title><para>
1921          The specification does not provide any means to
1922          immediately skip from the current Buffer to the
1923          next in the queue.  A conditional stop (following
1924          the next complete traversal) is available.
1925          If necessary an additonal entry point could be
1926           provided in future revisions.
1927        </para></note>
1928     ]]>
1929
1930     <![ %Annote [
1931       <note><title>Annotation (Rewind() optional)</title><para>
1932          The INITIAL state is not identical to the STOPPED state.
1933          Applications that want to verify whether a Source
1934          has indeed been PLAYING before becoming STOPPED can
1935          use Rewind() to reset the Source state to INITIAL.
1936          This is an optional operation that can safely be
1937          omitted by application without this constraint. 
1938          Applications that want to guard against Play() on
1939          a Source that is INITIAL can query the Source state
1940          first.         
1941       </para></note>
1942     ]]>
1943
1944     <![ %Annote [
1945       <note><title>Annotation (Play() on a PLAYING Source)</title><para>
1946          Repeated Play() commands applied a PLAYING Source are
1947          interpreted as an (atomic) sequence to stop and restart a
1948          Source. This can be used by applications that want to restart
1949          a sound but do not care whether the Source has finished or not,
1950          and do not want an audible pause. One example is the DOOM 
1951          chaingun repeatedly abbreviating the pistol sound. To guard
1952          against redundant Play() commands, an application can query
1953          the current state before executing Play(). If the application
1954          coder wants to be sure that the Source will play the buffer
1955          again, she can either increment PLAY_COUNT, or queue the buffer.
1956        </para></note>
1957     ]]>
1958
1959     <![ %Annote [
1960       <note><title>Annotation (redundant commands)</title><para>
1961          The simple variant (e.g. SourcePlay) is redundant to
1962          the vector variant (e.g. SourcePlayv). However, these
1963          calls will be used frequently, and the simple variant
1964          is provided for convenience. However, &AL; does not
1965          enable applications to use literals as source names.
1966        </para></note>
1967     ]]>
1968
1969     </sect3>
1970
1971     <sect3>
1972     <title>Resetting Configuration</title>
1973     <para>
1974       The INITIAL state is not necessarily identical to the 
1975       default state in which Source is created. INITIAL merely
1976       indicates that the Source can be executed using the
1977       SourcePlay command. A STOPPED or INITIAL Source can
1978       be reset into the default configuration by using a
1979       sequence Source commands as necessary. As the application
1980       has to specify all relevant state anyway to create a
1981       useful Source configuration, no reset command is provided.
1982     </para>
1983   
1984
1985     <![ %RFC [
1986        <note id="rfc-bk000802-01"><title>RFC: remove INITIAL</title><para>  
1987          INITIAL is identical to STOPPED. The only additional information
1988          conveyed is that INITIAL indicates a source has never been played. 
1989          Once a Source is STOPPED, it is not possible by state query alone 
1990          to decide whether it has played again. If Sources are used only 
1991          once, an application can use INITIAL to verify a Source has been 
1992          played.
1993          The problem that I have with this is that if we acknowledge that
1994          the application might need to verify a Source has played once,
1995          why force the application to throw away Sources to accomplish
1996          this? An explicit state PLAYABLE replacing INITIAL and its
1997          inauspicious connotations (default state) and a state transition
1998          function Rewind() that makes a STOPPED Source PLAYABLE again would 
1999          be one possibility to address this need. The obvious drawback is
2000          that it breaks backwards compatibility.
2001       </para></note>
2002     ]]>
2003
2004
2005     <![ %RFC [
2006        <note id="rfc-bk000731-01"><title>RFC: state issues </title><para>  
2007         A Source is active if it is PAUSED or PLAYING.
2008
2009         A Source that is STOPPED preserves configuration state,
2010           including buffer/queue information.
2011
2012         Only a Source that is Reset() to INITIAL looses all
2013           buffer and queue information. In this case, the INITIAL
2014
2015         Sources will be stopped implicitely when reaching the
2016            end of a non-repeating (non-looping) buffer traversal.
2017         Sources can be stopped explicitely by the application
2018         with either Stop() or Reset(). 
2019
2020        Stop() propagates
2021         the source to STOPPED preserving its configuration state,
2022         setting its execution state to the same as if it reached
2023         the end of execution.
2024   
2025       </para></note>
2026     ]]>
2027
2028
2029     <![ %Annote [
2030       <note><title>Annotation (illegal NOPs)</title><para>
2031           In the current specification there are no illegal NOPs.
2032           In other words, no sequence of commands affecting the
2033           execution state will generate an INVALID_OPERATION error.  
2034       </para></note>
2035     ]]>
2036
2037
2038      <![ %RFC [
2039      <note><title>RFC/bk000504:</title><para>
2040        No  UNDEFINED state. Always valid state. I.e. we have a default Buffer
2041        that is used for sources where the application doesn't specify,
2042        and what's in it? Default gain is zero? We need to specify
2043        INITIAL.
2044      </para></note>
2045
2046      <note><title>RFC/bk000504:</title><para>
2047        Potential ambiguity: how to we distinguish STOPPED as
2048        requested by the application from INACTIVE for
2049        non-looping sounds once the buffer has been iterated?
2050        Related: handling of Sources using an underflowing
2051        streaming buffer? IMO not recommended, make this
2052        undefined on error.
2053      </para></note>
2054
2055
2056      <note><title>RFC/bk000504:</title><para>
2057        Possible redundancy: the only reason for STOP seems to
2058        be resetting the play positions. Redundant if we
2059        ever manipulate offsets directly (rewind/set).
2060      </para></note>
2061
2062      <note><title>RFC/bk000504:</title><para>
2063        Possible redundancy:
2064        If we ever want to support explicit setting of the start
2065        position/offset into Buffer, START is equivalent to Set(0).
2066        Also see LOOP (implies has to be STOPPED). Fade-Out and
2067        Fade-In control - always manually?
2068      </para></note>
2069
2070      ]]>     
2071    </sect3>
2072    </sect2>
2073    </sect1>
2074    </chapter>
2075
2076