From 613c6755e9ada079d345ad27fa9ecb2638a33ee5 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood Date: Fri, 3 Jun 2011 22:51:46 +0200 Subject: [PATCH] Fix sound explorer. Looping sounds were always showing as 'Looping', even after they stopped. Detection of stopped sounds is much better now. Instead of only logging a sound as stopped when the audio source is destroyed, we now detect whether or not it is associated with an audio channel or not (the normal way to stop a sound is to set the channel to NULL). This is still a bit fuzzy, since an audio channel doesn't necessarily have to be playing, but states where an audio source is associated with a non-playing audio channel are only short temporary states that don't affect the usefulness of the sound explorer. --- indra/llaudio/llaudioengine.cpp | 59 ++++++++++++++---------- indra/llaudio/llaudioengine.h | 21 +++++++-- indra/newview/llfloaterexploresounds.cpp | 29 ++++-------- 3 files changed, 61 insertions(+), 48 deletions(-) diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp index b61d934dd..fa5444cf5 100644 --- a/indra/llaudio/llaudioengine.cpp +++ b/indra/llaudio/llaudioengine.cpp @@ -1336,16 +1336,17 @@ LLAudioSource::LLAudioSource(const LLUUID& id, const LLUUID& owner_id, const F32 LLAudioSource::~LLAudioSource() { + // + // Record destruction of LLAudioSource object. + if(mType != LLAudioEngine::AUDIO_TYPE_UI) + logSoundStop(mLogID, true); + // if (mChannelp) { // Stop playback of this sound mChannelp->setSource(NULL); - mChannelp = NULL; + setChannel(NULL); } - // - if(mType != LLAudioEngine::AUDIO_TYPE_UI) // && mSourceID.notNull()) - logSoundStop(mLogID); - // } @@ -1356,10 +1357,17 @@ void LLAudioSource::setChannel(LLAudioChannel *channelp) return; } + // + if (!channelp) + { + if(mType != LLAudioEngine::AUDIO_TYPE_UI) + logSoundStop(mLogID, false); + } + // + mChannelp = channelp; } - void LLAudioSource::update() { if (!getCurrentBuffer()) @@ -1434,10 +1442,6 @@ bool LLAudioSource::setupChannel() bool LLAudioSource::play(const LLUUID &audio_uuid) { - // - if(mType != LLAudioEngine::AUDIO_TYPE_UI) //&& mSourceID.notNull()) - logSoundPlay(mLogID, this, mPositionGlobal, mType, audio_uuid, mOwnerID, mSourceID, mIsTrigger, mLoop); // is mID okay for source id? - // // Special abuse of play(); don't play a sound, but kill it. if (audio_uuid.isNull()) { @@ -1453,6 +1457,11 @@ bool LLAudioSource::play(const LLUUID &audio_uuid) return false; } + // + if(mType != LLAudioEngine::AUDIO_TYPE_UI) //&& mSourceID.notNull()) + logSoundPlay(this, audio_uuid); + // + // Reset our age timeout if someone attempts to play the source. mAgeTimer.reset(); @@ -1846,36 +1855,38 @@ bool LLAudioData::load() std::map gSoundHistory; // static -void logSoundPlay(LLUUID id, LLAudioSource* audio_source, LLVector3d position, S32 type, LLUUID assetid, LLUUID ownerid, LLUUID sourceid, bool is_trigger, bool is_looped) +void logSoundPlay(LLAudioSource* audio_source, LLUUID const& assetid) { LLSoundHistoryItem item; - item.mID = id; + item.mID = audio_source->getLogID(); item.mAudioSource = audio_source; - item.mPosition = position; - item.mType = type; + item.mPosition = audio_source->getPositionGlobal(); + item.mType = audio_source->getType(); item.mAssetID = assetid; - item.mOwnerID = ownerid; - item.mSourceID = sourceid; + item.mOwnerID = audio_source->getOwnerID(); + item.mSourceID = audio_source->getSourceID(); item.mPlaying = true; item.mTimeStarted = LLTimer::getElapsedSeconds(); item.mTimeStopped = F64_MAX; - item.mIsTrigger = is_trigger; - item.mIsLooped = is_looped; + item.mIsTrigger = audio_source->getIsTrigger(); + item.mIsLooped = audio_source->isLoop(); item.mReviewed = false; item.mReviewedCollision = false; - gSoundHistory[id] = item; + gSoundHistory[item.mID] = item; } //static -void logSoundStop(LLUUID id) +void logSoundStop(LLUUID const& id, bool destructed) { - if(gSoundHistory.find(id) != gSoundHistory.end()) + std::map::iterator iter = gSoundHistory.find(id); + if(iter != gSoundHistory.end() && iter->second.mAudioSource) { - gSoundHistory[id].mPlaying = false; - gSoundHistory[id].mTimeStopped = LLTimer::getElapsedSeconds(); - gSoundHistory[id].mAudioSource = NULL; // just in case + iter->second.mPlaying = false; + iter->second.mTimeStopped = LLTimer::getElapsedSeconds(); + if (destructed) + iter->second.mAudioSource = NULL; pruneSoundLog(); } } diff --git a/indra/llaudio/llaudioengine.h b/indra/llaudio/llaudioengine.h index 5a5d161a9..c41458553 100644 --- a/indra/llaudio/llaudioengine.h +++ b/indra/llaudio/llaudioengine.h @@ -306,7 +306,11 @@ public: void setPlayedOnce(const bool played_once) { mPlayedOnce = played_once; } void setType(S32 type) { mType = type; } - S32 getType() { return mType; } + S32 getType(void) const { return mType; } + + LLUUID const& getOwnerID(void) const { return mOwnerID; } + LLUUID const& getSourceID(void) const { return mSourceID; } + bool getIsTrigger(void) const { return mIsTrigger; } void setPositionGlobal(const LLVector3d &position_global) { mPositionGlobal = position_global; } LLVector3d getPositionGlobal() const { return mPositionGlobal; } @@ -504,12 +508,23 @@ struct LLSoundHistoryItem LLSoundHistoryItem() : mType(0), mPlaying(false), mIsTrigger(false), mIsLooped(false), mReviewed(false), mReviewedCollision(false), mTimeStarted(0), mTimeStopped(0), mAudioSource(0) {} + + bool isPlaying(void) const + { + return mPlaying && mAudioSource && mAudioSource->getChannel() + // It's only REALLY playing if the following also returns true, + // but it's too hard detect when that part is starting/stopping, + // so in the sound explorer we call "playing" (or "looping") + // those audio source that have a channel assigned and call + // it a day. + /*&& mAudioSource->getChannel()->isPlaying()*/ ; + } }; extern std::map gSoundHistory; -extern void logSoundPlay(LLUUID id, LLAudioSource* audio_source, LLVector3d position, S32 type, LLUUID assetid, LLUUID ownerid, LLUUID sourceid, bool is_trigger, bool is_looped); -extern void logSoundStop(LLUUID id); +extern void logSoundPlay(LLAudioSource* audio_source, LLUUID const& assetid); +extern void logSoundStop(LLUUID const& id, bool destructed); extern void pruneSoundLog(); extern int gSoundHistoryPruneCounter; diff --git a/indra/newview/llfloaterexploresounds.cpp b/indra/newview/llfloaterexploresounds.cpp index 56c57b4bd..7fdcfda10 100644 --- a/indra/newview/llfloaterexploresounds.cpp +++ b/indra/newview/llfloaterexploresounds.cpp @@ -110,9 +110,9 @@ class LLSoundHistoryItemCompare public: bool operator() (LLSoundHistoryItem first, LLSoundHistoryItem second) { - if(first.mPlaying) + if(first.isPlaying()) { - if(second.mPlaying) + if(second.isPlaying()) { return (first.mTimeStarted > second.mTimeStarted); } @@ -121,7 +121,7 @@ public: return true; } } - else if(second.mPlaying) + else if(second.isPlaying()) { return false; } @@ -205,17 +205,12 @@ BOOL LLFloaterExploreSounds::tick() LLSD& playing_column = element["columns"][0]; playing_column["column"] = "playing"; - if (item.mIsLooped) + if(item.isPlaying()) { - playing_column["value"] = " Looping"; - } - else if(item.mPlaying) - { - playing_column["value"] = " Playing"; + playing_column["value"] = item.mIsLooped ? " Looping" : " Playing"; } else { - S32 time = (LLTimer::getElapsedSeconds() - item.mTimeStopped); S32 hours = time / 3600; S32 mins = time / 60; @@ -358,23 +353,15 @@ void LLFloaterExploreSounds::handle_stop(void* user_data) { LLSoundHistoryItem item = floater->getItem((*selection_iter)->getValue()); if(item.mID.isNull()) continue; - if(item.mPlaying) + if(item.isPlaying()) { - if(item.mAudioSource) - { - S32 type = item.mType; - item.mAudioSource->setType(LLAudioEngine::AUDIO_TYPE_UI); - if(item.mAudioSource) - item.mAudioSource->play(LLUUID::null); - if(item.mAudioSource) - item.mAudioSource->setType(type); - } + item.mAudioSource->play(LLUUID::null); } } } + void LLFloaterExploreSounds::blacklistSound(void* user_data) { - LLFloaterBlacklist::show(); LLFloaterExploreSounds* floater = (LLFloaterExploreSounds*)user_data; LLScrollListCtrl* list = floater->getChild("sound_list");