Check for bad FMOD_RESULT return values for practically every fmod api call. Wavedata dsp also now attached before fmod's fader DSP, and although that makes the stream channelgroup less than necessary, channelgroups are still nice to have.

This commit is contained in:
Shyotl
2014-11-26 01:15:17 -06:00
parent 87f87bf2ff
commit f5204cc8f5
5 changed files with 287 additions and 255 deletions

View File

@@ -58,7 +58,7 @@ public:
const std::string& getURL() { return mInternetStreamURL; }
FMOD_OPENSTATE getOpenState(unsigned int* percentbuffered=NULL, bool* starving=NULL, bool* diskbusy=NULL);
FMOD_RESULT getOpenState(FMOD_OPENSTATE& openstate, unsigned int* percentbuffered = NULL, bool* starving = NULL, bool* diskbusy = NULL);
protected:
FMOD::System* mSystem;
FMOD::Channel* mStreamChannel;
@@ -121,7 +121,9 @@ LLStreamingAudio_FMODSTUDIO::LLStreamingAudio_FMODSTUDIO(FMOD::System *system) :
mCurrentInternetStreamp(NULL),
mFMODInternetStreamChannelp(NULL),
mGain(1.0f),
mMetaData(NULL)
mMetaData(NULL),
mStreamGroup(NULL),
mStreamDSP(NULL)
{
FMOD_RESULT result;
@@ -140,8 +142,7 @@ LLStreamingAudio_FMODSTUDIO::LLStreamingAudio_FMODSTUDIO(FMOD::System *system) :
// Leave the net buffer properties at the default.
//FSOUND_Stream_Net_SetBufferProperties(20000, 40, 80);
result = system->createChannelGroup("stream", &mStreamGroup);
Check_FMOD_Error(result,"FMOD::System::createChannelGroup");
Check_FMOD_Error(system->createChannelGroup("stream", &mStreamGroup), "FMOD::System::createChannelGroup");
FMOD_DSP_DESCRIPTION dspdesc;
memset(&dspdesc, 0, sizeof(FMOD_DSP_DESCRIPTION)); //Zero out everything
@@ -150,11 +151,7 @@ LLStreamingAudio_FMODSTUDIO::LLStreamingAudio_FMODSTUDIO(FMOD::System *system) :
dspdesc.numoutputbuffers = 1;
dspdesc.read = &waveDataCallback; //Assign callback.
result = system->createDSP(&dspdesc, &mStreamDSP);
Check_FMOD_Error(result, "FMOD::System::createDSPByType");
result = mStreamGroup->addDSP(FMOD_CHANNELCONTROL_DSP_TAIL, mStreamDSP);
Check_FMOD_Error(result, "FMOD::ChannelGroup::addDSP");
mStreamDSP->setActive(false);
Check_FMOD_Error(system->createDSP(&dspdesc, &mStreamDSP), "FMOD::System::createDSP");
}
@@ -168,14 +165,7 @@ LLStreamingAudio_FMODSTUDIO::~LLStreamingAudio_FMODSTUDIO()
ms_sleep(10);
}
if (mStreamGroup)
{
if (mStreamDSP)
mStreamGroup->removeDSP(mStreamDSP);
mStreamGroup->release();
}
if (mStreamDSP)
mStreamDSP->release();
cleanupWaveData();
}
@@ -279,9 +269,15 @@ void LLStreamingAudio_FMODSTUDIO::update()
unsigned int progress;
bool starving;
bool diskbusy;
FMOD_OPENSTATE open_state = mCurrentInternetStreamp->getOpenState(&progress, &starving, &diskbusy);
FMOD_OPENSTATE open_state;
FMOD_RESULT result = mCurrentInternetStreamp->getOpenState(open_state, &progress, &starving, &diskbusy);
if (open_state == FMOD_OPENSTATE_READY)
if (result != FMOD_OK || open_state == FMOD_OPENSTATE_ERROR)
{
stop();
return;
}
else if (open_state == FMOD_OPENSTATE_READY)
{
// Stream is live
@@ -292,15 +288,13 @@ void LLStreamingAudio_FMODSTUDIO::update()
// Reset volume to previously set volume
setGain(getGain());
if (mStreamDSP)
mStreamDSP->setActive(true);
mFMODInternetStreamChannelp->setPaused(false);
{
Check_FMOD_Error(mFMODInternetStreamChannelp->addDSP(FMOD_CHANNELCONTROL_DSP_TAIL, mStreamDSP), "FMOD::Channel::addDSP");
}
Check_FMOD_Error(mFMODInternetStreamChannelp->setPaused(false), "FMOD::Channel::setPaused");
}
}
else if(open_state == FMOD_OPENSTATE_ERROR)
{
stop();
return;
}
if(mFMODInternetStreamChannelp)
{
@@ -336,7 +330,7 @@ void LLStreamingAudio_FMODSTUDIO::update()
if (!LLStringUtil::compareInsensitive(name, "Sample Rate Change"))
{
llinfos << "Stream forced changing sample rate to " << *((float *)tag.data) << llendl;
mFMODInternetStreamChannelp->setFrequency(*((float *)tag.data));
Check_FMOD_Error(mFMODInternetStreamChannelp->setFrequency(*((float *)tag.data)), "FMOD::Channel::setFrequency");
}
continue;
default:
@@ -402,18 +396,17 @@ void LLStreamingAudio_FMODSTUDIO::update()
if(starving)
{
bool paused = false;
mFMODInternetStreamChannelp->getPaused(&paused);
if(!paused)
if (mFMODInternetStreamChannelp->getPaused(&paused) == FMOD_OK && !paused)
{
llinfos << "Stream starvation detected! Pausing stream until buffer nearly full." << llendl;
llinfos << " (diskbusy="<<diskbusy<<")" << llendl;
llinfos << " (progress="<<progress<<")" << llendl;
mFMODInternetStreamChannelp->setPaused(true);
Check_FMOD_Error(mFMODInternetStreamChannelp->setPaused(true), "FMOD::Channel::setPaused");
}
}
else if(progress > 80)
{
mFMODInternetStreamChannelp->setPaused(false);
Check_FMOD_Error(mFMODInternetStreamChannelp->setPaused(false), "FMOD::Channel::setPaused");
}
}
}
@@ -429,18 +422,14 @@ void LLStreamingAudio_FMODSTUDIO::stop()
mMetaData = NULL;
}
if (mStreamDSP)
{
mSystem->lockDSP();
mStreamDSP->setActive(false);
gWaveDataBufferSize = 0;
mSystem->unlockDSP();
}
if (mFMODInternetStreamChannelp)
{
mFMODInternetStreamChannelp->setPaused(true);
mFMODInternetStreamChannelp->setPriority(0);
Check_FMOD_Error(mFMODInternetStreamChannelp->setPaused(true), "FMOD::Channel::setPaused");
Check_FMOD_Error(mFMODInternetStreamChannelp->setPriority(0), "FMOD::Channel::setPriority");
if (mStreamDSP)
{
Check_FMOD_Error(mFMODInternetStreamChannelp->removeDSP(mStreamDSP), "FMOD::Channel::removeDSP");
}
mFMODInternetStreamChannelp = NULL;
}
@@ -521,7 +510,7 @@ void LLStreamingAudio_FMODSTUDIO::setGain(F32 vol)
{
vol = llclamp(vol * vol, 0.f, 1.f); //should vol be squared here?
mFMODInternetStreamChannelp->setVolume(vol);
Check_FMOD_Error(mFMODInternetStreamChannelp->setVolume(vol), "FMOD::Channel::setVolume");
}
}
@@ -534,8 +523,8 @@ void LLStreamingAudio_FMODSTUDIO::setGain(F32 vol)
return false;
bool muted = false;
mFMODInternetStreamChannelp->getMute(&muted);
if(muted)
FMOD_RESULT res = mFMODInternetStreamChannelp->getMute(&muted);
if(res != FMOD_OK || muted)
return false;
{
U32 buff_size;
@@ -582,7 +571,8 @@ LLAudioStreamManagerFMODSTUDIO::LLAudioStreamManagerFMODSTUDIO(FMOD::System *sys
FMOD::Channel *LLAudioStreamManagerFMODSTUDIO::startStream()
{
// We need a live and opened stream before we try and play it.
if (!mInternetStream || getOpenState() != FMOD_OPENSTATE_READY)
FMOD_OPENSTATE open_state;
if (getOpenState(open_state) != FMOD_OK || open_state != FMOD_OPENSTATE_READY)
{
llwarns << "No internet stream to start playing!" << llendl;
return NULL;
@@ -591,7 +581,7 @@ FMOD::Channel *LLAudioStreamManagerFMODSTUDIO::startStream()
if(mStreamChannel)
return mStreamChannel; //Already have a channel for this stream.
mSystem->playSound(mInternetStream, mChannelGroup, true, &mStreamChannel);
Check_FMOD_Error(mSystem->playSound(mInternetStream, mChannelGroup, true, &mStreamChannel), "FMOD::System::playSound");
return mStreamChannel;
}
@@ -600,13 +590,17 @@ bool LLAudioStreamManagerFMODSTUDIO::stopStream()
if (mInternetStream)
{
bool close = true;
switch (getOpenState())
FMOD_OPENSTATE open_state;
if (getOpenState(open_state) == FMOD_OK)
{
case FMOD_OPENSTATE_CONNECTING:
close = false;
break;
default:
close = true;
switch (open_state)
{
case FMOD_OPENSTATE_CONNECTING:
close = false;
break;
default:
close = true;
}
}
if (close && mInternetStream->release() == FMOD_OK)
@@ -626,21 +620,23 @@ bool LLAudioStreamManagerFMODSTUDIO::stopStream()
}
}
FMOD_OPENSTATE LLAudioStreamManagerFMODSTUDIO::getOpenState(unsigned int* percentbuffered, bool* starving, bool* diskbusy)
FMOD_RESULT LLAudioStreamManagerFMODSTUDIO::getOpenState(FMOD_OPENSTATE& state, unsigned int* percentbuffered, bool* starving, bool* diskbusy)
{
FMOD_OPENSTATE state;
mInternetStream->getOpenState(&state, percentbuffered, starving, diskbusy);
return state;
if (!mInternetStream)
return FMOD_ERR_INVALID_HANDLE;
FMOD_RESULT result = mInternetStream->getOpenState(&state, percentbuffered, starving, diskbusy);
Check_FMOD_Error(result, "FMOD::Sound::getOpenState");
return result;
}
void LLStreamingAudio_FMODSTUDIO::setBufferSizes(U32 streambuffertime, U32 decodebuffertime)
{
mSystem->setStreamBufferSize(streambuffertime/1000*128*128, FMOD_TIMEUNIT_RAWBYTES);
Check_FMOD_Error(mSystem->setStreamBufferSize(streambuffertime / 1000 * 128 * 128, FMOD_TIMEUNIT_RAWBYTES), "FMOD::System::setStreamBufferSize");
FMOD_ADVANCEDSETTINGS settings;
memset(&settings,0,sizeof(settings));
settings.cbSize=sizeof(settings);
settings.defaultDecodeBufferSize = decodebuffertime;//ms
mSystem->setAdvancedSettings(&settings);
Check_FMOD_Error(mSystem->setAdvancedSettings(&settings), "FMOD::System::setAdvancedSettings");
}
bool LLStreamingAudio_FMODSTUDIO::releaseDeadStreams()
@@ -663,4 +659,17 @@ bool LLStreamingAudio_FMODSTUDIO::releaseDeadStreams()
}
return mDeadStreams.empty();
}
void LLStreamingAudio_FMODSTUDIO::cleanupWaveData()
{
if (mStreamGroup)
{
Check_FMOD_Error(mStreamGroup->release(), "FMOD::ChannelGroup::release");
mStreamGroup = NULL;
}
if(mStreamDSP)
Check_FMOD_Error(mStreamDSP->release(), "FMOD::DSP::release");
mStreamDSP = NULL;
}