Remove FMOD Ex
This commit is contained in:
@@ -27,7 +27,6 @@ set(cmake_SOURCE_FILES
|
||||
ELFIO.cmake
|
||||
EXPAT.cmake
|
||||
ExamplePlugin.cmake
|
||||
FMODEX.cmake
|
||||
FMODSTUDIO.cmake
|
||||
FindAPR.cmake
|
||||
FindAutobuild.cmake
|
||||
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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<MIXBUFFERFORMAT> *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
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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="<<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_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<float> 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<LLAudioStreamManagerFMODEX *>::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();
|
||||
}
|
||||
@@ -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<LLAudioStreamManagerFMODEX *> mDeadStreams;
|
||||
|
||||
std::string mURL;
|
||||
std::string mPendingURL;
|
||||
F32 mGain;
|
||||
|
||||
LLSD *mMetaData;
|
||||
};
|
||||
|
||||
|
||||
#endif // LL_STREAMINGAUDIO_FMOD_H
|
||||
@@ -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})
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user