aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llaudio
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:50 -0500
committerJacek Antonelli2008-08-15 23:44:50 -0500
commit89fe5dab825a62a0e3fd8d248cbc91c65eb2a426 (patch)
treebcff14b7888d04a2fec799c59369f6095224bd08 /linden/indra/llaudio
parentSecond Life viewer sources 1.13.3.2 (diff)
downloadmeta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.zip
meta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.tar.gz
meta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.tar.bz2
meta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.tar.xz
Second Life viewer sources 1.14.0.0
Diffstat (limited to 'linden/indra/llaudio')
-rw-r--r--linden/indra/llaudio/audioengine_fmod.cpp11
-rw-r--r--linden/indra/llaudio/llaudio_vc8.vcproj321
-rw-r--r--linden/indra/llaudio/llaudiodecodemgr.cpp378
-rw-r--r--linden/indra/llaudio/llaudiodecodemgr.h12
4 files changed, 520 insertions, 202 deletions
diff --git a/linden/indra/llaudio/audioengine_fmod.cpp b/linden/indra/llaudio/audioengine_fmod.cpp
index 0e8ea67..2e8f45f 100644
--- a/linden/indra/llaudio/audioengine_fmod.cpp
+++ b/linden/indra/llaudio/audioengine_fmod.cpp
@@ -491,16 +491,17 @@ BOOL LLAudioChannelFMOD::updateBuffer()
491 // If we have a source for the channel, we need to update its gain. 491 // If we have a source for the channel, we need to update its gain.
492 if (mCurrentSourcep) 492 if (mCurrentSourcep)
493 { 493 {
494 // SJB: warnings can spam and hurt framerate, disabling
494 if (!FSOUND_SetVolume(mChannelID, llround(mCurrentSourcep->getGain() * 255.0f))) 495 if (!FSOUND_SetVolume(mChannelID, llround(mCurrentSourcep->getGain() * 255.0f)))
495 { 496 {
496 llwarns << "LLAudioChannelFMOD::updateBuffer error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl; 497// llwarns << "LLAudioChannelFMOD::updateBuffer error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl;
497 } 498 }
498 499
499 if (!FSOUND_SetLoopMode(mChannelID, mCurrentSourcep->isLoop() ? FSOUND_LOOP_NORMAL : FSOUND_LOOP_OFF)) 500 if (!FSOUND_SetLoopMode(mChannelID, mCurrentSourcep->isLoop() ? FSOUND_LOOP_NORMAL : FSOUND_LOOP_OFF))
500 { 501 {
501 llwarns << "Channel " << mChannelID << llendl; 502// llwarns << "Channel " << mChannelID << "Source ID: " << mCurrentSourcep->getID()
502 llwarns << "Source ID: " << mCurrentSourcep->getID() << " at " << mCurrentSourcep->getPositionGlobal() << llendl; 503// << " at " << mCurrentSourcep->getPositionGlobal() << llendl;
503 llwarns << "LLAudioChannelFMOD::updateBuffer error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl; 504// llwarns << "LLAudioChannelFMOD::updateBuffer error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl;
504 } 505 }
505 } 506 }
506 507
@@ -686,7 +687,7 @@ BOOL LLAudioBufferFMOD::loadWAV(const char *filename)
686 // MikeS. - Loading the sound file manually and then handing it over to FMOD, 687 // MikeS. - Loading the sound file manually and then handing it over to FMOD,
687 // since FMOD uses posix IO internally, 688 // since FMOD uses posix IO internally,
688 // which doesn't work with unicode file paths. 689 // which doesn't work with unicode file paths.
689 FILE* sound_file = LLFile::fopen(filename,"rb"); 690 FILE* sound_file = LLFile::fopen(filename,"rb"); /* Flawfinder: ignore */
690 if (sound_file) 691 if (sound_file)
691 { 692 {
692 fseek(sound_file,0,SEEK_END); 693 fseek(sound_file,0,SEEK_END);
diff --git a/linden/indra/llaudio/llaudio_vc8.vcproj b/linden/indra/llaudio/llaudio_vc8.vcproj
new file mode 100644
index 0000000..d0b4bb4
--- /dev/null
+++ b/linden/indra/llaudio/llaudio_vc8.vcproj
@@ -0,0 +1,321 @@
1<?xml version="1.0" encoding="Windows-1252"?>
2<VisualStudioProject
3 ProjectType="Visual C++"
4 Version="8.00"
5 Name="llaudio"
6 ProjectGUID="{93B2BA29-FBE9-4376-92C1-6108DCFE09D3}"
7 RootNamespace="llaudio"
8 Keyword="Win32Proj"
9 >
10 <Platforms>
11 <Platform
12 Name="Win32"
13 />
14 </Platforms>
15 <ToolFiles>
16 </ToolFiles>
17 <Configurations>
18 <Configuration
19 Name="Debug|Win32"
20 OutputDirectory="../lib_$(ConfigurationName)/i686-win32"
21 IntermediateDirectory="Debug"
22 ConfigurationType="4"
23 InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
24 CharacterSet="1"
25 >
26 <Tool
27 Name="VCPreBuildEventTool"
28 />
29 <Tool
30 Name="VCCustomBuildTool"
31 />
32 <Tool
33 Name="VCXMLDataGeneratorTool"
34 />
35 <Tool
36 Name="VCWebServiceProxyGeneratorTool"
37 />
38 <Tool
39 Name="VCMIDLTool"
40 />
41 <Tool
42 Name="VCCLCompilerTool"
43 Optimization="0"
44 AdditionalIncludeDirectories="..\llcommon;..\llmath;..\llvfs;..\llmessage;..\..\libraries\i686-win32\include;..\..\libraries\include\;"
45 PreprocessorDefinitions="WIN32;_DEBUG;_LIB;LL_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_USE_32BIT_TIME_T;LL_DEBUG"
46 MinimalRebuild="true"
47 BasicRuntimeChecks="3"
48 RuntimeLibrary="1"
49 StructMemberAlignment="4"
50 TreatWChar_tAsBuiltInType="false"
51 ForceConformanceInForLoopScope="true"
52 UsePrecompiledHeader="0"
53 WarningLevel="3"
54 WarnAsError="true"
55 Detect64BitPortabilityProblems="false"
56 DebugInformationFormat="4"
57 />
58 <Tool
59 Name="VCManagedResourceCompilerTool"
60 />
61 <Tool
62 Name="VCResourceCompilerTool"
63 />
64 <Tool
65 Name="VCPreLinkEventTool"
66 />
67 <Tool
68 Name="VCLibrarianTool"
69 OutputFile="$(OutDir)/llaudio.lib"
70 />
71 <Tool
72 Name="VCALinkTool"
73 />
74 <Tool
75 Name="VCXDCMakeTool"
76 />
77 <Tool
78 Name="VCBscMakeTool"
79 />
80 <Tool
81 Name="VCFxCopTool"
82 />
83 <Tool
84 Name="VCPostBuildEventTool"
85 />
86 </Configuration>
87 <Configuration
88 Name="Release|Win32"
89 OutputDirectory="../lib_$(ConfigurationName)/i686-win32"
90 IntermediateDirectory="Release"
91 ConfigurationType="4"
92 InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
93 CharacterSet="1"
94 >
95 <Tool
96 Name="VCPreBuildEventTool"
97 />
98 <Tool
99 Name="VCCustomBuildTool"
100 />
101 <Tool
102 Name="VCXMLDataGeneratorTool"
103 />
104 <Tool
105 Name="VCWebServiceProxyGeneratorTool"
106 />
107 <Tool
108 Name="VCMIDLTool"
109 />
110 <Tool
111 Name="VCCLCompilerTool"
112 AdditionalIncludeDirectories="..\llcommon;..\llmath;..\llvfs;..\llmessage;..\..\libraries\i686-win32\include;..\..\libraries\include\"
113 PreprocessorDefinitions="WIN32;NDEBUG;_LIB;LL_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_USE_32BIT_TIME_T;LL_RELEASE"
114 RuntimeLibrary="0"
115 StructMemberAlignment="0"
116 TreatWChar_tAsBuiltInType="false"
117 ForceConformanceInForLoopScope="true"
118 UsePrecompiledHeader="0"
119 WarningLevel="3"
120 WarnAsError="true"
121 Detect64BitPortabilityProblems="false"
122 DebugInformationFormat="3"
123 />
124 <Tool
125 Name="VCManagedResourceCompilerTool"
126 />
127 <Tool
128 Name="VCResourceCompilerTool"
129 />
130 <Tool
131 Name="VCPreLinkEventTool"
132 />
133 <Tool
134 Name="VCLibrarianTool"
135 OutputFile="$(OutDir)/llaudio.lib"
136 />
137 <Tool
138 Name="VCALinkTool"
139 />
140 <Tool
141 Name="VCXDCMakeTool"
142 />
143 <Tool
144 Name="VCBscMakeTool"
145 />
146 <Tool
147 Name="VCFxCopTool"
148 />
149 <Tool
150 Name="VCPostBuildEventTool"
151 />
152 </Configuration>
153 <Configuration
154 Name="ReleaseNoOpt|Win32"
155 OutputDirectory="../lib_$(ConfigurationName)/i686-win32"
156 IntermediateDirectory="$(ConfigurationName)"
157 ConfigurationType="4"
158 InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
159 CharacterSet="1"
160 >
161 <Tool
162 Name="VCPreBuildEventTool"
163 />
164 <Tool
165 Name="VCCustomBuildTool"
166 />
167 <Tool
168 Name="VCXMLDataGeneratorTool"
169 />
170 <Tool
171 Name="VCWebServiceProxyGeneratorTool"
172 />
173 <Tool
174 Name="VCMIDLTool"
175 />
176 <Tool
177 Name="VCCLCompilerTool"
178 Optimization="0"
179 AdditionalIncludeDirectories="..\llcommon;..\llmath;..\llvfs;..\llmessage;..\..\libraries\i686-win32\include;..\..\libraries\include\"
180 PreprocessorDefinitions="WIN32;NDEBUG;_LIB;LL_WINDOWS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_USE_32BIT_TIME_T;LL_RELEASE"
181 RuntimeLibrary="0"
182 StructMemberAlignment="0"
183 TreatWChar_tAsBuiltInType="false"
184 ForceConformanceInForLoopScope="true"
185 UsePrecompiledHeader="0"
186 WarningLevel="3"
187 WarnAsError="true"
188 Detect64BitPortabilityProblems="false"
189 DebugInformationFormat="3"
190 />
191 <Tool
192 Name="VCManagedResourceCompilerTool"
193 />
194 <Tool
195 Name="VCResourceCompilerTool"
196 />
197 <Tool
198 Name="VCPreLinkEventTool"
199 />
200 <Tool
201 Name="VCLibrarianTool"
202 OutputFile="$(OutDir)/llaudio.lib"
203 />
204 <Tool
205 Name="VCALinkTool"
206 />
207 <Tool
208 Name="VCXDCMakeTool"
209 />
210 <Tool
211 Name="VCBscMakeTool"
212 />
213 <Tool
214 Name="VCFxCopTool"
215 />
216 <Tool
217 Name="VCPostBuildEventTool"
218 />
219 </Configuration>
220 </Configurations>
221 <References>
222 </References>
223 <Files>
224 <Filter
225 Name="Source Files"
226 Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
227 UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
228 >
229 <File
230 RelativePath=".\audioengine.cpp"
231 >
232 </File>
233 <File
234 RelativePath=".\audioengine_fmod.cpp"
235 >
236 </File>
237 <File
238 RelativePath=".\listener.cpp"
239 >
240 </File>
241 <File
242 RelativePath=".\listener_fmod.cpp"
243 >
244 </File>
245 <File
246 RelativePath=".\llaudiodecodemgr.cpp"
247 >
248 </File>
249 <File
250 RelativePath=".\vorbisdecode.cpp"
251 >
252 </File>
253 <File
254 RelativePath=".\vorbisencode.cpp"
255 >
256 </File>
257 </Filter>
258 <Filter
259 Name="Header Files"
260 Filter="h;hpp;hxx;hm;inl;inc;xsd"
261 UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
262 >
263 <File
264 RelativePath=".\audioengine.h"
265 >
266 </File>
267 <File
268 RelativePath=".\audioengine_fmod.h"
269 >
270 </File>
271 <File
272 RelativePath=".\fmod.h"
273 >
274 </File>
275 <File
276 RelativePath=".\fmod_errors.h"
277 >
278 </File>
279 <File
280 RelativePath=".\listener.h"
281 >
282 </File>
283 <File
284 RelativePath=".\listener_ds3d.h"
285 >
286 </File>
287 <File
288 RelativePath=".\listener_fmod.h"
289 >
290 </File>
291 <File
292 RelativePath=".\listener_openal.h"
293 >
294 </File>
295 <File
296 RelativePath=".\llaudiodecodemgr.h"
297 >
298 </File>
299 <File
300 RelativePath=".\vorbisdecode.h"
301 >
302 </File>
303 <File
304 RelativePath=".\vorbisencode.h"
305 >
306 </File>
307 <File
308 RelativePath=".\wavefile.h"
309 >
310 </File>
311 </Filter>
312 <Filter
313 Name="Resource Files"
314 Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
315 UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
316 >
317 </Filter>
318 </Files>
319 <Globals>
320 </Globals>
321</VisualStudioProject>
diff --git a/linden/indra/llaudio/llaudiodecodemgr.cpp b/linden/indra/llaudio/llaudiodecodemgr.cpp
index d98ff5d..832c314 100644
--- a/linden/indra/llaudio/llaudiodecodemgr.cpp
+++ b/linden/indra/llaudio/llaudiodecodemgr.cpp
@@ -52,9 +52,25 @@ LLAudioDecodeMgr *gAudioDecodeMgrp = NULL;
52 52
53static const S32 WAV_HEADER_SIZE = 44; 53static const S32 WAV_HEADER_SIZE = 44;
54 54
55class LLVorbisDecodeState 55
56//////////////////////////////////////////////////////////////////////////////
57
58
59class LLVorbisDecodeState : public LLRefCount
56{ 60{
57public: 61public:
62 class WriteResponder : public LLLFSThread::Responder
63 {
64 public:
65 WriteResponder(LLVorbisDecodeState* decoder) : mDecoder(decoder) {}
66 ~WriteResponder() {}
67 void completed(S32 bytes)
68 {
69 mDecoder->ioComplete(bytes);
70 }
71 LLPointer<LLVorbisDecodeState> mDecoder;
72 };
73
58 LLVorbisDecodeState(const LLUUID &uuid, const LLString &out_filename); 74 LLVorbisDecodeState(const LLUUID &uuid, const LLString &out_filename);
59 virtual ~LLVorbisDecodeState(); 75 virtual ~LLVorbisDecodeState();
60 76
@@ -64,12 +80,14 @@ public:
64 80
65 void flushBadFile(); 81 void flushBadFile();
66 82
83 void ioComplete(S32 bytes) { mBytesRead = bytes; }
67 BOOL isValid() const { return mValid; } 84 BOOL isValid() const { return mValid; }
68 BOOL isDone() const { return mDone; } 85 BOOL isDone() const { return mDone; }
69 const LLUUID &getUUID() const { return mUUID; } 86 const LLUUID &getUUID() const { return mUUID; }
70protected: 87protected:
71 BOOL mValid; 88 BOOL mValid;
72 BOOL mDone; 89 BOOL mDone;
90 LLAtomicS32 mBytesRead;
73 LLUUID mUUID; 91 LLUUID mUUID;
74 92
75 std::vector<U8> mWAVBuffer; 93 std::vector<U8> mWAVBuffer;
@@ -83,172 +101,6 @@ protected:
83 S32 mCurrentSection; 101 S32 mCurrentSection;
84}; 102};
85 103
86void LLVorbisDecodeState::flushBadFile()
87{
88 if (mInFilep)
89 {
90 llwarns << "Flushing bad vorbis file from VFS for " << mUUID << llendl;
91 mInFilep->remove();
92 }
93}
94
95
96LLAudioDecodeMgr::LLAudioDecodeMgr()
97{
98 mCurrentDecodep = NULL;
99}
100
101LLAudioDecodeMgr::~LLAudioDecodeMgr()
102{
103 delete mCurrentDecodep;
104 mCurrentDecodep = NULL;
105}
106
107
108void LLAudioDecodeMgr::processQueue(const F32 num_secs)
109{
110 LLUUID uuid;
111
112 LLTimer decode_timer;
113
114 BOOL done = FALSE;
115 while (!done)
116 {
117 if (mCurrentDecodep)
118 {
119 BOOL res;
120
121 // Decode in a loop until we're done or have run out of time.
122 while(!(res = mCurrentDecodep->decodeSection()) && (decode_timer.getElapsedTimeF32() < num_secs))
123 {
124 // decodeSection does all of the work above
125 }
126
127 if (mCurrentDecodep->isDone() && !mCurrentDecodep->isValid())
128 {
129 // We had an error when decoding, abort.
130 llwarns << mCurrentDecodep->getUUID() << " has invalid vorbis data, aborting decode" << llendl;
131 mCurrentDecodep->flushBadFile();
132 LLAudioData *adp = gAudiop->getAudioData(mCurrentDecodep->getUUID());
133 adp->setHasValidData(FALSE);
134 delete mCurrentDecodep;
135 mCurrentDecodep = NULL;
136 done = TRUE;
137 }
138
139 if (!res)
140 {
141 // We've used up out time slice, bail...
142 done = TRUE;
143 }
144 else if (mCurrentDecodep)
145 {
146 if (mCurrentDecodep->finishDecode())
147 {
148 // We finished!
149 if (mCurrentDecodep->isValid() && mCurrentDecodep->isDone())
150 {
151 LLAudioData *adp = gAudiop->getAudioData(mCurrentDecodep->getUUID());
152 adp->setHasDecodedData(TRUE);
153 adp->setHasValidData(TRUE);
154
155 // At this point, we could see if anyone needs this sound immediately, but
156 // I'm not sure that there's a reason to - we need to poll all of the playing
157 // sounds anyway.
158 //llinfos << "Finished the vorbis decode, now what?" << llendl;
159 }
160 else
161 {
162 llinfos << "Vorbis decode failed!!!" << llendl;
163 }
164 delete mCurrentDecodep;
165 mCurrentDecodep = NULL;
166 }
167 done = TRUE; // done for now
168 }
169 }
170
171 if (!done)
172 {
173 if (!mDecodeQueue.getLength())
174 {
175 // Nothing else on the queue.
176 done = TRUE;
177 }
178 else
179 {
180 LLUUID uuid;
181 mDecodeQueue.pop(uuid);
182 if (gAudiop->hasDecodedFile(uuid))
183 {
184 // This file has already been decoded, don't decode it again.
185 continue;
186 }
187
188 lldebugs << "Decoding " << uuid << " from audio queue!" << llendl;
189
190 char uuid_str[64]; /*Flawfinder: ignore*/
191 char d_path[LL_MAX_PATH]; /*Flawfinder: ignore*/
192
193 LLTimer timer;
194 timer.reset();
195
196 uuid.toString(uuid_str);
197 snprintf(d_path, LL_MAX_PATH, "%s.dsf", gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_str).c_str()); /*Flawfinder: ignore*/
198
199 mCurrentDecodep = new LLVorbisDecodeState(uuid, d_path);
200 if (!mCurrentDecodep->initDecode())
201 {
202 delete mCurrentDecodep;
203 mCurrentDecodep = NULL;
204 }
205 }
206 }
207 }
208}
209
210
211BOOL LLAudioDecodeMgr::addDecodeRequest(const LLUUID &uuid)
212{
213 if (gAudiop->hasDecodedFile(uuid))
214 {
215 // Already have a decoded version, don't need to decode it.
216 return TRUE;
217 }
218
219 if (gAssetStorage->hasLocalAsset(uuid, LLAssetType::AT_SOUND))
220 {
221 // Just put it on the decode queue.
222 gAudioDecodeMgrp->mDecodeQueue.push(uuid);
223 return TRUE;
224 }
225
226 return FALSE;
227}
228
229
230S32 LLAudioDecodeMgr::getRequestCount()
231{
232 /*
233 S32 count = 0;
234 if (mCurrentTransfer.notNull())
235 {
236 count++;
237 }
238
239 count += mRequestQueue.getLength();
240 return count;
241 */
242 return 0;
243}
244
245
246
247
248
249
250
251
252size_t vfs_read(void *ptr, size_t size, size_t nmemb, void *datasource) 104size_t vfs_read(void *ptr, size_t size, size_t nmemb, void *datasource)
253{ 105{
254 LLVFile *file = (LLVFile *)datasource; 106 LLVFile *file = (LLVFile *)datasource;
@@ -303,26 +155,21 @@ int vfs_seek(void *datasource, ogg_int64_t offset, int whence)
303int vfs_close (void *datasource) 155int vfs_close (void *datasource)
304{ 156{
305 LLVFile *file = (LLVFile *)datasource; 157 LLVFile *file = (LLVFile *)datasource;
306
307 delete file; 158 delete file;
308
309 return 0; 159 return 0;
310} 160}
311 161
312long vfs_tell (void *datasource) 162long vfs_tell (void *datasource)
313{ 163{
314 LLVFile *file = (LLVFile *)datasource; 164 LLVFile *file = (LLVFile *)datasource;
315
316 return file->tell(); 165 return file->tell();
317} 166}
318 167
319
320
321
322LLVorbisDecodeState::LLVorbisDecodeState(const LLUUID &uuid, const LLString &out_filename) 168LLVorbisDecodeState::LLVorbisDecodeState(const LLUUID &uuid, const LLString &out_filename)
323{ 169{
324 mDone = FALSE; 170 mDone = FALSE;
325 mValid = FALSE; 171 mValid = FALSE;
172 mBytesRead = -1;
326 mUUID = uuid; 173 mUUID = uuid;
327 mInFilep = NULL; 174 mInFilep = NULL;
328 mCurrentSection = 0; 175 mCurrentSection = 0;
@@ -594,32 +441,27 @@ BOOL LLVorbisDecodeState::finishDecode()
594 return TRUE; // we've finished 441 return TRUE; // we've finished
595 } 442 }
596#if !defined(USE_WAV_VFILE) 443#if !defined(USE_WAV_VFILE)
597 mFileHandle = LLLFSThread::sLocal->write(mOutFilename, &mWAVBuffer[0], 0, data_length); 444 mBytesRead = -1;
445 mFileHandle = LLLFSThread::sLocal->write(mOutFilename, &mWAVBuffer[0], 0, data_length,
446 new WriteResponder(this));
598#endif 447#endif
599 } 448 }
600 449
601 if (mFileHandle != LLLFSThread::nullHandle()) 450 if (mFileHandle != LLLFSThread::nullHandle())
602 { 451 {
603 LLLFSThread::status_t s = LLLFSThread::sLocal->getRequestStatus(mFileHandle); 452 if (mBytesRead >= 0)
604 if (s != LLLFSThread::STATUS_COMPLETE)
605 {
606 if (s != LLLFSThread::STATUS_QUEUED && s != LLLFSThread::STATUS_INPROGRESS)
607 {
608 llerrs << "Bad file status in LLVorbisDecodeState::finishDecode: " << s << llendl;
609 }
610 return FALSE; // not finished
611 }
612 else
613 { 453 {
614 LLLFSThread::Request* req = (LLLFSThread::Request*)LLLFSThread::sLocal->getRequest(mFileHandle); 454 if (mBytesRead == 0)
615 if (req->getBytesRead() == 0) //!= req->getBytes() // should be safe, but needs testing
616 { 455 {
617 llwarns << "Unable to write file in LLVorbisDecodeState::finishDecode" << llendl; 456 llwarns << "Unable to write file in LLVorbisDecodeState::finishDecode" << llendl;
618 mValid = FALSE; 457 mValid = FALSE;
619 return TRUE; // we've finished 458 return TRUE; // we've finished
620 } 459 }
621 } 460 }
622 LLLFSThread::sLocal->completeRequest(mFileHandle); 461 else
462 {
463 return FALSE; // not done
464 }
623 } 465 }
624 466
625 mDone = TRUE; 467 mDone = TRUE;
@@ -633,3 +475,165 @@ BOOL LLVorbisDecodeState::finishDecode()
633 475
634 return TRUE; 476 return TRUE;
635} 477}
478
479void LLVorbisDecodeState::flushBadFile()
480{
481 if (mInFilep)
482 {
483 llwarns << "Flushing bad vorbis file from VFS for " << mUUID << llendl;
484 mInFilep->remove();
485 }
486}
487
488//////////////////////////////////////////////////////////////////////////////
489
490class LLAudioDecodeMgr::Impl
491{
492 friend class LLAudioDecodeMgr;
493public:
494 Impl() {};
495 ~Impl() {};
496
497 void processQueue(const F32 num_secs = 0.005);
498
499protected:
500 LLLinkedQueue<LLUUID> mDecodeQueue;
501 LLPointer<LLVorbisDecodeState> mCurrentDecodep;
502};
503
504
505void LLAudioDecodeMgr::Impl::processQueue(const F32 num_secs)
506{
507 LLUUID uuid;
508
509 LLTimer decode_timer;
510
511 BOOL done = FALSE;
512 while (!done)
513 {
514 if (mCurrentDecodep)
515 {
516 BOOL res;
517
518 // Decode in a loop until we're done or have run out of time.
519 while(!(res = mCurrentDecodep->decodeSection()) && (decode_timer.getElapsedTimeF32() < num_secs))
520 {
521 // decodeSection does all of the work above
522 }
523
524 if (mCurrentDecodep->isDone() && !mCurrentDecodep->isValid())
525 {
526 // We had an error when decoding, abort.
527 llwarns << mCurrentDecodep->getUUID() << " has invalid vorbis data, aborting decode" << llendl;
528 mCurrentDecodep->flushBadFile();
529 LLAudioData *adp = gAudiop->getAudioData(mCurrentDecodep->getUUID());
530 adp->setHasValidData(FALSE);
531 mCurrentDecodep = NULL;
532 done = TRUE;
533 }
534
535 if (!res)
536 {
537 // We've used up out time slice, bail...
538 done = TRUE;
539 }
540 else if (mCurrentDecodep)
541 {
542 if (mCurrentDecodep->finishDecode())
543 {
544 // We finished!
545 if (mCurrentDecodep->isValid() && mCurrentDecodep->isDone())
546 {
547 LLAudioData *adp = gAudiop->getAudioData(mCurrentDecodep->getUUID());
548 adp->setHasDecodedData(TRUE);
549 adp->setHasValidData(TRUE);
550
551 // At this point, we could see if anyone needs this sound immediately, but
552 // I'm not sure that there's a reason to - we need to poll all of the playing
553 // sounds anyway.
554 //llinfos << "Finished the vorbis decode, now what?" << llendl;
555 }
556 else
557 {
558 llinfos << "Vorbis decode failed!!!" << llendl;
559 }
560 mCurrentDecodep = NULL;
561 }
562 done = TRUE; // done for now
563 }
564 }
565
566 if (!done)
567 {
568 if (!mDecodeQueue.getLength())
569 {
570 // Nothing else on the queue.
571 done = TRUE;
572 }
573 else
574 {
575 LLUUID uuid;
576 mDecodeQueue.pop(uuid);
577 if (gAudiop->hasDecodedFile(uuid))
578 {
579 // This file has already been decoded, don't decode it again.
580 continue;
581 }
582
583 lldebugs << "Decoding " << uuid << " from audio queue!" << llendl;
584
585 char uuid_str[64]; /*Flawfinder: ignore*/
586 char d_path[LL_MAX_PATH]; /*Flawfinder: ignore*/
587
588 LLTimer timer;
589 timer.reset();
590
591 uuid.toString(uuid_str);
592 snprintf(d_path, LL_MAX_PATH, "%s.dsf", gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_str).c_str()); /*Flawfinder: ignore*/
593
594 mCurrentDecodep = new LLVorbisDecodeState(uuid, d_path);
595 if (!mCurrentDecodep->initDecode())
596 {
597 mCurrentDecodep = NULL;
598 }
599 }
600 }
601 }
602}
603
604//////////////////////////////////////////////////////////////////////////////
605
606LLAudioDecodeMgr::LLAudioDecodeMgr()
607{
608 mImpl = new Impl;
609}
610
611LLAudioDecodeMgr::~LLAudioDecodeMgr()
612{
613 delete mImpl;
614}
615
616void LLAudioDecodeMgr::processQueue(const F32 num_secs)
617{
618 mImpl->processQueue(num_secs);
619}
620
621BOOL LLAudioDecodeMgr::addDecodeRequest(const LLUUID &uuid)
622{
623 if (gAudiop->hasDecodedFile(uuid))
624 {
625 // Already have a decoded version, don't need to decode it.
626 return TRUE;
627 }
628
629 if (gAssetStorage->hasLocalAsset(uuid, LLAssetType::AT_SOUND))
630 {
631 // Just put it on the decode queue.
632 mImpl->mDecodeQueue.push(uuid);
633 return TRUE;
634 }
635
636 return FALSE;
637}
638
639
diff --git a/linden/indra/llaudio/llaudiodecodemgr.h b/linden/indra/llaudio/llaudiodecodemgr.h
index 3480004..aab7144 100644
--- a/linden/indra/llaudio/llaudiodecodemgr.h
+++ b/linden/indra/llaudio/llaudiodecodemgr.h
@@ -38,7 +38,6 @@
38class LLVFS; 38class LLVFS;
39class LLVorbisDecodeState; 39class LLVorbisDecodeState;
40 40
41
42class LLAudioDecodeMgr 41class LLAudioDecodeMgr
43{ 42{
44public: 43public:
@@ -46,19 +45,12 @@ public:
46 ~LLAudioDecodeMgr(); 45 ~LLAudioDecodeMgr();
47 46
48 void processQueue(const F32 num_secs = 0.005); 47 void processQueue(const F32 num_secs = 0.005);
49
50 LLLinkedQueue<LLUUID> mDecodeQueue;
51
52 LLVorbisDecodeState *mCurrentDecodep;
53
54 BOOL addDecodeRequest(const LLUUID &uuid); 48 BOOL addDecodeRequest(const LLUUID &uuid);
55 void addAudioRequest(const LLUUID &uuid); 49 void addAudioRequest(const LLUUID &uuid);
56
57 S32 getRequestCount();
58 50
59protected: 51protected:
60 LLLinkedQueue<LLUUID> mDownloadQueue; 52 class Impl;
61 LLFrameTimer mCurrentTransferAge; 53 Impl* mImpl;
62}; 54};
63 55
64extern LLAudioDecodeMgr *gAudioDecodeMgrp; 56extern LLAudioDecodeMgr *gAudioDecodeMgrp;