From 36c8c92098004c4f2eb80114a49f3660a2d3dcbb Mon Sep 17 00:00:00 2001 From: maksymsproductengine Date: Fri, 14 Mar 2014 06:39:09 +0200 Subject: MAINT-3804 FIXED Crash in LLAudioEngine::getAudioData when playing gestures with audio device disabled. --- indra/llaudio/llaudiodecodemgr.cpp | 17 ++++++---- indra/llaudio/llaudioengine.cpp | 66 +++++++++++++++++++++++++++++++------- 2 files changed, 66 insertions(+), 17 deletions(-) (limited to 'indra/llaudio') diff --git a/indra/llaudio/llaudiodecodemgr.cpp b/indra/llaudio/llaudiodecodemgr.cpp index 8c31f8b4de..ef63b2cc04 100755 --- a/indra/llaudio/llaudiodecodemgr.cpp +++ b/indra/llaudio/llaudiodecodemgr.cpp @@ -570,9 +570,14 @@ void LLAudioDecodeMgr::Impl::processQueue(const F32 num_secs) // We had an error when decoding, abort. LL_WARNS("AudioEngine") << mCurrentDecodep->getUUID() << " has invalid vorbis data, aborting decode" << LL_ENDL; mCurrentDecodep->flushBadFile(); - LLAudioData *adp = gAudiop->getAudioData(mCurrentDecodep->getUUID()); - adp->setHasValidData(false); - adp->setHasCompletedDecode(true); + + if (gAudiop) + { + LLAudioData *adp = gAudiop->getAudioData(mCurrentDecodep->getUUID()); + adp->setHasValidData(false); + adp->setHasCompletedDecode(true); + } + mCurrentDecodep = NULL; done = TRUE; } @@ -584,7 +589,7 @@ void LLAudioDecodeMgr::Impl::processQueue(const F32 num_secs) } else if (mCurrentDecodep) { - if (mCurrentDecodep->finishDecode()) + if (gAudiop && mCurrentDecodep->finishDecode()) { // We finished! LLAudioData *adp = gAudiop->getAudioData(mCurrentDecodep->getUUID()); @@ -625,7 +630,7 @@ void LLAudioDecodeMgr::Impl::processQueue(const F32 num_secs) { LLUUID uuid; mDecodeQueue.pop(uuid); - if (gAudiop->hasDecodedFile(uuid)) + if (!gAudiop || gAudiop->hasDecodedFile(uuid)) { // This file has already been decoded, don't decode it again. continue; @@ -671,7 +676,7 @@ void LLAudioDecodeMgr::processQueue(const F32 num_secs) BOOL LLAudioDecodeMgr::addDecodeRequest(const LLUUID &uuid) { - if (gAudiop->hasDecodedFile(uuid)) + if (gAudiop && gAudiop->hasDecodedFile(uuid)) { // Already have a decoded version, don't need to decode it. LL_DEBUGS("AudioEngine") << "addDecodeRequest for " << uuid << " has decoded file already" << LL_ENDL; diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp index ca614f5395..ecdfcaf73a 100755 --- a/indra/llaudio/llaudioengine.cpp +++ b/indra/llaudio/llaudioengine.cpp @@ -674,8 +674,8 @@ void LLAudioEngine::cleanupBuffer(LLAudioBuffer *bufferp) bool LLAudioEngine::preloadSound(const LLUUID &uuid) { LL_DEBUGS("AudioEngine")<<"( "<getAudioData(uuid); // We don't care about the return value, this is just to make sure + + getAudioData(uuid); // We don't care about the return value, this is just to make sure // that we have an entry, which will mean that the audio engine knows about this if (gAudioDecodeMgrp->addDecodeRequest(uuid)) @@ -828,7 +828,7 @@ void LLAudioEngine::triggerSound(const LLUUID &audio_uuid, const LLUUID& owner_i source_id.generate(); LLAudioSource *asp = new LLAudioSource(source_id, owner_id, gain, type); - gAudiop->addAudioSource(asp); + addAudioSource(asp); if (pos_global.isExactlyZero()) { asp->setAmbient(true); @@ -1211,8 +1211,8 @@ void LLAudioEngine::startNextTransfer() if (asset_id.notNull()) { LL_INFOS("AudioEngine") << "Getting audio asset data for: " << asset_id << LL_ENDL; - gAudiop->mCurrentTransfer = asset_id; - gAudiop->mCurrentTransferTimer.reset(); + mCurrentTransfer = asset_id; + mCurrentTransferTimer.reset(); gAssetStorage->getAssetData(asset_id, LLAssetType::AT_SOUND, assetCallback, NULL); } @@ -1226,6 +1226,12 @@ void LLAudioEngine::startNextTransfer() // static void LLAudioEngine::assetCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type, void *user_data, S32 result_code, LLExtStat ext_status) { + if (!gAudiop) + { + LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL; + return; + } + if (result_code) { LL_INFOS("AudioEngine") << "Boom, error in audio file transfer: " << LLAssetStorage::getErrorString( result_code ) << " (" << result_code << ")" << LL_ENDL; @@ -1350,7 +1356,12 @@ void LLAudioSource::updatePriority() // Priority is based on distance LLVector3 dist_vec; dist_vec.setVec(getPositionGlobal()); - dist_vec -= gAudiop->getListenerPos(); + + if (gAudiop) + { + dist_vec -= gAudiop->getListenerPos(); + } + F32 dist_squared = llmax(1.f, dist_vec.magVecSquared()); mPriority = mGain / dist_squared; @@ -1367,6 +1378,11 @@ bool LLAudioSource::setupChannel() return false; } + if (!gAudiop) + { + LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL; + return false; + } if (!mChannelp) { @@ -1410,6 +1426,12 @@ bool LLAudioSource::play(const LLUUID &audio_uuid) // Reset our age timeout if someone attempts to play the source. mAgeTimer.reset(); + if (!gAudiop) + { + LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL; + return false; + } + LLAudioData *adp = gAudiop->getAudioData(audio_uuid); addAudioData(adp); @@ -1517,6 +1539,13 @@ void LLAudioSource::addAudioData(LLAudioData *adp, const bool set_current) { // Only handle a single piece of audio data associated with a source right now, // until I implement prefetch. + + if (!gAudiop) + { + LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL; + return; + } + if (set_current) { if (!mCurrentDatap) @@ -1685,6 +1714,12 @@ void LLAudioChannel::setSource(LLAudioSource *sourcep) bool LLAudioChannel::updateBuffer() { + if (!gAudiop) + { + LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL; + return false; + } + if (!mCurrentSourcep) { // This channel isn't associated with any source, nothing @@ -1693,10 +1728,7 @@ bool LLAudioChannel::updateBuffer() } // Initialize the channel's gain setting for this sound. - if(gAudiop) - { - setSecondaryGain(gAudiop->getSecondaryGain(mCurrentSourcep->getType())); - } + setSecondaryGain(gAudiop->getSecondaryGain(mCurrentSourcep->getType())); LLAudioBuffer *bufferp = mCurrentSourcep->getCurrentBuffer(); if (bufferp == mCurrentBufferp) @@ -1753,8 +1785,14 @@ LLAudioData::LLAudioData(const LLUUID &uuid) : // This is a null sound. return; } + + if (!gAudiop) + { + LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL; + return; + } - if (gAudiop && gAudiop->hasDecodedFile(uuid)) + if (gAudiop->hasDecodedFile(uuid)) { // Already have a decoded version, don't need to decode it. setHasLocalData(true); @@ -1777,6 +1815,12 @@ bool LLAudioData::load() LL_INFOS("AudioEngine") << "Already have a buffer for this sound, don't bother loading!" << LL_ENDL; return true; } + + if (!gAudiop) + { + LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL; + return false; + } mBufferp = gAudiop->getFreeBuffer(); if (!mBufferp) -- cgit v1.2.3 From 4f565ed077058cd3ce90ffd347c4a8346d734dbd Mon Sep 17 00:00:00 2001 From: Monty Brandenberg Date: Fri, 14 Mar 2014 19:48:35 -0400 Subject: Update fmodex to 4.44.31. Move DSP descriptor to heap storage. --- indra/llaudio/llaudioengine_fmodex.cpp | 23 +++++++++++++---------- indra/llaudio/llaudioengine_fmodex.h | 3 ++- 2 files changed, 15 insertions(+), 11 deletions(-) (limited to 'indra/llaudio') diff --git a/indra/llaudio/llaudioengine_fmodex.cpp b/indra/llaudio/llaudioengine_fmodex.cpp index e9b74b8f41..71f5d47367 100644 --- a/indra/llaudio/llaudioengine_fmodex.cpp +++ b/indra/llaudio/llaudioengine_fmodex.cpp @@ -5,7 +5,7 @@ * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2014, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -320,8 +320,8 @@ void LLAudioEngine_FMODEX::shutdown() llinfos << "LLAudioEngine_FMODEX::shutdown() closing FMOD Ex" << llendl; if ( mSystem ) // speculative fix for MAINT-2657 { - mSystem->close(); - mSystem->release(); + mSystem->close(); + mSystem->release(); } llinfos << "LLAudioEngine_FMODEX::shutdown() done closing FMOD Ex" << llendl; @@ -347,15 +347,14 @@ bool LLAudioEngine_FMODEX::initWind() if (!mWindDSP) { - FMOD_DSP_DESCRIPTION dspdesc; - memset(&dspdesc, 0, sizeof(FMOD_DSP_DESCRIPTION)); //Set everything to zero - strncpy(dspdesc.name,"Wind Unit", sizeof(dspdesc.name)); //Set name to "Wind Unit" - dspdesc.channels=2; - dspdesc.read = &windCallback; //Assign callback. - if(Check_FMOD_Error(mSystem->createDSP(&dspdesc, &mWindDSP), "FMOD::createDSP")) + memset(&mWindDSPDesc, 0, sizeof(mWindDSPDesc)); //Set everything to zero + strncpy(mWindDSPDesc.name, "Wind Unit", sizeof(mWindDSPDesc.name)); + mWindDSPDesc.channels = 2; + mWindDSPDesc.read = &windCallback; // Assign callback - may be called from arbitrary threads + if (Check_FMOD_Error(mSystem->createDSP(&mWindDSPDesc, &mWindDSP), "FMOD::createDSP")) return false; - if(mWindGen) + if (mWindGen) delete mWindGen; float frequency = 44100; @@ -364,6 +363,7 @@ bool LLAudioEngine_FMODEX::initWind() mWindDSP->setUserData((void*)mWindGen); } + // *TODO: Should this guard against multiple plays? if (mWindDSP) { mSystem->playDSP(FMOD_CHANNEL_FREE, mWindDSP, false, 0); @@ -741,6 +741,9 @@ void LLAudioChannelFMODEX::set3DMode(bool use3d) } } +// *NOTE: This is almost certainly being called on the mixer thread, +// not the main thread. May have implications for callees or audio +// engine shutdown. FMOD_RESULT F_CALLBACK windCallback(FMOD_DSP_STATE *dsp_state, float *originalbuffer, float *newbuffer, unsigned int length, int inchannels, int outchannels) { diff --git a/indra/llaudio/llaudioengine_fmodex.h b/indra/llaudio/llaudioengine_fmodex.h index 415a9ed0ef..ca9a6c0df0 100644 --- a/indra/llaudio/llaudioengine_fmodex.h +++ b/indra/llaudio/llaudioengine_fmodex.h @@ -5,7 +5,7 @@ * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2014, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -74,6 +74,7 @@ protected: LLWindGen *mWindGen; + FMOD_DSP_DESCRIPTION mWindDSPDesc; FMOD::DSP *mWindDSP; FMOD::System *mSystem; bool mEnableProfiler; -- cgit v1.2.3 From c62d2cca2962f9847f844df137c21aa44edc2d75 Mon Sep 17 00:00:00 2001 From: Monty Brandenberg Date: Fri, 14 Mar 2014 20:58:35 -0400 Subject: Additions & fixes for lib copy, use only forwarded ptrs in LLAE interfaces. Copy3rdPartyLibs needed to copy the now-corrected fmodexL libraries and it had a bad library reference on Linux for release. In llaudio land, the audio engine interfaces, even the fmodex specializations, seem to want to be external-structure free so use a forward declaration and pointer to FMOD_DSP_DESCRIPTION and deal with it in the ctor/dtor. --- indra/llaudio/llaudioengine_fmodex.cpp | 12 +++++++----- indra/llaudio/llaudioengine_fmodex.h | 3 ++- 2 files changed, 9 insertions(+), 6 deletions(-) (limited to 'indra/llaudio') diff --git a/indra/llaudio/llaudioengine_fmodex.cpp b/indra/llaudio/llaudioengine_fmodex.cpp index 71f5d47367..36e8044a25 100644 --- a/indra/llaudio/llaudioengine_fmodex.cpp +++ b/indra/llaudio/llaudioengine_fmodex.cpp @@ -55,11 +55,13 @@ LLAudioEngine_FMODEX::LLAudioEngine_FMODEX(bool enable_profiler) mWindDSP = NULL; mSystem = NULL; mEnableProfiler = enable_profiler; + mWindDSPDesc = new FMOD_DSP_DESCRIPTION(); } LLAudioEngine_FMODEX::~LLAudioEngine_FMODEX() { + delete mWindDSPDesc; } @@ -347,11 +349,11 @@ bool LLAudioEngine_FMODEX::initWind() if (!mWindDSP) { - memset(&mWindDSPDesc, 0, sizeof(mWindDSPDesc)); //Set everything to zero - strncpy(mWindDSPDesc.name, "Wind Unit", sizeof(mWindDSPDesc.name)); - mWindDSPDesc.channels = 2; - mWindDSPDesc.read = &windCallback; // Assign callback - may be called from arbitrary threads - if (Check_FMOD_Error(mSystem->createDSP(&mWindDSPDesc, &mWindDSP), "FMOD::createDSP")) + memset(mWindDSPDesc, 0, sizeof(*mWindDSPDesc)); //Set everything to zero + strncpy(mWindDSPDesc->name, "Wind Unit", sizeof(mWindDSPDesc->name)); + mWindDSPDesc->channels = 2; + mWindDSPDesc->read = &windCallback; // Assign callback - may be called from arbitrary threads + if (Check_FMOD_Error(mSystem->createDSP(mWindDSPDesc, &mWindDSP), "FMOD::createDSP")) return false; if (mWindGen) diff --git a/indra/llaudio/llaudioengine_fmodex.h b/indra/llaudio/llaudioengine_fmodex.h index ca9a6c0df0..ca389d489f 100644 --- a/indra/llaudio/llaudioengine_fmodex.h +++ b/indra/llaudio/llaudioengine_fmodex.h @@ -41,6 +41,7 @@ namespace FMOD class Sound; class DSP; } +typedef struct FMOD_DSP_DESCRIPTION FMOD_DSP_DESCRIPTION; //Interfaces class LLAudioEngine_FMODEX : public LLAudioEngine @@ -74,7 +75,7 @@ protected: LLWindGen *mWindGen; - FMOD_DSP_DESCRIPTION mWindDSPDesc; + FMOD_DSP_DESCRIPTION *mWindDSPDesc; FMOD::DSP *mWindDSP; FMOD::System *mSystem; bool mEnableProfiler; -- cgit v1.2.3