]> gitweb.factorcode.org Git - factor.git/blob - extra/audio/engine/engine-docs.factor
Update some copyright headers to follow the current convention
[factor.git] / extra / audio / engine / engine-docs.factor
1 ! Copyright (C) 2010 Joe Groff.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: alien audio byte-arrays destructors help.markup
4 help.syntax kernel math strings ;
5 IN: audio.engine
6
7 HELP: <audio-engine>
8 { $values
9     { "device-name" { $maybe string } } { "voice-count" integer }
10     { "engine" audio-engine }
11 }
12 { $description "Constructs an " { $link audio-engine } " instance capable of playing " { $snippet "voice-count" } " simultaneous clips. The OpenAL device named " { $snippet "device-name" } " will be used, or the default device if " { $snippet "device-name" } " is " { $link f } ". An error will be thrown if the engine cannot be initialized. The engine is returned in the stopped state; to start audio processing, use " { $link start-audio } " or " { $link start-audio* } "." } ;
13
14 HELP: <audio-orientation-state>
15 { $values
16     { "forward" "a sequence of 3 floats" } { "up" "a sequence of 3 floats" }
17     { "audio-orientation-state" audio-orientation-state }
18 }
19 { $description "Constructs an " { $link audio-orientation-state } " tuple." } ;
20
21 HELP: <standard-audio-engine>
22 { $values
23
24     { "engine" audio-engine }
25 }
26 { $description "Constructs an " { $link audio-engine } " instance by calling " { $link <audio-engine> } " with the default values of " { $link f } " for the " { $snippet "device-name" } " and 16 for the " { $snippet "voice-count" } ". The engine is returned in the stopped state; to start audio processing, use " { $link start-audio } " or " { $link start-audio* } "." } ;
27
28 HELP: <static-audio-clip>
29 { $values
30     { "audio-engine" audio-engine } { "source" "an object implementing the " { $link "audio.engine-sources" } } { "audio" audio } { "loop?" boolean }
31     { "audio-clip/f" { $maybe audio-clip } }
32 }
33 { $description "Constructs a " { $link static-audio-clip } " tied to " { $snippet "source" } " and playing audio generated by " { $snippet "generator" } ". The clip won't be played until " { $link play-clip } " or " { $link play-clips } " is called on it. If " { $snippet "loop?" } " is true, the clip will repeat indefinitely when played until stopped with " { $link stop-clip } ". Otherwise, the clip will automatically be " { $link dispose } "d by the " { $link audio-engine } " after it finishes playing. If the engine has no available voices, no clip will be constructed, and " { $link f } " will be returned." } ;
34
35 HELP: <streaming-audio-clip>
36 { $values
37     { "audio-engine" audio-engine } { "source" "an object implementing the " { $link "audio.engine-sources" } } { "generator" "an object implementing the " { $link "audio.engine-generators" } } { "buffer-count" integer }
38     { "audio-clip/f" { $maybe audio-clip } }
39 }
40 { $description "Constructs a " { $link streaming-audio-clip } " tied to " { $snippet "source" } " and playing audio generated by " { $snippet "generator" } ". " { $snippet "buffer-count" } " buffers will be allocated for the clip. The clip won't be played until " { $link play-clip } " or " { $link play-clips } " is called on it. The clip will automatically be " { $link dispose } "d by the " { $link audio-engine } " when the generator stops supplying data and all the buffered data has played. The clip will in turn dispose its generator when it is disposed. If the engine has no available voices, no clip will be constructed, the generator will be disposed, and " { $link f } " will be returned." } ;
41
42 HELP: audio-clip
43 { $class-description "Opaque type of clips being played by an " { $link audio-engine } ". There are two subclasses provided:"
44 { $list
45     { { $link static-audio-clip } ", constructed by " { $link <static-audio-clip> } " or " { $link play-static-audio-clip } }
46     { { $link streaming-audio-clip } ", constructed by " { $link <streaming-audio-clip> } " or " { $link play-streaming-audio-clip } }
47 }
48 "Clip objects are transient. They get " { $link dispose } "d and invalidated by the controlling " { $link audio-engine } " when their playback finishes or is stopped. The " { $link play-clip } ", " { $link pause-clip } ", and " { $link stop-clip } " words control playback of individual clips. " { $link play-clips } ", " { $link pause-clips } ", and " { $link stop-clips } " synchronize the playing, pausing, or stopping of multiple clips." } ;
49
50 HELP: audio-context-not-available
51 { $values
52     { "device-name" { $maybe string } }
53 }
54 { $description "Errors of this type are thrown by " { $link <audio-engine> } " when an OpenAL context cannot be created for the device named " { $snippet "device-name" } "." } ;
55
56 HELP: audio-device-not-found
57 { $values
58     { "device-name" { $maybe string } }
59 }
60 { $description "Errors of this type are thrown by " { $link <audio-engine> } " when it is unable to open the OpenAL device named " { $snippet "device-name" } "." } ;
61
62 HELP: audio-distance
63 { $values
64     { "source" "an object implementing the " { $link "audio.engine-sources" } }
65     { "distance" float }
66 }
67 { $description "Returns the reference distance (that is, the distance from the listener below which the clip plays at full volume) for a playing audio clip. Larger reference distances make the clip play louder at further distances from the listener." } ;
68
69 HELP: audio-engine
70 { $class-description "Objects of this class encapsulate the state for an active audio engine. Audio processing on an engine can be started and stopped with " { $link start-audio } ", " { $link start-audio* } ", and " { $link stop-audio } ". While running, " { $link update-audio } " must be called on an engine regularly to update source and listener attributes and refill buffers for streaming clips."
71 $nl
72 "An engine object should be treated as opaque, except for the " { $snippet "listener" } " slot. This slot may be filled with any object implementing the " { $link "audio.engine-listener" } " protocol, which will then be used to control the position, velocity, volume, and other attributes of the lisetener. By default, this slot contains an " { $link audio-listener } " tuple with all the slots set to their initial values." } ;
73
74 HELP: audio-gain
75 { $values
76     { "source/listener" "an object implementing the " { $link "audio.engine-sources" } " or " { $link "audio.engine-listener" } }
77     { "gain" "a " { $link float } " between 0.0 and 1.0" }
78 }
79 { $description "Returns the base gain for an individual audio clip, or for the listener. A clip source's gain will be attenuated by its distance from the listener. The listener's gain will be multiplied on top of each source's gain." } ;
80
81 HELP: audio-listener
82 { $class-description "A tuple class that trivially implements the " { $link "audio.engine-listener" } " with accessors on its tuple slots."
83 { $list
84     { { $snippet "position" } " provides the " { $link audio-position } "." }
85     { { $snippet "gain" } " provides the " { $link audio-gain } "." }
86     { { $snippet "velocity" } " provides the " { $link audio-velocity } "." }
87     { { $snippet "orientation" } " provides the " { $link audio-orientation } "." }
88 } } ;
89
90 HELP: audio-orientation
91 { $values
92     { "listener" "an object implementing the " { $link "audio.engine-listener" } }
93     { "orientation" audio-orientation }
94 }
95 { $description "Returns the orientation of the listener. The orientation must be returned in an " { $snippet "audio-orientation" } " tuple with the following slots:"
96 { $list
97     { { $snippet "forward" } " is a 3-component vector indicating the direction the listener is facing." }
98     { { $snippet "up" } " is a 3-component vector indicating the \"up\" direction for the listener. This vector does not need to be normal to the " { $snippet "forward" } " vector." }
99 } "The vectors do not need to be normalized." } ;
100
101 HELP: audio-position
102 { $values
103     { "source/listener" "an object implementing the " { $link "audio.engine-sources" } " or " { $link "audio.engine-listener" } }
104     { "position" "a 3-component float vector" }
105 }
106 { $description "Returns the position of an audio clip or of the listener. These positions determine the distance between clips and the listener, which in turn control the attenuation of the clips." } ;
107
108 HELP: audio-relative?
109 { $values
110     { "source" "an object implementing the " { $link "audio.engine-sources" } }
111     { "relative?" boolean }
112 }
113 { $description "If true, the " { $link audio-position } " and " { $link audio-velocity } " of the clip will be taken as being relative to the listener instead of in world space." } ;
114
115 HELP: audio-rolloff
116 { $values
117     { "source" "an object implementing the " { $link "audio.engine-sources" } }
118     { "rolloff" float }
119 }
120 { $description "Returns the rolloff factor for an audio clip. Rolloff factors greater than one will result in greater distance-based attenuation, and factors less than one will result in lesser attenuation." } ;
121
122 HELP: audio-source
123 { $class-description "A tuple class that trivially implements the " { $link "audio.engine-sources" } " with accessors on its tuple slots."
124 { $list
125     { { $snippet "position" } " provides the " { $link audio-position } "." }
126     { { $snippet "gain" } " provides the " { $link audio-gain } "." }
127     { { $snippet "velocity" } " provides the " { $link audio-velocity } "." }
128     { { $snippet "relative?" } " provides the " { $link audio-relative? } " value." }
129     { { $snippet "distance" } " provides the " { $link audio-distance } "." }
130     { { $snippet "rolloff" } " provides the " { $link audio-rolloff } "." }
131 } } ;
132
133 HELP: audio-velocity
134 { $values
135     { "source/listener" "an object implementing the " { $link "audio.engine-sources" } " or " { $link "audio.engine-listener" } }
136     { "velocity" "a 3-component float vector" }
137 }
138 { $description "Returns the velocity of an audio clip or of the listener. The relative velocity of each source to the listener is used to calculate a Doppler effect on its associated clips." } ;
139
140 HELP: generate-audio
141 { $values
142     { "generator" "an object implementing the " { $link "audio.engine-generators" } }
143     { "c-ptr" { $maybe c-ptr } } { "size" { $maybe integer } }
144 }
145 { $description "Tells " { $snippet "generator" } " to generate another block of PCM data. " { $snippet "c-ptr" } " can be a " { $link byte-array } " or " { $link alien } " pointer. " { $snippet "size" } " indicates the size in bytes of the returned buffer. The generator is allowed to reuse the buffer; the engine will copy the data to its own internal buffer before its next call to " { $snippet "generate-audio" } ". The method can provide " { $link f } " for both outputs or a " { $snippet "size" } " of 0 to indicate that its stream is exhausted." } ;
146
147 HELP: generator-audio-format
148 { $values
149     { "generator" "an object implementing the " { $link "audio.engine-generators" } }
150     { "channels" integer } { "sample-bits" integer } { "sample-rate" integer }
151 }
152 { $description "Returns the number of channels (1 for mono, 2 for stereo), number of bits per sample, and sample rate in hertz of the PCM data generated by " { $snippet "generator" } "." } ;
153
154 HELP: pause-clip
155 { $values
156     { "audio-clip" audio-clip }
157 }
158 { $description "Pauses the " { $link audio-clip } "." }
159 { $notes "Use " { $link pause-clips } " to synchronize the pausing of multiple clips." } ;
160
161 HELP: pause-clips
162 { $values
163     { "audio-clips" "a sequence of " { $link audio-clip } "s" }
164 }
165 { $description "Pauses all of the " { $link audio-clip } "s at the exact same time." } ;
166
167 HELP: play-clip
168 { $values
169     { "audio-clip" audio-clip }
170 }
171 { $description "Starts or resumes playing the " { $link audio-clip } "." }
172 { $notes "Use " { $link play-clips } " to synchronize the playing of multiple clips." } ;
173
174 HELP: play-clips
175 { $values
176     { "audio-clips" "a sequence of " { $link audio-clip } "s" }
177 }
178 { $description "Plays all of the " { $link audio-clip } "s at the exact same time." } ;
179
180 HELP: play-static-audio-clip
181 { $values
182     { "audio-engine" audio-engine } { "source" "an object implementing the " { $link "audio.engine-sources" } } { "audio" audio } { "loop?" boolean }
183     { "audio-clip/f" { $maybe audio-clip } }
184 }
185 { $description "Constructs and immediately starts playing a " { $link static-audio-clip } " tied to " { $snippet "source" } " and playing audio generated by " { $snippet "generator" } ". If " { $snippet "loop?" } " is true, the clip will repeat indefinitely until stopped with " { $link stop-clip } ". Otherwise, the clip will automatically be " { $link dispose } "d by the " { $link audio-engine } " when it finishes playing. If the engine has no available voices, no clip will be constructed, and " { $link f } " will be returned." }
186 { $notes "Use " { $link play-clips } " with " { $link <static-audio-clip> } " and " { $link <streaming-audio-clip> } " to synchronize the playing of multiple clips." } ;
187
188 HELP: play-streaming-audio-clip
189 { $values
190     { "audio-engine" audio-engine } { "source" "an object implementing the " { $link "audio.engine-sources" } } { "generator" "an object implementing the " { $link "audio.engine-generators" } } { "buffer-count" integer }
191     { "audio-clip/f" { $maybe audio-clip } }
192 }
193 { $description "Constructs and immediately starts playing a " { $link streaming-audio-clip } " tied to " { $snippet "source" } " and playing audio generated by " { $snippet "generator" } ". " { $snippet "buffer-count" } " buffers will be allocated for the clip. The clip will automatically be " { $link dispose } "d by the " { $link audio-engine } " when the generator stops supplying data and all the buffered data has played. The clip will in turn dispose its generator when it is disposed. If the engine has no available voices, no clip will be constructed, the generator will be disposed, and " { $link f } " will be returned." }
194 { $notes "Use " { $link play-clips } " with " { $link <static-audio-clip> } " and " { $link <streaming-audio-clip> } " to synchronize the playing of multiple clips." } ;
195
196 HELP: start-audio
197 { $values
198     { "audio-engine" audio-engine }
199 }
200 { $description "Starts processing of the " { $link audio-engine } ", and starts a thread that will call " { $link update-audio } " 50 times per second. If you will be integrating your own timer mechanism, " { $link start-audio* } " will start processing without providing the update thread." } ;
201
202 HELP: start-audio*
203 { $values
204     { "audio-engine" audio-engine }
205 }
206 { $description "Starts processing of the " { $link audio-engine } ". Unlike " { $link start-audio } ", this does not start a thread to call " { $link update-audio } " for you. This is useful if you will be integrating your own timer mechanism (such as a " { $vocab-link "game.loop" } ") to keep the audio engine updated." } ;
207
208 HELP: static-audio-clip
209 { $class-description "An " { $link audio-clip } " that plays back static, prerendered, fixed-size PCM data from an " { $link audio } " object. Use " { $link <static-audio-clip> } " or " { $link play-static-audio-clip } " to construct static audio clips." } ;
210
211 HELP: stop-audio
212 { $values
213     { "audio-engine" audio-engine }
214 }
215 { $description "Stops processing of the " { $link audio-engine } " and invalidates any currently playing " { $link audio-clip } "s. The engine can be restarted using " { $link start-audio } " or " { $link start-audio* } "; however, any clips that were playing will remain invalidated." } ;
216
217 HELP: stop-clip
218 { $values
219     { "audio-clip" audio-clip }
220 }
221 { $description "Stops and disposes an audio clip." }
222 { $notes "Use " { $link pause-clip } " if playback will need to be continued. Use " { $link stop-clips } " to synchronize the stopping of multiple clips." } ;
223
224 HELP: stop-clips
225 { $values
226     { "audio-clips" "a sequence of " { $link audio-clip } "s" }
227 }
228 { $description "Stops all of the " { $link audio-clip } "s at the exact same time. All of the clips will be " { $link dispose } "d and rendered invalid." }
229 { $notes "Use " { $link pause-clips } " if playback will need to be continued." } ;
230
231 HELP: streaming-audio-clip
232 { $class-description "An " { $link audio-clip } " that plays back PCM data streamed by a generator object implementing the " { $link "audio.engine-generators" } ". Use " { $link <streaming-audio-clip> } " or " { $link play-streaming-audio-clip } " to construct streaming audio clips." } ;
233
234 HELP: update-audio
235 { $values
236     { "audio-engine" audio-engine }
237 }
238 { $description "Updates the " { $link audio-engine } " state, refilling processed audio buffers for playing " { $link streaming-audio-clip } "s as well as updating the listener and source attributes of every audio clip. " { $link start-audio } " will start up a timer that will call " { $snippet "update-audio" } " regularly for you. If you start the audio engine using " { $link start-audio* } ", you will need to arrange for " { $snippet "update-audio" } " to be regularly invoked yourself." } ;
239
240 ARTICLE: "audio.engine-generators" "Audio generator protocol"
241 { $link streaming-audio-clip } "s require a " { $snippet "generator" } " object to supply PCM data to the audio engine as it is needed. To function as a generator, an object must provide methods for the following generic words:"
242 { $subsections
243     generate-audio
244     generator-audio-format
245 }
246 "A generator object must also be " { $link disposable } "." ;
247
248 ARTICLE: "audio.engine-listener" "Audio listener protocol"
249 "The " { $link audio-engine } " has a " { $snippet "listener" } " slot. The engine uses the object in this slot to determine the position, velocity, volume, and other attributes of the frame of reference for audio playback. These attributes are dynamic; every time " { $link update-audio } " runs, the listener attributes are queried and updated. The listener object must provide methods for the following generic words:"
250 { $subsections
251     audio-position
252     audio-gain
253     audio-velocity
254     audio-orientation
255 }
256 "Some of these methods are shared with the " { $link "audio.engine-sources" } "."
257 $nl
258 "For simple applications, a tuple class is provided with a trivial implementation of these methods:"
259 { $subsections
260     audio-listener
261 } ;
262
263 ARTICLE: "audio.engine-sources" "Audio source protocol"
264 "Every audio clip has an associated " { $snippet "source" } " object. The " { $link audio-engine } " uses this object to determine the position, velocity, volume, and other attributes of the clip. These attributes are dynamic; every time " { $link update-audio } " runs, these attributes are queried and updated for every currently playing clip. The source object must provide methods for the following generic words:"
265 { $subsections
266     audio-position
267     audio-gain
268     audio-velocity
269     audio-relative?
270     audio-distance
271     audio-rolloff
272 }
273 "Some of these methods are shared with the " { $link "audio.engine-listener" } "."
274 $nl
275 "For simple applications, a tuple class is provided with a trivial implementation of these methods:"
276 { $subsections
277     audio-source
278 } ;
279
280 ARTICLE: "audio.engine" "Audio playback engine"
281 "The " { $vocab-link "audio.engine" } " manages playback of prerendered and streaming audio clips. It uses OpenAL as the underlying interface to audio hardware. As clips play, their 3D location, volume, and other attributes can be updated on the fly."
282 $nl
283 "An " { $link audio-engine } " object manages the connection to the OpenAL implementation and any playing clips:"
284 { $subsections
285     audio-engine
286     <audio-engine>
287     <standard-audio-engine>
288 }
289 "The audio engine can be started and stopped. While it is running, it must be regularly updated to keep audio buffers full and clip attributes up to date."
290 { $subsections
291     start-audio
292     start-audio*
293     stop-audio
294     update-audio
295 }
296 "Audio clips are represented by " { $link audio-clip } " objects while they are playing. Words are provided to control the playback of clips:"
297 { $subsections
298     audio-clip
299     play-clip
300     pause-clip
301     stop-clip
302     play-clips
303     pause-clips
304     stop-clips
305 }
306 "Two types of audio clip objects can be played by the engine. A " { $link static-audio-clip } " plays back a static, prerendered, fixed-size block of PCM data from an " { $link audio } " object."
307 { $subsections
308     static-audio-clip
309     <static-audio-clip>
310     play-static-audio-clip
311 }
312 "A " { $link streaming-audio-clip } " generates PCM data on the fly from a generator object."
313 { $subsections
314     "audio.engine-generators"
315     streaming-audio-clip
316     <streaming-audio-clip>
317     play-streaming-audio-clip
318 }
319 "Every audio clip has an associated " { $snippet "source" } " object that determines the clip's 3D position, velocity, volume, and other attributes. The engine itself has a " { $snippet "listener" } " that describes the position, orientation, velocity, and volume that make up the frame of reference for audio playback."
320 { $subsections
321     "audio.engine-sources"
322     "audio.engine-listener"
323 } ;
324
325 ABOUT: "audio.engine"