Handle fmodex internal channel release by registering channel callbacks. Harden channel<->source associations. Assign console output for audio system "AudioEngine" and "AudioImpl" tags. Added base LLAudioChannel::cleanup() vfunc to handle non-impl-related variable cleanup. Killed some redundant code.
This commit is contained in:
@@ -126,7 +126,7 @@ bool LLAudioEngine::init(const S32 num_channels, void* userdata)
|
|||||||
// Initialize the decode manager
|
// Initialize the decode manager
|
||||||
gAudioDecodeMgrp = new LLAudioDecodeMgr;
|
gAudioDecodeMgrp = new LLAudioDecodeMgr;
|
||||||
|
|
||||||
llinfos << "LLAudioEngine::init() AudioEngine successfully initialized" << llendl;
|
LL_INFOS("AudioEngine") << "LLAudioEngine::init() AudioEngine successfully initialized" << llendl;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -311,8 +311,7 @@ void LLAudioEngine::idle(F32 max_decode_time)
|
|||||||
LLAudioChannel *channelp = getFreeChannel(max_priority);
|
LLAudioChannel *channelp = getFreeChannel(max_priority);
|
||||||
if (channelp)
|
if (channelp)
|
||||||
{
|
{
|
||||||
//llinfos << "Replacing source in channel due to priority!" << llendl;
|
LL_DEBUGS("AudioEngine") << "Replacing source in channel due to priority!" << llendl;
|
||||||
max_sourcep->setChannel(channelp);
|
|
||||||
channelp->setSource(max_sourcep);
|
channelp->setSource(max_sourcep);
|
||||||
if (max_sourcep->isSyncSlave())
|
if (max_sourcep->isSyncSlave())
|
||||||
{
|
{
|
||||||
@@ -348,18 +347,22 @@ void LLAudioEngine::idle(F32 max_decode_time)
|
|||||||
}
|
}
|
||||||
|
|
||||||
LLAudioChannel *channelp = sourcep->getChannel();
|
LLAudioChannel *channelp = sourcep->getChannel();
|
||||||
if (!channelp)
|
bool is_stopped = channelp && channelp->isPlaying();
|
||||||
|
if (is_stopped || (sourcep->isLoop() && channelp->mLoopedThisFrame))
|
||||||
{
|
{
|
||||||
// This sound isn't playing, so we just process move the queue
|
// This sound isn't playing, so we just process move the queue
|
||||||
sourcep->mCurrentDatap = sourcep->mQueuedDatap;
|
sourcep->mCurrentDatap = sourcep->mQueuedDatap;
|
||||||
sourcep->mQueuedDatap = NULL;
|
sourcep->mQueuedDatap = NULL;
|
||||||
|
|
||||||
// Reset the timer so the source doesn't die.
|
if(is_stopped)
|
||||||
sourcep->mAgeTimer.reset();
|
|
||||||
// Make sure we have the buffer set up if we just decoded the data
|
|
||||||
if (sourcep->mCurrentDatap)
|
|
||||||
{
|
{
|
||||||
updateBufferForData(sourcep->mCurrentDatap);
|
// Reset the timer so the source doesn't die.
|
||||||
|
sourcep->mAgeTimer.reset();
|
||||||
|
// Make sure we have the buffer set up if we just decoded the data
|
||||||
|
if (sourcep->mCurrentDatap)
|
||||||
|
{
|
||||||
|
updateBufferForData(sourcep->mCurrentDatap);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Actually play the associated data.
|
// Actually play the associated data.
|
||||||
@@ -372,52 +375,6 @@ void LLAudioEngine::idle(F32 max_decode_time)
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
// Check to see if the current sound is done playing, or looped.
|
|
||||||
if (!channelp->isPlaying())
|
|
||||||
{
|
|
||||||
sourcep->mCurrentDatap = sourcep->mQueuedDatap;
|
|
||||||
sourcep->mQueuedDatap = NULL;
|
|
||||||
|
|
||||||
// Reset the timer so the source doesn't die.
|
|
||||||
sourcep->mAgeTimer.reset();
|
|
||||||
|
|
||||||
// Make sure we have the buffer set up if we just decoded the data
|
|
||||||
if (sourcep->mCurrentDatap)
|
|
||||||
{
|
|
||||||
updateBufferForData(sourcep->mCurrentDatap);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Actually play the associated data.
|
|
||||||
sourcep->setupChannel();
|
|
||||||
channelp = sourcep->getChannel();
|
|
||||||
if (channelp)
|
|
||||||
{
|
|
||||||
channelp->updateBuffer();
|
|
||||||
channelp->play();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (sourcep->isLoop())
|
|
||||||
{
|
|
||||||
// It's a loop, we need to check and see if we're done with it.
|
|
||||||
if (channelp->mLoopedThisFrame)
|
|
||||||
{
|
|
||||||
sourcep->mCurrentDatap = sourcep->mQueuedDatap;
|
|
||||||
sourcep->mQueuedDatap = NULL;
|
|
||||||
|
|
||||||
// Actually, should do a time sync so if we're a loop master/slave
|
|
||||||
// we don't drift away.
|
|
||||||
sourcep->setupChannel();
|
|
||||||
channelp = sourcep->getChannel();
|
|
||||||
if (channelp)
|
|
||||||
{
|
|
||||||
channelp->updateBuffer();
|
|
||||||
channelp->play();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lame, update the channels AGAIN.
|
// Lame, update the channels AGAIN.
|
||||||
@@ -491,7 +448,7 @@ void LLAudioEngine::idle(F32 max_decode_time)
|
|||||||
{
|
{
|
||||||
if (!mBuffers[i]->mInUse && mBuffers[i]->mLastUseTimer.getElapsedTimeF32() > 30.f)
|
if (!mBuffers[i]->mInUse && mBuffers[i]->mLastUseTimer.getElapsedTimeF32() > 30.f)
|
||||||
{
|
{
|
||||||
//llinfos << "Flushing unused buffer!" << llendl;
|
LL_DEBUGS("AudioEngine") << "Flushing unused buffer!" << llendl;
|
||||||
mBuffers[i]->mAudioDatap->mBufferp = NULL;
|
mBuffers[i]->mAudioDatap->mBufferp = NULL;
|
||||||
delete mBuffers[i];
|
delete mBuffers[i];
|
||||||
mBuffers[i] = NULL;
|
mBuffers[i] = NULL;
|
||||||
@@ -603,8 +560,7 @@ LLAudioBuffer * LLAudioEngine::getFreeBuffer()
|
|||||||
|
|
||||||
if (buffer_id >= 0)
|
if (buffer_id >= 0)
|
||||||
{
|
{
|
||||||
lldebugs << "Taking over unused buffer " << buffer_id << llendl;
|
LL_DEBUGS("AudioEngine") << "Taking over unused buffer! max_age=" << max_age << llendl;
|
||||||
//llinfos << "Flushing unused buffer!" << llendl;
|
|
||||||
mBuffers[buffer_id]->mAudioDatap->mBufferp = NULL;
|
mBuffers[buffer_id]->mAudioDatap->mBufferp = NULL;
|
||||||
for (U32 i = 0; i < MAX_CHANNELS; i++)
|
for (U32 i = 0; i < MAX_CHANNELS; i++)
|
||||||
{
|
{
|
||||||
@@ -638,6 +594,7 @@ LLAudioChannel * LLAudioEngine::getFreeChannel(const F32 priority)
|
|||||||
// Channel is allocated but not playing right now, use it.
|
// Channel is allocated but not playing right now, use it.
|
||||||
if (!mChannels[i]->isPlaying() && !mChannels[i]->isWaiting())
|
if (!mChannels[i]->isPlaying() && !mChannels[i]->isWaiting())
|
||||||
{
|
{
|
||||||
|
LL_DEBUGS("AudioEngine") << "Replacing unused channel" << llendl;
|
||||||
mChannels[i]->cleanup();
|
mChannels[i]->cleanup();
|
||||||
if (mChannels[i]->getSource())
|
if (mChannels[i]->getSource())
|
||||||
{
|
{
|
||||||
@@ -670,9 +627,9 @@ LLAudioChannel * LLAudioEngine::getFreeChannel(const F32 priority)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LL_DEBUGS("AudioEngine") << "Flushing min channel" << llendl;
|
||||||
// Flush the minimum priority channel, and return it.
|
// Flush the minimum priority channel, and return it.
|
||||||
min_channelp->cleanup();
|
min_channelp->cleanup();
|
||||||
min_channelp->getSource()->setChannel(NULL);
|
|
||||||
return min_channelp;
|
return min_channelp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1006,10 +963,13 @@ LLAudioData * LLAudioEngine::getAudioData(const LLUUID &audio_uuid)
|
|||||||
if( sourcep && sourcep->getCurrentData() && sourcep->getCurrentData()->getID() == audio_uuid )
|
if( sourcep && sourcep->getCurrentData() && sourcep->getCurrentData()->getID() == audio_uuid )
|
||||||
{
|
{
|
||||||
LLAudioChannel* chan=sourcep->getChannel();
|
LLAudioChannel* chan=sourcep->getChannel();
|
||||||
delete sourcep;
|
|
||||||
if(chan)
|
if(chan)
|
||||||
|
{
|
||||||
|
LL_DEBUGS("AudioEngine") << "removeAudioData" << llendl;
|
||||||
chan->cleanup();
|
chan->cleanup();
|
||||||
mAllSources.erase(iter2++);
|
}
|
||||||
|
delete sourcep;
|
||||||
|
mAllSources.erase(iter2++);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
++iter2;
|
++iter2;
|
||||||
@@ -1043,7 +1003,7 @@ void LLAudioEngine::cleanupAudioSource(LLAudioSource *asp)
|
|||||||
iter = mAllSources.find(asp->getID());
|
iter = mAllSources.find(asp->getID());
|
||||||
if (iter == mAllSources.end())
|
if (iter == mAllSources.end())
|
||||||
{
|
{
|
||||||
llwarns << "Cleaning up unknown audio source!" << llendl;
|
LL_WARNS("AudioEngine") << "Cleaning up unknown audio source!" << llendl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
delete asp;
|
delete asp;
|
||||||
@@ -1264,7 +1224,7 @@ void LLAudioEngine::startNextTransfer()
|
|||||||
|
|
||||||
if (asset_id.notNull())
|
if (asset_id.notNull())
|
||||||
{
|
{
|
||||||
llinfos << "Getting asset data for: " << asset_id << llendl;
|
LL_DEBUGS("AudioEngine") << "Getting asset data for: " << asset_id << llendl;
|
||||||
gAudiop->mCurrentTransfer = asset_id;
|
gAudiop->mCurrentTransfer = asset_id;
|
||||||
gAudiop->mCurrentTransferTimer.reset();
|
gAudiop->mCurrentTransferTimer.reset();
|
||||||
gAssetStorage->getAssetData(asset_id, LLAssetType::AT_SOUND,
|
gAssetStorage->getAssetData(asset_id, LLAssetType::AT_SOUND,
|
||||||
@@ -1282,7 +1242,7 @@ void LLAudioEngine::assetCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::E
|
|||||||
{
|
{
|
||||||
if (result_code)
|
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.
|
// Need to mark data as bad to avoid constant rerequests.
|
||||||
LLAudioData *adp = gAudiop->getAudioData(uuid);
|
LLAudioData *adp = gAudiop->getAudioData(uuid);
|
||||||
if (adp)
|
if (adp)
|
||||||
@@ -1299,7 +1259,7 @@ void LLAudioEngine::assetCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::E
|
|||||||
if (!adp)
|
if (!adp)
|
||||||
{
|
{
|
||||||
// Should never happen
|
// Should never happen
|
||||||
llwarns << "Got asset callback without audio data for " << uuid << llendl;
|
LL_WARNS("AudioEngine") << "Got asset callback without audio data for " << uuid << llendl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1360,8 +1320,7 @@ LLAudioSource::~LLAudioSource()
|
|||||||
if (mChannelp)
|
if (mChannelp)
|
||||||
{
|
{
|
||||||
// Stop playback of this sound
|
// Stop playback of this sound
|
||||||
mChannelp->setSource(NULL);
|
mChannelp->cleanup();
|
||||||
setChannel(NULL);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1404,7 +1363,7 @@ void LLAudioSource::update()
|
|||||||
}
|
}
|
||||||
else if (adp->hasCompletedDecode()) // Only mark corrupted after decode is done
|
else if (adp->hasCompletedDecode()) // Only mark corrupted after decode is done
|
||||||
{
|
{
|
||||||
llwarns << "Marking LLAudioSource corrupted for " << adp->getID() << llendl;
|
LL_WARNS("AudioEngine") << "Marking LLAudioSource corrupted for " << adp->getID() << llendl;
|
||||||
mCorrupted = true ;
|
mCorrupted = true ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1475,7 +1434,6 @@ bool LLAudioSource::play(const LLUUID &audio_uuid)
|
|||||||
if (getChannel())
|
if (getChannel())
|
||||||
{
|
{
|
||||||
getChannel()->setSource(NULL);
|
getChannel()->setSource(NULL);
|
||||||
setChannel(NULL);
|
|
||||||
if (!isMuted())
|
if (!isMuted())
|
||||||
{
|
{
|
||||||
mCurrentDatap = NULL;
|
mCurrentDatap = NULL;
|
||||||
@@ -1729,11 +1687,16 @@ LLAudioChannel::~LLAudioChannel()
|
|||||||
{
|
{
|
||||||
// Need to disconnect any sources which are using this channel.
|
// Need to disconnect any sources which are using this channel.
|
||||||
//llinfos << "Cleaning up audio channel" << llendl;
|
//llinfos << "Cleaning up audio channel" << llendl;
|
||||||
if (mCurrentSourcep)
|
cleanup();
|
||||||
{
|
}
|
||||||
|
|
||||||
|
void LLAudioChannel::cleanup()
|
||||||
|
{
|
||||||
|
if(mCurrentSourcep)
|
||||||
mCurrentSourcep->setChannel(NULL);
|
mCurrentSourcep->setChannel(NULL);
|
||||||
}
|
|
||||||
mCurrentBufferp = NULL;
|
mCurrentBufferp = NULL;
|
||||||
|
mCurrentSourcep = NULL;
|
||||||
|
mWaiting = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1744,22 +1707,21 @@ void LLAudioChannel::setSource(LLAudioSource *sourcep)
|
|||||||
if (!sourcep)
|
if (!sourcep)
|
||||||
{
|
{
|
||||||
// Clearing the source for this channel, don't need to do anything.
|
// Clearing the source for this channel, don't need to do anything.
|
||||||
//llinfos << "Clearing source for channel" << llendl;
|
LL_DEBUGS("AudioEngine") << "Clearing source for channel" << llendl;
|
||||||
cleanup();
|
cleanup();
|
||||||
mCurrentSourcep = NULL;
|
|
||||||
mWaiting = false;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sourcep == mCurrentSourcep)
|
if (sourcep == mCurrentSourcep)
|
||||||
{
|
{
|
||||||
// Don't reallocate the channel, this will make FMOD goofy.
|
// Don't reallocate the channel, this will make FMOD goofy.
|
||||||
//llinfos << "Calling setSource with same source!" << llendl;
|
LL_DEBUGS("AudioEngine") << "Calling setSource with same source!" << llendl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cleanup();
|
||||||
mCurrentSourcep = sourcep;
|
mCurrentSourcep = sourcep;
|
||||||
|
mCurrentSourcep->setChannel(this);
|
||||||
|
|
||||||
updateBuffer();
|
updateBuffer();
|
||||||
update3DPosition();
|
update3DPosition();
|
||||||
}
|
}
|
||||||
@@ -1796,7 +1758,10 @@ bool LLAudioChannel::updateBuffer()
|
|||||||
// The source changed what buffer it's playing. We need to clean up
|
// The source changed what buffer it's playing. We need to clean up
|
||||||
// the existing channel
|
// the existing channel
|
||||||
//
|
//
|
||||||
|
LLAudioSource* source = mCurrentSourcep;
|
||||||
cleanup();
|
cleanup();
|
||||||
|
mCurrentSourcep = source;
|
||||||
|
mCurrentSourcep->setChannel(this);
|
||||||
|
|
||||||
mCurrentBufferp = bufferp;
|
mCurrentBufferp = bufferp;
|
||||||
if (bufferp)
|
if (bufferp)
|
||||||
@@ -1856,7 +1821,7 @@ bool LLAudioData::load()
|
|||||||
if (mBufferp)
|
if (mBufferp)
|
||||||
{
|
{
|
||||||
// We already have this sound in a buffer, don't do anything.
|
// 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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1864,7 +1829,7 @@ bool LLAudioData::load()
|
|||||||
if (!mBufferp)
|
if (!mBufferp)
|
||||||
{
|
{
|
||||||
// No free buffers, abort.
|
// No free buffers, abort.
|
||||||
lldebugs << "Not able to allocate a new audio buffer, aborting." << llendl;
|
LL_DEBUGS("AudioEngine") << "Not able to allocate a new audio buffer, aborting." << llendl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -447,7 +447,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
virtual void play() = 0;
|
virtual void play() = 0;
|
||||||
virtual void playSynced(LLAudioChannel *channelp) = 0;
|
virtual void playSynced(LLAudioChannel *channelp) = 0;
|
||||||
virtual void cleanup() = 0;
|
virtual void cleanup();
|
||||||
void setWaiting(bool waiting) { mWaiting = waiting; }
|
void setWaiting(bool waiting) { mWaiting = waiting; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -576,6 +576,7 @@ void LLAudioChannelFMOD::updateLoop()
|
|||||||
|
|
||||||
void LLAudioChannelFMOD::cleanup()
|
void LLAudioChannelFMOD::cleanup()
|
||||||
{
|
{
|
||||||
|
LLAudioChannel::cleanup();
|
||||||
if (!mChannelID)
|
if (!mChannelID)
|
||||||
{
|
{
|
||||||
//llinfos << "Aborting cleanup with no channelID." << llendl;
|
//llinfos << "Aborting cleanup with no channelID." << llendl;
|
||||||
@@ -588,7 +589,6 @@ void LLAudioChannelFMOD::cleanup()
|
|||||||
LL_DEBUGS("FMOD") << "LLAudioChannelFMOD::cleanup error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl;
|
LL_DEBUGS("FMOD") << "LLAudioChannelFMOD::cleanup error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl;
|
||||||
}
|
}
|
||||||
|
|
||||||
mCurrentBufferp = NULL;
|
|
||||||
mChannelID = 0;
|
mChannelID = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ inline bool Check_FMOD_Error(FMOD_RESULT result, const char *string)
|
|||||||
{
|
{
|
||||||
if(result == FMOD_OK)
|
if(result == FMOD_OK)
|
||||||
return false;
|
return false;
|
||||||
llwarns << string << " Error: " << FMOD_ErrorString(result) << llendl;
|
LL_WARNS("AudioImpl") << string << " Error: " << FMOD_ErrorString(result) << llendl;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,11 +101,11 @@ void* F_STDCALL decode_alloc(unsigned int size, FMOD_MEMORY_TYPE type, const cha
|
|||||||
{
|
{
|
||||||
if(type & FMOD_MEMORY_STREAM_DECODE)
|
if(type & FMOD_MEMORY_STREAM_DECODE)
|
||||||
{
|
{
|
||||||
llinfos << "Decode buffer size: " << size << llendl;
|
LL_INFOS("AudioImpl") << "Decode buffer size: " << size << llendl;
|
||||||
}
|
}
|
||||||
else if(type & FMOD_MEMORY_STREAM_FILE)
|
else if(type & FMOD_MEMORY_STREAM_FILE)
|
||||||
{
|
{
|
||||||
llinfos << "Strean buffer size: " << size << llendl;
|
LL_INFOS("AudioImpl") << "Stream buffer size: " << size << llendl;
|
||||||
}
|
}
|
||||||
return new char[size];
|
return new char[size];
|
||||||
}
|
}
|
||||||
@@ -344,7 +344,7 @@ void LLAudioEngine_FMODEX::allocateListener(void)
|
|||||||
mListenerp = (LLListener *) new LLListener_FMODEX(mSystem);
|
mListenerp = (LLListener *) new LLListener_FMODEX(mSystem);
|
||||||
if (!mListenerp)
|
if (!mListenerp)
|
||||||
{
|
{
|
||||||
llwarns << "Listener creation failed" << llendl;
|
LL_WARNS("AudioImpl") << "Listener creation failed" << llendl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -353,13 +353,13 @@ void LLAudioEngine_FMODEX::shutdown()
|
|||||||
{
|
{
|
||||||
stopInternetStream();
|
stopInternetStream();
|
||||||
|
|
||||||
llinfos << "About to LLAudioEngine::shutdown()" << llendl;
|
LL_INFOS("AudioImpl") << "About to LLAudioEngine::shutdown()" << llendl;
|
||||||
LLAudioEngine::shutdown();
|
LLAudioEngine::shutdown();
|
||||||
|
|
||||||
llinfos << "LLAudioEngine_FMODEX::shutdown() closing FMOD Ex" << llendl;
|
LL_INFOS("AudioImpl") << "LLAudioEngine_FMODEX::shutdown() closing FMOD Ex" << llendl;
|
||||||
mSystem->close();
|
mSystem->close();
|
||||||
mSystem->release();
|
mSystem->release();
|
||||||
llinfos << "LLAudioEngine_FMODEX::shutdown() done closing FMOD Ex" << llendl;
|
LL_INFOS("AudioImpl") << "LLAudioEngine_FMODEX::shutdown() done closing FMOD Ex" << llendl;
|
||||||
|
|
||||||
delete mListenerp;
|
delete mListenerp;
|
||||||
mListenerp = NULL;
|
mListenerp = NULL;
|
||||||
@@ -493,6 +493,27 @@ LLAudioChannelFMODEX::~LLAudioChannelFMODEX()
|
|||||||
cleanup();
|
cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static FMOD_RESULT F_CALLBACK channel_callback(FMOD_CHANNEL *channel, FMOD_CHANNEL_CALLBACKTYPE type, void *commanddata1, void *commanddata2)
|
||||||
|
{
|
||||||
|
if(type == FMOD_CHANNEL_CALLBACKTYPE_END)
|
||||||
|
{
|
||||||
|
FMOD::Channel* chan = reinterpret_cast<FMOD::Channel*>(channel);
|
||||||
|
LLAudioChannelFMODEX* audio_channel = NULL;
|
||||||
|
chan->getUserData((void**)&audio_channel);
|
||||||
|
if(audio_channel)
|
||||||
|
{
|
||||||
|
audio_channel->onRelease();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FMOD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LLAudioChannelFMODEX::onRelease()
|
||||||
|
{
|
||||||
|
mChannelp = NULL; //Null out channel here so cleanup doesn't try to redundantly stop it.
|
||||||
|
cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
bool LLAudioChannelFMODEX::updateBuffer()
|
bool LLAudioChannelFMODEX::updateBuffer()
|
||||||
{
|
{
|
||||||
if (LLAudioChannel::updateBuffer())
|
if (LLAudioChannel::updateBuffer())
|
||||||
@@ -508,7 +529,7 @@ bool LLAudioChannelFMODEX::updateBuffer()
|
|||||||
{
|
{
|
||||||
// This is bad, there should ALWAYS be a sound associated with a legit
|
// This is bad, there should ALWAYS be a sound associated with a legit
|
||||||
// buffer.
|
// buffer.
|
||||||
llerrs << "No FMOD sound!" << llendl;
|
LL_ERRS("AudioImpl") << "No FMOD sound!" << llendl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -519,9 +540,13 @@ bool LLAudioChannelFMODEX::updateBuffer()
|
|||||||
{
|
{
|
||||||
FMOD_RESULT result = getSystem()->playSound(FMOD_CHANNEL_FREE, soundp, true, &mChannelp);
|
FMOD_RESULT result = getSystem()->playSound(FMOD_CHANNEL_FREE, soundp, true, &mChannelp);
|
||||||
Check_FMOD_Error(result, "FMOD::System::playSound");
|
Check_FMOD_Error(result, "FMOD::System::playSound");
|
||||||
}
|
if(result == FMOD_OK)
|
||||||
|
{
|
||||||
|
|
||||||
//llinfos << "Setting up channel " << std::hex << mChannelID << std::dec << llendl;
|
mChannelp->setCallback(&channel_callback);
|
||||||
|
mChannelp->setUserData(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have a source for the channel, we need to update its gain.
|
// If we have a source for the channel, we need to update its gain.
|
||||||
@@ -535,13 +560,6 @@ bool LLAudioChannelFMODEX::updateBuffer()
|
|||||||
Check_FMOD_Error(result, "FMOD::Channel::setVolume");
|
Check_FMOD_Error(result, "FMOD::Channel::setVolume");
|
||||||
result = mChannelp->setMode(mCurrentSourcep->isLoop() ? FMOD_LOOP_NORMAL : FMOD_LOOP_OFF);
|
result = mChannelp->setMode(mCurrentSourcep->isLoop() ? FMOD_LOOP_NORMAL : FMOD_LOOP_OFF);
|
||||||
Check_FMOD_Error(result, "FMOD::Channel::setMode");
|
Check_FMOD_Error(result, "FMOD::Channel::setMode");
|
||||||
/*if(Check_FMOD_Error(result, "FMOD::Channel::setMode"))
|
|
||||||
{
|
|
||||||
S32 index;
|
|
||||||
mChannelp->getIndex(&index);
|
|
||||||
llwarns << "Channel " << index << "Source ID: " << mCurrentSourcep->getID()
|
|
||||||
<< " at " << mCurrentSourcep->getPositionGlobal() << llendl;
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -608,16 +626,17 @@ void LLAudioChannelFMODEX::updateLoop()
|
|||||||
|
|
||||||
void LLAudioChannelFMODEX::cleanup()
|
void LLAudioChannelFMODEX::cleanup()
|
||||||
{
|
{
|
||||||
|
LLAudioChannel::cleanup();
|
||||||
|
|
||||||
if (!mChannelp)
|
if (!mChannelp)
|
||||||
{
|
{
|
||||||
//llinfos << "Aborting cleanup with no channel handle." << llendl;
|
//llinfos << "Aborting cleanup with no channel handle." << llendl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//llinfos << "Cleaning up channel: " << mChannelID << llendl;
|
mChannelp->setCallback(NULL);
|
||||||
Check_FMOD_Error(mChannelp->stop(),"FMOD::Channel::stop");
|
Check_FMOD_Error(mChannelp->stop(),"FMOD::Channel::stop");
|
||||||
|
|
||||||
mCurrentBufferp = NULL;
|
|
||||||
mChannelp = NULL;
|
mChannelp = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -626,7 +645,7 @@ void LLAudioChannelFMODEX::play()
|
|||||||
{
|
{
|
||||||
if (!mChannelp)
|
if (!mChannelp)
|
||||||
{
|
{
|
||||||
llwarns << "Playing without a channel handle, aborting" << llendl;
|
LL_WARNS("AudioImpl") << "Playing without a channel handle, aborting" << llendl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -734,7 +753,7 @@ bool LLAudioBufferFMODEX::loadWAV(const std::string& filename)
|
|||||||
if (result != FMOD_OK)
|
if (result != FMOD_OK)
|
||||||
{
|
{
|
||||||
// We failed to load the file for some reason.
|
// We failed to load the file for some reason.
|
||||||
llwarns << "Could not load data '" << filename << "': " << FMOD_ErrorString(result) << llendl;
|
LL_WARNS("AudioImpl") << "Could not load data '" << filename << "': " << FMOD_ErrorString(result) << llendl;
|
||||||
|
|
||||||
//
|
//
|
||||||
// If we EVER want to load wav files provided by end users, we need
|
// If we EVER want to load wav files provided by end users, we need
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ class LLAudioChannelFMODEX : public LLAudioChannel
|
|||||||
public:
|
public:
|
||||||
LLAudioChannelFMODEX(FMOD::System *audioengine);
|
LLAudioChannelFMODEX(FMOD::System *audioengine);
|
||||||
virtual ~LLAudioChannelFMODEX();
|
virtual ~LLAudioChannelFMODEX();
|
||||||
|
void onRelease();
|
||||||
protected:
|
protected:
|
||||||
/*virtual*/ void play();
|
/*virtual*/ void play();
|
||||||
/*virtual*/ void playSynced(LLAudioChannel *channelp);
|
/*virtual*/ void playSynced(LLAudioChannel *channelp);
|
||||||
|
|||||||
@@ -186,10 +186,9 @@ LLAudioChannelOpenAL::~LLAudioChannelOpenAL()
|
|||||||
|
|
||||||
void LLAudioChannelOpenAL::cleanup()
|
void LLAudioChannelOpenAL::cleanup()
|
||||||
{
|
{
|
||||||
|
LLAudioChannel::cleanup();
|
||||||
alSourceStop(mALSource);
|
alSourceStop(mALSource);
|
||||||
alSourcei(mALSource, AL_BUFFER, AL_NONE);
|
alSourcei(mALSource, AL_BUFFER, AL_NONE);
|
||||||
|
|
||||||
mCurrentBufferp = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LLAudioChannelOpenAL::play()
|
void LLAudioChannelOpenAL::play()
|
||||||
|
|||||||
Reference in New Issue
Block a user