From 97e6c15e935666c1b295b7508a182d0da4b481f1 Mon Sep 17 00:00:00 2001 From: Jacek Antonelli Date: Wed, 19 Nov 2008 12:51:29 -0600 Subject: VWR-2662: OpenAL support (patch by Tofu Linden) --- linden/indra/llaudio/CMakeLists.txt | 19 ++ linden/indra/llaudio/audioengine.cpp | 323 ++++++++++++++------- linden/indra/llaudio/audioengine.h | 130 +++++---- linden/indra/llaudio/audioengine_fmod.cpp | 271 ++++++------------ linden/indra/llaudio/audioengine_fmod.h | 31 +- linden/indra/llaudio/audioengine_openal.cpp | 422 ++++++++++++++++++++++++++++ linden/indra/llaudio/audioengine_openal.h | 100 +++++++ linden/indra/llaudio/listener_fmod.h | 10 +- linden/indra/llaudio/listener_openal.cpp | 94 +++++++ linden/indra/llaudio/listener_openal.h | 12 +- linden/indra/llaudio/windgen.h | 138 +++++++++ 11 files changed, 1184 insertions(+), 366 deletions(-) create mode 100644 linden/indra/llaudio/audioengine_openal.cpp create mode 100644 linden/indra/llaudio/audioengine_openal.h create mode 100644 linden/indra/llaudio/listener_openal.cpp create mode 100644 linden/indra/llaudio/windgen.h (limited to 'linden/indra/llaudio') diff --git a/linden/indra/llaudio/CMakeLists.txt b/linden/indra/llaudio/CMakeLists.txt index b662023..aa15a9d 100644 --- a/linden/indra/llaudio/CMakeLists.txt +++ b/linden/indra/llaudio/CMakeLists.txt @@ -9,6 +9,7 @@ include(LLCommon) include(LLMath) include(LLMessage) include(LLVFS) +include(LLMedia) include_directories( ${FMOD_INCLUDE_DIR} @@ -20,6 +21,10 @@ include_directories( ${VORBISENC_INCLUDE_DIRS} ${VORBISFILE_INCLUDE_DIRS} ${VORBIS_INCLUDE_DIRS} + ${OPENAL_LIB_INCLUDE_DIRS} + ${FREEAULT_LIB_INCLUDE_DIRS} + ${LLMEDIA_INCLUDE_DIRS} + ${GSTREAMER_INCLUDE_DIRS} ) set(llaudio_SOURCE_FILES @@ -38,6 +43,7 @@ set(llaudio_HEADER_FILES llaudiodecodemgr.h vorbisdecode.h vorbisencode.h + windgen.h ) if (FMOD) @@ -59,6 +65,19 @@ if (FMOD) endif (LINUX) endif (FMOD) +if (OPENAL) + list(APPEND llaudio_SOURCE_FILES + audioengine_openal.cpp + listener_openal.cpp + ) + + list(APPEND llaudio_HEADER_FILES + audioengine_openal.h + listener_openal.h + ) + +endif (OPENAL) + set_source_files_properties(${llaudio_HEADER_FILES} PROPERTIES HEADER_FILE_ONLY TRUE) diff --git a/linden/indra/llaudio/audioengine.cpp b/linden/indra/llaudio/audioengine.cpp index 5dd5b28..0a450e9 100644 --- a/linden/indra/llaudio/audioengine.cpp +++ b/linden/indra/llaudio/audioengine.cpp @@ -44,14 +44,13 @@ #include "llaudiodecodemgr.h" #include "llassetstorage.h" +#include "llmediamanager.h" + // necessary for grabbing sounds from sim (implemented in viewer) 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 @@ -75,13 +74,13 @@ void LLAudioEngine::setDefaults() mListenerp = NULL; - mMuted = FALSE; + mMuted = false; mUserData = NULL; mLastStatus = 0; mNumChannels = 0; - mEnableWind = FALSE; + mEnableWind = false; S32 i; for (i = 0; i < MAX_CHANNELS; i++) @@ -91,15 +90,18 @@ void LLAudioEngine::setDefaults() for (i = 0; i < MAX_BUFFERS; i++) { mBuffers[i] = NULL; - } + } mMasterGain = 1.f; mInternetStreamGain = 0.125f; mNextWindUpdate = 0.f; + + mInternetStreamMedia = NULL; + mInternetStreamURL.clear(); } -BOOL LLAudioEngine::init(const S32 num_channels, void* userdata) +bool LLAudioEngine::init(const S32 num_channels, void* userdata) { setDefaults(); @@ -111,7 +113,9 @@ BOOL LLAudioEngine::init(const S32 num_channels, void* userdata) // Initialize the decode manager gAudioDecodeMgrp = new LLAudioDecodeMgr; - return TRUE; + llinfos << "LLAudioEngine::init() AudioEngine successfully initialized" << llendl; + + return true; } @@ -141,22 +145,146 @@ void LLAudioEngine::shutdown() S32 i; for (i = 0; i < MAX_CHANNELS; i++) { - if (mChannels[i]) - { - delete mChannels[i]; - mChannels[i] = NULL; - } + delete mChannels[i]; + mChannels[i] = NULL; } // Clean up buffers for (i = 0; i < MAX_BUFFERS; i++) { - if (mBuffers[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) { - delete mBuffers[i]; - mBuffers[i] = NULL; + 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; } + 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; } @@ -200,7 +328,7 @@ void LLAudioEngine::idle(F32 max_decode_time) { if (mBuffers[i]) { - mBuffers[i]->mInUse = FALSE; + mBuffers[i]->mInUse = false; } } @@ -252,11 +380,11 @@ void LLAudioEngine::idle(F32 max_decode_time) { // 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); + channelp->setWaiting(true); } else { - channelp->setWaiting(FALSE); + channelp->setWaiting(false); channelp->play(); } } @@ -396,7 +524,7 @@ void LLAudioEngine::idle(F32 max_decode_time) if (sync_masterp->getChannel()) { channelp->playSynced(master_channelp); - channelp->setWaiting(FALSE); + channelp->setWaiting(false); } } } @@ -426,7 +554,7 @@ void LLAudioEngine::idle(F32 max_decode_time) { if (mChannels[i]) { - mChannels[i]->mLoopedThisFrame = FALSE; + mChannels[i]->mLoopedThisFrame = false; } } @@ -437,13 +565,17 @@ void LLAudioEngine::idle(F32 max_decode_time) // 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) + + +bool LLAudioEngine::updateBufferForData(LLAudioData *adp, const LLUUID &audio_uuid) { if (!adp) { - return FALSE; + return false; } // Update the audio buffer first - load a sound if we have it. @@ -466,14 +598,14 @@ BOOL LLAudioEngine::updateBufferForData(LLAudioData *adp, const LLUUID &audio_uu } else { - return FALSE; + return false; } } - return TRUE; + return true; } -void LLAudioEngine::enableWind(BOOL enable) +void LLAudioEngine::enableWind(bool enable) { if (enable && (!mEnableWind)) { @@ -601,7 +733,7 @@ void LLAudioEngine::cleanupBuffer(LLAudioBuffer *bufferp) } -BOOL LLAudioEngine::preloadSound(const LLUUID &uuid) +bool LLAudioEngine::preloadSound(const LLUUID &uuid) { gAudiop->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 @@ -609,23 +741,23 @@ BOOL LLAudioEngine::preloadSound(const LLUUID &uuid) if (gAudioDecodeMgrp->addDecodeRequest(uuid)) { // This means that we do have a local copy, and we're working on decoding it. - return TRUE; + return true; } // At some point we need to have the audio/asset system check the static VFS // before it goes off and fetches stuff from the server. //llwarns << "Used internal preload for non-local sound" << llendl; - return FALSE; + return false; } -BOOL LLAudioEngine::isWindEnabled() +bool LLAudioEngine::isWindEnabled() { return mEnableWind; } -void LLAudioEngine::setMuted(BOOL muted) +void LLAudioEngine::setMuted(bool muted) { mMuted = muted; enableWind(!mMuted); @@ -735,7 +867,7 @@ void LLAudioEngine::triggerSound(const LLUUID &audio_uuid, const LLUUID& owner_i gAudiop->addAudioSource(asp); if (pos_global.isExactlyZero()) { - asp->setAmbient(TRUE); + asp->setAmbient(true); } else { @@ -914,7 +1046,7 @@ void LLAudioEngine::cleanupAudioSource(LLAudioSource *asp) } -BOOL LLAudioEngine::hasDecodedFile(const LLUUID &uuid) +bool LLAudioEngine::hasDecodedFile(const LLUUID &uuid) { std::string uuid_str; uuid.toString(uuid_str); @@ -925,16 +1057,16 @@ BOOL LLAudioEngine::hasDecodedFile(const LLUUID &uuid) if (gDirUtilp->fileExists(wav_path)) { - return TRUE; + return true; } else { - return FALSE; + return false; } } -BOOL LLAudioEngine::hasLocalFile(const LLUUID &uuid) +bool LLAudioEngine::hasLocalFile(const LLUUID &uuid) { // See if it's in the VFS. return gVFS->getExists(uuid, LLAssetType::AT_SOUND); @@ -1150,9 +1282,9 @@ void LLAudioEngine::assetCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::E LLAudioData *adp = gAudiop->getAudioData(uuid); if (adp) { - adp->setHasValidData(FALSE); - adp->setHasLocalData(FALSE); - adp->setHasDecodedData(FALSE); + adp->setHasValidData(false); + adp->setHasLocalData(false); + adp->setHasDecodedData(false); } } else @@ -1165,8 +1297,8 @@ void LLAudioEngine::assetCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::E } else { - adp->setHasValidData(TRUE); - adp->setHasLocalData(TRUE); + adp->setHasValidData(true); + adp->setHasLocalData(true); gAudioDecodeMgrp->addDecodeRequest(uuid); } } @@ -1185,12 +1317,12 @@ 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), + mAmbient(false), + mLoop(false), + mSyncMaster(false), + mSyncSlave(false), + mQueueSounds(false), + mPlayedOnce(false), mChannelp(NULL), mCurrentDatap(NULL), mQueuedDatap(NULL) @@ -1254,7 +1386,7 @@ void LLAudioSource::updatePriority() } } -BOOL LLAudioSource::setupChannel() +bool LLAudioSource::setupChannel() { LLAudioData *adp = getCurrentData(); @@ -1262,7 +1394,7 @@ BOOL LLAudioSource::setupChannel() { // We're not ready to play back the sound yet, so don't try and allocate a channel for it. //llwarns << "Aborting, no buffer" << llendl; - return FALSE; + return false; } @@ -1280,15 +1412,15 @@ BOOL LLAudioSource::setupChannel() // Now we have to reprioritize. // For now, just don't play the sound. //llwarns << "Aborting, no free channels" << llendl; - return FALSE; + return false; } mChannelp->setSource(this); - return TRUE; + return true; } -BOOL LLAudioSource::play(const LLUUID &audio_uuid) +bool LLAudioSource::play(const LLUUID &audio_uuid) { if (audio_uuid.isNull()) { @@ -1296,7 +1428,7 @@ BOOL LLAudioSource::play(const LLUUID &audio_uuid) { getChannel()->setSource(NULL); setChannel(NULL); - addAudioData(NULL, TRUE); + addAudioData(NULL, true); } } // Reset our age timeout if someone attempts to play the source. @@ -1304,7 +1436,7 @@ BOOL LLAudioSource::play(const LLUUID &audio_uuid) LLAudioData *adp = gAudiop->getAudioData(audio_uuid); - BOOL has_buffer = gAudiop->updateBufferForData(adp, audio_uuid); + bool has_buffer = gAudiop->updateBufferForData(adp, audio_uuid); addAudioData(adp); @@ -1312,47 +1444,48 @@ BOOL LLAudioSource::play(const LLUUID &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; + return false; } if (!setupChannel()) { - return FALSE; + 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()->setWaiting(true); + return true; } getChannel()->play(); - return TRUE; + return true; } -BOOL LLAudioSource::isDone() +bool LLAudioSource::isDone() { const F32 MAX_AGE = 60.f; const F32 MAX_UNPLAYED_AGE = 15.f; + if (isLoop()) { // Looped sources never die on their own. - return FALSE; + return false; } if (hasPendingPreloads()) { - return FALSE; + return false; } if (mQueuedDatap) { // Don't kill this sound if we've got something queued up to play. - return FALSE; + return false; } F32 elapsed = mAgeTimer.getElapsedTimeF32(); @@ -1365,11 +1498,11 @@ BOOL LLAudioSource::isDone() // We don't have a channel assigned, and it's been // over 5 seconds since we tried to play it. Don't bother. //llinfos << "No channel assigned, source is done" << llendl; - return TRUE; + return true; } else { - return FALSE; + return false; } } @@ -1377,27 +1510,27 @@ BOOL LLAudioSource::isDone() { if (elapsed > MAX_AGE) { - // Arbitarily cut off non-looped sounds when they're 20 seconds old. - return TRUE; + // 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; + return false; } } if ((elapsed > MAX_UNPLAYED_AGE) || mPlayedOnce) { // The sound isn't playing back after 5 seconds or we're already done playing it, kill it. - return TRUE; + return true; } - return FALSE; + return false; } -void LLAudioSource::addAudioData(LLAudioData *adp, const BOOL set_current) +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. @@ -1465,7 +1598,7 @@ void LLAudioSource::addAudioData(LLAudioData *adp, const BOOL set_current) } -BOOL LLAudioSource::hasPendingPreloads() const +bool LLAudioSource::hasPendingPreloads() const { // Check to see if we've got any preloads on deck for this source data_map::const_iterator iter; @@ -1475,11 +1608,11 @@ BOOL LLAudioSource::hasPendingPreloads() const if (!adp->hasDecodedData()) { // This source is still waiting for a preload - return TRUE; + return true; } } - return FALSE; + return false; } @@ -1514,8 +1647,8 @@ LLAudioBuffer *LLAudioSource::getCurrentBuffer() LLAudioChannel::LLAudioChannel() : mCurrentSourcep(NULL), mCurrentBufferp(NULL), - mLoopedThisFrame(FALSE), - mWaiting(FALSE) + mLoopedThisFrame(false), + mWaiting(false) { } @@ -1542,7 +1675,7 @@ void LLAudioChannel::setSource(LLAudioSource *sourcep) //llinfos << "Clearing source for channel" << llendl; cleanup(); mCurrentSourcep = NULL; - mWaiting = FALSE; + mWaiting = false; return; } @@ -1558,13 +1691,13 @@ void LLAudioChannel::setSource(LLAudioSource *sourcep) } -BOOL LLAudioChannel::updateBuffer() +bool LLAudioChannel::updateBuffer() { if (!mCurrentSourcep) { // This channel isn't associated with any source, nothing // to be updated - return FALSE; + return false; } LLAudioBuffer *bufferp = mCurrentSourcep->getCurrentBuffer(); @@ -1574,9 +1707,9 @@ BOOL LLAudioChannel::updateBuffer() { // The source hasn't changed what buffer it's playing bufferp->mLastUseTimer.reset(); - bufferp->mInUse = TRUE; + bufferp->mInUse = true; } - return FALSE; + return false; } // @@ -1589,16 +1722,16 @@ BOOL LLAudioChannel::updateBuffer() if (bufferp) { bufferp->mLastUseTimer.reset(); - bufferp->mInUse = TRUE; + bufferp->mInUse = true; } if (!mCurrentBufferp) { // There's no new buffer to be played, so we just abort. - return FALSE; + return false; } - return TRUE; + return true; } @@ -1612,9 +1745,9 @@ BOOL LLAudioChannel::updateBuffer() LLAudioData::LLAudioData(const LLUUID &uuid) : mID(uuid), mBufferp(NULL), - mHasLocalData(FALSE), - mHasDecodedData(FALSE), - mHasValidData(TRUE) + mHasLocalData(false), + mHasDecodedData(false), + mHasValidData(true) { if (uuid.isNull()) { @@ -1625,24 +1758,24 @@ LLAudioData::LLAudioData(const LLUUID &uuid) : if (gAudiop && gAudiop->hasDecodedFile(uuid)) { // Already have a decoded version, don't need to decode it. - mHasLocalData = TRUE; - mHasDecodedData = TRUE; + mHasLocalData = true; + mHasDecodedData = true; } else if (gAssetStorage && gAssetStorage->hasLocalAsset(uuid, LLAssetType::AT_SOUND)) { - mHasLocalData = TRUE; + mHasLocalData = true; } } -BOOL LLAudioData::load() +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. llinfos << "Already have a buffer for this sound, don't bother loading!" << llendl; - return TRUE; + return true; } mBufferp = gAudiop->getFreeBuffer(); @@ -1650,7 +1783,7 @@ BOOL LLAudioData::load() { // No free buffers, abort. llinfos << "Not able to allocate a new audio buffer, aborting." << llendl; - return FALSE; + return false; } std::string uuid_str; @@ -1664,10 +1797,10 @@ BOOL LLAudioData::load() gAudiop->cleanupBuffer(mBufferp); mBufferp = NULL; - return FALSE; + return false; } mBufferp->mAudioDatap = this; - return TRUE; + return true; } diff --git a/linden/indra/llaudio/audioengine.h b/linden/indra/llaudio/audioengine.h index e38413f..94134f5 100644 --- a/linden/indra/llaudio/audioengine.h +++ b/linden/indra/llaudio/audioengine.h @@ -45,6 +45,8 @@ #include "llframetimer.h" #include "llassettype.h" +class LLMediaBase; + const F32 LL_WIND_UPDATE_INTERVAL = 0.1f; const F32 LL_ROLLOFF_MULTIPLIER_UNDER_WATER = 5.f; // How much sounds are weaker under water const F32 LL_WIND_UNDERWATER_CENTER_FREQ = 20.f; @@ -82,9 +84,7 @@ public: virtual ~LLAudioEngine(); // initialization/startup/shutdown - //virtual BOOL init(); - - virtual BOOL init(const S32 num_channels, void *userdata); + virtual bool init(const S32 num_channels, void *userdata); virtual void shutdown(); // Used by the mechanics of the engine @@ -97,14 +97,14 @@ public: // // "End user" functionality // - virtual BOOL isWindEnabled(); - virtual void enableWind(BOOL state_b); + 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. - virtual void setMuted(BOOL muted); - virtual BOOL getMuted() const { return mMuted; } + virtual void setMuted(bool muted); + virtual bool getMuted() const { return mMuted; } F32 getMasterGain(); void setMasterGain(F32 gain); @@ -123,7 +123,7 @@ 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); + bool preloadSound(const LLUUID &id); void addAudioSource(LLAudioSource *asp); void cleanupAudioSource(LLAudioSource *asp); @@ -132,14 +132,16 @@ public: LLAudioData *getAudioData(const LLUUID &audio_uuid); - 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; } + // 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); // use a value from 0.0 to 1.0, inclusive - virtual void setInternetStreamGain(F32 vol) { mInternetStreamGain = vol; } - virtual const std::string& getInternetStreamURL() { return LLStringUtil::null; } + virtual void setInternetStreamGain(F32 vol); + virtual const std::string& getInternetStreamURL(); // For debugging usage virtual LLVector3 getListenerPos(); @@ -148,17 +150,16 @@ public: 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(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type, void *user_data, S32 result_code, LLExtStat ext_status); - friend class LLPipeline; // For debugging public: F32 mMaxWindGain; // Hack. Public to set before fade in? @@ -176,11 +177,6 @@ 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); @@ -195,13 +191,13 @@ protected: protected: LLListener *mListenerp; - BOOL mMuted; + bool mMuted; void* mUserData; S32 mLastStatus; S32 mNumChannels; - BOOL mEnableWind; + bool mEnableWind; LLUUID mCurrentTransfer; // Audio file currently being transferred by the system LLFrameTimer mCurrentTransferTimer; @@ -225,6 +221,7 @@ protected: // Hack! Internet streams are treated differently from other sources! F32 mInternetStreamGain; + std::string mInternetStreamURL; F32 mNextWindUpdate; @@ -232,6 +229,7 @@ protected: private: void setDefaults(); + LLMediaBase *mInternetStreamMedia; }; @@ -255,24 +253,24 @@ public: 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 setAmbient(const BOOL ambient) { mAmbient = ambient; } - BOOL isAmbient() const { return mAmbient; } + void setAmbient(const bool ambient) { mAmbient = ambient; } + bool isAmbient() const { return mAmbient; } - 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 setPositionGlobal(const LLVector3d &position_global) { mPositionGlobal = position_global; } LLVector3d getPositionGlobal() const { return mPositionGlobal; } @@ -284,16 +282,16 @@ public: virtual void setGain(const F32 gain) { mGain = llclamp(gain, 0.f, 1.f); } const LLUUID &getID() const { return mID; } - BOOL isDone(); + bool isDone(); LLAudioData *getCurrentData(); LLAudioData *getQueuedData(); LLAudioBuffer *getCurrentBuffer(); - BOOL setupChannel(); - BOOL play(const LLUUID &audio_id); // Start the audio source playing + bool setupChannel(); + bool play(const LLUUID &audio_id); // Start the audio source playing - 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; @@ -306,12 +304,12 @@ 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; LLVector3d mPositionGlobal; LLVector3 mVelocity; @@ -340,27 +338,27 @@ class LLAudioData { public: LLAudioData(const LLUUID &uuid); - BOOL load(); + bool load(); LLUUID getID() const { return mID; } LLAudioBuffer *getBuffer() const { return mBufferp; } - BOOL hasLocalData() const { return mHasLocalData; } - BOOL hasDecodedData() const { return mHasDecodedData; } - BOOL hasValidData() const { return mHasValidData; } + bool hasLocalData() const { return mHasLocalData; } + bool hasDecodedData() const { return mHasDecodedData; } + bool hasValidData() const { return mHasValidData; } - void setHasLocalData(const BOOL hld) { mHasLocalData = hld; } - void setHasDecodedData(const BOOL hdd) { mHasDecodedData = hdd; } - void setHasValidData(const BOOL hvd) { mHasValidData = hvd; } + void setHasLocalData(const bool hld) { mHasLocalData = hld; } + void setHasDecodedData(const bool hdd) { mHasDecodedData = hdd; } + void setHasValidData(const bool hvd) { mHasValidData = hvd; } friend class LLAudioEngine; // Severe laziness, bad. protected: LLUUID mID; LLAudioBuffer *mBufferp; // If this data is being used by the audio system, a pointer to the buffer will be set here. - BOOL mHasLocalData; - BOOL mHasDecodedData; - BOOL mHasValidData; + bool mHasLocalData; + bool mHasDecodedData; + bool mHasValidData; }; @@ -386,18 +384,18 @@ 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 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 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. + bool mLoopedThisFrame; + bool mWaiting; // Waiting for sync. }; @@ -412,14 +410,14 @@ class LLAudioBuffer { public: virtual ~LLAudioBuffer() {}; - virtual BOOL loadWAV(const std::string& filename) = 0; + virtual bool loadWAV(const std::string& filename) = 0; virtual U32 getLength() = 0; friend class LLAudioEngine; friend class LLAudioChannel; friend class LLAudioData; protected: - BOOL mInUse; + bool mInUse; LLAudioData *mAudioDatap; LLFrameTimer mLastUseTimer; }; diff --git a/linden/indra/llaudio/audioengine_fmod.cpp b/linden/indra/llaudio/audioengine_fmod.cpp index 16d820c..354ef95 100644 --- a/linden/indra/llaudio/audioengine_fmod.cpp +++ b/linden/indra/llaudio/audioengine_fmod.cpp @@ -1,7 +1,6 @@ /** * @file audioengine_fmod.cpp - * @brief Implementation of LLAudioEngine class abstracting the audio - * support as a FMOD 3D implementation + * @brief Implementation of LLAudioEngine class abstracting the audio support as a FMOD 3D implementation * * $LicenseInfo:firstyear=2002&license=viewergpl$ * @@ -46,27 +45,12 @@ #include "sound_ids.h" +extern "C" { + void * F_CALLBACKAPI windCallback(void *originalbuffer, void *newbuffer, int length, void* userdata); +} -void * F_CALLBACKAPI windCallback(void *originalbuffer, void *newbuffer, int length, void* userdata); FSOUND_DSPUNIT *gWindDSP = NULL; -// These globals for the wind filter. Blech! -F64 gbuf0 = 0.0; -F64 gbuf1 = 0.0; -F64 gbuf2 = 0.0; -F64 gbuf3 = 0.0; -F64 gbuf4 = 0.0; -F64 gbuf5 = 0.0; -F64 gY0 = 0.0; -F64 gY1 = 0.0; - -F32 gTargetGain = 0.f; -F32 gCurrentGain = 0.f; -F32 gTargetFreq = 100.f; -F32 gCurrentFreq = 100.f; -F32 gTargetPanGainR = 0.5f; -F32 gCurrentPanGainR = 0.5f; - // Safe strcpy #if 0 //(unused) //LL_WINDOWS || LL_LINUX @@ -94,9 +78,10 @@ static size_t strlcpy( char* dest, const char* src, size_t dst_size ) LLAudioEngine_FMOD::LLAudioEngine_FMOD() { - mInited = FALSE; + mInited = false; mCurrentInternetStreamp = NULL; mInternetStreamChannel = -1; + mWindGen = NULL; } @@ -105,7 +90,7 @@ LLAudioEngine_FMOD::~LLAudioEngine_FMOD() } -BOOL LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata) +bool LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata) { mFadeIn = -10000; @@ -124,7 +109,7 @@ BOOL LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata) { LL_WARNS("AppInit") << "Error : You are using the wrong FMOD version (" << version << ")! You should be using FMOD " << FMOD_VERSION << LL_ENDL; - //return FALSE; + //return false; } U32 fmod_flags = 0x0; @@ -139,7 +124,7 @@ BOOL LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata) { LL_WARNS("AppInit") << "Error setting FMOD window: " << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL; - return FALSE; + return false; } // Play audio when we don't have focus. // (For example, IM client on top of us.) @@ -167,7 +152,7 @@ BOOL LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata) // on top of ALSA is ironically more reliable than raw ALSA. // Ack, and ESD has more reliable failure modes - but has worse // latency - than all of them, so wins for now. - BOOL audio_ok = FALSE; + bool audio_ok = false; if (!audio_ok) if (NULL == getenv("LL_BAD_ESD")) /*Flawfinder: ignore*/ @@ -178,7 +163,7 @@ BOOL LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata) { LL_DEBUGS("AppInit") << "ESD audio output initialized OKAY" << LL_ENDL; - audio_ok = TRUE; + audio_ok = true; } else { LL_WARNS("AppInit") << "ESD audio output FAILED to initialize: " << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL; @@ -195,7 +180,7 @@ BOOL LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata) FSOUND_Init(44100, num_channels, fmod_flags)) { LL_DEBUGS("AppInit") << "OSS audio output initialized OKAY" << LL_ENDL; - audio_ok = TRUE; + audio_ok = true; } else { LL_WARNS("AppInit") << "OSS audio output FAILED to initialize: " << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL; @@ -212,7 +197,7 @@ BOOL LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata) FSOUND_Init(44100, num_channels, fmod_flags)) { LL_DEBUGS("AppInit") << "ALSA audio output initialized OKAY" << LL_ENDL; - audio_ok = TRUE; + audio_ok = true; } else { LL_WARNS("AppInit") << "ALSA audio output FAILED to initialize: " << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL; @@ -224,7 +209,7 @@ BOOL LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata) if (!audio_ok) { LL_WARNS("AppInit") << "Overall audio init failure." << LL_ENDL; - return FALSE; + return false; } // On Linux, FMOD causes a SIGPIPE for some netstream error @@ -250,7 +235,7 @@ BOOL LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata) { LL_WARNS("AppInit") << "Error initializing FMOD: " << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL; - return FALSE; + return false; } #endif @@ -259,17 +244,9 @@ BOOL LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata) LL_DEBUGS("AppInit") << "LLAudioEngine_FMOD::init() FMOD initialized correctly" << LL_ENDL; - mInited = TRUE; + mInited = true; - return TRUE; -} - - -void LLAudioEngine_FMOD::idle(F32 max_decode_time) -{ - LLAudioEngine::idle(max_decode_time); - - updateInternetStream(); + return true; } @@ -287,7 +264,7 @@ void LLAudioEngine_FMOD::shutdown() { if (gWindDSP) { - FSOUND_DSP_SetActive(gWindDSP,FALSE); + FSOUND_DSP_SetActive(gWindDSP,false); FSOUND_DSP_Free(gWindDSP); } @@ -318,13 +295,15 @@ LLAudioChannel *LLAudioEngine_FMOD::createChannel() void LLAudioEngine_FMOD::initWind() { + mWindGen = new LLWindGen; + if (!gWindDSP) { - gWindDSP = FSOUND_DSP_Create(&windCallback, FSOUND_DSP_DEFAULTPRIORITY_CLEARUNIT + 20, NULL); + gWindDSP = FSOUND_DSP_Create(&windCallback, FSOUND_DSP_DEFAULTPRIORITY_CLEARUNIT + 20, mWindGen); } if (gWindDSP) { - FSOUND_DSP_SetActive(gWindDSP, TRUE); + FSOUND_DSP_SetActive(gWindDSP, true); } mNextWindUpdate = 0.0; } @@ -334,10 +313,13 @@ void LLAudioEngine_FMOD::cleanupWind() { if (gWindDSP) { - FSOUND_DSP_SetActive(gWindDSP, FALSE); + FSOUND_DSP_SetActive(gWindDSP, false); FSOUND_DSP_Free(gWindDSP); gWindDSP = NULL; } + + delete mWindGen; + mWindGen = NULL; } @@ -367,9 +349,9 @@ void LLAudioEngine_FMOD::updateWind(LLVector3 wind_vec, F32 camera_height_above_ pitch = 1.0 + mapWindVecToPitch(wind_vec); center_freq = 80.0 * pow(pitch,2.5*(mapWindVecToGain(wind_vec)+1.0)); - gTargetFreq = (F32)center_freq; - gTargetGain = (F32)mapWindVecToGain(wind_vec) * mMaxWindGain; - gTargetPanGainR = (F32)mapWindVecToPan(wind_vec); + mWindGen->mTargetFreq = (F32)center_freq; + mWindGen->mTargetGain = (F32)mapWindVecToGain(wind_vec) * mMaxWindGain; + mWindGen->mTargetPanGainR = (F32)mapWindVecToPan(wind_vec); } } @@ -457,11 +439,11 @@ LLAudioChannelFMOD::~LLAudioChannelFMOD() } -BOOL LLAudioChannelFMOD::updateBuffer() +bool LLAudioChannelFMOD::updateBuffer() { if (LLAudioChannel::updateBuffer()) { - // Base class update returned TRUE, which means that we need to actually + // Base class update returned true, which means that we need to actually // set up the channel for a different buffer. LLAudioBufferFMOD *bufferp = (LLAudioBufferFMOD *)mCurrentSourcep->getCurrentBuffer(); @@ -473,13 +455,13 @@ BOOL LLAudioChannelFMOD::updateBuffer() // This is bad, there should ALWAYS be a sample associated with a legit // buffer. llerrs << "No FMOD sample!" << llendl; - return FALSE; + return false; } // Actually play the sound. Start it off paused so we can do all the necessary // setup. - mChannelID = FSOUND_PlaySoundEx(FSOUND_FREE, samplep, FSOUND_DSP_GetSFXUnit(), TRUE); + mChannelID = FSOUND_PlaySoundEx(FSOUND_FREE, samplep, FSOUND_DSP_GetSFXUnit(), true); //llinfos << "Setting up channel " << std::hex << mChannelID << std::dec << llendl; } @@ -501,7 +483,7 @@ BOOL LLAudioChannelFMOD::updateBuffer() } } - return TRUE; + return true; } @@ -524,12 +506,12 @@ void LLAudioChannelFMOD::update3DPosition() if (mCurrentSourcep->isAmbient()) { // Ambient sound, don't need to do any positional updates. - bufferp->set3DMode(FALSE); + bufferp->set3DMode(false); } else { // Localized sound. Update the position and velocity of the sound. - bufferp->set3DMode(TRUE); + bufferp->set3DMode(true); LLVector3 float_pos; float_pos.setVec(mCurrentSourcep->getPositionGlobal()); @@ -556,7 +538,7 @@ void LLAudioChannelFMOD::updateLoop() U32 cur_pos = FSOUND_GetCurrentPosition(mChannelID); if (cur_pos < (U32)mLastSamplePos) { - mLoopedThisFrame = TRUE; + mLoopedThisFrame = true; } mLastSamplePos = cur_pos; } @@ -589,11 +571,11 @@ void LLAudioChannelFMOD::play() return; } - if (!FSOUND_SetPaused(mChannelID, FALSE)) + if (!FSOUND_SetPaused(mChannelID, false)) { llwarns << "LLAudioChannelFMOD::play error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl; } - getSource()->setPlayedOnce(TRUE); + getSource()->setPlayedOnce(true); } @@ -618,11 +600,11 @@ void LLAudioChannelFMOD::playSynced(LLAudioChannel *channelp) } -BOOL LLAudioChannelFMOD::isPlaying() +bool LLAudioChannelFMOD::isPlaying() { if (!mChannelID) { - return FALSE; + return false; } return FSOUND_IsPlaying(mChannelID) && (!FSOUND_GetPaused(mChannelID)); @@ -652,14 +634,14 @@ LLAudioBufferFMOD::~LLAudioBufferFMOD() } -BOOL LLAudioBufferFMOD::loadWAV(const std::string& filename) +bool LLAudioBufferFMOD::loadWAV(const std::string& filename) { // Try to open a wav file from disk. This will eventually go away, as we don't // really want to block doing this. if (filename.empty()) { // invalid filename, abort. - return FALSE; + return false; } S32 file_size = 0; @@ -667,7 +649,7 @@ BOOL LLAudioBufferFMOD::loadWAV(const std::string& filename) if (!apr_file) { // File not found, abort. - return FALSE; + return false; } apr_file_close(apr_file); @@ -717,11 +699,11 @@ BOOL LLAudioBufferFMOD::loadWAV(const std::string& filename) // // file is probably corrupt - remove it. LLFile::remove(filename); - return FALSE; + return false; } - // Everything went well, return TRUE - return TRUE; + // Everything went well, return true + return true; } @@ -736,7 +718,7 @@ U32 LLAudioBufferFMOD::getLength() } -void LLAudioBufferFMOD::set3DMode(BOOL use3d) +void LLAudioBufferFMOD::set3DMode(bool use3d) { U16 current_mode = FSOUND_Sample_GetMode(mSamplep); @@ -765,7 +747,7 @@ void LLAudioEngine_FMOD::initInternetStream() { // Number of milliseconds of audio to buffer for the audio card. // Must be larger than the usual Second Life frame stutter time. - FSOUND_Stream_SetBufferSize(200); + FSOUND_Stream_SetBufferSize(200); // 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 @@ -810,19 +792,19 @@ signed char F_CALLBACKAPI LLAudioEngine_FMOD::callbackMetaData(char *name, char if (!strcmp("ARTIST", name)) { strlcpy(self->mInternetStreamArtist, value, 256); - self->mInternetStreamNewMetaData = TRUE; - return TRUE; + self->mInternetStreamNewMetaData = true; + return true; } if (!strcmp("TITLE", name)) { strlcpy(self->mInternetStreamTitle, value, 256); - self->mInternetStreamNewMetaData = TRUE; - return TRUE; + self->mInternetStreamNewMetaData = true; + return true; } */ - return TRUE; + return true; } @@ -867,7 +849,7 @@ void LLAudioEngine_FMOD::updateInternetStream() { // Reset volume to previously set volume setInternetStreamGain(mInternetStreamGain); - FSOUND_SetPaused(mInternetStreamChannel, FALSE); + FSOUND_SetPaused(mInternetStreamChannel, false); //FSOUND_Stream_Net_SetMetadataCallback(mInternetStream, callbackMetaData, this); } } @@ -909,7 +891,7 @@ void LLAudioEngine_FMOD::stopInternetStream() { if (mInternetStreamChannel != -1) { - FSOUND_SetPaused(mInternetStreamChannel, TRUE); + FSOUND_SetPaused(mInternetStreamChannel, true); FSOUND_SetPriority(mInternetStreamChannel, 0); mInternetStreamChannel = -1; } @@ -971,16 +953,10 @@ int LLAudioEngine_FMOD::isInternetStreamPlaying() } -void LLAudioEngine_FMOD::getInternetStreamInfo(char* artist_out, char* title_out) -{ - //strlcpy(artist_out, mInternetStreamArtist, 256); - //strlcpy(title_out, mInternetStreamTitle, 256); -} - - void LLAudioEngine_FMOD::setInternetStreamGain(F32 vol) { - LLAudioEngine::setInternetStreamGain(vol); + mInternetStreamGain = vol; + if (mInternetStreamChannel != -1) { vol = llclamp(vol, 0.f, 1.f); @@ -990,15 +966,9 @@ void LLAudioEngine_FMOD::setInternetStreamGain(F32 vol) } -const std::string& LLAudioEngine_FMOD::getInternetStreamURL() -{ - return mInternetStreamURL; -} - - LLAudioStreamFMOD::LLAudioStreamFMOD(const std::string& url) : mInternetStream(NULL), - mReady(FALSE) + mReady(false) { mInternetStreamURL = url; mInternetStream = FSOUND_Stream_Open(url.c_str(), FSOUND_NORMAL | FSOUND_NONBLOCKING, 0, 0); @@ -1007,11 +977,11 @@ LLAudioStreamFMOD::LLAudioStreamFMOD(const std::string& url) : llwarns << "Couldn't open fmod stream, error " << FMOD_ErrorString(FSOUND_GetError()) << llendl; - mReady = FALSE; + mReady = false; return; } - mReady = TRUE; + mReady = true; } int LLAudioStreamFMOD::startStream() @@ -1026,10 +996,10 @@ int LLAudioStreamFMOD::startStream() // Make sure the stream is set to 2D mode. FSOUND_Stream_SetMode(mInternetStream, FSOUND_2D); - return FSOUND_Stream_PlayEx(FSOUND_FREE, mInternetStream, NULL, TRUE); + return FSOUND_Stream_PlayEx(FSOUND_FREE, mInternetStream, NULL, true); } -BOOL LLAudioStreamFMOD::stopStream() +bool LLAudioStreamFMOD::stopStream() { if (mInternetStream) { @@ -1039,34 +1009,34 @@ BOOL LLAudioStreamFMOD::stopStream() unsigned int flags = 0x0; FSOUND_Stream_Net_GetStatus(mInternetStream, &status, &read_percent, &bitrate, &flags); - BOOL close = TRUE; + bool close = true; switch (status) { case FSOUND_STREAM_NET_CONNECTING: - close = FALSE; + close = false; break; case FSOUND_STREAM_NET_NOTCONNECTED: case FSOUND_STREAM_NET_BUFFERING: case FSOUND_STREAM_NET_READY: case FSOUND_STREAM_NET_ERROR: default: - close = TRUE; + close = true; } if (close) { FSOUND_Stream_Close(mInternetStream); mInternetStream = NULL; - return TRUE; + return true; } else { - return FALSE; + return false; } } else { - return TRUE; + return true; } } @@ -1076,94 +1046,35 @@ int LLAudioStreamFMOD::getOpenState() return open_state; } -/* This determines the format of the mixbuffer being passed in. change if you want to support int32 or float32 */ -#if LL_DARWIN - #define MIXBUFFERFORMAT S32 -#else - #define MIXBUFFERFORMAT S16 -#endif - -inline MIXBUFFERFORMAT clipSample(MIXBUFFERFORMAT sample, MIXBUFFERFORMAT min, MIXBUFFERFORMAT max) -{ - if (sample > max) - sample = max; - else if (sample < min) - sample = min; - - return sample; -} - -void * F_CALLBACKAPI windCallback(void *originalbuffer, void *newbuffer, int length, void*) +void * F_CALLBACKAPI windCallback(void *originalbuffer, void *newbuffer, int length, void* userdata) { -// originalbuffer = fsounds original mixbuffer. -// newbuffer = the buffer passed from the previous DSP unit. -// length = length in samples at this mix time. -// param = user parameter passed through in FSOUND_DSP_Create. -// -// modify the buffer in some fashion + // originalbuffer = fmod's original mixbuffer. + // newbuffer = the buffer passed from the previous DSP unit. + // length = length in samples at this mix time. + // param = user parameter passed through in FSOUND_DSP_Create. + // + // modify the buffer in some fashion - U8 *cursamplep = (U8*)newbuffer; - U8 wordsize = 2; + LLWindGen *windgen = + (LLWindGen *)userdata; + U8 stride; #if LL_DARWIN - wordsize = sizeof(MIXBUFFERFORMAT); + stride = sizeof(LLAudioEngine_FMOD::MIXBUFFERFORMAT); #else - int mixertype = FSOUND_GetMixer(); - if (mixertype == FSOUND_MIXER_BLENDMODE || mixertype == FSOUND_MIXER_QUALITY_FPU) - { - wordsize = 4; - } -#endif - - 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; - -#if 1 // LLAE_WIND_PINK apply pinking filter - 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; -#endif - -#if 1 //LLAE_WIND_RESONANT // do a resonant filter on the noise - nextSample = (double)( a0 * nextSample - b1 * gY0 - b2 * gY1 ); - - gY1 = gY0; - gY0 = nextSample; + int mixertype = FSOUND_GetMixer(); + if (mixertype == FSOUND_MIXER_BLENDMODE || + mixertype == FSOUND_MIXER_QUALITY_FPU) + { + stride = 4; + } + else + { + stride = 2; + } #endif - nextSample *= gCurrentGain; - - MIXBUFFERFORMAT sample; - - sample = llfloor(((F32)nextSample*32768.f*(1.0f - gCurrentPanGainR))+0.5f); - *(MIXBUFFERFORMAT*)cursamplep = clipSample((*(MIXBUFFERFORMAT*)cursamplep) + sample, -32768, 32767); - cursamplep += wordsize; - - sample = llfloor(((F32)nextSample*32768.f*gCurrentPanGainR)+0.5f); - *(MIXBUFFERFORMAT*)cursamplep = clipSample((*(MIXBUFFERFORMAT*)cursamplep) + sample, -32768, 32767); - cursamplep += wordsize; - } + newbuffer = windgen->windGenerate((LLAudioEngine_FMOD::MIXBUFFERFORMAT *)newbuffer, length, stride); return newbuffer; } diff --git a/linden/indra/llaudio/audioengine_fmod.h b/linden/indra/llaudio/audioengine_fmod.h index 41177b6..132afb1 100644 --- a/linden/indra/llaudio/audioengine_fmod.h +++ b/linden/indra/llaudio/audioengine_fmod.h @@ -35,6 +35,7 @@ #include "audioengine.h" #include "listener_fmod.h" +#include "windgen.h" #include "fmod.h" @@ -47,13 +48,11 @@ public: virtual ~LLAudioEngine_FMOD(); // initialization/startup/shutdown - virtual BOOL init(const S32 num_channels, void *user_data); + virtual bool init(const S32 num_channels, void *user_data); virtual void allocateListener(); virtual void shutdown(); - virtual void idle(F32 max_decode_time = 0.f); - // Internet stream methods virtual void initInternetStream(); virtual void startInternetStream(const std::string& url); @@ -61,15 +60,19 @@ public: virtual void stopInternetStream(); 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 initWind(); /*virtual*/ void cleanupWind(); /*virtual*/void updateWind(LLVector3 direction, F32 camera_height_above_water); +#if LL_DARWIN + typedef S32 MIXBUFFERFORMAT; +#else + typedef S16 MIXBUFFERFORMAT; +#endif + 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. @@ -79,7 +82,6 @@ protected: static signed char F_CALLBACKAPI callbackMetaData(char* name, char* value, void* userdata); LLAudioStreamFMOD *mCurrentInternetStreamp; - std::string mInternetStreamURL; int mInternetStreamChannel; std::list mDeadStreams; @@ -88,11 +90,12 @@ protected: //F32 mMaxDistance[MAX_BUFFERS]; S32 mFadeIn; - BOOL mInited; + bool mInited; // On Windows, userdata is the HWND of the application window. void* mUserData; + LLWindGen *mWindGen; }; @@ -106,9 +109,9 @@ protected: /*virtual*/ void play(); /*virtual*/ void playSynced(LLAudioChannel *channelp); /*virtual*/ void cleanup(); - /*virtual*/ BOOL isPlaying(); + /*virtual*/ bool isPlaying(); - /*virtual*/ BOOL updateBuffer(); + /*virtual*/ bool updateBuffer(); /*virtual*/ void update3DPosition(); /*virtual*/ void updateLoop(); @@ -124,11 +127,11 @@ public: LLAudioBufferFMOD(); virtual ~LLAudioBufferFMOD(); - /*virtual*/ BOOL loadWAV(const std::string& filename); + /*virtual*/ bool loadWAV(const std::string& filename); /*virtual*/ U32 getLength(); friend class LLAudioChannelFMOD; - void set3DMode(BOOL use3d); + void set3DMode(bool use3d); protected: FSOUND_SAMPLE *getSample() { return mSamplep; } protected: @@ -140,15 +143,15 @@ class LLAudioStreamFMOD public: LLAudioStreamFMOD(const std::string& url); int startStream(); - BOOL stopStream(); // Returns true if the stream was successfully stopped. - BOOL ready(); + bool stopStream(); // Returns true if the stream was successfully stopped. + bool ready(); const std::string& getURL() { return mInternetStreamURL; } int getOpenState(); protected: FSOUND_STREAM* mInternetStream; - BOOL mReady; + bool mReady; std::string mInternetStreamURL; }; diff --git a/linden/indra/llaudio/audioengine_openal.cpp b/linden/indra/llaudio/audioengine_openal.cpp new file mode 100644 index 0000000..606d9f6 --- /dev/null +++ b/linden/indra/llaudio/audioengine_openal.cpp @@ -0,0 +1,422 @@ +/** + * @file audioengine_openal.cpp + * @brief implementation of audio engine using OpenAL + * support as a OpenAL 3D implementation + * + * $LicenseInfo:firstyear=2002&license=viewergpl$ + * + * Copyright (c) 2002-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "lldir.h" + +#include "audioengine_openal.h" +#include "listener_openal.h" + + +// 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; + + +LLAudioEngine_OpenAL::LLAudioEngine_OpenAL() +{ + mWindGen = NULL; +} + +LLAudioEngine_OpenAL::~LLAudioEngine_OpenAL() +{ +} + +bool LLAudioEngine_OpenAL::init(const S32 num_channels, void* userdata) +{ + mWindGen = NULL; + LLAudioEngine::init(num_channels, userdata); + + if(!alutInit(NULL, NULL)) + { + llwarns << "LLAudioEngine_OpenAL::init() ALUT initialization failed: " << alutGetErrorString (alutGetError ()) << llendl; + return false; + } + + 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; + + ALint major = alutGetMajorVersion (); + ALint minor = alutGetMinorVersion (); + llinfos << "ALUT version: " << major << "." << minor << llendl; + + ALCdevice *device = alcGetContextsDevice(alcGetCurrentContext()); + + 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; + + llinfos << "LLAudioEngine_OpenAL::init() Speed of sound is: " << alGetFloat(AL_SPEED_OF_SOUND) << llendl; + + return true; +} + +void LLAudioEngine_OpenAL::allocateListener() +{ + mListenerp = (LLListener *) new LLListener_OpenAL(); + if(!mListenerp) + { + llwarns << "LLAudioEngine_OpenAL::allocateListener() Listener creation failed" << llendl; + } +} + +void LLAudioEngine_OpenAL::shutdown() +{ + llinfos << "About to LLAudioEngine::shutdown()" << llendl; + LLAudioEngine::shutdown(); + + llinfos << "About to alutExit()" << llendl; + if(!alutExit()) + { + llwarns << "Nuts." << llendl; + llwarns << "LLAudioEngine_OpenAL::shutdown() ALUT shutdown failed: " << alutGetErrorString (alutGetError ()) << llendl; + } + + llinfos << "LLAudioEngine_OpenAL::shutdown() OpenAL successfully shut down" << llendl; + + delete mListenerp; + mListenerp = NULL; +} + +LLAudioBuffer *LLAudioEngine_OpenAL::createBuffer() +{ + return new LLAudioBufferOpenAL(); +} + +LLAudioChannel *LLAudioEngine_OpenAL::createChannel() +{ + return new LLAudioChannelOpenAL(); +} + +void LLAudioEngine_OpenAL::setInternalGain(F32 gain) +{ + //llinfos << "LLAudioEngine_OpenAL::setInternalGain() Gain: " << gain << llendl; + alListenerf(AL_GAIN, gain); +} + +LLAudioChannelOpenAL::LLAudioChannelOpenAL() +{ + alGenSources(1, &mALSource); +} + +LLAudioChannelOpenAL::~LLAudioChannelOpenAL() +{ + cleanup(); + alDeleteSources(1, &mALSource); +} + +void LLAudioChannelOpenAL::cleanup() +{ + alSourceStop(mALSource); + mCurrentBufferp = NULL; +} + +void LLAudioChannelOpenAL::play() +{ + if(!isPlaying()){ + alSourcePlay(mALSource); + getSource()->setPlayedOnce(true); + } +} + +void LLAudioChannelOpenAL::playSynced(LLAudioChannel *channelp) +{ + play(); +} + +bool LLAudioChannelOpenAL::isPlaying() +{ + ALint state; + alGetSourcei(mALSource, AL_SOURCE_STATE, &state); + if(state == AL_PLAYING){ + return true; + } + return false; +} + +bool LLAudioChannelOpenAL::updateBuffer() +{ + 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(); + alSourcei(mALSource, AL_BUFFER, bufferp->getBuffer()); + alSourcef(mALSource, AL_GAIN, mCurrentSourcep->getGain()); + alSourcei(mALSource, AL_LOOPING, mCurrentSourcep->isLoop() ? AL_TRUE : AL_FALSE); + } + + return true; +} + +void LLAudioChannelOpenAL::update3DPosition() +{ + if(!mCurrentSourcep) + { + return; + } + 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 { + LLVector3 float_pos; + float_pos.setVec(mCurrentSourcep->getPositionGlobal()); + alSourcefv(mALSource, 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); + } + //llinfos << "LLAudioChannelOpenAL::update3DPosition() Gain: " << mCurrentSourcep->getGain() << llendl; + alSourcef(mALSource, AL_GAIN, mCurrentSourcep->getGain()); +} + +LLAudioBufferOpenAL::LLAudioBufferOpenAL() +{ + mALBuffer = AL_NONE; +} + +LLAudioBufferOpenAL::~LLAudioBufferOpenAL() +{ + cleanup(); +} + +void LLAudioBufferOpenAL::cleanup() +{ + 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)) { + 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; + } + + return true; +} + +U32 LLAudioBufferOpenAL::getLength(){ + if(mALBuffer == AL_NONE){ + return 0; + } + ALint length; + alGetBufferi(mALBuffer, AL_SIZE, &length); + return length >> 2; +} + +// ------------ + +void LLAudioEngine_OpenAL::initWind(){ + ALenum error; + llinfos << "LLAudioEngine_OpenAL::initWind() start" << llendl; + + alGetError(); /* clear error */ + + alGenSources(1,&wind_source); + + if((error=alGetError()) != AL_NO_ERROR) + { + llwarns << "LLAudioEngine_OpenAL::initWind() Error creating wind sources: "<; + + llinfos << "LLAudioEngine_OpenAL::initWind() done" << llendl; +} + +void LLAudioEngine_OpenAL::cleanupWind(){ + llinfos << "LLAudioEngine_OpenAL::cleanupWind()" << llendl; + + alDeleteSources(1, &wind_source); + + if(winddata) + free(winddata); + + delete mWindGen; + mWindGen = NULL; +} + +void LLAudioEngine_OpenAL::updateWind(LLVector3 wind_vec, F32 camera_altitude) +{ + LLVector3 wind_pos; + F64 pitch; + F64 center_freq; + ALenum error; + + mMaxWindGain=1.0; + + if (!mEnableWind) + return; + + if(!winddata) + 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(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; + + // 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); + + //llinfos << "empty_num_wind_buffers: " << empty_num_wind_buffers <<" (" << unprocessed << ":" << processed << ")" << llendl; + + while(processed--) // unqueue old buffers + { + 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 + { + alDeleteBuffers(1, &buffer); + } + } + + while (empty_num_wind_buffers > 0) // fill+queue new buffers + { + ALuint buffer; + alGetError(); /* clear error */ + alGenBuffers(1,&buffer); + if((error=alGetError()) != AL_NO_ERROR) + { + llwarns << "LLAudioEngine_OpenAL::initWind() Error creating wind buffer: " << error << llendl; + break; + } + + 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 playing; + alGetSourcei(wind_source, AL_SOURCE_STATE, &playing); + if(playing != AL_PLAYING) + { + alSourcePlay(wind_source); + + llinfos << "Wind had stopped - probably ran out of buffers - restarting: " << (unprocessed+empty_num_wind_buffers) << " now queued." << llendl; + } +} + diff --git a/linden/indra/llaudio/audioengine_openal.h b/linden/indra/llaudio/audioengine_openal.h new file mode 100644 index 0000000..6289f99 --- /dev/null +++ b/linden/indra/llaudio/audioengine_openal.h @@ -0,0 +1,100 @@ +/** + * @file audioengine_openal.cpp + * @brief implementation of audio engine using OpenAL + * support as a OpenAL 3D implementation + * + * Copyright (c) 2002-2008, Linden Research, Inc. + * + * $LicenseInfo:firstyear=2002&license=viewergpl$ + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + + +#ifndef LL_AUDIOENGINE_OpenAL_H +#define LL_AUDIOENGINE_OpenAL_H + +#include "audioengine.h" +#include "listener_openal.h" +#include "windgen.h" + +class LLAudioEngine_OpenAL : public LLAudioEngine +{ + public: + LLAudioEngine_OpenAL(); + virtual ~LLAudioEngine_OpenAL(); + + virtual bool init(const S32 num_channels, void *user_data); + virtual void allocateListener(); + + virtual void shutdown(); + + void setInternalGain(F32 gain); + + LLAudioBuffer* createBuffer(); + LLAudioChannel* createChannel(); + + /*virtual*/ void initWind(); + /*virtual*/ void cleanupWind(); + /*virtual*/ void updateWind(LLVector3 direction, F32 camera_altitude); + + private: + void * windDSP(void *newbuffer, int length); + LLWindGen *mWindGen; +}; + +class LLAudioChannelOpenAL : public LLAudioChannel +{ + public: + LLAudioChannelOpenAL(); + virtual ~LLAudioChannelOpenAL(); + protected: + void play(); + void playSynced(LLAudioChannel *channelp); + void cleanup(); + bool isPlaying(); + + bool updateBuffer(); + void update3DPosition(); + void updateLoop(){}; + + ALuint mALSource; +}; + +class LLAudioBufferOpenAL : public LLAudioBuffer{ + public: + LLAudioBufferOpenAL(); + virtual ~LLAudioBufferOpenAL(); + + bool loadWAV(const std::string& filename); + U32 getLength(); + + friend class LLAudioChannelOpenAL; + protected: + void cleanup(); + ALuint getBuffer() {return mALBuffer;} + + ALuint mALBuffer; +}; + +#endif diff --git a/linden/indra/llaudio/listener_fmod.h b/linden/indra/llaudio/listener_fmod.h index 7b7c4c6..95b31ac 100644 --- a/linden/indra/llaudio/listener_fmod.h +++ b/linden/indra/llaudio/listener_fmod.h @@ -37,11 +37,6 @@ class LLListener_FMOD : public LLListener { - protected: - F32 mDopplerFactor; - F32 mDistanceFactor; - F32 mRolloffFactor; - public: LLListener_FMOD(); virtual ~LLListener_FMOD(); @@ -59,6 +54,11 @@ class LLListener_FMOD : public LLListener virtual F32 getDistanceFactor(); virtual void setRolloffFactor(F32 factor); virtual F32 getRolloffFactor(); + + protected: + F32 mDopplerFactor; + F32 mDistanceFactor; + F32 mRolloffFactor; }; #endif diff --git a/linden/indra/llaudio/listener_openal.cpp b/linden/indra/llaudio/listener_openal.cpp new file mode 100644 index 0000000..e72b078 --- /dev/null +++ b/linden/indra/llaudio/listener_openal.cpp @@ -0,0 +1,94 @@ +/** + * @file audioengine_openal.cpp + * @brief implementation of audio engine using OpenAL + * support as a OpenAL 3D implementation + * + * $LicenseInfo:firstyear=2002&license=viewergpl$ + * + * Copyright (c) 2002-2007, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "audioengine.h" + +#include "listener_openal.h" + +LLListener_OpenAL::LLListener_OpenAL(){ + init(); +} + +LLListener_OpenAL::~LLListener_OpenAL(){ +} + +void LLListener_OpenAL::translate(LLVector3 offset){ + LLListener::translate(offset); + llinfos << "LLListener_OpenAL::translate() : " << offset << llendl; +} + +void LLListener_OpenAL::setPosition(LLVector3 pos){ + LLListener::setPosition(pos); + //llinfos << "LLListener_OpenAL::setPosition() : " << pos << llendl; +} + +void LLListener_OpenAL::setVelocity(LLVector3 vel){ + LLListener::setVelocity(vel); +} + +void LLListener_OpenAL::orient(LLVector3 up, LLVector3 at){ + LLListener::orient(up, at); + //llinfos << "LLListener_OpenAL::orient() up: " << up << " at: " << at << llendl; +} + +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); +} + +void LLListener_OpenAL::setDopplerFactor(F32 factor){ + //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; + return factor; +} + diff --git a/linden/indra/llaudio/listener_openal.h b/linden/indra/llaudio/listener_openal.h index cc4bb9e..737343e 100644 --- a/linden/indra/llaudio/listener_openal.h +++ b/linden/indra/llaudio/listener_openal.h @@ -40,12 +40,6 @@ class LLListener_OpenAL : public LLListener { - private: - protected: - public: - - private: - protected: public: LLListener_OpenAL(); virtual ~LLListener_OpenAL(); @@ -54,6 +48,12 @@ class LLListener_OpenAL : public LLListener 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(); + + protected: }; #endif diff --git a/linden/indra/llaudio/windgen.h b/linden/indra/llaudio/windgen.h new file mode 100644 index 0000000..39ce568 --- /dev/null +++ b/linden/indra/llaudio/windgen.h @@ -0,0 +1,138 @@ +/** + * @file windgen.h + * @brief Templated wind noise generation + * + * $LicenseInfo:firstyear=2002&license=viewergpl$ + * + * Copyright (c) 2002-2008, Linden Research, Inc. + * + * Second Life Viewer Source Code + * The source code in this file ("Source Code") is provided by Linden Lab + * to you under the terms of the GNU General Public License, version 2.0 + * ("GPL"), unless you have obtained a separate licensing agreement + * ("Other License"), formally executed by you and Linden Lab. Terms of + * the GPL can be found in doc/GPL-license.txt in this distribution, or + * online at http://secondlife.com/developers/opensource/gplv2 + * + * There are special exceptions to the terms and conditions of the GPL as + * it is applied to this Source Code. View the full text of the exception + * in the file doc/FLOSS-exception.txt in this software distribution, or + * online at http://secondlife.com/developers/opensource/flossexception + * + * By copying, modifying or distributing this software, you acknowledge + * that you have read and understood your obligations described above, + * and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ +#ifndef WINDGEN_H +#define WINDGEN_H + +#include "llcommon.h" +#include "llrand.h" + +template +class LLWindGen +{ +public: + LLWindGen() : + mTargetGain(0.f), + mTargetFreq(100.f), + mTargetPanGainR(0.5f), + mbuf0(0.0), + mbuf1(0.0), + mbuf2(0.0), + mbuf3(0.0), + mbuf4(0.0), + mbuf5(0.0), + mY0(0.0), + mY1(0.0), + mCurrentGain(0.f), + mCurrentFreq(100.f), + mCurrentPanGainR(0.5f) {}; + + static const U32 getInputSamplingRate() {return mInputSamplingRate;} + + // newbuffer = the buffer passed from the previous DSP unit. + // numsamples = length in samples-per-channel at this mix time. + // stride = number of bytes between start of each sample. + // NOTE: generates L/R interleaved stereo + MIXBUFFERFORMAT_T* windGenerate(MIXBUFFERFORMAT_T *newbuffer, int numsamples, int stride) + { + U8 *cursamplep = (U8*)newbuffer; + + double bandwidth = 50.0F; + double a0,b1,b2; + + // calculate resonant filter coeffs + b2 = exp(-(F_TWO_PI) * (bandwidth / mInputSamplingRate)); + + while (numsamples--) + { + mCurrentFreq = (float)((0.999 * mCurrentFreq) + (0.001 * mTargetFreq)); + mCurrentGain = (float)((0.999 * mCurrentGain) + (0.001 * mTargetGain)); + mCurrentPanGainR = (float)((0.999 * mCurrentPanGainR) + (0.001 * mTargetPanGainR)); + b1 = (-4.0 * b2) / (1.0 + b2) * cos(F_TWO_PI * (mCurrentFreq / mInputSamplingRate)); + 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; + +#if 1 // LLAE_WIND_PINK apply pinking filter + mbuf0 = 0.997f * mbuf0 + 0.0126502f * nextSample; + mbuf1 = 0.985f * mbuf1 + 0.0139083f * nextSample; + mbuf2 = 0.950f * mbuf2 + 0.0205439f * nextSample; + mbuf3 = 0.850f * mbuf3 + 0.0387225f * nextSample; + mbuf4 = 0.620f * mbuf4 + 0.0465932f * nextSample; + mbuf5 = 0.250f * mbuf5 + 0.1093477f * nextSample; + + nextSample = mbuf0 + mbuf1 + mbuf2 + mbuf3 + mbuf4 + mbuf5; +#endif + +#if 1 //LLAE_WIND_RESONANT // do a resonant filter on the noise + nextSample = (double)( a0 * nextSample - b1 * mY0 - b2 * mY1 ); + + mY1 = mY0; + mY0 = nextSample; +#endif + + nextSample *= mCurrentGain; + + MIXBUFFERFORMAT_T sample; + + sample = llfloor(((F32)nextSample*32768.f*(1.0f - mCurrentPanGainR))+0.5f); + *(MIXBUFFERFORMAT_T*)cursamplep = llclamp(sample, (MIXBUFFERFORMAT_T)-32768, (MIXBUFFERFORMAT_T)32767); + cursamplep += stride; + + sample = llfloor(((F32)nextSample*32768.f*mCurrentPanGainR)+0.5f); + *(MIXBUFFERFORMAT_T*)cursamplep = llclamp(sample, (MIXBUFFERFORMAT_T)-32768, (MIXBUFFERFORMAT_T)32767); + cursamplep += stride; + } + + return newbuffer; + } + + F32 mTargetGain; + F32 mTargetFreq; + F32 mTargetPanGainR; + +private: + static const U32 mInputSamplingRate = 44100; + F64 mbuf0; + F64 mbuf1; + F64 mbuf2; + F64 mbuf3; + F64 mbuf4; + F64 mbuf5; + F64 mY0; + F64 mY1; + F32 mCurrentGain; + F32 mCurrentFreq; + F32 mCurrentPanGainR; +}; + +#endif -- cgit v1.1 From 73d23531e60425993305dbcd6e1f12eb4da79d2c Mon Sep 17 00:00:00 2001 From: McCabe Maxsted Date: Sun, 23 Nov 2008 20:22:10 -0700 Subject: Trying to get openal working --- linden/indra/llaudio/audioengine_openal.cpp | 4 ++-- linden/indra/llaudio/listener_openal.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'linden/indra/llaudio') diff --git a/linden/indra/llaudio/audioengine_openal.cpp b/linden/indra/llaudio/audioengine_openal.cpp index 606d9f6..85d2080 100644 --- a/linden/indra/llaudio/audioengine_openal.cpp +++ b/linden/indra/llaudio/audioengine_openal.cpp @@ -321,10 +321,10 @@ void LLAudioEngine_OpenAL::updateWind(LLVector3 wind_vec, F32 camera_altitude) mMaxWindGain=1.0; - if (!mEnableWind) + if (mEnableWind) return; - if(!winddata) + if(winddata) return; if (mWindUpdateTimer.checkExpirationAndReset(LL_WIND_UPDATE_INTERVAL)) diff --git a/linden/indra/llaudio/listener_openal.h b/linden/indra/llaudio/listener_openal.h index 737343e..33063bb 100644 --- a/linden/indra/llaudio/listener_openal.h +++ b/linden/indra/llaudio/listener_openal.h @@ -35,8 +35,8 @@ #include "listener.h" -#include "AL/al.h" -#include "AL/alut.h" +#include "al.h" +#include "alut.h" class LLListener_OpenAL : public LLListener { -- cgit v1.1 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 +- 7 files changed, 689 insertions(+), 379 deletions(-) (limited to 'linden/indra/llaudio') 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; -- cgit v1.1 From b29b13ad98c5c79fd63bae10b4b099a03fa9dc35 Mon Sep 17 00:00:00 2001 From: Jacek Antonelli Date: Sat, 6 Dec 2008 14:03:10 -0600 Subject: Updated audio engine to LL's openal branch r1532. --- linden/indra/llaudio/audioengine.cpp | 184 ++++++- linden/indra/llaudio/audioengine.h | 56 +- linden/indra/llaudio/audioengine_openal.cpp | 767 ++++++++++------------------ linden/indra/llaudio/audioengine_openal.h | 107 ++-- 4 files changed, 502 insertions(+), 612 deletions(-) (limited to 'linden/indra/llaudio') diff --git a/linden/indra/llaudio/audioengine.cpp b/linden/indra/llaudio/audioengine.cpp index 5fb38c0..239981b 100644 --- a/linden/indra/llaudio/audioengine.cpp +++ b/linden/indra/llaudio/audioengine.cpp @@ -51,9 +51,6 @@ 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 @@ -77,7 +74,8 @@ void LLAudioEngine::setDefaults() mListenerp = NULL; - mMuted = FALSE; + mMuted = false; + mUserData = NULL; mLastStatus = 0; @@ -98,16 +96,20 @@ 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) +bool LLAudioEngine::init(const S32 num_channels, void* userdata) { setDefaults(); mNumChannels = num_channels; + mUserData = userdata; allocateListener(); @@ -126,6 +128,9 @@ void LLAudioEngine::shutdown() delete gAudioDecodeMgrp; gAudioDecodeMgrp = NULL; + // Clean up wind source + cleanupWind(); + // Clean up audio sources source_map::iterator iter_src; for (iter_src = mAllSources.begin(); iter_src != mAllSources.end(); iter_src++) @@ -146,22 +151,146 @@ void LLAudioEngine::shutdown() S32 i; for (i = 0; i < MAX_CHANNELS; i++) { - if (mChannels[i]) - { - delete mChannels[i]; - mChannels[i] = NULL; - } + delete mChannels[i]; + mChannels[i] = NULL; } // Clean up buffers for (i = 0; i < MAX_BUFFERS; i++) { - if (mBuffers[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) { - delete mBuffers[i]; - mBuffers[i] = NULL; + 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; + } + 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; } @@ -449,6 +578,8 @@ void LLAudioEngine::idle(F32 max_decode_time) // missed picking it up in all the places that can add // or request new data. startNextTransfer(); + + updateInternetStream(); } @@ -758,7 +889,7 @@ void LLAudioEngine::triggerSound(const LLUUID &audio_uuid, const LLUUID& owner_i LLUUID source_id; source_id.generate(); - LLAudioSource *asp = new LLAudioSource(source_id, owner_id, gain); + LLAudioSource *asp = new LLAudioSource(source_id, owner_id, gain, type); gAudiop->addAudioSource(asp); if (pos_global.isExactlyZero()) { @@ -1207,18 +1338,18 @@ void LLAudioEngine::assetCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::E // -LLAudioSource::LLAudioSource(const LLUUID& id, const LLUUID& owner_id, const F32 gain) +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), mType(type), - mAmbient(FALSE), - mLoop(FALSE), - mSyncMaster(FALSE), - mSyncSlave(FALSE), - mQueueSounds(FALSE), - mPlayedOnce(FALSE), + mAmbient(false), + mLoop(false), + mSyncMaster(false), + mSyncSlave(false), + mQueueSounds(false), + mPlayedOnce(false), mChannelp(NULL), mCurrentDatap(NULL), mQueuedDatap(NULL) @@ -1364,7 +1495,8 @@ bool LLAudioSource::play(const LLUUID &audio_uuid) bool LLAudioSource::isDone() { const F32 MAX_AGE = 60.f; - const F32 MAX_UNPLAYED_AGE = 30.f; + const F32 MAX_UNPLAYED_AGE = 15.f; + if (isLoop()) { // Looped sources never die on their own. @@ -1542,8 +1674,8 @@ LLAudioBuffer *LLAudioSource::getCurrentBuffer() LLAudioChannel::LLAudioChannel() : mCurrentSourcep(NULL), mCurrentBufferp(NULL), - mLoopedThisFrame(FALSE), - mWaiting(FALSE), + mLoopedThisFrame(false), + mWaiting(false), mSecondaryGain(1.0f) { } @@ -1609,8 +1741,8 @@ bool LLAudioChannel::updateBuffer() } // - // The source changed what buffer it's playing. Whe need to clean up the - // existing fmod channel + // The source changed what buffer it's playing. We need to clean up + // the existing channel // cleanup(); diff --git a/linden/indra/llaudio/audioengine.h b/linden/indra/llaudio/audioengine.h index 937a8e1..aff7759 100644 --- a/linden/indra/llaudio/audioengine.h +++ b/linden/indra/llaudio/audioengine.h @@ -69,6 +69,7 @@ class LLVFS; class LLAudioSource; class LLAudioData; class LLAudioChannel; +class LLAudioChannelOpenAL; class LLAudioBuffer; @@ -79,8 +80,10 @@ class LLAudioBuffer; class LLAudioEngine { + friend class LLAudioChannelOpenAL; // bleh. channel needs some listener methods. + public: - enum LLAudioType + typedef enum LLAudioType { AUDIO_TYPE_NONE = 0, AUDIO_TYPE_SFX = 1, @@ -93,9 +96,7 @@ public: virtual ~LLAudioEngine(); // initialization/startup/shutdown - //virtual BOOL init(); - - virtual BOOL init(const S32 num_channels); + virtual bool init(const S32 num_channels, void *userdata); virtual std::string getDriverName(bool verbose) = 0; virtual void shutdown(); @@ -140,7 +141,7 @@ public: 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); + bool preloadSound(const LLUUID &id); void addAudioSource(LLAudioSource *asp); void cleanupAudioSource(LLAudioSource *asp); @@ -149,15 +150,16 @@ public: LLAudioData *getAudioData(const LLUUID &audio_uuid); - 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; } + // 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); // use a value from 0.0 to 1.0, inclusive - virtual void setInternetStreamGain(F32 vol) { mInternetStreamGain = vol; } - virtual const std::string& getInternetStreamURL() { return LLStringUtil::null; } - virtual void InitStreamer() = 0; + virtual void setInternetStreamGain(F32 vol); + virtual const std::string& getInternetStreamURL(); // For debugging usage virtual LLVector3 getListenerPos(); @@ -193,11 +195,6 @@ 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); @@ -212,7 +209,8 @@ protected: protected: LLListener *mListenerp; - BOOL mMuted; + bool mMuted; + void* mUserData; S32 mLastStatus; @@ -242,6 +240,7 @@ protected: // Hack! Internet streams are treated differently from other sources! F32 mInternetStreamGain; + std::string mInternetStreamURL; F32 mNextWindUpdate; @@ -249,6 +248,7 @@ protected: private: void setDefaults(); + LLMediaBase *mInternetStreamMedia; }; @@ -264,7 +264,7 @@ 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); + 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 @@ -326,12 +326,12 @@ 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; @@ -420,8 +420,8 @@ 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 65203dd..002dfba 100644 --- a/linden/indra/llaudio/audioengine_openal.cpp +++ b/linden/indra/llaudio/audioengine_openal.cpp @@ -4,26 +4,26 @@ * support as a OpenAL 3D implementation * * $LicenseInfo:firstyear=2002&license=viewergpl$ - * + * * Copyright (c) 2002-2008, Linden Research, Inc. - * + * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab * to you under the terms of the GNU General Public License, version 2.0 * ("GPL"), unless you have obtained a separate licensing agreement * ("Other License"), formally executed by you and Linden Lab. Terms of * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 - * + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception - * + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, * and agree to abide by those obligations. - * + * * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. @@ -36,31 +36,29 @@ #include "audioengine_openal.h" #include "listener_openal.h" + LLAudioEngine_OpenAL::LLAudioEngine_OpenAL() + : + mWindGen(NULL), + mWindBuf(NULL), + mWindBufFreq(0), + mWindBufSamples(0), + mWindBufBytes(0), + mWindSource(AL_NONE), + mNumEmptyWindALBuffers(MAX_NUM_WIND_BUFFERS) { - - #if LL_GSTREAMER_ENABLED - mMedia_data = new LLMediaManagerData; - // initialize GStreamer - LLMediaImplGStreamer::startup( mMedia_data ); - - m_streamer=new LLMediaImplGStreamer (); - - if(!m_streamer) - { - llwarns << "LLAudioEngine_OpenAL::LLAudioEngine_OpenAL() Failed to create our private gstreamer audio instance" << llendl; - } - #endif } +// virtual LLAudioEngine_OpenAL::~LLAudioEngine_OpenAL() { } - -BOOL LLAudioEngine_OpenAL::init(const S32 num_channels) +// virtual +bool LLAudioEngine_OpenAL::init(const S32 num_channels, void* userdata) { - LLAudioEngine::init(num_channels); + mWindGen = NULL; + LLAudioEngine::init(num_channels, userdata); if(!alutInit(NULL, NULL)) { @@ -68,27 +66,39 @@ BOOL LLAudioEngine_OpenAL::init(const S32 num_channels) return false; } - initInternetStream(); - llinfos << "LLAudioEngine_OpenAL::init() OpenAL successfully initialized" << llendl; - llinfos << "LLAudioEngine_OpenAL::init() Speed of sound is: " << alGetFloat(AL_SPEED_OF_SOUND) << 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; + + ALint major = alutGetMajorVersion (); + ALint minor = alutGetMinorVersion (); + llinfos << "ALUT version: " << major << "." << minor << llendl; - return TRUE; + ALCdevice *device = alcGetContextsDevice(alcGetCurrentContext()); + + 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; + + return true; } +// virtual 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); - version << "OpenAL"; @@ -112,17 +122,7 @@ std::string LLAudioEngine_OpenAL::getDriverName(bool verbose) 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 -} - - +// virtual void LLAudioEngine_OpenAL::allocateListener() { mListenerp = (LLListener *) new LLListener_OpenAL(); @@ -132,6 +132,7 @@ void LLAudioEngine_OpenAL::allocateListener() } } +// virtual void LLAudioEngine_OpenAL::shutdown() { llinfos << "About to LLAudioEngine::shutdown()" << llendl; @@ -143,21 +144,11 @@ void LLAudioEngine_OpenAL::shutdown() llwarns << "Nuts." << llendl; llwarns << "LLAudioEngine_OpenAL::shutdown() ALUT shutdown failed: " << alutGetErrorString (alutGetError ()) << llendl; } - else - { - llinfos << "LLAudioEngine_OpenAL::shutdown() OpenAL successfully shut down" << llendl; - } - + + 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() @@ -177,44 +168,75 @@ void LLAudioEngine_OpenAL::setInternalGain(F32 gain) } LLAudioChannelOpenAL::LLAudioChannelOpenAL() + : + mALSource(AL_NONE), + mLastSamplePos(0) { - alGenSources(1, &ALSource); + alGenSources(1, &mALSource); } LLAudioChannelOpenAL::~LLAudioChannelOpenAL() { cleanup(); - alDeleteSources(1, &ALSource); + alDeleteSources(1, &mALSource); } void LLAudioChannelOpenAL::cleanup() { - alSourceStop(ALSource); + alSourceStop(mALSource); mCurrentBufferp = NULL; } void LLAudioChannelOpenAL::play() { + if (mALSource == AL_NONE) + { + llwarns << "Playing without a mALSource, aborting" << llendl; + return; + } + if(!isPlaying()) { - alSourcePlay(ALSource); - getSource()->setPlayedOnce(TRUE); + 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); + + llinfos << "Syncing with master at " << master_offset + << "sec" << llendl; + // *TODO: detect when this fails, maybe use AL_SAMPLE_ + alSourcef(mALSource, AL_SEC_OFFSET, master_offset); + } + } play(); } bool LLAudioChannelOpenAL::isPlaying() { - ALint state; - alGetSourcei(ALSource, AL_SOURCE_STATE, &state); - if(state == AL_PLAYING) + if (mALSource != AL_NONE) { - return TRUE; + ALint state; + alGetSourcei(mALSource, AL_SOURCE_STATE, &state); + if(state == AL_PLAYING) + { + return true; + } } + return false; } @@ -225,14 +247,48 @@ 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(ALSource, AL_BUFFER, bufferp->getBuffer()); - alSourcef(ALSource, AL_GAIN, mCurrentSourcep->getGain()); - alSourcei(ALSource, AL_LOOPING, mCurrentSourcep->isLoop() ? AL_TRUE : AL_FALSE); + 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()); + alSourcef(mALSource, AL_REFERENCE_DISTANCE, + gAudiop->mListenerp->getDistanceFactor()); } 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; +} + + void LLAudioChannelOpenAL::update3DPosition() { if(!mCurrentSourcep) @@ -241,30 +297,25 @@ void LLAudioChannelOpenAL::update3DPosition() } if (mCurrentSourcep->isAmbient()) { - 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 - { + 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); + alSourcei (mALSource, AL_SOURCE_RELATIVE, AL_TRUE); + } else { LLVector3 float_pos; float_pos.setVec(mCurrentSourcep->getPositionGlobal()); - alSourcefv(ALSource, AL_POSITION, float_pos.mV); - //llinfos << "LLAudioChannelOpenAL::update3DPosition() Velocity: " << mCurrentSourcep->getVelocity() << llendl; - 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); + alSourcefv(mALSource, AL_POSITION, float_pos.mV); + alSourcefv(mALSource, AL_VELOCITY, mCurrentSourcep->getVelocity().mV); + //alSource3f(mALSource, AL_DIRECTION, 0.0, 0.0, 0.0); + alSourcei (mALSource, AL_SOURCE_RELATIVE, AL_FALSE); } - //llinfos << "LLAudioChannelOpenAL::update3DPosition() Gain: " << mCurrentSourcep->getGain() << llendl; - alSourcef(ALSource, AL_GAIN, mCurrentSourcep->getGain()); + + alSourcef(mALSource, AL_GAIN, mCurrentSourcep->getGain() * getSecondaryGain()); } LLAudioBufferOpenAL::LLAudioBufferOpenAL() { - ALBuffer = AL_NONE; + mALBuffer = AL_NONE; } LLAudioBufferOpenAL::~LLAudioBufferOpenAL() @@ -274,33 +325,49 @@ LLAudioBufferOpenAL::~LLAudioBufferOpenAL() void LLAudioBufferOpenAL::cleanup() { - if(ALBuffer != AL_NONE) + if(mALBuffer != AL_NONE) { - alDeleteBuffers(1, &ALBuffer); + alDeleteBuffers(1, &mALBuffer); + mALBuffer = AL_NONE; } } bool LLAudioBufferOpenAL::loadWAV(const std::string& filename) { cleanup(); - ALBuffer = alutCreateBufferFromFile(filename.c_str()); - if(ALBuffer == AL_NONE) + mALBuffer = alutCreateBufferFromFile(filename.c_str()); + if(mALBuffer == AL_NONE) { - return FALSE; + 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; } return true; } - U32 LLAudioBufferOpenAL::getLength() { - if(ALBuffer == AL_NONE) + if(mALBuffer == AL_NONE) { return 0; } ALint length; - alGetBufferi(ALBuffer, AL_SIZE, &length); + alGetBufferi(mALBuffer, AL_SIZE, &length); return length >> 2; } @@ -308,65 +375,78 @@ U32 LLAudioBufferOpenAL::getLength() void LLAudioEngine_OpenAL::initWind() { + ALenum error; + llinfos << "LLAudioEngine_OpenAL::initWind() start" << llendl; - if (true) - return; - - llinfos << "initWind() start" << llendl; + mNumEmptyWindALBuffers = MAX_NUM_WIND_BUFFERS; - alGenBuffers(mNumWindBuffers,mWindBuffers); + alGetError(); /* clear error */ + alGenSources(1,&mWindSource); - checkALError(); - - // ok lets make a wind buffer now - for(int counter=0;counter; - alSourcePlay(mWindSource); - checkALError(); + mWindBufFreq = mWindGen->getInputSamplingRate(); + mWindBufSamples = llceil(mWindBufFreq * WIND_BUFFER_SIZE_SEC); + mWindBufBytes = mWindBufSamples * 2 /*stereo*/ * sizeof(WIND_SAMPLE_T); - llinfos << "LLAudioEngine_OpenAL::initWind() done" << llendl; + mWindBuf = new WIND_SAMPLE_T [mWindBufSamples * 2 /*stereo*/]; + if(mWindBuf==NULL) + { + llerrs << "LLAudioEngine_OpenAL::initWind() Error creating wind memory buffer" << llendl; + mEnableWind=false; + } + + llinfos << "LLAudioEngine_OpenAL::initWind() done" << llendl; } -void LLAudioEngine_OpenAL::cleanupWind(){ +void LLAudioEngine_OpenAL::cleanupWind() +{ llinfos << "LLAudioEngine_OpenAL::cleanupWind()" << llendl; - alDeleteBuffers(mNumWindBuffers,mWindBuffers); - alDeleteSources(1, &mWindSource); + if (mWindSource != AL_NONE) + { + // detach and delete all outstanding buffers on the wind source + alSourceStop(mWindSource); + int processed; + alGetSourcei(mWindSource, AL_BUFFERS_PROCESSED, &processed); + while (processed--) + { + ALuint buffer = AL_NONE; + alSourceUnqueueBuffers(mWindSource, 1, &buffer); + alDeleteBuffers(1, &buffer); + } - checkALError(); -} + // delete the wind source itself + alDeleteSources(1, &mWindSource); -void LLAudioEngine_OpenAL::checkALError() -{ - ALenum error; - if((error=alGetError()) != AL_NO_ERROR) - llwarns << "LLAudioEngine_OpenAL Error: "<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); + + 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); - - } - - int processed; - alGetSourcei(mWindSource, AL_BUFFERS_PROCESSED, &processed); - - while(processed--) - { - ALuint buffer; - alSourceUnqueueBuffers(mWindSource, 1, &buffer); - checkALError(); - alBufferData(buffer,AL_FORMAT_STEREO16,windDSP((void*)mWindData,mWindDataSize/mBytesPerSample),mWindDataSize,mSampleRate); - checkALError(); - alSourceQueueBuffers(mWindSource, 1, &buffer); - checkALError(); + 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); } - 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; + // ok lets make a wind buffer now - #if LL_GSTREAMER_ENABLED - if( ! m_streamer->addCommand(LLMediaBase::COMMAND_STOP)) - { - llinfos << "attempting to stop stream failed!" << llendl; - } - m_streamer->updateMedia(); - #endif - mInternetStreamURL.erase(); -} + int 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); -void LLAudioEngine_OpenAL::pauseInternetStream(int pause) -{ - #if LL_GSTREAMER_ENABLED - if(!m_streamer) - return; - // DCF_DEBUG - llinfos << "entered LLAudioEngine_OpenAL::pauseInternetStream()" << llendl; + //llinfos << "mNumEmptyWindALBuffers: " << mNumEmptyWindALBuffers <<" (" << unprocessed << ":" << processed << ")" << llendl; - if(pause) + while(processed--) // unqueue old buffers { - if(!m_streamer->addCommand(LLMediaBase::COMMAND_PAUSE)) + ALuint buffer; + int error; + alGetError(); /* clear error */ + alSourceUnqueueBuffers(mWindSource, 1, &buffer); + error = alGetError(); + if(error != AL_NO_ERROR) { - llinfos << "attempting to pause stream failed!" << llendl; + llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping (unqueuing) buffers" << llendl; } - m_streamer->updateMedia(); - } - else - { - if( ! m_streamer->addCommand(LLMediaBase::COMMAND_START)) + else { - llinfos << "attempting to pause stream failed!" << llendl; + alDeleteBuffers(1, &buffer); } - m_streamer->updateMedia(); } - #endif -} - -int LLAudioEngine_OpenAL::isInternetStreamPlaying() -{ + unprocessed += mNumEmptyWindALBuffers; + while (mNumEmptyWindALBuffers > 0) // fill+queue new buffers + { + ALuint buffer; + alGetError(); /* clear error */ + alGenBuffers(1,&buffer); + if((error=alGetError()) != AL_NO_ERROR) + { + llwarns << "LLAudioEngine_OpenAL::initWind() Error creating wind buffer: " << error << llendl; + break; + } - #if LL_GSTREAMER_ENABLED - if(!m_streamer) - return 0; + alBufferData(buffer, + AL_FORMAT_STEREO16, + mWindGen->windGenerate(mWindBuf, + mWindBufSamples, 2), + mWindBufBytes, + mWindBufFreq); + error = alGetError(); + if(error != AL_NO_ERROR) + llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping (bufferdata) buffers" << llendl; + + alSourceQueueBuffers(mWindSource, 1, &buffer); + error = alGetError(); + if(error != AL_NO_ERROR) + llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping (queuing) buffers" << llendl; - if(m_streamer->getStatus() == LLMediaBase::STATUS_STARTED) - { - return 1; // Active and playing + --mNumEmptyWindALBuffers; } - if(m_streamer->getStatus() == LLMediaBase::STATUS_PAUSED) + int playing; + alGetSourcei(mWindSource, AL_SOURCE_STATE, &playing); + if(playing != AL_PLAYING) { - 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 -} - + alSourcePlay(mWindSource); -const std::string& LLAudioEngine_OpenAL::getInternetStreamURL() -{ - return mInternetStreamURL; + llinfos << "Wind had stopped - probably ran out of buffers - restarting: " << (unprocessed+mNumEmptyWindALBuffers) << " now queued." << llendl; + } } diff --git a/linden/indra/llaudio/audioengine_openal.h b/linden/indra/llaudio/audioengine_openal.h index 5d5c7d8..b03153a 100644 --- a/linden/indra/llaudio/audioengine_openal.h +++ b/linden/indra/llaudio/audioengine_openal.h @@ -3,27 +3,28 @@ * @brief implementation of audio engine using OpenAL * support as a OpenAL 3D implementation * - * Copyright (c) 2002-2008, Linden Research, Inc. * * $LicenseInfo:firstyear=2002&license=viewergpl$ - * + * + * Copyright (c) 2002-2008, Linden Research, Inc. + * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab * to you under the terms of the GNU General Public License, version 2.0 * ("GPL"), unless you have obtained a separate licensing agreement * ("Other License"), formally executed by you and Linden Lab. Terms of * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 - * + * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * * There are special exceptions to the terms and conditions of the GPL as * it is applied to this Source Code. View the full text of the exception * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception - * + * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception + * * By copying, modifying or distributing this software, you acknowledge * that you have read and understood your obligations described above, * and agree to abide by those obligations. - * + * * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, * COMPLETENESS OR PERFORMANCE. @@ -31,16 +32,12 @@ */ -#ifndef LL_AUDIOENGINE_OpenAL_H -#define LL_AUDIOENGINE_OpenAL_H - -#include +#ifndef LL_AUDIOENGINE_OPENAL_H +#define LL_AUDIOENGINE_OPENAL_H #include "audioengine.h" #include "listener_openal.h" -#include "llmediamanager.h" -#include "llmediaimplgstreamer.h" -#include "llrand.h" +#include "windgen.h" class LLAudioEngine_OpenAL : public LLAudioEngine { @@ -48,58 +45,34 @@ class LLAudioEngine_OpenAL : public LLAudioEngine LLAudioEngine_OpenAL(); virtual ~LLAudioEngine_OpenAL(); - virtual BOOL init(const S32 num_channels); - virtual std::string getDriverName(bool verbose); + virtual bool init(const S32 num_channels, void *user_data); + 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(); - // 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; + /*virtual*/ void initWind(); + /*virtual*/ void cleanupWind(); + /*virtual*/ void updateWind(LLVector3 direction, F32 camera_altitude); + + private: void * windDSP(void *newbuffer, int length); -#if LL_GSTREAMER_ENABLED - LLMediaManagerData * mMedia_data; - LLMediaImplGStreamer * m_streamer; -#endif + typedef S16 WIND_SAMPLE_T; + LLWindGen *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 = 0.05f; // 1/20th sec }; class LLAudioChannelOpenAL : public LLAudioChannel @@ -108,16 +81,17 @@ class LLAudioChannelOpenAL : public LLAudioChannel LLAudioChannelOpenAL(); virtual ~LLAudioChannelOpenAL(); protected: - void play(); - void playSynced(LLAudioChannel *channelp); - void cleanup(); - bool isPlaying(); + /*virtual*/ void play(); + /*virtual*/ void playSynced(LLAudioChannel *channelp); + /*virtual*/ void cleanup(); + /*virtual*/ bool isPlaying(); - bool updateBuffer(); - void update3DPosition(); - void updateLoop(){}; + /*virtual*/ bool updateBuffer(); + /*virtual*/ void update3DPosition(); + /*virtual*/ void updateLoop(); - ALuint ALSource; + ALuint mALSource; + ALint mLastSamplePos; }; class LLAudioBufferOpenAL : public LLAudioBuffer{ @@ -131,8 +105,9 @@ class LLAudioBufferOpenAL : public LLAudioBuffer{ friend class LLAudioChannelOpenAL; protected: void cleanup(); - ALuint getBuffer(){return ALBuffer;} - ALuint ALBuffer; + ALuint getBuffer() {return mALBuffer;} + + ALuint mALBuffer; }; #endif -- cgit v1.1 From 324dfa1561efba6492b72ad4d9306e69b9124776 Mon Sep 17 00:00:00 2001 From: Anders Arnholm Date: Fri, 19 Dec 2008 10:12:25 +0100 Subject: Clean up logging to used standard LL metods. --- linden/indra/llaudio/audioengine.cpp | 56 +++++++++++----------- linden/indra/llaudio/audioengine_openal.cpp | 74 ++++++++++++++--------------- 2 files changed, 65 insertions(+), 65 deletions(-) (limited to 'linden/indra/llaudio') diff --git a/linden/indra/llaudio/audioengine.cpp b/linden/indra/llaudio/audioengine.cpp index 239981b..da9bcba 100644 --- a/linden/indra/llaudio/audioengine.cpp +++ b/linden/indra/llaudio/audioengine.cpp @@ -116,7 +116,7 @@ bool LLAudioEngine::init(const S32 num_channels, void* userdata) // Initialize the decode manager gAudioDecodeMgrp = new LLAudioDecodeMgr; - llinfos << "LLAudioEngine::init() AudioEngine successfully initialized" << llendl; + LL_INFOS("AudioEngine") << "LLAudioEngine::init() AudioEngine successfully initialized" << llendl; return true; } @@ -171,7 +171,7 @@ void LLAudioEngine::shutdown() // virtual void LLAudioEngine::startInternetStream(const std::string& url) { - llinfos << "entered startInternetStream()" << llendl; + LL_INFOS("AudioEngine") << "entered startInternetStream()" << llendl; if (!mInternetStreamMedia) { @@ -179,7 +179,7 @@ void LLAudioEngine::startInternetStream(const std::string& url) if (mgr) { mInternetStreamMedia = mgr->createSourceFromMimeType(LLURI(url).scheme(), "audio/mpeg"); // assumes that whatever media implementation supports mp3 also supports vorbis. - llinfos << "mInternetStreamMedia is now " << mInternetStreamMedia << llendl; + LL_INFOS("AudioEngine") << "mInternetStreamMedia is now " << mInternetStreamMedia << llendl; } } @@ -187,14 +187,14 @@ void LLAudioEngine::startInternetStream(const std::string& url) return; if (!url.empty()) { - llinfos << "Starting internet stream: " << url << llendl; + LL_INFOS("AudioEngine") << "Starting internet stream: " << url << llendl; mInternetStreamURL = url; mInternetStreamMedia->navigateTo ( url ); - llinfos << "Playing....." << llendl; + LL_INFOS("AudioEngine") << "Playing....." << llendl; mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_START); mInternetStreamMedia->updateMedia(); } else { - llinfos << "setting stream to NULL"<< llendl; + LL_INFOS("AudioEngine") << "setting stream to NULL"<< llendl; mInternetStreamURL.clear(); mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_STOP); mInternetStreamMedia->updateMedia(); @@ -205,12 +205,12 @@ void LLAudioEngine::startInternetStream(const std::string& url) // virtual void LLAudioEngine::stopInternetStream() { - llinfos << "entered stopInternetStream()" << llendl; + LL_INFOS("AudioEngine") << "entered stopInternetStream()" << llendl; if(mInternetStreamMedia) { if( ! mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_STOP)){ - llinfos << "attempting to stop stream failed!" << llendl; + LL_INFOS("AudioEngine") << "attempting to stop stream failed!" << llendl; } mInternetStreamMedia->updateMedia(); } @@ -221,7 +221,7 @@ void LLAudioEngine::stopInternetStream() // virtual void LLAudioEngine::pauseInternetStream(int pause) { - llinfos << "entered pauseInternetStream()" << llendl; + LL_INFOS("AudioEngine") << "entered pauseInternetStream()" << llendl; if(!mInternetStreamMedia) return; @@ -230,12 +230,12 @@ void LLAudioEngine::pauseInternetStream(int pause) { if(! mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_PAUSE)) { - llinfos << "attempting to pause stream failed!" << llendl; + LL_INFOS("AudioEngine") << "attempting to pause stream failed!" << llendl; } } else { if(! mInternetStreamMedia->addCommand(LLMediaBase::COMMAND_START)) { - llinfos << "attempting to unpause stream failed!" << llendl; + LL_INFOS("AudioEngine") << "attempting to unpause stream failed!" << llendl; } } mInternetStreamMedia->updateMedia(); @@ -386,7 +386,7 @@ void LLAudioEngine::idle(F32 max_decode_time) LLAudioChannel *channelp = getFreeChannel(max_priority); if (channelp) { - //llinfos << "Replacing source in channel due to priority!" << llendl; + //LL_INFOS("AudioEngine") << "Replacing source in channel due to priority!" << llendl; max_sourcep->setChannel(channelp); channelp->setSource(max_sourcep); if (max_sourcep->isSyncSlave()) @@ -553,7 +553,7 @@ void LLAudioEngine::idle(F32 max_decode_time) { if (!mBuffers[i]->mInUse && mBuffers[i]->mLastUseTimer.getElapsedTimeF32() > 30.f) { - //llinfos << "Flushing unused buffer!" << llendl; + //LL_INFOS("AudioEngine") << "Flushing unused buffer!" << llendl; mBuffers[i]->mAudioDatap->mBufferp = NULL; delete mBuffers[i]; mBuffers[i] = NULL; @@ -666,8 +666,8 @@ LLAudioBuffer *LLAudioEngine::getFreeBuffer() if (buffer_id >= 0) { - llinfos << "Taking over unused buffer " << buffer_id << llendl; - //llinfos << "Flushing unused buffer!" << llendl; + LL_INFOS("AudioEngine") << "Taking over unused buffer " << buffer_id << llendl; + //LL_INFOS("AudioEngine") << "Flushing unused buffer!" << llendl; mBuffers[buffer_id]->mAudioDatap->mBufferp = NULL; delete mBuffers[buffer_id]; mBuffers[buffer_id] = createBuffer(); @@ -879,7 +879,7 @@ void LLAudioEngine::triggerSound(const LLUUID &audio_uuid, const LLUUID& owner_i 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; + //LL_INFOS("AudioEngine") << "Localized: " << audio_uuid << llendl; if (mMuted) { @@ -1101,10 +1101,10 @@ bool LLAudioEngine::hasLocalFile(const LLUUID &uuid) void LLAudioEngine::startNextTransfer() { - //llinfos << "LLAudioEngine::startNextTransfer()" << llendl; + //LL_INFOS("AudioEngine") << "LLAudioEngine::startNextTransfer()" << llendl; if (mCurrentTransfer.notNull() || getMuted()) { - //llinfos << "Transfer in progress, aborting" << llendl; + //LL_INFOS("AudioEngine") << "Transfer in progress, aborting" << llendl; return; } @@ -1285,7 +1285,7 @@ void LLAudioEngine::startNextTransfer() if (asset_id.notNull()) { - llinfos << "Getting asset data for: " << asset_id << llendl; + LL_INFOS("AudioEngine") << "Getting asset data for: " << asset_id << llendl; gAudiop->mCurrentTransfer = asset_id; gAudiop->mCurrentTransferTimer.reset(); gAssetStorage->getAssetData(asset_id, LLAssetType::AT_SOUND, @@ -1293,7 +1293,7 @@ void LLAudioEngine::startNextTransfer() } else { - //llinfos << "No pending transfers?" << llendl; + //LL_INFOS("AudioEngine") << "No pending transfers?" << llendl; } } @@ -1303,7 +1303,7 @@ void LLAudioEngine::assetCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::E { if (result_code) { - llinfos << "Boom, error in audio file transfer: " << LLAssetStorage::getErrorString( result_code ) << " (" << result_code << ")" << llendl; + LL_INFOS("AudioEngine") << "Boom, error in audio file transfer: " << LLAssetStorage::getErrorString( result_code ) << " (" << result_code << ")" << llendl; // Need to mark data as bad to avoid constant rerequests. LLAudioData *adp = gAudiop->getAudioData(uuid); if (adp) @@ -1524,7 +1524,7 @@ bool LLAudioSource::isDone() { // We don't have a channel assigned, and it's been // over 5 seconds since we tried to play it. Don't bother. - //llinfos << "No channel assigned, source is done" << llendl; + //LL_INFOS("AudioEngine") << "No channel assigned, source is done" << llendl; return true; } else @@ -1684,7 +1684,7 @@ LLAudioChannel::LLAudioChannel() : LLAudioChannel::~LLAudioChannel() { // Need to disconnect any sources which are using this channel. - //llinfos << "Cleaning up audio channel" << llendl; + //LL_INFOS("AudioEngine") << "Cleaning up audio channel" << llendl; if (mCurrentSourcep) { mCurrentSourcep->setChannel(NULL); @@ -1695,12 +1695,12 @@ LLAudioChannel::~LLAudioChannel() void LLAudioChannel::setSource(LLAudioSource *sourcep) { - //llinfos << this << ": setSource(" << sourcep << ")" << llendl; + //LL_INFOS("AudioEngine") << this << ": setSource(" << sourcep << ")" << llendl; if (!sourcep) { // Clearing the source for this channel, don't need to do anything. - //llinfos << "Clearing source for channel" << llendl; + //LL_INFOS("AudioEngine") << "Clearing source for channel" << llendl; cleanup(); mCurrentSourcep = NULL; mWaiting = false; @@ -1710,7 +1710,7 @@ void LLAudioChannel::setSource(LLAudioSource *sourcep) if (sourcep == mCurrentSourcep) { // Don't reallocate the channel, this will make FMOD goofy. - //llinfos << "Calling setSource with same source!" << llendl; + //LL_INFOS("AudioEngine") << "Calling setSource with same source!" << llendl; } mCurrentSourcep = sourcep; @@ -1802,7 +1802,7 @@ bool LLAudioData::load() if (mBufferp) { // We already have this sound in a buffer, don't do anything. - llinfos << "Already have a buffer for this sound, don't bother loading!" << llendl; + LL_INFOS("AudioEngine") << "Already have a buffer for this sound, don't bother loading!" << llendl; return true; } @@ -1810,7 +1810,7 @@ bool LLAudioData::load() if (!mBufferp) { // No free buffers, abort. - llinfos << "Not able to allocate a new audio buffer, aborting." << llendl; + LL_INFOS("AudioEngine") << "Not able to allocate a new audio buffer, aborting." << llendl; return false; } diff --git a/linden/indra/llaudio/audioengine_openal.cpp b/linden/indra/llaudio/audioengine_openal.cpp index 002dfba..f13a5fa 100644 --- a/linden/indra/llaudio/audioengine_openal.cpp +++ b/linden/indra/llaudio/audioengine_openal.cpp @@ -62,33 +62,33 @@ bool LLAudioEngine_OpenAL::init(const S32 num_channels, void* userdata) if(!alutInit(NULL, NULL)) { - llwarns << "LLAudioEngine_OpenAL::init() ALUT initialization failed: " << alutGetErrorString (alutGetError ()) << llendl; + LL_WARNS("OpenAL") << "LLAudioEngine_OpenAL::init() ALUT initialization failed: " << alutGetErrorString (alutGetError ()) << LL_ENDL; return false; } - llinfos << "LLAudioEngine_OpenAL::init() OpenAL successfully initialized" << llendl; + LL_INFOS("OpenAL") << "LLAudioEngine_OpenAL::init() OpenAL successfully initialized" << LL_ENDL; - 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; + LL_INFOS("OpenAL") << "OpenAL version: " + << ll_safe_string(alGetString(AL_VERSION)) << LL_ENDL; + LL_INFOS("OpenAL") << "OpenAL vendor: " + << ll_safe_string(alGetString(AL_VENDOR)) << LL_ENDL; + LL_INFOS("OpenAL") << "OpenAL renderer: " + << ll_safe_string(alGetString(AL_RENDERER)) << LL_ENDL; ALint major = alutGetMajorVersion (); ALint minor = alutGetMinorVersion (); - llinfos << "ALUT version: " << major << "." << minor << llendl; + LL_INFOS("OpenAL") << "ALUT version: " << major << "." << minor << LL_ENDL; ALCdevice *device = alcGetContextsDevice(alcGetCurrentContext()); alcGetIntegerv(device, ALC_MAJOR_VERSION, 1, &major); alcGetIntegerv(device, ALC_MAJOR_VERSION, 1, &minor); - llinfos << "ALC version: " << major << "." << minor << llendl; + LL_INFOS("OpenAL") << "ALC version: " << major << "." << minor << LL_ENDL; - llinfos << "ALC default device: " + LL_INFOS("OpenAL") << "ALC default device: " << ll_safe_string(alcGetString(device, ALC_DEFAULT_DEVICE_SPECIFIER)) - << llendl; + << LL_ENDL; return true; } @@ -128,24 +128,24 @@ void LLAudioEngine_OpenAL::allocateListener() mListenerp = (LLListener *) new LLListener_OpenAL(); if(!mListenerp) { - llwarns << "LLAudioEngine_OpenAL::allocateListener() Listener creation failed" << llendl; + LL_WARNS("OpenAL") << "LLAudioEngine_OpenAL::allocateListener() Listener creation failed" << LL_ENDL; } } // virtual void LLAudioEngine_OpenAL::shutdown() { - llinfos << "About to LLAudioEngine::shutdown()" << llendl; + LL_INFOS("OpenAL") << "About to LLAudioEngine::shutdown()" << LL_ENDL; LLAudioEngine::shutdown(); - llinfos << "About to alutExit()" << llendl; + LL_INFOS("OpenAL") << "About to alutExit()" << LL_ENDL; if(!alutExit()) { - llwarns << "Nuts." << llendl; - llwarns << "LLAudioEngine_OpenAL::shutdown() ALUT shutdown failed: " << alutGetErrorString (alutGetError ()) << llendl; + LL_WARNS("OpenAL") << "Nuts." << LL_ENDL; + LL_WARNS("OpenAL") << "LLAudioEngine_OpenAL::shutdown() ALUT shutdown failed: " << alutGetErrorString (alutGetError ()) << LL_ENDL; } - llinfos << "LLAudioEngine_OpenAL::shutdown() OpenAL successfully shut down" << llendl; + LL_INFOS("OpenAL") << "LLAudioEngine_OpenAL::shutdown() OpenAL successfully shut down" << LL_ENDL; delete mListenerp; mListenerp = NULL; @@ -163,7 +163,7 @@ LLAudioChannel *LLAudioEngine_OpenAL::createChannel() void LLAudioEngine_OpenAL::setInternalGain(F32 gain) { - //llinfos << "LLAudioEngine_OpenAL::setInternalGain() Gain: " << gain << llendl; + //LL_INFOS("OpenAL") << "LLAudioEngine_OpenAL::setInternalGain() Gain: " << gain << LL_ENDL; alListenerf(AL_GAIN, gain); } @@ -191,7 +191,7 @@ void LLAudioChannelOpenAL::play() { if (mALSource == AL_NONE) { - llwarns << "Playing without a mALSource, aborting" << llendl; + LL_WARNS("OpenAL") << "Playing without a mALSource, aborting" << LL_ENDL; return; } @@ -216,8 +216,8 @@ void LLAudioChannelOpenAL::playSynced(LLAudioChannel *channelp) alGetSourcef(masterchannelp->mALSource, AL_SEC_OFFSET, &master_offset); - llinfos << "Syncing with master at " << master_offset - << "sec" << llendl; + LL_INFOS("OpenAL") << "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); } @@ -341,18 +341,18 @@ bool LLAudioBufferOpenAL::loadWAV(const std::string& filename) ALenum error = alutGetError(); if (gDirUtilp->fileExists(filename)) { - llwarns << + LL_WARNS("OpenAL") << "LLAudioBufferOpenAL::loadWAV() Error loading " << filename - << " " << alutGetErrorString(error) << llendl; + << " " << alutGetErrorString(error) << LL_ENDL; } else { // It's common for the file to not actually exist. - lldebugs << + LL_DEBUGS("OpenAL") << "LLAudioBufferOpenAL::loadWAV() Error loading " << filename - << " " << alutGetErrorString(error) << llendl; + << " " << alutGetErrorString(error) << LL_ENDL; } return false; } @@ -376,7 +376,7 @@ U32 LLAudioBufferOpenAL::getLength() void LLAudioEngine_OpenAL::initWind() { ALenum error; - llinfos << "LLAudioEngine_OpenAL::initWind() start" << llendl; + LL_INFOS("OpenAL") << "LLAudioEngine_OpenAL::initWind() start" << LL_ENDL; mNumEmptyWindALBuffers = MAX_NUM_WIND_BUFFERS; @@ -386,7 +386,7 @@ void LLAudioEngine_OpenAL::initWind() if((error=alGetError()) != AL_NO_ERROR) { - llwarns << "LLAudioEngine_OpenAL::initWind() Error creating wind sources: "<; @@ -399,16 +399,16 @@ void LLAudioEngine_OpenAL::initWind() if(mWindBuf==NULL) { - llerrs << "LLAudioEngine_OpenAL::initWind() Error creating wind memory buffer" << llendl; + LL_ERRS("OpenAL") << "LLAudioEngine_OpenAL::initWind() Error creating wind memory buffer" << LL_ENDL; mEnableWind=false; } - llinfos << "LLAudioEngine_OpenAL::initWind() done" << llendl; + LL_INFOS("OpenAL") << "LLAudioEngine_OpenAL::initWind() done" << LL_ENDL; } void LLAudioEngine_OpenAL::cleanupWind() { - llinfos << "LLAudioEngine_OpenAL::cleanupWind()" << llendl; + LL_INFOS("OpenAL") << "LLAudioEngine_OpenAL::cleanupWind()" << LL_ENDL; if (mWindSource != AL_NONE) { @@ -484,7 +484,7 @@ void LLAudioEngine_OpenAL::updateWind(LLVector3 wind_vec, F32 camera_altitude) mNumEmptyWindALBuffers = llmin(mNumEmptyWindALBuffers + processed * 3 - unprocessed, MAX_NUM_WIND_BUFFERS-unprocessed); mNumEmptyWindALBuffers = llmax(mNumEmptyWindALBuffers, 0); - //llinfos << "mNumEmptyWindALBuffers: " << mNumEmptyWindALBuffers <<" (" << unprocessed << ":" << processed << ")" << llendl; + //LL_INFOS("OpenAL") << "mNumEmptyWindALBuffers: " << mNumEmptyWindALBuffers <<" (" << unprocessed << ":" << processed << ")" << LL_ENDL; while(processed--) // unqueue old buffers { @@ -495,7 +495,7 @@ void LLAudioEngine_OpenAL::updateWind(LLVector3 wind_vec, F32 camera_altitude) error = alGetError(); if(error != AL_NO_ERROR) { - llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping (unqueuing) buffers" << llendl; + LL_WARNS("OpenAL") << "LLAudioEngine_OpenAL::updateWind() error swapping (unqueuing) buffers" << LL_ENDL; } else { @@ -511,7 +511,7 @@ void LLAudioEngine_OpenAL::updateWind(LLVector3 wind_vec, F32 camera_altitude) alGenBuffers(1,&buffer); if((error=alGetError()) != AL_NO_ERROR) { - llwarns << "LLAudioEngine_OpenAL::initWind() Error creating wind buffer: " << error << llendl; + LL_WARNS("OpenAL") << "LLAudioEngine_OpenAL::initWind() Error creating wind buffer: " << error << LL_ENDL; break; } @@ -523,12 +523,12 @@ void LLAudioEngine_OpenAL::updateWind(LLVector3 wind_vec, F32 camera_altitude) mWindBufFreq); error = alGetError(); if(error != AL_NO_ERROR) - llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping (bufferdata) buffers" << llendl; + LL_WARNS("OpenAL") << "LLAudioEngine_OpenAL::updateWind() error swapping (bufferdata) buffers" << LL_ENDL; alSourceQueueBuffers(mWindSource, 1, &buffer); error = alGetError(); if(error != AL_NO_ERROR) - llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping (queuing) buffers" << llendl; + LL_WARNS("OpenAL") << "LLAudioEngine_OpenAL::updateWind() error swapping (queuing) buffers" << LL_ENDL; --mNumEmptyWindALBuffers; } @@ -539,6 +539,6 @@ void LLAudioEngine_OpenAL::updateWind(LLVector3 wind_vec, F32 camera_altitude) { alSourcePlay(mWindSource); - llinfos << "Wind had stopped - probably ran out of buffers - restarting: " << (unprocessed+mNumEmptyWindALBuffers) << " now queued." << llendl; + LL_INFOS("OpenAL") << "Wind had stopped - probably ran out of buffers - restarting: " << (unprocessed+mNumEmptyWindALBuffers) << " now queued." << LL_ENDL; } } -- cgit v1.1