aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--linden/indra/llaudio/audioengine.cpp184
-rw-r--r--linden/indra/llaudio/audioengine.h56
-rw-r--r--linden/indra/llaudio/audioengine_openal.cpp767
-rw-r--r--linden/indra/llaudio/audioengine_openal.h107
-rw-r--r--linden/indra/newview/llaudiosourcevo.cpp2
-rw-r--r--linden/indra/newview/llpreviewsound.cpp3
-rw-r--r--linden/indra/newview/llstartup.cpp51
-rw-r--r--linden/indra/newview/llviewermessage.cpp3
-rw-r--r--linden/indra/newview/llviewertexteditor.cpp3
-rw-r--r--linden/indra/newview/llvoavatar.cpp11
10 files changed, 549 insertions, 638 deletions
diff --git a/linden/indra/llaudio/audioengine.cpp b/linden/indra/llaudio/audioengine.cpp
index 5fb38c0..239981b 100644
--- a/linden/indra/llaudio/audioengine.cpp
+++ b/linden/indra/llaudio/audioengine.cpp
@@ -51,9 +51,6 @@ extern void request_sound(const LLUUID &sound_guid);
51 51
52LLAudioEngine* gAudiop = NULL; 52LLAudioEngine* gAudiop = NULL;
53 53
54// Maximum amount of time we wait for a transfer to complete before starting
55// off another one.
56const F32 MAX_CURRENT_TRANSFER_TIME = 60.f;
57 54
58// 55//
59// LLAudioEngine implementation 56// LLAudioEngine implementation
@@ -77,7 +74,8 @@ void LLAudioEngine::setDefaults()
77 74
78 mListenerp = NULL; 75 mListenerp = NULL;
79 76
80 mMuted = FALSE; 77 mMuted = false;
78 mUserData = NULL;
81 79
82 mLastStatus = 0; 80 mLastStatus = 0;
83 81
@@ -98,16 +96,20 @@ void LLAudioEngine::setDefaults()
98 mInternetStreamGain = 0.125f; 96 mInternetStreamGain = 0.125f;
99 mNextWindUpdate = 0.f; 97 mNextWindUpdate = 0.f;
100 98
99 mInternetStreamMedia = NULL;
100 mInternetStreamURL.clear();
101
101 for (U32 i = 0; i < LLAudioEngine::AUDIO_TYPE_COUNT; i++) 102 for (U32 i = 0; i < LLAudioEngine::AUDIO_TYPE_COUNT; i++)
102 mSecondaryGain[i] = 1.0f; 103 mSecondaryGain[i] = 1.0f;
103} 104}
104 105
105 106
106BOOL LLAudioEngine::init(const S32 num_channels) 107bool LLAudioEngine::init(const S32 num_channels, void* userdata)
107{ 108{
108 setDefaults(); 109 setDefaults();
109 110
110 mNumChannels = num_channels; 111 mNumChannels = num_channels;
112 mUserData = userdata;
111 113
112 allocateListener(); 114 allocateListener();
113 115
@@ -126,6 +128,9 @@ void LLAudioEngine::shutdown()
126 delete gAudioDecodeMgrp; 128 delete gAudioDecodeMgrp;
127 gAudioDecodeMgrp = NULL; 129 gAudioDecodeMgrp = NULL;
128 130
131 // Clean up wind source
132 cleanupWind();
133
129 // Clean up audio sources 134 // Clean up audio sources
130 source_map::iterator iter_src; 135 source_map::iterator iter_src;
131 for (iter_src = mAllSources.begin(); iter_src != mAllSources.end(); iter_src++) 136 for (iter_src = mAllSources.begin(); iter_src != mAllSources.end(); iter_src++)
@@ -146,22 +151,146 @@ void LLAudioEngine::shutdown()
146 S32 i; 151 S32 i;
147 for (i = 0; i < MAX_CHANNELS; i++) 152 for (i = 0; i < MAX_CHANNELS; i++)
148 { 153 {
149 if (mChannels[i]) 154 delete mChannels[i];
150 { 155 mChannels[i] = NULL;
151 delete mChannels[i];
152 mChannels[i] = NULL;
153 }
154 } 156 }
155 157
156 // Clean up buffers 158 // Clean up buffers
157 for (i = 0; i < MAX_BUFFERS; i++) 159 for (i = 0; i < MAX_BUFFERS; i++)
158 { 160 {
159 if (mBuffers[i]) 161 delete mBuffers[i];
162 mBuffers[i] = NULL;
163 }
164
165 delete mInternetStreamMedia;
166 mInternetStreamMedia = NULL;
167 mInternetStreamURL.clear();
168}
169
170
171// virtual
172void LLAudioEngine::startInternetStream(const std::string& url)
173{
174 llinfos << "entered startInternetStream()" << llendl;
175
176 if (!mInternetStreamMedia)
177 {
178 LLMediaManager* mgr = LLMediaManager::getInstance();
179 if (mgr)
160 { 180 {
161 delete mBuffers[i]; 181 mInternetStreamMedia = mgr->createSourceFromMimeType(LLURI(url).scheme(), "audio/mpeg"); // assumes that whatever media implementation supports mp3 also supports vorbis.
162 mBuffers[i] = NULL; 182 llinfos << "mInternetStreamMedia is now " << mInternetStreamMedia << llendl;
183 }
184 }
185
186 if(!mInternetStreamMedia)
187 return;
188
189 if (!url.empty()) {
190 llinfos << "Starting internet stream: " << url << llendl;
191 mInternetStreamURL = url;
192 mInternetStreamMedia->navigateTo ( url );
193 llinfos << "Playing....." << llendl;
194 mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_START);
195 mInternetStreamMedia->updateMedia();
196 } else {
197 llinfos << "setting stream to NULL"<< llendl;
198 mInternetStreamURL.clear();
199 mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_STOP);
200 mInternetStreamMedia->updateMedia();
201 }
202 //#endif
203}
204
205// virtual
206void LLAudioEngine::stopInternetStream()
207{
208 llinfos << "entered stopInternetStream()" << llendl;
209
210 if(mInternetStreamMedia)
211 {
212 if( ! mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_STOP)){
213 llinfos << "attempting to stop stream failed!" << llendl;
214 }
215 mInternetStreamMedia->updateMedia();
216 }
217
218 mInternetStreamURL.clear();
219}
220
221// virtual
222void LLAudioEngine::pauseInternetStream(int pause)
223{
224 llinfos << "entered pauseInternetStream()" << llendl;
225
226 if(!mInternetStreamMedia)
227 return;
228
229 if(pause)
230 {
231 if(! mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_PAUSE))
232 {
233 llinfos << "attempting to pause stream failed!" << llendl;
163 } 234 }
235 } else {
236 if(! mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_START))
237 {
238 llinfos << "attempting to unpause stream failed!" << llendl;
239 }
240 }
241 mInternetStreamMedia->updateMedia();
242}
243
244// virtual
245void LLAudioEngine::updateInternetStream()
246{
247 if (mInternetStreamMedia)
248 mInternetStreamMedia->updateMedia();
249}
250
251// virtual
252int LLAudioEngine::isInternetStreamPlaying()
253{
254 if (!mInternetStreamMedia)
255 return 0;
256
257 if (mInternetStreamMedia->getStatus() == LLMediaBase::STATUS_STARTED)
258 {
259 return 1; // Active and playing
260 }
261
262 if (mInternetStreamMedia->getStatus() == LLMediaBase::STATUS_PAUSED)
263 {
264 return 2; // paused
164 } 265 }
266
267 return 0; // Stopped
268}
269
270// virtual
271void LLAudioEngine::getInternetStreamInfo(char* artist, char* title)
272{
273 artist[0] = 0;
274 title[0] = 0;
275}
276
277// virtual
278void LLAudioEngine::setInternetStreamGain(F32 vol)
279{
280 mInternetStreamGain = vol;
281
282 if(!mInternetStreamMedia)
283 return;
284
285 vol = llclamp(vol, 0.f, 1.f);
286 mInternetStreamMedia->setVolume(vol);
287 mInternetStreamMedia->updateMedia();
288}
289
290// virtual
291const std::string& LLAudioEngine::getInternetStreamURL()
292{
293 return mInternetStreamURL;
165} 294}
166 295
167 296
@@ -449,6 +578,8 @@ void LLAudioEngine::idle(F32 max_decode_time)
449 // missed picking it up in all the places that can add 578 // missed picking it up in all the places that can add
450 // or request new data. 579 // or request new data.
451 startNextTransfer(); 580 startNextTransfer();
581
582 updateInternetStream();
452} 583}
453 584
454 585
@@ -758,7 +889,7 @@ void LLAudioEngine::triggerSound(const LLUUID &audio_uuid, const LLUUID& owner_i
758 LLUUID source_id; 889 LLUUID source_id;
759 source_id.generate(); 890 source_id.generate();
760 891
761 LLAudioSource *asp = new LLAudioSource(source_id, owner_id, gain); 892 LLAudioSource *asp = new LLAudioSource(source_id, owner_id, gain, type);
762 gAudiop->addAudioSource(asp); 893 gAudiop->addAudioSource(asp);
763 if (pos_global.isExactlyZero()) 894 if (pos_global.isExactlyZero())
764 { 895 {
@@ -1207,18 +1338,18 @@ void LLAudioEngine::assetCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::E
1207// 1338//
1208 1339
1209 1340
1210LLAudioSource::LLAudioSource(const LLUUID& id, const LLUUID& owner_id, const F32 gain) 1341LLAudioSource::LLAudioSource(const LLUUID& id, const LLUUID& owner_id, const F32 gain, const S32 type)
1211: mID(id), 1342: mID(id),
1212 mOwnerID(owner_id), 1343 mOwnerID(owner_id),
1213 mPriority(0.f), 1344 mPriority(0.f),
1214 mGain(gain), 1345 mGain(gain),
1215 mType(type), 1346 mType(type),
1216 mAmbient(FALSE), 1347 mAmbient(false),
1217 mLoop(FALSE), 1348 mLoop(false),
1218 mSyncMaster(FALSE), 1349 mSyncMaster(false),
1219 mSyncSlave(FALSE), 1350 mSyncSlave(false),
1220 mQueueSounds(FALSE), 1351 mQueueSounds(false),
1221 mPlayedOnce(FALSE), 1352 mPlayedOnce(false),
1222 mChannelp(NULL), 1353 mChannelp(NULL),
1223 mCurrentDatap(NULL), 1354 mCurrentDatap(NULL),
1224 mQueuedDatap(NULL) 1355 mQueuedDatap(NULL)
@@ -1364,7 +1495,8 @@ bool LLAudioSource::play(const LLUUID &audio_uuid)
1364bool LLAudioSource::isDone() 1495bool LLAudioSource::isDone()
1365{ 1496{
1366 const F32 MAX_AGE = 60.f; 1497 const F32 MAX_AGE = 60.f;
1367 const F32 MAX_UNPLAYED_AGE = 30.f; 1498 const F32 MAX_UNPLAYED_AGE = 15.f;
1499
1368 if (isLoop()) 1500 if (isLoop())
1369 { 1501 {
1370 // Looped sources never die on their own. 1502 // Looped sources never die on their own.
@@ -1542,8 +1674,8 @@ LLAudioBuffer *LLAudioSource::getCurrentBuffer()
1542LLAudioChannel::LLAudioChannel() : 1674LLAudioChannel::LLAudioChannel() :
1543 mCurrentSourcep(NULL), 1675 mCurrentSourcep(NULL),
1544 mCurrentBufferp(NULL), 1676 mCurrentBufferp(NULL),
1545 mLoopedThisFrame(FALSE), 1677 mLoopedThisFrame(false),
1546 mWaiting(FALSE), 1678 mWaiting(false),
1547 mSecondaryGain(1.0f) 1679 mSecondaryGain(1.0f)
1548{ 1680{
1549} 1681}
@@ -1609,8 +1741,8 @@ bool LLAudioChannel::updateBuffer()
1609 } 1741 }
1610 1742
1611 // 1743 //
1612 // The source changed what buffer it's playing. Whe need to clean up the 1744 // The source changed what buffer it's playing. We need to clean up
1613 // existing fmod channel 1745 // the existing channel
1614 // 1746 //
1615 cleanup(); 1747 cleanup();
1616 1748
diff --git a/linden/indra/llaudio/audioengine.h b/linden/indra/llaudio/audioengine.h
index 937a8e1..aff7759 100644
--- a/linden/indra/llaudio/audioengine.h
+++ b/linden/indra/llaudio/audioengine.h
@@ -69,6 +69,7 @@ class LLVFS;
69class LLAudioSource; 69class LLAudioSource;
70class LLAudioData; 70class LLAudioData;
71class LLAudioChannel; 71class LLAudioChannel;
72class LLAudioChannelOpenAL;
72class LLAudioBuffer; 73class LLAudioBuffer;
73 74
74 75
@@ -79,8 +80,10 @@ class LLAudioBuffer;
79 80
80class LLAudioEngine 81class LLAudioEngine
81{ 82{
83 friend class LLAudioChannelOpenAL; // bleh. channel needs some listener methods.
84
82public: 85public:
83 enum LLAudioType 86 typedef enum LLAudioType
84 { 87 {
85 AUDIO_TYPE_NONE = 0, 88 AUDIO_TYPE_NONE = 0,
86 AUDIO_TYPE_SFX = 1, 89 AUDIO_TYPE_SFX = 1,
@@ -93,9 +96,7 @@ public:
93 virtual ~LLAudioEngine(); 96 virtual ~LLAudioEngine();
94 97
95 // initialization/startup/shutdown 98 // initialization/startup/shutdown
96 //virtual BOOL init(); 99 virtual bool init(const S32 num_channels, void *userdata);
97
98 virtual BOOL init(const S32 num_channels);
99 virtual std::string getDriverName(bool verbose) = 0; 100 virtual std::string getDriverName(bool verbose) = 0;
100 virtual void shutdown(); 101 virtual void shutdown();
101 102
@@ -140,7 +141,7 @@ public:
140 void triggerSound(const LLUUID &sound_id, const LLUUID& owner_id, const F32 gain, 141 void triggerSound(const LLUUID &sound_id, const LLUUID& owner_id, const F32 gain,
141 const S32 type = LLAudioEngine::AUDIO_TYPE_NONE, 142 const S32 type = LLAudioEngine::AUDIO_TYPE_NONE,
142 const LLVector3d &pos_global = LLVector3d::zero); 143 const LLVector3d &pos_global = LLVector3d::zero);
143 BOOL preloadSound(const LLUUID &id); 144 bool preloadSound(const LLUUID &id);
144 145
145 void addAudioSource(LLAudioSource *asp); 146 void addAudioSource(LLAudioSource *asp);
146 void cleanupAudioSource(LLAudioSource *asp); 147 void cleanupAudioSource(LLAudioSource *asp);
@@ -149,15 +150,16 @@ public:
149 LLAudioData *getAudioData(const LLUUID &audio_uuid); 150 LLAudioData *getAudioData(const LLUUID &audio_uuid);
150 151
151 152
152 virtual void startInternetStream(const std::string& url) = 0; 153 // Internet stream methods
153 virtual void stopInternetStream() = 0; 154 virtual void startInternetStream(const std::string& url);
154 virtual void pauseInternetStream(int pause) = 0; 155 virtual void stopInternetStream();
155 virtual int isInternetStreamPlaying() = 0; 156 virtual void pauseInternetStream(int pause);
156 virtual void getInternetStreamInfo(char* artist, char* title) { artist[0] = 0; title[0] = 0; } 157 virtual void updateInternetStream();
158 virtual int isInternetStreamPlaying();
159 virtual void getInternetStreamInfo(char* artist, char* title);
157 // use a value from 0.0 to 1.0, inclusive 160 // use a value from 0.0 to 1.0, inclusive
158 virtual void setInternetStreamGain(F32 vol) { mInternetStreamGain = vol; } 161 virtual void setInternetStreamGain(F32 vol);
159 virtual const std::string& getInternetStreamURL() { return LLStringUtil::null; } 162 virtual const std::string& getInternetStreamURL();
160 virtual void InitStreamer() = 0;
161 163
162 // For debugging usage 164 // For debugging usage
163 virtual LLVector3 getListenerPos(); 165 virtual LLVector3 getListenerPos();
@@ -193,11 +195,6 @@ protected:
193 virtual void allocateListener() = 0; 195 virtual void allocateListener() = 0;
194 196
195 197
196 // Internet stream methods
197 virtual void initInternetStream() {}
198 virtual void updateInternetStream() {}
199
200
201 // listener methods 198 // listener methods
202 virtual void setListenerPos(LLVector3 vec); 199 virtual void setListenerPos(LLVector3 vec);
203 virtual void setListenerVelocity(LLVector3 vec); 200 virtual void setListenerVelocity(LLVector3 vec);
@@ -212,7 +209,8 @@ protected:
212protected: 209protected:
213 LLListener *mListenerp; 210 LLListener *mListenerp;
214 211
215 BOOL mMuted; 212 bool mMuted;
213 void* mUserData;
216 214
217 S32 mLastStatus; 215 S32 mLastStatus;
218 216
@@ -242,6 +240,7 @@ protected:
242 240
243 // Hack! Internet streams are treated differently from other sources! 241 // Hack! Internet streams are treated differently from other sources!
244 F32 mInternetStreamGain; 242 F32 mInternetStreamGain;
243 std::string mInternetStreamURL;
245 244
246 F32 mNextWindUpdate; 245 F32 mNextWindUpdate;
247 246
@@ -249,6 +248,7 @@ protected:
249 248
250private: 249private:
251 void setDefaults(); 250 void setDefaults();
251 LLMediaBase *mInternetStreamMedia;
252}; 252};
253 253
254 254
@@ -264,7 +264,7 @@ class LLAudioSource
264public: 264public:
265 // owner_id is the id of the agent responsible for making this sound 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 266 // play, for example, the owner of the object currently playing it
267 LLAudioSource(const LLUUID &id, const LLUUID& owner_id, const F32 gain); 267 LLAudioSource(const LLUUID &id, const LLUUID& owner_id, const F32 gain, const S32 type = LLAudioEngine::AUDIO_TYPE_NONE);
268 virtual ~LLAudioSource(); 268 virtual ~LLAudioSource();
269 269
270 virtual void update(); // Update this audio source 270 virtual void update(); // Update this audio source
@@ -326,12 +326,12 @@ protected:
326 LLUUID mOwnerID; // owner of the object playing the sound 326 LLUUID mOwnerID; // owner of the object playing the sound
327 F32 mPriority; 327 F32 mPriority;
328 F32 mGain; 328 F32 mGain;
329 BOOL mAmbient; 329 bool mAmbient;
330 BOOL mLoop; 330 bool mLoop;
331 BOOL mSyncMaster; 331 bool mSyncMaster;
332 BOOL mSyncSlave; 332 bool mSyncSlave;
333 BOOL mQueueSounds; 333 bool mQueueSounds;
334 BOOL mPlayedOnce; 334 bool mPlayedOnce;
335 S32 mType; 335 S32 mType;
336 LLVector3d mPositionGlobal; 336 LLVector3d mPositionGlobal;
337 LLVector3 mVelocity; 337 LLVector3 mVelocity;
@@ -420,8 +420,8 @@ protected:
420protected: 420protected:
421 LLAudioSource *mCurrentSourcep; 421 LLAudioSource *mCurrentSourcep;
422 LLAudioBuffer *mCurrentBufferp; 422 LLAudioBuffer *mCurrentBufferp;
423 BOOL mLoopedThisFrame; 423 bool mLoopedThisFrame;
424 BOOL mWaiting; // Waiting for sync. 424 bool mWaiting; // Waiting for sync.
425 F32 mSecondaryGain; 425 F32 mSecondaryGain;
426}; 426};
427 427
diff --git a/linden/indra/llaudio/audioengine_openal.cpp b/linden/indra/llaudio/audioengine_openal.cpp
index 65203dd..002dfba 100644
--- a/linden/indra/llaudio/audioengine_openal.cpp
+++ b/linden/indra/llaudio/audioengine_openal.cpp
@@ -4,26 +4,26 @@
4 * support as a OpenAL 3D implementation 4 * support as a OpenAL 3D implementation
5 * 5 *
6 * $LicenseInfo:firstyear=2002&license=viewergpl$ 6 * $LicenseInfo:firstyear=2002&license=viewergpl$
7 * 7 *
8 * Copyright (c) 2002-2008, Linden Research, Inc. 8 * Copyright (c) 2002-2008, Linden Research, Inc.
9 * 9 *
10 * Second Life Viewer Source Code 10 * Second Life Viewer Source Code
11 * The source code in this file ("Source Code") is provided by Linden Lab 11 * The source code in this file ("Source Code") is provided by Linden Lab
12 * to you under the terms of the GNU General Public License, version 2.0 12 * to you under the terms of the GNU General Public License, version 2.0
13 * ("GPL"), unless you have obtained a separate licensing agreement 13 * ("GPL"), unless you have obtained a separate licensing agreement
14 * ("Other License"), formally executed by you and Linden Lab. Terms of 14 * ("Other License"), formally executed by you and Linden Lab. Terms of
15 * the GPL can be found in doc/GPL-license.txt in this distribution, or 15 * the GPL can be found in doc/GPL-license.txt in this distribution, or
16 * online at http://secondlife.com/developers/opensource/gplv2 16 * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
17 * 17 *
18 * There are special exceptions to the terms and conditions of the GPL as 18 * There are special exceptions to the terms and conditions of the GPL as
19 * it is applied to this Source Code. View the full text of the exception 19 * it is applied to this Source Code. View the full text of the exception
20 * in the file doc/FLOSS-exception.txt in this software distribution, or 20 * in the file doc/FLOSS-exception.txt in this software distribution, or
21 * online at http://secondlife.com/developers/opensource/flossexception 21 * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
22 * 22 *
23 * By copying, modifying or distributing this software, you acknowledge 23 * By copying, modifying or distributing this software, you acknowledge
24 * that you have read and understood your obligations described above, 24 * that you have read and understood your obligations described above,
25 * and agree to abide by those obligations. 25 * and agree to abide by those obligations.
26 * 26 *
27 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO 27 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
28 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, 28 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
29 * COMPLETENESS OR PERFORMANCE. 29 * COMPLETENESS OR PERFORMANCE.
@@ -36,31 +36,29 @@
36#include "audioengine_openal.h" 36#include "audioengine_openal.h"
37#include "listener_openal.h" 37#include "listener_openal.h"
38 38
39
39LLAudioEngine_OpenAL::LLAudioEngine_OpenAL() 40LLAudioEngine_OpenAL::LLAudioEngine_OpenAL()
41 :
42 mWindGen(NULL),
43 mWindBuf(NULL),
44 mWindBufFreq(0),
45 mWindBufSamples(0),
46 mWindBufBytes(0),
47 mWindSource(AL_NONE),
48 mNumEmptyWindALBuffers(MAX_NUM_WIND_BUFFERS)
40{ 49{
41
42 #if LL_GSTREAMER_ENABLED
43 mMedia_data = new LLMediaManagerData;
44 // initialize GStreamer
45 LLMediaImplGStreamer::startup( mMedia_data );
46
47 m_streamer=new LLMediaImplGStreamer ();
48
49 if(!m_streamer)
50 {
51 llwarns << "LLAudioEngine_OpenAL::LLAudioEngine_OpenAL() Failed to create our private gstreamer audio instance" << llendl;
52 }
53 #endif
54} 50}
55 51
52// virtual
56LLAudioEngine_OpenAL::~LLAudioEngine_OpenAL() 53LLAudioEngine_OpenAL::~LLAudioEngine_OpenAL()
57{ 54{
58} 55}
59 56
60 57// virtual
61BOOL LLAudioEngine_OpenAL::init(const S32 num_channels) 58bool LLAudioEngine_OpenAL::init(const S32 num_channels, void* userdata)
62{ 59{
63 LLAudioEngine::init(num_channels); 60 mWindGen = NULL;
61 LLAudioEngine::init(num_channels, userdata);
64 62
65 if(!alutInit(NULL, NULL)) 63 if(!alutInit(NULL, NULL))
66 { 64 {
@@ -68,27 +66,39 @@ BOOL LLAudioEngine_OpenAL::init(const S32 num_channels)
68 return false; 66 return false;
69 } 67 }
70 68
71 initInternetStream();
72
73 llinfos << "LLAudioEngine_OpenAL::init() OpenAL successfully initialized" << llendl; 69 llinfos << "LLAudioEngine_OpenAL::init() OpenAL successfully initialized" << llendl;
74 70
75 llinfos << "LLAudioEngine_OpenAL::init() Speed of sound is: " << alGetFloat(AL_SPEED_OF_SOUND) << llendl; 71 llinfos << "OpenAL version: "
72 << ll_safe_string(alGetString(AL_VERSION)) << llendl;
73 llinfos << "OpenAL vendor: "
74 << ll_safe_string(alGetString(AL_VENDOR)) << llendl;
75 llinfos << "OpenAL renderer: "
76 << ll_safe_string(alGetString(AL_RENDERER)) << llendl;
77
78 ALint major = alutGetMajorVersion ();
79 ALint minor = alutGetMinorVersion ();
80 llinfos << "ALUT version: " << major << "." << minor << llendl;
76 81
77 return TRUE; 82 ALCdevice *device = alcGetContextsDevice(alcGetCurrentContext());
83
84 alcGetIntegerv(device, ALC_MAJOR_VERSION, 1, &major);
85 alcGetIntegerv(device, ALC_MAJOR_VERSION, 1, &minor);
86 llinfos << "ALC version: " << major << "." << minor << llendl;
87
88 llinfos << "ALC default device: "
89 << ll_safe_string(alcGetString(device,
90 ALC_DEFAULT_DEVICE_SPECIFIER))
91 << llendl;
92
93 return true;
78} 94}
79 95
96// virtual
80std::string LLAudioEngine_OpenAL::getDriverName(bool verbose) 97std::string LLAudioEngine_OpenAL::getDriverName(bool verbose)
81{ 98{
82 ALCdevice *device = alcGetContextsDevice(alcGetCurrentContext()); 99 ALCdevice *device = alcGetContextsDevice(alcGetCurrentContext());
83
84 std::ostringstream version; 100 std::ostringstream version;
85 101
86 ALint major = alutGetMajorVersion ();
87 ALint minor = alutGetMinorVersion ();
88
89 alcGetIntegerv(device, ALC_MAJOR_VERSION, 1, &major);
90 alcGetIntegerv(device, ALC_MAJOR_VERSION, 1, &minor);
91
92 version << 102 version <<
93 "OpenAL"; 103 "OpenAL";
94 104
@@ -112,17 +122,7 @@ std::string LLAudioEngine_OpenAL::getDriverName(bool verbose)
112 return version.str(); 122 return version.str();
113} 123}
114 124
115 125// virtual
116void LLAudioEngine_OpenAL::idle(F32 max_decode_time)
117{
118 LLAudioEngine::idle(max_decode_time);
119 #if LL_GSTREAMER_ENABLED
120 if(m_streamer != NULL)
121 m_streamer->updateMedia();
122 #endif
123}
124
125
126void LLAudioEngine_OpenAL::allocateListener() 126void LLAudioEngine_OpenAL::allocateListener()
127{ 127{
128 mListenerp = (LLListener *) new LLListener_OpenAL(); 128 mListenerp = (LLListener *) new LLListener_OpenAL();
@@ -132,6 +132,7 @@ void LLAudioEngine_OpenAL::allocateListener()
132 } 132 }
133} 133}
134 134
135// virtual
135void LLAudioEngine_OpenAL::shutdown() 136void LLAudioEngine_OpenAL::shutdown()
136{ 137{
137 llinfos << "About to LLAudioEngine::shutdown()" << llendl; 138 llinfos << "About to LLAudioEngine::shutdown()" << llendl;
@@ -143,21 +144,11 @@ void LLAudioEngine_OpenAL::shutdown()
143 llwarns << "Nuts." << llendl; 144 llwarns << "Nuts." << llendl;
144 llwarns << "LLAudioEngine_OpenAL::shutdown() ALUT shutdown failed: " << alutGetErrorString (alutGetError ()) << llendl; 145 llwarns << "LLAudioEngine_OpenAL::shutdown() ALUT shutdown failed: " << alutGetErrorString (alutGetError ()) << llendl;
145 } 146 }
146 else 147
147 { 148 llinfos << "LLAudioEngine_OpenAL::shutdown() OpenAL successfully shut down" << llendl;
148 llinfos << "LLAudioEngine_OpenAL::shutdown() OpenAL successfully shut down" << llendl; 149
149 }
150
151 delete mListenerp; 150 delete mListenerp;
152 mListenerp = NULL; 151 mListenerp = NULL;
153
154 #if LL_GSTREAMER_ENABLED
155 if(m_streamer)
156 {
157 delete m_streamer;
158 m_streamer = NULL;
159 }
160 #endif
161} 152}
162 153
163LLAudioBuffer *LLAudioEngine_OpenAL::createBuffer() 154LLAudioBuffer *LLAudioEngine_OpenAL::createBuffer()
@@ -177,44 +168,75 @@ void LLAudioEngine_OpenAL::setInternalGain(F32 gain)
177} 168}
178 169
179LLAudioChannelOpenAL::LLAudioChannelOpenAL() 170LLAudioChannelOpenAL::LLAudioChannelOpenAL()
171 :
172 mALSource(AL_NONE),
173 mLastSamplePos(0)
180{ 174{
181 alGenSources(1, &ALSource); 175 alGenSources(1, &mALSource);
182} 176}
183 177
184LLAudioChannelOpenAL::~LLAudioChannelOpenAL() 178LLAudioChannelOpenAL::~LLAudioChannelOpenAL()
185{ 179{
186 cleanup(); 180 cleanup();
187 alDeleteSources(1, &ALSource); 181 alDeleteSources(1, &mALSource);
188} 182}
189 183
190void LLAudioChannelOpenAL::cleanup() 184void LLAudioChannelOpenAL::cleanup()
191{ 185{
192 alSourceStop(ALSource); 186 alSourceStop(mALSource);
193 mCurrentBufferp = NULL; 187 mCurrentBufferp = NULL;
194} 188}
195 189
196void LLAudioChannelOpenAL::play() 190void LLAudioChannelOpenAL::play()
197{ 191{
192 if (mALSource == AL_NONE)
193 {
194 llwarns << "Playing without a mALSource, aborting" << llendl;
195 return;
196 }
197
198 if(!isPlaying()) 198 if(!isPlaying())
199 { 199 {
200 alSourcePlay(ALSource); 200 alSourcePlay(mALSource);
201 getSource()->setPlayedOnce(TRUE); 201 getSource()->setPlayedOnce(true);
202 } 202 }
203} 203}
204 204
205void LLAudioChannelOpenAL::playSynced(LLAudioChannel *channelp) 205void LLAudioChannelOpenAL::playSynced(LLAudioChannel *channelp)
206{ 206{
207 if (channelp)
208 {
209 LLAudioChannelOpenAL *masterchannelp =
210 (LLAudioChannelOpenAL*)channelp;
211 if (mALSource != AL_NONE &&
212 masterchannelp->mALSource != AL_NONE)
213 {
214 // we have channels allocated to master and slave
215 ALfloat master_offset;
216 alGetSourcef(masterchannelp->mALSource, AL_SEC_OFFSET,
217 &master_offset);
218
219 llinfos << "Syncing with master at " << master_offset
220 << "sec" << llendl;
221 // *TODO: detect when this fails, maybe use AL_SAMPLE_
222 alSourcef(mALSource, AL_SEC_OFFSET, master_offset);
223 }
224 }
207 play(); 225 play();
208} 226}
209 227
210bool LLAudioChannelOpenAL::isPlaying() 228bool LLAudioChannelOpenAL::isPlaying()
211{ 229{
212 ALint state; 230 if (mALSource != AL_NONE)
213 alGetSourcei(ALSource, AL_SOURCE_STATE, &state);
214 if(state == AL_PLAYING)
215 { 231 {
216 return TRUE; 232 ALint state;
233 alGetSourcei(mALSource, AL_SOURCE_STATE, &state);
234 if(state == AL_PLAYING)
235 {
236 return true;
237 }
217 } 238 }
239
218 return false; 240 return false;
219} 241}
220 242
@@ -225,14 +247,48 @@ bool LLAudioChannelOpenAL::updateBuffer()
225 // Base class update returned true, which means that we need to actually 247 // Base class update returned true, which means that we need to actually
226 // set up the source for a different buffer. 248 // set up the source for a different buffer.
227 LLAudioBufferOpenAL *bufferp = (LLAudioBufferOpenAL *)mCurrentSourcep->getCurrentBuffer(); 249 LLAudioBufferOpenAL *bufferp = (LLAudioBufferOpenAL *)mCurrentSourcep->getCurrentBuffer();
228 alSourcei(ALSource, AL_BUFFER, bufferp->getBuffer()); 250 ALuint buffer = bufferp->getBuffer();
229 alSourcef(ALSource, AL_GAIN, mCurrentSourcep->getGain()); 251 alSourcei(mALSource, AL_BUFFER, buffer);
230 alSourcei(ALSource, AL_LOOPING, mCurrentSourcep->isLoop() ? AL_TRUE : AL_FALSE); 252 mLastSamplePos = 0;
253 }
254
255 if (mCurrentSourcep)
256 {
257 alSourcef(mALSource, AL_GAIN,
258 mCurrentSourcep->getGain() * getSecondaryGain());
259 alSourcei(mALSource, AL_LOOPING,
260 mCurrentSourcep->isLoop() ? AL_TRUE : AL_FALSE);
261 alSourcef(mALSource, AL_ROLLOFF_FACTOR,
262 gAudiop->mListenerp->getRolloffFactor());
263 alSourcef(mALSource, AL_REFERENCE_DISTANCE,
264 gAudiop->mListenerp->getDistanceFactor());
231 } 265 }
232 266
233 return true; 267 return true;
234} 268}
235 269
270
271void LLAudioChannelOpenAL::updateLoop()
272{
273 if (mALSource == AL_NONE)
274 {
275 return;
276 }
277
278 // Hack: We keep track of whether we looped or not by seeing when the
279 // sample position looks like it's going backwards. Not reliable; may
280 // yield false negatives.
281 //
282 ALint cur_pos;
283 alGetSourcei(mALSource, AL_SAMPLE_OFFSET, &cur_pos);
284 if (cur_pos < mLastSamplePos)
285 {
286 mLoopedThisFrame = true;
287 }
288 mLastSamplePos = cur_pos;
289}
290
291
236void LLAudioChannelOpenAL::update3DPosition() 292void LLAudioChannelOpenAL::update3DPosition()
237{ 293{
238 if(!mCurrentSourcep) 294 if(!mCurrentSourcep)
@@ -241,30 +297,25 @@ void LLAudioChannelOpenAL::update3DPosition()
241 } 297 }
242 if (mCurrentSourcep->isAmbient()) 298 if (mCurrentSourcep->isAmbient())
243 { 299 {
244 alSource3f(ALSource, AL_POSITION, 0.0, 0.0, 0.0); 300 alSource3f(mALSource, AL_POSITION, 0.0, 0.0, 0.0);
245 alSource3f(ALSource, AL_VELOCITY, 0.0, 0.0, 0.0); 301 alSource3f(mALSource, AL_VELOCITY, 0.0, 0.0, 0.0);
246 //alSource3f(ALSource, AL_DIRECTION, 0.0, 0.0, 0.0); 302 //alSource3f(mALSource, AL_DIRECTION, 0.0, 0.0, 0.0);
247 alSourcef (ALSource, AL_ROLLOFF_FACTOR, 0.0); 303 alSourcei (mALSource, AL_SOURCE_RELATIVE, AL_TRUE);
248 alSourcei (ALSource, AL_SOURCE_RELATIVE, AL_TRUE); 304 } else {
249 }
250 else
251 {
252 LLVector3 float_pos; 305 LLVector3 float_pos;
253 float_pos.setVec(mCurrentSourcep->getPositionGlobal()); 306 float_pos.setVec(mCurrentSourcep->getPositionGlobal());
254 alSourcefv(ALSource, AL_POSITION, float_pos.mV); 307 alSourcefv(mALSource, AL_POSITION, float_pos.mV);
255 //llinfos << "LLAudioChannelOpenAL::update3DPosition() Velocity: " << mCurrentSourcep->getVelocity() << llendl; 308 alSourcefv(mALSource, AL_VELOCITY, mCurrentSourcep->getVelocity().mV);
256 alSourcefv(ALSource, AL_VELOCITY, mCurrentSourcep->getVelocity().mV); 309 //alSource3f(mALSource, AL_DIRECTION, 0.0, 0.0, 0.0);
257 //alSource3f(ALSource, AL_DIRECTION, 0.0, 0.0, 0.0); 310 alSourcei (mALSource, AL_SOURCE_RELATIVE, AL_FALSE);
258 alSourcef (ALSource, AL_ROLLOFF_FACTOR, 1.0);
259 alSourcei (ALSource, AL_SOURCE_RELATIVE, AL_FALSE);
260 } 311 }
261 //llinfos << "LLAudioChannelOpenAL::update3DPosition() Gain: " << mCurrentSourcep->getGain() << llendl; 312
262 alSourcef(ALSource, AL_GAIN, mCurrentSourcep->getGain()); 313 alSourcef(mALSource, AL_GAIN, mCurrentSourcep->getGain() * getSecondaryGain());
263} 314}
264 315
265LLAudioBufferOpenAL::LLAudioBufferOpenAL() 316LLAudioBufferOpenAL::LLAudioBufferOpenAL()
266{ 317{
267 ALBuffer = AL_NONE; 318 mALBuffer = AL_NONE;
268} 319}
269 320
270LLAudioBufferOpenAL::~LLAudioBufferOpenAL() 321LLAudioBufferOpenAL::~LLAudioBufferOpenAL()
@@ -274,33 +325,49 @@ LLAudioBufferOpenAL::~LLAudioBufferOpenAL()
274 325
275void LLAudioBufferOpenAL::cleanup() 326void LLAudioBufferOpenAL::cleanup()
276{ 327{
277 if(ALBuffer != AL_NONE) 328 if(mALBuffer != AL_NONE)
278 { 329 {
279 alDeleteBuffers(1, &ALBuffer); 330 alDeleteBuffers(1, &mALBuffer);
331 mALBuffer = AL_NONE;
280 } 332 }
281} 333}
282 334
283bool LLAudioBufferOpenAL::loadWAV(const std::string& filename) 335bool LLAudioBufferOpenAL::loadWAV(const std::string& filename)
284{ 336{
285 cleanup(); 337 cleanup();
286 ALBuffer = alutCreateBufferFromFile(filename.c_str()); 338 mALBuffer = alutCreateBufferFromFile(filename.c_str());
287 if(ALBuffer == AL_NONE) 339 if(mALBuffer == AL_NONE)
288 { 340 {
289 return FALSE; 341 ALenum error = alutGetError();
342 if (gDirUtilp->fileExists(filename))
343 {
344 llwarns <<
345 "LLAudioBufferOpenAL::loadWAV() Error loading "
346 << filename
347 << " " << alutGetErrorString(error) << llendl;
348 }
349 else
350 {
351 // It's common for the file to not actually exist.
352 lldebugs <<
353 "LLAudioBufferOpenAL::loadWAV() Error loading "
354 << filename
355 << " " << alutGetErrorString(error) << llendl;
356 }
357 return false;
290 } 358 }
291 359
292 return true; 360 return true;
293} 361}
294 362
295
296U32 LLAudioBufferOpenAL::getLength() 363U32 LLAudioBufferOpenAL::getLength()
297{ 364{
298 if(ALBuffer == AL_NONE) 365 if(mALBuffer == AL_NONE)
299 { 366 {
300 return 0; 367 return 0;
301 } 368 }
302 ALint length; 369 ALint length;
303 alGetBufferi(ALBuffer, AL_SIZE, &length); 370 alGetBufferi(mALBuffer, AL_SIZE, &length);
304 return length >> 2; 371 return length >> 2;
305} 372}
306 373
@@ -308,65 +375,78 @@ U32 LLAudioBufferOpenAL::getLength()
308 375
309void LLAudioEngine_OpenAL::initWind() 376void LLAudioEngine_OpenAL::initWind()
310{ 377{
378 ALenum error;
379 llinfos << "LLAudioEngine_OpenAL::initWind() start" << llendl;
311 380
312 if (true) 381 mNumEmptyWindALBuffers = MAX_NUM_WIND_BUFFERS;
313 return;
314
315 llinfos << "initWind() start" << llendl;
316 382
317 alGenBuffers(mNumWindBuffers,mWindBuffers); 383 alGetError(); /* clear error */
384
318 alGenSources(1,&mWindSource); 385 alGenSources(1,&mWindSource);
319 checkALError(); 386
320 387 if((error=alGetError()) != AL_NO_ERROR)
321 // ok lets make a wind buffer now
322 for(int counter=0;counter<mNumWindBuffers;counter++)
323 { 388 {
324 389 llwarns << "LLAudioEngine_OpenAL::initWind() Error creating wind sources: "<<error<<llendl;
325 alBufferData(mWindBuffers[counter],AL_FORMAT_STEREO16,windDSP((void*)mWindData,mWindDataSize/mBytesPerSample),mWindDataSize,mSampleRate);
326 checkALError();
327 } 390 }
328 391
329 alSourceQueueBuffers(mWindSource, mNumWindBuffers, mWindBuffers); 392 mWindGen = new LLWindGen<WIND_SAMPLE_T>;
330 checkALError();
331 393
332 alSourcePlay(mWindSource); 394 mWindBufFreq = mWindGen->getInputSamplingRate();
333 checkALError(); 395 mWindBufSamples = llceil(mWindBufFreq * WIND_BUFFER_SIZE_SEC);
396 mWindBufBytes = mWindBufSamples * 2 /*stereo*/ * sizeof(WIND_SAMPLE_T);
334 397
335 llinfos << "LLAudioEngine_OpenAL::initWind() done" << llendl; 398 mWindBuf = new WIND_SAMPLE_T [mWindBufSamples * 2 /*stereo*/];
336 399
400 if(mWindBuf==NULL)
401 {
402 llerrs << "LLAudioEngine_OpenAL::initWind() Error creating wind memory buffer" << llendl;
403 mEnableWind=false;
404 }
405
406 llinfos << "LLAudioEngine_OpenAL::initWind() done" << llendl;
337} 407}
338 408
339void LLAudioEngine_OpenAL::cleanupWind(){ 409void LLAudioEngine_OpenAL::cleanupWind()
410{
340 llinfos << "LLAudioEngine_OpenAL::cleanupWind()" << llendl; 411 llinfos << "LLAudioEngine_OpenAL::cleanupWind()" << llendl;
341 412
342 alDeleteBuffers(mNumWindBuffers,mWindBuffers); 413 if (mWindSource != AL_NONE)
343 alDeleteSources(1, &mWindSource); 414 {
415 // detach and delete all outstanding buffers on the wind source
416 alSourceStop(mWindSource);
417 int processed;
418 alGetSourcei(mWindSource, AL_BUFFERS_PROCESSED, &processed);
419 while (processed--)
420 {
421 ALuint buffer = AL_NONE;
422 alSourceUnqueueBuffers(mWindSource, 1, &buffer);
423 alDeleteBuffers(1, &buffer);
424 }
344 425
345 checkALError(); 426 // delete the wind source itself
346} 427 alDeleteSources(1, &mWindSource);
347 428
348void LLAudioEngine_OpenAL::checkALError() 429 mWindSource = AL_NONE;
349{ 430 }
350 ALenum error; 431
351 if((error=alGetError()) != AL_NO_ERROR) 432 delete[] mWindBuf;
352 llwarns << "LLAudioEngine_OpenAL Error: "<<error<<llendl; 433 mWindBuf = NULL;
353 434
435 delete mWindGen;
436 mWindGen = NULL;
354} 437}
355 438
356void LLAudioEngine_OpenAL::updateWind(LLVector3 wind_vec, F32 camera_altitude) 439void LLAudioEngine_OpenAL::updateWind(LLVector3 wind_vec, F32 camera_altitude)
357{ 440{
358
359 if (true)
360 return;
361
362 LLVector3 wind_pos; 441 LLVector3 wind_pos;
363 F32 pitch; 442 F64 pitch;
364 F32 center_freq; 443 F64 center_freq;
365 444 ALenum error;
445
366 if (!mEnableWind) 446 if (!mEnableWind)
367 return; 447 return;
368 448
369 if(!mWindData) 449 if(!mWindBuf)
370 return; 450 return;
371 451
372 if (mWindUpdateTimer.checkExpirationAndReset(LL_WIND_UPDATE_INTERVAL)) 452 if (mWindUpdateTimer.checkExpirationAndReset(LL_WIND_UPDATE_INTERVAL))
@@ -377,385 +457,88 @@ void LLAudioEngine_OpenAL::updateWind(LLVector3 wind_vec, F32 camera_altitude)
377 // where +X = right, +Y = up, +Z = backwards 457 // where +X = right, +Y = up, +Z = backwards
378 458
379 wind_vec.setVec(-wind_vec.mV[1], wind_vec.mV[2], -wind_vec.mV[0]); 459 wind_vec.setVec(-wind_vec.mV[1], wind_vec.mV[2], -wind_vec.mV[0]);
380 460
381 461 pitch = 1.0 + mapWindVecToPitch(wind_vec);
382 pitch = 1.0f + mapWindVecToPitch(wind_vec); 462 center_freq = 80.0 * pow(pitch,2.5*(mapWindVecToGain(wind_vec)+1.0));
383 center_freq = 80.0f * powf(pitch,2.5f*(mapWindVecToGain(wind_vec)+1.0f)); 463
384 464 mWindGen->mTargetFreq = (F32)center_freq;
385 //TESTING 465 mWindGen->mTargetGain = (F32)mapWindVecToGain(wind_vec) * mMaxWindGain;
386 mMaxWindGain=1.0; 466 mWindGen->mTargetPanGainR = (F32)mapWindVecToPan(wind_vec);
387 467
388 mTargetFreq = center_freq;
389 mTargetGain = (F32)mapWindVecToGain(wind_vec) * mMaxWindGain;
390 mTargetPanGainR = (F32)mapWindVecToPan(wind_vec);
391
392 ALfloat source0Pos[]={mListenerp->getPosition().mV[0],mListenerp->getPosition().mV[1],mListenerp->getPosition().mV[2]};
393 ALfloat source0Vel[]={ 0.0, 0.0, 0.0};
394
395 alSourcef(mWindSource, AL_GAIN, mTargetGain);
396 alSourcef(mWindSource, AL_PITCH, pitch);
397 alSourcefv(mWindSource, AL_POSITION, source0Pos);
398 alSourcefv(mWindSource, AL_VELOCITY, source0Vel);
399 alSourcei(mWindSource, AL_LOOPING, AL_FALSE); 468 alSourcei(mWindSource, AL_LOOPING, AL_FALSE);
400 469 alSource3f(mWindSource, AL_POSITION, 0.0, 0.0, 0.0);
401 } 470 alSource3f(mWindSource, AL_VELOCITY, 0.0, 0.0, 0.0);
402 471 alSourcef(mWindSource, AL_ROLLOFF_FACTOR, 0.0);
403 int processed; 472 alSourcei(mWindSource, AL_SOURCE_RELATIVE, AL_TRUE);
404 alGetSourcei(mWindSource, AL_BUFFERS_PROCESSED, &processed);
405
406 while(processed--)
407 {
408 ALuint buffer;
409 alSourceUnqueueBuffers(mWindSource, 1, &buffer);
410 checkALError();
411 alBufferData(buffer,AL_FORMAT_STEREO16,windDSP((void*)mWindData,mWindDataSize/mBytesPerSample),mWindDataSize,mSampleRate);
412 checkALError();
413 alSourceQueueBuffers(mWindSource, 1, &buffer);
414 checkALError();
415 } 473 }
416 474
417 int playing; 475 // ok lets make a wind buffer now
418 alGetSourcei(mWindSource, AL_SOURCE_STATE, &playing);
419 if(playing==AL_STOPPED)
420 alSourcePlay(mWindSource);
421
422 checkALError();
423}
424
425
426void * LLAudioEngine_OpenAL::windDSP(void *newbuffer, int length)
427{
428 // *NOTE: This function gets called a *lot*.
429 // Keep performance in mind if you mess with this.
430 // newbuffer = the buffer being constructed
431 // length = length in samples of the buffer
432
433
434 //clear the buffer
435 memset(newbuffer, 0, length*mBytesPerSample);
436
437 // This turns off wind synth if it is muted or very very low volume
438 if (mTargetGain < 0.0005f)
439 {
440 llinfos << "Wind off" << llendl;
441 return newbuffer;
442 }
443
444 static const U8 SUBSAMPLES = 2;
445 static const F32 FILTER_SAMPLE_PERIOD = (F32)SUBSAMPLES / float(mSampleRate);
446 static const F32 BANDWIDTH = 50.0f;
447 static const F32 B2 = expf(-F_TWO_PI * BANDWIDTH * FILTER_SAMPLE_PERIOD);
448
449 static F32 pinking_buf0 = 0.0f;
450 static F32 pinking_buf1 = 0.0f;
451 static F32 pinking_buf2 = 0.0f;
452 static F32 Y0 = 0.0f;
453 static F32 Y1 = 0.0f;
454 static F32 last_sample = 0.0f;
455 static F32 current_freq = 0.0f;
456 static F32 current_gain = 0.0f;
457 static F32 current_pan_gain_r = 0.0f;
458
459 F32 a0 = 0.0f, b1 = 0.0f;
460
461 U8 *cursamplep = (U8*)newbuffer;
462
463 //we assume 16-bit samples, because the ALUT specification maxes out there
464 U8 wordsize = 2;
465
466 bool interp_freq = false;
467
468 //if the frequency isn't changing much, we don't need to interpolate in the inner loop
469 if (llabs(mTargetFreq - current_freq) > 200.0f)
470 {
471 interp_freq = true;
472 }
473 else
474 {
475 // calculate resonant filter coefficients
476 current_freq = mTargetFreq;
477 b1 = (-4.0f * B2) / (1.0f + B2) * cosf(F_TWO_PI * (current_freq * FILTER_SAMPLE_PERIOD));
478 a0 = (1.0f - B2) * sqrtf(1.0f - (b1 * b1) / (4.0f * B2));
479 }
480
481 while (length)
482 {
483 F32 next_sample;
484
485 // Start with white noise [-16384, 16383]
486 next_sample = (F32)rand() * (1.0f / (F32)(RAND_MAX / (U16_MAX / 4))) + (S16_MIN / 4);
487
488 // Apply a pinking filter
489 // Magic numbers taken from PKE method at http://www.firstpr.com.au/dsp/pink-noise/
490 pinking_buf0 = pinking_buf0 * 0.99765f + next_sample * 0.0990460f;
491 pinking_buf1 = pinking_buf1 * 0.96300f + next_sample * 0.2965164f;
492 pinking_buf2 = pinking_buf2 * 0.57000f + next_sample * 1.0526913f;
493
494 next_sample = pinking_buf0 + pinking_buf1 + pinking_buf2 + next_sample * 0.1848f;
495
496 if (interp_freq)
497 {
498 // calculate resonant filter coefficients
499 current_freq = (0.999f * current_freq) + (0.001f * mTargetFreq);
500 b1 = (-4.0f * B2) / (1.0f + B2) * cosf(F_TWO_PI * (current_freq * FILTER_SAMPLE_PERIOD));
501 a0 = (1.0f - B2) * sqrtf(1.0f - (b1 * b1) / (4.0f * B2));
502 }
503
504 // Apply a resonant low-pass filter on the pink noise
505 next_sample = ( a0 * next_sample - b1 * Y0 - B2 * Y1 );
506
507 Y1 = Y0;
508 Y0 = next_sample;
509
510 current_gain = (0.999f * current_gain) + (0.001f * mTargetGain);
511 current_pan_gain_r = (0.999f * current_pan_gain_r) + (0.001f * mTargetPanGainR);
512
513 next_sample *= current_gain;
514 F32 delta = (next_sample - last_sample) / (F32)SUBSAMPLES;
515
516 S32 sample_left;
517 S32 sample_right;
518
519 // Mix into the audio buffer, clipping if necessary for 16-bit mix buffers.
520 // *TODO: Should do something more intelligent like reducing wind gain to avoid clipping
521 for (int i=SUBSAMPLES; i && length; --i, --length)
522 {
523 last_sample = last_sample + delta;
524 sample_right = (S32)(last_sample * current_pan_gain_r);
525 sample_left = (S32)(last_sample - sample_right);
526
527 *(S16*)cursamplep = llclamp(sample_left, S16_MIN, S16_MAX);
528 cursamplep += wordsize;
529
530 *(S16*)cursamplep = llclamp(sample_right, S16_MIN, S16_MAX);
531 cursamplep += wordsize;
532 }
533 }
534 return newbuffer;
535
536}
537
538
539
540
541/*
542
543
544
545
546 // newbuffer = the buffer passed from the previous DSP unit.
547 // length = length in samples at this mix time.
548
549 U8 *cursamplep = (U8*)newbuffer;
550 U8 wordsize = 2;
551
552 double bandwidth = 50;
553 double inputSamplingRate = 44100;
554 double a0,b1,b2;
555
556 // calculate resonant filter coeffs
557 b2 = exp(-(F_TWO_PI) * (bandwidth / inputSamplingRate));
558
559 while (length--)
560 {
561 gCurrentFreq = (float)((0.999 * gCurrentFreq) + (0.001 * gTargetFreq));
562 gCurrentGain = (float)((0.999 * gCurrentGain) + (0.001 * gTargetGain));
563 gCurrentPanGainR = (float)((0.999 * gCurrentPanGainR) + (0.001 * gTargetPanGainR));
564 b1 = (-4.0 * b2) / (1.0 + b2) * cos(F_TWO_PI * (gCurrentFreq / inputSamplingRate));
565 a0 = (1.0 - b2) * sqrt(1.0 - (b1 * b1) / (4.0 * b2));
566 double nextSample;
567
568 // start with white noise
569 nextSample = ll_frand(2.0f) - 1.0f;
570
571 gbuf0 = 0.997f * gbuf0 + 0.0126502f * nextSample;
572 gbuf1 = 0.985f * gbuf1 + 0.0139083f * nextSample;
573 gbuf2 = 0.950f * gbuf2 + 0.0205439f * nextSample;
574 gbuf3 = 0.850f * gbuf3 + 0.0387225f * nextSample;
575 gbuf4 = 0.620f * gbuf4 + 0.0465932f * nextSample;
576 gbuf5 = 0.250f * gbuf5 + 0.1093477f * nextSample;
577
578 nextSample = gbuf0 + gbuf1 + gbuf2 + gbuf3 + gbuf4 + gbuf5;
579
580 nextSample = (double)( a0 * nextSample - b1 * gY0 - b2 * gY1 );
581
582 gY1 = gY0;
583 gY0 = nextSample;
584 nextSample *= gCurrentGain;
585
586 S16 sample;
587
588 sample = llfloor(((F32)nextSample*32768.f*(1.0f - gCurrentPanGainR))+0.5f);
589 *(S16*)cursamplep = clipSample(sample, -32768, 32767);
590
591 cursamplep += wordsize;
592
593 sample = llfloor(((F32)nextSample*32768.f*gCurrentPanGainR)+0.5f);
594
595 sample = llfloor(((F32)nextSample*32768.f*gCurrentPanGainR)+0.5f);
596 *(S16*)cursamplep = clipSample(sample, -32768, 32767);
597 cursamplep += wordsize;
598 }
599
600 return newbuffer;
601}
602*/
603
604// ------------
605
606void LLAudioEngine_OpenAL::InitStreamer()
607{
608 #if LL_GSTREAMER_ENABLED
609 m_streamer=new LLMediaImplGStreamer ();
610
611 if(!m_streamer)
612 {
613 llwarns << "LLAudioEngine_OpenAL::LLAudioEngine_OpenAL() Failed to create our private gstreamer audio instance" << llendl;
614 }
615
616 if(m_streamer)
617 {
618 m_streamer->init ();
619 }
620 #endif
621}
622
623
624// ------------
625
626void LLAudioEngine_OpenAL::initInternetStream()
627{
628 if(!mInternetStreamURL.empty())
629 mInternetStreamURL.erase();
630}
631
632
633void LLAudioEngine_OpenAL::startInternetStream(const std::string& url_cstr)
634{
635
636 std::string url(url_cstr);
637
638 #if LL_GSTREAMER_ENABLED
639 if(!m_streamer)
640 return;
641 // DCF_DEBUG
642 llinfos << "entered LLAudioEngine_OpenAL::startInternetStream()" << llendl;
643
644 if (!url.empty())
645 {
646 llinfos << "LLAudioEngine_OpenAL::startInternetStream() Starting internet stream: " << url << llendl;
647 mInternetStreamURL=url;
648 m_streamer->navigateTo ( url );
649 llinfos << "Playing....." << llendl;
650 m_streamer->addCommand(LLMediaBase::COMMAND_START);
651 m_streamer->updateMedia();
652
653 }
654 else
655 {
656 llinfos << "LLAudioEngine_OpenAL setting stream to NULL"<< llendl;
657 mInternetStreamURL.erase();
658 m_streamer->addCommand(LLMediaBase::COMMAND_STOP);
659 m_streamer->updateMedia();
660 }
661 #endif
662}
663
664
665void LLAudioEngine_OpenAL::updateInternetStream()
666{
667 // DCF_DEBUG
668 llinfos << "entered LLAudioEngine_OpenAL::updateInternetStream()" << llendl;
669
670}
671
672
673void LLAudioEngine_OpenAL::stopInternetStream()
674{
675 // DCF_DEBUG
676 llinfos << "entered LLAudioEngine_OpenAL::stopInternetStream()" << llendl;
677 476
678 #if LL_GSTREAMER_ENABLED 477 int processed, queued, unprocessed;
679 if( ! m_streamer->addCommand(LLMediaBase::COMMAND_STOP)) 478 alGetSourcei(mWindSource, AL_BUFFERS_PROCESSED, &processed);
680 { 479 alGetSourcei(mWindSource, AL_BUFFERS_QUEUED, &queued);
681 llinfos << "attempting to stop stream failed!" << llendl; 480 unprocessed = queued - processed;
682 }
683 m_streamer->updateMedia();
684 #endif
685 mInternetStreamURL.erase();
686}
687 481
482 // ensure that there are always at least 3x as many filled buffers
483 // queued as we managed to empty since last time.
484 mNumEmptyWindALBuffers = llmin(mNumEmptyWindALBuffers + processed * 3 - unprocessed, MAX_NUM_WIND_BUFFERS-unprocessed);
485 mNumEmptyWindALBuffers = llmax(mNumEmptyWindALBuffers, 0);
688 486
689void LLAudioEngine_OpenAL::pauseInternetStream(int pause) 487 //llinfos << "mNumEmptyWindALBuffers: " << mNumEmptyWindALBuffers <<" (" << unprocessed << ":" << processed << ")" << llendl;
690{
691 #if LL_GSTREAMER_ENABLED
692 if(!m_streamer)
693 return;
694 // DCF_DEBUG
695 llinfos << "entered LLAudioEngine_OpenAL::pauseInternetStream()" << llendl;
696 488
697 if(pause) 489 while(processed--) // unqueue old buffers
698 { 490 {
699 if(!m_streamer->addCommand(LLMediaBase::COMMAND_PAUSE)) 491 ALuint buffer;
492 int error;
493 alGetError(); /* clear error */
494 alSourceUnqueueBuffers(mWindSource, 1, &buffer);
495 error = alGetError();
496 if(error != AL_NO_ERROR)
700 { 497 {
701 llinfos << "attempting to pause stream failed!" << llendl; 498 llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping (unqueuing) buffers" << llendl;
702 } 499 }
703 m_streamer->updateMedia(); 500 else
704 }
705 else
706 {
707 if( ! m_streamer->addCommand(LLMediaBase::COMMAND_START))
708 { 501 {
709 llinfos << "attempting to pause stream failed!" << llendl; 502 alDeleteBuffers(1, &buffer);
710 } 503 }
711 m_streamer->updateMedia();
712 } 504 }
713 #endif
714}
715
716 505
717int LLAudioEngine_OpenAL::isInternetStreamPlaying() 506 unprocessed += mNumEmptyWindALBuffers;
718{ 507 while (mNumEmptyWindALBuffers > 0) // fill+queue new buffers
508 {
509 ALuint buffer;
510 alGetError(); /* clear error */
511 alGenBuffers(1,&buffer);
512 if((error=alGetError()) != AL_NO_ERROR)
513 {
514 llwarns << "LLAudioEngine_OpenAL::initWind() Error creating wind buffer: " << error << llendl;
515 break;
516 }
719 517
720 #if LL_GSTREAMER_ENABLED 518 alBufferData(buffer,
721 if(!m_streamer) 519 AL_FORMAT_STEREO16,
722 return 0; 520 mWindGen->windGenerate(mWindBuf,
521 mWindBufSamples, 2),
522 mWindBufBytes,
523 mWindBufFreq);
524 error = alGetError();
525 if(error != AL_NO_ERROR)
526 llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping (bufferdata) buffers" << llendl;
527
528 alSourceQueueBuffers(mWindSource, 1, &buffer);
529 error = alGetError();
530 if(error != AL_NO_ERROR)
531 llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping (queuing) buffers" << llendl;
723 532
724 if(m_streamer->getStatus() == LLMediaBase::STATUS_STARTED) 533 --mNumEmptyWindALBuffers;
725 {
726 return 1; // Active and playing
727 } 534 }
728 535
729 if(m_streamer->getStatus() == LLMediaBase::STATUS_PAUSED) 536 int playing;
537 alGetSourcei(mWindSource, AL_SOURCE_STATE, &playing);
538 if(playing != AL_PLAYING)
730 { 539 {
731 return 2; // paused 540 alSourcePlay(mWindSource);
732 }
733
734 #endif
735 return 0; // Stopped
736}
737
738
739void LLAudioEngine_OpenAL::getInternetStreamInfo(char* artist_out, char* title_out)
740{
741}
742
743
744void LLAudioEngine_OpenAL::setInternetStreamGain(F32 vol)
745{
746 #if LL_GSTREAMER_ENABLED
747 // Set the gstreamer volume here
748 if(!m_streamer)
749 return;
750
751 vol = llclamp(vol, 0.f, 1.f);
752 m_streamer->setVolume(vol);
753 m_streamer->updateMedia();
754 #endif
755}
756
757 541
758const std::string& LLAudioEngine_OpenAL::getInternetStreamURL() 542 llinfos << "Wind had stopped - probably ran out of buffers - restarting: " << (unprocessed+mNumEmptyWindALBuffers) << " now queued." << llendl;
759{ 543 }
760 return mInternetStreamURL;
761} 544}
diff --git a/linden/indra/llaudio/audioengine_openal.h b/linden/indra/llaudio/audioengine_openal.h
index 5d5c7d8..b03153a 100644
--- a/linden/indra/llaudio/audioengine_openal.h
+++ b/linden/indra/llaudio/audioengine_openal.h
@@ -3,27 +3,28 @@
3 * @brief implementation of audio engine using OpenAL 3 * @brief implementation of audio engine using OpenAL
4 * support as a OpenAL 3D implementation 4 * support as a OpenAL 3D implementation
5 * 5 *
6 * Copyright (c) 2002-2008, Linden Research, Inc.
7 * 6 *
8 * $LicenseInfo:firstyear=2002&license=viewergpl$ 7 * $LicenseInfo:firstyear=2002&license=viewergpl$
9 * 8 *
9 * Copyright (c) 2002-2008, Linden Research, Inc.
10 *
10 * Second Life Viewer Source Code 11 * Second Life Viewer Source Code
11 * The source code in this file ("Source Code") is provided by Linden Lab 12 * The source code in this file ("Source Code") is provided by Linden Lab
12 * to you under the terms of the GNU General Public License, version 2.0 13 * to you under the terms of the GNU General Public License, version 2.0
13 * ("GPL"), unless you have obtained a separate licensing agreement 14 * ("GPL"), unless you have obtained a separate licensing agreement
14 * ("Other License"), formally executed by you and Linden Lab. Terms of 15 * ("Other License"), formally executed by you and Linden Lab. Terms of
15 * the GPL can be found in doc/GPL-license.txt in this distribution, or 16 * the GPL can be found in doc/GPL-license.txt in this distribution, or
16 * online at http://secondlife.com/developers/opensource/gplv2 17 * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
17 * 18 *
18 * There are special exceptions to the terms and conditions of the GPL as 19 * There are special exceptions to the terms and conditions of the GPL as
19 * it is applied to this Source Code. View the full text of the exception 20 * it is applied to this Source Code. View the full text of the exception
20 * in the file doc/FLOSS-exception.txt in this software distribution, or 21 * in the file doc/FLOSS-exception.txt in this software distribution, or
21 * online at http://secondlife.com/developers/opensource/flossexception 22 * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
22 * 23 *
23 * By copying, modifying or distributing this software, you acknowledge 24 * By copying, modifying or distributing this software, you acknowledge
24 * that you have read and understood your obligations described above, 25 * that you have read and understood your obligations described above,
25 * and agree to abide by those obligations. 26 * and agree to abide by those obligations.
26 * 27 *
27 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO 28 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
28 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, 29 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
29 * COMPLETENESS OR PERFORMANCE. 30 * COMPLETENESS OR PERFORMANCE.
@@ -31,16 +32,12 @@
31 */ 32 */
32 33
33 34
34#ifndef LL_AUDIOENGINE_OpenAL_H 35#ifndef LL_AUDIOENGINE_OPENAL_H
35#define LL_AUDIOENGINE_OpenAL_H 36#define LL_AUDIOENGINE_OPENAL_H
36
37#include <string>
38 37
39#include "audioengine.h" 38#include "audioengine.h"
40#include "listener_openal.h" 39#include "listener_openal.h"
41#include "llmediamanager.h" 40#include "windgen.h"
42#include "llmediaimplgstreamer.h"
43#include "llrand.h"
44 41
45class LLAudioEngine_OpenAL : public LLAudioEngine 42class LLAudioEngine_OpenAL : public LLAudioEngine
46{ 43{
@@ -48,58 +45,34 @@ class LLAudioEngine_OpenAL : public LLAudioEngine
48 LLAudioEngine_OpenAL(); 45 LLAudioEngine_OpenAL();
49 virtual ~LLAudioEngine_OpenAL(); 46 virtual ~LLAudioEngine_OpenAL();
50 47
51 virtual BOOL init(const S32 num_channels); 48 virtual bool init(const S32 num_channels, void *user_data);
52 virtual std::string getDriverName(bool verbose); 49 virtual std::string getDriverName(bool verbose);
53 virtual void allocateListener(); 50 virtual void allocateListener();
54 51
55 virtual void shutdown(); 52 virtual void shutdown();
56 53
57 virtual void idle(F32 max_decode_time = 0.f);
58
59 void setInternalGain(F32 gain); 54 void setInternalGain(F32 gain);
60 55
61 LLAudioBuffer* createBuffer(); 56 LLAudioBuffer* createBuffer();
62 LLAudioChannel* createChannel(); 57 LLAudioChannel* createChannel();
63 58
64 // Internet stream methods 59 /*virtual*/ void initWind();
65 virtual void initInternetStream(); 60 /*virtual*/ void cleanupWind();
66 virtual void startInternetStream(const std::string& url_cstr); 61 /*virtual*/ void updateWind(LLVector3 direction, F32 camera_altitude);
67 virtual void stopInternetStream(); 62
68 virtual void updateInternetStream(); 63 private:
69 virtual void pauseInternetStream(int pause);
70 virtual int isInternetStreamPlaying();
71 virtual void getInternetStreamInfo(char* artist, char* title);
72 virtual void setInternetStreamGain(F32 vol);
73 virtual const std::string& getInternetStreamURL();
74 virtual void InitStreamer();
75
76 void checkALError();
77
78 void initWind();
79 void cleanupWind();
80 void updateWind(LLVector3 direction, F32 camera_altitude);
81
82 protected:
83 static const S32 mNumWindBuffers=20;
84 static const S32 mSampleRate=44100;
85 static const S32 mBytesPerSample=4;
86 static const S32 mWindDataSize=8820; //44100 * 0.200 * 2 channels * 2 bytes per sample
87
88 BOOL mFirstWind;
89 ALuint mWindBuffers[mNumWindBuffers];
90 ALuint mWindSource;
91
92 F32 mTargetGain;
93 F32 mTargetFreq;
94 F32 mTargetPanGainR;
95 S16 mWindData[mWindDataSize];
96
97 std::string mInternetStreamURL;
98 void * windDSP(void *newbuffer, int length); 64 void * windDSP(void *newbuffer, int length);
99#if LL_GSTREAMER_ENABLED 65 typedef S16 WIND_SAMPLE_T;
100 LLMediaManagerData * mMedia_data; 66 LLWindGen<WIND_SAMPLE_T> *mWindGen;
101 LLMediaImplGStreamer * m_streamer; 67 S16 *mWindBuf;
102#endif 68 U32 mWindBufFreq;
69 U32 mWindBufSamples;
70 U32 mWindBufBytes;
71 ALuint mWindSource;
72 int mNumEmptyWindALBuffers;
73
74 static const int MAX_NUM_WIND_BUFFERS = 80;
75 static const float WIND_BUFFER_SIZE_SEC = 0.05f; // 1/20th sec
103}; 76};
104 77
105class LLAudioChannelOpenAL : public LLAudioChannel 78class LLAudioChannelOpenAL : public LLAudioChannel
@@ -108,16 +81,17 @@ class LLAudioChannelOpenAL : public LLAudioChannel
108 LLAudioChannelOpenAL(); 81 LLAudioChannelOpenAL();
109 virtual ~LLAudioChannelOpenAL(); 82 virtual ~LLAudioChannelOpenAL();
110 protected: 83 protected:
111 void play(); 84 /*virtual*/ void play();
112 void playSynced(LLAudioChannel *channelp); 85 /*virtual*/ void playSynced(LLAudioChannel *channelp);
113 void cleanup(); 86 /*virtual*/ void cleanup();
114 bool isPlaying(); 87 /*virtual*/ bool isPlaying();
115 88
116 bool updateBuffer(); 89 /*virtual*/ bool updateBuffer();
117 void update3DPosition(); 90 /*virtual*/ void update3DPosition();
118 void updateLoop(){}; 91 /*virtual*/ void updateLoop();
119 92
120 ALuint ALSource; 93 ALuint mALSource;
94 ALint mLastSamplePos;
121}; 95};
122 96
123class LLAudioBufferOpenAL : public LLAudioBuffer{ 97class LLAudioBufferOpenAL : public LLAudioBuffer{
@@ -131,8 +105,9 @@ class LLAudioBufferOpenAL : public LLAudioBuffer{
131 friend class LLAudioChannelOpenAL; 105 friend class LLAudioChannelOpenAL;
132 protected: 106 protected:
133 void cleanup(); 107 void cleanup();
134 ALuint getBuffer(){return ALBuffer;} 108 ALuint getBuffer() {return mALBuffer;}
135 ALuint ALBuffer; 109
110 ALuint mALBuffer;
136}; 111};
137 112
138#endif 113#endif
diff --git a/linden/indra/newview/llaudiosourcevo.cpp b/linden/indra/newview/llaudiosourcevo.cpp
index e668078..9c25d94 100644
--- a/linden/indra/newview/llaudiosourcevo.cpp
+++ b/linden/indra/newview/llaudiosourcevo.cpp
@@ -39,7 +39,7 @@
39#include "llviewerparcelmgr.h" 39#include "llviewerparcelmgr.h"
40 40
41LLAudioSourceVO::LLAudioSourceVO(const LLUUID &sound_id, const LLUUID& owner_id, const F32 gain, LLViewerObject *objectp) 41LLAudioSourceVO::LLAudioSourceVO(const LLUUID &sound_id, const LLUUID& owner_id, const F32 gain, LLViewerObject *objectp)
42: LLAudioSource(sound_id, owner_id, gain), 42: LLAudioSource(sound_id, owner_id, gain, LLAudioEngine::AUDIO_TYPE_SFX),
43 mObjectp(objectp), 43 mObjectp(objectp),
44 mActualGain(gain) 44 mActualGain(gain)
45{ 45{
diff --git a/linden/indra/newview/llpreviewsound.cpp b/linden/indra/newview/llpreviewsound.cpp
index 9ba6fd5..6b79bfb 100644
--- a/linden/indra/newview/llpreviewsound.cpp
+++ b/linden/indra/newview/llpreviewsound.cpp
@@ -106,7 +106,6 @@ void LLPreviewSound::auditionSound( void *userdata )
106 if(item && gAudiop) 106 if(item && gAudiop)
107 { 107 {
108 LLVector3d lpos_global = gAgent.getPositionGlobal(); 108 LLVector3d lpos_global = gAgent.getPositionGlobal();
109 F32 volume = gSavedSettings.getBOOL("MuteSounds") ? 0.f : SOUND_GAIN * gSavedSettings.getF32("AudioLevelSFX"); 109 gAudiop->triggerSound(item->getAssetUUID(), gAgent.getID(), SOUND_GAIN, LLAudioEngine::AUDIO_TYPE_UI, lpos_global);
110 gAudiop->triggerSound(item->getAssetUUID(), gAgent.getID(), volume, lpos_global);
111 } 110 }
112} 111}
diff --git a/linden/indra/newview/llstartup.cpp b/linden/indra/newview/llstartup.cpp
index 636cf31..11e4ac5 100644
--- a/linden/indra/newview/llstartup.cpp
+++ b/linden/indra/newview/llstartup.cpp
@@ -583,28 +583,55 @@ bool idle_startup()
583 583
584 if (FALSE == gSavedSettings.getBOOL("NoAudio")) 584 if (FALSE == gSavedSettings.getBOOL("NoAudio"))
585 { 585 {
586 586 gAudiop = NULL;
587 gAudiop = (LLAudioEngine *) new LLAudioEngine_OpenAL(); 587
588#ifdef LL_OPENAL
589 if (!gAudiop
590#if !LL_WINDOWS
591 && NULL == getenv("LL_BAD_OPENAL_DRIVER")
592#endif // !LL_WINDOWS
593 )
594 {
595 gAudiop = (LLAudioEngine *) new LLAudioEngine_OpenAL();
596 }
597#endif
598
599#ifdef LL_FMOD
600 if (!gAudiop
601#if !LL_WINDOWS
602 && NULL == getenv("LL_BAD_FMOD_DRIVER")
603#endif // !LL_WINDOWS
604 )
605 {
606 gAudiop = (LLAudioEngine *) new LLAudioEngine_FMOD();
607 }
608#endif
588 609
589 if (gAudiop) 610 if (gAudiop)
590 { 611 {
591 BOOL init = gAudiop->init(kAUDIO_NUM_SOURCES); 612#if LL_WINDOWS
592 if(!init) 613 // FMOD on Windows needs the window handle to stop playing audio
614 // when window is minimized. JC
615 void* window_handle = (HWND)gViewerWindow->getPlatformWindow();
616#else
617 void* window_handle = NULL;
618#endif
619 bool init = gAudiop->init(kAUDIO_NUM_SOURCES, window_handle);
620 if(init)
593 { 621 {
594 LL_WARNS("AppInit") << "Unable to initialize audio engine" << LL_ENDL; 622 gAudiop->setMuted(TRUE);
595 gAudiop=NULL;
596 } 623 }
597 else 624 else
598 { 625 {
599 gAudiop->setMuted(TRUE); 626 LL_WARNS("AppInit") << "Unable to initialize audio engine" << LL_ENDL;
600 LL_INFOS("AppInit") << "Audio Engine Initialized." << LL_ENDL; 627 delete gAudiop;
628 gAudiop = NULL;
601 } 629 }
602 } 630 }
603 } 631 }
604 else 632
605 { 633 LL_INFOS("AppInit") << "Audio Engine Initialized." << LL_ENDL;
606 gAudiop = NULL; 634
607 }
608 635
609 if (LLTimer::knownBadTimer()) 636 if (LLTimer::knownBadTimer())
610 { 637 {
diff --git a/linden/indra/newview/llviewermessage.cpp b/linden/indra/newview/llviewermessage.cpp
index 0e39026..260265e 100644
--- a/linden/indra/newview/llviewermessage.cpp
+++ b/linden/indra/newview/llviewermessage.cpp
@@ -3308,8 +3308,7 @@ void process_sound_trigger(LLMessageSystem *msg, void **)
3308 return; 3308 return;
3309 } 3309 }
3310 3310
3311 F32 volume = gSavedSettings.getBOOL("MuteSounds") ? 0.f : (gain * gSavedSettings.getF32("AudioLevelSFX")); 3311 gAudiop->triggerSound(sound_id, owner_id, gain, LLAudioEngine::AUDIO_TYPE_SFX, pos_global);
3312 gAudiop->triggerSound(sound_id, owner_id, volume, pos_global);
3313} 3312}
3314 3313
3315void process_preload_sound(LLMessageSystem *msg, void **user_data) 3314void process_preload_sound(LLMessageSystem *msg, void **user_data)
diff --git a/linden/indra/newview/llviewertexteditor.cpp b/linden/indra/newview/llviewertexteditor.cpp
index 8a55b3f..1dda1ca 100644
--- a/linden/indra/newview/llviewertexteditor.cpp
+++ b/linden/indra/newview/llviewertexteditor.cpp
@@ -1402,8 +1402,7 @@ void LLViewerTextEditor::openEmbeddedSound( LLInventoryItem* item )
1402 const F32 SOUND_GAIN = 1.0f; 1402 const F32 SOUND_GAIN = 1.0f;
1403 if(gAudiop) 1403 if(gAudiop)
1404 { 1404 {
1405 F32 volume = gSavedSettings.getBOOL("MuteSounds") ? 0.f : (SOUND_GAIN * gSavedSettings.getF32("AudioLevelSFX")); 1405 gAudiop->triggerSound(item->getAssetUUID(), gAgentID, SOUND_GAIN, LLAudioEngine::AUDIO_TYPE_UI, lpos_global);
1406 gAudiop->triggerSound(item->getAssetUUID(), gAgentID, volume, lpos_global);
1407 } 1406 }
1408 showCopyToInvDialog( item ); 1407 showCopyToInvDialog( item );
1409} 1408}
diff --git a/linden/indra/newview/llvoavatar.cpp b/linden/indra/newview/llvoavatar.cpp
index e480eb3..327cd57 100644
--- a/linden/indra/newview/llvoavatar.cpp
+++ b/linden/indra/newview/llvoavatar.cpp
@@ -3828,10 +3828,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
3828// AUDIO_STEP_LO_SPEED, AUDIO_STEP_HI_SPEED, 3828// AUDIO_STEP_LO_SPEED, AUDIO_STEP_HI_SPEED,
3829// AUDIO_STEP_LO_GAIN, AUDIO_STEP_HI_GAIN ); 3829// AUDIO_STEP_LO_GAIN, AUDIO_STEP_HI_GAIN );
3830 3830
3831 F32 ambient_volume = gSavedSettings.getF32("AudioLevelAmbient"); 3831 const F32 STEP_VOLUME = 0.5f;
3832 F32 gain = gSavedSettings.getBOOL("MuteAmbient")
3833 ? 0.f
3834 : (.50f * ambient_volume * ambient_volume);
3835 LLUUID& step_sound_id = getStepSound(); 3832 LLUUID& step_sound_id = getStepSound();
3836 3833
3837 LLVector3d foot_pos_global = gAgent.getPosGlobalFromAgent(foot_pos_agent); 3834 LLVector3d foot_pos_global = gAgent.getPosGlobalFromAgent(foot_pos_agent);
@@ -3839,7 +3836,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
3839 if (LLViewerParcelMgr::getInstance()->canHearSound(foot_pos_global) 3836 if (LLViewerParcelMgr::getInstance()->canHearSound(foot_pos_global)
3840 && !LLMuteList::getInstance()->isMuted(getID(), LLMute::flagObjectSounds)) 3837 && !LLMuteList::getInstance()->isMuted(getID(), LLMute::flagObjectSounds))
3841 { 3838 {
3842 gAudiop->triggerSound(step_sound_id, getID(), gain, foot_pos_global); 3839 gAudiop->triggerSound(step_sound_id, getID(), STEP_VOLUME, LLAudioEngine::AUDIO_TYPE_AMBIENT, foot_pos_global);
3843 } 3840 }
3844 } 3841 }
3845 } 3842 }
@@ -4819,8 +4816,8 @@ BOOL LLVOAvatar::processSingleAnimationStateChange( const LLUUID& anim_id, BOOL
4819 //else 4816 //else
4820 { 4817 {
4821 LLUUID sound_id = LLUUID(gSavedSettings.getString("UISndTyping")); 4818 LLUUID sound_id = LLUUID(gSavedSettings.getString("UISndTyping"));
4822 F32 volume = gSavedSettings.getBOOL("MuteSounds") ? 0.f : gSavedSettings.getF32("AudioLevelSFX"); 4819 gAudiop->triggerSound(sound_id, getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_SFX, char_pos_global);
4823 gAudiop->triggerSound(sound_id, getID(), volume, char_pos_global); 4820
4824 } 4821 }
4825 } 4822 }
4826 } 4823 }