From 1d2995666f8448d9b2235d82782ba2f58e91dc84 Mon Sep 17 00:00:00 2001 From: Drake Arconis Date: Sat, 16 Jan 2016 13:07:51 -0500 Subject: [PATCH] Remove FMOD Ex --- indra/cmake/CMakeLists.txt | 1 - indra/cmake/FMODEX.cmake | 116 --- indra/cmake/FMODSTUDIO.cmake | 11 +- indra/llaudio/CMakeLists.txt | 21 +- indra/llaudio/llaudioengine_fmodex.cpp | 1027 -------------------- indra/llaudio/llaudioengine_fmodex.h | 139 --- indra/llaudio/llaudioengine_fmodstudio.cpp | 2 +- indra/llaudio/lllistener_fmodex.cpp | 141 --- indra/llaudio/lllistener_fmodex.h | 71 -- indra/llaudio/llstreamingaudio_fmodex.cpp | 596 ------------ indra/llaudio/llstreamingaudio_fmodex.h | 89 -- indra/newview/CMakeLists.txt | 11 +- indra/newview/llappviewer.cpp | 14 +- indra/newview/llstartup.cpp | 15 - 14 files changed, 11 insertions(+), 2243 deletions(-) delete mode 100644 indra/cmake/FMODEX.cmake delete mode 100644 indra/llaudio/llaudioengine_fmodex.cpp delete mode 100644 indra/llaudio/llaudioengine_fmodex.h delete mode 100644 indra/llaudio/lllistener_fmodex.cpp delete mode 100644 indra/llaudio/lllistener_fmodex.h delete mode 100644 indra/llaudio/llstreamingaudio_fmodex.cpp delete mode 100644 indra/llaudio/llstreamingaudio_fmodex.h diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt index 70e448385..3c53fade8 100644 --- a/indra/cmake/CMakeLists.txt +++ b/indra/cmake/CMakeLists.txt @@ -27,7 +27,6 @@ set(cmake_SOURCE_FILES ELFIO.cmake EXPAT.cmake ExamplePlugin.cmake - FMODEX.cmake FMODSTUDIO.cmake FindAPR.cmake FindAutobuild.cmake diff --git a/indra/cmake/FMODEX.cmake b/indra/cmake/FMODEX.cmake deleted file mode 100644 index ae95866c4..000000000 --- a/indra/cmake/FMODEX.cmake +++ /dev/null @@ -1,116 +0,0 @@ -# -*- cmake -*- - -include(Linking) - -if (FMODEX AND FMODSTUDIO) - message( FATAL_ERROR "You can not enable two FMOD variants at the same time." ) -endif (FMODEX AND FMODSTUDIO) - -unset(FMOD_LIBRARY_RELEASE CACHE) -unset(FMOD_LIBRARY_DEBUG CACHE) -unset(FMOD_INCLUDE_DIR CACHE) - -set(FMOD_EXTERNAL_LIB OFF) - -if(STANDALONE OR WINDOWS) - if (NOT FMODEX_SDK_DIR AND WINDOWS) - GET_FILENAME_COMPONENT(REG_DIR [HKEY_CURRENT_USER\\Software\\FMOD\ Programmers\ API\ Windows] ABSOLUTE) - set(FMODEX_SDK_DIR ${REG_DIR} CACHE PATH "Path to the FMOD Ex SDK." FORCE) - endif (NOT FMODEX_SDK_DIR AND WINDOWS) - if(NOT FMODEX_SDK_DIR AND STANDALONE) - message(FATAL_ERROR "FMODEX_SDK_DIR not set!") - endif(NOT FMODEX_SDK_DIR AND STANDALONE) -endif(STANDALONE OR WINDOWS) - -if(FMODEX_SDK_DIR) - set(fmod_lib_paths "${FMODEX_SDK_DIR}/api" "${FMODEX_SDK_DIR}/api/lib" ) - set(fmod_inc_paths "${FMODEX_SDK_DIR}/api/inc") - - if(WINDOWS) - set(CMAKE_FIND_LIBRARY_SUFFIXES_OLD ${CMAKE_FIND_LIBRARY_SUFFIXES}) - set(CMAKE_FIND_LIBRARY_SUFFIXES .dll) - endif(WINDOWS) - if(WORD_SIZE EQUAL 64) - find_library(FMOD_LIBRARY_RELEASE fmodex64 PATHS ${fmod_lib_paths} NO_DEFAULT_PATH) - find_library(FMOD_LIBRARY_DEBUG fmodexL64 PATHS ${fmod_lib_paths} NO_DEFAULT_PATH) - else(WORD_SIZE EQUAL 64)#Check if CMAKE_FIND_LIBRARY_PREFIXES is set to 'lib' for darwin. - find_library(FMOD_LIBRARY_RELEASE fmodex PATHS ${fmod_lib_paths} NO_DEFAULT_PATH) - find_library(FMOD_LIBRARY_DEBUG fmodexL PATHS ${fmod_lib_paths} NO_DEFAULT_PATH) - endif(WORD_SIZE EQUAL 64) - if(WINDOWS) - set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES_OLD}) - if(WORD_SIZE EQUAL 64) - find_library(FMOD_LINK_LIBRARY_RELEASE fmodex64_vc PATHS ${fmod_lib_paths} NO_DEFAULT_PATH) - find_library(FMOD_LINK_LIBRARY_DEBUG fmodexL64_vc PATHS ${fmod_lib_paths} NO_DEFAULT_PATH) - else(WORD_SIZE EQUAL 64)#Check if CMAKE_FIND_LIBRARY_PREFIXES is set to 'lib' for darwin. - find_library(FMOD_LINK_LIBRARY_RELEASE fmodex_vc PATHS ${fmod_lib_paths} NO_DEFAULT_PATH) - find_library(FMOD_LINK_LIBRARY_DEBUG fmodexL_vc PATHS ${fmod_lib_paths} NO_DEFAULT_PATH) - endif(WORD_SIZE EQUAL 64) - else(WINDOWS) - set(FMOD_LINK_LIBRARY_RELEASE ${FMOD_LIBRARY_RELEASE}) - set(FMOD_LINK_LIBRARY_DEBUG ${FMOD_LIBRARY_DEBUG}) - endif(WINDOWS) - find_path(FMOD_INCLUDE_DIR fmod.hpp ${fmod_inc_paths}) - if(NOT FMOD_LIBRARY_RELEASE OR NOT FMOD_INCLUDE_DIR) - if(STANDALONE) - message(FATAL_ERROR "Provided FMODEX_SDK_DIR path not found '{$FMODEX_SDK_DIR}'") - else(STANDALONE) - message(STATUS "Provided FMODEX_SDK_DIR path not found '${FMODEX_SDK_DIR}'. Falling back to prebuilts") - endif(STANDALONE) - else(NOT FMOD_LIBRARY_RELEASE OR NOT FMOD_INCLUDE_DIR) - message(STATUS "Using system-provided FMOD Ex Libraries") - set(FMOD_EXTERNAL_LIB ON) - endif(NOT FMOD_LIBRARY_RELEASE OR NOT FMOD_INCLUDE_DIR) -endif (FMODEX_SDK_DIR) - -if (NOT FMOD_LIBRARY_RELEASE OR NOT FMOD_INCLUDE_DIR) - if(WINDOWS) - set(lib_suffix .dll) - elseif(DARWIN) - set(lib_suffix .dylib) - else(WINDOWS) - set(lib_suffix .so) - endif(WINDOWS) - if(WINDOWS) - if(WORD_SIZE EQUAL 64) - set(FMOD_LIBRARY_RELEASE ${LIBS_PREBUILT_DIR}/lib/release/fmodex64${lib_suffix}) - set(FMOD_LIBRARY_DEBUG ${LIBS_PREBUILT_DIR}/lib/debug/fmodexL64${lib_suffix}) - else(WORD_SIZE EQUAL 64) - set(FMOD_LIBRARY_RELEASE ${LIBS_PREBUILT_DIR}/lib/release/fmodex${lib_suffix}) - set(FMOD_LIBRARY_DEBUG ${LIBS_PREBUILT_DIR}/lib/debug/fmodexL${lib_suffix}) - endif(WORD_SIZE EQUAL 64) - else(WINDOWS) - if(WORD_SIZE EQUAL 64) - set(FMOD_LIBRARY_RELEASE ${LIBS_PREBUILT_DIR}/lib/release/libfmodex64${lib_suffix}) - set(FMOD_LIBRARY_DEBUG ${LIBS_PREBUILT_DIR}/lib/debug/libfmodex64L${lib_suffix}) - else(WORD_SIZE EQUAL 64) - set(FMOD_LIBRARY_RELEASE ${LIBS_PREBUILT_DIR}/lib/release/libfmodex${lib_suffix}) - set(FMOD_LIBRARY_DEBUG ${LIBS_PREBUILT_DIR}/lib/debug/libfmodexL${lib_suffix}) - endif(WORD_SIZE EQUAL 64) - endif(WINDOWS) - set(FMOD_LINK_LIBRARY_RELEASE ${FMOD_LIBRARY_RELEASE}) - set(FMOD_LINK_LIBRARY_DEBUG ${FMOD_LIBRARY_DEBUG}) - if(WINDOWS) - string(REPLACE ".dll" "_vc.lib" FMOD_LINK_LIBRARY_RELEASE ${FMOD_LIBRARY_RELEASE}) - string(REPLACE ".dll" "_vc.lib" FMOD_LINK_LIBRARY_DEBUG ${FMOD_LIBRARY_DEBUG}) - endif(WINDOWS) - use_prebuilt_binary(fmodex) - set(FMOD_INCLUDE_DIR - ${LIBS_PREBUILT_DIR}/include/fmodex) -endif(NOT FMOD_LIBRARY_RELEASE OR NOT FMOD_INCLUDE_DIR) - -if(FMOD_LIBRARY_RELEASE AND FMOD_INCLUDE_DIR) - set(FMOD ON) - if (NOT FMOD_LIBRARY_DEBUG) #Use release library in debug configuration if debug library is absent. - set(FMOD_LIBRARY_DEBUG ${FMOD_LIBRARY_RELEASE}) - endif (NOT FMOD_LIBRARY_DEBUG) -else (FMOD_LIBRARY_RELEASE AND FMOD_INCLUDE_DIR) - message(STATUS "No support for FMOD EX audio (need to set FMODEX_SDK_DIR?)") - set(FMOD OFF) - set(FMODEX OFF) -endif (FMOD_LIBRARY_RELEASE AND FMOD_INCLUDE_DIR) - -if (FMOD) - message(STATUS "Building with FMOD Ex audio support") - set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_FMODEX") -endif (FMOD) diff --git a/indra/cmake/FMODSTUDIO.cmake b/indra/cmake/FMODSTUDIO.cmake index bfaf6ac66..e7ce595ef 100644 --- a/indra/cmake/FMODSTUDIO.cmake +++ b/indra/cmake/FMODSTUDIO.cmake @@ -2,10 +2,6 @@ include(Linking) -if (FMODEX AND FMODSTUDIO) - message( FATAL_ERROR "You can not enable two FMOD variants at the same time." ) -endif (FMODEX AND FMODSTUDIO) - unset(FMOD_LIBRARY_RELEASE CACHE) unset(FMOD_LIBRARY_DEBUG CACHE) unset(FMOD_INCLUDE_DIR CACHE) @@ -86,10 +82,17 @@ if (NOT FMOD_LIBRARY_RELEASE OR NOT FMOD_INCLUDE_DIR) endif(WINDOWS) set(FMOD_LINK_LIBRARY_RELEASE ${FMOD_LIBRARY_RELEASE}) set(FMOD_LINK_LIBRARY_DEBUG ${FMOD_LIBRARY_DEBUG}) + if(WINDOWS) string(REPLACE ".dll" "_vc.lib" FMOD_LINK_LIBRARY_RELEASE ${FMOD_LIBRARY_RELEASE}) string(REPLACE ".dll" "_vc.lib" FMOD_LINK_LIBRARY_DEBUG ${FMOD_LIBRARY_DEBUG}) endif(WINDOWS) + + set (FMOD_LIBRARY + debug ${FMOD_LINK_LIBRARY_DEBUG} + optimized ${FMOD_LINK_LIBRARY_RELEASE} + ) + use_prebuilt_binary(fmodstudio) set(FMOD_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/fmodstudio) diff --git a/indra/llaudio/CMakeLists.txt b/indra/llaudio/CMakeLists.txt index 9644dc5a8..f6ea97d07 100644 --- a/indra/llaudio/CMakeLists.txt +++ b/indra/llaudio/CMakeLists.txt @@ -5,12 +5,7 @@ project(llaudio) include(00-Common) include(Audio) include(LLAudio) -if (FMODSTUDIO) - include(FMODSTUDIO) -endif (FMODSTUDIO) -if (FMODEX) - include(FMODEX) -endif (FMODEX) +include(FMODSTUDIO) include(OPENAL) include(LLCommon) include(LLMath) @@ -68,20 +63,6 @@ if (FMODSTUDIO) ) endif (FMODSTUDIO) -if (FMODEX) - 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) list(APPEND llaudio_SOURCE_FILES llaudioengine_openal.cpp diff --git a/indra/llaudio/llaudioengine_fmodex.cpp b/indra/llaudio/llaudioengine_fmodex.cpp deleted file mode 100644 index 8b71012ba..000000000 --- a/indra/llaudio/llaudioengine_fmodex.cpp +++ /dev/null @@ -1,1027 +0,0 @@ -/** - * @file audioengine_FMODEX.cpp - * @brief Implementation of LLAudioEngine class abstracting the audio support as a FMOD 3D implementation - * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/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" - -#if LL_WINDOWS //Some ugly code to make missing fmodex.dll not cause a fatal error. -#define WIN32_LEAN_AND_MEAN -#include "windows.h" -#include -#pragma comment(lib, "delayimp.lib") - -bool attemptDelayLoad() -{ - __try - { -#if defined(_WIN64) - if( FAILED( __HrLoadAllImportsForDll( "fmodex64.dll" ) ) ) - return false; -#else - if( FAILED( __HrLoadAllImportsForDll( "fmodex.dll" ) ) ) - return false; -#endif - } - __except( EXCEPTION_EXECUTE_HANDLER ) - { - return false; - } - return true; -} -#endif - -static bool sVerboseDebugging = false; - -FMOD_RESULT F_CALLBACK windCallback(FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int outchannels); - -FMOD::ChannelGroup *LLAudioEngine_FMODEX::mChannelGroups[LLAudioEngine::AUDIO_TYPE_COUNT] = {0}; - -//This class is designed to keep track of all sound<->channel assocations. -//Used to verify validity of sound and channel pointers, as well as catch cases were sounds -//are released with active channels still attached. -class CFMODSoundChecks -{ - typedef std::map > active_sounds_t; - typedef std::set dead_sounds_t; - typedef std::map active_channels_t; - typedef std::map dead_channels_t; - - active_sounds_t mActiveSounds; - dead_sounds_t mDeadSounds; - active_channels_t mActiveChannels; - dead_channels_t mDeadChannels; -public: - enum STATUS - { - ACTIVE, - DEAD, - UNKNOWN - }; - STATUS getPtrStatus(LLAudioChannel* channel) - { - if(!channel) - return UNKNOWN; - return getPtrStatus(dynamic_cast(channel)->mChannelp); - } - STATUS getPtrStatus(LLAudioBuffer* sound) - { - if(!sound) - return UNKNOWN; - return getPtrStatus(dynamic_cast(sound)->mSoundp); - } - STATUS getPtrStatus(FMOD::Channel* channel) - { - if(!channel) - return UNKNOWN; - else if(mActiveChannels.find(channel) != mActiveChannels.end()) - return ACTIVE; - else if(mDeadChannels.find(channel) != mDeadChannels.end()) - return DEAD; - return UNKNOWN; - } - STATUS getPtrStatus(FMOD::Sound* sound) - { - if(!sound) - return UNKNOWN; - if(mActiveSounds.find(sound) != mActiveSounds.end()) - return ACTIVE; - else if(mDeadSounds.find(sound) != mDeadSounds.end()) - return DEAD; - return UNKNOWN; - } - void addNewSound(FMOD::Sound* sound) - { - assertActiveState(sound,true,false); - - mDeadSounds.erase(sound); - mActiveSounds.insert(std::make_pair(sound,std::set())); - } - void removeSound(FMOD::Sound* sound) - { - assertActiveState(sound,true); - - active_sounds_t::const_iterator it = mActiveSounds.find(sound); - llassert(it != mActiveSounds.end()); - if(it != mActiveSounds.end()) - { - if(!it->second.empty()) - { - LL_WARNS("AudioImpl") << "Removing sound " << sound << " with attached channels: \n"; - for(std::set::iterator it2 = it->second.begin(); it2 != it->second.end();++it2) - { - switch(getPtrStatus(*it2)) - { - case ACTIVE: - LL_CONT << " Channel " << *it2 << " ACTIVE\n"; - break; - case DEAD: - LL_CONT << " Channel " << *it2 << " DEAD\n"; - break; - default: - LL_CONT << " Channel " << *it2 << " UNKNOWN\n"; - } - } - LL_CONT << LL_ENDL; - } - llassert(it->second.empty()); - mDeadSounds.insert(sound); - mActiveSounds.erase(sound); - } - } - void addNewChannelToSound(FMOD::Sound* sound,FMOD::Channel* channel) - { - assertActiveState(sound,true); - assertActiveState(channel,true,false); - - mActiveSounds[sound].insert(channel); - mActiveChannels.insert(std::make_pair(channel,sound)); - } - void removeChannel(FMOD::Channel* channel) - { - assertActiveState(channel,true); - - active_channels_t::const_iterator it = mActiveChannels.find(channel); - llassert(it != mActiveChannels.end()); - if(it != mActiveChannels.end()) - { -#ifdef SHOW_ASSERT - STATUS status = getPtrStatus(it->second); - llassert(status != DEAD); - llassert(status != UNKNOWN); -#endif - - active_sounds_t::iterator it2 = mActiveSounds.find(it->second); - llassert(it2 != mActiveSounds.end()); - if(it2 != mActiveSounds.end()) - { - it2->second.erase(channel); - } - mDeadChannels.insert(*it); - mActiveChannels.erase(channel); - } - } - - template - void assertActiveState(T ptr, bool try_log=false, bool active=true) - { -#ifndef SHOW_ASSERT - if(try_log && sVerboseDebugging) -#endif - { - CFMODSoundChecks::STATUS chan = getPtrStatus(ptr); - if(try_log && sVerboseDebugging) - { - if(active) - { - if(chan == CFMODSoundChecks::DEAD) - LL_WARNS("AudioImpl") << __FUNCTION__ << ": Using unexpectedly dead " << typeid(T*).name() << " " << ptr << LL_ENDL; - else if(chan == CFMODSoundChecks::UNKNOWN) - LL_WARNS("AudioImpl") << __FUNCTION__ << ": Using unexpectedly unknown " << typeid(T*).name() << " " << ptr << LL_ENDL; - } - else if(chan == CFMODSoundChecks::ACTIVE) - LL_WARNS("AudioImpl") << __FUNCTION__ << ": Using unexpectedly active " << typeid(T*).name() << " " << ptr << LL_ENDL; - } - llassert( active == (chan == CFMODSoundChecks::ACTIVE) ); - } - } -} gSoundCheck; - -LLAudioEngine_FMODEX::LLAudioEngine_FMODEX(bool enable_profiler, bool verbose_debugging) -{ - sVerboseDebugging = verbose_debugging; - mInited = false; - mWindGen = NULL; - mWindDSP = NULL; - mSystem = NULL; - mEnableProfiler = enable_profiler; -} - - -LLAudioEngine_FMODEX::~LLAudioEngine_FMODEX() -{ -} - - -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; -} - -void* F_STDCALL decode_alloc(unsigned int size, FMOD_MEMORY_TYPE type, const char *sourcestr) -{ - if(type & FMOD_MEMORY_STREAM_DECODE) - { - LL_INFOS("AudioImpl") << "Decode buffer size: " << size << LL_ENDL; - } - else if(type & FMOD_MEMORY_STREAM_FILE) - { - LL_INFOS("AudioImpl") << "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) -{ - -#if LL_WINDOWS - if(!attemptDelayLoad()) - return false; -#endif - - U32 version = 0; - 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; - - 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"); - - U32 fmod_flags = FMOD_INIT_NORMAL; - if(mEnableProfiler) - { - fmod_flags |= FMOD_INIT_ENABLE_PROFILE; - } - -#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; - if((result = mSystem->setOutput(FMOD_OUTPUTTYPE_PULSEAUDIO)) == FMOD_OK && - (result = mSystem->init(num_channels + 2, fmod_flags, 0)) == FMOD_OK) - { - LL_DEBUGS("AppInit") << "PulseAudio output initialized OKAY" << LL_ENDL; - 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 + 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; - 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; - 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; - }; - } -#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 - - 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; - char r_name[256]; - FMOD_SPEAKERMODE speaker_mode; - if (!Check_FMOD_Error(mSystem->getDSPBufferSize(&r_bufferlength, &r_numbuffers), "FMOD::System::getDSPBufferSize") && - !Check_FMOD_Error(mSystem->getSoftwareFormat(&r_samplerate, NULL, &r_channels, NULL, NULL, &r_bits), "FMOD::System::getSoftwareFormat") && - !Check_FMOD_Error(mSystem->getDriverInfo(0, r_name, 255, 0), "FMOD::System::getDriverInfo") && - !Check_FMOD_Error(mSystem->getSpeakerMode(&speaker_mode), "FMOD::System::getSpeakerMode")) - { - std::string speaker_mode_str = "unknown"; - switch(speaker_mode) - { - #define SPEAKER_MODE_CASE(MODE) case MODE: speaker_mode_str = #MODE; break; - SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_RAW) - SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_MONO) - SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_STEREO) - SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_QUAD) - SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_SURROUND) - SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_5POINT1) - SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_7POINT1) - SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_SRS5_1_MATRIX) - SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_MYEARS) - default:; - #undef SPEAKER_MODE_CASE - } - - r_name[255] = '\0'; - int latency = 1000.0 * r_bufferlength * r_numbuffers /r_samplerate; - - LL_INFOS("AppInit") << "FMOD device: "<< r_name << "\n" - << "Output mode: "<< speaker_mode_str << "\n" - << "FMOD Ex parameters: " << r_samplerate << " Hz * " << r_channels << " * " <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("AudioImpl") << "Listener creation failed" << LL_ENDL; - } -} - - -void LLAudioEngine_FMODEX::shutdown() -{ - LL_INFOS("AudioImpl") << "About to LLAudioEngine::shutdown()" << LL_ENDL; - LLAudioEngine::shutdown(); - - LL_INFOS("AudioImpl") << "LLAudioEngine_FMODEX::shutdown() closing FMOD Ex" << LL_ENDL; - if ( mSystem ) // speculative fix for MAINT-2657 - { - LL_INFOS("AudioImpl") << "LLAudioEngine_FMODEX::shutdown() Requesting FMOD Ex system closure" << LL_ENDL; - Check_FMOD_Error(mSystem->close(), "FMOD::System::close"); - LL_INFOS("AudioImpl") << "LLAudioEngine_FMODEX::shutdown() Requesting FMOD Ex system release" << LL_ENDL; - Check_FMOD_Error(mSystem->release(), "FMOD::System::release"); - } - LL_INFOS("AudioImpl") << "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; - - cleanupWind(); - - - FMOD_DSP_DESCRIPTION dspdesc; - memset(&dspdesc, 0, sizeof(FMOD_DSP_DESCRIPTION)); //Set everything to zero - strncpy(dspdesc.name,"Wind Unit", sizeof(dspdesc.name)); //Set name to "Wind Unit" - dspdesc.channels=2; - dspdesc.read = &windCallback; //Assign callback. - if(Check_FMOD_Error(mSystem->createDSP(&dspdesc, &mWindDSP), "FMOD::createDSP") || !mWindDSP) - return false; - - float frequency = 44100; - if (!Check_FMOD_Error(mWindDSP->getDefaults(&frequency,0,0,0), "FMOD::DSP::getDefaults")) - { - mWindGen = new LLWindGen((U32)frequency); - if (!Check_FMOD_Error(mWindDSP->setUserData((void*)mWindGen), "FMOD::DSP::setUserData") && - !Check_FMOD_Error(mSystem->playDSP(FMOD_CHANNEL_FREE, mWindDSP, false, 0), "FMOD::System::playDSP")) - return true; //Success - } - - cleanupWind(); - return false; -} - - -void LLAudioEngine_FMODEX::cleanupWind() -{ - if (mWindDSP) - { - 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; - 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() -{ - if(sVerboseDebugging) - LL_DEBUGS("AudioImpl") << "Destructing Audio Channel. mChannelp = " << mChannelp << LL_ENDL; - - cleanup(); -} - -static FMOD_RESULT F_CALLBACK channel_callback(FMOD_CHANNEL *channel, FMOD_CHANNEL_CALLBACKTYPE type, void *commanddata1, void *commanddata2) -{ - if(type == FMOD_CHANNEL_CALLBACKTYPE_END) - { - FMOD::Channel* chan = reinterpret_cast(channel); - LLAudioChannelFMODEX* audio_channel = NULL; - chan->getUserData((void**)&audio_channel); - if(audio_channel) - { - audio_channel->onRelease(); - } - } - return FMOD_OK; -} - -void LLAudioChannelFMODEX::onRelease() -{ - llassert(mChannelp); - if(sVerboseDebugging) - LL_DEBUGS("AudioImpl") << "Fmod signaled channel release for channel " << mChannelp << LL_ENDL; - gSoundCheck.removeChannel(mChannelp); - mChannelp = NULL; //Null out channel here so cleanup doesn't try to redundantly stop it. - cleanup(); -} - -bool LLAudioChannelFMODEX::updateBuffer() -{ - if (LLAudioChannel::updateBuffer()) - { - // Base class update returned true, which means the channel buffer was changed, and not is null. - - // Grab the FMOD sample associated with the buffer - FMOD::Sound *soundp = ((LLAudioBufferFMODEX*)mCurrentBufferp)->getSound(); - if (!soundp) - { - // This is bad, there should ALWAYS be a sound associated with a legit - // buffer. - LL_ERRS("AudioImpl") << "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"); - if(result == FMOD_OK) - { - if(sVerboseDebugging) - LL_DEBUGS("AudioImpl") << "Created channel " << mChannelp << " for sound " << soundp << LL_ENDL; - - gSoundCheck.addNewChannelToSound(soundp,mChannelp); - mChannelp->setCallback(&channel_callback); - mChannelp->setUserData(this); - } - } - } - - // If we have a source for the channel, we need to update its gain. - if (mCurrentSourcep && mChannelp) - { - FMOD_RESULT result; - - gSoundCheck.assertActiveState(this); - result = mChannelp->setVolume(getSecondaryGain() * mCurrentSourcep->getGain()); - Check_FMOD_Error(result, "FMOD::Channel::setVolume"); - result = mChannelp->setMode(mCurrentSourcep->isLoop() ? FMOD_LOOP_NORMAL : FMOD_LOOP_OFF); - Check_FMOD_Error(result, "FMOD::Channel::setMode"); - } - - 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; - } - - gSoundCheck.assertActiveState(this); - - 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; - } - - gSoundCheck.assertActiveState(this); - - // - // 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; -} - - -void LLAudioChannelFMODEX::cleanup() -{ - LLAudioChannel::cleanup(); - - if (!mChannelp) - { - llassert(mCurrentBufferp == NULL); - //LL_INFOS("AudioImpl") << "Aborting cleanup with no channel handle." << LL_ENDL; - return; - } - - if(sVerboseDebugging) - LL_DEBUGS("AudioImpl") << "Stopping channel " << mChannelp << LL_ENDL; - - gSoundCheck.removeChannel(mChannelp); - mChannelp->setCallback(NULL); - Check_FMOD_Error(mChannelp->stop(),"FMOD::Channel::stop"); - - mChannelp = NULL; - mLastSamplePos = 0; -} - - -void LLAudioChannelFMODEX::play() -{ - if (!mChannelp) - { - LL_WARNS("AudioImpl") << "Playing without a channel handle, aborting" << LL_ENDL; - return; - } - - gSoundCheck.assertActiveState(this,true); - - bool paused=true; - Check_FMOD_Error(mChannelp->getPaused(&paused), "FMOD::Channel::getPaused"); - if(!paused) - { - Check_FMOD_Error(mChannelp->setPaused(true), "FMOD::Channel::setPaused"); - Check_FMOD_Error(mChannelp->setPosition(0,FMOD_TIMEUNIT_PCMBYTES), "FMOD::Channel::setPosition"); - } - Check_FMOD_Error(mChannelp->setPaused(false), "FMOD::Channel::setPaused"); - - if(sVerboseDebugging) - LL_DEBUGS("AudioImpl") << "Playing channel " << mChannelp << LL_ENDL; - - getSource()->setPlayedOnce(true); - - if(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; - } - - gSoundCheck.assertActiveState(this,true); - - U32 cur_pos; - if(Check_FMOD_Error(fmod_channelp->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; - } - - gSoundCheck.assertActiveState(this); - - bool paused, 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) : LLAudioBuffer(), mSystemp(system), mSoundp(NULL) -{ -} - - -LLAudioBufferFMODEX::~LLAudioBufferFMODEX() -{ - if(mSoundp) - { - if(sVerboseDebugging) - LL_DEBUGS("AudioImpl") << "Release sound " << mSoundp << LL_ENDL; - - gSoundCheck.removeSound(mSoundp); - 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; - } - - if (!LLAPRFile::isExist(filename, LL_APR_RPB)) - { - // File not found, abort. - return false; - } - - if (mSoundp) - { - gSoundCheck.removeSound(mSoundp); - // If there's already something loaded in this buffer, clean it up. - 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("AudioImpl") << "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; - } - - gSoundCheck.addNewSound(mSoundp); - - // Everything went well, return true - return true; -} - - -U32 LLAudioBufferFMODEX::getLength() -{ - if (!mSoundp) - { - return 0; - } - - gSoundCheck.assertActiveState(this); - U32 length; - Check_FMOD_Error(mSoundp->getLength(&length, FMOD_TIMEUNIT_PCMBYTES),"FMOD::Sound::getLength"); - return length; -} - - -void LLAudioChannelFMODEX::set3DMode(bool use3d) -{ - gSoundCheck.assertActiveState(this); - - 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"); - } -} - - -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); - - 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 fe93d8c48..000000000 --- a/indra/llaudio/llaudioengine_fmodex.h +++ /dev/null @@ -1,139 +0,0 @@ -/** - * @file audioengine_FMODEX.h - * @brief Definition of LLAudioEngine class abstracting the audio - * support as a FMOD 3D implementation - * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LL_AUDIOENGINE_FMODEX_H -#define LL_AUDIOENGINE_FMODEX_H - -#include "llaudioengine.h" -#include "lllistener_fmodex.h" -#include "llwindgen.h" - -//Stubs -class LLAudioStreamManagerFMODEX; -namespace FMOD -{ - class System; - class Channel; - class ChannelGroup; - class Sound; - class DSP; -} - -//Interfaces -class LLAudioEngine_FMODEX : public LLAudioEngine -{ -public: - LLAudioEngine_FMODEX(bool enable_profiler, bool verbose_debugging); - 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;} -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 *mWindDSP; - FMOD::System *mSystem; - bool mEnableProfiler; - -public: - static FMOD::ChannelGroup *mChannelGroups[LLAudioEngine::AUDIO_TYPE_COUNT]; -}; - - -class LLAudioChannelFMODEX : public LLAudioChannel -{ -public: - LLAudioChannelFMODEX(FMOD::System *audioengine); - virtual ~LLAudioChannelFMODEX(); - void onRelease(); -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; - - friend class CFMODSoundChecks; -}; - - -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; - - friend class CFMODSoundChecks; -}; - - -#endif // LL_AUDIOENGINE_FMODEX_H diff --git a/indra/llaudio/llaudioengine_fmodstudio.cpp b/indra/llaudio/llaudioengine_fmodstudio.cpp index d86748ebe..930af7fc2 100644 --- a/indra/llaudio/llaudioengine_fmodstudio.cpp +++ b/indra/llaudio/llaudioengine_fmodstudio.cpp @@ -477,7 +477,7 @@ std::string LLAudioEngine_FMODSTUDIO::getDriverName(bool verbose) return llformat("FMOD Studio %1x.%02x.%02x", version >> 16, version >> 8 & 0x000000FF, version & 0x000000FF); } } - return "FMODEx"; + return "FMOD Studio"; } diff --git a/indra/llaudio/lllistener_fmodex.cpp b/indra/llaudio/lllistener_fmodex.cpp deleted file mode 100644 index e70dc7c60..000000000 --- a/indra/llaudio/lllistener_fmodex.cpp +++ /dev/null @@ -1,141 +0,0 @@ -/** - * @file listener_fmod.cpp - * @brief implementation of LISTENER class abstracting the audio - * support as a FMOD 3D implementation (windows only) - * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/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() -{ - 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 8a91b3a2e..000000000 --- a/indra/llaudio/lllistener_fmodex.h +++ /dev/null @@ -1,71 +0,0 @@ -/** - * @file listener_fmod.h - * @brief Description of LISTENER class abstracting the audio support - * as an FMOD 3D implementation (windows and Linux) - * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/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/llstreamingaudio_fmodex.cpp b/indra/llaudio/llstreamingaudio_fmodex.cpp deleted file mode 100644 index 39436977a..000000000 --- a/indra/llaudio/llstreamingaudio_fmodex.cpp +++ /dev/null @@ -1,596 +0,0 @@ -/** - * @file streamingaudio_fmod.cpp - * @brief LLStreamingAudio_FMODEX implementation - * - * $LicenseInfo:firstyear=2009&license=viewergpl$ - * - * Copyright (c) 2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#include "linden_common.h" - -#include "llmath.h" - -#include "fmod.hpp" -#include "fmod_errors.h" - -#include "llstreamingaudio_fmodex.h" - -inline bool Check_FMOD_Error(FMOD_RESULT result, const char *string) -{ - if (result == FMOD_OK) - return false; - LL_WARNS("AudioImpl") << string << " Error: " << FMOD_ErrorString(result) << LL_ENDL; - return true; -} - -class LLAudioStreamManagerFMODEX -{ -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_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), - mMetaData(NULL) -{ - FMOD_RESULT result; - - // Number of milliseconds of audio to buffer for the audio card. - // Must be larger than the usual Second Life frame stutter time. - const U32 buffer_seconds = 10; //sec - const U32 estimated_bitrate = 128; //kbit/sec - 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() -{ - stop(); - for (U32 i = 0; i < 100; ++i) - { - if (releaseDeadStreams()) - break; - ms_sleep(10); - } -} - - -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()) - { - if(mDeadStreams.empty()) - { - LL_INFOS() << "Starting internet stream: " << url << LL_ENDL; - mCurrentInternetStreamp = new LLAudioStreamManagerFMODEX(mSystem,url); - mURL = url; - mMetaData = new LLSD; - } - 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(); - } -} - -enum utf_endian_type_t -{ - UTF16LE, - UTF16BE, - UTF16 -}; - -std::string utf16input_to_utf8(unsigned char* input, U32 len, utf_endian_type_t type) -{ - if (type == UTF16) - { - type = UTF16BE; //Default - if (len > 2) - { - //Parse and strip BOM. - if ((input[0] == 0xFE && input[1] == 0xFF) || - (input[0] == 0xFF && input[1] == 0xFE)) - { - input += 2; - len -= 2; - type = input[0] == 0xFE ? UTF16BE : UTF16LE; - } - } - } - llutf16string out_16((U16*)input, len / 2); - if (len % 2) - { - out_16.push_back((input)[len - 1] << 8); - } - if (type == UTF16BE) - { - for (llutf16string::iterator i = out_16.begin(); i < out_16.end(); ++i) - { - llutf16string::value_type v = *i; - *i = ((v & 0x00FF) << 8) | ((v & 0xFF00) >> 8); - } - } - return utf16str_to_utf8str(out_16); -} - -void LLStreamingAudio_FMODEX::update() -{ - 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; - mMetaData = new LLSD; - mPendingURL.clear(); - } - - // 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 res = mCurrentInternetStreamp->getOpenState(open_state, &progress, &starving, &diskbusy); - - if (res != 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()); - Check_FMOD_Error(mFMODInternetStreamChannelp->setPaused(false), "FMOD::Channel::setPaused"); - } - } - - if(mFMODInternetStreamChannelp) - { - if(!mMetaData) - mMetaData = new LLSD; - - FMOD::Sound *sound = NULL; - - if(mFMODInternetStreamChannelp->getCurrentSound(&sound) == FMOD_OK && sound) - { - FMOD_TAG tag; - S32 tagcount, dirtytagcount; - if(sound->getNumTags(&tagcount, &dirtytagcount) == FMOD_OK && dirtytagcount) - { - mMetaData->clear(); - - for(S32 i = 0; i < tagcount; ++i) - { - if(sound->getTag(NULL, i, &tag)!=FMOD_OK) - continue; - std::string name = tag.name; - switch(tag.type) //Crappy tag translate table. - { - case(FMOD_TAGTYPE_ID3V2): - if (!LLStringUtil::compareInsensitive(name, "TIT2")) name = "TITLE"; - else if(name == "TPE1") name = "ARTIST"; - break; - case(FMOD_TAGTYPE_ASF): - if (!LLStringUtil::compareInsensitive(name, "Title")) name = "TITLE"; - else if (!LLStringUtil::compareInsensitive(name, "WM/AlbumArtist")) name = "ARTIST"; - break; - case(FMOD_TAGTYPE_FMOD): - if (!LLStringUtil::compareInsensitive(name, "Sample Rate Change")) - { - LL_INFOS() << "Stream forced changing sample rate to " << *((float *)tag.data) << LL_ENDL; - Check_FMOD_Error(mFMODInternetStreamChannelp->setFrequency(*((float *)tag.data)), "FMOD::Channel::setFrequency"); - } - continue; - default: - if (!LLStringUtil::compareInsensitive(name, "TITLE") || - !LLStringUtil::compareInsensitive(name, "ARTIST")) - LLStringUtil::toUpper(name); - break; - } - - switch(tag.datatype) - { - case(FMOD_TAGDATATYPE_INT): - (*mMetaData)[name]=*(LLSD::Integer*)(tag.data); - LL_INFOS() << tag.name << ": " << *(int*)(tag.data) << LL_ENDL; - break; - case(FMOD_TAGDATATYPE_FLOAT): - (*mMetaData)[name]=*(LLSD::Float*)(tag.data); - LL_INFOS() << 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)); - if (out.length() && out[out.size() - 1] == 0) - out.erase(out.size() - 1); - (*mMetaData)[name]=out; - LL_INFOS() << tag.name << "(RAW): " << out << LL_ENDL; - } - break; - case(FMOD_TAGDATATYPE_STRING_UTF8) : - { - U8 offs = 0; - if (tag.datalen > 3 && ((unsigned char*)tag.data)[0] == 0xEF && ((char*)tag.data)[1] == 0xBB && ((char*)tag.data)[2] == 0xBF) - offs = 3; - std::string out((char*)tag.data + offs, tag.datalen - offs); - if (out.length() && out[out.size() - 1] == 0) - out.erase(out.size() - 1); - (*mMetaData)[name] = out; - LL_INFOS() << tag.name << "(UTF8): " << out << LL_ENDL; - } - break; - case(FMOD_TAGDATATYPE_STRING_UTF16): - { - std::string out = utf16input_to_utf8((unsigned char*)tag.data, tag.datalen, UTF16); - if (out.length() && out[out.size() - 1] == 0) - out.erase(out.size() - 1); - (*mMetaData)[name] = out; - LL_INFOS() << tag.name << "(UTF16): " << out << LL_ENDL; - } - break; - case(FMOD_TAGDATATYPE_STRING_UTF16BE): - { - std::string out = utf16input_to_utf8((unsigned char*)tag.data, tag.datalen, UTF16BE); - if (out.length() && out[out.size() - 1] == 0) - out.erase(out.size() - 1); - (*mMetaData)[name] = out; - LL_INFOS() << tag.name << "(UTF16BE): " << out << LL_ENDL; - } - 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"); - } - } - } -} - -void LLStreamingAudio_FMODEX::stop() -{ - mPendingURL.clear(); - - if(mMetaData) - { - delete mMetaData; - mMetaData = 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; - //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 - } - 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? - - Check_FMOD_Error(mFMODInternetStreamChannelp->setVolume(vol), "FMOD::Channel::setVolume"); - } -} - -/*virtual*/ bool LLStreamingAudio_FMODEX::getWaveData(float* arr, S32 count, S32 stride/*=1*/) -{ - if(!mFMODInternetStreamChannelp || !mCurrentInternetStreamp) - return false; - - bool muted=false; - FMOD_RESULT res = mFMODInternetStreamChannelp->getMute(&muted); - if(res != FMOD_OK || muted) - return false; - - static std::vector local_array(count); //Have to have an extra buffer to mix channels. Bleh. - if(count > (S32)local_array.size()) //Expand the array if needed. Try to minimize allocation calls, so don't ever shrink. - local_array.resize(count); - - if( mFMODInternetStreamChannelp->getWaveData(&local_array[0],count,0) == FMOD_OK && - mFMODInternetStreamChannelp->getWaveData(&arr[0],count,1) == FMOD_OK ) - { - for(S32 i = count-1;i>=0;i-=stride) - { - arr[i] += local_array[i]; - arr[i] *= .5f; - } - return true; - } - 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_CREATESOUNDEXINFO exinfo; - memset(&exinfo,0,sizeof(exinfo)); - exinfo.cbsize = sizeof(exinfo); - exinfo.suggestedsoundtype = FMOD_SOUND_TYPE_OGGVORBIS; //Hint to speed up loading.*/ - - 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_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. - - 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_OPENSTATE open_state; - if (getOpenState(open_state) == FMOD_OK) - { - 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; - } -} - -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) -{ - 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_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(); -} \ No newline at end of file diff --git a/indra/llaudio/llstreamingaudio_fmodex.h b/indra/llaudio/llstreamingaudio_fmodex.h deleted file mode 100644 index 15a4af931..000000000 --- a/indra/llaudio/llstreamingaudio_fmodex.h +++ /dev/null @@ -1,89 +0,0 @@ -/** - * @file streamingaudio_fmod.h - * @author Tofu Linden - * @brief Definition of LLStreamingAudio_FMOD implementation - * - * $LicenseInfo:firstyear=2009&license=viewergpl$ - * - * Copyright (c) 2009, Linden Research, Inc. - * - * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 - * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception - * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. - * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. - * $/LicenseInfo$ - */ - -#ifndef LL_STREAMINGAUDIO_FMOD_H -#define LL_STREAMINGAUDIO_FMOD_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(int pause); - /*virtual*/ void update(); - /*virtual*/ int isPlaying(); - /*virtual*/ void setGain(F32 vol); - /*virtual*/ F32 getGain(); - /*virtual*/ std::string getURL(); - - /*virtual*/ bool supportsMetaData(){return true;} - /*virtual*/ const LLSD *getMetaData(){return mMetaData;} //return NULL if not playing. - /*virtual*/ bool supportsWaveData(){return true;} - /*virtual*/ bool getWaveData(float* arr, S32 count, S32 stride = 1); - /*virtual*/ bool supportsAdjustableBufferSizes(){return true;} - /*virtual*/ void setBufferSizes(U32 streambuffertime, U32 decodebuffertime); -private: - bool releaseDeadStreams(); - - FMOD::System *mSystem; - - LLAudioStreamManagerFMODEX *mCurrentInternetStreamp; - FMOD::Channel *mFMODInternetStreamChannelp; - std::list mDeadStreams; - - std::string mURL; - std::string mPendingURL; - F32 mGain; - - LLSD *mMetaData; -}; - - -#endif // LL_STREAMINGAUDIO_FMOD_H diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 7ebe1c7f3..72f045f63 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -9,12 +9,7 @@ include(BuildVersion) include(CMakeCopyIfDifferent) include(DBusGlib) include(ELFIO) -if(FMODSTUDIO) - include(FMODSTUDIO) -endif(FMODSTUDIO) -if(FMODEX) - include(FMODEX) -endif(FMODEX) +include(FMODSTUDIO) include(GLOD) include(FindOpenGL) include(Hunspell) @@ -1417,10 +1412,6 @@ if (WINDOWS) list(APPEND viewer_SOURCE_FILES ${viewer_INSTALLER_FILES}) endif (WINDOWS) -if (FMODSTUDIO) - set(FMOD_LIBRARY ${FMOD_LINK_LIBRARY_RELEASE}) -endif (FMODSTUDIO) - set_source_files_properties(llstartup.cpp PROPERTIES COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS}") list(APPEND viewer_SOURCE_FILES ${viewer_HEADER_FILES}) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 8ceb12c31..a0ae18270 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -4490,19 +4490,7 @@ void LLAppViewer::shutdownAudio() if (gAudiop) { // shut down the audio subsystem - - bool want_longname = false; - if (gAudiop->getDriverName(want_longname) == "FMOD") - { - // This hack exists because fmod likes to occasionally - // crash or hang forever when shutting down, for no - // apparent reason. - LL_WARNS() << "Hack, skipping FMOD audio engine cleanup" << LL_ENDL; - } - else - { - gAudiop->shutdown(); - } + gAudiop->shutdown(); delete gAudiop; gAudiop = NULL; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 526f4ee23..4198a5247 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -49,10 +49,6 @@ # include "llaudioengine_fmodstudio.h" #endif -#if LL_FMODEX -# include "llaudioengine_fmodex.h" -#endif - #ifdef LL_OPENAL #include "llaudioengine_openal.h" #endif @@ -434,17 +430,6 @@ void init_audio() } #endif -#ifdef LL_FMODEX - if (!gAudiop -#if !LL_WINDOWS - && NULL == getenv("LL_BAD_FMODEX_DRIVER") -#endif // !LL_WINDOWS - ) - { - gAudiop = (LLAudioEngine *) new LLAudioEngine_FMODEX(gSavedSettings.getBOOL("SHEnableFMODExProfiler"),gSavedSettings.getBOOL("SHEnableFMODEXVerboseDebugging")); - } -#endif - #ifdef LL_OPENAL if (!gAudiop #if !LL_WINDOWS