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

@@ -285,7 +285,7 @@ bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata)
return false;
#endif
U32 version;
U32 version = 0;
FMOD_RESULT result;
LL_DEBUGS("AppInit") << "LLAudioEngine_FMODEX::init() initializing FMOD" << LL_ENDL;
@@ -331,7 +331,7 @@ bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata)
if (NULL == getenv("LL_BAD_FMOD_PULSEAUDIO")) /*Flawfinder: ignore*/
{
LL_DEBUGS("AppInit") << "Trying PulseAudio audio output..." << LL_ENDL;
if(mSystem->setOutput(FMOD_OUTPUTTYPE_PULSEAUDIO) == FMOD_OK &&
if((result = mSystem->setOutput(FMOD_OUTPUTTYPE_PULSEAUDIO)) == FMOD_OK &&
(result = mSystem->init(num_channels + 2, fmod_flags, 0)) == FMOD_OK)
{
LL_DEBUGS("AppInit") << "PulseAudio output initialized OKAY" << LL_ENDL;
@@ -352,7 +352,7 @@ bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata)
if (NULL == getenv("LL_BAD_FMOD_ALSA")) /*Flawfinder: ignore*/
{
LL_DEBUGS("AppInit") << "Trying ALSA audio output..." << LL_ENDL;
if(mSystem->setOutput(FMOD_OUTPUTTYPE_ALSA) == FMOD_OK &&
if((result = mSystem->setOutput(FMOD_OUTPUTTYPE_ALSA)) == FMOD_OK &&
(result = mSystem->init(num_channels + 2, fmod_flags, 0)) == FMOD_OK)
{
LL_DEBUGS("AppInit") << "ALSA audio output initialized OKAY" << LL_ENDL;
@@ -373,7 +373,7 @@ bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata)
if (NULL == getenv("LL_BAD_FMOD_OSS")) /*Flawfinder: ignore*/
{
LL_DEBUGS("AppInit") << "Trying OSS audio output..." << LL_ENDL;
if(mSystem->setOutput(FMOD_OUTPUTTYPE_OSS) == FMOD_OK &&
if((result = mSystem->setOutput(FMOD_OUTPUTTYPE_OSS) == FMOD_OK) &&
(result = mSystem->init(num_channels + 2, fmod_flags, 0)) == FMOD_OK)
{
LL_DEBUGS("AppInit") << "OSS audio output initialized OKAY" << LL_ENDL;
@@ -398,20 +398,22 @@ bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata)
// We're interested in logging which output method we
// ended up with, for QA purposes.
FMOD_OUTPUTTYPE output_type;
mSystem->getOutput(&output_type);
switch (output_type)
if(!Check_FMOD_Error(mSystem->getOutput(&output_type), "FMOD::System::getOutput"))
{
case FMOD_OUTPUTTYPE_NOSOUND:
LL_INFOS("AppInit") << "Audio output: NoSound" << LL_ENDL; break;
case FMOD_OUTPUTTYPE_PULSEAUDIO:
LL_INFOS("AppInit") << "Audio output: PulseAudio" << LL_ENDL; break;
case FMOD_OUTPUTTYPE_ALSA:
LL_INFOS("AppInit") << "Audio output: ALSA" << LL_ENDL; break;
case FMOD_OUTPUTTYPE_OSS:
LL_INFOS("AppInit") << "Audio output: OSS" << LL_ENDL; break;
default:
LL_INFOS("AppInit") << "Audio output: Unknown!" << LL_ENDL; break;
};
switch (output_type)
{
case FMOD_OUTPUTTYPE_NOSOUND:
LL_INFOS("AppInit") << "Audio output: NoSound" << LL_ENDL; break;
case FMOD_OUTPUTTYPE_PULSEAUDIO:
LL_INFOS("AppInit") << "Audio output: PulseAudio" << LL_ENDL; break;
case FMOD_OUTPUTTYPE_ALSA:
LL_INFOS("AppInit") << "Audio output: ALSA" << LL_ENDL; break;
case FMOD_OUTPUTTYPE_OSS:
LL_INFOS("AppInit") << "Audio output: OSS" << LL_ENDL; break;
default:
LL_INFOS("AppInit") << "Audio output: Unknown!" << LL_ENDL; break;
};
}
#else // LL_LINUX
// initialize the FMOD engine
@@ -435,10 +437,10 @@ bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata)
if (mEnableProfiler)
{
mSystem->createChannelGroup("None", &mChannelGroups[AUDIO_TYPE_NONE]);
mSystem->createChannelGroup("SFX", &mChannelGroups[AUDIO_TYPE_SFX]);
mSystem->createChannelGroup("UI", &mChannelGroups[AUDIO_TYPE_UI]);
mSystem->createChannelGroup("Ambient", &mChannelGroups[AUDIO_TYPE_AMBIENT]);
Check_FMOD_Error(mSystem->createChannelGroup("None", &mChannelGroups[AUDIO_TYPE_NONE]), "FMOD::System::createChannelGroup");
Check_FMOD_Error(mSystem->createChannelGroup("SFX", &mChannelGroups[AUDIO_TYPE_SFX]), "FMOD::System::createChannelGroup");
Check_FMOD_Error(mSystem->createChannelGroup("UI", &mChannelGroups[AUDIO_TYPE_UI]), "FMOD::System::createChannelGroup");
Check_FMOD_Error(mSystem->createChannelGroup("Ambient", &mChannelGroups[AUDIO_TYPE_AMBIENT]), "FMOD::System::createChannelGroup");
}
// set up our favourite FMOD-native streaming audio implementation if none has already been added
@@ -451,35 +453,40 @@ bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata)
unsigned int r_bufferlength;
char r_name[256];
FMOD_SPEAKERMODE speaker_mode;
mSystem->getDSPBufferSize(&r_bufferlength, &r_numbuffers);
mSystem->getSoftwareFormat(&r_samplerate, NULL, &r_channels, NULL, NULL, &r_bits);
mSystem->getDriverInfo(0, r_name, 255, 0);
mSystem->getSpeakerMode(&speaker_mode);
std::string speaker_mode_str = "unknown";
switch(speaker_mode)
if (!Check_FMOD_Error(mSystem->getDSPBufferSize(&r_bufferlength, &r_numbuffers), "FMOD::System::getDSPBufferSize") &&
!Check_FMOD_Error(mSystem->getSoftwareFormat(&r_samplerate, NULL, &r_channels, NULL, NULL, &r_bits), "FMOD::System::getSoftwareFormat") &&
!Check_FMOD_Error(mSystem->getDriverInfo(0, r_name, 255, 0), "FMOD::System::getDriverInfo") &&
!Check_FMOD_Error(mSystem->getSpeakerMode(&speaker_mode), "FMOD::System::getSpeakerMode"))
{
#define SPEAKER_MODE_CASE(MODE) case MODE: speaker_mode_str = #MODE; break;
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_RAW)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_MONO)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_STEREO)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_QUAD)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_SURROUND)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_5POINT1)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_7POINT1)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_SRS5_1_MATRIX)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_MYEARS)
default:;
#undef SPEAKER_MODE_CASE
std::string speaker_mode_str = "unknown";
switch(speaker_mode)
{
#define SPEAKER_MODE_CASE(MODE) case MODE: speaker_mode_str = #MODE; break;
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_RAW)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_MONO)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_STEREO)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_QUAD)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_SURROUND)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_5POINT1)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_7POINT1)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_SRS5_1_MATRIX)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_MYEARS)
default:;
#undef SPEAKER_MODE_CASE
}
r_name[255] = '\0';
int latency = 1000.0 * r_bufferlength * r_numbuffers /r_samplerate;
LL_INFOS("AppInit") << "FMOD device: "<< r_name << "\n"
<< "Output mode: "<< speaker_mode_str << "\n"
<< "FMOD Ex parameters: " << r_samplerate << " Hz * " << r_channels << " * " <<r_bits <<" bit\n"
<< "\tbuffer " << r_bufferlength << " * " << r_numbuffers << " (" << latency <<"ms)" << LL_ENDL;
}
else
{
LL_WARNS("AppInit") << "Failed to retrieve FMOD device info!" << LL_ENDL;
}
r_name[255] = '\0';
int latency = 1000.0 * r_bufferlength * r_numbuffers /r_samplerate;
LL_INFOS("AppInit") << "FMOD device: "<< r_name << "\n"
<< "Output mode: "<< speaker_mode_str << "\n"
<< "FMOD Ex parameters: " << r_samplerate << " Hz * " << r_channels << " * " <<r_bits <<" bit\n"
<< "\tbuffer " << r_bufferlength << " * " << r_numbuffers << " (" << latency <<"ms)" << LL_ENDL;
mInited = true;
return true;
@@ -520,9 +527,9 @@ void LLAudioEngine_FMODEX::shutdown()
if ( mSystem ) // speculative fix for MAINT-2657
{
LL_INFOS("AudioImpl") << "LLAudioEngine_FMODEX::shutdown() Requesting FMOD Ex system closure" << LL_ENDL;
mSystem->close();
Check_FMOD_Error(mSystem->close(), "FMOD::System::close");
LL_INFOS("AudioImpl") << "LLAudioEngine_FMODEX::shutdown() Requesting FMOD Ex system release" << LL_ENDL;
mSystem->release();
Check_FMOD_Error(mSystem->release(), "FMOD::System::release");
}
LL_INFOS("AudioImpl") << "LLAudioEngine_FMODEX::shutdown() done closing FMOD Ex" << LL_ENDL;
@@ -546,30 +553,27 @@ bool LLAudioEngine_FMODEX::initWind()
{
mNextWindUpdate = 0.0;
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"))
return false;
cleanupWind();
if(mWindGen)
delete mWindGen;
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") || !mWindDSP)
return false;
float frequency = 44100;
mWindDSP->getDefaults(&frequency,0,0,0);
float frequency = 44100;
if (!Check_FMOD_Error(mWindDSP->getDefaults(&frequency,0,0,0), "FMOD::DSP::getDefaults"))
{
mWindGen = new LLWindGen<MIXBUFFERFORMAT>((U32)frequency);
mWindDSP->setUserData((void*)mWindGen);
if (!Check_FMOD_Error(mWindDSP->setUserData((void*)mWindGen), "FMOD::DSP::setUserData") &&
!Check_FMOD_Error(mSystem->playDSP(FMOD_CHANNEL_FREE, mWindDSP, false, 0), "FMOD::System::playDSP"))
return true; //Success
}
if (mWindDSP)
{
mSystem->playDSP(FMOD_CHANNEL_FREE, mWindDSP, false, 0);
return true;
}
cleanupWind();
return false;
}
@@ -578,8 +582,8 @@ void LLAudioEngine_FMODEX::cleanupWind()
{
if (mWindDSP)
{
mWindDSP->remove();
mWindDSP->release();
Check_FMOD_Error(mWindDSP->remove(), "FMOD::DSP::remove");
Check_FMOD_Error(mWindDSP->release(), "FMOD::DSP::release");
mWindDSP = NULL;
}
@@ -631,8 +635,8 @@ void LLAudioEngine_FMODEX::setInternalGain(F32 gain)
gain = llclamp( gain, 0.0f, 1.0f );
FMOD::ChannelGroup *master_group;
mSystem->getMasterChannelGroup(&master_group);
if(Check_FMOD_Error(mSystem->getMasterChannelGroup(&master_group), "FMOD::System::getMasterChannelGroup"))
return;
master_group->setVolume(gain);
LLStreamingAudioInterface *saimpl = getStreamingAudioImpl();
@@ -1015,10 +1019,9 @@ FMOD_RESULT F_CALLBACK windCallback(FMOD_DSP_STATE *dsp_state, float *originalbu
FMOD::DSP *thisdsp = (FMOD::DSP *)dsp_state->instance;
thisdsp->getUserData((void **)&windgen);
S32 channels, configwidth, configheight;
thisdsp->getInfo(0, 0, &channels, &configwidth, &configheight);
windgen->windGenerate((LLAudioEngine_FMODEX::MIXBUFFERFORMAT *)newbuffer, length);
if (windgen)
windgen->windGenerate((LLAudioEngine_FMODEX::MIXBUFFERFORMAT *)newbuffer, length);
return FMOD_OK;
}

View File

@@ -79,7 +79,7 @@ bool attemptDelayLoad()
static bool sVerboseDebugging = false;
FMOD_RESULT F_CALLBACK windCallback(FMOD_DSP_STATE *dsp_state, float *originalbuffer, float *newbuffer, unsigned int length, int inchannels, int *outchannels);
FMOD_RESULT F_CALLBACK windCallback(FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int *outchannels);
FMOD::ChannelGroup *LLAudioEngine_FMODSTUDIO::mChannelGroups[LLAudioEngine::AUDIO_TYPE_COUNT] = {0};
@@ -287,7 +287,7 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata)
return false;
#endif
U32 version;
U32 version = 0;
FMOD_RESULT result;
LL_DEBUGS("AppInit") << "LLAudioEngine_FMODSTUDIO::init() initializing FMOD" << LL_ENDL;
@@ -330,7 +330,7 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata)
if (NULL == getenv("LL_BAD_FMOD_PULSEAUDIO")) /*Flawfinder: ignore*/
{
LL_DEBUGS("AppInit") << "Trying PulseAudio audio output..." << LL_ENDL;
if(mSystem->setOutput(FMOD_OUTPUTTYPE_PULSEAUDIO) == FMOD_OK &&
if((result = mSystem->setOutput(FMOD_OUTPUTTYPE_PULSEAUDIO)) == FMOD_OK &&
(result = mSystem->init(num_channels + 2, fmod_flags, 0)) == FMOD_OK)
{
LL_DEBUGS("AppInit") << "PulseAudio output initialized OKAY" << LL_ENDL;
@@ -351,7 +351,7 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata)
if (NULL == getenv("LL_BAD_FMOD_ALSA")) /*Flawfinder: ignore*/
{
LL_DEBUGS("AppInit") << "Trying ALSA audio output..." << LL_ENDL;
if(mSystem->setOutput(FMOD_OUTPUTTYPE_ALSA) == FMOD_OK &&
if((result = mSystem->setOutput(FMOD_OUTPUTTYPE_ALSA)) == FMOD_OK &&
(result = mSystem->init(num_channels + 2, fmod_flags, 0)) == FMOD_OK)
{
LL_DEBUGS("AppInit") << "ALSA audio output initialized OKAY" << LL_ENDL;
@@ -372,7 +372,7 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata)
if (NULL == getenv("LL_BAD_FMOD_OSS")) /*Flawfinder: ignore*/
{
LL_DEBUGS("AppInit") << "Trying OSS audio output..." << LL_ENDL;
if(mSystem->setOutput(FMOD_OUTPUTTYPE_OSS) == FMOD_OK &&
if((result = mSystem->setOutput(FMOD_OUTPUTTYPE_OSS) == FMOD_OK) &&
(result = mSystem->init(num_channels + 2, fmod_flags, 0)) == FMOD_OK)
{
LL_DEBUGS("AppInit") << "OSS audio output initialized OKAY" << LL_ENDL;
@@ -397,20 +397,22 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata)
// We're interested in logging which output method we
// ended up with, for QA purposes.
FMOD_OUTPUTTYPE output_type;
mSystem->getOutput(&output_type);
switch (output_type)
if(!Check_FMOD_Error(mSystem->getOutput(&output_type), "FMOD::System::getOutput"))
{
case FMOD_OUTPUTTYPE_NOSOUND:
LL_INFOS("AppInit") << "Audio output: NoSound" << LL_ENDL; break;
case FMOD_OUTPUTTYPE_PULSEAUDIO:
LL_INFOS("AppInit") << "Audio output: PulseAudio" << LL_ENDL; break;
case FMOD_OUTPUTTYPE_ALSA:
LL_INFOS("AppInit") << "Audio output: ALSA" << LL_ENDL; break;
case FMOD_OUTPUTTYPE_OSS:
LL_INFOS("AppInit") << "Audio output: OSS" << LL_ENDL; break;
default:
LL_INFOS("AppInit") << "Audio output: Unknown!" << LL_ENDL; break;
};
switch (output_type)
{
case FMOD_OUTPUTTYPE_NOSOUND:
LL_INFOS("AppInit") << "Audio output: NoSound" << LL_ENDL; break;
case FMOD_OUTPUTTYPE_PULSEAUDIO:
LL_INFOS("AppInit") << "Audio output: PulseAudio" << LL_ENDL; break;
case FMOD_OUTPUTTYPE_ALSA:
LL_INFOS("AppInit") << "Audio output: ALSA" << LL_ENDL; break;
case FMOD_OUTPUTTYPE_OSS:
LL_INFOS("AppInit") << "Audio output: OSS" << LL_ENDL; break;
default:
LL_INFOS("AppInit") << "Audio output: Unknown!" << LL_ENDL; break;
};
}
#else // LL_LINUX
// initialize the FMOD engine
@@ -434,10 +436,10 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata)
if (mEnableProfiler)
{
mSystem->createChannelGroup("None", &mChannelGroups[AUDIO_TYPE_NONE]);
mSystem->createChannelGroup("SFX", &mChannelGroups[AUDIO_TYPE_SFX]);
mSystem->createChannelGroup("UI", &mChannelGroups[AUDIO_TYPE_UI]);
mSystem->createChannelGroup("Ambient", &mChannelGroups[AUDIO_TYPE_AMBIENT]);
Check_FMOD_Error(mSystem->createChannelGroup("None", &mChannelGroups[AUDIO_TYPE_NONE]), "FMOD::System::createChannelGroup");
Check_FMOD_Error(mSystem->createChannelGroup("SFX", &mChannelGroups[AUDIO_TYPE_SFX]), "FMOD::System::createChannelGroup");
Check_FMOD_Error(mSystem->createChannelGroup("UI", &mChannelGroups[AUDIO_TYPE_UI]), "FMOD::System::createChannelGroup");
Check_FMOD_Error(mSystem->createChannelGroup("Ambient", &mChannelGroups[AUDIO_TYPE_AMBIENT]), "FMOD::System::createChannelGroup");
}
// set up our favourite FMOD-native streaming audio implementation if none has already been added
@@ -450,32 +452,37 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata)
unsigned int r_bufferlength;
char r_name[256];
FMOD_SPEAKERMODE speaker_mode;
mSystem->getDSPBufferSize(&r_bufferlength, &r_numbuffers);
mSystem->getSoftwareFormat(&r_samplerate, &speaker_mode, NULL);
mSystem->getDriverInfo(0, r_name, 255, NULL, NULL, &speaker_mode, NULL);
std::string speaker_mode_str = "unknown";
switch(speaker_mode)
if (!Check_FMOD_Error(mSystem->getDSPBufferSize(&r_bufferlength, &r_numbuffers), "FMOD::System::getDSPBufferSize") &&
!Check_FMOD_Error(mSystem->getSoftwareFormat(&r_samplerate, &speaker_mode, NULL), "FMOD::System::getSoftwareFormat") &&
!Check_FMOD_Error(mSystem->getDriverInfo(0, r_name, 255, NULL, NULL, &speaker_mode, NULL), "FMOD::System::getDriverInfo"))
{
#define SPEAKER_MODE_CASE(MODE) case MODE: speaker_mode_str = #MODE; break;
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_RAW)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_MONO)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_STEREO)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_QUAD)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_SURROUND)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_5POINT1)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_7POINT1)
default:;
#undef SPEAKER_MODE_CASE
std::string speaker_mode_str = "unknown";
switch(speaker_mode)
{
#define SPEAKER_MODE_CASE(MODE) case MODE: speaker_mode_str = #MODE; break;
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_RAW)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_MONO)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_STEREO)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_QUAD)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_SURROUND)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_5POINT1)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_7POINT1)
default:;
#undef SPEAKER_MODE_CASE
}
r_name[255] = '\0';
int latency = 1000.0 * r_bufferlength * r_numbuffers /r_samplerate;
LL_INFOS("AppInit") << "FMOD device: "<< r_name << "\n"
<< "Output mode: "<< speaker_mode_str << "\n"
<< "FMOD Studio parameters: " << r_samplerate << " Hz * " <<" bit\n"
<< "\tbuffer " << r_bufferlength << " * " << r_numbuffers << " (" << latency <<"ms)" << LL_ENDL;
}
else
{
LL_WARNS("AppInit") << "Failed to retrieve FMOD device info!" << LL_ENDL;
}
r_name[255] = '\0';
int latency = 1000.0 * r_bufferlength * r_numbuffers /r_samplerate;
LL_INFOS("AppInit") << "FMOD device: "<< r_name << "\n"
<< "Output mode: "<< speaker_mode_str << "\n"
<< "FMOD Studio parameters: " << r_samplerate << " Hz * " <<" bit\n"
<< "\tbuffer " << r_bufferlength << " * " << r_numbuffers << " (" << latency <<"ms)" << LL_ENDL;
mInited = true;
return true;
@@ -516,9 +523,9 @@ void LLAudioEngine_FMODSTUDIO::shutdown()
if ( mSystem ) // speculative fix for MAINT-2657
{
LL_INFOS("AudioImpl") << "LLAudioEngine_FMODSTUDIO::shutdown() Requesting FMOD Studio system closure" << LL_ENDL;
mSystem->close();
Check_FMOD_Error(mSystem->close(), "FMOD::System::close");
LL_INFOS("AudioImpl") << "LLAudioEngine_FMODSTUDIO::shutdown() Requesting FMOD Studio system release" << LL_ENDL;
mSystem->release();
Check_FMOD_Error(mSystem->release(), "FMOD::System::release");
}
LL_INFOS("AudioImpl") << "LLAudioEngine_FMODSTUDIO::shutdown() done closing FMOD Studio" << LL_ENDL;
@@ -542,34 +549,30 @@ bool LLAudioEngine_FMODSTUDIO::initWind()
{
mNextWindUpdate = 0.0;
if (!mWindDSP)
{
FMOD_DSP_DESCRIPTION dspdesc;
memset(&dspdesc, 0, sizeof(FMOD_DSP_DESCRIPTION)); //Set everything to zero
dspdesc.pluginsdkversion = FMOD_PLUGIN_SDK_VERSION;
strncpy(dspdesc.name,"Wind Unit", sizeof(dspdesc.name)); //Set name to "Wind Unit"
dspdesc.numoutputbuffers = 1;
dspdesc.read = &windCallback; //Assign callback.
if(Check_FMOD_Error(mSystem->createDSP(&dspdesc, &mWindDSP), "FMOD::createDSP"))
return false;
cleanupWind();
if(mWindGen)
delete mWindGen;
FMOD_DSP_DESCRIPTION dspdesc;
memset(&dspdesc, 0, sizeof(FMOD_DSP_DESCRIPTION)); //Set everything to zero
dspdesc.pluginsdkversion = FMOD_PLUGIN_SDK_VERSION;
strncpy(dspdesc.name,"Wind Unit", sizeof(dspdesc.name)); //Set name to "Wind Unit"
dspdesc.numoutputbuffers = 1;
dspdesc.read = &windCallback; //Assign callback.
if (Check_FMOD_Error(mSystem->createDSP(&dspdesc, &mWindDSP), "FMOD::createDSP") || !mWindDSP)
return false;
int frequency = 44100;
mSystem->getSoftwareFormat(&frequency, NULL, NULL);
int frequency = 44100;
if (!Check_FMOD_Error(mSystem->getSoftwareFormat(&frequency, NULL, NULL), "FMOD::System::getSoftwareFormat"))
{
mWindGen = new LLWindGen<MIXBUFFERFORMAT>((U32)frequency);
mWindDSP->setUserData((void*)mWindGen);
FMOD_SPEAKERMODE mode;
if (!Check_FMOD_Error(mWindDSP->setUserData((void*)mWindGen), "FMOD::DSP::setUserData") &&
!Check_FMOD_Error(mSystem->playDSP(mWindDSP, NULL, false, 0), "FMOD::System::playDSP") &&
!Check_FMOD_Error(mSystem->getSoftwareFormat(NULL, &mode, NULL), "FMOD::System::getSoftwareFormat") &&
!Check_FMOD_Error(mWindDSP->setChannelFormat(FMOD_CHANNELMASK_STEREO, 2, mode), "FMOD::DSP::setChannelFormat"))
return true; //Success
}
if (mWindDSP)
{
mSystem->playDSP(mWindDSP, NULL, false, 0);
FMOD_SPEAKERMODE mode;
mSystem->getSoftwareFormat(NULL, &mode, NULL);
mWindDSP->setChannelFormat(FMOD_CHANNELMASK_STEREO, 2, mode);
return true;
}
cleanupWind();
return false;
}
@@ -578,7 +581,10 @@ void LLAudioEngine_FMODSTUDIO::cleanupWind()
{
if (mWindDSP)
{
mWindDSP->release();
FMOD::ChannelGroup* mastergroup = NULL;
if (!Check_FMOD_Error(mSystem->getMasterChannelGroup(&mastergroup), "FMOD::System::getMasterChannelGroup") && mastergroup)
Check_FMOD_Error(mastergroup->removeDSP(mWindDSP), "FMOD::ChannelGroup::removeDSP");
Check_FMOD_Error(mWindDSP->release(), "FMOD::DSP::release");
mWindDSP = NULL;
}
@@ -630,8 +636,9 @@ void LLAudioEngine_FMODSTUDIO::setInternalGain(F32 gain)
gain = llclamp( gain, 0.0f, 1.0f );
FMOD::ChannelGroup *master_group;
mSystem->getMasterChannelGroup(&master_group);
if(Check_FMOD_Error(mSystem->getMasterChannelGroup(&master_group), "FMOD::System::getMasterChannelGroup"))
return;
master_group->setVolume(gain);
LLStreamingAudioInterface *saimpl = getStreamingAudioImpl();
@@ -999,21 +1006,20 @@ void LLAudioChannelFMODSTUDIO::set3DMode(bool use3d)
}
FMOD_RESULT F_CALLBACK windCallback(FMOD_DSP_STATE *dsp_state, float *originalbuffer, float *newbuffer, unsigned int length, int inchannels, int *outchannels)
FMOD_RESULT F_CALLBACK windCallback(FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int *outchannels)
{
// originalbuffer = fmod's original mixbuffer.
// newbuffer = the buffer passed from the previous DSP unit.
// length = length in samples at this mix time.
// userdata = user parameter passed through in FSOUND_DSP_Create.
// inbuffer = incomming data.
// newbuffer = outgoing data. AKA this DSP's output.
// length = length in samples at this mix time. True buffer size, in bytes, would be (length * sizeof(float) * inchannels).
// userdata = user-provided data attached this DSP via FMOD::DSP::setUserData.
LLWindGen<LLAudioEngine_FMODSTUDIO::MIXBUFFERFORMAT> *windgen;
FMOD::DSP *thisdsp = (FMOD::DSP *)dsp_state->instance;
thisdsp->getUserData((void **)&windgen);
S32 channels, configwidth, configheight;
thisdsp->getInfo(0, 0, &channels, &configwidth, &configheight);
windgen->windGenerate((LLAudioEngine_FMODSTUDIO::MIXBUFFERFORMAT *)newbuffer, length);
if (windgen)
windgen->windGenerate((LLAudioEngine_FMODSTUDIO::MIXBUFFERFORMAT *)outbuffer, length);
return FMOD_OK;
}

View File

@@ -39,6 +39,13 @@
#include "llstreamingaudio_fmodex.h"
inline bool Check_FMOD_Error(FMOD_RESULT result, const char *string)
{
if (result == FMOD_OK)
return false;
LL_WARNS("AudioImpl") << string << " Error: " << FMOD_ErrorString(result) << LL_ENDL;
return true;
}
class LLAudioStreamManagerFMODEX
{
@@ -50,7 +57,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;
@@ -72,11 +79,14 @@ LLStreamingAudio_FMODEX::LLStreamingAudio_FMODEX(FMOD::System *system) :
mGain(1.0f),
mMetaData(NULL)
{
FMOD_RESULT result;
// Number of milliseconds of audio to buffer for the audio card.
// Must be larger than the usual Second Life frame stutter time.
const U32 buffer_seconds = 10; //sec
const U32 estimated_bitrate = 128; //kbit/sec
mSystem->setStreamBufferSize(estimated_bitrate * buffer_seconds * 128/*bytes/kbit*/, FMOD_TIMEUNIT_RAWBYTES);
result = mSystem->setStreamBufferSize(estimated_bitrate * buffer_seconds * 128/*bytes/kbit*/, FMOD_TIMEUNIT_RAWBYTES);
Check_FMOD_Error(result, "FMOD::System::setStreamBufferSize");
// Here's where we set the size of the network buffer and some buffering
// parameters. In this case we want a network buffer of 16k, we want it
@@ -200,9 +210,15 @@ void LLStreamingAudio_FMODEX::update()
unsigned int progress;
bool starving;
bool diskbusy;
FMOD_OPENSTATE open_state = mCurrentInternetStreamp->getOpenState(&progress, &starving, &diskbusy);
FMOD_OPENSTATE open_state;
FMOD_RESULT res = mCurrentInternetStreamp->getOpenState(open_state, &progress, &starving, &diskbusy);
if (open_state == FMOD_OPENSTATE_READY)
if (res != FMOD_OK || open_state == FMOD_OPENSTATE_ERROR)
{
stop();
return;
}
else if (open_state == FMOD_OPENSTATE_READY)
{
// Stream is live
@@ -212,14 +228,9 @@ void LLStreamingAudio_FMODEX::update()
{
// Reset volume to previously set volume
setGain(getGain());
mFMODInternetStreamChannelp->setPaused(false);
Check_FMOD_Error(mFMODInternetStreamChannelp->setPaused(false), "FMOD::Channel::setPaused");
}
}
else if(open_state == FMOD_OPENSTATE_ERROR)
{
stop();
return;
}
if(mFMODInternetStreamChannelp)
{
@@ -255,7 +266,7 @@ void LLStreamingAudio_FMODEX::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:
@@ -321,18 +332,17 @@ void LLStreamingAudio_FMODEX::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");
}
}
}
@@ -349,8 +359,8 @@ void LLStreamingAudio_FMODEX::stop()
}
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");
mFMODInternetStreamChannelp = NULL;
}
@@ -431,7 +441,7 @@ void LLStreamingAudio_FMODEX::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");
}
}
@@ -441,8 +451,8 @@ void LLStreamingAudio_FMODEX::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;
static std::vector<float> local_array(count); //Have to have an extra buffer to mix channels. Bleh.
@@ -495,7 +505,8 @@ LLAudioStreamManagerFMODEX::LLAudioStreamManagerFMODEX(FMOD::System *system, con
FMOD::Channel *LLAudioStreamManagerFMODEX::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;
@@ -504,7 +515,7 @@ FMOD::Channel *LLAudioStreamManagerFMODEX::startStream()
if(mStreamChannel)
return mStreamChannel; //Already have a channel for this stream.
mSystem->playSound(FMOD_CHANNEL_FREE, mInternetStream, true, &mStreamChannel);
Check_FMOD_Error(mSystem->playSound(FMOD_CHANNEL_FREE, mInternetStream, true, &mStreamChannel), "FMOD::System::playSound");
return mStreamChannel;
}
@@ -513,17 +524,17 @@ bool LLAudioStreamManagerFMODEX::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;
/*case FSOUND_STREAM_NET_NOTCONNECTED:
case FSOUND_STREAM_NET_BUFFERING:
case FSOUND_STREAM_NET_READY:
case FSOUND_STREAM_NET_ERROR:*/
default:
close = true;
switch (open_state)
{
case FMOD_OPENSTATE_CONNECTING:
close = false;
break;
default:
close = true;
}
}
if (close && mInternetStream->release() == FMOD_OK)
@@ -543,21 +554,23 @@ bool LLAudioStreamManagerFMODEX::stopStream()
}
}
FMOD_OPENSTATE LLAudioStreamManagerFMODEX::getOpenState(unsigned int* percentbuffered, bool* starving, bool* diskbusy)
FMOD_RESULT LLAudioStreamManagerFMODEX::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_FMODEX::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.cbSize=sizeof(settings);
settings.defaultDecodeBufferSize = decodebuffertime;//ms
mSystem->setAdvancedSettings(&settings);
Check_FMOD_Error(mSystem->setAdvancedSettings(&settings), "FMOD::System::setAdvancedSettings");
}
bool LLStreamingAudio_FMODEX::releaseDeadStreams()

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;
}

View File

@@ -75,6 +75,7 @@ class LLStreamingAudio_FMODSTUDIO : public LLStreamingAudioInterface
private:
bool releaseDeadStreams();
void cleanupWaveData();
FMOD::System *mSystem;