diff --git a/.gitignore b/.gitignore index 591a2f99c8..399b833ba2 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ *.bak *.diff *.orig +*.patch *.pyc *.rej *.swp diff --git a/autobuild.xml b/autobuild.xml index 9a15b9441a..87b71fd7cf 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -990,11 +990,11 @@ fmodstudio copyright - FMOD Studio, copyright (c) Firelight Technologies Pty, Ltd., 2012-2017. + FMOD Studio by Firelight Technologies Pty Ltd. description - FMOD Studio audio system library + FMOD Studio API license - fmodstudio + fmod license_file LICENSES/fmodstudio.txt name @@ -1061,58 +1061,6 @@ version 2.01.01 - fmodex - - copyright - COPYRIGHT 2014 FIRELIGHT TECHNOLOGIES PTY LTD. ALL RIGHTS RESERVED - license - fmodex - license_file - LICENSES/fmodex.txt - name - fmodex - platforms - - darwin - - archive - - hash - cba1feed7f6bb671d791a517fddf205a - url - file:///opt/firestorm/fmodex-44461-darwin-201601300040-r23.tar.bz2 - - name - darwin - - linux - - archive - - hash - 9b090869508fabee82dc53cae977fb99 - url - file:///opt/firestorm/fmodex-44461-linux-201601282301-r23.tar.bz2 - - name - linux - - windows - - archive - - hash - 5b1b5ce866afd2a74e445af1fffe6a8b - url - file:///c:/cygwin/opt/firestorm/fmodex-44461-windows-201601282252-r23.tar.bz2 - - name - windows - - - version - 4.44.61 - fontconfig copyright diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt index 7065aa044c..4e6dd92424 100644 --- a/indra/cmake/CMakeLists.txt +++ b/indra/cmake/CMakeLists.txt @@ -30,7 +30,6 @@ set(cmake_SOURCE_FILES FindAutobuild.cmake FindBerkeleyDB.cmake FindFMODSTUDIO.cmake - FindFMODEX.cmake FindGLH.cmake FindGoogleBreakpad.cmake FindHUNSPELL.cmake @@ -42,7 +41,6 @@ set(cmake_SOURCE_FILES FindXmlRpcEpi.cmake FindZLIB.cmake FMODSTUDIO.cmake - FMODEX.cmake FreeType.cmake GLEXT.cmake GLH.cmake diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index 069eada980..858d32b974 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -68,14 +68,6 @@ if(WINDOWS) set(release_files ${release_files} fmod.dll) endif (FMODSTUDIO) - if (FMODEX) - if(ADDRESS_SIZE EQUAL 32) - set(release_files ${release_files} fmodex.dll) - else(ADDRESS_SIZE EQUAL 32) - set(release_files ${release_files} fmodex64.dll) - endif(ADDRESS_SIZE EQUAL 32) - endif (FMODEX) - if (OPENAL) set(release_files ${release_files} OpenAL32.dll alut.dll) endif (OPENAL) @@ -208,11 +200,6 @@ elseif(DARWIN) set(release_files ${release_files} libfmod.dylib) endif (FMODSTUDIO) - if (FMODEX) - set(debug_files ${debug_files} libfmodexL.dylib) - set(release_files ${release_files} libfmodex.dylib) - endif (FMODEX) - elseif(LINUX) # linux is weird, multiple side by side configurations aren't supported # and we don't seem to have any debug shared libs built yet anyways... @@ -271,16 +258,6 @@ elseif(LINUX) set(release_files ${release_files} "libfmod.so") endif (FMODSTUDIO) - if (FMODEX) - if(ADDRESS_SIZE EQUAL 32) - set(debug_files ${debug_files} "libfmodexL.so") - set(release_files ${release_files} "libfmodex.so") - else(ADDRESS_SIZE EQUAL 32) - set(debug_files ${debug_files} "libfmodexL64.so") - set(release_files ${release_files} "libfmodex64.so") - endif(ADDRESS_SIZE EQUAL 32) - endif (FMODEX) - else(WINDOWS) message(STATUS "WARNING: unrecognized platform for staging 3rd party libs, skipping...") set(vivox_lib_dir "${CMAKE_SOURCE_DIR}/newview/vivox-runtime/i686-linux") diff --git a/indra/cmake/FMODEX.cmake b/indra/cmake/FMODEX.cmake deleted file mode 100644 index 642b11e00a..0000000000 --- a/indra/cmake/FMODEX.cmake +++ /dev/null @@ -1,62 +0,0 @@ -# -*- cmake -*- - -# FMOD can be set when launching the make using the argument -DFMODEX:BOOL=ON -# When building using proprietary binaries though (i.e. having access to LL private servers), -# we always build with FMODEX. -# Open source devs should use the -DFMODEX:BOOL=ON then if they want to build with FMOD, whether -# they are using USESYSTEMLIBS or not. -if (INSTALL_PROPRIETARY) - set(FMODEX ON CACHE BOOL "Using FMOD Ex sound library.") -endif (INSTALL_PROPRIETARY) - -if (FMODEX) - if (FMODSTUDIO) - MESSAGE(FATAL_ERROR "You cannot use FMOD Ex if you are already using FMOD Studio.") - endif (FMODSTUDIO) - - if (USESYSTEMLIBS) - # In that case, we use the version of the library installed on the system - set(FMODEX_FIND_REQUIRED ON) - include(FindFMODEX) - else (USESYSTEMLIBS) - if (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR) - # If the path have been specified in the arguments, use that - set(FMODEX_LIBRARIES ${FMODEX_LIBRARY}) - MESSAGE(STATUS "Using FMODEX path: ${FMODEX_LIBRARIES}, ${FMODEX_INCLUDE_DIR}") - else (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR) - # If not, we're going to try to get the package listed in autobuild.xml - # Note: if you're not using INSTALL_PROPRIETARY, the package URL should be local (file:/// URL) - # as accessing the private LL location will fail if you don't have the credential - include(Prebuilt) - use_prebuilt_binary(fmodex) - if (WINDOWS) - if( ADDRESS_SIZE EQUAL 32 ) - set(FMODEX_LIBRARY - debug fmodexL_vc - optimized fmodex_vc) - else( ) - set(FMODEX_LIBRARY - debug fmodexL64_vc - optimized fmodex64_vc) - endif( ) - elseif (DARWIN) - set(FMODEX_LIBRARY - debug fmodexL - optimized fmodex) - elseif (LINUX) - if( ADDRESS_SIZE EQUAL 64 ) - set(FMODEX_LIBRARY - debug fmodexL64 - optimized fmodex64) - else( ) - set(FMODEX_LIBRARY - debug fmodexL - optimized fmodex) - endif( ) - endif (WINDOWS) - set(FMODEX_LIBRARIES ${FMODEX_LIBRARY}) - set(FMODEX_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/fmodex) - endif (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR) - endif (USESYSTEMLIBS) -endif (FMODEX) - diff --git a/indra/cmake/FindFMODEX.cmake b/indra/cmake/FindFMODEX.cmake deleted file mode 100644 index b621727c0e..0000000000 --- a/indra/cmake/FindFMODEX.cmake +++ /dev/null @@ -1,65 +0,0 @@ -# -*- cmake -*- - -# - Find FMODEX -# Find the FMODEX includes and library -# This module defines -# FMODEX_INCLUDE_DIR, where to find fmod.h and fmod_errors.h -# FMODEX_LIBRARIES, the libraries needed to use FMODEX. -# FMODEX, If false, do not try to use FMODEX. -# also defined, but not for general use are -# FMODEX_LIBRARY, where to find the FMODEX library. - -FIND_PATH(FMODEX_INCLUDE_DIR fmod.h PATH_SUFFIXES fmod) - -SET(FMODEX_NAMES ${FMODEX_NAMES} fmodex fmodvc fmodexL_vc) -FIND_LIBRARY(FMODEX_LIBRARY - NAMES ${FMODEX_NAMES} - PATH_SUFFIXES fmodex - ) - -IF (FMODEX_SDK_DIR OR WINDOWS) - if(WINDOWS) - set(FMODEX_SDK_DIR "$ENV{PROGRAMFILES}/FMOD SoundSystem/FMOD Programmers API Windows" CACHE PATH "Path to FMODEX") - STRING(REGEX REPLACE "\\\\" "/" FMODEX_SDK_DIR ${FMODEX_SDK_DIR}) - endif(WINDOWS) - find_library(FMODEX_LIBRARY - fmodex_vc fmodexL_vc - PATHS - ${FMODEX_SDK_DIR}/api/lib - ${FMODEX_SDK_DIR}/api - ${FMODEX_SDK_DIR} - ) - find_path(FMODEX_INCLUDE_DIR fmod.h - ${FMODEX_SDK_DIR}/api/inc - ${FMODEX_SDK_DIR}/api - ${FMODEX_SDK_DIR} - ) - find_path(FMODEX_INCLUDE_DIR fmod.h - ${FMODEX_SDK_DIR}/api/inc - ${FMODEX_SDK_DIR}/api - ${FMODEX_SDK_DIR} - ) - IF (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR) - SET(FMODEX_LIBRARIES ${FMODEX_LIBRARY}) - SET(FMODEX_FOUND "YES") - endif (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR) -ENDIF (FMODEX_SDK_DIR OR WINDOWS) - -IF (FMODEX_FOUND) - IF (NOT FMODEX_FIND_QUIETLY) - MESSAGE(STATUS "Found FMODEX: ${FMODEX_LIBRARIES}") - ENDIF (NOT FMODEX_FIND_QUIETLY) -ELSE (FMODEX_FOUND) - IF (FMODEX_FIND_REQUIRED) - MESSAGE(FATAL_ERROR "Could not find FMODEX library") - ENDIF (FMODEX_FIND_REQUIRED) -ENDIF (FMODEX_FOUND) - -# Deprecated declarations. -SET (NATIVE_FMODEX_INCLUDE_PATH ${FMODEX_INCLUDE_DIR} ) -GET_FILENAME_COMPONENT (NATIVE_FMODEX_LIB_PATH ${FMODEX_LIBRARY} PATH) - -MARK_AS_ADVANCED( - FMODEX_LIBRARY - FMODEX_INCLUDE_DIR - ) diff --git a/indra/lib/python/indra/util/llmanifest.py b/indra/lib/python/indra/util/llmanifest.py index f8771b5936..dd331a4556 100755 --- a/indra/lib/python/indra/util/llmanifest.py +++ b/indra/lib/python/indra/util/llmanifest.py @@ -160,8 +160,6 @@ BASE_ARGUMENTS=[ description="""The name of a file containing the full version number."""), dict(name='viewer_flavor', description='Type of viewer build. Can be oss or hvk.', default="oss"), - dict(name='fmodversion', - description='Version of FMOD used. Can be fmodstudio or fmodex.', default=None) ] def usage(arguments, srctree=""): diff --git a/indra/llaudio/CMakeLists.txt b/indra/llaudio/CMakeLists.txt index 9da9e8f27c..558ede7bf6 100644 --- a/indra/llaudio/CMakeLists.txt +++ b/indra/llaudio/CMakeLists.txt @@ -5,7 +5,6 @@ project(llaudio) include(00-Common) include(LLAudio) include(FMODSTUDIO) -include(FMODEX) include(OPENAL) include(LLCommon) include(LLMath) @@ -60,23 +59,6 @@ if (FMODSTUDIO) ) endif (FMODSTUDIO) -if (FMODEX) - include_directories( - ${FMODEX_INCLUDE_DIR} - ) - list(APPEND llaudio_SOURCE_FILES - llaudioengine_fmodex.cpp - lllistener_fmodex.cpp - llstreamingaudio_fmodex.cpp - ) - - list(APPEND llaudio_HEADER_FILES - llaudioengine_fmodex.h - lllistener_fmodex.h - llstreamingaudio_fmodex.h - ) -endif (FMODEX) - if (OPENAL) include_directories( ${OPENAL_LIBRARIES} diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp index 77935169bb..8be13d7834 100644 --- a/indra/llaudio/llaudioengine.cpp +++ b/indra/llaudio/llaudioengine.cpp @@ -118,7 +118,7 @@ void LLAudioEngine::setDefaults() } -bool LLAudioEngine::init(const S32 num_channels, void* userdata) +bool LLAudioEngine::init(const S32 num_channels, void* userdata, const std::string &app_title) { setDefaults(); diff --git a/indra/llaudio/llaudioengine.h b/indra/llaudio/llaudioengine.h index f685f3fc84..44ed31520f 100644 --- a/indra/llaudio/llaudioengine.h +++ b/indra/llaudio/llaudioengine.h @@ -104,7 +104,7 @@ public: virtual ~LLAudioEngine(); // initialization/startup/shutdown - virtual bool init(const S32 num_channels, void *userdata); + virtual bool init(const S32 num_channels, void *userdata, const std::string &app_title); virtual std::string getDriverName(bool verbose) = 0; virtual void shutdown(); diff --git a/indra/llaudio/llaudioengine_fmodex.cpp b/indra/llaudio/llaudioengine_fmodex.cpp deleted file mode 100644 index d5f5b11bf7..0000000000 --- a/indra/llaudio/llaudioengine_fmodex.cpp +++ /dev/null @@ -1,975 +0,0 @@ -/** - * @file audioengine_fmodex.cpp - * @brief Implementation of LLAudioEngine class abstracting the audio - * support as a FMODEX implementation - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2014, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "linden_common.h" - -#include "llstreamingaudio.h" -#include "llstreamingaudio_fmodex.h" - -#include "llaudioengine_fmodex.h" -#include "lllistener_fmodex.h" - -#include "llerror.h" -#include "llmath.h" -#include "llrand.h" - -#include "fmod.hpp" -#include "fmod_errors.h" -#include "lldir.h" -#include "llapr.h" - -#include "sound_ids.h" - -#include "indra_constants.h" - -FMOD_RESULT F_CALLBACK windCallback(FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int outchannels); - -// Output device selection -static inline bool Check_FMOD_Error(FMOD_RESULT result, const char *string); - -LLUUID FMOD_GUID_to_LLUUID(FMOD_GUID guid) -{ - return LLUUID(llformat("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", guid.Data1, guid.Data2, guid.Data3, - guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7])); -} - -void set_device(FMOD::System* system, const LLUUID& device_uuid) -{ - LL_INFOS() << "LLAudioEngine_FMODEX::setDevice with device_uuid=" << device_uuid << LL_ENDL; - - int drivercount; - if (!Check_FMOD_Error(system->getNumDrivers(&drivercount), "FMOD::System::getNumDrivers") && drivercount > 0) - { - if (device_uuid.isNull()) - { - LL_INFOS() << "Setting driver \"Default\"" << LL_ENDL; - Check_FMOD_Error(system->setDriver(0), "FMOD::System::setDriver"); - } - else - { - FMOD_GUID guid; - - for (int i = 0; i < drivercount; ++i) - { - if (!Check_FMOD_Error(system->getDriverInfo(i, NULL, 0, &guid), "FMOD::System::getDriverInfo")) - { - LLUUID driver_guid = FMOD_GUID_to_LLUUID(guid); - - if (driver_guid == device_uuid) - { - LL_INFOS() << "Setting driver " << i << ": " << driver_guid << LL_ENDL; - Check_FMOD_Error(system->setDriver(i), "FMOD::System::setDriver"); - return; - } - } - } - - LL_INFOS() << "Device not available (anymore) - falling back to default" << LL_ENDL; - Check_FMOD_Error(system->setDriver(0), "FMOD::System::setDriver"); - } - } -} - -FMOD_RESULT F_CALLBACK systemCallback(FMOD_SYSTEM *system, FMOD_SYSTEM_CALLBACKTYPE type, void *commanddata1, void *commanddata2) -{ - FMOD::System* sys = (FMOD::System*)system; - LLAudioEngine_FMODEX* audio_engine = NULL; - if (sys) - { - void* userdata = NULL; - Check_FMOD_Error(sys->getUserData(&userdata), "FMOD::System::getUserData"); - audio_engine = (LLAudioEngine_FMODEX*)userdata; - } - - switch (type) - { - case FMOD_SYSTEM_CALLBACKTYPE_DEVICELISTCHANGED: - LL_DEBUGS() << "FMOD system callback FMOD_SYSTEM_CALLBACK_DEVICELISTCHANGED" << LL_ENDL; - if (sys && audio_engine) - { - set_device(sys, audio_engine->getSelectedDeviceUUID()); - audio_engine->OnOutputDeviceListChanged(audio_engine->getDevices()); - } - break; - default: - break; - } - return FMOD_OK; -} -// > - -FMOD::ChannelGroup *LLAudioEngine_FMODEX::mChannelGroups[LLAudioEngine::AUDIO_TYPE_COUNT] = {0}; - -LLAudioEngine_FMODEX::LLAudioEngine_FMODEX(bool enable_profiler) -{ - mInited = false; - mWindGen = NULL; - mWindDSP = NULL; - mSystem = NULL; - mEnableProfiler = enable_profiler; - mWindDSPDesc = new FMOD_DSP_DESCRIPTION(); - mSelectedDeviceUUID = LLUUID::null; // Output device selection -} - - -LLAudioEngine_FMODEX::~LLAudioEngine_FMODEX() -{ - delete mWindDSPDesc; -} - - -static // Make this file scope so it doesn't collide with the same function in llstreamingaudio_fmodex.cpp -inline bool Check_FMOD_Error(FMOD_RESULT result, const char *string) -{ - if(result == FMOD_OK) - return false; - // Always print out error - //LL_DEBUGS() << string << " Error: " << FMOD_ErrorString(result) << LL_ENDL; - if (result != FMOD_ERR_INVALID_HANDLE) - { - LL_WARNS() << string << " Error: " << FMOD_ErrorString(result) << LL_ENDL; - } - else - { - LL_DEBUGS() << string << " Error: " << FMOD_ErrorString(result) << LL_ENDL; - } - // - return true; -} - -void* F_STDCALL decode_alloc(unsigned int size, FMOD_MEMORY_TYPE type, const char *sourcestr) -{ - if(type & FMOD_MEMORY_STREAM_DECODE) - { - LL_INFOS() << "Decode buffer size: " << size << LL_ENDL; - } - else if(type & FMOD_MEMORY_STREAM_FILE) - { - LL_INFOS() << "Stream buffer size: " << size << LL_ENDL; - } - return new char[size]; -} -void* F_STDCALL decode_realloc(void *ptr, unsigned int size, FMOD_MEMORY_TYPE type, const char *sourcestr) -{ - memset(ptr,0,size); - return ptr; -} -void F_STDCALL decode_dealloc(void *ptr, FMOD_MEMORY_TYPE type, const char *sourcestr) -{ - delete[] (char*)ptr; -} - -bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata) -{ - U32 version; - FMOD_RESULT result; - - LL_DEBUGS("AppInit") << "LLAudioEngine_FMODEX::init() initializing FMOD" << LL_ENDL; - - //result = FMOD::Memory_Initialize(NULL, 0, &decode_alloc, &decode_realloc, &decode_dealloc, FMOD_MEMORY_STREAM_DECODE | FMOD_MEMORY_STREAM_FILE); - //if(Check_FMOD_Error(result, "FMOD::Memory_Initialize")) - // return false; - - // turn off non-error log spam to fmod.log (TODO: why do we even have an fmod.log if we don't link against log lib?) - FMOD::Debug_SetLevel(FMOD_DEBUG_LEVEL_ERROR); - - result = FMOD::System_Create(&mSystem); - if(Check_FMOD_Error(result, "FMOD::System_Create")) - return false; - - //will call LLAudioEngine_FMODEX::allocateListener, which needs a valid mSystem pointer. - LLAudioEngine::init(num_channels, userdata); - - result = mSystem->getVersion(&version); - Check_FMOD_Error(result, "FMOD::System::getVersion"); - - if (version < FMOD_VERSION) - { - LL_WARNS("AppInit") << "Error : You are using the wrong FMOD Ex version (" << version - << ")! You should be using FMOD Ex" << FMOD_VERSION << LL_ENDL; - } - - result = mSystem->setSoftwareFormat(44100, FMOD_SOUND_FORMAT_PCM16, 0, 0, FMOD_DSP_RESAMPLER_LINEAR); - Check_FMOD_Error(result,"FMOD::System::setSoftwareFormat"); - - // In this case, all sounds, PLUS wind and stream will be software. - result = mSystem->setSoftwareChannels(num_channels + 2); - Check_FMOD_Error(result,"FMOD::System::setSoftwareChannels"); - - // Output device selection - Check_FMOD_Error(mSystem->setCallback(systemCallback), "FMOD::System::setCallback"); - Check_FMOD_Error(mSystem->setUserData(this), "FMOD::System::setUserData"); - // - - U32 fmod_flags = FMOD_INIT_NORMAL; - if(mEnableProfiler) - { - fmod_flags |= FMOD_INIT_ENABLE_PROFILE; - // FMOD fixes - //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]); - // - } - -#if LL_LINUX - bool audio_ok = false; - - if (!audio_ok) - { - if (NULL == getenv("LL_BAD_FMOD_PULSEAUDIO")) /*Flawfinder: ignore*/ - { - LL_DEBUGS("AppInit") << "Trying PulseAudio audio output..." << LL_ENDL; - // FMOD fixes - //if(mSystem->setOutput(FMOD_OUTPUTTYPE_PULSEAUDIO) == FMOD_OK && - // (result = mSystem->init(num_channels + 2, fmod_flags, 0)) == FMOD_OK) - if((result = mSystem->setOutput(FMOD_OUTPUTTYPE_PULSEAUDIO)) == FMOD_OK && - // - (result = mSystem->init(num_channels + 2, fmod_flags, const_cast(APP_NAME.c_str()))) == FMOD_OK) - { - LL_DEBUGS("AppInit") << "PulseAudio output initialized OKAY" << LL_ENDL; - audio_ok = true; - } - else - { - Check_FMOD_Error(result, "PulseAudio audio output FAILED to initialize"); - } - } - else - { - LL_DEBUGS("AppInit") << "PulseAudio audio output SKIPPED" << LL_ENDL; - } - } - if (!audio_ok) - { - if (NULL == getenv("LL_BAD_FMOD_ALSA")) /*Flawfinder: ignore*/ - { - LL_DEBUGS("AppInit") << "Trying ALSA audio output..." << LL_ENDL; - // FMOD fixes - //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; - audio_ok = true; - } - else - { - Check_FMOD_Error(result, "ALSA audio output FAILED to initialize"); - } - } - else - { - LL_DEBUGS("AppInit") << "ALSA audio output SKIPPED" << LL_ENDL; - } - } - if (!audio_ok) - { - if (NULL == getenv("LL_BAD_FMOD_OSS")) /*Flawfinder: ignore*/ - { - LL_DEBUGS("AppInit") << "Trying OSS audio output..." << LL_ENDL; - // FMOD fixes - //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; - audio_ok = true; - } - else - { - Check_FMOD_Error(result, "OSS audio output FAILED to initialize"); - } - } - else - { - LL_DEBUGS("AppInit") << "OSS audio output SKIPPED" << LL_ENDL; - } - } - if (!audio_ok) - { - LL_WARNS("AppInit") << "Overall audio init failure." << LL_ENDL; - return false; - } - - // We're interested in logging which output method we - // ended up with, for QA purposes. - FMOD_OUTPUTTYPE output_type; - // FMOD fixes - //mSystem->getOutput(&output_type); - if(!Check_FMOD_Error(mSystem->getOutput(&output_type), "FMOD::System::getOutput")) - { - // - 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; - }; - // FMOD fixes - } - // -#else // LL_LINUX - - // initialize the FMOD engine - result = mSystem->init( num_channels + 2, fmod_flags, 0); - if (result == FMOD_ERR_OUTPUT_CREATEBUFFER) - { - /* - Ok, the speaker mode selected isn't supported by this soundcard. Switch it - back to stereo... - */ - result = mSystem->setSpeakerMode(FMOD_SPEAKERMODE_STEREO); - Check_FMOD_Error(result,"Error falling back to stereo mode"); - /* - ... and re-init. - */ - result = mSystem->init( num_channels + 2, fmod_flags, 0); - } - if(Check_FMOD_Error(result, "Error initializing FMOD Ex")) - return false; -#endif - - // FMOD fixes - if (mEnableProfiler) - { - 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 - if (!getStreamingAudioImpl()) // no existing implementation added - setStreamingAudioImpl(new LLStreamingAudio_FMODEX(mSystem)); - - LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init() FMOD Ex initialized correctly" << LL_ENDL; - - int r_numbuffers, r_samplerate, r_channels, r_bits; - unsigned int r_bufferlength; - mSystem->getDSPBufferSize(&r_bufferlength, &r_numbuffers); - LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_bufferlength=" << r_bufferlength << " bytes" << LL_ENDL; - LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_numbuffers=" << r_numbuffers << LL_ENDL; - - mSystem->getSoftwareFormat(&r_samplerate, NULL, &r_channels, NULL, NULL, &r_bits); - LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_samplerate=" << r_samplerate << "Hz" << LL_ENDL; - LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_channels=" << r_channels << LL_ENDL; - LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_bits =" << r_bits << LL_ENDL; - - char r_name[512]; - mSystem->getDriverInfo(0, r_name, 511, 0); - r_name[511] = '\0'; - LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): r_name=\"" << r_name << "\"" << LL_ENDL; - - int latency = 100; // optimistic default - i suspect if sample rate is 0, everything breaks. - if ( r_samplerate != 0 ) - latency = (int)(1000.0f * r_bufferlength * r_numbuffers / r_samplerate); - LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): latency=" << latency << "ms" << LL_ENDL; - - mInited = true; - - LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init(): initialization complete." << LL_ENDL; - - // Output device selection - getDevices(); // Purely to print out available devices for debugging reasons - - return true; -} - -// Output device selection -//virtual -LLAudioEngine_FMODEX::output_device_map_t LLAudioEngine_FMODEX::getDevices() -{ - output_device_map_t driver_map; - - int drivercount; - char r_name[512]; - FMOD_GUID guid; - - if (!Check_FMOD_Error(mSystem->getNumDrivers(&drivercount), "FMOD::System::getNumDrivers")) - { - for (int i = 0; i < drivercount; ++i) - { - memset(r_name, 0, sizeof(r_name)); - if (!Check_FMOD_Error(mSystem->getDriverInfo(i, r_name, 511, &guid), "FMOD::System::getDriverInfo")) - { - LLUUID driver_guid = FMOD_GUID_to_LLUUID(guid); - driver_map.insert(std::make_pair(driver_guid, r_name)); - - LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::getDevices(): r_name=\"" << r_name << "\" - guid: " << driver_guid << LL_ENDL; - } - } - } - - return driver_map; -} - -//virtual -void LLAudioEngine_FMODEX::setDevice(const LLUUID& device_uuid) -{ - mSelectedDeviceUUID = device_uuid; - set_device(mSystem, device_uuid); -} -// - -std::string LLAudioEngine_FMODEX::getDriverName(bool verbose) -{ - llassert_always(mSystem); - if (verbose) - { - U32 version; - if(!Check_FMOD_Error(mSystem->getVersion(&version), "FMOD::System::getVersion")) - { - return llformat("FMOD Ex %1x.%02x.%02x", version >> 16, version >> 8 & 0x000000FF, version & 0x000000FF); - } - } - return "FMODEx"; -} - - -void LLAudioEngine_FMODEX::allocateListener(void) -{ - mListenerp = (LLListener *) new LLListener_FMODEX(mSystem); - if (!mListenerp) - { - LL_WARNS() << "Listener creation failed" << LL_ENDL; - } -} - - -void LLAudioEngine_FMODEX::shutdown() -{ - // FMOD fixes - //stopInternetStream(); - - LL_INFOS() << "About to LLAudioEngine::shutdown()" << LL_ENDL; - LLAudioEngine::shutdown(); - - LL_INFOS() << "LLAudioEngine_FMODEX::shutdown() closing FMOD Ex" << LL_ENDL; - if ( mSystem ) // speculative fix for MAINT-2657 - { - // FMOD fixes - //mSystem->close(); - //mSystem->release(); - Check_FMOD_Error(mSystem->close(), "FMOD::System::close"); - LL_INFOS() << "LLAudioEngine_FMODEX::shutdown() FMOD Ex system closed. Now releasing..." << LL_ENDL; - Check_FMOD_Error(mSystem->release(), "FMOD::System::release"); - // - } - LL_INFOS() << "LLAudioEngine_FMODEX::shutdown() done closing FMOD Ex" << LL_ENDL; - - delete mListenerp; - mListenerp = NULL; -} - - -LLAudioBuffer * LLAudioEngine_FMODEX::createBuffer() -{ - return new LLAudioBufferFMODEX(mSystem); -} - - -LLAudioChannel * LLAudioEngine_FMODEX::createChannel() -{ - return new LLAudioChannelFMODEX(mSystem); -} - -bool LLAudioEngine_FMODEX::initWind() -{ - mNextWindUpdate = 0.0; - - if (!mWindDSP) - { - memset(mWindDSPDesc, 0, sizeof(*mWindDSPDesc)); //Set everything to zero - strncpy(mWindDSPDesc->name, "Wind Unit", sizeof(mWindDSPDesc->name)); - mWindDSPDesc->channels = 2; - mWindDSPDesc->read = &windCallback; // Assign callback - may be called from arbitrary threads - if (Check_FMOD_Error(mSystem->createDSP(mWindDSPDesc, &mWindDSP), "FMOD::createDSP")) - return false; - - if (mWindGen) - delete mWindGen; - - float frequency = 44100; - mWindDSP->getDefaults(&frequency,0,0,0); - mWindGen = new LLWindGen((U32)frequency); - mWindDSP->setUserData((void*)mWindGen); - } - - // *TODO: Should this guard against multiple plays? - if (mWindDSP) - { - mSystem->playDSP(FMOD_CHANNEL_FREE, mWindDSP, false, 0); - return true; - } - return false; -} - - -void LLAudioEngine_FMODEX::cleanupWind() -{ - if (mWindDSP) - { - // FMOD fixes - //mWindDSP->remove(); - //mWindDSP->release(); - Check_FMOD_Error(mWindDSP->remove(), "FMOD::DSP::remove"); - Check_FMOD_Error(mWindDSP->release(), "FMOD::DSP::release"); - // - mWindDSP = NULL; - } - - delete mWindGen; - mWindGen = NULL; -} - - -//----------------------------------------------------------------------- -void LLAudioEngine_FMODEX::updateWind(LLVector3 wind_vec, F32 camera_height_above_water) -{ - LLVector3 wind_pos; - F64 pitch; - F64 center_freq; - - if (!mEnableWind) - { - return; - } - - if (mWindUpdateTimer.checkExpirationAndReset(LL_WIND_UPDATE_INTERVAL)) - { - - // wind comes in as Linden coordinate (+X = forward, +Y = left, +Z = up) - // need to convert this to the conventional orientation DS3D and OpenAL use - // where +X = right, +Y = up, +Z = backwards - - wind_vec.setVec(-wind_vec.mV[1], wind_vec.mV[2], -wind_vec.mV[0]); - - // cerr << "Wind update" << endl; - - pitch = 1.0 + mapWindVecToPitch(wind_vec); - center_freq = 80.0 * pow(pitch,2.5*(mapWindVecToGain(wind_vec)+1.0)); - - mWindGen->mTargetFreq = (F32)center_freq; - mWindGen->mTargetGain = (F32)mapWindVecToGain(wind_vec) * mMaxWindGain; - mWindGen->mTargetPanGainR = (F32)mapWindVecToPan(wind_vec); - } -} - -//----------------------------------------------------------------------- -void LLAudioEngine_FMODEX::setInternalGain(F32 gain) -{ - if (!mInited) - { - return; - } - - gain = llclamp( gain, 0.0f, 1.0f ); - - FMOD::ChannelGroup *master_group; - // FMOD fixes - //mSystem->getMasterChannelGroup(&master_group); - if(Check_FMOD_Error(mSystem->getMasterChannelGroup(&master_group), "FMOD::System::getMasterChannelGroup")) - return; - // - master_group->setVolume(gain); - - LLStreamingAudioInterface *saimpl = getStreamingAudioImpl(); - if ( saimpl ) - { - // fmod likes its streaming audio channel gain re-asserted after - // master volume change. - saimpl->setGain(saimpl->getGain()); - } -} - -// -// LLAudioChannelFMODEX implementation -// - -LLAudioChannelFMODEX::LLAudioChannelFMODEX(FMOD::System *system) : LLAudioChannel(), mSystemp(system), mChannelp(NULL), mLastSamplePos(0) -{ -} - - -LLAudioChannelFMODEX::~LLAudioChannelFMODEX() -{ - cleanup(); -} - -bool LLAudioChannelFMODEX::updateBuffer() -{ - if (LLAudioChannel::updateBuffer()) - { - // Base class update returned true, which means that we need to actually - // set up the channel for a different buffer. - - LLAudioBufferFMODEX *bufferp = (LLAudioBufferFMODEX *)mCurrentSourcep->getCurrentBuffer(); - - // Grab the FMOD sample associated with the buffer - FMOD::Sound *soundp = bufferp->getSound(); - if (!soundp) - { - // This is bad, there should ALWAYS be a sound associated with a legit - // buffer. - LL_ERRS() << "No FMOD sound!" << LL_ENDL; - return false; - } - - - // Actually play the sound. Start it off paused so we can do all the necessary - // setup. - if(!mChannelp) - { - FMOD_RESULT result = getSystem()->playSound(FMOD_CHANNEL_FREE, soundp, true, &mChannelp); - Check_FMOD_Error(result, "FMOD::System::playSound"); - } - - //LL_INFOS() << "Setting up channel " << std::hex << mChannelID << std::dec << LL_ENDL; - } - - // If we have a source for the channel, we need to update its gain. - if (mCurrentSourcep) - { - // SJB: warnings can spam and hurt framerate, disabling - //FMOD_RESULT result; - - mChannelp->setVolume(getSecondaryGain() * mCurrentSourcep->getGain()); - //Check_FMOD_Error(result, "FMOD::Channel::setVolume"); - - mChannelp->setMode(mCurrentSourcep->isLoop() ? FMOD_LOOP_NORMAL : FMOD_LOOP_OFF); - /*if(Check_FMOD_Error(result, "FMOD::Channel::setMode")) - { - S32 index; - mChannelp->getIndex(&index); - LL_WARNS() << "Channel " << index << "Source ID: " << mCurrentSourcep->getID() - << " at " << mCurrentSourcep->getPositionGlobal() << LL_ENDL; - }*/ - } - - return true; -} - - -void LLAudioChannelFMODEX::update3DPosition() -{ - if (!mChannelp) - { - // We're not actually a live channel (i.e., we're not playing back anything) - return; - } - - LLAudioBufferFMODEX *bufferp = (LLAudioBufferFMODEX *)mCurrentBufferp; - if (!bufferp) - { - // We don't have a buffer associated with us (should really have been picked up - // by the above if. - return; - } - - if (mCurrentSourcep->isAmbient()) - { - // Ambient sound, don't need to do any positional updates. - set3DMode(false); - } - else - { - // Localized sound. Update the position and velocity of the sound. - set3DMode(true); - - LLVector3 float_pos; - float_pos.setVec(mCurrentSourcep->getPositionGlobal()); - FMOD_RESULT result = mChannelp->set3DAttributes((FMOD_VECTOR*)float_pos.mV, (FMOD_VECTOR*)mCurrentSourcep->getVelocity().mV); - Check_FMOD_Error(result, "FMOD::Channel::set3DAttributes"); - } -} - - -void LLAudioChannelFMODEX::updateLoop() -{ - if (!mChannelp) - { - // May want to clear up the loop/sample counters. - return; - } - - // - // Hack: We keep track of whether we looped or not by seeing when the - // sample position looks like it's going backwards. Not reliable; may - // yield false negatives. - // - U32 cur_pos; - // FMOD fixes - //mChannelp->getPosition(&cur_pos,FMOD_TIMEUNIT_PCMBYTES); - Check_FMOD_Error(mChannelp->getPosition(&cur_pos,FMOD_TIMEUNIT_PCMBYTES),"FMOD::Channel::getPosition"); - // - - if (cur_pos < (U32)mLastSamplePos) - { - mLoopedThisFrame = true; - } - mLastSamplePos = cur_pos; -} - - -void LLAudioChannelFMODEX::cleanup() -{ - if (!mChannelp) - { - //LL_INFOS() << "Aborting cleanup with no channel handle." << LL_ENDL; - return; - } - - //LL_INFOS() << "Cleaning up channel: " << mChannelID << LL_ENDL; - Check_FMOD_Error(mChannelp->stop(),"FMOD::Channel::stop"); - - mCurrentBufferp = NULL; - mChannelp = NULL; -} - - -void LLAudioChannelFMODEX::play() -{ - if (!mChannelp) - { - LL_WARNS() << "Playing without a channel handle, aborting" << LL_ENDL; - return; - } - - // FMOD fixes - //Check_FMOD_Error(mChannelp->setPaused(false), "FMOD::Channel::pause"); - Check_FMOD_Error(mChannelp->setPaused(false), "FMOD::Channel::setPaused"); - // - - getSource()->setPlayedOnce(true); - - if(LLAudioEngine_FMODEX::mChannelGroups[getSource()->getType()]) - // FMOD fixes - //mChannelp->setChannelGroup(LLAudioEngine_FMODEX::mChannelGroups[getSource()->getType()]); - Check_FMOD_Error(mChannelp->setChannelGroup(LLAudioEngine_FMODEX::mChannelGroups[getSource()->getType()]),"FMOD::Channel::setChannelGroup"); - // -} - - -void LLAudioChannelFMODEX::playSynced(LLAudioChannel *channelp) -{ - LLAudioChannelFMODEX *fmod_channelp = (LLAudioChannelFMODEX*)channelp; - if (!(fmod_channelp->mChannelp && mChannelp)) - { - // Don't have channels allocated to both the master and the slave - return; - } - - U32 cur_pos; - if(Check_FMOD_Error(mChannelp->getPosition(&cur_pos,FMOD_TIMEUNIT_PCMBYTES), "Unable to retrieve current position")) - return; - - cur_pos %= mCurrentBufferp->getLength(); - - // Try to match the position of our sync master - Check_FMOD_Error(mChannelp->setPosition(cur_pos,FMOD_TIMEUNIT_PCMBYTES),"Unable to set current position"); - - // Start us playing - play(); -} - - -bool LLAudioChannelFMODEX::isPlaying() -{ - if (!mChannelp) - { - return false; - } - - bool paused, playing; - // FMOD fixes - //mChannelp->getPaused(&paused); - //mChannelp->isPlaying(&playing); - Check_FMOD_Error(mChannelp->getPaused(&paused),"FMOD::Channel::getPaused"); - Check_FMOD_Error(mChannelp->isPlaying(&playing),"FMOD::Channel::isPlaying"); - // - return !paused && playing; -} - - -// -// LLAudioChannelFMODEX implementation -// - - -LLAudioBufferFMODEX::LLAudioBufferFMODEX(FMOD::System *system) : mSystemp(system), mSoundp(NULL) -{ -} - - -LLAudioBufferFMODEX::~LLAudioBufferFMODEX() -{ - if(mSoundp) - { - // FMOD fixes - //mSoundp->release(); - Check_FMOD_Error(mSoundp->release(),"FMOD::Sound::Release"); - // - mSoundp = NULL; - } -} - - -bool LLAudioBufferFMODEX::loadWAV(const std::string& filename) -{ - // Try to open a wav file from disk. This will eventually go away, as we don't - // really want to block doing this. - if (filename.empty()) - { - // invalid filename, abort. - return false; - } - - // FMOD fixes - //if (!LLAPRFile::isExist(filename, NULL, LL_APR_RPB)) - if (!gDirUtilp->fileExists(filename)) - // - { - // File not found, abort. - return false; - } - - if (mSoundp) - { - // If there's already something loaded in this buffer, clean it up. - // FMOD fixes - //mSoundp->release(); - Check_FMOD_Error(mSoundp->release(),"FMOD::Sound::release"); - // - mSoundp = NULL; - } - - 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 -#if LL_WINDOWS - FMOD_RESULT result = getSystem()->createSound((const char*)utf8str_to_utf16str(filename).c_str(), base_mode | FMOD_UNICODE, &exinfo, &mSoundp); -#else - FMOD_RESULT result = getSystem()->createSound(filename.c_str(), base_mode, &exinfo, &mSoundp); -#endif - - if (result != FMOD_OK) - { - // We failed to load the file for some reason. - LL_WARNS() << "Could not load data '" << filename << "': " << FMOD_ErrorString(result) << LL_ENDL; - - // - // If we EVER want to load wav files provided by end users, we need - // to rethink this! - // - // file is probably corrupt - remove it. - LLFile::remove(filename); - return false; - } - - // Everything went well, return true - return true; -} - - -U32 LLAudioBufferFMODEX::getLength() -{ - if (!mSoundp) - { - return 0; - } - - U32 length; - // FMOD fixes - //mSoundp->getLength(&length, FMOD_TIMEUNIT_PCMBYTES); - Check_FMOD_Error(mSoundp->getLength(&length, FMOD_TIMEUNIT_PCMBYTES),"FMOD::Sound::getLength"); - // - return length; -} - - -void LLAudioChannelFMODEX::set3DMode(bool use3d) -{ - FMOD_MODE current_mode; - // FMOD fixes - //if(mChannelp->getMode(¤t_mode) != FMOD_OK) - if(Check_FMOD_Error(mChannelp->getMode(¤t_mode),"FMOD::Channel::getMode")) - // - return; - FMOD_MODE new_mode = current_mode; - new_mode &= ~(use3d ? FMOD_2D : FMOD_3D); - new_mode |= use3d ? FMOD_3D : FMOD_2D; - - if(current_mode != new_mode) - { - // FMOD fixes - //mChannelp->setMode(new_mode); - Check_FMOD_Error(mChannelp->setMode(new_mode),"FMOD::Channel::setMode"); - // - } -} - -// *NOTE: This is almost certainly being called on the mixer thread, -// not the main thread. May have implications for callees or audio -// engine shutdown. - -FMOD_RESULT F_CALLBACK windCallback(FMOD_DSP_STATE *dsp_state, float *originalbuffer, float *newbuffer, 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. - - LLWindGen *windgen; - FMOD::DSP *thisdsp = (FMOD::DSP *)dsp_state->instance; - - thisdsp->getUserData((void **)&windgen); - // FMOD fixes - //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; -} diff --git a/indra/llaudio/llaudioengine_fmodex.h b/indra/llaudio/llaudioengine_fmodex.h deleted file mode 100644 index d0de2d602a..0000000000 --- a/indra/llaudio/llaudioengine_fmodex.h +++ /dev/null @@ -1,141 +0,0 @@ -/** - * @file audioengine_fmodex.h - * @brief Definition of LLAudioEngine class abstracting the audio - * support as a FMODEX implementation - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2014, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_AUDIOENGINE_FMODEX_H -#define LL_AUDIOENGINE_FMODEX_H - -#include "llaudioengine.h" -#include "llwindgen.h" - -//Stubs -class LLAudioStreamManagerFMODEX; -namespace FMOD -{ - class System; - class Channel; - class ChannelGroup; - class Sound; - class DSP; -} -typedef struct FMOD_DSP_DESCRIPTION FMOD_DSP_DESCRIPTION; - -//Interfaces -class LLAudioEngine_FMODEX : public LLAudioEngine -{ -public: - LLAudioEngine_FMODEX(bool enable_profiler); - virtual ~LLAudioEngine_FMODEX(); - - // initialization/startup/shutdown - virtual bool init(const S32 num_channels, void *user_data); - virtual std::string getDriverName(bool verbose); - virtual void allocateListener(); - - virtual void shutdown(); - - /*virtual*/ bool initWind(); - /*virtual*/ void cleanupWind(); - - /*virtual*/void updateWind(LLVector3 direction, F32 camera_height_above_water); - - typedef F32 MIXBUFFERFORMAT; - - FMOD::System *getSystem() const {return mSystem;} - - // Output device selection - /*virtual*/ std::map getDevices(); - /*virtual*/ void setDevice(const LLUUID& device_uuid); - - LLUUID getSelectedDeviceUUID() const { return mSelectedDeviceUUID; } - // - -protected: - /*virtual*/ LLAudioBuffer *createBuffer(); // Get a free buffer, or flush an existing one if you have to. - /*virtual*/ LLAudioChannel *createChannel(); // Create a new audio channel. - - /*virtual*/ void setInternalGain(F32 gain); - - bool mInited; - - LLWindGen *mWindGen; - - FMOD_DSP_DESCRIPTION *mWindDSPDesc; - FMOD::DSP *mWindDSP; - FMOD::System *mSystem; - bool mEnableProfiler; - - // Output device selection - LLUUID mSelectedDeviceUUID; - -public: - static FMOD::ChannelGroup *mChannelGroups[LLAudioEngine::AUDIO_TYPE_COUNT]; -}; - - -class LLAudioChannelFMODEX : public LLAudioChannel -{ -public: - LLAudioChannelFMODEX(FMOD::System *audioengine); - virtual ~LLAudioChannelFMODEX(); - -protected: - /*virtual*/ void play(); - /*virtual*/ void playSynced(LLAudioChannel *channelp); - /*virtual*/ void cleanup(); - /*virtual*/ bool isPlaying(); - - /*virtual*/ bool updateBuffer(); - /*virtual*/ void update3DPosition(); - /*virtual*/ void updateLoop(); - - void set3DMode(bool use3d); -protected: - FMOD::System *getSystem() const {return mSystemp;} - FMOD::System *mSystemp; - FMOD::Channel *mChannelp; - S32 mLastSamplePos; -}; - - -class LLAudioBufferFMODEX : public LLAudioBuffer -{ -public: - LLAudioBufferFMODEX(FMOD::System *audioengine); - virtual ~LLAudioBufferFMODEX(); - - /*virtual*/ bool loadWAV(const std::string& filename); - /*virtual*/ U32 getLength(); - friend class LLAudioChannelFMODEX; -protected: - FMOD::System *getSystem() const {return mSystemp;} - FMOD::System *mSystemp; - FMOD::Sound *getSound() const{ return mSoundp; } - FMOD::Sound *mSoundp; -}; - - -#endif // LL_AUDIOENGINE_FMODEX_H diff --git a/indra/llaudio/llaudioengine_fmodstudio.cpp b/indra/llaudio/llaudioengine_fmodstudio.cpp index 48203b0371..3790107fd1 100644 --- a/indra/llaudio/llaudioengine_fmodstudio.cpp +++ b/indra/llaudio/llaudioengine_fmodstudio.cpp @@ -1,11 +1,11 @@ /** * @file audioengine_fmodstudio.cpp * @brief Implementation of LLAudioEngine class abstracting the audio - * support as a FMOD Studio implementation + * support as a FMODSTUDIO implementation * - * $LicenseInfo:firstyear=2014&license=viewerlgpl$ + * $LicenseInfo:firstyear=2020&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2014, Linden Research, Inc. + * Copyright (C) 2020, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -37,508 +37,538 @@ #include "llmath.h" #include "llrand.h" -#include "fmod.hpp" -#include "fmod_errors.h" +#include "fmodstudio/fmod.hpp" +#include "fmodstudio/fmod_errors.h" #include "lldir.h" +#include "llapr.h" #include "sound_ids.h" -#include "indra_constants.h" - const U32 EXTRA_SOUND_CHANNELS = 10; -FMOD_RESULT F_CALLBACK windDSPCallback(FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, 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}; static inline bool Check_FMOD_Error(FMOD_RESULT result, const char *string) { - if (result == FMOD_OK) - { - return false; - } + if (result == FMOD_OK) + { + return false; + } - if (result != FMOD_ERR_INVALID_HANDLE) - { - LL_WARNS() << string << " Error: " << FMOD_ErrorString(result) << LL_ENDL; - } - else - { - LL_DEBUGS() << string << " Error: " << FMOD_ErrorString(result) << LL_ENDL; - } + if (result != FMOD_ERR_INVALID_HANDLE) + { + LL_WARNS("FMOD") << string << " Error: " << FMOD_ErrorString(result) << LL_ENDL; + } + else + { + LL_DEBUGS("FMOD") << string << " Error: " << FMOD_ErrorString(result) << LL_ENDL; + } - return true; + return true; } LLUUID FMOD_GUID_to_LLUUID(FMOD_GUID guid) { - return LLUUID(llformat("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", guid.Data1, guid.Data2, guid.Data3, - guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7])); + return LLUUID(llformat("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", guid.Data1, guid.Data2, guid.Data3, + guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7])); } void set_device(FMOD::System* system, const LLUUID& device_uuid) { - LL_INFOS() << "LLAudioEngine_FMODSTUDIO::setDevice with device_uuid=" << device_uuid << LL_ENDL; + LL_INFOS() << "LLAudioEngine_FMODSTUDIO::setDevice with device_uuid=" << device_uuid << LL_ENDL; - int drivercount; - if (!Check_FMOD_Error(system->getNumDrivers(&drivercount), "FMOD::System::getNumDrivers") && drivercount > 0) - { - if (device_uuid.isNull()) - { - LL_INFOS() << "Setting driver \"Default\"" << LL_ENDL; - Check_FMOD_Error(system->setDriver(0), "FMOD::System::setDriver"); - } - else - { - FMOD_GUID guid; - int r_samplerate, r_channels; + int drivercount; + if (!Check_FMOD_Error(system->getNumDrivers(&drivercount), "FMOD::System::getNumDrivers") && drivercount > 0) + { + if (device_uuid.isNull()) + { + LL_INFOS("FMOD") << "Setting driver \"Default\"" << LL_ENDL; + Check_FMOD_Error(system->setDriver(0), "FMOD::System::setDriver"); + } + else + { + FMOD_GUID guid; + int r_samplerate, r_channels; - for (int i = 0; i < drivercount; ++i) - { - if (!Check_FMOD_Error(system->getDriverInfo(i, NULL, 0, &guid, &r_samplerate, NULL, &r_channels), "FMOD::System::getDriverInfo")) - { - LLUUID driver_guid = FMOD_GUID_to_LLUUID(guid); + for (int i = 0; i < drivercount; ++i) + { + if (!Check_FMOD_Error(system->getDriverInfo(i, NULL, 0, &guid, &r_samplerate, NULL, &r_channels), "FMOD::System::getDriverInfo")) + { + LLUUID driver_guid = FMOD_GUID_to_LLUUID(guid); - if (driver_guid == device_uuid) - { - LL_INFOS() << "Setting driver " << i << ": " << driver_guid << LL_ENDL; - Check_FMOD_Error(system->setDriver(i), "FMOD::System::setDriver"); - return; - } - } - } + if (driver_guid == device_uuid) + { + LL_INFOS("FMOD") << "Setting driver " << i << ": " << driver_guid << LL_ENDL; + Check_FMOD_Error(system->setDriver(i), "FMOD::System::setDriver"); + return; + } + } + } - LL_INFOS() << "Device not available (anymore) - falling back to default" << LL_ENDL; - Check_FMOD_Error(system->setDriver(0), "FMOD::System::setDriver"); - } - } + LL_INFOS("FMOD") << "Device not available (anymore) - falling back to default" << LL_ENDL; + Check_FMOD_Error(system->setDriver(0), "FMOD::System::setDriver"); + } + } } FMOD_RESULT F_CALLBACK systemCallback(FMOD_SYSTEM *system, FMOD_SYSTEM_CALLBACK_TYPE type, void *commanddata1, void *commanddata2, void* userdata) { - FMOD::System* sys = (FMOD::System*)system; - LLAudioEngine_FMODSTUDIO* audio_engine = (LLAudioEngine_FMODSTUDIO*)userdata; + FMOD::System* sys = (FMOD::System*)system; + LLAudioEngine_FMODSTUDIO* audio_engine = (LLAudioEngine_FMODSTUDIO*)userdata; - switch (type) - { - case FMOD_SYSTEM_CALLBACK_DEVICELISTCHANGED: - LL_DEBUGS() << "FMOD system callback FMOD_SYSTEM_CALLBACK_DEVICELISTCHANGED" << LL_ENDL; - if (sys && audio_engine) - { - set_device(sys, audio_engine->getSelectedDeviceUUID()); - audio_engine->OnOutputDeviceListChanged(audio_engine->getDevices()); - } - break; - default: - break; - } - return FMOD_OK; + switch (type) + { + case FMOD_SYSTEM_CALLBACK_DEVICELISTCHANGED: + LL_DEBUGS("FMOD") << "FMOD system callback FMOD_SYSTEM_CALLBACK_DEVICELISTCHANGED" << LL_ENDL; + if (sys && audio_engine) + { + set_device(sys, audio_engine->getSelectedDeviceUUID()); + audio_engine->OnOutputDeviceListChanged(audio_engine->getDevices()); + } + break; + default: + break; + } + return FMOD_OK; } LLAudioEngine_FMODSTUDIO::LLAudioEngine_FMODSTUDIO(bool enable_profiler, U32 resample_method) - : mInited(false) - , mWindGen(NULL) - , mWindDSPDesc(NULL) - , mWindDSP(NULL) - , mSystem(NULL) - , mEnableProfiler(enable_profiler) - , mResampleMethod(resample_method) - , mSelectedDeviceUUID() +: mInited(false), + mWindGen(NULL), + mWindDSP(NULL), + mSystem(NULL), + mEnableProfiler(enable_profiler), + mWindDSPDesc(NULL), + mResampleMethod(resample_method), + mSelectedDeviceUUID() { } LLAudioEngine_FMODSTUDIO::~LLAudioEngine_FMODSTUDIO() { + // mWindDSPDesc, mWindGen and mWindDSP get cleaned up on cleanupWind in LLAudioEngine::shutdown() + // mSystem gets cleaned up at shutdown() } -bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata) +bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata, const std::string &app_title) { - U32 version; - FMOD_RESULT result; + U32 version; + FMOD_RESULT result; - LL_DEBUGS("AppInit") << "LLAudioEngine_FMODSTUDIO::init() initializing FMOD" << LL_ENDL; + LL_DEBUGS("AppInit") << "LLAudioEngine_FMODSTUDIO::init() initializing FMOD" << LL_ENDL; - result = FMOD::System_Create(&mSystem); - if(Check_FMOD_Error(result, "FMOD::System_Create")) - return false; + result = FMOD::System_Create(&mSystem); + if (Check_FMOD_Error(result, "FMOD::System_Create")) + return false; - //will call LLAudioEngine_FMODSTUDIO::allocateListener, which needs a valid mSystem pointer. - LLAudioEngine::init(num_channels, userdata); - - result = mSystem->getVersion(&version); - Check_FMOD_Error(result, "FMOD::System::getVersion"); + //will call LLAudioEngine_FMODSTUDIO::allocateListener, which needs a valid mSystem pointer. + LLAudioEngine::init(num_channels, userdata, app_title); - if (version < FMOD_VERSION) - { - LL_WARNS("AppInit") << "Error : You are using the wrong FMOD Studio version (" << version - << ")! You should be using FMOD Studio" << FMOD_VERSION << LL_ENDL; - } + result = mSystem->getVersion(&version); + Check_FMOD_Error(result, "FMOD::System::getVersion"); - // In this case, all sounds, PLUS wind and stream will be software. - result = mSystem->setSoftwareChannels(num_channels + EXTRA_SOUND_CHANNELS); - Check_FMOD_Error(result,"FMOD::System::setSoftwareChannels"); + if (version < FMOD_VERSION) + { + LL_WARNS("AppInit") << "FMOD Studio version mismatch, actual: " << version + << " expected:" << FMOD_VERSION << LL_ENDL; + } - Check_FMOD_Error(mSystem->setCallback(systemCallback), "FMOD::System::setCallback"); - Check_FMOD_Error(mSystem->setUserData(this), "FMOD::System::setUserData"); + // In this case, all sounds, PLUS wind and stream will be software. + result = mSystem->setSoftwareChannels(num_channels + EXTRA_SOUND_CHANNELS); + Check_FMOD_Error(result, "FMOD::System::setSoftwareChannels"); - FMOD_ADVANCEDSETTINGS adv_settings = { }; - adv_settings.cbSize = sizeof(FMOD_ADVANCEDSETTINGS); - switch (mResampleMethod) - { - default: - case RESAMPLE_LINEAR: - adv_settings.resamplerMethod = FMOD_DSP_RESAMPLER_LINEAR; - break; - case RESAMPLE_CUBIC: - adv_settings.resamplerMethod = FMOD_DSP_RESAMPLER_CUBIC; - break; - case RESAMPLE_SPLINE: - adv_settings.resamplerMethod = FMOD_DSP_RESAMPLER_SPLINE; - break; - } + Check_FMOD_Error(mSystem->setCallback(systemCallback), "FMOD::System::setCallback"); + Check_FMOD_Error(mSystem->setUserData(this), "FMOD::System::setUserData"); - result = mSystem->setAdvancedSettings(&adv_settings); - Check_FMOD_Error(result, "FMOD::System::setAdvancedSettings"); + FMOD_ADVANCEDSETTINGS settings = { }; + settings.cbSize = sizeof(FMOD_ADVANCEDSETTINGS); + switch (mResampleMethod) + { + default: + case RESAMPLE_LINEAR: + settings.resamplerMethod = FMOD_DSP_RESAMPLER_LINEAR; + break; + case RESAMPLE_CUBIC: + settings.resamplerMethod = FMOD_DSP_RESAMPLER_CUBIC; + break; + case RESAMPLE_SPLINE: + settings.resamplerMethod = FMOD_DSP_RESAMPLER_SPLINE; + break; + } - U32 fmod_flags = FMOD_INIT_NORMAL | FMOD_INIT_3D_RIGHTHANDED | FMOD_INIT_THREAD_UNSAFE; - if(mEnableProfiler) - { - fmod_flags |= FMOD_INIT_PROFILE_ENABLE; - } + result = mSystem->setAdvancedSettings(&settings); + Check_FMOD_Error(result, "FMOD::System::setAdvancedSettings"); + + // FMOD_INIT_THREAD_UNSAFE Disables thread safety for API calls. + // Only use this if FMOD is being called from a single thread, and if Studio API is not being used. + U32 fmod_flags = FMOD_INIT_NORMAL | FMOD_INIT_3D_RIGHTHANDED | FMOD_INIT_THREAD_UNSAFE; + if (mEnableProfiler) + { + fmod_flags |= FMOD_INIT_PROFILE_ENABLE; + } #if LL_LINUX - bool audio_ok = false; + bool audio_ok = false; - if (!audio_ok) - { - if (NULL == getenv("LL_BAD_FMOD_PULSEAUDIO")) /*Flawfinder: ignore*/ - { - LL_DEBUGS("AppInit") << "Trying PulseAudio audio output..." << LL_ENDL; - if((result = mSystem->setOutput(FMOD_OUTPUTTYPE_PULSEAUDIO)) == FMOD_OK && - (result = mSystem->init(num_channels + EXTRA_SOUND_CHANNELS, fmod_flags, const_cast(APP_NAME.c_str()))) == FMOD_OK) - { - LL_DEBUGS("AppInit") << "PulseAudio output initialized OKAY" << LL_ENDL; - audio_ok = true; - } - else - { - Check_FMOD_Error(result, "PulseAudio audio output FAILED to initialize"); - } - } - else - { - LL_DEBUGS("AppInit") << "PulseAudio audio output SKIPPED" << LL_ENDL; - } - } - if (!audio_ok) - { - if (NULL == getenv("LL_BAD_FMOD_ALSA")) /*Flawfinder: ignore*/ - { - LL_DEBUGS("AppInit") << "Trying ALSA audio output..." << LL_ENDL; - if((result = mSystem->setOutput(FMOD_OUTPUTTYPE_ALSA)) == FMOD_OK && - (result = mSystem->init(num_channels + EXTRA_SOUND_CHANNELS, fmod_flags, 0)) == FMOD_OK) - { - LL_DEBUGS("AppInit") << "ALSA audio output initialized OKAY" << LL_ENDL; - audio_ok = true; - } - else - { - Check_FMOD_Error(result, "ALSA audio output FAILED to initialize"); - } - } - else - { - LL_DEBUGS("AppInit") << "ALSA audio output SKIPPED" << LL_ENDL; - } - } - if (!audio_ok) - { - LL_WARNS("AppInit") << "Overall audio init failure." << LL_ENDL; - return false; - } + if (!audio_ok) + { + const char* env_string = getenv("LL_BAD_FMOD_PULSEAUDIO"); + if (NULL == env_string) + { + LL_DEBUGS("AppInit") << "Trying PulseAudio audio output..." << LL_ENDL; + if ((result = mSystem->setOutput(FMOD_OUTPUTTYPE_PULSEAUDIO)) == FMOD_OK && + (result = mSystem->init(num_channels + EXTRA_SOUND_CHANNELS, fmod_flags, const_cast(app_title.c_str()))) == FMOD_OK) + { + LL_DEBUGS("AppInit") << "PulseAudio output initialized OKAY" << LL_ENDL; + audio_ok = true; + } + else + { + Check_FMOD_Error(result, "PulseAudio audio output FAILED to initialize"); + } + } + else + { + LL_DEBUGS("AppInit") << "PulseAudio audio output SKIPPED" << LL_ENDL; + } + } + if (!audio_ok) + { + const char* env_string = getenv("LL_BAD_FMOD_ALSA"); + if (NULL == env_string) + { + LL_DEBUGS("AppInit") << "Trying ALSA audio output..." << LL_ENDL; + if ((result = mSystem->setOutput(FMOD_OUTPUTTYPE_ALSA)) == FMOD_OK && + (result = mSystem->init(num_channels + EXTRA_SOUND_CHANNELS, fmod_flags, 0)) == FMOD_OK) + { + LL_DEBUGS("AppInit") << "ALSA audio output initialized OKAY" << LL_ENDL; + audio_ok = true; + } + else + { + Check_FMOD_Error(result, "ALSA audio output FAILED to initialize"); + } + } + else + { + LL_DEBUGS("AppInit") << "ALSA audio output SKIPPED" << LL_ENDL; + } + } + if (!audio_ok) + { + LL_WARNS("AppInit") << "Overall audio init failure." << LL_ENDL; + return false; + } - // We're interested in logging which output method we - // ended up with, for QA purposes. - FMOD_OUTPUTTYPE output_type; - if(!Check_FMOD_Error(mSystem->getOutput(&output_type), "FMOD::System::getOutput")) - { - 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; - default: - LL_INFOS("AppInit") << "Audio output: Unknown!" << LL_ENDL; break; - }; - } + // We're interested in logging which output method we + // ended up with, for QA purposes. + FMOD_OUTPUTTYPE output_type; + if (!Check_FMOD_Error(mSystem->getOutput(&output_type), "FMOD::System::getOutput")) + { + 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; + default: + LL_INFOS("AppInit") << "Audio output: Unknown!" << LL_ENDL; break; + }; + } #else // LL_LINUX - // initialize the FMOD engine - result = mSystem->init( num_channels + EXTRA_SOUND_CHANNELS, fmod_flags, 0); - if (result == FMOD_ERR_OUTPUT_CREATEBUFFER) - { - /* - Ok, the speaker mode selected isn't supported by this soundcard. Switch it - back to stereo... - */ - result = mSystem->setSoftwareFormat(44100, FMOD_SPEAKERMODE_STEREO, 0); - Check_FMOD_Error(result,"Error falling back to stereo mode"); - /* - ... and re-init. - */ - result = mSystem->init( num_channels + EXTRA_SOUND_CHANNELS, fmod_flags, 0); - } - if(Check_FMOD_Error(result, "Error initializing FMOD Studio")) - return false; + // initialize the FMOD engine + result = mSystem->init(num_channels + EXTRA_SOUND_CHANNELS, fmod_flags, 0); + if (Check_FMOD_Error(result, "Error initializing FMOD Studio with default settins, retrying with other format")) + { + result = mSystem->setSoftwareFormat(44100, FMOD_SPEAKERMODE_STEREO, 0/*- ignore*/); + if (Check_FMOD_Error(result, "Error setting sotware format. Can't init.")) + { + return false; + } + result = mSystem->init(num_channels + EXTRA_SOUND_CHANNELS, fmod_flags, 0); + } + if (Check_FMOD_Error(result, "Error initializing FMOD Studio")) + { + return false; + } #endif - if (mEnableProfiler) - { - 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"); - } + if (mEnableProfiler) + { + 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 - if (!getStreamingAudioImpl()) // no existing implementation added - setStreamingAudioImpl(new LLStreamingAudio_FMODSTUDIO(mSystem)); + // set up our favourite FMOD-native streaming audio implementation if none has already been added + if (!getStreamingAudioImpl()) // no existing implementation added + setStreamingAudioImpl(new LLStreamingAudio_FMODSTUDIO(mSystem)); - LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init() FMOD Studio initialized correctly" << LL_ENDL; + LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init() FMOD Studio initialized correctly" << LL_ENDL; - FMOD_ADVANCEDSETTINGS adv_settings_dump = { }; - mSystem->getAdvancedSettings(&adv_settings_dump); + FMOD_ADVANCEDSETTINGS settings_dump = { }; + mSystem->getAdvancedSettings(&settings_dump); + LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init(): resampler=" << settings_dump.resamplerMethod << " bytes" << LL_ENDL; - LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init(): resampler=" << adv_settings.resamplerMethod << " bytes" << LL_ENDL; + int r_numbuffers, r_samplerate, r_channels; + unsigned int r_bufferlength; + char r_name[512]; + int latency = 100; + mSystem->getDSPBufferSize(&r_bufferlength, &r_numbuffers); + LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init(): r_bufferlength=" << r_bufferlength << " bytes" << LL_ENDL; + LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init(): r_numbuffers=" << r_numbuffers << LL_ENDL; - int r_numbuffers, r_samplerate, r_channels; - unsigned int r_bufferlength; - mSystem->getDSPBufferSize(&r_bufferlength, &r_numbuffers); - LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init(): r_bufferlength=" << r_bufferlength << " bytes" << LL_ENDL; - LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init(): r_numbuffers=" << r_numbuffers << LL_ENDL; + mSystem->getDriverInfo(0, r_name, 511, NULL, &r_samplerate, NULL, &r_channels); + r_name[511] = '\0'; + LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init(): r_name=\"" << r_name << "\"" << LL_ENDL; + LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init(): r_samplerate=" << r_samplerate << "Hz" << LL_ENDL; + LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init(): r_channels=" << r_channels << LL_ENDL; - char r_name[512]; - mSystem->getDriverInfo(0, r_name, 511, NULL, &r_samplerate, NULL, &r_channels); - r_name[511] = '\0'; - LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init(): r_name=\"" << r_name << "\"" << LL_ENDL; - LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init(): r_samplerate=" << r_samplerate << "Hz" << LL_ENDL; - LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init(): r_channels=" << r_channels << LL_ENDL; + if (r_samplerate != 0) + latency = (int)(1000.0f * r_bufferlength * r_numbuffers / r_samplerate); + LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init(): latency=" << latency << "ms" << LL_ENDL; - int latency = 100; // optimistic default - i suspect if sample rate is 0, everything breaks. - if ( r_samplerate != 0 ) - latency = (int)(1000.0f * r_bufferlength * r_numbuffers / r_samplerate); - LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init(): latency=" << latency << "ms" << LL_ENDL; + mInited = true; - mInited = true; + LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init(): initialization complete." << LL_ENDL; - LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::init(): initialization complete." << LL_ENDL; + getDevices(); // Purely to print out available devices for debugging reasons - getDevices(); // Purely to print out available devices for debugging reasons - - return true; + return true; } //virtual LLAudioEngine_FMODSTUDIO::output_device_map_t LLAudioEngine_FMODSTUDIO::getDevices() { - output_device_map_t driver_map; + output_device_map_t driver_map; - int drivercount; - int r_samplerate, r_channels; - char r_name[512]; - FMOD_GUID guid; + int drivercount; + int r_samplerate, r_channels; + char r_name[512]; + FMOD_GUID guid; - if (!Check_FMOD_Error(mSystem->getNumDrivers(&drivercount), "FMOD::System::getNumDrivers")) - { - for (int i = 0; i < drivercount; ++i) - { - memset(r_name, 0, sizeof(r_name)); - if (!Check_FMOD_Error(mSystem->getDriverInfo(i, r_name, 511, &guid, &r_samplerate, NULL, &r_channels), "FMOD::System::getDriverInfo")) - { - LLUUID driver_guid = FMOD_GUID_to_LLUUID(guid); - driver_map.insert(std::make_pair(driver_guid, r_name)); + if (!Check_FMOD_Error(mSystem->getNumDrivers(&drivercount), "FMOD::System::getNumDrivers")) + { + for (int i = 0; i < drivercount; ++i) + { + memset(r_name, 0, sizeof(r_name)); + if (!Check_FMOD_Error(mSystem->getDriverInfo(i, r_name, 511, &guid, &r_samplerate, NULL, &r_channels), "FMOD::System::getDriverInfo")) + { + LLUUID driver_guid = FMOD_GUID_to_LLUUID(guid); + driver_map.insert(std::make_pair(driver_guid, r_name)); - LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::getDevices(): r_name=\"" << r_name << "\" - guid: " << driver_guid << LL_ENDL; - } - } - } + LL_INFOS("AppInit") << "LLAudioEngine_FMODSTUDIO::getDevices(): r_name=\"" << r_name << "\" - guid: " << driver_guid << LL_ENDL; + } + } + } - return driver_map; + return driver_map; } //virtual void LLAudioEngine_FMODSTUDIO::setDevice(const LLUUID& device_uuid) { - mSelectedDeviceUUID = device_uuid; - set_device(mSystem, device_uuid); + mSelectedDeviceUUID = device_uuid; + set_device(mSystem, device_uuid); } std::string LLAudioEngine_FMODSTUDIO::getDriverName(bool verbose) { - llassert_always(mSystem); - if (verbose) - { - U32 version; - if(!Check_FMOD_Error(mSystem->getVersion(&version), "FMOD::System::getVersion")) - { - return llformat("FMOD Studio %1x.%02x.%02x", version >> 16, version >> 8 & 0x000000FF, version & 0x000000FF); - } - } - return "FMOD Studio"; + llassert_always(mSystem); + if (verbose) + { + U32 version; + if (!Check_FMOD_Error(mSystem->getVersion(&version), "FMOD::System::getVersion")) + { + return llformat("FMOD Studio %1x.%02x.%02x", version >> 16, version >> 8 & 0x000000FF, version & 0x000000FF); + } + } + return "FMOD Studio"; } void LLAudioEngine_FMODSTUDIO::allocateListener(void) -{ - try - { - mListenerp = (LLListener *) new LLListener_FMODSTUDIO(mSystem); - } - catch (const std::bad_alloc& e) - { - LL_WARNS() << "Listener allocation failed due to: " << e.what() << LL_ENDL; - } +{ + try + { + mListenerp = (LLListener *) new LLListener_FMODSTUDIO(mSystem); + } + catch (const std::bad_alloc& e) + { + LL_WARNS("FMOD") << "Listener allocation failed due to: " << e.what() << LL_ENDL; + } } void LLAudioEngine_FMODSTUDIO::shutdown() { - LL_INFOS() << "About to LLAudioEngine::shutdown()" << LL_ENDL; - LLAudioEngine::shutdown(); - - LL_INFOS() << "LLAudioEngine_FMODSTUDIO::shutdown() closing FMOD Studio" << LL_ENDL; - if ( mSystem ) // speculative fix for MAINT-2657 - { - Check_FMOD_Error(mSystem->close(), "FMOD::System::close"); - Check_FMOD_Error(mSystem->release(), "FMOD::System::release"); - } - LL_INFOS() << "LLAudioEngine_FMODSTUDIO::shutdown() done closing FMOD Studio" << LL_ENDL; + stopInternetStream(); - delete mListenerp; - mListenerp = NULL; + LL_INFOS("FMOD") << "About to LLAudioEngine::shutdown()" << LL_ENDL; + LLAudioEngine::shutdown(); + + LL_INFOS("FMOD") << "LLAudioEngine_FMODSTUDIO::shutdown() closing FMOD Studio" << LL_ENDL; + if (mSystem) + { + Check_FMOD_Error(mSystem->close(), "FMOD::System::close"); + Check_FMOD_Error(mSystem->release(), "FMOD::System::release"); + } + LL_INFOS("FMOD") << "LLAudioEngine_FMODSTUDIO::shutdown() done closing FMOD Studio" << LL_ENDL; + + delete mListenerp; + mListenerp = NULL; } LLAudioBuffer * LLAudioEngine_FMODSTUDIO::createBuffer() { - return new LLAudioBufferFMODSTUDIO(mSystem); + return new LLAudioBufferFMODSTUDIO(mSystem); } LLAudioChannel * LLAudioEngine_FMODSTUDIO::createChannel() { - return new LLAudioChannelFMODSTUDIO(mSystem); + return new LLAudioChannelFMODSTUDIO(mSystem); } bool LLAudioEngine_FMODSTUDIO::initWind() { - mNextWindUpdate = 0.0; + mNextWindUpdate = 0.0; - cleanupWind(); + if (!mWindDSPDesc) + { + mWindDSPDesc = new FMOD_DSP_DESCRIPTION(); + } - mWindDSPDesc = new FMOD_DSP_DESCRIPTION(); - memset(mWindDSPDesc, 0, sizeof(*mWindDSPDesc)); //Set everything to zero - mWindDSPDesc->pluginsdkversion = FMOD_PLUGIN_SDK_VERSION; - strncpy(mWindDSPDesc->name, "Wind Unit", sizeof(mWindDSPDesc->name)); //Set name to "Wind Unit" - mWindDSPDesc->numoutputbuffers = 1; - mWindDSPDesc->read = &windDSPCallback; //Assign callback. - if (Check_FMOD_Error(mSystem->createDSP(mWindDSPDesc, &mWindDSP), "FMOD::createDSP") || !mWindDSP) - return false; + if (!mWindDSP) + { + memset(mWindDSPDesc, 0, sizeof(*mWindDSPDesc)); //Set everything to zero + strncpy(mWindDSPDesc->name, "Wind Unit", sizeof(mWindDSPDesc->name)); + mWindDSPDesc->pluginsdkversion = FMOD_PLUGIN_SDK_VERSION; + mWindDSPDesc->read = &windCallback; // Assign callback - may be called from arbitrary threads + if (Check_FMOD_Error(mSystem->createDSP(mWindDSPDesc, &mWindDSP), "FMOD::createDSP")) + return false; - int frequency = 44100; - FMOD_SPEAKERMODE mode; - if (!Check_FMOD_Error(mSystem->getSoftwareFormat(&frequency, &mode, nullptr), "FMOD::System::getSoftwareFormat")) - { - mWindGen = new LLWindGen((U32)frequency); + if (mWindGen) + delete mWindGen; - if (!Check_FMOD_Error(mWindDSP->setUserData((void*)mWindGen), "FMOD::DSP::setUserData") && - !Check_FMOD_Error(mWindDSP->setChannelFormat(FMOD_CHANNELMASK_STEREO, 2, mode), "FMOD::DSP::setChannelFormat") && - !Check_FMOD_Error(mSystem->playDSP(mWindDSP, nullptr, false, nullptr), "FMOD::System::playDSP")) - return true; //Success - } + int frequency = 44100; - cleanupWind(); - return false; + FMOD_SPEAKERMODE mode; + if (Check_FMOD_Error(mSystem->getSoftwareFormat(&frequency, &mode, nullptr), "FMOD::System::getSoftwareFormat")) + { + cleanupWind(); + return false; + } + + mWindGen = new LLWindGen((U32)frequency); + + if (Check_FMOD_Error(mWindDSP->setUserData((void*)mWindGen), "FMOD::DSP::setUserData")) + { + cleanupWind(); + return false; + } + if (Check_FMOD_Error(mWindDSP->setChannelFormat(FMOD_CHANNELMASK_STEREO, 2, mode), "FMOD::DSP::setChannelFormat")) + { + cleanupWind(); + return false; + } + } + + // *TODO: Should this guard against multiple plays? + if (Check_FMOD_Error(mSystem->playDSP(mWindDSP, nullptr, false, nullptr), "FMOD::System::playDSP")) + { + cleanupWind(); + return false; + } + return true; } void LLAudioEngine_FMODSTUDIO::cleanupWind() { - if (mWindDSP) - { - 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; - } + if (mWindDSP) + { + FMOD::ChannelGroup* master_group = NULL; + if (!Check_FMOD_Error(mSystem->getMasterChannelGroup(&master_group), "FMOD::System::getMasterChannelGroup") + && master_group) + { + Check_FMOD_Error(master_group->removeDSP(mWindDSP), "FMOD::ChannelGroup::removeDSP"); + } + Check_FMOD_Error(mWindDSP->release(), "FMOD::DSP::release"); + mWindDSP = NULL; + } - delete mWindDSPDesc; - mWindDSPDesc = NULL; + delete mWindDSPDesc; + mWindDSPDesc = NULL; - delete mWindGen; - mWindGen = NULL; + delete mWindGen; + mWindGen = NULL; } //----------------------------------------------------------------------- void LLAudioEngine_FMODSTUDIO::updateWind(LLVector3 wind_vec, F32 camera_height_above_water) { - LLVector3 wind_pos; - F64 pitch; - F64 center_freq; + LLVector3 wind_pos; + F64 pitch; + F64 center_freq; - if (!mEnableWind) - { - return; - } - - if (mWindUpdateTimer.checkExpirationAndReset(LL_WIND_UPDATE_INTERVAL)) - { - - // wind comes in as Linden coordinate (+X = forward, +Y = left, +Z = up) - // need to convert this to the conventional orientation DS3D and OpenAL use - // where +X = right, +Y = up, +Z = backwards + if (!mEnableWind) + { + return; + } - wind_vec.setVec(-wind_vec.mV[1], wind_vec.mV[2], -wind_vec.mV[0]); + if (mWindUpdateTimer.checkExpirationAndReset(LL_WIND_UPDATE_INTERVAL)) + { - // cerr << "Wind update" << endl; + // wind comes in as Linden coordinate (+X = forward, +Y = left, +Z = up) + // need to convert this to the conventional orientation DS3D and OpenAL use + // where +X = right, +Y = up, +Z = backwards - pitch = 1.0 + mapWindVecToPitch(wind_vec); - center_freq = 80.0 * pow(pitch,2.5*(mapWindVecToGain(wind_vec)+1.0)); - - mWindGen->mTargetFreq = (F32)center_freq; - mWindGen->mTargetGain = (F32)mapWindVecToGain(wind_vec) * mMaxWindGain; - mWindGen->mTargetPanGainR = (F32)mapWindVecToPan(wind_vec); - } + wind_vec.setVec(-wind_vec.mV[1], wind_vec.mV[2], -wind_vec.mV[0]); + + // cerr << "Wind update" << endl; + + pitch = 1.0 + mapWindVecToPitch(wind_vec); + center_freq = 80.0 * pow(pitch, 2.5*(mapWindVecToGain(wind_vec) + 1.0)); + + mWindGen->mTargetFreq = (F32)center_freq; + mWindGen->mTargetGain = (F32)mapWindVecToGain(wind_vec) * mMaxWindGain; + mWindGen->mTargetPanGainR = (F32)mapWindVecToPan(wind_vec); + } } //----------------------------------------------------------------------- void LLAudioEngine_FMODSTUDIO::setInternalGain(F32 gain) { - if (!mInited) - { - return; - } + if (!mInited) + { + return; + } - gain = llclamp( gain, 0.0f, 1.0f ); + gain = llclamp(gain, 0.0f, 1.0f); - FMOD::ChannelGroup *master_group; - if(Check_FMOD_Error(mSystem->getMasterChannelGroup(&master_group), "FMOD::System::getMasterChannelGroup")) - return; + FMOD::ChannelGroup* master_group = NULL; + if (!Check_FMOD_Error(mSystem->getMasterChannelGroup(&master_group), "FMOD::System::getMasterChannelGroup") + && master_group) + { + master_group->setVolume(gain); + } - master_group->setVolume(gain); - - LLStreamingAudioInterface *saimpl = getStreamingAudioImpl(); - if ( saimpl ) - { - // fmod likes its streaming audio channel gain re-asserted after - // master volume change. - saimpl->setGain(saimpl->getGain()); - } + LLStreamingAudioInterface *saimpl = getStreamingAudioImpl(); + if (saimpl) + { + // fmod likes its streaming audio channel gain re-asserted after + // master volume change. + saimpl->setGain(saimpl->getGain()); + } } // @@ -552,191 +582,195 @@ LLAudioChannelFMODSTUDIO::LLAudioChannelFMODSTUDIO(FMOD::System *system) : LLAud LLAudioChannelFMODSTUDIO::~LLAudioChannelFMODSTUDIO() { - cleanup(); + cleanup(); } bool LLAudioChannelFMODSTUDIO::updateBuffer() { - if (mCurrentSourcep) - { - if (LLAudioChannel::updateBuffer()) - { - // Base class update returned true, which means that we need to actually - // set up the channel for a different buffer. + if (!mCurrentSourcep) + { + // This channel isn't associated with any source, nothing + // to be updated + return false; + } - LLAudioBufferFMODSTUDIO *bufferp = (LLAudioBufferFMODSTUDIO *) mCurrentSourcep->getCurrentBuffer(); + if (LLAudioChannel::updateBuffer()) + { + // Base class update returned true, which means that we need to actually + // set up the channel for a different buffer. - // Grab the FMOD sample associated with the buffer - FMOD::Sound *soundp = bufferp->getSound(); - if (!soundp) - { - // This is bad, there should ALWAYS be a sound associated with a legit - // buffer. - LL_ERRS() << "No FMOD sound!" << LL_ENDL; - return false; - } + LLAudioBufferFMODSTUDIO *bufferp = (LLAudioBufferFMODSTUDIO *)mCurrentSourcep->getCurrentBuffer(); + + // Grab the FMOD sample associated with the buffer + FMOD::Sound *soundp = bufferp->getSound(); + if (!soundp) + { + // This is bad, there should ALWAYS be a sound associated with a legit + // buffer. + LL_ERRS() << "No FMOD sound!" << LL_ENDL; + return false; + } - // Actually play the sound. Start it off paused so we can do all the necessary - // setup. - if (!mChannelp) - { - FMOD_RESULT result = getSystem()->playSound(soundp, nullptr, true, &mChannelp); - Check_FMOD_Error(result, "FMOD::System::playSound"); - } + // Actually play the sound. Start it off paused so we can do all the necessary + // setup. + if (!mChannelp) + { + FMOD_RESULT result = getSystem()->playSound(soundp, NULL /*free channel?*/, true, &mChannelp); + Check_FMOD_Error(result, "FMOD::System::playSound"); + } - //LL_INFOS() << "Setting up channel " << std::hex << mChannelID << std::dec << LL_ENDL; - } + // Setting up channel mChannelID + } - //FMOD_RESULT result; + // If we have a source for the channel, we need to update its gain. + if (mCurrentSourcep) + { + // SJB: warnings can spam and hurt framerate, disabling + //FMOD_RESULT result; - mChannelp->setVolume(getSecondaryGain() * mCurrentSourcep->getGain()); - //Check_FMOD_Error(result, "FMOD::Channel::setVolume"); + mChannelp->setVolume(getSecondaryGain() * mCurrentSourcep->getGain()); + //Check_FMOD_Error(result, "FMOD::Channel::setVolume"); - mChannelp->setMode(mCurrentSourcep->isLoop() ? FMOD_LOOP_NORMAL : FMOD_LOOP_OFF); - /*if(Check_FMOD_Error(result, "FMOD::Channel::setMode")) - { - S32 index; - mChannelp->getIndex(&index); - LL_WARNS() << "Channel " << index << "Source ID: " << mCurrentSourcep->getID() - << " at " << mCurrentSourcep->getPositionGlobal() << LL_ENDL; - }*/ - } - else - { - LL_DEBUGS() << "No source buffer!" << LL_ENDL; - return false; - } + mChannelp->setMode(mCurrentSourcep->isLoop() ? FMOD_LOOP_NORMAL : FMOD_LOOP_OFF); + /*if(Check_FMOD_Error(result, "FMOD::Channel::setMode")) + { + S32 index; + mChannelp->getIndex(&index); + LL_WARNS() << "Channel " << index << "Source ID: " << mCurrentSourcep->getID() + << " at " << mCurrentSourcep->getPositionGlobal() << LL_ENDL; + }*/ + } - return true; + return true; } void LLAudioChannelFMODSTUDIO::update3DPosition() { - if (!mChannelp) - { - // We're not actually a live channel (i.e., we're not playing back anything) - return; - } + if (!mChannelp) + { + // We're not actually a live channel (i.e., we're not playing back anything) + return; + } - LLAudioBufferFMODSTUDIO *bufferp = (LLAudioBufferFMODSTUDIO *)mCurrentBufferp; - if (!bufferp) - { - // We don't have a buffer associated with us (should really have been picked up - // by the above if. - return; - } + LLAudioBufferFMODSTUDIO *bufferp = (LLAudioBufferFMODSTUDIO *)mCurrentBufferp; + if (!bufferp) + { + // We don't have a buffer associated with us (should really have been picked up + // by the above if. + return; + } - if (mCurrentSourcep->isAmbient()) - { - // Ambient sound, don't need to do any positional updates. - set3DMode(false); - } - else - { - // Localized sound. Update the position and velocity of the sound. - set3DMode(true); + if (mCurrentSourcep->isAmbient()) + { + // Ambient sound, don't need to do any positional updates. + set3DMode(false); + } + else + { + // Localized sound. Update the position and velocity of the sound. + set3DMode(true); - LLVector3 float_pos; - float_pos.setVec(mCurrentSourcep->getPositionGlobal()); - FMOD_RESULT result = mChannelp->set3DAttributes((FMOD_VECTOR*)float_pos.mV, (FMOD_VECTOR*)mCurrentSourcep->getVelocity().mV); - Check_FMOD_Error(result, "FMOD::Channel::set3DAttributes"); - } + LLVector3 float_pos; + float_pos.setVec(mCurrentSourcep->getPositionGlobal()); + FMOD_RESULT result = mChannelp->set3DAttributes((FMOD_VECTOR*)float_pos.mV, (FMOD_VECTOR*)mCurrentSourcep->getVelocity().mV); + Check_FMOD_Error(result, "FMOD::Channel::set3DAttributes"); + } } void LLAudioChannelFMODSTUDIO::updateLoop() { - if (!mChannelp) - { - // May want to clear up the loop/sample counters. - return; - } + if (!mChannelp) + { + // May want to clear up the loop/sample counters. + return; + } - // - // Hack: We keep track of whether we looped or not by seeing when the - // sample position looks like it's going backwards. Not reliable; may - // yield false negatives. - // - U32 cur_pos; - Check_FMOD_Error(mChannelp->getPosition(&cur_pos,FMOD_TIMEUNIT_PCMBYTES),"FMOD::Channel::getPosition"); + // + // Hack: We keep track of whether we looped or not by seeing when the + // sample position looks like it's going backwards. Not reliable; may + // yield false negatives. + // + U32 cur_pos; + Check_FMOD_Error(mChannelp->getPosition(&cur_pos, FMOD_TIMEUNIT_PCMBYTES), "FMOD::Channel::getPosition"); - if (cur_pos < (U32)mLastSamplePos) - { - mLoopedThisFrame = true; - } - mLastSamplePos = cur_pos; + if (cur_pos < (U32)mLastSamplePos) + { + mLoopedThisFrame = true; + } + mLastSamplePos = cur_pos; } void LLAudioChannelFMODSTUDIO::cleanup() { - if (!mChannelp) - { - //LL_INFOS() << "Aborting cleanup with no channel handle." << LL_ENDL; - return; - } + if (!mChannelp) + { + // Aborting cleanup with no channel handle. + return; + } - //LL_INFOS() << "Cleaning up channel: " << mChannelID << LL_ENDL; - Check_FMOD_Error(mChannelp->stop(),"FMOD::Channel::stop"); + //Cleaning up channel mChannelID + Check_FMOD_Error(mChannelp->stop(), "FMOD::Channel::stop"); - mCurrentBufferp = NULL; - mChannelp = NULL; + mCurrentBufferp = NULL; + mChannelp = NULL; } void LLAudioChannelFMODSTUDIO::play() { - if (!mChannelp) - { - LL_WARNS() << "Playing without a channel handle, aborting" << LL_ENDL; - return; - } + if (!mChannelp) + { + LL_WARNS() << "Playing without a channel handle, aborting" << LL_ENDL; + return; + } - Check_FMOD_Error(mChannelp->setPaused(false), "FMOD::Channel::setPaused"); + Check_FMOD_Error(mChannelp->setPaused(false), "FMOD::Channel::setPaused"); - getSource()->setPlayedOnce(true); + getSource()->setPlayedOnce(true); - if(LLAudioEngine_FMODSTUDIO::mChannelGroups[getSource()->getType()]) - Check_FMOD_Error(mChannelp->setChannelGroup(LLAudioEngine_FMODSTUDIO::mChannelGroups[getSource()->getType()]),"FMOD::Channel::setChannelGroup"); + if (LLAudioEngine_FMODSTUDIO::mChannelGroups[getSource()->getType()]) + Check_FMOD_Error(mChannelp->setChannelGroup(LLAudioEngine_FMODSTUDIO::mChannelGroups[getSource()->getType()]), "FMOD::Channel::setChannelGroup"); } void LLAudioChannelFMODSTUDIO::playSynced(LLAudioChannel *channelp) { - LLAudioChannelFMODSTUDIO *fmod_channelp = (LLAudioChannelFMODSTUDIO*)channelp; - if (!(fmod_channelp->mChannelp && mChannelp)) - { - // Don't have channels allocated to both the master and the slave - return; - } + LLAudioChannelFMODSTUDIO *fmod_channelp = (LLAudioChannelFMODSTUDIO*)channelp; + if (!(fmod_channelp->mChannelp && mChannelp)) + { + // Don't have channels allocated to both the master and the slave + return; + } - U32 cur_pos; - if(Check_FMOD_Error(mChannelp->getPosition(&cur_pos,FMOD_TIMEUNIT_PCMBYTES), "Unable to retrieve current position")) - return; + U32 cur_pos; + if (Check_FMOD_Error(mChannelp->getPosition(&cur_pos, FMOD_TIMEUNIT_PCMBYTES), "Unable to retrieve current position")) + return; - cur_pos %= mCurrentBufferp->getLength(); - - // Try to match the position of our sync master - Check_FMOD_Error(mChannelp->setPosition(cur_pos,FMOD_TIMEUNIT_PCMBYTES),"Unable to set current position"); + cur_pos %= mCurrentBufferp->getLength(); - // Start us playing - play(); + // Try to match the position of our sync master + Check_FMOD_Error(mChannelp->setPosition(cur_pos, FMOD_TIMEUNIT_PCMBYTES), "Unable to set current position"); + + // Start us playing + play(); } bool LLAudioChannelFMODSTUDIO::isPlaying() { - if (!mChannelp) - { - return false; - } + if (!mChannelp) + { + return false; + } - bool paused, playing; - Check_FMOD_Error(mChannelp->getPaused(&paused),"FMOD::Channel::getPaused"); - Check_FMOD_Error(mChannelp->isPlaying(&playing),"FMOD::Channel::isPlaying"); - return !paused && playing; + bool paused, playing; + Check_FMOD_Error(mChannelp->getPaused(&paused),"FMOD::Channel::getPaused"); + Check_FMOD_Error(mChannelp->isPlaying(&playing),"FMOD::Channel::isPlaying"); + return !paused && playing; } @@ -752,109 +786,111 @@ LLAudioBufferFMODSTUDIO::LLAudioBufferFMODSTUDIO(FMOD::System *system) : mSystem LLAudioBufferFMODSTUDIO::~LLAudioBufferFMODSTUDIO() { - if(mSoundp) - { - Check_FMOD_Error(mSoundp->release(),"FMOD::Sound::Release"); - mSoundp = NULL; - } + if (mSoundp) + { + Check_FMOD_Error(mSoundp->release(), "FMOD::Sound::Release"); + mSoundp = NULL; + } } bool LLAudioBufferFMODSTUDIO::loadWAV(const std::string& filename) { - // Try to open a wav file from disk. This will eventually go away, as we don't - // really want to block doing this. - if (filename.empty()) - { - // invalid filename, abort. - return false; - } + // Try to open a wav file from disk. This will eventually go away, as we don't + // really want to block doing this. + if (filename.empty()) + { + // invalid filename, abort. + return false; + } - if (!gDirUtilp->fileExists(filename)) - { - // File not found, abort. - return false; - } - - if (mSoundp) - { - // If there's already something loaded in this buffer, clean it up. - Check_FMOD_Error(mSoundp->release(),"FMOD::Sound::release"); - mSoundp = NULL; - } + if (!LLAPRFile::isExist(filename, NULL, LL_APR_RPB)) + { + // File not found, abort. + return false; + } - FMOD_MODE base_mode = FMOD_LOOP_NORMAL; - 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 - FMOD_RESULT result = getSystem()->createSound(filename.c_str(), base_mode, &exinfo, &mSoundp); - if (result != FMOD_OK) - { - // We failed to load the file for some reason. - LL_WARNS() << "Could not load data '" << filename << "': " << FMOD_ErrorString(result) << LL_ENDL; + if (mSoundp) + { + // If there's already something loaded in this buffer, clean it up. + Check_FMOD_Error(mSoundp->release(), "FMOD::Sound::release"); + mSoundp = NULL; + } - // - // If we EVER want to load wav files provided by end users, we need - // to rethink this! - // - // file is probably corrupt - remove it. - LLFile::remove(filename); - return false; - } + FMOD_MODE base_mode = FMOD_LOOP_NORMAL; + 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 (since 1.05 fmod studio expects everything in UTF-8) + FMOD_RESULT result = getSystem()->createSound(filename.c_str(), base_mode, &exinfo, &mSoundp); - // Everything went well, return true - return true; + if (result != FMOD_OK) + { + // We failed to load the file for some reason. + LL_WARNS() << "Could not load data '" << filename << "': " << FMOD_ErrorString(result) << LL_ENDL; + + // + // If we EVER want to load wav files provided by end users, we need + // to rethink this! + // + // file is probably corrupt - remove it. + LLFile::remove(filename); + return false; + } + + // Everything went well, return true + return true; } U32 LLAudioBufferFMODSTUDIO::getLength() { - if (!mSoundp) - { - return 0; - } + if (!mSoundp) + { + return 0; + } - U32 length; - Check_FMOD_Error(mSoundp->getLength(&length, FMOD_TIMEUNIT_PCMBYTES),"FMOD::Sound::getLength"); - return length; + U32 length; + Check_FMOD_Error(mSoundp->getLength(&length, FMOD_TIMEUNIT_PCMBYTES), "FMOD::Sound::getLength"); + return length; } void LLAudioChannelFMODSTUDIO::set3DMode(bool use3d) { - FMOD_MODE current_mode; - if(Check_FMOD_Error(mChannelp->getMode(¤t_mode),"FMOD::Channel::getMode")) - return; - FMOD_MODE new_mode = current_mode; - new_mode &= ~(use3d ? FMOD_2D : FMOD_3D); - new_mode |= use3d ? FMOD_3D : FMOD_2D; + FMOD_MODE current_mode; + if (Check_FMOD_Error(mChannelp->getMode(¤t_mode), "FMOD::Channel::getMode")) + return; + FMOD_MODE new_mode = current_mode; + new_mode &= ~(use3d ? FMOD_2D : FMOD_3D); + new_mode |= use3d ? FMOD_3D : FMOD_2D; - if(current_mode != new_mode) - { - Check_FMOD_Error(mChannelp->setMode(new_mode),"FMOD::Channel::setMode"); - } + if (current_mode != new_mode) + { + Check_FMOD_Error(mChannelp->setMode(new_mode), "FMOD::Channel::setMode"); + } } // *NOTE: This is almost certainly being called on the mixer thread, // not the main thread. May have implications for callees or audio // engine shutdown. -FMOD_RESULT F_CALLBACK windDSPCallback(FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, 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) { - // 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 *windgen; - FMOD::DSP *thisdsp = (FMOD::DSP *)dsp_state->instance; + // inbuffer = fmod's original mixbuffer. + // outbuffer = the buffer passed from the previous DSP unit. + // length = length in samples at this mix time. - thisdsp->getUserData((void **)&windgen); - - if (windgen) - windgen->windGenerate((LLAudioEngine_FMODSTUDIO::MIXBUFFERFORMAT *)outbuffer, length); + LLWindGen *windgen = NULL; + FMOD::DSP *thisdsp = (FMOD::DSP *)dsp_state->instance; - return FMOD_OK; + thisdsp->getUserData((void **)&windgen); + + if (windgen) + { + windgen->windGenerate((LLAudioEngine_FMODSTUDIO::MIXBUFFERFORMAT *)outbuffer, length); + } + + return FMOD_OK; } diff --git a/indra/llaudio/llaudioengine_fmodstudio.h b/indra/llaudio/llaudioengine_fmodstudio.h index 3b80f45336..91f7cc89e4 100644 --- a/indra/llaudio/llaudioengine_fmodstudio.h +++ b/indra/llaudio/llaudioengine_fmodstudio.h @@ -1,11 +1,11 @@ /** * @file audioengine_fmodstudio.h * @brief Definition of LLAudioEngine class abstracting the audio - * support as a FMOD Studio implementation + * support as a FMODSTUDIO implementation * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * $LicenseInfo:firstyear=2020&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2014, Linden Research, Inc. + * Copyright (C) 2020, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -57,7 +57,7 @@ public: virtual ~LLAudioEngine_FMODSTUDIO(); // initialization/startup/shutdown - virtual bool init(const S32 num_channels, void *user_data); + virtual bool init(const S32 num_channels, void *user_data, const std::string &app_title); virtual std::string getDriverName(bool verbose); virtual void allocateListener(); @@ -103,8 +103,8 @@ public: class LLAudioChannelFMODSTUDIO : public LLAudioChannel { public: - LLAudioChannelFMODSTUDIO(FMOD::System *audioengine); - virtual ~LLAudioChannelFMODSTUDIO(); + LLAudioChannelFMODSTUDIO(FMOD::System *audioengine); + virtual ~LLAudioChannelFMODSTUDIO(); protected: /*virtual*/ void play(); @@ -128,8 +128,8 @@ protected: class LLAudioBufferFMODSTUDIO : public LLAudioBuffer { public: - LLAudioBufferFMODSTUDIO(FMOD::System *audioengine); - virtual ~LLAudioBufferFMODSTUDIO(); + LLAudioBufferFMODSTUDIO(FMOD::System *audioengine); + virtual ~LLAudioBufferFMODSTUDIO(); /*virtual*/ bool loadWAV(const std::string& filename); /*virtual*/ U32 getLength(); diff --git a/indra/llaudio/llaudioengine_openal.cpp b/indra/llaudio/llaudioengine_openal.cpp index 8067c832fd..66e56e4c70 100644 --- a/indra/llaudio/llaudioengine_openal.cpp +++ b/indra/llaudio/llaudioengine_openal.cpp @@ -52,10 +52,10 @@ LLAudioEngine_OpenAL::~LLAudioEngine_OpenAL() } // virtual -bool LLAudioEngine_OpenAL::init(const S32 num_channels, void* userdata) +bool LLAudioEngine_OpenAL::init(const S32 num_channels, void* userdata, const std::string &app_title) { mWindGen = NULL; - LLAudioEngine::init(num_channels, userdata); + LLAudioEngine::init(num_channels, userdata, app_title); if(!alutInit(NULL, NULL)) { @@ -241,6 +241,13 @@ bool LLAudioChannelOpenAL::isPlaying() bool LLAudioChannelOpenAL::updateBuffer() { + if (!mCurrentSourcep) + { + // This channel isn't associated with any source, nothing + // to be updated + return false; + } + if (LLAudioChannel::updateBuffer()) { // Base class update returned true, which means that we need to actually diff --git a/indra/llaudio/llaudioengine_openal.h b/indra/llaudio/llaudioengine_openal.h index 6639d9dfe6..366f9259e3 100644 --- a/indra/llaudio/llaudioengine_openal.h +++ b/indra/llaudio/llaudioengine_openal.h @@ -40,8 +40,8 @@ class LLAudioEngine_OpenAL : public LLAudioEngine LLAudioEngine_OpenAL(); virtual ~LLAudioEngine_OpenAL(); - virtual bool init(const S32 num_channels, void *user_data); - virtual std::string getDriverName(bool verbose); + virtual bool init(const S32 num_channels, void *user_data, const std::string &app_title); + virtual std::string getDriverName(bool verbose); virtual void allocateListener(); virtual void shutdown(); diff --git a/indra/llaudio/lllistener_fmodex.cpp b/indra/llaudio/lllistener_fmodex.cpp deleted file mode 100644 index 31ab47a635..0000000000 --- a/indra/llaudio/lllistener_fmodex.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/** - * @file listener_fmodex.cpp - * @brief Implementation of LISTENER class abstracting the audio - * support as a FMODEX implementation - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "linden_common.h" -#include "llaudioengine.h" -#include "lllistener_fmodex.h" -#include "fmod.hpp" - -//----------------------------------------------------------------------- -// constructor -//----------------------------------------------------------------------- -LLListener_FMODEX::LLListener_FMODEX(FMOD::System *system) -{ - mSystem = system; - init(); -} - -//----------------------------------------------------------------------- -LLListener_FMODEX::~LLListener_FMODEX() -{ -} - -//----------------------------------------------------------------------- -void LLListener_FMODEX::init(void) -{ - // do inherited - LLListener::init(); - mDopplerFactor = 1.0f; - mRolloffFactor = 1.0f; -} - -//----------------------------------------------------------------------- -void LLListener_FMODEX::translate(LLVector3 offset) -{ - LLListener::translate(offset); - - mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)mPosition.mV, NULL, (FMOD_VECTOR*)mListenAt.mV, (FMOD_VECTOR*)mListenUp.mV); -} - -//----------------------------------------------------------------------- -void LLListener_FMODEX::setPosition(LLVector3 pos) -{ - LLListener::setPosition(pos); - - mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)mPosition.mV, NULL, (FMOD_VECTOR*)mListenAt.mV, (FMOD_VECTOR*)mListenUp.mV); -} - -//----------------------------------------------------------------------- -void LLListener_FMODEX::setVelocity(LLVector3 vel) -{ - LLListener::setVelocity(vel); - - mSystem->set3DListenerAttributes(0, NULL, (FMOD_VECTOR*)mVelocity.mV, (FMOD_VECTOR*)mListenAt.mV, (FMOD_VECTOR*)mListenUp.mV); -} - -//----------------------------------------------------------------------- -void LLListener_FMODEX::orient(LLVector3 up, LLVector3 at) -{ - LLListener::orient(up, at); - - // Welcome to the transition between right and left - // (coordinate systems, that is) - // Leaving the at vector alone results in a L/R reversal - // since DX is left-handed and we (LL, OpenGL, OpenAL) are right-handed - at = -at; - - mSystem->set3DListenerAttributes(0, NULL, NULL, (FMOD_VECTOR*)at.mV, (FMOD_VECTOR*)up.mV); -} - -//----------------------------------------------------------------------- -void LLListener_FMODEX::commitDeferredChanges() -{ - if(!mSystem) - { - return; - } - - mSystem->update(); -} - - -void LLListener_FMODEX::setRolloffFactor(F32 factor) -{ - //An internal FMODEx optimization skips 3D updates if there have not been changes to the 3D sound environment. - //Sadly, a change in rolloff is not accounted for, thus we must touch the listener properties as well. - //In short: Changing the position ticks a dirtyflag inside fmodex, which makes it not skip 3D processing next update call. - if(mRolloffFactor != factor) - { - LLVector3 pos = mVelocity - LLVector3(0.f,0.f,.1f); - mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)pos.mV, NULL, NULL, NULL); - mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)mVelocity.mV, NULL, NULL, NULL); - } - mRolloffFactor = factor; - mSystem->set3DSettings(mDopplerFactor, 1.f, mRolloffFactor); -} - - -F32 LLListener_FMODEX::getRolloffFactor() -{ - return mRolloffFactor; -} - - -void LLListener_FMODEX::setDopplerFactor(F32 factor) -{ - mDopplerFactor = factor; - mSystem->set3DSettings(mDopplerFactor, 1.f, mRolloffFactor); -} - - -F32 LLListener_FMODEX::getDopplerFactor() -{ - return mDopplerFactor; -} - - diff --git a/indra/llaudio/lllistener_fmodex.h b/indra/llaudio/lllistener_fmodex.h deleted file mode 100644 index 073b65d53a..0000000000 --- a/indra/llaudio/lllistener_fmodex.h +++ /dev/null @@ -1,65 +0,0 @@ -/** - * @file listener_fmodex.h - * @brief Description of LISTENER class abstracting the audio support - * as an FMOD 3D implementation (windows and Linux) - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_LISTENER_FMODEX_H -#define LL_LISTENER_FMODEX_H - -#include "lllistener.h" - -//Stubs -namespace FMOD -{ - class System; -} - -//Interfaces -class LLListener_FMODEX : public LLListener -{ - public: - LLListener_FMODEX(FMOD::System *system); - virtual ~LLListener_FMODEX(); - virtual void init(); - - virtual void translate(LLVector3 offset); - virtual void setPosition(LLVector3 pos); - virtual void setVelocity(LLVector3 vel); - virtual void orient(LLVector3 up, LLVector3 at); - virtual void commitDeferredChanges(); - - virtual void setDopplerFactor(F32 factor); - virtual F32 getDopplerFactor(); - virtual void setRolloffFactor(F32 factor); - virtual F32 getRolloffFactor(); - protected: - FMOD::System *mSystem; - F32 mDopplerFactor; - F32 mRolloffFactor; -}; - -#endif - - diff --git a/indra/llaudio/lllistener_fmodstudio.cpp b/indra/llaudio/lllistener_fmodstudio.cpp index f5a10442dc..abd5e345b5 100644 --- a/indra/llaudio/lllistener_fmodstudio.cpp +++ b/indra/llaudio/lllistener_fmodstudio.cpp @@ -1,11 +1,11 @@ /** * @file listener_fmodstudio.cpp * @brief Implementation of LISTENER class abstracting the audio - * support as a FMOD Studio implementation + * support as a FMODSTUDIO implementation * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * $LicenseInfo:firstyear=2020&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2020, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,17 +28,15 @@ #include "linden_common.h" #include "llaudioengine.h" #include "lllistener_fmodstudio.h" -#include "fmod.hpp" +#include "fmodstudio/fmod.hpp" //----------------------------------------------------------------------- // constructor //----------------------------------------------------------------------- -LLListener_FMODSTUDIO::LLListener_FMODSTUDIO(FMOD::System *system) - : LLListener(), - mDopplerFactor(1.0f), - mRolloffFactor(1.0f) +LLListener_FMODSTUDIO::LLListener_FMODSTUDIO(FMOD::System *system) { - mSystem = system; + mSystem = system; + init(); } //----------------------------------------------------------------------- @@ -46,82 +44,93 @@ LLListener_FMODSTUDIO::~LLListener_FMODSTUDIO() { } +//----------------------------------------------------------------------- +void LLListener_FMODSTUDIO::init(void) +{ + // do inherited + LLListener::init(); + mDopplerFactor = 1.0f; + mRolloffFactor = 1.0f; +} + //----------------------------------------------------------------------- void LLListener_FMODSTUDIO::translate(LLVector3 offset) { - LLListener::translate(offset); + LLListener::translate(offset); - mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)mPosition.mV, NULL, NULL, NULL); + mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)mPosition.mV, NULL, (FMOD_VECTOR*)mListenAt.mV, (FMOD_VECTOR*)mListenUp.mV); } //----------------------------------------------------------------------- void LLListener_FMODSTUDIO::setPosition(LLVector3 pos) { - LLListener::setPosition(pos); + LLListener::setPosition(pos); - mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)mPosition.mV, NULL, NULL, NULL); + mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)mPosition.mV, NULL, (FMOD_VECTOR*)mListenAt.mV, (FMOD_VECTOR*)mListenUp.mV); } //----------------------------------------------------------------------- void LLListener_FMODSTUDIO::setVelocity(LLVector3 vel) { - LLListener::setVelocity(vel); + LLListener::setVelocity(vel); - mSystem->set3DListenerAttributes(0, NULL, (FMOD_VECTOR*)mVelocity.mV, NULL, NULL); + mSystem->set3DListenerAttributes(0, NULL, (FMOD_VECTOR*)mVelocity.mV, (FMOD_VECTOR*)mListenAt.mV, (FMOD_VECTOR*)mListenUp.mV); } //----------------------------------------------------------------------- void LLListener_FMODSTUDIO::orient(LLVector3 up, LLVector3 at) { - LLListener::orient(up, at); + LLListener::orient(up, at); - mSystem->set3DListenerAttributes(0, NULL, NULL, (FMOD_VECTOR*)at.mV, (FMOD_VECTOR*)up.mV); + // at = -at; by default Fmod studio is 'left-handed' but we are providing + // flag FMOD_INIT_3D_RIGHTHANDED so no correction are needed + + mSystem->set3DListenerAttributes(0, NULL, NULL, (FMOD_VECTOR*)at.mV, (FMOD_VECTOR*)up.mV); } //----------------------------------------------------------------------- void LLListener_FMODSTUDIO::commitDeferredChanges() { - if(!mSystem) - { - return; - } + if (!mSystem) + { + return; + } - mSystem->update(); + mSystem->update(); } void LLListener_FMODSTUDIO::setRolloffFactor(F32 factor) { - //An internal FMOD Studio optimization skips 3D updates if there have not been changes to the 3D sound environment. - //Sadly, a change in rolloff is not accounted for, thus we must touch the listener properties as well. - //In short: Changing the position ticks a dirtyflag inside fmod studio, which makes it not skip 3D processing next update call. - if(mRolloffFactor != factor) - { - LLVector3 tmp_pos = mPosition - LLVector3(0.f,0.f,.1f); - mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*) tmp_pos.mV, NULL, NULL, NULL); - mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*) mPosition.mV, NULL, NULL, NULL); - } - mRolloffFactor = factor; - mSystem->set3DSettings(mDopplerFactor, 1.f, mRolloffFactor); + //An internal FMOD optimization skips 3D updates if there have not been changes to the 3D sound environment. + // (this was true for FMODex, looks to be still true for FMOD STUDIO, but needs a recheck) + //Sadly, a change in rolloff is not accounted for, thus we must touch the listener properties as well. + //In short: Changing the position ticks a dirtyflag inside fmod, which makes it not skip 3D processing next update call. + if (mRolloffFactor != factor) + { + LLVector3 pos = mPosition - LLVector3(0.f, 0.f, .1f); + mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)pos.mV, NULL, NULL, NULL); + mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)mPosition.mV, NULL, NULL, NULL); + } + mRolloffFactor = factor; + mSystem->set3DSettings(mDopplerFactor, 1.f, mRolloffFactor); } F32 LLListener_FMODSTUDIO::getRolloffFactor() { - return mRolloffFactor; + return mRolloffFactor; } void LLListener_FMODSTUDIO::setDopplerFactor(F32 factor) { - mDopplerFactor = factor; - mSystem->set3DSettings(mDopplerFactor, 1.f, mRolloffFactor); + mDopplerFactor = factor; + mSystem->set3DSettings(mDopplerFactor, 1.f, mRolloffFactor); } F32 LLListener_FMODSTUDIO::getDopplerFactor() { - return mDopplerFactor; + return mDopplerFactor; } - - diff --git a/indra/llaudio/lllistener_fmodstudio.h b/indra/llaudio/lllistener_fmodstudio.h index ebe42f0e38..6ad85d9700 100644 --- a/indra/llaudio/lllistener_fmodstudio.h +++ b/indra/llaudio/lllistener_fmodstudio.h @@ -1,11 +1,11 @@ /** * @file listener_fmodstudio.h * @brief Description of LISTENER class abstracting the audio support - * as an FMOD Studio implementation (windows and Linux) + * as an FMOD 3D implementation * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * $LicenseInfo:firstyear=2020&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2020, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -39,24 +39,25 @@ namespace FMOD //Interfaces class LLListener_FMODSTUDIO : public LLListener { - public: - LLListener_FMODSTUDIO(FMOD::System *system); - virtual ~LLListener_FMODSTUDIO(); +public: + LLListener_FMODSTUDIO(FMOD::System *system); + virtual ~LLListener_FMODSTUDIO(); + virtual void init(); - virtual void translate(LLVector3 offset); - virtual void setPosition(LLVector3 pos); - virtual void setVelocity(LLVector3 vel); - virtual void orient(LLVector3 up, LLVector3 at); - virtual void commitDeferredChanges(); + virtual void translate(LLVector3 offset); + virtual void setPosition(LLVector3 pos); + virtual void setVelocity(LLVector3 vel); + virtual void orient(LLVector3 up, LLVector3 at); + virtual void commitDeferredChanges(); - virtual void setDopplerFactor(F32 factor); - virtual F32 getDopplerFactor(); - virtual void setRolloffFactor(F32 factor); - virtual F32 getRolloffFactor(); - protected: - FMOD::System *mSystem; - F32 mDopplerFactor; - F32 mRolloffFactor; + virtual void setDopplerFactor(F32 factor); + virtual F32 getDopplerFactor(); + virtual void setRolloffFactor(F32 factor); + virtual F32 getRolloffFactor(); +protected: + FMOD::System *mSystem; + F32 mDopplerFactor; + F32 mRolloffFactor; }; #endif diff --git a/indra/llaudio/llstreamingaudio_fmodex.cpp b/indra/llaudio/llstreamingaudio_fmodex.cpp deleted file mode 100644 index 6d4c7df8cc..0000000000 --- a/indra/llaudio/llstreamingaudio_fmodex.cpp +++ /dev/null @@ -1,667 +0,0 @@ -/** - * @file streamingaudio_fmodex.cpp - * @brief LLStreamingAudio_FMODEX implementation - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "linden_common.h" - -#include "llmath.h" - -#include "fmod.hpp" -#include "fmod_errors.h" - -#include "llstreamingaudio_fmodex.h" - -// FMOD fixes -static 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 -{ -public: - LLAudioStreamManagerFMODEX(FMOD::System *system, const std::string& url); - FMOD::Channel* startStream(); - bool stopStream(); // Returns true if the stream was successfully stopped. - bool ready(); - - const std::string& getURL() { return mInternetStreamURL; } - - // FMOD fixes - //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; - FMOD::Sound* mInternetStream; - bool mReady; - - std::string mInternetStreamURL; -}; - - - -//--------------------------------------------------------------------------- -// Internet Streaming -//--------------------------------------------------------------------------- -LLStreamingAudio_FMODEX::LLStreamingAudio_FMODEX(FMOD::System *system) : - mSystem(system), - mCurrentInternetStreamp(NULL), - mFMODInternetStreamChannelp(NULL), - mGain(1.0f) -{ - // FMOD fixes - 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 - // FMOD fixes - //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 - // to prebuffer 40% of that when we first connect, and we want it - // to rebuffer 80% of that whenever we encounter a buffer underrun. - - // Leave the net buffer properties at the default. - //FSOUND_Stream_Net_SetBufferProperties(20000, 40, 80); -} - - -LLStreamingAudio_FMODEX::~LLStreamingAudio_FMODEX() -{ - // FMOD fixes - //// nothing interesting/safe to do. - LL_INFOS() << "LLStreamingAudio_FMODEX::~LLStreamingAudio_FMODEX() destructing FMOD Ex Streaming" << LL_ENDL; - stop(); - for (U32 i = 0; i < 100; ++i) - { - if (releaseDeadStreams()) - break; - ms_sleep(10); - } - LL_INFOS() << "LLStreamingAudio_FMODEX::~LLStreamingAudio_FMODEX() finished" << LL_ENDL; - // -} - -void LLStreamingAudio_FMODEX::start(const std::string& url) -{ - //if (!mInited) - //{ - // LL_WARNS() << "startInternetStream before audio initialized" << LL_ENDL; - // return; - //} - - // "stop" stream but don't clear url, etc. in case url == mInternetStreamURL - stop(); - - if (!url.empty()) - { - // FMOD fixes - //LL_INFOS() << "Starting internet stream: " << url << LL_ENDL; - //mCurrentInternetStreamp = new LLAudioStreamManagerFMODEX(mSystem,url); - //mURL = url; - if(mDeadStreams.empty()) - { - LL_INFOS() << "Starting internet stream: " << url << LL_ENDL; - mCurrentInternetStreamp = new LLAudioStreamManagerFMODEX(mSystem,url); - mURL = url; - } - else - { - LL_INFOS() << "Deferring stream load until buffer release: " << url << LL_ENDL; - mPendingURL = url; - } - // - } - else - { - LL_INFOS() << "Set internet stream to null" << LL_ENDL; - mURL.clear(); - } -} - - -void LLStreamingAudio_FMODEX::update() -{ - // FMOD fixes - //// Kill dead internet streams, if possible - //std::list::iterator iter; - //for (iter = mDeadStreams.begin(); iter != mDeadStreams.end();) - //{ - // LLAudioStreamManagerFMODEX *streamp = *iter; - // if (streamp->stopStream()) - // { - // LL_INFOS() << "Closed dead stream" << LL_ENDL; - // delete streamp; - // mDeadStreams.erase(iter++); - // } - // else - // { - // iter++; - // } - //} - if (!releaseDeadStreams()) - { - llassert_always(mCurrentInternetStreamp == NULL); - return; - } - - if(!mPendingURL.empty()) - { - llassert_always(mCurrentInternetStreamp == NULL); - LL_INFOS() << "Starting internet stream: " << mPendingURL << LL_ENDL; - mCurrentInternetStreamp = new LLAudioStreamManagerFMODEX(mSystem,mPendingURL); - mURL = mPendingURL; - mPendingURL.clear(); - } - // - - // Don't do anything if there are no streams playing - if (!mCurrentInternetStreamp) - { - return; - } - - unsigned int progress; - bool starving; - bool diskbusy; - // FMOD fixes - //FMOD_OPENSTATE open_state = mCurrentInternetStreamp->getOpenState(&progress, &starving, &diskbusy); - - //if (open_state == FMOD_OPENSTATE_READY) - - FMOD_OPENSTATE open_state; - FMOD_RESULT result = mCurrentInternetStreamp->getOpenState(open_state, &progress, &starving, &diskbusy); - - if (result != FMOD_OK || open_state == FMOD_OPENSTATE_ERROR) - { - stop(); - return; - } - else if (open_state == FMOD_OPENSTATE_READY) - // - { - // Stream is live - - // start the stream if it's ready - if (!mFMODInternetStreamChannelp && - (mFMODInternetStreamChannelp = mCurrentInternetStreamp->startStream())) - { - // Reset volume to previously set volume - setGain(getGain()); - // FMOD fixes - //mFMODInternetStreamChannelp->setPaused(false); - Check_FMOD_Error(mFMODInternetStreamChannelp->setPaused(false), "FMOD::Channel::setPaused"); - // - } - } - // FMOD fixes - //else if(open_state == FMOD_OPENSTATE_ERROR) - //{ - // stop(); - // return; - //} - // - - if(mFMODInternetStreamChannelp) - { - FMOD::Sound *sound = NULL; - - // FmodEX Error checking - //if(mFMODInternetStreamChannelp->getCurrentSound(&sound) == FMOD_OK && sound) - if (!Check_FMOD_Error(mFMODInternetStreamChannelp->getCurrentSound(&sound), "FMOD::Channel::getCurrentSound") && sound) - // - { - FMOD_TAG tag; - S32 tagcount, dirtytagcount; - - // FmodEX Error checking - //if(sound->getNumTags(&tagcount, &dirtytagcount) == FMOD_OK && dirtytagcount) - if (!Check_FMOD_Error(sound->getNumTags(&tagcount, &dirtytagcount), "FMOD::Sound::getNumTags") && dirtytagcount) - // - { - // Stream metadata - originally by Shyotl Khur - LL_DEBUGS("StreamMetadata") << "Tag count: " << tagcount << " Dirty tag count: " << dirtytagcount << LL_ENDL; - - mMetadata.clear(); - mNewMetadata = true; - // - for(S32 i = 0; i < tagcount; ++i) - { - // FmodEX Error checking - //if(sound->getTag(NULL, i, &tag) != FMOD_OK) - if(Check_FMOD_Error(sound->getTag(NULL, i, &tag), "FMOD::Sound::getTag")) - // - continue; - - // Stream metadata - originally by Shyotl Khur - //if (tag.type == FMOD_TAGTYPE_FMOD) - //{ - // if (!strcmp(tag.name, "Sample Rate Change")) - // { - // LL_INFOS("FmodEX") << "Stream forced changing sample rate to " << *((float *)tag.data) << LL_ENDL; - // mFMODInternetStreamChannelp->setFrequency(*((float *)tag.data)); - // } - // continue; - //} - LL_DEBUGS("StreamMetadata") << "Tag name: " << tag.name << " - Tag type: " << tag.type << " - Tag data type: " << tag.datatype << LL_ENDL; - std::string name = tag.name; - switch(tag.type) - { - case(FMOD_TAGTYPE_ID3V2): - { - if(name == "TIT2") name = "TITLE"; - else if(name == "TPE1") name = "ARTIST"; - break; - } - case(FMOD_TAGTYPE_ASF): - { - if(name == "Title") name = "TITLE"; - else if(name == "WM/AlbumArtist") name = "ARTIST"; - break; - } - case(FMOD_TAGTYPE_VORBISCOMMENT): - { - if(name == "title") name = "TITLE"; - else if(name == "artist") name = "ARTIST"; - break; - } - case(FMOD_TAGTYPE_FMOD): - { - if (!strcmp(tag.name, "Sample Rate Change")) - { - LL_INFOS() << "Stream forced changing sample rate to " << *((float *)tag.data) << LL_ENDL; - mFMODInternetStreamChannelp->setFrequency(*((float *)tag.data)); - } - continue; - } - default: - break; - } - switch(tag.datatype) - { - case(FMOD_TAGDATATYPE_INT): - { - (mMetadata)[name]=*(LLSD::Integer*)(tag.data); - LL_DEBUGS("StreamMetadata") << tag.name << ": " << *(int*)(tag.data) << LL_ENDL; - break; - } - case(FMOD_TAGDATATYPE_FLOAT): - { - (mMetadata)[name]=*(LLSD::Real*)(tag.data); - LL_DEBUGS("StreamMetadata") << tag.name << ": " << *(float*)(tag.data) << LL_ENDL; - break; - } - case(FMOD_TAGDATATYPE_STRING): - { - std::string out = rawstr_to_utf8(std::string((char*)tag.data,tag.datalen)); - (mMetadata)[name]=out; - LL_DEBUGS("StreamMetadata") << tag.name << ": " << out << LL_ENDL; - break; - } - case(FMOD_TAGDATATYPE_STRING_UTF8): - { - std::string out((char*)tag.data); - (mMetadata)[name]=out; - LL_DEBUGS("StreamMetadata") << tag.name << ": " << out << LL_ENDL; - break; - } - case(FMOD_TAGDATATYPE_STRING_UTF16): - { - std::string out((char*)tag.data,tag.datalen); - (mMetadata)[std::string(tag.name)]=out; - LL_DEBUGS("StreamMetadata") << tag.name << ": " << out << LL_ENDL; - break; - } - case(FMOD_TAGDATATYPE_STRING_UTF16BE): - { - std::string out((char*)tag.data,tag.datalen); - //U16* buf = (U16*)out.c_str(); - //for(U32 j = 0; j < out.size()/2; ++j) - //(((buf[j] & 0xff)<<8) | ((buf[j] & 0xff00)>>8)); - (mMetadata)[std::string(tag.name)]=out; - LL_DEBUGS("StreamMetadata") << tag.name << ": " << out << LL_ENDL; - break; - } - default: - break; - } - // Stream metadata - originally by Shyotl Khur - } - } - - if(starving) - { - bool paused = false; - // FMOD fixes - //mFMODInternetStreamChannelp->getPaused(&paused); - //if(!paused) - if (mFMODInternetStreamChannelp->getPaused(&paused) == FMOD_OK && !paused) - // - { - LL_INFOS() << "Stream starvation detected! Pausing stream until buffer nearly full." << LL_ENDL; - LL_INFOS() << " (diskbusy="< FMOD fixes - //mFMODInternetStreamChannelp->setPaused(true); - Check_FMOD_Error(mFMODInternetStreamChannelp->setPaused(true), "FMOD::Channel::setPaused"); - // - } - } - else if(progress > 80) - { - // FMOD fixes - //mFMODInternetStreamChannelp->setPaused(false); - Check_FMOD_Error(mFMODInternetStreamChannelp->setPaused(false), "FMOD::Channel::setPaused"); - // - } - } - } -} - -void LLStreamingAudio_FMODEX::stop() -{ - // FMOD fixes - mPendingURL.clear(); - - if (mFMODInternetStreamChannelp) - { - // FMOD fixes - //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; - } - - if (mCurrentInternetStreamp) - { - LL_INFOS() << "Stopping internet stream: " << mCurrentInternetStreamp->getURL() << LL_ENDL; - if (mCurrentInternetStreamp->stopStream()) - { - delete mCurrentInternetStreamp; - } - else - { - LL_WARNS() << "Pushing stream to dead list: " << mCurrentInternetStreamp->getURL() << LL_ENDL; - mDeadStreams.push_back(mCurrentInternetStreamp); - } - mCurrentInternetStreamp = NULL; - //mURL.clear(); - } -} - -void LLStreamingAudio_FMODEX::pause(int pauseopt) -{ - if (pauseopt < 0) - { - pauseopt = mCurrentInternetStreamp ? 1 : 0; - } - - if (pauseopt) - { - if (mCurrentInternetStreamp) - { - stop(); - } - } - else - { - start(getURL()); - } -} - - -// A stream is "playing" if it has been requested to start. That -// doesn't necessarily mean audio is coming out of the speakers. -int LLStreamingAudio_FMODEX::isPlaying() -{ - if (mCurrentInternetStreamp) - { - return 1; // Active and playing - } - // FMOD fixes - //else if (!mURL.empty()) - else if (!mURL.empty() || !mPendingURL.empty()) - // - { - return 2; // "Paused" - } - else - { - return 0; - } -} - - -F32 LLStreamingAudio_FMODEX::getGain() -{ - return mGain; -} - - -std::string LLStreamingAudio_FMODEX::getURL() -{ - return mURL; -} - - -void LLStreamingAudio_FMODEX::setGain(F32 vol) -{ - mGain = vol; - - if (mFMODInternetStreamChannelp) - { - vol = llclamp(vol * vol, 0.f, 1.f); //should vol be squared here? - - // FMOD fixes - //mFMODInternetStreamChannelp->setVolume(vol); - Check_FMOD_Error(mFMODInternetStreamChannelp->setVolume(vol), "FMOD::Channel::setVolume"); - // - } -} - -// Streamtitle display -// virtual -bool LLStreamingAudio_FMODEX::getNewMetadata(LLSD& metadata) -{ - if (mCurrentInternetStreamp) - { - if (mNewMetadata) - { - metadata = mMetadata; - mNewMetadata = false; - return true; - } - - return mNewMetadata; - } - - metadata = LLSD(); - return false; -} -// - -/////////////////////////////////////////////////////// -// manager of possibly-multiple internet audio streams - -LLAudioStreamManagerFMODEX::LLAudioStreamManagerFMODEX(FMOD::System *system, const std::string& url) : - mSystem(system), - mStreamChannel(NULL), - mInternetStream(NULL), - mReady(false) -{ - mInternetStreamURL = url; - - FMOD_RESULT result = mSystem->createStream(url.c_str(), FMOD_2D | FMOD_NONBLOCKING | FMOD_IGNORETAGS, 0, &mInternetStream); - - if (result != FMOD_OK) - { - LL_WARNS() << "Couldn't open fmod stream, error " - << FMOD_ErrorString(result) - << LL_ENDL; - mReady = false; - return; - } - - mReady = true; -} - -FMOD::Channel *LLAudioStreamManagerFMODEX::startStream() -{ - // We need a live and opened stream before we try and play it. - // FMOD fixes - //if (!mInternetStream || getOpenState() != FMOD_OPENSTATE_READY) - FMOD_OPENSTATE open_state; - if (getOpenState(open_state) != FMOD_OK || open_state != FMOD_OPENSTATE_READY) - // - { - LL_WARNS() << "No internet stream to start playing!" << LL_ENDL; - return NULL; - } - - if(mStreamChannel) - return mStreamChannel; //Already have a channel for this stream. - - // FMOD fixes - //mSystem->playSound(FMOD_CHANNEL_FREE, mInternetStream, true, &mStreamChannel); - Check_FMOD_Error(mSystem->playSound(FMOD_CHANNEL_FREE, mInternetStream, true, &mStreamChannel), "FMOD::System::playSound"); - // - return mStreamChannel; -} - -bool LLAudioStreamManagerFMODEX::stopStream() -{ - if (mInternetStream) - { - bool close = true; - // FMOD fixes - //switch (getOpenState()) - FMOD_OPENSTATE open_state; - if (getOpenState(open_state) == FMOD_OK) - { - switch (open_state) - // - { - case FMOD_OPENSTATE_CONNECTING: - close = false; - break; - default: - close = true; - } - // FMOD fixes - } - // - - // FMOD fixes - //if (close) - //{ - // mInternetStream->release(); - if (close && mInternetStream->release() == FMOD_OK) - { - // - mStreamChannel = NULL; - mInternetStream = NULL; - return true; - } - else - { - return false; - } - } - else - { - return true; - } -} - -// FMOD fixes -//FMOD_OPENSTATE LLAudioStreamManagerFMODEX::getOpenState(unsigned int* percentbuffered, bool* starving, bool* diskbusy) -//{ -// FMOD_OPENSTATE state; -// mInternetStream->getOpenState(&state, percentbuffered, starving, diskbusy); -// return state; -//} -FMOD_RESULT LLAudioStreamManagerFMODEX::getOpenState(FMOD_OPENSTATE& state, unsigned int* percentbuffered, bool* starving, bool* diskbusy) -{ - 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) -{ - // FMOD fixes - //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 - // FMOD fixes - //mSystem->setAdvancedSettings(&settings); - Check_FMOD_Error(mSystem->setAdvancedSettings(&settings), "FMOD::System::setAdvancedSettings"); - // -} - -// FMOD fixes -bool LLStreamingAudio_FMODEX::releaseDeadStreams() -{ - // Kill dead internet streams, if possible - std::list::iterator iter; - for (iter = mDeadStreams.begin(); iter != mDeadStreams.end();) - { - LLAudioStreamManagerFMODEX *streamp = *iter; - if (streamp->stopStream()) - { - LL_INFOS() << "Closed dead stream" << LL_ENDL; - delete streamp; - mDeadStreams.erase(iter++); - } - else - { - iter++; - } - } - - return mDeadStreams.empty(); -} -// diff --git a/indra/llaudio/llstreamingaudio_fmodex.h b/indra/llaudio/llstreamingaudio_fmodex.h deleted file mode 100644 index b197151f86..0000000000 --- a/indra/llaudio/llstreamingaudio_fmodex.h +++ /dev/null @@ -1,87 +0,0 @@ -/** - * @file streamingaudio_fmodex.h - * @brief Definition of LLStreamingAudio_FMODEX implementation - * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_STREAMINGAUDIO_FMODEX_H -#define LL_STREAMINGAUDIO_FMODEX_H - -#include "stdtypes.h" // from llcommon - -#include "llstreamingaudio.h" -#include "lltimer.h" - -//Stubs -class LLAudioStreamManagerFMODEX; -namespace FMOD -{ - class System; - class Channel; -} - -//Interfaces -class LLStreamingAudio_FMODEX : public LLStreamingAudioInterface -{ - public: - LLStreamingAudio_FMODEX(FMOD::System *system); - /*virtual*/ ~LLStreamingAudio_FMODEX(); - - /*virtual*/ void start(const std::string& url); - /*virtual*/ void stop(); - /*virtual*/ void pause(S32 pause); - /*virtual*/ void update(); - /*virtual*/ S32 isPlaying(); - /*virtual*/ void setGain(F32 vol); - /*virtual*/ F32 getGain(); - /*virtual*/ std::string getURL(); - - /*virtual*/ bool supportsAdjustableBufferSizes(){return true;} - /*virtual*/ void setBufferSizes(U32 streambuffertime, U32 decodebuffertime); - - // Streamtitle display - virtual bool getNewMetadata(LLSD& metadata); - // - -private: - // FMOD fixes - bool releaseDeadStreams(); - - FMOD::System *mSystem; - - LLAudioStreamManagerFMODEX *mCurrentInternetStreamp; - FMOD::Channel *mFMODInternetStreamChannelp; - std::list mDeadStreams; - - std::string mURL; - std::string mPendingURL; // FMOD fixes - F32 mGain; - - // Streamtitle display - bool mNewMetadata; - LLSD mMetadata; - // Streamtitle display -}; - - -#endif // LL_STREAMINGAUDIO_FMODEX_H diff --git a/indra/llaudio/llstreamingaudio_fmodstudio.cpp b/indra/llaudio/llstreamingaudio_fmodstudio.cpp index edf63c90c6..5fef19d6d2 100644 --- a/indra/llaudio/llstreamingaudio_fmodstudio.cpp +++ b/indra/llaudio/llstreamingaudio_fmodstudio.cpp @@ -2,9 +2,9 @@ * @file streamingaudio_fmodstudio.cpp * @brief LLStreamingAudio_FMODSTUDIO implementation * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * $LicenseInfo:firstyear=2020&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2020, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,38 +28,38 @@ #include "llmath.h" -#include "fmod.hpp" -#include "fmod_errors.h" +#include "fmodstudio/fmod.hpp" +#include "fmodstudio/fmod_errors.h" #include "llstreamingaudio_fmodstudio.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; + if (result == FMOD_OK) + return false; + LL_WARNS("AudioImpl") << string << " Error: " << FMOD_ErrorString(result) << LL_ENDL; + return true; } class LLAudioStreamManagerFMODSTUDIO { public: - LLAudioStreamManagerFMODSTUDIO(FMOD::System *system, FMOD::ChannelGroup *group, const std::string& url); - FMOD::Channel* startStream(); - bool stopStream(); // Returns true if the stream was successfully stopped. - bool ready(); + LLAudioStreamManagerFMODSTUDIO(FMOD::System *system, FMOD::ChannelGroup *group, const std::string& url); + FMOD::Channel* startStream(); + bool stopStream(); // Returns true if the stream was successfully stopped. + bool ready(); - const std::string& getURL() { return mInternetStreamURL; } + const std::string& getURL() { return mInternetStreamURL; } - FMOD_RESULT getOpenState(FMOD_OPENSTATE& openstate, 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::ChannelGroup* mChannelGroup; - FMOD::Channel* mStreamChannel; - FMOD::Sound* mInternetStream; - bool mReady; + FMOD::System* mSystem; + FMOD::ChannelGroup* mChannelGroup; + FMOD::Channel* mStreamChannel; + FMOD::Sound* mInternetStream; + bool mReady; - std::string mInternetStreamURL; + std::string mInternetStreamURL; }; @@ -68,290 +68,285 @@ protected: // Internet Streaming //--------------------------------------------------------------------------- LLStreamingAudio_FMODSTUDIO::LLStreamingAudio_FMODSTUDIO(FMOD::System *system) : - mSystem(system), - mCurrentInternetStreamp(NULL), - mStreamGroup(NULL), - mFMODInternetStreamChannelp(NULL), - mGain(1.0f) +mSystem(system), +mCurrentInternetStreamp(NULL), +mStreamGroup(NULL), +mFMODInternetStreamChannelp(NULL), +mGain(1.0f) { - 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 + Check_FMOD_Error(mSystem->setStreamBufferSize(estimated_bitrate * buffer_seconds * 128/*bytes/kbit*/, FMOD_TIMEUNIT_RAWBYTES), "FMOD::System::setStreamBufferSize"); - // 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 - result = mSystem->setStreamBufferSize(estimated_bitrate * buffer_seconds * 128/*bytes/kbit*/, FMOD_TIMEUNIT_RAWBYTES); - Check_FMOD_Error(result, "FMOD::System::setStreamBufferSize"); - - Check_FMOD_Error(system->createChannelGroup("stream", &mStreamGroup), "FMOD::System::createChannelGroup"); + Check_FMOD_Error(system->createChannelGroup("stream", &mStreamGroup), "FMOD::System::createChannelGroup"); } LLStreamingAudio_FMODSTUDIO::~LLStreamingAudio_FMODSTUDIO() { - stop(); - for (U32 i = 0; i < 100; ++i) - { - if (releaseDeadStreams()) - break; - ms_sleep(10); - } - + stop(); + for (U32 i = 0; i < 100; ++i) + { + if (releaseDeadStreams()) + break; + ms_sleep(10); + } } void LLStreamingAudio_FMODSTUDIO::start(const std::string& url) { - //if (!mInited) - //{ - // LL_WARNS() << "startInternetStream before audio initialized" << LL_ENDL; - // return; - //} + //if (!mInited) + //{ + // LL_WARNS() << "startInternetStream before audio initialized" << LL_ENDL; + // return; + //} - // "stop" stream but don't clear url, etc. in case url == mInternetStreamURL - stop(); + // "stop" stream but don't clear url, etc. in case url == mInternetStreamURL + stop(); - if (!url.empty()) - { - if(mDeadStreams.empty()) - { - LL_INFOS() << "Starting internet stream: " << url << LL_ENDL; - mCurrentInternetStreamp = new LLAudioStreamManagerFMODSTUDIO(mSystem, mStreamGroup, url); - mURL = url; - } - else - { - LL_INFOS() << "Deferring stream load until buffer release: " << url << LL_ENDL; - mPendingURL = url; - } - } - else - { - LL_INFOS() << "Set internet stream to null" << LL_ENDL; - mURL.clear(); - } + if (!url.empty()) + { + if (mDeadStreams.empty()) + { + LL_INFOS() << "Starting internet stream: " << url << LL_ENDL; + mCurrentInternetStreamp = new LLAudioStreamManagerFMODSTUDIO(mSystem, mStreamGroup, url); + mURL = url; + } + else + { + LL_INFOS() << "Deferring stream load until buffer release: " << url << LL_ENDL; + mPendingURL = url; + } + } + else + { + LL_INFOS() << "Set internet stream to null" << LL_ENDL; + mURL.clear(); + } } void LLStreamingAudio_FMODSTUDIO::update() { - if (!releaseDeadStreams()) - { - llassert_always(mCurrentInternetStreamp == NULL); - return; - } + if (!releaseDeadStreams()) + { + llassert_always(mCurrentInternetStreamp == NULL); + return; + } - if(!mPendingURL.empty()) - { - llassert_always(mCurrentInternetStreamp == NULL); - LL_INFOS() << "Starting internet stream: " << mPendingURL << LL_ENDL; - mCurrentInternetStreamp = new LLAudioStreamManagerFMODSTUDIO(mSystem, mStreamGroup, mPendingURL); - mURL = mPendingURL; - mPendingURL.clear(); - } + if (!mPendingURL.empty()) + { + llassert_always(mCurrentInternetStreamp == NULL); + LL_INFOS() << "Starting internet stream: " << mPendingURL << LL_ENDL; + mCurrentInternetStreamp = new LLAudioStreamManagerFMODSTUDIO(mSystem, mStreamGroup, mPendingURL); + mURL = mPendingURL; + mPendingURL.clear(); + } - // Don't do anything if there are no streams playing - if (!mCurrentInternetStreamp) - { - return; - } + // Don't do anything if there are no streams playing + if (!mCurrentInternetStreamp) + { + return; + } - unsigned int progress; - bool starving; - bool diskbusy; - FMOD_OPENSTATE open_state; - FMOD_RESULT result = mCurrentInternetStreamp->getOpenState(open_state, &progress, &starving, &diskbusy); + unsigned int progress; + bool starving; + bool diskbusy; + FMOD_OPENSTATE open_state; - if (result != FMOD_OK || open_state == FMOD_OPENSTATE_ERROR) - { - stop(); - return; - } - else if (open_state == FMOD_OPENSTATE_READY) - { - // Stream is live + if (Check_FMOD_Error(mCurrentInternetStreamp->getOpenState(open_state, &progress, &starving, &diskbusy), "FMOD::Sound::getOpenState") || open_state == FMOD_OPENSTATE_ERROR) + { + stop(); + return; + } + else if (open_state == FMOD_OPENSTATE_READY) + { + // Stream is live - // start the stream if it's ready - if (!mFMODInternetStreamChannelp && - (mFMODInternetStreamChannelp = mCurrentInternetStreamp->startStream())) - { - // Reset volume to previously set volume - setGain(getGain()); - Check_FMOD_Error(mFMODInternetStreamChannelp->setPaused(false), "FMOD::Channel::setPaused"); - } - } + // start the stream if it's ready + if (!mFMODInternetStreamChannelp && + (mFMODInternetStreamChannelp = mCurrentInternetStreamp->startStream())) + { + // Reset volume to previously set volume + setGain(getGain()); + Check_FMOD_Error(mFMODInternetStreamChannelp->setPaused(false), "FMOD::Channel::setPaused"); + } + } - if(mFMODInternetStreamChannelp) - { - FMOD::Sound *sound = NULL; + if (mFMODInternetStreamChannelp) + { + FMOD::Sound *sound = NULL; - if (!Check_FMOD_Error(mFMODInternetStreamChannelp->getCurrentSound(&sound), "FMOD::Channel::getCurrentSound") && sound) - { - FMOD_TAG tag; - S32 tagcount, dirtytagcount; + if (!Check_FMOD_Error(mFMODInternetStreamChannelp->getCurrentSound(&sound), "FMOD::Channel::getCurrentSound") && sound) + { + FMOD_TAG tag; + S32 tagcount, dirtytagcount; - if (!Check_FMOD_Error(sound->getNumTags(&tagcount, &dirtytagcount), "FMOD::Sound::getNumTags") && dirtytagcount) - { - LL_DEBUGS("StreamMetadata") << "Tag count: " << tagcount << " Dirty tag count: " << dirtytagcount << LL_ENDL; + if (!Check_FMOD_Error(sound->getNumTags(&tagcount, &dirtytagcount), "FMOD::Sound::getNumTags") && dirtytagcount) + { + LL_DEBUGS("StreamMetadata") << "Tag count: " << tagcount << " Dirty tag count: " << dirtytagcount << LL_ENDL; - // Stream metadata - originally by Shyotl Khur - mMetadata.clear(); - mNewMetadata = true; - // - for(S32 i = 0; i < tagcount; ++i) - { - if(Check_FMOD_Error(sound->getTag(NULL, i, &tag), "FMOD::Sound::getTag")) - continue; + // Stream metadata - originally by Shyotl Khur + mMetadata.clear(); + mNewMetadata = true; + // + for (S32 i = 0; i < tagcount; ++i) + { + if (Check_FMOD_Error(sound->getTag(NULL, i, &tag), "FMOD::Sound::getTag")) + continue; - LL_DEBUGS("StreamMetadata") << "Tag name: " << tag.name << " - Tag type: " << tag.type << " - Tag data type: " << tag.datatype << LL_ENDL; + LL_DEBUGS("StreamMetadata") << "Tag name: " << tag.name << " - Tag type: " << tag.type << " - Tag data type: " << tag.datatype << LL_ENDL; - std::string name = tag.name; - switch(tag.type) - { - case(FMOD_TAGTYPE_ID3V2): - { - if(name == "TIT2") name = "TITLE"; - else if(name == "TPE1") name = "ARTIST"; - break; - } - case(FMOD_TAGTYPE_ASF): - { - if(name == "Title") name = "TITLE"; - else if(name == "WM/AlbumArtist") name = "ARTIST"; - break; - } - case(FMOD_TAGTYPE_VORBISCOMMENT): - { - if(name == "title") name = "TITLE"; - else if(name == "artist") name = "ARTIST"; - break; - } - case(FMOD_TAGTYPE_FMOD): - { - if (!strcmp(tag.name, "Sample Rate Change")) - { - LL_INFOS() << "Stream forced changing sample rate to " << *((float *)tag.data) << LL_ENDL; - mFMODInternetStreamChannelp->setFrequency(*((float *)tag.data)); - } - continue; - } - default: - break; - } - switch(tag.datatype) - { - case(FMOD_TAGDATATYPE_INT): - { - (mMetadata)[name]=*(LLSD::Integer*)(tag.data); - LL_DEBUGS("StreamMetadata") << tag.name << ": " << *(int*)(tag.data) << LL_ENDL; - break; - } - case(FMOD_TAGDATATYPE_FLOAT): - { - (mMetadata)[name]=*(LLSD::Real*)(tag.data); - LL_DEBUGS("StreamMetadata") << tag.name << ": " << *(float*)(tag.data) << LL_ENDL; - break; - } - case(FMOD_TAGDATATYPE_STRING): - { - std::string out = rawstr_to_utf8(std::string((char*)tag.data,tag.datalen)); - (mMetadata)[name]=out; - LL_DEBUGS("StreamMetadata") << tag.name << ": " << out << LL_ENDL; - break; - } - case(FMOD_TAGDATATYPE_STRING_UTF8): - { - std::string out((char*)tag.data); - (mMetadata)[name]=out; - LL_DEBUGS("StreamMetadata") << tag.name << ": " << out << LL_ENDL; - break; - } - case(FMOD_TAGDATATYPE_STRING_UTF16): - { - std::string out((char*)tag.data,tag.datalen); - (mMetadata)[std::string(tag.name)]=out; - LL_DEBUGS("StreamMetadata") << tag.name << ": " << out << LL_ENDL; - break; - } - case(FMOD_TAGDATATYPE_STRING_UTF16BE): - { - std::string out((char*)tag.data,tag.datalen); - //U16* buf = (U16*)out.c_str(); - //for(U32 j = 0; j < out.size()/2; ++j) - //(((buf[j] & 0xff)<<8) | ((buf[j] & 0xff00)>>8)); - (mMetadata)[std::string(tag.name)]=out; - LL_DEBUGS("StreamMetadata") << tag.name << ": " << out << LL_ENDL; - break; - } - default: - break; - } - } - } + std::string name = tag.name; + switch (tag.type) + { + case FMOD_TAGTYPE_ID3V2: + { + if (name == "TIT2") name = "TITLE"; + else if (name == "TPE1") name = "ARTIST"; + break; + } + case FMOD_TAGTYPE_ASF: + { + if (name == "Title") name = "TITLE"; + else if (name == "WM/AlbumArtist") name = "ARTIST"; + break; + } + case FMOD_TAGTYPE_VORBISCOMMENT: + { + if (name == "title") name = "TITLE"; + else if (name == "artist") name = "ARTIST"; + break; + } + case FMOD_TAGTYPE_FMOD: + { + if (!strcmp(tag.name, "Sample Rate Change")) + { + LL_INFOS() << "Stream forced changing sample rate to " << *((float *)tag.data) << LL_ENDL; + mFMODInternetStreamChannelp->setFrequency(*((float *)tag.data)); + } + continue; + } + default: + break; + } + switch (tag.datatype) + { + case FMOD_TAGDATATYPE_INT: + { + (mMetadata)[name]=*(LLSD::Integer*)(tag.data); + LL_DEBUGS("StreamMetadata") << tag.name << ": " << *(int*)(tag.data) << LL_ENDL; + break; + } + case FMOD_TAGDATATYPE_FLOAT: + { + (mMetadata)[name]=*(LLSD::Real*)(tag.data); + LL_DEBUGS("StreamMetadata") << tag.name << ": " << *(float*)(tag.data) << LL_ENDL; + break; + } + case FMOD_TAGDATATYPE_STRING: + { + std::string out = rawstr_to_utf8(std::string((char*)tag.data,tag.datalen)); + (mMetadata)[name]=out; + LL_DEBUGS("StreamMetadata") << tag.name << ": " << out << LL_ENDL; + break; + } + case FMOD_TAGDATATYPE_STRING_UTF8: + { + std::string out((char*)tag.data); + (mMetadata)[name]=out; + LL_DEBUGS("StreamMetadata") << tag.name << ": " << out << LL_ENDL; + break; + } + case FMOD_TAGDATATYPE_STRING_UTF16: + { + std::string out((char*)tag.data,tag.datalen); + (mMetadata)[std::string(tag.name)]=out; + LL_DEBUGS("StreamMetadata") << tag.name << ": " << out << LL_ENDL; + break; + } + case FMOD_TAGDATATYPE_STRING_UTF16BE: + { + std::string out((char*)tag.data,tag.datalen); + //U16* buf = (U16*)out.c_str(); + //for(U32 j = 0; j < out.size()/2; ++j) + //(((buf[j] & 0xff)<<8) | ((buf[j] & 0xff00)>>8)); + (mMetadata)[std::string(tag.name)]=out; + LL_DEBUGS("StreamMetadata") << tag.name << ": " << out << LL_ENDL; + break; + } + default: + break; + } + } + } - if(starving) - { - bool paused = false; - if (mFMODInternetStreamChannelp->getPaused(&paused) == FMOD_OK && !paused) - { - LL_INFOS() << "Stream starvation detected! Pausing stream until buffer nearly full." << LL_ENDL; - LL_INFOS() << " (diskbusy="<setPaused(true), "FMOD::Channel::setPaused"); - } - } - else if(progress > 80) - { - Check_FMOD_Error(mFMODInternetStreamChannelp->setPaused(false), "FMOD::Channel::setPaused"); - } - } - } + if (starving) + { + bool paused = false; + if (!Check_FMOD_Error(mFMODInternetStreamChannelp->getPaused(&paused), "FMOD:Channel::getPaused") && !paused) + { + LL_INFOS() << "Stream starvation detected! Pausing stream until buffer nearly full." << LL_ENDL; + LL_INFOS() << " (diskbusy=" << diskbusy << ")" << LL_ENDL; + LL_INFOS() << " (progress=" << progress << ")" << LL_ENDL; + Check_FMOD_Error(mFMODInternetStreamChannelp->setPaused(true), "FMOD::Channel::setPaused"); + } + } + else if (progress > 80) + { + Check_FMOD_Error(mFMODInternetStreamChannelp->setPaused(false), "FMOD::Channel::setPaused"); + } + } + } } void LLStreamingAudio_FMODSTUDIO::stop() { - mPendingURL.clear(); + mPendingURL.clear(); - if (mFMODInternetStreamChannelp) - { - Check_FMOD_Error(mFMODInternetStreamChannelp->setPaused(true), "FMOD::Channel::setPaused"); - Check_FMOD_Error(mFMODInternetStreamChannelp->setPriority(0), "FMOD::Channel::setPriority"); - mFMODInternetStreamChannelp = NULL; - } + if (mFMODInternetStreamChannelp) + { + Check_FMOD_Error(mFMODInternetStreamChannelp->setPaused(true), "FMOD::Channel::setPaused"); + Check_FMOD_Error(mFMODInternetStreamChannelp->setPriority(0), "FMOD::Channel::setPriority"); + mFMODInternetStreamChannelp = NULL; + } - if (mCurrentInternetStreamp) - { - LL_INFOS() << "Stopping internet stream: " << mCurrentInternetStreamp->getURL() << LL_ENDL; - if (mCurrentInternetStreamp->stopStream()) - { - delete mCurrentInternetStreamp; - } - else - { - LL_WARNS() << "Pushing stream to dead list: " << mCurrentInternetStreamp->getURL() << LL_ENDL; - mDeadStreams.push_back(mCurrentInternetStreamp); - } - mCurrentInternetStreamp = NULL; - } + if (mCurrentInternetStreamp) + { + LL_INFOS() << "Stopping internet stream: " << mCurrentInternetStreamp->getURL() << LL_ENDL; + if (mCurrentInternetStreamp->stopStream()) + { + delete mCurrentInternetStreamp; + } + else + { + LL_WARNS() << "Pushing stream to dead list: " << mCurrentInternetStreamp->getURL() << LL_ENDL; + mDeadStreams.push_back(mCurrentInternetStreamp); + } + mCurrentInternetStreamp = NULL; + } } void LLStreamingAudio_FMODSTUDIO::pause(int pauseopt) { - if (pauseopt < 0) - { - pauseopt = mCurrentInternetStreamp ? 1 : 0; - } + if (pauseopt < 0) + { + pauseopt = mCurrentInternetStreamp ? 1 : 0; + } - if (pauseopt) - { - if (mCurrentInternetStreamp) - { - stop(); - } - } - else - { - start(getURL()); - } + if (pauseopt) + { + if (mCurrentInternetStreamp) + { + stop(); + } + } + else + { + start(getURL()); + } } @@ -359,179 +354,179 @@ void LLStreamingAudio_FMODSTUDIO::pause(int pauseopt) // doesn't necessarily mean audio is coming out of the speakers. int LLStreamingAudio_FMODSTUDIO::isPlaying() { - if (mCurrentInternetStreamp) - { - return 1; // Active and playing - } - else if (!mURL.empty() || !mPendingURL.empty()) - { - return 2; // "Paused" - } - else - { - return 0; - } + if (mCurrentInternetStreamp) + { + return 1; // Active and playing + } + else if (!mURL.empty() || !mPendingURL.empty()) + { + return 2; // "Paused" + } + else + { + return 0; + } } F32 LLStreamingAudio_FMODSTUDIO::getGain() { - return mGain; + return mGain; } std::string LLStreamingAudio_FMODSTUDIO::getURL() { - return mURL; + return mURL; } void LLStreamingAudio_FMODSTUDIO::setGain(F32 vol) { - mGain = vol; + mGain = vol; - if (mFMODInternetStreamChannelp) - { - vol = llclamp(vol * vol, 0.f, 1.f); //should vol be squared here? + if (mFMODInternetStreamChannelp) + { + vol = llclamp(vol * vol, 0.f, 1.f); //should vol be squared here? - Check_FMOD_Error(mFMODInternetStreamChannelp->setVolume(vol), "FMOD::Channel::setVolume"); - } + Check_FMOD_Error(mFMODInternetStreamChannelp->setVolume(vol), "FMOD::Channel::setVolume"); + } } // Streamtitle display // virtual bool LLStreamingAudio_FMODSTUDIO::getNewMetadata(LLSD& metadata) { - if (mCurrentInternetStreamp) - { - if (mNewMetadata) - { - metadata = mMetadata; - mNewMetadata = false; - return true; - } - - return mNewMetadata; - } + if (mCurrentInternetStreamp) + { + if (mNewMetadata) + { + metadata = mMetadata; + mNewMetadata = false; + return true; + } + + return mNewMetadata; + } - metadata = LLSD(); - return false; + metadata = LLSD(); + return false; } // /////////////////////////////////////////////////////// // manager of possibly-multiple internet audio streams LLAudioStreamManagerFMODSTUDIO::LLAudioStreamManagerFMODSTUDIO(FMOD::System *system, FMOD::ChannelGroup *group, const std::string& url) : - mSystem(system), - mChannelGroup(group), - mStreamChannel(NULL), - mInternetStream(NULL), - mReady(false) +mSystem(system), +mChannelGroup(group), +mStreamChannel(NULL), +mInternetStream(NULL), +mReady(false) { - mInternetStreamURL = url; + mInternetStreamURL = url; - FMOD_RESULT result = mSystem->createStream(url.c_str(), FMOD_2D | FMOD_NONBLOCKING | FMOD_IGNORETAGS, 0, &mInternetStream); + FMOD_RESULT result = mSystem->createStream(url.c_str(), FMOD_2D | FMOD_NONBLOCKING | FMOD_IGNORETAGS, 0, &mInternetStream); - if (result!= FMOD_OK) - { - LL_WARNS() << "Couldn't open fmod stream, error " - << FMOD_ErrorString(result) - << LL_ENDL; - mReady = false; - return; - } + if (result != FMOD_OK) + { + LL_WARNS() << "Couldn't open fmod stream, error " + << FMOD_ErrorString(result) + << LL_ENDL; + mReady = false; + return; + } - mReady = true; + mReady = true; } FMOD::Channel *LLAudioStreamManagerFMODSTUDIO::startStream() { - // We need a live and opened stream before we try and play it. - FMOD_OPENSTATE open_state; - if (getOpenState(open_state) != FMOD_OK || open_state != FMOD_OPENSTATE_READY) - { - LL_WARNS() << "No internet stream to start playing!" << LL_ENDL; - return NULL; - } + // We need a live and opened stream before we try and play it. + FMOD_OPENSTATE open_state; + if (!mInternetStream || Check_FMOD_Error(getOpenState(open_state), "FMOD::Sound::getOpenState") || open_state != FMOD_OPENSTATE_READY) + { + LL_WARNS() << "No internet stream to start playing!" << LL_ENDL; + return NULL; + } - if(mStreamChannel) - return mStreamChannel; //Already have a channel for this stream. + if (mStreamChannel) + return mStreamChannel; //Already have a channel for this stream. - Check_FMOD_Error(mSystem->playSound(mInternetStream, mChannelGroup, true, &mStreamChannel), "FMOD::System::playSound"); - return mStreamChannel; + Check_FMOD_Error(mSystem->playSound(mInternetStream, mChannelGroup, true, &mStreamChannel), "FMOD::System::playSound"); + return mStreamChannel; } bool LLAudioStreamManagerFMODSTUDIO::stopStream() { - if (mInternetStream) - { - bool close = true; - FMOD_OPENSTATE open_state; - if (getOpenState(open_state) == FMOD_OK) - { - switch (open_state) - { - case FMOD_OPENSTATE_CONNECTING: - close = false; - break; - default: - close = true; - } - } + if (mInternetStream) + { + bool close = true; + FMOD_OPENSTATE open_state; + if (!Check_FMOD_Error(getOpenState(open_state), "FMOD::Sound::getOpenState")) + { + switch (open_state) + { + case FMOD_OPENSTATE_CONNECTING: + close = false; + break; + default: + close = true; + } + } - if (close && mInternetStream->release() == FMOD_OK) - { - mStreamChannel = NULL; - mInternetStream = NULL; - return true; - } - else - { - return false; - } - } - else - { - return true; - } + if (close && !Check_FMOD_Error(mInternetStream->release(), "FMOD::Sound::release")) + { + mStreamChannel = NULL; + mInternetStream = NULL; + return true; + } + else + { + return false; + } + } + else + { + return true; + } } FMOD_RESULT LLAudioStreamManagerFMODSTUDIO::getOpenState(FMOD_OPENSTATE& state, unsigned int* percentbuffered, bool* starving, bool* diskbusy) { - 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; + 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) { - 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 - Check_FMOD_Error(mSystem->setAdvancedSettings(&settings), "FMOD::System::setAdvancedSettings"); + 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 + Check_FMOD_Error(mSystem->setAdvancedSettings(&settings), "FMOD::System::setAdvancedSettings"); } bool LLStreamingAudio_FMODSTUDIO::releaseDeadStreams() { - // Kill dead internet streams, if possible - std::list::iterator iter; - for (iter = mDeadStreams.begin(); iter != mDeadStreams.end();) - { - LLAudioStreamManagerFMODSTUDIO *streamp = *iter; - if (streamp->stopStream()) - { - LL_INFOS() << "Closed dead stream" << LL_ENDL; - delete streamp; - mDeadStreams.erase(iter++); - } - else - { - iter++; - } - } + // Kill dead internet streams, if possible + std::list::iterator iter; + for (iter = mDeadStreams.begin(); iter != mDeadStreams.end();) + { + LLAudioStreamManagerFMODSTUDIO *streamp = *iter; + if (streamp->stopStream()) + { + LL_INFOS() << "Closed dead stream" << LL_ENDL; + delete streamp; + mDeadStreams.erase(iter++); + } + else + { + iter++; + } + } - return mDeadStreams.empty(); + return mDeadStreams.empty(); } diff --git a/indra/llaudio/llstreamingaudio_fmodstudio.h b/indra/llaudio/llstreamingaudio_fmodstudio.h index d220ddd02c..7ec5a0dbf4 100644 --- a/indra/llaudio/llstreamingaudio_fmodstudio.h +++ b/indra/llaudio/llstreamingaudio_fmodstudio.h @@ -2,9 +2,9 @@ * @file streamingaudio_fmodstudio.h * @brief Definition of LLStreamingAudio_FMODSTUDIO implementation * - * $LicenseInfo:firstyear=2002&license=viewerlgpl$ + * $LicenseInfo:firstyear=2020&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2020, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -45,41 +45,41 @@ namespace FMOD //Interfaces class LLStreamingAudio_FMODSTUDIO : public LLStreamingAudioInterface { - public: - LLStreamingAudio_FMODSTUDIO(FMOD::System *system); - /*virtual*/ ~LLStreamingAudio_FMODSTUDIO(); +public: + LLStreamingAudio_FMODSTUDIO(FMOD::System *system); + /*virtual*/ ~LLStreamingAudio_FMODSTUDIO(); - /*virtual*/ void start(const std::string& url); - /*virtual*/ void stop(); - /*virtual*/ void pause(S32 pause); - /*virtual*/ void update(); - /*virtual*/ S32 isPlaying(); - /*virtual*/ void setGain(F32 vol); - /*virtual*/ F32 getGain(); - /*virtual*/ std::string getURL(); + /*virtual*/ void start(const std::string& url); + /*virtual*/ void stop(); + /*virtual*/ void pause(S32 pause); + /*virtual*/ void update(); + /*virtual*/ S32 isPlaying(); + /*virtual*/ void setGain(F32 vol); + /*virtual*/ F32 getGain(); + /*virtual*/ std::string getURL(); - /*virtual*/ bool supportsAdjustableBufferSizes(){return true;} - /*virtual*/ void setBufferSizes(U32 streambuffertime, U32 decodebuffertime); - //Streamtitle display DKO - virtual bool getNewMetadata(LLSD& metadata); - // DKO + /*virtual*/ bool supportsAdjustableBufferSizes(){return true;} + /*virtual*/ void setBufferSizes(U32 streambuffertime, U32 decodebuffertime); + //Streamtitle display DKO + virtual bool getNewMetadata(LLSD& metadata); + // DKO private: - bool releaseDeadStreams(); + bool releaseDeadStreams(); - FMOD::System *mSystem; + FMOD::System *mSystem; - LLAudioStreamManagerFMODSTUDIO *mCurrentInternetStreamp; - FMOD::ChannelGroup* mStreamGroup; - FMOD::Channel *mFMODInternetStreamChannelp; - std::list mDeadStreams; + LLAudioStreamManagerFMODSTUDIO *mCurrentInternetStreamp; + FMOD::ChannelGroup* mStreamGroup; + FMOD::Channel *mFMODInternetStreamChannelp; + std::list mDeadStreams; - std::string mURL; - std::string mPendingURL; - F32 mGain; - // Streamtitle display - bool mNewMetadata; - LLSD mMetadata; - // Streamtitle display + std::string mURL; + std::string mPendingURL; + F32 mGain; + // Streamtitle display + bool mNewMetadata; + LLSD mMetadata; + // Streamtitle display }; diff --git a/indra/llui/llspellcheck.cpp b/indra/llui/llspellcheck.cpp index 990e651853..63a86fc0b2 100644 --- a/indra/llui/llspellcheck.cpp +++ b/indra/llui/llspellcheck.cpp @@ -50,7 +50,7 @@ LLSpellChecker::LLSpellChecker() : mHunspell(NULL) { // Load initial dictionary information - refreshDictionaryMap(); + //refreshDictionaryMap(); // FIRE-29649: Crash when opening spellcheck settings } LLSpellChecker::~LLSpellChecker() @@ -58,6 +58,14 @@ LLSpellChecker::~LLSpellChecker() delete mHunspell; } +// FIRE-29649: Crash when opening spellcheck settings +void LLSpellChecker::initSingleton() +{ + // Load initial dictionary information + refreshDictionaryMap(); +} +// + bool LLSpellChecker::checkSpelling(const std::string& word) const { if ( (!mHunspell) || (word.length() < 3) || (0 != mHunspell->spell(word.c_str())) ) diff --git a/indra/llui/llspellcheck.h b/indra/llui/llspellcheck.h index f1964cc091..36628780a3 100644 --- a/indra/llui/llspellcheck.h +++ b/indra/llui/llspellcheck.h @@ -47,6 +47,7 @@ public: protected: void addToDictFile(const std::string& dict_path, const std::string& word); void initHunspell(const std::string& dict_language); + void initSingleton(); // FIRE-29649: Crash when opening spellcheck settings public: typedef std::list dict_list_t; diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index b919b4f39d..6cf0b18913 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -19,7 +19,6 @@ include(DirectX) include(DragDrop) include(EXPAT) include(FMODSTUDIO) -include(FMODEX) include(GLOD) include(Hunspell) include(JsonCpp) @@ -79,10 +78,6 @@ if(FMODSTUDIO) include_directories(${FMODSTUDIO_INCLUDE_DIR}) endif(FMODSTUDIO) -if(FMODEX) - include_directories(${FMODEX_INCLUDE_DIR}) -endif(FMODEX) - include_directories( ${DBUSGLIB_INCLUDE_DIRS} ${JSONCPP_INCLUDE_DIR} @@ -2128,15 +2123,11 @@ if (FMODSTUDIO) set(FMODWRAPPER_LIBRARY ${FMODSTUDIO_LIBRARY}) endif (FMODSTUDIO) -if (FMODEX) - set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_FMODEX") - set(FMODWRAPPER_LIBRARY ${FMODEX_LIBRARY}) -endif (FMODEX) - # Output device selection # set_source_files_properties(llstartup.cpp PROPERTIES COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS}") -set_source_files_properties(llstartup.cpp llfloaterpreference.cpp llfloaterabout.cpp PROPERTIES COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS}") +set_source_files_properties(llstartup.cpp llfloaterpreference.cpp PROPERTIES COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS}") # +set_source_files_properties(llprogressview.cpp PROPERTIES COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS}") list(APPEND viewer_SOURCE_FILES ${viewer_HEADER_FILES}) @@ -2174,12 +2165,6 @@ else (OPENSIM) set(ND_VIEWER_FLAVOR "hvk") endif (OPENSIM) -if (FMODSTUDIO) - set(FMODVERSION "fmodstudio") -elseif (FMODEX) - set(FMODVERSION "fmodex") -endif (FMODSTUDIO) - if (WINDOWS) set_target_properties(${VIEWER_BINARY_NAME} PROPERTIES @@ -2264,19 +2249,11 @@ if (WINDOWS) if (FMODSTUDIO) list(APPEND COPY_INPUT_DEPENDENCIES - ${SHARED_LIB_STAGING_DIR}/Release/fmod.dll - ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/fmod.dll - ${SHARED_LIB_STAGING_DIR}/Debug/fmodL.dll - ) - endif (FMODSTUDIO) - - if (FMODEX) - list(APPEND COPY_INPUT_DEPENDENCIES - ${SHARED_LIB_STAGING_DIR}/Release/fmodex.dll - ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/fmodex.dll - ${SHARED_LIB_STAGING_DIR}/Debug/fmodexL.dll + ${SHARED_LIB_STAGING_DIR}/Release/fmod.dll + ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/fmod.dll + ${SHARED_LIB_STAGING_DIR}/Debug/fmodL.dll ) - endif (FMODEX) + endif (FMODSTUDIO) if (OPENAL) list(APPEND COPY_INPUT_DEPENDENCIES @@ -2294,6 +2271,7 @@ if (WINDOWS) --arch=${ARCH} --artwork=${ARTWORK_DIR} "--bugsplat=${BUGSPLAT_DB}" + "--fmodstudio=${FMODSTUDIO}" --build=${CMAKE_CURRENT_BINARY_DIR} --buildtype=${CMAKE_BUILD_TYPE} "--channel=${VIEWER_CHANNEL}" @@ -2304,7 +2282,6 @@ if (WINDOWS) --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/copy_touched.bat --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt --viewer_flavor=${ND_VIEWER_FLAVOR} - --fmodversion=${FMODVERSION} --openal=${OPENAL} DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py @@ -2358,6 +2335,7 @@ if (WINDOWS) --arch=${ARCH} --artwork=${ARTWORK_DIR} "--bugsplat=${BUGSPLAT_DB}" + "--fmodstudio=${FMODSTUDIO}" --build=${CMAKE_CURRENT_BINARY_DIR} --buildtype=${CMAKE_BUILD_TYPE} "--channel=${VIEWER_CHANNEL}" @@ -2368,7 +2346,6 @@ if (WINDOWS) --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/touched.bat --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt --viewer_flavor=${ND_VIEWER_FLAVOR} - --fmodversion=${FMODVERSION} --openal=${OPENAL} DEPENDS ${VIEWER_BINARY_NAME} @@ -2531,6 +2508,7 @@ endif (NOT ENABLE_MEDIA_PLUGINS) --arch=${ARCH} --artwork=${ARTWORK_DIR} "--bugsplat=${BUGSPLAT_DB}" + "--fmodstudio=${FMODSTUDIO}" --build=${CMAKE_CURRENT_BINARY_DIR} --buildtype=${CMAKE_BUILD_TYPE} "--channel=${VIEWER_CHANNEL}" @@ -2541,7 +2519,6 @@ endif (NOT ENABLE_MEDIA_PLUGINS) --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.touched --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt --viewer_flavor=${ND_VIEWER_FLAVOR} - --fmodversion=${FMODVERSION} --openal=${OPENAL} DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py @@ -2558,6 +2535,7 @@ endif (NOT ENABLE_MEDIA_PLUGINS) --arch=${ARCH} --artwork=${ARTWORK_DIR} "--bugsplat=${BUGSPLAT_DB}" + "--fmodstudio=${FMODSTUDIO}" --build=${CMAKE_CURRENT_BINARY_DIR} --buildtype=${CMAKE_BUILD_TYPE} "--channel=${VIEWER_CHANNEL}" @@ -2567,7 +2545,6 @@ endif (NOT ENABLE_MEDIA_PLUGINS) --source=${CMAKE_CURRENT_SOURCE_DIR} --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt --viewer_flavor=${ND_VIEWER_FLAVOR} - --fmodversion=${FMODVERSION} --openal=${OPENAL} DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py @@ -2642,6 +2619,7 @@ if (DARWIN) --arch=${ARCH} --artwork=${ARTWORK_DIR} "--bugsplat=${BUGSPLAT_DB}" + "--fmodstudio=${FMODSTUDIO}" --build=${CMAKE_CURRENT_BINARY_DIR} --buildtype=${CMAKE_BUILD_TYPE} --bundleid=${MACOSX_BUNDLE_GUI_IDENTIFIER} @@ -2652,7 +2630,6 @@ if (DARWIN) --source=${CMAKE_CURRENT_SOURCE_DIR} --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt --viewer_flavor=${ND_VIEWER_FLAVOR} - --fmodversion=${FMODVERSION} --openal=${OPENAL} DEPENDS ${VIEWER_BINARY_NAME} @@ -2679,6 +2656,7 @@ if (DARWIN) --arch=${ARCH} --artwork=${ARTWORK_DIR} "--bugsplat=${BUGSPLAT_DB}" + "--fmodstudio=${FMODSTUDIO}" --build=${CMAKE_CURRENT_BINARY_DIR} --buildtype=${CMAKE_BUILD_TYPE} "--channel=${VIEWER_CHANNEL}" @@ -2689,7 +2667,6 @@ if (DARWIN) --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.touched --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt --viewer_flavor=${ND_VIEWER_FLAVOR} - --fmodversion=${FMODVERSION} --openal=${OPENAL} ${SIGNING_SETTING} DEPENDS diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index 133cad286f..49df80bfeb 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -6.4.3 +6.4.4 diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 44f50382cd..64637cc96e 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -20647,7 +20647,7 @@ Change of this parameter will affect the layout of buttons in notification toast FMODProfilerEnable Comment - Enable profiler tool if using FMOD + Enable profiler tool if using FMOD Studio Persist 1 Type @@ -20658,7 +20658,7 @@ Change of this parameter will affect the layout of buttons in notification toast FMODDecodeBufferSize Comment - Sets the streaming decode buffer size (in milliseconds) + Sets the streaming decode buffer size (in milliseconds) for FMOD Studio Persist 1 Type @@ -20669,7 +20669,7 @@ Change of this parameter will affect the layout of buttons in notification toast FMODStreamBufferSize Comment - Sets the streaming buffer size (in milliseconds) + Sets the streaming buffer size (in milliseconds) for FMOD Studio Persist 1 Type @@ -20680,7 +20680,7 @@ Change of this parameter will affect the layout of buttons in notification toast FMODResampleMethod Comment - Sets the method used for internal resampler 0(Linear), 1(Cubic), 2(Spline) + Sets the method used for internal resampler 0(Linear), 1(Cubic), 2(Spline) for FMOD Studio Persist 1 Type diff --git a/indra/newview/fsareasearch.cpp b/indra/newview/fsareasearch.cpp index 1a7e65633f..065ced1660 100644 --- a/indra/newview/fsareasearch.cpp +++ b/indra/newview/fsareasearch.cpp @@ -81,6 +81,18 @@ const F32 MIN_DISTANCE_MOVED = 1.0f; const F32 REQUEST_TIMEOUT = 30.0f; +F32 calculateObjectDistance(LLVector3d agent_pos, LLViewerObject* object) +{ + if (object->isHUDAttachment()) + { + return 0.f; + } + else + { + return dist_vec(agent_pos, object->getPositionGlobal()); + } +} + class FSAreaSearch::FSParcelChangeObserver : public LLParcelObserver { public: @@ -624,8 +636,8 @@ void FSAreaSearch::requestObjectProperties(const std::vector& request_list, msg->newMessageFast(_PREHASH_ObjectDeselect); } msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addUUIDFast(_PREHASH_AgentID, gAgentID); + msg->addUUIDFast(_PREHASH_SessionID, gAgentSessionID); select_count++; start_new_message = false; } @@ -777,7 +789,7 @@ void FSAreaSearch::matchObject(FSObjectProperties& details, LLViewerObject* obje if (mFilterDistance) { - S32 distance = dist_vec(mPanelList->getAgentLastPosition(), objectp->getPositionGlobal());// used mAgentLastPosition instead of gAgent->getPositionGlobal for performace + S32 distance = (S32)calculateObjectDistance(mPanelList->getAgentLastPosition(), objectp);// used mAgentLastPosition instead of gAgent->getPositionGlobal for performace if (!(distance >= mFilterDistanceMin && distance <= mFilterDistanceMax)) { return; @@ -989,7 +1001,7 @@ void FSAreaSearch::matchObject(FSObjectProperties& details, LLViewerObject* obje row_params.value = object_id.asString(); cell_params.column = "distance"; - cell_params.value = llformat("%1.0f m", dist_vec(mPanelList->getAgentLastPosition(), objectp->getPositionGlobal())); // used mAgentLastPosition instead of gAgent->getPositionGlobal for performace + cell_params.value = llformat("%1.0f m", calculateObjectDistance(mPanelList->getAgentLastPosition(), objectp)); // used mAgentLastPosition instead of gAgent->getPositionGlobal for performace row_params.columns.add(cell_params); cell_params.column = "name"; @@ -1471,7 +1483,7 @@ void FSPanelAreaSearchList::updateScrollList() { if (agent_moved && distance_column) { - item->getColumn(distance_column->mIndex)->setValue(LLSD(llformat("%1.0f m", dist_vec(current_agent_position, objectp->getPositionGlobal())))); + item->getColumn(distance_column->mIndex)->setValue(LLSD(llformat("%1.0f m", calculateObjectDistance(current_agent_position, objectp)))); } } } @@ -1614,7 +1626,7 @@ bool FSPanelAreaSearchList::onContextMenuItemEnable(const LLSD& userdata) { LLUUID object_id = mResultList->getFirstSelected()->getUUID(); LLViewerObject* objectp = gObjectList.findObject(object_id); - return (objectp && dist_vec_squared(gAgent.getPositionGlobal(), objectp->getPositionGlobal()) < gAgentCamera.mDrawDistance * gAgentCamera.mDrawDistance); + return (objectp && calculateObjectDistance(gAgent.getPositionGlobal(), objectp) < gAgentCamera.mDrawDistance); } else { @@ -1978,8 +1990,8 @@ void FSPanelAreaSearchList::sitOnObject(FSObjectProperties& details, LLViewerObj { gMessageSystem->newMessageFast(_PREHASH_AgentRequestSit); gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgentID); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgentSessionID); gMessageSystem->nextBlockFast(_PREHASH_TargetObject); gMessageSystem->addUUIDFast(_PREHASH_TargetID, objectp->mID); gMessageSystem->addVector3Fast(_PREHASH_Offset, LLVector3::zero); diff --git a/indra/newview/fsfloatersearch.cpp b/indra/newview/fsfloatersearch.cpp index 630cc48162..778faeda38 100644 --- a/indra/newview/fsfloatersearch.cpp +++ b/indra/newview/fsfloatersearch.cpp @@ -242,7 +242,7 @@ FSFloaterSearch::~FSFloaterSearch() { delete mRemoteParcelObserver; delete mAvatarPropertiesObserver; - gGenericDispatcher.addHandler("classifiedclickthrough", NULL); + gGenericDispatcher.addHandler("classifiedclickthrough", nullptr); } // virtual @@ -314,17 +314,13 @@ BOOL FSFloaterSearch::postBuild() mDetailSnapshot = getChild("snapshot"); mDetailMaturity = getChild("maturity_icon"); mTabContainer = getChild("ls_tabs"); - if (mTabContainer) - { - mTabContainer->setCommitCallback(boost::bind(&FSFloaterSearch::onTabChange, this)); - } + mTabContainer->setCommitCallback(boost::bind(&FSFloaterSearch::onTabChange, this)); + flushDetails(); - if (mDetailsPanel) - { - mDetailsPanel->setVisible(false); - } + mDetailsPanel->setVisible(false); + mHasSelection = false; if (!mTabContainer->selectTab(gSavedSettings.getS32("FSLastSearchTab"))) @@ -344,7 +340,7 @@ void FSFloaterSearch::onTabChange() mDetailsPanel->setVisible(false); mPanelWeb->resetFocusOnLoad(); } - // If on legacy preople search and skin uses full profile preview, hide preview panel + // If on legacy people search and skin uses full profile preview, hide preview panel else if (active_panel == mPanelPeople && mPanelProfile) { mDetailsPanel->setVisible(false); @@ -356,16 +352,17 @@ void FSFloaterSearch::onTabChange() } //static -LLPanel* FSFloaterSearch::getSearchPanel(std::string panel_name) +template +T* FSFloaterSearch::getSearchPanel(const std::string& panel_name) { - FSFloaterSearch* search_instance = LLFloaterReg::getTypedInstance("search"); + FSFloaterSearch* search_instance = LLFloaterReg::findTypedInstance("search"); if (search_instance && search_instance->mTabContainer) { - return search_instance->mTabContainer->getPanelByName(panel_name); + return dynamic_cast(search_instance->mTabContainer->getPanelByName(panel_name)); } else { - return NULL; + return nullptr; } } @@ -452,7 +449,7 @@ void FSFloaterSearch::displayParcelDetails(const LLParcelData& parcel_data) map["LOCATION"] = llformat("%s (%d, %d, %d)", parcel_data.sim_name.c_str(), region_x, region_y, region_z); mParcelGlobal = LLVector3d(parcel_data.global_x, parcel_data.global_y, parcel_data.global_z); - mDetailsPanel->setVisible(true); + mDetailsPanel->setVisible(mTabContainer->getCurrentPanel()->getName() == "panel_ls_places" || mTabContainer->getCurrentPanel()->getName() == "panel_ls_land"); mHasSelection = true; mDetailMaturity->setVisible(true); mDetailTitle->setValue(parcel_data.name); @@ -478,7 +475,7 @@ void FSFloaterSearch::displayAvatarDetails(LLAvatarData*& avatar_data) mDetailAux2->setValue(getString("string.partner", map)); } - mDetailsPanel->setVisible(true); + mDetailsPanel->setVisible(mTabContainer->getCurrentPanel()->getName() == "panel_ls_people"); mHasSelection = true; mDetailTitle->setValue(LLTrans::getString("LoadingData")); mDetailDesc->setValue(avatar_data->about_text); @@ -500,7 +497,7 @@ void FSFloaterSearch::displayGroupDetails(LLGroupMgrGroupData*& group_data) map["MEMBER_COUNT"] = llformat("%d",group_data->mMemberCount); map["FOUNDER"] = LLSLURL("agent", group_data->mFounderID, "inspect").getSLURLString(); - mDetailsPanel->setVisible(true); + mDetailsPanel->setVisible(mTabContainer->getCurrentPanel()->getName() == "panel_ls_groups"); mHasSelection = true; mDetailTitle->setValue(LLTrans::getString("LoadingData")); mDetailDesc->setValue(group_data->mCharter); @@ -536,7 +533,7 @@ void FSFloaterSearch::displayClassifiedDetails(LLAvatarClassifiedInfo*& c_info) map["LISTING_PRICE"] = llformat("L$%d", c_info->price_for_listing); map["SLURL"] = LLSLURL("parcel", c_info->parcel_id, "about").getSLURLString(); - mDetailsPanel->setVisible(true); + mDetailsPanel->setVisible(mTabContainer->getCurrentPanel()->getName() == "panel_ls_groupspanel_ls_classifieds"); mHasSelection = true; mDetailMaturity->setVisible(true); mParcelGlobal = c_info->pos_global; @@ -583,7 +580,7 @@ void FSFloaterSearch::displayEventDetails(U32 eventId, F64 eventEpoch, const std mParcelGlobal = eventGlobalPos; mEventID = eventId; - mDetailsPanel->setVisible(true); + mDetailsPanel->setVisible(mTabContainer->getCurrentPanel()->getName() == "panel_ls_events"); mHasSelection = true; mDetailMaturity->setVisible(true); mDetailTitle->setValue(eventName); @@ -728,7 +725,7 @@ void FSFloaterSearch::onBtnEventReminder() static LLPanelInjector t_panel_fs_search_people("panel_ls_people"); FSPanelSearchPeople::FSPanelSearchPeople() : FSSearchPanelBase() -, mQueryID(NULL) +, mQueryID(nullptr) , mStartSearch(0) , mResultsReceived(0) , mResultsContent() @@ -863,9 +860,11 @@ void FSPanelSearchPeople::onSelectItem() { return; } - FSFloaterSearch* search_instance = LLFloaterReg::getTypedInstance("search"); + FSFloaterSearch* search_instance = LLFloaterReg::findTypedInstance("search"); if (search_instance) + { search_instance->FSFloaterSearch::onSelectedItem(mSearchResults->getSelectedValue(), FSFloaterSearch::SC_AVATAR); + } } // static @@ -886,10 +885,10 @@ void FSPanelSearchPeople::processSearchReply(LLMessageSystem* msg, void**) } LL_DEBUGS("Search") << "received search results - QueryID: " << query_id << " AgentID: " << agent_id << LL_ENDL; - FSPanelSearchPeople* self = (FSPanelSearchPeople*)FSFloaterSearch::getSearchPanel("panel_ls_people"); + FSPanelSearchPeople* self = FSFloaterSearch::getSearchPanel("panel_ls_people"); // floater is closed or these are not results from our last request - if (NULL == self || query_id != self->getQueryID()) + if (!self || query_id != self->getQueryID()) { return; } @@ -914,7 +913,7 @@ void FSPanelSearchPeople::processSearchReply(LLMessageSystem* msg, void**) search_results->setCommentText(LLTrans::getString("not_found", map)); return; } - else if(status & STATUS_SEARCH_PLACES_SHORTSTRING) + else if (status & STATUS_SEARCH_PLACES_SHORTSTRING) { search_results->setEnabled(FALSE); search_results->setCommentText(LLTrans::getString("search_short")); @@ -1004,7 +1003,7 @@ void FSPanelSearchPeople::processSearchReply(LLMessageSystem* msg, void**) static LLPanelInjector t_panel_fs_search_groups("panel_ls_groups"); FSPanelSearchGroups::FSPanelSearchGroups() : FSSearchPanelBase() -, mQueryID(NULL) +, mQueryID(nullptr) , mStartSearch(0) , mResultsReceived(0) , mResultsContent() @@ -1114,7 +1113,7 @@ void FSPanelSearchGroups::find() void FSPanelSearchGroups::onBtnFind() { std::string text = mSearchComboBox->getSimple(); - if(!text.empty()) + if (!text.empty()) { LLSearchHistory::getInstance()->addEntry(text); } @@ -1164,7 +1163,7 @@ void FSPanelSearchGroups::onSelectItem() { return; } - FSFloaterSearch* search_instance = LLFloaterReg::getTypedInstance("search"); + FSFloaterSearch* search_instance = LLFloaterReg::findTypedInstance("search"); if (search_instance) { search_instance->FSFloaterSearch::onSelectedItem(mSearchResults->getSelectedValue(), FSFloaterSearch::SC_GROUP); @@ -1191,10 +1190,10 @@ void FSPanelSearchGroups::processSearchReply(LLMessageSystem* msg, void**) } LL_DEBUGS("Search") << "received directory request - QueryID: " << query_id << " AgentID: " << agent_id << LL_ENDL; - FSPanelSearchGroups* self = (FSPanelSearchGroups*)FSFloaterSearch::getSearchPanel("panel_ls_groups"); + FSPanelSearchGroups* self = FSFloaterSearch::getSearchPanel("panel_ls_groups"); // floater is closed or these are not results from our last request - if (NULL == self || query_id != self->mQueryID) + if (!self || query_id != self->mQueryID) { return; } @@ -1312,7 +1311,7 @@ void FSPanelSearchGroups::processSearchReply(LLMessageSystem* msg, void**) static LLPanelInjector t_panel_fs_search_places("panel_ls_places"); FSPanelSearchPlaces::FSPanelSearchPlaces() : FSSearchPanelBase() -, mQueryID(NULL) +, mQueryID(nullptr) , mStartSearch(0) , mResultsReceived(0) , mResultsContent() @@ -1496,7 +1495,7 @@ void FSPanelSearchPlaces::onSelectItem() { return; } - FSFloaterSearch* search_instance = LLFloaterReg::getTypedInstance("search"); + FSFloaterSearch* search_instance = LLFloaterReg::findTypedInstance("search"); if (search_instance) { search_instance->FSFloaterSearch::onSelectedItem(mSearchResults->getSelectedValue(), FSFloaterSearch::SC_PLACE); @@ -1524,10 +1523,10 @@ void FSPanelSearchPlaces::processSearchReply(LLMessageSystem* msg, void**) } LL_DEBUGS("Search") << "received directory request - QueryID: " << query_id << " AgentID: " << agent_id << LL_ENDL; - FSPanelSearchPlaces* self = (FSPanelSearchPlaces*)FSFloaterSearch::getSearchPanel("panel_ls_places"); + FSPanelSearchPlaces* self = FSFloaterSearch::getSearchPanel("panel_ls_places"); // floater is closed or these are not results from our last request - if (NULL == self || query_id != self->getQueryID()) + if (!self || query_id != self->getQueryID()) { return; } @@ -1665,7 +1664,7 @@ void FSPanelSearchPlaces::processSearchReply(LLMessageSystem* msg, void**) static LLPanelInjector t_panel_fs_search_land("panel_ls_land"); FSPanelSearchLand::FSPanelSearchLand() : FSSearchPanelBase() -, mQueryID(NULL) +, mQueryID(nullptr) , mStartSearch(0) , mResultsReceived(0) , mResultsContent() @@ -1875,7 +1874,7 @@ void FSPanelSearchLand::onSelectItem() { return; } - FSFloaterSearch* search_instance = LLFloaterReg::getTypedInstance("search"); + FSFloaterSearch* search_instance = LLFloaterReg::findTypedInstance("search"); if (search_instance) { search_instance->FSFloaterSearch::onSelectedItem(mSearchResults->getSelectedValue(), FSFloaterSearch::SC_PLACE); @@ -1906,10 +1905,10 @@ void FSPanelSearchLand::processSearchReply(LLMessageSystem* msg, void**) } LL_DEBUGS("Search") << "received directory request - QueryID: " << query_id << " AgentID: " << agent_id << LL_ENDL; - FSPanelSearchLand* self = (FSPanelSearchLand*)FSFloaterSearch::getSearchPanel("panel_ls_land"); + FSPanelSearchLand* self = FSFloaterSearch::getSearchPanel("panel_ls_land"); // floater is closed or these are not results from our last request - if (NULL == self || query_id != self->mQueryID) + if (!self || query_id != self->mQueryID) { return; } @@ -1957,7 +1956,7 @@ void FSPanelSearchLand::processSearchReply(LLMessageSystem* msg, void**) LL_DEBUGS("Search") << "Got: " << name << " ClassifiedID: " << parcel_id << LL_ENDL; search_results->setEnabled(TRUE); found_one = true; - if ( msg->getSizeFast(_PREHASH_QueryReplies, i, _PREHASH_ProductSKU) > 0 ) + if (msg->getSizeFast(_PREHASH_QueryReplies, i, _PREHASH_ProductSKU) > 0) { msg->getStringFast( _PREHASH_QueryReplies, _PREHASH_ProductSKU, land_sku, i); land_type = LLProductInfoRequestManager::instance().getDescriptionForSku(land_sku); @@ -2064,7 +2063,7 @@ void FSPanelSearchLand::processSearchReply(LLMessageSystem* msg, void**) static LLPanelInjector t_panel_fs_search_classifieds("panel_ls_classifieds"); FSPanelSearchClassifieds::FSPanelSearchClassifieds() : FSSearchPanelBase() -, mQueryID(NULL) +, mQueryID(nullptr) , mStartSearch(0) , mResultsReceived(0) , mResultsContent() @@ -2173,7 +2172,7 @@ void FSPanelSearchClassifieds::find() void FSPanelSearchClassifieds::onBtnFind() { std::string text = mSearchComboBox->getSimple(); - if(!text.empty()) + if (!text.empty()) { LLSearchHistory::getInstance()->addEntry(text); } @@ -2223,7 +2222,7 @@ void FSPanelSearchClassifieds::onSelectItem() { return; } - FSFloaterSearch* search_instance = LLFloaterReg::getTypedInstance("search"); + FSFloaterSearch* search_instance = LLFloaterReg::findTypedInstance("search"); if (search_instance) { search_instance->FSFloaterSearch::onSelectedItem(mSearchResults->getSelectedValue(), FSFloaterSearch::SC_CLASSIFIED); @@ -2251,7 +2250,7 @@ void FSPanelSearchClassifieds::processSearchReply(LLMessageSystem* msg, void**) } LL_DEBUGS("Search") << "received directory request - QueryID: " << query_id << " AgentID: " << agent_id << LL_ENDL; - FSPanelSearchClassifieds* self = (FSPanelSearchClassifieds*)FSFloaterSearch::getSearchPanel("panel_ls_classifieds"); + FSPanelSearchClassifieds* self = FSFloaterSearch::getSearchPanel("panel_ls_classifieds"); if (msg->getNumberOfBlocks("StatusData")) { @@ -2264,7 +2263,7 @@ void FSPanelSearchClassifieds::processSearchReply(LLMessageSystem* msg, void**) } // floater is closed or these are not results from our last request - if (NULL == self || query_id != self->mQueryID) + if (!self || query_id != self->mQueryID) { return; } @@ -2379,7 +2378,7 @@ void FSPanelSearchClassifieds::processSearchReply(LLMessageSystem* msg, void**) static LLPanelInjector t_panel_fs_search_events("panel_ls_events"); FSPanelSearchEvents::FSPanelSearchEvents() : FSSearchPanelBase() -, mQueryID(NULL) +, mQueryID(nullptr) , mResultsReceived(0) , mStartSearch(0) , mDay(0) @@ -2617,7 +2616,7 @@ void FSPanelSearchEvents::onSelectItem() return; } S32 event_id = mSearchResults->getSelectedValue(); - FSFloaterSearch* search_instance = LLFloaterReg::getTypedInstance("search"); + FSFloaterSearch* search_instance = LLFloaterReg::findTypedInstance("search"); if (search_instance) { search_instance->FSFloaterSearch::onSelectedEvent(event_id); @@ -2643,10 +2642,10 @@ void FSPanelSearchEvents::processSearchReply(LLMessageSystem* msg, void**) } LL_DEBUGS("Search") << "received directory request - QueryID: " << query_id << " AgentID: " << agent_id << LL_ENDL; - FSPanelSearchEvents* self = (FSPanelSearchEvents*)FSFloaterSearch::getSearchPanel("panel_ls_events"); + FSPanelSearchEvents* self = FSFloaterSearch::getSearchPanel("panel_ls_events"); // floater is closed or these are not results from our last request - if (NULL == self || query_id != self->mQueryID) + if (!self || query_id != self->mQueryID) { return; } @@ -2741,7 +2740,7 @@ void FSPanelSearchEvents::processSearchReply(LLMessageSystem* msg, void**) // Skip empty events... if (owner_id.isNull()) { - LL_INFOS("Search") << "Skipped " << event_id << " because of a NULL owner result" << LL_ENDL; + LL_INFOS("Search") << "Skipped " << event_id << " because of a nullptr owner result" << LL_ENDL; continue; } // Skips events that don't match our scope... @@ -2817,7 +2816,7 @@ void FSPanelSearchEvents::processSearchReply(LLMessageSystem* msg, void**) static LLPanelInjector t_panel_fs_search_web("panel_ls_web"); FSPanelSearchWeb::FSPanelSearchWeb() : FSSearchPanelBase() -, mWebBrowser(NULL) +, mWebBrowser(nullptr) , mResetFocusOnLoad(false) { // declare a map that transforms a category name into @@ -2964,7 +2963,7 @@ std::string filterShortWords(std::string query_string) void fillSearchComboBox(LLSearchComboBox* search_combo) { - if (search_combo == NULL) + if (search_combo == nullptr) { return; } diff --git a/indra/newview/fsfloatersearch.h b/indra/newview/fsfloatersearch.h index 88baf70468..0f6ba1b52a 100644 --- a/indra/newview/fsfloatersearch.h +++ b/indra/newview/fsfloatersearch.h @@ -362,7 +362,9 @@ public: U32 eventCover, LLVector3d eventGlobalPos); void setLoadingProgress(bool started); - static LLPanel* getSearchPanel(std::string panel_name); + + template + static T* getSearchPanel(const std::string& panel_name); private: virtual void onClose(bool app_quitting); diff --git a/indra/newview/linux_tools/client-readme.txt b/indra/newview/linux_tools/client-readme.txt index 71f0b65155..5290e607a7 100644 --- a/indra/newview/linux_tools/client-readme.txt +++ b/indra/newview/linux_tools/client-readme.txt @@ -180,8 +180,8 @@ The 'firestorm' script which launches Firestorm contains some configuration options for advanced troubleshooters. * AUDIO - Edit the 'secondlife' script and you will see these audio - options: LL_BAD_OPENAL_DRIVER, LL_BAD_FMOD_ESD, LL_BAD_FMOD_OSS, and - LL_BAD_FMOD_ALSA. Firestorm tries to use OpenAL, ESD, OSS, then ALSA + options: LL_BAD_OPENAL_DRIVER, LL_BAD_FMODSTUDIO_DRIVER. + Firestorm tries to use OpenAL, FMODSTUDIO (PULSEAUDIO, ALSA) audio drivers in this order; you may uncomment the corresponding LL_BAD_* option to skip an audio driver which you believe may be causing you trouble. diff --git a/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh index 0ba74ef072..57da1b18ae 100755 --- a/indra/newview/linux_tools/wrapper.sh +++ b/indra/newview/linux_tools/wrapper.sh @@ -20,18 +20,15 @@ exportMutliArchDRIPath() { ## These options are for self-assisted troubleshooting during this beta ## testing phase; you should not usually need to touch them. -## - Avoids using any FMOD Ex audio driver. -#export LL_BAD_FMODEX_DRIVER=x - +## - Avoids using any FMOD STUDIO audio driver. +#export LL_BAD_FMODSTUDIO_DRIVER=x ## - Avoids using any OpenAL audio driver. #export LL_BAD_OPENAL_DRIVER=x -## - Avoids using the FMOD Ex PulseAudio audio driver. +## - Avoids using the FMOD Studio PulseAudio audio driver. #export LL_BAD_FMOD_PULSEAUDIO=x -## - Avoids using the FMOD or FMOD Ex ALSA audio driver. +## - Avoids using the FMOD Studio ALSA audio driver. #export LL_BAD_FMOD_ALSA=x -## - Avoids using the FMOD or FMOD Ex OSS audio driver. -#export LL_BAD_FMOD_OSS=x ## - Avoids the optional OpenGL extensions which have proven most problematic ## on some hardware. Disabling this option may cause BETTER PERFORMANCE but diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp index 991a68b3d7..2e5fff5589 100644 --- a/indra/newview/llfloaterabout.cpp +++ b/indra/newview/llfloaterabout.cpp @@ -143,10 +143,6 @@ BOOL LLFloaterAbout::postBuild() // boost::bind(&LLFloaterAbout::onClickUpdateCheck, this)); // -#if LL_FMODSTUDIO || LL_FMODEX - childSetVisible("logos_panel", true); -#endif - static const LLUIColor about_color = LLUIColorTable::instance().getColor("TextFgReadOnlyColor"); if (gAgent.getRegion()) diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index bebfc26c88..fe0d1c863a 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -6061,7 +6061,7 @@ BOOL FSPanelPreferenceSounds::postBuild() mOutputDevicePanel = findChild("output_device_settings_panel"); mOutputDeviceComboBox = findChild("sound_output_device"); -#if LL_FMODSTUDIO || LL_FMODEX +#if LL_FMODSTUDIO if (gAudiop && mOutputDevicePanel && mOutputDeviceComboBox) { gSavedSettings.getControl("FSOutputDeviceUUID")->getSignal()->connect(boost::bind(&FSPanelPreferenceSounds::onOutputDeviceChanged, this, _2)); diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp index 89c97f687c..be242afaf6 100644 --- a/indra/newview/llprogressview.cpp +++ b/indra/newview/llprogressview.cpp @@ -230,7 +230,7 @@ void LLProgressView::setStartupComplete() mFadeToWorldTimer.start(); } - // NickyD: FIRE-3063; Enable Audio for all media sources again. They got disabled during postBuild(), but as we never reach LLProgressView::draw + // FIRE-3063; Enable Audio for all media sources again. They got disabled during postBuild(), but as we never reach LLProgressView::draw // if the progress is disabled, we would never get media audio back. LLViewerMedia::getInstance()->setOnlyAudibleMediaTextureID(LLUUID::null); } @@ -255,7 +255,7 @@ void LLProgressView::setVisible(BOOL visible) } } -// ## Zi: Fade teleport screens +// Fade teleport screens void LLProgressView::fade(BOOL in) { if(in) @@ -271,7 +271,7 @@ void LLProgressView::fade(BOOL in) // set visibility will be done in the draw() method after fade } } -// ## Zi: Fade teleport screens +// Fade teleport screens void LLProgressView::drawStartTexture(F32 alpha) { @@ -308,6 +308,33 @@ void LLProgressView::drawStartTexture(F32 alpha) gGL.popMatrix(); } +void LLProgressView::drawLogos(F32 alpha) +{ + if (mLogosList.empty()) + { + return; + } + + // logos are tied to label, + // due to potential resizes we have to figure offsets out on draw or resize + LLTextBox *logos_label = getChild("logos_lbl"); + S32 offset_x, offset_y; + logos_label->localPointToScreen(0, 0, &offset_x, &offset_y); + std::vector::const_iterator iter = mLogosList.begin(); + std::vector::const_iterator end = mLogosList.end(); + for (; iter != end; iter++) + { + gl_draw_scaled_image_with_border(iter->mDrawRect.mLeft + offset_x, + iter->mDrawRect.mBottom + offset_y, + iter->mDrawRect.getWidth(), + iter->mDrawRect.getHeight(), + iter->mTexturep.get(), + UI_VERTEX_COLOR % alpha, + FALSE, + iter->mClipRect, + iter->mOffsetRect); + } +} void LLProgressView::draw() { @@ -324,6 +351,7 @@ void LLProgressView::draw() } LLPanel::draw(); + drawLogos(alpha); return; } @@ -336,6 +364,7 @@ void LLProgressView::draw() drawStartTexture(alpha); LLPanel::draw(); + drawLogos(alpha); // faded out completely - remove panel and reveal world if (mFadeToWorldTimer.getElapsedTimeF32() > FADE_TO_WORLD_TIME ) @@ -362,7 +391,7 @@ void LLProgressView::draw() // FIXME: this causes a crash that i haven't been able to fix mMediaCtrl->unloadMediaSource(); - gStartTexture = NULL; + releaseTextures(); } return; } @@ -370,6 +399,7 @@ void LLProgressView::draw() drawStartTexture(1.0f); // draw children LLPanel::draw(); + drawLogos(1.0f); } void LLProgressView::setText(const std::string& text) @@ -388,6 +418,199 @@ void LLProgressView::setMessage(const std::string& msg) mMessageText->setValue(mMessage); } +void LLProgressView::loadLogo(const std::string &path, + const U8 image_codec, + const LLRect &pos_rect, + const LLRectf &clip_rect, + const LLRectf &offset_rect) +{ + // We need these images very early, so we have to force-load them, otherwise they might not load in time. + if (!gDirUtilp->fileExists(path)) + { + return; + } + + LLPointer start_image_frmted = LLImageFormatted::createFromType(image_codec); + if (!start_image_frmted->load(path)) + { + LL_WARNS("AppInit") << "Image load failed: " << path << LL_ENDL; + return; + } + + LLPointer raw = new LLImageRaw; + if (!start_image_frmted->decode(raw, 0.0f)) + { + LL_WARNS("AppInit") << "Image decode failed " << path << LL_ENDL; + return; + } + // HACK: getLocalTexture allows only power of two dimentions + raw->expandToPowerOfTwo(); + + TextureData data; + data.mTexturep = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE); + data.mDrawRect = pos_rect; + data.mClipRect = clip_rect; + data.mOffsetRect = offset_rect; + mLogosList.push_back(data); +} + +void LLProgressView::initLogos() +{ + mLogosList.clear(); + + const U8 image_codec = IMG_CODEC_PNG; + const LLRectf default_clip(0.f, 1.f, 1.f, 0.f); + const S32 default_height = 28; + const S32 default_pad = 15; + + S32 icon_width, icon_height; + + // We don't know final screen rect yet, so we can't precalculate position fully + LLTextBox *logos_label = getChild("logos_lbl"); + S32 texture_start_x = logos_label->getFont()->getWidthF32(logos_label->getText()) + default_pad; + S32 texture_start_y = -7; + + // Normally we would just preload these textures from textures.xml, + // and display them via icon control, but they are only needed on + // startup and preloaded/UI ones stay forever + // (and this code was done already so simply reused it) + std::string temp_str = gDirUtilp->getExpandedFilename(LL_PATH_DEFAULT_SKIN, "textures", "3p_icons"); + + temp_str += gDirUtilp->getDirDelimiter(); + +#ifdef LL_FMODSTUDIO + // original image size is 264x96, it is on longer side but + // with no internal paddings so it gets additional padding + icon_width = 77; + icon_height = 21; + S32 pad_y = 4; + texture_start_x++; + loadLogo(temp_str + "fmod_logo.png", + image_codec, + LLRect(texture_start_x, texture_start_y + pad_y + icon_height, texture_start_x + icon_width, texture_start_y + pad_y), + default_clip, + default_clip); + + texture_start_x += icon_width + default_pad + 1; +#endif + +#ifdef HAVOK_TPV // Don't show on non-Havok builds + // original image size is 342x113, central element is on a larger side + // plus internal padding, so it gets slightly more height than desired 32 + icon_width = 88; + icon_height = 29; + pad_y = -1; + loadLogo(temp_str + "havok_logo.png", + image_codec, + LLRect(texture_start_x, texture_start_y + pad_y + icon_height, texture_start_x + icon_width, texture_start_y + pad_y), + default_clip, + default_clip); + + texture_start_x += icon_width + default_pad; +#endif // Don't show on non-Havok builds + + // 108x41 + icon_width = 74; + loadLogo(temp_str + "vivox_logo.png", + image_codec, + LLRect(texture_start_x, texture_start_y + default_height, texture_start_x + icon_width, texture_start_y), + default_clip, + default_clip); +} + +void LLProgressView::initStartTexture(S32 location_id, bool is_in_production) +{ + if (gStartTexture.notNull()) + { + gStartTexture = NULL; + LL_INFOS("AppInit") << "re-initializing start screen" << LL_ENDL; + } + + LL_DEBUGS("AppInit") << "Loading startup bitmap..." << LL_ENDL; + + U8 image_codec = IMG_CODEC_PNG; + std::string temp_str = gDirUtilp->getLindenUserDir() + gDirUtilp->getDirDelimiter(); + + if ((S32)START_LOCATION_ID_LAST == location_id) + { + temp_str += LLStartUp::getScreenLastFilename(); + } + else + { + std::string path = temp_str + LLStartUp::getScreenHomeFilename(); + + if (!gDirUtilp->fileExists(path) && is_in_production) + { + // Fallback to old file, can be removed later + // Home image only sets when user changes home, so it will take time for users to switch to pngs + temp_str += "screen_home.bmp"; + image_codec = IMG_CODEC_BMP; + } + else + { + temp_str = path; + } + } + + LLPointer start_image_frmted = LLImageFormatted::createFromType(image_codec); + + // Turn off start screen to get around the occasional readback + // driver bug + if (!gSavedSettings.getBOOL("UseStartScreen")) + { + LL_INFOS("AppInit") << "Bitmap load disabled" << LL_ENDL; + return; + } + else if (!start_image_frmted->load(temp_str)) + { + LL_WARNS("AppInit") << "Bitmap load failed" << LL_ENDL; + gStartTexture = NULL; + } + else + { + gStartImageWidth = start_image_frmted->getWidth(); + gStartImageHeight = start_image_frmted->getHeight(); + + LLPointer raw = new LLImageRaw; + if (!start_image_frmted->decode(raw, 0.0f)) + { + LL_WARNS("AppInit") << "Bitmap decode failed" << LL_ENDL; + gStartTexture = NULL; + } + else + { + // HACK: getLocalTexture allows only power of two dimentions + raw->expandToPowerOfTwo(); + gStartTexture = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE); + } + } + + if (gStartTexture.isNull()) + { + gStartTexture = LLViewerTexture::sBlackImagep; + gStartImageWidth = gStartTexture->getWidth(); + gStartImageHeight = gStartTexture->getHeight(); + } +} + +void LLProgressView::initTextures(S32 location_id, bool is_in_production) +{ + initStartTexture(location_id, is_in_production); + initLogos(); + + childSetVisible("panel_icons", mLogosList.empty() ? FALSE : TRUE); + childSetVisible("panel_top_spacer", mLogosList.empty() ? TRUE : FALSE); +} + +void LLProgressView::releaseTextures() +{ + gStartTexture = NULL; + mLogosList.clear(); + + childSetVisible("panel_top_spacer", TRUE); + childSetVisible("panel_icons", FALSE); +} + void LLProgressView::setCancelButtonVisible(BOOL b, const std::string& label) { mCancelBtn->setVisible( b ); diff --git a/indra/newview/llprogressview.h b/indra/newview/llprogressview.h index 448b626fe4..3432c135a3 100644 --- a/indra/newview/llprogressview.h +++ b/indra/newview/llprogressview.h @@ -35,6 +35,7 @@ class LLImageRaw; class LLButton; class LLProgressBar; +class LLViewerTexture; class LLTextBox; class LLProgressView : @@ -52,6 +53,7 @@ public: /*virtual*/ void draw(); void drawStartTexture(F32 alpha); + void drawLogos(F32 alpha); /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask); @@ -73,6 +75,10 @@ public: void setStartupComplete(); + // we have to preload local textures to make sure they won't be grey + void initTextures(S32 location_id, bool is_in_production); + void releaseTextures(); + void setCancelButtonVisible(BOOL b, const std::string& label); static void onCancelButtonClicked( void* ); @@ -100,6 +106,25 @@ protected: bool handleUpdate(const LLSD& event_data); static void onIdle(void* user_data); + void loadLogo(const std::string &path, const U8 image_codec, const LLRect &pos_rect, const LLRectf &clip_rect, const LLRectf &offset_rect); + // logos have unusual location and need to be preloaded to not appear grey, then deleted + void initLogos(); + // Loads a bitmap to display during load + void initStartTexture(S32 location_id, bool is_in_production); + +private: + // We need to draw textures on login, but only once. + // So this vector gets filled up for textures to render and gets cleaned later + // Some textures have unusual requirements, so we are rendering directly + class TextureData + { + public: + LLPointer mTexturep; + LLRect mDrawRect; + LLRectf mClipRect; + LLRectf mOffsetRect; + }; + std::vector mLogosList; }; class LLProgressViewMini : diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index a0d1311f53..546c432382 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -43,10 +43,6 @@ # include "llaudioengine_fmodstudio.h" #endif -#ifdef LL_FMODEX -# include "llaudioengine_fmodex.h" -#endif - #ifdef LL_OPENAL #include "llaudioengine_openal.h" #endif @@ -989,20 +985,11 @@ bool idle_startup() #ifdef LL_FMODSTUDIO #if !LL_WINDOWS - if (NULL == getenv("LL_BAD_FMODSTUDIO_DRIVER")) + if (NULL == getenv("LL_BAD_FMODSTUDIO_DRIVER")) #endif // !LL_WINDOWS - { - gAudiop = (LLAudioEngine *) new LLAudioEngine_FMODSTUDIO(gSavedSettings.getBOOL("FMODProfilerEnable"), gSavedSettings.getU32("FMODResampleMethod")); - } -#endif - -#ifdef LL_FMODEX -#if !LL_WINDOWS - if (NULL == getenv("LL_BAD_FMODEX_DRIVER")) -#endif // !LL_WINDOWS - { - gAudiop = (LLAudioEngine *) new LLAudioEngine_FMODEX(gSavedSettings.getBOOL("FMODProfilerEnable")); - } + { + gAudiop = (LLAudioEngine *) new LLAudioEngine_FMODSTUDIO(gSavedSettings.getBOOL("FMODProfilerEnable"), gSavedSettings.getU32("FMODResampleMethod")); + } #endif #ifdef LL_OPENAL @@ -1024,7 +1011,7 @@ bool idle_startup() #else void* window_handle = NULL; #endif - bool init = gAudiop->init(kAUDIO_NUM_SOURCES, window_handle); + bool init = gAudiop->init(kAUDIO_NUM_SOURCES, window_handle, LLAppViewer::instance()->getSecondLifeTitle()); if(init) { // Output device selection @@ -1568,9 +1555,8 @@ bool idle_startup() gViewerWindow->getWindow()->setCursor(UI_CURSOR_WAIT); - init_start_screen(agent_location_id); - // Display the startup progress bar. + gViewerWindow->initTextures(agent_location_id); gViewerWindow->setShowProgress(TRUE,!gSavedSettings.getBOOL("FSDisableLoginScreens")); gViewerWindow->setProgressCancelButtonVisible(TRUE, LLTrans::getString("Quit")); @@ -3649,84 +3635,6 @@ std::string LLStartUp::getUserId() return gUserCredential->userID(); } -// Loads a bitmap to display during load -void init_start_screen(S32 location_id) -{ - if (gStartTexture.notNull()) - { - gStartTexture = NULL; - LL_INFOS("AppInit") << "re-initializing start screen" << LL_ENDL; - } - - LL_DEBUGS("AppInit") << "Loading startup bitmap..." << LL_ENDL; - - U8 image_codec = IMG_CODEC_PNG; - std::string temp_str = gDirUtilp->getLindenUserDir() + gDirUtilp->getDirDelimiter(); - - if ((S32)START_LOCATION_ID_LAST == location_id) - { - temp_str += LLStartUp::getScreenLastFilename(); - } - else - { - std::string path = temp_str + LLStartUp::getScreenHomeFilename(); - - // OpenSim support - //if (!gDirUtilp->fileExists(path) && LLGridManager::getInstance()->isInProductionGrid()) - if (!gDirUtilp->fileExists(path) && LLGridManager::getInstance()->isInSLMain()) - // - { - // Fallback to old file, can be removed later - // Home image only sets when user changes home, so it will take time for users to switch to pngs - temp_str += "screen_home.bmp"; - image_codec = IMG_CODEC_BMP; - } - else - { - temp_str = path; - } - } - - LLPointer start_image_frmted = LLImageFormatted::createFromType(image_codec); - - // Turn off start screen to get around the occasional readback - // driver bug - if(!gSavedSettings.getBOOL("UseStartScreen")) - { - LL_INFOS("AppInit") << "Bitmap load disabled" << LL_ENDL; - return; - } - else if(!start_image_frmted->load(temp_str) ) - { - LL_WARNS("AppInit") << "Bitmap load failed" << LL_ENDL; - gStartTexture = NULL; - } - else - { - gStartImageWidth = start_image_frmted->getWidth(); - gStartImageHeight = start_image_frmted->getHeight(); - - LLPointer raw = new LLImageRaw; - if (!start_image_frmted->decode(raw, 0.0f)) - { - LL_WARNS("AppInit") << "Bitmap decode failed" << LL_ENDL; - gStartTexture = NULL; - } - else - { - raw->expandToPowerOfTwo(); - gStartTexture = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE) ; - } - } - - if(gStartTexture.isNull()) - { - gStartTexture = LLViewerTexture::sBlackImagep ; - gStartImageWidth = gStartTexture->getWidth() ; - gStartImageHeight = gStartTexture->getHeight() ; - } -} - // frees the bitmap void release_start_screen() diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 5288726cc5..ecdb041ee0 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -76,6 +76,8 @@ #include "lldrawpoolbump.h" #include "llpostprocess.h" #include "llscenemonitor.h" + +#include "llenvironment.h" // [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a) #include "rlvhandler.h" #include "rlvlocks.h" @@ -83,10 +85,6 @@ #include "llpresetsmanager.h" #include "fsdata.h" -#include "llenvironment.h" - -#include "llenvironment.h" - extern LLPointer gStartTexture; extern bool gShiftFrame; diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index 51b99d9067..71988d4de5 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -1984,7 +1984,8 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use // If there is a new music URL and it's valid, play it. if (music_url.size() > 12) { - if (music_url.substr(0, 7) == "http://") + if (music_url.substr(0, 7) == "http://" + || music_url.substr(0, 8) == "https://") { LLViewerRegion *region = LLWorld::getInstance()->getRegion(msg->getSender()); optionally_start_music(music_url, parcel->mLocalID, region->getRegionID()); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 2ce77962ad..571cb3c711 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -6319,7 +6319,18 @@ void LLViewerWindow::revealIntroPanel() } } -void LLViewerWindow::setShowProgress(const BOOL show,BOOL fullscreen) +void LLViewerWindow::initTextures(S32 location_id) +{ + if (mProgressView) + { + // OpenSim support + //mProgressView->initTextures(location_id, LLGridManager::getInstance()->isInProductionGrid()); + mProgressView->initTextures(location_id, LLGridManager::getInstance()->isInSLMain()); + // + } +} + +void LLViewerWindow::setShowProgress(const BOOL show, BOOL fullscreen) { if(show) { @@ -6404,7 +6415,6 @@ void LLViewerWindow::setProgressCancelButtonVisible( BOOL b, const std::string& } } - LLProgressView *LLViewerWindow::getProgressView() const { return mProgressView; diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index 04b0308f57..1b9193c098 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -304,7 +304,8 @@ public: BOOL getCursorHidden() { return mCursorHidden; } void moveCursorToCenter(); // move to center of window - void setShowProgress(const BOOL show,BOOL fullscreen); + void initTextures(S32 location_id); + void setShowProgress(const BOOL show, BOOL fullscreen); BOOL getShowProgress() const; void setProgressString(const std::string& string); void setProgressPercent(const F32 percent); diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp index e18b42d025..da84f93d7d 100644 --- a/indra/newview/llxmlrpctransaction.cpp +++ b/indra/newview/llxmlrpctransaction.cpp @@ -265,6 +265,22 @@ void LLXMLRPCTransaction::Handler::onCompleted(LLCore::HttpHandle handle, // the contents of a buffer array are potentially noncontiguous, so we // will need to copy them into an contiguous block of memory for XMLRPC. LLCore::BufferArray *body = response->getBody(); + + // crash in transaction completion (see bugsplat https://app.bugsplat.com/v2/keycrash?database=fs_windows&stackKeyId=13) + if(body == nullptr) + { + // status should be 0 but log it anyway + // everything past this point appears to depend on the body data + // so log the issues and return. + LL_WARNS() + << "LLXMLRPCTransaction response has no body. status=" + << status.toHex() << ": " << status.toString() << LL_ENDL; + LL_WARNS() + << "LLXMLRPCTransaction request URI: " + << mImpl->mURI << LL_ENDL; + return; + } + // char * bodydata = new char[body->size()]; body->read(0, bodydata, body->size()); @@ -302,8 +318,7 @@ void LLXMLRPCTransaction::Handler::onCompleted(LLCore::HttpHandle handle, << faultString << LL_ENDL; LL_WARNS() << "LLXMLRPCTransaction request URI: " << mImpl->mURI << LL_ENDL; - } - + } } //========================================================================= diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 03932dfdd6..6cfcfc6135 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -459,7 +459,7 @@ void LLPipeline::init() sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips"); LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO"); - LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO"); + // Vertex Array Objects are required in OpenGL core profile //LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO"); LLVertexBuffer::sUseVAO = LLRender::sGLCoreProfile ? TRUE : gSavedSettings.getBOOL("RenderUseVAO"); // diff --git a/indra/newview/skins/ansastorm/xui/pl/panel_main_inventory.xml b/indra/newview/skins/ansastorm/xui/pl/panel_main_inventory.xml index 08621cdaf9..56b358453e 100644 --- a/indra/newview/skins/ansastorm/xui/pl/panel_main_inventory.xml +++ b/indra/newview/skins/ansastorm/xui/pl/panel_main_inventory.xml @@ -51,6 +51,11 @@ + + + + + diff --git a/indra/newview/skins/default/textures/3p_icons/fmod_logo.png b/indra/newview/skins/default/textures/3p_icons/fmod_logo.png new file mode 100644 index 0000000000..5a50e0ad34 Binary files /dev/null and b/indra/newview/skins/default/textures/3p_icons/fmod_logo.png differ diff --git a/indra/newview/skins/default/textures/3p_icons/havok_logo.png b/indra/newview/skins/default/textures/3p_icons/havok_logo.png new file mode 100644 index 0000000000..ff1ea3a72e Binary files /dev/null and b/indra/newview/skins/default/textures/3p_icons/havok_logo.png differ diff --git a/indra/newview/skins/default/textures/3p_icons/vivox_logo.png b/indra/newview/skins/default/textures/3p_icons/vivox_logo.png new file mode 100644 index 0000000000..6f20e87b7a Binary files /dev/null and b/indra/newview/skins/default/textures/3p_icons/vivox_logo.png differ diff --git a/indra/newview/skins/default/textures/icons/FMOD_logo.png b/indra/newview/skins/default/textures/icons/FMOD_logo.png deleted file mode 100644 index 0675b5d13d..0000000000 Binary files a/indra/newview/skins/default/textures/icons/FMOD_logo.png and /dev/null differ diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 24d25bc4aa..556070f542 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -584,6 +584,7 @@ with the same filename but different name + @@ -1048,7 +1049,6 @@ with the same filename but different name - diff --git a/indra/newview/skins/default/textures/widgets/ProgressBarSolid.png b/indra/newview/skins/default/textures/widgets/ProgressBarSolid.png new file mode 100644 index 0000000000..ec0926bfa1 Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/ProgressBarSolid.png differ diff --git a/indra/newview/skins/default/xui/de/floater_about.xml b/indra/newview/skins/default/xui/de/floater_about.xml index fe15e040ce..c47cace98e 100644 --- a/indra/newview/skins/default/xui/de/floater_about.xml +++ b/indra/newview/skins/default/xui/de/floater_about.xml @@ -44,6 +44,37 @@ UI-Künstler und Designer: + + 3Dconnexion SDK Copyright (C) 1992-2009 3Dconnexion. +APR Copyright (C) 2011 The Apache Software Foundation +Collada DOM Copyright 2006 Sony Computer Entertainment Inc. +cURL Copyright (C) 1996-2010, Daniel Stenberg (daniel@haxx.se). +DBus/dbus-glib Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc. +expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd. +FMOD Sound System Copyright (C) Firelight Technologies Pty, Ltd., 1994-2020 +FreeType Copyright (C) 1996-2002, 2006 David Turner, Robert Wilhelm und Werner Lemberg. +GL Copyright (C) 1999-2004 Brian Paul. +GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University sowie David Luebke, Brenden Schubert, University of Virginia. +Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited. +HACD Copyright (C) 2011, Khaled Mamou (kmamou@gmail.com) +jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW). +jpeglib Copyright (C) 1991-1998, Thomas G. Lane. +ogg/vorbis Copyright (C) 2002, Xiphophorus. +OpenSSL Copyright (C) 1998-2008 The OpenSSL Project. +PCRE Copyright (c) 1997-2012 University of Cambridge. +SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga. +SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com). +xmlrpc-epi Copyright (C) 2000 Epinions, Inc. +zlib Copyright (C) 1995-2012 Jean-loup Gailly und Mark Adler. + +Second Life Viewer verwendet Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (und Lizenzgeber). Alle Rechte vorbehalten. Details siehe www.havok.com. + +Diese Software enthält von der NVIDIA Corporation bereitgestellten Quellcode. + +Alle Rechte vorbehalten. Details siehe licenses.txt. + +Audiocodierung für Voice-Chat: Polycom(R) Siren14(TM) (ITU-T Rec. G.722.1 Annex C) + diff --git a/indra/newview/skins/default/xui/de/floater_save_pref_preset.xml b/indra/newview/skins/default/xui/de/floater_save_pref_preset.xml index 8acb33cedf..7fa7400495 100644 --- a/indra/newview/skins/default/xui/de/floater_save_pref_preset.xml +++ b/indra/newview/skins/default/xui/de/floater_save_pref_preset.xml @@ -1,11 +1,5 @@ - - Grafikvoreinstellung speichern - - - Kameravoreinstellung speichern - Geben Sie einen Namen für die Voreinstellung ein oder wählen Sie eine vorhandene Voreinstellung aus. diff --git a/indra/newview/skins/default/xui/de/panel_progress.xml b/indra/newview/skins/default/xui/de/panel_progress.xml new file mode 100644 index 0000000000..a5c5276a0d --- /dev/null +++ b/indra/newview/skins/default/xui/de/panel_progress.xml @@ -0,0 +1,23 @@ + + + + + + + + + + Anmeldung... + + + + + [APP_NAME] verwendet + + + + + + + + diff --git a/indra/newview/skins/default/xui/en/floater_about.xml b/indra/newview/skins/default/xui/en/floater_about.xml index 41d286ccc1..d7704a8bab 100644 --- a/indra/newview/skins/default/xui/en/floater_about.xml +++ b/indra/newview/skins/default/xui/en/floater_about.xml @@ -227,40 +227,17 @@ Adam Frisby, Alexandrea Fride, DarkAgent Baphomet, David Rowe, Digital Scribe, H label="Licenses" help_topic="about_licenses_tab" name="licenses_panel"> - - - - 3Dconnexion SDK Copyright (C) 1992-2009 3Dconnexion APR Copyright (C) 2011 The Apache Software Foundation @@ -293,70 +270,6 @@ All rights reserved. See licenses.txt for details. Voice chat Audio coding: Polycom(R) Siren14(TM) (ITU-T Rec. G.722.1 Annex C) - - - - - - - - - - - diff --git a/indra/newview/skins/default/xui/en/floater_fs_area_search.xml b/indra/newview/skins/default/xui/en/floater_fs_area_search.xml index 4c67afe116..722ea7d415 100644 --- a/indra/newview/skins/default/xui/en/floater_fs_area_search.xml +++ b/indra/newview/skins/default/xui/en/floater_fs_area_search.xml @@ -308,6 +308,7 @@ name="only_list" height="15" follows="top|left" + right="-5" left="5"> Only list objects that are: @@ -541,6 +542,7 @@ height="15" top_pad="5" follows="top|left" + right="-5" left="5"> Exclude objects that are: diff --git a/indra/newview/skins/default/xui/en/panel_progress.xml b/indra/newview/skins/default/xui/en/panel_progress.xml index 860caf2d21..5d68d67227 100644 --- a/indra/newview/skins/default/xui/en/panel_progress.xml +++ b/indra/newview/skins/default/xui/en/panel_progress.xml @@ -44,68 +44,128 @@ width="670" /> - - - - + left="0" + orientation="vertical" + name="vertical_centering" + animate="false" + top="0" + width="670"> + + + + + + + + + + + + + + [APP_NAME] uses + + + Use Region Settings Sky [INDEX]([ALTITUDE]m) No parcel is selected. Environmental settings are disabled. - Environmental settings are not available across region boundries. + Environmental settings are not available across region boundaries. Environmental settings are not available on this region. The estate manager does not allow changing parcel environments in this region. The parcel must be at least 128 square meters to support an environment. diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 5380fb6335..90e91d3c8b 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -369,17 +369,6 @@ to notecards on this region. Only items with unrestricted 'next owner' permissions -"can be attached to notecards. - - - - -Items of this type can't be attached -to notecards on this region. - - -Only items with unrestricted -'next owner' permissions can be attached to notecards. diff --git a/indra/newview/skins/default/xui/en/widgets/density_ctrl.xml b/indra/newview/skins/default/xui/en/widgets/density_ctrl.xml index 0f3f0159db..eb665fd3cb 100644 --- a/indra/newview/skins/default/xui/en/widgets/density_ctrl.xml +++ b/indra/newview/skins/default/xui/en/widgets/density_ctrl.xml @@ -13,6 +13,7 @@ follows="left|top" height="11" layout="topleft" + name="exponential_term_label" left="15" top_pad="-5" width="120"> @@ -45,6 +46,7 @@ Exponential Term follows="left|top" height="11" layout="topleft" + name="exponential_scale_factor_label" left="15" top_pad="-5" width="120"> @@ -69,6 +71,7 @@ Exponential Scale Factor follows="left|top" height="11" layout="topleft" + name="linear_term_label" left="15" top_pad="-5" width="120"> @@ -93,6 +96,7 @@ Linear Term follows="left|top" height="11" layout="topleft" + name="constant_term_label" left="15" top_pad="-5" width="120"> @@ -117,6 +121,7 @@ Constant Term follows="left|top" height="11" layout="topleft" + name="max_altitude_label" left="15" top_pad="15" width="80"> diff --git a/indra/newview/skins/default/xui/es/floater_about.xml b/indra/newview/skins/default/xui/es/floater_about.xml index 061a2bdeef..e26053dc17 100644 --- a/indra/newview/skins/default/xui/es/floater_about.xml +++ b/indra/newview/skins/default/xui/es/floater_about.xml @@ -83,6 +83,38 @@ Artistas y Diseñadores de la interfaz: + +3Dconnexion SDK Copyright (C) 1992-2009 3Dconnexion +APR Copyright (C) 2011 The Apache Software Foundation +Collada DOM Copyright 2006 Sony Computer Entertainment Inc. +cURL Copyright (C) 1996-2010, Daniel Stenberg, (daniel@haxx.se) +DBus/dbus-glib Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc. +expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd. +FMOD Sound System, Copyright (C) Firelight Technologies Pty, Ltd., 1994-2020 +FreeType Copyright (C) 1996-2002, 2006 David Turner, Robert Wilhelm, y Werner Lemberg. +GL Copyright (C) 1999-2004 Brian Paul. +GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University and David Luebke, Brenden Schubert, University of Virginia. +Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited. +HACD Copyright (C) 2011, Khaled Mamou (kmamou@gmail.com) +jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW) +jpeglib Copyright (C) 1991-1998, Thomas G. Lane. +ogg/vorbis Copyright (C) 2002, Xiphophorus +OpenSSL Copyright (C) 1998-2008 The OpenSSL Project. +PCRE Copyright (c) 1997-2012 University of Cambridge +SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga +SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) +xmlrpc-epi Copyright (C) 2000 Epinions, Inc. +zlib Copyright (C) 1995-2012 Jean-loup Gailly y Mark Adler. +Algunos iconos por Joseph Wain / glyphish.com + +Second Life Viewer usa Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (y sus licenciadores). Todos los derechos reservados. Ver www.havok.com para más detalles. + +Este software contiene código fuente proporcionado por NVIDIA Corporation. + +Todos los derechos reservados. Ver licenses.txt para más detalles. + +Codificación de audio del chat de voz: Polycom(R) Siren14(TM) (ITU-T Rec. G.722.1 Annex C) + diff --git a/indra/newview/skins/default/xui/it/floater_about.xml b/indra/newview/skins/default/xui/it/floater_about.xml index 9ff9741d40..02dd582ab0 100644 --- a/indra/newview/skins/default/xui/it/floater_about.xml +++ b/indra/newview/skins/default/xui/it/floater_about.xml @@ -64,6 +64,37 @@ con contributi open source da: + + 3Dconnexion SDK Copyright (C) 1992-2009 3Dconnexion +APR Copyright (C) 2011 The Apache Software Foundation +Collada DOM Copyright 2006 Sony Computer Entertainment Inc. +cURL Copyright (C) 1996-2010, Daniel Stenberg, (daniel@haxx.se) +DBus/dbus-glib Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc. +expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd. +FMOD Sound System Copyright (C) Firelight Technologies Pty, Ltd., 1994-2020 +FreeType Copyright (C) 1996-2002, 2006 David Turner, Robert Wilhelm, and Werner Lemberg. +GL Copyright (C) 1999-2004 Brian Paul. +GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University and David Luebke, Brenden Schubert, University of Virginia. +Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited. +HACD Copyright (C) 2011, Khaled Mamou (kmamou@gmail.com) +jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW) +jpeglib Copyright (C) 1991-1998, Thomas G. Lane. +ogg/vorbis Copyright (C) 2002, Xiphophorus +OpenSSL Copyright (C) 1998-2008 The OpenSSL Project. +PCRE Copyright (c) 1997-2012 University of Cambridge +SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga +SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) +xmlrpc-epi Copyright (C) 2000 Epinions, Inc. +zlib Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler. + +Il Viewer Second Life utilizza Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (e licenziatari). Tutti i diritti riservati. Per informazioni dettagliate, vedere www.havok.com. + +Questo software contiene codice sorgente fornito da NVIDIA Corporation. + +Tutti i diritti riservati. Per informazioni dettagliate, vedere licenses.txt. + +Codifica audio chat vocale: Polycom(R) Siren14(TM) (ITU-T Rec. G.722.1 Annex C) + diff --git a/indra/newview/skins/default/xui/ja/floater_about.xml b/indra/newview/skins/default/xui/ja/floater_about.xml index 0e0b04d33f..e913cf9497 100644 --- a/indra/newview/skins/default/xui/ja/floater_about.xml +++ b/indra/newview/skins/default/xui/ja/floater_about.xml @@ -11,6 +11,34 @@ Dummy Name は実行時間に置き換え + 3Dconnexion SDK Copyright (C) 1992-2009 3Dconnexion +APR Copyright (C) 2011 The Apache Software Foundation +Collada DOM Copyright 2006 Sony Computer Entertainment Inc. +cURL Copyright (C) 1996-2010, Daniel Stenberg, (daniel@haxx.se) +DBus/dbus-glib Copyright (C) 2002, 2003 CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc. +expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd. +FMOD Sound System Copyright (C) Firelight Technologies Pty, Ltd., 1994-2020 +FreeType Copyright (C) 1996-2002, 2006 David Turner, Robert Wilhelm, and Werner Lemberg. +GL Copyright (C) 1999-2004 Brian Paul. +GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University and David Luebke, Brenden Schubert, University of Virginia. +Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited. +jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW) +jpeglib Copyright (C) 1991-1998, Thomas G. Lane. +ogg/vorbis Copyright (C) 2002, Xiphophorus +OpenSSL Copyright (C) 1998-2008 The OpenSSL Project. +PCRE Copyright (c) 1997-2012 University of Cambridge +SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga +SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) +xmlrpc-epi Copyright (C) 2000 Epinions, Inc. +zlib Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler. + +Second Life ビューワでは Havok (TM) Physics が使用されています。(c)Copyright 1999-2010 Havok.com Inc. (and its Licensors).無断複写・複製・転載を禁じます。詳細については www.havok.com をご参照ください。 + +このソフトウェアには、NVIDIA Corporation によるソースコードが含まれます。 + +無断複写・複製・転載を禁じます。詳細については licenses.txt をご参照ください。 + +ボイスチャットのオーディオコーディング:Polycom(R) Siren14(TM) (ITU-T Rec.G.722.1 Annex C) diff --git a/indra/newview/skins/default/xui/pl/floater_about_land.xml b/indra/newview/skins/default/xui/pl/floater_about_land.xml index c92019b84b..46dbd31599 100644 --- a/indra/newview/skins/default/xui/pl/floater_about_land.xml +++ b/indra/newview/skins/default/xui/pl/floater_about_land.xml @@ -452,5 +452,6 @@ teksturę: + diff --git a/indra/newview/skins/default/xui/pl/floater_adjust_environment.xml b/indra/newview/skins/default/xui/pl/floater_adjust_environment.xml new file mode 100644 index 0000000000..5966ca63c9 --- /dev/null +++ b/indra/newview/skins/default/xui/pl/floater_adjust_environment.xml @@ -0,0 +1,74 @@ + + + + + + + + Otoczenie: + + + Hor. błękitu: + + + Gęst. błękitu: + + + + + + + @@ -114,6 +120,8 @@ + + diff --git a/indra/newview/skins/default/xui/pl/menu_inventory_add.xml b/indra/newview/skins/default/xui/pl/menu_inventory_add.xml index e5f3c2710a..1e228cc987 100644 --- a/indra/newview/skins/default/xui/pl/menu_inventory_add.xml +++ b/indra/newview/skins/default/xui/pl/menu_inventory_add.xml @@ -33,4 +33,9 @@ + + + + + diff --git a/indra/newview/skins/default/xui/pl/menu_save_settings.xml b/indra/newview/skins/default/xui/pl/menu_save_settings.xml new file mode 100644 index 0000000000..918fc75184 --- /dev/null +++ b/indra/newview/skins/default/xui/pl/menu_save_settings.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/indra/newview/skins/default/xui/pl/menu_settings_add.xml b/indra/newview/skins/default/xui/pl/menu_settings_add.xml new file mode 100644 index 0000000000..6cb3a68898 --- /dev/null +++ b/indra/newview/skins/default/xui/pl/menu_settings_add.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/indra/newview/skins/default/xui/pl/menu_settings_gear.xml b/indra/newview/skins/default/xui/pl/menu_settings_gear.xml new file mode 100644 index 0000000000..a002d3c236 --- /dev/null +++ b/indra/newview/skins/default/xui/pl/menu_settings_gear.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/pl/menu_viewer.xml b/indra/newview/skins/default/xui/pl/menu_viewer.xml index fd4ad6dbd0..0c2a800e62 100644 --- a/indra/newview/skins/default/xui/pl/menu_viewer.xml +++ b/indra/newview/skins/default/xui/pl/menu_viewer.xml @@ -105,31 +105,31 @@ - + - + + + + - - + @@ -463,6 +463,9 @@ + + + @@ -488,7 +491,7 @@ - + diff --git a/indra/newview/skins/default/xui/pl/notifications.xml b/indra/newview/skins/default/xui/pl/notifications.xml index d1e3f32ad2..5d49484e6c 100644 --- a/indra/newview/skins/default/xui/pl/notifications.xml +++ b/indra/newview/skins/default/xui/pl/notifications.xml @@ -1989,6 +1989,11 @@ Kontynuować? Odznaczenie tej opcji może usunąć ograniczenia nadane przez właścicieli działek w celu zapobiegania dokuczaniu, zachowaniu prywatności lub aby chronić nieletnich przed materiałami dla dorosłych. Porozmawiaj z właścicielami działek, jeśli to konieczne. + + (Zmiana w całym majątku: [ESTATENAME]) Odznaczenie tej opcji spowoduje usunięcie wszelkich niestandardowych otoczeń, które zostały dodane do działek przez ich właścicieli. Przedyskutuj zmianę z właścicielami działek w razie potrzeby. +Czy chcesz kontynuować? + + Na pewno chcesz zmienić treść umowy dla tego majątku? @@ -2454,7 +2459,15 @@ Zamieść go na stronie internetowej żeby umożliwić innym łatwy dostęp do t Ten plik cyklu dziennego używa brakującego pliku nieba: [SKY]. - Ustawienia nie mogą zostać zastosowane w regionie. Opuszczenie regionu, a następnie powrócenie do niego może naprawić problem. Powód: [FAIL_REASON] + Ustawienia nie mogą zostać zastosowane w regionie. Powód: [FAIL_REASON] + + + Lokalna tekstura jest używana na ścieżce [TRACK], klatce #[FRAMENO] ([FRAME]%) w polu [FIELD]. +Otoczenia nie mogą zostać zapisane gdy lokalne tekstury są w użyciu. + + + Lokalna tekstura jest używana w polu [FIELD]. +Otoczenia nie mogą zostać zapisane gdy lokalne tekstury są w użyciu. Nie można usunąć ostatniego klucza w cyklu dnia, bo nie może on być pusty. Zmodyfikuj ten klucz zamiast go usuwać, a potem dodaj nowy. @@ -3394,6 +3407,10 @@ Zostaną zablokowane na kilka sekund dla bezpieczeństwa. Nie można zastąpić domyślnego ustawienia. + + '[NAME]' jest w użyciu. Możesz zastąpić +to ustawienie lub wybrać inną nazwę. + Błąd podczas usuwania ustawienia [NAME]. @@ -4963,4 +4980,92 @@ Jeśli nie zgadzasz się z niniejszymi warunkami użytkowania, nie należy przep Włączenie obsługi HiDPI może mieć niekorzystne skutki i pogorszyć wydajność. + + + + + + + + + + + + + + Nie można załadować ustawień dla [NAME] z bazy danych. + + + Nie można zastosować tych ustawień do otoczenia. + + + Nie można zastosować tych ustawień do otoczenia. + + + Ten region nie obsługuje ustawień otoczenia. + + + Zapisz bieżące ustawienia otoczenia jako: +
+ + [DESC] (nowe) + +
+ + + + +
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 686a33a4be..d2f0f874bb 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -570,6 +570,7 @@ class WindowsManifest(ViewerManifest): # self.path("*.gif") # Remove VMP + # Plugin host application self.path2basename(os.path.join(os.pardir, 'llplugin', 'slplugin', self.args['configuration']), @@ -586,21 +587,14 @@ class WindowsManifest(ViewerManifest): print err.message print "Skipping GLOD library (assumming linked statically)" - # Get fmodstudio dll - if self.args['fmodversion'].lower() == 'fmodstudio': - if self.args['configuration'].lower() == 'debug': + # Get fmodstudio dll if needed + if self.args['fmodstudio'] == 'ON': + if(self.args['configuration'].lower() == 'debug'): self.path("fmodL.dll") else: self.path("fmod.dll") - # Get fmodex dll - if self.args['fmodversion'].lower() == 'fmodex': - if(self.address_size == 64): - self.path("fmodex64.dll") - else: - self.path("fmodex.dll") - - # Get openal dll + # Get openal dll if needed if self.args.get('openal') == 'ON': self.path("OpenAL32.dll") self.path("alut.dll") @@ -1171,17 +1165,18 @@ class DarwinManifest(ViewerManifest): # ): # self.path2basename(relpkgdir, libfile) - # # dylibs that vary based on configuration - # if self.args['configuration'].lower() == 'debug': - # for libfile in ( - # "libfmodexL.dylib", - # ): - # dylibs += path_optional(os.path.join(debpkgdir, libfile), libfile) - # else: - # for libfile in ( - # "libfmodex.dylib", - # ): - # dylibs += path_optional(os.path.join(relpkgdir, libfile), libfile) + # # Fmod studio dylibs (vary based on configuration) + # if self.args['fmodstudio'] == 'ON': + # if self.args['configuration'].lower() == 'debug': + # for libfile in ( + # "libfmodL.dylib", + # ): + # dylibs += path_optional(os.path.join(debpkgdir, libfile), libfile) + # else: + # for libfile in ( + # "libfmod.dylib", + # ): + # dylibs += path_optional(os.path.join(relpkgdir, libfile), libfile) # # our apps # executable_path = {} @@ -1441,8 +1436,8 @@ class DarwinManifest(ViewerManifest): ): self.path2basename(relpkgdir, libfile) - # dylibs that vary based on configuration - if self.args['fmodversion'].lower() == 'fmodstudio': + # Fmod studio dylibs (vary based on configuration) + if self.args['fmodstudio'] == 'ON': if self.args['configuration'].lower() == 'debug': for libfile in ( "libfmodL.dylib", @@ -1454,19 +1449,6 @@ class DarwinManifest(ViewerManifest): ): dylibs += path_optional(os.path.join(relpkgdir, libfile), libfile) - # dylibs that vary based on configuration - if self.args['fmodversion'].lower() == 'fmodex': - if self.args['configuration'].lower() == 'debug': - for libfile in ( - "libfmodexL.dylib", - ): - dylibs += path_optional(os.path.join(debpkgdir, libfile), libfile) - else: - for libfile in ( - "libfmodex.dylib", - ): - dylibs += path_optional(os.path.join(relpkgdir, libfile), libfile) - # our apps executable_path = {} for app_bld_dir, app in (("mac_crash_logger", "mac-crash-logger.app"), @@ -2199,16 +2181,14 @@ class Linux_i686_Manifest(LinuxManifest): print "tcmalloc files not found, skipping" pass - if self.args['fmodversion'].lower() == 'fmodex': - self.path("libfmodex-*.so") - self.path("libfmodex.so") - self.path("libfmodex.so*") - pass - - if self.args['fmodversion'].lower() == 'fmodstudio': - self.path("libfmod.so") - self.path("libfmod.so*") - pass + if self.args['fmodstudio'] == 'ON': + try: + self.path("libfmod.so") + self.path("libfmod.so*") + pass + except: + print "Skipping libfmod.so - not found" + pass # Vivox runtimes @@ -2243,16 +2223,15 @@ class Linux_x86_64_Manifest(LinuxManifest): # No, we don't need to dink with this. A usable library # is now in the slvoice package, and we need to just use it as is. # self.path("libopenal32.so", "libvivoxoal.so.1") # vivox's sdk expects this soname - if self.args['fmodversion'].lower() == 'fmodex': - self.path("libfmodex64-*.so") - self.path("libfmodex64.so") - self.path("libfmodex64.so*") - pass - if self.args['fmodversion'].lower() == 'fmodstudio': - self.path("libfmod.so") - self.path("libfmod.so*") - pass + if self.args['fmodstudio'] == 'ON': + try: + self.path("libfmod.so") + self.path("libfmod.so*") + pass + except: + print "Skipping libfmod.so - not found" + pass with self.prefix(dst="bin"): self.path2basename("../llplugin/slplugin", "SLPlugin") @@ -2307,6 +2286,7 @@ if __name__ == "__main__": extra_arguments = [ dict(name='bugsplat', description="""BugSplat database to which to post crashes, if BugSplat crash reporting is desired""", default=''), + dict(name='fmodstudio', description="""Indication if fmod studio libraries are needed""", default='OFF'), dict(name='openal', description="""Indication openal libraries are needed""", default='OFF') ] try: diff --git a/scripts/configure_firestorm.sh b/scripts/configure_firestorm.sh index 3ce2959fec..447c931687 100755 --- a/scripts/configure_firestorm.sh +++ b/scripts/configure_firestorm.sh @@ -16,7 +16,6 @@ FALSE=1 # -DROOT_PROJECT_NAME:STRING=SecondLife # -DUSE_KDU=TRUE # -DFMODSTUDIO:BOOL=ON -# -DFMODEX:BOOL=ON # -DOPENSIM:BOOL=ON # -DUSE_AVX_OPTIMIZATION:BOOL=OFF # -DUSE_AVX2_OPTIMIZATION:BOOL=OFF @@ -34,7 +33,6 @@ WANTS_PACKAGE=$FALSE WANTS_VERSION=$FALSE WANTS_KDU=$FALSE WANTS_FMODSTUDIO=$FALSE -WANTS_FMODEX=$FALSE WANTS_OPENAL=$FALSE WANTS_OPENSIM=$TRUE WANTS_SINGLEGRID=$FALSE @@ -72,7 +70,6 @@ showUsage() echo " --package : Build installer" echo " --no-package : Build without installer (Overrides --package)" echo " --fmodstudio : Build with FMOD Studio" - echo " --fmodex : Build with FMOD Ex" echo " --openal : Build with OpenAL" echo " --opensim : Build with OpenSim support (Disables Havok features)" echo " --no-opensim : Build without OpenSim support (Overrides --opensim)" @@ -93,7 +90,7 @@ getArgs() # $* = the options passed in from main { if [ $# -gt 0 ]; then - while getoptex "clean build config version package no-package fmodstudio fmodex openal ninja jobs: platform: kdu opensim no-opensim singlegrid: avx avx2 crashreporting testbuild: help chan: btype:" "$@" ; do + while getoptex "clean build config version package no-package fmodstudio openal ninja jobs: platform: kdu opensim no-opensim singlegrid: avx avx2 crashreporting testbuild: help chan: btype:" "$@" ; do #ensure options are valid if [ -z "$OPTOPT" ] ; then @@ -112,7 +109,6 @@ getArgs() ;; kdu) WANTS_KDU=$TRUE;; fmodstudio) WANTS_FMODSTUDIO=$TRUE;; - fmodex) WANTS_FMODEX=$TRUE;; openal) WANTS_OPENAL=$TRUE;; opensim) WANTS_OPENSIM=$TRUE;; no-opensim) WANTS_OPENSIM=$FALSE;; @@ -300,7 +296,6 @@ echo -e "configure_firestorm.sh" > $LOG echo -e " PLATFORM: $PLATFORM" | tee -a $LOG echo -e " KDU: `b2a $WANTS_KDU`" | tee -a $LOG echo -e " FMODSTUDIO: `b2a $WANTS_FMODSTUDIO`" | tee -a $LOG -echo -e " FMODEX: `b2a $WANTS_FMODEX`" | tee -a $LOG echo -e " OPENAL: `b2a $WANTS_OPENAL`" | tee -a $LOG echo -e " OPENSIM: `b2a $WANTS_OPENSIM`" | tee -a $LOG if [ $WANTS_SINGLEGRID -eq $TRUE ] ; then @@ -429,11 +424,6 @@ if [ $WANTS_CONFIG -eq $TRUE ] ; then else FMODSTUDIO="-DFMODSTUDIO:BOOL=OFF" fi - if [ $WANTS_FMODEX -eq $TRUE ] ; then - FMODEX="-DFMODEX:BOOL=ON" - else - FMODEX="-DFMODEX:BOOL=OFF" - fi if [ $WANTS_OPENAL -eq $TRUE ] ; then OPENAL="-DOPENAL:BOOL=ON" else @@ -517,7 +507,7 @@ if [ $WANTS_CONFIG -eq $TRUE ] ; then UNATTENDED="-DUNATTENDED=ON" fi - cmake -G "$TARGET" ../indra $CHANNEL ${GITHASH} $FMODSTUDIO $FMODEX $OPENAL $KDU $OPENSIM $SINGLEGRID $AVX_OPTIMIZATION $AVX2_OPTIMIZATION $TESTBUILD $PACKAGE \ + cmake -G "$TARGET" ../indra $CHANNEL ${GITHASH} $FMODSTUDIO $OPENAL $KDU $OPENSIM $SINGLEGRID $AVX_OPTIMIZATION $AVX2_OPTIMIZATION $TESTBUILD $PACKAGE \ $UNATTENDED -DLL_TESTS:BOOL=OFF -DADDRESS_SIZE:STRING=$AUTOBUILD_ADDRSIZE -DCMAKE_BUILD_TYPE:STRING=$BTYPE \ $CRASH_REPORTING -DVIEWER_SYMBOL_FILE:STRING="${VIEWER_SYMBOL_FILE:-}" -DROOT_PROJECT_NAME:STRING=Firestorm $LL_ARGS_PASSTHRU | tee $LOG