chp-rendering.sgml 74 KB

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