summaryrefslogtreecommitdiff
path: root/indra/llaudio
diff options
context:
space:
mode:
authorErik Kundiman <erik@megapahit.org>2024-05-16 13:52:40 +0800
committerErik Kundiman <erik@megapahit.org>2024-05-16 13:52:40 +0800
commit6d51e91895a7f2435c46a876410ccc6c63fe8c82 (patch)
treef2b48ebd99cb414227bf365f47665b8d4baa752b /indra/llaudio
parentd1b5917bb9c92e4e47eba19b43781e4d1328b1ca (diff)
parent094dcc07f8c1d90ae723dbe60eddacb90a09eae8 (diff)
Merge tag '7.1.7-release'
source for viewer 7.1.7.8974243247
Diffstat (limited to 'indra/llaudio')
-rwxr-xr-xindra/llaudio/llaudiodecodemgr.cpp884
-rw-r--r--indra/llaudio/llaudiodecodemgr.h20
-rw-r--r--indra/llaudio/llaudioengine.cpp2622
-rwxr-xr-xindra/llaudio/llaudioengine.h512
-rw-r--r--indra/llaudio/llaudioengine_fmodstudio.cpp16
-rw-r--r--indra/llaudio/llaudioengine_fmodstudio.h108
-rw-r--r--indra/llaudio/llaudioengine_openal.cpp760
-rw-r--r--indra/llaudio/llaudioengine_openal.h98
-rw-r--r--indra/llaudio/lllistener.cpp50
-rw-r--r--indra/llaudio/lllistener.h54
-rw-r--r--indra/llaudio/lllistener_ds3d.h40
-rw-r--r--indra/llaudio/lllistener_fmodstudio.cpp10
-rw-r--r--indra/llaudio/lllistener_fmodstudio.h12
-rw-r--r--indra/llaudio/lllistener_openal.cpp72
-rw-r--r--indra/llaudio/lllistener_openal.h36
-rw-r--r--indra/llaudio/llstreamingaudio.h34
-rw-r--r--indra/llaudio/llstreamingaudio_fmodstudio.cpp30
-rw-r--r--indra/llaudio/llstreamingaudio_fmodstudio.h14
-rw-r--r--indra/llaudio/llvorbisencode.cpp898
-rw-r--r--indra/llaudio/llvorbisencode.h12
-rw-r--r--indra/llaudio/llwindgen.h268
21 files changed, 3275 insertions, 3275 deletions
diff --git a/indra/llaudio/llaudiodecodemgr.cpp b/indra/llaudio/llaudiodecodemgr.cpp
index 190c5290cb..ba4939f595 100755
--- a/indra/llaudio/llaudiodecodemgr.cpp
+++ b/indra/llaudio/llaudiodecodemgr.cpp
@@ -1,24 +1,24 @@
-/**
+/**
* @file llaudiodecodemgr.cpp
*
* $LicenseInfo:firstyear=2003&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -56,476 +56,476 @@ static const S32 WAV_HEADER_SIZE = 44;
class LLVorbisDecodeState : public LLThreadSafeRefCount
{
public:
- class WriteResponder : public LLLFSThread::Responder
- {
- public:
- WriteResponder(LLVorbisDecodeState* decoder) : mDecoder(decoder) {}
- ~WriteResponder() {}
- void completed(S32 bytes)
- {
- mDecoder->ioComplete(bytes);
- }
- LLPointer<LLVorbisDecodeState> mDecoder;
- };
-
- LLVorbisDecodeState(const LLUUID &uuid, const std::string &out_filename);
-
- BOOL initDecode();
- BOOL decodeSection(); // Return TRUE if done.
- BOOL finishDecode();
-
- void flushBadFile();
-
- void ioComplete(S32 bytes) { mBytesRead = bytes; }
- BOOL isValid() const { return mValid; }
- BOOL isDone() const { return mDone; }
- const LLUUID &getUUID() const { return mUUID; }
+ class WriteResponder : public LLLFSThread::Responder
+ {
+ public:
+ WriteResponder(LLVorbisDecodeState* decoder) : mDecoder(decoder) {}
+ ~WriteResponder() {}
+ void completed(S32 bytes)
+ {
+ mDecoder->ioComplete(bytes);
+ }
+ LLPointer<LLVorbisDecodeState> mDecoder;
+ };
+
+ LLVorbisDecodeState(const LLUUID &uuid, const std::string &out_filename);
+
+ BOOL initDecode();
+ BOOL decodeSection(); // Return TRUE if done.
+ BOOL finishDecode();
+
+ void flushBadFile();
+
+ void ioComplete(S32 bytes) { mBytesRead = bytes; }
+ BOOL isValid() const { return mValid; }
+ BOOL isDone() const { return mDone; }
+ const LLUUID &getUUID() const { return mUUID; }
protected:
- virtual ~LLVorbisDecodeState();
-
- BOOL mValid;
- BOOL mDone;
- LLAtomicS32 mBytesRead;
- LLUUID mUUID;
-
- std::vector<U8> mWAVBuffer;
- std::string mOutFilename;
- LLLFSThread::handle_t mFileHandle;
-
- LLFileSystem *mInFilep;
- OggVorbis_File mVF;
- S32 mCurrentSection;
+ virtual ~LLVorbisDecodeState();
+
+ BOOL mValid;
+ BOOL mDone;
+ LLAtomicS32 mBytesRead;
+ LLUUID mUUID;
+
+ std::vector<U8> mWAVBuffer;
+ std::string mOutFilename;
+ LLLFSThread::handle_t mFileHandle;
+
+ LLFileSystem *mInFilep;
+ OggVorbis_File mVF;
+ S32 mCurrentSection;
};
size_t cache_read(void *ptr, size_t size, size_t nmemb, void *datasource)
{
- LLFileSystem *file = (LLFileSystem *)datasource;
-
- if (file->read((U8*)ptr, (S32)(size * nmemb))) /*Flawfinder: ignore*/
- {
- S32 read = file->getLastBytesRead();
- return read / size; /*Flawfinder: ignore*/
- }
- else
- {
- return 0;
- }
+ LLFileSystem *file = (LLFileSystem *)datasource;
+
+ if (file->read((U8*)ptr, (S32)(size * nmemb))) /*Flawfinder: ignore*/
+ {
+ S32 read = file->getLastBytesRead();
+ return read / size; /*Flawfinder: ignore*/
+ }
+ else
+ {
+ return 0;
+ }
}
S32 cache_seek(void *datasource, ogg_int64_t offset, S32 whence)
{
- LLFileSystem *file = (LLFileSystem *)datasource;
-
- // cache has 31-bit files
- if (offset > S32_MAX)
- {
- return -1;
- }
-
- S32 origin;
- switch (whence) {
- case SEEK_SET:
- origin = 0;
- break;
- case SEEK_END:
- origin = file->getSize();
- break;
- case SEEK_CUR:
- origin = -1;
- break;
- default:
- LL_ERRS("AudioEngine") << "Invalid whence argument to cache_seek" << LL_ENDL;
- return -1;
- }
-
- if (file->seek((S32)offset, origin))
- {
- return 0;
- }
- else
- {
- return -1;
- }
+ LLFileSystem *file = (LLFileSystem *)datasource;
+
+ // cache has 31-bit files
+ if (offset > S32_MAX)
+ {
+ return -1;
+ }
+
+ S32 origin;
+ switch (whence) {
+ case SEEK_SET:
+ origin = 0;
+ break;
+ case SEEK_END:
+ origin = file->getSize();
+ break;
+ case SEEK_CUR:
+ origin = -1;
+ break;
+ default:
+ LL_ERRS("AudioEngine") << "Invalid whence argument to cache_seek" << LL_ENDL;
+ return -1;
+ }
+
+ if (file->seek((S32)offset, origin))
+ {
+ return 0;
+ }
+ else
+ {
+ return -1;
+ }
}
S32 cache_close (void *datasource)
{
- LLFileSystem *file = (LLFileSystem *)datasource;
- delete file;
- return 0;
+ LLFileSystem *file = (LLFileSystem *)datasource;
+ delete file;
+ return 0;
}
long cache_tell (void *datasource)
{
- LLFileSystem *file = (LLFileSystem *)datasource;
- return file->tell();
+ LLFileSystem *file = (LLFileSystem *)datasource;
+ return file->tell();
}
LLVorbisDecodeState::LLVorbisDecodeState(const LLUUID &uuid, const std::string &out_filename)
{
- mDone = FALSE;
- mValid = FALSE;
- mBytesRead = -1;
- mUUID = uuid;
- mInFilep = NULL;
- mCurrentSection = 0;
- mOutFilename = out_filename;
- mFileHandle = LLLFSThread::nullHandle();
+ mDone = FALSE;
+ mValid = FALSE;
+ mBytesRead = -1;
+ mUUID = uuid;
+ mInFilep = NULL;
+ mCurrentSection = 0;
+ mOutFilename = out_filename;
+ mFileHandle = LLLFSThread::nullHandle();
// No default value for mVF, it's an ogg structure?
- // Hey, let's zero it anyway, for predictability.
- memset(&mVF, 0, sizeof(mVF));
+ // Hey, let's zero it anyway, for predictability.
+ memset(&mVF, 0, sizeof(mVF));
}
LLVorbisDecodeState::~LLVorbisDecodeState()
{
- if (!mDone)
- {
- delete mInFilep;
- mInFilep = NULL;
- }
+ if (!mDone)
+ {
+ delete mInFilep;
+ mInFilep = NULL;
+ }
}
BOOL LLVorbisDecodeState::initDecode()
{
- ov_callbacks cache_callbacks;
- cache_callbacks.read_func = cache_read;
- cache_callbacks.seek_func = cache_seek;
- cache_callbacks.close_func = cache_close;
- cache_callbacks.tell_func = cache_tell;
-
- LL_DEBUGS("AudioEngine") << "Initing decode from vfile: " << mUUID << LL_ENDL;
-
- mInFilep = new LLFileSystem(mUUID, LLAssetType::AT_SOUND);
- if (!mInFilep || !mInFilep->getSize())
- {
- LL_WARNS("AudioEngine") << "unable to open vorbis source vfile for reading" << LL_ENDL;
- delete mInFilep;
- mInFilep = NULL;
- return FALSE;
- }
-
- S32 r = ov_open_callbacks(mInFilep, &mVF, NULL, 0, cache_callbacks);
- if(r < 0)
- {
- LL_WARNS("AudioEngine") << r << " Input to vorbis decode does not appear to be an Ogg bitstream: " << mUUID << LL_ENDL;
- return(FALSE);
- }
-
- S32 sample_count = (S32)ov_pcm_total(&mVF, -1);
- size_t size_guess = (size_t)sample_count;
- vorbis_info* vi = ov_info(&mVF, -1);
- size_guess *= (vi? vi->channels : 1);
- size_guess *= 2;
- size_guess += 2048;
-
- bool abort_decode = false;
-
- if (vi)
- {
- if( vi->channels < 1 || vi->channels > LLVORBIS_CLIP_MAX_CHANNELS )
- {
- abort_decode = true;
- LL_WARNS("AudioEngine") << "Bad channel count: " << vi->channels << LL_ENDL;
- }
- }
- else // !vi
- {
- abort_decode = true;
- LL_WARNS("AudioEngine") << "No default bitstream found" << LL_ENDL;
- }
-
- if( (size_t)sample_count > LLVORBIS_CLIP_REJECT_SAMPLES ||
- (size_t)sample_count <= 0)
- {
- abort_decode = true;
- LL_WARNS("AudioEngine") << "Illegal sample count: " << sample_count << LL_ENDL;
- }
-
- if( size_guess > LLVORBIS_CLIP_REJECT_SIZE )
- {
- abort_decode = true;
- LL_WARNS("AudioEngine") << "Illegal sample size: " << size_guess << LL_ENDL;
- }
-
- if( abort_decode )
- {
- LL_WARNS("AudioEngine") << "Canceling initDecode. Bad asset: " << mUUID << LL_ENDL;
- vorbis_comment* comment = ov_comment(&mVF,-1);
- if (comment && comment->vendor)
- {
- LL_WARNS("AudioEngine") << "Bad asset encoded by: " << comment->vendor << LL_ENDL;
- }
- delete mInFilep;
- mInFilep = NULL;
- return FALSE;
- }
-
- try
- {
- mWAVBuffer.reserve(size_guess);
- mWAVBuffer.resize(WAV_HEADER_SIZE);
- }
- catch (std::bad_alloc&)
- {
- LL_WARNS("AudioEngine") << "Out of memory when trying to alloc buffer: " << size_guess << LL_ENDL;
- delete mInFilep;
- mInFilep = NULL;
- return FALSE;
- }
-
- {
- // write the .wav format header
- //"RIFF"
- mWAVBuffer[0] = 0x52;
- mWAVBuffer[1] = 0x49;
- mWAVBuffer[2] = 0x46;
- mWAVBuffer[3] = 0x46;
-
- // length = datalen + 36 (to be filled in later)
- mWAVBuffer[4] = 0x00;
- mWAVBuffer[5] = 0x00;
- mWAVBuffer[6] = 0x00;
- mWAVBuffer[7] = 0x00;
-
- //"WAVE"
- mWAVBuffer[8] = 0x57;
- mWAVBuffer[9] = 0x41;
- mWAVBuffer[10] = 0x56;
- mWAVBuffer[11] = 0x45;
-
- // "fmt "
- mWAVBuffer[12] = 0x66;
- mWAVBuffer[13] = 0x6D;
- mWAVBuffer[14] = 0x74;
- mWAVBuffer[15] = 0x20;
-
- // chunk size = 16
- mWAVBuffer[16] = 0x10;
- mWAVBuffer[17] = 0x00;
- mWAVBuffer[18] = 0x00;
- mWAVBuffer[19] = 0x00;
-
- // format (1 = PCM)
- mWAVBuffer[20] = 0x01;
- mWAVBuffer[21] = 0x00;
-
- // number of channels
- mWAVBuffer[22] = 0x01;
- mWAVBuffer[23] = 0x00;
-
- // samples per second
- mWAVBuffer[24] = 0x44;
- mWAVBuffer[25] = 0xAC;
- mWAVBuffer[26] = 0x00;
- mWAVBuffer[27] = 0x00;
-
- // average bytes per second
- mWAVBuffer[28] = 0x88;
- mWAVBuffer[29] = 0x58;
- mWAVBuffer[30] = 0x01;
- mWAVBuffer[31] = 0x00;
-
- // bytes to output at a single time
- mWAVBuffer[32] = 0x02;
- mWAVBuffer[33] = 0x00;
-
- // 16 bits per sample
- mWAVBuffer[34] = 0x10;
- mWAVBuffer[35] = 0x00;
-
- // "data"
- mWAVBuffer[36] = 0x64;
- mWAVBuffer[37] = 0x61;
- mWAVBuffer[38] = 0x74;
- mWAVBuffer[39] = 0x61;
-
- // these are the length of the data chunk, to be filled in later
- mWAVBuffer[40] = 0x00;
- mWAVBuffer[41] = 0x00;
- mWAVBuffer[42] = 0x00;
- mWAVBuffer[43] = 0x00;
- }
-
- //{
- //char **ptr=ov_comment(&mVF,-1)->user_comments;
-// vorbis_info *vi=ov_info(&vf,-1);
- //while(*ptr){
- // fprintf(stderr,"%s\n",*ptr);
- // ++ptr;
- //}
+ ov_callbacks cache_callbacks;
+ cache_callbacks.read_func = cache_read;
+ cache_callbacks.seek_func = cache_seek;
+ cache_callbacks.close_func = cache_close;
+ cache_callbacks.tell_func = cache_tell;
+
+ LL_DEBUGS("AudioEngine") << "Initing decode from vfile: " << mUUID << LL_ENDL;
+
+ mInFilep = new LLFileSystem(mUUID, LLAssetType::AT_SOUND);
+ if (!mInFilep || !mInFilep->getSize())
+ {
+ LL_WARNS("AudioEngine") << "unable to open vorbis source vfile for reading" << LL_ENDL;
+ delete mInFilep;
+ mInFilep = NULL;
+ return FALSE;
+ }
+
+ S32 r = ov_open_callbacks(mInFilep, &mVF, NULL, 0, cache_callbacks);
+ if(r < 0)
+ {
+ LL_WARNS("AudioEngine") << r << " Input to vorbis decode does not appear to be an Ogg bitstream: " << mUUID << LL_ENDL;
+ return(FALSE);
+ }
+
+ S32 sample_count = (S32)ov_pcm_total(&mVF, -1);
+ size_t size_guess = (size_t)sample_count;
+ vorbis_info* vi = ov_info(&mVF, -1);
+ size_guess *= (vi? vi->channels : 1);
+ size_guess *= 2;
+ size_guess += 2048;
+
+ bool abort_decode = false;
+
+ if (vi)
+ {
+ if( vi->channels < 1 || vi->channels > LLVORBIS_CLIP_MAX_CHANNELS )
+ {
+ abort_decode = true;
+ LL_WARNS("AudioEngine") << "Bad channel count: " << vi->channels << LL_ENDL;
+ }
+ }
+ else // !vi
+ {
+ abort_decode = true;
+ LL_WARNS("AudioEngine") << "No default bitstream found" << LL_ENDL;
+ }
+
+ if( (size_t)sample_count > LLVORBIS_CLIP_REJECT_SAMPLES ||
+ (size_t)sample_count <= 0)
+ {
+ abort_decode = true;
+ LL_WARNS("AudioEngine") << "Illegal sample count: " << sample_count << LL_ENDL;
+ }
+
+ if( size_guess > LLVORBIS_CLIP_REJECT_SIZE )
+ {
+ abort_decode = true;
+ LL_WARNS("AudioEngine") << "Illegal sample size: " << size_guess << LL_ENDL;
+ }
+
+ if( abort_decode )
+ {
+ LL_WARNS("AudioEngine") << "Canceling initDecode. Bad asset: " << mUUID << LL_ENDL;
+ vorbis_comment* comment = ov_comment(&mVF,-1);
+ if (comment && comment->vendor)
+ {
+ LL_WARNS("AudioEngine") << "Bad asset encoded by: " << comment->vendor << LL_ENDL;
+ }
+ delete mInFilep;
+ mInFilep = NULL;
+ return FALSE;
+ }
+
+ try
+ {
+ mWAVBuffer.reserve(size_guess);
+ mWAVBuffer.resize(WAV_HEADER_SIZE);
+ }
+ catch (std::bad_alloc&)
+ {
+ LL_WARNS("AudioEngine") << "Out of memory when trying to alloc buffer: " << size_guess << LL_ENDL;
+ delete mInFilep;
+ mInFilep = NULL;
+ return FALSE;
+ }
+
+ {
+ // write the .wav format header
+ //"RIFF"
+ mWAVBuffer[0] = 0x52;
+ mWAVBuffer[1] = 0x49;
+ mWAVBuffer[2] = 0x46;
+ mWAVBuffer[3] = 0x46;
+
+ // length = datalen + 36 (to be filled in later)
+ mWAVBuffer[4] = 0x00;
+ mWAVBuffer[5] = 0x00;
+ mWAVBuffer[6] = 0x00;
+ mWAVBuffer[7] = 0x00;
+
+ //"WAVE"
+ mWAVBuffer[8] = 0x57;
+ mWAVBuffer[9] = 0x41;
+ mWAVBuffer[10] = 0x56;
+ mWAVBuffer[11] = 0x45;
+
+ // "fmt "
+ mWAVBuffer[12] = 0x66;
+ mWAVBuffer[13] = 0x6D;
+ mWAVBuffer[14] = 0x74;
+ mWAVBuffer[15] = 0x20;
+
+ // chunk size = 16
+ mWAVBuffer[16] = 0x10;
+ mWAVBuffer[17] = 0x00;
+ mWAVBuffer[18] = 0x00;
+ mWAVBuffer[19] = 0x00;
+
+ // format (1 = PCM)
+ mWAVBuffer[20] = 0x01;
+ mWAVBuffer[21] = 0x00;
+
+ // number of channels
+ mWAVBuffer[22] = 0x01;
+ mWAVBuffer[23] = 0x00;
+
+ // samples per second
+ mWAVBuffer[24] = 0x44;
+ mWAVBuffer[25] = 0xAC;
+ mWAVBuffer[26] = 0x00;
+ mWAVBuffer[27] = 0x00;
+
+ // average bytes per second
+ mWAVBuffer[28] = 0x88;
+ mWAVBuffer[29] = 0x58;
+ mWAVBuffer[30] = 0x01;
+ mWAVBuffer[31] = 0x00;
+
+ // bytes to output at a single time
+ mWAVBuffer[32] = 0x02;
+ mWAVBuffer[33] = 0x00;
+
+ // 16 bits per sample
+ mWAVBuffer[34] = 0x10;
+ mWAVBuffer[35] = 0x00;
+
+ // "data"
+ mWAVBuffer[36] = 0x64;
+ mWAVBuffer[37] = 0x61;
+ mWAVBuffer[38] = 0x74;
+ mWAVBuffer[39] = 0x61;
+
+ // these are the length of the data chunk, to be filled in later
+ mWAVBuffer[40] = 0x00;
+ mWAVBuffer[41] = 0x00;
+ mWAVBuffer[42] = 0x00;
+ mWAVBuffer[43] = 0x00;
+ }
+
+ //{
+ //char **ptr=ov_comment(&mVF,-1)->user_comments;
+// vorbis_info *vi=ov_info(&vf,-1);
+ //while(*ptr){
+ // fprintf(stderr,"%s\n",*ptr);
+ // ++ptr;
+ //}
// fprintf(stderr,"\nBitstream is %d channel, %ldHz\n",vi->channels,vi->rate);
// fprintf(stderr,"\nDecoded length: %ld samples\n", (long)ov_pcm_total(&vf,-1));
// fprintf(stderr,"Encoded by: %s\n\n",ov_comment(&vf,-1)->vendor);
- //}
- return TRUE;
+ //}
+ return TRUE;
}
BOOL LLVorbisDecodeState::decodeSection()
{
- if (!mInFilep)
- {
- LL_WARNS("AudioEngine") << "No cache file to decode in vorbis!" << LL_ENDL;
- return TRUE;
- }
- if (mDone)
- {
-// LL_WARNS("AudioEngine") << "Already done with decode, aborting!" << LL_ENDL;
- return TRUE;
- }
- char pcmout[4096]; /*Flawfinder: ignore*/
-
- BOOL eof = FALSE;
- long ret=ov_read(&mVF, pcmout, sizeof(pcmout), 0, 2, 1, &mCurrentSection);
- if (ret == 0)
- {
- /* EOF */
- eof = TRUE;
- mDone = TRUE;
- mValid = TRUE;
-// LL_INFOS("AudioEngine") << "Vorbis EOF" << LL_ENDL;
- }
- else if (ret < 0)
- {
- /* error in the stream. Not a problem, just reporting it in
- case we (the app) cares. In this case, we don't. */
-
- LL_WARNS("AudioEngine") << "BAD vorbis decode in decodeSection." << LL_ENDL;
-
- mValid = FALSE;
- mDone = TRUE;
- // We're done, return TRUE.
- return TRUE;
- }
- else
- {
-// LL_INFOS("AudioEngine") << "Vorbis read " << ret << "bytes" << LL_ENDL;
- /* we don't bother dealing with sample rate changes, etc, but.
- you'll have to*/
- std::copy(pcmout, pcmout+ret, std::back_inserter(mWAVBuffer));
- }
- return eof;
+ if (!mInFilep)
+ {
+ LL_WARNS("AudioEngine") << "No cache file to decode in vorbis!" << LL_ENDL;
+ return TRUE;
+ }
+ if (mDone)
+ {
+// LL_WARNS("AudioEngine") << "Already done with decode, aborting!" << LL_ENDL;
+ return TRUE;
+ }
+ char pcmout[4096]; /*Flawfinder: ignore*/
+
+ BOOL eof = FALSE;
+ long ret=ov_read(&mVF, pcmout, sizeof(pcmout), 0, 2, 1, &mCurrentSection);
+ if (ret == 0)
+ {
+ /* EOF */
+ eof = TRUE;
+ mDone = TRUE;
+ mValid = TRUE;
+// LL_INFOS("AudioEngine") << "Vorbis EOF" << LL_ENDL;
+ }
+ else if (ret < 0)
+ {
+ /* error in the stream. Not a problem, just reporting it in
+ case we (the app) cares. In this case, we don't. */
+
+ LL_WARNS("AudioEngine") << "BAD vorbis decode in decodeSection." << LL_ENDL;
+
+ mValid = FALSE;
+ mDone = TRUE;
+ // We're done, return TRUE.
+ return TRUE;
+ }
+ else
+ {
+// LL_INFOS("AudioEngine") << "Vorbis read " << ret << "bytes" << LL_ENDL;
+ /* we don't bother dealing with sample rate changes, etc, but.
+ you'll have to*/
+ std::copy(pcmout, pcmout+ret, std::back_inserter(mWAVBuffer));
+ }
+ return eof;
}
BOOL LLVorbisDecodeState::finishDecode()
{
- if (!isValid())
- {
- LL_WARNS("AudioEngine") << "Bogus vorbis decode state for " << getUUID() << ", aborting!" << LL_ENDL;
- return TRUE; // We've finished
- }
-
- if (mFileHandle == LLLFSThread::nullHandle())
- {
- ov_clear(&mVF);
-
- // write "data" chunk length, in little-endian format
- S32 data_length = mWAVBuffer.size() - WAV_HEADER_SIZE;
- mWAVBuffer[40] = (data_length) & 0x000000FF;
- mWAVBuffer[41] = (data_length >> 8) & 0x000000FF;
- mWAVBuffer[42] = (data_length >> 16) & 0x000000FF;
- mWAVBuffer[43] = (data_length >> 24) & 0x000000FF;
- // write overall "RIFF" length, in little-endian format
- data_length += 36;
- mWAVBuffer[4] = (data_length) & 0x000000FF;
- mWAVBuffer[5] = (data_length >> 8) & 0x000000FF;
- mWAVBuffer[6] = (data_length >> 16) & 0x000000FF;
- mWAVBuffer[7] = (data_length >> 24) & 0x000000FF;
-
- //
- // FUDGECAKES!!! Vorbis encode/decode messes up loop point transitions (pop)
- // do a cheap-and-cheesy crossfade
- //
- {
- S16 *samplep;
- S32 i;
- S32 fade_length;
- char pcmout[4096]; /*Flawfinder: ignore*/
-
- fade_length = llmin((S32)128,(S32)(data_length-36)/8);
- if((S32)mWAVBuffer.size() >= (WAV_HEADER_SIZE + 2* fade_length))
- {
- memcpy(pcmout, &mWAVBuffer[WAV_HEADER_SIZE], (2 * fade_length)); /*Flawfinder: ignore*/
- }
- llendianswizzle(&pcmout, 2, fade_length);
-
- samplep = (S16 *)pcmout;
- for (i = 0 ;i < fade_length; i++)
- {
- *samplep = llfloor((F32)*samplep * ((F32)i/(F32)fade_length));
- samplep++;
- }
-
- llendianswizzle(&pcmout, 2, fade_length);
- if((WAV_HEADER_SIZE+(2 * fade_length)) < (S32)mWAVBuffer.size())
- {
- memcpy(&mWAVBuffer[WAV_HEADER_SIZE], pcmout, (2 * fade_length)); /*Flawfinder: ignore*/
- }
- S32 near_end = mWAVBuffer.size() - (2 * fade_length);
- if ((S32)mWAVBuffer.size() >= ( near_end + 2* fade_length))
- {
- memcpy(pcmout, &mWAVBuffer[near_end], (2 * fade_length)); /*Flawfinder: ignore*/
- }
- llendianswizzle(&pcmout, 2, fade_length);
-
- samplep = (S16 *)pcmout;
- for (i = fade_length-1 ; i >= 0; i--)
- {
- *samplep = llfloor((F32)*samplep * ((F32)i/(F32)fade_length));
- samplep++;
- }
-
- llendianswizzle(&pcmout, 2, fade_length);
- if (near_end + (2 * fade_length) < (S32)mWAVBuffer.size())
- {
- memcpy(&mWAVBuffer[near_end], pcmout, (2 * fade_length));/*Flawfinder: ignore*/
- }
- }
-
- if (36 == data_length)
- {
- LL_WARNS("AudioEngine") << "BAD Vorbis decode in finishDecode!" << LL_ENDL;
- mValid = FALSE;
- return TRUE; // we've finished
- }
- mBytesRead = -1;
- mFileHandle = LLLFSThread::sLocal->write(mOutFilename, &mWAVBuffer[0], 0, mWAVBuffer.size(),
- new WriteResponder(this));
- }
-
- if (mFileHandle != LLLFSThread::nullHandle())
- {
- if (mBytesRead >= 0)
- {
- if (mBytesRead == 0)
- {
- LL_WARNS("AudioEngine") << "Unable to write file in LLVorbisDecodeState::finishDecode" << LL_ENDL;
- mValid = FALSE;
- return TRUE; // we've finished
- }
- }
- else
- {
- return FALSE; // not done
- }
- }
-
- mDone = TRUE;
-
- LL_DEBUGS("AudioEngine") << "Finished decode for " << getUUID() << LL_ENDL;
-
- return TRUE;
+ if (!isValid())
+ {
+ LL_WARNS("AudioEngine") << "Bogus vorbis decode state for " << getUUID() << ", aborting!" << LL_ENDL;
+ return TRUE; // We've finished
+ }
+
+ if (mFileHandle == LLLFSThread::nullHandle())
+ {
+ ov_clear(&mVF);
+
+ // write "data" chunk length, in little-endian format
+ S32 data_length = mWAVBuffer.size() - WAV_HEADER_SIZE;
+ mWAVBuffer[40] = (data_length) & 0x000000FF;
+ mWAVBuffer[41] = (data_length >> 8) & 0x000000FF;
+ mWAVBuffer[42] = (data_length >> 16) & 0x000000FF;
+ mWAVBuffer[43] = (data_length >> 24) & 0x000000FF;
+ // write overall "RIFF" length, in little-endian format
+ data_length += 36;
+ mWAVBuffer[4] = (data_length) & 0x000000FF;
+ mWAVBuffer[5] = (data_length >> 8) & 0x000000FF;
+ mWAVBuffer[6] = (data_length >> 16) & 0x000000FF;
+ mWAVBuffer[7] = (data_length >> 24) & 0x000000FF;
+
+ //
+ // FUDGECAKES!!! Vorbis encode/decode messes up loop point transitions (pop)
+ // do a cheap-and-cheesy crossfade
+ //
+ {
+ S16 *samplep;
+ S32 i;
+ S32 fade_length;
+ char pcmout[4096]; /*Flawfinder: ignore*/
+
+ fade_length = llmin((S32)128,(S32)(data_length-36)/8);
+ if((S32)mWAVBuffer.size() >= (WAV_HEADER_SIZE + 2* fade_length))
+ {
+ memcpy(pcmout, &mWAVBuffer[WAV_HEADER_SIZE], (2 * fade_length)); /*Flawfinder: ignore*/
+ }
+ llendianswizzle(&pcmout, 2, fade_length);
+
+ samplep = (S16 *)pcmout;
+ for (i = 0 ;i < fade_length; i++)
+ {
+ *samplep = llfloor((F32)*samplep * ((F32)i/(F32)fade_length));
+ samplep++;
+ }
+
+ llendianswizzle(&pcmout, 2, fade_length);
+ if((WAV_HEADER_SIZE+(2 * fade_length)) < (S32)mWAVBuffer.size())
+ {
+ memcpy(&mWAVBuffer[WAV_HEADER_SIZE], pcmout, (2 * fade_length)); /*Flawfinder: ignore*/
+ }
+ S32 near_end = mWAVBuffer.size() - (2 * fade_length);
+ if ((S32)mWAVBuffer.size() >= ( near_end + 2* fade_length))
+ {
+ memcpy(pcmout, &mWAVBuffer[near_end], (2 * fade_length)); /*Flawfinder: ignore*/
+ }
+ llendianswizzle(&pcmout, 2, fade_length);
+
+ samplep = (S16 *)pcmout;
+ for (i = fade_length-1 ; i >= 0; i--)
+ {
+ *samplep = llfloor((F32)*samplep * ((F32)i/(F32)fade_length));
+ samplep++;
+ }
+
+ llendianswizzle(&pcmout, 2, fade_length);
+ if (near_end + (2 * fade_length) < (S32)mWAVBuffer.size())
+ {
+ memcpy(&mWAVBuffer[near_end], pcmout, (2 * fade_length));/*Flawfinder: ignore*/
+ }
+ }
+
+ if (36 == data_length)
+ {
+ LL_WARNS("AudioEngine") << "BAD Vorbis decode in finishDecode!" << LL_ENDL;
+ mValid = FALSE;
+ return TRUE; // we've finished
+ }
+ mBytesRead = -1;
+ mFileHandle = LLLFSThread::sLocal->write(mOutFilename, &mWAVBuffer[0], 0, mWAVBuffer.size(),
+ new WriteResponder(this));
+ }
+
+ if (mFileHandle != LLLFSThread::nullHandle())
+ {
+ if (mBytesRead >= 0)
+ {
+ if (mBytesRead == 0)
+ {
+ LL_WARNS("AudioEngine") << "Unable to write file in LLVorbisDecodeState::finishDecode" << LL_ENDL;
+ mValid = FALSE;
+ return TRUE; // we've finished
+ }
+ }
+ else
+ {
+ return FALSE; // not done
+ }
+ }
+
+ mDone = TRUE;
+
+ LL_DEBUGS("AudioEngine") << "Finished decode for " << getUUID() << LL_ENDL;
+
+ return TRUE;
}
void LLVorbisDecodeState::flushBadFile()
{
- if (mInFilep)
- {
- LL_WARNS("AudioEngine") << "Flushing bad vorbis file from cache for " << mUUID << LL_ENDL;
- mInFilep->remove();
- }
+ if (mInFilep)
+ {
+ LL_WARNS("AudioEngine") << "Flushing bad vorbis file from cache for " << mUUID << LL_ENDL;
+ mInFilep->remove();
+ }
}
//////////////////////////////////////////////////////////////////////////////
@@ -781,21 +781,21 @@ void LLAudioDecodeMgr::processQueue()
BOOL LLAudioDecodeMgr::addDecodeRequest(const LLUUID &uuid)
{
- if (gAudiop && gAudiop->hasDecodedFile(uuid))
- {
- // Already have a decoded version, don't need to decode it.
- LL_DEBUGS("AudioEngine") << "addDecodeRequest for " << uuid << " has decoded file already" << LL_ENDL;
- return TRUE;
- }
-
- if (gAssetStorage->hasLocalAsset(uuid, LLAssetType::AT_SOUND))
- {
- // Just put it on the decode queue.
- LL_DEBUGS("AudioEngine") << "addDecodeRequest for " << uuid << " has local asset file already" << LL_ENDL;
+ if (gAudiop && gAudiop->hasDecodedFile(uuid))
+ {
+ // Already have a decoded version, don't need to decode it.
+ LL_DEBUGS("AudioEngine") << "addDecodeRequest for " << uuid << " has decoded file already" << LL_ENDL;
+ return TRUE;
+ }
+
+ if (gAssetStorage->hasLocalAsset(uuid, LLAssetType::AT_SOUND))
+ {
+ // Just put it on the decode queue.
+ LL_DEBUGS("AudioEngine") << "addDecodeRequest for " << uuid << " has local asset file already" << LL_ENDL;
mImpl->mDecodeQueue.push_back(uuid);
- return TRUE;
- }
+ return TRUE;
+ }
- LL_DEBUGS("AudioEngine") << "addDecodeRequest for " << uuid << " no file available" << LL_ENDL;
- return FALSE;
+ LL_DEBUGS("AudioEngine") << "addDecodeRequest for " << uuid << " no file available" << LL_ENDL;
+ return FALSE;
}
diff --git a/indra/llaudio/llaudiodecodemgr.h b/indra/llaudio/llaudiodecodemgr.h
index 4c17b46156..02d5c67587 100644
--- a/indra/llaudio/llaudiodecodemgr.h
+++ b/indra/llaudio/llaudiodecodemgr.h
@@ -1,24 +1,24 @@
-/**
+/**
* @file llaudiodecodemgr.h
*
* $LicenseInfo:firstyear=2003&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -42,12 +42,12 @@ class LLAudioDecodeMgr : public LLSingleton<LLAudioDecodeMgr>
LLSINGLETON(LLAudioDecodeMgr);
~LLAudioDecodeMgr();
public:
- void processQueue();
- BOOL addDecodeRequest(const LLUUID &uuid);
- void addAudioRequest(const LLUUID &uuid);
-
+ void processQueue();
+ BOOL addDecodeRequest(const LLUUID &uuid);
+ void addAudioRequest(const LLUUID &uuid);
+
protected:
- class Impl;
+ class Impl;
Impl* mImpl;
};
diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp
index ece0a12a7a..3697422ac8 100644
--- a/indra/llaudio/llaudioengine.cpp
+++ b/indra/llaudio/llaudioengine.cpp
@@ -1,4 +1,4 @@
- /**
+ /**
* @file audioengine.cpp
* @brief implementation of LLAudioEngine class abstracting the Open
* AL audio support
@@ -6,21 +6,21 @@
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -41,7 +41,7 @@
#include "llassetstorage.h"
-// necessary for grabbing sounds from sim (implemented in viewer)
+// necessary for grabbing sounds from sim (implemented in viewer)
extern void request_sound(const LLUUID &sound_guid);
LLAudioEngine* gAudiop = NULL;
@@ -54,7 +54,7 @@ LLAudioEngine* gAudiop = NULL;
LLAudioEngine::LLAudioEngine()
{
- setDefaults();
+ setDefaults();
}
@@ -64,1173 +64,1173 @@ LLAudioEngine::~LLAudioEngine()
LLStreamingAudioInterface* LLAudioEngine::getStreamingAudioImpl()
{
- return mStreamingAudioImpl;
+ return mStreamingAudioImpl;
}
void LLAudioEngine::setStreamingAudioImpl(LLStreamingAudioInterface *impl)
{
- mStreamingAudioImpl = impl;
+ mStreamingAudioImpl = impl;
}
void LLAudioEngine::setDefaults()
{
- mMaxWindGain = 1.f;
+ mMaxWindGain = 1.f;
- mListenerp = NULL;
+ mListenerp = NULL;
- mMuted = false;
- mUserData = NULL;
+ mMuted = false;
+ mUserData = NULL;
- mLastStatus = 0;
+ mLastStatus = 0;
- mEnableWind = false;
+ mEnableWind = false;
- mChannels.fill(nullptr);
- mBuffers.fill(nullptr);
+ mChannels.fill(nullptr);
+ mBuffers.fill(nullptr);
- mMasterGain = 1.f;
- // Setting mInternalGain to an out of range value fixes the issue reported in STORM-830.
- // There is an edge case in setMasterGain during startup which prevents setInternalGain from
- // being called if the master volume setting and mInternalGain both equal 0, so using -1 forces
- // the if statement in setMasterGain to execute when the viewer starts up.
- mInternalGain = -1.f;
- mNextWindUpdate = 0.f;
+ mMasterGain = 1.f;
+ // Setting mInternalGain to an out of range value fixes the issue reported in STORM-830.
+ // There is an edge case in setMasterGain during startup which prevents setInternalGain from
+ // being called if the master volume setting and mInternalGain both equal 0, so using -1 forces
+ // the if statement in setMasterGain to execute when the viewer starts up.
+ mInternalGain = -1.f;
+ mNextWindUpdate = 0.f;
- mStreamingAudioImpl = NULL;
+ mStreamingAudioImpl = NULL;
- for (U32 i = 0; i < LLAudioEngine::AUDIO_TYPE_COUNT; i++)
- mSecondaryGain[i] = 1.0f;
+ for (U32 i = 0; i < LLAudioEngine::AUDIO_TYPE_COUNT; i++)
+ mSecondaryGain[i] = 1.0f;
}
bool LLAudioEngine::init(void* userdata, const std::string &app_title)
{
- setDefaults();
+ setDefaults();
- mUserData = userdata;
-
- allocateListener();
+ mUserData = userdata;
- LL_INFOS("AudioEngine") << "LLAudioEngine::init() AudioEngine successfully initialized" << LL_ENDL;
+ allocateListener();
- return true;
+ LL_INFOS("AudioEngine") << "LLAudioEngine::init() AudioEngine successfully initialized" << LL_ENDL;
+
+ return true;
}
void LLAudioEngine::shutdown()
{
- // Clean up wind source
- cleanupWind();
+ // Clean up wind source
+ cleanupWind();
- // Clean up audio sources
- for (source_map::value_type& src_pair : mAllSources)
- {
- delete src_pair.second;
- }
+ // Clean up audio sources
+ for (source_map::value_type& src_pair : mAllSources)
+ {
+ delete src_pair.second;
+ }
- // Clean up audio data
- for (data_map::value_type& data_pair : mAllData)
- {
- delete data_pair.second;
- }
+ // Clean up audio data
+ for (data_map::value_type& data_pair : mAllData)
+ {
+ delete data_pair.second;
+ }
- // Clean up channels
- S32 i;
- for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++)
- {
- delete mChannels[i];
- mChannels[i] = NULL;
- }
+ // Clean up channels
+ S32 i;
+ for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++)
+ {
+ delete mChannels[i];
+ mChannels[i] = NULL;
+ }
- // Clean up buffers
- for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++)
- {
- delete mBuffers[i];
- mBuffers[i] = NULL;
- }
+ // Clean up buffers
+ for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++)
+ {
+ delete mBuffers[i];
+ mBuffers[i] = NULL;
+ }
}
// virtual
void LLAudioEngine::startInternetStream(const std::string& url)
{
- if (mStreamingAudioImpl)
- mStreamingAudioImpl->start(url);
+ if (mStreamingAudioImpl)
+ mStreamingAudioImpl->start(url);
}
// virtual
void LLAudioEngine::stopInternetStream()
{
- if (mStreamingAudioImpl)
- mStreamingAudioImpl->stop();
+ if (mStreamingAudioImpl)
+ mStreamingAudioImpl->stop();
}
// virtual
void LLAudioEngine::pauseInternetStream(S32 pause)
{
- if (mStreamingAudioImpl)
- mStreamingAudioImpl->pause(pause);
+ if (mStreamingAudioImpl)
+ mStreamingAudioImpl->pause(pause);
}
// virtual
void LLAudioEngine::updateInternetStream()
{
- if (mStreamingAudioImpl)
- mStreamingAudioImpl->update();
+ if (mStreamingAudioImpl)
+ mStreamingAudioImpl->update();
}
// virtual
LLAudioEngine::LLAudioPlayState LLAudioEngine::isInternetStreamPlaying()
{
- if (mStreamingAudioImpl)
- return (LLAudioEngine::LLAudioPlayState) mStreamingAudioImpl->isPlaying();
+ if (mStreamingAudioImpl)
+ return (LLAudioEngine::LLAudioPlayState) mStreamingAudioImpl->isPlaying();
- return LLAudioEngine::AUDIO_STOPPED; // Stopped
+ return LLAudioEngine::AUDIO_STOPPED; // Stopped
}
// virtual
void LLAudioEngine::setInternetStreamGain(F32 vol)
{
- if (mStreamingAudioImpl)
- mStreamingAudioImpl->setGain(vol);
+ if (mStreamingAudioImpl)
+ mStreamingAudioImpl->setGain(vol);
}
// virtual
std::string LLAudioEngine::getInternetStreamURL()
{
- if (mStreamingAudioImpl)
- return mStreamingAudioImpl->getURL();
+ if (mStreamingAudioImpl)
+ return mStreamingAudioImpl->getURL();
- return std::string();
+ return std::string();
}
void LLAudioEngine::updateChannels()
{
- S32 i;
- for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++)
- {
- if (mChannels[i])
- {
- mChannels[i]->updateBuffer();
- mChannels[i]->update3DPosition();
- mChannels[i]->updateLoop();
- }
- }
+ S32 i;
+ for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++)
+ {
+ if (mChannels[i])
+ {
+ mChannels[i]->updateBuffer();
+ mChannels[i]->update3DPosition();
+ mChannels[i]->updateLoop();
+ }
+ }
}
void LLAudioEngine::idle()
{
- // "Update" all of our audio sources, clean up dead ones.
- // Primarily does position updating, cleanup of unused audio sources.
- // Also does regeneration of the current priority of each audio source.
-
- S32 i;
- for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++)
- {
- if (mBuffers[i])
- {
- mBuffers[i]->mInUse = false;
- }
- }
-
- F32 max_priority = -1.f;
- LLAudioSource *max_sourcep = NULL; // Maximum priority source without a channel
- source_map::iterator iter;
- for (iter = mAllSources.begin(); iter != mAllSources.end();)
- {
- LLAudioSource *sourcep = iter->second;
-
- // Update this source
- sourcep->update();
- sourcep->updatePriority();
-
- if (sourcep->isDone())
- {
- // The source is done playing, clean it up.
- delete sourcep;
+ // "Update" all of our audio sources, clean up dead ones.
+ // Primarily does position updating, cleanup of unused audio sources.
+ // Also does regeneration of the current priority of each audio source.
+
+ S32 i;
+ for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++)
+ {
+ if (mBuffers[i])
+ {
+ mBuffers[i]->mInUse = false;
+ }
+ }
+
+ F32 max_priority = -1.f;
+ LLAudioSource *max_sourcep = NULL; // Maximum priority source without a channel
+ source_map::iterator iter;
+ for (iter = mAllSources.begin(); iter != mAllSources.end();)
+ {
+ LLAudioSource *sourcep = iter->second;
+
+ // Update this source
+ sourcep->update();
+ sourcep->updatePriority();
+
+ if (sourcep->isDone())
+ {
+ // The source is done playing, clean it up.
+ delete sourcep;
iter = mAllSources.erase(iter);
- continue;
- }
-
- if (sourcep->isMuted())
- {
- ++iter;
- continue;
- }
-
- if (!sourcep->getChannel() && sourcep->getCurrentBuffer())
- {
- // We could potentially play this sound if its priority is high enough.
- if (sourcep->getPriority() > max_priority)
- {
- max_priority = sourcep->getPriority();
- max_sourcep = sourcep;
- }
- }
-
- // Move on to the next source
- iter++;
- }
-
- // Now, do priority-based organization of audio sources.
- // All channels used, check priorities.
- // Find channel with lowest priority
- if (max_sourcep)
- {
- LLAudioChannel *channelp = getFreeChannel(max_priority);
- if (channelp)
- {
- //LL_INFOS() << "Replacing source in channel due to priority!" << LL_ENDL;
- max_sourcep->setChannel(channelp);
- channelp->setSource(max_sourcep);
- if (max_sourcep->isSyncSlave())
- {
- // A sync slave, it doesn't start playing until it's synced up with the master.
- // Flag this channel as waiting for sync, and return true.
- channelp->setWaiting(true);
- }
- else
- {
- channelp->setWaiting(false);
- channelp->play();
- }
- }
- }
-
-
- // Do this BEFORE we update the channels
- // Update the channels to sync up with any changes that the source made,
- // such as changing what sound was playing.
- updateChannels();
-
- // Update queued sounds (switch to next queued data if the current has finished playing)
- for (source_map::value_type& src_pair : mAllSources)
- {
- // This is lame, instead of this I could actually iterate through all the sources
- // attached to each channel, since only those with active channels
- // can have anything interesting happen with their queue? (Maybe not true)
- LLAudioSource *sourcep = src_pair.second;
- if (!sourcep->mQueuedDatap || sourcep->isMuted())
- {
- // Muted, or nothing queued, so we don't care.
- continue;
- }
-
- LLAudioChannel *channelp = sourcep->getChannel();
- if (!channelp)
- {
- // This sound isn't playing, so we just process move the queue
- sourcep->mCurrentDatap = sourcep->mQueuedDatap;
- sourcep->mQueuedDatap = NULL;
-
- // Reset the timer so the source doesn't die.
- sourcep->mAgeTimer.reset();
- // Make sure we have the buffer set up if we just decoded the data
- if (sourcep->mCurrentDatap)
- {
- updateBufferForData(sourcep->mCurrentDatap);
- }
-
- // Actually play the associated data.
- sourcep->setupChannel();
- channelp = sourcep->getChannel();
- if (channelp)
- {
- channelp->updateBuffer();
- sourcep->getChannel()->play();
- }
- continue;
- }
-
- // Check to see if the current sound is done playing.
- if (!channelp->isPlaying())
- {
- sourcep->mCurrentDatap = sourcep->mQueuedDatap;
- sourcep->mQueuedDatap = NULL;
-
- // Reset the timer so the source doesn't die.
- sourcep->mAgeTimer.reset();
-
- // Make sure we have the buffer set up if we just decoded the data
- if (sourcep->mCurrentDatap)
- {
- updateBufferForData(sourcep->mCurrentDatap);
- }
-
- // Actually play the associated data.
- sourcep->setupChannel();
- channelp->updateBuffer();
- sourcep->getChannel()->play();
- continue;
- }
-
- // Check to see if the current sound is looped.
- if (sourcep->isLoop())
- {
- // It's a loop, we need to check and see if we're done with it.
- if (channelp->mLoopedThisFrame)
- {
- sourcep->mCurrentDatap = sourcep->mQueuedDatap;
- sourcep->mQueuedDatap = NULL;
-
- // Actually, should do a time sync so if we're a loop master/slave
- // we don't drift away.
- sourcep->setupChannel();
- sourcep->getChannel()->play();
- }
- }
- }
-
- // Lame, update the channels AGAIN.
- // Update the channels to sync up with any changes that the source made,
- // such as changing what sound was playing.
- updateChannels();
-
- // Hack! For now, just use a global sync master;
- LLAudioSource *sync_masterp = NULL;
- LLAudioChannel *master_channelp = NULL;
- F32 max_sm_priority = -1.f;
- for (source_map::value_type& src_pair : mAllSources)
- {
- LLAudioSource *sourcep = src_pair.second;
- if (!sourcep->isMuted() && sourcep->isSyncMaster() && sourcep->getPriority() > max_sm_priority)
- {
- sync_masterp = sourcep;
- master_channelp = sync_masterp->getChannel();
- max_sm_priority = sourcep->getPriority();
- }
- }
-
- if (master_channelp && master_channelp->mLoopedThisFrame)
- {
- // Synchronize loop slaves with their masters
- // Update queued sounds (switch to next queued data if the current has finished playing)
- for (source_map::value_type& src_pair : mAllSources)
- {
- LLAudioSource *sourcep = src_pair.second;
-
- if (!sourcep->isSyncSlave())
- {
- // Not a loop slave, we don't need to do anything
- continue;
- }
-
- LLAudioChannel *channelp = sourcep->getChannel();
- if (!channelp)
- {
- // Not playing, don't need to bother.
- continue;
- }
-
- if (!channelp->isPlaying())
- {
- // Now we need to check if our loop master has just looped, and
- // start playback if that's the case.
- if (sync_masterp->getChannel())
- {
- channelp->playSynced(master_channelp);
- channelp->setWaiting(false);
- }
- }
- }
- }
-
- // Sync up everything that the audio engine needs done.
- commitDeferredChanges();
-
- // Flush unused buffers that are stale enough
- for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++)
- {
- if (mBuffers[i])
- {
- if (!mBuffers[i]->mInUse && mBuffers[i]->mLastUseTimer.getElapsedTimeF32() > 30.f)
- {
- //LL_INFOS() << "Flushing unused buffer!" << LL_ENDL;
- mBuffers[i]->mAudioDatap->mBufferp = NULL;
- delete mBuffers[i];
- mBuffers[i] = NULL;
- }
- }
- }
-
-
- // Clear all of the looped flags for the channels
- for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++)
- {
- if (mChannels[i])
- {
- mChannels[i]->mLoopedThisFrame = false;
- }
- }
-
- // Decode audio files
+ continue;
+ }
+
+ if (sourcep->isMuted())
+ {
+ ++iter;
+ continue;
+ }
+
+ if (!sourcep->getChannel() && sourcep->getCurrentBuffer())
+ {
+ // We could potentially play this sound if its priority is high enough.
+ if (sourcep->getPriority() > max_priority)
+ {
+ max_priority = sourcep->getPriority();
+ max_sourcep = sourcep;
+ }
+ }
+
+ // Move on to the next source
+ iter++;
+ }
+
+ // Now, do priority-based organization of audio sources.
+ // All channels used, check priorities.
+ // Find channel with lowest priority
+ if (max_sourcep)
+ {
+ LLAudioChannel *channelp = getFreeChannel(max_priority);
+ if (channelp)
+ {
+ //LL_INFOS() << "Replacing source in channel due to priority!" << LL_ENDL;
+ max_sourcep->setChannel(channelp);
+ channelp->setSource(max_sourcep);
+ if (max_sourcep->isSyncSlave())
+ {
+ // A sync slave, it doesn't start playing until it's synced up with the master.
+ // Flag this channel as waiting for sync, and return true.
+ channelp->setWaiting(true);
+ }
+ else
+ {
+ channelp->setWaiting(false);
+ channelp->play();
+ }
+ }
+ }
+
+
+ // Do this BEFORE we update the channels
+ // Update the channels to sync up with any changes that the source made,
+ // such as changing what sound was playing.
+ updateChannels();
+
+ // Update queued sounds (switch to next queued data if the current has finished playing)
+ for (source_map::value_type& src_pair : mAllSources)
+ {
+ // This is lame, instead of this I could actually iterate through all the sources
+ // attached to each channel, since only those with active channels
+ // can have anything interesting happen with their queue? (Maybe not true)
+ LLAudioSource *sourcep = src_pair.second;
+ if (!sourcep->mQueuedDatap || sourcep->isMuted())
+ {
+ // Muted, or nothing queued, so we don't care.
+ continue;
+ }
+
+ LLAudioChannel *channelp = sourcep->getChannel();
+ if (!channelp)
+ {
+ // This sound isn't playing, so we just process move the queue
+ sourcep->mCurrentDatap = sourcep->mQueuedDatap;
+ sourcep->mQueuedDatap = NULL;
+
+ // Reset the timer so the source doesn't die.
+ sourcep->mAgeTimer.reset();
+ // Make sure we have the buffer set up if we just decoded the data
+ if (sourcep->mCurrentDatap)
+ {
+ updateBufferForData(sourcep->mCurrentDatap);
+ }
+
+ // Actually play the associated data.
+ sourcep->setupChannel();
+ channelp = sourcep->getChannel();
+ if (channelp)
+ {
+ channelp->updateBuffer();
+ sourcep->getChannel()->play();
+ }
+ continue;
+ }
+
+ // Check to see if the current sound is done playing.
+ if (!channelp->isPlaying())
+ {
+ sourcep->mCurrentDatap = sourcep->mQueuedDatap;
+ sourcep->mQueuedDatap = NULL;
+
+ // Reset the timer so the source doesn't die.
+ sourcep->mAgeTimer.reset();
+
+ // Make sure we have the buffer set up if we just decoded the data
+ if (sourcep->mCurrentDatap)
+ {
+ updateBufferForData(sourcep->mCurrentDatap);
+ }
+
+ // Actually play the associated data.
+ sourcep->setupChannel();
+ channelp->updateBuffer();
+ sourcep->getChannel()->play();
+ continue;
+ }
+
+ // Check to see if the current sound is looped.
+ if (sourcep->isLoop())
+ {
+ // It's a loop, we need to check and see if we're done with it.
+ if (channelp->mLoopedThisFrame)
+ {
+ sourcep->mCurrentDatap = sourcep->mQueuedDatap;
+ sourcep->mQueuedDatap = NULL;
+
+ // Actually, should do a time sync so if we're a loop master/slave
+ // we don't drift away.
+ sourcep->setupChannel();
+ sourcep->getChannel()->play();
+ }
+ }
+ }
+
+ // Lame, update the channels AGAIN.
+ // Update the channels to sync up with any changes that the source made,
+ // such as changing what sound was playing.
+ updateChannels();
+
+ // Hack! For now, just use a global sync master;
+ LLAudioSource *sync_masterp = NULL;
+ LLAudioChannel *master_channelp = NULL;
+ F32 max_sm_priority = -1.f;
+ for (source_map::value_type& src_pair : mAllSources)
+ {
+ LLAudioSource *sourcep = src_pair.second;
+ if (!sourcep->isMuted() && sourcep->isSyncMaster() && sourcep->getPriority() > max_sm_priority)
+ {
+ sync_masterp = sourcep;
+ master_channelp = sync_masterp->getChannel();
+ max_sm_priority = sourcep->getPriority();
+ }
+ }
+
+ if (master_channelp && master_channelp->mLoopedThisFrame)
+ {
+ // Synchronize loop slaves with their masters
+ // Update queued sounds (switch to next queued data if the current has finished playing)
+ for (source_map::value_type& src_pair : mAllSources)
+ {
+ LLAudioSource *sourcep = src_pair.second;
+
+ if (!sourcep->isSyncSlave())
+ {
+ // Not a loop slave, we don't need to do anything
+ continue;
+ }
+
+ LLAudioChannel *channelp = sourcep->getChannel();
+ if (!channelp)
+ {
+ // Not playing, don't need to bother.
+ continue;
+ }
+
+ if (!channelp->isPlaying())
+ {
+ // Now we need to check if our loop master has just looped, and
+ // start playback if that's the case.
+ if (sync_masterp->getChannel())
+ {
+ channelp->playSynced(master_channelp);
+ channelp->setWaiting(false);
+ }
+ }
+ }
+ }
+
+ // Sync up everything that the audio engine needs done.
+ commitDeferredChanges();
+
+ // Flush unused buffers that are stale enough
+ for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++)
+ {
+ if (mBuffers[i])
+ {
+ if (!mBuffers[i]->mInUse && mBuffers[i]->mLastUseTimer.getElapsedTimeF32() > 30.f)
+ {
+ //LL_INFOS() << "Flushing unused buffer!" << LL_ENDL;
+ mBuffers[i]->mAudioDatap->mBufferp = NULL;
+ delete mBuffers[i];
+ mBuffers[i] = NULL;
+ }
+ }
+ }
+
+
+ // Clear all of the looped flags for the channels
+ for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++)
+ {
+ if (mChannels[i])
+ {
+ mChannels[i]->mLoopedThisFrame = false;
+ }
+ }
+
+ // Decode audio files
LLAudioDecodeMgr::getInstance()->processQueue();
-
- // Call this every frame, just in case we somehow
- // missed picking it up in all the places that can add
- // or request new data.
- startNextTransfer();
- updateInternetStream();
+ // Call this every frame, just in case we somehow
+ // missed picking it up in all the places that can add
+ // or request new data.
+ startNextTransfer();
+
+ updateInternetStream();
}
bool LLAudioEngine::updateBufferForData(LLAudioData *adp, const LLUUID &audio_uuid)
{
- if (!adp)
- {
- return false;
- }
-
- // Update the audio buffer first - load a sound if we have it.
- // Note that this could potentially cause us to waste time updating buffers
- // for sounds that actually aren't playing, although this should be mitigated
- // by the fact that we limit the number of buffers, and we flush buffers based
- // on priority.
- if (!adp->getBuffer())
- {
- if (adp->hasDecodedData())
- {
- adp->load();
- }
- else if (adp->hasLocalData())
- {
- if (audio_uuid.notNull())
- {
+ if (!adp)
+ {
+ return false;
+ }
+
+ // Update the audio buffer first - load a sound if we have it.
+ // Note that this could potentially cause us to waste time updating buffers
+ // for sounds that actually aren't playing, although this should be mitigated
+ // by the fact that we limit the number of buffers, and we flush buffers based
+ // on priority.
+ if (!adp->getBuffer())
+ {
+ if (adp->hasDecodedData())
+ {
+ adp->load();
+ }
+ else if (adp->hasLocalData())
+ {
+ if (audio_uuid.notNull())
+ {
LLAudioDecodeMgr::getInstance()->addDecodeRequest(audio_uuid);
- }
- }
- else
- {
- return false;
- }
- }
- return true;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+ return true;
}
void LLAudioEngine::enableWind(bool enable)
{
- if (enable && (!mEnableWind))
- {
- mEnableWind = initWind();
- }
- else if (mEnableWind && (!enable))
- {
- mEnableWind = false;
- cleanupWind();
- }
+ if (enable && (!mEnableWind))
+ {
+ mEnableWind = initWind();
+ }
+ else if (mEnableWind && (!enable))
+ {
+ mEnableWind = false;
+ cleanupWind();
+ }
}
LLAudioBuffer * LLAudioEngine::getFreeBuffer()
{
- S32 i;
- for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++)
- {
- if (!mBuffers[i])
- {
- mBuffers[i] = createBuffer();
- return mBuffers[i];
- }
- }
-
-
- // Grab the oldest unused buffer
- F32 max_age = -1.f;
- S32 buffer_id = -1;
- for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++)
- {
- if (mBuffers[i])
- {
- if (!mBuffers[i]->mInUse)
- {
- if (mBuffers[i]->mLastUseTimer.getElapsedTimeF32() > max_age)
- {
- max_age = mBuffers[i]->mLastUseTimer.getElapsedTimeF32();
- buffer_id = i;
- }
- }
- }
- }
-
- if (buffer_id >= 0)
- {
- LL_DEBUGS() << "Taking over unused buffer " << buffer_id << LL_ENDL;
- //LL_INFOS() << "Flushing unused buffer!" << LL_ENDL;
- mBuffers[buffer_id]->mAudioDatap->mBufferp = NULL;
- delete mBuffers[buffer_id];
- mBuffers[buffer_id] = createBuffer();
- return mBuffers[buffer_id];
- }
- return NULL;
+ S32 i;
+ for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++)
+ {
+ if (!mBuffers[i])
+ {
+ mBuffers[i] = createBuffer();
+ return mBuffers[i];
+ }
+ }
+
+
+ // Grab the oldest unused buffer
+ F32 max_age = -1.f;
+ S32 buffer_id = -1;
+ for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++)
+ {
+ if (mBuffers[i])
+ {
+ if (!mBuffers[i]->mInUse)
+ {
+ if (mBuffers[i]->mLastUseTimer.getElapsedTimeF32() > max_age)
+ {
+ max_age = mBuffers[i]->mLastUseTimer.getElapsedTimeF32();
+ buffer_id = i;
+ }
+ }
+ }
+ }
+
+ if (buffer_id >= 0)
+ {
+ LL_DEBUGS() << "Taking over unused buffer " << buffer_id << LL_ENDL;
+ //LL_INFOS() << "Flushing unused buffer!" << LL_ENDL;
+ mBuffers[buffer_id]->mAudioDatap->mBufferp = NULL;
+ delete mBuffers[buffer_id];
+ mBuffers[buffer_id] = createBuffer();
+ return mBuffers[buffer_id];
+ }
+ return NULL;
}
LLAudioChannel * LLAudioEngine::getFreeChannel(const F32 priority)
{
- S32 i;
+ S32 i;
for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++)
- {
- if (!mChannels[i])
- {
- // No channel allocated here, use it.
- mChannels[i] = createChannel();
- return mChannels[i];
- }
- else
- {
- // Channel is allocated but not playing right now, use it.
- if (!mChannels[i]->isPlaying() && !mChannels[i]->isWaiting())
- {
- mChannels[i]->cleanup();
- if (mChannels[i]->getSource())
- {
- mChannels[i]->getSource()->setChannel(NULL);
- }
- return mChannels[i];
- }
- }
- }
-
- // All channels used, check priorities.
- // Find channel with lowest priority and see if we want to replace it.
- F32 min_priority = 10000.f;
- LLAudioChannel *min_channelp = NULL;
+ {
+ if (!mChannels[i])
+ {
+ // No channel allocated here, use it.
+ mChannels[i] = createChannel();
+ return mChannels[i];
+ }
+ else
+ {
+ // Channel is allocated but not playing right now, use it.
+ if (!mChannels[i]->isPlaying() && !mChannels[i]->isWaiting())
+ {
+ mChannels[i]->cleanup();
+ if (mChannels[i]->getSource())
+ {
+ mChannels[i]->getSource()->setChannel(NULL);
+ }
+ return mChannels[i];
+ }
+ }
+ }
+
+ // All channels used, check priorities.
+ // Find channel with lowest priority and see if we want to replace it.
+ F32 min_priority = 10000.f;
+ LLAudioChannel *min_channelp = NULL;
for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++)
- {
- LLAudioChannel *channelp = mChannels[i];
- LLAudioSource *sourcep = channelp->getSource();
- if (sourcep->getPriority() < min_priority)
- {
- min_channelp = channelp;
- min_priority = sourcep->getPriority();
- }
- }
+ {
+ LLAudioChannel *channelp = mChannels[i];
+ LLAudioSource *sourcep = channelp->getSource();
+ if (sourcep->getPriority() < min_priority)
+ {
+ min_channelp = channelp;
+ min_priority = sourcep->getPriority();
+ }
+ }
- if (min_priority > priority || !min_channelp)
- {
- // All playing channels have higher priority, return.
- return NULL;
- }
+ if (min_priority > priority || !min_channelp)
+ {
+ // All playing channels have higher priority, return.
+ return NULL;
+ }
- // Flush the minimum priority channel, and return it.
- min_channelp->cleanup();
- min_channelp->getSource()->setChannel(NULL);
- return min_channelp;
+ // Flush the minimum priority channel, and return it.
+ min_channelp->cleanup();
+ min_channelp->getSource()->setChannel(NULL);
+ return min_channelp;
}
void LLAudioEngine::cleanupBuffer(LLAudioBuffer *bufferp)
{
- S32 i;
- for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++)
- {
- if (mBuffers[i] == bufferp)
- {
- delete mBuffers[i];
- mBuffers[i] = NULL;
- }
- }
+ S32 i;
+ for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++)
+ {
+ if (mBuffers[i] == bufferp)
+ {
+ delete mBuffers[i];
+ mBuffers[i] = NULL;
+ }
+ }
}
bool LLAudioEngine::preloadSound(const LLUUID &uuid)
{
- LL_DEBUGS("AudioEngine")<<"( "<<uuid<<" )"<<LL_ENDL;
+ LL_DEBUGS("AudioEngine")<<"( "<<uuid<<" )"<<LL_ENDL;
- getAudioData(uuid); // We don't care about the return value, this is just to make sure
- // that we have an entry, which will mean that the audio engine knows about this
+ getAudioData(uuid); // We don't care about the return value, this is just to make sure
+ // that we have an entry, which will mean that the audio engine knows about this
if (LLAudioDecodeMgr::getInstance()->addDecodeRequest(uuid))
- {
- // This means that we do have a local copy, and we're working on decoding it.
- return true;
- }
+ {
+ // This means that we do have a local copy, and we're working on decoding it.
+ return true;
+ }
- return false;
+ return false;
}
bool LLAudioEngine::isWindEnabled()
{
- return mEnableWind;
+ return mEnableWind;
}
void LLAudioEngine::setMuted(bool muted)
{
- if (muted != mMuted)
- {
- mMuted = muted;
- setMasterGain(mMasterGain);
- }
- enableWind(!mMuted);
+ if (muted != mMuted)
+ {
+ mMuted = muted;
+ setMasterGain(mMasterGain);
+ }
+ enableWind(!mMuted);
}
void LLAudioEngine::setMasterGain(const F32 gain)
{
- mMasterGain = gain;
- F32 internal_gain = getMuted() ? 0.f : gain;
- if (internal_gain != mInternalGain)
- {
- mInternalGain = internal_gain;
- setInternalGain(mInternalGain);
- }
+ mMasterGain = gain;
+ F32 internal_gain = getMuted() ? 0.f : gain;
+ if (internal_gain != mInternalGain)
+ {
+ mInternalGain = internal_gain;
+ setInternalGain(mInternalGain);
+ }
}
F32 LLAudioEngine::getMasterGain()
{
- return mMasterGain;
+ return mMasterGain;
}
void LLAudioEngine::setSecondaryGain(S32 type, F32 gain)
{
- llassert(type < LLAudioEngine::AUDIO_TYPE_COUNT);
-
- mSecondaryGain[type] = gain;
+ llassert(type < LLAudioEngine::AUDIO_TYPE_COUNT);
+
+ mSecondaryGain[type] = gain;
}
F32 LLAudioEngine::getSecondaryGain(S32 type)
{
- return mSecondaryGain[type];
+ return mSecondaryGain[type];
}
F32 LLAudioEngine::getInternetStreamGain()
{
- if (mStreamingAudioImpl)
- return mStreamingAudioImpl->getGain();
- else
- return 1.0f;
+ if (mStreamingAudioImpl)
+ return mStreamingAudioImpl->getGain();
+ else
+ return 1.0f;
}
void LLAudioEngine::setMaxWindGain(F32 gain)
{
- mMaxWindGain = gain;
+ mMaxWindGain = gain;
}
F64 LLAudioEngine::mapWindVecToGain(LLVector3 wind_vec)
{
- F64 gain = 0.0;
-
- gain = wind_vec.magVec();
+ F64 gain = 0.0;
+
+ gain = wind_vec.magVec();
- if (gain)
- {
- if (gain > 20)
- {
- gain = 20;
- }
- gain = gain/20.0;
- }
+ if (gain)
+ {
+ if (gain > 20)
+ {
+ gain = 20;
+ }
+ gain = gain/20.0;
+ }
- return (gain);
+ return (gain);
}
F64 LLAudioEngine::mapWindVecToPitch(LLVector3 wind_vec)
{
- LLVector3 listen_right;
- F64 theta;
-
- // Wind frame is in listener-relative coordinates
- LLVector3 norm_wind = wind_vec;
- norm_wind.normVec();
- listen_right.setVec(1.0,0.0,0.0);
+ LLVector3 listen_right;
+ F64 theta;
+
+ // Wind frame is in listener-relative coordinates
+ LLVector3 norm_wind = wind_vec;
+ norm_wind.normVec();
+ listen_right.setVec(1.0,0.0,0.0);
- // measure angle between wind vec and listener right axis (on 0,PI)
- theta = acos(norm_wind * listen_right);
+ // measure angle between wind vec and listener right axis (on 0,PI)
+ theta = acos(norm_wind * listen_right);
- // put it on 0, 1
- theta /= F_PI;
+ // put it on 0, 1
+ theta /= F_PI;
- // put it on [0, 0.5, 0]
- if (theta > 0.5) theta = 1.0-theta;
- if (theta < 0) theta = 0;
+ // put it on [0, 0.5, 0]
+ if (theta > 0.5) theta = 1.0-theta;
+ if (theta < 0) theta = 0;
- return (theta);
+ return (theta);
}
F64 LLAudioEngine::mapWindVecToPan(LLVector3 wind_vec)
{
- LLVector3 listen_right;
- F64 theta;
-
- // Wind frame is in listener-relative coordinates
- listen_right.setVec(1.0,0.0,0.0);
+ LLVector3 listen_right;
+ F64 theta;
- LLVector3 norm_wind = wind_vec;
- norm_wind.normVec();
+ // Wind frame is in listener-relative coordinates
+ listen_right.setVec(1.0,0.0,0.0);
- // measure angle between wind vec and listener right axis (on 0,PI)
- theta = acos(norm_wind * listen_right);
+ LLVector3 norm_wind = wind_vec;
+ norm_wind.normVec();
- // put it on 0, 1
- theta /= F_PI;
+ // measure angle between wind vec and listener right axis (on 0,PI)
+ theta = acos(norm_wind * listen_right);
- return (theta);
+ // put it on 0, 1
+ theta /= F_PI;
+
+ return (theta);
}
void LLAudioEngine::triggerSound(const LLUUID &audio_uuid, const LLUUID& owner_id, const F32 gain,
- const S32 type, const LLVector3d &pos_global)
-{
- // Create a new source (since this can't be associated with an existing source.
- //LL_INFOS() << "Localized: " << audio_uuid << LL_ENDL;
-
- if (mMuted)
- {
- return;
- }
-
- LLUUID source_id;
- source_id.generate();
-
- LLAudioSource *asp = new LLAudioSource(source_id, owner_id, gain, type);
- addAudioSource(asp);
- if (pos_global.isExactlyZero())
- {
- // For sound preview and UI
- asp->setForcedPriority(true);
- }
- else
- {
- asp->setPositionGlobal(pos_global);
- }
- asp->updatePriority();
- asp->play(audio_uuid);
+ const S32 type, const LLVector3d &pos_global)
+{
+ // Create a new source (since this can't be associated with an existing source.
+ //LL_INFOS() << "Localized: " << audio_uuid << LL_ENDL;
+
+ if (mMuted)
+ {
+ return;
+ }
+
+ LLUUID source_id;
+ source_id.generate();
+
+ LLAudioSource *asp = new LLAudioSource(source_id, owner_id, gain, type);
+ addAudioSource(asp);
+ if (pos_global.isExactlyZero())
+ {
+ // For sound preview and UI
+ asp->setForcedPriority(true);
+ }
+ else
+ {
+ asp->setPositionGlobal(pos_global);
+ }
+ asp->updatePriority();
+ asp->play(audio_uuid);
}
void LLAudioEngine::triggerSound(SoundData& soundData)
{
- triggerSound(soundData.audio_uuid, soundData.owner_id, soundData.gain, soundData.type, soundData.pos_global);
+ triggerSound(soundData.audio_uuid, soundData.owner_id, soundData.gain, soundData.type, soundData.pos_global);
}
void LLAudioEngine::setListenerPos(LLVector3 aVec)
{
- mListenerp->setPosition(aVec);
+ mListenerp->setPosition(aVec);
}
LLVector3 LLAudioEngine::getListenerPos()
{
- if (mListenerp)
- {
- return(mListenerp->getPosition());
- }
- else
- {
- return(LLVector3::zero);
- }
+ if (mListenerp)
+ {
+ return(mListenerp->getPosition());
+ }
+ else
+ {
+ return(LLVector3::zero);
+ }
}
void LLAudioEngine::setListenerVelocity(LLVector3 aVec)
{
- mListenerp->setVelocity(aVec);
+ mListenerp->setVelocity(aVec);
}
void LLAudioEngine::translateListener(LLVector3 aVec)
{
- mListenerp->translate(aVec);
+ mListenerp->translate(aVec);
}
void LLAudioEngine::orientListener(LLVector3 up, LLVector3 at)
{
- mListenerp->orient(up, at);
+ mListenerp->orient(up, at);
}
void LLAudioEngine::setListener(LLVector3 pos, LLVector3 vel, LLVector3 up, LLVector3 at)
{
- mListenerp->set(pos,vel,up,at);
+ mListenerp->set(pos,vel,up,at);
}
void LLAudioEngine::setDopplerFactor(F32 factor)
{
- if (mListenerp)
- {
- mListenerp->setDopplerFactor(factor);
- }
+ if (mListenerp)
+ {
+ mListenerp->setDopplerFactor(factor);
+ }
}
F32 LLAudioEngine::getDopplerFactor()
{
- if (mListenerp)
- {
- return mListenerp->getDopplerFactor();
- }
- else
- {
- return 0.f;
- }
+ if (mListenerp)
+ {
+ return mListenerp->getDopplerFactor();
+ }
+ else
+ {
+ return 0.f;
+ }
}
void LLAudioEngine::setRolloffFactor(F32 factor)
{
- if (mListenerp)
- {
- mListenerp->setRolloffFactor(factor);
- }
+ if (mListenerp)
+ {
+ mListenerp->setRolloffFactor(factor);
+ }
}
F32 LLAudioEngine::getRolloffFactor()
{
- if (mListenerp)
- {
- return mListenerp->getRolloffFactor();
- }
- else
- {
- return 0.f;
- }
+ if (mListenerp)
+ {
+ return mListenerp->getRolloffFactor();
+ }
+ else
+ {
+ return 0.f;
+ }
}
void LLAudioEngine::commitDeferredChanges()
{
- mListenerp->commitDeferredChanges();
+ mListenerp->commitDeferredChanges();
}
LLAudioSource * LLAudioEngine::findAudioSource(const LLUUID &source_id)
{
- source_map::iterator iter;
- iter = mAllSources.find(source_id);
+ source_map::iterator iter;
+ iter = mAllSources.find(source_id);
- if (iter == mAllSources.end())
- {
- return NULL;
- }
- else
- {
- return iter->second;
- }
+ if (iter == mAllSources.end())
+ {
+ return NULL;
+ }
+ else
+ {
+ return iter->second;
+ }
}
LLAudioData * LLAudioEngine::getAudioData(const LLUUID &audio_uuid)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA;
- data_map::iterator iter;
- iter = mAllData.find(audio_uuid);
- if (iter == mAllData.end())
- {
- // Create the new audio data
- LLAudioData *adp = new LLAudioData(audio_uuid);
- mAllData[audio_uuid] = adp;
- return adp;
- }
- else
- {
- return iter->second;
- }
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA;
+ data_map::iterator iter;
+ iter = mAllData.find(audio_uuid);
+ if (iter == mAllData.end())
+ {
+ // Create the new audio data
+ LLAudioData *adp = new LLAudioData(audio_uuid);
+ mAllData[audio_uuid] = adp;
+ return adp;
+ }
+ else
+ {
+ return iter->second;
+ }
}
void LLAudioEngine::addAudioSource(LLAudioSource *asp)
{
- mAllSources[asp->getID()] = asp;
+ mAllSources[asp->getID()] = asp;
}
void LLAudioEngine::cleanupAudioSource(LLAudioSource *asp)
{
- source_map::iterator iter;
- iter = mAllSources.find(asp->getID());
- if (iter == mAllSources.end())
- {
- LL_WARNS() << "Cleaning up unknown audio source!" << LL_ENDL;
- return;
- }
- else
- {
- LL_DEBUGS("AudioEngine") << "Cleaning up audio sources for "<< asp->getID() <<LL_ENDL;
- delete asp;
- mAllSources.erase(iter);
- }
+ source_map::iterator iter;
+ iter = mAllSources.find(asp->getID());
+ if (iter == mAllSources.end())
+ {
+ LL_WARNS() << "Cleaning up unknown audio source!" << LL_ENDL;
+ return;
+ }
+ else
+ {
+ LL_DEBUGS("AudioEngine") << "Cleaning up audio sources for "<< asp->getID() <<LL_ENDL;
+ delete asp;
+ mAllSources.erase(iter);
+ }
}
bool LLAudioEngine::hasDecodedFile(const LLUUID &uuid)
{
- std::string uuid_str;
- uuid.toString(uuid_str);
+ std::string uuid_str;
+ uuid.toString(uuid_str);
- std::string wav_path;
- wav_path = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_str);
- wav_path += ".dsf";
+ std::string wav_path;
+ wav_path = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_str);
+ wav_path += ".dsf";
- if (gDirUtilp->fileExists(wav_path))
- {
- return true;
- }
- else
- {
- return false;
- }
+ if (gDirUtilp->fileExists(wav_path))
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
}
bool LLAudioEngine::hasLocalFile(const LLUUID &uuid)
{
- // See if it's in the cache.
- bool have_local = LLFileSystem::getExists(uuid, LLAssetType::AT_SOUND);
- LL_DEBUGS("AudioEngine") << "sound uuid " << uuid << " exists in cache" << LL_ENDL;
- return have_local;
+ // See if it's in the cache.
+ bool have_local = LLFileSystem::getExists(uuid, LLAssetType::AT_SOUND);
+ LL_DEBUGS("AudioEngine") << "sound uuid " << uuid << " exists in cache" << LL_ENDL;
+ return have_local;
}
void LLAudioEngine::startNextTransfer()
{
- //LL_INFOS() << "LLAudioEngine::startNextTransfer()" << LL_ENDL;
- if (mCurrentTransfer.notNull() || getMuted())
- {
- //LL_INFOS() << "Transfer in progress, aborting" << LL_ENDL;
- return;
- }
-
- // Get the ID for the next asset that we want to transfer.
- // Pick one in the following order:
- LLUUID asset_id;
- S32 i;
- LLAudioSource *asp = NULL;
- LLAudioData *adp = NULL;
- data_map::iterator data_iter;
-
- // Check all channels for currently playing sounds.
- F32 max_pri = -1.f;
- for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++)
- {
- if (!mChannels[i])
- {
- continue;
- }
-
- asp = mChannels[i]->getSource();
- if (!asp)
- {
- continue;
- }
- if (asp->getPriority() <= max_pri)
- {
- continue;
- }
-
- if (asp->getPriority() <= max_pri)
- {
- continue;
- }
-
- adp = asp->getCurrentData();
- if (!adp)
- {
- continue;
- }
+ //LL_INFOS() << "LLAudioEngine::startNextTransfer()" << LL_ENDL;
+ if (mCurrentTransfer.notNull() || getMuted())
+ {
+ //LL_INFOS() << "Transfer in progress, aborting" << LL_ENDL;
+ return;
+ }
+
+ // Get the ID for the next asset that we want to transfer.
+ // Pick one in the following order:
+ LLUUID asset_id;
+ S32 i;
+ LLAudioSource *asp = NULL;
+ LLAudioData *adp = NULL;
+ data_map::iterator data_iter;
+
+ // Check all channels for currently playing sounds.
+ F32 max_pri = -1.f;
+ for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++)
+ {
+ if (!mChannels[i])
+ {
+ continue;
+ }
+
+ asp = mChannels[i]->getSource();
+ if (!asp)
+ {
+ continue;
+ }
+ if (asp->getPriority() <= max_pri)
+ {
+ continue;
+ }
+
+ if (asp->getPriority() <= max_pri)
+ {
+ continue;
+ }
+
+ adp = asp->getCurrentData();
+ if (!adp)
+ {
+ continue;
+ }
if (!adp->hasLocalData() && !adp->hasDecodeFailed())
- {
- asset_id = adp->getID();
- max_pri = asp->getPriority();
- }
- }
-
- // Check all channels for currently queued sounds.
- if (asset_id.isNull())
- {
- max_pri = -1.f;
- for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++)
- {
- if (!mChannels[i])
- {
- continue;
- }
-
- LLAudioSource *asp;
- asp = mChannels[i]->getSource();
- if (!asp)
- {
- continue;
- }
-
- if (asp->getPriority() <= max_pri)
- {
- continue;
- }
-
- adp = asp->getQueuedData();
- if (!adp)
- {
- continue;
- }
+ {
+ asset_id = adp->getID();
+ max_pri = asp->getPriority();
+ }
+ }
+
+ // Check all channels for currently queued sounds.
+ if (asset_id.isNull())
+ {
+ max_pri = -1.f;
+ for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++)
+ {
+ if (!mChannels[i])
+ {
+ continue;
+ }
+
+ LLAudioSource *asp;
+ asp = mChannels[i]->getSource();
+ if (!asp)
+ {
+ continue;
+ }
+
+ if (asp->getPriority() <= max_pri)
+ {
+ continue;
+ }
+
+ adp = asp->getQueuedData();
+ if (!adp)
+ {
+ continue;
+ }
if (!adp->hasLocalData() && !adp->hasDecodeFailed())
- {
- asset_id = adp->getID();
- max_pri = asp->getPriority();
- }
- }
- }
-
- // Check all live channels for other sounds (preloads).
- if (asset_id.isNull())
- {
- max_pri = -1.f;
- for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++)
- {
- if (!mChannels[i])
- {
- continue;
- }
-
- LLAudioSource *asp;
- asp = mChannels[i]->getSource();
- if (!asp)
- {
- continue;
- }
-
- if (asp->getPriority() <= max_pri)
- {
- continue;
- }
-
-
- for (data_map::value_type& preload_pair : asp->mPreloadMap)
- {
- LLAudioData *adp = preload_pair.second;
- if (!adp)
- {
- continue;
- }
+ {
+ asset_id = adp->getID();
+ max_pri = asp->getPriority();
+ }
+ }
+ }
+
+ // Check all live channels for other sounds (preloads).
+ if (asset_id.isNull())
+ {
+ max_pri = -1.f;
+ for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++)
+ {
+ if (!mChannels[i])
+ {
+ continue;
+ }
+
+ LLAudioSource *asp;
+ asp = mChannels[i]->getSource();
+ if (!asp)
+ {
+ continue;
+ }
+
+ if (asp->getPriority() <= max_pri)
+ {
+ continue;
+ }
+
+
+ for (data_map::value_type& preload_pair : asp->mPreloadMap)
+ {
+ LLAudioData *adp = preload_pair.second;
+ if (!adp)
+ {
+ continue;
+ }
if (!adp->hasLocalData() && !adp->hasDecodeFailed())
- {
- asset_id = adp->getID();
- max_pri = asp->getPriority();
- }
- }
- }
- }
-
- // Check all sources
- if (asset_id.isNull())
- {
- max_pri = -1.f;
- source_map::iterator source_iter;
- for (source_map::value_type& source_pair : mAllSources)
- {
- asp = source_pair.second;
- if (!asp)
- {
- continue;
- }
-
- if (asp->getPriority() <= max_pri)
- {
- continue;
- }
-
- adp = asp->getCurrentData();
+ {
+ asset_id = adp->getID();
+ max_pri = asp->getPriority();
+ }
+ }
+ }
+ }
+
+ // Check all sources
+ if (asset_id.isNull())
+ {
+ max_pri = -1.f;
+ source_map::iterator source_iter;
+ for (source_map::value_type& source_pair : mAllSources)
+ {
+ asp = source_pair.second;
+ if (!asp)
+ {
+ continue;
+ }
+
+ if (asp->getPriority() <= max_pri)
+ {
+ continue;
+ }
+
+ adp = asp->getCurrentData();
if (adp && !adp->hasLocalData() && !adp->hasDecodeFailed())
- {
- asset_id = adp->getID();
- max_pri = asp->getPriority();
- continue;
- }
+ {
+ asset_id = adp->getID();
+ max_pri = asp->getPriority();
+ continue;
+ }
- adp = asp->getQueuedData();
+ adp = asp->getQueuedData();
if (adp && !adp->hasLocalData() && !adp->hasDecodeFailed())
- {
- asset_id = adp->getID();
- max_pri = asp->getPriority();
- continue;
- }
-
- for (data_map::value_type& preload_pair : asp->mPreloadMap)
- {
- LLAudioData *adp = preload_pair.second;
- if (!adp)
- {
- continue;
- }
+ {
+ asset_id = adp->getID();
+ max_pri = asp->getPriority();
+ continue;
+ }
+
+ for (data_map::value_type& preload_pair : asp->mPreloadMap)
+ {
+ LLAudioData *adp = preload_pair.second;
+ if (!adp)
+ {
+ continue;
+ }
if (!adp->hasLocalData() && !adp->hasDecodeFailed())
- {
- asset_id = adp->getID();
- max_pri = asp->getPriority();
- break;
- }
- }
- }
- }
-
- if (asset_id.notNull())
- {
- LL_INFOS() << "Getting asset data for: " << asset_id << LL_ENDL;
- mCurrentTransfer = asset_id;
- mCurrentTransferTimer.reset();
- gAssetStorage->getAssetData(asset_id, LLAssetType::AT_SOUND,
- assetCallback, NULL);
- }
- else
- {
- //LL_INFOS() << "No pending transfers?" << LL_ENDL;
- }
+ {
+ asset_id = adp->getID();
+ max_pri = asp->getPriority();
+ break;
+ }
+ }
+ }
+ }
+
+ if (asset_id.notNull())
+ {
+ LL_INFOS() << "Getting asset data for: " << asset_id << LL_ENDL;
+ mCurrentTransfer = asset_id;
+ mCurrentTransferTimer.reset();
+ gAssetStorage->getAssetData(asset_id, LLAssetType::AT_SOUND,
+ assetCallback, NULL);
+ }
+ else
+ {
+ //LL_INFOS() << "No pending transfers?" << LL_ENDL;
+ }
}
// static
void LLAudioEngine::assetCallback(const LLUUID &uuid, LLAssetType::EType type, void *user_data, S32 result_code, LLExtStat ext_status)
{
- if (!gAudiop)
- {
- LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL;
- return;
- }
-
- if (result_code)
- {
- LL_INFOS() << "Boom, error in audio file transfer: " << LLAssetStorage::getErrorString( result_code ) << " (" << result_code << ")" << LL_ENDL;
- // Need to mark data as bad to avoid constant rerequests.
- LLAudioData *adp = gAudiop->getAudioData(uuid);
- if (adp)
- { // Make sure everything is cleared
+ if (!gAudiop)
+ {
+ LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL;
+ return;
+ }
+
+ if (result_code)
+ {
+ LL_INFOS() << "Boom, error in audio file transfer: " << LLAssetStorage::getErrorString( result_code ) << " (" << result_code << ")" << LL_ENDL;
+ // Need to mark data as bad to avoid constant rerequests.
+ LLAudioData *adp = gAudiop->getAudioData(uuid);
+ if (adp)
+ { // Make sure everything is cleared
adp->setHasDecodeFailed(true);
- adp->setHasLocalData(false);
- adp->setHasDecodedData(false);
- adp->setHasCompletedDecode(true);
- }
- }
- else
- {
- LLAudioData *adp = gAudiop->getAudioData(uuid);
- if (!adp)
+ adp->setHasLocalData(false);
+ adp->setHasDecodedData(false);
+ adp->setHasCompletedDecode(true);
+ }
+ }
+ else
+ {
+ LLAudioData *adp = gAudiop->getAudioData(uuid);
+ if (!adp)
{
- // Should never happen
- LL_WARNS() << "Got asset callback without audio data for " << uuid << LL_ENDL;
+ // Should never happen
+ LL_WARNS() << "Got asset callback without audio data for " << uuid << LL_ENDL;
}
- else
- {
- // LL_INFOS() << "Got asset callback with good audio data for " << uuid << ", making decode request" << LL_ENDL;
+ else
+ {
+ // LL_INFOS() << "Got asset callback with good audio data for " << uuid << ", making decode request" << LL_ENDL;
adp->setHasDecodeFailed(false);
- adp->setHasLocalData(true);
+ adp->setHasLocalData(true);
LLAudioDecodeMgr::getInstance()->addDecodeRequest(uuid);
- }
- }
- gAudiop->mCurrentTransfer = LLUUID::null;
- gAudiop->startNextTransfer();
+ }
+ }
+ gAudiop->mCurrentTransfer = LLUUID::null;
+ gAudiop->startNextTransfer();
}
@@ -1240,142 +1240,142 @@ void LLAudioEngine::assetCallback(const LLUUID &uuid, LLAssetType::EType type, v
LLAudioSource::LLAudioSource(const LLUUID& id, const LLUUID& owner_id, const F32 gain, const S32 type)
-: mID(id),
- mOwnerID(owner_id),
- mPriority(0.f),
- mGain(gain),
- mSourceMuted(false),
- mForcedPriority(false),
- mLoop(false),
- mSyncMaster(false),
- mSyncSlave(false),
- mQueueSounds(false),
- mPlayedOnce(false),
- mCorrupted(false),
- mType(type),
- mChannelp(NULL),
- mCurrentDatap(NULL),
- mQueuedDatap(NULL)
+: mID(id),
+ mOwnerID(owner_id),
+ mPriority(0.f),
+ mGain(gain),
+ mSourceMuted(false),
+ mForcedPriority(false),
+ mLoop(false),
+ mSyncMaster(false),
+ mSyncSlave(false),
+ mQueueSounds(false),
+ mPlayedOnce(false),
+ mCorrupted(false),
+ mType(type),
+ mChannelp(NULL),
+ mCurrentDatap(NULL),
+ mQueuedDatap(NULL)
{
}
LLAudioSource::~LLAudioSource()
{
- if (mChannelp)
- {
- // Stop playback of this sound
- mChannelp->setSource(NULL);
- mChannelp = NULL;
- }
+ if (mChannelp)
+ {
+ // Stop playback of this sound
+ mChannelp->setSource(NULL);
+ mChannelp = NULL;
+ }
}
void LLAudioSource::setChannel(LLAudioChannel *channelp)
{
- if (channelp == mChannelp)
- {
- return;
- }
+ if (channelp == mChannelp)
+ {
+ return;
+ }
- mChannelp = channelp;
+ mChannelp = channelp;
}
void LLAudioSource::update()
{
- if(mCorrupted)
- {
- return ; //no need to update
- }
-
- if (!getCurrentBuffer())
- {
- LLAudioData *adp = getCurrentData();
- if (adp)
- {
- // Hack - try and load the sound. Will do this as a callback
- // on decode later.
+ if(mCorrupted)
+ {
+ return ; //no need to update
+ }
+
+ if (!getCurrentBuffer())
+ {
+ LLAudioData *adp = getCurrentData();
+ if (adp)
+ {
+ // Hack - try and load the sound. Will do this as a callback
+ // on decode later.
if (adp->getBuffer())
- {
- play(adp->getID());
- }
+ {
+ play(adp->getID());
+ }
else if (adp->hasDecodedData() && !adp->hasWAVLoadFailed())
{
adp->load();
}
else if (adp->hasCompletedDecode() && adp->hasDecodeFailed()) // Only mark corrupted after decode is done
- {
- LL_WARNS() << "Marking LLAudioSource corrupted for " << adp->getID() << LL_ENDL;
- mCorrupted = true ;
- }
- }
- }
+ {
+ LL_WARNS() << "Marking LLAudioSource corrupted for " << adp->getID() << LL_ENDL;
+ mCorrupted = true ;
+ }
+ }
+ }
}
void LLAudioSource::updatePriority()
{
- if (isForcedPriority())
- {
- mPriority = 1.f;
- }
- else if (isMuted())
- {
- mPriority = 0.f;
- }
- else
- {
- // Priority is based on distance
- LLVector3 dist_vec;
- dist_vec.setVec(getPositionGlobal());
+ if (isForcedPriority())
+ {
+ mPriority = 1.f;
+ }
+ else if (isMuted())
+ {
+ mPriority = 0.f;
+ }
+ else
+ {
+ // Priority is based on distance
+ LLVector3 dist_vec;
+ dist_vec.setVec(getPositionGlobal());
- if (gAudiop)
- {
- dist_vec -= gAudiop->getListenerPos();
- }
+ if (gAudiop)
+ {
+ dist_vec -= gAudiop->getListenerPos();
+ }
- F32 dist_squared = llmax(1.f, dist_vec.magVecSquared());
+ F32 dist_squared = llmax(1.f, dist_vec.magVecSquared());
- mPriority = mGain / dist_squared;
- }
+ mPriority = mGain / dist_squared;
+ }
}
bool LLAudioSource::setupChannel()
{
- LLAudioData *adp = getCurrentData();
+ LLAudioData *adp = getCurrentData();
- if (!adp->getBuffer())
- {
- // We're not ready to play back the sound yet, so don't try and allocate a channel for it.
- //LL_WARNS() << "Aborting, no buffer" << LL_ENDL;
- return false;
- }
+ if (!adp->getBuffer())
+ {
+ // We're not ready to play back the sound yet, so don't try and allocate a channel for it.
+ //LL_WARNS() << "Aborting, no buffer" << LL_ENDL;
+ return false;
+ }
- if (!gAudiop)
- {
- LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL;
- return false;
- }
+ if (!gAudiop)
+ {
+ LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL;
+ return false;
+ }
- if (!mChannelp)
- {
- // Update the priority, in case we need to push out another channel.
- updatePriority();
+ if (!mChannelp)
+ {
+ // Update the priority, in case we need to push out another channel.
+ updatePriority();
- setChannel(gAudiop->getFreeChannel(getPriority()));
- }
+ setChannel(gAudiop->getFreeChannel(getPriority()));
+ }
- if (!mChannelp)
- {
- // Ugh, we don't have any free channels.
- // Now we have to reprioritize.
- // For now, just don't play the sound.
- //LL_WARNS() << "Aborting, no free channels" << LL_ENDL;
- return false;
- }
+ if (!mChannelp)
+ {
+ // Ugh, we don't have any free channels.
+ // Now we have to reprioritize.
+ // For now, just don't play the sound.
+ //LL_WARNS() << "Aborting, no free channels" << LL_ENDL;
+ return false;
+ }
- mChannelp->setSource(this);
- return true;
+ mChannelp->setSource(this);
+ return true;
}
void LLAudioSource::stop()
@@ -1390,249 +1390,249 @@ void LLAudioSource::stop()
bool LLAudioSource::play(const LLUUID &audio_uuid)
{
- // Special abuse of play(); don't play a sound, but kill it.
- if (audio_uuid.isNull())
- {
- if (getChannel())
- {
- getChannel()->setSource(NULL);
- setChannel(NULL);
- if (!isMuted())
- {
- mCurrentDatap = NULL;
- }
- }
- return false;
- }
-
- // Reset our age timeout if someone attempts to play the source.
- mAgeTimer.reset();
-
- if (!gAudiop)
- {
- LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL;
- return false;
- }
-
- LLAudioData *adp = gAudiop->getAudioData(audio_uuid);
- addAudioData(adp);
-
- if (isMuted())
- {
- return false;
- }
-
- bool has_buffer = gAudiop->updateBufferForData(adp, audio_uuid);
- if (!has_buffer)
- {
- // Don't bother trying to set up a channel or anything, we don't have an audio buffer.
- return false;
- }
-
- if (!setupChannel())
- {
- return false;
- }
-
- if (isSyncSlave())
- {
- // A sync slave, it doesn't start playing until it's synced up with the master.
- // Flag this channel as waiting for sync, and return true.
- getChannel()->setWaiting(true);
- return true;
- }
-
- getChannel()->play();
- return true;
+ // Special abuse of play(); don't play a sound, but kill it.
+ if (audio_uuid.isNull())
+ {
+ if (getChannel())
+ {
+ getChannel()->setSource(NULL);
+ setChannel(NULL);
+ if (!isMuted())
+ {
+ mCurrentDatap = NULL;
+ }
+ }
+ return false;
+ }
+
+ // Reset our age timeout if someone attempts to play the source.
+ mAgeTimer.reset();
+
+ if (!gAudiop)
+ {
+ LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL;
+ return false;
+ }
+
+ LLAudioData *adp = gAudiop->getAudioData(audio_uuid);
+ addAudioData(adp);
+
+ if (isMuted())
+ {
+ return false;
+ }
+
+ bool has_buffer = gAudiop->updateBufferForData(adp, audio_uuid);
+ if (!has_buffer)
+ {
+ // Don't bother trying to set up a channel or anything, we don't have an audio buffer.
+ return false;
+ }
+
+ if (!setupChannel())
+ {
+ return false;
+ }
+
+ if (isSyncSlave())
+ {
+ // A sync slave, it doesn't start playing until it's synced up with the master.
+ // Flag this channel as waiting for sync, and return true.
+ getChannel()->setWaiting(true);
+ return true;
+ }
+
+ getChannel()->play();
+ return true;
}
bool LLAudioSource::isDone() const
{
- if(mCorrupted)
- {
- return true ;
- }
-
- const F32 MAX_AGE = 60.f;
- const F32 MAX_UNPLAYED_AGE = 15.f;
- const F32 MAX_MUTED_AGE = 11.f;
-
- if (isLoop())
- {
- // Looped sources never die on their own.
- return false;
- }
-
- if (hasPendingPreloads())
- {
- return false;
- }
-
- if (mQueuedDatap)
- {
- // Don't kill this sound if we've got something queued up to play.
- return false;
- }
-
- F32 elapsed = mAgeTimer.getElapsedTimeF32();
-
- // This is a single-play source
- if (!mChannelp)
- {
- if ((elapsed > (mSourceMuted ? MAX_MUTED_AGE : MAX_UNPLAYED_AGE)) || mPlayedOnce)
- {
- // We don't have a channel assigned, and it's been
- // over 15 seconds since we tried to play it. Don't bother.
- //LL_INFOS() << "No channel assigned, source is done" << LL_ENDL;
- return true;
- }
- else
- {
- return false;
- }
- }
-
- if (mChannelp->isPlaying())
- {
- if (elapsed > MAX_AGE)
- {
- // Arbitarily cut off non-looped sounds when they're old.
- return true;
- }
- else
- {
- // Sound is still playing and we haven't timed out, don't kill it.
- return false;
- }
- }
-
- if ((elapsed > MAX_UNPLAYED_AGE) || mPlayedOnce)
- {
- // The sound isn't playing back after 15 seconds or we're already done playing it, kill it.
- return true;
- }
-
- return false;
+ if(mCorrupted)
+ {
+ return true ;
+ }
+
+ const F32 MAX_AGE = 60.f;
+ const F32 MAX_UNPLAYED_AGE = 15.f;
+ const F32 MAX_MUTED_AGE = 11.f;
+
+ if (isLoop())
+ {
+ // Looped sources never die on their own.
+ return false;
+ }
+
+ if (hasPendingPreloads())
+ {
+ return false;
+ }
+
+ if (mQueuedDatap)
+ {
+ // Don't kill this sound if we've got something queued up to play.
+ return false;
+ }
+
+ F32 elapsed = mAgeTimer.getElapsedTimeF32();
+
+ // This is a single-play source
+ if (!mChannelp)
+ {
+ if ((elapsed > (mSourceMuted ? MAX_MUTED_AGE : MAX_UNPLAYED_AGE)) || mPlayedOnce)
+ {
+ // We don't have a channel assigned, and it's been
+ // over 15 seconds since we tried to play it. Don't bother.
+ //LL_INFOS() << "No channel assigned, source is done" << LL_ENDL;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ if (mChannelp->isPlaying())
+ {
+ if (elapsed > MAX_AGE)
+ {
+ // Arbitarily cut off non-looped sounds when they're old.
+ return true;
+ }
+ else
+ {
+ // Sound is still playing and we haven't timed out, don't kill it.
+ return false;
+ }
+ }
+
+ if ((elapsed > MAX_UNPLAYED_AGE) || mPlayedOnce)
+ {
+ // The sound isn't playing back after 15 seconds or we're already done playing it, kill it.
+ return true;
+ }
+
+ return false;
}
void LLAudioSource::addAudioData(LLAudioData *adp, const bool set_current)
{
- // Only handle a single piece of audio data associated with a source right now,
- // until I implement prefetch.
-
- if (!gAudiop)
- {
- LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL;
- return;
- }
-
- if (set_current)
- {
- if (!mCurrentDatap)
- {
- mCurrentDatap = adp;
- if (mChannelp)
- {
- mChannelp->updateBuffer();
- mChannelp->play();
- }
-
- // Make sure the audio engine knows that we want to request this sound.
- gAudiop->startNextTransfer();
- return;
- }
- else if (mQueueSounds)
- {
- // If we have current data, and we're queuing, put
- // the object onto the queue.
- if (mQueuedDatap)
- {
- // We only queue one sound at a time, and it's a FIFO.
- // Don't put it onto the queue.
- return;
- }
-
- if (adp == mCurrentDatap && isLoop())
- {
- // No point in queueing the same sound if
- // we're looping.
- return;
- }
- mQueuedDatap = adp;
-
- // Make sure the audio engine knows that we want to request this sound.
- gAudiop->startNextTransfer();
- }
- else
- {
- if (mCurrentDatap != adp)
- {
- // Right now, if we're currently playing this sound in a channel, we
- // update the buffer that the channel's associated with
- // and play it. This may not be the correct behavior.
- mCurrentDatap = adp;
- if (mChannelp)
- {
- mChannelp->updateBuffer();
- mChannelp->play();
- }
- // Make sure the audio engine knows that we want to request this sound.
- gAudiop->startNextTransfer();
- }
- }
- }
- else
- {
- // Add it to the preload list.
- mPreloadMap[adp->getID()] = adp;
- gAudiop->startNextTransfer();
- }
+ // Only handle a single piece of audio data associated with a source right now,
+ // until I implement prefetch.
+
+ if (!gAudiop)
+ {
+ LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL;
+ return;
+ }
+
+ if (set_current)
+ {
+ if (!mCurrentDatap)
+ {
+ mCurrentDatap = adp;
+ if (mChannelp)
+ {
+ mChannelp->updateBuffer();
+ mChannelp->play();
+ }
+
+ // Make sure the audio engine knows that we want to request this sound.
+ gAudiop->startNextTransfer();
+ return;
+ }
+ else if (mQueueSounds)
+ {
+ // If we have current data, and we're queuing, put
+ // the object onto the queue.
+ if (mQueuedDatap)
+ {
+ // We only queue one sound at a time, and it's a FIFO.
+ // Don't put it onto the queue.
+ return;
+ }
+
+ if (adp == mCurrentDatap && isLoop())
+ {
+ // No point in queueing the same sound if
+ // we're looping.
+ return;
+ }
+ mQueuedDatap = adp;
+
+ // Make sure the audio engine knows that we want to request this sound.
+ gAudiop->startNextTransfer();
+ }
+ else
+ {
+ if (mCurrentDatap != adp)
+ {
+ // Right now, if we're currently playing this sound in a channel, we
+ // update the buffer that the channel's associated with
+ // and play it. This may not be the correct behavior.
+ mCurrentDatap = adp;
+ if (mChannelp)
+ {
+ mChannelp->updateBuffer();
+ mChannelp->play();
+ }
+ // Make sure the audio engine knows that we want to request this sound.
+ gAudiop->startNextTransfer();
+ }
+ }
+ }
+ else
+ {
+ // Add it to the preload list.
+ mPreloadMap[adp->getID()] = adp;
+ gAudiop->startNextTransfer();
+ }
}
bool LLAudioSource::hasPendingPreloads() const
{
- // Check to see if we've got any preloads on deck for this source
- for (const data_map::value_type& preload_pair : mPreloadMap)
- {
- LLAudioData *adp = preload_pair.second;
- // note: a bad UUID will forever be !hasDecodedData()
+ // Check to see if we've got any preloads on deck for this source
+ for (const data_map::value_type& preload_pair : mPreloadMap)
+ {
+ LLAudioData *adp = preload_pair.second;
+ // note: a bad UUID will forever be !hasDecodedData()
// but also hasDecodeFailed(), hence the check for hasDecodeFailed()
- if (!adp)
- {
- continue;
- }
+ if (!adp)
+ {
+ continue;
+ }
if (!adp->hasDecodedData() && !adp->hasDecodeFailed())
- {
- // This source is still waiting for a preload
- return true;
- }
- }
+ {
+ // This source is still waiting for a preload
+ return true;
+ }
+ }
- return false;
+ return false;
}
LLAudioData * LLAudioSource::getCurrentData()
{
- return mCurrentDatap;
+ return mCurrentDatap;
}
LLAudioData * LLAudioSource::getQueuedData()
{
- return mQueuedDatap;
+ return mQueuedDatap;
}
LLAudioBuffer * LLAudioSource::getCurrentBuffer()
{
- if (!mCurrentDatap)
- {
- return NULL;
- }
+ if (!mCurrentDatap)
+ {
+ return NULL;
+ }
- return mCurrentDatap->getBuffer();
+ return mCurrentDatap->getBuffer();
}
@@ -1644,106 +1644,106 @@ LLAudioBuffer * LLAudioSource::getCurrentBuffer()
LLAudioChannel::LLAudioChannel() :
- mCurrentSourcep(NULL),
- mCurrentBufferp(NULL),
- mLoopedThisFrame(false),
- mWaiting(false),
- mSecondaryGain(1.0f)
+ mCurrentSourcep(NULL),
+ mCurrentBufferp(NULL),
+ mLoopedThisFrame(false),
+ mWaiting(false),
+ mSecondaryGain(1.0f)
{
}
LLAudioChannel::~LLAudioChannel()
{
- // Need to disconnect any sources which are using this channel.
- //LL_INFOS() << "Cleaning up audio channel" << LL_ENDL;
- if (mCurrentSourcep)
- {
- mCurrentSourcep->setChannel(NULL);
- }
- mCurrentBufferp = NULL;
+ // Need to disconnect any sources which are using this channel.
+ //LL_INFOS() << "Cleaning up audio channel" << LL_ENDL;
+ if (mCurrentSourcep)
+ {
+ mCurrentSourcep->setChannel(NULL);
+ }
+ mCurrentBufferp = NULL;
}
void LLAudioChannel::setSource(LLAudioSource *sourcep)
{
- //LL_INFOS() << this << ": setSource(" << sourcep << ")" << LL_ENDL;
+ //LL_INFOS() << this << ": setSource(" << sourcep << ")" << LL_ENDL;
- if (!sourcep)
- {
- // Clearing the source for this channel, don't need to do anything.
- //LL_INFOS() << "Clearing source for channel" << LL_ENDL;
- cleanup();
- mCurrentSourcep = NULL;
- mWaiting = false;
- }
- else
- {
- LL_DEBUGS("AudioEngine") << "( id: " << sourcep->getID() << ")" << LL_ENDL;
+ if (!sourcep)
+ {
+ // Clearing the source for this channel, don't need to do anything.
+ //LL_INFOS() << "Clearing source for channel" << LL_ENDL;
+ cleanup();
+ mCurrentSourcep = NULL;
+ mWaiting = false;
+ }
+ else
+ {
+ LL_DEBUGS("AudioEngine") << "( id: " << sourcep->getID() << ")" << LL_ENDL;
- if (sourcep == mCurrentSourcep)
- {
- // Don't reallocate the channel, this will make FMOD goofy.
- //LL_INFOS() << "Calling setSource with same source!" << LL_ENDL;
- }
+ if (sourcep == mCurrentSourcep)
+ {
+ // Don't reallocate the channel, this will make FMOD goofy.
+ //LL_INFOS() << "Calling setSource with same source!" << LL_ENDL;
+ }
- mCurrentSourcep = sourcep;
+ mCurrentSourcep = sourcep;
- updateBuffer();
- update3DPosition();
- }
+ updateBuffer();
+ update3DPosition();
+ }
}
bool LLAudioChannel::updateBuffer()
{
- if (!gAudiop)
- {
- LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL;
- return false;
- }
+ if (!gAudiop)
+ {
+ LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL;
+ return false;
+ }
- if (!mCurrentSourcep)
- {
- // This channel isn't associated with any source, nothing
- // to be updated
- return false;
- }
+ if (!mCurrentSourcep)
+ {
+ // This channel isn't associated with any source, nothing
+ // to be updated
+ return false;
+ }
- // Initialize the channel's gain setting for this sound.
- setSecondaryGain(gAudiop->getSecondaryGain(mCurrentSourcep->getType()));
+ // Initialize the channel's gain setting for this sound.
+ setSecondaryGain(gAudiop->getSecondaryGain(mCurrentSourcep->getType()));
- LLAudioBuffer *bufferp = mCurrentSourcep->getCurrentBuffer();
- if (bufferp == mCurrentBufferp)
- {
- if (bufferp)
- {
- // The source hasn't changed what buffer it's playing
- bufferp->mLastUseTimer.reset();
- bufferp->mInUse = true;
- }
- return false;
- }
+ LLAudioBuffer *bufferp = mCurrentSourcep->getCurrentBuffer();
+ if (bufferp == mCurrentBufferp)
+ {
+ if (bufferp)
+ {
+ // The source hasn't changed what buffer it's playing
+ bufferp->mLastUseTimer.reset();
+ bufferp->mInUse = true;
+ }
+ return false;
+ }
- //
- // The source changed what buffer it's playing. We need to clean up
- // the existing channel
- //
- cleanup();
+ //
+ // The source changed what buffer it's playing. We need to clean up
+ // the existing channel
+ //
+ cleanup();
- mCurrentBufferp = bufferp;
- if (bufferp)
- {
- bufferp->mLastUseTimer.reset();
- bufferp->mInUse = true;
- }
+ mCurrentBufferp = bufferp;
+ if (bufferp)
+ {
+ bufferp->mLastUseTimer.reset();
+ bufferp->mInUse = true;
+ }
- if (!mCurrentBufferp)
- {
- // There's no new buffer to be played, so we just abort.
- return false;
- }
+ if (!mCurrentBufferp)
+ {
+ // There's no new buffer to be played, so we just abort.
+ return false;
+ }
- return true;
+ return true;
}
@@ -1755,82 +1755,82 @@ bool LLAudioChannel::updateBuffer()
LLAudioData::LLAudioData(const LLUUID &uuid) :
- mID(uuid),
- mBufferp(NULL),
- mHasLocalData(false),
- mHasDecodedData(false),
- mHasCompletedDecode(false),
+ mID(uuid),
+ mBufferp(NULL),
+ mHasLocalData(false),
+ mHasDecodedData(false),
+ mHasCompletedDecode(false),
mHasDecodeFailed(false),
mHasWAVLoadFailed(false)
{
- if (uuid.isNull())
- {
- // This is a null sound.
- return;
- }
-
- if (!gAudiop)
- {
- LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL;
- return;
- }
-
- if (gAudiop->hasDecodedFile(uuid))
- {
- // Already have a decoded version, don't need to decode it.
- setHasLocalData(true);
- setHasDecodedData(true);
- setHasCompletedDecode(true);
- }
- else if (gAssetStorage && gAssetStorage->hasLocalAsset(uuid, LLAssetType::AT_SOUND))
- {
- setHasLocalData(true);
- }
+ if (uuid.isNull())
+ {
+ // This is a null sound.
+ return;
+ }
+
+ if (!gAudiop)
+ {
+ LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL;
+ return;
+ }
+
+ if (gAudiop->hasDecodedFile(uuid))
+ {
+ // Already have a decoded version, don't need to decode it.
+ setHasLocalData(true);
+ setHasDecodedData(true);
+ setHasCompletedDecode(true);
+ }
+ else if (gAssetStorage && gAssetStorage->hasLocalAsset(uuid, LLAssetType::AT_SOUND))
+ {
+ setHasLocalData(true);
+ }
}
//return false when the audio file is corrupted.
bool LLAudioData::load()
{
- // For now, just assume we're going to use one buffer per audiodata.
- if (mBufferp)
- {
- // We already have this sound in a buffer, don't do anything.
- LL_INFOS() << "Already have a buffer for this sound, don't bother loading!" << LL_ENDL;
+ // For now, just assume we're going to use one buffer per audiodata.
+ if (mBufferp)
+ {
+ // We already have this sound in a buffer, don't do anything.
+ LL_INFOS() << "Already have a buffer for this sound, don't bother loading!" << LL_ENDL;
mHasWAVLoadFailed = false;
- return true;
- }
+ return true;
+ }
- if (!gAudiop)
- {
- LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL;
+ if (!gAudiop)
+ {
+ LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL;
mHasWAVLoadFailed = true;
- return false;
- }
-
- mBufferp = gAudiop->getFreeBuffer();
- if (!mBufferp)
- {
- // No free buffers, abort.
- LL_INFOS() << "Not able to allocate a new audio buffer, aborting." << LL_ENDL;
+ return false;
+ }
+
+ mBufferp = gAudiop->getFreeBuffer();
+ if (!mBufferp)
+ {
+ // No free buffers, abort.
+ LL_INFOS() << "Not able to allocate a new audio buffer, aborting." << LL_ENDL;
// *TODO: Mark this failure differently so the audio engine could retry loading this buffer in the future
mHasWAVLoadFailed = true;
- return true;
- }
+ return true;
+ }
- std::string uuid_str;
- std::string wav_path;
- mID.toString(uuid_str);
- wav_path= gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_str) + ".dsf";
+ std::string uuid_str;
+ std::string wav_path;
+ mID.toString(uuid_str);
+ wav_path= gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_str) + ".dsf";
mHasWAVLoadFailed = !mBufferp->loadWAV(wav_path);
if (mHasWAVLoadFailed)
- {
- // Hrm. Right now, let's unset the buffer, since it's empty.
- gAudiop->cleanupBuffer(mBufferp);
- mBufferp = NULL;
-
- return false;
- }
- mBufferp->mAudioDatap = this;
- return true;
+ {
+ // Hrm. Right now, let's unset the buffer, since it's empty.
+ gAudiop->cleanupBuffer(mBufferp);
+ mBufferp = NULL;
+
+ return false;
+ }
+ mBufferp->mAudioDatap = this;
+ return true;
}
diff --git a/indra/llaudio/llaudioengine.h b/indra/llaudio/llaudioengine.h
index c045d18c42..2a16050c5b 100755
--- a/indra/llaudio/llaudioengine.h
+++ b/indra/llaudio/llaudioengine.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file audioengine.h
* @brief Definition of LLAudioEngine base class abstracting the audio support
*
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -62,186 +62,186 @@ struct SoundData;
//
// LLAudioEngine definition
//
-class LLAudioEngine
+class LLAudioEngine
{
- friend class LLAudioChannelOpenAL; // bleh. channel needs some listener methods.
-
+ friend class LLAudioChannelOpenAL; // bleh. channel needs some listener methods.
+
public:
- enum LLAudioType
- {
- AUDIO_TYPE_NONE = 0,
- AUDIO_TYPE_SFX = 1,
- AUDIO_TYPE_UI = 2,
- AUDIO_TYPE_AMBIENT = 3,
- AUDIO_TYPE_COUNT = 4 // last
- };
-
- enum LLAudioPlayState
- {
- // isInternetStreamPlaying() returns an *S32*, with
- // 0 = stopped, 1 = playing, 2 = paused.
- AUDIO_STOPPED = 0,
- AUDIO_PLAYING = 1,
- AUDIO_PAUSED = 2
- };
-
- LLAudioEngine();
- virtual ~LLAudioEngine();
-
- // initialization/startup/shutdown
- virtual bool init(void *userdata, const std::string &app_title);
- virtual std::string getDriverName(bool verbose) = 0;
- virtual LLStreamingAudioInterface *createDefaultStreamingAudioImpl() const = 0;
- virtual void shutdown();
-
- // Used by the mechanics of the engine
- //virtual void processQueue(const LLUUID &sound_guid);
- virtual void setListener(LLVector3 pos,LLVector3 vel,LLVector3 up,LLVector3 at);
- virtual void updateWind(LLVector3 direction, F32 camera_height_above_water) = 0;
- virtual void idle();
- virtual void updateChannels();
-
- //
- // "End user" functionality
- //
- virtual bool isWindEnabled();
- virtual void enableWind(bool state_b);
-
- // Use these for temporarily muting the audio system.
- // Does not change buffers, initialization, etc. but
- // stops playing new sounds.
- void setMuted(bool muted);
- bool getMuted() const { return mMuted; }
+ enum LLAudioType
+ {
+ AUDIO_TYPE_NONE = 0,
+ AUDIO_TYPE_SFX = 1,
+ AUDIO_TYPE_UI = 2,
+ AUDIO_TYPE_AMBIENT = 3,
+ AUDIO_TYPE_COUNT = 4 // last
+ };
+
+ enum LLAudioPlayState
+ {
+ // isInternetStreamPlaying() returns an *S32*, with
+ // 0 = stopped, 1 = playing, 2 = paused.
+ AUDIO_STOPPED = 0,
+ AUDIO_PLAYING = 1,
+ AUDIO_PAUSED = 2
+ };
+
+ LLAudioEngine();
+ virtual ~LLAudioEngine();
+
+ // initialization/startup/shutdown
+ virtual bool init(void *userdata, const std::string &app_title);
+ virtual std::string getDriverName(bool verbose) = 0;
+ virtual LLStreamingAudioInterface *createDefaultStreamingAudioImpl() const = 0;
+ virtual void shutdown();
+
+ // Used by the mechanics of the engine
+ //virtual void processQueue(const LLUUID &sound_guid);
+ virtual void setListener(LLVector3 pos,LLVector3 vel,LLVector3 up,LLVector3 at);
+ virtual void updateWind(LLVector3 direction, F32 camera_height_above_water) = 0;
+ virtual void idle();
+ virtual void updateChannels();
+
+ //
+ // "End user" functionality
+ //
+ virtual bool isWindEnabled();
+ virtual void enableWind(bool state_b);
+
+ // Use these for temporarily muting the audio system.
+ // Does not change buffers, initialization, etc. but
+ // stops playing new sounds.
+ void setMuted(bool muted);
+ bool getMuted() const { return mMuted; }
#ifdef USE_PLUGIN_MEDIA
- LLPluginClassMedia* initializeMedia(const std::string& media_type);
+ LLPluginClassMedia* initializeMedia(const std::string& media_type);
#endif
- F32 getMasterGain();
- void setMasterGain(F32 gain);
+ F32 getMasterGain();
+ void setMasterGain(F32 gain);
+
+ F32 getSecondaryGain(S32 type);
+ void setSecondaryGain(S32 type, F32 gain);
- F32 getSecondaryGain(S32 type);
- void setSecondaryGain(S32 type, F32 gain);
+ F32 getInternetStreamGain();
- F32 getInternetStreamGain();
+ virtual void setDopplerFactor(F32 factor);
+ virtual F32 getDopplerFactor();
+ virtual void setRolloffFactor(F32 factor);
+ virtual F32 getRolloffFactor();
+ virtual void setMaxWindGain(F32 gain);
- virtual void setDopplerFactor(F32 factor);
- virtual F32 getDopplerFactor();
- virtual void setRolloffFactor(F32 factor);
- virtual F32 getRolloffFactor();
- virtual void setMaxWindGain(F32 gain);
+ // Methods actually related to setting up and removing sounds
+ // Owner ID is the owner of the object making the request
+ void triggerSound(const LLUUID &sound_id, const LLUUID& owner_id, const F32 gain,
+ const S32 type = LLAudioEngine::AUDIO_TYPE_NONE,
+ const LLVector3d &pos_global = LLVector3d::zero);
+ void triggerSound(SoundData& soundData);
- // Methods actually related to setting up and removing sounds
- // Owner ID is the owner of the object making the request
- void triggerSound(const LLUUID &sound_id, const LLUUID& owner_id, const F32 gain,
- const S32 type = LLAudioEngine::AUDIO_TYPE_NONE,
- const LLVector3d &pos_global = LLVector3d::zero);
- void triggerSound(SoundData& soundData);
+ bool preloadSound(const LLUUID &id);
- bool preloadSound(const LLUUID &id);
+ void addAudioSource(LLAudioSource *asp);
+ void cleanupAudioSource(LLAudioSource *asp);
- void addAudioSource(LLAudioSource *asp);
- void cleanupAudioSource(LLAudioSource *asp);
+ LLAudioSource *findAudioSource(const LLUUID &source_id);
+ LLAudioData *getAudioData(const LLUUID &audio_uuid);
- LLAudioSource *findAudioSource(const LLUUID &source_id);
- LLAudioData *getAudioData(const LLUUID &audio_uuid);
+ // Internet stream implementation manipulation
+ LLStreamingAudioInterface *getStreamingAudioImpl();
+ void setStreamingAudioImpl(LLStreamingAudioInterface *impl);
+ // Internet stream methods - these will call down into the *mStreamingAudioImpl if it exists
+ void startInternetStream(const std::string& url);
+ void stopInternetStream();
+ void pauseInternetStream(S32 pause);
+ void updateInternetStream(); // expected to be called often
+ LLAudioPlayState isInternetStreamPlaying();
+ // use a value from 0.0 to 1.0, inclusive
+ void setInternetStreamGain(F32 vol);
+ std::string getInternetStreamURL();
- // Internet stream implementation manipulation
- LLStreamingAudioInterface *getStreamingAudioImpl();
- void setStreamingAudioImpl(LLStreamingAudioInterface *impl);
- // Internet stream methods - these will call down into the *mStreamingAudioImpl if it exists
- void startInternetStream(const std::string& url);
- void stopInternetStream();
- void pauseInternetStream(S32 pause);
- void updateInternetStream(); // expected to be called often
- LLAudioPlayState isInternetStreamPlaying();
- // use a value from 0.0 to 1.0, inclusive
- void setInternetStreamGain(F32 vol);
- std::string getInternetStreamURL();
-
- // For debugging usage
- virtual LLVector3 getListenerPos();
+ // For debugging usage
+ virtual LLVector3 getListenerPos();
- LLAudioBuffer *getFreeBuffer(); // Get a free buffer, or flush an existing one if you have to.
- LLAudioChannel *getFreeChannel(const F32 priority); // Get a free channel or flush an existing one if your priority is higher
- void cleanupBuffer(LLAudioBuffer *bufferp);
+ LLAudioBuffer *getFreeBuffer(); // Get a free buffer, or flush an existing one if you have to.
+ LLAudioChannel *getFreeChannel(const F32 priority); // Get a free channel or flush an existing one if your priority is higher
+ void cleanupBuffer(LLAudioBuffer *bufferp);
- bool hasDecodedFile(const LLUUID &uuid);
- bool hasLocalFile(const LLUUID &uuid);
+ bool hasDecodedFile(const LLUUID &uuid);
+ bool hasLocalFile(const LLUUID &uuid);
- bool updateBufferForData(LLAudioData *adp, const LLUUID &audio_uuid = LLUUID::null);
+ bool updateBufferForData(LLAudioData *adp, const LLUUID &audio_uuid = LLUUID::null);
- // Asset callback when we're retrieved a sound from the asset server.
- void startNextTransfer();
- static void assetCallback(const LLUUID &uuid, LLAssetType::EType type, void *user_data, S32 result_code, LLExtStat ext_status);
+ // Asset callback when we're retrieved a sound from the asset server.
+ void startNextTransfer();
+ static void assetCallback(const LLUUID &uuid, LLAssetType::EType type, void *user_data, S32 result_code, LLExtStat ext_status);
- friend class LLPipeline; // For debugging
+ friend class LLPipeline; // For debugging
public:
- F32 mMaxWindGain; // Hack. Public to set before fade in?
+ F32 mMaxWindGain; // Hack. Public to set before fade in?
protected:
- virtual LLAudioBuffer *createBuffer() = 0;
- virtual LLAudioChannel *createChannel() = 0;
+ virtual LLAudioBuffer *createBuffer() = 0;
+ virtual LLAudioChannel *createChannel() = 0;
- virtual bool initWind() = 0;
- virtual void cleanupWind() = 0;
- virtual void setInternalGain(F32 gain) = 0;
+ virtual bool initWind() = 0;
+ virtual void cleanupWind() = 0;
+ virtual void setInternalGain(F32 gain) = 0;
- void commitDeferredChanges();
+ void commitDeferredChanges();
- virtual void allocateListener() = 0;
+ virtual void allocateListener() = 0;
- // listener methods
- virtual void setListenerPos(LLVector3 vec);
- virtual void setListenerVelocity(LLVector3 vec);
- virtual void orientListener(LLVector3 up, LLVector3 at);
- virtual void translateListener(LLVector3 vec);
+ // listener methods
+ virtual void setListenerPos(LLVector3 vec);
+ virtual void setListenerVelocity(LLVector3 vec);
+ virtual void orientListener(LLVector3 up, LLVector3 at);
+ virtual void translateListener(LLVector3 vec);
- F64 mapWindVecToGain(LLVector3 wind_vec);
- F64 mapWindVecToPitch(LLVector3 wind_vec);
- F64 mapWindVecToPan(LLVector3 wind_vec);
+ F64 mapWindVecToGain(LLVector3 wind_vec);
+ F64 mapWindVecToPitch(LLVector3 wind_vec);
+ F64 mapWindVecToPan(LLVector3 wind_vec);
protected:
- LLListener *mListenerp;
+ LLListener *mListenerp;
- bool mMuted;
- void* mUserData;
+ bool mMuted;
+ void* mUserData;
- S32 mLastStatus;
-
- bool mEnableWind;
+ S32 mLastStatus;
- LLUUID mCurrentTransfer; // Audio file currently being transferred by the system
- LLFrameTimer mCurrentTransferTimer;
+ bool mEnableWind;
- // A list of all audio sources that are known to the viewer at this time.
- // This is most likely a superset of the ones that we actually have audio
- // data for, or are playing back.
- typedef std::map<LLUUID, LLAudioSource *> source_map;
- typedef std::map<LLUUID, LLAudioData *> data_map;
+ LLUUID mCurrentTransfer; // Audio file currently being transferred by the system
+ LLFrameTimer mCurrentTransferTimer;
- source_map mAllSources;
- data_map mAllData;
+ // A list of all audio sources that are known to the viewer at this time.
+ // This is most likely a superset of the ones that we actually have audio
+ // data for, or are playing back.
+ typedef std::map<LLUUID, LLAudioSource *> source_map;
+ typedef std::map<LLUUID, LLAudioData *> data_map;
+
+ source_map mAllSources;
+ data_map mAllData;
std::array<LLAudioChannel*, LL_MAX_AUDIO_CHANNELS> mChannels;
- // Buffers needs to change into a different data structure, as the number of buffers
- // that we have active should be limited by RAM usage, not count.
+ // Buffers needs to change into a different data structure, as the number of buffers
+ // that we have active should be limited by RAM usage, not count.
std::array<LLAudioBuffer*, LL_MAX_AUDIO_BUFFERS> mBuffers;
-
- F32 mMasterGain;
- F32 mInternalGain; // Actual gain set; either mMasterGain or 0 when mMuted is true.
- F32 mSecondaryGain[AUDIO_TYPE_COUNT];
- F32 mNextWindUpdate;
+ F32 mMasterGain;
+ F32 mInternalGain; // Actual gain set; either mMasterGain or 0 when mMuted is true.
+ F32 mSecondaryGain[AUDIO_TYPE_COUNT];
+
+ F32 mNextWindUpdate;
- LLFrameTimer mWindUpdateTimer;
+ LLFrameTimer mWindUpdateTimer;
private:
- void setDefaults();
- LLStreamingAudioInterface *mStreamingAudioImpl;
+ void setDefaults();
+ LLStreamingAudioInterface *mStreamingAudioImpl;
};
@@ -255,56 +255,56 @@ private:
class LLAudioSource
{
public:
- // owner_id is the id of the agent responsible for making this sound
- // play, for example, the owner of the object currently playing it
- LLAudioSource(const LLUUID &id, const LLUUID& owner_id, const F32 gain, const S32 type = LLAudioEngine::AUDIO_TYPE_NONE);
- virtual ~LLAudioSource();
+ // owner_id is the id of the agent responsible for making this sound
+ // play, for example, the owner of the object currently playing it
+ LLAudioSource(const LLUUID &id, const LLUUID& owner_id, const F32 gain, const S32 type = LLAudioEngine::AUDIO_TYPE_NONE);
+ virtual ~LLAudioSource();
- virtual void update(); // Update this audio source
- void updatePriority();
+ virtual void update(); // Update this audio source
+ void updatePriority();
- void preload(const LLUUID &audio_id); // Only used for preloading UI sounds, now.
+ void preload(const LLUUID &audio_id); // Only used for preloading UI sounds, now.
- void addAudioData(LLAudioData *adp, bool set_current = TRUE);
+ void addAudioData(LLAudioData *adp, bool set_current = TRUE);
- void setForcedPriority(const bool ambient) { mForcedPriority = ambient; }
- bool isForcedPriority() const { return mForcedPriority; }
+ void setForcedPriority(const bool ambient) { mForcedPriority = ambient; }
+ bool isForcedPriority() const { return mForcedPriority; }
- void setLoop(const bool loop) { mLoop = loop; }
- bool isLoop() const { return mLoop; }
+ void setLoop(const bool loop) { mLoop = loop; }
+ bool isLoop() const { return mLoop; }
- void setSyncMaster(const bool master) { mSyncMaster = master; }
- bool isSyncMaster() const { return mSyncMaster; }
+ void setSyncMaster(const bool master) { mSyncMaster = master; }
+ bool isSyncMaster() const { return mSyncMaster; }
- void setSyncSlave(const bool slave) { mSyncSlave = slave; }
- bool isSyncSlave() const { return mSyncSlave; }
+ void setSyncSlave(const bool slave) { mSyncSlave = slave; }
+ bool isSyncSlave() const { return mSyncSlave; }
- void setQueueSounds(const bool queue) { mQueueSounds = queue; }
- bool isQueueSounds() const { return mQueueSounds; }
+ void setQueueSounds(const bool queue) { mQueueSounds = queue; }
+ bool isQueueSounds() const { return mQueueSounds; }
- void setPlayedOnce(const bool played_once) { mPlayedOnce = played_once; }
+ void setPlayedOnce(const bool played_once) { mPlayedOnce = played_once; }
- void setType(S32 type) { mType = type; }
- S32 getType() { return mType; }
+ void setType(S32 type) { mType = type; }
+ S32 getType() { return mType; }
- void setPositionGlobal(const LLVector3d &position_global) { mPositionGlobal = position_global; }
- LLVector3d getPositionGlobal() const { return mPositionGlobal; }
- LLVector3 getVelocity() const { return mVelocity; }
- F32 getPriority() const { return mPriority; }
+ void setPositionGlobal(const LLVector3d &position_global) { mPositionGlobal = position_global; }
+ LLVector3d getPositionGlobal() const { return mPositionGlobal; }
+ LLVector3 getVelocity() const { return mVelocity; }
+ F32 getPriority() const { return mPriority; }
- // Gain should always be clamped between 0 and 1.
- F32 getGain() const { return mGain; }
- virtual void setGain(const F32 gain) { mGain = llclamp(gain, 0.f, 1.f); }
+ // Gain should always be clamped between 0 and 1.
+ F32 getGain() const { return mGain; }
+ virtual void setGain(const F32 gain) { mGain = llclamp(gain, 0.f, 1.f); }
- const LLUUID &getID() const { return mID; }
- bool isDone() const;
- bool isMuted() const { return mSourceMuted; }
+ const LLUUID &getID() const { return mID; }
+ bool isDone() const;
+ bool isMuted() const { return mSourceMuted; }
- LLAudioData *getCurrentData();
- LLAudioData *getQueuedData();
- LLAudioBuffer *getCurrentBuffer();
+ LLAudioData *getCurrentData();
+ LLAudioData *getQueuedData();
+ LLAudioBuffer *getCurrentBuffer();
- bool setupChannel();
+ bool setupChannel();
// Stop the audio source, reset audio id even if muted
void stop();
@@ -313,40 +313,40 @@ public:
// takes mute into account to preserve previous id if nessesary
bool play(const LLUUID &audio_id);
- bool hasPendingPreloads() const; // Has preloads that haven't been done yet
+ bool hasPendingPreloads() const; // Has preloads that haven't been done yet
- friend class LLAudioEngine;
- friend class LLAudioChannel;
+ friend class LLAudioEngine;
+ friend class LLAudioChannel;
protected:
- void setChannel(LLAudioChannel *channelp);
- LLAudioChannel *getChannel() const { return mChannelp; }
+ void setChannel(LLAudioChannel *channelp);
+ LLAudioChannel *getChannel() const { return mChannelp; }
protected:
- LLUUID mID; // The ID of the source is that of the object if it's attached to an object.
- LLUUID mOwnerID; // owner of the object playing the sound
- F32 mPriority;
- F32 mGain;
- bool mSourceMuted;
- bool mForcedPriority; // ignore mute, set high priority, researved for sound preview and UI
- bool mLoop;
- bool mSyncMaster;
- bool mSyncSlave;
- bool mQueueSounds;
- bool mPlayedOnce;
- bool mCorrupted;
- S32 mType;
- LLVector3d mPositionGlobal;
- LLVector3 mVelocity;
-
- //LLAudioSource *mSyncMasterp; // If we're a slave, the source that we're synced to.
- LLAudioChannel *mChannelp; // If we're currently playing back, this is the channel that we're assigned to.
- LLAudioData *mCurrentDatap;
- LLAudioData *mQueuedDatap;
-
- typedef std::map<LLUUID, LLAudioData *> data_map;
- data_map mPreloadMap;
-
- LLFrameTimer mAgeTimer;
+ LLUUID mID; // The ID of the source is that of the object if it's attached to an object.
+ LLUUID mOwnerID; // owner of the object playing the sound
+ F32 mPriority;
+ F32 mGain;
+ bool mSourceMuted;
+ bool mForcedPriority; // ignore mute, set high priority, researved for sound preview and UI
+ bool mLoop;
+ bool mSyncMaster;
+ bool mSyncSlave;
+ bool mQueueSounds;
+ bool mPlayedOnce;
+ bool mCorrupted;
+ S32 mType;
+ LLVector3d mPositionGlobal;
+ LLVector3 mVelocity;
+
+ //LLAudioSource *mSyncMasterp; // If we're a slave, the source that we're synced to.
+ LLAudioChannel *mChannelp; // If we're currently playing back, this is the channel that we're assigned to.
+ LLAudioData *mCurrentDatap;
+ LLAudioData *mQueuedDatap;
+
+ typedef std::map<LLUUID, LLAudioData *> data_map;
+ data_map mPreloadMap;
+
+ LLFrameTimer mAgeTimer;
};
@@ -404,34 +404,34 @@ class LLAudioData
class LLAudioChannel
{
public:
- LLAudioChannel();
- virtual ~LLAudioChannel();
+ LLAudioChannel();
+ virtual ~LLAudioChannel();
- virtual void setSource(LLAudioSource *sourcep);
- LLAudioSource *getSource() const { return mCurrentSourcep; }
+ virtual void setSource(LLAudioSource *sourcep);
+ LLAudioSource *getSource() const { return mCurrentSourcep; }
- void setSecondaryGain(F32 gain) { mSecondaryGain = gain; }
- F32 getSecondaryGain() { return mSecondaryGain; }
+ void setSecondaryGain(F32 gain) { mSecondaryGain = gain; }
+ F32 getSecondaryGain() { return mSecondaryGain; }
- friend class LLAudioEngine;
- friend class LLAudioSource;
+ friend class LLAudioEngine;
+ friend class LLAudioSource;
protected:
- virtual void play() = 0;
- virtual void playSynced(LLAudioChannel *channelp) = 0;
- virtual void cleanup() = 0;
- virtual bool isPlaying() = 0;
- void setWaiting(const bool waiting) { mWaiting = waiting; }
- bool isWaiting() const { return mWaiting; }
-
- virtual bool updateBuffer(); // Check to see if the buffer associated with the source changed, and update if necessary.
- virtual void update3DPosition() = 0;
- virtual void updateLoop() = 0; // Update your loop/completion status, for use by queueing/syncing.
+ virtual void play() = 0;
+ virtual void playSynced(LLAudioChannel *channelp) = 0;
+ virtual void cleanup() = 0;
+ virtual bool isPlaying() = 0;
+ void setWaiting(const bool waiting) { mWaiting = waiting; }
+ bool isWaiting() const { return mWaiting; }
+
+ virtual bool updateBuffer(); // Check to see if the buffer associated with the source changed, and update if necessary.
+ virtual void update3DPosition() = 0;
+ virtual void updateLoop() = 0; // Update your loop/completion status, for use by queueing/syncing.
protected:
- LLAudioSource *mCurrentSourcep;
- LLAudioBuffer *mCurrentBufferp;
- bool mLoopedThisFrame;
- bool mWaiting; // Waiting for sync.
- F32 mSecondaryGain;
+ LLAudioSource *mCurrentSourcep;
+ LLAudioBuffer *mCurrentBufferp;
+ bool mLoopedThisFrame;
+ bool mWaiting; // Waiting for sync.
+ F32 mSecondaryGain;
};
@@ -445,39 +445,39 @@ protected:
class LLAudioBuffer
{
public:
- virtual ~LLAudioBuffer() {};
- virtual bool loadWAV(const std::string& filename) = 0;
- virtual U32 getLength() = 0;
+ virtual ~LLAudioBuffer() {};
+ virtual bool loadWAV(const std::string& filename) = 0;
+ virtual U32 getLength() = 0;
- friend class LLAudioEngine;
- friend class LLAudioChannel;
- friend class LLAudioData;
+ friend class LLAudioEngine;
+ friend class LLAudioChannel;
+ friend class LLAudioData;
protected:
- bool mInUse;
- LLAudioData *mAudioDatap;
- LLFrameTimer mLastUseTimer;
+ bool mInUse;
+ LLAudioData *mAudioDatap;
+ LLFrameTimer mLastUseTimer;
};
struct SoundData
{
- LLUUID audio_uuid;
- LLUUID owner_id;
- F32 gain;
- S32 type;
- LLVector3d pos_global;
-
- SoundData(const LLUUID &audio_uuid,
- const LLUUID& owner_id,
- const F32 gain,
- const S32 type = LLAudioEngine::AUDIO_TYPE_NONE,
- const LLVector3d &pos_global = LLVector3d::zero) :
- audio_uuid(audio_uuid),
- owner_id(owner_id),
- gain(gain),
- type(type),
- pos_global(pos_global)
- {
- }
+ LLUUID audio_uuid;
+ LLUUID owner_id;
+ F32 gain;
+ S32 type;
+ LLVector3d pos_global;
+
+ SoundData(const LLUUID &audio_uuid,
+ const LLUUID& owner_id,
+ const F32 gain,
+ const S32 type = LLAudioEngine::AUDIO_TYPE_NONE,
+ const LLVector3d &pos_global = LLVector3d::zero) :
+ audio_uuid(audio_uuid),
+ owner_id(owner_id),
+ gain(gain),
+ type(type),
+ pos_global(pos_global)
+ {
+ }
};
diff --git a/indra/llaudio/llaudioengine_fmodstudio.cpp b/indra/llaudio/llaudioengine_fmodstudio.cpp
index c6313ea289..f9e2855b82 100644
--- a/indra/llaudio/llaudioengine_fmodstudio.cpp
+++ b/indra/llaudio/llaudioengine_fmodstudio.cpp
@@ -1,26 +1,26 @@
-/**
+/**
* @file audioengine_fmodstudio.cpp
- * @brief Implementation of LLAudioEngine class abstracting the audio
+ * @brief Implementation of LLAudioEngine class abstracting the audio
* support as a FMODSTUDIO implementation
*
* $LicenseInfo:firstyear=2020&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2020, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -308,7 +308,7 @@ bool LLAudioEngine_FMODSTUDIO::initWind()
if (!mWindDSP)
{
- memset(mWindDSPDesc, 0, sizeof(*mWindDSPDesc)); //Set everything to zero
+ memset(mWindDSPDesc, 0, sizeof(*mWindDSPDesc)); //Set everything to zero
strncpy(mWindDSPDesc->name, "Wind Unit", sizeof(mWindDSPDesc->name));
mWindDSPDesc->pluginsdkversion = FMOD_PLUGIN_SDK_VERSION;
mWindDSPDesc->read = &windCallback; // Assign callback - may be called from arbitrary threads
@@ -681,7 +681,7 @@ bool LLAudioBufferFMODSTUDIO::loadWAV(const std::string& filename)
FMOD_CREATESOUNDEXINFO exinfo;
memset(&exinfo, 0, sizeof(exinfo));
exinfo.cbsize = sizeof(exinfo);
- exinfo.suggestedsoundtype = FMOD_SOUND_TYPE_WAV; //Hint to speed up loading.
+ exinfo.suggestedsoundtype = FMOD_SOUND_TYPE_WAV; //Hint to speed up loading.
// Load up the wav file into an fmod sample (since 1.05 fmod studio expects everything in UTF-8)
FMOD_RESULT result = getSystem()->createSound(filename.c_str(), base_mode, &exinfo, &mSoundp);
diff --git a/indra/llaudio/llaudioengine_fmodstudio.h b/indra/llaudio/llaudioengine_fmodstudio.h
index 29e7bc6bf0..eb346e0466 100644
--- a/indra/llaudio/llaudioengine_fmodstudio.h
+++ b/indra/llaudio/llaudioengine_fmodstudio.h
@@ -1,26 +1,26 @@
-/**
+/**
* @file audioengine_fmodstudio.h
- * @brief Definition of LLAudioEngine class abstracting the audio
+ * @brief Definition of LLAudioEngine class abstracting the audio
* support as a FMODSTUDIO implementation
*
* $LicenseInfo:firstyear=2020&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2020, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -35,54 +35,54 @@
class LLAudioStreamManagerFMODSTUDIO;
namespace FMOD
{
- class System;
- class Channel;
- class ChannelGroup;
- class Sound;
- class DSP;
+ class System;
+ class Channel;
+ class ChannelGroup;
+ class Sound;
+ class DSP;
}
typedef struct FMOD_DSP_DESCRIPTION FMOD_DSP_DESCRIPTION;
//Interfaces
-class LLAudioEngine_FMODSTUDIO : public LLAudioEngine
+class LLAudioEngine_FMODSTUDIO : public LLAudioEngine
{
public:
- LLAudioEngine_FMODSTUDIO(bool enable_profiler);
- virtual ~LLAudioEngine_FMODSTUDIO();
+ LLAudioEngine_FMODSTUDIO(bool enable_profiler);
+ virtual ~LLAudioEngine_FMODSTUDIO();
- // initialization/startup/shutdown
- virtual bool init(void *user_data, const std::string &app_title);
- virtual std::string getDriverName(bool verbose);
- virtual LLStreamingAudioInterface* createDefaultStreamingAudioImpl() const;
- virtual void allocateListener();
+ // initialization/startup/shutdown
+ virtual bool init(void *user_data, const std::string &app_title);
+ virtual std::string getDriverName(bool verbose);
+ virtual LLStreamingAudioInterface* createDefaultStreamingAudioImpl() const;
+ virtual void allocateListener();
- virtual void shutdown();
+ virtual void shutdown();
- /*virtual*/ bool initWind();
- /*virtual*/ void cleanupWind();
+ /*virtual*/ bool initWind();
+ /*virtual*/ void cleanupWind();
- /*virtual*/void updateWind(LLVector3 direction, F32 camera_height_above_water);
+ /*virtual*/void updateWind(LLVector3 direction, F32 camera_height_above_water);
- typedef F32 MIXBUFFERFORMAT;
+ typedef F32 MIXBUFFERFORMAT;
- FMOD::System *getSystem() const {return mSystem;}
+ FMOD::System *getSystem() const {return mSystem;}
protected:
- /*virtual*/ LLAudioBuffer *createBuffer(); // Get a free buffer, or flush an existing one if you have to.
- /*virtual*/ LLAudioChannel *createChannel(); // Create a new audio channel.
+ /*virtual*/ LLAudioBuffer *createBuffer(); // Get a free buffer, or flush an existing one if you have to.
+ /*virtual*/ LLAudioChannel *createChannel(); // Create a new audio channel.
- /*virtual*/ void setInternalGain(F32 gain);
+ /*virtual*/ void setInternalGain(F32 gain);
- bool mInited;
+ bool mInited;
- LLWindGen<MIXBUFFERFORMAT> *mWindGen;
+ LLWindGen<MIXBUFFERFORMAT> *mWindGen;
- FMOD_DSP_DESCRIPTION *mWindDSPDesc;
- FMOD::DSP *mWindDSP;
- FMOD::System *mSystem;
- bool mEnableProfiler;
+ FMOD_DSP_DESCRIPTION *mWindDSPDesc;
+ FMOD::DSP *mWindDSP;
+ FMOD::System *mSystem;
+ bool mEnableProfiler;
public:
- static FMOD::ChannelGroup *mChannelGroups[LLAudioEngine::AUDIO_TYPE_COUNT];
+ static FMOD::ChannelGroup *mChannelGroups[LLAudioEngine::AUDIO_TYPE_COUNT];
};
@@ -93,21 +93,21 @@ public:
virtual ~LLAudioChannelFMODSTUDIO();
protected:
- /*virtual*/ void play();
- /*virtual*/ void playSynced(LLAudioChannel *channelp);
- /*virtual*/ void cleanup();
- /*virtual*/ bool isPlaying();
+ /*virtual*/ void play();
+ /*virtual*/ void playSynced(LLAudioChannel *channelp);
+ /*virtual*/ void cleanup();
+ /*virtual*/ bool isPlaying();
- /*virtual*/ bool updateBuffer();
- /*virtual*/ void update3DPosition();
- /*virtual*/ void updateLoop();
+ /*virtual*/ bool updateBuffer();
+ /*virtual*/ void update3DPosition();
+ /*virtual*/ void updateLoop();
- void set3DMode(bool use3d);
+ void set3DMode(bool use3d);
protected:
- FMOD::System *getSystem() const {return mSystemp;}
- FMOD::System *mSystemp;
- FMOD::Channel *mChannelp;
- S32 mLastSamplePos;
+ FMOD::System *getSystem() const {return mSystemp;}
+ FMOD::System *mSystemp;
+ FMOD::Channel *mChannelp;
+ S32 mLastSamplePos;
};
@@ -117,14 +117,14 @@ public:
LLAudioBufferFMODSTUDIO(FMOD::System *audioengine);
virtual ~LLAudioBufferFMODSTUDIO();
- /*virtual*/ bool loadWAV(const std::string& filename);
- /*virtual*/ U32 getLength();
- friend class LLAudioChannelFMODSTUDIO;
+ /*virtual*/ bool loadWAV(const std::string& filename);
+ /*virtual*/ U32 getLength();
+ friend class LLAudioChannelFMODSTUDIO;
protected:
- FMOD::System *getSystem() const {return mSystemp;}
- FMOD::System *mSystemp;
- FMOD::Sound *getSound() const{ return mSoundp; }
- FMOD::Sound *mSoundp;
+ FMOD::System *getSystem() const {return mSystemp;}
+ FMOD::System *mSystemp;
+ FMOD::Sound *getSound() const{ return mSoundp; }
+ FMOD::Sound *mSoundp;
};
diff --git a/indra/llaudio/llaudioengine_openal.cpp b/indra/llaudio/llaudioengine_openal.cpp
index 0a79614424..1c4c67e6f6 100644
--- a/indra/llaudio/llaudioengine_openal.cpp
+++ b/indra/llaudio/llaudioengine_openal.cpp
@@ -6,21 +6,21 @@
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -35,14 +35,14 @@
const float LLAudioEngine_OpenAL::WIND_BUFFER_SIZE_SEC = 0.05f;
LLAudioEngine_OpenAL::LLAudioEngine_OpenAL()
- :
- mWindGen(NULL),
- mWindBuf(NULL),
- mWindBufFreq(0),
- mWindBufSamples(0),
- mWindBufBytes(0),
- mWindSource(AL_NONE),
- mNumEmptyWindALBuffers(MAX_NUM_WIND_BUFFERS)
+ :
+ mWindGen(NULL),
+ mWindBuf(NULL),
+ mWindBufFreq(0),
+ mWindBufSamples(0),
+ mWindBufBytes(0),
+ mWindSource(AL_NONE),
+ mNumEmptyWindALBuffers(MAX_NUM_WIND_BUFFERS)
{
}
@@ -54,187 +54,187 @@ LLAudioEngine_OpenAL::~LLAudioEngine_OpenAL()
// virtual
bool LLAudioEngine_OpenAL::init(void* userdata, const std::string &app_title)
{
- mWindGen = NULL;
- LLAudioEngine::init(userdata, app_title);
+ mWindGen = NULL;
+ LLAudioEngine::init(userdata, app_title);
- if(!alutInit(NULL, NULL))
- {
- LL_WARNS() << "LLAudioEngine_OpenAL::init() ALUT initialization failed: " << alutGetErrorString (alutGetError ()) << LL_ENDL;
- return false;
- }
+ if(!alutInit(NULL, NULL))
+ {
+ LL_WARNS() << "LLAudioEngine_OpenAL::init() ALUT initialization failed: " << alutGetErrorString (alutGetError ()) << LL_ENDL;
+ return false;
+ }
- LL_INFOS() << "LLAudioEngine_OpenAL::init() OpenAL successfully initialized" << LL_ENDL;
+ LL_INFOS() << "LLAudioEngine_OpenAL::init() OpenAL successfully initialized" << LL_ENDL;
- LL_INFOS() << "OpenAL version: "
- << ll_safe_string(alGetString(AL_VERSION)) << LL_ENDL;
- LL_INFOS() << "OpenAL vendor: "
- << ll_safe_string(alGetString(AL_VENDOR)) << LL_ENDL;
- LL_INFOS() << "OpenAL renderer: "
- << ll_safe_string(alGetString(AL_RENDERER)) << LL_ENDL;
+ LL_INFOS() << "OpenAL version: "
+ << ll_safe_string(alGetString(AL_VERSION)) << LL_ENDL;
+ LL_INFOS() << "OpenAL vendor: "
+ << ll_safe_string(alGetString(AL_VENDOR)) << LL_ENDL;
+ LL_INFOS() << "OpenAL renderer: "
+ << ll_safe_string(alGetString(AL_RENDERER)) << LL_ENDL;
- ALint major = alutGetMajorVersion ();
- ALint minor = alutGetMinorVersion ();
- LL_INFOS() << "ALUT version: " << major << "." << minor << LL_ENDL;
+ ALint major = alutGetMajorVersion ();
+ ALint minor = alutGetMinorVersion ();
+ LL_INFOS() << "ALUT version: " << major << "." << minor << LL_ENDL;
- ALCdevice *device = alcGetContextsDevice(alcGetCurrentContext());
+ ALCdevice *device = alcGetContextsDevice(alcGetCurrentContext());
- alcGetIntegerv(device, ALC_MAJOR_VERSION, 1, &major);
- alcGetIntegerv(device, ALC_MAJOR_VERSION, 1, &minor);
- LL_INFOS() << "ALC version: " << major << "." << minor << LL_ENDL;
+ alcGetIntegerv(device, ALC_MAJOR_VERSION, 1, &major);
+ alcGetIntegerv(device, ALC_MAJOR_VERSION, 1, &minor);
+ LL_INFOS() << "ALC version: " << major << "." << minor << LL_ENDL;
- LL_INFOS() << "ALC default device: "
- << ll_safe_string(alcGetString(device,
- ALC_DEFAULT_DEVICE_SPECIFIER))
- << LL_ENDL;
+ LL_INFOS() << "ALC default device: "
+ << ll_safe_string(alcGetString(device,
+ ALC_DEFAULT_DEVICE_SPECIFIER))
+ << LL_ENDL;
- return true;
+ return true;
}
// virtual
std::string LLAudioEngine_OpenAL::getDriverName(bool verbose)
{
- ALCdevice *device = alcGetContextsDevice(alcGetCurrentContext());
- std::ostringstream version;
-
- version <<
- "OpenAL";
-
- if (verbose)
- {
- version <<
- ", version " <<
- ll_safe_string(alGetString(AL_VERSION)) <<
- " / " <<
- ll_safe_string(alGetString(AL_VENDOR)) <<
- " / " <<
- ll_safe_string(alGetString(AL_RENDERER));
-
- if (device)
- version <<
- ": " <<
- ll_safe_string(alcGetString(device,
- ALC_DEFAULT_DEVICE_SPECIFIER));
- }
-
- return version.str();
+ ALCdevice *device = alcGetContextsDevice(alcGetCurrentContext());
+ std::ostringstream version;
+
+ version <<
+ "OpenAL";
+
+ if (verbose)
+ {
+ version <<
+ ", version " <<
+ ll_safe_string(alGetString(AL_VERSION)) <<
+ " / " <<
+ ll_safe_string(alGetString(AL_VENDOR)) <<
+ " / " <<
+ ll_safe_string(alGetString(AL_RENDERER));
+
+ if (device)
+ version <<
+ ": " <<
+ ll_safe_string(alcGetString(device,
+ ALC_DEFAULT_DEVICE_SPECIFIER));
+ }
+
+ return version.str();
}
// virtual
void LLAudioEngine_OpenAL::allocateListener()
{
- mListenerp = (LLListener *) new LLListener_OpenAL();
- if(!mListenerp)
- {
- LL_WARNS() << "LLAudioEngine_OpenAL::allocateListener() Listener creation failed" << LL_ENDL;
- }
+ mListenerp = (LLListener *) new LLListener_OpenAL();
+ if(!mListenerp)
+ {
+ LL_WARNS() << "LLAudioEngine_OpenAL::allocateListener() Listener creation failed" << LL_ENDL;
+ }
}
// virtual
void LLAudioEngine_OpenAL::shutdown()
{
- LL_INFOS() << "About to LLAudioEngine::shutdown()" << LL_ENDL;
- LLAudioEngine::shutdown();
+ LL_INFOS() << "About to LLAudioEngine::shutdown()" << LL_ENDL;
+ LLAudioEngine::shutdown();
- LL_INFOS() << "About to alutExit()" << LL_ENDL;
- if(!alutExit())
- {
- LL_WARNS() << "Nuts." << LL_ENDL;
- LL_WARNS() << "LLAudioEngine_OpenAL::shutdown() ALUT shutdown failed: " << alutGetErrorString (alutGetError ()) << LL_ENDL;
- }
+ LL_INFOS() << "About to alutExit()" << LL_ENDL;
+ if(!alutExit())
+ {
+ LL_WARNS() << "Nuts." << LL_ENDL;
+ LL_WARNS() << "LLAudioEngine_OpenAL::shutdown() ALUT shutdown failed: " << alutGetErrorString (alutGetError ()) << LL_ENDL;
+ }
- LL_INFOS() << "LLAudioEngine_OpenAL::shutdown() OpenAL successfully shut down" << LL_ENDL;
+ LL_INFOS() << "LLAudioEngine_OpenAL::shutdown() OpenAL successfully shut down" << LL_ENDL;
- delete mListenerp;
- mListenerp = NULL;
+ delete mListenerp;
+ mListenerp = NULL;
}
LLAudioBuffer *LLAudioEngine_OpenAL::createBuffer()
{
- return new LLAudioBufferOpenAL();
+ return new LLAudioBufferOpenAL();
}
LLAudioChannel *LLAudioEngine_OpenAL::createChannel()
{
- return new LLAudioChannelOpenAL();
+ return new LLAudioChannelOpenAL();
}
void LLAudioEngine_OpenAL::setInternalGain(F32 gain)
{
- //LL_INFOS() << "LLAudioEngine_OpenAL::setInternalGain() Gain: " << gain << LL_ENDL;
- alListenerf(AL_GAIN, gain);
+ //LL_INFOS() << "LLAudioEngine_OpenAL::setInternalGain() Gain: " << gain << LL_ENDL;
+ alListenerf(AL_GAIN, gain);
}
LLAudioChannelOpenAL::LLAudioChannelOpenAL()
- :
- mALSource(AL_NONE),
- mLastSamplePos(0)
+ :
+ mALSource(AL_NONE),
+ mLastSamplePos(0)
{
- alGenSources(1, &mALSource);
+ alGenSources(1, &mALSource);
}
LLAudioChannelOpenAL::~LLAudioChannelOpenAL()
{
- cleanup();
- alDeleteSources(1, &mALSource);
+ cleanup();
+ alDeleteSources(1, &mALSource);
}
void LLAudioChannelOpenAL::cleanup()
{
- alSourceStop(mALSource);
- mCurrentBufferp = NULL;
+ alSourceStop(mALSource);
+ mCurrentBufferp = NULL;
}
void LLAudioChannelOpenAL::play()
{
- if (mALSource == AL_NONE)
- {
- LL_WARNS() << "Playing without a mALSource, aborting" << LL_ENDL;
- return;
- }
-
- if(!isPlaying())
- {
- alSourcePlay(mALSource);
- getSource()->setPlayedOnce(true);
- }
+ if (mALSource == AL_NONE)
+ {
+ LL_WARNS() << "Playing without a mALSource, aborting" << LL_ENDL;
+ return;
+ }
+
+ if(!isPlaying())
+ {
+ alSourcePlay(mALSource);
+ getSource()->setPlayedOnce(true);
+ }
}
void LLAudioChannelOpenAL::playSynced(LLAudioChannel *channelp)
{
- if (channelp)
- {
- LLAudioChannelOpenAL *masterchannelp =
- (LLAudioChannelOpenAL*)channelp;
- if (mALSource != AL_NONE &&
- masterchannelp->mALSource != AL_NONE)
- {
- // we have channels allocated to master and slave
- ALfloat master_offset;
- alGetSourcef(masterchannelp->mALSource, AL_SEC_OFFSET,
- &master_offset);
-
- LL_INFOS() << "Syncing with master at " << master_offset
- << "sec" << LL_ENDL;
- // *TODO: detect when this fails, maybe use AL_SAMPLE_
- alSourcef(mALSource, AL_SEC_OFFSET, master_offset);
- }
- }
- play();
+ if (channelp)
+ {
+ LLAudioChannelOpenAL *masterchannelp =
+ (LLAudioChannelOpenAL*)channelp;
+ if (mALSource != AL_NONE &&
+ masterchannelp->mALSource != AL_NONE)
+ {
+ // we have channels allocated to master and slave
+ ALfloat master_offset;
+ alGetSourcef(masterchannelp->mALSource, AL_SEC_OFFSET,
+ &master_offset);
+
+ LL_INFOS() << "Syncing with master at " << master_offset
+ << "sec" << LL_ENDL;
+ // *TODO: detect when this fails, maybe use AL_SAMPLE_
+ alSourcef(mALSource, AL_SEC_OFFSET, master_offset);
+ }
+ }
+ play();
}
bool LLAudioChannelOpenAL::isPlaying()
{
- if (mALSource != AL_NONE)
- {
- ALint state;
- alGetSourcei(mALSource, AL_SOURCE_STATE, &state);
- if(state == AL_PLAYING)
- {
- return true;
- }
- }
-
- return false;
+ if (mALSource != AL_NONE)
+ {
+ ALint state;
+ alGetSourcei(mALSource, AL_SOURCE_STATE, &state);
+ if(state == AL_PLAYING)
+ {
+ return true;
+ }
+ }
+
+ return false;
}
bool LLAudioChannelOpenAL::updateBuffer()
@@ -246,306 +246,306 @@ bool LLAudioChannelOpenAL::updateBuffer()
return false;
}
- if (LLAudioChannel::updateBuffer())
- {
- // Base class update returned true, which means that we need to actually
- // set up the source for a different buffer.
- LLAudioBufferOpenAL *bufferp = (LLAudioBufferOpenAL *)mCurrentSourcep->getCurrentBuffer();
- ALuint buffer = bufferp->getBuffer();
- alSourcei(mALSource, AL_BUFFER, buffer);
- mLastSamplePos = 0;
- }
-
- if (mCurrentSourcep)
- {
- alSourcef(mALSource, AL_GAIN,
- mCurrentSourcep->getGain() * getSecondaryGain());
- alSourcei(mALSource, AL_LOOPING,
- mCurrentSourcep->isLoop() ? AL_TRUE : AL_FALSE);
- alSourcef(mALSource, AL_ROLLOFF_FACTOR,
- gAudiop->mListenerp->getRolloffFactor());
- }
-
- return true;
+ if (LLAudioChannel::updateBuffer())
+ {
+ // Base class update returned true, which means that we need to actually
+ // set up the source for a different buffer.
+ LLAudioBufferOpenAL *bufferp = (LLAudioBufferOpenAL *)mCurrentSourcep->getCurrentBuffer();
+ ALuint buffer = bufferp->getBuffer();
+ alSourcei(mALSource, AL_BUFFER, buffer);
+ mLastSamplePos = 0;
+ }
+
+ if (mCurrentSourcep)
+ {
+ alSourcef(mALSource, AL_GAIN,
+ mCurrentSourcep->getGain() * getSecondaryGain());
+ alSourcei(mALSource, AL_LOOPING,
+ mCurrentSourcep->isLoop() ? AL_TRUE : AL_FALSE);
+ alSourcef(mALSource, AL_ROLLOFF_FACTOR,
+ gAudiop->mListenerp->getRolloffFactor());
+ }
+
+ return true;
}
void LLAudioChannelOpenAL::updateLoop()
{
- if (mALSource == AL_NONE)
- {
- return;
- }
-
- // Hack: We keep track of whether we looped or not by seeing when the
- // sample position looks like it's going backwards. Not reliable; may
- // yield false negatives.
- //
- ALint cur_pos;
- alGetSourcei(mALSource, AL_SAMPLE_OFFSET, &cur_pos);
- if (cur_pos < mLastSamplePos)
- {
- mLoopedThisFrame = true;
- }
- mLastSamplePos = cur_pos;
+ if (mALSource == AL_NONE)
+ {
+ return;
+ }
+
+ // Hack: We keep track of whether we looped or not by seeing when the
+ // sample position looks like it's going backwards. Not reliable; may
+ // yield false negatives.
+ //
+ ALint cur_pos;
+ alGetSourcei(mALSource, AL_SAMPLE_OFFSET, &cur_pos);
+ if (cur_pos < mLastSamplePos)
+ {
+ mLoopedThisFrame = true;
+ }
+ mLastSamplePos = cur_pos;
}
void LLAudioChannelOpenAL::update3DPosition()
{
- if(!mCurrentSourcep)
- {
- return;
- }
- if (mCurrentSourcep->isForcedPriority())
- {
- alSource3f(mALSource, AL_POSITION, 0.0, 0.0, 0.0);
- alSource3f(mALSource, AL_VELOCITY, 0.0, 0.0, 0.0);
- alSourcei (mALSource, AL_SOURCE_RELATIVE, AL_TRUE);
- } else {
- LLVector3 float_pos;
- float_pos.setVec(mCurrentSourcep->getPositionGlobal());
- alSourcefv(mALSource, AL_POSITION, float_pos.mV);
- alSourcefv(mALSource, AL_VELOCITY, mCurrentSourcep->getVelocity().mV);
- alSourcei (mALSource, AL_SOURCE_RELATIVE, AL_FALSE);
- }
-
- alSourcef(mALSource, AL_GAIN, mCurrentSourcep->getGain() * getSecondaryGain());
+ if(!mCurrentSourcep)
+ {
+ return;
+ }
+ if (mCurrentSourcep->isForcedPriority())
+ {
+ alSource3f(mALSource, AL_POSITION, 0.0, 0.0, 0.0);
+ alSource3f(mALSource, AL_VELOCITY, 0.0, 0.0, 0.0);
+ alSourcei (mALSource, AL_SOURCE_RELATIVE, AL_TRUE);
+ } else {
+ LLVector3 float_pos;
+ float_pos.setVec(mCurrentSourcep->getPositionGlobal());
+ alSourcefv(mALSource, AL_POSITION, float_pos.mV);
+ alSourcefv(mALSource, AL_VELOCITY, mCurrentSourcep->getVelocity().mV);
+ alSourcei (mALSource, AL_SOURCE_RELATIVE, AL_FALSE);
+ }
+
+ alSourcef(mALSource, AL_GAIN, mCurrentSourcep->getGain() * getSecondaryGain());
}
LLAudioBufferOpenAL::LLAudioBufferOpenAL()
{
- mALBuffer = AL_NONE;
+ mALBuffer = AL_NONE;
}
LLAudioBufferOpenAL::~LLAudioBufferOpenAL()
{
- cleanup();
+ cleanup();
}
void LLAudioBufferOpenAL::cleanup()
{
- if(mALBuffer != AL_NONE)
- {
- alDeleteBuffers(1, &mALBuffer);
- mALBuffer = AL_NONE;
- }
+ if(mALBuffer != AL_NONE)
+ {
+ alDeleteBuffers(1, &mALBuffer);
+ mALBuffer = AL_NONE;
+ }
}
bool LLAudioBufferOpenAL::loadWAV(const std::string& filename)
{
- cleanup();
- mALBuffer = alutCreateBufferFromFile(filename.c_str());
- if(mALBuffer == AL_NONE)
- {
- ALenum error = alutGetError();
- if (gDirUtilp->fileExists(filename))
- {
- LL_WARNS() <<
- "LLAudioBufferOpenAL::loadWAV() Error loading "
- << filename
- << " " << alutGetErrorString(error) << LL_ENDL;
- }
- else
- {
- // It's common for the file to not actually exist.
- LL_DEBUGS() <<
- "LLAudioBufferOpenAL::loadWAV() Error loading "
- << filename
- << " " << alutGetErrorString(error) << LL_ENDL;
- }
- return false;
- }
-
- return true;
+ cleanup();
+ mALBuffer = alutCreateBufferFromFile(filename.c_str());
+ if(mALBuffer == AL_NONE)
+ {
+ ALenum error = alutGetError();
+ if (gDirUtilp->fileExists(filename))
+ {
+ LL_WARNS() <<
+ "LLAudioBufferOpenAL::loadWAV() Error loading "
+ << filename
+ << " " << alutGetErrorString(error) << LL_ENDL;
+ }
+ else
+ {
+ // It's common for the file to not actually exist.
+ LL_DEBUGS() <<
+ "LLAudioBufferOpenAL::loadWAV() Error loading "
+ << filename
+ << " " << alutGetErrorString(error) << LL_ENDL;
+ }
+ return false;
+ }
+
+ return true;
}
U32 LLAudioBufferOpenAL::getLength()
{
- if(mALBuffer == AL_NONE)
- {
- return 0;
- }
- ALint length;
- alGetBufferi(mALBuffer, AL_SIZE, &length);
- return length / 2; // convert size in bytes to size in (16-bit) samples
+ if(mALBuffer == AL_NONE)
+ {
+ return 0;
+ }
+ ALint length;
+ alGetBufferi(mALBuffer, AL_SIZE, &length);
+ return length / 2; // convert size in bytes to size in (16-bit) samples
}
// ------------
bool LLAudioEngine_OpenAL::initWind()
{
- ALenum error;
- LL_INFOS() << "LLAudioEngine_OpenAL::initWind() start" << LL_ENDL;
+ ALenum error;
+ LL_INFOS() << "LLAudioEngine_OpenAL::initWind() start" << LL_ENDL;
+
+ mNumEmptyWindALBuffers = MAX_NUM_WIND_BUFFERS;
+
+ alGetError(); /* clear error */
- mNumEmptyWindALBuffers = MAX_NUM_WIND_BUFFERS;
+ alGenSources(1,&mWindSource);
- alGetError(); /* clear error */
-
- alGenSources(1,&mWindSource);
-
- if((error=alGetError()) != AL_NO_ERROR)
- {
- LL_WARNS() << "LLAudioEngine_OpenAL::initWind() Error creating wind sources: "<<error<<LL_ENDL;
- }
+ if((error=alGetError()) != AL_NO_ERROR)
+ {
+ LL_WARNS() << "LLAudioEngine_OpenAL::initWind() Error creating wind sources: "<<error<<LL_ENDL;
+ }
- mWindGen = new LLWindGen<WIND_SAMPLE_T>;
+ mWindGen = new LLWindGen<WIND_SAMPLE_T>;
- mWindBufFreq = mWindGen->getInputSamplingRate();
- mWindBufSamples = llceil(mWindBufFreq * WIND_BUFFER_SIZE_SEC);
- mWindBufBytes = mWindBufSamples * 2 /*stereo*/ * sizeof(WIND_SAMPLE_T);
+ mWindBufFreq = mWindGen->getInputSamplingRate();
+ mWindBufSamples = llceil(mWindBufFreq * WIND_BUFFER_SIZE_SEC);
+ mWindBufBytes = mWindBufSamples * 2 /*stereo*/ * sizeof(WIND_SAMPLE_T);
- mWindBuf = new WIND_SAMPLE_T [mWindBufSamples * 2 /*stereo*/];
+ mWindBuf = new WIND_SAMPLE_T [mWindBufSamples * 2 /*stereo*/];
- if(mWindBuf==NULL)
- {
- LL_ERRS() << "LLAudioEngine_OpenAL::initWind() Error creating wind memory buffer" << LL_ENDL;
- return false;
- }
+ if(mWindBuf==NULL)
+ {
+ LL_ERRS() << "LLAudioEngine_OpenAL::initWind() Error creating wind memory buffer" << LL_ENDL;
+ return false;
+ }
- LL_INFOS() << "LLAudioEngine_OpenAL::initWind() done" << LL_ENDL;
+ LL_INFOS() << "LLAudioEngine_OpenAL::initWind() done" << LL_ENDL;
- return true;
+ return true;
}
void LLAudioEngine_OpenAL::cleanupWind()
{
- LL_INFOS() << "LLAudioEngine_OpenAL::cleanupWind()" << LL_ENDL;
-
- if (mWindSource != AL_NONE)
- {
- // detach and delete all outstanding buffers on the wind source
- alSourceStop(mWindSource);
- ALint processed;
- alGetSourcei(mWindSource, AL_BUFFERS_PROCESSED, &processed);
- while (processed--)
- {
- ALuint buffer = AL_NONE;
- alSourceUnqueueBuffers(mWindSource, 1, &buffer);
- alDeleteBuffers(1, &buffer);
- }
-
- // delete the wind source itself
- alDeleteSources(1, &mWindSource);
-
- mWindSource = AL_NONE;
- }
-
- delete[] mWindBuf;
- mWindBuf = NULL;
-
- delete mWindGen;
- mWindGen = NULL;
+ LL_INFOS() << "LLAudioEngine_OpenAL::cleanupWind()" << LL_ENDL;
+
+ if (mWindSource != AL_NONE)
+ {
+ // detach and delete all outstanding buffers on the wind source
+ alSourceStop(mWindSource);
+ ALint processed;
+ alGetSourcei(mWindSource, AL_BUFFERS_PROCESSED, &processed);
+ while (processed--)
+ {
+ ALuint buffer = AL_NONE;
+ alSourceUnqueueBuffers(mWindSource, 1, &buffer);
+ alDeleteBuffers(1, &buffer);
+ }
+
+ // delete the wind source itself
+ alDeleteSources(1, &mWindSource);
+
+ mWindSource = AL_NONE;
+ }
+
+ delete[] mWindBuf;
+ mWindBuf = NULL;
+
+ delete mWindGen;
+ mWindGen = NULL;
}
void LLAudioEngine_OpenAL::updateWind(LLVector3 wind_vec, F32 camera_altitude)
{
- LLVector3 wind_pos;
- F64 pitch;
- F64 center_freq;
- ALenum error;
-
- if (!mEnableWind)
- return;
-
- if(!mWindBuf)
- return;
-
- if (mWindUpdateTimer.checkExpirationAndReset(LL_WIND_UPDATE_INTERVAL))
- {
-
- // wind comes in as Linden coordinate (+X = forward, +Y = left, +Z = up)
- // need to convert this to the conventional orientation DS3D and OpenAL use
- // where +X = right, +Y = up, +Z = backwards
-
- wind_vec.setVec(-wind_vec.mV[1], wind_vec.mV[2], -wind_vec.mV[0]);
-
- pitch = 1.0 + mapWindVecToPitch(wind_vec);
- center_freq = 80.0 * pow(pitch,2.5*(mapWindVecToGain(wind_vec)+1.0));
-
- mWindGen->mTargetFreq = (F32)center_freq;
- mWindGen->mTargetGain = (F32)mapWindVecToGain(wind_vec) * mMaxWindGain;
- mWindGen->mTargetPanGainR = (F32)mapWindVecToPan(wind_vec);
-
- alSourcei(mWindSource, AL_LOOPING, AL_FALSE);
- alSource3f(mWindSource, AL_POSITION, 0.0, 0.0, 0.0);
- alSource3f(mWindSource, AL_VELOCITY, 0.0, 0.0, 0.0);
- alSourcef(mWindSource, AL_ROLLOFF_FACTOR, 0.0);
- alSourcei(mWindSource, AL_SOURCE_RELATIVE, AL_TRUE);
- }
-
- // ok lets make a wind buffer now
-
- ALint processed, queued, unprocessed;
- alGetSourcei(mWindSource, AL_BUFFERS_PROCESSED, &processed);
- alGetSourcei(mWindSource, AL_BUFFERS_QUEUED, &queued);
- unprocessed = queued - processed;
-
- // ensure that there are always at least 3x as many filled buffers
- // queued as we managed to empty since last time.
- mNumEmptyWindALBuffers = llmin(mNumEmptyWindALBuffers + processed * 3 - unprocessed, MAX_NUM_WIND_BUFFERS-unprocessed);
- mNumEmptyWindALBuffers = llmax(mNumEmptyWindALBuffers, 0);
-
- //LL_INFOS() << "mNumEmptyWindALBuffers: " << mNumEmptyWindALBuffers <<" (" << unprocessed << ":" << processed << ")" << LL_ENDL;
-
- while(processed--) // unqueue old buffers
- {
- ALuint buffer;
- ALenum error;
- alGetError(); /* clear error */
- alSourceUnqueueBuffers(mWindSource, 1, &buffer);
- error = alGetError();
- if(error != AL_NO_ERROR)
- {
- LL_WARNS() << "LLAudioEngine_OpenAL::updateWind() error swapping (unqueuing) buffers" << LL_ENDL;
- }
- else
- {
- alDeleteBuffers(1, &buffer);
- }
- }
-
- unprocessed += mNumEmptyWindALBuffers;
- while (mNumEmptyWindALBuffers > 0) // fill+queue new buffers
- {
- ALuint buffer;
- alGetError(); /* clear error */
- alGenBuffers(1,&buffer);
- if((error=alGetError()) != AL_NO_ERROR)
- {
- LL_WARNS() << "LLAudioEngine_OpenAL::updateWind() Error creating wind buffer: " << error << LL_ENDL;
- break;
- }
-
- alBufferData(buffer,
- AL_FORMAT_STEREO16,
- mWindGen->windGenerate(mWindBuf,
- mWindBufSamples),
- mWindBufBytes,
- mWindBufFreq);
- error = alGetError();
- if(error != AL_NO_ERROR)
- {
- LL_WARNS() << "LLAudioEngine_OpenAL::updateWind() error swapping (bufferdata) buffers" << LL_ENDL;
- }
-
- alSourceQueueBuffers(mWindSource, 1, &buffer);
- error = alGetError();
- if(error != AL_NO_ERROR)
- {
- LL_WARNS() << "LLAudioEngine_OpenAL::updateWind() error swapping (queuing) buffers" << LL_ENDL;
- }
-
- --mNumEmptyWindALBuffers;
- }
-
- ALint playing;
- alGetSourcei(mWindSource, AL_SOURCE_STATE, &playing);
- if(playing != AL_PLAYING)
- {
- alSourcePlay(mWindSource);
-
- LL_DEBUGS() << "Wind had stopped - probably ran out of buffers - restarting: " << (unprocessed+mNumEmptyWindALBuffers) << " now queued." << LL_ENDL;
- }
+ LLVector3 wind_pos;
+ F64 pitch;
+ F64 center_freq;
+ ALenum error;
+
+ if (!mEnableWind)
+ return;
+
+ if(!mWindBuf)
+ return;
+
+ if (mWindUpdateTimer.checkExpirationAndReset(LL_WIND_UPDATE_INTERVAL))
+ {
+
+ // wind comes in as Linden coordinate (+X = forward, +Y = left, +Z = up)
+ // need to convert this to the conventional orientation DS3D and OpenAL use
+ // where +X = right, +Y = up, +Z = backwards
+
+ wind_vec.setVec(-wind_vec.mV[1], wind_vec.mV[2], -wind_vec.mV[0]);
+
+ pitch = 1.0 + mapWindVecToPitch(wind_vec);
+ center_freq = 80.0 * pow(pitch,2.5*(mapWindVecToGain(wind_vec)+1.0));
+
+ mWindGen->mTargetFreq = (F32)center_freq;
+ mWindGen->mTargetGain = (F32)mapWindVecToGain(wind_vec) * mMaxWindGain;
+ mWindGen->mTargetPanGainR = (F32)mapWindVecToPan(wind_vec);
+
+ alSourcei(mWindSource, AL_LOOPING, AL_FALSE);
+ alSource3f(mWindSource, AL_POSITION, 0.0, 0.0, 0.0);
+ alSource3f(mWindSource, AL_VELOCITY, 0.0, 0.0, 0.0);
+ alSourcef(mWindSource, AL_ROLLOFF_FACTOR, 0.0);
+ alSourcei(mWindSource, AL_SOURCE_RELATIVE, AL_TRUE);
+ }
+
+ // ok lets make a wind buffer now
+
+ ALint processed, queued, unprocessed;
+ alGetSourcei(mWindSource, AL_BUFFERS_PROCESSED, &processed);
+ alGetSourcei(mWindSource, AL_BUFFERS_QUEUED, &queued);
+ unprocessed = queued - processed;
+
+ // ensure that there are always at least 3x as many filled buffers
+ // queued as we managed to empty since last time.
+ mNumEmptyWindALBuffers = llmin(mNumEmptyWindALBuffers + processed * 3 - unprocessed, MAX_NUM_WIND_BUFFERS-unprocessed);
+ mNumEmptyWindALBuffers = llmax(mNumEmptyWindALBuffers, 0);
+
+ //LL_INFOS() << "mNumEmptyWindALBuffers: " << mNumEmptyWindALBuffers <<" (" << unprocessed << ":" << processed << ")" << LL_ENDL;
+
+ while(processed--) // unqueue old buffers
+ {
+ ALuint buffer;
+ ALenum error;
+ alGetError(); /* clear error */
+ alSourceUnqueueBuffers(mWindSource, 1, &buffer);
+ error = alGetError();
+ if(error != AL_NO_ERROR)
+ {
+ LL_WARNS() << "LLAudioEngine_OpenAL::updateWind() error swapping (unqueuing) buffers" << LL_ENDL;
+ }
+ else
+ {
+ alDeleteBuffers(1, &buffer);
+ }
+ }
+
+ unprocessed += mNumEmptyWindALBuffers;
+ while (mNumEmptyWindALBuffers > 0) // fill+queue new buffers
+ {
+ ALuint buffer;
+ alGetError(); /* clear error */
+ alGenBuffers(1,&buffer);
+ if((error=alGetError()) != AL_NO_ERROR)
+ {
+ LL_WARNS() << "LLAudioEngine_OpenAL::updateWind() Error creating wind buffer: " << error << LL_ENDL;
+ break;
+ }
+
+ alBufferData(buffer,
+ AL_FORMAT_STEREO16,
+ mWindGen->windGenerate(mWindBuf,
+ mWindBufSamples),
+ mWindBufBytes,
+ mWindBufFreq);
+ error = alGetError();
+ if(error != AL_NO_ERROR)
+ {
+ LL_WARNS() << "LLAudioEngine_OpenAL::updateWind() error swapping (bufferdata) buffers" << LL_ENDL;
+ }
+
+ alSourceQueueBuffers(mWindSource, 1, &buffer);
+ error = alGetError();
+ if(error != AL_NO_ERROR)
+ {
+ LL_WARNS() << "LLAudioEngine_OpenAL::updateWind() error swapping (queuing) buffers" << LL_ENDL;
+ }
+
+ --mNumEmptyWindALBuffers;
+ }
+
+ ALint playing;
+ alGetSourcei(mWindSource, AL_SOURCE_STATE, &playing);
+ if(playing != AL_PLAYING)
+ {
+ alSourcePlay(mWindSource);
+
+ LL_DEBUGS() << "Wind had stopped - probably ran out of buffers - restarting: " << (unprocessed+mNumEmptyWindALBuffers) << " now queued." << LL_ENDL;
+ }
}
diff --git a/indra/llaudio/llaudioengine_openal.h b/indra/llaudio/llaudioengine_openal.h
index 562c96c794..9aadc84ddf 100644
--- a/indra/llaudio/llaudioengine_openal.h
+++ b/indra/llaudio/llaudioengine_openal.h
@@ -7,21 +7,21 @@
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -36,73 +36,73 @@
class LLAudioEngine_OpenAL : public LLAudioEngine
{
- public:
- LLAudioEngine_OpenAL();
- virtual ~LLAudioEngine_OpenAL();
+ public:
+ LLAudioEngine_OpenAL();
+ virtual ~LLAudioEngine_OpenAL();
virtual bool init(void *user_data, const std::string &app_title);
virtual std::string getDriverName(bool verbose);
virtual LLStreamingAudioInterface* createDefaultStreamingAudioImpl() const { return nullptr; }
- virtual void allocateListener();
+ virtual void allocateListener();
- virtual void shutdown();
+ virtual void shutdown();
- void setInternalGain(F32 gain);
+ void setInternalGain(F32 gain);
- LLAudioBuffer* createBuffer();
- LLAudioChannel* createChannel();
+ LLAudioBuffer* createBuffer();
+ LLAudioChannel* createChannel();
- /*virtual*/ bool initWind();
- /*virtual*/ void cleanupWind();
- /*virtual*/ void updateWind(LLVector3 direction, F32 camera_altitude);
+ /*virtual*/ bool initWind();
+ /*virtual*/ void cleanupWind();
+ /*virtual*/ void updateWind(LLVector3 direction, F32 camera_altitude);
- private:
+ private:
typedef S16 WIND_SAMPLE_T;
- LLWindGen<WIND_SAMPLE_T> *mWindGen;
- S16 *mWindBuf;
- U32 mWindBufFreq;
- U32 mWindBufSamples;
- U32 mWindBufBytes;
- ALuint mWindSource;
+ LLWindGen<WIND_SAMPLE_T> *mWindGen;
+ S16 *mWindBuf;
+ U32 mWindBufFreq;
+ U32 mWindBufSamples;
+ U32 mWindBufBytes;
+ ALuint mWindSource;
int mNumEmptyWindALBuffers;
- static const int MAX_NUM_WIND_BUFFERS = 80;
- static const float WIND_BUFFER_SIZE_SEC; // 1/20th sec
+ static const int MAX_NUM_WIND_BUFFERS = 80;
+ static const float WIND_BUFFER_SIZE_SEC; // 1/20th sec
};
class LLAudioChannelOpenAL : public LLAudioChannel
{
- public:
- LLAudioChannelOpenAL();
- virtual ~LLAudioChannelOpenAL();
- protected:
- /*virtual*/ void play();
- /*virtual*/ void playSynced(LLAudioChannel *channelp);
- /*virtual*/ void cleanup();
- /*virtual*/ bool isPlaying();
-
- /*virtual*/ bool updateBuffer();
- /*virtual*/ void update3DPosition();
- /*virtual*/ void updateLoop();
-
- ALuint mALSource;
- ALint mLastSamplePos;
+ public:
+ LLAudioChannelOpenAL();
+ virtual ~LLAudioChannelOpenAL();
+ protected:
+ /*virtual*/ void play();
+ /*virtual*/ void playSynced(LLAudioChannel *channelp);
+ /*virtual*/ void cleanup();
+ /*virtual*/ bool isPlaying();
+
+ /*virtual*/ bool updateBuffer();
+ /*virtual*/ void update3DPosition();
+ /*virtual*/ void updateLoop();
+
+ ALuint mALSource;
+ ALint mLastSamplePos;
};
class LLAudioBufferOpenAL : public LLAudioBuffer{
- public:
- LLAudioBufferOpenAL();
- virtual ~LLAudioBufferOpenAL();
+ public:
+ LLAudioBufferOpenAL();
+ virtual ~LLAudioBufferOpenAL();
- bool loadWAV(const std::string& filename);
- U32 getLength();
+ bool loadWAV(const std::string& filename);
+ U32 getLength();
- friend class LLAudioChannelOpenAL;
- protected:
- void cleanup();
- ALuint getBuffer() {return mALBuffer;}
+ friend class LLAudioChannelOpenAL;
+ protected:
+ void cleanup();
+ ALuint getBuffer() {return mALBuffer;}
- ALuint mALBuffer;
+ ALuint mALBuffer;
};
#endif
diff --git a/indra/llaudio/lllistener.cpp b/indra/llaudio/lllistener.cpp
index df2366c8c2..663121d6bc 100644
--- a/indra/llaudio/lllistener.cpp
+++ b/indra/llaudio/lllistener.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file listener.cpp
* @brief Implementation of LISTENER class abstracting the audio support
*
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -36,7 +36,7 @@
//-----------------------------------------------------------------------
LLListener::LLListener()
{
- init();
+ init();
}
//-----------------------------------------------------------------------
@@ -47,64 +47,64 @@ LLListener::~LLListener()
//-----------------------------------------------------------------------
void LLListener::init(void)
{
- mPosition.zeroVec();
- mListenAt.setVec(DEFAULT_AT);
- mListenUp.setVec(DEFAULT_UP);
- mVelocity.zeroVec();
+ mPosition.zeroVec();
+ mListenAt.setVec(DEFAULT_AT);
+ mListenUp.setVec(DEFAULT_UP);
+ mVelocity.zeroVec();
}
//-----------------------------------------------------------------------
void LLListener::translate(LLVector3 offset)
{
- mPosition += offset;
+ mPosition += offset;
}
//-----------------------------------------------------------------------
void LLListener::setPosition(LLVector3 pos)
{
- mPosition = pos;
+ mPosition = pos;
}
//-----------------------------------------------------------------------
LLVector3 LLListener::getPosition(void)
{
- return(mPosition);
+ return(mPosition);
}
//-----------------------------------------------------------------------
LLVector3 LLListener::getAt(void)
{
- return(mListenAt);
+ return(mListenAt);
}
//-----------------------------------------------------------------------
LLVector3 LLListener::getUp(void)
{
- return(mListenUp);
+ return(mListenUp);
}
//-----------------------------------------------------------------------
void LLListener::setVelocity(LLVector3 vel)
{
- mVelocity = vel;
+ mVelocity = vel;
}
//-----------------------------------------------------------------------
void LLListener::orient(LLVector3 up, LLVector3 at)
{
- mListenUp = up;
- mListenAt = at;
+ mListenUp = up;
+ mListenAt = at;
}
//-----------------------------------------------------------------------
void LLListener::set(LLVector3 pos, LLVector3 vel, LLVector3 up, LLVector3 at)
{
- mPosition = pos;
- mVelocity = vel;
+ mPosition = pos;
+ mVelocity = vel;
- setPosition(pos);
- setVelocity(vel);
- orient(up,at);
+ setPosition(pos);
+ setVelocity(vel);
+ orient(up,at);
}
//-----------------------------------------------------------------------
@@ -115,7 +115,7 @@ void LLListener::setDopplerFactor(F32 factor)
//-----------------------------------------------------------------------
F32 LLListener::getDopplerFactor()
{
- return (1.f);
+ return (1.f);
}
//-----------------------------------------------------------------------
@@ -126,7 +126,7 @@ void LLListener::setRolloffFactor(F32 factor)
//-----------------------------------------------------------------------
F32 LLListener::getRolloffFactor()
{
- return (1.f);
+ return (1.f);
}
//-----------------------------------------------------------------------
diff --git a/indra/llaudio/lllistener.h b/indra/llaudio/lllistener.h
index 41836bf039..b1142cffb2 100644
--- a/indra/llaudio/lllistener.h
+++ b/indra/llaudio/lllistener.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file listener.h
* @brief Description of LISTENER base class abstracting the audio support.
*
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -29,43 +29,43 @@
#include "v3math.h"
-class LLListener
+class LLListener
{
private:
protected:
- LLVector3 mPosition;
- LLVector3 mVelocity;
- LLVector3 mListenAt;
- LLVector3 mListenUp;
+ LLVector3 mPosition;
+ LLVector3 mVelocity;
+ LLVector3 mListenAt;
+ LLVector3 mListenUp;
public:
private:
protected:
- public:
- LLListener();
- virtual ~LLListener();
- virtual void init();
+ public:
+ LLListener();
+ virtual ~LLListener();
+ virtual void init();
- virtual void set(LLVector3 pos, LLVector3 vel, LLVector3 up, LLVector3 at);
+ virtual void set(LLVector3 pos, LLVector3 vel, LLVector3 up, LLVector3 at);
- virtual void setPosition(LLVector3 pos);
- virtual void setVelocity(LLVector3 vel);
+ virtual void setPosition(LLVector3 pos);
+ virtual void setVelocity(LLVector3 vel);
- virtual void orient(LLVector3 up, LLVector3 at);
- virtual void translate(LLVector3 offset);
+ virtual void orient(LLVector3 up, LLVector3 at);
+ virtual void translate(LLVector3 offset);
- virtual void setDopplerFactor(F32 factor);
- virtual void setRolloffFactor(F32 factor);
+ virtual void setDopplerFactor(F32 factor);
+ virtual void setRolloffFactor(F32 factor);
- virtual LLVector3 getPosition();
- virtual LLVector3 getAt();
- virtual LLVector3 getUp();
+ virtual LLVector3 getPosition();
+ virtual LLVector3 getAt();
+ virtual LLVector3 getUp();
- virtual F32 getDopplerFactor();
- virtual F32 getRolloffFactor();
+ virtual F32 getDopplerFactor();
+ virtual F32 getRolloffFactor();
- virtual void commitDeferredChanges();
+ virtual void commitDeferredChanges();
};
#endif
diff --git a/indra/llaudio/lllistener_ds3d.h b/indra/llaudio/lllistener_ds3d.h
index 9150ccd5b9..22cd158507 100644
--- a/indra/llaudio/lllistener_ds3d.h
+++ b/indra/llaudio/lllistener_ds3d.h
@@ -1,4 +1,4 @@
-/**
+/**
* @file listener_ds3d.h
* @brief Description of LISTENER class abstracting the audio support
* as a DirectSound 3D implementation (windows only)
@@ -6,21 +6,21 @@
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -38,29 +38,29 @@ class LLListener_DS3D : public LLListener
{
private:
protected:
- IDirectSound3DListener8 *m3DListener;
+ IDirectSound3DListener8 *m3DListener;
public:
private:
protected:
- public:
- LLListener_DS3D();
- virtual ~LLListener_DS3D();
- virtual void init();
+ public:
+ LLListener_DS3D();
+ virtual ~LLListener_DS3D();
+ virtual void init();
- virtual void setDS3DLPtr (IDirectSound3DListener8 *listener_p);
+ virtual void setDS3DLPtr (IDirectSound3DListener8 *listener_p);
- virtual void translate(LLVector3 offset);
- virtual void setPosition(LLVector3 pos);
- virtual void setVelocity(LLVector3 vel);
- virtual void orient(LLVector3 up, LLVector3 at);
+ virtual void translate(LLVector3 offset);
+ virtual void setPosition(LLVector3 pos);
+ virtual void setVelocity(LLVector3 vel);
+ virtual void orient(LLVector3 up, LLVector3 at);
- virtual void setDopplerFactor(F32 factor);
- virtual F32 getDopplerFactor();
- virtual void setRolloffFactor(F32 factor);
- virtual F32 getRolloffFactor();
+ virtual void setDopplerFactor(F32 factor);
+ virtual F32 getDopplerFactor();
+ virtual void setRolloffFactor(F32 factor);
+ virtual F32 getRolloffFactor();
- virtual void commitDeferredChanges();
+ virtual void commitDeferredChanges();
};
#endif
diff --git a/indra/llaudio/lllistener_fmodstudio.cpp b/indra/llaudio/lllistener_fmodstudio.cpp
index abd5e345b5..9dc55eec79 100644
--- a/indra/llaudio/lllistener_fmodstudio.cpp
+++ b/indra/llaudio/lllistener_fmodstudio.cpp
@@ -1,4 +1,4 @@
-/**
+/**
* @file listener_fmodstudio.cpp
* @brief Implementation of LISTENER class abstracting the audio
* support as a FMODSTUDIO implementation
@@ -6,21 +6,21 @@
* $LicenseInfo:firstyear=2020&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2020, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
diff --git a/indra/llaudio/lllistener_fmodstudio.h b/indra/llaudio/lllistener_fmodstudio.h
index 6ad85d9700..5287cbedc6 100644
--- a/indra/llaudio/lllistener_fmodstudio.h
+++ b/indra/llaudio/lllistener_fmodstudio.h
@@ -1,4 +1,4 @@
-/**
+/**
* @file listener_fmodstudio.h
* @brief Description of LISTENER class abstracting the audio support
* as an FMOD 3D implementation
@@ -6,21 +6,21 @@
* $LicenseInfo:firstyear=2020&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2020, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -33,7 +33,7 @@
//Stubs
namespace FMOD
{
- class System;
+ class System;
}
//Interfaces
diff --git a/indra/llaudio/lllistener_openal.cpp b/indra/llaudio/lllistener_openal.cpp
index 9dd4c86854..2934dc1889 100644
--- a/indra/llaudio/lllistener_openal.cpp
+++ b/indra/llaudio/lllistener_openal.cpp
@@ -6,21 +6,21 @@
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -32,7 +32,7 @@
LLListener_OpenAL::LLListener_OpenAL()
{
- init();
+ init();
}
LLListener_OpenAL::~LLListener_OpenAL()
@@ -41,70 +41,70 @@ LLListener_OpenAL::~LLListener_OpenAL()
void LLListener_OpenAL::translate(LLVector3 offset)
{
- //LL_INFOS() << "LLListener_OpenAL::translate() : " << offset << LL_ENDL;
- LLListener::translate(offset);
+ //LL_INFOS() << "LLListener_OpenAL::translate() : " << offset << LL_ENDL;
+ LLListener::translate(offset);
}
void LLListener_OpenAL::setPosition(LLVector3 pos)
{
- //LL_INFOS() << "LLListener_OpenAL::setPosition() : " << pos << LL_ENDL;
- LLListener::setPosition(pos);
+ //LL_INFOS() << "LLListener_OpenAL::setPosition() : " << pos << LL_ENDL;
+ LLListener::setPosition(pos);
}
void LLListener_OpenAL::setVelocity(LLVector3 vel)
{
- LLListener::setVelocity(vel);
+ LLListener::setVelocity(vel);
}
void LLListener_OpenAL::orient(LLVector3 up, LLVector3 at)
{
- //LL_INFOS() << "LLListener_OpenAL::orient() up: " << up << " at: " << at << LL_ENDL;
- LLListener::orient(up, at);
+ //LL_INFOS() << "LLListener_OpenAL::orient() up: " << up << " at: " << at << LL_ENDL;
+ LLListener::orient(up, at);
}
void LLListener_OpenAL::commitDeferredChanges()
{
- ALfloat orientation[6];
- orientation[0] = mListenAt.mV[0];
- orientation[1] = mListenAt.mV[1];
- orientation[2] = mListenAt.mV[2];
- orientation[3] = mListenUp.mV[0];
- orientation[4] = mListenUp.mV[1];
- orientation[5] = mListenUp.mV[2];
-
- ALfloat velocity[3];
- velocity[0] = mVelocity.mV[0];
- velocity[1] = mVelocity.mV[1];
- velocity[2] = mVelocity.mV[2];
-
- alListenerfv(AL_ORIENTATION, orientation);
- alListenerfv(AL_POSITION, mPosition.mV);
- alListenerfv(AL_VELOCITY, velocity);
+ ALfloat orientation[6];
+ orientation[0] = mListenAt.mV[0];
+ orientation[1] = mListenAt.mV[1];
+ orientation[2] = mListenAt.mV[2];
+ orientation[3] = mListenUp.mV[0];
+ orientation[4] = mListenUp.mV[1];
+ orientation[5] = mListenUp.mV[2];
+
+ ALfloat velocity[3];
+ velocity[0] = mVelocity.mV[0];
+ velocity[1] = mVelocity.mV[1];
+ velocity[2] = mVelocity.mV[2];
+
+ alListenerfv(AL_ORIENTATION, orientation);
+ alListenerfv(AL_POSITION, mPosition.mV);
+ alListenerfv(AL_VELOCITY, velocity);
}
void LLListener_OpenAL::setDopplerFactor(F32 factor)
{
- //LL_INFOS() << "LLListener_OpenAL::setDopplerFactor() : " << factor << LL_ENDL;
- alDopplerFactor(factor);
+ //LL_INFOS() << "LLListener_OpenAL::setDopplerFactor() : " << factor << LL_ENDL;
+ alDopplerFactor(factor);
}
F32 LLListener_OpenAL::getDopplerFactor()
{
- ALfloat factor;
- factor = alGetFloat(AL_DOPPLER_FACTOR);
- //LL_INFOS() << "LLListener_OpenAL::getDopplerFactor() : " << factor << LL_ENDL;
- return factor;
+ ALfloat factor;
+ factor = alGetFloat(AL_DOPPLER_FACTOR);
+ //LL_INFOS() << "LLListener_OpenAL::getDopplerFactor() : " << factor << LL_ENDL;
+ return factor;
}
void LLListener_OpenAL::setRolloffFactor(F32 factor)
{
- mRolloffFactor = factor;
+ mRolloffFactor = factor;
}
F32 LLListener_OpenAL::getRolloffFactor()
{
- return mRolloffFactor;
+ return mRolloffFactor;
}
diff --git a/indra/llaudio/lllistener_openal.h b/indra/llaudio/lllistener_openal.h
index cb163b11a5..a877270201 100644
--- a/indra/llaudio/lllistener_openal.h
+++ b/indra/llaudio/lllistener_openal.h
@@ -1,4 +1,4 @@
-/**
+/**
* @file listener_openal.h
* @brief Description of LISTENER class abstracting the audio support
* as an OpenAL implementation
@@ -6,21 +6,21 @@
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -35,23 +35,23 @@
class LLListener_OpenAL : public LLListener
{
- public:
- LLListener_OpenAL();
- virtual ~LLListener_OpenAL();
+ public:
+ LLListener_OpenAL();
+ virtual ~LLListener_OpenAL();
- virtual void translate(LLVector3 offset);
- virtual void setPosition(LLVector3 pos);
- virtual void setVelocity(LLVector3 vel);
- virtual void orient(LLVector3 up, LLVector3 at);
- virtual void commitDeferredChanges();
+ virtual void translate(LLVector3 offset);
+ virtual void setPosition(LLVector3 pos);
+ virtual void setVelocity(LLVector3 vel);
+ virtual void orient(LLVector3 up, LLVector3 at);
+ virtual void commitDeferredChanges();
- virtual void setDopplerFactor(F32 factor);
- virtual F32 getDopplerFactor();
- virtual void setRolloffFactor(F32 factor);
- virtual F32 getRolloffFactor();
+ virtual void setDopplerFactor(F32 factor);
+ virtual F32 getDopplerFactor();
+ virtual void setRolloffFactor(F32 factor);
+ virtual F32 getRolloffFactor();
protected:
- F32 mRolloffFactor;
+ F32 mRolloffFactor;
};
#endif
diff --git a/indra/llaudio/llstreamingaudio.h b/indra/llaudio/llstreamingaudio.h
index 93479f9d59..3a024d8db8 100644
--- a/indra/llaudio/llstreamingaudio.h
+++ b/indra/llaudio/llstreamingaudio.h
@@ -1,4 +1,4 @@
-/**
+/**
* @file streamingaudio.h
* @author Tofu Linden
* @brief Definition of LLStreamingAudioInterface base class abstracting the streaming audio interface
@@ -6,21 +6,21 @@
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -34,19 +34,19 @@
class LLStreamingAudioInterface
{
public:
- virtual ~LLStreamingAudioInterface() {}
+ virtual ~LLStreamingAudioInterface() {}
- virtual void start(const std::string& url) = 0;
- virtual void stop() = 0;
- virtual void pause(int pause) = 0;
- virtual void update() = 0;
- virtual int isPlaying() = 0;
- // use a value from 0.0 to 1.0, inclusive
- virtual void setGain(F32 vol) = 0;
- virtual F32 getGain() = 0;
- virtual std::string getURL() = 0;
- virtual bool supportsAdjustableBufferSizes(){return false;}
- virtual void setBufferSizes(U32 streambuffertime, U32 decodebuffertime){};
+ virtual void start(const std::string& url) = 0;
+ virtual void stop() = 0;
+ virtual void pause(int pause) = 0;
+ virtual void update() = 0;
+ virtual int isPlaying() = 0;
+ // use a value from 0.0 to 1.0, inclusive
+ virtual void setGain(F32 vol) = 0;
+ virtual F32 getGain() = 0;
+ virtual std::string getURL() = 0;
+ virtual bool supportsAdjustableBufferSizes(){return false;}
+ virtual void setBufferSizes(U32 streambuffertime, U32 decodebuffertime){};
};
#endif // LL_STREAMINGAUDIO_H
diff --git a/indra/llaudio/llstreamingaudio_fmodstudio.cpp b/indra/llaudio/llstreamingaudio_fmodstudio.cpp
index 85577992a6..22fc86c0cd 100644
--- a/indra/llaudio/llstreamingaudio_fmodstudio.cpp
+++ b/indra/llaudio/llstreamingaudio_fmodstudio.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file streamingaudio_fmodstudio.cpp
* @brief LLStreamingAudio_FMODSTUDIO implementation
*
* $LicenseInfo:firstyear=2020&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2020, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -42,7 +42,7 @@ public:
bool stopStream(); // Returns true if the stream was successfully stopped.
bool ready();
- const std::string& getURL() { return mInternetStreamURL; }
+ const std::string& getURL() { return mInternetStreamURL; }
FMOD_OPENSTATE getOpenState(unsigned int* percentbuffered = NULL, bool* starving = NULL, bool* diskbusy = NULL);
protected:
@@ -68,17 +68,17 @@ mRetryCount(0)
{
// Number of milliseconds of audio to buffer for the audio card.
// Must be larger than the usual Second Life frame stutter time.
- const U32 buffer_seconds = 10; //sec
- const U32 estimated_bitrate = 128; //kbit/sec
+ const U32 buffer_seconds = 10; //sec
+ const U32 estimated_bitrate = 128; //kbit/sec
FMOD_RESULT result = mSystem->setStreamBufferSize(estimated_bitrate * buffer_seconds * 128/*bytes/kbit*/, FMOD_TIMEUNIT_RAWBYTES);
if (result != FMOD_OK)
{
LL_WARNS("FMOD") << "setStreamBufferSize error: " << FMOD_ErrorString(result) << LL_ENDL;
}
- // Here's where we set the size of the network buffer and some buffering
- // parameters. In this case we want a network buffer of 16k, we want it
- // to prebuffer 40% of that when we first connect, and we want it
+ // Here's where we set the size of the network buffer and some buffering
+ // parameters. In this case we want a network buffer of 16k, we want it
+ // to prebuffer 40% of that when we first connect, and we want it
// to rebuffer 80% of that whenever we encounter a buffer underrun.
// Leave the net buffer properties at the default.
@@ -151,8 +151,8 @@ void LLStreamingAudio_FMODSTUDIO::start(const std::string& url)
{
//if (!mInited)
//{
- // LL_WARNS() << "startInternetStream before audio initialized" << LL_ENDL;
- // return;
+ // LL_WARNS() << "startInternetStream before audio initialized" << LL_ENDL;
+ // return;
//}
// "stop" stream but don't clear url, etc. in case url == mInternetStreamURL
@@ -365,7 +365,7 @@ void LLStreamingAudio_FMODSTUDIO::setGain(F32 vol)
if (mFMODInternetStreamChannelp)
{
- vol = llclamp(vol * vol, 0.f, 1.f); //should vol be squared here?
+ vol = llclamp(vol * vol, 0.f, 1.f); //should vol be squared here?
mFMODInternetStreamChannelp->setVolume(vol);
}
@@ -406,7 +406,7 @@ FMOD::Channel *LLAudioStreamManagerFMODSTUDIO::startStream()
}
if (mStreamChannel)
- return mStreamChannel; //Already have a channel for this stream.
+ return mStreamChannel; //Already have a channel for this stream.
FMOD_RESULT result = mSystem->playSound(mInternetStream, NULL, true, &mStreamChannel);
if (result != FMOD_OK)
diff --git a/indra/llaudio/llstreamingaudio_fmodstudio.h b/indra/llaudio/llstreamingaudio_fmodstudio.h
index 35a7b1226e..2127841809 100644
--- a/indra/llaudio/llstreamingaudio_fmodstudio.h
+++ b/indra/llaudio/llstreamingaudio_fmodstudio.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file streamingaudio_fmodstudio.h
* @brief Definition of LLStreamingAudio_FMODSTUDIO implementation
*
* $LicenseInfo:firstyear=2020&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2020, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -36,8 +36,8 @@
class LLAudioStreamManagerFMODSTUDIO;
namespace FMOD
{
- class System;
- class Channel;
+ class System;
+ class Channel;
}
//Interfaces
diff --git a/indra/llaudio/llvorbisencode.cpp b/indra/llaudio/llvorbisencode.cpp
index 2e1ed9b505..573c947764 100644
--- a/indra/llaudio/llvorbisencode.cpp
+++ b/indra/llaudio/llvorbisencode.cpp
@@ -1,25 +1,25 @@
-/**
+/**
* @file vorbisencode.cpp
* @brief Vorbis encoding routine routine for Indra.
*
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -39,161 +39,161 @@
#if 0
#include "VorbisFramework.h"
-#define vorbis_analysis mac_vorbis_analysis
-#define vorbis_analysis_headerout mac_vorbis_analysis_headerout
-#define vorbis_analysis_init mac_vorbis_analysis_init
-#define vorbis_encode_ctl mac_vorbis_encode_ctl
-#define vorbis_encode_setup_init mac_vorbis_encode_setup_init
-#define vorbis_encode_setup_managed mac_vorbis_encode_setup_managed
-
-#define vorbis_info_init mac_vorbis_info_init
-#define vorbis_info_clear mac_vorbis_info_clear
-#define vorbis_comment_init mac_vorbis_comment_init
-#define vorbis_comment_clear mac_vorbis_comment_clear
-#define vorbis_block_init mac_vorbis_block_init
-#define vorbis_block_clear mac_vorbis_block_clear
-#define vorbis_dsp_clear mac_vorbis_dsp_clear
-#define vorbis_analysis_buffer mac_vorbis_analysis_buffer
-#define vorbis_analysis_wrote mac_vorbis_analysis_wrote
-#define vorbis_analysis_blockout mac_vorbis_analysis_blockout
-
-#define ogg_stream_packetin mac_ogg_stream_packetin
-#define ogg_stream_init mac_ogg_stream_init
-#define ogg_stream_flush mac_ogg_stream_flush
-#define ogg_stream_pageout mac_ogg_stream_pageout
-#define ogg_page_eos mac_ogg_page_eos
-#define ogg_stream_clear mac_ogg_stream_clear
+#define vorbis_analysis mac_vorbis_analysis
+#define vorbis_analysis_headerout mac_vorbis_analysis_headerout
+#define vorbis_analysis_init mac_vorbis_analysis_init
+#define vorbis_encode_ctl mac_vorbis_encode_ctl
+#define vorbis_encode_setup_init mac_vorbis_encode_setup_init
+#define vorbis_encode_setup_managed mac_vorbis_encode_setup_managed
+
+#define vorbis_info_init mac_vorbis_info_init
+#define vorbis_info_clear mac_vorbis_info_clear
+#define vorbis_comment_init mac_vorbis_comment_init
+#define vorbis_comment_clear mac_vorbis_comment_clear
+#define vorbis_block_init mac_vorbis_block_init
+#define vorbis_block_clear mac_vorbis_block_clear
+#define vorbis_dsp_clear mac_vorbis_dsp_clear
+#define vorbis_analysis_buffer mac_vorbis_analysis_buffer
+#define vorbis_analysis_wrote mac_vorbis_analysis_wrote
+#define vorbis_analysis_blockout mac_vorbis_analysis_blockout
+
+#define ogg_stream_packetin mac_ogg_stream_packetin
+#define ogg_stream_init mac_ogg_stream_init
+#define ogg_stream_flush mac_ogg_stream_flush
+#define ogg_stream_pageout mac_ogg_stream_pageout
+#define ogg_page_eos mac_ogg_page_eos
+#define ogg_stream_clear mac_ogg_stream_clear
#endif
S32 check_for_invalid_wav_formats(const std::string& in_fname, std::string& error_msg)
{
- U16 num_channels = 0;
- U32 sample_rate = 0;
- U32 bits_per_sample = 0;
- U32 physical_file_size = 0;
- U32 chunk_length = 0;
- U32 raw_data_length = 0;
- U32 bytes_per_sec = 0;
- BOOL uncompressed_pcm = FALSE;
+ U16 num_channels = 0;
+ U32 sample_rate = 0;
+ U32 bits_per_sample = 0;
+ U32 physical_file_size = 0;
+ U32 chunk_length = 0;
+ U32 raw_data_length = 0;
+ U32 bytes_per_sec = 0;
+ BOOL uncompressed_pcm = FALSE;
- unsigned char wav_header[44]; /*Flawfinder: ignore*/
+ unsigned char wav_header[44]; /*Flawfinder: ignore*/
- error_msg.clear();
+ error_msg.clear();
- //********************************
- LLAPRFile infile ;
+ //********************************
+ LLAPRFile infile ;
infile.open(in_fname,LL_APR_RB);
- //********************************
- if (!infile.getFileHandle())
- {
- error_msg = "CannotUploadSoundFile";
- return(LLVORBISENC_SOURCE_OPEN_ERR);
- }
-
- infile.read(wav_header, 44);
- physical_file_size = infile.seek(APR_END,0);
-
- if (strncmp((char *)&(wav_header[0]),"RIFF",4))
- {
- error_msg = "SoundFileNotRIFF";
- return(LLVORBISENC_WAV_FORMAT_ERR);
- }
-
- if (strncmp((char *)&(wav_header[8]),"WAVE",4))
- {
- error_msg = "SoundFileNotRIFF";
- return(LLVORBISENC_WAV_FORMAT_ERR);
- }
-
- // parse the chunks
-
- U32 file_pos = 12; // start at the first chunk (usually fmt but not always)
-
- while ((file_pos + 8)< physical_file_size)
- {
- infile.seek(APR_SET,file_pos);
- infile.read(wav_header, 44);
-
- chunk_length = ((U32) wav_header[7] << 24)
- + ((U32) wav_header[6] << 16)
- + ((U32) wav_header[5] << 8)
- + wav_header[4];
-
- if (chunk_length > physical_file_size - file_pos - 4)
- {
- infile.close();
- error_msg = "SoundFileInvalidChunkSize";
- return(LLVORBISENC_CHUNK_SIZE_ERR);
- }
-
-// LL_INFOS() << "chunk found: '" << wav_header[0] << wav_header[1] << wav_header[2] << wav_header[3] << "'" << LL_ENDL;
-
- if (!(strncmp((char *)&(wav_header[0]),"fmt ",4)))
- {
- if ((wav_header[8] == 0x01) && (wav_header[9] == 0x00))
- {
- uncompressed_pcm = TRUE;
- }
- num_channels = ((U16) wav_header[11] << 8) + wav_header[10];
- sample_rate = ((U32) wav_header[15] << 24)
- + ((U32) wav_header[14] << 16)
- + ((U32) wav_header[13] << 8)
- + wav_header[12];
- bits_per_sample = ((U16) wav_header[23] << 8) + wav_header[22];
- bytes_per_sec = ((U32) wav_header[19] << 24)
- + ((U32) wav_header[18] << 16)
- + ((U32) wav_header[17] << 8)
- + wav_header[16];
- }
- else if (!(strncmp((char *)&(wav_header[0]),"data",4)))
- {
- raw_data_length = chunk_length;
- }
- file_pos += (chunk_length + 8);
- chunk_length = 0;
- }
- //****************
- infile.close();
- //****************
-
- if (!uncompressed_pcm)
- {
- error_msg = "SoundFileNotPCM";
- return(LLVORBISENC_PCM_FORMAT_ERR);
- }
-
- if ((num_channels < 1) || (num_channels > LLVORBIS_CLIP_MAX_CHANNELS))
- {
- error_msg = "SoundFileInvalidChannelCount";
- return(LLVORBISENC_MULTICHANNEL_ERR);
- }
-
- if (sample_rate != LLVORBIS_CLIP_SAMPLE_RATE)
- {
- error_msg = "SoundFileInvalidSampleRate";
- return(LLVORBISENC_UNSUPPORTED_SAMPLE_RATE);
- }
-
- if ((bits_per_sample != 16) && (bits_per_sample != 8))
- {
- error_msg = "SoundFileInvalidWordSize";
- return(LLVORBISENC_UNSUPPORTED_WORD_SIZE);
- }
-
- if (!raw_data_length)
- {
- error_msg = "SoundFileInvalidHeader";
- return(LLVORBISENC_CLIP_TOO_LONG);
- }
-
- F32 clip_length = (F32)raw_data_length/(F32)bytes_per_sec;
-
- if (clip_length > LLVORBIS_CLIP_MAX_TIME)
- {
- error_msg = "SoundFileInvalidTooLong";
- return(LLVORBISENC_CLIP_TOO_LONG);
- }
+ //********************************
+ if (!infile.getFileHandle())
+ {
+ error_msg = "CannotUploadSoundFile";
+ return(LLVORBISENC_SOURCE_OPEN_ERR);
+ }
+
+ infile.read(wav_header, 44);
+ physical_file_size = infile.seek(APR_END,0);
+
+ if (strncmp((char *)&(wav_header[0]),"RIFF",4))
+ {
+ error_msg = "SoundFileNotRIFF";
+ return(LLVORBISENC_WAV_FORMAT_ERR);
+ }
+
+ if (strncmp((char *)&(wav_header[8]),"WAVE",4))
+ {
+ error_msg = "SoundFileNotRIFF";
+ return(LLVORBISENC_WAV_FORMAT_ERR);
+ }
+
+ // parse the chunks
+
+ U32 file_pos = 12; // start at the first chunk (usually fmt but not always)
+
+ while ((file_pos + 8)< physical_file_size)
+ {
+ infile.seek(APR_SET,file_pos);
+ infile.read(wav_header, 44);
+
+ chunk_length = ((U32) wav_header[7] << 24)
+ + ((U32) wav_header[6] << 16)
+ + ((U32) wav_header[5] << 8)
+ + wav_header[4];
+
+ if (chunk_length > physical_file_size - file_pos - 4)
+ {
+ infile.close();
+ error_msg = "SoundFileInvalidChunkSize";
+ return(LLVORBISENC_CHUNK_SIZE_ERR);
+ }
+
+// LL_INFOS() << "chunk found: '" << wav_header[0] << wav_header[1] << wav_header[2] << wav_header[3] << "'" << LL_ENDL;
+
+ if (!(strncmp((char *)&(wav_header[0]),"fmt ",4)))
+ {
+ if ((wav_header[8] == 0x01) && (wav_header[9] == 0x00))
+ {
+ uncompressed_pcm = TRUE;
+ }
+ num_channels = ((U16) wav_header[11] << 8) + wav_header[10];
+ sample_rate = ((U32) wav_header[15] << 24)
+ + ((U32) wav_header[14] << 16)
+ + ((U32) wav_header[13] << 8)
+ + wav_header[12];
+ bits_per_sample = ((U16) wav_header[23] << 8) + wav_header[22];
+ bytes_per_sec = ((U32) wav_header[19] << 24)
+ + ((U32) wav_header[18] << 16)
+ + ((U32) wav_header[17] << 8)
+ + wav_header[16];
+ }
+ else if (!(strncmp((char *)&(wav_header[0]),"data",4)))
+ {
+ raw_data_length = chunk_length;
+ }
+ file_pos += (chunk_length + 8);
+ chunk_length = 0;
+ }
+ //****************
+ infile.close();
+ //****************
+
+ if (!uncompressed_pcm)
+ {
+ error_msg = "SoundFileNotPCM";
+ return(LLVORBISENC_PCM_FORMAT_ERR);
+ }
+
+ if ((num_channels < 1) || (num_channels > LLVORBIS_CLIP_MAX_CHANNELS))
+ {
+ error_msg = "SoundFileInvalidChannelCount";
+ return(LLVORBISENC_MULTICHANNEL_ERR);
+ }
+
+ if (sample_rate != LLVORBIS_CLIP_SAMPLE_RATE)
+ {
+ error_msg = "SoundFileInvalidSampleRate";
+ return(LLVORBISENC_UNSUPPORTED_SAMPLE_RATE);
+ }
+
+ if ((bits_per_sample != 16) && (bits_per_sample != 8))
+ {
+ error_msg = "SoundFileInvalidWordSize";
+ return(LLVORBISENC_UNSUPPORTED_WORD_SIZE);
+ }
+
+ if (!raw_data_length)
+ {
+ error_msg = "SoundFileInvalidHeader";
+ return(LLVORBISENC_CLIP_TOO_LONG);
+ }
+
+ F32 clip_length = (F32)raw_data_length/(F32)bytes_per_sec;
+
+ if (clip_length > LLVORBIS_CLIP_MAX_TIME)
+ {
+ error_msg = "SoundFileInvalidTooLong";
+ return(LLVORBISENC_CLIP_TOO_LONG);
+ }
return(LLVORBISENC_NOERR);
}
@@ -201,306 +201,306 @@ S32 check_for_invalid_wav_formats(const std::string& in_fname, std::string& erro
S32 encode_vorbis_file(const std::string& in_fname, const std::string& out_fname)
{
#define READ_BUFFER 1024
- unsigned char readbuffer[READ_BUFFER*4+44]; /* out of the data segment, not the stack */ /*Flawfinder: ignore*/
-
- ogg_stream_state os; /* take physical pages, weld into a logical stream of packets */
- ogg_page og; /* one Ogg bitstream page. Vorbis packets are inside */
- ogg_packet op; /* one raw packet of data for decode */
-
- vorbis_info vi; /* struct that stores all the static vorbis bitstream settings */
- vorbis_comment vc; /* struct that stores all the user comments */
-
- vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */
- vorbis_block vb; /* local working space for packet->PCM decode */
-
- int eos=0;
- int result;
-
- U16 num_channels = 0;
- U32 sample_rate = 0;
- U32 bits_per_sample = 0;
-
- S32 format_error = 0;
- std::string error_msg;
- if ((format_error = check_for_invalid_wav_formats(in_fname, error_msg)))
- {
- LL_WARNS() << error_msg << ": " << in_fname << LL_ENDL;
- return(format_error);
- }
+ unsigned char readbuffer[READ_BUFFER*4+44]; /* out of the data segment, not the stack */ /*Flawfinder: ignore*/
+
+ ogg_stream_state os; /* take physical pages, weld into a logical stream of packets */
+ ogg_page og; /* one Ogg bitstream page. Vorbis packets are inside */
+ ogg_packet op; /* one raw packet of data for decode */
+
+ vorbis_info vi; /* struct that stores all the static vorbis bitstream settings */
+ vorbis_comment vc; /* struct that stores all the user comments */
+
+ vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */
+ vorbis_block vb; /* local working space for packet->PCM decode */
+
+ int eos=0;
+ int result;
+
+ U16 num_channels = 0;
+ U32 sample_rate = 0;
+ U32 bits_per_sample = 0;
+
+ S32 format_error = 0;
+ std::string error_msg;
+ if ((format_error = check_for_invalid_wav_formats(in_fname, error_msg)))
+ {
+ LL_WARNS() << error_msg << ": " << in_fname << LL_ENDL;
+ return(format_error);
+ }
#if 1
- unsigned char wav_header[44]; /*Flawfinder: ignore*/
-
- S32 data_left = 0;
-
- LLAPRFile infile ;
- infile.open(in_fname,LL_APR_RB);
- if (!infile.getFileHandle())
- {
- LL_WARNS() << "Couldn't open temporary ogg file for writing: " << in_fname
- << LL_ENDL;
- return(LLVORBISENC_SOURCE_OPEN_ERR);
- }
-
- LLAPRFile outfile ;
- outfile.open(out_fname,LL_APR_WPB);
- if (!outfile.getFileHandle())
- {
- LL_WARNS() << "Couldn't open upload sound file for reading: " << in_fname
- << LL_ENDL;
- return(LLVORBISENC_DEST_OPEN_ERR);
- }
-
- // parse the chunks
- U32 chunk_length = 0;
- U32 file_pos = 12; // start at the first chunk (usually fmt but not always)
-
- while (infile.eof() != APR_EOF)
- {
- infile.seek(APR_SET,file_pos);
- infile.read(wav_header, 44);
-
- chunk_length = ((U32) wav_header[7] << 24)
- + ((U32) wav_header[6] << 16)
- + ((U32) wav_header[5] << 8)
- + wav_header[4];
-
-// LL_INFOS() << "chunk found: '" << wav_header[0] << wav_header[1] << wav_header[2] << wav_header[3] << "'" << LL_ENDL;
-
- if (!(strncmp((char *)&(wav_header[0]),"fmt ",4)))
- {
- num_channels = ((U16) wav_header[11] << 8) + wav_header[10];
- sample_rate = ((U32) wav_header[15] << 24)
- + ((U32) wav_header[14] << 16)
- + ((U32) wav_header[13] << 8)
- + wav_header[12];
- bits_per_sample = ((U16) wav_header[23] << 8) + wav_header[22];
- }
- else if (!(strncmp((char *)&(wav_header[0]),"data",4)))
- {
- infile.seek(APR_SET,file_pos+8);
- // leave the file pointer at the beginning of the data chunk data
- data_left = chunk_length;
- break;
- }
- file_pos += (chunk_length + 8);
- chunk_length = 0;
- }
-
-
- /********** Encode setup ************/
-
- /* choose an encoding mode */
- /* (mode 0: 44kHz stereo uncoupled, roughly 128kbps VBR) */
- vorbis_info_init(&vi);
-
- // always encode to mono
-
- // SL-52913 & SL-53779 determined this quality level to be our 'good
- // enough' general-purpose quality level with a nice low bitrate.
- // Equivalent to oggenc -q0.5
- F32 quality = 0.05f;
-// quality = (bitrate==128000 ? 0.4f : 0.1);
-
-// if (vorbis_encode_init(&vi, /* num_channels */ 1 ,sample_rate, -1, bitrate, -1))
- if (vorbis_encode_init_vbr(&vi, /* num_channels */ 1 ,sample_rate, quality))
-// if (vorbis_encode_setup_managed(&vi,1,sample_rate,-1,bitrate,-1) ||
-// vorbis_encode_ctl(&vi,OV_ECTL_RATEMANAGE_AVG,NULL) ||
-// vorbis_encode_setup_init(&vi))
- {
- LL_WARNS() << "unable to initialize vorbis codec at quality " << quality << LL_ENDL;
- // LL_WARNS() << "unable to initialize vorbis codec at bitrate " << bitrate << LL_ENDL;
- return(LLVORBISENC_DEST_OPEN_ERR);
- }
-
- /* add a comment */
- vorbis_comment_init(&vc);
-// vorbis_comment_add(&vc,"Linden");
-
- /* set up the analysis state and auxiliary encoding storage */
- vorbis_analysis_init(&vd,&vi);
- vorbis_block_init(&vd,&vb);
-
- /* set up our packet->stream encoder */
- /* pick a random serial number; that way we can more likely build
- chained streams just by concatenation */
- ogg_stream_init(&os, ll_rand());
-
- /* Vorbis streams begin with three headers; the initial header (with
- most of the codec setup parameters) which is mandated by the Ogg
- bitstream spec. The second header holds any comment fields. The
- third header holds the bitstream codebook. We merely need to
- make the headers, then pass them to libvorbis one at a time;
- libvorbis handles the additional Ogg bitstream constraints */
-
- {
- ogg_packet header;
- ogg_packet header_comm;
- ogg_packet header_code;
-
- vorbis_analysis_headerout(&vd,&vc,&header,&header_comm,&header_code);
- ogg_stream_packetin(&os,&header); /* automatically placed in its own
- page */
- ogg_stream_packetin(&os,&header_comm);
- ogg_stream_packetin(&os,&header_code);
-
- /* We don't have to write out here, but doing so makes streaming
- * much easier, so we do, flushing ALL pages. This ensures the actual
- * audio data will start on a new page
- */
- while(!eos){
- int result=ogg_stream_flush(&os,&og);
- if(result==0)break;
- outfile.write(og.header, og.header_len);
- outfile.write(og.body, og.body_len);
- }
-
- }
-
-
- while(!eos)
- {
- long bytes_per_sample = bits_per_sample/8;
-
- long bytes=(long)infile.read(readbuffer,llclamp((S32)(READ_BUFFER*num_channels*bytes_per_sample),0,data_left)); /* stereo hardwired here */
-
- if (bytes==0)
- {
- /* end of file. this can be done implicitly in the mainline,
- but it's easier to see here in non-clever fashion.
- Tell the library we're at end of stream so that it can handle
- the last frame and mark end of stream in the output properly */
-
- vorbis_analysis_wrote(&vd,0);
-// eos = 1;
-
- }
- else
- {
- long i;
- long samples;
- int temp;
-
- data_left -= bytes;
+ unsigned char wav_header[44]; /*Flawfinder: ignore*/
+
+ S32 data_left = 0;
+
+ LLAPRFile infile ;
+ infile.open(in_fname,LL_APR_RB);
+ if (!infile.getFileHandle())
+ {
+ LL_WARNS() << "Couldn't open temporary ogg file for writing: " << in_fname
+ << LL_ENDL;
+ return(LLVORBISENC_SOURCE_OPEN_ERR);
+ }
+
+ LLAPRFile outfile ;
+ outfile.open(out_fname,LL_APR_WPB);
+ if (!outfile.getFileHandle())
+ {
+ LL_WARNS() << "Couldn't open upload sound file for reading: " << in_fname
+ << LL_ENDL;
+ return(LLVORBISENC_DEST_OPEN_ERR);
+ }
+
+ // parse the chunks
+ U32 chunk_length = 0;
+ U32 file_pos = 12; // start at the first chunk (usually fmt but not always)
+
+ while (infile.eof() != APR_EOF)
+ {
+ infile.seek(APR_SET,file_pos);
+ infile.read(wav_header, 44);
+
+ chunk_length = ((U32) wav_header[7] << 24)
+ + ((U32) wav_header[6] << 16)
+ + ((U32) wav_header[5] << 8)
+ + wav_header[4];
+
+// LL_INFOS() << "chunk found: '" << wav_header[0] << wav_header[1] << wav_header[2] << wav_header[3] << "'" << LL_ENDL;
+
+ if (!(strncmp((char *)&(wav_header[0]),"fmt ",4)))
+ {
+ num_channels = ((U16) wav_header[11] << 8) + wav_header[10];
+ sample_rate = ((U32) wav_header[15] << 24)
+ + ((U32) wav_header[14] << 16)
+ + ((U32) wav_header[13] << 8)
+ + wav_header[12];
+ bits_per_sample = ((U16) wav_header[23] << 8) + wav_header[22];
+ }
+ else if (!(strncmp((char *)&(wav_header[0]),"data",4)))
+ {
+ infile.seek(APR_SET,file_pos+8);
+ // leave the file pointer at the beginning of the data chunk data
+ data_left = chunk_length;
+ break;
+ }
+ file_pos += (chunk_length + 8);
+ chunk_length = 0;
+ }
+
+
+ /********** Encode setup ************/
+
+ /* choose an encoding mode */
+ /* (mode 0: 44kHz stereo uncoupled, roughly 128kbps VBR) */
+ vorbis_info_init(&vi);
+
+ // always encode to mono
+
+ // SL-52913 & SL-53779 determined this quality level to be our 'good
+ // enough' general-purpose quality level with a nice low bitrate.
+ // Equivalent to oggenc -q0.5
+ F32 quality = 0.05f;
+// quality = (bitrate==128000 ? 0.4f : 0.1);
+
+// if (vorbis_encode_init(&vi, /* num_channels */ 1 ,sample_rate, -1, bitrate, -1))
+ if (vorbis_encode_init_vbr(&vi, /* num_channels */ 1 ,sample_rate, quality))
+// if (vorbis_encode_setup_managed(&vi,1,sample_rate,-1,bitrate,-1) ||
+// vorbis_encode_ctl(&vi,OV_ECTL_RATEMANAGE_AVG,NULL) ||
+// vorbis_encode_setup_init(&vi))
+ {
+ LL_WARNS() << "unable to initialize vorbis codec at quality " << quality << LL_ENDL;
+ // LL_WARNS() << "unable to initialize vorbis codec at bitrate " << bitrate << LL_ENDL;
+ return(LLVORBISENC_DEST_OPEN_ERR);
+ }
+
+ /* add a comment */
+ vorbis_comment_init(&vc);
+// vorbis_comment_add(&vc,"Linden");
+
+ /* set up the analysis state and auxiliary encoding storage */
+ vorbis_analysis_init(&vd,&vi);
+ vorbis_block_init(&vd,&vb);
+
+ /* set up our packet->stream encoder */
+ /* pick a random serial number; that way we can more likely build
+ chained streams just by concatenation */
+ ogg_stream_init(&os, ll_rand());
+
+ /* Vorbis streams begin with three headers; the initial header (with
+ most of the codec setup parameters) which is mandated by the Ogg
+ bitstream spec. The second header holds any comment fields. The
+ third header holds the bitstream codebook. We merely need to
+ make the headers, then pass them to libvorbis one at a time;
+ libvorbis handles the additional Ogg bitstream constraints */
+
+ {
+ ogg_packet header;
+ ogg_packet header_comm;
+ ogg_packet header_code;
+
+ vorbis_analysis_headerout(&vd,&vc,&header,&header_comm,&header_code);
+ ogg_stream_packetin(&os,&header); /* automatically placed in its own
+ page */
+ ogg_stream_packetin(&os,&header_comm);
+ ogg_stream_packetin(&os,&header_code);
+
+ /* We don't have to write out here, but doing so makes streaming
+ * much easier, so we do, flushing ALL pages. This ensures the actual
+ * audio data will start on a new page
+ */
+ while(!eos){
+ int result=ogg_stream_flush(&os,&og);
+ if(result==0)break;
+ outfile.write(og.header, og.header_len);
+ outfile.write(og.body, og.body_len);
+ }
+
+ }
+
+
+ while(!eos)
+ {
+ long bytes_per_sample = bits_per_sample/8;
+
+ long bytes=(long)infile.read(readbuffer,llclamp((S32)(READ_BUFFER*num_channels*bytes_per_sample),0,data_left)); /* stereo hardwired here */
+
+ if (bytes==0)
+ {
+ /* end of file. this can be done implicitly in the mainline,
+ but it's easier to see here in non-clever fashion.
+ Tell the library we're at end of stream so that it can handle
+ the last frame and mark end of stream in the output properly */
+
+ vorbis_analysis_wrote(&vd,0);
+// eos = 1;
+
+ }
+ else
+ {
+ long i;
+ long samples;
+ int temp;
+
+ data_left -= bytes;
/* data to encode */
-
- /* expose the buffer to submit data */
- float **buffer=vorbis_analysis_buffer(&vd,READ_BUFFER);
-
- i = 0;
- samples = bytes / (num_channels * bytes_per_sample);
-
- if (num_channels == 2)
- {
- if (bytes_per_sample == 2)
- {
- /* uninterleave samples */
- for(i=0; i<samples ;i++)
- {
- temp = ((signed char *)readbuffer)[i*4+1]; /*Flawfinder: ignore*/
- temp += ((signed char *)readbuffer)[i*4+3]; /*Flawfinder: ignore*/
- temp <<= 8;
- temp += readbuffer[i*4];
- temp += readbuffer[i*4+2];
-
- buffer[0][i] = ((float)temp) / 65536.f;
- }
- }
- else // presume it's 1 byte per which is unsigned (F#@%ing wav "standard")
- {
- /* uninterleave samples */
- for(i=0; i<samples ;i++)
- {
- temp = readbuffer[i*2+0];
- temp += readbuffer[i*2+1];
- temp -= 256;
- buffer[0][i] = ((float)temp) / 256.f;
- }
- }
- }
- else if (num_channels == 1)
- {
- if (bytes_per_sample == 2)
- {
- for(i=0; i < samples ;i++)
- {
- temp = ((signed char*)readbuffer)[i*2+1];
- temp <<= 8;
- temp += readbuffer[i*2];
- buffer[0][i] = ((float)temp) / 32768.f;
- }
- }
- else // presume it's 1 byte per which is unsigned (F#@%ing wav "standard")
- {
- for(i=0; i < samples ;i++)
- {
- temp = readbuffer[i];
- temp -= 128;
- buffer[0][i] = ((float)temp) / 128.f;
- }
- }
- }
-
- /* tell the library how much we actually submitted */
- vorbis_analysis_wrote(&vd,i);
- }
-
- /* vorbis does some data preanalysis, then divvies up blocks for
- more involved (potentially parallel) processing. Get a single
- block for encoding now */
- while(vorbis_analysis_blockout(&vd,&vb)==1)
- {
-
- /* analysis */
- /* Do the main analysis, creating a packet */
- vorbis_analysis(&vb, NULL);
- vorbis_bitrate_addblock(&vb);
-
- while(vorbis_bitrate_flushpacket(&vd, &op))
- {
-
- /* weld the packet into the bitstream */
- ogg_stream_packetin(&os,&op);
-
- /* write out pages (if any) */
- while(!eos)
- {
- result = ogg_stream_pageout(&os,&og);
-
- if(result==0)
- break;
-
- outfile.write(og.header, og.header_len);
- outfile.write(og.body, og.body_len);
-
- /* this could be set above, but for illustrative purposes, I do
- it here (to show that vorbis does know where the stream ends) */
-
- if(ogg_page_eos(&og))
- eos=1;
-
- }
- }
- }
- }
-
-
-
- /* clean up and exit. vorbis_info_clear() must be called last */
-
- ogg_stream_clear(&os);
- vorbis_block_clear(&vb);
- vorbis_dsp_clear(&vd);
- vorbis_comment_clear(&vc);
- vorbis_info_clear(&vi);
-
- /* ogg_page and ogg_packet structs always point to storage in
- libvorbis. They're never freed or manipulated directly */
-
-// fprintf(stderr,"Vorbis encoding: Done.\n");
- LL_INFOS() << "Vorbis encoding: Done." << LL_ENDL;
-
+
+ /* expose the buffer to submit data */
+ float **buffer=vorbis_analysis_buffer(&vd,READ_BUFFER);
+
+ i = 0;
+ samples = bytes / (num_channels * bytes_per_sample);
+
+ if (num_channels == 2)
+ {
+ if (bytes_per_sample == 2)
+ {
+ /* uninterleave samples */
+ for(i=0; i<samples ;i++)
+ {
+ temp = ((signed char *)readbuffer)[i*4+1]; /*Flawfinder: ignore*/
+ temp += ((signed char *)readbuffer)[i*4+3]; /*Flawfinder: ignore*/
+ temp <<= 8;
+ temp += readbuffer[i*4];
+ temp += readbuffer[i*4+2];
+
+ buffer[0][i] = ((float)temp) / 65536.f;
+ }
+ }
+ else // presume it's 1 byte per which is unsigned (F#@%ing wav "standard")
+ {
+ /* uninterleave samples */
+ for(i=0; i<samples ;i++)
+ {
+ temp = readbuffer[i*2+0];
+ temp += readbuffer[i*2+1];
+ temp -= 256;
+ buffer[0][i] = ((float)temp) / 256.f;
+ }
+ }
+ }
+ else if (num_channels == 1)
+ {
+ if (bytes_per_sample == 2)
+ {
+ for(i=0; i < samples ;i++)
+ {
+ temp = ((signed char*)readbuffer)[i*2+1];
+ temp <<= 8;
+ temp += readbuffer[i*2];
+ buffer[0][i] = ((float)temp) / 32768.f;
+ }
+ }
+ else // presume it's 1 byte per which is unsigned (F#@%ing wav "standard")
+ {
+ for(i=0; i < samples ;i++)
+ {
+ temp = readbuffer[i];
+ temp -= 128;
+ buffer[0][i] = ((float)temp) / 128.f;
+ }
+ }
+ }
+
+ /* tell the library how much we actually submitted */
+ vorbis_analysis_wrote(&vd,i);
+ }
+
+ /* vorbis does some data preanalysis, then divvies up blocks for
+ more involved (potentially parallel) processing. Get a single
+ block for encoding now */
+ while(vorbis_analysis_blockout(&vd,&vb)==1)
+ {
+
+ /* analysis */
+ /* Do the main analysis, creating a packet */
+ vorbis_analysis(&vb, NULL);
+ vorbis_bitrate_addblock(&vb);
+
+ while(vorbis_bitrate_flushpacket(&vd, &op))
+ {
+
+ /* weld the packet into the bitstream */
+ ogg_stream_packetin(&os,&op);
+
+ /* write out pages (if any) */
+ while(!eos)
+ {
+ result = ogg_stream_pageout(&os,&og);
+
+ if(result==0)
+ break;
+
+ outfile.write(og.header, og.header_len);
+ outfile.write(og.body, og.body_len);
+
+ /* this could be set above, but for illustrative purposes, I do
+ it here (to show that vorbis does know where the stream ends) */
+
+ if(ogg_page_eos(&og))
+ eos=1;
+
+ }
+ }
+ }
+ }
+
+
+
+ /* clean up and exit. vorbis_info_clear() must be called last */
+
+ ogg_stream_clear(&os);
+ vorbis_block_clear(&vb);
+ vorbis_dsp_clear(&vd);
+ vorbis_comment_clear(&vc);
+ vorbis_info_clear(&vi);
+
+ /* ogg_page and ogg_packet structs always point to storage in
+ libvorbis. They're never freed or manipulated directly */
+
+// fprintf(stderr,"Vorbis encoding: Done.\n");
+ LL_INFOS() << "Vorbis encoding: Done." << LL_ENDL;
+
#endif
- return(LLVORBISENC_NOERR);
-
+ return(LLVORBISENC_NOERR);
+
}
diff --git a/indra/llaudio/llvorbisencode.h b/indra/llaudio/llvorbisencode.h
index 7372765075..34009fb8d8 100644
--- a/indra/llaudio/llvorbisencode.h
+++ b/indra/llaudio/llvorbisencode.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file vorbisencode.h
* @brief Vorbis encoding routine routine for Indra.
*
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -46,7 +46,7 @@ const U32 LLVORBIS_CLIP_SAMPLE_RATE = 44100;
const U32 LLVORBIS_CLIP_MAX_SAMPLES_PER_CHANNEL = (U32)(LLVORBIS_CLIP_MAX_TIME * LLVORBIS_CLIP_SAMPLE_RATE);
const U32 LLVORBIS_CLIP_MAX_SAMPLES = LLVORBIS_CLIP_MAX_SAMPLES_PER_CHANNEL * LLVORBIS_CLIP_MAX_CHANNELS;
const size_t LLVORBIS_CLIP_MAX_SAMPLE_DATA = LLVORBIS_CLIP_MAX_SAMPLES * 2; // 2 = 16-bit
-
+
// Treat anything this long as a bad asset. A little fudge factor at the end:
// Make that a lot of fudge factor. We're allowing 30 sec for now - 3x legal upload
const size_t LLVORBIS_CLIP_REJECT_SAMPLES = LLVORBIS_CLIP_MAX_SAMPLES * 3;
diff --git a/indra/llaudio/llwindgen.h b/indra/llaudio/llwindgen.h
index ec58f76f5f..57a14d902d 100644
--- a/indra/llaudio/llwindgen.h
+++ b/indra/llaudio/llwindgen.h
@@ -1,25 +1,25 @@
-/**
+/**
* @file windgen.h
* @brief Templated wind noise generation
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
@@ -33,137 +33,137 @@ template <class MIXBUFFERFORMAT_T>
class LLWindGen
{
public:
- LLWindGen(const U32 sample_rate = 44100) :
- mTargetGain(0.f),
- mTargetFreq(100.f),
- mTargetPanGainR(0.5f),
- mInputSamplingRate(sample_rate),
- mSubSamples(2),
- mFilterBandWidth(50.f),
- mBuf0(0.0f),
- mBuf1(0.0f),
- mBuf2(0.0f),
- mY0(0.0f),
- mY1(0.0f),
- mCurrentGain(0.f),
- mCurrentFreq(100.f),
- mCurrentPanGainR(0.5f),
- mLastSample(0.f)
- {
- mSamplePeriod = (F32)mSubSamples / (F32)mInputSamplingRate;
- mB2 = expf(-F_TWO_PI * mFilterBandWidth * mSamplePeriod);
- }
-
- const U32 getInputSamplingRate() { return mInputSamplingRate; }
- const F32 getNextSample();
- const F32 getClampedSample(bool clamp, F32 sample);
-
- // newbuffer = the buffer passed from the previous DSP unit.
- // numsamples = length in samples-per-channel at this mix time.
- // NOTE: generates L/R interleaved stereo
- MIXBUFFERFORMAT_T* windGenerate(MIXBUFFERFORMAT_T *newbuffer, int numsamples)
- {
- MIXBUFFERFORMAT_T *cursamplep = newbuffer;
-
- // Filter coefficients
- F32 a0 = 0.0f, b1 = 0.0f;
-
- // No need to clip at normal volumes
- bool clip = mCurrentGain > 2.0f;
-
- bool interp_freq = false;
-
- //if the frequency isn't changing much, we don't need to interpolate in the inner loop
- if (llabs(mTargetFreq - mCurrentFreq) < (mCurrentFreq * 0.112))
- {
- // calculate resonant filter coefficients
- mCurrentFreq = mTargetFreq;
- b1 = (-4.0f * mB2) / (1.0f + mB2) * cosf(F_TWO_PI * (mCurrentFreq * mSamplePeriod));
- a0 = (1.0f - mB2) * sqrtf(1.0f - (b1 * b1) / (4.0f * mB2));
- }
- else
- {
- interp_freq = true;
- }
-
- while (numsamples)
- {
- F32 next_sample;
-
- // Start with white noise
- // This expression is fragile, rearrange it and it will break!
- next_sample = getNextSample();
-
- // Apply a pinking filter
- // Magic numbers taken from PKE method at http://www.firstpr.com.au/dsp/pink-noise/
- mBuf0 = mBuf0 * 0.99765f + next_sample * 0.0990460f;
- mBuf1 = mBuf1 * 0.96300f + next_sample * 0.2965164f;
- mBuf2 = mBuf2 * 0.57000f + next_sample * 1.0526913f;
-
- next_sample = mBuf0 + mBuf1 + mBuf2 + next_sample * 0.1848f;
-
- if (interp_freq)
- {
- // calculate and interpolate resonant filter coefficients
- mCurrentFreq = (0.999f * mCurrentFreq) + (0.001f * mTargetFreq);
- b1 = (-4.0f * mB2) / (1.0f + mB2) * cosf(F_TWO_PI * (mCurrentFreq * mSamplePeriod));
- a0 = (1.0f - mB2) * sqrtf(1.0f - (b1 * b1) / (4.0f * mB2));
- }
-
- // Apply a resonant low-pass filter on the pink noise
- next_sample = a0 * next_sample - b1 * mY0 - mB2 * mY1;
- mY1 = mY0;
- mY0 = next_sample;
-
- mCurrentGain = (0.999f * mCurrentGain) + (0.001f * mTargetGain);
- mCurrentPanGainR = (0.999f * mCurrentPanGainR) + (0.001f * mTargetPanGainR);
-
- // For a 3dB pan law use:
- // next_sample *= mCurrentGain * ((mCurrentPanGainR*(mCurrentPanGainR-1)*1.652+1.413);
- next_sample *= mCurrentGain;
-
- // delta is used to interpolate between synthesized samples
- F32 delta = (next_sample - mLastSample) / (F32)mSubSamples;
-
- // Fill the audio buffer, clipping if necessary
- for (U8 i=mSubSamples; i && numsamples; --i, --numsamples)
- {
- mLastSample = mLastSample + delta;
- MIXBUFFERFORMAT_T sample_right = (MIXBUFFERFORMAT_T)getClampedSample(clip, mLastSample * mCurrentPanGainR);
- MIXBUFFERFORMAT_T sample_left = (MIXBUFFERFORMAT_T)getClampedSample(clip, mLastSample - (F32)sample_right);
-
- *cursamplep = sample_left;
- ++cursamplep;
- *cursamplep = sample_right;
- ++cursamplep;
- }
- }
-
- return newbuffer;
- }
-
+ LLWindGen(const U32 sample_rate = 44100) :
+ mTargetGain(0.f),
+ mTargetFreq(100.f),
+ mTargetPanGainR(0.5f),
+ mInputSamplingRate(sample_rate),
+ mSubSamples(2),
+ mFilterBandWidth(50.f),
+ mBuf0(0.0f),
+ mBuf1(0.0f),
+ mBuf2(0.0f),
+ mY0(0.0f),
+ mY1(0.0f),
+ mCurrentGain(0.f),
+ mCurrentFreq(100.f),
+ mCurrentPanGainR(0.5f),
+ mLastSample(0.f)
+ {
+ mSamplePeriod = (F32)mSubSamples / (F32)mInputSamplingRate;
+ mB2 = expf(-F_TWO_PI * mFilterBandWidth * mSamplePeriod);
+ }
+
+ const U32 getInputSamplingRate() { return mInputSamplingRate; }
+ const F32 getNextSample();
+ const F32 getClampedSample(bool clamp, F32 sample);
+
+ // newbuffer = the buffer passed from the previous DSP unit.
+ // numsamples = length in samples-per-channel at this mix time.
+ // NOTE: generates L/R interleaved stereo
+ MIXBUFFERFORMAT_T* windGenerate(MIXBUFFERFORMAT_T *newbuffer, int numsamples)
+ {
+ MIXBUFFERFORMAT_T *cursamplep = newbuffer;
+
+ // Filter coefficients
+ F32 a0 = 0.0f, b1 = 0.0f;
+
+ // No need to clip at normal volumes
+ bool clip = mCurrentGain > 2.0f;
+
+ bool interp_freq = false;
+
+ //if the frequency isn't changing much, we don't need to interpolate in the inner loop
+ if (llabs(mTargetFreq - mCurrentFreq) < (mCurrentFreq * 0.112))
+ {
+ // calculate resonant filter coefficients
+ mCurrentFreq = mTargetFreq;
+ b1 = (-4.0f * mB2) / (1.0f + mB2) * cosf(F_TWO_PI * (mCurrentFreq * mSamplePeriod));
+ a0 = (1.0f - mB2) * sqrtf(1.0f - (b1 * b1) / (4.0f * mB2));
+ }
+ else
+ {
+ interp_freq = true;
+ }
+
+ while (numsamples)
+ {
+ F32 next_sample;
+
+ // Start with white noise
+ // This expression is fragile, rearrange it and it will break!
+ next_sample = getNextSample();
+
+ // Apply a pinking filter
+ // Magic numbers taken from PKE method at http://www.firstpr.com.au/dsp/pink-noise/
+ mBuf0 = mBuf0 * 0.99765f + next_sample * 0.0990460f;
+ mBuf1 = mBuf1 * 0.96300f + next_sample * 0.2965164f;
+ mBuf2 = mBuf2 * 0.57000f + next_sample * 1.0526913f;
+
+ next_sample = mBuf0 + mBuf1 + mBuf2 + next_sample * 0.1848f;
+
+ if (interp_freq)
+ {
+ // calculate and interpolate resonant filter coefficients
+ mCurrentFreq = (0.999f * mCurrentFreq) + (0.001f * mTargetFreq);
+ b1 = (-4.0f * mB2) / (1.0f + mB2) * cosf(F_TWO_PI * (mCurrentFreq * mSamplePeriod));
+ a0 = (1.0f - mB2) * sqrtf(1.0f - (b1 * b1) / (4.0f * mB2));
+ }
+
+ // Apply a resonant low-pass filter on the pink noise
+ next_sample = a0 * next_sample - b1 * mY0 - mB2 * mY1;
+ mY1 = mY0;
+ mY0 = next_sample;
+
+ mCurrentGain = (0.999f * mCurrentGain) + (0.001f * mTargetGain);
+ mCurrentPanGainR = (0.999f * mCurrentPanGainR) + (0.001f * mTargetPanGainR);
+
+ // For a 3dB pan law use:
+ // next_sample *= mCurrentGain * ((mCurrentPanGainR*(mCurrentPanGainR-1)*1.652+1.413);
+ next_sample *= mCurrentGain;
+
+ // delta is used to interpolate between synthesized samples
+ F32 delta = (next_sample - mLastSample) / (F32)mSubSamples;
+
+ // Fill the audio buffer, clipping if necessary
+ for (U8 i=mSubSamples; i && numsamples; --i, --numsamples)
+ {
+ mLastSample = mLastSample + delta;
+ MIXBUFFERFORMAT_T sample_right = (MIXBUFFERFORMAT_T)getClampedSample(clip, mLastSample * mCurrentPanGainR);
+ MIXBUFFERFORMAT_T sample_left = (MIXBUFFERFORMAT_T)getClampedSample(clip, mLastSample - (F32)sample_right);
+
+ *cursamplep = sample_left;
+ ++cursamplep;
+ *cursamplep = sample_right;
+ ++cursamplep;
+ }
+ }
+
+ return newbuffer;
+ }
+
public:
- F32 mTargetGain;
- F32 mTargetFreq;
- F32 mTargetPanGainR;
-
+ F32 mTargetGain;
+ F32 mTargetFreq;
+ F32 mTargetPanGainR;
+
private:
- U32 mInputSamplingRate;
- U8 mSubSamples;
- F32 mSamplePeriod;
- F32 mFilterBandWidth;
- F32 mB2;
-
- F32 mBuf0;
- F32 mBuf1;
- F32 mBuf2;
- F32 mY0;
- F32 mY1;
-
- F32 mCurrentGain;
- F32 mCurrentFreq;
- F32 mCurrentPanGainR;
- F32 mLastSample;
+ U32 mInputSamplingRate;
+ U8 mSubSamples;
+ F32 mSamplePeriod;
+ F32 mFilterBandWidth;
+ F32 mB2;
+
+ F32 mBuf0;
+ F32 mBuf1;
+ F32 mBuf2;
+ F32 mY0;
+ F32 mY1;
+
+ F32 mCurrentGain;
+ F32 mCurrentFreq;
+ F32 mCurrentPanGainR;
+ F32 mLastSample;
};
template<class T> inline const F32 LLWindGen<T>::getNextSample() { return (F32)rand() * (1.0f / (F32)(RAND_MAX / (U16_MAX / 8))) + (F32)(S16_MIN / 8); }