Skip to content
Snippets Groups Projects
Commit 2171d7fb authored by Andrey Lihatskiy's avatar Andrey Lihatskiy
Browse files

Merge branch 'master' into DRTVWR-501-maint

parents 882d7eee 1702a656
No related branches found
No related tags found
No related merge requests found
Showing
with 1489 additions and 1374 deletions
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
*.bak *.bak
*.diff *.diff
*.orig *.orig
*.patch
*.pyc *.pyc
*.rej *.rej
*.swp *.swp
......
...@@ -729,38 +729,28 @@ ...@@ -729,38 +729,28 @@
<key>version</key> <key>version</key>
<string>2.1.1.500375</string> <string>2.1.1.500375</string>
</map> </map>
<key>fmodex</key> <key>fmodstudio</key>
<map> <map>
<key>copyright</key> <key>copyright</key>
<string>COPYRIGHT 2014 FIRELIGHT TECHNOLOGIES PTY LTD. ALL RIGHTS RESERVED</string> <string>FMOD Studio by Firelight Technologies Pty Ltd.</string>
<key>description</key>
<string>FMOD Studio API</string>
<key>license</key> <key>license</key>
<string>fmodex</string> <string>fmod</string>
<key>license_file</key> <key>license_file</key>
<string>LICENSES/fmodex.txt</string> <string>LICENSES/fmodstudio.txt</string>
<key>name</key> <key>name</key>
<string>fmodex</string> <string>fmodstudio</string>
<key>platforms</key> <key>platforms</key>
<map> <map>
<key>darwin</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>ed0d8767652aecd65a7fef3e28645bad</string>
<key>url</key>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/fmodex_3p-update-fmodex/rev/297261/arch/Darwin/installer/fmodex-4.44.31.297261-darwin-297261.tar.bz2</string>
</map>
<key>name</key>
<string>darwin</string>
</map>
<key>darwin64</key> <key>darwin64</key>
<map> <map>
<key>archive</key> <key>archive</key>
<map> <map>
<key>hash</key> <key>hash</key>
<string>93257fce19120c01751362775a01b925</string> <string>dc4c9122de8bf77f34cfc8227d10a272</string>
<key>url</key> <key>url</key>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/1545/3481/fmodex-4.44.64.501533-darwin64-501533.tar.bz2</string> <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/59038/554626/fmodstudio-2.00.07.541681-darwin64-541681.tar.bz2</string>
</map> </map>
<key>name</key> <key>name</key>
<string>darwin64</string> <string>darwin64</string>
...@@ -770,9 +760,9 @@ ...@@ -770,9 +760,9 @@
<key>archive</key> <key>archive</key>
<map> <map>
<key>hash</key> <key>hash</key>
<string>b847ec838da1ad1dd646df9d74e9b395</string> <string>c491bdc1690f3d920c66be509ccc6ef2</string>
<key>url</key> <key>url</key>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/p64_3p-fmodex/rev/314207/arch/Linux/installer/fmodex-4.44.61.314207-linux-314207.tar.bz2</string> <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/59039/554632/fmodstudio-2.00.07.541681-linux-541681.tar.bz2</string>
</map> </map>
<key>name</key> <key>name</key>
<string>linux</string> <string>linux</string>
...@@ -782,9 +772,9 @@ ...@@ -782,9 +772,9 @@
<key>archive</key> <key>archive</key>
<map> <map>
<key>hash</key> <key>hash</key>
<string>89a75d8719f7b2cbe1e54cd8407bb992</string> <string>ae75cdb1cc9da824c9e270bf97bfdd6c</string>
<key>url</key> <key>url</key>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/1544/3476/fmodex-4.44.64.501533-linux64-501533.tar.bz2</string> <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/54589/506866/fmodstudio-2.00.07.538806-linux64-538806.tar.bz2</string>
</map> </map>
<key>name</key> <key>name</key>
<string>linux64</string> <string>linux64</string>
...@@ -794,9 +784,9 @@ ...@@ -794,9 +784,9 @@
<key>archive</key> <key>archive</key>
<map> <map>
<key>hash</key> <key>hash</key>
<string>601c2fc41a18812a45678ef9a87ef772</string> <string>7f0294b038eab2d89ecc73bbf08b6d94</string>
<key>url</key> <key>url</key>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/1546/3486/fmodex-4.44.64.501533-windows-501533.tar.bz2</string> <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/59042/554668/fmodstudio-2.00.07.541681-windows-541681.tar.bz2</string>
</map> </map>
<key>name</key> <key>name</key>
<string>windows</string> <string>windows</string>
...@@ -806,16 +796,16 @@ ...@@ -806,16 +796,16 @@
<key>archive</key> <key>archive</key>
<map> <map>
<key>hash</key> <key>hash</key>
<string>e5cde35ae26ebfa256cfe670986e152e</string> <string>da2e8e2b809d8fe635ee437baa2a7386</string>
<key>url</key> <key>url</key>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/1547/3487/fmodex-4.44.64.501533-windows64-501533.tar.bz2</string> <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/59041/554656/fmodstudio-2.00.07.541681-windows64-541681.tar.bz2</string>
</map> </map>
<key>name</key> <key>name</key>
<string>windows64</string> <string>windows64</string>
</map> </map>
</map> </map>
<key>version</key> <key>version</key>
<string>4.44.64.501533</string> <string>2.00.07.541681</string>
</map> </map>
<key>fontconfig</key> <key>fontconfig</key>
<map> <map>
......
...@@ -28,7 +28,6 @@ set(cmake_SOURCE_FILES ...@@ -28,7 +28,6 @@ set(cmake_SOURCE_FILES
FindAPR.cmake FindAPR.cmake
FindAutobuild.cmake FindAutobuild.cmake
FindBerkeleyDB.cmake FindBerkeleyDB.cmake
FindFMODEX.cmake
FindGLH.cmake FindGLH.cmake
FindGoogleBreakpad.cmake FindGoogleBreakpad.cmake
FindHUNSPELL.cmake FindHUNSPELL.cmake
...@@ -39,7 +38,7 @@ set(cmake_SOURCE_FILES ...@@ -39,7 +38,7 @@ set(cmake_SOURCE_FILES
FindURIPARSER.cmake FindURIPARSER.cmake
FindXmlRpcEpi.cmake FindXmlRpcEpi.cmake
FindZLIB.cmake FindZLIB.cmake
FMODEX.cmake FMODSTUDIO.cmake
FreeType.cmake FreeType.cmake
GLEXT.cmake GLEXT.cmake
GLH.cmake GLH.cmake
......
...@@ -62,14 +62,10 @@ if(WINDOWS) ...@@ -62,14 +62,10 @@ if(WINDOWS)
endif(ADDRESS_SIZE EQUAL 32) endif(ADDRESS_SIZE EQUAL 32)
endif (BUGSPLAT_DB) endif (BUGSPLAT_DB)
if (FMODEX) if (FMODSTUDIO)
set(debug_files ${debug_files} fmodL.dll)
if(ADDRESS_SIZE EQUAL 32) set(release_files ${release_files} fmod.dll)
set(release_files ${release_files} fmodex.dll) endif (FMODSTUDIO)
else(ADDRESS_SIZE EQUAL 32)
set(release_files ${release_files} fmodex64.dll)
endif(ADDRESS_SIZE EQUAL 32)
endif (FMODEX)
#******************************* #*******************************
# Copy MS C runtime dlls, required for packaging. # Copy MS C runtime dlls, required for packaging.
...@@ -192,10 +188,10 @@ elseif(DARWIN) ...@@ -192,10 +188,10 @@ elseif(DARWIN)
libnghttp2.14.14.0.dylib libnghttp2.14.14.0.dylib
) )
if (FMODEX) if (FMODSTUDIO)
set(debug_files ${debug_files} libfmodexL.dylib) set(debug_files ${debug_files} libfmodL.dylib)
set(release_files ${release_files} libfmodex.dylib) set(release_files ${release_files} libfmod.dylib)
endif (FMODEX) endif (FMODSTUDIO)
elseif(LINUX) elseif(LINUX)
# linux is weird, multiple side by side configurations aren't supported # linux is weird, multiple side by side configurations aren't supported
...@@ -242,10 +238,10 @@ elseif(LINUX) ...@@ -242,10 +238,10 @@ elseif(LINUX)
libfontconfig.so.1 libfontconfig.so.1
) )
if (FMODEX) if (FMODSTUDIO)
set(debug_files ${debug_files} "libfmodexL.so") set(debug_files ${debug_files} "libfmodL.so")
set(release_files ${release_files} "libfmodex.so") set(release_files ${release_files} "libfmod.so")
endif (FMODEX) endif (FMODSTUDIO)
else(WINDOWS) else(WINDOWS)
message(STATUS "WARNING: unrecognized platform for staging 3rd party libs, skipping...") message(STATUS "WARNING: unrecognized platform for staging 3rd party libs, skipping...")
......
# -*- cmake -*-
# FMOD can be set when launching the make using the argument -DFMOD:BOOL=ON
# When building using proprietary binaries though (i.e. having access to LL private servers),
# we always build with FMODEX.
# Open source devs should use the -DFMODEX:BOOL=ON then if they want to build with FMOD, whether
# they are using USESYSTEMLIBS or not.
if (INSTALL_PROPRIETARY)
set(FMODEX ON CACHE BOOL "Using FMOD Ex sound library.")
endif (INSTALL_PROPRIETARY)
if (FMODEX)
if (USESYSTEMLIBS)
# In that case, we use the version of the library installed on the system
set(FMODEX_FIND_REQUIRED ON)
include(FindFMODEX)
else (USESYSTEMLIBS)
if (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR)
# If the path have been specified in the arguments, use that
set(FMODEX_LIBRARIES ${FMODEX_LIBRARY})
MESSAGE(STATUS "Using FMODEX path: ${FMODEX_LIBRARIES}, ${FMODEX_INCLUDE_DIR}")
else (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR)
# If not, we're going to try to get the package listed in autobuild.xml
# Note: if you're not using INSTALL_PROPRIETARY, the package URL should be local (file:/// URL)
# as accessing the private LL location will fail if you don't have the credential
include(Prebuilt)
use_prebuilt_binary(fmodex)
if (WINDOWS)
set(FMODEX_LIBRARY
debug fmodexL_vc
optimized fmodex_vc)
elseif (DARWIN)
set(FMODEX_LIBRARY
debug fmodexL
optimized fmodex)
elseif (LINUX)
set(FMODEX_LIBRARY
debug fmodexL
optimized fmodex)
endif (WINDOWS)
set(FMODEX_LIBRARIES ${FMODEX_LIBRARY})
set(FMODEX_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/fmodex)
endif (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR)
endif (USESYSTEMLIBS)
endif (FMODEX)
# -*- cmake -*-
# FMODSTUDIO can be set when launching the make using the argument -DFMODSTUDIO:BOOL=ON
# When building using proprietary binaries though (i.e. having access to LL private servers),
# we always build with FMODSTUDIO.
if (INSTALL_PROPRIETARY)
set(FMODSTUDIO ON CACHE BOOL "Using FMODSTUDIO sound library.")
endif (INSTALL_PROPRIETARY)
if (FMODSTUDIO)
if (FMODSTUDIO_LIBRARY AND FMODSTUDIO_INCLUDE_DIR)
# If the path have been specified in the arguments, use that
set(FMODSTUDIO_LIBRARIES ${FMODSTUDIO_LIBRARY})
else (FMODSTUDIO_LIBRARY AND FMODSTUDIO_INCLUDE_DIR)
# If not, we're going to try to get the package listed in autobuild.xml
# Note: if you're not using INSTALL_PROPRIETARY, the package URL should be local (file:/// URL)
# as accessing the private LL location will fail if you don't have the credential
include(Prebuilt)
use_prebuilt_binary(fmodstudio)
if (WINDOWS)
set(FMODSTUDIO_LIBRARY
debug fmodL_vc
optimized fmod_vc)
elseif (DARWIN)
#despite files being called libfmod.dylib, we are searching for fmod
set(FMODSTUDIO_LIBRARY
debug fmodL
optimized fmod)
elseif (LINUX)
set(FMODSTUDIO_LIBRARY
debug fmodL
optimized fmod)
endif (WINDOWS)
set(FMODSTUDIO_LIBRARIES ${FMODSTUDIO_LIBRARY})
set(FMODSTUDIO_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/fmodstudio)
endif (FMODSTUDIO_LIBRARY AND FMODSTUDIO_INCLUDE_DIR)
endif (FMODSTUDIO)
# -*- cmake -*-
# - Find FMODEX
# Find the FMODEX includes and library
# This module defines
# FMODEX_INCLUDE_DIR, where to find fmod.h and fmod_errors.h
# FMODEX_LIBRARIES, the libraries needed to use FMODEX.
# FMODEX, If false, do not try to use FMODEX.
# also defined, but not for general use are
# FMODEX_LIBRARY, where to find the FMODEX library.
FIND_PATH(FMODEX_INCLUDE_DIR fmod.h PATH_SUFFIXES fmod)
SET(FMODEX_NAMES ${FMODEX_NAMES} fmodex fmodvc fmodexL_vc)
FIND_LIBRARY(FMODEX_LIBRARY
NAMES ${FMODEX_NAMES}
PATH_SUFFIXES fmodex
)
IF (FMODEX_SDK_DIR OR WINDOWS)
if(WINDOWS)
set(FMODEX_SDK_DIR "$ENV{PROGRAMFILES}/FMOD SoundSystem/FMOD Programmers API Windows" CACHE PATH "Path to FMODEX")
STRING(REGEX REPLACE "\\\\" "/" FMODEX_SDK_DIR ${FMODEX_SDK_DIR})
endif(WINDOWS)
find_library(FMODEX_LIBRARY
fmodex_vc fmodexL_vc
PATHS
${FMODEX_SDK_DIR}/api/lib
${FMODEX_SDK_DIR}/api
${FMODEX_SDK_DIR}
)
find_path(FMODEX_INCLUDE_DIR fmod.h
${FMODEX_SDK_DIR}/api/inc
${FMODEX_SDK_DIR}/api
${FMODEX_SDK_DIR}
)
find_path(FMODEX_INCLUDE_DIR fmod.h
${FMODEX_SDK_DIR}/api/inc
${FMODEX_SDK_DIR}/api
${FMODEX_SDK_DIR}
)
IF (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR)
SET(FMODEX_LIBRARIES ${FMODEX_LIBRARY})
SET(FMODEX_FOUND "YES")
endif (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR)
ENDIF (FMODEX_SDK_DIR OR WINDOWS)
IF (FMODEX_FOUND)
IF (NOT FMODEX_FIND_QUIETLY)
MESSAGE(STATUS "Found FMODEX: ${FMODEX_LIBRARIES}")
ENDIF (NOT FMODEX_FIND_QUIETLY)
ELSE (FMODEX_FOUND)
IF (FMODEX_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could not find FMODEX library")
ENDIF (FMODEX_FIND_REQUIRED)
ENDIF (FMODEX_FOUND)
# Deprecated declarations.
SET (NATIVE_FMODEX_INCLUDE_PATH ${FMODEX_INCLUDE_DIR} )
GET_FILENAME_COMPONENT (NATIVE_FMODEX_LIB_PATH ${FMODEX_LIBRARY} PATH)
MARK_AS_ADVANCED(
FMODEX_LIBRARY
FMODEX_INCLUDE_DIR
)
...@@ -4,7 +4,7 @@ project(llaudio) ...@@ -4,7 +4,7 @@ project(llaudio)
include(00-Common) include(00-Common)
include(LLAudio) include(LLAudio)
include(FMODEX) include(FMODSTUDIO)
include(OPENAL) include(OPENAL)
include(LLCommon) include(LLCommon)
include(LLMath) include(LLMath)
...@@ -42,22 +42,22 @@ set(llaudio_HEADER_FILES ...@@ -42,22 +42,22 @@ set(llaudio_HEADER_FILES
llwindgen.h llwindgen.h
) )
if (FMODEX) if (FMODSTUDIO)
include_directories( include_directories(
${FMODEX_INCLUDE_DIR} ${FMODSTUDIO_INCLUDE_DIR}
) )
list(APPEND llaudio_SOURCE_FILES list(APPEND llaudio_SOURCE_FILES
llaudioengine_fmodex.cpp llaudioengine_fmodstudio.cpp
lllistener_fmodex.cpp lllistener_fmodstudio.cpp
llstreamingaudio_fmodex.cpp llstreamingaudio_fmodstudio.cpp
) )
list(APPEND llaudio_HEADER_FILES list(APPEND llaudio_HEADER_FILES
llaudioengine_fmodex.h llaudioengine_fmodstudio.h
lllistener_fmodex.h lllistener_fmodstudio.h
llstreamingaudio_fmodex.h llstreamingaudio_fmodstudio.h
) )
endif (FMODEX) endif (FMODSTUDIO)
if (OPENAL) if (OPENAL)
list(APPEND llaudio_SOURCE_FILES list(APPEND llaudio_SOURCE_FILES
......
...@@ -111,7 +111,7 @@ void LLAudioEngine::setDefaults() ...@@ -111,7 +111,7 @@ void LLAudioEngine::setDefaults()
} }
bool LLAudioEngine::init(const S32 num_channels, void* userdata) bool LLAudioEngine::init(const S32 num_channels, void* userdata, const std::string &app_title)
{ {
setDefaults(); setDefaults();
......
...@@ -99,7 +99,7 @@ class LLAudioEngine ...@@ -99,7 +99,7 @@ class LLAudioEngine
virtual ~LLAudioEngine(); virtual ~LLAudioEngine();
// initialization/startup/shutdown // initialization/startup/shutdown
virtual bool init(const S32 num_channels, void *userdata); virtual bool init(const S32 num_channels, void *userdata, const std::string &app_title);
virtual std::string getDriverName(bool verbose) = 0; virtual std::string getDriverName(bool verbose) = 0;
virtual void shutdown(); virtual void shutdown();
......
This diff is collapsed.
This diff is collapsed.
/** /**
* @file audioengine_fmodex.h * @file audioengine_fmodstudio.h
* @brief Definition of LLAudioEngine class abstracting the audio * @brief Definition of LLAudioEngine class abstracting the audio
* support as a FMODEX implementation * support as a FMODSTUDIO implementation
* *
* $LicenseInfo:firstyear=2002&license=viewerlgpl$ * $LicenseInfo:firstyear=2020&license=viewerlgpl$
* Second Life Viewer Source Code * Second Life Viewer Source Code
* Copyright (C) 2014, Linden Research, Inc. * Copyright (C) 2020, Linden Research, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
...@@ -25,14 +25,14 @@ ...@@ -25,14 +25,14 @@
* $/LicenseInfo$ * $/LicenseInfo$
*/ */
#ifndef LL_AUDIOENGINE_FMODEX_H #ifndef LL_AUDIOENGINE_FMODSTUDIO_H
#define LL_AUDIOENGINE_FMODEX_H #define LL_AUDIOENGINE_FMODSTUDIO_H
#include "llaudioengine.h" #include "llaudioengine.h"
#include "llwindgen.h" #include "llwindgen.h"
//Stubs //Stubs
class LLAudioStreamManagerFMODEX; class LLAudioStreamManagerFMODSTUDIO;
namespace FMOD namespace FMOD
{ {
class System; class System;
...@@ -44,14 +44,14 @@ namespace FMOD ...@@ -44,14 +44,14 @@ namespace FMOD
typedef struct FMOD_DSP_DESCRIPTION FMOD_DSP_DESCRIPTION; typedef struct FMOD_DSP_DESCRIPTION FMOD_DSP_DESCRIPTION;
//Interfaces //Interfaces
class LLAudioEngine_FMODEX : public LLAudioEngine class LLAudioEngine_FMODSTUDIO : public LLAudioEngine
{ {
public: public:
LLAudioEngine_FMODEX(bool enable_profiler); LLAudioEngine_FMODSTUDIO(bool enable_profiler);
virtual ~LLAudioEngine_FMODEX(); virtual ~LLAudioEngine_FMODSTUDIO();
// initialization/startup/shutdown // initialization/startup/shutdown
virtual bool init(const S32 num_channels, void *user_data); virtual bool init(const S32 num_channels, void *user_data, const std::string &app_title);
virtual std::string getDriverName(bool verbose); virtual std::string getDriverName(bool verbose);
virtual void allocateListener(); virtual void allocateListener();
...@@ -85,11 +85,11 @@ class LLAudioEngine_FMODEX : public LLAudioEngine ...@@ -85,11 +85,11 @@ class LLAudioEngine_FMODEX : public LLAudioEngine
}; };
class LLAudioChannelFMODEX : public LLAudioChannel class LLAudioChannelFMODSTUDIO : public LLAudioChannel
{ {
public: public:
LLAudioChannelFMODEX(FMOD::System *audioengine); LLAudioChannelFMODSTUDIO(FMOD::System *audioengine);
virtual ~LLAudioChannelFMODEX(); virtual ~LLAudioChannelFMODSTUDIO();
protected: protected:
/*virtual*/ void play(); /*virtual*/ void play();
...@@ -110,15 +110,15 @@ class LLAudioChannelFMODEX : public LLAudioChannel ...@@ -110,15 +110,15 @@ class LLAudioChannelFMODEX : public LLAudioChannel
}; };
class LLAudioBufferFMODEX : public LLAudioBuffer class LLAudioBufferFMODSTUDIO : public LLAudioBuffer
{ {
public: public:
LLAudioBufferFMODEX(FMOD::System *audioengine); LLAudioBufferFMODSTUDIO(FMOD::System *audioengine);
virtual ~LLAudioBufferFMODEX(); virtual ~LLAudioBufferFMODSTUDIO();
/*virtual*/ bool loadWAV(const std::string& filename); /*virtual*/ bool loadWAV(const std::string& filename);
/*virtual*/ U32 getLength(); /*virtual*/ U32 getLength();
friend class LLAudioChannelFMODEX; friend class LLAudioChannelFMODSTUDIO;
protected: protected:
FMOD::System *getSystem() const {return mSystemp;} FMOD::System *getSystem() const {return mSystemp;}
FMOD::System *mSystemp; FMOD::System *mSystemp;
...@@ -127,4 +127,4 @@ class LLAudioBufferFMODEX : public LLAudioBuffer ...@@ -127,4 +127,4 @@ class LLAudioBufferFMODEX : public LLAudioBuffer
}; };
#endif // LL_AUDIOENGINE_FMODEX_H #endif // LL_AUDIOENGINE_FMODSTUDIO_H
...@@ -52,7 +52,7 @@ LLAudioEngine_OpenAL::~LLAudioEngine_OpenAL() ...@@ -52,7 +52,7 @@ LLAudioEngine_OpenAL::~LLAudioEngine_OpenAL()
} }
// virtual // virtual
bool LLAudioEngine_OpenAL::init(const S32 num_channels, void* userdata) bool LLAudioEngine_OpenAL::init(const S32 num_channels, void* userdata, const std::string &app_title)
{ {
mWindGen = NULL; mWindGen = NULL;
LLAudioEngine::init(num_channels, userdata); LLAudioEngine::init(num_channels, userdata);
...@@ -239,6 +239,13 @@ bool LLAudioChannelOpenAL::isPlaying() ...@@ -239,6 +239,13 @@ bool LLAudioChannelOpenAL::isPlaying()
bool LLAudioChannelOpenAL::updateBuffer() bool LLAudioChannelOpenAL::updateBuffer()
{ {
if (!mCurrentSourcep)
{
// This channel isn't associated with any source, nothing
// to be updated
return false;
}
if (LLAudioChannel::updateBuffer()) if (LLAudioChannel::updateBuffer())
{ {
// Base class update returned true, which means that we need to actually // Base class update returned true, which means that we need to actually
......
...@@ -40,8 +40,8 @@ class LLAudioEngine_OpenAL : public LLAudioEngine ...@@ -40,8 +40,8 @@ class LLAudioEngine_OpenAL : public LLAudioEngine
LLAudioEngine_OpenAL(); LLAudioEngine_OpenAL();
virtual ~LLAudioEngine_OpenAL(); virtual ~LLAudioEngine_OpenAL();
virtual bool init(const S32 num_channels, void *user_data); virtual bool init(const S32 num_channels, void *user_data, const std::string &app_title);
virtual std::string getDriverName(bool verbose); virtual std::string getDriverName(bool verbose);
virtual void allocateListener(); virtual void allocateListener();
virtual void shutdown(); virtual void shutdown();
......
/** /**
* @file listener_fmodex.cpp * @file listener_fmodstudio.cpp
* @brief Implementation of LISTENER class abstracting the audio * @brief Implementation of LISTENER class abstracting the audio
* support as a FMODEX implementation * support as a FMODSTUDIO implementation
* *
* $LicenseInfo:firstyear=2002&license=viewerlgpl$ * $LicenseInfo:firstyear=2020&license=viewerlgpl$
* Second Life Viewer Source Code * Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc. * Copyright (C) 2020, Linden Research, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
...@@ -27,114 +27,110 @@ ...@@ -27,114 +27,110 @@
#include "linden_common.h" #include "linden_common.h"
#include "llaudioengine.h" #include "llaudioengine.h"
#include "lllistener_fmodex.h" #include "lllistener_fmodstudio.h"
#include "fmod.hpp" #include "fmodstudio/fmod.hpp"
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
// constructor // constructor
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
LLListener_FMODEX::LLListener_FMODEX(FMOD::System *system) LLListener_FMODSTUDIO::LLListener_FMODSTUDIO(FMOD::System *system)
{ {
mSystem = system; mSystem = system;
init(); init();
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
LLListener_FMODEX::~LLListener_FMODEX() LLListener_FMODSTUDIO::~LLListener_FMODSTUDIO()
{ {
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
void LLListener_FMODEX::init(void) void LLListener_FMODSTUDIO::init(void)
{ {
// do inherited // do inherited
LLListener::init(); LLListener::init();
mDopplerFactor = 1.0f; mDopplerFactor = 1.0f;
mRolloffFactor = 1.0f; mRolloffFactor = 1.0f;
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
void LLListener_FMODEX::translate(LLVector3 offset) void LLListener_FMODSTUDIO::translate(LLVector3 offset)
{ {
LLListener::translate(offset); LLListener::translate(offset);
mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)mPosition.mV, NULL, (FMOD_VECTOR*)mListenAt.mV, (FMOD_VECTOR*)mListenUp.mV); mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)mPosition.mV, NULL, (FMOD_VECTOR*)mListenAt.mV, (FMOD_VECTOR*)mListenUp.mV);
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
void LLListener_FMODEX::setPosition(LLVector3 pos) void LLListener_FMODSTUDIO::setPosition(LLVector3 pos)
{ {
LLListener::setPosition(pos); LLListener::setPosition(pos);
mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)mPosition.mV, NULL, (FMOD_VECTOR*)mListenAt.mV, (FMOD_VECTOR*)mListenUp.mV); mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)mPosition.mV, NULL, (FMOD_VECTOR*)mListenAt.mV, (FMOD_VECTOR*)mListenUp.mV);
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
void LLListener_FMODEX::setVelocity(LLVector3 vel) void LLListener_FMODSTUDIO::setVelocity(LLVector3 vel)
{ {
LLListener::setVelocity(vel); LLListener::setVelocity(vel);
mSystem->set3DListenerAttributes(0, NULL, (FMOD_VECTOR*)mVelocity.mV, (FMOD_VECTOR*)mListenAt.mV, (FMOD_VECTOR*)mListenUp.mV); mSystem->set3DListenerAttributes(0, NULL, (FMOD_VECTOR*)mVelocity.mV, (FMOD_VECTOR*)mListenAt.mV, (FMOD_VECTOR*)mListenUp.mV);
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
void LLListener_FMODEX::orient(LLVector3 up, LLVector3 at) void LLListener_FMODSTUDIO::orient(LLVector3 up, LLVector3 at)
{ {
LLListener::orient(up, at); LLListener::orient(up, at);
// Welcome to the transition between right and left // at = -at; by default Fmod studio is 'left-handed' but we are providing
// (coordinate systems, that is) // flag FMOD_INIT_3D_RIGHTHANDED so no correction are needed
// 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); mSystem->set3DListenerAttributes(0, NULL, NULL, (FMOD_VECTOR*)at.mV, (FMOD_VECTOR*)up.mV);
} }
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
void LLListener_FMODEX::commitDeferredChanges() void LLListener_FMODSTUDIO::commitDeferredChanges()
{ {
if(!mSystem) if (!mSystem)
{ {
return; return;
} }
mSystem->update(); mSystem->update();
} }
void LLListener_FMODEX::setRolloffFactor(F32 factor) void LLListener_FMODSTUDIO::setRolloffFactor(F32 factor)
{ {
//An internal FMODEx optimization skips 3D updates if there have not been changes to the 3D sound environment. //An internal FMOD 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. // (this was true for FMODex, looks to be still true for FMOD STUDIO, but needs a recheck)
//In short: Changing the position ticks a dirtyflag inside fmodex, which makes it not skip 3D processing next update call. //Sadly, a change in rolloff is not accounted for, thus we must touch the listener properties as well.
if(mRolloffFactor != factor) //In short: Changing the position ticks a dirtyflag inside fmod, which makes it not skip 3D processing next update call.
{ if (mRolloffFactor != factor)
LLVector3 pos = mVelocity - LLVector3(0.f,0.f,.1f); {
mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)pos.mV, NULL, NULL, NULL); LLVector3 pos = mPosition - LLVector3(0.f, 0.f, .1f);
mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)mVelocity.mV, NULL, NULL, NULL); mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)pos.mV, NULL, NULL, NULL);
} mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)mPosition.mV, NULL, NULL, NULL);
mRolloffFactor = factor; }
mSystem->set3DSettings(mDopplerFactor, 1.f, mRolloffFactor); mRolloffFactor = factor;
mSystem->set3DSettings(mDopplerFactor, 1.f, mRolloffFactor);
} }
F32 LLListener_FMODEX::getRolloffFactor() F32 LLListener_FMODSTUDIO::getRolloffFactor()
{ {
return mRolloffFactor; return mRolloffFactor;
} }
void LLListener_FMODEX::setDopplerFactor(F32 factor) void LLListener_FMODSTUDIO::setDopplerFactor(F32 factor)
{ {
mDopplerFactor = factor; mDopplerFactor = factor;
mSystem->set3DSettings(mDopplerFactor, 1.f, mRolloffFactor); mSystem->set3DSettings(mDopplerFactor, 1.f, mRolloffFactor);
} }
F32 LLListener_FMODEX::getDopplerFactor() F32 LLListener_FMODSTUDIO::getDopplerFactor()
{ {
return mDopplerFactor; return mDopplerFactor;
} }
/** /**
* @file listener_fmodex.h * @file listener_fmodstudio.h
* @brief Description of LISTENER class abstracting the audio support * @brief Description of LISTENER class abstracting the audio support
* as an FMOD 3D implementation (windows and Linux) * as an FMOD 3D implementation
* *
* $LicenseInfo:firstyear=2002&license=viewerlgpl$ * $LicenseInfo:firstyear=2020&license=viewerlgpl$
* Second Life Viewer Source Code * Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc. * Copyright (C) 2020, Linden Research, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
...@@ -25,8 +25,8 @@ ...@@ -25,8 +25,8 @@
* $/LicenseInfo$ * $/LicenseInfo$
*/ */
#ifndef LL_LISTENER_FMODEX_H #ifndef LL_LISTENER_FMODSTUDIO_H
#define LL_LISTENER_FMODEX_H #define LL_LISTENER_FMODSTUDIO_H
#include "lllistener.h" #include "lllistener.h"
...@@ -37,27 +37,27 @@ namespace FMOD ...@@ -37,27 +37,27 @@ namespace FMOD
} }
//Interfaces //Interfaces
class LLListener_FMODEX : public LLListener class LLListener_FMODSTUDIO : public LLListener
{ {
public: public:
LLListener_FMODEX(FMOD::System *system); LLListener_FMODSTUDIO(FMOD::System *system);
virtual ~LLListener_FMODEX(); virtual ~LLListener_FMODSTUDIO();
virtual void init(); virtual void init();
virtual void translate(LLVector3 offset); virtual void translate(LLVector3 offset);
virtual void setPosition(LLVector3 pos); virtual void setPosition(LLVector3 pos);
virtual void setVelocity(LLVector3 vel); virtual void setVelocity(LLVector3 vel);
virtual void orient(LLVector3 up, LLVector3 at); virtual void orient(LLVector3 up, LLVector3 at);
virtual void commitDeferredChanges(); virtual void commitDeferredChanges();
virtual void setDopplerFactor(F32 factor); virtual void setDopplerFactor(F32 factor);
virtual F32 getDopplerFactor(); virtual F32 getDopplerFactor();
virtual void setRolloffFactor(F32 factor); virtual void setRolloffFactor(F32 factor);
virtual F32 getRolloffFactor(); virtual F32 getRolloffFactor();
protected: protected:
FMOD::System *mSystem; FMOD::System *mSystem;
F32 mDopplerFactor; F32 mDopplerFactor;
F32 mRolloffFactor; F32 mRolloffFactor;
}; };
#endif #endif
......
/**
* @file streamingaudio_fmodex.cpp
* @brief LLStreamingAudio_FMODEX implementation
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "llmath.h"
#include "fmod.hpp"
#include "fmod_errors.h"
#include "llstreamingaudio_fmodex.h"
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_OPENSTATE getOpenState(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)
{
// Number of milliseconds of audio to buffer for the audio card.
// Must be larger than the usual Second Life frame stutter time.
const U32 buffer_seconds = 10; //sec
const U32 estimated_bitrate = 128; //kbit/sec
mSystem->setStreamBufferSize(estimated_bitrate * buffer_seconds * 128/*bytes/kbit*/, FMOD_TIMEUNIT_RAWBYTES);
// 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()
{
// nothing interesting/safe to do.
}
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())
{
LL_INFOS() << "Starting internet stream: " << url << LL_ENDL;
mCurrentInternetStreamp = new LLAudioStreamManagerFMODEX(mSystem,url);
mURL = url;
}
else
{
LL_INFOS() << "Set internet stream to null" << LL_ENDL;
mURL.clear();
}
}
void LLStreamingAudio_FMODEX::update()
{
// 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++;
}
}
// Don't do anything if there are no streams playing
if (!mCurrentInternetStreamp)
{
return;
}
unsigned int progress;
bool starving;
bool diskbusy;
FMOD_OPENSTATE open_state = mCurrentInternetStreamp->getOpenState(&progress, &starving, &diskbusy);
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());
mFMODInternetStreamChannelp->setPaused(false);
}
}
else if(open_state == FMOD_OPENSTATE_ERROR)
{
stop();
return;
}
if(mFMODInternetStreamChannelp)
{
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)
{
for(S32 i = 0; i < tagcount; ++i)
{
if(sound->getTag(NULL, i, &tag)!=FMOD_OK)
continue;
if (tag.type == FMOD_TAGTYPE_FMOD)
{
if (!strcmp(tag.name, "Sample Rate Change"))
{
LL_INFOS() << "Stream forced changing sample rate to " << *((float *)tag.data) << LL_ENDL;
mFMODInternetStreamChannelp->setFrequency(*((float *)tag.data));
}
continue;
}
}
}
if(starving)
{
bool paused = false;
mFMODInternetStreamChannelp->getPaused(&paused);
if(!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;
mFMODInternetStreamChannelp->setPaused(true);
}
}
else if(progress > 80)
{
mFMODInternetStreamChannelp->setPaused(false);
}
}
}
}
void LLStreamingAudio_FMODEX::stop()
{
if (mFMODInternetStreamChannelp)
{
mFMODInternetStreamChannelp->setPaused(true);
mFMODInternetStreamChannelp->setPriority(0);
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())
{
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?
mFMODInternetStreamChannelp->setVolume(vol);
}
}
///////////////////////////////////////////////////////
// manager of possibly-multiple internet audio streams
LLAudioStreamManagerFMODEX::LLAudioStreamManagerFMODEX(FMOD::System *system, const std::string& url) :
mSystem(system),
mStreamChannel(NULL),
mInternetStream(NULL),
mReady(false)
{
mInternetStreamURL = url;
FMOD_RESULT result = mSystem->createStream(url.c_str(), FMOD_2D | FMOD_NONBLOCKING | FMOD_IGNORETAGS, 0, &mInternetStream);
if (result!= FMOD_OK)
{
LL_WARNS() << "Couldn't open fmod stream, error "
<< FMOD_ErrorString(result)
<< LL_ENDL;
mReady = false;
return;
}
mReady = true;
}
FMOD::Channel *LLAudioStreamManagerFMODEX::startStream()
{
// We need a live and opened stream before we try and play it.
if (!mInternetStream || getOpenState() != 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.
mSystem->playSound(FMOD_CHANNEL_FREE, mInternetStream, true, &mStreamChannel);
return mStreamChannel;
}
bool LLAudioStreamManagerFMODEX::stopStream()
{
if (mInternetStream)
{
bool close = true;
switch (getOpenState())
{
case FMOD_OPENSTATE_CONNECTING:
close = false;
break;
default:
close = true;
}
if (close)
{
mInternetStream->release();
mStreamChannel = NULL;
mInternetStream = NULL;
return true;
}
else
{
return false;
}
}
else
{
return true;
}
}
FMOD_OPENSTATE LLAudioStreamManagerFMODEX::getOpenState(unsigned int* percentbuffered, bool* starving, bool* diskbusy)
{
FMOD_OPENSTATE state;
mInternetStream->getOpenState(&state, percentbuffered, starving, diskbusy);
return state;
}
void LLStreamingAudio_FMODEX::setBufferSizes(U32 streambuffertime, U32 decodebuffertime)
{
mSystem->setStreamBufferSize(streambuffertime/1000*128*128, FMOD_TIMEUNIT_RAWBYTES);
FMOD_ADVANCEDSETTINGS settings;
memset(&settings,0,sizeof(settings));
settings.cbsize=sizeof(settings);
settings.defaultDecodeBufferSize = decodebuffertime;//ms
mSystem->setAdvancedSettings(&settings);
}
/**
* @file streamingaudio_fmodstudio.cpp
* @brief LLStreamingAudio_FMODSTUDIO implementation
*
* $LicenseInfo:firstyear=2020&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2020, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "llmath.h"
#include "fmodstudio/fmod.hpp"
#include "fmodstudio/fmod_errors.h"
#include "llstreamingaudio_fmodstudio.h"
class LLAudioStreamManagerFMODSTUDIO
{
public:
LLAudioStreamManagerFMODSTUDIO(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_OPENSTATE getOpenState(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_FMODSTUDIO::LLStreamingAudio_FMODSTUDIO(FMOD::System *system) :
mSystem(system),
mCurrentInternetStreamp(NULL),
mFMODInternetStreamChannelp(NULL),
mGain(1.0f)
{
// Number of milliseconds of audio to buffer for the audio card.
// Must be larger than the usual Second Life frame stutter time.
const U32 buffer_seconds = 10; //sec
const U32 estimated_bitrate = 128; //kbit/sec
mSystem->setStreamBufferSize(estimated_bitrate * buffer_seconds * 128/*bytes/kbit*/, FMOD_TIMEUNIT_RAWBYTES);
// 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_FMODSTUDIO::~LLStreamingAudio_FMODSTUDIO()
{
// nothing interesting/safe to do.
}
void LLStreamingAudio_FMODSTUDIO::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())
{
LL_INFOS() << "Starting internet stream: " << url << LL_ENDL;
mCurrentInternetStreamp = new LLAudioStreamManagerFMODSTUDIO(mSystem, url);
mURL = url;
}
else
{
LL_INFOS() << "Set internet stream to null" << LL_ENDL;
mURL.clear();
}
}
void LLStreamingAudio_FMODSTUDIO::update()
{
// Kill dead internet streams, if possible
std::list<LLAudioStreamManagerFMODSTUDIO *>::iterator iter;
for (iter = mDeadStreams.begin(); iter != mDeadStreams.end();)
{
LLAudioStreamManagerFMODSTUDIO *streamp = *iter;
if (streamp->stopStream())
{
LL_INFOS() << "Closed dead stream" << LL_ENDL;
delete streamp;
mDeadStreams.erase(iter++);
}
else
{
iter++;
}
}
// Don't do anything if there are no streams playing
if (!mCurrentInternetStreamp)
{
return;
}
unsigned int progress;
bool starving;
bool diskbusy;
FMOD_OPENSTATE open_state = mCurrentInternetStreamp->getOpenState(&progress, &starving, &diskbusy);
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());
mFMODInternetStreamChannelp->setPaused(false);
}
}
else if (open_state == FMOD_OPENSTATE_ERROR)
{
stop();
return;
}
if (mFMODInternetStreamChannelp)
{
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)
{
for (S32 i = 0; i < tagcount; ++i)
{
if (sound->getTag(NULL, i, &tag) != FMOD_OK)
continue;
if (tag.type == FMOD_TAGTYPE_FMOD)
{
if (!strcmp(tag.name, "Sample Rate Change"))
{
LL_INFOS() << "Stream forced changing sample rate to " << *((float *)tag.data) << LL_ENDL;
mFMODInternetStreamChannelp->setFrequency(*((float *)tag.data));
}
continue;
}
}
}
if (starving)
{
bool paused = false;
mFMODInternetStreamChannelp->getPaused(&paused);
if (!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;
mFMODInternetStreamChannelp->setPaused(true);
}
}
else if (progress > 80)
{
mFMODInternetStreamChannelp->setPaused(false);
}
}
}
}
void LLStreamingAudio_FMODSTUDIO::stop()
{
if (mFMODInternetStreamChannelp)
{
mFMODInternetStreamChannelp->setPaused(true);
mFMODInternetStreamChannelp->setPriority(0);
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_FMODSTUDIO::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_FMODSTUDIO::isPlaying()
{
if (mCurrentInternetStreamp)
{
return 1; // Active and playing
}
else if (!mURL.empty())
{
return 2; // "Paused"
}
else
{
return 0;
}
}
F32 LLStreamingAudio_FMODSTUDIO::getGain()
{
return mGain;
}
std::string LLStreamingAudio_FMODSTUDIO::getURL()
{
return mURL;
}
void LLStreamingAudio_FMODSTUDIO::setGain(F32 vol)
{
mGain = vol;
if (mFMODInternetStreamChannelp)
{
vol = llclamp(vol * vol, 0.f, 1.f); //should vol be squared here?
mFMODInternetStreamChannelp->setVolume(vol);
}
}
///////////////////////////////////////////////////////
// manager of possibly-multiple internet audio streams
LLAudioStreamManagerFMODSTUDIO::LLAudioStreamManagerFMODSTUDIO(FMOD::System *system, const std::string& url) :
mSystem(system),
mStreamChannel(NULL),
mInternetStream(NULL),
mReady(false)
{
mInternetStreamURL = url;
FMOD_RESULT result = mSystem->createStream(url.c_str(), FMOD_2D | FMOD_NONBLOCKING | FMOD_IGNORETAGS, 0, &mInternetStream);
if (result != FMOD_OK)
{
LL_WARNS() << "Couldn't open fmod stream, error "
<< FMOD_ErrorString(result)
<< LL_ENDL;
mReady = false;
return;
}
mReady = true;
}
FMOD::Channel *LLAudioStreamManagerFMODSTUDIO::startStream()
{
// We need a live and opened stream before we try and play it.
if (!mInternetStream || getOpenState() != 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.
mSystem->playSound(mInternetStream, NULL, true, &mStreamChannel);
return mStreamChannel;
}
bool LLAudioStreamManagerFMODSTUDIO::stopStream()
{
if (mInternetStream)
{
bool close = true;
switch (getOpenState())
{
case FMOD_OPENSTATE_CONNECTING:
close = false;
break;
default:
close = true;
}
if (close)
{
mInternetStream->release();
mStreamChannel = NULL;
mInternetStream = NULL;
return true;
}
else
{
return false;
}
}
else
{
return true;
}
}
FMOD_OPENSTATE LLAudioStreamManagerFMODSTUDIO::getOpenState(unsigned int* percentbuffered, bool* starving, bool* diskbusy)
{
FMOD_OPENSTATE state;
mInternetStream->getOpenState(&state, percentbuffered, starving, diskbusy);
return state;
}
void LLStreamingAudio_FMODSTUDIO::setBufferSizes(U32 streambuffertime, U32 decodebuffertime)
{
mSystem->setStreamBufferSize(streambuffertime / 1000 * 128 * 128, FMOD_TIMEUNIT_RAWBYTES);
FMOD_ADVANCEDSETTINGS settings;
memset(&settings, 0, sizeof(settings));
settings.cbSize = sizeof(settings);
settings.defaultDecodeBufferSize = decodebuffertime;//ms
mSystem->setAdvancedSettings(&settings);
}
/** /**
* @file streamingaudio_fmodex.h * @file streamingaudio_fmodstudio.h
* @brief Definition of LLStreamingAudio_FMODEX implementation * @brief Definition of LLStreamingAudio_FMODSTUDIO implementation
* *
* $LicenseInfo:firstyear=2002&license=viewerlgpl$ * $LicenseInfo:firstyear=2020&license=viewerlgpl$
* Second Life Viewer Source Code * Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc. * Copyright (C) 2020, Linden Research, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
...@@ -24,8 +24,8 @@ ...@@ -24,8 +24,8 @@
* $/LicenseInfo$ * $/LicenseInfo$
*/ */
#ifndef LL_STREAMINGAUDIO_FMODEX_H #ifndef LL_STREAMINGAUDIO_FMODSTUDIO_H
#define LL_STREAMINGAUDIO_FMODEX_H #define LL_STREAMINGAUDIO_FMODSTUDIO_H
#include "stdtypes.h" // from llcommon #include "stdtypes.h" // from llcommon
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
#include "lltimer.h" #include "lltimer.h"
//Stubs //Stubs
class LLAudioStreamManagerFMODEX; class LLAudioStreamManagerFMODSTUDIO;
namespace FMOD namespace FMOD
{ {
class System; class System;
...@@ -41,33 +41,33 @@ namespace FMOD ...@@ -41,33 +41,33 @@ namespace FMOD
} }
//Interfaces //Interfaces
class LLStreamingAudio_FMODEX : public LLStreamingAudioInterface class LLStreamingAudio_FMODSTUDIO : public LLStreamingAudioInterface
{ {
public: public:
LLStreamingAudio_FMODEX(FMOD::System *system); LLStreamingAudio_FMODSTUDIO(FMOD::System *system);
/*virtual*/ ~LLStreamingAudio_FMODEX(); /*virtual*/ ~LLStreamingAudio_FMODSTUDIO();
/*virtual*/ void start(const std::string& url); /*virtual*/ void start(const std::string& url);
/*virtual*/ void stop(); /*virtual*/ void stop();
/*virtual*/ void pause(S32 pause); /*virtual*/ void pause(S32 pause);
/*virtual*/ void update(); /*virtual*/ void update();
/*virtual*/ S32 isPlaying(); /*virtual*/ S32 isPlaying();
/*virtual*/ void setGain(F32 vol); /*virtual*/ void setGain(F32 vol);
/*virtual*/ F32 getGain(); /*virtual*/ F32 getGain();
/*virtual*/ std::string getURL(); /*virtual*/ std::string getURL();
/*virtual*/ bool supportsAdjustableBufferSizes(){return true;} /*virtual*/ bool supportsAdjustableBufferSizes(){return true;}
/*virtual*/ void setBufferSizes(U32 streambuffertime, U32 decodebuffertime); /*virtual*/ void setBufferSizes(U32 streambuffertime, U32 decodebuffertime);
private: private:
FMOD::System *mSystem; FMOD::System *mSystem;
LLAudioStreamManagerFMODEX *mCurrentInternetStreamp; LLAudioStreamManagerFMODSTUDIO *mCurrentInternetStreamp;
FMOD::Channel *mFMODInternetStreamChannelp; FMOD::Channel *mFMODInternetStreamChannelp;
std::list<LLAudioStreamManagerFMODEX *> mDeadStreams; std::list<LLAudioStreamManagerFMODSTUDIO *> mDeadStreams;
std::string mURL; std::string mURL;
F32 mGain; F32 mGain;
}; };
#endif // LL_STREAMINGAUDIO_FMODEX_H #endif // LL_STREAMINGAUDIO_FMODSTUDIO_H
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment