diff options
Diffstat (limited to 'indra/llaudio')
| -rw-r--r-- | indra/llaudio/CMakeLists.txt | 4 | ||||
| -rw-r--r--[-rwxr-xr-x] | indra/llaudio/llaudiodecodemgr.cpp | 2 | ||||
| -rw-r--r--[-rwxr-xr-x] | indra/llaudio/llaudioengine.h | 0 | ||||
| -rw-r--r-- | indra/llaudio/llaudioengine_openal.cpp | 104 | ||||
| -rw-r--r-- | indra/llaudio/llaudioengine_openal.h | 19 |
5 files changed, 127 insertions, 2 deletions
diff --git a/indra/llaudio/CMakeLists.txt b/indra/llaudio/CMakeLists.txt index f36da83c69..75534a9f60 100644 --- a/indra/llaudio/CMakeLists.txt +++ b/indra/llaudio/CMakeLists.txt @@ -71,3 +71,7 @@ if( TARGET ll::fmodstudio ) endif() include(LibraryInstall) + +if (USE_PRECOMPILED_HEADERS) + target_precompile_headers(llaudio REUSE_FROM llprecompiled) +endif () diff --git a/indra/llaudio/llaudiodecodemgr.cpp b/indra/llaudio/llaudiodecodemgr.cpp index d8a6fffea6..232b429130 100755..100644 --- a/indra/llaudio/llaudiodecodemgr.cpp +++ b/indra/llaudio/llaudiodecodemgr.cpp @@ -199,7 +199,7 @@ bool LLVorbisDecodeState::initDecode() LL_DEBUGS("AudioEngine") << "Initing decode from vfile: " << mUUID << LL_ENDL; mInFilep = new LLFileSystem(mUUID, LLAssetType::AT_SOUND); - if (!mInFilep || !mInFilep->getSize()) + if (!mInFilep || mInFilep->getSize() <= 0) { LL_WARNS("AudioEngine") << "unable to open vorbis source vfile for reading" << LL_ENDL; delete mInFilep; diff --git a/indra/llaudio/llaudioengine.h b/indra/llaudio/llaudioengine.h index a9a229c0a5..a9a229c0a5 100755..100644 --- a/indra/llaudio/llaudioengine.h +++ b/indra/llaudio/llaudioengine.h diff --git a/indra/llaudio/llaudioengine_openal.cpp b/indra/llaudio/llaudioengine_openal.cpp index 755547bfaa..4126c8ef80 100644 --- a/indra/llaudio/llaudioengine_openal.cpp +++ b/indra/llaudio/llaudioengine_openal.cpp @@ -42,7 +42,14 @@ LLAudioEngine_OpenAL::LLAudioEngine_OpenAL() mWindBufSamples(0), mWindBufBytes(0), mWindSource(AL_NONE), - mNumEmptyWindALBuffers(MAX_NUM_WIND_BUFFERS) + mNumEmptyWindALBuffers(MAX_NUM_WIND_BUFFERS), + mALDevice(NULL), + mHasReopenExt(false), + mReopenDeviceSOFT(NULL), + mHasSystemEventsExt(false), + mEventControlSOFT(NULL), + mEventCallbackSOFT(NULL), + mDefaultDeviceChanged(false) { } @@ -87,6 +94,38 @@ bool LLAudioEngine_OpenAL::init(void* userdata, const std::string &app_title) ALC_DEFAULT_DEVICE_SPECIFIER)) << LL_ENDL; + mALDevice = device; + + mHasReopenExt = alcIsExtensionPresent(mALDevice, "ALC_SOFT_reopen_device"); + if (mHasReopenExt) + { + mReopenDeviceSOFT = (LPALCREOPENDEVICESOFT)alcGetProcAddress(mALDevice, "alcReopenDeviceSOFT"); + mHasReopenExt = (mReopenDeviceSOFT != NULL); + } + LL_INFOS() << "ALC_SOFT_reopen_device " << (mHasReopenExt ? "supported" : "NOT supported") << LL_ENDL; + + mHasSystemEventsExt = alcIsExtensionPresent(mALDevice, "ALC_SOFT_system_events"); + if (mHasSystemEventsExt) + { + mEventControlSOFT = (LPALCEVENTCONTROLSOFT)alcGetProcAddress(mALDevice, "alcEventControlSOFT"); + mEventCallbackSOFT = (LPALCEVENTCALLBACKSOFT)alcGetProcAddress(mALDevice, "alcEventCallbackSOFT"); + mHasSystemEventsExt = (mEventControlSOFT != NULL && mEventCallbackSOFT != NULL); + } + LL_INFOS() << "ALC_SOFT_system_events " << (mHasSystemEventsExt ? "supported" : "NOT supported") << LL_ENDL; + + if (mHasReopenExt && mHasSystemEventsExt) + { + mEventCallbackSOFT(&LLAudioEngine_OpenAL::onDeviceEventSOFT, this); + ALCenum events[] = { ALC_EVENT_TYPE_DEFAULT_DEVICE_CHANGED_SOFT }; + mEventControlSOFT(1, events, ALC_TRUE); + LL_INFOS() << "Registered for ALC default-device-change notifications" << LL_ENDL; + } + else + { + LL_INFOS() << "Dynamic OS default output device following is not available; " + << "a viewer restart will be needed to pick up default device changes" << LL_ENDL; + } + return true; } @@ -130,9 +169,72 @@ void LLAudioEngine_OpenAL::allocateListener() } // virtual +void LLAudioEngine_OpenAL::idle() +{ + LLAudioEngine::idle(); + + if (mDefaultDeviceChanged) + { + mDefaultDeviceChanged = false; + reopenOnDefaultDevice(); + } +} + +// static +void ALC_APIENTRY LLAudioEngine_OpenAL::onDeviceEventSOFT(ALCenum eventType, ALCenum /*deviceType*/, + ALCdevice* /*device*/, ALCsizei /*length*/, + const ALCchar* /*message*/, void* userParam) noexcept +{ + // This may run on OpenAL's internal thread, so just flip the mDefaultDeviceChanged flag + // and handle device change in idle(). + if (eventType == ALC_EVENT_TYPE_DEFAULT_DEVICE_CHANGED_SOFT) + { + LLAudioEngine_OpenAL* self = static_cast<LLAudioEngine_OpenAL*>(userParam); + if (self) + { + self->mDefaultDeviceChanged = true; + } + } +} + +void LLAudioEngine_OpenAL::reopenOnDefaultDevice() +{ + if (!mHasReopenExt || !mReopenDeviceSOFT || !mALDevice) + { + return; + } + + std::string old_name = ll_safe_string(alcGetString(mALDevice, ALC_DEVICE_SPECIFIER)); + LL_INFOS() << "OS default audio device changed; reopening OpenAL device (was: " + << old_name << ")" << LL_ENDL; + + // Clear any prior device error state so failures below report accurately. + (void)alcGetError(mALDevice); + + if (mReopenDeviceSOFT(mALDevice, NULL, NULL)) + { + LL_INFOS() << "OpenAL device reopened successfully, now on: " + << ll_safe_string(alcGetString(mALDevice, ALC_DEVICE_SPECIFIER)) << LL_ENDL; + } + else + { + ALCenum error = alcGetError(mALDevice); + LL_WARNS() << "alcReopenDeviceSOFT() failed: alc error " << error << LL_ENDL; + } +} + +// virtual void LLAudioEngine_OpenAL::shutdown() { LL_INFOS() << "About to LLAudioEngine::shutdown()" << LL_ENDL; + + if (mHasSystemEventsExt && mEventControlSOFT && mEventCallbackSOFT) + { + ALCenum events[] = { ALC_EVENT_TYPE_DEFAULT_DEVICE_CHANGED_SOFT }; + mEventControlSOFT(1, events, ALC_FALSE); + mEventCallbackSOFT(NULL, NULL); + } + LLAudioEngine::shutdown(); // If a subsequent error occurs while there is still an error recorded diff --git a/indra/llaudio/llaudioengine_openal.h b/indra/llaudio/llaudioengine_openal.h index 574bec416d..da1f376800 100644 --- a/indra/llaudio/llaudioengine_openal.h +++ b/indra/llaudio/llaudioengine_openal.h @@ -33,6 +33,7 @@ #include "llaudioengine.h" #include "lllistener_openal.h" #include "llwindgen.h" +#include "llatomic.h" class LLAudioEngine_OpenAL : public LLAudioEngine { @@ -46,6 +47,7 @@ class LLAudioEngine_OpenAL : public LLAudioEngine virtual void allocateListener(); virtual void shutdown(); + virtual void idle(); void setInternalGain(F32 gain); @@ -68,6 +70,23 @@ class LLAudioEngine_OpenAL : public LLAudioEngine static const int MAX_NUM_WIND_BUFFERS = 80; static const float WIND_BUFFER_SIZE_SEC; // 1/20th sec + + ALCdevice* mALDevice; + + bool mHasReopenExt; + LPALCREOPENDEVICESOFT mReopenDeviceSOFT; + + bool mHasSystemEventsExt; + LPALCEVENTCONTROLSOFT mEventControlSOFT; + LPALCEVENTCALLBACKSOFT mEventCallbackSOFT; + + // Set by onDeviceEventSOFT(), consumed by idle() + LLAtomicBool mDefaultDeviceChanged; + + static void ALC_APIENTRY onDeviceEventSOFT(ALCenum eventType, ALCenum deviceType, + ALCdevice* device, ALCsizei length, + const ALCchar* message, void* userParam) noexcept; + void reopenOnDefaultDevice(); }; class LLAudioChannelOpenAL : public LLAudioChannel |
