PageRenderTime 81ms CodeModel.GetById 25ms app.highlight 51ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/llaudio/llaudioengine.h

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