diff options
author | McCabe Maxsted | 2010-11-02 21:32:04 -0700 |
---|---|---|
committer | McCabe Maxsted | 2010-11-02 21:32:04 -0700 |
commit | b5074f1a8e3306f1be9e93172d26c97ff088cea0 (patch) | |
tree | a53d5cc54a1f339b7637a9d7d8248eca42995af2 /linden/indra/llaudio/llaudioengine.h | |
parent | Revert "Fix Bug #671 (aka VWR-1603): Duckwalk is too fast" (diff) | |
parent | Uploaded the linux64 libraries created by Aleric to imprudenceviewer.org (diff) | |
download | meta-impy-b5074f1a8e3306f1be9e93172d26c97ff088cea0.zip meta-impy-b5074f1a8e3306f1be9e93172d26c97ff088cea0.tar.gz meta-impy-b5074f1a8e3306f1be9e93172d26c97ff088cea0.tar.bz2 meta-impy-b5074f1a8e3306f1be9e93172d26c97ff088cea0.tar.xz |
Merged webkit_plugins into weekly. Huzzah! The weekly branch now has browser/media plugin support
Diffstat (limited to 'linden/indra/llaudio/llaudioengine.h')
-rw-r--r-- | linden/indra/llaudio/llaudioengine.h | 457 |
1 files changed, 457 insertions, 0 deletions
diff --git a/linden/indra/llaudio/llaudioengine.h b/linden/indra/llaudio/llaudioengine.h new file mode 100644 index 0000000..a1b240e --- /dev/null +++ b/linden/indra/llaudio/llaudioengine.h | |||
@@ -0,0 +1,457 @@ | |||
1 | /** | ||
2 | * @file audioengine.h | ||
3 | * @brief Definition of LLAudioEngine base class abstracting the audio support | ||
4 | * | ||
5 | * $LicenseInfo:firstyear=2000&license=viewergpl$ | ||
6 | * | ||
7 | * Copyright (c) 2000-2009, Linden Research, Inc. | ||
8 | * | ||
9 | * Second Life Viewer Source Code | ||
10 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
11 | * to you under the terms of the GNU General Public License, version 2.0 | ||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 | ||
16 | * | ||
17 | * There are special exceptions to the terms and conditions of the GPL as | ||
18 | * it is applied to this Source Code. View the full text of the exception | ||
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
20 | * online at | ||
21 | * http://secondlifegrid.net/programs/open_source/licensing/flossexception | ||
22 | * | ||
23 | * By copying, modifying or distributing this software, you acknowledge | ||
24 | * that you have read and understood your obligations described above, | ||
25 | * and agree to abide by those obligations. | ||
26 | * | ||
27 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
28 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
29 | * COMPLETENESS OR PERFORMANCE. | ||
30 | * $/LicenseInfo$ | ||
31 | */ | ||
32 | |||
33 | |||
34 | #ifndef LL_AUDIOENGINE_H | ||
35 | #define LL_AUDIOENGINE_H | ||
36 | |||
37 | #include <list> | ||
38 | #include <map> | ||
39 | |||
40 | #include "v3math.h" | ||
41 | #include "v3dmath.h" | ||
42 | #include "lltimer.h" | ||
43 | #include "lluuid.h" | ||
44 | #include "llframetimer.h" | ||
45 | #include "llassettype.h" | ||
46 | |||
47 | #include "lllistener.h" | ||
48 | |||
49 | const F32 LL_WIND_UPDATE_INTERVAL = 0.1f; | ||
50 | const F32 LL_ROLLOFF_MULTIPLIER_UNDER_WATER = 5.f; // How much sounds are weaker under water | ||
51 | const F32 LL_WIND_UNDERWATER_CENTER_FREQ = 20.f; | ||
52 | |||
53 | const F32 ATTACHED_OBJECT_TIMEOUT = 5.0f; | ||
54 | const F32 DEFAULT_MIN_DISTANCE = 2.0f; | ||
55 | |||
56 | #define MAX_CHANNELS 30 | ||
57 | // Number of maximum rezzed objects with sounds + sounds without an object + UI sounds. | ||
58 | #define MAX_BUFFERS 100 | ||
59 | |||
60 | // This define is intended to allow us to switch from os based wav | ||
61 | // file loading to vfs based wav file loading. The problem is that I | ||
62 | // am unconvinced that the LLWaveFile works for loading sounds from | ||
63 | // memory. So, until that is fixed up, changed, whatever, this remains | ||
64 | // undefined. | ||
65 | //#define USE_WAV_VFILE | ||
66 | |||
67 | class LLVFS; | ||
68 | |||
69 | class LLAudioSource; | ||
70 | class LLAudioData; | ||
71 | class LLAudioChannel; | ||
72 | class LLAudioChannelOpenAL; | ||
73 | class LLAudioBuffer; | ||
74 | class LLStreamingAudioInterface; | ||
75 | |||
76 | |||
77 | // | ||
78 | // LLAudioEngine definition | ||
79 | // | ||
80 | |||
81 | class LLAudioEngine | ||
82 | { | ||
83 | friend class LLAudioChannelOpenAL; // bleh. channel needs some listener methods. | ||
84 | |||
85 | public: | ||
86 | enum LLAudioType | ||
87 | { | ||
88 | AUDIO_TYPE_NONE = 0, | ||
89 | AUDIO_TYPE_SFX = 1, | ||
90 | AUDIO_TYPE_UI = 2, | ||
91 | AUDIO_TYPE_AMBIENT = 3, | ||
92 | AUDIO_TYPE_GESTURE = 4, | ||
93 | AUDIO_TYPE_COUNT = 5 // last | ||
94 | }; | ||
95 | |||
96 | LLAudioEngine(); | ||
97 | virtual ~LLAudioEngine(); | ||
98 | |||
99 | // initialization/startup/shutdown | ||
100 | virtual bool init(const S32 num_channels, void *userdata); | ||
101 | virtual std::string getDriverName(bool verbose) = 0; | ||
102 | virtual void shutdown(); | ||
103 | |||
104 | // Used by the mechanics of the engine | ||
105 | //virtual void processQueue(const LLUUID &sound_guid); | ||
106 | virtual void setListener(LLVector3 pos,LLVector3 vel,LLVector3 up,LLVector3 at); | ||
107 | virtual void updateWind(LLVector3 direction, F32 camera_height_above_water) = 0; | ||
108 | virtual void idle(F32 max_decode_time = 0.f); | ||
109 | virtual void updateChannels(); | ||
110 | |||
111 | // | ||
112 | // "End user" functionality | ||
113 | // | ||
114 | virtual bool isWindEnabled(); | ||
115 | virtual void enableWind(bool state_b); | ||
116 | |||
117 | // Use these for temporarily muting the audio system. | ||
118 | // Does not change buffers, initialization, etc. but | ||
119 | // stops playing new sounds. | ||
120 | void setMuted(bool muted); | ||
121 | bool getMuted() const { return mMuted; } | ||
122 | #ifdef USE_PLUGIN_MEDIA | ||
123 | LLPluginClassMedia* initializeMedia(const std::string& media_type); | ||
124 | #endif | ||
125 | F32 getMasterGain(); | ||
126 | void setMasterGain(F32 gain); | ||
127 | |||
128 | F32 getSecondaryGain(S32 type); | ||
129 | void setSecondaryGain(S32 type, F32 gain); | ||
130 | |||
131 | F32 getInternetStreamGain(); | ||
132 | |||
133 | virtual void setDopplerFactor(F32 factor); | ||
134 | virtual F32 getDopplerFactor(); | ||
135 | virtual void setRolloffFactor(F32 factor); | ||
136 | virtual F32 getRolloffFactor(); | ||
137 | virtual void setMaxWindGain(F32 gain); | ||
138 | |||
139 | |||
140 | // Methods actually related to setting up and removing sounds | ||
141 | // Owner ID is the owner of the object making the request | ||
142 | void triggerSound(const LLUUID &sound_id, const LLUUID& owner_id, const F32 gain, | ||
143 | const S32 type = LLAudioEngine::AUDIO_TYPE_NONE, | ||
144 | const LLVector3d &pos_global = LLVector3d::zero); | ||
145 | bool preloadSound(const LLUUID &id); | ||
146 | |||
147 | void addAudioSource(LLAudioSource *asp); | ||
148 | void cleanupAudioSource(LLAudioSource *asp); | ||
149 | |||
150 | LLAudioSource *findAudioSource(const LLUUID &source_id); | ||
151 | LLAudioData *getAudioData(const LLUUID &audio_uuid); | ||
152 | |||
153 | // Internet stream implementation manipulation | ||
154 | LLStreamingAudioInterface *getStreamingAudioImpl(); | ||
155 | void setStreamingAudioImpl(LLStreamingAudioInterface *impl); | ||
156 | // Internet stream methods - these will call down into the *mStreamingAudioImpl if it exists | ||
157 | void startInternetStream(const std::string& url); | ||
158 | void stopInternetStream(); | ||
159 | void pauseInternetStream(int pause); | ||
160 | void updateInternetStream(); // expected to be called often | ||
161 | int isInternetStreamPlaying(); | ||
162 | // use a value from 0.0 to 1.0, inclusive | ||
163 | void setInternetStreamGain(F32 vol); | ||
164 | std::string getInternetStreamURL(); | ||
165 | |||
166 | // For debugging usage | ||
167 | virtual LLVector3 getListenerPos(); | ||
168 | |||
169 | LLAudioBuffer *getFreeBuffer(); // Get a free buffer, or flush an existing one if you have to. | ||
170 | LLAudioChannel *getFreeChannel(const F32 priority); // Get a free channel or flush an existing one if your priority is higher | ||
171 | void cleanupBuffer(LLAudioBuffer *bufferp); | ||
172 | |||
173 | bool hasDecodedFile(const LLUUID &uuid); | ||
174 | bool hasLocalFile(const LLUUID &uuid); | ||
175 | |||
176 | bool updateBufferForData(LLAudioData *adp, const LLUUID &audio_uuid = LLUUID::null); | ||
177 | |||
178 | |||
179 | // Asset callback when we're retrieved a sound from the asset server. | ||
180 | void startNextTransfer(); | ||
181 | static void assetCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type, void *user_data, S32 result_code, LLExtStat ext_status); | ||
182 | |||
183 | friend class LLPipeline; // For debugging | ||
184 | public: | ||
185 | F32 mMaxWindGain; // Hack. Public to set before fade in? | ||
186 | |||
187 | protected: | ||
188 | virtual LLAudioBuffer *createBuffer() = 0; | ||
189 | virtual LLAudioChannel *createChannel() = 0; | ||
190 | |||
191 | virtual void initWind() = 0; | ||
192 | virtual void cleanupWind() = 0; | ||
193 | virtual void setInternalGain(F32 gain) = 0; | ||
194 | |||
195 | void commitDeferredChanges(); | ||
196 | |||
197 | virtual void allocateListener() = 0; | ||
198 | |||
199 | |||
200 | // listener methods | ||
201 | virtual void setListenerPos(LLVector3 vec); | ||
202 | virtual void setListenerVelocity(LLVector3 vec); | ||
203 | virtual void orientListener(LLVector3 up, LLVector3 at); | ||
204 | virtual void translateListener(LLVector3 vec); | ||
205 | |||
206 | |||
207 | F64 mapWindVecToGain(LLVector3 wind_vec); | ||
208 | F64 mapWindVecToPitch(LLVector3 wind_vec); | ||
209 | F64 mapWindVecToPan(LLVector3 wind_vec); | ||
210 | |||
211 | protected: | ||
212 | LLListener *mListenerp; | ||
213 | |||
214 | bool mMuted; | ||
215 | void* mUserData; | ||
216 | |||
217 | S32 mLastStatus; | ||
218 | |||
219 | S32 mNumChannels; | ||
220 | bool mEnableWind; | ||
221 | |||
222 | LLUUID mCurrentTransfer; // Audio file currently being transferred by the system | ||
223 | LLFrameTimer mCurrentTransferTimer; | ||
224 | |||
225 | // A list of all audio sources that are known to the viewer at this time. | ||
226 | // This is most likely a superset of the ones that we actually have audio | ||
227 | // data for, or are playing back. | ||
228 | typedef std::map<LLUUID, LLAudioSource *> source_map; | ||
229 | typedef std::map<LLUUID, LLAudioData *> data_map; | ||
230 | |||
231 | source_map mAllSources; | ||
232 | data_map mAllData; | ||
233 | |||
234 | LLAudioChannel *mChannels[MAX_CHANNELS]; | ||
235 | |||
236 | // Buffers needs to change into a different data structure, as the number of buffers | ||
237 | // that we have active should be limited by RAM usage, not count. | ||
238 | LLAudioBuffer *mBuffers[MAX_BUFFERS]; | ||
239 | |||
240 | F32 mMasterGain; | ||
241 | F32 mInternalGain; // Actual gain set; either mMasterGain or 0 when mMuted is true. | ||
242 | F32 mSecondaryGain[AUDIO_TYPE_COUNT]; | ||
243 | |||
244 | F32 mNextWindUpdate; | ||
245 | |||
246 | LLFrameTimer mWindUpdateTimer; | ||
247 | |||
248 | private: | ||
249 | void setDefaults(); | ||
250 | LLStreamingAudioInterface *mStreamingAudioImpl; | ||
251 | }; | ||
252 | |||
253 | |||
254 | |||
255 | |||
256 | // | ||
257 | // Standard audio source. Can be derived from for special sources, such as those attached to objects. | ||
258 | // | ||
259 | |||
260 | |||
261 | class LLAudioSource | ||
262 | { | ||
263 | public: | ||
264 | // owner_id is the id of the agent responsible for making this sound | ||
265 | // play, for example, the owner of the object currently playing it | ||
266 | LLAudioSource(const LLUUID &id, const LLUUID& owner_id, const F32 gain, const S32 type = LLAudioEngine::AUDIO_TYPE_NONE); | ||
267 | virtual ~LLAudioSource(); | ||
268 | |||
269 | virtual void update(); // Update this audio source | ||
270 | void updatePriority(); | ||
271 | |||
272 | void preload(const LLUUID &audio_id); // Only used for preloading UI sounds, now. | ||
273 | |||
274 | void addAudioData(LLAudioData *adp, bool set_current = TRUE); | ||
275 | |||
276 | void setAmbient(const bool ambient) { mAmbient = ambient; } | ||
277 | bool isAmbient() const { return mAmbient; } | ||
278 | |||
279 | void setLoop(const bool loop) { mLoop = loop; } | ||
280 | bool isLoop() const { return mLoop; } | ||
281 | |||
282 | void setSyncMaster(const bool master) { mSyncMaster = master; } | ||
283 | bool isSyncMaster() const { return mSyncMaster; } | ||
284 | |||
285 | void setSyncSlave(const bool slave) { mSyncSlave = slave; } | ||
286 | bool isSyncSlave() const { return mSyncSlave; } | ||
287 | |||
288 | void setQueueSounds(const bool queue) { mQueueSounds = queue; } | ||
289 | bool isQueueSounds() const { return mQueueSounds; } | ||
290 | |||
291 | void setPlayedOnce(const bool played_once) { mPlayedOnce = played_once; } | ||
292 | |||
293 | void setType(S32 type) { mType = type; } | ||
294 | S32 getType() { return mType; } | ||
295 | |||
296 | void setPositionGlobal(const LLVector3d &position_global) { mPositionGlobal = position_global; } | ||
297 | LLVector3d getPositionGlobal() const { return mPositionGlobal; } | ||
298 | LLVector3 getVelocity() const { return mVelocity; } | ||
299 | F32 getPriority() const { return mPriority; } | ||
300 | |||
301 | // Gain should always be clamped between 0 and 1. | ||
302 | F32 getGain() const { return mGain; } | ||
303 | virtual void setGain(const F32 gain) { mGain = llclamp(gain, 0.f, 1.f); } | ||
304 | |||
305 | const LLUUID &getID() const { return mID; } | ||
306 | bool isDone() const; | ||
307 | bool isMuted() const { return mSourceMuted; } | ||
308 | |||
309 | LLAudioData *getCurrentData(); | ||
310 | LLAudioData *getQueuedData(); | ||
311 | LLAudioBuffer *getCurrentBuffer(); | ||
312 | |||
313 | bool setupChannel(); | ||
314 | bool play(const LLUUID &audio_id); // Start the audio source playing | ||
315 | |||
316 | bool hasPendingPreloads() const; // Has preloads that haven't been done yet | ||
317 | |||
318 | friend class LLAudioEngine; | ||
319 | friend class LLAudioChannel; | ||
320 | protected: | ||
321 | void setChannel(LLAudioChannel *channelp); | ||
322 | LLAudioChannel *getChannel() const { return mChannelp; } | ||
323 | |||
324 | protected: | ||
325 | LLUUID mID; // The ID of the source is that of the object if it's attached to an object. | ||
326 | LLUUID mOwnerID; // owner of the object playing the sound | ||
327 | F32 mPriority; | ||
328 | F32 mGain; | ||
329 | bool mSourceMuted; | ||
330 | bool mAmbient; | ||
331 | bool mLoop; | ||
332 | bool mSyncMaster; | ||
333 | bool mSyncSlave; | ||
334 | bool mQueueSounds; | ||
335 | bool mPlayedOnce; | ||
336 | S32 mType; | ||
337 | LLVector3d mPositionGlobal; | ||
338 | LLVector3 mVelocity; | ||
339 | |||
340 | //LLAudioSource *mSyncMasterp; // If we're a slave, the source that we're synced to. | ||
341 | LLAudioChannel *mChannelp; // If we're currently playing back, this is the channel that we're assigned to. | ||
342 | LLAudioData *mCurrentDatap; | ||
343 | LLAudioData *mQueuedDatap; | ||
344 | |||
345 | typedef std::map<LLUUID, LLAudioData *> data_map; | ||
346 | data_map mPreloadMap; | ||
347 | |||
348 | LLFrameTimer mAgeTimer; | ||
349 | }; | ||
350 | |||
351 | |||
352 | |||
353 | |||
354 | // | ||
355 | // Generic metadata about a particular piece of audio data. | ||
356 | // The actual data is handled by the derived LLAudioBuffer classes which are | ||
357 | // derived for each audio engine. | ||
358 | // | ||
359 | |||
360 | |||
361 | class LLAudioData | ||
362 | { | ||
363 | public: | ||
364 | LLAudioData(const LLUUID &uuid); | ||
365 | bool load(); | ||
366 | |||
367 | LLUUID getID() const { return mID; } | ||
368 | LLAudioBuffer *getBuffer() const { return mBufferp; } | ||
369 | |||
370 | bool hasLocalData() const { return mHasLocalData; } | ||
371 | bool hasDecodedData() const { return mHasDecodedData; } | ||
372 | bool hasValidData() const { return mHasValidData; } | ||
373 | |||
374 | void setHasLocalData(const bool hld) { mHasLocalData = hld; } | ||
375 | void setHasDecodedData(const bool hdd) { mHasDecodedData = hdd; } | ||
376 | void setHasValidData(const bool hvd) { mHasValidData = hvd; } | ||
377 | |||
378 | friend class LLAudioEngine; // Severe laziness, bad. | ||
379 | |||
380 | protected: | ||
381 | LLUUID mID; | ||
382 | LLAudioBuffer *mBufferp; // If this data is being used by the audio system, a pointer to the buffer will be set here. | ||
383 | bool mHasLocalData; | ||
384 | bool mHasDecodedData; | ||
385 | bool mHasValidData; | ||
386 | }; | ||
387 | |||
388 | |||
389 | // | ||
390 | // Base class for an audio channel, i.e. a channel which is capable of playing back a sound. | ||
391 | // Management of channels is done generically, methods for actually manipulating the channel | ||
392 | // are derived for each audio engine. | ||
393 | // | ||
394 | |||
395 | |||
396 | class LLAudioChannel | ||
397 | { | ||
398 | public: | ||
399 | LLAudioChannel(); | ||
400 | virtual ~LLAudioChannel(); | ||
401 | |||
402 | virtual void setSource(LLAudioSource *sourcep); | ||
403 | LLAudioSource *getSource() const { return mCurrentSourcep; } | ||
404 | |||
405 | void setSecondaryGain(F32 gain) { mSecondaryGain = gain; } | ||
406 | F32 getSecondaryGain() { return mSecondaryGain; } | ||
407 | |||
408 | friend class LLAudioEngine; | ||
409 | friend class LLAudioSource; | ||
410 | protected: | ||
411 | virtual void play() = 0; | ||
412 | virtual void playSynced(LLAudioChannel *channelp) = 0; | ||
413 | virtual void cleanup() = 0; | ||
414 | virtual bool isPlaying() = 0; | ||
415 | void setWaiting(const bool waiting) { mWaiting = waiting; } | ||
416 | bool isWaiting() const { return mWaiting; } | ||
417 | |||
418 | virtual bool updateBuffer(); // Check to see if the buffer associated with the source changed, and update if necessary. | ||
419 | virtual void update3DPosition() = 0; | ||
420 | virtual void updateLoop() = 0; // Update your loop/completion status, for use by queueing/syncing. | ||
421 | protected: | ||
422 | LLAudioSource *mCurrentSourcep; | ||
423 | LLAudioBuffer *mCurrentBufferp; | ||
424 | bool mLoopedThisFrame; | ||
425 | bool mWaiting; // Waiting for sync. | ||
426 | F32 mSecondaryGain; | ||
427 | }; | ||
428 | |||
429 | |||
430 | |||
431 | |||
432 | // Basically an interface class to the engine-specific implementation | ||
433 | // of audio data that's ready for playback. | ||
434 | // Will likely get more complex as we decide to do stuff like real streaming audio. | ||
435 | |||
436 | |||
437 | class LLAudioBuffer | ||
438 | { | ||
439 | public: | ||
440 | virtual ~LLAudioBuffer() {}; | ||
441 | virtual bool loadWAV(const std::string& filename) = 0; | ||
442 | virtual U32 getLength() = 0; | ||
443 | |||
444 | friend class LLAudioEngine; | ||
445 | friend class LLAudioChannel; | ||
446 | friend class LLAudioData; | ||
447 | protected: | ||
448 | bool mInUse; | ||
449 | LLAudioData *mAudioDatap; | ||
450 | LLFrameTimer mLastUseTimer; | ||
451 | }; | ||
452 | |||
453 | |||
454 | |||
455 | extern LLAudioEngine* gAudiop; | ||
456 | |||
457 | #endif | ||