Provide FMOD Ex with format hints. Use software mixing only. Fixed issue with channels being silently stolen due to maxchannels being too low (Wind and streaming audio + 30 sound sources were exceeding max channel count)

This commit is contained in:
Shyotl
2011-12-23 18:00:54 -06:00
parent b4dad425aa
commit 37095dc2cd
3 changed files with 37 additions and 25 deletions

View File

@@ -158,6 +158,7 @@ bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata)
} }
result = mSystem->getDriverInfo(0, name, 256, 0); result = mSystem->getDriverInfo(0, name, 256, 0);
Check_FMOD_Error(result, "FMOD::System::getDriverInfo"); Check_FMOD_Error(result, "FMOD::System::getDriverInfo");
if (strstr(name, "SigmaTel")) if (strstr(name, "SigmaTel"))
{ {
/* /*
@@ -171,9 +172,9 @@ bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata)
} }
#endif //LL_WINDOWS #endif //LL_WINDOWS
// Only static sounds (not wind, not stream) can possibly be hardware. Only reserve for those. // In this case, all sounds, PLUS wind and stream will be software.
result = mSystem->setHardwareChannels(num_channels); result = mSystem->setSoftwareChannels(num_channels+2);
Check_FMOD_Error(result,"FMOD::System::setHardwareChannels"); Check_FMOD_Error(result,"FMOD::System::setSoftwareChannels");
U32 fmod_flags = FMOD_INIT_NORMAL; U32 fmod_flags = FMOD_INIT_NORMAL;
if(mEnableProfiler) if(mEnableProfiler)
@@ -276,13 +277,13 @@ bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata)
LL_DEBUGS("AppInit") << "Audio output: ESD" << LL_ENDL; break; LL_DEBUGS("AppInit") << "Audio output: ESD" << LL_ENDL; break;
case FSOUND_OUTPUT_ALSA: case FSOUND_OUTPUT_ALSA:
LL_DEBUGS("AppInit") << "Audio output: ALSA" << LL_ENDL; break; LL_DEBUGS("AppInit") << "Audio output: ALSA" << LL_ENDL; break;
default: default:
LL_INFOS("AppInit") << "Audio output: Unknown!" << LL_ENDL; break; LL_INFOS("AppInit") << "Audio output: Unknown!" << LL_ENDL; break;
}; };
#else // LL_LINUX #else // LL_LINUX
// initialize the FMOD engine // initialize the FMOD engine
result = mSystem->init( num_channels, fmod_flags, 0); result = mSystem->init( num_channels + 2, fmod_flags, 0);
if (result == FMOD_ERR_OUTPUT_CREATEBUFFER) if (result == FMOD_ERR_OUTPUT_CREATEBUFFER)
{ {
/* /*
@@ -392,6 +393,7 @@ bool LLAudioEngine_FMODEX::initWind()
mWindGen = new LLWindGen<MIXBUFFERFORMAT>((U32)frequency); mWindGen = new LLWindGen<MIXBUFFERFORMAT>((U32)frequency);
mWindDSP->setUserData((void*)mWindGen); mWindDSP->setUserData((void*)mWindGen);
} }
if (mWindDSP) if (mWindDSP)
{ {
mSystem->playDSP(FMOD_CHANNEL_FREE, mWindDSP, false, 0); mSystem->playDSP(FMOD_CHANNEL_FREE, mWindDSP, false, 0);
@@ -490,7 +492,6 @@ LLAudioChannelFMODEX::~LLAudioChannelFMODEX()
cleanup(); cleanup();
} }
bool LLAudioChannelFMODEX::updateBuffer() bool LLAudioChannelFMODEX::updateBuffer()
{ {
if (LLAudioChannel::updateBuffer()) if (LLAudioChannel::updateBuffer())
@@ -513,15 +514,20 @@ bool LLAudioChannelFMODEX::updateBuffer()
// Actually play the sound. Start it off paused so we can do all the necessary // Actually play the sound. Start it off paused so we can do all the necessary
// setup. // setup.
FMOD_RESULT result = getEngine()->getSystem()->playSound(FMOD_CHANNEL_FREE, soundp, true, &mChannelp); if(!mChannelp)
if(!Check_FMOD_Error(result, "FMOD::System::playSound") &&
mCurrentSourcep &&
(mCurrentSourcep->getType() == LLAudioEngine::AUDIO_TYPE_SFX ||
mCurrentSourcep->getType() == LLAudioEngine::AUDIO_TYPE_AMBIENT))
{ {
FMOD::SoundGroup *world_group = getEngine()->getWorldSoundGroup(); if(mCurrentSourcep)
if(world_group) {
soundp->setSoundGroup(world_group); S32 type = mCurrentSourcep->getType();
if(type == LLAudioEngine::AUDIO_TYPE_SFX || type == LLAudioEngine::AUDIO_TYPE_AMBIENT)
{
FMOD::SoundGroup *world_group = getEngine()->getWorldSoundGroup();
if(world_group)
soundp->setSoundGroup(world_group);
}
}
FMOD_RESULT result = getEngine()->getSystem()->playSound(FMOD_CHANNEL_FREE, soundp, false, &mChannelp);
Check_FMOD_Error(result, "FMOD::System::playSound");
} }
//llinfos << "Setting up channel " << std::hex << mChannelID << std::dec << llendl; //llinfos << "Setting up channel " << std::hex << mChannelID << std::dec << llendl;
@@ -531,13 +537,13 @@ bool LLAudioChannelFMODEX::updateBuffer()
if (mCurrentSourcep) if (mCurrentSourcep)
{ {
// SJB: warnings can spam and hurt framerate, disabling // SJB: warnings can spam and hurt framerate, disabling
U32 result; FMOD_RESULT result;
result = mChannelp->setVolume(getSecondaryGain() * mCurrentSourcep->getGain()); result = mChannelp->setVolume(getSecondaryGain() * mCurrentSourcep->getGain());
//Check_FMOD_Error(result, "LLAudioChannelFMODEX::updateBuffer"); //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);
/*if(Check_FMOD_ERROR(result, "LLAudioChannelFMODEX::updateBuffer")) /*if(Check_FMOD_Error(result, "FMOD::Channel::setMode"))
{ {
S32 index; S32 index;
mChannelp->getIndex(&index); mChannelp->getIndex(&index);
@@ -599,7 +605,7 @@ void LLAudioChannelFMODEX::updateLoop()
// //
U32 cur_pos; U32 cur_pos;
mChannelp->getPosition(&cur_pos,FMOD_TIMEUNIT_PCMBYTES); mChannelp->getPosition(&cur_pos,FMOD_TIMEUNIT_PCMBYTES);
if (cur_pos < (U32)mLastSamplePos) if (cur_pos < (U32)mLastSamplePos)
{ {
mLoopedThisFrame = true; mLoopedThisFrame = true;
@@ -718,13 +724,16 @@ bool LLAudioBufferFMODEX::loadWAV(const std::string& filename)
mSoundp = NULL; mSoundp = NULL;
} }
FMOD_MODE base_mode = FMOD_LOOP_NORMAL; FMOD_MODE base_mode = FMOD_LOOP_NORMAL | FMOD_SOFTWARE;
FMOD_CREATESOUNDEXINFO exinfo;
memset(&exinfo,0,sizeof(exinfo));
exinfo.cbsize = sizeof(exinfo);
exinfo.suggestedsoundtype = FMOD_SOUND_TYPE_WAV; //Hint to speed up loading.
// Load up the wav file into an fmod sample // Load up the wav file into an fmod sample
#if LL_WINDOWS #if LL_WINDOWS
FMOD_RESULT result = getEngine()->getSystem()->createSound((const char*)utf8str_to_utf16str(filename).c_str(), base_mode | FMOD_UNICODE, 0, &mSoundp); FMOD_RESULT result = getEngine()->getSystem()->createSound((const char*)utf8str_to_utf16str(filename).c_str(), base_mode | FMOD_UNICODE, &exinfo, &mSoundp);
#else #else
FMOD_RESULT result = getEngine()->getSystem()->createSound(filename.c_str(), base_mode | FMOD_SOFTWARE, 0, &mSoundp); FMOD_RESULT result = getEngine()->getSystem()->createSound(filename.c_str(), base_mode, &exinfo, &mSoundp);
#endif #endif
if (result != FMOD_OK) if (result != FMOD_OK)

View File

@@ -123,8 +123,6 @@ public:
/*virtual*/ bool loadWAV(const std::string& filename); /*virtual*/ bool loadWAV(const std::string& filename);
/*virtual*/ U32 getLength(); /*virtual*/ U32 getLength();
friend class LLAudioChannelFMODEX; friend class LLAudioChannelFMODEX;
void set3DMode(bool use3d);
protected: protected:
LLAudioEngine_FMODEX *getEngine() const {return mEnginep;} LLAudioEngine_FMODEX *getEngine() const {return mEnginep;}
LLAudioEngine_FMODEX *mEnginep; LLAudioEngine_FMODEX *mEnginep;

View File

@@ -346,7 +346,12 @@ LLAudioStreamManagerFMODEX::LLAudioStreamManagerFMODEX(FMOD::System *system, con
{ {
mInternetStreamURL = url; mInternetStreamURL = url;
FMOD_RESULT result = mSystem->createStream(url.c_str(), FMOD_2D | FMOD_NONBLOCKING, 0, &mInternetStream); FMOD_CREATESOUNDEXINFO exinfo;
memset(&exinfo,0,sizeof(exinfo));
exinfo.cbsize = sizeof(exinfo);
exinfo.suggestedsoundtype = FMOD_SOUND_TYPE_MPEG; //Hint to speed up loading.
FMOD_RESULT result = mSystem->createStream(url.c_str(), FMOD_2D | FMOD_NONBLOCKING, &exinfo, &mInternetStream);
if (result!= FMOD_OK) if (result!= FMOD_OK)
{ {