]> gitweb.factorcode.org Git - factor.git/blob - extra/audio/engine/engine-docs.factor
20b195a0cbe0a7b78c349404dd9586ec7918f843
[factor.git] / extra / audio / engine / engine-docs.factor
1 ! (c)2010 Joe Groff bsd license
2 USING: alien audio byte-arrays destructors help.markup
3 help.syntax kernel math strings ;
4 IN: audio.engine
5
6 HELP: <audio-engine>
7 { $values
8     { "device-name" { $maybe string } } { "voice-count" integer }
9     { "engine" audio-engine }
10 }
11 { $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* } "." } ;
12
13 HELP: <audio-orientation-state>
14 { $values
15     { "forward" "a sequence of 3 floats" } { "up" "a sequence of 3 floats" }
16     { "audio-orientation-state" audio-orientation-state }
17 }
18 { $description "Constructs an " { $link audio-orientation-state } " tuple." } ;
19
20 HELP: <standard-audio-engine>
21 { $values
22
23     { "engine" audio-engine }
24 }
25 { $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* } "." } ;
26
27 HELP: <static-audio-clip>
28 { $values
29     { "audio-engine" audio-engine } { "source" "an object implementing the " { $link "audio.engine-sources" } } { "audio" audio } { "loop?" boolean }
30     { "audio-clip/f" { $maybe audio-clip } }
31 }
32 { $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." } ;
33
34 HELP: <streaming-audio-clip>
35 { $values
36     { "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 }
37     { "audio-clip/f" { $maybe audio-clip } }
38 }
39 { $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." } ;
40
41 HELP: audio-clip
42 { $class-description "Opaque type of clips being played by an " { $link audio-engine } ". There are two subclasses provided:"
43 { $list
44     { { $link static-audio-clip } ", constructed by " { $link <static-audio-clip> } " or " { $link play-static-audio-clip } }
45     { { $link streaming-audio-clip } ", constructed by " { $link <streaming-audio-clip> } " or " { $link play-streaming-audio-clip } }
46 }
47 "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." } ;
48
49 HELP: audio-context-not-available
50 { $values
51     { "device-name" { $maybe string } }
52 }
53 { $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" } "." } ;
54
55 HELP: audio-device-not-found
56 { $values
57     { "device-name" { $maybe string } }
58 }
59 { $description "Errors of this type are thrown by " { $link <audio-engine> } " when it is unable to open the OpenAL device named " { $snippet "device-name" } "." } ;
60
61 HELP: audio-distance
62 { $values
63     { "source" "an object implementing the " { $link "audio.engine-sources" } }
64     { "distance" float }
65 }
66 { $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." } ;
67
68 HELP: audio-engine
69 { $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."
70 $nl
71 "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." } ;
72
73 HELP: audio-gain
74 { $values
75     { "source/listener" "an object implementing the " { $link "audio.engine-sources" } " or " { $link "audio.engine-listener" } }
76     { "gain" "a " { $link float } " between 0.0 and 1.0" }
77 }
78 { $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." } ;
79
80 HELP: audio-listener
81 { $class-description "A tuple class that trivially implements the " { $link "audio.engine-listener" } " with accessors on its tuple slots."
82 { $list
83     { { $snippet "position" } " provides the " { $link audio-position } "." }
84     { { $snippet "gain" } " provides the " { $link audio-gain } "." }
85     { { $snippet "velocity" } " provides the " { $link audio-velocity } "." }
86     { { $snippet "orientation" } " provides the " { $link audio-orientation } "." }
87 } } ;
88
89 HELP: audio-orientation
90 { $values
91     { "listener" "an object implementing the " { $link "audio.engine-listener" } }
92     { "orientation" audio-orientation }
93 }
94 { $description "Returns the orientation of the listener. The orientation must be returned in an " { $snippet "audio-orientation" } " tuple with the following slots:"
95 { $list
96     { { $snippet "forward" } " is a 3-component vector indicating the direction the listener is facing." }
97     { { $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." }
98 } "The vectors do not need to be normalized." } ;
99
100 HELP: audio-position
101 { $values
102     { "source/listener" "an object implementing the " { $link "audio.engine-sources" } " or " { $link "audio.engine-listener" } }
103     { "position" "a 3-component float vector" }
104 }
105 { $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." } ;
106
107 HELP: audio-relative?
108 { $values
109     { "source" "an object implementing the " { $link "audio.engine-sources" } }
110     { "relative?" boolean }
111 }
112 { $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." } ;
113
114 HELP: audio-rolloff
115 { $values
116     { "source" "an object implementing the " { $link "audio.engine-sources" } }
117     { "rolloff" float }
118 }
119 { $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." } ;
120
121 HELP: audio-source
122 { $class-description "A tuple class that trivially implements the " { $link "audio.engine-sources" } " with accessors on its tuple slots."
123 { $list
124     { { $snippet "position" } " provides the " { $link audio-position } "." }
125     { { $snippet "gain" } " provides the " { $link audio-gain } "." }
126     { { $snippet "velocity" } " provides the " { $link audio-velocity } "." }
127     { { $snippet "relative?" } " provides the " { $link audio-relative? } " value." }
128     { { $snippet "distance" } " provides the " { $link audio-distance } "." }
129     { { $snippet "rolloff" } " provides the " { $link audio-rolloff } "." }
130 } } ;
131
132 HELP: audio-velocity
133 { $values
134     { "source/listener" "an object implementing the " { $link "audio.engine-sources" } " or " { $link "audio.engine-listener" } }
135     { "velocity" "a 3-component float vector" }
136 }
137 { $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." } ;
138
139 HELP: generate-audio
140 { $values
141     { "generator" "an object implementing the " { $link "audio.engine-generators" } }
142     { "c-ptr" { $maybe c-ptr } } { "size" { $maybe integer } }
143 }
144 { $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." } ;
145
146 HELP: generator-audio-format
147 { $values
148     { "generator" "an object implementing the " { $link "audio.engine-generators" } }
149     { "channels" integer } { "sample-bits" integer } { "sample-rate" integer }
150 }
151 { $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" } "." } ;
152
153 HELP: pause-clip
154 { $values
155     { "audio-clip" audio-clip }
156 }
157 { $description "Pauses the " { $link audio-clip } "." }
158 { $notes "Use " { $link pause-clips } " to synchronize the pausing of multiple clips." } ;
159
160 HELP: pause-clips
161 { $values
162     { "audio-clips" "a sequence of " { $link audio-clip } "s" }
163 }
164 { $description "Pauses all of the " { $link audio-clip } "s at the exact same time." } ;
165
166 HELP: play-clip
167 { $values
168     { "audio-clip" audio-clip }
169 }
170 { $description "Starts or resumes playing the " { $link audio-clip } "." }
171 { $notes "Use " { $link play-clips } " to synchronize the playing of multiple clips." } ;
172
173 HELP: play-clips
174 { $values
175     { "audio-clips" "a sequence of " { $link audio-clip } "s" }
176 }
177 { $description "Plays all of the " { $link audio-clip } "s at the exact same time." } ;
178
179 HELP: play-static-audio-clip
180 { $values
181     { "audio-engine" audio-engine } { "source" "an object implementing the " { $link "audio.engine-sources" } } { "audio" audio } { "loop?" boolean }
182     { "audio-clip/f" { $maybe audio-clip } }
183 }
184 { $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." }
185 { $notes "Use " { $link play-clips } " with " { $link <static-audio-clip> } " and " { $link <streaming-audio-clip> } " to synchronize the playing of multiple clips." } ;
186
187 HELP: play-streaming-audio-clip
188 { $values
189     { "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 }
190     { "audio-clip/f" { $maybe audio-clip } }
191 }
192 { $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." }
193 { $notes "Use " { $link play-clips } " with " { $link <static-audio-clip> } " and " { $link <streaming-audio-clip> } " to synchronize the playing of multiple clips." } ;
194
195 HELP: start-audio
196 { $values
197     { "audio-engine" audio-engine }
198 }
199 { $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." } ;
200
201 HELP: start-audio*
202 { $values
203     { "audio-engine" audio-engine }
204 }
205 { $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." } ;
206
207 HELP: static-audio-clip
208 { $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." } ;
209
210 HELP: stop-audio
211 { $values
212     { "audio-engine" audio-engine }
213 }
214 { $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." } ;
215
216 HELP: stop-clip
217 { $values
218     { "audio-clip" audio-clip }
219 }
220 { $description "Stops and disposes an audio clip." }
221 { $notes "Use " { $link pause-clip } " if playback will need to be continued. Use " { $link stop-clips } " to synchronize the stopping of multiple clips." } ;
222
223 HELP: stop-clips
224 { $values
225     { "audio-clips" "a sequence of " { $link audio-clip } "s" }
226 }
227 { $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." }
228 { $notes "Use " { $link pause-clips } " if playback will need to be continued." } ;
229
230 HELP: streaming-audio-clip
231 { $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." } ;
232
233 HELP: update-audio
234 { $values
235     { "audio-engine" audio-engine }
236 }
237 { $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." } ;
238
239 ARTICLE: "audio.engine-generators" "Audio generator protocol"
240 { $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:"
241 { $subsections
242     generate-audio
243     generator-audio-format
244 }
245 "A generator object must also be " { $link disposable } "." ;
246
247 ARTICLE: "audio.engine-listener" "Audio listener protocol"
248 "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:"
249 { $subsections
250     audio-position
251     audio-gain
252     audio-velocity
253     audio-orientation
254 }
255 "Some of these methods are shared with the " { $link "audio.engine-sources" } "."
256 $nl
257 "For simple applications, a tuple class is provided with a trivial implementation of these methods:"
258 { $subsections
259     audio-listener
260 } ;
261
262 ARTICLE: "audio.engine-sources" "Audio source protocol"
263 "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:"
264 { $subsections
265     audio-position
266     audio-gain
267     audio-velocity
268     audio-relative?
269     audio-distance
270     audio-rolloff
271 }
272 "Some of these methods are shared with the " { $link "audio.engine-listener" } "."
273 $nl
274 "For simple applications, a tuple class is provided with a trivial implementation of these methods:"
275 { $subsections
276     audio-source
277 } ;
278
279 ARTICLE: "audio.engine" "Audio playback engine"
280 "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."
281 $nl
282 "An " { $link audio-engine } " object manages the connection to the OpenAL implementation and any playing clips:"
283 { $subsections
284     audio-engine
285     <audio-engine>
286     <standard-audio-engine>
287 }
288 "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."
289 { $subsections
290     start-audio
291     start-audio*
292     stop-audio
293     update-audio
294 }
295 "Audio clips are represented by " { $link audio-clip } " objects while they are playing. Words are provided to control the playback of clips:"
296 { $subsections
297     audio-clip
298     play-clip
299     pause-clip
300     stop-clip
301     play-clips
302     pause-clips
303     stop-clips
304 }
305 "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."
306 { $subsections
307     static-audio-clip
308     <static-audio-clip>
309     play-static-audio-clip
310 }
311 "A " { $link streaming-audio-clip } " generates PCM data on the fly from a generator object."
312 { $subsections
313     "audio.engine-generators"
314     streaming-audio-clip
315     <streaming-audio-clip>
316     play-streaming-audio-clip
317 }
318 "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."
319 { $subsections
320     "audio.engine-sources"
321     "audio.engine-listener"
322 } ;
323
324 ABOUT: "audio.engine"