aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--ChangeLog.txt72
-rw-r--r--linden/indra/cmake/LLAudio.cmake3
-rw-r--r--linden/indra/cmake/OPENAL.cmake85
-rw-r--r--linden/indra/llaudio/CMakeLists.txt19
-rw-r--r--linden/indra/llaudio/audioengine.cpp395
-rw-r--r--linden/indra/llaudio/audioengine.h161
-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.cpp544
-rw-r--r--linden/indra/llaudio/audioengine_openal.h113
-rw-r--r--linden/indra/llaudio/listener_fmod.h10
-rw-r--r--linden/indra/llaudio/listener_openal.cpp98
-rw-r--r--linden/indra/llaudio/listener_openal.h7
-rw-r--r--linden/indra/llaudio/llaudiodecodemgr.cpp23
-rw-r--r--linden/indra/llaudio/windgen.h138
-rw-r--r--linden/indra/llcommon/llversionviewer.h2
-rw-r--r--linden/indra/llmedia/llmediaimplgstreamer.cpp126
-rw-r--r--linden/indra/llmedia/llmediaimplgstreamer.h2
-rw-r--r--linden/indra/llmedia/llmediamanager.cpp4
-rw-r--r--linden/indra/newview/CMakeLists.txt3
-rw-r--r--linden/indra/newview/app_settings/logcontrol.xml7
-rw-r--r--linden/indra/newview/llappviewer.cpp3
-rw-r--r--linden/indra/newview/llaudiosourcevo.cpp2
-rw-r--r--linden/indra/newview/llfloaterabout.cpp5
-rw-r--r--linden/indra/newview/llpreviewlandmark.cpp10
-rw-r--r--linden/indra/newview/llpreviewsound.cpp3
-rw-r--r--linden/indra/newview/llstartup.cpp44
-rw-r--r--linden/indra/newview/llviewermessage.cpp9
-rw-r--r--linden/indra/newview/llviewertexteditor.cpp3
-rw-r--r--linden/indra/newview/llvoavatar.cpp11
-rw-r--r--linden/indra/newview/skins/default/xui/en-us/floater_instant_message_group.xml164
-rwxr-xr-xlinden/indra/newview/viewer_manifest.py34
-rw-r--r--linden/install.xml33
33 files changed, 1873 insertions, 562 deletions
diff --git a/ChangeLog.txt b/ChangeLog.txt
index 5ced8eb..094fb1e 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -1,5 +1,10 @@
12008-12-30 McCabe Maxsted <hakushakukun@gmail.com> 12008-12-30 McCabe Maxsted <hakushakukun@gmail.com>
2 2
3 * Merged in balp's openal branch.
4
5
62008-12-30 McCabe Maxsted <hakushakukun@gmail.com>
7
3 * linden/indra/CMakeLists.txt: 8 * linden/indra/CMakeLists.txt:
4 "Added fix for VWR-10392 as well as other fixes. 9 "Added fix for VWR-10392 as well as other fixes.
5 * linden/indra/cmake/00-Common.cmake: 10 * linden/indra/cmake/00-Common.cmake:
@@ -72,6 +77,14 @@
72 Bumped version to 1.1.0 alpha. 77 Bumped version to 1.1.0 alpha.
73 78
74 79
802008-12-12 Balp Allen <Anders@Arnholm.se>
81
82 * Bumped version to RC3
83
84 * Applied patches from Henri's CoolViewer:
85 Possible to discard much more given items.
86
87
752008-12-11 McCabe Maxsted <hakushakukun@gmail.com> 882008-12-11 McCabe Maxsted <hakushakukun@gmail.com>
76 89
77 * linden/indra/newview/llfloaterinspect.cpp: 90 * linden/indra/newview/llfloaterinspect.cpp:
@@ -275,6 +288,65 @@
275 Patch by Aleric Inglewood. 288 Patch by Aleric Inglewood.
276 289
277 290
291 * linden/indra/llaudio/audioengine.cpp:
292 Updated audio engine to LL's openal branch r1532.
293 * linden/indra/llaudio/audioengine.h:
294 Ditto.
295 * linden/indra/llaudio/audioengine_openal.cpp:
296 Ditto.
297 * linden/indra/llaudio/audioengine_openal.h:
298 Ditto.
299 * linden/indra/newview/llaudiosourcevo.cpp:
300 Ditto.
301 * linden/indra/newview/llpreviewsound.cpp:
302 Ditto.
303 * linden/indra/newview/llstartup.cpp:
304 Ditto.
305 * linden/indra/newview/llviewermessage.cpp:
306 Ditto.
307 * linden/indra/newview/llviewertexteditor.cpp:
308 Ditto.
309 * linden/indra/newview/llvoavatar.cpp:
310 Ditto.
311
312
3132008-11-21 Jacek Antonelli <jacek.antonelli@gmail.com>
314
315 * linden/indra/cmake/OPENAL.cmake:
316 Cross-platform checking for OpenAL libs.
317 * linden/indra/cmake/LLAudio.cmake:
318 Ditto.
319
320
3212008-11-20 Jacek Antonelli <jacek.antonelli@gmail.com>
322
323 * linden/indra/cmake/OPENAL.cmake:
324 Enable OpenAL by default.
325 Configure with -DOPENAL:BOOL=OFF to disable.
326
327
3282008-11-19 Jacek Antonelli <jacek.antonelli@gmail.com>
329
330 * linden/indra/newview/viewer_manifest.py:
331 Package up OpenAL libs.
332
333
334 * indra/llaudio/audioengine_openal.cpp:
335 VWR-2662: OpenAL support (patch by Tofu Linden)
336 * indra/llaudio/audioengine_openal.h: Ditto.
337 * indra/llaudio/listener_openal.cpp: Ditto.
338 * indra/llaudio/listener_openal.h: Ditto.
339 * indra/llaudio/windgen.h: Ditto.
340 * indra/cmake/LLAudio.cmake: Ditto.
341 * indra/llaudio/CMakeLists.txt: Ditto.
342 * indra/llaudio/audioengine.h: Ditto.
343 * indra/llaudio/audioengine_fmod.cpp: Ditto.
344 * indra/llaudio/audioengine_fmod.h: Ditto.
345 * indra/llaudio/listener_fmod.h: Ditto.
346 * indra/newview/CMakeLists.txt: Ditto.
347 * indra/newview/llappviewer.cpp: Ditto.
348 * indra/newview/llstartup.cpp: Ditto.
349
2782008-12-06 McCabe Maxsted <hakushakukun@gmail.com> 3502008-12-06 McCabe Maxsted <hakushakukun@gmail.com>
279 351
280 * linden/indra/llcommon/llversionviewer.h: 352 * linden/indra/llcommon/llversionviewer.h:
diff --git a/linden/indra/cmake/LLAudio.cmake b/linden/indra/cmake/LLAudio.cmake
index 7b9f254..dcfd269 100644
--- a/linden/indra/cmake/LLAudio.cmake
+++ b/linden/indra/cmake/LLAudio.cmake
@@ -1,9 +1,11 @@
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
8 ${OPENAL_INCLUDE_DIRS}
7 ) 9 )
8 10
9set(LLAUDIO_LIBRARIES 11set(LLAUDIO_LIBRARIES
@@ -12,4 +14,5 @@ set(LLAUDIO_LIBRARIES
12 ${VORBISFILE_LIBRARIES} 14 ${VORBISFILE_LIBRARIES}
13 ${VORBIS_LIBRARIES} 15 ${VORBIS_LIBRARIES}
14 ${OGG_LIBRARIES} 16 ${OGG_LIBRARIES}
17 ${OPENAL_LIBRARIES}
15 ) 18 )
diff --git a/linden/indra/cmake/OPENAL.cmake b/linden/indra/cmake/OPENAL.cmake
new file mode 100644
index 0000000..a2bae5d
--- /dev/null
+++ b/linden/indra/cmake/OPENAL.cmake
@@ -0,0 +1,85 @@
1# -*- cmake -*-
2
3set(OPENAL ON CACHE BOOL "Enable OpenAL")
4
5
6if (OPENAL)
7
8 # message(STATUS "Building with OpenAL audio support")
9
10 # OPENAL_LIB
11
12 find_library(OPENAL_LIB
13 NAMES openal OpenAL OpenAL32 wrap_oal
14 PATHS ${ARCH_PREBUILT_DIRS_RELEASE}
15 )
16
17 if (NOT OPENAL_LIB)
18 message(FATAL_ERROR "OpenAL not found!")
19 else (NOT OPENAL_LIB)
20 # message(STATUS "OpenAL found: ${OPENAL_LIB}")
21 endif (NOT OPENAL_LIB)
22
23
24
25 # OPENAL_INCLUDE_DIR
26
27 find_path(OPENAL_INCLUDE_DIR
28 NAMES al.h
29 PATHS ${LIBS_PREBUILT_DIR}/include /usr/include/AL
30 )
31
32 if (NOT OPENAL_INCLUDE_DIR)
33 message(FATAL_ERROR "al.h not found!")
34 else (NOT OPENAL_INCLUDE_DIR)
35 # message(STATUS "al.h found in: ${OPENAL_INCLUDE_DIR}")
36 endif (NOT OPENAL_INCLUDE_DIR)
37
38
39
40 # ALUT_LIB
41
42 find_library(ALUT_LIB
43 NAMES alut freealut
44 PATHS ${ARCH_PREBUILT_DIRS_RELEASE}
45 )
46
47 if (NOT ALUT_LIB)
48 message(FATAL_ERROR "ALUT not found!")
49 else (NOT ALUT_LIB)
50 # message(STATUS "ALUT found: ${ALUT_LIB}")
51 endif (NOT ALUT_LIB)
52
53
54
55 # ALUT_INCLUDE_DIR
56
57 find_path(ALUT_INCLUDE_DIR
58 NAMES alut.h
59 PATHS ${LIBS_PREBUILT_DIR}/include /usr/include/AL
60 )
61
62 if (NOT ALUT_INCLUDE_DIR)
63 message(FATAL_ERROR "alut.h not found!")
64 else (NOT ALUT_INCLUDE_DIR)
65 # message(STATUS "alut.h found in: ${ALUT_INCLUDE_DIR}")
66 endif (NOT ALUT_INCLUDE_DIR)
67
68
69
70 set(OPENAL_LIBRARIES
71 ${OPENAL_LIB}
72 ${ALUT_LIB}
73 )
74
75 set(OPENAL_INCLUDE_DIRS
76 ${OPENAL_INCLUDE_DIR}
77 ${ALUT_INCLUDE_DIR}
78 )
79
80
81 set(OPENAL_FOUND TRUE CACHE BOOL
82 "Found OpenAL and ALUT libraries successfully"
83 )
84
85endif (OPENAL)
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..da9bcba 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,21 @@ 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();
101
102 for (U32 i = 0; i < LLAudioEngine::AUDIO_TYPE_COUNT; i++)
103 mSecondaryGain[i] = 1.0f;
99} 104}
100 105
101 106
102BOOL LLAudioEngine::init(const S32 num_channels, void* userdata) 107bool LLAudioEngine::init(const S32 num_channels, void* userdata)
103{ 108{
104 setDefaults(); 109 setDefaults();
105 110
@@ -111,7 +116,9 @@ BOOL LLAudioEngine::init(const S32 num_channels, void* userdata)
111 // Initialize the decode manager 116 // Initialize the decode manager
112 gAudioDecodeMgrp = new LLAudioDecodeMgr; 117 gAudioDecodeMgrp = new LLAudioDecodeMgr;
113 118
114 return TRUE; 119 LL_INFOS("AudioEngine") << "LLAudioEngine::init() AudioEngine successfully initialized" << llendl;
120
121 return true;
115} 122}
116 123
117 124
@@ -121,6 +128,9 @@ void LLAudioEngine::shutdown()
121 delete gAudioDecodeMgrp; 128 delete gAudioDecodeMgrp;
122 gAudioDecodeMgrp = NULL; 129 gAudioDecodeMgrp = NULL;
123 130
131 // Clean up wind source
132 cleanupWind();
133
124 // Clean up audio sources 134 // Clean up audio sources
125 source_map::iterator iter_src; 135 source_map::iterator iter_src;
126 for (iter_src = mAllSources.begin(); iter_src != mAllSources.end(); iter_src++) 136 for (iter_src = mAllSources.begin(); iter_src != mAllSources.end(); iter_src++)
@@ -141,22 +151,146 @@ void LLAudioEngine::shutdown()
141 S32 i; 151 S32 i;
142 for (i = 0; i < MAX_CHANNELS; i++) 152 for (i = 0; i < MAX_CHANNELS; i++)
143 { 153 {
144 if (mChannels[i]) 154 delete mChannels[i];
145 { 155 mChannels[i] = NULL;
146 delete mChannels[i];
147 mChannels[i] = NULL;
148 }
149 } 156 }
150 157
151 // Clean up buffers 158 // Clean up buffers
152 for (i = 0; i < MAX_BUFFERS; i++) 159 for (i = 0; i < MAX_BUFFERS; i++)
153 { 160 {
154 if (mBuffers[i]) 161 delete mBuffers[i];
162 mBuffers[i] = NULL;
163 }
164
165 delete mInternetStreamMedia;
166 mInternetStreamMedia = NULL;
167 mInternetStreamURL.clear();
168}
169
170
171// virtual
172void LLAudioEngine::startInternetStream(const std::string& url)
173{
174 LL_INFOS("AudioEngine") << "entered startInternetStream()" << llendl;
175
176 if (!mInternetStreamMedia)
177 {
178 LLMediaManager* mgr = LLMediaManager::getInstance();
179 if (mgr)
155 { 180 {
156 delete mBuffers[i]; 181 mInternetStreamMedia = mgr->createSourceFromMimeType(LLURI(url).scheme(), "audio/mpeg"); // assumes that whatever media implementation supports mp3 also supports vorbis.
157 mBuffers[i] = NULL; 182 LL_INFOS("AudioEngine") << "mInternetStreamMedia is now " << mInternetStreamMedia << llendl;
183 }
184 }
185
186 if(!mInternetStreamMedia)
187 return;
188
189 if (!url.empty()) {
190 LL_INFOS("AudioEngine") << "Starting internet stream: " << url << llendl;
191 mInternetStreamURL = url;
192 mInternetStreamMedia->navigateTo ( url );
193 LL_INFOS("AudioEngine") << "Playing....." << llendl;
194 mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_START);
195 mInternetStreamMedia->updateMedia();
196 } else {
197 LL_INFOS("AudioEngine") << "setting stream to NULL"<< llendl;
198 mInternetStreamURL.clear();
199 mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_STOP);
200 mInternetStreamMedia->updateMedia();
201 }
202 //#endif
203}
204
205// virtual
206void LLAudioEngine::stopInternetStream()
207{
208 LL_INFOS("AudioEngine") << "entered stopInternetStream()" << llendl;
209
210 if(mInternetStreamMedia)
211 {
212 if( ! mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_STOP)){
213 LL_INFOS("AudioEngine") << "attempting to stop stream failed!" << llendl;
214 }
215 mInternetStreamMedia->updateMedia();
216 }
217
218 mInternetStreamURL.clear();
219}
220
221// virtual
222void LLAudioEngine::pauseInternetStream(int pause)
223{
224 LL_INFOS("AudioEngine") << "entered pauseInternetStream()" << llendl;
225
226 if(!mInternetStreamMedia)
227 return;
228
229 if(pause)
230 {
231 if(! mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_PAUSE))
232 {
233 LL_INFOS("AudioEngine") << "attempting to pause stream failed!" << llendl;
234 }
235 } else {
236 if(! mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_START))
237 {
238 LL_INFOS("AudioEngine") << "attempting to unpause stream failed!" << llendl;
158 } 239 }
159 } 240 }
241 mInternetStreamMedia->updateMedia();
242}
243
244// virtual
245void LLAudioEngine::updateInternetStream()
246{
247 if (mInternetStreamMedia)
248 mInternetStreamMedia->updateMedia();
249}
250
251// virtual
252int LLAudioEngine::isInternetStreamPlaying()
253{
254 if (!mInternetStreamMedia)
255 return 0;
256
257 if (mInternetStreamMedia->getStatus() == LLMediaBase::STATUS_STARTED)
258 {
259 return 1; // Active and playing
260 }
261
262 if (mInternetStreamMedia->getStatus() == LLMediaBase::STATUS_PAUSED)
263 {
264 return 2; // paused
265 }
266
267 return 0; // Stopped
268}
269
270// virtual
271void LLAudioEngine::getInternetStreamInfo(char* artist, char* title)
272{
273 artist[0] = 0;
274 title[0] = 0;
275}
276
277// virtual
278void LLAudioEngine::setInternetStreamGain(F32 vol)
279{
280 mInternetStreamGain = vol;
281
282 if(!mInternetStreamMedia)
283 return;
284
285 vol = llclamp(vol, 0.f, 1.f);
286 mInternetStreamMedia->setVolume(vol);
287 mInternetStreamMedia->updateMedia();
288}
289
290// virtual
291const std::string& LLAudioEngine::getInternetStreamURL()
292{
293 return mInternetStreamURL;
160} 294}
161 295
162 296
@@ -167,6 +301,13 @@ void LLAudioEngine::updateChannels()
167 { 301 {
168 if (mChannels[i]) 302 if (mChannels[i])
169 { 303 {
304 // set secondary gain if type is available
305 LLAudioSource* source = mChannels[i]->getSource();
306 if (source)
307 {
308 mChannels[i]->setSecondaryGain(mSecondaryGain[source->getType()]);
309 }
310
170 mChannels[i]->updateBuffer(); 311 mChannels[i]->updateBuffer();
171 mChannels[i]->update3DPosition(); 312 mChannels[i]->update3DPosition();
172 mChannels[i]->updateLoop(); 313 mChannels[i]->updateLoop();
@@ -200,7 +341,7 @@ void LLAudioEngine::idle(F32 max_decode_time)
200 { 341 {
201 if (mBuffers[i]) 342 if (mBuffers[i])
202 { 343 {
203 mBuffers[i]->mInUse = FALSE; 344 mBuffers[i]->mInUse = false;
204 } 345 }
205 } 346 }
206 347
@@ -245,18 +386,18 @@ void LLAudioEngine::idle(F32 max_decode_time)
245 LLAudioChannel *channelp = getFreeChannel(max_priority); 386 LLAudioChannel *channelp = getFreeChannel(max_priority);
246 if (channelp) 387 if (channelp)
247 { 388 {
248 //llinfos << "Replacing source in channel due to priority!" << llendl; 389 //LL_INFOS("AudioEngine") << "Replacing source in channel due to priority!" << llendl;
249 max_sourcep->setChannel(channelp); 390 max_sourcep->setChannel(channelp);
250 channelp->setSource(max_sourcep); 391 channelp->setSource(max_sourcep);
251 if (max_sourcep->isSyncSlave()) 392 if (max_sourcep->isSyncSlave())
252 { 393 {
253 // A sync slave, it doesn't start playing until it's synced up with the master. 394 // 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. 395 // Flag this channel as waiting for sync, and return true.
255 channelp->setWaiting(TRUE); 396 channelp->setWaiting(true);
256 } 397 }
257 else 398 else
258 { 399 {
259 channelp->setWaiting(FALSE); 400 channelp->setWaiting(false);
260 channelp->play(); 401 channelp->play();
261 } 402 }
262 } 403 }
@@ -396,7 +537,7 @@ void LLAudioEngine::idle(F32 max_decode_time)
396 if (sync_masterp->getChannel()) 537 if (sync_masterp->getChannel())
397 { 538 {
398 channelp->playSynced(master_channelp); 539 channelp->playSynced(master_channelp);
399 channelp->setWaiting(FALSE); 540 channelp->setWaiting(false);
400 } 541 }
401 } 542 }
402 } 543 }
@@ -412,7 +553,7 @@ void LLAudioEngine::idle(F32 max_decode_time)
412 { 553 {
413 if (!mBuffers[i]->mInUse && mBuffers[i]->mLastUseTimer.getElapsedTimeF32() > 30.f) 554 if (!mBuffers[i]->mInUse && mBuffers[i]->mLastUseTimer.getElapsedTimeF32() > 30.f)
414 { 555 {
415 //llinfos << "Flushing unused buffer!" << llendl; 556 //LL_INFOS("AudioEngine") << "Flushing unused buffer!" << llendl;
416 mBuffers[i]->mAudioDatap->mBufferp = NULL; 557 mBuffers[i]->mAudioDatap->mBufferp = NULL;
417 delete mBuffers[i]; 558 delete mBuffers[i];
418 mBuffers[i] = NULL; 559 mBuffers[i] = NULL;
@@ -426,7 +567,7 @@ void LLAudioEngine::idle(F32 max_decode_time)
426 { 567 {
427 if (mChannels[i]) 568 if (mChannels[i])
428 { 569 {
429 mChannels[i]->mLoopedThisFrame = FALSE; 570 mChannels[i]->mLoopedThisFrame = false;
430 } 571 }
431 } 572 }
432 573
@@ -437,13 +578,17 @@ void LLAudioEngine::idle(F32 max_decode_time)
437 // missed picking it up in all the places that can add 578 // missed picking it up in all the places that can add
438 // or request new data. 579 // or request new data.
439 startNextTransfer(); 580 startNextTransfer();
581
582 updateInternetStream();
440} 583}
441 584
442BOOL LLAudioEngine::updateBufferForData(LLAudioData *adp, const LLUUID &audio_uuid) 585
586
587bool LLAudioEngine::updateBufferForData(LLAudioData *adp, const LLUUID &audio_uuid)
443{ 588{
444 if (!adp) 589 if (!adp)
445 { 590 {
446 return FALSE; 591 return false;
447 } 592 }
448 593
449 // Update the audio buffer first - load a sound if we have it. 594 // Update the audio buffer first - load a sound if we have it.
@@ -466,14 +611,14 @@ BOOL LLAudioEngine::updateBufferForData(LLAudioData *adp, const LLUUID &audio_uu
466 } 611 }
467 else 612 else
468 { 613 {
469 return FALSE; 614 return false;
470 } 615 }
471 } 616 }
472 return TRUE; 617 return true;
473} 618}
474 619
475 620
476void LLAudioEngine::enableWind(BOOL enable) 621void LLAudioEngine::enableWind(bool enable)
477{ 622{
478 if (enable && (!mEnableWind)) 623 if (enable && (!mEnableWind))
479 { 624 {
@@ -521,8 +666,8 @@ LLAudioBuffer *LLAudioEngine::getFreeBuffer()
521 666
522 if (buffer_id >= 0) 667 if (buffer_id >= 0)
523 { 668 {
524 llinfos << "Taking over unused buffer " << buffer_id << llendl; 669 LL_INFOS("AudioEngine") << "Taking over unused buffer " << buffer_id << llendl;
525 //llinfos << "Flushing unused buffer!" << llendl; 670 //LL_INFOS("AudioEngine") << "Flushing unused buffer!" << llendl;
526 mBuffers[buffer_id]->mAudioDatap->mBufferp = NULL; 671 mBuffers[buffer_id]->mAudioDatap->mBufferp = NULL;
527 delete mBuffers[buffer_id]; 672 delete mBuffers[buffer_id];
528 mBuffers[buffer_id] = createBuffer(); 673 mBuffers[buffer_id] = createBuffer();
@@ -601,7 +746,7 @@ void LLAudioEngine::cleanupBuffer(LLAudioBuffer *bufferp)
601} 746}
602 747
603 748
604BOOL LLAudioEngine::preloadSound(const LLUUID &uuid) 749bool LLAudioEngine::preloadSound(const LLUUID &uuid)
605{ 750{
606 gAudiop->getAudioData(uuid); // We don't care about the return value, this is just to make sure 751 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 752 // that we have an entry, which will mean that the audio engine knows about this
@@ -609,23 +754,23 @@ BOOL LLAudioEngine::preloadSound(const LLUUID &uuid)
609 if (gAudioDecodeMgrp->addDecodeRequest(uuid)) 754 if (gAudioDecodeMgrp->addDecodeRequest(uuid))
610 { 755 {
611 // This means that we do have a local copy, and we're working on decoding it. 756 // This means that we do have a local copy, and we're working on decoding it.
612 return TRUE; 757 return true;
613 } 758 }
614 759
615 // At some point we need to have the audio/asset system check the static VFS 760 // 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. 761 // before it goes off and fetches stuff from the server.
617 //llwarns << "Used internal preload for non-local sound" << llendl; 762 //llwarns << "Used internal preload for non-local sound" << llendl;
618 return FALSE; 763 return false;
619} 764}
620 765
621 766
622BOOL LLAudioEngine::isWindEnabled() 767bool LLAudioEngine::isWindEnabled()
623{ 768{
624 return mEnableWind; 769 return mEnableWind;
625} 770}
626 771
627 772
628void LLAudioEngine::setMuted(BOOL muted) 773void LLAudioEngine::setMuted(bool muted)
629{ 774{
630 mMuted = muted; 775 mMuted = muted;
631 enableWind(!mMuted); 776 enableWind(!mMuted);
@@ -643,6 +788,18 @@ F32 LLAudioEngine::getMasterGain()
643 return mMasterGain; 788 return mMasterGain;
644} 789}
645 790
791void LLAudioEngine::setSecondaryGain(S32 type, F32 gain)
792{
793 llassert(type < LLAudioEngine::AUDIO_TYPE_COUNT);
794
795 mSecondaryGain[type] = gain;
796}
797
798F32 LLAudioEngine::getSecondaryGain(S32 type)
799{
800 return mSecondaryGain[type];
801}
802
646F32 LLAudioEngine::getInternetStreamGain() 803F32 LLAudioEngine::getInternetStreamGain()
647{ 804{
648 return mInternetStreamGain; 805 return mInternetStreamGain;
@@ -718,10 +875,11 @@ F64 LLAudioEngine::mapWindVecToPan(LLVector3 wind_vec)
718} 875}
719 876
720 877
721void LLAudioEngine::triggerSound(const LLUUID &audio_uuid, const LLUUID& owner_id, const F32 gain, const LLVector3d &pos_global) 878void LLAudioEngine::triggerSound(const LLUUID &audio_uuid, const LLUUID& owner_id, const F32 gain,
879 const S32 type, const LLVector3d &pos_global)
722{ 880{
723 // Create a new source (since this can't be associated with an existing source. 881 // Create a new source (since this can't be associated with an existing source.
724 //llinfos << "Localized: " << audio_uuid << llendl; 882 //LL_INFOS("AudioEngine") << "Localized: " << audio_uuid << llendl;
725 883
726 if (mMuted) 884 if (mMuted)
727 { 885 {
@@ -731,11 +889,11 @@ void LLAudioEngine::triggerSound(const LLUUID &audio_uuid, const LLUUID& owner_i
731 LLUUID source_id; 889 LLUUID source_id;
732 source_id.generate(); 890 source_id.generate();
733 891
734 LLAudioSource *asp = new LLAudioSource(source_id, owner_id, gain); 892 LLAudioSource *asp = new LLAudioSource(source_id, owner_id, gain, type);
735 gAudiop->addAudioSource(asp); 893 gAudiop->addAudioSource(asp);
736 if (pos_global.isExactlyZero()) 894 if (pos_global.isExactlyZero())
737 { 895 {
738 asp->setAmbient(TRUE); 896 asp->setAmbient(true);
739 } 897 }
740 else 898 else
741 { 899 {
@@ -914,7 +1072,7 @@ void LLAudioEngine::cleanupAudioSource(LLAudioSource *asp)
914} 1072}
915 1073
916 1074
917BOOL LLAudioEngine::hasDecodedFile(const LLUUID &uuid) 1075bool LLAudioEngine::hasDecodedFile(const LLUUID &uuid)
918{ 1076{
919 std::string uuid_str; 1077 std::string uuid_str;
920 uuid.toString(uuid_str); 1078 uuid.toString(uuid_str);
@@ -925,16 +1083,16 @@ BOOL LLAudioEngine::hasDecodedFile(const LLUUID &uuid)
925 1083
926 if (gDirUtilp->fileExists(wav_path)) 1084 if (gDirUtilp->fileExists(wav_path))
927 { 1085 {
928 return TRUE; 1086 return true;
929 } 1087 }
930 else 1088 else
931 { 1089 {
932 return FALSE; 1090 return false;
933 } 1091 }
934} 1092}
935 1093
936 1094
937BOOL LLAudioEngine::hasLocalFile(const LLUUID &uuid) 1095bool LLAudioEngine::hasLocalFile(const LLUUID &uuid)
938{ 1096{
939 // See if it's in the VFS. 1097 // See if it's in the VFS.
940 return gVFS->getExists(uuid, LLAssetType::AT_SOUND); 1098 return gVFS->getExists(uuid, LLAssetType::AT_SOUND);
@@ -943,10 +1101,10 @@ BOOL LLAudioEngine::hasLocalFile(const LLUUID &uuid)
943 1101
944void LLAudioEngine::startNextTransfer() 1102void LLAudioEngine::startNextTransfer()
945{ 1103{
946 //llinfos << "LLAudioEngine::startNextTransfer()" << llendl; 1104 //LL_INFOS("AudioEngine") << "LLAudioEngine::startNextTransfer()" << llendl;
947 if (mCurrentTransfer.notNull() || getMuted()) 1105 if (mCurrentTransfer.notNull() || getMuted())
948 { 1106 {
949 //llinfos << "Transfer in progress, aborting" << llendl; 1107 //LL_INFOS("AudioEngine") << "Transfer in progress, aborting" << llendl;
950 return; 1108 return;
951 } 1109 }
952 1110
@@ -1127,7 +1285,7 @@ void LLAudioEngine::startNextTransfer()
1127 1285
1128 if (asset_id.notNull()) 1286 if (asset_id.notNull())
1129 { 1287 {
1130 llinfos << "Getting asset data for: " << asset_id << llendl; 1288 LL_INFOS("AudioEngine") << "Getting asset data for: " << asset_id << llendl;
1131 gAudiop->mCurrentTransfer = asset_id; 1289 gAudiop->mCurrentTransfer = asset_id;
1132 gAudiop->mCurrentTransferTimer.reset(); 1290 gAudiop->mCurrentTransferTimer.reset();
1133 gAssetStorage->getAssetData(asset_id, LLAssetType::AT_SOUND, 1291 gAssetStorage->getAssetData(asset_id, LLAssetType::AT_SOUND,
@@ -1135,7 +1293,7 @@ void LLAudioEngine::startNextTransfer()
1135 } 1293 }
1136 else 1294 else
1137 { 1295 {
1138 //llinfos << "No pending transfers?" << llendl; 1296 //LL_INFOS("AudioEngine") << "No pending transfers?" << llendl;
1139 } 1297 }
1140} 1298}
1141 1299
@@ -1145,14 +1303,14 @@ void LLAudioEngine::assetCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::E
1145{ 1303{
1146 if (result_code) 1304 if (result_code)
1147 { 1305 {
1148 llinfos << "Boom, error in audio file transfer: " << LLAssetStorage::getErrorString( result_code ) << " (" << result_code << ")" << llendl; 1306 LL_INFOS("AudioEngine") << "Boom, error in audio file transfer: " << LLAssetStorage::getErrorString( result_code ) << " (" << result_code << ")" << llendl;
1149 // Need to mark data as bad to avoid constant rerequests. 1307 // Need to mark data as bad to avoid constant rerequests.
1150 LLAudioData *adp = gAudiop->getAudioData(uuid); 1308 LLAudioData *adp = gAudiop->getAudioData(uuid);
1151 if (adp) 1309 if (adp)
1152 { 1310 {
1153 adp->setHasValidData(FALSE); 1311 adp->setHasValidData(false);
1154 adp->setHasLocalData(FALSE); 1312 adp->setHasLocalData(false);
1155 adp->setHasDecodedData(FALSE); 1313 adp->setHasDecodedData(false);
1156 } 1314 }
1157 } 1315 }
1158 else 1316 else
@@ -1165,8 +1323,8 @@ void LLAudioEngine::assetCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::E
1165 } 1323 }
1166 else 1324 else
1167 { 1325 {
1168 adp->setHasValidData(TRUE); 1326 adp->setHasValidData(true);
1169 adp->setHasLocalData(TRUE); 1327 adp->setHasLocalData(true);
1170 gAudioDecodeMgrp->addDecodeRequest(uuid); 1328 gAudioDecodeMgrp->addDecodeRequest(uuid);
1171 } 1329 }
1172 } 1330 }
@@ -1180,17 +1338,18 @@ void LLAudioEngine::assetCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::E
1180// 1338//
1181 1339
1182 1340
1183LLAudioSource::LLAudioSource(const LLUUID& id, const LLUUID& owner_id, const F32 gain) 1341LLAudioSource::LLAudioSource(const LLUUID& id, const LLUUID& owner_id, const F32 gain, const S32 type)
1184: mID(id), 1342: mID(id),
1185 mOwnerID(owner_id), 1343 mOwnerID(owner_id),
1186 mPriority(0.f), 1344 mPriority(0.f),
1187 mGain(gain), 1345 mGain(gain),
1188 mAmbient(FALSE), 1346 mType(type),
1189 mLoop(FALSE), 1347 mAmbient(false),
1190 mSyncMaster(FALSE), 1348 mLoop(false),
1191 mSyncSlave(FALSE), 1349 mSyncMaster(false),
1192 mQueueSounds(FALSE), 1350 mSyncSlave(false),
1193 mPlayedOnce(FALSE), 1351 mQueueSounds(false),
1352 mPlayedOnce(false),
1194 mChannelp(NULL), 1353 mChannelp(NULL),
1195 mCurrentDatap(NULL), 1354 mCurrentDatap(NULL),
1196 mQueuedDatap(NULL) 1355 mQueuedDatap(NULL)
@@ -1254,7 +1413,7 @@ void LLAudioSource::updatePriority()
1254 } 1413 }
1255} 1414}
1256 1415
1257BOOL LLAudioSource::setupChannel() 1416bool LLAudioSource::setupChannel()
1258{ 1417{
1259 LLAudioData *adp = getCurrentData(); 1418 LLAudioData *adp = getCurrentData();
1260 1419
@@ -1262,7 +1421,7 @@ BOOL LLAudioSource::setupChannel()
1262 { 1421 {
1263 // We're not ready to play back the sound yet, so don't try and allocate a channel for it. 1422 // 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; 1423 //llwarns << "Aborting, no buffer" << llendl;
1265 return FALSE; 1424 return false;
1266 } 1425 }
1267 1426
1268 1427
@@ -1280,15 +1439,15 @@ BOOL LLAudioSource::setupChannel()
1280 // Now we have to reprioritize. 1439 // Now we have to reprioritize.
1281 // For now, just don't play the sound. 1440 // For now, just don't play the sound.
1282 //llwarns << "Aborting, no free channels" << llendl; 1441 //llwarns << "Aborting, no free channels" << llendl;
1283 return FALSE; 1442 return false;
1284 } 1443 }
1285 1444
1286 mChannelp->setSource(this); 1445 mChannelp->setSource(this);
1287 return TRUE; 1446 return true;
1288} 1447}
1289 1448
1290 1449
1291BOOL LLAudioSource::play(const LLUUID &audio_uuid) 1450bool LLAudioSource::play(const LLUUID &audio_uuid)
1292{ 1451{
1293 if (audio_uuid.isNull()) 1452 if (audio_uuid.isNull())
1294 { 1453 {
@@ -1296,7 +1455,7 @@ BOOL LLAudioSource::play(const LLUUID &audio_uuid)
1296 { 1455 {
1297 getChannel()->setSource(NULL); 1456 getChannel()->setSource(NULL);
1298 setChannel(NULL); 1457 setChannel(NULL);
1299 addAudioData(NULL, TRUE); 1458 addAudioData(NULL, true);
1300 } 1459 }
1301 } 1460 }
1302 // Reset our age timeout if someone attempts to play the source. 1461 // Reset our age timeout if someone attempts to play the source.
@@ -1304,7 +1463,7 @@ BOOL LLAudioSource::play(const LLUUID &audio_uuid)
1304 1463
1305 LLAudioData *adp = gAudiop->getAudioData(audio_uuid); 1464 LLAudioData *adp = gAudiop->getAudioData(audio_uuid);
1306 1465
1307 BOOL has_buffer = gAudiop->updateBufferForData(adp, audio_uuid); 1466 bool has_buffer = gAudiop->updateBufferForData(adp, audio_uuid);
1308 1467
1309 1468
1310 addAudioData(adp); 1469 addAudioData(adp);
@@ -1312,47 +1471,48 @@ BOOL LLAudioSource::play(const LLUUID &audio_uuid)
1312 if (!has_buffer) 1471 if (!has_buffer)
1313 { 1472 {
1314 // Don't bother trying to set up a channel or anything, we don't have an audio buffer. 1473 // Don't bother trying to set up a channel or anything, we don't have an audio buffer.
1315 return FALSE; 1474 return false;
1316 } 1475 }
1317 1476
1318 if (!setupChannel()) 1477 if (!setupChannel())
1319 { 1478 {
1320 return FALSE; 1479 return false;
1321 } 1480 }
1322 1481
1323 if (isSyncSlave()) 1482 if (isSyncSlave())
1324 { 1483 {
1325 // A sync slave, it doesn't start playing until it's synced up with the master. 1484 // 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. 1485 // Flag this channel as waiting for sync, and return true.
1327 getChannel()->setWaiting(TRUE); 1486 getChannel()->setWaiting(true);
1328 return TRUE; 1487 return true;
1329 } 1488 }
1330 1489
1331 getChannel()->play(); 1490 getChannel()->play();
1332 return TRUE; 1491 return true;
1333} 1492}
1334 1493
1335 1494
1336BOOL LLAudioSource::isDone() 1495bool LLAudioSource::isDone()
1337{ 1496{
1338 const F32 MAX_AGE = 60.f; 1497 const F32 MAX_AGE = 60.f;
1339 const F32 MAX_UNPLAYED_AGE = 15.f; 1498 const F32 MAX_UNPLAYED_AGE = 15.f;
1499
1340 if (isLoop()) 1500 if (isLoop())
1341 { 1501 {
1342 // Looped sources never die on their own. 1502 // Looped sources never die on their own.
1343 return FALSE; 1503 return false;
1344 } 1504 }
1345 1505
1346 1506
1347 if (hasPendingPreloads()) 1507 if (hasPendingPreloads())
1348 { 1508 {
1349 return FALSE; 1509 return false;
1350 } 1510 }
1351 1511
1352 if (mQueuedDatap) 1512 if (mQueuedDatap)
1353 { 1513 {
1354 // Don't kill this sound if we've got something queued up to play. 1514 // Don't kill this sound if we've got something queued up to play.
1355 return FALSE; 1515 return false;
1356 } 1516 }
1357 1517
1358 F32 elapsed = mAgeTimer.getElapsedTimeF32(); 1518 F32 elapsed = mAgeTimer.getElapsedTimeF32();
@@ -1364,12 +1524,12 @@ BOOL LLAudioSource::isDone()
1364 { 1524 {
1365 // We don't have a channel assigned, and it's been 1525 // We don't have a channel assigned, and it's been
1366 // over 5 seconds since we tried to play it. Don't bother. 1526 // over 5 seconds since we tried to play it. Don't bother.
1367 //llinfos << "No channel assigned, source is done" << llendl; 1527 //LL_INFOS("AudioEngine") << "No channel assigned, source is done" << llendl;
1368 return TRUE; 1528 return true;
1369 } 1529 }
1370 else 1530 else
1371 { 1531 {
1372 return FALSE; 1532 return false;
1373 } 1533 }
1374 } 1534 }
1375 1535
@@ -1377,27 +1537,27 @@ BOOL LLAudioSource::isDone()
1377 { 1537 {
1378 if (elapsed > MAX_AGE) 1538 if (elapsed > MAX_AGE)
1379 { 1539 {
1380 // Arbitarily cut off non-looped sounds when they're 20 seconds old. 1540 // Arbitarily cut off non-looped sounds when they're old.
1381 return TRUE; 1541 return true;
1382 } 1542 }
1383 else 1543 else
1384 { 1544 {
1385 // Sound is still playing and we haven't timed out, don't kill it. 1545 // Sound is still playing and we haven't timed out, don't kill it.
1386 return FALSE; 1546 return false;
1387 } 1547 }
1388 } 1548 }
1389 1549
1390 if ((elapsed > MAX_UNPLAYED_AGE) || mPlayedOnce) 1550 if ((elapsed > MAX_UNPLAYED_AGE) || mPlayedOnce)
1391 { 1551 {
1392 // The sound isn't playing back after 5 seconds or we're already done playing it, kill it. 1552 // The sound isn't playing back after 5 seconds or we're already done playing it, kill it.
1393 return TRUE; 1553 return true;
1394 } 1554 }
1395 1555
1396 return FALSE; 1556 return false;
1397} 1557}
1398 1558
1399 1559
1400void LLAudioSource::addAudioData(LLAudioData *adp, const BOOL set_current) 1560void LLAudioSource::addAudioData(LLAudioData *adp, const bool set_current)
1401{ 1561{
1402 // Only handle a single piece of audio data associated with a source right now, 1562 // Only handle a single piece of audio data associated with a source right now,
1403 // until I implement prefetch. 1563 // until I implement prefetch.
@@ -1465,7 +1625,7 @@ void LLAudioSource::addAudioData(LLAudioData *adp, const BOOL set_current)
1465} 1625}
1466 1626
1467 1627
1468BOOL LLAudioSource::hasPendingPreloads() const 1628bool LLAudioSource::hasPendingPreloads() const
1469{ 1629{
1470 // Check to see if we've got any preloads on deck for this source 1630 // Check to see if we've got any preloads on deck for this source
1471 data_map::const_iterator iter; 1631 data_map::const_iterator iter;
@@ -1475,11 +1635,11 @@ BOOL LLAudioSource::hasPendingPreloads() const
1475 if (!adp->hasDecodedData()) 1635 if (!adp->hasDecodedData())
1476 { 1636 {
1477 // This source is still waiting for a preload 1637 // This source is still waiting for a preload
1478 return TRUE; 1638 return true;
1479 } 1639 }
1480 } 1640 }
1481 1641
1482 return FALSE; 1642 return false;
1483} 1643}
1484 1644
1485 1645
@@ -1514,8 +1674,9 @@ LLAudioBuffer *LLAudioSource::getCurrentBuffer()
1514LLAudioChannel::LLAudioChannel() : 1674LLAudioChannel::LLAudioChannel() :
1515 mCurrentSourcep(NULL), 1675 mCurrentSourcep(NULL),
1516 mCurrentBufferp(NULL), 1676 mCurrentBufferp(NULL),
1517 mLoopedThisFrame(FALSE), 1677 mLoopedThisFrame(false),
1518 mWaiting(FALSE) 1678 mWaiting(false),
1679 mSecondaryGain(1.0f)
1519{ 1680{
1520} 1681}
1521 1682
@@ -1523,7 +1684,7 @@ LLAudioChannel::LLAudioChannel() :
1523LLAudioChannel::~LLAudioChannel() 1684LLAudioChannel::~LLAudioChannel()
1524{ 1685{
1525 // Need to disconnect any sources which are using this channel. 1686 // Need to disconnect any sources which are using this channel.
1526 //llinfos << "Cleaning up audio channel" << llendl; 1687 //LL_INFOS("AudioEngine") << "Cleaning up audio channel" << llendl;
1527 if (mCurrentSourcep) 1688 if (mCurrentSourcep)
1528 { 1689 {
1529 mCurrentSourcep->setChannel(NULL); 1690 mCurrentSourcep->setChannel(NULL);
@@ -1534,22 +1695,22 @@ LLAudioChannel::~LLAudioChannel()
1534 1695
1535void LLAudioChannel::setSource(LLAudioSource *sourcep) 1696void LLAudioChannel::setSource(LLAudioSource *sourcep)
1536{ 1697{
1537 //llinfos << this << ": setSource(" << sourcep << ")" << llendl; 1698 //LL_INFOS("AudioEngine") << this << ": setSource(" << sourcep << ")" << llendl;
1538 1699
1539 if (!sourcep) 1700 if (!sourcep)
1540 { 1701 {
1541 // Clearing the source for this channel, don't need to do anything. 1702 // Clearing the source for this channel, don't need to do anything.
1542 //llinfos << "Clearing source for channel" << llendl; 1703 //LL_INFOS("AudioEngine") << "Clearing source for channel" << llendl;
1543 cleanup(); 1704 cleanup();
1544 mCurrentSourcep = NULL; 1705 mCurrentSourcep = NULL;
1545 mWaiting = FALSE; 1706 mWaiting = false;
1546 return; 1707 return;
1547 } 1708 }
1548 1709
1549 if (sourcep == mCurrentSourcep) 1710 if (sourcep == mCurrentSourcep)
1550 { 1711 {
1551 // Don't reallocate the channel, this will make FMOD goofy. 1712 // Don't reallocate the channel, this will make FMOD goofy.
1552 //llinfos << "Calling setSource with same source!" << llendl; 1713 //LL_INFOS("AudioEngine") << "Calling setSource with same source!" << llendl;
1553 } 1714 }
1554 1715
1555 mCurrentSourcep = sourcep; 1716 mCurrentSourcep = sourcep;
@@ -1558,13 +1719,13 @@ void LLAudioChannel::setSource(LLAudioSource *sourcep)
1558} 1719}
1559 1720
1560 1721
1561BOOL LLAudioChannel::updateBuffer() 1722bool LLAudioChannel::updateBuffer()
1562{ 1723{
1563 if (!mCurrentSourcep) 1724 if (!mCurrentSourcep)
1564 { 1725 {
1565 // This channel isn't associated with any source, nothing 1726 // This channel isn't associated with any source, nothing
1566 // to be updated 1727 // to be updated
1567 return FALSE; 1728 return false;
1568 } 1729 }
1569 1730
1570 LLAudioBuffer *bufferp = mCurrentSourcep->getCurrentBuffer(); 1731 LLAudioBuffer *bufferp = mCurrentSourcep->getCurrentBuffer();
@@ -1574,14 +1735,14 @@ BOOL LLAudioChannel::updateBuffer()
1574 { 1735 {
1575 // The source hasn't changed what buffer it's playing 1736 // The source hasn't changed what buffer it's playing
1576 bufferp->mLastUseTimer.reset(); 1737 bufferp->mLastUseTimer.reset();
1577 bufferp->mInUse = TRUE; 1738 bufferp->mInUse = true;
1578 } 1739 }
1579 return FALSE; 1740 return false;
1580 } 1741 }
1581 1742
1582 // 1743 //
1583 // The source changed what buffer it's playing. Whe need to clean up the 1744 // The source changed what buffer it's playing. We need to clean up
1584 // existing fmod channel 1745 // the existing channel
1585 // 1746 //
1586 cleanup(); 1747 cleanup();
1587 1748
@@ -1589,16 +1750,16 @@ BOOL LLAudioChannel::updateBuffer()
1589 if (bufferp) 1750 if (bufferp)
1590 { 1751 {
1591 bufferp->mLastUseTimer.reset(); 1752 bufferp->mLastUseTimer.reset();
1592 bufferp->mInUse = TRUE; 1753 bufferp->mInUse = true;
1593 } 1754 }
1594 1755
1595 if (!mCurrentBufferp) 1756 if (!mCurrentBufferp)
1596 { 1757 {
1597 // There's no new buffer to be played, so we just abort. 1758 // There's no new buffer to be played, so we just abort.
1598 return FALSE; 1759 return false;
1599 } 1760 }
1600 1761
1601 return TRUE; 1762 return true;
1602} 1763}
1603 1764
1604 1765
@@ -1612,9 +1773,9 @@ BOOL LLAudioChannel::updateBuffer()
1612LLAudioData::LLAudioData(const LLUUID &uuid) : 1773LLAudioData::LLAudioData(const LLUUID &uuid) :
1613 mID(uuid), 1774 mID(uuid),
1614 mBufferp(NULL), 1775 mBufferp(NULL),
1615 mHasLocalData(FALSE), 1776 mHasLocalData(false),
1616 mHasDecodedData(FALSE), 1777 mHasDecodedData(false),
1617 mHasValidData(TRUE) 1778 mHasValidData(true)
1618{ 1779{
1619 if (uuid.isNull()) 1780 if (uuid.isNull())
1620 { 1781 {
@@ -1625,32 +1786,32 @@ LLAudioData::LLAudioData(const LLUUID &uuid) :
1625 if (gAudiop && gAudiop->hasDecodedFile(uuid)) 1786 if (gAudiop && gAudiop->hasDecodedFile(uuid))
1626 { 1787 {
1627 // Already have a decoded version, don't need to decode it. 1788 // Already have a decoded version, don't need to decode it.
1628 mHasLocalData = TRUE; 1789 mHasLocalData = true;
1629 mHasDecodedData = TRUE; 1790 mHasDecodedData = true;
1630 } 1791 }
1631 else if (gAssetStorage && gAssetStorage->hasLocalAsset(uuid, LLAssetType::AT_SOUND)) 1792 else if (gAssetStorage && gAssetStorage->hasLocalAsset(uuid, LLAssetType::AT_SOUND))
1632 { 1793 {
1633 mHasLocalData = TRUE; 1794 mHasLocalData = true;
1634 } 1795 }
1635} 1796}
1636 1797
1637 1798
1638BOOL LLAudioData::load() 1799bool LLAudioData::load()
1639{ 1800{
1640 // For now, just assume we're going to use one buffer per audiodata. 1801 // For now, just assume we're going to use one buffer per audiodata.
1641 if (mBufferp) 1802 if (mBufferp)
1642 { 1803 {
1643 // We already have this sound in a buffer, don't do anything. 1804 // 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; 1805 LL_INFOS("AudioEngine") << "Already have a buffer for this sound, don't bother loading!" << llendl;
1645 return TRUE; 1806 return true;
1646 } 1807 }
1647 1808
1648 mBufferp = gAudiop->getFreeBuffer(); 1809 mBufferp = gAudiop->getFreeBuffer();
1649 if (!mBufferp) 1810 if (!mBufferp)
1650 { 1811 {
1651 // No free buffers, abort. 1812 // No free buffers, abort.
1652 llinfos << "Not able to allocate a new audio buffer, aborting." << llendl; 1813 LL_INFOS("AudioEngine") << "Not able to allocate a new audio buffer, aborting." << llendl;
1653 return FALSE; 1814 return false;
1654 } 1815 }
1655 1816
1656 std::string uuid_str; 1817 std::string uuid_str;
@@ -1664,10 +1825,10 @@ BOOL LLAudioData::load()
1664 gAudiop->cleanupBuffer(mBufferp); 1825 gAudiop->cleanupBuffer(mBufferp);
1665 mBufferp = NULL; 1826 mBufferp = NULL;
1666 1827
1667 return FALSE; 1828 return false;
1668 } 1829 }
1669 mBufferp->mAudioDatap = this; 1830 mBufferp->mAudioDatap = this;
1670 return TRUE; 1831 return true;
1671} 1832}
1672 1833
1673 1834
diff --git a/linden/indra/llaudio/audioengine.h b/linden/indra/llaudio/audioengine.h
index e38413f..15cb35f 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;
@@ -67,6 +69,7 @@ class LLVFS;
67class LLAudioSource; 69class LLAudioSource;
68class LLAudioData; 70class LLAudioData;
69class LLAudioChannel; 71class LLAudioChannel;
72class LLAudioChannelOpenAL;
70class LLAudioBuffer; 73class LLAudioBuffer;
71 74
72 75
@@ -77,14 +80,24 @@ class LLAudioBuffer;
77 80
78class LLAudioEngine 81class LLAudioEngine
79{ 82{
83 friend class LLAudioChannelOpenAL; // bleh. channel needs some listener methods.
84
80public: 85public:
86 enum LLAudioType
87 {
88 AUDIO_TYPE_NONE = 0,
89 AUDIO_TYPE_SFX = 1,
90 AUDIO_TYPE_UI = 2,
91 AUDIO_TYPE_AMBIENT = 3,
92 AUDIO_TYPE_COUNT = 4 // last
93 };
94
81 LLAudioEngine(); 95 LLAudioEngine();
82 virtual ~LLAudioEngine(); 96 virtual ~LLAudioEngine();
83 97
84 // initialization/startup/shutdown 98 // initialization/startup/shutdown
85 //virtual BOOL init(); 99 virtual bool init(const S32 num_channels, void *userdata);
86 100 virtual std::string getDriverName(bool verbose) = 0;
87 virtual BOOL init(const S32 num_channels, void *userdata);
88 virtual void shutdown(); 101 virtual void shutdown();
89 102
90 // Used by the mechanics of the engine 103 // Used by the mechanics of the engine
@@ -97,18 +110,21 @@ public:
97 // 110 //
98 // "End user" functionality 111 // "End user" functionality
99 // 112 //
100 virtual BOOL isWindEnabled(); 113 virtual bool isWindEnabled();
101 virtual void enableWind(BOOL state_b); 114 virtual void enableWind(bool state_b);
102 115
103 // Use these for temporarily muting the audio system. 116 // Use these for temporarily muting the audio system.
104 // Does not change buffers, initialization, etc. but 117 // Does not change buffers, initialization, etc. but
105 // stops playing new sounds. 118 // stops playing new sounds.
106 virtual void setMuted(BOOL muted); 119 virtual void setMuted(bool muted);
107 virtual BOOL getMuted() const { return mMuted; } 120 virtual bool getMuted() const { return mMuted; }
108 121
109 F32 getMasterGain(); 122 F32 getMasterGain();
110 void setMasterGain(F32 gain); 123 void setMasterGain(F32 gain);
111 124
125 F32 getSecondaryGain(S32 type);
126 void setSecondaryGain(S32 type, F32 gain);
127
112 F32 getInternetStreamGain(); 128 F32 getInternetStreamGain();
113 129
114 virtual void setDopplerFactor(F32 factor); 130 virtual void setDopplerFactor(F32 factor);
@@ -122,8 +138,10 @@ public:
122 138
123 // Methods actually related to setting up and removing sounds 139 // Methods actually related to setting up and removing sounds
124 // Owner ID is the owner of the object making the request 140 // 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); 141 void triggerSound(const LLUUID &sound_id, const LLUUID& owner_id, const F32 gain,
126 BOOL preloadSound(const LLUUID &id); 142 const S32 type = LLAudioEngine::AUDIO_TYPE_NONE,
143 const LLVector3d &pos_global = LLVector3d::zero);
144 bool preloadSound(const LLUUID &id);
127 145
128 void addAudioSource(LLAudioSource *asp); 146 void addAudioSource(LLAudioSource *asp);
129 void cleanupAudioSource(LLAudioSource *asp); 147 void cleanupAudioSource(LLAudioSource *asp);
@@ -132,14 +150,16 @@ public:
132 LLAudioData *getAudioData(const LLUUID &audio_uuid); 150 LLAudioData *getAudioData(const LLUUID &audio_uuid);
133 151
134 152
135 virtual void startInternetStream(const std::string& url) = 0; 153 // Internet stream methods
136 virtual void stopInternetStream() = 0; 154 virtual void startInternetStream(const std::string& url);
137 virtual void pauseInternetStream(int pause) = 0; 155 virtual void stopInternetStream();
138 virtual int isInternetStreamPlaying() = 0; 156 virtual void pauseInternetStream(int pause);
139 virtual void getInternetStreamInfo(char* artist, char* title) { artist[0] = 0; title[0] = 0; } 157 virtual void updateInternetStream();
158 virtual int isInternetStreamPlaying();
159 virtual void getInternetStreamInfo(char* artist, char* title);
140 // use a value from 0.0 to 1.0, inclusive 160 // use a value from 0.0 to 1.0, inclusive
141 virtual void setInternetStreamGain(F32 vol) { mInternetStreamGain = vol; } 161 virtual void setInternetStreamGain(F32 vol);
142 virtual const std::string& getInternetStreamURL() { return LLStringUtil::null; } 162 virtual const std::string& getInternetStreamURL();
143 163
144 // For debugging usage 164 // For debugging usage
145 virtual LLVector3 getListenerPos(); 165 virtual LLVector3 getListenerPos();
@@ -148,17 +168,16 @@ public:
148 LLAudioChannel *getFreeChannel(const F32 priority); // Get a free channel or flush an existing one if your priority is higher 168 LLAudioChannel *getFreeChannel(const F32 priority); // Get a free channel or flush an existing one if your priority is higher
149 void cleanupBuffer(LLAudioBuffer *bufferp); 169 void cleanupBuffer(LLAudioBuffer *bufferp);
150 170
151 BOOL hasDecodedFile(const LLUUID &uuid); 171 bool hasDecodedFile(const LLUUID &uuid);
152 BOOL hasLocalFile(const LLUUID &uuid); 172 bool hasLocalFile(const LLUUID &uuid);
153 173
154 BOOL updateBufferForData(LLAudioData *adp, const LLUUID &audio_uuid = LLUUID::null); 174 bool updateBufferForData(LLAudioData *adp, const LLUUID &audio_uuid = LLUUID::null);
155 175
156 176
157 // Asset callback when we're retrieved a sound from the asset server. 177 // Asset callback when we're retrieved a sound from the asset server.
158 void startNextTransfer(); 178 void startNextTransfer();
159 static void assetCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type, void *user_data, S32 result_code, LLExtStat ext_status); 179 static void assetCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type, void *user_data, S32 result_code, LLExtStat ext_status);
160 180
161
162 friend class LLPipeline; // For debugging 181 friend class LLPipeline; // For debugging
163public: 182public:
164 F32 mMaxWindGain; // Hack. Public to set before fade in? 183 F32 mMaxWindGain; // Hack. Public to set before fade in?
@@ -176,11 +195,6 @@ protected:
176 virtual void allocateListener() = 0; 195 virtual void allocateListener() = 0;
177 196
178 197
179 // Internet stream methods
180 virtual void initInternetStream() {}
181 virtual void updateInternetStream() {}
182
183
184 // listener methods 198 // listener methods
185 virtual void setListenerPos(LLVector3 vec); 199 virtual void setListenerPos(LLVector3 vec);
186 virtual void setListenerVelocity(LLVector3 vec); 200 virtual void setListenerVelocity(LLVector3 vec);
@@ -195,13 +209,13 @@ protected:
195protected: 209protected:
196 LLListener *mListenerp; 210 LLListener *mListenerp;
197 211
198 BOOL mMuted; 212 bool mMuted;
199 void* mUserData; 213 void* mUserData;
200 214
201 S32 mLastStatus; 215 S32 mLastStatus;
202 216
203 S32 mNumChannels; 217 S32 mNumChannels;
204 BOOL mEnableWind; 218 bool mEnableWind;
205 219
206 LLUUID mCurrentTransfer; // Audio file currently being transferred by the system 220 LLUUID mCurrentTransfer; // Audio file currently being transferred by the system
207 LLFrameTimer mCurrentTransferTimer; 221 LLFrameTimer mCurrentTransferTimer;
@@ -222,9 +236,11 @@ protected:
222 LLAudioBuffer *mBuffers[MAX_BUFFERS]; 236 LLAudioBuffer *mBuffers[MAX_BUFFERS];
223 237
224 F32 mMasterGain; 238 F32 mMasterGain;
239 F32 mSecondaryGain[AUDIO_TYPE_COUNT];
225 240
226 // Hack! Internet streams are treated differently from other sources! 241 // Hack! Internet streams are treated differently from other sources!
227 F32 mInternetStreamGain; 242 F32 mInternetStreamGain;
243 std::string mInternetStreamURL;
228 244
229 F32 mNextWindUpdate; 245 F32 mNextWindUpdate;
230 246
@@ -232,6 +248,7 @@ protected:
232 248
233private: 249private:
234 void setDefaults(); 250 void setDefaults();
251 LLMediaBase *mInternetStreamMedia;
235}; 252};
236 253
237 254
@@ -247,7 +264,7 @@ class LLAudioSource
247public: 264public:
248 // owner_id is the id of the agent responsible for making this sound 265 // owner_id is the id of the agent responsible for making this sound
249 // play, for example, the owner of the object currently playing it 266 // play, for example, the owner of the object currently playing it
250 LLAudioSource(const LLUUID &id, const LLUUID& owner_id, const F32 gain); 267 LLAudioSource(const LLUUID &id, const LLUUID& owner_id, const F32 gain, const S32 type = LLAudioEngine::AUDIO_TYPE_NONE);
251 virtual ~LLAudioSource(); 268 virtual ~LLAudioSource();
252 269
253 virtual void update(); // Update this audio source 270 virtual void update(); // Update this audio source
@@ -255,24 +272,27 @@ public:
255 272
256 void preload(const LLUUID &audio_id); // Only used for preloading UI sounds, now. 273 void preload(const LLUUID &audio_id); // Only used for preloading UI sounds, now.
257 274
258 void addAudioData(LLAudioData *adp, BOOL set_current = TRUE); 275 void addAudioData(LLAudioData *adp, bool set_current = TRUE);
276
277 void setAmbient(const bool ambient) { mAmbient = ambient; }
278 bool isAmbient() const { return mAmbient; }
259 279
260 void setAmbient(const BOOL ambient) { mAmbient = ambient; } 280 void setLoop(const bool loop) { mLoop = loop; }
261 BOOL isAmbient() const { return mAmbient; } 281 bool isLoop() const { return mLoop; }
262 282
263 void setLoop(const BOOL loop) { mLoop = loop; } 283 void setSyncMaster(const bool master) { mSyncMaster = master; }
264 BOOL isLoop() const { return mLoop; } 284 bool isSyncMaster() const { return mSyncMaster; }
265 285
266 void setSyncMaster(const BOOL master) { mSyncMaster = master; } 286 void setSyncSlave(const bool slave) { mSyncSlave = slave; }
267 BOOL isSyncMaster() const { return mSyncMaster; } 287 bool isSyncSlave() const { return mSyncSlave; }
268 288
269 void setSyncSlave(const BOOL slave) { mSyncSlave = slave; } 289 void setQueueSounds(const bool queue) { mQueueSounds = queue; }
270 BOOL isSyncSlave() const { return mSyncSlave; } 290 bool isQueueSounds() const { return mQueueSounds; }
271 291
272 void setQueueSounds(const BOOL queue) { mQueueSounds = queue; } 292 void setPlayedOnce(const bool played_once) { mPlayedOnce = played_once; }
273 BOOL isQueueSounds() const { return mQueueSounds; }
274 293
275 void setPlayedOnce(const BOOL played_once) { mPlayedOnce = played_once; } 294 void setType(S32 type) { mType = type; }
295 S32 getType() { return mType; }
276 296
277 void setPositionGlobal(const LLVector3d &position_global) { mPositionGlobal = position_global; } 297 void setPositionGlobal(const LLVector3d &position_global) { mPositionGlobal = position_global; }
278 LLVector3d getPositionGlobal() const { return mPositionGlobal; } 298 LLVector3d getPositionGlobal() const { return mPositionGlobal; }
@@ -284,16 +304,16 @@ public:
284 virtual void setGain(const F32 gain) { mGain = llclamp(gain, 0.f, 1.f); } 304 virtual void setGain(const F32 gain) { mGain = llclamp(gain, 0.f, 1.f); }
285 305
286 const LLUUID &getID() const { return mID; } 306 const LLUUID &getID() const { return mID; }
287 BOOL isDone(); 307 bool isDone();
288 308
289 LLAudioData *getCurrentData(); 309 LLAudioData *getCurrentData();
290 LLAudioData *getQueuedData(); 310 LLAudioData *getQueuedData();
291 LLAudioBuffer *getCurrentBuffer(); 311 LLAudioBuffer *getCurrentBuffer();
292 312
293 BOOL setupChannel(); 313 bool setupChannel();
294 BOOL play(const LLUUID &audio_id); // Start the audio source playing 314 bool play(const LLUUID &audio_id); // Start the audio source playing
295 315
296 BOOL hasPendingPreloads() const; // Has preloads that haven't been done yet 316 bool hasPendingPreloads() const; // Has preloads that haven't been done yet
297 317
298 friend class LLAudioEngine; 318 friend class LLAudioEngine;
299 friend class LLAudioChannel; 319 friend class LLAudioChannel;
@@ -306,12 +326,13 @@ protected:
306 LLUUID mOwnerID; // owner of the object playing the sound 326 LLUUID mOwnerID; // owner of the object playing the sound
307 F32 mPriority; 327 F32 mPriority;
308 F32 mGain; 328 F32 mGain;
309 BOOL mAmbient; 329 bool mAmbient;
310 BOOL mLoop; 330 bool mLoop;
311 BOOL mSyncMaster; 331 bool mSyncMaster;
312 BOOL mSyncSlave; 332 bool mSyncSlave;
313 BOOL mQueueSounds; 333 bool mQueueSounds;
314 BOOL mPlayedOnce; 334 bool mPlayedOnce;
335 S32 mType;
315 LLVector3d mPositionGlobal; 336 LLVector3d mPositionGlobal;
316 LLVector3 mVelocity; 337 LLVector3 mVelocity;
317 338
@@ -340,27 +361,27 @@ class LLAudioData
340{ 361{
341public: 362public:
342 LLAudioData(const LLUUID &uuid); 363 LLAudioData(const LLUUID &uuid);
343 BOOL load(); 364 bool load();
344 365
345 LLUUID getID() const { return mID; } 366 LLUUID getID() const { return mID; }
346 LLAudioBuffer *getBuffer() const { return mBufferp; } 367 LLAudioBuffer *getBuffer() const { return mBufferp; }
347 368
348 BOOL hasLocalData() const { return mHasLocalData; } 369 bool hasLocalData() const { return mHasLocalData; }
349 BOOL hasDecodedData() const { return mHasDecodedData; } 370 bool hasDecodedData() const { return mHasDecodedData; }
350 BOOL hasValidData() const { return mHasValidData; } 371 bool hasValidData() const { return mHasValidData; }
351 372
352 void setHasLocalData(const BOOL hld) { mHasLocalData = hld; } 373 void setHasLocalData(const bool hld) { mHasLocalData = hld; }
353 void setHasDecodedData(const BOOL hdd) { mHasDecodedData = hdd; } 374 void setHasDecodedData(const bool hdd) { mHasDecodedData = hdd; }
354 void setHasValidData(const BOOL hvd) { mHasValidData = hvd; } 375 void setHasValidData(const bool hvd) { mHasValidData = hvd; }
355 376
356 friend class LLAudioEngine; // Severe laziness, bad. 377 friend class LLAudioEngine; // Severe laziness, bad.
357 378
358protected: 379protected:
359 LLUUID mID; 380 LLUUID mID;
360 LLAudioBuffer *mBufferp; // If this data is being used by the audio system, a pointer to the buffer will be set here. 381 LLAudioBuffer *mBufferp; // If this data is being used by the audio system, a pointer to the buffer will be set here.
361 BOOL mHasLocalData; 382 bool mHasLocalData;
362 BOOL mHasDecodedData; 383 bool mHasDecodedData;
363 BOOL mHasValidData; 384 bool mHasValidData;
364}; 385};
365 386
366 387
@@ -380,24 +401,28 @@ public:
380 virtual void setSource(LLAudioSource *sourcep); 401 virtual void setSource(LLAudioSource *sourcep);
381 LLAudioSource *getSource() const { return mCurrentSourcep; } 402 LLAudioSource *getSource() const { return mCurrentSourcep; }
382 403
404 void setSecondaryGain(F32 gain) { mSecondaryGain = gain; }
405 F32 getSecondaryGain() { return mSecondaryGain; }
406
383 friend class LLAudioEngine; 407 friend class LLAudioEngine;
384 friend class LLAudioSource; 408 friend class LLAudioSource;
385protected: 409protected:
386 virtual void play() = 0; 410 virtual void play() = 0;
387 virtual void playSynced(LLAudioChannel *channelp) = 0; 411 virtual void playSynced(LLAudioChannel *channelp) = 0;
388 virtual void cleanup() = 0; 412 virtual void cleanup() = 0;
389 virtual BOOL isPlaying() = 0; 413 virtual bool isPlaying() = 0;
390 void setWaiting(const BOOL waiting) { mWaiting = waiting; } 414 void setWaiting(const bool waiting) { mWaiting = waiting; }
391 BOOL isWaiting() const { return mWaiting; } 415 bool isWaiting() const { return mWaiting; }
392 416
393 virtual BOOL updateBuffer(); // Check to see if the buffer associated with the source changed, and update if necessary. 417 virtual bool updateBuffer(); // Check to see if the buffer associated with the source changed, and update if necessary.
394 virtual void update3DPosition() = 0; 418 virtual void update3DPosition() = 0;
395 virtual void updateLoop() = 0; // Update your loop/completion status, for use by queueing/syncing. 419 virtual void updateLoop() = 0; // Update your loop/completion status, for use by queueing/syncing.
396protected: 420protected:
397 LLAudioSource *mCurrentSourcep; 421 LLAudioSource *mCurrentSourcep;
398 LLAudioBuffer *mCurrentBufferp; 422 LLAudioBuffer *mCurrentBufferp;
399 BOOL mLoopedThisFrame; 423 bool mLoopedThisFrame;
400 BOOL mWaiting; // Waiting for sync. 424 bool mWaiting; // Waiting for sync.
425 F32 mSecondaryGain;
401}; 426};
402 427
403 428
@@ -412,14 +437,14 @@ class LLAudioBuffer
412{ 437{
413public: 438public:
414 virtual ~LLAudioBuffer() {}; 439 virtual ~LLAudioBuffer() {};
415 virtual BOOL loadWAV(const std::string& filename) = 0; 440 virtual bool loadWAV(const std::string& filename) = 0;
416 virtual U32 getLength() = 0; 441 virtual U32 getLength() = 0;
417 442
418 friend class LLAudioEngine; 443 friend class LLAudioEngine;
419 friend class LLAudioChannel; 444 friend class LLAudioChannel;
420 friend class LLAudioData; 445 friend class LLAudioData;
421protected: 446protected:
422 BOOL mInUse; 447 bool mInUse;
423 LLAudioData *mAudioDatap; 448 LLAudioData *mAudioDatap;
424 LLFrameTimer mLastUseTimer; 449 LLFrameTimer mLastUseTimer;
425}; 450};
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..f13a5fa
--- /dev/null
+++ b/linden/indra/llaudio/audioengine_openal.cpp
@@ -0,0 +1,544 @@
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://secondlifegrid.net/programs/open_source/licensing/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://secondlifegrid.net/programs/open_source/licensing/flossexception
22 *
23 * By copying, modifying or distributing this software, you acknowledge
24 * that you have read and understood your obligations described above,
25 * and agree to abide by those obligations.
26 *
27 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
28 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
29 * COMPLETENESS OR PERFORMANCE.
30 * $/LicenseInfo$
31 */
32
33#include "linden_common.h"
34#include "lldir.h"
35
36#include "audioengine_openal.h"
37#include "listener_openal.h"
38
39
40LLAudioEngine_OpenAL::LLAudioEngine_OpenAL()
41 :
42 mWindGen(NULL),
43 mWindBuf(NULL),
44 mWindBufFreq(0),
45 mWindBufSamples(0),
46 mWindBufBytes(0),
47 mWindSource(AL_NONE),
48 mNumEmptyWindALBuffers(MAX_NUM_WIND_BUFFERS)
49{
50}
51
52// virtual
53LLAudioEngine_OpenAL::~LLAudioEngine_OpenAL()
54{
55}
56
57// virtual
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 LL_WARNS("OpenAL") << "LLAudioEngine_OpenAL::init() ALUT initialization failed: " << alutGetErrorString (alutGetError ()) << LL_ENDL;
66 return false;
67 }
68
69 LL_INFOS("OpenAL") << "LLAudioEngine_OpenAL::init() OpenAL successfully initialized" << LL_ENDL;
70
71 LL_INFOS("OpenAL") << "OpenAL version: "
72 << ll_safe_string(alGetString(AL_VERSION)) << LL_ENDL;
73 LL_INFOS("OpenAL") << "OpenAL vendor: "
74 << ll_safe_string(alGetString(AL_VENDOR)) << LL_ENDL;
75 LL_INFOS("OpenAL") << "OpenAL renderer: "
76 << ll_safe_string(alGetString(AL_RENDERER)) << LL_ENDL;
77
78 ALint major = alutGetMajorVersion ();
79 ALint minor = alutGetMinorVersion ();
80 LL_INFOS("OpenAL") << "ALUT version: " << major << "." << minor << LL_ENDL;
81
82 ALCdevice *device = alcGetContextsDevice(alcGetCurrentContext());
83
84 alcGetIntegerv(device, ALC_MAJOR_VERSION, 1, &major);
85 alcGetIntegerv(device, ALC_MAJOR_VERSION, 1, &minor);
86 LL_INFOS("OpenAL") << "ALC version: " << major << "." << minor << LL_ENDL;
87
88 LL_INFOS("OpenAL") << "ALC default device: "
89 << ll_safe_string(alcGetString(device,
90 ALC_DEFAULT_DEVICE_SPECIFIER))
91 << LL_ENDL;
92
93 return true;
94}
95
96// virtual
97std::string LLAudioEngine_OpenAL::getDriverName(bool verbose)
98{
99 ALCdevice *device = alcGetContextsDevice(alcGetCurrentContext());
100 std::ostringstream version;
101
102 version <<
103 "OpenAL";
104
105 if (verbose)
106 {
107 version <<
108 ", version " <<
109 ll_safe_string(alGetString(AL_VERSION)) <<
110 " / " <<
111 ll_safe_string(alGetString(AL_VENDOR)) <<
112 " / " <<
113 ll_safe_string(alGetString(AL_RENDERER));
114
115 if (device)
116 version <<
117 ": " <<
118 ll_safe_string(alcGetString(device,
119 ALC_DEFAULT_DEVICE_SPECIFIER));
120 }
121
122 return version.str();
123}
124
125// virtual
126void LLAudioEngine_OpenAL::allocateListener()
127{
128 mListenerp = (LLListener *) new LLListener_OpenAL();
129 if(!mListenerp)
130 {
131 LL_WARNS("OpenAL") << "LLAudioEngine_OpenAL::allocateListener() Listener creation failed" << LL_ENDL;
132 }
133}
134
135// virtual
136void LLAudioEngine_OpenAL::shutdown()
137{
138 LL_INFOS("OpenAL") << "About to LLAudioEngine::shutdown()" << LL_ENDL;
139 LLAudioEngine::shutdown();
140
141 LL_INFOS("OpenAL") << "About to alutExit()" << LL_ENDL;
142 if(!alutExit())
143 {
144 LL_WARNS("OpenAL") << "Nuts." << LL_ENDL;
145 LL_WARNS("OpenAL") << "LLAudioEngine_OpenAL::shutdown() ALUT shutdown failed: " << alutGetErrorString (alutGetError ()) << LL_ENDL;
146 }
147
148 LL_INFOS("OpenAL") << "LLAudioEngine_OpenAL::shutdown() OpenAL successfully shut down" << LL_ENDL;
149
150 delete mListenerp;
151 mListenerp = NULL;
152}
153
154LLAudioBuffer *LLAudioEngine_OpenAL::createBuffer()
155{
156 return new LLAudioBufferOpenAL();
157}
158
159LLAudioChannel *LLAudioEngine_OpenAL::createChannel()
160{
161 return new LLAudioChannelOpenAL();
162}
163
164void LLAudioEngine_OpenAL::setInternalGain(F32 gain)
165{
166 //LL_INFOS("OpenAL") << "LLAudioEngine_OpenAL::setInternalGain() Gain: " << gain << LL_ENDL;
167 alListenerf(AL_GAIN, gain);
168}
169
170LLAudioChannelOpenAL::LLAudioChannelOpenAL()
171 :
172 mALSource(AL_NONE),
173 mLastSamplePos(0)
174{
175 alGenSources(1, &mALSource);
176}
177
178LLAudioChannelOpenAL::~LLAudioChannelOpenAL()
179{
180 cleanup();
181 alDeleteSources(1, &mALSource);
182}
183
184void LLAudioChannelOpenAL::cleanup()
185{
186 alSourceStop(mALSource);
187 mCurrentBufferp = NULL;
188}
189
190void LLAudioChannelOpenAL::play()
191{
192 if (mALSource == AL_NONE)
193 {
194 LL_WARNS("OpenAL") << "Playing without a mALSource, aborting" << LL_ENDL;
195 return;
196 }
197
198 if(!isPlaying())
199 {
200 alSourcePlay(mALSource);
201 getSource()->setPlayedOnce(true);
202 }
203}
204
205void LLAudioChannelOpenAL::playSynced(LLAudioChannel *channelp)
206{
207 if (channelp)
208 {
209 LLAudioChannelOpenAL *masterchannelp =
210 (LLAudioChannelOpenAL*)channelp;
211 if (mALSource != AL_NONE &&
212 masterchannelp->mALSource != AL_NONE)
213 {
214 // we have channels allocated to master and slave
215 ALfloat master_offset;
216 alGetSourcef(masterchannelp->mALSource, AL_SEC_OFFSET,
217 &master_offset);
218
219 LL_INFOS("OpenAL") << "Syncing with master at " << master_offset
220 << "sec" << LL_ENDL;
221 // *TODO: detect when this fails, maybe use AL_SAMPLE_
222 alSourcef(mALSource, AL_SEC_OFFSET, master_offset);
223 }
224 }
225 play();
226}
227
228bool LLAudioChannelOpenAL::isPlaying()
229{
230 if (mALSource != AL_NONE)
231 {
232 ALint state;
233 alGetSourcei(mALSource, AL_SOURCE_STATE, &state);
234 if(state == AL_PLAYING)
235 {
236 return true;
237 }
238 }
239
240 return false;
241}
242
243bool LLAudioChannelOpenAL::updateBuffer()
244{
245 if (LLAudioChannel::updateBuffer())
246 {
247 // Base class update returned true, which means that we need to actually
248 // set up the source for a different buffer.
249 LLAudioBufferOpenAL *bufferp = (LLAudioBufferOpenAL *)mCurrentSourcep->getCurrentBuffer();
250 ALuint buffer = bufferp->getBuffer();
251 alSourcei(mALSource, AL_BUFFER, buffer);
252 mLastSamplePos = 0;
253 }
254
255 if (mCurrentSourcep)
256 {
257 alSourcef(mALSource, AL_GAIN,
258 mCurrentSourcep->getGain() * getSecondaryGain());
259 alSourcei(mALSource, AL_LOOPING,
260 mCurrentSourcep->isLoop() ? AL_TRUE : AL_FALSE);
261 alSourcef(mALSource, AL_ROLLOFF_FACTOR,
262 gAudiop->mListenerp->getRolloffFactor());
263 alSourcef(mALSource, AL_REFERENCE_DISTANCE,
264 gAudiop->mListenerp->getDistanceFactor());
265 }
266
267 return true;
268}
269
270
271void LLAudioChannelOpenAL::updateLoop()
272{
273 if (mALSource == AL_NONE)
274 {
275 return;
276 }
277
278 // Hack: We keep track of whether we looped or not by seeing when the
279 // sample position looks like it's going backwards. Not reliable; may
280 // yield false negatives.
281 //
282 ALint cur_pos;
283 alGetSourcei(mALSource, AL_SAMPLE_OFFSET, &cur_pos);
284 if (cur_pos < mLastSamplePos)
285 {
286 mLoopedThisFrame = true;
287 }
288 mLastSamplePos = cur_pos;
289}
290
291
292void LLAudioChannelOpenAL::update3DPosition()
293{
294 if(!mCurrentSourcep)
295 {
296 return;
297 }
298 if (mCurrentSourcep->isAmbient())
299 {
300 alSource3f(mALSource, AL_POSITION, 0.0, 0.0, 0.0);
301 alSource3f(mALSource, AL_VELOCITY, 0.0, 0.0, 0.0);
302 //alSource3f(mALSource, AL_DIRECTION, 0.0, 0.0, 0.0);
303 alSourcei (mALSource, AL_SOURCE_RELATIVE, AL_TRUE);
304 } else {
305 LLVector3 float_pos;
306 float_pos.setVec(mCurrentSourcep->getPositionGlobal());
307 alSourcefv(mALSource, AL_POSITION, float_pos.mV);
308 alSourcefv(mALSource, AL_VELOCITY, mCurrentSourcep->getVelocity().mV);
309 //alSource3f(mALSource, AL_DIRECTION, 0.0, 0.0, 0.0);
310 alSourcei (mALSource, AL_SOURCE_RELATIVE, AL_FALSE);
311 }
312
313 alSourcef(mALSource, AL_GAIN, mCurrentSourcep->getGain() * getSecondaryGain());
314}
315
316LLAudioBufferOpenAL::LLAudioBufferOpenAL()
317{
318 mALBuffer = AL_NONE;
319}
320
321LLAudioBufferOpenAL::~LLAudioBufferOpenAL()
322{
323 cleanup();
324}
325
326void LLAudioBufferOpenAL::cleanup()
327{
328 if(mALBuffer != AL_NONE)
329 {
330 alDeleteBuffers(1, &mALBuffer);
331 mALBuffer = AL_NONE;
332 }
333}
334
335bool LLAudioBufferOpenAL::loadWAV(const std::string& filename)
336{
337 cleanup();
338 mALBuffer = alutCreateBufferFromFile(filename.c_str());
339 if(mALBuffer == AL_NONE)
340 {
341 ALenum error = alutGetError();
342 if (gDirUtilp->fileExists(filename))
343 {
344 LL_WARNS("OpenAL") <<
345 "LLAudioBufferOpenAL::loadWAV() Error loading "
346 << filename
347 << " " << alutGetErrorString(error) << LL_ENDL;
348 }
349 else
350 {
351 // It's common for the file to not actually exist.
352 LL_DEBUGS("OpenAL") <<
353 "LLAudioBufferOpenAL::loadWAV() Error loading "
354 << filename
355 << " " << alutGetErrorString(error) << LL_ENDL;
356 }
357 return false;
358 }
359
360 return true;
361}
362
363U32 LLAudioBufferOpenAL::getLength()
364{
365 if(mALBuffer == AL_NONE)
366 {
367 return 0;
368 }
369 ALint length;
370 alGetBufferi(mALBuffer, AL_SIZE, &length);
371 return length >> 2;
372}
373
374// ------------
375
376void LLAudioEngine_OpenAL::initWind()
377{
378 ALenum error;
379 LL_INFOS("OpenAL") << "LLAudioEngine_OpenAL::initWind() start" << LL_ENDL;
380
381 mNumEmptyWindALBuffers = MAX_NUM_WIND_BUFFERS;
382
383 alGetError(); /* clear error */
384
385 alGenSources(1,&mWindSource);
386
387 if((error=alGetError()) != AL_NO_ERROR)
388 {
389 LL_WARNS("OpenAL") << "LLAudioEngine_OpenAL::initWind() Error creating wind sources: "<<error<<LL_ENDL;
390 }
391
392 mWindGen = new LLWindGen<WIND_SAMPLE_T>;
393
394 mWindBufFreq = mWindGen->getInputSamplingRate();
395 mWindBufSamples = llceil(mWindBufFreq * WIND_BUFFER_SIZE_SEC);
396 mWindBufBytes = mWindBufSamples * 2 /*stereo*/ * sizeof(WIND_SAMPLE_T);
397
398 mWindBuf = new WIND_SAMPLE_T [mWindBufSamples * 2 /*stereo*/];
399
400 if(mWindBuf==NULL)
401 {
402 LL_ERRS("OpenAL") << "LLAudioEngine_OpenAL::initWind() Error creating wind memory buffer" << LL_ENDL;
403 mEnableWind=false;
404 }
405
406 LL_INFOS("OpenAL") << "LLAudioEngine_OpenAL::initWind() done" << LL_ENDL;
407}
408
409void LLAudioEngine_OpenAL::cleanupWind()
410{
411 LL_INFOS("OpenAL") << "LLAudioEngine_OpenAL::cleanupWind()" << LL_ENDL;
412
413 if (mWindSource != AL_NONE)
414 {
415 // detach and delete all outstanding buffers on the wind source
416 alSourceStop(mWindSource);
417 int processed;
418 alGetSourcei(mWindSource, AL_BUFFERS_PROCESSED, &processed);
419 while (processed--)
420 {
421 ALuint buffer = AL_NONE;
422 alSourceUnqueueBuffers(mWindSource, 1, &buffer);
423 alDeleteBuffers(1, &buffer);
424 }
425
426 // delete the wind source itself
427 alDeleteSources(1, &mWindSource);
428
429 mWindSource = AL_NONE;
430 }
431
432 delete[] mWindBuf;
433 mWindBuf = NULL;
434
435 delete mWindGen;
436 mWindGen = NULL;
437}
438
439void LLAudioEngine_OpenAL::updateWind(LLVector3 wind_vec, F32 camera_altitude)
440{
441 LLVector3 wind_pos;
442 F64 pitch;
443 F64 center_freq;
444 ALenum error;
445
446 if (!mEnableWind)
447 return;
448
449 if(!mWindBuf)
450 return;
451
452 if (mWindUpdateTimer.checkExpirationAndReset(LL_WIND_UPDATE_INTERVAL))
453 {
454
455 // wind comes in as Linden coordinate (+X = forward, +Y = left, +Z = up)
456 // need to convert this to the conventional orientation DS3D and OpenAL use
457 // where +X = right, +Y = up, +Z = backwards
458
459 wind_vec.setVec(-wind_vec.mV[1], wind_vec.mV[2], -wind_vec.mV[0]);
460
461 pitch = 1.0 + mapWindVecToPitch(wind_vec);
462 center_freq = 80.0 * pow(pitch,2.5*(mapWindVecToGain(wind_vec)+1.0));
463
464 mWindGen->mTargetFreq = (F32)center_freq;
465 mWindGen->mTargetGain = (F32)mapWindVecToGain(wind_vec) * mMaxWindGain;
466 mWindGen->mTargetPanGainR = (F32)mapWindVecToPan(wind_vec);
467
468 alSourcei(mWindSource, AL_LOOPING, AL_FALSE);
469 alSource3f(mWindSource, AL_POSITION, 0.0, 0.0, 0.0);
470 alSource3f(mWindSource, AL_VELOCITY, 0.0, 0.0, 0.0);
471 alSourcef(mWindSource, AL_ROLLOFF_FACTOR, 0.0);
472 alSourcei(mWindSource, AL_SOURCE_RELATIVE, AL_TRUE);
473 }
474
475 // ok lets make a wind buffer now
476
477 int processed, queued, unprocessed;
478 alGetSourcei(mWindSource, AL_BUFFERS_PROCESSED, &processed);
479 alGetSourcei(mWindSource, AL_BUFFERS_QUEUED, &queued);
480 unprocessed = queued - processed;
481
482 // ensure that there are always at least 3x as many filled buffers
483 // queued as we managed to empty since last time.
484 mNumEmptyWindALBuffers = llmin(mNumEmptyWindALBuffers + processed * 3 - unprocessed, MAX_NUM_WIND_BUFFERS-unprocessed);
485 mNumEmptyWindALBuffers = llmax(mNumEmptyWindALBuffers, 0);
486
487 //LL_INFOS("OpenAL") << "mNumEmptyWindALBuffers: " << mNumEmptyWindALBuffers <<" (" << unprocessed << ":" << processed << ")" << LL_ENDL;
488
489 while(processed--) // unqueue old buffers
490 {
491 ALuint buffer;
492 int error;
493 alGetError(); /* clear error */
494 alSourceUnqueueBuffers(mWindSource, 1, &buffer);
495 error = alGetError();
496 if(error != AL_NO_ERROR)
497 {
498 LL_WARNS("OpenAL") << "LLAudioEngine_OpenAL::updateWind() error swapping (unqueuing) buffers" << LL_ENDL;
499 }
500 else
501 {
502 alDeleteBuffers(1, &buffer);
503 }
504 }
505
506 unprocessed += mNumEmptyWindALBuffers;
507 while (mNumEmptyWindALBuffers > 0) // fill+queue new buffers
508 {
509 ALuint buffer;
510 alGetError(); /* clear error */
511 alGenBuffers(1,&buffer);
512 if((error=alGetError()) != AL_NO_ERROR)
513 {
514 LL_WARNS("OpenAL") << "LLAudioEngine_OpenAL::initWind() Error creating wind buffer: " << error << LL_ENDL;
515 break;
516 }
517
518 alBufferData(buffer,
519 AL_FORMAT_STEREO16,
520 mWindGen->windGenerate(mWindBuf,
521 mWindBufSamples, 2),
522 mWindBufBytes,
523 mWindBufFreq);
524 error = alGetError();
525 if(error != AL_NO_ERROR)
526 LL_WARNS("OpenAL") << "LLAudioEngine_OpenAL::updateWind() error swapping (bufferdata) buffers" << LL_ENDL;
527
528 alSourceQueueBuffers(mWindSource, 1, &buffer);
529 error = alGetError();
530 if(error != AL_NO_ERROR)
531 LL_WARNS("OpenAL") << "LLAudioEngine_OpenAL::updateWind() error swapping (queuing) buffers" << LL_ENDL;
532
533 --mNumEmptyWindALBuffers;
534 }
535
536 int playing;
537 alGetSourcei(mWindSource, AL_SOURCE_STATE, &playing);
538 if(playing != AL_PLAYING)
539 {
540 alSourcePlay(mWindSource);
541
542 LL_INFOS("OpenAL") << "Wind had stopped - probably ran out of buffers - restarting: " << (unprocessed+mNumEmptyWindALBuffers) << " now queued." << LL_ENDL;
543 }
544}
diff --git a/linden/indra/llaudio/audioengine_openal.h b/linden/indra/llaudio/audioengine_openal.h
new file mode 100644
index 0000000..b03153a
--- /dev/null
+++ b/linden/indra/llaudio/audioengine_openal.h
@@ -0,0 +1,113 @@
1/**
2 * @file audioengine_openal.cpp
3 * @brief implementation of audio engine using OpenAL
4 * support as a OpenAL 3D implementation
5 *
6 *
7 * $LicenseInfo:firstyear=2002&license=viewergpl$
8 *
9 * Copyright (c) 2002-2008, Linden Research, Inc.
10 *
11 * Second Life Viewer Source Code
12 * The source code in this file ("Source Code") is provided by Linden Lab
13 * to you under the terms of the GNU General Public License, version 2.0
14 * ("GPL"), unless you have obtained a separate licensing agreement
15 * ("Other License"), formally executed by you and Linden Lab. Terms of
16 * the GPL can be found in doc/GPL-license.txt in this distribution, or
17 * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
18 *
19 * There are special exceptions to the terms and conditions of the GPL as
20 * it is applied to this Source Code. View the full text of the exception
21 * in the file doc/FLOSS-exception.txt in this software distribution, or
22 * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
23 *
24 * By copying, modifying or distributing this software, you acknowledge
25 * that you have read and understood your obligations described above,
26 * and agree to abide by those obligations.
27 *
28 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
29 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
30 * COMPLETENESS OR PERFORMANCE.
31 * $/LicenseInfo$
32 */
33
34
35#ifndef LL_AUDIOENGINE_OPENAL_H
36#define LL_AUDIOENGINE_OPENAL_H
37
38#include "audioengine.h"
39#include "listener_openal.h"
40#include "windgen.h"
41
42class LLAudioEngine_OpenAL : public LLAudioEngine
43{
44 public:
45 LLAudioEngine_OpenAL();
46 virtual ~LLAudioEngine_OpenAL();
47
48 virtual bool init(const S32 num_channels, void *user_data);
49 virtual std::string getDriverName(bool verbose);
50 virtual void allocateListener();
51
52 virtual void shutdown();
53
54 void setInternalGain(F32 gain);
55
56 LLAudioBuffer* createBuffer();
57 LLAudioChannel* createChannel();
58
59 /*virtual*/ void initWind();
60 /*virtual*/ void cleanupWind();
61 /*virtual*/ void updateWind(LLVector3 direction, F32 camera_altitude);
62
63 private:
64 void * windDSP(void *newbuffer, int length);
65 typedef S16 WIND_SAMPLE_T;
66 LLWindGen<WIND_SAMPLE_T> *mWindGen;
67 S16 *mWindBuf;
68 U32 mWindBufFreq;
69 U32 mWindBufSamples;
70 U32 mWindBufBytes;
71 ALuint mWindSource;
72 int mNumEmptyWindALBuffers;
73
74 static const int MAX_NUM_WIND_BUFFERS = 80;
75 static const float WIND_BUFFER_SIZE_SEC = 0.05f; // 1/20th sec
76};
77
78class LLAudioChannelOpenAL : public LLAudioChannel
79{
80 public:
81 LLAudioChannelOpenAL();
82 virtual ~LLAudioChannelOpenAL();
83 protected:
84 /*virtual*/ void play();
85 /*virtual*/ void playSynced(LLAudioChannel *channelp);
86 /*virtual*/ void cleanup();
87 /*virtual*/ bool isPlaying();
88
89 /*virtual*/ bool updateBuffer();
90 /*virtual*/ void update3DPosition();
91 /*virtual*/ void updateLoop();
92
93 ALuint mALSource;
94 ALint mLastSamplePos;
95};
96
97class LLAudioBufferOpenAL : public LLAudioBuffer{
98 public:
99 LLAudioBufferOpenAL();
100 virtual ~LLAudioBufferOpenAL();
101
102 bool loadWAV(const std::string& filename);
103 U32 getLength();
104
105 friend class LLAudioChannelOpenAL;
106 protected:
107 void cleanup();
108 ALuint getBuffer() {return mALBuffer;}
109
110 ALuint mALBuffer;
111};
112
113#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..637af30
--- /dev/null
+++ b/linden/indra/llaudio/listener_openal.cpp
@@ -0,0 +1,98 @@
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 // Effect is way too strong by default, scale it down here.
85 // Scaling the speed of sound up causes crashes.
86 factor *= 0.005f;
87 //llinfos << "LLListener_OpenAL::setDopplerFactor() : " << factor << llendl;
88 alDopplerFactor(factor);
89}
90
91F32 LLListener_OpenAL::getDopplerFactor(){
92 ALfloat factor;
93 factor = 0.0f;
94 alDopplerFactor(factor);
95 llinfos << "LLListener_OpenAL::getDopplerFactor() : " << factor << llendl;
96 return factor;
97}
98
diff --git a/linden/indra/llaudio/listener_openal.h b/linden/indra/llaudio/listener_openal.h
index cc4bb9e..7551161 100644
--- a/linden/indra/llaudio/listener_openal.h
+++ b/linden/indra/llaudio/listener_openal.h
@@ -35,7 +35,8 @@
35 35
36#include "listener.h" 36#include "listener.h"
37 37
38#include "AL/al.h" 38
39//#include "AL/al.h"
39#include "AL/alut.h" 40#include "AL/alut.h"
40 41
41class LLListener_OpenAL : public LLListener 42class LLListener_OpenAL : public LLListener
@@ -54,6 +55,10 @@ class LLListener_OpenAL : public LLListener
54 virtual void setPosition(LLVector3 pos); 55 virtual void setPosition(LLVector3 pos);
55 virtual void setVelocity(LLVector3 vel); 56 virtual void setVelocity(LLVector3 vel);
56 virtual void orient(LLVector3 up, LLVector3 at); 57 virtual void orient(LLVector3 up, LLVector3 at);
58 virtual void commitDeferredChanges();
59
60 virtual void setDopplerFactor(F32 factor);
61 virtual F32 getDopplerFactor();
57}; 62};
58 63
59#endif 64#endif
diff --git a/linden/indra/llaudio/llaudiodecodemgr.cpp b/linden/indra/llaudio/llaudiodecodemgr.cpp
index 7cd48a9..cfd0500 100644
--- a/linden/indra/llaudio/llaudiodecodemgr.cpp
+++ b/linden/indra/llaudio/llaudiodecodemgr.cpp
@@ -374,16 +374,16 @@ BOOL LLVorbisDecodeState::finishDecode()
374 374
375 // write "data" chunk length, in little-endian format 375 // write "data" chunk length, in little-endian format
376 S32 data_length = mWAVBuffer.size() - WAV_HEADER_SIZE; 376 S32 data_length = mWAVBuffer.size() - WAV_HEADER_SIZE;
377 mWAVBuffer[40] = (data_length) & 0x000000FF; 377 mWAVBuffer[40] = (data_length - 8) & 0x000000FF;
378 mWAVBuffer[41] = (data_length >> 8) & 0x000000FF; 378 mWAVBuffer[41] = ((data_length - 8)>> 8) & 0x000000FF;
379 mWAVBuffer[42] = (data_length >> 16) & 0x000000FF; 379 mWAVBuffer[42] = ((data_length - 8)>> 16) & 0x000000FF;
380 mWAVBuffer[43] = (data_length >> 24) & 0x000000FF; 380 mWAVBuffer[43] = ((data_length - 8)>> 24) & 0x000000FF;
381
381 // write overall "RIFF" length, in little-endian format 382 // write overall "RIFF" length, in little-endian format
382 data_length += 36; 383 mWAVBuffer[4] = (data_length + 28) & 0x000000FF;
383 mWAVBuffer[4] = (data_length) & 0x000000FF; 384 mWAVBuffer[5] = ((data_length + 28) >> 8) & 0x000000FF;
384 mWAVBuffer[5] = (data_length >> 8) & 0x000000FF; 385 mWAVBuffer[6] = ((data_length + 28) >> 16) & 0x000000FF;
385 mWAVBuffer[6] = (data_length >> 16) & 0x000000FF; 386 mWAVBuffer[7] = ((data_length + 28) >> 24) & 0x000000FF;
386 mWAVBuffer[7] = (data_length >> 24) & 0x000000FF;
387 387
388 // 388 //
389 // FUDGECAKES!!! Vorbis encode/decode messes up loop point transitions (pop) 389 // FUDGECAKES!!! Vorbis encode/decode messes up loop point transitions (pop)
@@ -395,7 +395,8 @@ BOOL LLVorbisDecodeState::finishDecode()
395 S32 fade_length; 395 S32 fade_length;
396 char pcmout[4096]; /*Flawfinder: ignore*/ 396 char pcmout[4096]; /*Flawfinder: ignore*/
397 397
398 fade_length = llmin((S32)128,(S32)(data_length-36)/8); 398 fade_length = llmin((S32)128,(S32)(data_length)/8);
399
399 if((S32)mWAVBuffer.size() >= (WAV_HEADER_SIZE + 2* fade_length)) 400 if((S32)mWAVBuffer.size() >= (WAV_HEADER_SIZE + 2* fade_length))
400 { 401 {
401 memcpy(pcmout, &mWAVBuffer[WAV_HEADER_SIZE], (2 * fade_length)); /*Flawfinder: ignore*/ 402 memcpy(pcmout, &mWAVBuffer[WAV_HEADER_SIZE], (2 * fade_length)); /*Flawfinder: ignore*/
@@ -435,7 +436,7 @@ BOOL LLVorbisDecodeState::finishDecode()
435 } 436 }
436 } 437 }
437 438
438 if (36 == data_length) 439 if (0 == data_length)
439 { 440 {
440 llwarns << "BAD Vorbis decode in finishDecode!" << llendl; 441 llwarns << "BAD Vorbis decode in finishDecode!" << llendl;
441 mValid = FALSE; 442 mValid = FALSE;
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/llcommon/llversionviewer.h b/linden/indra/llcommon/llversionviewer.h
index 4032c5b..2b31117 100644
--- a/linden/indra/llcommon/llversionviewer.h
+++ b/linden/indra/llcommon/llversionviewer.h
@@ -45,6 +45,6 @@ const char * const IMP_VIEWER_NAME = "Imprudence";
45const S32 IMP_VERSION_MAJOR = 1; 45const S32 IMP_VERSION_MAJOR = 1;
46const S32 IMP_VERSION_MINOR = 1; 46const S32 IMP_VERSION_MINOR = 1;
47const S32 IMP_VERSION_PATCH = 0; 47const S32 IMP_VERSION_PATCH = 0;
48const char * const IMP_VERSION_TEST = "alpha"; 48const char * const IMP_VERSION_TEST = "openal-1";
49 49
50#endif 50#endif
diff --git a/linden/indra/llmedia/llmediaimplgstreamer.cpp b/linden/indra/llmedia/llmediaimplgstreamer.cpp
index 5d6a648..fa42756 100644
--- a/linden/indra/llmedia/llmediaimplgstreamer.cpp
+++ b/linden/indra/llmedia/llmediaimplgstreamer.cpp
@@ -49,6 +49,7 @@ extern "C" {
49 49
50#include "llmediaimplgstreamer_syms.h" 50#include "llmediaimplgstreamer_syms.h"
51 51
52#include "llerror.h"
52// register this impl with media manager factory 53// register this impl with media manager factory
53static LLMediaImplRegister sLLMediaImplGStreamerReg( "LLMediaImplGStreamer", new LLMediaImplGStreamerMaker() ); 54static LLMediaImplRegister sLLMediaImplGStreamerReg( "LLMediaImplGStreamer", new LLMediaImplGStreamerMaker() );
54 55
@@ -73,12 +74,14 @@ LLMediaImplGStreamer () :
73 mTextureFormatType ( LL_MEDIA_UNSIGNED_INT_8_8_8_8_REV ), 74 mTextureFormatType ( LL_MEDIA_UNSIGNED_INT_8_8_8_8_REV ),
74 mPump ( NULL ), 75 mPump ( NULL ),
75 mPlaybin ( NULL ), 76 mPlaybin ( NULL ),
76 mVideoSink ( NULL ) 77 mVideoSink ( NULL ),
78 mState( GST_STATE_NULL )
77#ifdef LL_GST_SOUNDSINK 79#ifdef LL_GST_SOUNDSINK
78 ,mAudioSink ( NULL ) 80 ,mAudioSink ( NULL )
79#endif // LL_GST_SOUNDSINK 81#endif // LL_GST_SOUNDSINK
80{ 82{
81 DEBUGMSG("constructing media..."); 83 LL_DEBUGS("MediaManager") << "constructing media..." << LL_ENDL;
84 mVolume = -1.0; // XXX Hack to make the vould change happend first time
82 85
83 setMediaDepth(4); 86 setMediaDepth(4);
84 87
@@ -99,11 +102,12 @@ LLMediaImplGStreamer () :
99 102
100 if (NULL == getenv("LL_GSTREAMER_EXTERNAL")) { 103 if (NULL == getenv("LL_GSTREAMER_EXTERNAL")) {
101 // instantiate and connect a custom video sink 104 // instantiate and connect a custom video sink
105 LL_DEBUGS("MediaManager") << "extrenal video sink..." << LL_ENDL;
102 mVideoSink = 106 mVideoSink =
103 GST_SLVIDEO(llgst_element_factory_make ("private-slvideo", "slvideo")); 107 GST_SLVIDEO(llgst_element_factory_make ("private-slvideo", "slvideo"));
104 if (!mVideoSink) 108 if (!mVideoSink)
105 { 109 {
106 WARNMSG("Could not instantiate private-slvideo element."); 110 LL_WARNS("MediaImpl") << "Could not instantiate private-slvideo element." << LL_ENDL;
107 // todo: cleanup. 111 // todo: cleanup.
108 return; // error 112 return; // error
109 } 113 }
@@ -111,12 +115,13 @@ LLMediaImplGStreamer () :
111 g_object_set(mPlaybin, "video-sink", mVideoSink, NULL); 115 g_object_set(mPlaybin, "video-sink", mVideoSink, NULL);
112 116
113#ifdef LL_GST_SOUNDSINK 117#ifdef LL_GST_SOUNDSINK
118 LL_DEBUGS("MediaManager") << "extrenal audio sink..." << LL_ENDL;
114 // instantiate and connect a custom audio sink 119 // instantiate and connect a custom audio sink
115 mAudioSink = 120 mAudioSink =
116 GST_SLSOUND(llgst_element_factory_make ("private-slsound", "slsound")); 121 GST_SLSOUND(llgst_element_factory_make ("private-slsound", "slsound"));
117 if (!mAudioSink) 122 if (!mAudioSink)
118 { 123 {
119 WARNMSG("Could not instantiate private-slsound element."); 124 LL_WARN("MediaImpl") << "Could not instantiate private-slsound element." << LL_ENDL;
120 // todo: cleanup. 125 // todo: cleanup.
121 return; // error 126 return; // error
122 } 127 }
@@ -149,7 +154,7 @@ int LLMediaImplGStreamer::getTextureFormatInternal() const
149LLMediaImplGStreamer:: 154LLMediaImplGStreamer::
150~LLMediaImplGStreamer () 155~LLMediaImplGStreamer ()
151{ 156{
152 DEBUGMSG("dtor of media..."); 157 LL_DEBUGS("MediaImpl") << ("dtor of media...") << LL_ENDL;
153 unload(); 158 unload();
154} 159}
155 160
@@ -176,21 +181,23 @@ startup ( LLMediaManagerData* init_data )
176 "libgstvideo-0.10.so.0", 181 "libgstvideo-0.10.so.0",
177 "libgstaudio-0.10.so.0") ) 182 "libgstaudio-0.10.so.0") )
178 { 183 {
179 WARNMSG("Couldn't find suitable GStreamer 0.10 support on this system - video playback disabled."); 184 LL_WARNS("MediaImpl") << "Couldn't find suitable GStreamer 0.10 support on this system - video playback disabled." << LL_ENDL;
180 return false; 185 return false;
181 } 186 }
182 187
183 if (llgst_segtrap_set_enabled) 188 if (llgst_segtrap_set_enabled)
184 llgst_segtrap_set_enabled(FALSE); 189 llgst_segtrap_set_enabled(FALSE);
185 else 190 else
186 WARNMSG("gst_segtrap_set_enabled() is not available; Automated crash-reporter may cease to function until next restart."); 191 {
192 LL_WARNS("MediaImpl") << "gst_segtrap_set_enabled() is not available; Automated crash-reporter may cease to function until next restart." << LL_ENDL;
193 }
187 194
188 // Protect against GStreamer resetting the locale, yuck. 195 // Protect against GStreamer resetting the locale, yuck.
189 static std::string saved_locale; 196 static std::string saved_locale;
190 saved_locale = setlocale(LC_ALL, NULL); 197 saved_locale = setlocale(LC_ALL, NULL);
191 if (0 == llgst_init_check(NULL, NULL, NULL)) 198 if (0 == llgst_init_check(NULL, NULL, NULL))
192 { 199 {
193 WARNMSG("GST init failed for unspecified reason."); 200 LL_WARNS("MediaImpl") << "GST init failed for unspecified reason." << LL_ENDL;
194 setlocale(LC_ALL, saved_locale.c_str() ); 201 setlocale(LC_ALL, saved_locale.c_str() );
195 return false; 202 return false;
196 } 203 }
@@ -222,7 +229,7 @@ closedown()
222// 229//
223//#define LL_GST_REPORT_STATE_CHANGES 230//#define LL_GST_REPORT_STATE_CHANGES
224#ifdef LL_GST_REPORT_STATE_CHANGES 231#ifdef LL_GST_REPORT_STATE_CHANGES
225static char* get_gst_state_name(GstState state) 232static const char* get_gst_state_name(GstState state)
226{ 233{
227 switch (state) { 234 switch (state) {
228 case GST_STATE_VOID_PENDING: return "VOID_PENDING"; 235 case GST_STATE_VOID_PENDING: return "VOID_PENDING";
@@ -241,17 +248,7 @@ LLMediaImplGStreamer::bus_callback (GstBus *bus,
241 GstMessage *message, 248 GstMessage *message,
242 gpointer data) 249 gpointer data)
243{ 250{
244 if (GST_MESSAGE_TYPE(message) != GST_MESSAGE_STATE_CHANGED && 251 LL_DEBUGS("MediaCallback") << "Got GST message type: " << LLGST_MESSAGE_TYPE_NAME (message) << LL_ENDL;
245 GST_MESSAGE_TYPE(message) != GST_MESSAGE_BUFFERING)
246 {
247 DEBUGMSG("Got GST message type: %s",
248 LLGST_MESSAGE_TYPE_NAME (message));
249 }
250 else
251 {
252 DEBUGMSG("Got GST message type: %s",
253 LLGST_MESSAGE_TYPE_NAME (message));
254 }
255 252
256 LLMediaImplGStreamer *impl = (LLMediaImplGStreamer*)data; 253 LLMediaImplGStreamer *impl = (LLMediaImplGStreamer*)data;
257 254
@@ -262,7 +259,7 @@ LLMediaImplGStreamer::bus_callback (GstBus *bus,
262 { 259 {
263 gint percent = 0; 260 gint percent = 0;
264 llgst_message_parse_buffering(message, &percent); 261 llgst_message_parse_buffering(message, &percent);
265 DEBUGMSG("GST buffering: %d%%", percent); 262 LL_DEBUGS("MediaBuffering") << "GST buffering: " << percent << "%%" << LL_ENDL;
266 LLMediaEvent event( impl, percent ); 263 LLMediaEvent event( impl, percent );
267 impl->getEventEmitter().update( &LLMediaObserver::onUpdateProgress, event ); 264 impl->getEventEmitter().update( &LLMediaObserver::onUpdateProgress, event );
268 265
@@ -279,16 +276,18 @@ LLMediaImplGStreamer::bus_callback (GstBus *bus,
279 &pending_state); 276 &pending_state);
280#ifdef LL_GST_REPORT_STATE_CHANGES 277#ifdef LL_GST_REPORT_STATE_CHANGES
281 // not generally very useful, and rather spammy. 278 // not generally very useful, and rather spammy.
282 DEBUGMSG("state change (old,<new>,pending): %s,<%s>,%s", 279 LL_DEBUGS("MediaState") << "GST state change (old,<new>,pending): "<< get_gst_state_name(old_state) << ",<" << get_gst_state_name(new_state) << ">," << get_gst_state_name(pending_state) << LL_ENDL;
283 get_gst_state_name(old_state),
284 get_gst_state_name(new_state),
285 get_gst_state_name(pending_state));
286#endif // LL_GST_REPORT_STATE_CHANGES 280#endif // LL_GST_REPORT_STATE_CHANGES
287 281
288 switch (new_state) { 282 switch (new_state) {
289 case GST_STATE_VOID_PENDING: 283 case GST_STATE_VOID_PENDING:
290 break; 284 break;
291 case GST_STATE_NULL: 285 case GST_STATE_NULL:
286 LL_DEBUGS("MediaImpl") << "State changed to NULL" << LL_ENDL;
287 if (impl->getState() == GST_STATE_PLAYING) { // We got stoped by gstremer...
288 impl->play();
289 LL_DEBUGS("MediaImpl") << "Trying to restart." << LL_ENDL;
290 }
292 break; 291 break;
293 case GST_STATE_READY: 292 case GST_STATE_READY:
294 break; 293 break;
@@ -309,11 +308,12 @@ LLMediaImplGStreamer::bus_callback (GstBus *bus,
309 gchar *debug = NULL; 308 gchar *debug = NULL;
310 309
311 llgst_message_parse_error (message, &err, &debug); 310 llgst_message_parse_error (message, &err, &debug);
312 WARNMSG("GST error: %s", err->message); 311 LL_WARNS("MediaImpl") << "GST Error: " << err->message << LL_ENDL;
313 g_error_free (err); 312 g_error_free (err);
314 g_free (debug); 313 g_free (debug);
315 314
316 impl->addCommand(LLMediaBase::COMMAND_STOP); 315 impl->addCommand(LLMediaBase::COMMAND_STOP);
316 //impl->addCommand(LLMediaBase::COMMAND_START);
317 317
318 break; 318 break;
319 } 319 }
@@ -324,7 +324,8 @@ LLMediaImplGStreamer::bus_callback (GstBus *bus,
324 gchar *debug = NULL; 324 gchar *debug = NULL;
325 325
326 llgst_message_parse_info (message, &err, &debug); 326 llgst_message_parse_info (message, &err, &debug);
327 INFOMSG("GST info: %s", err->message); 327 LL_INFOS("MediaImpl") << "GST info: " << err->message
328 << LL_ENDL;
328 g_error_free (err); 329 g_error_free (err);
329 g_free (debug); 330 g_free (debug);
330 } 331 }
@@ -335,18 +336,36 @@ LLMediaImplGStreamer::bus_callback (GstBus *bus,
335 gchar *debug = NULL; 336 gchar *debug = NULL;
336 337
337 llgst_message_parse_warning (message, &err, &debug); 338 llgst_message_parse_warning (message, &err, &debug);
338 WARNMSG("GST warning: %s", err->message); 339 LL_WARNS("MediaImpl") << "GST warning: " << err->message
340 << LL_ENDL;
339 g_error_free (err); 341 g_error_free (err);
340 g_free (debug); 342 g_free (debug);
341 343
342 break; 344 break;
343 } 345 }
346 case GST_MESSAGE_TAG: {
347#if 0
348 GstTagList *tag_list;
349 gchar *title;
350 gchar *artist;
351 llgst_message_parse_tag(message, &tag_list);
352 gboolean hazTitle = llgst_tag_list_get_string(tag_list,
353 GST_TAG_TITLE, &title);
354 gboolean hazArtist = llgst_tag_list_get_string(tag_list,
355 GST_TAG_ARTIST, &artist);
356 if(hazTitle)
357 LL_INFOS("MediaInfo") << "Title is " << title << LL_ENDL;
358 if(hazArtist)
359 LL_INFOS("MediaInfo") << "Artist is " << artist << LL_ENDL;
360#endif
361 break;
362 }
344 case GST_MESSAGE_EOS: 363 case GST_MESSAGE_EOS:
345 /* end-of-stream */ 364 /* end-of-stream */
346 DEBUGMSG("GST end-of-stream."); 365 LL_DEBUGS("MediaImpl") << "GST end-of-stream." << LL_ENDL;
347 if (impl->isLooping()) 366 if (impl->isLooping())
348 { 367 {
349 DEBUGMSG("looping media..."); 368 LL_DEBUGS("MediaImpl") << "looping media..." << LL_ENDL;
350 impl->stop(); 369 impl->stop();
351 impl->play(); 370 impl->play();
352 } 371 }
@@ -374,7 +393,8 @@ bool
374LLMediaImplGStreamer:: 393LLMediaImplGStreamer::
375navigateTo ( const std::string urlIn ) 394navigateTo ( const std::string urlIn )
376{ 395{
377 DEBUGMSG("Setting media URI: %s", urlIn.c_str()); 396 LL_DEBUGS("MediaImpl") << "Setting media URI: " << urlIn.c_str()
397 << LL_ENDL;
378 398
379 if (NULL == mPump 399 if (NULL == mPump
380#ifdef LL_GST_SOUNDSINK 400#ifdef LL_GST_SOUNDSINK
@@ -412,10 +432,11 @@ bool
412LLMediaImplGStreamer:: 432LLMediaImplGStreamer::
413unload () 433unload ()
414{ 434{
415 DEBUGMSG("unloading media..."); 435 LL_DEBUGS("MediaImpl") << "unloading media..." << LL_ENDL;
416 if (mPlaybin) 436 if (mPlaybin)
417 { 437 {
418 llgst_element_set_state (mPlaybin, GST_STATE_NULL); 438 llgst_element_set_state (mPlaybin, GST_STATE_NULL);
439 mState = GST_STATE_NULL;
419 llgst_object_unref (GST_OBJECT (mPlaybin)); 440 llgst_object_unref (GST_OBJECT (mPlaybin));
420 mPlaybin = NULL; 441 mPlaybin = NULL;
421 } 442 }
@@ -443,7 +464,7 @@ bool
443LLMediaImplGStreamer:: 464LLMediaImplGStreamer::
444updateMedia () 465updateMedia ()
445{ 466{
446 DEBUGMSG("updating media..."); 467 //LL_DEBUGS("MediaImpl") << "updating media..." << LL_ENDL;
447 468
448 // sanity check 469 // sanity check
449 if (NULL == mPump 470 if (NULL == mPump
@@ -452,7 +473,7 @@ updateMedia ()
452#endif 473#endif
453 || NULL == mPlaybin) 474 || NULL == mPlaybin)
454 { 475 {
455 DEBUGMSG("dead media..."); 476 LL_DEBUGS("MediaImpl") << "dead media..." << LL_ENDL;
456 return false; 477 return false;
457 } 478 }
458 479
@@ -460,36 +481,33 @@ updateMedia ()
460 switch (nextCommand()) 481 switch (nextCommand())
461 { 482 {
462 case LLMediaBase::COMMAND_START: 483 case LLMediaBase::COMMAND_START:
463 DEBUGMSG("COMMAND_START"); 484 LL_DEBUGS("MediaImpl") << "COMMAND_START" << LL_ENDL;
464 if (getStatus() == LLMediaBase::STATUS_PAUSED || 485 if (getStatus() == LLMediaBase::STATUS_PAUSED ||
465 getStatus() == LLMediaBase::STATUS_NAVIGATING || 486 getStatus() == LLMediaBase::STATUS_NAVIGATING ||
466 getStatus() == LLMediaBase::STATUS_STOPPED) 487 getStatus() == LLMediaBase::STATUS_STOPPED)
467 { 488 {
468 DEBUGMSG("doing COMMAND_START");
469 play(); 489 play();
470 setStatus(LLMediaBase::STATUS_STARTED); 490 setStatus(LLMediaBase::STATUS_STARTED);
471 clearCommand(); 491 clearCommand();
472 } 492 }
473 break; 493 break;
474 case LLMediaBase::COMMAND_STOP: 494 case LLMediaBase::COMMAND_STOP:
475 DEBUGMSG("COMMAND_STOP"); 495 LL_DEBUGS("MediaImpl") << "COMMAND_STOP" << LL_ENDL;
476 DEBUGMSG("doing COMMAND_STOP");
477 stop(); 496 stop();
478 setStatus(LLMediaBase::STATUS_STOPPED); 497 setStatus(LLMediaBase::STATUS_STOPPED);
479 clearCommand(); 498 clearCommand();
480 break; 499 break;
481 case LLMediaBase::COMMAND_PAUSE: 500 case LLMediaBase::COMMAND_PAUSE:
482 DEBUGMSG("COMMAND_PAUSE"); 501 LL_DEBUGS("MediaImpl") << "COMMAND_PAUSE" << LL_ENDL;
483 if (getStatus() == LLMediaBase::STATUS_STARTED) 502 if (getStatus() == LLMediaBase::STATUS_STARTED)
484 { 503 {
485 DEBUGMSG("doing COMMAND_PAUSE");
486 pause(); 504 pause();
487 setStatus(LLMediaBase::STATUS_PAUSED); 505 setStatus(LLMediaBase::STATUS_PAUSED);
488 clearCommand(); 506 clearCommand();
489 } 507 }
490 break; 508 break;
491 default: 509 default:
492 DEBUGMSG("COMMAND_?"); 510 LL_INFOS("MediaImpl") << "Unknown command" << LL_ENDL;
493 clearCommand(); 511 clearCommand();
494 break; 512 break;
495 case LLMediaBase::COMMAND_NONE: 513 case LLMediaBase::COMMAND_NONE:
@@ -507,7 +525,7 @@ updateMedia ()
507 GST_OBJECT_LOCK(mVideoSink); 525 GST_OBJECT_LOCK(mVideoSink);
508 if (mVideoSink->retained_frame_ready) 526 if (mVideoSink->retained_frame_ready)
509 { 527 {
510 DEBUGMSG("NEW FRAME "); 528 LL_DEBUGS("MediaImpl") <<"NEW FRAME " << LL_ENDL;
511 if (mVideoSink->retained_frame_width != getMediaWidth() || 529 if (mVideoSink->retained_frame_width != getMediaWidth() ||
512 mVideoSink->retained_frame_height != getMediaHeight()) 530 mVideoSink->retained_frame_height != getMediaHeight())
513 // *TODO: also check for change in format 531 // *TODO: also check for change in format
@@ -527,8 +545,9 @@ updateMedia ()
527 mTextureFormatType = LL_MEDIA_UNSIGNED_INT_8_8_8_8_REV; 545 mTextureFormatType = LL_MEDIA_UNSIGNED_INT_8_8_8_8_REV;
528 } 546 }
529 mMediaRowbytes = neww * newd; 547 mMediaRowbytes = neww * newd;
530 DEBUGMSG("video container resized to %dx%d", 548 LL_DEBUGS("MediaImpl")
531 neww, newh); 549 << "video container resized to " <<
550 neww <<"x"<< newh << LL_ENDL;
532 551
533 delete[] mediaData; 552 delete[] mediaData;
534 mediaData = new unsigned char[mMediaRowbytes * 553 mediaData = new unsigned char[mMediaRowbytes *
@@ -568,9 +587,10 @@ bool
568LLMediaImplGStreamer:: 587LLMediaImplGStreamer::
569stop () 588stop ()
570{ 589{
571 DEBUGMSG("stopping media..."); 590 LL_DEBUGS("MediaImpl") << "stopping media..." << LL_ENDL;
572 // todo: error-check this? 591 // todo: error-check this?
573 llgst_element_set_state(mPlaybin, GST_STATE_READY); 592 llgst_element_set_state(mPlaybin, GST_STATE_READY);
593 mState = GST_STATE_READY;
574 return true; 594 return true;
575} 595}
576 596
@@ -580,9 +600,10 @@ bool
580LLMediaImplGStreamer:: 600LLMediaImplGStreamer::
581play () 601play ()
582{ 602{
583 DEBUGMSG("playing media..."); 603 LL_DEBUGS("MediaImpl") << "playing media..." << LL_ENDL;
584 // todo: error-check this? 604 // todo: error-check this?
585 llgst_element_set_state(mPlaybin, GST_STATE_PLAYING); 605 llgst_element_set_state(mPlaybin, GST_STATE_PLAYING);
606 mState = GST_STATE_PLAYING;
586 return true; 607 return true;
587} 608}
588 609
@@ -592,9 +613,10 @@ bool
592LLMediaImplGStreamer:: 613LLMediaImplGStreamer::
593pause () 614pause ()
594{ 615{
595 DEBUGMSG("pausing media..."); 616 LL_DEBUGS("MediaImpl") <<"pausing media..." << LL_ENDL;
596 // todo: error-check this? 617 // todo: error-check this?
597 llgst_element_set_state(mPlaybin, GST_STATE_PAUSED); 618 llgst_element_set_state(mPlaybin, GST_STATE_PAUSED);
619 mState = GST_STATE_PAUSED;
598 return true; 620 return true;
599}; 621};
600 622
@@ -624,8 +646,8 @@ seek( double time )
624 GST_SEEK_TYPE_SET, gint64(time*1000000000.0F), 646 GST_SEEK_TYPE_SET, gint64(time*1000000000.0F),
625 GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE); 647 GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
626 } 648 }
627 DEBUGMSG("MEDIA SEEK REQUEST to %fsec result was %d", 649 LL_DEBUGS("MediaImpl") << "MEDIA SEEK REQUEST to " << float(time)
628 float(time), int(success)); 650 << "sec result was " << int(success) << LL_ENDL;
629 return success; 651 return success;
630} 652}
631 653
@@ -636,6 +658,12 @@ bool
636LLMediaImplGStreamer:: 658LLMediaImplGStreamer::
637setVolume(float volume) 659setVolume(float volume)
638{ 660{
661 // XXX hack to make volume volume changes less othen
662 // bug in gstreamer 0.10.21
663 if(mVolume == volume)
664 return true;
665
666 LL_DEBUGS("MediaImpl") << "setVolume(" << volume << ") : " << getpid() << LL_ENDL;
639 mVolume = volume; 667 mVolume = volume;
640 if (mPlaybin) 668 if (mPlaybin)
641 { 669 {
diff --git a/linden/indra/llmedia/llmediaimplgstreamer.h b/linden/indra/llmedia/llmediaimplgstreamer.h
index 247b0ce..4d0638a 100644
--- a/linden/indra/llmedia/llmediaimplgstreamer.h
+++ b/linden/indra/llmedia/llmediaimplgstreamer.h
@@ -100,9 +100,11 @@ class LLMediaImplGStreamer:
100 GMainLoop *mPump; // event pump for this media 100 GMainLoop *mPump; // event pump for this media
101 GstElement *mPlaybin; 101 GstElement *mPlaybin;
102 GstSLVideo *mVideoSink; 102 GstSLVideo *mVideoSink;
103 GstState mState;
103#ifdef LL_GST_SOUNDSINK 104#ifdef LL_GST_SOUNDSINK
104 GstSLSound *mAudioSink; 105 GstSLSound *mAudioSink;
105#endif // LL_GST_SOUNDSINK 106#endif // LL_GST_SOUNDSINK
107 GstState getState() const { return mState; }
106}; 108};
107 109
108class LLMediaImplGStreamerMaker : public LLMediaImplMaker 110class LLMediaImplGStreamerMaker : public LLMediaImplMaker
diff --git a/linden/indra/llmedia/llmediamanager.cpp b/linden/indra/llmedia/llmediamanager.cpp
index 16c731f..57256e6 100644
--- a/linden/indra/llmedia/llmediamanager.cpp
+++ b/linden/indra/llmedia/llmediamanager.cpp
@@ -40,6 +40,7 @@
40# include "llmediaimplllmozlib.h" 40# include "llmediaimplllmozlib.h"
41#endif 41#endif
42 42
43#include "llerror.h"
43LLMediaManager* LLMediaManager::sInstance = 0; 44LLMediaManager* LLMediaManager::sInstance = 0;
44 45
45 46
@@ -75,6 +76,7 @@ void LLMediaManager::initClass( LLMediaManagerData* init_data )
75 if ( ! sInstance ) 76 if ( ! sInstance )
76 sInstance = new LLMediaManager(); 77 sInstance = new LLMediaManager();
77 78
79 LL_DEBUGS("MediaManager") << "LLMediaManager::initClass" << LL_ENDL;
78 // Initialize impl classes here - this breaks the encapsulation model 80 // Initialize impl classes here - this breaks the encapsulation model
79 // but some of the initialization takes a long time and we only want to 81 // but some of the initialization takes a long time and we only want to
80 // do it once at app startup before any of the impls have been created 82 // do it once at app startup before any of the impls have been created
@@ -84,10 +86,12 @@ void LLMediaManager::initClass( LLMediaManagerData* init_data )
84 LLMediaImplExample2::startup( init_data ); 86 LLMediaImplExample2::startup( init_data );
85 87
86#if LL_QUICKTIME_ENABLED 88#if LL_QUICKTIME_ENABLED
89 LL_DEBUGS("MediaManager") << "LLMediaManager::initClass: starting quicktime." << LL_ENDL;
87 LLMediaImplQuickTime::startup( init_data ); 90 LLMediaImplQuickTime::startup( init_data );
88#endif // LL_QUICKTIME_ENABLED 91#endif // LL_QUICKTIME_ENABLED
89 92
90#if LL_GSTREAMER_ENABLED 93#if LL_GSTREAMER_ENABLED
94 LL_DEBUGS("MediaManager") << "LLMediaManager::initClass: starting gstreamer" << LL_ENDL;
91 LLMediaImplGStreamer::startup( init_data ); 95 LLMediaImplGStreamer::startup( init_data );
92#endif // LL_GSTREAMER_ENABLED 96#endif // LL_GSTREAMER_ENABLED
93} 97}
diff --git a/linden/indra/newview/CMakeLists.txt b/linden/indra/newview/CMakeLists.txt
index 53054aa..8d70751 100644
--- a/linden/indra/newview/CMakeLists.txt
+++ b/linden/indra/newview/CMakeLists.txt
@@ -8,6 +8,8 @@ include(BuildVersion)
8include(DBusGlib) 8include(DBusGlib)
9include(DirectX) 9include(DirectX)
10include(ELFIO) 10include(ELFIO)
11include(FMOD)
12include(OPENAL)
11include(FindOpenGL) 13include(FindOpenGL)
12include(LLAudio) 14include(LLAudio)
13include(LLCharacter) 15include(LLCharacter)
@@ -55,6 +57,7 @@ include_directories(
55 ${LLXML_INCLUDE_DIRS} 57 ${LLXML_INCLUDE_DIRS}
56 ${LSCRIPT_INCLUDE_DIRS} 58 ${LSCRIPT_INCLUDE_DIRS}
57 ${LSCRIPT_INCLUDE_DIRS}/lscript_compile 59 ${LSCRIPT_INCLUDE_DIRS}/lscript_compile
60 ${GSTREAMER_INCLUDE_DIRS}
58 ) 61 )
59 62
60set(viewer_SOURCE_FILES 63set(viewer_SOURCE_FILES
diff --git a/linden/indra/newview/app_settings/logcontrol.xml b/linden/indra/newview/app_settings/logcontrol.xml
index d7bb64c..f3b08f9 100644
--- a/linden/indra/newview/app_settings/logcontrol.xml
+++ b/linden/indra/newview/app_settings/logcontrol.xml
@@ -40,6 +40,13 @@
40 </array> 40 </array>
41 <key>tags</key> 41 <key>tags</key>
42 <array> 42 <array>
43 <string>OpenAL</string>
44 <string>AudioEngine</string>
45 <string>MediaImpl</string>
46 <string>MediaInfo</string>
47 <string>MediaCallback</string>
48 <string>MediaBuffering</string>
49 <string>MediaState</string>
43 </array> 50 </array>
44 </map> 51 </map>
45 </array> 52 </array>
diff --git a/linden/indra/newview/llappviewer.cpp b/linden/indra/newview/llappviewer.cpp
index 14214b5..2cf418e 100644
--- a/linden/indra/newview/llappviewer.cpp
+++ b/linden/indra/newview/llappviewer.cpp
@@ -1179,7 +1179,8 @@ bool LLAppViewer::cleanup()
1179 1179
1180 llinfos << "Global stuff deleted" << llendflush; 1180 llinfos << "Global stuff deleted" << llendflush;
1181 1181
1182#if !LL_RELEASE_FOR_DOWNLOAD 1182#if (!defined(LL_FMOD)) || (!LL_RELEASE_FOR_DOWNLOAD)
1183 // OpenAL likes to crash on exit if we *don't* explicitly shut it down.
1183 if (gAudiop) 1184 if (gAudiop)
1184 { 1185 {
1185 gAudiop->shutdown(); 1186 gAudiop->shutdown();
diff --git a/linden/indra/newview/llaudiosourcevo.cpp b/linden/indra/newview/llaudiosourcevo.cpp
index e668078..9c25d94 100644
--- a/linden/indra/newview/llaudiosourcevo.cpp
+++ b/linden/indra/newview/llaudiosourcevo.cpp
@@ -39,7 +39,7 @@
39#include "llviewerparcelmgr.h" 39#include "llviewerparcelmgr.h"
40 40
41LLAudioSourceVO::LLAudioSourceVO(const LLUUID &sound_id, const LLUUID& owner_id, const F32 gain, LLViewerObject *objectp) 41LLAudioSourceVO::LLAudioSourceVO(const LLUUID &sound_id, const LLUUID& owner_id, const F32 gain, LLViewerObject *objectp)
42: LLAudioSource(sound_id, owner_id, gain), 42: LLAudioSource(sound_id, owner_id, gain, LLAudioEngine::AUDIO_TYPE_SFX),
43 mObjectp(objectp), 43 mObjectp(objectp),
44 mActualGain(gain) 44 mActualGain(gain)
45{ 45{
diff --git a/linden/indra/newview/llfloaterabout.cpp b/linden/indra/newview/llfloaterabout.cpp
index af436c5..4953410 100644
--- a/linden/indra/newview/llfloaterabout.cpp
+++ b/linden/indra/newview/llfloaterabout.cpp
@@ -41,6 +41,7 @@
41 41
42#include "llcurl.h" 42#include "llcurl.h"
43#include "llimagej2c.h" 43#include "llimagej2c.h"
44#include "audioengine.h"
44 45
45#include "llviewertexteditor.h" 46#include "llviewertexteditor.h"
46#include "llviewercontrol.h" 47#include "llviewercontrol.h"
@@ -200,6 +201,10 @@ LLFloaterAbout::LLFloaterAbout()
200 support.append( LLImageJ2C::getEngineInfo() ); 201 support.append( LLImageJ2C::getEngineInfo() );
201 support.append("\n"); 202 support.append("\n");
202 203
204 support.append("Audio Driver Version: ");
205 support.append( gAudiop ? gAudiop->getDriverName(true) : "(none)" );
206 support.append("\n");
207
203 LLMediaManager *mgr = LLMediaManager::getInstance(); 208 LLMediaManager *mgr = LLMediaManager::getInstance();
204 if (mgr) 209 if (mgr)
205 { 210 {
diff --git a/linden/indra/newview/llpreviewlandmark.cpp b/linden/indra/newview/llpreviewlandmark.cpp
index 01d77f6..dba603b 100644
--- a/linden/indra/newview/llpreviewlandmark.cpp
+++ b/linden/indra/newview/llpreviewlandmark.cpp
@@ -90,7 +90,15 @@ LLPreviewLandmark::LLPreviewLandmark(const std::string& name,
90{ 90{
91 91
92 mFactoryMap["place_details_panel"] = LLCallbackMap(LLPreviewLandmark::createPlaceDetail, this); 92 mFactoryMap["place_details_panel"] = LLCallbackMap(LLPreviewLandmark::createPlaceDetail, this);
93 LLUICtrlFactory::getInstance()->buildFloater(this, "floater_preview_existing_landmark.xml", &getFactoryMap()); 93 if (show_keep_discard)
94 {
95 LLUICtrlFactory::getInstance()->buildFloater(this, "floater_preview_new_landmark.xml", &getFactoryMap());
96 childSetAction("Discard btn",onDiscardBtn,this);
97 }
98 else
99 {
100 LLUICtrlFactory::getInstance()->buildFloater(this, "floater_preview_existing_landmark.xml", &getFactoryMap());
101 }
94 102
95 /* 103 /*
96 childSetCommitCallback("desc_editor", LLPreview::onText, this); 104 childSetCommitCallback("desc_editor", LLPreview::onText, this);
diff --git a/linden/indra/newview/llpreviewsound.cpp b/linden/indra/newview/llpreviewsound.cpp
index 9ba6fd5..6b79bfb 100644
--- a/linden/indra/newview/llpreviewsound.cpp
+++ b/linden/indra/newview/llpreviewsound.cpp
@@ -106,7 +106,6 @@ void LLPreviewSound::auditionSound( void *userdata )
106 if(item && gAudiop) 106 if(item && gAudiop)
107 { 107 {
108 LLVector3d lpos_global = gAgent.getPositionGlobal(); 108 LLVector3d lpos_global = gAgent.getPositionGlobal();
109 F32 volume = gSavedSettings.getBOOL("MuteSounds") ? 0.f : SOUND_GAIN * gSavedSettings.getF32("AudioLevelSFX"); 109 gAudiop->triggerSound(item->getAssetUUID(), gAgent.getID(), SOUND_GAIN, LLAudioEngine::AUDIO_TYPE_UI, lpos_global);
110 gAudiop->triggerSound(item->getAssetUUID(), gAgent.getID(), volume, lpos_global);
111 } 110 }
112} 111}
diff --git a/linden/indra/newview/llstartup.cpp b/linden/indra/newview/llstartup.cpp
index 6371f2b..c863d19 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,28 @@ bool idle_startup()
579 583
580 if (FALSE == gSavedSettings.getBOOL("NoAudio")) 584 if (FALSE == gSavedSettings.getBOOL("NoAudio"))
581 { 585 {
582#ifdef LL_FMOD
583 gAudiop = (LLAudioEngine *) new LLAudioEngine_FMOD();
584#else
585 gAudiop = NULL; 586 gAudiop = NULL;
587
588#ifdef LL_OPENAL
589 if (!gAudiop
590#if !LL_WINDOWS
591 && NULL == getenv("LL_BAD_OPENAL_DRIVER")
592#endif // !LL_WINDOWS
593 )
594 {
595 gAudiop = (LLAudioEngine *) new LLAudioEngine_OpenAL();
596 }
597#endif
598
599#ifdef LL_FMOD
600 if (!gAudiop
601#if !LL_WINDOWS
602 && NULL == getenv("LL_BAD_FMOD_DRIVER")
603#endif // !LL_WINDOWS
604 )
605 {
606 gAudiop = (LLAudioEngine *) new LLAudioEngine_FMOD();
607 }
586#endif 608#endif
587 609
588 if (gAudiop) 610 if (gAudiop)
@@ -595,15 +617,21 @@ bool idle_startup()
595 void* window_handle = NULL; 617 void* window_handle = NULL;
596#endif 618#endif
597 bool init = gAudiop->init(kAUDIO_NUM_SOURCES, window_handle); 619 bool init = gAudiop->init(kAUDIO_NUM_SOURCES, window_handle);
598 if(!init) 620 if(init)
621 {
622 gAudiop->setMuted(TRUE);
623 }
624 else
599 { 625 {
600 LL_WARNS("AppInit") << "Unable to initialize audio engine" << LL_ENDL; 626 LL_WARNS("AppInit") << "Unable to initialize audio engine" << LL_ENDL;
627 delete gAudiop;
628 gAudiop = NULL;
601 } 629 }
602 gAudiop->setMuted(TRUE);
603 } 630 }
604 } 631 }
605 632
606 LL_INFOS("AppInit") << "Audio Engine Initialized." << LL_ENDL; 633 LL_INFOS("AppInit") << "Audio Engine Initialized." << LL_ENDL;
634
607 635
608 if (LLTimer::knownBadTimer()) 636 if (LLTimer::knownBadTimer())
609 { 637 {
@@ -750,6 +778,12 @@ bool idle_startup()
750 gLoginMenuBarView->setVisible( TRUE ); 778 gLoginMenuBarView->setVisible( TRUE );
751 gLoginMenuBarView->setEnabled( TRUE ); 779 gLoginMenuBarView->setEnabled( TRUE );
752 780
781 // DEV-16927. The following code removes errant keystrokes that happen while the window is being
782 // first made visible.
783#ifdef _WIN32
784 MSG msg;
785 while( PeekMessage( &msg, /*All hWnds owned by this thread */ NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE ) );
786#endif
753 timeout.reset(); 787 timeout.reset();
754 return FALSE; 788 return FALSE;
755 } 789 }
diff --git a/linden/indra/newview/llviewermessage.cpp b/linden/indra/newview/llviewermessage.cpp
index 0e39026..28ca198 100644
--- a/linden/indra/newview/llviewermessage.cpp
+++ b/linden/indra/newview/llviewermessage.cpp
@@ -833,9 +833,9 @@ void open_offer(const std::vector<LLUUID>& items, const std::string& from_name)
833 //if we are throttled, don't display them - Gigs 833 //if we are throttled, don't display them - Gigs
834 if (check_offer_throttle(from_name, false)) 834 if (check_offer_throttle(from_name, false))
835 { 835 {
836 // I'm not sure this is a good idea. JC 836 // I'm not sure this is a good idea. JC - Definitely a bad idea. HB
837 bool show_keep_discard = item->getPermissions().getCreator() != gAgent.getID(); 837 //bool show_keep_discard = item->getPermissions().getCreator() != gAgent.getID();
838 //bool show_keep_discard = true; 838 bool show_keep_discard = true;
839 switch(asset_type) 839 switch(asset_type)
840 { 840 {
841 case LLAssetType::AT_NOTECARD: 841 case LLAssetType::AT_NOTECARD:
@@ -3308,8 +3308,7 @@ void process_sound_trigger(LLMessageSystem *msg, void **)
3308 return; 3308 return;
3309 } 3309 }
3310 3310
3311 F32 volume = gSavedSettings.getBOOL("MuteSounds") ? 0.f : (gain * gSavedSettings.getF32("AudioLevelSFX")); 3311 gAudiop->triggerSound(sound_id, owner_id, gain, LLAudioEngine::AUDIO_TYPE_SFX, pos_global);
3312 gAudiop->triggerSound(sound_id, owner_id, volume, pos_global);
3313} 3312}
3314 3313
3315void process_preload_sound(LLMessageSystem *msg, void **user_data) 3314void process_preload_sound(LLMessageSystem *msg, void **user_data)
diff --git a/linden/indra/newview/llviewertexteditor.cpp b/linden/indra/newview/llviewertexteditor.cpp
index 8a55b3f..1dda1ca 100644
--- a/linden/indra/newview/llviewertexteditor.cpp
+++ b/linden/indra/newview/llviewertexteditor.cpp
@@ -1402,8 +1402,7 @@ void LLViewerTextEditor::openEmbeddedSound( LLInventoryItem* item )
1402 const F32 SOUND_GAIN = 1.0f; 1402 const F32 SOUND_GAIN = 1.0f;
1403 if(gAudiop) 1403 if(gAudiop)
1404 { 1404 {
1405 F32 volume = gSavedSettings.getBOOL("MuteSounds") ? 0.f : (SOUND_GAIN * gSavedSettings.getF32("AudioLevelSFX")); 1405 gAudiop->triggerSound(item->getAssetUUID(), gAgentID, SOUND_GAIN, LLAudioEngine::AUDIO_TYPE_UI, lpos_global);
1406 gAudiop->triggerSound(item->getAssetUUID(), gAgentID, volume, lpos_global);
1407 } 1406 }
1408 showCopyToInvDialog( item ); 1407 showCopyToInvDialog( item );
1409} 1408}
diff --git a/linden/indra/newview/llvoavatar.cpp b/linden/indra/newview/llvoavatar.cpp
index e480eb3..327cd57 100644
--- a/linden/indra/newview/llvoavatar.cpp
+++ b/linden/indra/newview/llvoavatar.cpp
@@ -3828,10 +3828,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
3828// AUDIO_STEP_LO_SPEED, AUDIO_STEP_HI_SPEED, 3828// AUDIO_STEP_LO_SPEED, AUDIO_STEP_HI_SPEED,
3829// AUDIO_STEP_LO_GAIN, AUDIO_STEP_HI_GAIN ); 3829// AUDIO_STEP_LO_GAIN, AUDIO_STEP_HI_GAIN );
3830 3830
3831 F32 ambient_volume = gSavedSettings.getF32("AudioLevelAmbient"); 3831 const F32 STEP_VOLUME = 0.5f;
3832 F32 gain = gSavedSettings.getBOOL("MuteAmbient")
3833 ? 0.f
3834 : (.50f * ambient_volume * ambient_volume);
3835 LLUUID& step_sound_id = getStepSound(); 3832 LLUUID& step_sound_id = getStepSound();
3836 3833
3837 LLVector3d foot_pos_global = gAgent.getPosGlobalFromAgent(foot_pos_agent); 3834 LLVector3d foot_pos_global = gAgent.getPosGlobalFromAgent(foot_pos_agent);
@@ -3839,7 +3836,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
3839 if (LLViewerParcelMgr::getInstance()->canHearSound(foot_pos_global) 3836 if (LLViewerParcelMgr::getInstance()->canHearSound(foot_pos_global)
3840 && !LLMuteList::getInstance()->isMuted(getID(), LLMute::flagObjectSounds)) 3837 && !LLMuteList::getInstance()->isMuted(getID(), LLMute::flagObjectSounds))
3841 { 3838 {
3842 gAudiop->triggerSound(step_sound_id, getID(), gain, foot_pos_global); 3839 gAudiop->triggerSound(step_sound_id, getID(), STEP_VOLUME, LLAudioEngine::AUDIO_TYPE_AMBIENT, foot_pos_global);
3843 } 3840 }
3844 } 3841 }
3845 } 3842 }
@@ -4819,8 +4816,8 @@ BOOL LLVOAvatar::processSingleAnimationStateChange( const LLUUID& anim_id, BOOL
4819 //else 4816 //else
4820 { 4817 {
4821 LLUUID sound_id = LLUUID(gSavedSettings.getString("UISndTyping")); 4818 LLUUID sound_id = LLUUID(gSavedSettings.getString("UISndTyping"));
4822 F32 volume = gSavedSettings.getBOOL("MuteSounds") ? 0.f : gSavedSettings.getF32("AudioLevelSFX"); 4819 gAudiop->triggerSound(sound_id, getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_SFX, char_pos_global);
4823 gAudiop->triggerSound(sound_id, getID(), volume, char_pos_global); 4820
4824 } 4821 }
4825 } 4822 }
4826 } 4823 }
diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_instant_message_group.xml b/linden/indra/newview/skins/default/xui/en-us/floater_instant_message_group.xml
index be18c7e..72c92bd 100644
--- a/linden/indra/newview/skins/default/xui/en-us/floater_instant_message_group.xml
+++ b/linden/indra/newview/skins/default/xui/en-us/floater_instant_message_group.xml
@@ -1,82 +1,82 @@
1<?xml version="1.0" encoding="utf-8" standalone="yes" ?> 1<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
2<floater border="true" bottom="-297" can_close="true" can_drag_on_left="false" 2<floater border="true" bottom="-297" can_close="true" can_drag_on_left="false"
3 can_minimize="true" can_resize="true" default_tab_group="1" enabled="true" 3 can_minimize="true" can_resize="true" default_tab_group="1" enabled="true"
4 follows="left|top|right|bottom" height="296" label="(unknown)" left="1" 4 follows="left|top|right|bottom" height="296" label="(unknown)" left="1"
5 min_height="200" min_width="360" mouse_opaque="true" name="im_floater" 5 min_height="200" min_width="360" mouse_opaque="true" name="im_floater"
6 rect_control="" title="(unknown)" width="501"> 6 rect_control="" title="(unknown)" width="501">
7 <string name="ringing"> 7 <string name="ringing">
8 Joining Voice Chat... 8 Joining Voice Chat...
9 </string> 9 </string>
10 <string name="connected"> 10 <string name="connected">
11 Connected, click End Call to hang up 11 Connected, click End Call to hang up
12 </string> 12 </string>
13 <string name="hang_up"> 13 <string name="hang_up">
14 Left Voice Chat 14 Left Voice Chat
15 </string> 15 </string>
16 <string name="voice_icon"> 16 <string name="voice_icon">
17 icn_voice-groupfocus.tga 17 icn_voice-groupfocus.tga
18 </string> 18 </string>
19 <string name="live_help_dialog" wordwrap="false"> 19 <string name="live_help_dialog" wordwrap="false">
20 *** Welcome to Help Request *** 20 *** Welcome to Help Request ***
21 Please first check our SL Help Pages by pressing F1, or by accessing the Knowledge Base http://secondlife.com/knowledgebase/ 21 Please first check our SL Help Pages by pressing F1, or by accessing the Knowledge Base http://secondlife.com/knowledgebase/
22 If your answer is not there, please enter your question to begin, then allow a few moments for available helpers to respond. 22 If your answer is not there, please enter your question to begin, then allow a few moments for available helpers to respond.
23 -=-=- Response times will vary, especially during peak times -=-=- 23 -=-=- Response times will vary, especially during peak times -=-=-
24 </string> 24 </string>
25 <string name="title_string"> 25 <string name="title_string">
26 Instant Message with [NAME] 26 Instant Message with [NAME]
27 </string> 27 </string>
28 <string name="typing_start_string"> 28 <string name="typing_start_string">
29 [NAME] is typing... 29 [NAME] is typing...
30 </string> 30 </string>
31 <string name="session_start_string"> 31 <string name="session_start_string">
32 Starting session with [NAME], please wait. 32 Starting session with [NAME], please wait.
33 </string> 33 </string>
34 <string name="moderated_chat_label"> 34 <string name="moderated_chat_label">
35 (Moderated: Voices off by default) 35 (Moderated: Voices off by default)
36 </string> 36 </string>
37 <string name="default_text_label"> 37 <string name="default_text_label">
38 Click here to instant message. 38 Click here to instant message.
39 </string> 39 </string>
40 <string name="muted_text_label"> 40 <string name="muted_text_label">
41 Your text chat has been disabled by a Group Moderator. 41 Your text chat has been disabled by a Group Moderator.
42 </string> 42 </string>
43 <layout_stack border="false" bottom="0" follows="left|top|right|bottom" height="276" left="0" 43 <layout_stack border="false" bottom="0" follows="left|top|right|bottom" height="276" left="0"
44 orientation="horizontal" tab_group="1" width="495" name="panels"> 44 orientation="horizontal" tab_group="1" width="495" name="panels">
45 <layout_panel border="false" bottom="0" default_tab_group="1" follows="left|top|bottom|right" 45 <layout_panel border="false" bottom="0" default_tab_group="1" follows="left|top|bottom|right"
46 height="130" left="0" min_width="210" name="im_contents_panel" width="175"> 46 height="130" left="0" min_width="210" name="im_contents_panel" width="175">
47 <button bottom="-20" follows="left|top" height="20" label="Group Info" left="5" 47 <button bottom="-20" follows="left|top" height="20" label="Group Info" left="5"
48 name="group_info_btn" tab_group="0" width="80" /> 48 name="group_info_btn" tab_group="0" width="80" />
49 <button bottom_delta="0" enabled="false" follows="left|top" halign="right" height="20" 49 <button bottom_delta="0" enabled="false" follows="left|top" halign="right" height="20"
50 image_overlay="icn_voice-call-start.tga" image_overlay_alignment="left" 50 image_overlay="icn_voice-call-start.tga" image_overlay_alignment="left"
51 label="Join Call" left_delta="85" name="start_call_btn" pad_right="12" 51 label="Join Call" left_delta="85" name="start_call_btn" pad_right="12"
52 width="80" /> 52 width="80" />
53 <button bottom_delta="0" follows="left|top" halign="right" height="20" 53 <button bottom_delta="0" follows="left|top" halign="right" height="20"
54 image_overlay="icn_voice-call-end.tga" image_overlay_alignment="left" 54 image_overlay="icn_voice-call-end.tga" image_overlay_alignment="left"
55 label="End Call" left_delta="0" name="end_call_btn" pad_right="12" 55 label="End Call" left_delta="0" name="end_call_btn" pad_right="12"
56 visible="false" width="80" /> 56 visible="false" width="80" />
57 <button bottom_delta="0" follows="right|top" height="20" label="&lt; &lt;" 57 <button bottom_delta="0" follows="right|top" height="20" label="&lt; &lt;"
58 label_selected="&gt; &gt;" left="143" name="toggle_active_speakers_btn" 58 label_selected="&gt; &gt;" left="143" name="toggle_active_speakers_btn"
59 right="176" 59 right="176"
60 tool_tip="Click here to toggle a list of active participants in this IM session." 60 tool_tip="Click here to toggle a list of active participants in this IM session."
61 visible="true" width="30" /> 61 visible="true" width="30" />
62 <text_editor type="string" length="1" bg_readonly_color="ChatHistoryBgColor" bg_writeable_color="ChatHistoryBgColor" 62 <text_editor type="string" length="1" bg_readonly_color="ChatHistoryBgColor" bg_writeable_color="ChatHistoryBgColor"
63 bottom="30" embedded_items="false" enabled="false" 63 bottom="30" embedded_items="false" enabled="false"
64 follows="left|top|right|bottom" font="SansSerif" left="4" 64 follows="left|top|right|bottom" font="SansSerif" left="4"
65 max_length="2147483647" mouse_opaque="true" name="im_history" 65 max_length="2147483647" mouse_opaque="true" name="im_history"
66 text_color="ChatHistoryTextColor" 66 text_color="ChatHistoryTextColor"
67 text_readonly_color="ChatHistoryTextColor" top="104" width="170" 67 text_readonly_color="ChatHistoryTextColor" top="104" width="170"
68 word_wrap="true" /> 68 word_wrap="true" />
69 <line_editor bevel_style="in" border_style="line" border_thickness="1" bottom="7" 69 <line_editor bevel_style="in" border_style="line" border_thickness="1" bottom="7"
70 enabled="true" follows="left|right|bottom" font="SansSerif" height="20" 70 enabled="true" follows="left|right|bottom" font="SansSerif" height="20"
71 left="5" max_length="1022" mouse_opaque="true" name="chat_editor" 71 left="5" max_length="1022" mouse_opaque="true" name="chat_editor"
72 select_all_on_focus_received="false" select_on_focus="false" tab_group="1" 72 select_all_on_focus_received="false" select_on_focus="false" tab_group="1"
73 width="106" /> 73 width="106" />
74 <button bottom="7" enabled="true" follows="right|bottom" font="SansSerif" 74 <button bottom="7" enabled="true" follows="right|bottom" font="SansSerif"
75 halign="center" height="20" label="Send" left="116" mouse_opaque="true" 75 halign="center" height="20" label="Send" left="116" mouse_opaque="true"
76 name="send_btn" scale_image="true" width="60" /> 76 name="send_btn" scale_image="true" width="60" />
77 </layout_panel> 77 </layout_panel>
78 <layout_panel auto_resize="false" bottom="0" can_resize="true" 78 <layout_panel auto_resize="false" bottom="0" can_resize="true"
79 filename="panel_speaker_controls.xml" height="120" left="0" min_width="140" 79 filename="panel_speaker_controls.xml" height="120" left="0" min_width="140"
80 name="active_speakers_panel" top_delta="0" visible="false" width="140" /> 80 name="active_speakers_panel" top_delta="0" visible="false" width="140" />
81 </layout_stack> 81 </layout_stack>
82</floater> 82</floater>
diff --git a/linden/indra/newview/viewer_manifest.py b/linden/indra/newview/viewer_manifest.py
index f707d15..d08fd8a 100755
--- a/linden/indra/newview/viewer_manifest.py
+++ b/linden/indra/newview/viewer_manifest.py
@@ -44,6 +44,16 @@ class ViewerManifest(LLManifest):
44 self.exclude("*.svn*") 44 self.exclude("*.svn*")
45 self.path(src="../../scripts/messages/message_template.msg", dst="app_settings/message_template.msg") 45 self.path(src="../../scripts/messages/message_template.msg", dst="app_settings/message_template.msg")
46 self.path(src="../../etc/message.xml", dst="app_settings/message.xml") 46 self.path(src="../../etc/message.xml", dst="app_settings/message.xml")
47 self.path(src="../../../ChangeLog.txt", dst="doc/ChangeLog.txt")
48 self.path(src="../../../CONTRIBUTE.txt", dst="doc/CONTRIBUTE.txt")
49 self.path(src="../../../MANIFESTO.txt", dst="doc/MANIFESTO.txt")
50 self.path(src="../../../README.txt", dst="doc/README.txt")
51 self.path(src="../../../RELEASE_NOTES.txt", dst="doc/RELEASE_NOTES.txt")
52 self.path(src="../../doc/contributions.txt", dst="doc/ll-contributions.txt")
53 self.path(src="../../doc/FLOSS-exception.txt", dst="doc/FLOSS-exception.txt")
54 self.path(src="../../doc/GPL-license.txt", dst="doc/GPL-license.txt")
55 self.path(src="../../doc/releasenotes-where.txt", dst="doc/ll-releasenotes-where.txt")
56#
47 57
48 if self.prefix(src="app_settings"): 58 if self.prefix(src="app_settings"):
49 self.exclude("logcontrol.xml") 59 self.exclude("logcontrol.xml")
@@ -236,18 +246,20 @@ class WindowsManifest(ViewerManifest):
236 self.end_prefix() 246 self.end_prefix()
237 247
238 # Vivox runtimes 248 # Vivox runtimes
239 #if self.prefix(src="vivox-runtime/i686-win32", dst=""): 249 if self.prefix(src="vivox-runtime/i686-win32", dst=""):
250 self.path("alut.dll")
251 self.path("wrap_oal.dll")
252
240 # self.path("SLVoice.exe") 253 # self.path("SLVoice.exe")
241 # self.path("SLVoiceAgent.exe") 254 # self.path("SLVoiceAgent.exe")
242 # self.path("libeay32.dll") 255 # self.path("libeay32.dll")
243 # self.path("srtp.dll") 256 # self.path("srtp.dll")
244 # self.path("ssleay32.dll") 257 # self.path("ssleay32.dll")
245 # self.path("tntk.dll") 258 # self.path("tntk.dll")
246 # self.path("alut.dll")
247 # self.path("vivoxsdk.dll") 259 # self.path("vivoxsdk.dll")
248 # self.path("ortp.dll") 260 # self.path("ortp.dll")
249 # self.path("wrap_oal.dll") 261
250 # self.end_prefix() 262 self.end_prefix()
251 263
252# # pull in the crash logger and updater from other projects 264# # pull in the crash logger and updater from other projects
253# self.path(src=self.find_existing_file( # tag:"crash-logger" here as a cue to the exporter 265# self.path(src=self.find_existing_file( # tag:"crash-logger" here as a cue to the exporter
@@ -432,9 +444,10 @@ class DarwinManifest(ViewerManifest):
432 self.path("Japanese.lproj") 444 self.path("Japanese.lproj")
433 self.path("Korean.lproj") 445 self.path("Korean.lproj")
434 446
447
435 # SLVoice and vivox lols 448 # SLVoice and vivox lols
436 #self.path("vivox-runtime/universal-darwin/libalut.dylib", "libalut.dylib") 449 self.path("vivox-runtime/universal-darwin/libalut.dylib", "libalut.dylib")
437 #self.path("vivox-runtime/universal-darwin/libopenal.dylib", "libopenal.dylib") 450 self.path("vivox-runtime/universal-darwin/libopenal.dylib", "libopenal.dylib")
438 #self.path("vivox-runtime/universal-darwin/libortp.dylib", "libortp.dylib") 451 #self.path("vivox-runtime/universal-darwin/libortp.dylib", "libortp.dylib")
439 #self.path("vivox-runtime/universal-darwin/libvivoxsdk.dylib", "libvivoxsdk.dylib") 452 #self.path("vivox-runtime/universal-darwin/libvivoxsdk.dylib", "libvivoxsdk.dylib")
440 #self.path("vivox-runtime/universal-darwin/SLVoice", "SLVoice") 453 #self.path("vivox-runtime/universal-darwin/SLVoice", "SLVoice")
@@ -667,12 +680,13 @@ class Linux_i686Manifest(LinuxManifest):
667 #if self.prefix(src="vivox-runtime/i686-linux", dst="bin"): 680 #if self.prefix(src="vivox-runtime/i686-linux", dst="bin"):
668 # self.path("SLVoice") 681 # self.path("SLVoice")
669 # self.end_prefix() 682 # self.end_prefix()
670 #if self.prefix(src="vivox-runtime/i686-linux", dst="lib"): 683
671 # self.path("libopenal.so.1") 684 if self.prefix(src="vivox-runtime/i686-linux", dst="lib"):
685 self.path("libopenal.so.1")
686 self.path("libalut.so")
672 # self.path("libortp.so") 687 # self.path("libortp.so")
673 # self.path("libvivoxsdk.so") 688 # self.path("libvivoxsdk.so")
674 # self.path("libalut.so") 689 self.end_prefix("lib")
675 # self.end_prefix("lib")
676 690
677class Linux_x86_64Manifest(LinuxManifest): 691class Linux_x86_64Manifest(LinuxManifest):
678 def construct(self): 692 def construct(self):
diff --git a/linden/install.xml b/linden/install.xml
index 6184335..f764a5e 100644
--- a/linden/install.xml
+++ b/linden/install.xml
@@ -753,6 +753,39 @@ anguage Infrstructure (CLI) international standard</string>
753 </map> 753 </map>
754 </map> 754 </map>
755 </map> 755 </map>
756 <key>openal</key>
757 <map>
758 <key>copyright</key>
759 <string>Copyright (C) 2008 by authors.</string>
760 <key>description</key>
761 <string>3D Audio library</string>
762 <key>license</key>
763 <string>lgpl</string>
764 <key>packages</key>
765 <map>
766 <key>darwin</key>
767 <map>
768 <key>md5sum</key>
769 <string>a0757244e3e6688fde2ffeea35cc1f96</string>
770 <key>url</key>
771 <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/openal-darwin-20080924.tar.bz2</uri>
772 </map>
773 <key>linux</key>
774 <map>
775 <key>md5sum</key>
776 <string>f0d9a8d1318b519cffe6c40c9cac4e21</string>
777 <key>url</key>
778 <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/openal-linux-20081010c-59a71b14-plughw.tar.bz2</uri>
779 </map>
780 <key>windows</key>
781 <map>
782 <key>md5sum</key>
783 <string>a0757244e3e6688fde2ffeea35cc1f96</string>
784 <key>url</key>
785 <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/openal-windows-20080924.tar.bz2</uri>
786 </map>
787 </map>
788 </map>
756 <key>openSSL</key> 789 <key>openSSL</key>
757 <map> 790 <map>
758 <key>license</key> 791 <key>license</key>