aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden
diff options
context:
space:
mode:
authorJacek Antonelli2008-11-19 12:51:29 -0600
committerJacek Antonelli2008-11-19 16:55:13 -0600
commit97e6c15e935666c1b295b7508a182d0da4b481f1 (patch)
treeef1d5e6a33a71b51a3deadb6de54a67b6a8c7f5e /linden
parentChanged to Imprudence.exec_marker to match llappviewer.cpp. (diff)
downloadmeta-impy-97e6c15e935666c1b295b7508a182d0da4b481f1.zip
meta-impy-97e6c15e935666c1b295b7508a182d0da4b481f1.tar.gz
meta-impy-97e6c15e935666c1b295b7508a182d0da4b481f1.tar.bz2
meta-impy-97e6c15e935666c1b295b7508a182d0da4b481f1.tar.xz
VWR-2662: OpenAL support (patch by Tofu Linden)
Diffstat (limited to 'linden')
-rw-r--r--linden/indra/cmake/LLAudio.cmake2
-rw-r--r--linden/indra/llaudio/CMakeLists.txt19
-rw-r--r--linden/indra/llaudio/audioengine.cpp323
-rw-r--r--linden/indra/llaudio/audioengine.h130
-rw-r--r--linden/indra/llaudio/audioengine_fmod.cpp271
-rw-r--r--linden/indra/llaudio/audioengine_fmod.h31
-rw-r--r--linden/indra/llaudio/audioengine_openal.cpp422
-rw-r--r--linden/indra/llaudio/audioengine_openal.h100
-rw-r--r--linden/indra/llaudio/listener_fmod.h10
-rw-r--r--linden/indra/llaudio/listener_openal.cpp94
-rw-r--r--linden/indra/llaudio/listener_openal.h12
-rw-r--r--linden/indra/llaudio/windgen.h138
-rw-r--r--linden/indra/newview/CMakeLists.txt7
-rw-r--r--linden/indra/newview/llappviewer.cpp3
-rw-r--r--linden/indra/newview/llstartup.cpp24
15 files changed, 1215 insertions, 371 deletions
diff --git a/linden/indra/cmake/LLAudio.cmake b/linden/indra/cmake/LLAudio.cmake
index 7b9f254..893aa68 100644
--- a/linden/indra/cmake/LLAudio.cmake
+++ b/linden/indra/cmake/LLAudio.cmake
@@ -1,6 +1,7 @@
1# -*- cmake -*- 1# -*- cmake -*-
2 2
3include(Audio) 3include(Audio)
4include(OPENAL)
4 5
5set(LLAUDIO_INCLUDE_DIRS 6set(LLAUDIO_INCLUDE_DIRS
6 ${LIBS_OPEN_DIR}/llaudio 7 ${LIBS_OPEN_DIR}/llaudio
@@ -12,4 +13,5 @@ set(LLAUDIO_LIBRARIES
12 ${VORBISFILE_LIBRARIES} 13 ${VORBISFILE_LIBRARIES}
13 ${VORBIS_LIBRARIES} 14 ${VORBIS_LIBRARIES}
14 ${OGG_LIBRARIES} 15 ${OGG_LIBRARIES}
16 ${OPENAL_LIBRARIES}
15 ) 17 )
diff --git a/linden/indra/llaudio/CMakeLists.txt b/linden/indra/llaudio/CMakeLists.txt
index b662023..aa15a9d 100644
--- a/linden/indra/llaudio/CMakeLists.txt
+++ b/linden/indra/llaudio/CMakeLists.txt
@@ -9,6 +9,7 @@ include(LLCommon)
9include(LLMath) 9include(LLMath)
10include(LLMessage) 10include(LLMessage)
11include(LLVFS) 11include(LLVFS)
12include(LLMedia)
12 13
13include_directories( 14include_directories(
14 ${FMOD_INCLUDE_DIR} 15 ${FMOD_INCLUDE_DIR}
@@ -20,6 +21,10 @@ include_directories(
20 ${VORBISENC_INCLUDE_DIRS} 21 ${VORBISENC_INCLUDE_DIRS}
21 ${VORBISFILE_INCLUDE_DIRS} 22 ${VORBISFILE_INCLUDE_DIRS}
22 ${VORBIS_INCLUDE_DIRS} 23 ${VORBIS_INCLUDE_DIRS}
24 ${OPENAL_LIB_INCLUDE_DIRS}
25 ${FREEAULT_LIB_INCLUDE_DIRS}
26 ${LLMEDIA_INCLUDE_DIRS}
27 ${GSTREAMER_INCLUDE_DIRS}
23 ) 28 )
24 29
25set(llaudio_SOURCE_FILES 30set(llaudio_SOURCE_FILES
@@ -38,6 +43,7 @@ set(llaudio_HEADER_FILES
38 llaudiodecodemgr.h 43 llaudiodecodemgr.h
39 vorbisdecode.h 44 vorbisdecode.h
40 vorbisencode.h 45 vorbisencode.h
46 windgen.h
41 ) 47 )
42 48
43if (FMOD) 49if (FMOD)
@@ -59,6 +65,19 @@ if (FMOD)
59 endif (LINUX) 65 endif (LINUX)
60endif (FMOD) 66endif (FMOD)
61 67
68if (OPENAL)
69 list(APPEND llaudio_SOURCE_FILES
70 audioengine_openal.cpp
71 listener_openal.cpp
72 )
73
74 list(APPEND llaudio_HEADER_FILES
75 audioengine_openal.h
76 listener_openal.h
77 )
78
79endif (OPENAL)
80
62set_source_files_properties(${llaudio_HEADER_FILES} 81set_source_files_properties(${llaudio_HEADER_FILES}
63 PROPERTIES HEADER_FILE_ONLY TRUE) 82 PROPERTIES HEADER_FILE_ONLY TRUE)
64 83
diff --git a/linden/indra/llaudio/audioengine.cpp b/linden/indra/llaudio/audioengine.cpp
index 5dd5b28..0a450e9 100644
--- a/linden/indra/llaudio/audioengine.cpp
+++ b/linden/indra/llaudio/audioengine.cpp
@@ -44,14 +44,13 @@
44#include "llaudiodecodemgr.h" 44#include "llaudiodecodemgr.h"
45#include "llassetstorage.h" 45#include "llassetstorage.h"
46 46
47#include "llmediamanager.h"
48
47// necessary for grabbing sounds from sim (implemented in viewer) 49// necessary for grabbing sounds from sim (implemented in viewer)
48extern void request_sound(const LLUUID &sound_guid); 50extern void request_sound(const LLUUID &sound_guid);
49 51
50LLAudioEngine* gAudiop = NULL; 52LLAudioEngine* gAudiop = NULL;
51 53
52// Maximum amount of time we wait for a transfer to complete before starting
53// off another one.
54const F32 MAX_CURRENT_TRANSFER_TIME = 60.f;
55 54
56// 55//
57// LLAudioEngine implementation 56// LLAudioEngine implementation
@@ -75,13 +74,13 @@ void LLAudioEngine::setDefaults()
75 74
76 mListenerp = NULL; 75 mListenerp = NULL;
77 76
78 mMuted = FALSE; 77 mMuted = false;
79 mUserData = NULL; 78 mUserData = NULL;
80 79
81 mLastStatus = 0; 80 mLastStatus = 0;
82 81
83 mNumChannels = 0; 82 mNumChannels = 0;
84 mEnableWind = FALSE; 83 mEnableWind = false;
85 84
86 S32 i; 85 S32 i;
87 for (i = 0; i < MAX_CHANNELS; i++) 86 for (i = 0; i < MAX_CHANNELS; i++)
@@ -91,15 +90,18 @@ void LLAudioEngine::setDefaults()
91 for (i = 0; i < MAX_BUFFERS; i++) 90 for (i = 0; i < MAX_BUFFERS; i++)
92 { 91 {
93 mBuffers[i] = NULL; 92 mBuffers[i] = NULL;
94 } 93 }
95 94
96 mMasterGain = 1.f; 95 mMasterGain = 1.f;
97 mInternetStreamGain = 0.125f; 96 mInternetStreamGain = 0.125f;
98 mNextWindUpdate = 0.f; 97 mNextWindUpdate = 0.f;
98
99 mInternetStreamMedia = NULL;
100 mInternetStreamURL.clear();
99} 101}
100 102
101 103
102BOOL LLAudioEngine::init(const S32 num_channels, void* userdata) 104bool LLAudioEngine::init(const S32 num_channels, void* userdata)
103{ 105{
104 setDefaults(); 106 setDefaults();
105 107
@@ -111,7 +113,9 @@ BOOL LLAudioEngine::init(const S32 num_channels, void* userdata)
111 // Initialize the decode manager 113 // Initialize the decode manager
112 gAudioDecodeMgrp = new LLAudioDecodeMgr; 114 gAudioDecodeMgrp = new LLAudioDecodeMgr;
113 115
114 return TRUE; 116 llinfos << "LLAudioEngine::init() AudioEngine successfully initialized" << llendl;
117
118 return true;
115} 119}
116 120
117 121
@@ -141,22 +145,146 @@ void LLAudioEngine::shutdown()
141 S32 i; 145 S32 i;
142 for (i = 0; i < MAX_CHANNELS; i++) 146 for (i = 0; i < MAX_CHANNELS; i++)
143 { 147 {
144 if (mChannels[i]) 148 delete mChannels[i];
145 { 149 mChannels[i] = NULL;
146 delete mChannels[i];
147 mChannels[i] = NULL;
148 }
149 } 150 }
150 151
151 // Clean up buffers 152 // Clean up buffers
152 for (i = 0; i < MAX_BUFFERS; i++) 153 for (i = 0; i < MAX_BUFFERS; i++)
153 { 154 {
154 if (mBuffers[i]) 155 delete mBuffers[i];
156 mBuffers[i] = NULL;
157 }
158
159 delete mInternetStreamMedia;
160 mInternetStreamMedia = NULL;
161 mInternetStreamURL.clear();
162}
163
164
165// virtual
166void LLAudioEngine::startInternetStream(const std::string& url)
167{
168 llinfos << "entered startInternetStream()" << llendl;
169
170 if (!mInternetStreamMedia)
171 {
172 LLMediaManager* mgr = LLMediaManager::getInstance();
173 if (mgr)
155 { 174 {
156 delete mBuffers[i]; 175 mInternetStreamMedia = mgr->createSourceFromMimeType(LLURI(url).scheme(), "audio/mpeg"); // assumes that whatever media implementation supports mp3 also supports vorbis.
157 mBuffers[i] = NULL; 176 llinfos << "mInternetStreamMedia is now " << mInternetStreamMedia << llendl;
177 }
178 }
179
180 if(!mInternetStreamMedia)
181 return;
182
183 if (!url.empty()) {
184 llinfos << "Starting internet stream: " << url << llendl;
185 mInternetStreamURL = url;
186 mInternetStreamMedia->navigateTo ( url );
187 llinfos << "Playing....." << llendl;
188 mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_START);
189 mInternetStreamMedia->updateMedia();
190 } else {
191 llinfos << "setting stream to NULL"<< llendl;
192 mInternetStreamURL.clear();
193 mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_STOP);
194 mInternetStreamMedia->updateMedia();
195 }
196 //#endif
197}
198
199// virtual
200void LLAudioEngine::stopInternetStream()
201{
202 llinfos << "entered stopInternetStream()" << llendl;
203
204 if(mInternetStreamMedia)
205 {
206 if( ! mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_STOP)){
207 llinfos << "attempting to stop stream failed!" << llendl;
158 } 208 }
209 mInternetStreamMedia->updateMedia();
159 } 210 }
211
212 mInternetStreamURL.clear();
213}
214
215// virtual
216void LLAudioEngine::pauseInternetStream(int pause)
217{
218 llinfos << "entered pauseInternetStream()" << llendl;
219
220 if(!mInternetStreamMedia)
221 return;
222
223 if(pause)
224 {
225 if(! mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_PAUSE))
226 {
227 llinfos << "attempting to pause stream failed!" << llendl;
228 }
229 } else {
230 if(! mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_START))
231 {
232 llinfos << "attempting to unpause stream failed!" << llendl;
233 }
234 }
235 mInternetStreamMedia->updateMedia();
236}
237
238// virtual
239void LLAudioEngine::updateInternetStream()
240{
241 if (mInternetStreamMedia)
242 mInternetStreamMedia->updateMedia();
243}
244
245// virtual
246int LLAudioEngine::isInternetStreamPlaying()
247{
248 if (!mInternetStreamMedia)
249 return 0;
250
251 if (mInternetStreamMedia->getStatus() == LLMediaBase::STATUS_STARTED)
252 {
253 return 1; // Active and playing
254 }
255
256 if (mInternetStreamMedia->getStatus() == LLMediaBase::STATUS_PAUSED)
257 {
258 return 2; // paused
259 }
260
261 return 0; // Stopped
262}
263
264// virtual
265void LLAudioEngine::getInternetStreamInfo(char* artist, char* title)
266{
267 artist[0] = 0;
268 title[0] = 0;
269}
270
271// virtual
272void LLAudioEngine::setInternetStreamGain(F32 vol)
273{
274 mInternetStreamGain = vol;
275
276 if(!mInternetStreamMedia)
277 return;
278
279 vol = llclamp(vol, 0.f, 1.f);
280 mInternetStreamMedia->setVolume(vol);
281 mInternetStreamMedia->updateMedia();
282}
283
284// virtual
285const std::string& LLAudioEngine::getInternetStreamURL()
286{
287 return mInternetStreamURL;
160} 288}
161 289
162 290
@@ -200,7 +328,7 @@ void LLAudioEngine::idle(F32 max_decode_time)
200 { 328 {
201 if (mBuffers[i]) 329 if (mBuffers[i])
202 { 330 {
203 mBuffers[i]->mInUse = FALSE; 331 mBuffers[i]->mInUse = false;
204 } 332 }
205 } 333 }
206 334
@@ -252,11 +380,11 @@ void LLAudioEngine::idle(F32 max_decode_time)
252 { 380 {
253 // A sync slave, it doesn't start playing until it's synced up with the master. 381 // A sync slave, it doesn't start playing until it's synced up with the master.
254 // Flag this channel as waiting for sync, and return true. 382 // Flag this channel as waiting for sync, and return true.
255 channelp->setWaiting(TRUE); 383 channelp->setWaiting(true);
256 } 384 }
257 else 385 else
258 { 386 {
259 channelp->setWaiting(FALSE); 387 channelp->setWaiting(false);
260 channelp->play(); 388 channelp->play();
261 } 389 }
262 } 390 }
@@ -396,7 +524,7 @@ void LLAudioEngine::idle(F32 max_decode_time)
396 if (sync_masterp->getChannel()) 524 if (sync_masterp->getChannel())
397 { 525 {
398 channelp->playSynced(master_channelp); 526 channelp->playSynced(master_channelp);
399 channelp->setWaiting(FALSE); 527 channelp->setWaiting(false);
400 } 528 }
401 } 529 }
402 } 530 }
@@ -426,7 +554,7 @@ void LLAudioEngine::idle(F32 max_decode_time)
426 { 554 {
427 if (mChannels[i]) 555 if (mChannels[i])
428 { 556 {
429 mChannels[i]->mLoopedThisFrame = FALSE; 557 mChannels[i]->mLoopedThisFrame = false;
430 } 558 }
431 } 559 }
432 560
@@ -437,13 +565,17 @@ void LLAudioEngine::idle(F32 max_decode_time)
437 // missed picking it up in all the places that can add 565 // missed picking it up in all the places that can add
438 // or request new data. 566 // or request new data.
439 startNextTransfer(); 567 startNextTransfer();
568
569 updateInternetStream();
440} 570}
441 571
442BOOL LLAudioEngine::updateBufferForData(LLAudioData *adp, const LLUUID &audio_uuid) 572
573
574bool LLAudioEngine::updateBufferForData(LLAudioData *adp, const LLUUID &audio_uuid)
443{ 575{
444 if (!adp) 576 if (!adp)
445 { 577 {
446 return FALSE; 578 return false;
447 } 579 }
448 580
449 // Update the audio buffer first - load a sound if we have it. 581 // Update the audio buffer first - load a sound if we have it.
@@ -466,14 +598,14 @@ BOOL LLAudioEngine::updateBufferForData(LLAudioData *adp, const LLUUID &audio_uu
466 } 598 }
467 else 599 else
468 { 600 {
469 return FALSE; 601 return false;
470 } 602 }
471 } 603 }
472 return TRUE; 604 return true;
473} 605}
474 606
475 607
476void LLAudioEngine::enableWind(BOOL enable) 608void LLAudioEngine::enableWind(bool enable)
477{ 609{
478 if (enable && (!mEnableWind)) 610 if (enable && (!mEnableWind))
479 { 611 {
@@ -601,7 +733,7 @@ void LLAudioEngine::cleanupBuffer(LLAudioBuffer *bufferp)
601} 733}
602 734
603 735
604BOOL LLAudioEngine::preloadSound(const LLUUID &uuid) 736bool LLAudioEngine::preloadSound(const LLUUID &uuid)
605{ 737{
606 gAudiop->getAudioData(uuid); // We don't care about the return value, this is just to make sure 738 gAudiop->getAudioData(uuid); // We don't care about the return value, this is just to make sure
607 // that we have an entry, which will mean that the audio engine knows about this 739 // that we have an entry, which will mean that the audio engine knows about this
@@ -609,23 +741,23 @@ BOOL LLAudioEngine::preloadSound(const LLUUID &uuid)
609 if (gAudioDecodeMgrp->addDecodeRequest(uuid)) 741 if (gAudioDecodeMgrp->addDecodeRequest(uuid))
610 { 742 {
611 // This means that we do have a local copy, and we're working on decoding it. 743 // This means that we do have a local copy, and we're working on decoding it.
612 return TRUE; 744 return true;
613 } 745 }
614 746
615 // At some point we need to have the audio/asset system check the static VFS 747 // At some point we need to have the audio/asset system check the static VFS
616 // before it goes off and fetches stuff from the server. 748 // before it goes off and fetches stuff from the server.
617 //llwarns << "Used internal preload for non-local sound" << llendl; 749 //llwarns << "Used internal preload for non-local sound" << llendl;
618 return FALSE; 750 return false;
619} 751}
620 752
621 753
622BOOL LLAudioEngine::isWindEnabled() 754bool LLAudioEngine::isWindEnabled()
623{ 755{
624 return mEnableWind; 756 return mEnableWind;
625} 757}
626 758
627 759
628void LLAudioEngine::setMuted(BOOL muted) 760void LLAudioEngine::setMuted(bool muted)
629{ 761{
630 mMuted = muted; 762 mMuted = muted;
631 enableWind(!mMuted); 763 enableWind(!mMuted);
@@ -735,7 +867,7 @@ void LLAudioEngine::triggerSound(const LLUUID &audio_uuid, const LLUUID& owner_i
735 gAudiop->addAudioSource(asp); 867 gAudiop->addAudioSource(asp);
736 if (pos_global.isExactlyZero()) 868 if (pos_global.isExactlyZero())
737 { 869 {
738 asp->setAmbient(TRUE); 870 asp->setAmbient(true);
739 } 871 }
740 else 872 else
741 { 873 {
@@ -914,7 +1046,7 @@ void LLAudioEngine::cleanupAudioSource(LLAudioSource *asp)
914} 1046}
915 1047
916 1048
917BOOL LLAudioEngine::hasDecodedFile(const LLUUID &uuid) 1049bool LLAudioEngine::hasDecodedFile(const LLUUID &uuid)
918{ 1050{
919 std::string uuid_str; 1051 std::string uuid_str;
920 uuid.toString(uuid_str); 1052 uuid.toString(uuid_str);
@@ -925,16 +1057,16 @@ BOOL LLAudioEngine::hasDecodedFile(const LLUUID &uuid)
925 1057
926 if (gDirUtilp->fileExists(wav_path)) 1058 if (gDirUtilp->fileExists(wav_path))
927 { 1059 {
928 return TRUE; 1060 return true;
929 } 1061 }
930 else 1062 else
931 { 1063 {
932 return FALSE; 1064 return false;
933 } 1065 }
934} 1066}
935 1067
936 1068
937BOOL LLAudioEngine::hasLocalFile(const LLUUID &uuid) 1069bool LLAudioEngine::hasLocalFile(const LLUUID &uuid)
938{ 1070{
939 // See if it's in the VFS. 1071 // See if it's in the VFS.
940 return gVFS->getExists(uuid, LLAssetType::AT_SOUND); 1072 return gVFS->getExists(uuid, LLAssetType::AT_SOUND);
@@ -1150,9 +1282,9 @@ void LLAudioEngine::assetCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::E
1150 LLAudioData *adp = gAudiop->getAudioData(uuid); 1282 LLAudioData *adp = gAudiop->getAudioData(uuid);
1151 if (adp) 1283 if (adp)
1152 { 1284 {
1153 adp->setHasValidData(FALSE); 1285 adp->setHasValidData(false);
1154 adp->setHasLocalData(FALSE); 1286 adp->setHasLocalData(false);
1155 adp->setHasDecodedData(FALSE); 1287 adp->setHasDecodedData(false);
1156 } 1288 }
1157 } 1289 }
1158 else 1290 else
@@ -1165,8 +1297,8 @@ void LLAudioEngine::assetCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::E
1165 } 1297 }
1166 else 1298 else
1167 { 1299 {
1168 adp->setHasValidData(TRUE); 1300 adp->setHasValidData(true);
1169 adp->setHasLocalData(TRUE); 1301 adp->setHasLocalData(true);
1170 gAudioDecodeMgrp->addDecodeRequest(uuid); 1302 gAudioDecodeMgrp->addDecodeRequest(uuid);
1171 } 1303 }
1172 } 1304 }
@@ -1185,12 +1317,12 @@ LLAudioSource::LLAudioSource(const LLUUID& id, const LLUUID& owner_id, const F32
1185 mOwnerID(owner_id), 1317 mOwnerID(owner_id),
1186 mPriority(0.f), 1318 mPriority(0.f),
1187 mGain(gain), 1319 mGain(gain),
1188 mAmbient(FALSE), 1320 mAmbient(false),
1189 mLoop(FALSE), 1321 mLoop(false),
1190 mSyncMaster(FALSE), 1322 mSyncMaster(false),
1191 mSyncSlave(FALSE), 1323 mSyncSlave(false),
1192 mQueueSounds(FALSE), 1324 mQueueSounds(false),
1193 mPlayedOnce(FALSE), 1325 mPlayedOnce(false),
1194 mChannelp(NULL), 1326 mChannelp(NULL),
1195 mCurrentDatap(NULL), 1327 mCurrentDatap(NULL),
1196 mQueuedDatap(NULL) 1328 mQueuedDatap(NULL)
@@ -1254,7 +1386,7 @@ void LLAudioSource::updatePriority()
1254 } 1386 }
1255} 1387}
1256 1388
1257BOOL LLAudioSource::setupChannel() 1389bool LLAudioSource::setupChannel()
1258{ 1390{
1259 LLAudioData *adp = getCurrentData(); 1391 LLAudioData *adp = getCurrentData();
1260 1392
@@ -1262,7 +1394,7 @@ BOOL LLAudioSource::setupChannel()
1262 { 1394 {
1263 // We're not ready to play back the sound yet, so don't try and allocate a channel for it. 1395 // We're not ready to play back the sound yet, so don't try and allocate a channel for it.
1264 //llwarns << "Aborting, no buffer" << llendl; 1396 //llwarns << "Aborting, no buffer" << llendl;
1265 return FALSE; 1397 return false;
1266 } 1398 }
1267 1399
1268 1400
@@ -1280,15 +1412,15 @@ BOOL LLAudioSource::setupChannel()
1280 // Now we have to reprioritize. 1412 // Now we have to reprioritize.
1281 // For now, just don't play the sound. 1413 // For now, just don't play the sound.
1282 //llwarns << "Aborting, no free channels" << llendl; 1414 //llwarns << "Aborting, no free channels" << llendl;
1283 return FALSE; 1415 return false;
1284 } 1416 }
1285 1417
1286 mChannelp->setSource(this); 1418 mChannelp->setSource(this);
1287 return TRUE; 1419 return true;
1288} 1420}
1289 1421
1290 1422
1291BOOL LLAudioSource::play(const LLUUID &audio_uuid) 1423bool LLAudioSource::play(const LLUUID &audio_uuid)
1292{ 1424{
1293 if (audio_uuid.isNull()) 1425 if (audio_uuid.isNull())
1294 { 1426 {
@@ -1296,7 +1428,7 @@ BOOL LLAudioSource::play(const LLUUID &audio_uuid)
1296 { 1428 {
1297 getChannel()->setSource(NULL); 1429 getChannel()->setSource(NULL);
1298 setChannel(NULL); 1430 setChannel(NULL);
1299 addAudioData(NULL, TRUE); 1431 addAudioData(NULL, true);
1300 } 1432 }
1301 } 1433 }
1302 // Reset our age timeout if someone attempts to play the source. 1434 // Reset our age timeout if someone attempts to play the source.
@@ -1304,7 +1436,7 @@ BOOL LLAudioSource::play(const LLUUID &audio_uuid)
1304 1436
1305 LLAudioData *adp = gAudiop->getAudioData(audio_uuid); 1437 LLAudioData *adp = gAudiop->getAudioData(audio_uuid);
1306 1438
1307 BOOL has_buffer = gAudiop->updateBufferForData(adp, audio_uuid); 1439 bool has_buffer = gAudiop->updateBufferForData(adp, audio_uuid);
1308 1440
1309 1441
1310 addAudioData(adp); 1442 addAudioData(adp);
@@ -1312,47 +1444,48 @@ BOOL LLAudioSource::play(const LLUUID &audio_uuid)
1312 if (!has_buffer) 1444 if (!has_buffer)
1313 { 1445 {
1314 // Don't bother trying to set up a channel or anything, we don't have an audio buffer. 1446 // Don't bother trying to set up a channel or anything, we don't have an audio buffer.
1315 return FALSE; 1447 return false;
1316 } 1448 }
1317 1449
1318 if (!setupChannel()) 1450 if (!setupChannel())
1319 { 1451 {
1320 return FALSE; 1452 return false;
1321 } 1453 }
1322 1454
1323 if (isSyncSlave()) 1455 if (isSyncSlave())
1324 { 1456 {
1325 // A sync slave, it doesn't start playing until it's synced up with the master. 1457 // A sync slave, it doesn't start playing until it's synced up with the master.
1326 // Flag this channel as waiting for sync, and return true. 1458 // Flag this channel as waiting for sync, and return true.
1327 getChannel()->setWaiting(TRUE); 1459 getChannel()->setWaiting(true);
1328 return TRUE; 1460 return true;
1329 } 1461 }
1330 1462
1331 getChannel()->play(); 1463 getChannel()->play();
1332 return TRUE; 1464 return true;
1333} 1465}
1334 1466
1335 1467
1336BOOL LLAudioSource::isDone() 1468bool LLAudioSource::isDone()
1337{ 1469{
1338 const F32 MAX_AGE = 60.f; 1470 const F32 MAX_AGE = 60.f;
1339 const F32 MAX_UNPLAYED_AGE = 15.f; 1471 const F32 MAX_UNPLAYED_AGE = 15.f;
1472
1340 if (isLoop()) 1473 if (isLoop())
1341 { 1474 {
1342 // Looped sources never die on their own. 1475 // Looped sources never die on their own.
1343 return FALSE; 1476 return false;
1344 } 1477 }
1345 1478
1346 1479
1347 if (hasPendingPreloads()) 1480 if (hasPendingPreloads())
1348 { 1481 {
1349 return FALSE; 1482 return false;
1350 } 1483 }
1351 1484
1352 if (mQueuedDatap) 1485 if (mQueuedDatap)
1353 { 1486 {
1354 // Don't kill this sound if we've got something queued up to play. 1487 // Don't kill this sound if we've got something queued up to play.
1355 return FALSE; 1488 return false;
1356 } 1489 }
1357 1490
1358 F32 elapsed = mAgeTimer.getElapsedTimeF32(); 1491 F32 elapsed = mAgeTimer.getElapsedTimeF32();
@@ -1365,11 +1498,11 @@ BOOL LLAudioSource::isDone()
1365 // We don't have a channel assigned, and it's been 1498 // We don't have a channel assigned, and it's been
1366 // over 5 seconds since we tried to play it. Don't bother. 1499 // over 5 seconds since we tried to play it. Don't bother.
1367 //llinfos << "No channel assigned, source is done" << llendl; 1500 //llinfos << "No channel assigned, source is done" << llendl;
1368 return TRUE; 1501 return true;
1369 } 1502 }
1370 else 1503 else
1371 { 1504 {
1372 return FALSE; 1505 return false;
1373 } 1506 }
1374 } 1507 }
1375 1508
@@ -1377,27 +1510,27 @@ BOOL LLAudioSource::isDone()
1377 { 1510 {
1378 if (elapsed > MAX_AGE) 1511 if (elapsed > MAX_AGE)
1379 { 1512 {
1380 // Arbitarily cut off non-looped sounds when they're 20 seconds old. 1513 // Arbitarily cut off non-looped sounds when they're old.
1381 return TRUE; 1514 return true;
1382 } 1515 }
1383 else 1516 else
1384 { 1517 {
1385 // Sound is still playing and we haven't timed out, don't kill it. 1518 // Sound is still playing and we haven't timed out, don't kill it.
1386 return FALSE; 1519 return false;
1387 } 1520 }
1388 } 1521 }
1389 1522
1390 if ((elapsed > MAX_UNPLAYED_AGE) || mPlayedOnce) 1523 if ((elapsed > MAX_UNPLAYED_AGE) || mPlayedOnce)
1391 { 1524 {
1392 // The sound isn't playing back after 5 seconds or we're already done playing it, kill it. 1525 // The sound isn't playing back after 5 seconds or we're already done playing it, kill it.
1393 return TRUE; 1526 return true;
1394 } 1527 }
1395 1528
1396 return FALSE; 1529 return false;
1397} 1530}
1398 1531
1399 1532
1400void LLAudioSource::addAudioData(LLAudioData *adp, const BOOL set_current) 1533void LLAudioSource::addAudioData(LLAudioData *adp, const bool set_current)
1401{ 1534{
1402 // Only handle a single piece of audio data associated with a source right now, 1535 // Only handle a single piece of audio data associated with a source right now,
1403 // until I implement prefetch. 1536 // until I implement prefetch.
@@ -1465,7 +1598,7 @@ void LLAudioSource::addAudioData(LLAudioData *adp, const BOOL set_current)
1465} 1598}
1466 1599
1467 1600
1468BOOL LLAudioSource::hasPendingPreloads() const 1601bool LLAudioSource::hasPendingPreloads() const
1469{ 1602{
1470 // Check to see if we've got any preloads on deck for this source 1603 // Check to see if we've got any preloads on deck for this source
1471 data_map::const_iterator iter; 1604 data_map::const_iterator iter;
@@ -1475,11 +1608,11 @@ BOOL LLAudioSource::hasPendingPreloads() const
1475 if (!adp->hasDecodedData()) 1608 if (!adp->hasDecodedData())
1476 { 1609 {
1477 // This source is still waiting for a preload 1610 // This source is still waiting for a preload
1478 return TRUE; 1611 return true;
1479 } 1612 }
1480 } 1613 }
1481 1614
1482 return FALSE; 1615 return false;
1483} 1616}
1484 1617
1485 1618
@@ -1514,8 +1647,8 @@ LLAudioBuffer *LLAudioSource::getCurrentBuffer()
1514LLAudioChannel::LLAudioChannel() : 1647LLAudioChannel::LLAudioChannel() :
1515 mCurrentSourcep(NULL), 1648 mCurrentSourcep(NULL),
1516 mCurrentBufferp(NULL), 1649 mCurrentBufferp(NULL),
1517 mLoopedThisFrame(FALSE), 1650 mLoopedThisFrame(false),
1518 mWaiting(FALSE) 1651 mWaiting(false)
1519{ 1652{
1520} 1653}
1521 1654
@@ -1542,7 +1675,7 @@ void LLAudioChannel::setSource(LLAudioSource *sourcep)
1542 //llinfos << "Clearing source for channel" << llendl; 1675 //llinfos << "Clearing source for channel" << llendl;
1543 cleanup(); 1676 cleanup();
1544 mCurrentSourcep = NULL; 1677 mCurrentSourcep = NULL;
1545 mWaiting = FALSE; 1678 mWaiting = false;
1546 return; 1679 return;
1547 } 1680 }
1548 1681
@@ -1558,13 +1691,13 @@ void LLAudioChannel::setSource(LLAudioSource *sourcep)
1558} 1691}
1559 1692
1560 1693
1561BOOL LLAudioChannel::updateBuffer() 1694bool LLAudioChannel::updateBuffer()
1562{ 1695{
1563 if (!mCurrentSourcep) 1696 if (!mCurrentSourcep)
1564 { 1697 {
1565 // This channel isn't associated with any source, nothing 1698 // This channel isn't associated with any source, nothing
1566 // to be updated 1699 // to be updated
1567 return FALSE; 1700 return false;
1568 } 1701 }
1569 1702
1570 LLAudioBuffer *bufferp = mCurrentSourcep->getCurrentBuffer(); 1703 LLAudioBuffer *bufferp = mCurrentSourcep->getCurrentBuffer();
@@ -1574,9 +1707,9 @@ BOOL LLAudioChannel::updateBuffer()
1574 { 1707 {
1575 // The source hasn't changed what buffer it's playing 1708 // The source hasn't changed what buffer it's playing
1576 bufferp->mLastUseTimer.reset(); 1709 bufferp->mLastUseTimer.reset();
1577 bufferp->mInUse = TRUE; 1710 bufferp->mInUse = true;
1578 } 1711 }
1579 return FALSE; 1712 return false;
1580 } 1713 }
1581 1714
1582 // 1715 //
@@ -1589,16 +1722,16 @@ BOOL LLAudioChannel::updateBuffer()
1589 if (bufferp) 1722 if (bufferp)
1590 { 1723 {
1591 bufferp->mLastUseTimer.reset(); 1724 bufferp->mLastUseTimer.reset();
1592 bufferp->mInUse = TRUE; 1725 bufferp->mInUse = true;
1593 } 1726 }
1594 1727
1595 if (!mCurrentBufferp) 1728 if (!mCurrentBufferp)
1596 { 1729 {
1597 // There's no new buffer to be played, so we just abort. 1730 // There's no new buffer to be played, so we just abort.
1598 return FALSE; 1731 return false;
1599 } 1732 }
1600 1733
1601 return TRUE; 1734 return true;
1602} 1735}
1603 1736
1604 1737
@@ -1612,9 +1745,9 @@ BOOL LLAudioChannel::updateBuffer()
1612LLAudioData::LLAudioData(const LLUUID &uuid) : 1745LLAudioData::LLAudioData(const LLUUID &uuid) :
1613 mID(uuid), 1746 mID(uuid),
1614 mBufferp(NULL), 1747 mBufferp(NULL),
1615 mHasLocalData(FALSE), 1748 mHasLocalData(false),
1616 mHasDecodedData(FALSE), 1749 mHasDecodedData(false),
1617 mHasValidData(TRUE) 1750 mHasValidData(true)
1618{ 1751{
1619 if (uuid.isNull()) 1752 if (uuid.isNull())
1620 { 1753 {
@@ -1625,24 +1758,24 @@ LLAudioData::LLAudioData(const LLUUID &uuid) :
1625 if (gAudiop && gAudiop->hasDecodedFile(uuid)) 1758 if (gAudiop && gAudiop->hasDecodedFile(uuid))
1626 { 1759 {
1627 // Already have a decoded version, don't need to decode it. 1760 // Already have a decoded version, don't need to decode it.
1628 mHasLocalData = TRUE; 1761 mHasLocalData = true;
1629 mHasDecodedData = TRUE; 1762 mHasDecodedData = true;
1630 } 1763 }
1631 else if (gAssetStorage && gAssetStorage->hasLocalAsset(uuid, LLAssetType::AT_SOUND)) 1764 else if (gAssetStorage && gAssetStorage->hasLocalAsset(uuid, LLAssetType::AT_SOUND))
1632 { 1765 {
1633 mHasLocalData = TRUE; 1766 mHasLocalData = true;
1634 } 1767 }
1635} 1768}
1636 1769
1637 1770
1638BOOL LLAudioData::load() 1771bool LLAudioData::load()
1639{ 1772{
1640 // For now, just assume we're going to use one buffer per audiodata. 1773 // For now, just assume we're going to use one buffer per audiodata.
1641 if (mBufferp) 1774 if (mBufferp)
1642 { 1775 {
1643 // We already have this sound in a buffer, don't do anything. 1776 // We already have this sound in a buffer, don't do anything.
1644 llinfos << "Already have a buffer for this sound, don't bother loading!" << llendl; 1777 llinfos << "Already have a buffer for this sound, don't bother loading!" << llendl;
1645 return TRUE; 1778 return true;
1646 } 1779 }
1647 1780
1648 mBufferp = gAudiop->getFreeBuffer(); 1781 mBufferp = gAudiop->getFreeBuffer();
@@ -1650,7 +1783,7 @@ BOOL LLAudioData::load()
1650 { 1783 {
1651 // No free buffers, abort. 1784 // No free buffers, abort.
1652 llinfos << "Not able to allocate a new audio buffer, aborting." << llendl; 1785 llinfos << "Not able to allocate a new audio buffer, aborting." << llendl;
1653 return FALSE; 1786 return false;
1654 } 1787 }
1655 1788
1656 std::string uuid_str; 1789 std::string uuid_str;
@@ -1664,10 +1797,10 @@ BOOL LLAudioData::load()
1664 gAudiop->cleanupBuffer(mBufferp); 1797 gAudiop->cleanupBuffer(mBufferp);
1665 mBufferp = NULL; 1798 mBufferp = NULL;
1666 1799
1667 return FALSE; 1800 return false;
1668 } 1801 }
1669 mBufferp->mAudioDatap = this; 1802 mBufferp->mAudioDatap = this;
1670 return TRUE; 1803 return true;
1671} 1804}
1672 1805
1673 1806
diff --git a/linden/indra/llaudio/audioengine.h b/linden/indra/llaudio/audioengine.h
index e38413f..94134f5 100644
--- a/linden/indra/llaudio/audioengine.h
+++ b/linden/indra/llaudio/audioengine.h
@@ -45,6 +45,8 @@
45#include "llframetimer.h" 45#include "llframetimer.h"
46#include "llassettype.h" 46#include "llassettype.h"
47 47
48class LLMediaBase;
49
48const F32 LL_WIND_UPDATE_INTERVAL = 0.1f; 50const F32 LL_WIND_UPDATE_INTERVAL = 0.1f;
49const F32 LL_ROLLOFF_MULTIPLIER_UNDER_WATER = 5.f; // How much sounds are weaker under water 51const F32 LL_ROLLOFF_MULTIPLIER_UNDER_WATER = 5.f; // How much sounds are weaker under water
50const F32 LL_WIND_UNDERWATER_CENTER_FREQ = 20.f; 52const F32 LL_WIND_UNDERWATER_CENTER_FREQ = 20.f;
@@ -82,9 +84,7 @@ public:
82 virtual ~LLAudioEngine(); 84 virtual ~LLAudioEngine();
83 85
84 // initialization/startup/shutdown 86 // initialization/startup/shutdown
85 //virtual BOOL init(); 87 virtual bool init(const S32 num_channels, void *userdata);
86
87 virtual BOOL init(const S32 num_channels, void *userdata);
88 virtual void shutdown(); 88 virtual void shutdown();
89 89
90 // Used by the mechanics of the engine 90 // Used by the mechanics of the engine
@@ -97,14 +97,14 @@ public:
97 // 97 //
98 // "End user" functionality 98 // "End user" functionality
99 // 99 //
100 virtual BOOL isWindEnabled(); 100 virtual bool isWindEnabled();
101 virtual void enableWind(BOOL state_b); 101 virtual void enableWind(bool state_b);
102 102
103 // Use these for temporarily muting the audio system. 103 // Use these for temporarily muting the audio system.
104 // Does not change buffers, initialization, etc. but 104 // Does not change buffers, initialization, etc. but
105 // stops playing new sounds. 105 // stops playing new sounds.
106 virtual void setMuted(BOOL muted); 106 virtual void setMuted(bool muted);
107 virtual BOOL getMuted() const { return mMuted; } 107 virtual bool getMuted() const { return mMuted; }
108 108
109 F32 getMasterGain(); 109 F32 getMasterGain();
110 void setMasterGain(F32 gain); 110 void setMasterGain(F32 gain);
@@ -123,7 +123,7 @@ public:
123 // Methods actually related to setting up and removing sounds 123 // Methods actually related to setting up and removing sounds
124 // Owner ID is the owner of the object making the request 124 // Owner ID is the owner of the object making the request
125 void triggerSound(const LLUUID &sound_id, const LLUUID& owner_id, const F32 gain, const LLVector3d &pos_global = LLVector3d::zero); 125 void triggerSound(const LLUUID &sound_id, const LLUUID& owner_id, const F32 gain, const LLVector3d &pos_global = LLVector3d::zero);
126 BOOL preloadSound(const LLUUID &id); 126 bool preloadSound(const LLUUID &id);
127 127
128 void addAudioSource(LLAudioSource *asp); 128 void addAudioSource(LLAudioSource *asp);
129 void cleanupAudioSource(LLAudioSource *asp); 129 void cleanupAudioSource(LLAudioSource *asp);
@@ -132,14 +132,16 @@ public:
132 LLAudioData *getAudioData(const LLUUID &audio_uuid); 132 LLAudioData *getAudioData(const LLUUID &audio_uuid);
133 133
134 134
135 virtual void startInternetStream(const std::string& url) = 0; 135 // Internet stream methods
136 virtual void stopInternetStream() = 0; 136 virtual void startInternetStream(const std::string& url);
137 virtual void pauseInternetStream(int pause) = 0; 137 virtual void stopInternetStream();
138 virtual int isInternetStreamPlaying() = 0; 138 virtual void pauseInternetStream(int pause);
139 virtual void getInternetStreamInfo(char* artist, char* title) { artist[0] = 0; title[0] = 0; } 139 virtual void updateInternetStream();
140 virtual int isInternetStreamPlaying();
141 virtual void getInternetStreamInfo(char* artist, char* title);
140 // use a value from 0.0 to 1.0, inclusive 142 // use a value from 0.0 to 1.0, inclusive
141 virtual void setInternetStreamGain(F32 vol) { mInternetStreamGain = vol; } 143 virtual void setInternetStreamGain(F32 vol);
142 virtual const std::string& getInternetStreamURL() { return LLStringUtil::null; } 144 virtual const std::string& getInternetStreamURL();
143 145
144 // For debugging usage 146 // For debugging usage
145 virtual LLVector3 getListenerPos(); 147 virtual LLVector3 getListenerPos();
@@ -148,17 +150,16 @@ public:
148 LLAudioChannel *getFreeChannel(const F32 priority); // Get a free channel or flush an existing one if your priority is higher 150 LLAudioChannel *getFreeChannel(const F32 priority); // Get a free channel or flush an existing one if your priority is higher
149 void cleanupBuffer(LLAudioBuffer *bufferp); 151 void cleanupBuffer(LLAudioBuffer *bufferp);
150 152
151 BOOL hasDecodedFile(const LLUUID &uuid); 153 bool hasDecodedFile(const LLUUID &uuid);
152 BOOL hasLocalFile(const LLUUID &uuid); 154 bool hasLocalFile(const LLUUID &uuid);
153 155
154 BOOL updateBufferForData(LLAudioData *adp, const LLUUID &audio_uuid = LLUUID::null); 156 bool updateBufferForData(LLAudioData *adp, const LLUUID &audio_uuid = LLUUID::null);
155 157
156 158
157 // Asset callback when we're retrieved a sound from the asset server. 159 // Asset callback when we're retrieved a sound from the asset server.
158 void startNextTransfer(); 160 void startNextTransfer();
159 static void assetCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type, void *user_data, S32 result_code, LLExtStat ext_status); 161 static void assetCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type, void *user_data, S32 result_code, LLExtStat ext_status);
160 162
161
162 friend class LLPipeline; // For debugging 163 friend class LLPipeline; // For debugging
163public: 164public:
164 F32 mMaxWindGain; // Hack. Public to set before fade in? 165 F32 mMaxWindGain; // Hack. Public to set before fade in?
@@ -176,11 +177,6 @@ protected:
176 virtual void allocateListener() = 0; 177 virtual void allocateListener() = 0;
177 178
178 179
179 // Internet stream methods
180 virtual void initInternetStream() {}
181 virtual void updateInternetStream() {}
182
183
184 // listener methods 180 // listener methods
185 virtual void setListenerPos(LLVector3 vec); 181 virtual void setListenerPos(LLVector3 vec);
186 virtual void setListenerVelocity(LLVector3 vec); 182 virtual void setListenerVelocity(LLVector3 vec);
@@ -195,13 +191,13 @@ protected:
195protected: 191protected:
196 LLListener *mListenerp; 192 LLListener *mListenerp;
197 193
198 BOOL mMuted; 194 bool mMuted;
199 void* mUserData; 195 void* mUserData;
200 196
201 S32 mLastStatus; 197 S32 mLastStatus;
202 198
203 S32 mNumChannels; 199 S32 mNumChannels;
204 BOOL mEnableWind; 200 bool mEnableWind;
205 201
206 LLUUID mCurrentTransfer; // Audio file currently being transferred by the system 202 LLUUID mCurrentTransfer; // Audio file currently being transferred by the system
207 LLFrameTimer mCurrentTransferTimer; 203 LLFrameTimer mCurrentTransferTimer;
@@ -225,6 +221,7 @@ protected:
225 221
226 // Hack! Internet streams are treated differently from other sources! 222 // Hack! Internet streams are treated differently from other sources!
227 F32 mInternetStreamGain; 223 F32 mInternetStreamGain;
224 std::string mInternetStreamURL;
228 225
229 F32 mNextWindUpdate; 226 F32 mNextWindUpdate;
230 227
@@ -232,6 +229,7 @@ protected:
232 229
233private: 230private:
234 void setDefaults(); 231 void setDefaults();
232 LLMediaBase *mInternetStreamMedia;
235}; 233};
236 234
237 235
@@ -255,24 +253,24 @@ public:
255 253
256 void preload(const LLUUID &audio_id); // Only used for preloading UI sounds, now. 254 void preload(const LLUUID &audio_id); // Only used for preloading UI sounds, now.
257 255
258 void addAudioData(LLAudioData *adp, BOOL set_current = TRUE); 256 void addAudioData(LLAudioData *adp, bool set_current = TRUE);
259 257
260 void setAmbient(const BOOL ambient) { mAmbient = ambient; } 258 void setAmbient(const bool ambient) { mAmbient = ambient; }
261 BOOL isAmbient() const { return mAmbient; } 259 bool isAmbient() const { return mAmbient; }
262 260
263 void setLoop(const BOOL loop) { mLoop = loop; } 261 void setLoop(const bool loop) { mLoop = loop; }
264 BOOL isLoop() const { return mLoop; } 262 bool isLoop() const { return mLoop; }
265 263
266 void setSyncMaster(const BOOL master) { mSyncMaster = master; } 264 void setSyncMaster(const bool master) { mSyncMaster = master; }
267 BOOL isSyncMaster() const { return mSyncMaster; } 265 bool isSyncMaster() const { return mSyncMaster; }
268 266
269 void setSyncSlave(const BOOL slave) { mSyncSlave = slave; } 267 void setSyncSlave(const bool slave) { mSyncSlave = slave; }
270 BOOL isSyncSlave() const { return mSyncSlave; } 268 bool isSyncSlave() const { return mSyncSlave; }
271 269
272 void setQueueSounds(const BOOL queue) { mQueueSounds = queue; } 270 void setQueueSounds(const bool queue) { mQueueSounds = queue; }
273 BOOL isQueueSounds() const { return mQueueSounds; } 271 bool isQueueSounds() const { return mQueueSounds; }
274 272
275 void setPlayedOnce(const BOOL played_once) { mPlayedOnce = played_once; } 273 void setPlayedOnce(const bool played_once) { mPlayedOnce = played_once; }
276 274
277 void setPositionGlobal(const LLVector3d &position_global) { mPositionGlobal = position_global; } 275 void setPositionGlobal(const LLVector3d &position_global) { mPositionGlobal = position_global; }
278 LLVector3d getPositionGlobal() const { return mPositionGlobal; } 276 LLVector3d getPositionGlobal() const { return mPositionGlobal; }
@@ -284,16 +282,16 @@ public:
284 virtual void setGain(const F32 gain) { mGain = llclamp(gain, 0.f, 1.f); } 282 virtual void setGain(const F32 gain) { mGain = llclamp(gain, 0.f, 1.f); }
285 283
286 const LLUUID &getID() const { return mID; } 284 const LLUUID &getID() const { return mID; }
287 BOOL isDone(); 285 bool isDone();
288 286
289 LLAudioData *getCurrentData(); 287 LLAudioData *getCurrentData();
290 LLAudioData *getQueuedData(); 288 LLAudioData *getQueuedData();
291 LLAudioBuffer *getCurrentBuffer(); 289 LLAudioBuffer *getCurrentBuffer();
292 290
293 BOOL setupChannel(); 291 bool setupChannel();
294 BOOL play(const LLUUID &audio_id); // Start the audio source playing 292 bool play(const LLUUID &audio_id); // Start the audio source playing
295 293
296 BOOL hasPendingPreloads() const; // Has preloads that haven't been done yet 294 bool hasPendingPreloads() const; // Has preloads that haven't been done yet
297 295
298 friend class LLAudioEngine; 296 friend class LLAudioEngine;
299 friend class LLAudioChannel; 297 friend class LLAudioChannel;
@@ -306,12 +304,12 @@ protected:
306 LLUUID mOwnerID; // owner of the object playing the sound 304 LLUUID mOwnerID; // owner of the object playing the sound
307 F32 mPriority; 305 F32 mPriority;
308 F32 mGain; 306 F32 mGain;
309 BOOL mAmbient; 307 bool mAmbient;
310 BOOL mLoop; 308 bool mLoop;
311 BOOL mSyncMaster; 309 bool mSyncMaster;
312 BOOL mSyncSlave; 310 bool mSyncSlave;
313 BOOL mQueueSounds; 311 bool mQueueSounds;
314 BOOL mPlayedOnce; 312 bool mPlayedOnce;
315 LLVector3d mPositionGlobal; 313 LLVector3d mPositionGlobal;
316 LLVector3 mVelocity; 314 LLVector3 mVelocity;
317 315
@@ -340,27 +338,27 @@ class LLAudioData
340{ 338{
341public: 339public:
342 LLAudioData(const LLUUID &uuid); 340 LLAudioData(const LLUUID &uuid);
343 BOOL load(); 341 bool load();
344 342
345 LLUUID getID() const { return mID; } 343 LLUUID getID() const { return mID; }
346 LLAudioBuffer *getBuffer() const { return mBufferp; } 344 LLAudioBuffer *getBuffer() const { return mBufferp; }
347 345
348 BOOL hasLocalData() const { return mHasLocalData; } 346 bool hasLocalData() const { return mHasLocalData; }
349 BOOL hasDecodedData() const { return mHasDecodedData; } 347 bool hasDecodedData() const { return mHasDecodedData; }
350 BOOL hasValidData() const { return mHasValidData; } 348 bool hasValidData() const { return mHasValidData; }
351 349
352 void setHasLocalData(const BOOL hld) { mHasLocalData = hld; } 350 void setHasLocalData(const bool hld) { mHasLocalData = hld; }
353 void setHasDecodedData(const BOOL hdd) { mHasDecodedData = hdd; } 351 void setHasDecodedData(const bool hdd) { mHasDecodedData = hdd; }
354 void setHasValidData(const BOOL hvd) { mHasValidData = hvd; } 352 void setHasValidData(const bool hvd) { mHasValidData = hvd; }
355 353
356 friend class LLAudioEngine; // Severe laziness, bad. 354 friend class LLAudioEngine; // Severe laziness, bad.
357 355
358protected: 356protected:
359 LLUUID mID; 357 LLUUID mID;
360 LLAudioBuffer *mBufferp; // If this data is being used by the audio system, a pointer to the buffer will be set here. 358 LLAudioBuffer *mBufferp; // If this data is being used by the audio system, a pointer to the buffer will be set here.
361 BOOL mHasLocalData; 359 bool mHasLocalData;
362 BOOL mHasDecodedData; 360 bool mHasDecodedData;
363 BOOL mHasValidData; 361 bool mHasValidData;
364}; 362};
365 363
366 364
@@ -386,18 +384,18 @@ protected:
386 virtual void play() = 0; 384 virtual void play() = 0;
387 virtual void playSynced(LLAudioChannel *channelp) = 0; 385 virtual void playSynced(LLAudioChannel *channelp) = 0;
388 virtual void cleanup() = 0; 386 virtual void cleanup() = 0;
389 virtual BOOL isPlaying() = 0; 387 virtual bool isPlaying() = 0;
390 void setWaiting(const BOOL waiting) { mWaiting = waiting; } 388 void setWaiting(const bool waiting) { mWaiting = waiting; }
391 BOOL isWaiting() const { return mWaiting; } 389 bool isWaiting() const { return mWaiting; }
392 390
393 virtual BOOL updateBuffer(); // Check to see if the buffer associated with the source changed, and update if necessary. 391 virtual bool updateBuffer(); // Check to see if the buffer associated with the source changed, and update if necessary.
394 virtual void update3DPosition() = 0; 392 virtual void update3DPosition() = 0;
395 virtual void updateLoop() = 0; // Update your loop/completion status, for use by queueing/syncing. 393 virtual void updateLoop() = 0; // Update your loop/completion status, for use by queueing/syncing.
396protected: 394protected:
397 LLAudioSource *mCurrentSourcep; 395 LLAudioSource *mCurrentSourcep;
398 LLAudioBuffer *mCurrentBufferp; 396 LLAudioBuffer *mCurrentBufferp;
399 BOOL mLoopedThisFrame; 397 bool mLoopedThisFrame;
400 BOOL mWaiting; // Waiting for sync. 398 bool mWaiting; // Waiting for sync.
401}; 399};
402 400
403 401
@@ -412,14 +410,14 @@ class LLAudioBuffer
412{ 410{
413public: 411public:
414 virtual ~LLAudioBuffer() {}; 412 virtual ~LLAudioBuffer() {};
415 virtual BOOL loadWAV(const std::string& filename) = 0; 413 virtual bool loadWAV(const std::string& filename) = 0;
416 virtual U32 getLength() = 0; 414 virtual U32 getLength() = 0;
417 415
418 friend class LLAudioEngine; 416 friend class LLAudioEngine;
419 friend class LLAudioChannel; 417 friend class LLAudioChannel;
420 friend class LLAudioData; 418 friend class LLAudioData;
421protected: 419protected:
422 BOOL mInUse; 420 bool mInUse;
423 LLAudioData *mAudioDatap; 421 LLAudioData *mAudioDatap;
424 LLFrameTimer mLastUseTimer; 422 LLFrameTimer mLastUseTimer;
425}; 423};
diff --git a/linden/indra/llaudio/audioengine_fmod.cpp b/linden/indra/llaudio/audioengine_fmod.cpp
index 16d820c..354ef95 100644
--- a/linden/indra/llaudio/audioengine_fmod.cpp
+++ b/linden/indra/llaudio/audioengine_fmod.cpp
@@ -1,7 +1,6 @@
1/** 1/**
2 * @file audioengine_fmod.cpp 2 * @file audioengine_fmod.cpp
3 * @brief Implementation of LLAudioEngine class abstracting the audio 3 * @brief Implementation of LLAudioEngine class abstracting the audio support as a FMOD 3D implementation
4 * support as a FMOD 3D implementation
5 * 4 *
6 * $LicenseInfo:firstyear=2002&license=viewergpl$ 5 * $LicenseInfo:firstyear=2002&license=viewergpl$
7 * 6 *
@@ -46,27 +45,12 @@
46 45
47#include "sound_ids.h" 46#include "sound_ids.h"
48 47
48extern "C" {
49 void * F_CALLBACKAPI windCallback(void *originalbuffer, void *newbuffer, int length, void* userdata);
50}
49 51
50void * F_CALLBACKAPI windCallback(void *originalbuffer, void *newbuffer, int length, void* userdata);
51FSOUND_DSPUNIT *gWindDSP = NULL; 52FSOUND_DSPUNIT *gWindDSP = NULL;
52 53
53// These globals for the wind filter. Blech!
54F64 gbuf0 = 0.0;
55F64 gbuf1 = 0.0;
56F64 gbuf2 = 0.0;
57F64 gbuf3 = 0.0;
58F64 gbuf4 = 0.0;
59F64 gbuf5 = 0.0;
60F64 gY0 = 0.0;
61F64 gY1 = 0.0;
62
63F32 gTargetGain = 0.f;
64F32 gCurrentGain = 0.f;
65F32 gTargetFreq = 100.f;
66F32 gCurrentFreq = 100.f;
67F32 gTargetPanGainR = 0.5f;
68F32 gCurrentPanGainR = 0.5f;
69
70 54
71// Safe strcpy 55// Safe strcpy
72#if 0 //(unused) //LL_WINDOWS || LL_LINUX 56#if 0 //(unused) //LL_WINDOWS || LL_LINUX
@@ -94,9 +78,10 @@ static size_t strlcpy( char* dest, const char* src, size_t dst_size )
94 78
95LLAudioEngine_FMOD::LLAudioEngine_FMOD() 79LLAudioEngine_FMOD::LLAudioEngine_FMOD()
96{ 80{
97 mInited = FALSE; 81 mInited = false;
98 mCurrentInternetStreamp = NULL; 82 mCurrentInternetStreamp = NULL;
99 mInternetStreamChannel = -1; 83 mInternetStreamChannel = -1;
84 mWindGen = NULL;
100} 85}
101 86
102 87
@@ -105,7 +90,7 @@ LLAudioEngine_FMOD::~LLAudioEngine_FMOD()
105} 90}
106 91
107 92
108BOOL LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata) 93bool LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata)
109{ 94{
110 mFadeIn = -10000; 95 mFadeIn = -10000;
111 96
@@ -124,7 +109,7 @@ BOOL LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata)
124 { 109 {
125 LL_WARNS("AppInit") << "Error : You are using the wrong FMOD version (" << version 110 LL_WARNS("AppInit") << "Error : You are using the wrong FMOD version (" << version
126 << ")! You should be using FMOD " << FMOD_VERSION << LL_ENDL; 111 << ")! You should be using FMOD " << FMOD_VERSION << LL_ENDL;
127 //return FALSE; 112 //return false;
128 } 113 }
129 114
130 U32 fmod_flags = 0x0; 115 U32 fmod_flags = 0x0;
@@ -139,7 +124,7 @@ BOOL LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata)
139 { 124 {
140 LL_WARNS("AppInit") << "Error setting FMOD window: " 125 LL_WARNS("AppInit") << "Error setting FMOD window: "
141 << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL; 126 << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL;
142 return FALSE; 127 return false;
143 } 128 }
144 // Play audio when we don't have focus. 129 // Play audio when we don't have focus.
145 // (For example, IM client on top of us.) 130 // (For example, IM client on top of us.)
@@ -167,7 +152,7 @@ BOOL LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata)
167 // on top of ALSA is ironically more reliable than raw ALSA. 152 // on top of ALSA is ironically more reliable than raw ALSA.
168 // Ack, and ESD has more reliable failure modes - but has worse 153 // Ack, and ESD has more reliable failure modes - but has worse
169 // latency - than all of them, so wins for now. 154 // latency - than all of them, so wins for now.
170 BOOL audio_ok = FALSE; 155 bool audio_ok = false;
171 156
172 if (!audio_ok) 157 if (!audio_ok)
173 if (NULL == getenv("LL_BAD_ESD")) /*Flawfinder: ignore*/ 158 if (NULL == getenv("LL_BAD_ESD")) /*Flawfinder: ignore*/
@@ -178,7 +163,7 @@ BOOL LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata)
178 { 163 {
179 LL_DEBUGS("AppInit") << "ESD audio output initialized OKAY" 164 LL_DEBUGS("AppInit") << "ESD audio output initialized OKAY"
180 << LL_ENDL; 165 << LL_ENDL;
181 audio_ok = TRUE; 166 audio_ok = true;
182 } else { 167 } else {
183 LL_WARNS("AppInit") << "ESD audio output FAILED to initialize: " 168 LL_WARNS("AppInit") << "ESD audio output FAILED to initialize: "
184 << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL; 169 << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL;
@@ -195,7 +180,7 @@ BOOL LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata)
195 FSOUND_Init(44100, num_channels, fmod_flags)) 180 FSOUND_Init(44100, num_channels, fmod_flags))
196 { 181 {
197 LL_DEBUGS("AppInit") << "OSS audio output initialized OKAY" << LL_ENDL; 182 LL_DEBUGS("AppInit") << "OSS audio output initialized OKAY" << LL_ENDL;
198 audio_ok = TRUE; 183 audio_ok = true;
199 } else { 184 } else {
200 LL_WARNS("AppInit") << "OSS audio output FAILED to initialize: " 185 LL_WARNS("AppInit") << "OSS audio output FAILED to initialize: "
201 << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL; 186 << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL;
@@ -212,7 +197,7 @@ BOOL LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata)
212 FSOUND_Init(44100, num_channels, fmod_flags)) 197 FSOUND_Init(44100, num_channels, fmod_flags))
213 { 198 {
214 LL_DEBUGS("AppInit") << "ALSA audio output initialized OKAY" << LL_ENDL; 199 LL_DEBUGS("AppInit") << "ALSA audio output initialized OKAY" << LL_ENDL;
215 audio_ok = TRUE; 200 audio_ok = true;
216 } else { 201 } else {
217 LL_WARNS("AppInit") << "ALSA audio output FAILED to initialize: " 202 LL_WARNS("AppInit") << "ALSA audio output FAILED to initialize: "
218 << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL; 203 << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL;
@@ -224,7 +209,7 @@ BOOL LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata)
224 if (!audio_ok) 209 if (!audio_ok)
225 { 210 {
226 LL_WARNS("AppInit") << "Overall audio init failure." << LL_ENDL; 211 LL_WARNS("AppInit") << "Overall audio init failure." << LL_ENDL;
227 return FALSE; 212 return false;
228 } 213 }
229 214
230 // On Linux, FMOD causes a SIGPIPE for some netstream error 215 // On Linux, FMOD causes a SIGPIPE for some netstream error
@@ -250,7 +235,7 @@ BOOL LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata)
250 { 235 {
251 LL_WARNS("AppInit") << "Error initializing FMOD: " 236 LL_WARNS("AppInit") << "Error initializing FMOD: "
252 << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL; 237 << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL;
253 return FALSE; 238 return false;
254 } 239 }
255 240
256#endif 241#endif
@@ -259,17 +244,9 @@ BOOL LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata)
259 244
260 LL_DEBUGS("AppInit") << "LLAudioEngine_FMOD::init() FMOD initialized correctly" << LL_ENDL; 245 LL_DEBUGS("AppInit") << "LLAudioEngine_FMOD::init() FMOD initialized correctly" << LL_ENDL;
261 246
262 mInited = TRUE; 247 mInited = true;
263 248
264 return TRUE; 249 return true;
265}
266
267
268void LLAudioEngine_FMOD::idle(F32 max_decode_time)
269{
270 LLAudioEngine::idle(max_decode_time);
271
272 updateInternetStream();
273} 250}
274 251
275 252
@@ -287,7 +264,7 @@ void LLAudioEngine_FMOD::shutdown()
287{ 264{
288 if (gWindDSP) 265 if (gWindDSP)
289 { 266 {
290 FSOUND_DSP_SetActive(gWindDSP,FALSE); 267 FSOUND_DSP_SetActive(gWindDSP,false);
291 FSOUND_DSP_Free(gWindDSP); 268 FSOUND_DSP_Free(gWindDSP);
292 } 269 }
293 270
@@ -318,13 +295,15 @@ LLAudioChannel *LLAudioEngine_FMOD::createChannel()
318 295
319void LLAudioEngine_FMOD::initWind() 296void LLAudioEngine_FMOD::initWind()
320{ 297{
298 mWindGen = new LLWindGen<MIXBUFFERFORMAT>;
299
321 if (!gWindDSP) 300 if (!gWindDSP)
322 { 301 {
323 gWindDSP = FSOUND_DSP_Create(&windCallback, FSOUND_DSP_DEFAULTPRIORITY_CLEARUNIT + 20, NULL); 302 gWindDSP = FSOUND_DSP_Create(&windCallback, FSOUND_DSP_DEFAULTPRIORITY_CLEARUNIT + 20, mWindGen);
324 } 303 }
325 if (gWindDSP) 304 if (gWindDSP)
326 { 305 {
327 FSOUND_DSP_SetActive(gWindDSP, TRUE); 306 FSOUND_DSP_SetActive(gWindDSP, true);
328 } 307 }
329 mNextWindUpdate = 0.0; 308 mNextWindUpdate = 0.0;
330} 309}
@@ -334,10 +313,13 @@ void LLAudioEngine_FMOD::cleanupWind()
334{ 313{
335 if (gWindDSP) 314 if (gWindDSP)
336 { 315 {
337 FSOUND_DSP_SetActive(gWindDSP, FALSE); 316 FSOUND_DSP_SetActive(gWindDSP, false);
338 FSOUND_DSP_Free(gWindDSP); 317 FSOUND_DSP_Free(gWindDSP);
339 gWindDSP = NULL; 318 gWindDSP = NULL;
340 } 319 }
320
321 delete mWindGen;
322 mWindGen = NULL;
341} 323}
342 324
343 325
@@ -367,9 +349,9 @@ void LLAudioEngine_FMOD::updateWind(LLVector3 wind_vec, F32 camera_height_above_
367 pitch = 1.0 + mapWindVecToPitch(wind_vec); 349 pitch = 1.0 + mapWindVecToPitch(wind_vec);
368 center_freq = 80.0 * pow(pitch,2.5*(mapWindVecToGain(wind_vec)+1.0)); 350 center_freq = 80.0 * pow(pitch,2.5*(mapWindVecToGain(wind_vec)+1.0));
369 351
370 gTargetFreq = (F32)center_freq; 352 mWindGen->mTargetFreq = (F32)center_freq;
371 gTargetGain = (F32)mapWindVecToGain(wind_vec) * mMaxWindGain; 353 mWindGen->mTargetGain = (F32)mapWindVecToGain(wind_vec) * mMaxWindGain;
372 gTargetPanGainR = (F32)mapWindVecToPan(wind_vec); 354 mWindGen->mTargetPanGainR = (F32)mapWindVecToPan(wind_vec);
373 } 355 }
374} 356}
375 357
@@ -457,11 +439,11 @@ LLAudioChannelFMOD::~LLAudioChannelFMOD()
457} 439}
458 440
459 441
460BOOL LLAudioChannelFMOD::updateBuffer() 442bool LLAudioChannelFMOD::updateBuffer()
461{ 443{
462 if (LLAudioChannel::updateBuffer()) 444 if (LLAudioChannel::updateBuffer())
463 { 445 {
464 // Base class update returned TRUE, which means that we need to actually 446 // Base class update returned true, which means that we need to actually
465 // set up the channel for a different buffer. 447 // set up the channel for a different buffer.
466 448
467 LLAudioBufferFMOD *bufferp = (LLAudioBufferFMOD *)mCurrentSourcep->getCurrentBuffer(); 449 LLAudioBufferFMOD *bufferp = (LLAudioBufferFMOD *)mCurrentSourcep->getCurrentBuffer();
@@ -473,13 +455,13 @@ BOOL LLAudioChannelFMOD::updateBuffer()
473 // This is bad, there should ALWAYS be a sample associated with a legit 455 // This is bad, there should ALWAYS be a sample associated with a legit
474 // buffer. 456 // buffer.
475 llerrs << "No FMOD sample!" << llendl; 457 llerrs << "No FMOD sample!" << llendl;
476 return FALSE; 458 return false;
477 } 459 }
478 460
479 461
480 // Actually play the sound. Start it off paused so we can do all the necessary 462 // Actually play the sound. Start it off paused so we can do all the necessary
481 // setup. 463 // setup.
482 mChannelID = FSOUND_PlaySoundEx(FSOUND_FREE, samplep, FSOUND_DSP_GetSFXUnit(), TRUE); 464 mChannelID = FSOUND_PlaySoundEx(FSOUND_FREE, samplep, FSOUND_DSP_GetSFXUnit(), true);
483 465
484 //llinfos << "Setting up channel " << std::hex << mChannelID << std::dec << llendl; 466 //llinfos << "Setting up channel " << std::hex << mChannelID << std::dec << llendl;
485 } 467 }
@@ -501,7 +483,7 @@ BOOL LLAudioChannelFMOD::updateBuffer()
501 } 483 }
502 } 484 }
503 485
504 return TRUE; 486 return true;
505} 487}
506 488
507 489
@@ -524,12 +506,12 @@ void LLAudioChannelFMOD::update3DPosition()
524 if (mCurrentSourcep->isAmbient()) 506 if (mCurrentSourcep->isAmbient())
525 { 507 {
526 // Ambient sound, don't need to do any positional updates. 508 // Ambient sound, don't need to do any positional updates.
527 bufferp->set3DMode(FALSE); 509 bufferp->set3DMode(false);
528 } 510 }
529 else 511 else
530 { 512 {
531 // Localized sound. Update the position and velocity of the sound. 513 // Localized sound. Update the position and velocity of the sound.
532 bufferp->set3DMode(TRUE); 514 bufferp->set3DMode(true);
533 515
534 LLVector3 float_pos; 516 LLVector3 float_pos;
535 float_pos.setVec(mCurrentSourcep->getPositionGlobal()); 517 float_pos.setVec(mCurrentSourcep->getPositionGlobal());
@@ -556,7 +538,7 @@ void LLAudioChannelFMOD::updateLoop()
556 U32 cur_pos = FSOUND_GetCurrentPosition(mChannelID); 538 U32 cur_pos = FSOUND_GetCurrentPosition(mChannelID);
557 if (cur_pos < (U32)mLastSamplePos) 539 if (cur_pos < (U32)mLastSamplePos)
558 { 540 {
559 mLoopedThisFrame = TRUE; 541 mLoopedThisFrame = true;
560 } 542 }
561 mLastSamplePos = cur_pos; 543 mLastSamplePos = cur_pos;
562} 544}
@@ -589,11 +571,11 @@ void LLAudioChannelFMOD::play()
589 return; 571 return;
590 } 572 }
591 573
592 if (!FSOUND_SetPaused(mChannelID, FALSE)) 574 if (!FSOUND_SetPaused(mChannelID, false))
593 { 575 {
594 llwarns << "LLAudioChannelFMOD::play error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl; 576 llwarns << "LLAudioChannelFMOD::play error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl;
595 } 577 }
596 getSource()->setPlayedOnce(TRUE); 578 getSource()->setPlayedOnce(true);
597} 579}
598 580
599 581
@@ -618,11 +600,11 @@ void LLAudioChannelFMOD::playSynced(LLAudioChannel *channelp)
618} 600}
619 601
620 602
621BOOL LLAudioChannelFMOD::isPlaying() 603bool LLAudioChannelFMOD::isPlaying()
622{ 604{
623 if (!mChannelID) 605 if (!mChannelID)
624 { 606 {
625 return FALSE; 607 return false;
626 } 608 }
627 609
628 return FSOUND_IsPlaying(mChannelID) && (!FSOUND_GetPaused(mChannelID)); 610 return FSOUND_IsPlaying(mChannelID) && (!FSOUND_GetPaused(mChannelID));
@@ -652,14 +634,14 @@ LLAudioBufferFMOD::~LLAudioBufferFMOD()
652} 634}
653 635
654 636
655BOOL LLAudioBufferFMOD::loadWAV(const std::string& filename) 637bool LLAudioBufferFMOD::loadWAV(const std::string& filename)
656{ 638{
657 // Try to open a wav file from disk. This will eventually go away, as we don't 639 // Try to open a wav file from disk. This will eventually go away, as we don't
658 // really want to block doing this. 640 // really want to block doing this.
659 if (filename.empty()) 641 if (filename.empty())
660 { 642 {
661 // invalid filename, abort. 643 // invalid filename, abort.
662 return FALSE; 644 return false;
663 } 645 }
664 646
665 S32 file_size = 0; 647 S32 file_size = 0;
@@ -667,7 +649,7 @@ BOOL LLAudioBufferFMOD::loadWAV(const std::string& filename)
667 if (!apr_file) 649 if (!apr_file)
668 { 650 {
669 // File not found, abort. 651 // File not found, abort.
670 return FALSE; 652 return false;
671 } 653 }
672 apr_file_close(apr_file); 654 apr_file_close(apr_file);
673 655
@@ -717,11 +699,11 @@ BOOL LLAudioBufferFMOD::loadWAV(const std::string& filename)
717 // 699 //
718 // file is probably corrupt - remove it. 700 // file is probably corrupt - remove it.
719 LLFile::remove(filename); 701 LLFile::remove(filename);
720 return FALSE; 702 return false;
721 } 703 }
722 704
723 // Everything went well, return TRUE 705 // Everything went well, return true
724 return TRUE; 706 return true;
725} 707}
726 708
727 709
@@ -736,7 +718,7 @@ U32 LLAudioBufferFMOD::getLength()
736} 718}
737 719
738 720
739void LLAudioBufferFMOD::set3DMode(BOOL use3d) 721void LLAudioBufferFMOD::set3DMode(bool use3d)
740{ 722{
741 U16 current_mode = FSOUND_Sample_GetMode(mSamplep); 723 U16 current_mode = FSOUND_Sample_GetMode(mSamplep);
742 724
@@ -765,7 +747,7 @@ void LLAudioEngine_FMOD::initInternetStream()
765{ 747{
766 // Number of milliseconds of audio to buffer for the audio card. 748 // Number of milliseconds of audio to buffer for the audio card.
767 // Must be larger than the usual Second Life frame stutter time. 749 // Must be larger than the usual Second Life frame stutter time.
768 FSOUND_Stream_SetBufferSize(200); 750 FSOUND_Stream_SetBufferSize(200);
769 751
770 // Here's where we set the size of the network buffer and some buffering 752 // Here's where we set the size of the network buffer and some buffering
771 // parameters. In this case we want a network buffer of 16k, we want it 753 // parameters. In this case we want a network buffer of 16k, we want it
@@ -810,19 +792,19 @@ signed char F_CALLBACKAPI LLAudioEngine_FMOD::callbackMetaData(char *name, char
810 if (!strcmp("ARTIST", name)) 792 if (!strcmp("ARTIST", name))
811 { 793 {
812 strlcpy(self->mInternetStreamArtist, value, 256); 794 strlcpy(self->mInternetStreamArtist, value, 256);
813 self->mInternetStreamNewMetaData = TRUE; 795 self->mInternetStreamNewMetaData = true;
814 return TRUE; 796 return true;
815 } 797 }
816 798
817 if (!strcmp("TITLE", name)) 799 if (!strcmp("TITLE", name))
818 { 800 {
819 strlcpy(self->mInternetStreamTitle, value, 256); 801 strlcpy(self->mInternetStreamTitle, value, 256);
820 self->mInternetStreamNewMetaData = TRUE; 802 self->mInternetStreamNewMetaData = true;
821 return TRUE; 803 return true;
822 } 804 }
823 */ 805 */
824 806
825 return TRUE; 807 return true;
826} 808}
827 809
828 810
@@ -867,7 +849,7 @@ void LLAudioEngine_FMOD::updateInternetStream()
867 { 849 {
868 // Reset volume to previously set volume 850 // Reset volume to previously set volume
869 setInternetStreamGain(mInternetStreamGain); 851 setInternetStreamGain(mInternetStreamGain);
870 FSOUND_SetPaused(mInternetStreamChannel, FALSE); 852 FSOUND_SetPaused(mInternetStreamChannel, false);
871 //FSOUND_Stream_Net_SetMetadataCallback(mInternetStream, callbackMetaData, this); 853 //FSOUND_Stream_Net_SetMetadataCallback(mInternetStream, callbackMetaData, this);
872 } 854 }
873 } 855 }
@@ -909,7 +891,7 @@ void LLAudioEngine_FMOD::stopInternetStream()
909{ 891{
910 if (mInternetStreamChannel != -1) 892 if (mInternetStreamChannel != -1)
911 { 893 {
912 FSOUND_SetPaused(mInternetStreamChannel, TRUE); 894 FSOUND_SetPaused(mInternetStreamChannel, true);
913 FSOUND_SetPriority(mInternetStreamChannel, 0); 895 FSOUND_SetPriority(mInternetStreamChannel, 0);
914 mInternetStreamChannel = -1; 896 mInternetStreamChannel = -1;
915 } 897 }
@@ -971,16 +953,10 @@ int LLAudioEngine_FMOD::isInternetStreamPlaying()
971} 953}
972 954
973 955
974void LLAudioEngine_FMOD::getInternetStreamInfo(char* artist_out, char* title_out)
975{
976 //strlcpy(artist_out, mInternetStreamArtist, 256);
977 //strlcpy(title_out, mInternetStreamTitle, 256);
978}
979
980
981void LLAudioEngine_FMOD::setInternetStreamGain(F32 vol) 956void LLAudioEngine_FMOD::setInternetStreamGain(F32 vol)
982{ 957{
983 LLAudioEngine::setInternetStreamGain(vol); 958 mInternetStreamGain = vol;
959
984 if (mInternetStreamChannel != -1) 960 if (mInternetStreamChannel != -1)
985 { 961 {
986 vol = llclamp(vol, 0.f, 1.f); 962 vol = llclamp(vol, 0.f, 1.f);
@@ -990,15 +966,9 @@ void LLAudioEngine_FMOD::setInternetStreamGain(F32 vol)
990} 966}
991 967
992 968
993const std::string& LLAudioEngine_FMOD::getInternetStreamURL()
994{
995 return mInternetStreamURL;
996}
997
998
999LLAudioStreamFMOD::LLAudioStreamFMOD(const std::string& url) : 969LLAudioStreamFMOD::LLAudioStreamFMOD(const std::string& url) :
1000 mInternetStream(NULL), 970 mInternetStream(NULL),
1001 mReady(FALSE) 971 mReady(false)
1002{ 972{
1003 mInternetStreamURL = url; 973 mInternetStreamURL = url;
1004 mInternetStream = FSOUND_Stream_Open(url.c_str(), FSOUND_NORMAL | FSOUND_NONBLOCKING, 0, 0); 974 mInternetStream = FSOUND_Stream_Open(url.c_str(), FSOUND_NORMAL | FSOUND_NONBLOCKING, 0, 0);
@@ -1007,11 +977,11 @@ LLAudioStreamFMOD::LLAudioStreamFMOD(const std::string& url) :
1007 llwarns << "Couldn't open fmod stream, error " 977 llwarns << "Couldn't open fmod stream, error "
1008 << FMOD_ErrorString(FSOUND_GetError()) 978 << FMOD_ErrorString(FSOUND_GetError())
1009 << llendl; 979 << llendl;
1010 mReady = FALSE; 980 mReady = false;
1011 return; 981 return;
1012 } 982 }
1013 983
1014 mReady = TRUE; 984 mReady = true;
1015} 985}
1016 986
1017int LLAudioStreamFMOD::startStream() 987int LLAudioStreamFMOD::startStream()
@@ -1026,10 +996,10 @@ int LLAudioStreamFMOD::startStream()
1026 // Make sure the stream is set to 2D mode. 996 // Make sure the stream is set to 2D mode.
1027 FSOUND_Stream_SetMode(mInternetStream, FSOUND_2D); 997 FSOUND_Stream_SetMode(mInternetStream, FSOUND_2D);
1028 998
1029 return FSOUND_Stream_PlayEx(FSOUND_FREE, mInternetStream, NULL, TRUE); 999 return FSOUND_Stream_PlayEx(FSOUND_FREE, mInternetStream, NULL, true);
1030} 1000}
1031 1001
1032BOOL LLAudioStreamFMOD::stopStream() 1002bool LLAudioStreamFMOD::stopStream()
1033{ 1003{
1034 if (mInternetStream) 1004 if (mInternetStream)
1035 { 1005 {
@@ -1039,34 +1009,34 @@ BOOL LLAudioStreamFMOD::stopStream()
1039 unsigned int flags = 0x0; 1009 unsigned int flags = 0x0;
1040 FSOUND_Stream_Net_GetStatus(mInternetStream, &status, &read_percent, &bitrate, &flags); 1010 FSOUND_Stream_Net_GetStatus(mInternetStream, &status, &read_percent, &bitrate, &flags);
1041 1011
1042 BOOL close = TRUE; 1012 bool close = true;
1043 switch (status) 1013 switch (status)
1044 { 1014 {
1045 case FSOUND_STREAM_NET_CONNECTING: 1015 case FSOUND_STREAM_NET_CONNECTING:
1046 close = FALSE; 1016 close = false;
1047 break; 1017 break;
1048 case FSOUND_STREAM_NET_NOTCONNECTED: 1018 case FSOUND_STREAM_NET_NOTCONNECTED:
1049 case FSOUND_STREAM_NET_BUFFERING: 1019 case FSOUND_STREAM_NET_BUFFERING:
1050 case FSOUND_STREAM_NET_READY: 1020 case FSOUND_STREAM_NET_READY:
1051 case FSOUND_STREAM_NET_ERROR: 1021 case FSOUND_STREAM_NET_ERROR:
1052 default: 1022 default:
1053 close = TRUE; 1023 close = true;
1054 } 1024 }
1055 1025
1056 if (close) 1026 if (close)
1057 { 1027 {
1058 FSOUND_Stream_Close(mInternetStream); 1028 FSOUND_Stream_Close(mInternetStream);
1059 mInternetStream = NULL; 1029 mInternetStream = NULL;
1060 return TRUE; 1030 return true;
1061 } 1031 }
1062 else 1032 else
1063 { 1033 {
1064 return FALSE; 1034 return false;
1065 } 1035 }
1066 } 1036 }
1067 else 1037 else
1068 { 1038 {
1069 return TRUE; 1039 return true;
1070 } 1040 }
1071} 1041}
1072 1042
@@ -1076,94 +1046,35 @@ int LLAudioStreamFMOD::getOpenState()
1076 return open_state; 1046 return open_state;
1077} 1047}
1078 1048
1079/* This determines the format of the mixbuffer being passed in. change if you want to support int32 or float32 */ 1049void * F_CALLBACKAPI windCallback(void *originalbuffer, void *newbuffer, int length, void* userdata)
1080#if LL_DARWIN
1081 #define MIXBUFFERFORMAT S32
1082#else
1083 #define MIXBUFFERFORMAT S16
1084#endif
1085
1086inline MIXBUFFERFORMAT clipSample(MIXBUFFERFORMAT sample, MIXBUFFERFORMAT min, MIXBUFFERFORMAT max)
1087{
1088 if (sample > max)
1089 sample = max;
1090 else if (sample < min)
1091 sample = min;
1092
1093 return sample;
1094}
1095
1096void * F_CALLBACKAPI windCallback(void *originalbuffer, void *newbuffer, int length, void*)
1097{ 1050{
1098// originalbuffer = fsounds original mixbuffer. 1051 // originalbuffer = fmod's original mixbuffer.
1099// newbuffer = the buffer passed from the previous DSP unit. 1052 // newbuffer = the buffer passed from the previous DSP unit.
1100// length = length in samples at this mix time. 1053 // length = length in samples at this mix time.
1101// param = user parameter passed through in FSOUND_DSP_Create. 1054 // param = user parameter passed through in FSOUND_DSP_Create.
1102// 1055 //
1103// modify the buffer in some fashion 1056 // modify the buffer in some fashion
1104 1057
1105 U8 *cursamplep = (U8*)newbuffer; 1058 LLWindGen<LLAudioEngine_FMOD::MIXBUFFERFORMAT> *windgen =
1106 U8 wordsize = 2; 1059 (LLWindGen<LLAudioEngine_FMOD::MIXBUFFERFORMAT> *)userdata;
1060 U8 stride;
1107 1061
1108#if LL_DARWIN 1062#if LL_DARWIN
1109 wordsize = sizeof(MIXBUFFERFORMAT); 1063 stride = sizeof(LLAudioEngine_FMOD::MIXBUFFERFORMAT);
1110#else 1064#else
1111 int mixertype = FSOUND_GetMixer(); 1065 int mixertype = FSOUND_GetMixer();
1112 if (mixertype == FSOUND_MIXER_BLENDMODE || mixertype == FSOUND_MIXER_QUALITY_FPU) 1066 if (mixertype == FSOUND_MIXER_BLENDMODE ||
1113 { 1067 mixertype == FSOUND_MIXER_QUALITY_FPU)
1114 wordsize = 4; 1068 {
1115 } 1069 stride = 4;
1116#endif 1070 }
1117 1071 else
1118 double bandwidth = 50; 1072 {
1119 double inputSamplingRate = 44100; 1073 stride = 2;
1120 double a0,b1,b2; 1074 }
1121
1122 // calculate resonant filter coeffs
1123 b2 = exp(-(F_TWO_PI) * (bandwidth / inputSamplingRate));
1124
1125 while (length--)
1126 {
1127 gCurrentFreq = (float)((0.999 * gCurrentFreq) + (0.001 * gTargetFreq));
1128 gCurrentGain = (float)((0.999 * gCurrentGain) + (0.001 * gTargetGain));
1129 gCurrentPanGainR = (float)((0.999 * gCurrentPanGainR) + (0.001 * gTargetPanGainR));
1130 b1 = (-4.0 * b2) / (1.0 + b2) * cos(F_TWO_PI * (gCurrentFreq / inputSamplingRate));
1131 a0 = (1.0 - b2) * sqrt(1.0 - (b1 * b1) / (4.0 * b2));
1132 double nextSample;
1133
1134 // start with white noise
1135 nextSample = ll_frand(2.0f) - 1.0f;
1136
1137#if 1 // LLAE_WIND_PINK apply pinking filter
1138 gbuf0 = 0.997f * gbuf0 + 0.0126502f * nextSample;
1139 gbuf1 = 0.985f * gbuf1 + 0.0139083f * nextSample;
1140 gbuf2 = 0.950f * gbuf2 + 0.0205439f * nextSample;
1141 gbuf3 = 0.850f * gbuf3 + 0.0387225f * nextSample;
1142 gbuf4 = 0.620f * gbuf4 + 0.0465932f * nextSample;
1143 gbuf5 = 0.250f * gbuf5 + 0.1093477f * nextSample;
1144
1145 nextSample = gbuf0 + gbuf1 + gbuf2 + gbuf3 + gbuf4 + gbuf5;
1146#endif
1147
1148#if 1 //LLAE_WIND_RESONANT // do a resonant filter on the noise
1149 nextSample = (double)( a0 * nextSample - b1 * gY0 - b2 * gY1 );
1150
1151 gY1 = gY0;
1152 gY0 = nextSample;
1153#endif 1075#endif
1154 1076
1155 nextSample *= gCurrentGain; 1077 newbuffer = windgen->windGenerate((LLAudioEngine_FMOD::MIXBUFFERFORMAT *)newbuffer, length, stride);
1156
1157 MIXBUFFERFORMAT sample;
1158
1159 sample = llfloor(((F32)nextSample*32768.f*(1.0f - gCurrentPanGainR))+0.5f);
1160 *(MIXBUFFERFORMAT*)cursamplep = clipSample((*(MIXBUFFERFORMAT*)cursamplep) + sample, -32768, 32767);
1161 cursamplep += wordsize;
1162
1163 sample = llfloor(((F32)nextSample*32768.f*gCurrentPanGainR)+0.5f);
1164 *(MIXBUFFERFORMAT*)cursamplep = clipSample((*(MIXBUFFERFORMAT*)cursamplep) + sample, -32768, 32767);
1165 cursamplep += wordsize;
1166 }
1167 1078
1168 return newbuffer; 1079 return newbuffer;
1169} 1080}
diff --git a/linden/indra/llaudio/audioengine_fmod.h b/linden/indra/llaudio/audioengine_fmod.h
index 41177b6..132afb1 100644
--- a/linden/indra/llaudio/audioengine_fmod.h
+++ b/linden/indra/llaudio/audioengine_fmod.h
@@ -35,6 +35,7 @@
35 35
36#include "audioengine.h" 36#include "audioengine.h"
37#include "listener_fmod.h" 37#include "listener_fmod.h"
38#include "windgen.h"
38 39
39#include "fmod.h" 40#include "fmod.h"
40 41
@@ -47,13 +48,11 @@ public:
47 virtual ~LLAudioEngine_FMOD(); 48 virtual ~LLAudioEngine_FMOD();
48 49
49 // initialization/startup/shutdown 50 // initialization/startup/shutdown
50 virtual BOOL init(const S32 num_channels, void *user_data); 51 virtual bool init(const S32 num_channels, void *user_data);
51 virtual void allocateListener(); 52 virtual void allocateListener();
52 53
53 virtual void shutdown(); 54 virtual void shutdown();
54 55
55 virtual void idle(F32 max_decode_time = 0.f);
56
57 // Internet stream methods 56 // Internet stream methods
58 virtual void initInternetStream(); 57 virtual void initInternetStream();
59 virtual void startInternetStream(const std::string& url); 58 virtual void startInternetStream(const std::string& url);
@@ -61,15 +60,19 @@ public:
61 virtual void stopInternetStream(); 60 virtual void stopInternetStream();
62 virtual void pauseInternetStream(int pause); 61 virtual void pauseInternetStream(int pause);
63 virtual int isInternetStreamPlaying(); 62 virtual int isInternetStreamPlaying();
64 virtual void getInternetStreamInfo(char* artist, char* title);
65 virtual void setInternetStreamGain(F32 vol); 63 virtual void setInternetStreamGain(F32 vol);
66 virtual const std::string& getInternetStreamURL();
67 64
68 /*virtual*/ void initWind(); 65 /*virtual*/ void initWind();
69 /*virtual*/ void cleanupWind(); 66 /*virtual*/ void cleanupWind();
70 67
71 /*virtual*/void updateWind(LLVector3 direction, F32 camera_height_above_water); 68 /*virtual*/void updateWind(LLVector3 direction, F32 camera_height_above_water);
72 69
70#if LL_DARWIN
71 typedef S32 MIXBUFFERFORMAT;
72#else
73 typedef S16 MIXBUFFERFORMAT;
74#endif
75
73protected: 76protected:
74 /*virtual*/ LLAudioBuffer *createBuffer(); // Get a free buffer, or flush an existing one if you have to. 77 /*virtual*/ LLAudioBuffer *createBuffer(); // Get a free buffer, or flush an existing one if you have to.
75 /*virtual*/ LLAudioChannel *createChannel(); // Create a new audio channel. 78 /*virtual*/ LLAudioChannel *createChannel(); // Create a new audio channel.
@@ -79,7 +82,6 @@ protected:
79 static signed char F_CALLBACKAPI callbackMetaData(char* name, char* value, void* userdata); 82 static signed char F_CALLBACKAPI callbackMetaData(char* name, char* value, void* userdata);
80 83
81 LLAudioStreamFMOD *mCurrentInternetStreamp; 84 LLAudioStreamFMOD *mCurrentInternetStreamp;
82 std::string mInternetStreamURL;
83 int mInternetStreamChannel; 85 int mInternetStreamChannel;
84 86
85 std::list<LLAudioStreamFMOD *> mDeadStreams; 87 std::list<LLAudioStreamFMOD *> mDeadStreams;
@@ -88,11 +90,12 @@ protected:
88 //F32 mMaxDistance[MAX_BUFFERS]; 90 //F32 mMaxDistance[MAX_BUFFERS];
89 91
90 S32 mFadeIn; 92 S32 mFadeIn;
91 BOOL mInited; 93 bool mInited;
92 94
93 // On Windows, userdata is the HWND of the application window. 95 // On Windows, userdata is the HWND of the application window.
94 void* mUserData; 96 void* mUserData;
95 97
98 LLWindGen<MIXBUFFERFORMAT> *mWindGen;
96}; 99};
97 100
98 101
@@ -106,9 +109,9 @@ protected:
106 /*virtual*/ void play(); 109 /*virtual*/ void play();
107 /*virtual*/ void playSynced(LLAudioChannel *channelp); 110 /*virtual*/ void playSynced(LLAudioChannel *channelp);
108 /*virtual*/ void cleanup(); 111 /*virtual*/ void cleanup();
109 /*virtual*/ BOOL isPlaying(); 112 /*virtual*/ bool isPlaying();
110 113
111 /*virtual*/ BOOL updateBuffer(); 114 /*virtual*/ bool updateBuffer();
112 /*virtual*/ void update3DPosition(); 115 /*virtual*/ void update3DPosition();
113 /*virtual*/ void updateLoop(); 116 /*virtual*/ void updateLoop();
114 117
@@ -124,11 +127,11 @@ public:
124 LLAudioBufferFMOD(); 127 LLAudioBufferFMOD();
125 virtual ~LLAudioBufferFMOD(); 128 virtual ~LLAudioBufferFMOD();
126 129
127 /*virtual*/ BOOL loadWAV(const std::string& filename); 130 /*virtual*/ bool loadWAV(const std::string& filename);
128 /*virtual*/ U32 getLength(); 131 /*virtual*/ U32 getLength();
129 friend class LLAudioChannelFMOD; 132 friend class LLAudioChannelFMOD;
130 133
131 void set3DMode(BOOL use3d); 134 void set3DMode(bool use3d);
132protected: 135protected:
133 FSOUND_SAMPLE *getSample() { return mSamplep; } 136 FSOUND_SAMPLE *getSample() { return mSamplep; }
134protected: 137protected:
@@ -140,15 +143,15 @@ class LLAudioStreamFMOD
140public: 143public:
141 LLAudioStreamFMOD(const std::string& url); 144 LLAudioStreamFMOD(const std::string& url);
142 int startStream(); 145 int startStream();
143 BOOL stopStream(); // Returns true if the stream was successfully stopped. 146 bool stopStream(); // Returns true if the stream was successfully stopped.
144 BOOL ready(); 147 bool ready();
145 148
146 const std::string& getURL() { return mInternetStreamURL; } 149 const std::string& getURL() { return mInternetStreamURL; }
147 150
148 int getOpenState(); 151 int getOpenState();
149protected: 152protected:
150 FSOUND_STREAM* mInternetStream; 153 FSOUND_STREAM* mInternetStream;
151 BOOL mReady; 154 bool mReady;
152 155
153 std::string mInternetStreamURL; 156 std::string mInternetStreamURL;
154}; 157};
diff --git a/linden/indra/llaudio/audioengine_openal.cpp b/linden/indra/llaudio/audioengine_openal.cpp
new file mode 100644
index 0000000..606d9f6
--- /dev/null
+++ b/linden/indra/llaudio/audioengine_openal.cpp
@@ -0,0 +1,422 @@
1/**
2 * @file audioengine_openal.cpp
3 * @brief implementation of audio engine using OpenAL
4 * support as a OpenAL 3D implementation
5 *
6 * $LicenseInfo:firstyear=2002&license=viewergpl$
7 *
8 * Copyright (c) 2002-2008, Linden Research, Inc.
9 *
10 * Second Life Viewer Source Code
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
13 * ("GPL"), unless you have obtained a separate licensing agreement
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
16 * online at http://secondlife.com/developers/opensource/gplv2
17 *
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
20 * in the file doc/FLOSS-exception.txt in this software distribution, or
21 * online at http://secondlife.com/developers/opensource/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#include "linden_common.h"
34#include "lldir.h"
35
36#include "audioengine_openal.h"
37#include "listener_openal.h"
38
39
40// Variables and definitions for Wind
41#define MAX_NUM_WIND_BUFFERS 40
42static int empty_num_wind_buffers = MAX_NUM_WIND_BUFFERS;
43static const float wind_buffer_size_sec = 0.05f; // 1/20th sec
44static const U32 wind_gen_freq = LLWindGen<S16>::getInputSamplingRate();
45static ALuint wind_source;
46static S16 *winddata=NULL;
47
48
49LLAudioEngine_OpenAL::LLAudioEngine_OpenAL()
50{
51 mWindGen = NULL;
52}
53
54LLAudioEngine_OpenAL::~LLAudioEngine_OpenAL()
55{
56}
57
58bool LLAudioEngine_OpenAL::init(const S32 num_channels, void* userdata)
59{
60 mWindGen = NULL;
61 LLAudioEngine::init(num_channels, userdata);
62
63 if(!alutInit(NULL, NULL))
64 {
65 llwarns << "LLAudioEngine_OpenAL::init() ALUT initialization failed: " << alutGetErrorString (alutGetError ()) << llendl;
66 return false;
67 }
68
69 llinfos << "LLAudioEngine_OpenAL::init() OpenAL successfully initialized" << llendl;
70
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;
81
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 llinfos << "LLAudioEngine_OpenAL::init() Speed of sound is: " << alGetFloat(AL_SPEED_OF_SOUND) << llendl;
94
95 return true;
96}
97
98void LLAudioEngine_OpenAL::allocateListener()
99{
100 mListenerp = (LLListener *) new LLListener_OpenAL();
101 if(!mListenerp)
102 {
103 llwarns << "LLAudioEngine_OpenAL::allocateListener() Listener creation failed" << llendl;
104 }
105}
106
107void LLAudioEngine_OpenAL::shutdown()
108{
109 llinfos << "About to LLAudioEngine::shutdown()" << llendl;
110 LLAudioEngine::shutdown();
111
112 llinfos << "About to alutExit()" << llendl;
113 if(!alutExit())
114 {
115 llwarns << "Nuts." << llendl;
116 llwarns << "LLAudioEngine_OpenAL::shutdown() ALUT shutdown failed: " << alutGetErrorString (alutGetError ()) << llendl;
117 }
118
119 llinfos << "LLAudioEngine_OpenAL::shutdown() OpenAL successfully shut down" << llendl;
120
121 delete mListenerp;
122 mListenerp = NULL;
123}
124
125LLAudioBuffer *LLAudioEngine_OpenAL::createBuffer()
126{
127 return new LLAudioBufferOpenAL();
128}
129
130LLAudioChannel *LLAudioEngine_OpenAL::createChannel()
131{
132 return new LLAudioChannelOpenAL();
133}
134
135void LLAudioEngine_OpenAL::setInternalGain(F32 gain)
136{
137 //llinfos << "LLAudioEngine_OpenAL::setInternalGain() Gain: " << gain << llendl;
138 alListenerf(AL_GAIN, gain);
139}
140
141LLAudioChannelOpenAL::LLAudioChannelOpenAL()
142{
143 alGenSources(1, &mALSource);
144}
145
146LLAudioChannelOpenAL::~LLAudioChannelOpenAL()
147{
148 cleanup();
149 alDeleteSources(1, &mALSource);
150}
151
152void LLAudioChannelOpenAL::cleanup()
153{
154 alSourceStop(mALSource);
155 mCurrentBufferp = NULL;
156}
157
158void LLAudioChannelOpenAL::play()
159{
160 if(!isPlaying()){
161 alSourcePlay(mALSource);
162 getSource()->setPlayedOnce(true);
163 }
164}
165
166void LLAudioChannelOpenAL::playSynced(LLAudioChannel *channelp)
167{
168 play();
169}
170
171bool LLAudioChannelOpenAL::isPlaying()
172{
173 ALint state;
174 alGetSourcei(mALSource, AL_SOURCE_STATE, &state);
175 if(state == AL_PLAYING){
176 return true;
177 }
178 return false;
179}
180
181bool LLAudioChannelOpenAL::updateBuffer()
182{
183 if (LLAudioChannel::updateBuffer())
184 {
185 // Base class update returned true, which means that we need to actually
186 // set up the source for a different buffer.
187 LLAudioBufferOpenAL *bufferp = (LLAudioBufferOpenAL *)mCurrentSourcep->getCurrentBuffer();
188 alSourcei(mALSource, AL_BUFFER, bufferp->getBuffer());
189 alSourcef(mALSource, AL_GAIN, mCurrentSourcep->getGain());
190 alSourcei(mALSource, AL_LOOPING, mCurrentSourcep->isLoop() ? AL_TRUE : AL_FALSE);
191 }
192
193 return true;
194}
195
196void LLAudioChannelOpenAL::update3DPosition()
197{
198 if(!mCurrentSourcep)
199 {
200 return;
201 }
202 if (mCurrentSourcep->isAmbient())
203 {
204 alSource3f(mALSource, AL_POSITION, 0.0, 0.0, 0.0);
205 alSource3f(mALSource, AL_VELOCITY, 0.0, 0.0, 0.0);
206 //alSource3f(mALSource, AL_DIRECTION, 0.0, 0.0, 0.0);
207 alSourcef (mALSource, AL_ROLLOFF_FACTOR, 0.0);
208 alSourcei (mALSource, AL_SOURCE_RELATIVE, AL_TRUE);
209 } else {
210 LLVector3 float_pos;
211 float_pos.setVec(mCurrentSourcep->getPositionGlobal());
212 alSourcefv(mALSource, AL_POSITION, float_pos.mV);
213 //llinfos << "LLAudioChannelOpenAL::update3DPosition() Velocity: " << mCurrentSourcep->getVelocity() << llendl;
214 alSourcefv(mALSource, AL_VELOCITY, mCurrentSourcep->getVelocity().mV);
215 //alSource3f(mALSource, AL_DIRECTION, 0.0, 0.0, 0.0);
216 alSourcef (mALSource, AL_ROLLOFF_FACTOR, 1.0);
217 alSourcei (mALSource, AL_SOURCE_RELATIVE, AL_FALSE);
218 }
219 //llinfos << "LLAudioChannelOpenAL::update3DPosition() Gain: " << mCurrentSourcep->getGain() << llendl;
220 alSourcef(mALSource, AL_GAIN, mCurrentSourcep->getGain());
221}
222
223LLAudioBufferOpenAL::LLAudioBufferOpenAL()
224{
225 mALBuffer = AL_NONE;
226}
227
228LLAudioBufferOpenAL::~LLAudioBufferOpenAL()
229{
230 cleanup();
231}
232
233void LLAudioBufferOpenAL::cleanup()
234{
235 if(mALBuffer != AL_NONE)
236 {
237 alDeleteBuffers(1, &mALBuffer);
238 mALBuffer = AL_NONE;
239 }
240}
241
242bool LLAudioBufferOpenAL::loadWAV(const std::string& filename)
243{
244 cleanup();
245 mALBuffer = alutCreateBufferFromFile(filename.c_str());
246 if(mALBuffer == AL_NONE){
247 ALenum error = alutGetError();
248 if (gDirUtilp->fileExists(filename)) {
249 llwarns <<
250 "LLAudioBufferOpenAL::loadWAV() Error loading "
251 << filename
252 << " " << alutGetErrorString(error) << llendl;
253 } else {
254 // It's common for the file to not actually exist.
255 lldebugs <<
256 "LLAudioBufferOpenAL::loadWAV() Error loading "
257 << filename
258 << " " << alutGetErrorString(error) << llendl;
259 }
260 return false;
261 }
262
263 return true;
264}
265
266U32 LLAudioBufferOpenAL::getLength(){
267 if(mALBuffer == AL_NONE){
268 return 0;
269 }
270 ALint length;
271 alGetBufferi(mALBuffer, AL_SIZE, &length);
272 return length >> 2;
273}
274
275// ------------
276
277void LLAudioEngine_OpenAL::initWind(){
278 ALenum error;
279 llinfos << "LLAudioEngine_OpenAL::initWind() start" << llendl;
280
281 alGetError(); /* clear error */
282
283 alGenSources(1,&wind_source);
284
285 if((error=alGetError()) != AL_NO_ERROR)
286 {
287 llwarns << "LLAudioEngine_OpenAL::initWind() Error creating wind sources: "<<error<<llendl;
288 }
289
290 winddata=(S16*)malloc(sizeof(S16)*llceil(wind_gen_freq*wind_buffer_size_sec*2*2)); //200ms @wind_gen_freqHz Stereo
291
292 if(winddata==NULL)
293 {
294 llerrs << "LLAudioEngine_OpenAL::initWind() Error creating wind memory buffer" << llendl;
295 mEnableWind=false;
296 }
297
298 mWindGen = new LLWindGen<S16>;
299
300 llinfos << "LLAudioEngine_OpenAL::initWind() done" << llendl;
301}
302
303void LLAudioEngine_OpenAL::cleanupWind(){
304 llinfos << "LLAudioEngine_OpenAL::cleanupWind()" << llendl;
305
306 alDeleteSources(1, &wind_source);
307
308 if(winddata)
309 free(winddata);
310
311 delete mWindGen;
312 mWindGen = NULL;
313}
314
315void LLAudioEngine_OpenAL::updateWind(LLVector3 wind_vec, F32 camera_altitude)
316{
317 LLVector3 wind_pos;
318 F64 pitch;
319 F64 center_freq;
320 ALenum error;
321
322 mMaxWindGain=1.0;
323
324 if (!mEnableWind)
325 return;
326
327 if(!winddata)
328 return;
329
330 if (mWindUpdateTimer.checkExpirationAndReset(LL_WIND_UPDATE_INTERVAL))
331 {
332
333 // wind comes in as Linden coordinate (+X = forward, +Y = left, +Z = up)
334 // need to convert this to the conventional orientation DS3D and OpenAL use
335 // where +X = right, +Y = up, +Z = backwards
336
337 wind_vec.setVec(-wind_vec.mV[1], wind_vec.mV[2], -wind_vec.mV[0]);
338
339 pitch = 1.0 + mapWindVecToPitch(wind_vec);
340 center_freq = 80.0 * pow(pitch,2.5*(mapWindVecToGain(wind_vec)+1.0));
341
342 mWindGen->mTargetFreq = (F32)center_freq;
343 mWindGen->mTargetGain = (F32)mapWindVecToGain(wind_vec) * mMaxWindGain;
344 mWindGen->mTargetPanGainR = (F32)mapWindVecToPan(wind_vec);
345
346 alSourcei(wind_source, AL_LOOPING, AL_FALSE);
347 alSource3f(wind_source, AL_POSITION, 0.0, 0.0, 0.0);
348 alSource3f(wind_source, AL_VELOCITY, 0.0, 0.0, 0.0);
349 alSourcef(wind_source, AL_ROLLOFF_FACTOR, 0.0);
350 alSourcei(wind_source, AL_SOURCE_RELATIVE, AL_TRUE);
351 }
352
353 // ok lets make a wind buffer now
354
355 int processed, queued, unprocessed;
356 alGetSourcei(wind_source, AL_BUFFERS_PROCESSED, &processed);
357 alGetSourcei(wind_source, AL_BUFFERS_QUEUED, &queued);
358 unprocessed = queued - processed;
359
360 // ensure that there are always at least 3x as many filled buffers
361 // queued as we managed to empty since last time.
362 empty_num_wind_buffers = llmin(empty_num_wind_buffers + processed * 3 - unprocessed, MAX_NUM_WIND_BUFFERS-unprocessed);
363 empty_num_wind_buffers = llmax(empty_num_wind_buffers, 0);
364
365 //llinfos << "empty_num_wind_buffers: " << empty_num_wind_buffers <<" (" << unprocessed << ":" << processed << ")" << llendl;
366
367 while(processed--) // unqueue old buffers
368 {
369 ALuint buffer;
370 int error;
371 alGetError(); /* clear error */
372 alSourceUnqueueBuffers(wind_source, 1, &buffer);
373 error = alGetError();
374 if(error != AL_NO_ERROR)
375 {
376 llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping (unqueuing) buffers" << llendl;
377 }
378 else
379 {
380 alDeleteBuffers(1, &buffer);
381 }
382 }
383
384 while (empty_num_wind_buffers > 0) // fill+queue new buffers
385 {
386 ALuint buffer;
387 alGetError(); /* clear error */
388 alGenBuffers(1,&buffer);
389 if((error=alGetError()) != AL_NO_ERROR)
390 {
391 llwarns << "LLAudioEngine_OpenAL::initWind() Error creating wind buffer: " << error << llendl;
392 break;
393 }
394
395 alBufferData(buffer,
396 AL_FORMAT_STEREO16,
397 mWindGen->windGenerate(winddata,
398 int(wind_gen_freq*wind_buffer_size_sec), 2),
399 int(2*wind_gen_freq*wind_buffer_size_sec*sizeof(S16)),
400 wind_gen_freq);
401 error = alGetError();
402 if(error != AL_NO_ERROR)
403 llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping (bufferdata) buffers" << llendl;
404
405 alSourceQueueBuffers(wind_source, 1, &buffer);
406 error = alGetError();
407 if(error != AL_NO_ERROR)
408 llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping (queuing) buffers" << llendl;
409
410 --empty_num_wind_buffers;
411 }
412
413 int playing;
414 alGetSourcei(wind_source, AL_SOURCE_STATE, &playing);
415 if(playing != AL_PLAYING)
416 {
417 alSourcePlay(wind_source);
418
419 llinfos << "Wind had stopped - probably ran out of buffers - restarting: " << (unprocessed+empty_num_wind_buffers) << " now queued." << llendl;
420 }
421}
422
diff --git a/linden/indra/llaudio/audioengine_openal.h b/linden/indra/llaudio/audioengine_openal.h
new file mode 100644
index 0000000..6289f99
--- /dev/null
+++ b/linden/indra/llaudio/audioengine_openal.h
@@ -0,0 +1,100 @@
1/**
2 * @file audioengine_openal.cpp
3 * @brief implementation of audio engine using OpenAL
4 * support as a OpenAL 3D implementation
5 *
6 * Copyright (c) 2002-2008, Linden Research, Inc.
7 *
8 * $LicenseInfo:firstyear=2002&license=viewergpl$
9 *
10 * Second Life Viewer Source Code
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
13 * ("GPL"), unless you have obtained a separate licensing agreement
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
16 * online at http://secondlife.com/developers/opensource/gplv2
17 *
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
20 * in the file doc/FLOSS-exception.txt in this software distribution, or
21 * online at http://secondlife.com/developers/opensource/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_OpenAL_H
35#define LL_AUDIOENGINE_OpenAL_H
36
37#include "audioengine.h"
38#include "listener_openal.h"
39#include "windgen.h"
40
41class LLAudioEngine_OpenAL : public LLAudioEngine
42{
43 public:
44 LLAudioEngine_OpenAL();
45 virtual ~LLAudioEngine_OpenAL();
46
47 virtual bool init(const S32 num_channels, void *user_data);
48 virtual void allocateListener();
49
50 virtual void shutdown();
51
52 void setInternalGain(F32 gain);
53
54 LLAudioBuffer* createBuffer();
55 LLAudioChannel* createChannel();
56
57 /*virtual*/ void initWind();
58 /*virtual*/ void cleanupWind();
59 /*virtual*/ void updateWind(LLVector3 direction, F32 camera_altitude);
60
61 private:
62 void * windDSP(void *newbuffer, int length);
63 LLWindGen<S16> *mWindGen;
64};
65
66class LLAudioChannelOpenAL : public LLAudioChannel
67{
68 public:
69 LLAudioChannelOpenAL();
70 virtual ~LLAudioChannelOpenAL();
71 protected:
72 void play();
73 void playSynced(LLAudioChannel *channelp);
74 void cleanup();
75 bool isPlaying();
76
77 bool updateBuffer();
78 void update3DPosition();
79 void updateLoop(){};
80
81 ALuint mALSource;
82};
83
84class LLAudioBufferOpenAL : public LLAudioBuffer{
85 public:
86 LLAudioBufferOpenAL();
87 virtual ~LLAudioBufferOpenAL();
88
89 bool loadWAV(const std::string& filename);
90 U32 getLength();
91
92 friend class LLAudioChannelOpenAL;
93 protected:
94 void cleanup();
95 ALuint getBuffer() {return mALBuffer;}
96
97 ALuint mALBuffer;
98};
99
100#endif
diff --git a/linden/indra/llaudio/listener_fmod.h b/linden/indra/llaudio/listener_fmod.h
index 7b7c4c6..95b31ac 100644
--- a/linden/indra/llaudio/listener_fmod.h
+++ b/linden/indra/llaudio/listener_fmod.h
@@ -37,11 +37,6 @@
37 37
38class LLListener_FMOD : public LLListener 38class LLListener_FMOD : public LLListener
39{ 39{
40 protected:
41 F32 mDopplerFactor;
42 F32 mDistanceFactor;
43 F32 mRolloffFactor;
44
45 public: 40 public:
46 LLListener_FMOD(); 41 LLListener_FMOD();
47 virtual ~LLListener_FMOD(); 42 virtual ~LLListener_FMOD();
@@ -59,6 +54,11 @@ class LLListener_FMOD : public LLListener
59 virtual F32 getDistanceFactor(); 54 virtual F32 getDistanceFactor();
60 virtual void setRolloffFactor(F32 factor); 55 virtual void setRolloffFactor(F32 factor);
61 virtual F32 getRolloffFactor(); 56 virtual F32 getRolloffFactor();
57
58 protected:
59 F32 mDopplerFactor;
60 F32 mDistanceFactor;
61 F32 mRolloffFactor;
62}; 62};
63 63
64#endif 64#endif
diff --git a/linden/indra/llaudio/listener_openal.cpp b/linden/indra/llaudio/listener_openal.cpp
new file mode 100644
index 0000000..e72b078
--- /dev/null
+++ b/linden/indra/llaudio/listener_openal.cpp
@@ -0,0 +1,94 @@
1/**
2 * @file audioengine_openal.cpp
3 * @brief implementation of audio engine using OpenAL
4 * support as a OpenAL 3D implementation
5 *
6 * $LicenseInfo:firstyear=2002&license=viewergpl$
7 *
8 * Copyright (c) 2002-2007, Linden Research, Inc.
9 *
10 * Second Life Viewer Source Code
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
13 * ("GPL"), unless you have obtained a separate licensing agreement
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
16 * online at http://secondlife.com/developers/opensource/gplv2
17 *
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
20 * in the file doc/FLOSS-exception.txt in this software distribution, or
21 * online at http://secondlife.com/developers/opensource/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#include "linden_common.h"
34#include "audioengine.h"
35
36#include "listener_openal.h"
37
38LLListener_OpenAL::LLListener_OpenAL(){
39 init();
40}
41
42LLListener_OpenAL::~LLListener_OpenAL(){
43}
44
45void LLListener_OpenAL::translate(LLVector3 offset){
46 LLListener::translate(offset);
47 llinfos << "LLListener_OpenAL::translate() : " << offset << llendl;
48}
49
50void LLListener_OpenAL::setPosition(LLVector3 pos){
51 LLListener::setPosition(pos);
52 //llinfos << "LLListener_OpenAL::setPosition() : " << pos << llendl;
53}
54
55void LLListener_OpenAL::setVelocity(LLVector3 vel){
56 LLListener::setVelocity(vel);
57}
58
59void LLListener_OpenAL::orient(LLVector3 up, LLVector3 at){
60 LLListener::orient(up, at);
61 //llinfos << "LLListener_OpenAL::orient() up: " << up << " at: " << at << llendl;
62}
63
64void LLListener_OpenAL::commitDeferredChanges(){
65 ALfloat orientation[6];
66 orientation[0] = mListenAt.mV[0];
67 orientation[1] = mListenAt.mV[1];
68 orientation[2] = mListenAt.mV[2];
69 orientation[3] = mListenUp.mV[0];
70 orientation[4] = mListenUp.mV[1];
71 orientation[5] = mListenUp.mV[2];
72
73 ALfloat velocity[3];
74 velocity[0] = mVelocity.mV[0];
75 velocity[1] = mVelocity.mV[1];
76 velocity[2] = mVelocity.mV[2];
77
78 alListenerfv(AL_ORIENTATION, orientation);
79 alListenerfv(AL_POSITION, mPosition.mV);
80 alListenerfv(AL_VELOCITY, velocity);
81}
82
83void LLListener_OpenAL::setDopplerFactor(F32 factor){
84 //llinfos << "LLListener_OpenAL::setDopplerFactor() : " << factor << llendl;
85 alDopplerFactor(factor);
86}
87
88F32 LLListener_OpenAL::getDopplerFactor(){
89 ALfloat factor;
90 factor = alGetFloat(AL_DOPPLER_FACTOR);
91 //llinfos << "LLListener_OpenAL::getDopplerFactor() : " << factor << llendl;
92 return factor;
93}
94
diff --git a/linden/indra/llaudio/listener_openal.h b/linden/indra/llaudio/listener_openal.h
index cc4bb9e..737343e 100644
--- a/linden/indra/llaudio/listener_openal.h
+++ b/linden/indra/llaudio/listener_openal.h
@@ -40,12 +40,6 @@
40 40
41class LLListener_OpenAL : public LLListener 41class LLListener_OpenAL : public LLListener
42{ 42{
43 private:
44 protected:
45 public:
46
47 private:
48 protected:
49 public: 43 public:
50 LLListener_OpenAL(); 44 LLListener_OpenAL();
51 virtual ~LLListener_OpenAL(); 45 virtual ~LLListener_OpenAL();
@@ -54,6 +48,12 @@ class LLListener_OpenAL : public LLListener
54 virtual void setPosition(LLVector3 pos); 48 virtual void setPosition(LLVector3 pos);
55 virtual void setVelocity(LLVector3 vel); 49 virtual void setVelocity(LLVector3 vel);
56 virtual void orient(LLVector3 up, LLVector3 at); 50 virtual void orient(LLVector3 up, LLVector3 at);
51 virtual void commitDeferredChanges();
52
53 virtual void setDopplerFactor(F32 factor);
54 virtual F32 getDopplerFactor();
55
56 protected:
57}; 57};
58 58
59#endif 59#endif
diff --git a/linden/indra/llaudio/windgen.h b/linden/indra/llaudio/windgen.h
new file mode 100644
index 0000000..39ce568
--- /dev/null
+++ b/linden/indra/llaudio/windgen.h
@@ -0,0 +1,138 @@
1/**
2 * @file windgen.h
3 * @brief Templated wind noise generation
4 *
5 * $LicenseInfo:firstyear=2002&license=viewergpl$
6 *
7 * Copyright (c) 2002-2008, 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://secondlife.com/developers/opensource/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 http://secondlife.com/developers/opensource/flossexception
21 *
22 * By copying, modifying or distributing this software, you acknowledge
23 * that you have read and understood your obligations described above,
24 * and agree to abide by those obligations.
25 *
26 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
27 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
28 * COMPLETENESS OR PERFORMANCE.
29 * $/LicenseInfo$
30 */
31#ifndef WINDGEN_H
32#define WINDGEN_H
33
34#include "llcommon.h"
35#include "llrand.h"
36
37template <class MIXBUFFERFORMAT_T>
38class LLWindGen
39{
40public:
41 LLWindGen() :
42 mTargetGain(0.f),
43 mTargetFreq(100.f),
44 mTargetPanGainR(0.5f),
45 mbuf0(0.0),
46 mbuf1(0.0),
47 mbuf2(0.0),
48 mbuf3(0.0),
49 mbuf4(0.0),
50 mbuf5(0.0),
51 mY0(0.0),
52 mY1(0.0),
53 mCurrentGain(0.f),
54 mCurrentFreq(100.f),
55 mCurrentPanGainR(0.5f) {};
56
57 static const U32 getInputSamplingRate() {return mInputSamplingRate;}
58
59 // newbuffer = the buffer passed from the previous DSP unit.
60 // numsamples = length in samples-per-channel at this mix time.
61 // stride = number of bytes between start of each sample.
62 // NOTE: generates L/R interleaved stereo
63 MIXBUFFERFORMAT_T* windGenerate(MIXBUFFERFORMAT_T *newbuffer, int numsamples, int stride)
64 {
65 U8 *cursamplep = (U8*)newbuffer;
66
67 double bandwidth = 50.0F;
68 double a0,b1,b2;
69
70 // calculate resonant filter coeffs
71 b2 = exp(-(F_TWO_PI) * (bandwidth / mInputSamplingRate));
72
73 while (numsamples--)
74 {
75 mCurrentFreq = (float)((0.999 * mCurrentFreq) + (0.001 * mTargetFreq));
76 mCurrentGain = (float)((0.999 * mCurrentGain) + (0.001 * mTargetGain));
77 mCurrentPanGainR = (float)((0.999 * mCurrentPanGainR) + (0.001 * mTargetPanGainR));
78 b1 = (-4.0 * b2) / (1.0 + b2) * cos(F_TWO_PI * (mCurrentFreq / mInputSamplingRate));
79 a0 = (1.0 - b2) * sqrt(1.0 - (b1 * b1) / (4.0 * b2));
80 double nextSample;
81
82 // start with white noise
83 nextSample = ll_frand(2.0f) - 1.0f;
84
85#if 1 // LLAE_WIND_PINK apply pinking filter
86 mbuf0 = 0.997f * mbuf0 + 0.0126502f * nextSample;
87 mbuf1 = 0.985f * mbuf1 + 0.0139083f * nextSample;
88 mbuf2 = 0.950f * mbuf2 + 0.0205439f * nextSample;
89 mbuf3 = 0.850f * mbuf3 + 0.0387225f * nextSample;
90 mbuf4 = 0.620f * mbuf4 + 0.0465932f * nextSample;
91 mbuf5 = 0.250f * mbuf5 + 0.1093477f * nextSample;
92
93 nextSample = mbuf0 + mbuf1 + mbuf2 + mbuf3 + mbuf4 + mbuf5;
94#endif
95
96#if 1 //LLAE_WIND_RESONANT // do a resonant filter on the noise
97 nextSample = (double)( a0 * nextSample - b1 * mY0 - b2 * mY1 );
98
99 mY1 = mY0;
100 mY0 = nextSample;
101#endif
102
103 nextSample *= mCurrentGain;
104
105 MIXBUFFERFORMAT_T sample;
106
107 sample = llfloor(((F32)nextSample*32768.f*(1.0f - mCurrentPanGainR))+0.5f);
108 *(MIXBUFFERFORMAT_T*)cursamplep = llclamp(sample, (MIXBUFFERFORMAT_T)-32768, (MIXBUFFERFORMAT_T)32767);
109 cursamplep += stride;
110
111 sample = llfloor(((F32)nextSample*32768.f*mCurrentPanGainR)+0.5f);
112 *(MIXBUFFERFORMAT_T*)cursamplep = llclamp(sample, (MIXBUFFERFORMAT_T)-32768, (MIXBUFFERFORMAT_T)32767);
113 cursamplep += stride;
114 }
115
116 return newbuffer;
117 }
118
119 F32 mTargetGain;
120 F32 mTargetFreq;
121 F32 mTargetPanGainR;
122
123private:
124 static const U32 mInputSamplingRate = 44100;
125 F64 mbuf0;
126 F64 mbuf1;
127 F64 mbuf2;
128 F64 mbuf3;
129 F64 mbuf4;
130 F64 mbuf5;
131 F64 mY0;
132 F64 mY1;
133 F32 mCurrentGain;
134 F32 mCurrentFreq;
135 F32 mCurrentPanGainR;
136};
137
138#endif
diff --git a/linden/indra/newview/CMakeLists.txt b/linden/indra/newview/CMakeLists.txt
index ddf6897..4bfbf02 100644
--- a/linden/indra/newview/CMakeLists.txt
+++ b/linden/indra/newview/CMakeLists.txt
@@ -8,6 +8,7 @@ include(BuildVersion)
8include(DirectX) 8include(DirectX)
9include(ELFIO) 9include(ELFIO)
10include(FMOD) 10include(FMOD)
11include(OPENAL)
11include(FindOpenGL) 12include(FindOpenGL)
12include(LLAudio) 13include(LLAudio)
13include(LLCharacter) 14include(LLCharacter)
@@ -56,6 +57,7 @@ include_directories(
56 ${LLXML_INCLUDE_DIRS} 57 ${LLXML_INCLUDE_DIRS}
57 ${LSCRIPT_INCLUDE_DIRS} 58 ${LSCRIPT_INCLUDE_DIRS}
58 ${LSCRIPT_INCLUDE_DIRS}/lscript_compile 59 ${LSCRIPT_INCLUDE_DIRS}/lscript_compile
60 ${GSTREAMER_INCLUDE_DIRS}
59 ) 61 )
60 62
61set(viewer_SOURCE_FILES 63set(viewer_SOURCE_FILES
@@ -1239,6 +1241,11 @@ set_source_files_properties(${viewer_CHARACTER_FILES}
1239 1241
1240list(APPEND viewer_SOURCE_FILES ${viewer_CHARACTER_FILES}) 1242list(APPEND viewer_SOURCE_FILES ${viewer_CHARACTER_FILES})
1241 1243
1244
1245if (OPENAL)
1246 set_source_files_properties(llstartup.cpp PROPERTIES COMPILE_FLAGS -DLL_OPENAL)
1247endif (OPENAL)
1248
1242if (FMOD) 1249if (FMOD)
1243 set_source_files_properties(llstartup.cpp PROPERTIES COMPILE_FLAGS -DLL_FMOD) 1250 set_source_files_properties(llstartup.cpp PROPERTIES COMPILE_FLAGS -DLL_FMOD)
1244 1251
diff --git a/linden/indra/newview/llappviewer.cpp b/linden/indra/newview/llappviewer.cpp
index 6301421..f442f38 100644
--- a/linden/indra/newview/llappviewer.cpp
+++ b/linden/indra/newview/llappviewer.cpp
@@ -1178,7 +1178,8 @@ bool LLAppViewer::cleanup()
1178 1178
1179 llinfos << "Global stuff deleted" << llendflush; 1179 llinfos << "Global stuff deleted" << llendflush;
1180 1180
1181#if !LL_RELEASE_FOR_DOWNLOAD 1181#if (!defined(LL_FMOD)) || (!LL_RELEASE_FOR_DOWNLOAD)
1182 // OpenAL likes to crash on exit if we *don't* explicitly shut it down.
1182 if (gAudiop) 1183 if (gAudiop)
1183 { 1184 {
1184 gAudiop->shutdown(); 1185 gAudiop->shutdown();
diff --git a/linden/indra/newview/llstartup.cpp b/linden/indra/newview/llstartup.cpp
index 0978fbb..941787b 100644
--- a/linden/indra/newview/llstartup.cpp
+++ b/linden/indra/newview/llstartup.cpp
@@ -45,6 +45,10 @@
45# include "audioengine_fmod.h" 45# include "audioengine_fmod.h"
46#endif 46#endif
47 47
48#ifdef LL_OPENAL
49#include "audioengine_openal.h"
50#endif
51
48#include "llares.h" 52#include "llares.h"
49#include "llcachename.h" 53#include "llcachename.h"
50#include "llviewercontrol.h" 54#include "llviewercontrol.h"
@@ -579,10 +583,17 @@ bool idle_startup()
579 583
580 if (FALSE == gSavedSettings.getBOOL("NoAudio")) 584 if (FALSE == gSavedSettings.getBOOL("NoAudio"))
581 { 585 {
586 gAudiop = NULL;
587
582#ifdef LL_FMOD 588#ifdef LL_FMOD
583 gAudiop = (LLAudioEngine *) new LLAudioEngine_FMOD(); 589 gAudiop = (LLAudioEngine *) new LLAudioEngine_FMOD();
584#else 590#endif
585 gAudiop = NULL; 591
592#ifdef LL_OPENAL
593 if (!gAudiop)
594 {
595 gAudiop = (LLAudioEngine *) new LLAudioEngine_OpenAL();
596 }
586#endif 597#endif
587 598
588 if (gAudiop) 599 if (gAudiop)
@@ -595,11 +606,16 @@ bool idle_startup()
595 void* window_handle = NULL; 606 void* window_handle = NULL;
596#endif 607#endif
597 bool init = gAudiop->init(kAUDIO_NUM_SOURCES, window_handle); 608 bool init = gAudiop->init(kAUDIO_NUM_SOURCES, window_handle);
598 if(!init) 609 if(init)
610 {
611 gAudiop->setMuted(TRUE);
612 }
613 else
599 { 614 {
600 LL_WARNS("AppInit") << "Unable to initialize audio engine" << LL_ENDL; 615 LL_WARNS("AppInit") << "Unable to initialize audio engine" << LL_ENDL;
616 delete gAudiop;
617 gAudiop = NULL;
601 } 618 }
602 gAudiop->setMuted(TRUE);
603 } 619 }
604 } 620 }
605 621