From 0b208f1539f79f5154a61214876b74a11374bec5 Mon Sep 17 00:00:00 2001 From: McCabe Maxsted Date: Sat, 6 Dec 2008 11:27:57 -0700 Subject: openal on windows branch --- linden/indra/llaudio/audioengine.cpp | 198 ++------ linden/indra/llaudio/audioengine.h | 75 ++- linden/indra/llaudio/audioengine_openal.cpp | 689 +++++++++++++++++++++------- linden/indra/llaudio/audioengine_openal.h | 62 ++- linden/indra/llaudio/listener_openal.cpp | 8 +- linden/indra/llaudio/listener_openal.h | 13 +- linden/indra/llaudio/llaudiodecodemgr.cpp | 23 +- linden/indra/newview/llfloaterabout.cpp | 5 + linden/indra/newview/llstartup.cpp | 45 +- linden/install.xml | 33 ++ 10 files changed, 745 insertions(+), 406 deletions(-) diff --git a/linden/indra/llaudio/audioengine.cpp b/linden/indra/llaudio/audioengine.cpp index 0a450e9..5fb38c0 100644 --- a/linden/indra/llaudio/audioengine.cpp +++ b/linden/indra/llaudio/audioengine.cpp @@ -51,6 +51,9 @@ extern void request_sound(const LLUUID &sound_guid); LLAudioEngine* gAudiop = NULL; +// Maximum amount of time we wait for a transfer to complete before starting +// off another one. +const F32 MAX_CURRENT_TRANSFER_TIME = 60.f; // // LLAudioEngine implementation @@ -74,8 +77,7 @@ void LLAudioEngine::setDefaults() mListenerp = NULL; - mMuted = false; - mUserData = NULL; + mMuted = FALSE; mLastStatus = 0; @@ -96,17 +98,16 @@ void LLAudioEngine::setDefaults() mInternetStreamGain = 0.125f; mNextWindUpdate = 0.f; - mInternetStreamMedia = NULL; - mInternetStreamURL.clear(); + for (U32 i = 0; i < LLAudioEngine::AUDIO_TYPE_COUNT; i++) + mSecondaryGain[i] = 1.0f; } -bool LLAudioEngine::init(const S32 num_channels, void* userdata) +BOOL LLAudioEngine::init(const S32 num_channels) { setDefaults(); mNumChannels = num_channels; - mUserData = userdata; allocateListener(); @@ -145,146 +146,22 @@ void LLAudioEngine::shutdown() S32 i; for (i = 0; i < MAX_CHANNELS; i++) { - delete mChannels[i]; - mChannels[i] = NULL; + if (mChannels[i]) + { + delete mChannels[i]; + mChannels[i] = NULL; + } } // Clean up buffers for (i = 0; i < MAX_BUFFERS; i++) { - delete mBuffers[i]; - mBuffers[i] = NULL; - } - - delete mInternetStreamMedia; - mInternetStreamMedia = NULL; - mInternetStreamURL.clear(); -} - - -// virtual -void LLAudioEngine::startInternetStream(const std::string& url) -{ - llinfos << "entered startInternetStream()" << llendl; - - if (!mInternetStreamMedia) - { - LLMediaManager* mgr = LLMediaManager::getInstance(); - if (mgr) + if (mBuffers[i]) { - mInternetStreamMedia = mgr->createSourceFromMimeType(LLURI(url).scheme(), "audio/mpeg"); // assumes that whatever media implementation supports mp3 also supports vorbis. - llinfos << "mInternetStreamMedia is now " << mInternetStreamMedia << llendl; - } - } - - if(!mInternetStreamMedia) - return; - - if (!url.empty()) { - llinfos << "Starting internet stream: " << url << llendl; - mInternetStreamURL = url; - mInternetStreamMedia->navigateTo ( url ); - llinfos << "Playing....." << llendl; - mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_START); - mInternetStreamMedia->updateMedia(); - } else { - llinfos << "setting stream to NULL"<< llendl; - mInternetStreamURL.clear(); - mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_STOP); - mInternetStreamMedia->updateMedia(); - } - //#endif -} - -// virtual -void LLAudioEngine::stopInternetStream() -{ - llinfos << "entered stopInternetStream()" << llendl; - - if(mInternetStreamMedia) - { - if( ! mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_STOP)){ - llinfos << "attempting to stop stream failed!" << llendl; + delete mBuffers[i]; + mBuffers[i] = NULL; } - mInternetStreamMedia->updateMedia(); } - - mInternetStreamURL.clear(); -} - -// virtual -void LLAudioEngine::pauseInternetStream(int pause) -{ - llinfos << "entered pauseInternetStream()" << llendl; - - if(!mInternetStreamMedia) - return; - - if(pause) - { - if(! mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_PAUSE)) - { - llinfos << "attempting to pause stream failed!" << llendl; - } - } else { - if(! mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_START)) - { - llinfos << "attempting to unpause stream failed!" << llendl; - } - } - mInternetStreamMedia->updateMedia(); -} - -// virtual -void LLAudioEngine::updateInternetStream() -{ - if (mInternetStreamMedia) - mInternetStreamMedia->updateMedia(); -} - -// virtual -int LLAudioEngine::isInternetStreamPlaying() -{ - if (!mInternetStreamMedia) - return 0; - - if (mInternetStreamMedia->getStatus() == LLMediaBase::STATUS_STARTED) - { - return 1; // Active and playing - } - - if (mInternetStreamMedia->getStatus() == LLMediaBase::STATUS_PAUSED) - { - return 2; // paused - } - - return 0; // Stopped -} - -// virtual -void LLAudioEngine::getInternetStreamInfo(char* artist, char* title) -{ - artist[0] = 0; - title[0] = 0; -} - -// virtual -void LLAudioEngine::setInternetStreamGain(F32 vol) -{ - mInternetStreamGain = vol; - - if(!mInternetStreamMedia) - return; - - vol = llclamp(vol, 0.f, 1.f); - mInternetStreamMedia->setVolume(vol); - mInternetStreamMedia->updateMedia(); -} - -// virtual -const std::string& LLAudioEngine::getInternetStreamURL() -{ - return mInternetStreamURL; } @@ -295,6 +172,13 @@ void LLAudioEngine::updateChannels() { if (mChannels[i]) { + // set secondary gain if type is available + LLAudioSource* source = mChannels[i]->getSource(); + if (source) + { + mChannels[i]->setSecondaryGain(mSecondaryGain[source->getType()]); + } + mChannels[i]->updateBuffer(); mChannels[i]->update3DPosition(); mChannels[i]->updateLoop(); @@ -565,8 +449,6 @@ void LLAudioEngine::idle(F32 max_decode_time) // missed picking it up in all the places that can add // or request new data. startNextTransfer(); - - updateInternetStream(); } @@ -775,6 +657,18 @@ F32 LLAudioEngine::getMasterGain() return mMasterGain; } +void LLAudioEngine::setSecondaryGain(S32 type, F32 gain) +{ + llassert(type < LLAudioEngine::AUDIO_TYPE_COUNT); + + mSecondaryGain[type] = gain; +} + +F32 LLAudioEngine::getSecondaryGain(S32 type) +{ + return mSecondaryGain[type]; +} + F32 LLAudioEngine::getInternetStreamGain() { return mInternetStreamGain; @@ -850,7 +744,8 @@ F64 LLAudioEngine::mapWindVecToPan(LLVector3 wind_vec) } -void LLAudioEngine::triggerSound(const LLUUID &audio_uuid, const LLUUID& owner_id, const F32 gain, const LLVector3d &pos_global) +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. //llinfos << "Localized: " << audio_uuid << llendl; @@ -1317,12 +1212,13 @@ LLAudioSource::LLAudioSource(const LLUUID& id, const LLUUID& owner_id, const F32 mOwnerID(owner_id), mPriority(0.f), mGain(gain), - mAmbient(false), - mLoop(false), - mSyncMaster(false), - mSyncSlave(false), - mQueueSounds(false), - mPlayedOnce(false), + mType(type), + mAmbient(FALSE), + mLoop(FALSE), + mSyncMaster(FALSE), + mSyncSlave(FALSE), + mQueueSounds(FALSE), + mPlayedOnce(FALSE), mChannelp(NULL), mCurrentDatap(NULL), mQueuedDatap(NULL) @@ -1468,8 +1364,7 @@ bool LLAudioSource::play(const LLUUID &audio_uuid) bool LLAudioSource::isDone() { const F32 MAX_AGE = 60.f; - const F32 MAX_UNPLAYED_AGE = 15.f; - + const F32 MAX_UNPLAYED_AGE = 30.f; if (isLoop()) { // Looped sources never die on their own. @@ -1647,8 +1542,9 @@ LLAudioBuffer *LLAudioSource::getCurrentBuffer() LLAudioChannel::LLAudioChannel() : mCurrentSourcep(NULL), mCurrentBufferp(NULL), - mLoopedThisFrame(false), - mWaiting(false) + mLoopedThisFrame(FALSE), + mWaiting(FALSE), + mSecondaryGain(1.0f) { } diff --git a/linden/indra/llaudio/audioengine.h b/linden/indra/llaudio/audioengine.h index 94134f5..937a8e1 100644 --- a/linden/indra/llaudio/audioengine.h +++ b/linden/indra/llaudio/audioengine.h @@ -80,11 +80,23 @@ class LLAudioBuffer; class LLAudioEngine { public: + enum LLAudioType + { + AUDIO_TYPE_NONE = 0, + AUDIO_TYPE_SFX = 1, + AUDIO_TYPE_UI = 2, + AUDIO_TYPE_AMBIENT = 3, + AUDIO_TYPE_COUNT = 4 // last + }; + LLAudioEngine(); virtual ~LLAudioEngine(); // initialization/startup/shutdown - virtual bool init(const S32 num_channels, void *userdata); + //virtual BOOL init(); + + virtual BOOL init(const S32 num_channels); + virtual std::string getDriverName(bool verbose) = 0; virtual void shutdown(); // Used by the mechanics of the engine @@ -109,6 +121,9 @@ public: F32 getMasterGain(); void setMasterGain(F32 gain); + F32 getSecondaryGain(S32 type); + void setSecondaryGain(S32 type, F32 gain); + F32 getInternetStreamGain(); virtual void setDopplerFactor(F32 factor); @@ -122,8 +137,10 @@ public: // 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 LLVector3d &pos_global = LLVector3d::zero); - bool preloadSound(const LLUUID &id); + 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); + BOOL preloadSound(const LLUUID &id); void addAudioSource(LLAudioSource *asp); void cleanupAudioSource(LLAudioSource *asp); @@ -132,16 +149,15 @@ public: LLAudioData *getAudioData(const LLUUID &audio_uuid); - // Internet stream methods - virtual void startInternetStream(const std::string& url); - virtual void stopInternetStream(); - virtual void pauseInternetStream(int pause); - virtual void updateInternetStream(); - virtual int isInternetStreamPlaying(); - virtual void getInternetStreamInfo(char* artist, char* title); + virtual void startInternetStream(const std::string& url) = 0; + virtual void stopInternetStream() = 0; + virtual void pauseInternetStream(int pause) = 0; + virtual int isInternetStreamPlaying() = 0; + virtual void getInternetStreamInfo(char* artist, char* title) { artist[0] = 0; title[0] = 0; } // use a value from 0.0 to 1.0, inclusive - virtual void setInternetStreamGain(F32 vol); - virtual const std::string& getInternetStreamURL(); + virtual void setInternetStreamGain(F32 vol) { mInternetStreamGain = vol; } + virtual const std::string& getInternetStreamURL() { return LLStringUtil::null; } + virtual void InitStreamer() = 0; // For debugging usage virtual LLVector3 getListenerPos(); @@ -177,6 +193,11 @@ protected: virtual void allocateListener() = 0; + // Internet stream methods + virtual void initInternetStream() {} + virtual void updateInternetStream() {} + + // listener methods virtual void setListenerPos(LLVector3 vec); virtual void setListenerVelocity(LLVector3 vec); @@ -191,8 +212,7 @@ protected: protected: LLListener *mListenerp; - bool mMuted; - void* mUserData; + BOOL mMuted; S32 mLastStatus; @@ -218,10 +238,10 @@ protected: LLAudioBuffer *mBuffers[MAX_BUFFERS]; F32 mMasterGain; + F32 mSecondaryGain[AUDIO_TYPE_COUNT]; // Hack! Internet streams are treated differently from other sources! F32 mInternetStreamGain; - std::string mInternetStreamURL; F32 mNextWindUpdate; @@ -229,7 +249,6 @@ protected: private: void setDefaults(); - LLMediaBase *mInternetStreamMedia; }; @@ -272,6 +291,9 @@ public: void setPlayedOnce(const bool played_once) { mPlayedOnce = played_once; } + 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; } @@ -304,12 +326,13 @@ protected: LLUUID mOwnerID; // owner of the object playing the sound F32 mPriority; F32 mGain; - bool mAmbient; - bool mLoop; - bool mSyncMaster; - bool mSyncSlave; - bool mQueueSounds; - bool mPlayedOnce; + BOOL mAmbient; + BOOL mLoop; + BOOL mSyncMaster; + BOOL mSyncSlave; + BOOL mQueueSounds; + BOOL mPlayedOnce; + S32 mType; LLVector3d mPositionGlobal; LLVector3 mVelocity; @@ -378,6 +401,9 @@ public: virtual void setSource(LLAudioSource *sourcep); LLAudioSource *getSource() const { return mCurrentSourcep; } + void setSecondaryGain(F32 gain) { mSecondaryGain = gain; } + F32 getSecondaryGain() { return mSecondaryGain; } + friend class LLAudioEngine; friend class LLAudioSource; protected: @@ -394,8 +420,9 @@ protected: protected: LLAudioSource *mCurrentSourcep; LLAudioBuffer *mCurrentBufferp; - bool mLoopedThisFrame; - bool mWaiting; // Waiting for sync. + BOOL mLoopedThisFrame; + BOOL mWaiting; // Waiting for sync. + F32 mSecondaryGain; }; diff --git a/linden/indra/llaudio/audioengine_openal.cpp b/linden/indra/llaudio/audioengine_openal.cpp index 85d2080..65203dd 100644 --- a/linden/indra/llaudio/audioengine_openal.cpp +++ b/linden/indra/llaudio/audioengine_openal.cpp @@ -36,29 +36,31 @@ #include "audioengine_openal.h" #include "listener_openal.h" +LLAudioEngine_OpenAL::LLAudioEngine_OpenAL() +{ -// Variables and definitions for Wind -#define MAX_NUM_WIND_BUFFERS 40 -static int empty_num_wind_buffers = MAX_NUM_WIND_BUFFERS; -static const float wind_buffer_size_sec = 0.05f; // 1/20th sec -static const U32 wind_gen_freq = LLWindGen::getInputSamplingRate(); -static ALuint wind_source; -static S16 *winddata=NULL; + #if LL_GSTREAMER_ENABLED + mMedia_data = new LLMediaManagerData; + // initialize GStreamer + LLMediaImplGStreamer::startup( mMedia_data ); + m_streamer=new LLMediaImplGStreamer (); -LLAudioEngine_OpenAL::LLAudioEngine_OpenAL() -{ - mWindGen = NULL; + if(!m_streamer) + { + llwarns << "LLAudioEngine_OpenAL::LLAudioEngine_OpenAL() Failed to create our private gstreamer audio instance" << llendl; + } + #endif } LLAudioEngine_OpenAL::~LLAudioEngine_OpenAL() { } -bool LLAudioEngine_OpenAL::init(const S32 num_channels, void* userdata) + +BOOL LLAudioEngine_OpenAL::init(const S32 num_channels) { - mWindGen = NULL; - LLAudioEngine::init(num_channels, userdata); + LLAudioEngine::init(num_channels); if(!alutInit(NULL, NULL)) { @@ -66,35 +68,61 @@ bool LLAudioEngine_OpenAL::init(const S32 num_channels, void* userdata) return false; } + initInternetStream(); + llinfos << "LLAudioEngine_OpenAL::init() OpenAL successfully initialized" << llendl; - llinfos << "OpenAL version: " - << ll_safe_string(alGetString(AL_VERSION)) << llendl; - llinfos << "OpenAL vendor: " - << ll_safe_string(alGetString(AL_VENDOR)) << llendl; - llinfos << "OpenAL renderer: " - << ll_safe_string(alGetString(AL_RENDERER)) << llendl; + llinfos << "LLAudioEngine_OpenAL::init() Speed of sound is: " << alGetFloat(AL_SPEED_OF_SOUND) << llendl; - ALint major = alutGetMajorVersion (); - ALint minor = alutGetMinorVersion (); - llinfos << "ALUT version: " << major << "." << minor << llendl; + return TRUE; +} +std::string LLAudioEngine_OpenAL::getDriverName(bool verbose) +{ ALCdevice *device = alcGetContextsDevice(alcGetCurrentContext()); + + std::ostringstream version; + + ALint major = alutGetMajorVersion (); + ALint minor = alutGetMinorVersion (); alcGetIntegerv(device, ALC_MAJOR_VERSION, 1, &major); alcGetIntegerv(device, ALC_MAJOR_VERSION, 1, &minor); - llinfos << "ALC version: " << major << "." << minor << llendl; - llinfos << "ALC default device: " - << ll_safe_string(alcGetString(device, - ALC_DEFAULT_DEVICE_SPECIFIER)) - << llendl; + version << + "OpenAL"; - llinfos << "LLAudioEngine_OpenAL::init() Speed of sound is: " << alGetFloat(AL_SPEED_OF_SOUND) << llendl; + 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 true; + return version.str(); +} + + +void LLAudioEngine_OpenAL::idle(F32 max_decode_time) +{ + LLAudioEngine::idle(max_decode_time); + #if LL_GSTREAMER_ENABLED + if(m_streamer != NULL) + m_streamer->updateMedia(); + #endif } + void LLAudioEngine_OpenAL::allocateListener() { mListenerp = (LLListener *) new LLListener_OpenAL(); @@ -115,11 +143,21 @@ void LLAudioEngine_OpenAL::shutdown() llwarns << "Nuts." << llendl; llwarns << "LLAudioEngine_OpenAL::shutdown() ALUT shutdown failed: " << alutGetErrorString (alutGetError ()) << llendl; } - - llinfos << "LLAudioEngine_OpenAL::shutdown() OpenAL successfully shut down" << llendl; - + else + { + llinfos << "LLAudioEngine_OpenAL::shutdown() OpenAL successfully shut down" << llendl; + } + delete mListenerp; mListenerp = NULL; + + #if LL_GSTREAMER_ENABLED + if(m_streamer) + { + delete m_streamer; + m_streamer = NULL; + } + #endif } LLAudioBuffer *LLAudioEngine_OpenAL::createBuffer() @@ -140,26 +178,27 @@ void LLAudioEngine_OpenAL::setInternalGain(F32 gain) LLAudioChannelOpenAL::LLAudioChannelOpenAL() { - alGenSources(1, &mALSource); + alGenSources(1, &ALSource); } LLAudioChannelOpenAL::~LLAudioChannelOpenAL() { cleanup(); - alDeleteSources(1, &mALSource); + alDeleteSources(1, &ALSource); } void LLAudioChannelOpenAL::cleanup() { - alSourceStop(mALSource); + alSourceStop(ALSource); mCurrentBufferp = NULL; } void LLAudioChannelOpenAL::play() { - if(!isPlaying()){ - alSourcePlay(mALSource); - getSource()->setPlayedOnce(true); + if(!isPlaying()) + { + alSourcePlay(ALSource); + getSource()->setPlayedOnce(TRUE); } } @@ -171,9 +210,10 @@ void LLAudioChannelOpenAL::playSynced(LLAudioChannel *channelp) bool LLAudioChannelOpenAL::isPlaying() { ALint state; - alGetSourcei(mALSource, AL_SOURCE_STATE, &state); - if(state == AL_PLAYING){ - return true; + alGetSourcei(ALSource, AL_SOURCE_STATE, &state); + if(state == AL_PLAYING) + { + return TRUE; } return false; } @@ -185,9 +225,9 @@ bool LLAudioChannelOpenAL::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(); - alSourcei(mALSource, AL_BUFFER, bufferp->getBuffer()); - alSourcef(mALSource, AL_GAIN, mCurrentSourcep->getGain()); - alSourcei(mALSource, AL_LOOPING, mCurrentSourcep->isLoop() ? AL_TRUE : AL_FALSE); + alSourcei(ALSource, AL_BUFFER, bufferp->getBuffer()); + alSourcef(ALSource, AL_GAIN, mCurrentSourcep->getGain()); + alSourcei(ALSource, AL_LOOPING, mCurrentSourcep->isLoop() ? AL_TRUE : AL_FALSE); } return true; @@ -201,28 +241,30 @@ void LLAudioChannelOpenAL::update3DPosition() } if (mCurrentSourcep->isAmbient()) { - alSource3f(mALSource, AL_POSITION, 0.0, 0.0, 0.0); - alSource3f(mALSource, AL_VELOCITY, 0.0, 0.0, 0.0); - //alSource3f(mALSource, AL_DIRECTION, 0.0, 0.0, 0.0); - alSourcef (mALSource, AL_ROLLOFF_FACTOR, 0.0); - alSourcei (mALSource, AL_SOURCE_RELATIVE, AL_TRUE); - } else { + alSource3f(ALSource, AL_POSITION, 0.0, 0.0, 0.0); + alSource3f(ALSource, AL_VELOCITY, 0.0, 0.0, 0.0); + //alSource3f(ALSource, AL_DIRECTION, 0.0, 0.0, 0.0); + alSourcef (ALSource, AL_ROLLOFF_FACTOR, 0.0); + alSourcei (ALSource, AL_SOURCE_RELATIVE, AL_TRUE); + } + else + { LLVector3 float_pos; float_pos.setVec(mCurrentSourcep->getPositionGlobal()); - alSourcefv(mALSource, AL_POSITION, float_pos.mV); + alSourcefv(ALSource, AL_POSITION, float_pos.mV); //llinfos << "LLAudioChannelOpenAL::update3DPosition() Velocity: " << mCurrentSourcep->getVelocity() << llendl; - alSourcefv(mALSource, AL_VELOCITY, mCurrentSourcep->getVelocity().mV); - //alSource3f(mALSource, AL_DIRECTION, 0.0, 0.0, 0.0); - alSourcef (mALSource, AL_ROLLOFF_FACTOR, 1.0); - alSourcei (mALSource, AL_SOURCE_RELATIVE, AL_FALSE); + alSourcefv(ALSource, AL_VELOCITY, mCurrentSourcep->getVelocity().mV); + //alSource3f(ALSource, AL_DIRECTION, 0.0, 0.0, 0.0); + alSourcef (ALSource, AL_ROLLOFF_FACTOR, 1.0); + alSourcei (ALSource, AL_SOURCE_RELATIVE, AL_FALSE); } //llinfos << "LLAudioChannelOpenAL::update3DPosition() Gain: " << mCurrentSourcep->getGain() << llendl; - alSourcef(mALSource, AL_GAIN, mCurrentSourcep->getGain()); + alSourcef(ALSource, AL_GAIN, mCurrentSourcep->getGain()); } LLAudioBufferOpenAL::LLAudioBufferOpenAL() { - mALBuffer = AL_NONE; + ALBuffer = AL_NONE; } LLAudioBufferOpenAL::~LLAudioBufferOpenAL() @@ -232,99 +274,99 @@ LLAudioBufferOpenAL::~LLAudioBufferOpenAL() void LLAudioBufferOpenAL::cleanup() { - if(mALBuffer != AL_NONE) + if(ALBuffer != AL_NONE) { - alDeleteBuffers(1, &mALBuffer); - mALBuffer = AL_NONE; + alDeleteBuffers(1, &ALBuffer); } } bool LLAudioBufferOpenAL::loadWAV(const std::string& filename) { cleanup(); - mALBuffer = alutCreateBufferFromFile(filename.c_str()); - if(mALBuffer == AL_NONE){ - ALenum error = alutGetError(); - if (gDirUtilp->fileExists(filename)) { - llwarns << - "LLAudioBufferOpenAL::loadWAV() Error loading " - << filename - << " " << alutGetErrorString(error) << llendl; - } else { - // It's common for the file to not actually exist. - lldebugs << - "LLAudioBufferOpenAL::loadWAV() Error loading " - << filename - << " " << alutGetErrorString(error) << llendl; - } - return false; + ALBuffer = alutCreateBufferFromFile(filename.c_str()); + if(ALBuffer == AL_NONE) + { + return FALSE; } return true; } -U32 LLAudioBufferOpenAL::getLength(){ - if(mALBuffer == AL_NONE){ + +U32 LLAudioBufferOpenAL::getLength() +{ + if(ALBuffer == AL_NONE) + { return 0; } ALint length; - alGetBufferi(mALBuffer, AL_SIZE, &length); + alGetBufferi(ALBuffer, AL_SIZE, &length); return length >> 2; } // ------------ -void LLAudioEngine_OpenAL::initWind(){ - ALenum error; - llinfos << "LLAudioEngine_OpenAL::initWind() start" << llendl; +void LLAudioEngine_OpenAL::initWind() +{ - alGetError(); /* clear error */ - - alGenSources(1,&wind_source); - - if((error=alGetError()) != AL_NO_ERROR) - { - llwarns << "LLAudioEngine_OpenAL::initWind() Error creating wind sources: "<; + alSourceQueueBuffers(mWindSource, mNumWindBuffers, mWindBuffers); + checkALError(); + + alSourcePlay(mWindSource); + checkALError(); llinfos << "LLAudioEngine_OpenAL::initWind() done" << llendl; + } void LLAudioEngine_OpenAL::cleanupWind(){ llinfos << "LLAudioEngine_OpenAL::cleanupWind()" << llendl; - alDeleteSources(1, &wind_source); - - if(winddata) - free(winddata); + alDeleteBuffers(mNumWindBuffers,mWindBuffers); + alDeleteSources(1, &mWindSource); + + checkALError(); +} + +void LLAudioEngine_OpenAL::checkALError() +{ + ALenum error; + if((error=alGetError()) != AL_NO_ERROR) + llwarns << "LLAudioEngine_OpenAL Error: "<mTargetFreq = (F32)center_freq; - mWindGen->mTargetGain = (F32)mapWindVecToGain(wind_vec) * mMaxWindGain; - mWindGen->mTargetPanGainR = (F32)mapWindVecToPan(wind_vec); - - alSourcei(wind_source, AL_LOOPING, AL_FALSE); - alSource3f(wind_source, AL_POSITION, 0.0, 0.0, 0.0); - alSource3f(wind_source, AL_VELOCITY, 0.0, 0.0, 0.0); - alSourcef(wind_source, AL_ROLLOFF_FACTOR, 0.0); - alSourcei(wind_source, AL_SOURCE_RELATIVE, AL_TRUE); - } - // ok lets make a wind buffer now - int processed, queued, unprocessed; - alGetSourcei(wind_source, AL_BUFFERS_PROCESSED, &processed); - alGetSourcei(wind_source, AL_BUFFERS_QUEUED, &queued); - unprocessed = queued - processed; + pitch = 1.0f + mapWindVecToPitch(wind_vec); + center_freq = 80.0f * powf(pitch,2.5f*(mapWindVecToGain(wind_vec)+1.0f)); - // ensure that there are always at least 3x as many filled buffers - // queued as we managed to empty since last time. - empty_num_wind_buffers = llmin(empty_num_wind_buffers + processed * 3 - unprocessed, MAX_NUM_WIND_BUFFERS-unprocessed); - empty_num_wind_buffers = llmax(empty_num_wind_buffers, 0); + //TESTING + mMaxWindGain=1.0; - //llinfos << "empty_num_wind_buffers: " << empty_num_wind_buffers <<" (" << unprocessed << ":" << processed << ")" << llendl; + mTargetFreq = center_freq; + mTargetGain = (F32)mapWindVecToGain(wind_vec) * mMaxWindGain; + mTargetPanGainR = (F32)mapWindVecToPan(wind_vec); - while(processed--) // unqueue old buffers + ALfloat source0Pos[]={mListenerp->getPosition().mV[0],mListenerp->getPosition().mV[1],mListenerp->getPosition().mV[2]}; + ALfloat source0Vel[]={ 0.0, 0.0, 0.0}; + + alSourcef(mWindSource, AL_GAIN, mTargetGain); + alSourcef(mWindSource, AL_PITCH, pitch); + alSourcefv(mWindSource, AL_POSITION, source0Pos); + alSourcefv(mWindSource, AL_VELOCITY, source0Vel); + alSourcei(mWindSource, AL_LOOPING, AL_FALSE); + + } + + int processed; + alGetSourcei(mWindSource, AL_BUFFERS_PROCESSED, &processed); + + while(processed--) { ALuint buffer; - int error; - alGetError(); /* clear error */ - alSourceUnqueueBuffers(wind_source, 1, &buffer); - error = alGetError(); - if(error != AL_NO_ERROR) - { - llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping (unqueuing) buffers" << llendl; - } - else + alSourceUnqueueBuffers(mWindSource, 1, &buffer); + checkALError(); + alBufferData(buffer,AL_FORMAT_STEREO16,windDSP((void*)mWindData,mWindDataSize/mBytesPerSample),mWindDataSize,mSampleRate); + checkALError(); + alSourceQueueBuffers(mWindSource, 1, &buffer); + checkALError(); + } + + int playing; + alGetSourcei(mWindSource, AL_SOURCE_STATE, &playing); + if(playing==AL_STOPPED) + alSourcePlay(mWindSource); + + checkALError(); +} + + +void * LLAudioEngine_OpenAL::windDSP(void *newbuffer, int length) +{ + // *NOTE: This function gets called a *lot*. + // Keep performance in mind if you mess with this. + // newbuffer = the buffer being constructed + // length = length in samples of the buffer + + + //clear the buffer + memset(newbuffer, 0, length*mBytesPerSample); + + // This turns off wind synth if it is muted or very very low volume + if (mTargetGain < 0.0005f) + { + llinfos << "Wind off" << llendl; + return newbuffer; + } + + static const U8 SUBSAMPLES = 2; + static const F32 FILTER_SAMPLE_PERIOD = (F32)SUBSAMPLES / float(mSampleRate); + static const F32 BANDWIDTH = 50.0f; + static const F32 B2 = expf(-F_TWO_PI * BANDWIDTH * FILTER_SAMPLE_PERIOD); + + static F32 pinking_buf0 = 0.0f; + static F32 pinking_buf1 = 0.0f; + static F32 pinking_buf2 = 0.0f; + static F32 Y0 = 0.0f; + static F32 Y1 = 0.0f; + static F32 last_sample = 0.0f; + static F32 current_freq = 0.0f; + static F32 current_gain = 0.0f; + static F32 current_pan_gain_r = 0.0f; + + F32 a0 = 0.0f, b1 = 0.0f; + + U8 *cursamplep = (U8*)newbuffer; + + //we assume 16-bit samples, because the ALUT specification maxes out there + U8 wordsize = 2; + + bool interp_freq = false; + + //if the frequency isn't changing much, we don't need to interpolate in the inner loop + if (llabs(mTargetFreq - current_freq) > 200.0f) + { + interp_freq = true; + } + else + { + // calculate resonant filter coefficients + current_freq = mTargetFreq; + b1 = (-4.0f * B2) / (1.0f + B2) * cosf(F_TWO_PI * (current_freq * FILTER_SAMPLE_PERIOD)); + a0 = (1.0f - B2) * sqrtf(1.0f - (b1 * b1) / (4.0f * B2)); + } + + while (length) + { + F32 next_sample; + + // Start with white noise [-16384, 16383] + next_sample = (F32)rand() * (1.0f / (F32)(RAND_MAX / (U16_MAX / 4))) + (S16_MIN / 4); + + // Apply a pinking filter + // Magic numbers taken from PKE method at http://www.firstpr.com.au/dsp/pink-noise/ + pinking_buf0 = pinking_buf0 * 0.99765f + next_sample * 0.0990460f; + pinking_buf1 = pinking_buf1 * 0.96300f + next_sample * 0.2965164f; + pinking_buf2 = pinking_buf2 * 0.57000f + next_sample * 1.0526913f; + + next_sample = pinking_buf0 + pinking_buf1 + pinking_buf2 + next_sample * 0.1848f; + + if (interp_freq) + { + // calculate resonant filter coefficients + current_freq = (0.999f * current_freq) + (0.001f * mTargetFreq); + b1 = (-4.0f * B2) / (1.0f + B2) * cosf(F_TWO_PI * (current_freq * FILTER_SAMPLE_PERIOD)); + a0 = (1.0f - B2) * sqrtf(1.0f - (b1 * b1) / (4.0f * B2)); + } + + // Apply a resonant low-pass filter on the pink noise + next_sample = ( a0 * next_sample - b1 * Y0 - B2 * Y1 ); + + Y1 = Y0; + Y0 = next_sample; + + current_gain = (0.999f * current_gain) + (0.001f * mTargetGain); + current_pan_gain_r = (0.999f * current_pan_gain_r) + (0.001f * mTargetPanGainR); + + next_sample *= current_gain; + F32 delta = (next_sample - last_sample) / (F32)SUBSAMPLES; + + S32 sample_left; + S32 sample_right; + + // Mix into the audio buffer, clipping if necessary for 16-bit mix buffers. + // *TODO: Should do something more intelligent like reducing wind gain to avoid clipping + for (int i=SUBSAMPLES; i && length; --i, --length) + { + last_sample = last_sample + delta; + sample_right = (S32)(last_sample * current_pan_gain_r); + sample_left = (S32)(last_sample - sample_right); + + *(S16*)cursamplep = llclamp(sample_left, S16_MIN, S16_MAX); + cursamplep += wordsize; + + *(S16*)cursamplep = llclamp(sample_right, S16_MIN, S16_MAX); + cursamplep += wordsize; + } + } + return newbuffer; + +} + + + + +/* + + + + + // newbuffer = the buffer passed from the previous DSP unit. + // length = length in samples at this mix time. + + U8 *cursamplep = (U8*)newbuffer; + U8 wordsize = 2; + + double bandwidth = 50; + double inputSamplingRate = 44100; + double a0,b1,b2; + + // calculate resonant filter coeffs + b2 = exp(-(F_TWO_PI) * (bandwidth / inputSamplingRate)); + + while (length--) + { + gCurrentFreq = (float)((0.999 * gCurrentFreq) + (0.001 * gTargetFreq)); + gCurrentGain = (float)((0.999 * gCurrentGain) + (0.001 * gTargetGain)); + gCurrentPanGainR = (float)((0.999 * gCurrentPanGainR) + (0.001 * gTargetPanGainR)); + b1 = (-4.0 * b2) / (1.0 + b2) * cos(F_TWO_PI * (gCurrentFreq / inputSamplingRate)); + a0 = (1.0 - b2) * sqrt(1.0 - (b1 * b1) / (4.0 * b2)); + double nextSample; + + // start with white noise + nextSample = ll_frand(2.0f) - 1.0f; + + gbuf0 = 0.997f * gbuf0 + 0.0126502f * nextSample; + gbuf1 = 0.985f * gbuf1 + 0.0139083f * nextSample; + gbuf2 = 0.950f * gbuf2 + 0.0205439f * nextSample; + gbuf3 = 0.850f * gbuf3 + 0.0387225f * nextSample; + gbuf4 = 0.620f * gbuf4 + 0.0465932f * nextSample; + gbuf5 = 0.250f * gbuf5 + 0.1093477f * nextSample; + + nextSample = gbuf0 + gbuf1 + gbuf2 + gbuf3 + gbuf4 + gbuf5; + + nextSample = (double)( a0 * nextSample - b1 * gY0 - b2 * gY1 ); + + gY1 = gY0; + gY0 = nextSample; + nextSample *= gCurrentGain; + + S16 sample; + + sample = llfloor(((F32)nextSample*32768.f*(1.0f - gCurrentPanGainR))+0.5f); + *(S16*)cursamplep = clipSample(sample, -32768, 32767); + + cursamplep += wordsize; + + sample = llfloor(((F32)nextSample*32768.f*gCurrentPanGainR)+0.5f); + + sample = llfloor(((F32)nextSample*32768.f*gCurrentPanGainR)+0.5f); + *(S16*)cursamplep = clipSample(sample, -32768, 32767); + cursamplep += wordsize; + } + + return newbuffer; +} +*/ + +// ------------ + +void LLAudioEngine_OpenAL::InitStreamer() +{ + #if LL_GSTREAMER_ENABLED + m_streamer=new LLMediaImplGStreamer (); + + if(!m_streamer) + { + llwarns << "LLAudioEngine_OpenAL::LLAudioEngine_OpenAL() Failed to create our private gstreamer audio instance" << llendl; + } + + if(m_streamer) + { + m_streamer->init (); + } + #endif +} + + +// ------------ + +void LLAudioEngine_OpenAL::initInternetStream() +{ + if(!mInternetStreamURL.empty()) + mInternetStreamURL.erase(); +} + + +void LLAudioEngine_OpenAL::startInternetStream(const std::string& url_cstr) +{ + + std::string url(url_cstr); + + #if LL_GSTREAMER_ENABLED + if(!m_streamer) + return; + // DCF_DEBUG + llinfos << "entered LLAudioEngine_OpenAL::startInternetStream()" << llendl; + + if (!url.empty()) + { + llinfos << "LLAudioEngine_OpenAL::startInternetStream() Starting internet stream: " << url << llendl; + mInternetStreamURL=url; + m_streamer->navigateTo ( url ); + llinfos << "Playing....." << llendl; + m_streamer->addCommand(LLMediaBase::COMMAND_START); + m_streamer->updateMedia(); + + } + else + { + llinfos << "LLAudioEngine_OpenAL setting stream to NULL"<< llendl; + mInternetStreamURL.erase(); + m_streamer->addCommand(LLMediaBase::COMMAND_STOP); + m_streamer->updateMedia(); + } + #endif +} + + +void LLAudioEngine_OpenAL::updateInternetStream() +{ + // DCF_DEBUG + llinfos << "entered LLAudioEngine_OpenAL::updateInternetStream()" << llendl; + +} + + +void LLAudioEngine_OpenAL::stopInternetStream() +{ + // DCF_DEBUG + llinfos << "entered LLAudioEngine_OpenAL::stopInternetStream()" << llendl; + + #if LL_GSTREAMER_ENABLED + if( ! m_streamer->addCommand(LLMediaBase::COMMAND_STOP)) + { + llinfos << "attempting to stop stream failed!" << llendl; + } + m_streamer->updateMedia(); + #endif + mInternetStreamURL.erase(); +} + + +void LLAudioEngine_OpenAL::pauseInternetStream(int pause) +{ + #if LL_GSTREAMER_ENABLED + if(!m_streamer) + return; + // DCF_DEBUG + llinfos << "entered LLAudioEngine_OpenAL::pauseInternetStream()" << llendl; + + if(pause) + { + if(!m_streamer->addCommand(LLMediaBase::COMMAND_PAUSE)) { - alDeleteBuffers(1, &buffer); + llinfos << "attempting to pause stream failed!" << llendl; } + m_streamer->updateMedia(); } - - while (empty_num_wind_buffers > 0) // fill+queue new buffers + else { - ALuint buffer; - alGetError(); /* clear error */ - alGenBuffers(1,&buffer); - if((error=alGetError()) != AL_NO_ERROR) + if( ! m_streamer->addCommand(LLMediaBase::COMMAND_START)) { - llwarns << "LLAudioEngine_OpenAL::initWind() Error creating wind buffer: " << error << llendl; - break; + llinfos << "attempting to pause stream failed!" << llendl; } + m_streamer->updateMedia(); + } + #endif +} - alBufferData(buffer, - AL_FORMAT_STEREO16, - mWindGen->windGenerate(winddata, - int(wind_gen_freq*wind_buffer_size_sec), 2), - int(2*wind_gen_freq*wind_buffer_size_sec*sizeof(S16)), - wind_gen_freq); - error = alGetError(); - if(error != AL_NO_ERROR) - llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping (bufferdata) buffers" << llendl; - - alSourceQueueBuffers(wind_source, 1, &buffer); - error = alGetError(); - if(error != AL_NO_ERROR) - llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping (queuing) buffers" << llendl; - --empty_num_wind_buffers; - } +int LLAudioEngine_OpenAL::isInternetStreamPlaying() +{ - int playing; - alGetSourcei(wind_source, AL_SOURCE_STATE, &playing); - if(playing != AL_PLAYING) + #if LL_GSTREAMER_ENABLED + if(!m_streamer) + return 0; + + if(m_streamer->getStatus() == LLMediaBase::STATUS_STARTED) { - alSourcePlay(wind_source); + return 1; // Active and playing + } - llinfos << "Wind had stopped - probably ran out of buffers - restarting: " << (unprocessed+empty_num_wind_buffers) << " now queued." << llendl; + if(m_streamer->getStatus() == LLMediaBase::STATUS_PAUSED) + { + return 2; // paused } + + #endif + return 0; // Stopped +} + + +void LLAudioEngine_OpenAL::getInternetStreamInfo(char* artist_out, char* title_out) +{ +} + + +void LLAudioEngine_OpenAL::setInternetStreamGain(F32 vol) +{ + #if LL_GSTREAMER_ENABLED + // Set the gstreamer volume here + if(!m_streamer) + return; + + vol = llclamp(vol, 0.f, 1.f); + m_streamer->setVolume(vol); + m_streamer->updateMedia(); + #endif } + +const std::string& LLAudioEngine_OpenAL::getInternetStreamURL() +{ + return mInternetStreamURL; +} diff --git a/linden/indra/llaudio/audioengine_openal.h b/linden/indra/llaudio/audioengine_openal.h index 6289f99..5d5c7d8 100644 --- a/linden/indra/llaudio/audioengine_openal.h +++ b/linden/indra/llaudio/audioengine_openal.h @@ -34,9 +34,13 @@ #ifndef LL_AUDIOENGINE_OpenAL_H #define LL_AUDIOENGINE_OpenAL_H +#include + #include "audioengine.h" #include "listener_openal.h" -#include "windgen.h" +#include "llmediamanager.h" +#include "llmediaimplgstreamer.h" +#include "llrand.h" class LLAudioEngine_OpenAL : public LLAudioEngine { @@ -44,23 +48,58 @@ class LLAudioEngine_OpenAL : public LLAudioEngine LLAudioEngine_OpenAL(); virtual ~LLAudioEngine_OpenAL(); - virtual bool init(const S32 num_channels, void *user_data); + virtual BOOL init(const S32 num_channels); + virtual std::string getDriverName(bool verbose); virtual void allocateListener(); virtual void shutdown(); + virtual void idle(F32 max_decode_time = 0.f); + void setInternalGain(F32 gain); LLAudioBuffer* createBuffer(); LLAudioChannel* createChannel(); - /*virtual*/ void initWind(); - /*virtual*/ void cleanupWind(); - /*virtual*/ void updateWind(LLVector3 direction, F32 camera_altitude); - - private: + // Internet stream methods + virtual void initInternetStream(); + virtual void startInternetStream(const std::string& url_cstr); + virtual void stopInternetStream(); + virtual void updateInternetStream(); + virtual void pauseInternetStream(int pause); + virtual int isInternetStreamPlaying(); + virtual void getInternetStreamInfo(char* artist, char* title); + virtual void setInternetStreamGain(F32 vol); + virtual const std::string& getInternetStreamURL(); + virtual void InitStreamer(); + + void checkALError(); + + void initWind(); + void cleanupWind(); + void updateWind(LLVector3 direction, F32 camera_altitude); + + protected: + static const S32 mNumWindBuffers=20; + static const S32 mSampleRate=44100; + static const S32 mBytesPerSample=4; + static const S32 mWindDataSize=8820; //44100 * 0.200 * 2 channels * 2 bytes per sample + + BOOL mFirstWind; + ALuint mWindBuffers[mNumWindBuffers]; + ALuint mWindSource; + + F32 mTargetGain; + F32 mTargetFreq; + F32 mTargetPanGainR; + S16 mWindData[mWindDataSize]; + + std::string mInternetStreamURL; void * windDSP(void *newbuffer, int length); - LLWindGen *mWindGen; +#if LL_GSTREAMER_ENABLED + LLMediaManagerData * mMedia_data; + LLMediaImplGStreamer * m_streamer; +#endif }; class LLAudioChannelOpenAL : public LLAudioChannel @@ -78,7 +117,7 @@ class LLAudioChannelOpenAL : public LLAudioChannel void update3DPosition(); void updateLoop(){}; - ALuint mALSource; + ALuint ALSource; }; class LLAudioBufferOpenAL : public LLAudioBuffer{ @@ -92,9 +131,8 @@ class LLAudioBufferOpenAL : public LLAudioBuffer{ friend class LLAudioChannelOpenAL; protected: void cleanup(); - ALuint getBuffer() {return mALBuffer;} - - ALuint mALBuffer; + ALuint getBuffer(){return ALBuffer;} + ALuint ALBuffer; }; #endif diff --git a/linden/indra/llaudio/listener_openal.cpp b/linden/indra/llaudio/listener_openal.cpp index e72b078..637af30 100644 --- a/linden/indra/llaudio/listener_openal.cpp +++ b/linden/indra/llaudio/listener_openal.cpp @@ -81,14 +81,18 @@ void LLListener_OpenAL::commitDeferredChanges(){ } void LLListener_OpenAL::setDopplerFactor(F32 factor){ + // Effect is way too strong by default, scale it down here. + // Scaling the speed of sound up causes crashes. + factor *= 0.005f; //llinfos << "LLListener_OpenAL::setDopplerFactor() : " << factor << llendl; alDopplerFactor(factor); } F32 LLListener_OpenAL::getDopplerFactor(){ ALfloat factor; - factor = alGetFloat(AL_DOPPLER_FACTOR); - //llinfos << "LLListener_OpenAL::getDopplerFactor() : " << factor << llendl; + factor = 0.0f; + alDopplerFactor(factor); + llinfos << "LLListener_OpenAL::getDopplerFactor() : " << factor << llendl; return factor; } diff --git a/linden/indra/llaudio/listener_openal.h b/linden/indra/llaudio/listener_openal.h index 33063bb..7551161 100644 --- a/linden/indra/llaudio/listener_openal.h +++ b/linden/indra/llaudio/listener_openal.h @@ -35,11 +35,18 @@ #include "listener.h" -#include "al.h" -#include "alut.h" + +//#include "AL/al.h" +#include "AL/alut.h" class LLListener_OpenAL : public LLListener { + private: + protected: + public: + + private: + protected: public: LLListener_OpenAL(); virtual ~LLListener_OpenAL(); @@ -52,8 +59,6 @@ class LLListener_OpenAL : public LLListener virtual void setDopplerFactor(F32 factor); virtual F32 getDopplerFactor(); - - protected: }; #endif diff --git a/linden/indra/llaudio/llaudiodecodemgr.cpp b/linden/indra/llaudio/llaudiodecodemgr.cpp index 7cd48a9..cfd0500 100644 --- a/linden/indra/llaudio/llaudiodecodemgr.cpp +++ b/linden/indra/llaudio/llaudiodecodemgr.cpp @@ -374,16 +374,16 @@ BOOL LLVorbisDecodeState::finishDecode() // 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; + mWAVBuffer[40] = (data_length - 8) & 0x000000FF; + mWAVBuffer[41] = ((data_length - 8)>> 8) & 0x000000FF; + mWAVBuffer[42] = ((data_length - 8)>> 16) & 0x000000FF; + mWAVBuffer[43] = ((data_length - 8)>> 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; + mWAVBuffer[4] = (data_length + 28) & 0x000000FF; + mWAVBuffer[5] = ((data_length + 28) >> 8) & 0x000000FF; + mWAVBuffer[6] = ((data_length + 28) >> 16) & 0x000000FF; + mWAVBuffer[7] = ((data_length + 28) >> 24) & 0x000000FF; // // FUDGECAKES!!! Vorbis encode/decode messes up loop point transitions (pop) @@ -395,7 +395,8 @@ BOOL LLVorbisDecodeState::finishDecode() S32 fade_length; char pcmout[4096]; /*Flawfinder: ignore*/ - fade_length = llmin((S32)128,(S32)(data_length-36)/8); + fade_length = llmin((S32)128,(S32)(data_length)/8); + if((S32)mWAVBuffer.size() >= (WAV_HEADER_SIZE + 2* fade_length)) { memcpy(pcmout, &mWAVBuffer[WAV_HEADER_SIZE], (2 * fade_length)); /*Flawfinder: ignore*/ @@ -435,7 +436,7 @@ BOOL LLVorbisDecodeState::finishDecode() } } - if (36 == data_length) + if (0 == data_length) { llwarns << "BAD Vorbis decode in finishDecode!" << llendl; mValid = FALSE; diff --git a/linden/indra/newview/llfloaterabout.cpp b/linden/indra/newview/llfloaterabout.cpp index 4704c5b..6bd2c41 100644 --- a/linden/indra/newview/llfloaterabout.cpp +++ b/linden/indra/newview/llfloaterabout.cpp @@ -41,6 +41,7 @@ #include "llcurl.h" #include "llimagej2c.h" +#include "audioengine.h" #include "llviewertexteditor.h" #include "llviewercontrol.h" @@ -200,6 +201,10 @@ LLFloaterAbout::LLFloaterAbout() support.append( LLImageJ2C::getEngineInfo() ); support.append("\n"); + support.append("Audio Driver Version: "); + support.append( gAudiop ? gAudiop->getDriverName(true) : "(none)" ); + support.append("\n"); + LLMediaManager *mgr = LLMediaManager::getInstance(); if (mgr) { diff --git a/linden/indra/newview/llstartup.cpp b/linden/indra/newview/llstartup.cpp index 941787b..636cf31 100644 --- a/linden/indra/newview/llstartup.cpp +++ b/linden/indra/newview/llstartup.cpp @@ -583,43 +583,28 @@ bool idle_startup() if (FALSE == gSavedSettings.getBOOL("NoAudio")) { - gAudiop = NULL; - -#ifdef LL_FMOD - gAudiop = (LLAudioEngine *) new LLAudioEngine_FMOD(); -#endif - -#ifdef LL_OPENAL - if (!gAudiop) - { - gAudiop = (LLAudioEngine *) new LLAudioEngine_OpenAL(); - } -#endif + + gAudiop = (LLAudioEngine *) new LLAudioEngine_OpenAL(); if (gAudiop) { -#if LL_WINDOWS - // FMOD on Windows needs the window handle to stop playing audio - // when window is minimized. JC - void* window_handle = (HWND)gViewerWindow->getPlatformWindow(); -#else - void* window_handle = NULL; -#endif - bool init = gAudiop->init(kAUDIO_NUM_SOURCES, window_handle); - if(init) + BOOL init = gAudiop->init(kAUDIO_NUM_SOURCES); + if(!init) { - gAudiop->setMuted(TRUE); + LL_WARNS("AppInit") << "Unable to initialize audio engine" << LL_ENDL; + gAudiop=NULL; } else { - LL_WARNS("AppInit") << "Unable to initialize audio engine" << LL_ENDL; - delete gAudiop; - gAudiop = NULL; + gAudiop->setMuted(TRUE); + LL_INFOS("AppInit") << "Audio Engine Initialized." << LL_ENDL; } } } - - LL_INFOS("AppInit") << "Audio Engine Initialized." << LL_ENDL; + else + { + gAudiop = NULL; + } if (LLTimer::knownBadTimer()) { @@ -766,6 +751,12 @@ bool idle_startup() gLoginMenuBarView->setVisible( TRUE ); gLoginMenuBarView->setEnabled( TRUE ); + // DEV-16927. The following code removes errant keystrokes that happen while the window is being + // first made visible. +#ifdef _WIN32 + MSG msg; + while( PeekMessage( &msg, /*All hWnds owned by this thread */ NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE ) ); +#endif timeout.reset(); return FALSE; } diff --git a/linden/install.xml b/linden/install.xml index 216c854..ce5b93a 100644 --- a/linden/install.xml +++ b/linden/install.xml @@ -819,6 +819,39 @@ anguage Infrstructure (CLI) international standard + openal + + copyright + Copyright (C) 2008 by authors. + description + 3D Audio library + license + lgpl + packages + + darwin + + md5sum + a0757244e3e6688fde2ffeea35cc1f96 + url + http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/openal-darwin-20080924.tar.bz2 + + linux + + md5sum + f0d9a8d1318b519cffe6c40c9cac4e21 + url + http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/openal-linux-20081010c-59a71b14-plughw.tar.bz2 + + windows + + md5sum + a0757244e3e6688fde2ffeea35cc1f96 + url + http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/openal-windows-20080924.tar.bz2 + + + openSSL license -- cgit v1.1