Compare commits

..

1 Commits

Author SHA1 Message Date
Shyotl
43aa145c94 It's silly that this was necessary... but it was. AMD... :( 2015-02-25 21:11:06 -06:00
1043 changed files with 14089 additions and 15918 deletions

View File

@@ -4,7 +4,7 @@
# other commands to guarantee full compatibility
# with the version specified
cmake_minimum_required(VERSION 2.8.10 FATAL_ERROR)
cmake_minimum_required(VERSION 2.6.2 FATAL_ERROR)
# Eventually the third-party support modules (cmake/*.cmake) should
# know the full path to all libraries. Until that happens we need
@@ -15,7 +15,7 @@ cmake_minimum_required(VERSION 2.8.10 FATAL_ERROR)
# CMP0003 to OLD and link to one library (apr) on a per-configuration
# basis to convince CMake to add the proper link directory. This line
# can be removed when we use full paths for all libraries.
#cmake_policy(SET CMP0003 OLD)
cmake_policy(SET CMP0003 OLD)
set(ROOT_PROJECT_NAME "Singularity" CACHE STRING
"The root project/makefile/solution name. Defaults to Singularity.")
@@ -27,6 +27,7 @@ include(Variables)
# Load versions now. Install locations need them.
include(BuildVersion)
include(UnixInstall)
if (NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE)
@@ -40,9 +41,6 @@ if(NOT STANDALONE)
# We prepare prebuilt binaries when not building standalone.
set(prepare_depends ${CMAKE_BINARY_DIR}/prepare/prebuilt)
endif(NOT STANDALONE)
if(WINDOWS)
set(prepare_depends ${prepare_depends} copy_win_libs)
endif(WINDOWS)
add_custom_target(prepare DEPENDS ${prepare_depends})
add_subdirectory(cmake)
@@ -109,16 +107,3 @@ add_custom_command(
DEPENDS ${CMAKE_SOURCE_DIR}/../install.xml
${CMAKE_BINARY_DIR}/DownloadPrebuilt.cmake
)
if(WINDOWS)
configure_file(${CMAKE_SOURCE_DIR}/cmake/CopyWinLibs.cmake.in
${CMAKE_BINARY_DIR}/CopyWinLibs.cmake @ONLY)
add_custom_command(
COMMENT "Copying prebuilt libraries to viewer executable directory"
OUTPUT ${CMAKE_BINARY_DIR}/CopyWinLibs
COMMAND ${CMAKE_COMMAND} -DCUR_CONFIG:STRING=${CMAKE_CFG_INTDIR} -P ${CMAKE_BINARY_DIR}/CopyWinLibs.cmake
DEPENDS ${CMAKE_BINARY_DIR}/prepare/prebuilt ${CMAKE_BINARY_DIR}/CopyWinLibs.cmake
)
add_custom_target(copy_win_libs DEPENDS ${CMAKE_BINARY_DIR}/CopyWinLibs)
endif(WINDOWS)

View File

@@ -440,7 +440,7 @@ void AIStateMachine::multiplex(event_type event)
// our need to run (by us having set need_run), so there is no need to run
// ourselves.
llassert(!mMultiplexMutex.isSelfLocked()); // We may never enter recursively!
if (!mMultiplexMutex.try_lock())
if (!mMultiplexMutex.tryLock())
{
Dout(dc::statemachine(mSMDebug), "Leaving because it is already being run [" << (void*)this << "]");
return;
@@ -762,7 +762,7 @@ void AIStateMachine::multiplex(event_type event)
//=========================================
// Release the lock on mMultiplexMutex *first*, before releasing the lock on mState,
// to avoid to ever call the try_lock() and fail, while this thread isn't still
// to avoid to ever call the tryLock() and fail, while this thread isn't still
// BEFORE the critical area of mState!
mMultiplexMutex.unlock();
@@ -1262,7 +1262,7 @@ void AIStateMachine::abort(void)
multiplex(insert_abort);
}
// Block until the current run finished.
if (!mRunMutex.try_lock())
if (!mRunMutex.tryLock())
{
llwarns << "AIStateMachine::abort() blocks because the statemachine is still executing code in another thread." << llendl;
mRunMutex.lock();

View File

@@ -45,10 +45,11 @@ if (WINDOWS)
if (MSVC10)
set(MSVC_DIR 10.0)
set(MSVC_SUFFIX 100)
elseif (MSVC12)
set(MSVC_DIR 12.0)
set(MSVC_SUFFIX 120)
endif (MSVC10)
if (MSVC11)
set(MSVC_DIR 11.0)
set(MSVC_SUFFIX 110)
endif (MSVC11)
# Remove default /Zm1000 flag that cmake inserts
string (REPLACE "/Zm1000" " " CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
@@ -84,27 +85,21 @@ if (WINDOWS)
/W3
/c
/Zc:forScope
/Zc:wchar_t-
/Zc:wchar_t-
/nologo
/Oy-
)
# SSE2 is implied on win64
if(WORD_SIZE EQUAL 32)
add_definitions(/arch:SSE2 /D_ATL_XP_TARGETING)
add_definitions(/arch:SSE2)
else(WORD_SIZE EQUAL 32)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /wd4267 /wd4250 /wd4244")
endif(WORD_SIZE EQUAL 32)
if (MSVC12)
# configure win32 API for windows vista+ compatibility
set(WINVER "0x0600" CACHE STRING "Win32 API Target version (see http://msdn.microsoft.com/en-us/library/aa383745%28v=VS.85%29.aspx)")
add_definitions("/DWINVER=${WINVER}" "/D_WIN32_WINNT=${WINVER}")
else (MSVC12)
# configure win32 API for windows XP+ compatibility
set(WINVER "0x0501" CACHE STRING "Win32 API Target version (see http://msdn.microsoft.com/en-us/library/aa383745%28v=VS.85%29.aspx)")
add_definitions("/DWINVER=${WINVER}" "/D_WIN32_WINNT=${WINVER}")
endif (MSVC12)
# configure win32 API for windows XP+ compatibility
set(WINVER "0x0501" CACHE STRING "Win32 API Target version (see http://msdn.microsoft.com/en-us/library/aa383745%28v=VS.85%29.aspx)")
add_definitions("/DWINVER=${WINVER}" "/D_WIN32_WINNT=${WINVER}")
# Are we using the crummy Visual Studio KDU build workaround?
if (NOT DISABLE_FATAL_WARNINGS)

View File

@@ -14,25 +14,25 @@ else (STANDALONE)
use_prebuilt_binary(apr_suite)
if (WINDOWS)
set(APR_LIBRARIES
debug libapr-1.lib
optimized libapr-1.lib
debug ${ARCH_PREBUILT_DIRS_DEBUG}/libapr-1.lib
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libapr-1.lib
)
set(APRICONV_LIBRARIES
debug libapriconv-1.lib
optimized libapriconv-1.lib
debug ${ARCH_PREBUILT_DIRS_DEBUG}/libapriconv-1.lib
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libapriconv-1.lib
)
set(APRUTIL_LIBRARIES
debug libaprutil-1.lib
optimized libaprutil-1.lib
debug ${ARCH_PREBUILT_DIRS_DEBUG}/libaprutil-1.lib ${APRICONV_LIBRARIES}
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libaprutil-1.lib ${APRICONV_LIBRARIES}
)
elseif (DARWIN)
set(APR_LIBRARIES
debug libapr-1.0.dylib
optimized libapr-1.0.dylib
debug ${ARCH_PREBUILT_DIRS_DEBUG}/libapr-1.0.dylib
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libapr-1.0.dylib
)
set(APRUTIL_LIBRARIES
debug libaprutil-1.dylib
optimized libaprutil-1.dylib
set(APRUTIL_LIBRARIES
debug ${ARCH_PREBUILT_DIRS_DEBUG}/libaprutil-1.dylib
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libaprutil-1.dylib
)
set(APRICONV_LIBRARIES iconv)
else (WINDOWS)
@@ -40,10 +40,7 @@ else (STANDALONE)
set(APRUTIL_LIBRARIES aprutil-1)
set(APRICONV_LIBRARIES iconv)
endif (WINDOWS)
set(APR_INCLUDE_DIR
${LIBS_PREBUILT_DIR}/include/apr-1
${LIBS_PREBUILT_LEGACY_DIR}/include/apr-1
)
set(APR_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/apr-1)
if (LINUX)
list(APPEND APRUTIL_LIBRARIES ${DB_LIBRARIES})

View File

@@ -9,10 +9,7 @@ if (STANDALONE)
pkg_check_modules(VORBISFILE REQUIRED vorbisfile)
else (STANDALONE)
use_prebuilt_binary(ogg-vorbis)
set(VORBIS_INCLUDE_DIRS
${LIBS_PREBUILT_DIR}/include
${LIBS_PREBUILT_LEGACY_DIR}/include
)
set(VORBIS_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include)
set(VORBISENC_INCLUDE_DIRS ${VORBIS_INCLUDE_DIRS})
set(VORBISFILE_INCLUDE_DIRS ${VORBIS_INCLUDE_DIRS})

View File

@@ -13,8 +13,5 @@ else (STANDALONE)
else (LINUX)
set(DB_LIBRARIES db-4.2)
endif (LINUX)
set(DB_INCLUDE_DIRS
${LIBS_PREBUILT_DIR}/include
${LIBS_PREBUILT_LEGACY_DIR}/include
)
set(DB_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include)
endif (STANDALONE)

View File

@@ -11,10 +11,7 @@ if (STANDALONE)
find_package(Boost 1.51.0 COMPONENTS date_time filesystem program_options regex system thread wave context)
else (STANDALONE)
use_prebuilt_binary(boost)
set(Boost_INCLUDE_DIRS
${LIBS_PREBUILT_DIR}/include
${LIBS_PREBUILT_LEGACY_DIR}/include
)
set(Boost_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include)
set(Boost_VERSION "1.52")
if (WINDOWS)

View File

@@ -38,6 +38,11 @@ if (WINDOWS)
${CMAKE_SOURCE_DIR}/newview/res/viewerRes.rc.in
${CMAKE_SOURCE_DIR}/newview/res/viewerRes.rc
)
configure_file(
${CMAKE_SOURCE_DIR}/newview/res/viewerRes_bc.rc.in
${CMAKE_SOURCE_DIR}/newview/res/viewerRes_bc.rc
)
endif (WINDOWS)
if (DARWIN)
@@ -70,12 +75,13 @@ if (LINUX)
)
endif (LINUX)
# Compose the version.
set(${ROOT_PROJECT_NAME}_VERSION "${vMAJOR}.${vMINOR}.${vPATCH}.${vBUILD}")
if (${ROOT_PROJECT_NAME}_VERSION MATCHES "^[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+$")
message(STATUS "Version is ${${ROOT_PROJECT_NAME}_VERSION}")
else (${ROOT_PROJECT_NAME}_VERSION MATCHES "^[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+$")
message(FATAL_ERROR "Could not determine version (${${ROOT_PROJECT_NAME}_VERSION})")
endif (${ROOT_PROJECT_NAME}_VERSION MATCHES "^[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+$")
set(viewer_VERSION "${vMAJOR}.${vMINOR}.${vPATCH}.${vBUILD}")
if (viewer_VERSION MATCHES "^[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+$")
message(STATUS "Version is ${viewer_VERSION}")
else (viewer_VERSION MATCHES "^[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+$")
message(FATAL_ERROR "Could not determine version (${viewer_VERSION})")
endif (viewer_VERSION MATCHES "^[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+$")
# Report version to caller.
#set(viewer_VERSION "${viewer_VERSION}" PARENT_SCOPE)

View File

@@ -13,15 +13,12 @@ else (STANDALONE)
add_definitions("-DCARES_STATICLIB")
set(CARES_LIBRARIES areslib)
elseif (DARWIN)
set(CARES_LIBRARIES
debug libcares.a
optimized libcares.a
set(CARES_LIBRARIES
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libcares.a
debug ${ARCH_PREBUILT_DIRS_DEBUG}/libcares.a
)
else (WINDOWS)
set(CARES_LIBRARIES cares)
endif (WINDOWS)
set(CARES_INCLUDE_DIRS
${LIBS_PREBUILT_DIR}/include/ares
${LIBS_PREBUILT_LEGACY_DIR}/include/ares
)
set(CARES_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/ares)
endif (STANDALONE)

View File

@@ -29,8 +29,8 @@ set(cmake_SOURCE_FILES
ELFIO.cmake
EXPAT.cmake
ExamplePlugin.cmake
FMOD.cmake
FMODEX.cmake
FMODSTUDIO.cmake
FindAPR.cmake
FindBerkeleyDB.cmake
FindCARes.cmake

View File

@@ -18,8 +18,5 @@ else (STANDALONE)
list(APPEND CURL_LIBRARIES idn)
endif(LINUX AND WORD_SIZE EQUAL 64)
endif (WINDOWS)
set(CURL_INCLUDE_DIRS
${LIBS_PREBUILT_DIR}/include
${LIBS_PREBUILT_LEGACY_DIR}/include
)
set(CURL_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include)
endif (STANDALONE)

View File

@@ -1,7 +1,6 @@
# -*- cmake -*-
include(Prebuilt)
include(Boost)
set(COLLADADOM_FIND_QUIETLY OFF)
set(COLLADADOM_FIND_REQUIRED ON)
@@ -20,33 +19,16 @@ else (STANDALONE)
endif (NOT DARWIN AND NOT WINDOWS)
set(COLLADADOM_INCLUDE_DIRS
${LIBS_PREBUILT_DIR}/include/collada
${LIBS_PREBUILT_DIR}/include/collada/1.4
${LIBS_PREBUILT_LEGACY_DIR}/include/collada
${LIBS_PREBUILT_LEGACY_DIR}/include/collada/1.4
)
${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/collada
${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/collada/1.4
)
if (WINDOWS)
if(MSVC12)
use_prebuilt_binary(pcre)
use_prebuilt_binary(libxml)
set(COLLADADOM_LIBRARIES
debug libcollada14dom23-sd
optimized libcollada14dom23-s
libxml2_a
debug pcrecppd
optimized pcrecpp
debug pcred
optimized pcre
${BOOST_SYSTEM_LIBRARIES}
add_definitions(-DDOM_DYNAMIC)
set(COLLADADOM_LIBRARIES
debug libcollada14dom22-d
optimized libcollada14dom22
)
else(MSVC12)
add_definitions(-DDOM_DYNAMIC)
set(COLLADADOM_LIBRARIES
debug libcollada14dom22-d
optimized libcollada14dom22
)
endif(MSVC12)
else (WINDOWS)
set(COLLADADOM_LIBRARIES
collada14dom

View File

@@ -2,7 +2,7 @@
# Copies a binary back to the source directory
MACRO(COPY_BACK_TO_SOURCE target)
SET(FROM $<TARGET_FILE:${target}>)
GET_TARGET_PROPERTY(FROM ${target} LOCATION)
SET(TO ${CMAKE_CURRENT_SOURCE_DIR})
#MESSAGE("TARGET ${target} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${FROM} ${TO}")
ADD_CUSTOM_COMMAND(

View File

@@ -0,0 +1,320 @@
# -*- cmake -*-
# The copy_win_libs folder contains file lists and a script used to
# copy dlls, exes and such needed to run the SecondLife from within
# VisualStudio.
include(CMakeCopyIfDifferent)
if(WORD_SIZE EQUAL 32)
set(debug_libs_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/debug")
set(release_libs_dir "${CMAKE_SOURCE_DIR}/../libraries/i686-win32/lib/release")
else(WORD_SIZE EQUAL 32)
set(debug_libs_dir "${CMAKE_SOURCE_DIR}/../libraries/x86_64-win/lib/debug")
set(release_libs_dir "${CMAKE_SOURCE_DIR}/../libraries/x86_64-win/lib/release")
endif(WORD_SIZE EQUAL 32)
set(vivox_src_dir "${CMAKE_SOURCE_DIR}/newview/vivox-runtime/i686-win32")
set(vivox_files
ca-bundle.crt
libsndfile-1.dll
ortp.dll
SLVoice.exe
vivoxoal.dll
vivoxplatform.dll
vivoxsdk.dll
zlib1.dll
)
copy_if_different(
${vivox_src_dir}
"${CMAKE_CURRENT_BINARY_DIR}/Debug"
out_targets
${vivox_files}
)
set(all_targets ${all_targets} ${out_targets})
set(debug_src_dir "${debug_libs_dir}")
set(debug_files
libhunspell.dll
libapr-1.dll
libaprutil-1.dll
libapriconv-1.dll
libeay32.dll
ssleay32.dll
libcollada14dom22-d.dll
glod.dll
)
copy_if_different(
${debug_src_dir}
"${CMAKE_CURRENT_BINARY_DIR}/Debug"
out_targets
${debug_files}
)
set(all_targets ${all_targets} ${out_targets})
# Debug config runtime files required for the plugin test mule
set(plugintest_debug_src_dir "${debug_libs_dir}")
set(plugintest_debug_files
libeay32.dll
qtcored4.dll
qtguid4.dll
qtnetworkd4.dll
qtopengld4.dll
qtwebkitd4.dll
ssleay32.dll
)
copy_if_different(
${plugintest_debug_src_dir}
"${CMAKE_CURRENT_BINARY_DIR}/../test_apps/llplugintest/Debug"
out_targets
${plugintest_debug_files}
)
set(all_targets ${all_targets} ${out_targets})
# Debug config runtime files required for the plugin test mule (Qt image format plugins)
set(plugintest_debug_src_dir "${debug_libs_dir}/imageformats")
set(plugintest_debug_files
qgifd4.dll
qicod4.dll
qjpegd4.dll
qmngd4.dll
qsvgd4.dll
qtiffd4.dll
)
copy_if_different(
${plugintest_debug_src_dir}
"${CMAKE_CURRENT_BINARY_DIR}/../test_apps/llplugintest/Debug/imageformats"
out_targets
${plugintest_debug_files}
)
set(all_targets ${all_targets} ${out_targets})
copy_if_different(
${plugintest_debug_src_dir}
"${CMAKE_CURRENT_BINARY_DIR}/llplugin/imageformats"
out_targets
${plugintest_debug_files}
)
set(all_targets ${all_targets} ${out_targets})
# Release & ReleaseDebInfo config runtime files required for the plugin test mule
set(plugintest_release_src_dir "${release_libs_dir}")
set(plugintest_release_files
libeay32.dll
qtcore4.dll
qtgui4.dll
qtnetwork4.dll
qtopengl4.dll
qtwebkit4.dll
ssleay32.dll
)
copy_if_different(
${plugintest_release_src_dir}
"${CMAKE_CURRENT_BINARY_DIR}/../test_apps/llplugintest/Release"
out_targets
${plugintest_release_files}
)
set(all_targets ${all_targets} ${out_targets})
copy_if_different(
${plugintest_release_src_dir}
"${CMAKE_CURRENT_BINARY_DIR}/../test_apps/llplugintest/RelWithDebInfo"
out_targets
${plugintest_release_files}
)
set(all_targets ${all_targets} ${out_targets})
# Release & ReleaseDebInfo config runtime files required for the plugin test mule (Qt image format plugins)
set(plugintest_release_src_dir "${release_libs_dir}/imageformats")
set(plugintest_release_files
qgif4.dll
qico4.dll
qjpeg4.dll
qmng4.dll
qsvg4.dll
qtiff4.dll
)
copy_if_different(
${plugintest_release_src_dir}
"${CMAKE_CURRENT_BINARY_DIR}/../test_apps/llplugintest/Release/imageformats"
out_targets
${plugintest_release_files}
)
set(all_targets ${all_targets} ${out_targets})
copy_if_different(
${plugintest_release_src_dir}
"${CMAKE_CURRENT_BINARY_DIR}/../test_apps/llplugintest/RelWithDebInfo/imageformats"
out_targets
${plugintest_release_files}
)
set(all_targets ${all_targets} ${out_targets})
copy_if_different(
${plugintest_release_src_dir}
"${CMAKE_CURRENT_BINARY_DIR}/Release/llplugin/imageformats"
out_targets
${plugintest_release_files}
)
set(all_targets ${all_targets} ${out_targets})
copy_if_different(
${plugintest_release_src_dir}
"${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/llplugin/imageformats"
out_targets
${plugintest_release_files}
)
set(all_targets ${all_targets} ${out_targets})
# Debug config runtime files required for the plugins
set(plugins_debug_src_dir "${debug_libs_dir}")
set(plugins_debug_files
libeay32.dll
qtcored4.dll
qtguid4.dll
qtnetworkd4.dll
qtopengld4.dll
qtwebkitd4.dll
ssleay32.dll
)
copy_if_different(
${plugins_debug_src_dir}
"${CMAKE_CURRENT_BINARY_DIR}/Debug/llplugin"
out_targets
${plugins_debug_files}
)
set(all_targets ${all_targets} ${out_targets})
# Release & ReleaseDebInfo config runtime files required for the plugins
set(plugins_release_src_dir "${release_libs_dir}")
set(plugins_release_files
libeay32.dll
qtcore4.dll
qtgui4.dll
qtnetwork4.dll
qtopengl4.dll
qtwebkit4.dll
ssleay32.dll
)
copy_if_different(
${plugins_release_src_dir}
"${CMAKE_CURRENT_BINARY_DIR}/Release/llplugin"
out_targets
${plugins_release_files}
)
set(all_targets ${all_targets} ${out_targets})
copy_if_different(
${plugins_release_src_dir}
"${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo/llplugin"
out_targets
${plugins_release_files}
)
set(all_targets ${all_targets} ${out_targets})
set(release_src_dir "${release_libs_dir}")
set(release_files
libhunspell.dll
libapr-1.dll
libaprutil-1.dll
libapriconv-1.dll
libeay32.dll
ssleay32.dll
libcollada14dom22.dll
glod.dll
)
if(WORD_SIZE EQUAL 32)
set(release_files ${release_files}
libtcmalloc_minimal.dll
)
endif(WORD_SIZE EQUAL 32)
if(FMODEX)
if (WORD_SIZE EQUAL 32)
set(fmodex_dll_file "fmodex.dll")
else (WORD_SIZE EQUAL 32)
set(fmodex_dll_file "fmodex64.dll")
endif (WORD_SIZE EQUAL 32)
find_path(FMODEX_BINARY_DIR "${fmodex_dll_file}"
"${release_src_dir}"
"${FMODEX_SDK_DIR}/api"
"${FMODEX_SDK_DIR}"
NO_DEFAULT_PATH
)
if(FMODEX_BINARY_DIR)
copy_if_different("${FMODEX_BINARY_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/Release" out_targets "${fmodex_dll_file}")
set(all_targets ${all_targets} ${out_targets})
copy_if_different("${FMODEX_BINARY_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo" out_targets "${fmodex_dll_file}")
set(all_targets ${all_targets} ${out_targets})
copy_if_different("${FMODEX_BINARY_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/Debug" out_targets "${fmodex_dll_file}")
set(all_targets ${all_targets} ${out_targets})
endif(FMODEX_BINARY_DIR)
endif(FMODEX)
if(FMOD)
find_path(FMOD_BINARY_DIR fmod.dll
${release_src_dir}
${FMOD_SDK_DIR}/api
${FMOD_SDK_DIR}
)
if(FMOD_BINARY_DIR)
copy_if_different("${FMOD_BINARY_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/Release" out_targets fmod.dll)
set(all_targets ${all_targets} ${out_targets})
copy_if_different("${FMOD_BINARY_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo" out_targets fmod.dll)
set(all_targets ${all_targets} ${out_targets})
copy_if_different("${FMOD_BINARY_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/Debug" out_targets fmod.dll)
set(all_targets ${all_targets} ${out_targets})
else(FMOD_BINARY_DIR)
list(APPEND release_files fmod.dll) #Required for compile. This will cause an error in copying binaries.
endif(FMOD_BINARY_DIR)
endif(FMOD)
copy_if_different(
${release_src_dir}
"${CMAKE_CURRENT_BINARY_DIR}/Release"
out_targets
${release_files}
)
set(all_targets ${all_targets} ${out_targets})
copy_if_different(
${vivox_src_dir}
"${CMAKE_CURRENT_BINARY_DIR}/Release"
out_targets
${vivox_files}
)
set(all_targets ${all_targets} ${out_targets})
copy_if_different(
${release_src_dir}
"${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo"
out_targets
${release_files}
)
set(all_targets ${all_targets} ${out_targets})
copy_if_different(
${vivox_src_dir}
"${CMAKE_CURRENT_BINARY_DIR}/RelWithDebInfo"
out_targets
${vivox_files}
)
set(all_targets ${all_targets} ${out_targets})
add_custom_target(copy_win_libs ALL
DEPENDS
${all_targets}
${release_appconfig_file}
${relwithdebinfo_appconfig_file}
${debug_appconfig_file}
)
add_dependencies(copy_win_libs prepare)

View File

@@ -1,181 +0,0 @@
# -*- cmake -*-
# The copy_win_libs folder contains file lists and a script used to
# copy dlls, exes and such needed to run the SecondLife from within
# VisualStudio.
set(LIBS_PREBUILT_DIR "@LIBS_PREBUILT_DIR@")
set(LIBS_PREBUILT_LEGACY_DIR "@LIBS_PREBUILT_LEGACY_DIR@")
set(MSVC10 "@MSVC10@")
set(WORD_SIZE "@WORD_SIZE@")
set(LIBS_RELEASE_DIR
${LIBS_PREBUILT_DIR}/lib/release
${LIBS_PREBUILT_LEGACY_DIR}/lib/release
)
set(LIBS_DEBUG_DIR
${LIBS_PREBUILT_DIR}/lib/debug
${LIBS_PREBUILT_LEGACY_DIR}/lib/debug
)
function(copy_files paths names dest)
string(FIND ${dest} ${CUR_CONFIG} idx)
if(${idx} LESS 0)
return()
endif(${idx} LESS 0)
foreach(f ${names})
foreach(p ${paths})
set(from_file "${p}/${f}")
set(to_dest "${CMAKE_BINARY_DIR}/newview/${dest}/")
if(EXISTS ${from_file})
message("Copying ${from_file} to ${to_dest}")
if(NOT EXISTS ${to_dest})
execute_process(COMMAND md "${to_dest}")
endif(NOT EXISTS ${to_dest})
execute_process(COMMAND ${CMAKE_COMMAND} -E copy "${from_file}" "${to_dest}${f}" RESULT_VARIABLE result)
if(${result})
message(SEND_ERROR "Unsuccessful.")
endif(${result})
set(found 1)
break()
endif(EXISTS ${from_file})
endforeach(p)
if(NOT found)
message(SEND_ERROR "Failed to find library: ${f}")
endif(NOT found)
endforeach(f)
endfunction(copy_files)
set(vivox_files
ca-bundle.crt
libsndfile-1.dll
ortp.dll
SLVoice.exe
vivoxoal.dll
vivoxplatform.dll
vivoxsdk.dll
zlib1.dll
)
copy_files("${LIBS_RELEASE_DIR}" "${vivox_files}" "Release" )
copy_files("${LIBS_RELEASE_DIR}" "${vivox_files}" "RelWithDebInfo")
copy_files("${LIBS_DEBUG_DIR}" "${vivox_files}" "Debug")
set(release_files
libhunspell.dll
libapr-1.dll
libaprutil-1.dll
libapriconv-1.dll
libeay32.dll
ssleay32.dll
glod.dll
qtcore4.dll
)
copy_files("${LIBS_RELEASE_DIR}" "${release_files}" "Release")
copy_files("${LIBS_RELEASE_DIR}" "${release_files}" "RelWithDebInfo")
copy_files("${LIBS_DEBUG_DIR}" "${release_files}" "Debug")
if(MSVC10)
copy_files("${LIBS_DEBUG_DIR}" "libcollada14dom22-d.dll" "Debug")
endif(MSVC10)
if(WORD_SIZE EQUAL 32)
set(release_files
libcollada14dom22.dll
libtcmalloc_minimal.dll
)
copy_files("${LIBS_RELEASE_DIR}" "${release_files}" "Release")
copy_files("${LIBS_RELEASE_DIR}" "${release_files}" "RelWithDebInfo")
endif(WORD_SIZE EQUAL 32)
set(plugins_release_files
libeay32.dll
qtcore4.dll
qtgui4.dll
qtnetwork4.dll
qtopengl4.dll
qtwebkit4.dll
ssleay32.dll
qtxmlpatterns4.dll
)
copy_files("${LIBS_RELEASE_DIR}" "${plugins_release_files}" "Release/llplugin")
copy_files("${LIBS_RELEASE_DIR}" "${plugins_release_files}" "RelWithDebInfo/llplugin")
if(0)
copy_files("${LIBS_RELEASE_DIR}" "${plugin_release_files}" "../test_apps/llplugintest/Release")
copy_files("${LIBS_RELEASE_DIR}" "${plugin_release_files}" "../test_apps/llplugintest/RelWithDebInfo")
endif(0)
# Debug config runtime files required for the plugins
set(plugins_debug_files
libeay32.dll
qtcored4.dll
qtguid4.dll
qtnetworkd4.dll
qtopengld4.dll
qtwebkitd4.dll
ssleay32.dll
qtxmlpatternsd4.dll
)
copy_files("${LIBS_DEBUG_DIR}" "${plugins_debug_files}" "Debug/llplugin")
if(0)
copy_files("${LIBS_DEBUG_DIR}" "${plugins_debug_files}" "../test_apps/llplugintest/Debug")
endif(0)
# Release & ReleaseDebInfo config runtime files required for the plugin test mule (Qt image format plugins)
set(plugin_image_release_files
qgif4.dll
qico4.dll
qjpeg4.dll
qmng4.dll
qsvg4.dll
qtiff4.dll
)
copy_files("${LIBS_RELEASE_DIR}/imageformats" "${plugin_image_release_files}" "Release/llplugin/imageformats")
copy_files("${LIBS_RELEASE_DIR}/imageformats" "${plugin_image_release_files}" "RelWithDebInfo/llplugin/imageformats")
if(0)
copy_files("${LIBS_RELEASE_DIR}/imageformats" "${plugin_image_release_files}" "../test_apps/llplugintest/imageformats/Release")
copy_files("${LIBS_RELEASE_DIR}/imageformats" "${plugin_image_release_files}" "../test_apps/llplugintest/imageformats/RelWithDebInfo")
endif(0)
# Debug config runtime files required for the plugin test mule (Qt image format plugins)
set(plugin_image_debug_files
qgifd4.dll
qicod4.dll
qjpegd4.dll
qmngd4.dll
qsvgd4.dll
qtiffd4.dll
)
copy_files("${LIBS_DEBUG_DIR}/imageformats" "${plugin_image_debug_files}" "Debug/llplugin/imageformats")
if(0)
copy_files("${LIBS_DEBUG_DIR}/imageformats" "${plugin_image_debug_files}" "../test_apps/llplugintest/imageformats/Debug")
endif(0)
# Release & ReleaseDebInfo config runtime files required for the plugin test mule (Qt image format plugins)
set(plugin_codec_release_files
qcncodecs4.dll
qjpcodecs4.dll
qkrcodecs4.dll
qtwcodecs4.dll
)
copy_files("${LIBS_RELEASE_DIR}/codecs" "${plugin_codec_release_files}" "Release/llplugin/codecs")
copy_files("${LIBS_RELEASE_DIR}/codecs" "${plugin_codec_release_files}" "RelWithDebInfo/llplugin/codecs")
if(0)
copy_files("${LIBS_RELEASE_DIR}/codecs" "${plugin_codec_release_files}" "../test_apps/llplugintest/codecs/Release")
copy_files("${LIBS_RELEASE_DIR}/codecs" "${plugin_codec_release_files}" "../test_apps/llplugintest/codecs/RelWithDebInfo")
endif(0)
# Debug config runtime files required for the plugin test mule (Qt image format plugins)
set(plugin_codec_debug_files
qcncodecsd4.dll
qjpcodecsd4.dll
qkrcodecsd4.dll
qtwcodecsd4.dll
)
copy_files("${LIBS_DEBUG_DIR}/codecs" "${plugin_codec_debug_files}" "Debug/llplugin/codecs")
if(0)
copy_files("${LIBS_DEBUG_DIR}/codecs" "${plugin_codec_debug_files}" "../test_apps/llplugintest/codecs/Debug")
endif(0)

View File

@@ -10,9 +10,8 @@ elseif (LINUX)
use_prebuilt_binary(dbusglib)
set(DBUSGLIB_FOUND ON FORCE BOOL)
set(DBUSGLIB_INCLUDE_DIRS
${LIBS_PREBUILT_DIR}/include/dbus
${LIBS_PREBUILT_LEGACY_DIR}/include/dbus
)
${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/dbus
)
# We don't need to explicitly link against dbus-glib itself, because
# the viewer probes for the system's copy at runtime.
set(DBUSGLIB_LIBRARIES

View File

@@ -11,32 +11,25 @@ if (WINDOWS)
set (DIRECTX_ARCHITECTURE x86)
endif (WORD_SIZE EQUAL 32)
SET(program_files $ENV{ProgramW6432})
if(NOT program_files)
SET(program_files $ENV{ProgramFiles})
endif(NOT program_files)
SET(program_files_x86 "ProgramFiles(x86)")
SET(program_files_x86 $ENV{${program_files_x86}})
find_path(DIRECTX_ROOT_DIR Include/dxdiag.h
PATHS
"$ENV{DXSDK_DIR}"
"${program_files}/Microsoft DirectX SDK (June 2010)"
"${program_files_x86}/Microsoft DirectX SDK (June 2010)"
"${program_files}/Microsoft DirectX SDK (February 2010)"
"${program_files_x86}/Microsoft DirectX SDK (February 2010)"
"${program_files}/Microsoft DirectX SDK (March 2009)"
"${program_files_x86}/Microsoft DirectX SDK (March 2009)"
"${program_files}/Microsoft DirectX SDK (August 2008)"
"${program_files_x86}/Microsoft DirectX SDK (August 2008)"
"${program_files}/Microsoft DirectX SDK (June 2008)"
"${program_files_x86}/Microsoft DirectX SDK (June 2008)"
"${program_files}/Microsoft DirectX SDK (March 2008)"
"${program_files_x86}/Microsoft DirectX SDK (March 2008)"
"${program_files}/Microsoft DirectX SDK (November 2007)"
"${program_files_x86}/Microsoft DirectX SDK (November 2007)"
"${program_files}/Microsoft DirectX SDK (August 2007)"
"${program_files_x86}/Microsoft DirectX SDK (August 2007)"
"$ENV{ProgramFiles}/Microsoft DirectX SDK (June 2010)"
"$ENV{ProgramFiles(x86)}/Microsoft DirectX SDK (June 2010)"
"$ENV{ProgramFiles}/Microsoft DirectX SDK (February 2010)"
"$ENV{ProgramFiles(x86)}/Microsoft DirectX SDK (February 2010)"
"$ENV{ProgramFiles}/Microsoft DirectX SDK (March 2009)"
"$ENV{ProgramFiles(x86)}/Microsoft DirectX SDK (March 2009)"
"$ENV{ProgramFiles}/Microsoft DirectX SDK (August 2008)"
"$ENV{ProgramFiles(x86)}/Microsoft DirectX SDK (August 2008)"
"$ENV{ProgramFiles}/Microsoft DirectX SDK (June 2008)"
"$ENV{ProgramFiles(x86)}/Microsoft DirectX SDK (June 2008)"
"$ENV{ProgramFiles}/Microsoft DirectX SDK (March 2008)"
"$ENV{ProgramFiles(x86)}/Microsoft DirectX SDK (March 2008)"
"$ENV{ProgramFiles}/Microsoft DirectX SDK (November 2007)"
"$ENV{ProgramFiles(x86)}/Microsoft DirectX SDK (November 2007)"
"$ENV{ProgramFiles}/Microsoft DirectX SDK (August 2007)"
"$ENV{ProgramFiles(x86)}/Microsoft DirectX SDK (August 2007)"
)
if (DIRECTX_ROOT_DIR)
@@ -45,10 +38,10 @@ if (WINDOWS)
else (DIRECTX_ROOT_DIR)
find_path (WIN_KIT_ROOT_DIR Include/um/windows.h
PATHS
"${program_files}/Windows Kits/8.1"
"${program_files_x86}/Windows Kits/8.1"
"${program_files}/Windows Kits/8.0"
"${program_files_x86}/Windows Kits/8.0"
"$ENV{ProgramFiles}/Windows Kits/8.1"
"$ENV{ProgramFiles(x86)}/Windows Kits/8.1"
"$ENV{ProgramFiles}/Windows Kits/8.0"
"$ENV{ProgramFiles(x86)}/Windows Kits/8.0"
)
find_path (WIN_KIT_LIB_DIR dxguid.lib

View File

@@ -2,7 +2,7 @@
# The top-level CMakeLists.txt configures packages and tool locations.
set(packages "@PREBUILT_PACKAGES@")
set(python "@PYTHON_EXECUTABLE@")
set(install_dir "@CMAKE_BINARY_DIR@/packages")
set(install_dir "@CMAKE_SOURCE_DIR@/..")
set(scp "@SCP_EXECUTABLE@")
set(scripts_dir "@SCRIPTS_DIR@")
set(sentinel_dir "@CMAKE_BINARY_DIR@/prepare")
@@ -20,7 +20,7 @@ foreach(package ${packages})
# This package is missing or out of date.
message(STATUS "Obtaining${proprietary_message} prebuilt '${package}'")
execute_process(
COMMAND ${python} install.py -p${prebuilt_type} --install-dir=${install_dir} --installed-manifest=${install_dir}/installed.xml ${scp_option} ${package}
COMMAND ${python} install.py -p${prebuilt_type} --install-dir=${install_dir} ${scp_option} ${package}
WORKING_DIRECTORY ${scripts_dir}
RESULT_VARIABLE result
)

View File

@@ -8,10 +8,7 @@ if (STANDALONE)
elseif (LINUX)
use_prebuilt_binary(elfio)
set(ELFIO_LIBRARIES ELFIO)
set(ELFIO_INCLUDE_DIR
${LIBS_PREBUILT_DIR}/include
${LIBS_PREBUILT_LEGACY_DIR}/include
)
set(ELFIO_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include)
set(ELFIO_FOUND "YES")
endif (STANDALONE)

View File

@@ -9,16 +9,9 @@ if (STANDALONE)
else (STANDALONE)
use_prebuilt_binary(expat)
if (WINDOWS)
if (MSVC12)
set(EXPAT_LIBRARIES expat)
else (MSVC12)
set(EXPAT_LIBRARIES libexpatMT)
endif (MSVC12)
set(EXPAT_LIBRARIES libexpatMT)
else (WINDOWS)
set(EXPAT_LIBRARIES expat)
endif (WINDOWS)
set(EXPAT_INCLUDE_DIRS
${LIBS_PREBUILT_DIR}/include
${LIBS_PREBUILT_LEGACY_DIR}/include
)
set(EXPAT_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include)
endif (STANDALONE)

52
indra/cmake/FMOD.cmake Normal file
View File

@@ -0,0 +1,52 @@
# -*- cmake -*-
include(Linking)
if(INSTALL_PROPRIETARY)
include(Prebuilt)
use_prebuilt_binary(fmod)
endif(INSTALL_PROPRIETARY)
find_library(FMOD_LIBRARY
NAMES fmod fmodvc fmod-3.75
PATHS
optimized ${ARCH_PREBUILT_DIRS_RELEASE}
debug ${ARCH_PREBUILT_DIRS_DEBUG}
)
if (NOT FMOD_LIBRARY)
set(FMOD_SDK_DIR CACHE PATH "Path to the FMOD SDK.")
if (FMOD_SDK_DIR)
find_library(FMOD_LIBRARY
NAMES fmodvc fmod-3.75 fmod
PATHS
${FMOD_SDK_DIR}/api/lib
${FMOD_SDK_DIR}/api
${FMOD_SDK_DIR}/lib
${FMOD_SDK_DIR}
)
endif (FMOD_SDK_DIR)
endif (NOT FMOD_LIBRARY)
find_path(FMOD_INCLUDE_DIR fmod.h
${LIBS_PREBUILT_DIR}/include
${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include
${FMOD_SDK_DIR}/api/inc
${FMOD_SDK_DIR}/inc
${FMOD_SDK_DIR}
)
if (FMOD_LIBRARY AND FMOD_INCLUDE_DIR)
set(FMOD ON CACHE BOOL "Use closed source FMOD sound library.")
else (FMOD_LIBRARY AND FMOD_INCLUDE_DIR)
set(FMOD_LIBRARY "")
set(FMOD_INCLUDE_DIR "")
if (FMOD)
message(STATUS "No support for FMOD audio (need to set FMOD_SDK_DIR?)")
endif (FMOD)
set(FMOD OFF CACHE BOOL "Use closed source FMOD sound library.")
endif (FMOD_LIBRARY AND FMOD_INCLUDE_DIR)
if (FMOD)
message(STATUS "Building with FMOD audio support")
endif (FMOD)

View File

@@ -2,115 +2,81 @@
include(Linking)
if (FMODEX AND FMODSTUDIO)
message( FATAL_ERROR "You can not enable two FMOD variants at the same time." )
endif (FMODEX AND FMODSTUDIO)
if (NOT FMODEX_LIBRARY)
set(FMODEX_SDK_DIR CACHE PATH "Path to the FMOD Ex SDK.")
if (FMODEX_SDK_DIR)
if(WORD_SIZE EQUAL 32)
find_library(FMODEX_LIBRARY
fmodex_vc fmodexL_vc fmodex fmodexL
PATHS
"${FMODEX_SDK_DIR}/api/lib"
"${FMODEX_SDK_DIR}/api"
"${FMODEX_SDK_DIR}/lib"
"${FMODEX_SDK_DIR}"
)
elseif(WORD_SIZE EQUAL 64)
find_library(FMODEX_LIBRARY
fmodex64_vc fmodexL64_vc fmodex64 fmodexL64
PATHS
"${FMODEX_SDK_DIR}/api/lib"
"${FMODEX_SDK_DIR}/api"
"${FMODEX_SDK_DIR}/lib"
"${FMODEX_SDK_DIR}"
)
endif(WORD_SIZE EQUAL 32)
endif(FMODEX_SDK_DIR)
if(WINDOWS AND NOT FMODEX_SDK_DIR)
GET_FILENAME_COMPONENT(FMODEX_PROG_DIR [HKEY_CURRENT_USER\\Software\\FMOD\ Programmers\ API\ Windows] ABSOLUTE CACHE)
if(WORD_SIZE EQUAL 32)
find_library(FMODEX_LIBRARY
fmodex_vc fmodexL_vc
PATHS
"${FMODEX_PROG_DIR}/api/lib"
"${FMODEX_PROG_DIR}/api"
"${FMODEX_PROG_DIR}"
)
else(WORD_SIZE EQUAL 32)
find_library(FMODEX_LIBRARY
fmodex64_vc fmodexL64_vc
PATHS
"${FMODEX_PROG_DIR}/api/lib"
"${FMODEX_PROG_DIR}/api"
"${FMODEX_PROG_DIR}"
)
endif(WORD_SIZE EQUAL 32)
if(FMODEX_LIBRARY)
message(STATUS "Found fmodex in ${FMODEX_PROG_DIR}")
set(FMODEX_SDK_DIR "${FMODEX_PROG_DIR}")
set(FMODEX_SDK_DIR "${FMODEX_PROG_DIR}" CACHE PATH "Path to the FMOD Ex SDK." FORCE)
endif(FMODEX_LIBRARY)
endif(WINDOWS AND NOT FMODEX_SDK_DIR)
endif (NOT FMODEX_LIBRARY)
unset(FMOD_LIBRARY_RELEASE CACHE)
unset(FMOD_LIBRARY_DEBUG CACHE)
unset(FMOD_INCLUDE_DIR CACHE)
find_path(FMODEX_INCLUDE_DIR fmod.hpp
"${LIBS_PREBUILT_DIR}/include/fmodex"
"${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/fmodex"
"${FMODEX_SDK_DIR}/api/inc"
"${FMODEX_SDK_DIR}/inc"
"${FMODEX_SDK_DIR}"
)
set(FMOD_EXTERNAL_LIB OFF)
if(DARWIN)
set(FMODEX_ORIG_LIBRARY "${FMODEX_LIBRARY}")
set(FMODEX_LIBRARY "${CMAKE_CURRENT_BINARY_DIR}/libfmodex.dylib")
endif(DARWIN)
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)
if (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR)
set(FMODEX ON CACHE BOOL "Use closed source FMOD Ex sound library.")
else (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR)
set(FMODEX_LIBRARY "")
set(FMODEX_INCLUDE_DIR "")
if (FMODEX)
message(STATUS "No support for FMOD Ex audio (need to set FMODEX_SDK_DIR?)")
endif (FMODEX)
set(FMODEX OFF CACHE BOOL "Use closed source FMOD Ex sound library.")
set(FMODEX OFF)
endif (FMOD_LIBRARY_RELEASE AND FMOD_INCLUDE_DIR)
endif (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR)
if (FMOD)
if (FMODEX)
message(STATUS "Building with FMOD Ex audio support")
set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_FMODEX")
endif (FMOD)
endif (FMODEX)

View File

@@ -1,112 +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 FMODSTUDIO_SDK_DIR AND WINDOWS)
#GET_FILENAME_COMPONENT(REG_DIR [HKEY_CURRENT_USER\\Software\\FMOD\ Studio\ API\ Windows] ABSOLUTE)
#set(FMODSTUDIO_SDK_DIR ${REG_DIR} CACHE PATH "Path to the FMOD Studio SDK." FORCE)
endif (NOT FMODSTUDIO_SDK_DIR AND WINDOWS)
if(NOT FMODSTUDIO_SDK_DIR AND STANDALONE)
message(FATAL_ERROR "FMODSTUDIO_SDK_DIR not set!")
endif(NOT FMODSTUDIO_SDK_DIR AND STANDALONE)
endif(STANDALONE OR WINDOWS)
if(FMODSTUDIO_SDK_DIR)
if(LINUX AND WORD_SIZE EQUAL 32)
set(fmod_lib_paths "${FMODSTUDIO_SDK_DIR}/api/lowlevel/lib/x86" )
elseif(LINUX)
set(fmod_lib_paths "${FMODSTUDIO_SDK_DIR}/api/lowlevel/lib/x86_64")
else(LINUX AND WORD_SIZE EQUAL 32)
set(fmod_lib_paths "${FMODSTUDIO_SDK_DIR}/api/lowlevel/lib")
endif(LINUX AND WORD_SIZE EQUAL 32)
set(fmod_inc_paths "${FMODSTUDIO_SDK_DIR}/api/lowlevel/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 AND WINDOWS)
find_library(FMOD_LIBRARY_RELEASE fmod64 PATHS ${fmod_lib_paths} NO_DEFAULT_PATH)
find_library(FMOD_LIBRARY_DEBUG fmodL64 PATHS ${fmod_lib_paths} NO_DEFAULT_PATH)
else(WORD_SIZE EQUAL 64 AND WINDOWS)#Check if CMAKE_FIND_LIBRARY_PREFIXES is set to 'lib' for darwin.
find_library(FMOD_LIBRARY_RELEASE fmod PATHS ${fmod_lib_paths} NO_DEFAULT_PATH)
find_library(FMOD_LIBRARY_DEBUG fmodL PATHS ${fmod_lib_paths} NO_DEFAULT_PATH)
endif(WORD_SIZE EQUAL 64 AND WINDOWS)
if(WINDOWS)
set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES_OLD})
string(REPLACE ".dll" "_vc.lib" FMOD_LINK_LIBRARY_RELEASE ${FMOD_LIBRARY_RELEASE})
string(REPLACE ".dll" "_vc.lib" FMOD_LINK_LIBRARY_DEBUG ${FMOD_LIBRARY_DEBUG})
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 FMODSTUDIO_SDK_DIR path not found '{$FMODSTUDIO_SDK_DIR}'")
else(STANDALONE)
message(STATUS "Provided FMODSTUDIO_SDK_DIR path not found '${FMODSTUDIO_SDK_DIR}'. Falling back to prebuilts")
endif(STANDALONE)
else(NOT FMOD_LIBRARY_RELEASE OR NOT FMOD_INCLUDE_DIR)
message(STATUS "Using system-provided FMOD Studio Libraries")
set(FMOD_EXTERNAL_LIB ON)
endif(NOT FMOD_LIBRARY_RELEASE OR NOT FMOD_INCLUDE_DIR)
endif (FMODSTUDIO_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/fmod64${lib_suffix})
set(FMOD_LIBRARY_DEBUG ${LIBS_PREBUILT_DIR}/lib/debug/fmodL64${lib_suffix})
else(WORD_SIZE EQUAL 64)
set(FMOD_LIBRARY_RELEASE ${LIBS_PREBUILT_DIR}/lib/release/fmod${lib_suffix})
set(FMOD_LIBRARY_DEBUG ${LIBS_PREBUILT_DIR}/lib/debug/fmodL${lib_suffix})
endif(WORD_SIZE EQUAL 64)
else(WINDOWS)
set(FMOD_LIBRARY_RELEASE ${LIBS_PREBUILT_DIR}/lib/release/libfmod${lib_suffix})
set(FMOD_LIBRARY_DEBUG ${LIBS_PREBUILT_DIR}/lib/debug/libfmodL${lib_suffix})
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(fmodstudio)
set(FMOD_INCLUDE_DIR
${LIBS_PREBUILT_DIR}/include/fmodstudio)
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 Studio audio (need to set FMODSTUDIO_SDK_DIR?)")
set(FMOD OFF)
set(FMODSTUDIO OFF)
endif (FMOD_LIBRARY_RELEASE AND FMOD_INCLUDE_DIR)
if (FMOD)
message(STATUS "Building with FMOD Studio audio support")
set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_FMODSTUDIO")
endif (FMOD)

View File

@@ -7,17 +7,12 @@ if (STANDALONE)
pkg_check_modules(FREETYPE REQUIRED freetype2)
else (STANDALONE)
use_prebuilt_binary(freetype)
if(MSVC12)
if (LINUX)
set(FREETYPE_INCLUDE_DIRS
${LIBS_PREBUILT_DIR}/include/freetype2
${LIBS_PREBUILT_LEGACY_DIR}/include/freetype2
)
else(MSVC12)
set(FREETYPE_INCLUDE_DIRS
${LIBS_PREBUILT_DIR}/include
${LIBS_PREBUILT_LEGACY_DIR}/include
)
endif (MSVC12)
${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include)
else (LINUX)
set(FREETYPE_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include)
endif (LINUX)
set(FREETYPE_LIBRARIES freetype)
endif (STANDALONE)

View File

@@ -8,9 +8,6 @@ if (STANDALONE)
include(FindGLOD)
else (STANDALONE)
use_prebuilt_binary(GLOD)
set(GLOD_INCLUDE_DIRS
${LIBS_PREBUILT_DIR}/include
${LIBS_PREBUILT_LEGACY_DIR}/include
)
set(GLOD_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include)
set(GLOD_LIBRARIES glod)
endif (STANDALONE)

View File

@@ -16,13 +16,10 @@ else (STANDALONE)
set(GSTREAMER010_FOUND ON FORCE BOOL)
set(GSTREAMER010_PLUGINS_BASE_FOUND ON FORCE BOOL)
set(GSTREAMER010_INCLUDE_DIRS
${LIBS_PREBUILT_DIR}/include/gstreamer-0.10
${LIBS_PREBUILT_DIR}/includeg/lib-2.0
${LIBS_PREBUILT_DIR}/include/libxml2
${LIBS_PREBUILT_LEGACY_DIR}/include/gstreamer-0.10
${LIBS_PREBUILT_LEGACY_DIR}/include/glib-2.0
${LIBS_PREBUILT_LEGACY_DIR}/include/libxml2
)
${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/gstreamer-0.10
${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/glib-2.0
${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/libxml2
)
endif (STANDALONE)

View File

@@ -17,10 +17,5 @@ else (STANDALONE)
endif (WINDOWS)
# yes, this does look dumb, no, it's not incorrect
# I think it's incorrect: the second one should go --Aleric
set(BREAKPAD_INCLUDE_DIRECTORIES
${LIBS_PREBUILT_DIR}/include/google_breakpad
${LIBS_PREBUILT_LEGACY_DIR}/include/google_breakpad
${LIBS_PREBUILT_DIR}/include/google_breakpad/google_breakpad
${LIBS_PREBUILT_LEGACY_DIR}/include/google_breakpad/google_breakpad
)
set(BREAKPAD_INCLUDE_DIRECTORIES "${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/google_breakpad" "${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/google_breakpad/google_breakpad")
endif (STANDALONE)

View File

@@ -25,9 +25,7 @@ else (STANDALONE)
set(TCMALLOC_LIBRARIES tcmalloc_minimal)
endif()
set(GOOGLE_PERFTOOLS_INCLUDE_DIR
${LIBS_PREBUILT_DIR}/include
${LIBS_PREBUILT_LEGACY_DIR}/include
)
${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include)
endif (LINUX)
endif (STANDALONE)

View File

@@ -6,10 +6,7 @@ if (STANDALONE)
else (STANDALONE)
use_prebuilt_binary(hunspell)
set(HUNSPELL_INCLUDE_DIR
${LIBS_PREBUILT_DIR}/include/hunspell
${LIBS_PREBUILT_LEGACY_DIR}/include/hunspell
)
set(HUNSPELL_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/hunspell)
if (LINUX OR DARWIN)
set(HUNSPELL_LIBRARY hunspell-1.3)

View File

@@ -13,14 +13,11 @@ else (STANDALONE)
set(JPEG_LIBRARIES jpeg)
elseif (DARWIN)
set(JPEG_LIBRARIES
debug libjpeg.a
optimized libjpeg.a
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libjpeg.a
debug ${ARCH_PREBUILT_DIRS_DEBUG}/libjpeg.a
)
elseif (WINDOWS)
set(JPEG_LIBRARIES jpeglib)
endif (LINUX)
set(JPEG_INCLUDE_DIRS
${LIBS_PREBUILT_DIR}/include
${LIBS_PREBUILT_LEGACY_DIR}/include
)
set(JPEG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include)
endif (STANDALONE)

View File

@@ -10,22 +10,13 @@ if (STANDALONE)
else (STANDALONE)
use_prebuilt_binary(jsoncpp)
if (WINDOWS)
if(MSVC12)
set(JSONCPP_LIBRARIES
debug json_vc${MSVC_SUFFIX}debug_libmt.lib
optimized json_vc${MSVC_SUFFIX}_libmt)
else(MSVC12)
set(JSONCPP_LIBRARIES
debug json_vc${MSVC_SUFFIX}d
optimized json_vc${MSVC_SUFFIX})
endif(MSVC12)
set(JSONCPP_LIBRARIES
debug json_vc${MSVC_SUFFIX}d
optimized json_vc${MSVC_SUFFIX})
elseif (DARWIN)
set(JSONCPP_LIBRARIES json_linux-gcc-4.0.1_libmt)
elseif (LINUX)
set(JSONCPP_LIBRARIES jsoncpp)
endif (WINDOWS)
set(JSONCPP_INCLUDE_DIR
${LIBS_PREBUILT_DIR}/include/jsoncpp
${LIBS_PREBUILT_LEGACY_DIR}/include/jsoncpp
)
set(JSONCPP_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/jsoncpp)
endif (STANDALONE)

View File

@@ -87,7 +87,7 @@ MACRO(ADD_BUILD_TEST_INTERNAL name parent libraries source_files)
${libraries}
)
SET(TEST_EXE $<TARGET_FILE:${name}_test>)
GET_TARGET_PROPERTY(TEST_EXE ${name}_test LOCATION)
SET(TEST_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${name}_test_ok.txt)
IF ("${wrapper}" STREQUAL "")

View File

@@ -1,13 +1,17 @@
# ll_deploy_sharedlibs_command
# target_exe: the cmake target of the executable for which the shared libs will be deployed.
macro(ll_deploy_sharedlibs_command target_exe)
SET(OUTPUT_PATH $<TARGET_FILE:${target_exe}>)
get_target_property(TARGET_LOCATION ${target_exe} LOCATION)
get_filename_component(OUTPUT_PATH ${TARGET_LOCATION} PATH)
if(DARWIN)
SET_TEST_PATH(SEARCH_DIRS)
get_target_property(IS_BUNDLE ${target_exe} MACOSX_BUNDLE)
if(IS_BUNDLE)
# If its a bundle the exe is not in the target location, this should find it.
get_filename_component(TARGET_FILE ${TARGET_LOCATION} NAME)
set(OUTPUT_PATH ${TARGET_LOCATION}.app/Contents/MacOS)
set(TARGET_LOCATION ${OUTPUT_PATH}/${TARGET_FILE})
set(OUTPUT_PATH ${OUTPUT_PATH}/../Resources)
endif(IS_BUNDLE)
elseif(WINDOWS)
@@ -22,7 +26,7 @@ macro(ll_deploy_sharedlibs_command target_exe)
TARGET ${target_exe} POST_BUILD
COMMAND ${CMAKE_COMMAND}
ARGS
"-DBIN_NAME=\"$<TARGET_FILE:${target_exe}>\""
"-DBIN_NAME=\"${TARGET_LOCATION}\""
"-DSEARCH_DIRS=\"${SEARCH_DIRS}\""
"-DDST_PATH=\"${OUTPUT_PATH}\""
"-P"
@@ -38,8 +42,7 @@ macro(ll_stage_sharedlib DSO_TARGET)
# Also this directory is shared with RunBuildTest.cmake, y'know, for the tests.
set_target_properties(${DSO_TARGET} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${SHARED_LIB_STAGING_DIR})
if(NOT WINDOWS)
SET(DSO_PATH $<TARGET_FILE:${DSO_TARGET}>)
get_target_property(DSO_PATH ${DSO_TARGET} LOCATION)
get_filename_component(DSO_FILE ${DSO_PATH} NAME)
if(DARWIN)
set(SHARED_LIB_STAGING_DIR_CONFIG ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/Resources)

View File

@@ -17,10 +17,7 @@ else (STANDALONE)
use_prebuilt_binary(mesa)
use_prebuilt_binary(SDL)
set (SDL_FOUND TRUE)
set (SDL_INCLUDE_DIR
${LIBS_PREBUILT_DIR}/include
${LIBS_PREBUILT_LEGACY_DIR}/include
)
set (SDL_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR})
if(WORD_SIZE EQUAL 64)
set (SDL_LIBRARY SDL)
else(WORD_SIZE EQUAL 64)

View File

@@ -5,35 +5,26 @@ set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES")
include(Variables)
if (NOT STANDALONE)
if(CMAKE_BUILD_TYPE)
string(TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_LOWER)
endif(CMAKE_BUILD_TYPE)
set(ARCH_PREBUILT_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/lib)
set(ARCH_PREBUILT_DIRS_RELEASE ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/lib/release)
set(ARCH_PREBUILT_DIRS_DEBUG ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/lib/debug)
if(WINDOWS OR ${CMAKE_GENERATOR} MATCHES "Xcode")
# the cmake xcode and VS generators implicitly append ${CMAKE_CFG_INTDIR} to the library paths for us
# fortunately both windows and darwin are case insensitive filesystems so this works.
set(ARCH_PREBUILT_LINK_DIRS
${LIBS_PREBUILT_DIR}/lib
${LIBS_PREBUILT_LEGACY_DIR}/lib
)
set(ARCH_PREBUILT_LINK_DIRS "${ARCH_PREBUILT_DIRS}")
else(WINDOWS OR ${CMAKE_GENERATOR} MATCHES "Xcode")
# else block is for linux and any other makefile based generators
set(ARCH_PREBUILT_LINK_DIRS
${LIBS_PREBUILT_DIR}/lib/${CMAKE_BUILD_TYPE_LOWER}
${LIBS_PREBUILT_LEGACY_DIR}/lib/${CMAKE_BUILD_TYPE_LOWER}
)
string(TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_LOWER)
set(ARCH_PREBUILT_LINK_DIRS ${ARCH_PREBUILT_DIRS}/${CMAKE_BUILD_TYPE_LOWER})
endif(WINDOWS OR ${CMAKE_GENERATOR} MATCHES "Xcode")
if (NOT "${CMAKE_BUILD_TYPE_LOWER}" STREQUAL "release")
if (NOT "${CMAKE_BUILD_TYPE}" STREQUAL "Release")
# When we're building something other than Release, append the
# packages/lib/release directory to deal with autobuild packages that don't
# provide (e.g.) lib/debug libraries.
list(APPEND ARCH_PREBUILT_LINK_DIRS
${LIBS_PREBUILT_DIR}/lib/release
${LIBS_PREBUILT_LEGACY_DIR}/lib/release
)
endif (NOT "${CMAKE_BUILD_TYPE_LOWER}" STREQUAL "release")
list(APPEND ARCH_PREBUILT_LINK_DIRS ${ARCH_PREBUILT_DIRS_RELEASE})
endif (NOT "${CMAKE_BUILD_TYPE}" STREQUAL "Release")
endif (NOT STANDALONE)
link_directories(${ARCH_PREBUILT_LINK_DIRS})
@@ -46,7 +37,7 @@ else (LINUX)
set(PTHREAD_LIBRARY "")
endif (LINUX)
if (WINDOWS)
if (WINDOWS)
set(WINDOWS_LIBRARIES
advapi32
shell32

View File

@@ -15,10 +15,7 @@ else (STANDALONE)
set(NDOF_LIBRARY ndofdev)
endif (WINDOWS)
set(NDOF_INCLUDE_DIR
${LIBS_PREBUILT_DIR}/include/ndofdev
${LIBS_PREBUILT_LEGACY_DIR}/include/ndofdev
)
set(NDOF_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/ndofdev)
set(NDOF_FOUND 1)
endif (STANDALONE)

View File

@@ -2,7 +2,6 @@
include(Linking)
include(Prebuilt)
if(NOT FMOD)
if (LINUX)
set(OPENAL ON CACHE BOOL "Enable OpenAL")
else (LINUX)
@@ -22,14 +21,9 @@ if (OPENAL)
openal
alut
)
set(OPENAL_INCLUDE_DIRS
${LIBS_PREBUILT_DIR}/include
${LIBS_PREBUILT_LEGACY_DIR}/include
)
set(OPENAL_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include)
endif (OPENAL)
if (OPENAL)
message(STATUS "Building with OpenAL audio support")
set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_OPENAL")
endif (OPENAL)
endif(NOT FMOD)

View File

@@ -3,8 +3,5 @@ include(Prebuilt)
if (NOT (STANDALONE OR DARWIN))
use_prebuilt_binary(glext)
set(GLEXT_INCLUDE_DIR
${LIBS_PREBUILT_DIR}/include
${LIBS_PREBUILT_LEGACY_DIR}/include
)
set(GLEXT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include)
endif (NOT (STANDALONE OR DARWIN))

View File

@@ -13,14 +13,9 @@ else (STANDALONE OR USE_SYSTEM_OPENSSL)
else (WINDOWS)
set(OPENSSL_LIBRARIES ssl)
endif (WINDOWS)
set(OPENSSL_INCLUDE_DIRS
${LIBS_PREBUILT_DIR}/include
${LIBS_PREBUILT_LEGACY_DIR}/include
)
set(OPENSSL_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include)
endif (STANDALONE OR USE_SYSTEM_OPENSSL)
if (LINUX)
set(CRYPTO_LIBRARIES crypto dl)
elseif (DARWIN)
if (LINUX OR DARWIN)
set(CRYPTO_LIBRARIES crypto)
endif (LINUX)
endif (LINUX OR DARWIN)

View File

@@ -9,42 +9,11 @@ if (STANDALONE)
else (STANDALONE)
use_prebuilt_binary(libpng)
if (WINDOWS)
if(MSVC12)
set(PNG_LIBRARIES libpng16)
else(MSVC12)
set(PNG_LIBRARIES libpng15)
endif(MSVC12)
set(PNG_LIBRARIES libpng15)
elseif(DARWIN)
set(PNG_LIBRARIES png15)
else(LINUX)
if (CMAKE_SIZEOF_VOID_P EQUAL 4) # Singu TODO: update png
set(PNG_LIBRARIES png15)
else ()
#
# When we have updated static libraries in competition with older
# shared libraries and we want the former to win, we need to do some
# extra work. The *_PRELOAD_ARCHIVES settings are invoked early
# and will pull in the entire archive to the binary giving it
# priority in symbol resolution. Beware of cmake moving the
# achive load itself to another place on the link command line. If
# that happens, you can try something like -Wl,-lpng16 here to hide
# the archive. Also be aware that the linker will not tolerate a
# second whole-archive load of the archive. See viewer's
# CMakeLists.txt for more information.
#
set(PNG_PRELOAD_ARCHIVES -Wl,--whole-archive png16 -Wl,--no-whole-archive)
set(PNG_LIBRARIES png16)
endif ()
set(PNG_LIBRARIES png15)
endif()
if (WINDOWS)
set(PNG_INCLUDE_DIRS
${LIBS_PREBUILT_DIR}/include/${PNG_LIBRARIES}
${LIBS_PREBUILT_LEGACY_DIR}/include/${PNG_LIBRARIES}
)
else (WINDOWS)
set(PNG_INCLUDE_DIRS
${LIBS_PREBUILT_DIR}/include/lib${PNG_LIBRARIES}
${LIBS_PREBUILT_LEGACY_DIR}/include/lib${PNG_LIBRARIES}
)
endif (WINDOWS)
set(PNG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/)
endif (STANDALONE)

View File

@@ -13,9 +13,8 @@ if (PULSEAUDIO)
use_prebuilt_binary(pulseaudio)
set(PULSEAUDIO_FOUND ON FORCE BOOL)
set(PULSEAUDIO_INCLUDE_DIRS
${LIBS_PREBUILT_DIR}/include
${LIBS_PREBUILT_LEGACY_DIR}/include
)
${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include
)
# We don't need to explicitly link against pulseaudio itself, because
# the viewer probes for the system's copy at runtime.
set(PULSEAUDIO_LIBRARIES

View File

@@ -9,29 +9,18 @@ if (DARWIN)
include(CMakeFindFrameworks)
find_library(QUICKTIME_LIBRARY QuickTime)
elseif (WINDOWS AND WORD_SIZE EQUAL 32)
SET(program_files "ProgramFiles(x86)")
SET(program_files $ENV{${program_files}})
if(NOT program_files)
SET(program_files $ENV{ProgramW6432})
endif(NOT program_files)
if(NOT program_files)
SET(program_files $ENV{ProgramFiles})
endif(NOT program_files)
set(QUICKTIME_SDK_DIR "${program_files}/QuickTime SDK"
set(QUICKTIME_SDK_DIR "$ENV{PROGRAMFILES}/QuickTime SDK"
CACHE PATH "Location of the QuickTime SDK.")
find_library(DEBUG_QUICKTIME_LIBRARY qtmlclient
PATHS
${LIBS_PREBUILT_DIR}/lib/debug
${LIBS_PREBUILT_LEGACY_DIR}/lib/debug
${ARCH_PREBUILT_DIRS_DEBUG}
"${QUICKTIME_SDK_DIR}\\libraries"
)
find_library(RELEASE_QUICKTIME_LIBRARY qtmlclient
PATHS
${LIBS_PREBUILT_DIR}/lib/release
${LIBS_PREBUILT_LEGACY_DIR}/lib/release
${ARCH_PREBUILT_DIRS_RELEASE}
"${QUICKTIME_SDK_DIR}\\libraries"
)
@@ -44,8 +33,7 @@ elseif (WINDOWS AND WORD_SIZE EQUAL 32)
endif (DEBUG_QUICKTIME_LIBRARY AND RELEASE_QUICKTIME_LIBRARY)
include_directories(
${LIBS_PREBUILT_DIR}/include/quicktime
${LIBS_PREBUILT_LEGACY_DIR}/include/quicktime
${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/quicktime
"${QUICKTIME_SDK_DIR}\\CIncludes"
)
endif (DARWIN)

View File

@@ -55,18 +55,12 @@ else (STANDALONE)
endif (LINUX)
include_directories (
${LIBS_PREBUILT_DIR}/packages/include
${LIBS_PREBUILT_DIR}/packages/include/cairo
${LIBS_PREBUILT_DIR}/packages/include/pixman-1
${LIBS_PREBUILT_LEGACY_DIR}/include
${LIBS_PREBUILT_LEGACY_DIR}/include/cairo
${LIBS_PREBUILT_LEGACY_DIR}/include/pixman-1
${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include
${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/cairo
${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/pixman-1
)
foreach(include ${${LL_ARCH}_INCLUDES})
include_directories(
${LIBS_PREBUILT_DIR}/include/${include}
${LIBS_PREBUILT_LEGACY_DIR}/include/${include}
)
include_directories(${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/${include})
endforeach(include)
endif (STANDALONE)

View File

@@ -11,6 +11,6 @@ if (INSTALL)
set(APP_BIN_DIR bin)
endif(NOT APP_BIN_DIR)
if(NOT APP_SHARE_DIR)
set(APP_SHARE_DIR share/secondlife-${${ROOT_PROJECT_NAME}_VERSION})
set(APP_SHARE_DIR share/secondlife-${viewer_VERSION})
endif(NOT APP_SHARE_DIR)
endif (INSTALL)

View File

@@ -32,6 +32,9 @@ set(DISABLE_TCMALLOC OFF CACHE BOOL "Disable linkage of TCMalloc. (64bit builds
set(LL_TESTS OFF CACHE BOOL "Build and run unit and integration tests (disable for build timing runs to reduce variation)")
set(DISABLE_FATAL_WARNINGS TRUE CACHE BOOL "Set this to FALSE to enable fatal warnings.")
set(LIBS_PREBUILT_DIR ${CMAKE_SOURCE_DIR}/../libraries CACHE PATH
"Location of prebuilt libraries.")
if (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
set(WINDOWS ON BOOL FORCE)
if (WORD_SIZE EQUAL 32)
@@ -151,12 +154,6 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(LL_ARCH_DIR universal-darwin)
endif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set(LIBS_PREBUILT_DIR ${CMAKE_BINARY_DIR}/packages CACHE PATH
"Location of prebuilt libraries.")
set(LIBS_PREBUILT_LEGACY_DIR ${CMAKE_BINARY_DIR}/packages/libraries/${LL_ARCH_DIR} CACHE PATH
"Legacy location of prebuilt libraries.")
if (WINDOWS AND WORD_SIZE EQUAL 32)
set(PREBUILT_TYPE windows)
elseif (WINDOWS AND WORD_SIZE EQUAL 64)

View File

@@ -32,8 +32,8 @@ if (WINDOWS)
)
elseif (DARWIN)
set(WEBKIT_PLUGIN_LIBRARIES
debug libllqtwebkit.dylib
optimized libllqtwebkit.dylib
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libllqtwebkit.dylib
debug ${ARCH_PREBUILT_DIRS_DEBUG}/libllqtwebkit.dylib
)
elseif (LINUX)
if (STANDALONE)
@@ -50,6 +50,7 @@ elseif (LINUX)
ssl
# qgif
# qjpeg
jscore
jpeg
fontconfig
X11
@@ -57,8 +58,5 @@ elseif (LINUX)
Xext
GL
)
if (CMAKE_SIZEOF_VOID_P EQUAL 4) # Singu TODO: update webkit
set(WEBKIT_PLUGIN_LIBRARIES ${WEBKIT_PLUGIN_LIBRARIES} jscore)
endif (CMAKE_SIZEOF_VOID_P EQUAL 4)
endif (STANDALONE)
endif (WINDOWS)

View File

@@ -9,8 +9,5 @@ if (STANDALONE)
else (STANDALONE)
use_prebuilt_binary(xmlrpc-epi)
set(XMLRPCEPI_LIBRARIES xmlrpc-epi)
set(XMLRPCEPI_INCLUDE_DIRS
${LIBS_PREBUILT_DIR}/include
${LIBS_PREBUILT_LEGACY_DIR}/include
)
set(XMLRPCEPI_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include)
endif (STANDALONE)

View File

@@ -17,9 +17,6 @@ else (STANDALONE)
set(ZLIB_LIBRARIES z)
endif (WINDOWS)
if (WINDOWS OR LINUX)
set(ZLIB_INCLUDE_DIRS
${LIBS_PREBUILT_DIR}/include/zlib
${LIBS_PREBUILT_LEGACY_DIR}/include/zlib
)
set(ZLIB_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/include/zlib)
endif (WINDOWS OR LINUX)
endif (STANDALONE)

View File

@@ -41,7 +41,6 @@ import shutil
import socket
import sys
import commands
import shlex
class CommandError(Exception):
pass
@@ -112,15 +111,11 @@ class PlatformSetup(object):
def build_dirs(self):
'''Return the top-level directories in which builds occur.
This can return more than one directory, e.g. if doing a
32-bit viewer and server build on Linux.'''
if(os.path.basename(os.path.normpath(os.getcwd())) == 'indra'):
prefix = '../'
else:
prefix = ''
return [prefix+'build-' + self.platform()]
return ['build-' + self.platform()]
def cmake_commandline(self, src_dir, build_dir, opts, simple):
'''Return the command line to run cmake with.'''
@@ -280,7 +275,9 @@ class LinuxSetup(UnixSetup):
return 'linux'
def build_dirs(self):
return [PlatformSetup.build_dirs(self)[0]+'-'+self.build_type.lower()]
platform_build = '%s-%s' % (self.platform(), self.build_type.lower())
return ['viewer-' + platform_build]
def cmake_commandline(self, src_dir, build_dir, opts, simple):
args = dict(
@@ -402,12 +399,6 @@ class DarwinSetup(UnixSetup):
else:
return UnixSetup.arch(self)
def build_dirs(self):
if(self.generator == 'Xcode'):
return PlatformSetup.build_dirs(self)
else:
return [PlatformSetup.build_dirs(self)[0]+'-'+self.build_type.lower()]
def cmake_commandline(self, src_dir, build_dir, opts, simple):
args = dict(
dir=src_dir,
@@ -417,17 +408,15 @@ class DarwinSetup(UnixSetup):
word_size=self.word_size,
unattended=self.unattended,
project_name=self.project_name,
universal='',
type='',
universal=self.universal,
type=self.build_type.upper(),
)
if(self.generator != 'Xcode'):
args['type'] = '-DCMAKE_BUILD_TYPE=%s' % self.build_type.upper()
if self.universal == 'ON':
args['universal'] = '-DCMAKE_OSX_ARCHITECTURES:STRING=\'i386;ppc\''
#if simple:
# return 'cmake %(opts)s %(dir)r' % args
return ('cmake -G %(generator)r '
'%(type)s '
'-DCMAKE_BUILD_TYPE:STRING=%(type)s '
'-DSTANDALONE:BOOL=%(standalone)s '
'-DUNATTENDED:BOOL=%(unattended)s '
'-DWORD_SIZE:STRING=%(word_size)s '
@@ -436,18 +425,6 @@ class DarwinSetup(UnixSetup):
'%(opts)s %(dir)r' % args)
def run_build(self, opts, targets):
if(self.generator != 'Xcode'):
if targets:
targets = ' '.join(targets)
else:
targets = 'all'
for d in self.build_dirs():
cmd = 'make -C %r %s %s' % (d, ' '.join(opts), targets)
print 'Running %r' % cmd
self.run(cmd)
return
cwd = getcwd()
if targets:
targets = ' '.join(['-target ' + repr(t) for t in targets])
@@ -470,14 +447,14 @@ class WindowsSetup(PlatformSetup):
'gen' : r'Visual Studio 10',
'ver' : r'10.0'
},
'vc120' : {
'gen' : r'Visual Studio 12',
'ver' : r'12.0'
'vc110' : {
'gen' : r'Visual Studio 11',
'ver' : r'11.0'
}
}
gens['vs2010'] = gens['vc100']
gens['vs2013'] = gens['vc120']
gens['vs2012'] = gens['vc110']
search_path = r'C:\windows'
exe_suffixes = ('.exe', '.bat', '.com')
@@ -520,24 +497,14 @@ class WindowsSetup(PlatformSetup):
generator = property(_get_generator, _set_generator)
def get_gen_str(self, gen):
if gen is None:
gen = self._generator
return self.gens[gen.lower()]['ver']
def os(self):
return 'win32'
def build_dirs(self):
if(os.path.basename(os.path.normpath(os.getcwd())) == 'indra'):
prefix = '../'
else:
prefix = ''
if self.word_size == 64:
return [prefix+'build-' + self.generator + '-Win64']
return ['build-' + self.generator + '-Win64']
else:
return [prefix+'build-' + self.generator]
return ['build-' + self.generator]
def cmake_commandline(self, src_dir, build_dir, opts, simple):
args = dict(
@@ -558,7 +525,7 @@ class WindowsSetup(PlatformSetup):
'-DSTANDALONE:BOOL=%(standalone)s '
'-DUNATTENDED:BOOL=%(unattended)s '
'-DWORD_SIZE:STRING=%(word_size)s '
'-DROOT_PROJECT_NAME:STRING=\"%(project_name)s\" '
'-DROOT_PROJECT_NAME:STRING=%(project_name)s '
'%(opts)s "%(dir)s"' % args)
def get_HKLM_registry_value(self, key_str, value_str):
@@ -570,53 +537,34 @@ class WindowsSetup(PlatformSetup):
return value
def find_visual_studio(self, gen=None):
gen = self.get_gen_str(gen)
if gen is None:
gen = self._generator
gen = gen.lower()
value_str = (r'EnvironmentDirectory')
key_str = (r'SOFTWARE\Microsoft\VisualStudio\%s\Setup\VS' %
gen)
self.gens[gen]['ver'])
print ('Reading VS environment from HKEY_LOCAL_MACHINE\%s\%s' %
(key_str, value_str))
try:
return self.get_HKLM_registry_value(key_str, value_str)
except WindowsError, err:
key_str = (r'SOFTWARE\Wow6432Node\Microsoft\VisualStudio\%s\Setup\VS' %
gen)
self.gens[gen]['ver'])
try:
return self.get_HKLM_registry_value(key_str, value_str)
except:
print >> sys.stderr, "Didn't find ", self.gens[gen]['gen']
return ''
def find_msbuild(self, gen=None):
gen = self.get_gen_str(gen)
key_str = (r'SOFTWARE\Microsoft\MSBuild\ToolsVersions\12.0')
print ('Checking MSBuild support for vs ver = %s' % gen)
if not self.get_HKLM_registry_value(key_str+'\\'+gen, "VCTargetsPath"):
return (None, None)
print ('Reading MSBuild location from HKEY_LOCAL_MACHINE\%s\MSBuildToolsPath' %
key_str)
print key_str
try:
return (self.get_HKLM_registry_value(key_str, 'MSBuildToolsPath'), gen)
except WindowsError, err:
key_str = (r'SOFTWARE\Wow6432Node\Microsoft\MSBuild\ToolsVersions\%s' %
gen)
try:
return (self.get_HKLM_registry_value(key_str, 'MSBuildToolsPath'), gen)
except WindowsError, err:
print 'Didn\'t find msbuild'
return (None, None)
def find_visual_studio_express(self, gen=None):
gen = self.get_gen_str(gen)
if gen is None:
gen = self._generator
gen = gen.lower()
try:
import _winreg
key_str = (r'SOFTWARE\Microsoft\VCEXpress\%s\Setup\VC' %
gen)
self.gens[gen]['ver'])
value_str = (r'ProductDir')
print ('Reading VS environment from HKEY_LOCAL_MACHINE\%s\%s' %
(key_str, value_str))
@@ -628,15 +576,17 @@ class WindowsSetup(PlatformSetup):
print 'Found: %s' % value
return value
except WindowsError, err:
print >> sys.stderr, "Didn't find ", gen
print >> sys.stderr, "Didn't find ", self.gens[gen]['gen']
return ''
def find_visual_studio_express_single(self, gen=None):
gen = self.get_gen_str(gen)
if gen is None:
gen = self._generator
gen = gen.lower()
try:
import _winreg
key_str = (r'SOFTWARE\Microsoft\VCEXpress\%s_Config\Setup\VC' %
gen)
self.gens[gen]['ver'])
value_str = (r'ProductDir')
print ('Reading VS environment from HKEY_CURRENT_USER\%s\%s' %
(key_str, value_str))
@@ -648,7 +598,7 @@ class WindowsSetup(PlatformSetup):
print 'Found: %s' % value
return value
except WindowsError, err:
print >> sys.stderr, "Didn't find ", gen
print >> sys.stderr, "Didn't find ", self.gens[gen]['gen']
return ''
def get_build_cmd(self):
@@ -657,7 +607,7 @@ class WindowsSetup(PlatformSetup):
if self.gens[self.generator]['ver'] in [ r'8.0', r'9.0' ]:
config = '\"%s|Win32\"' % config
return "buildconsole \"%s.sln\" /build %s" % (self.project_name, config), None
return "buildconsole %s.sln /build %s" % (self.project_name, config)
environment = self.find_visual_studio()
if environment == '':
environment = self.find_visual_studio_express()
@@ -672,23 +622,16 @@ class WindowsSetup(PlatformSetup):
print >> sys.stderr, "\nPlease see https://wiki.secondlife.com/wiki/Microsoft_Visual_Studio#Extra_steps_for_Visual_Studio_Express_editions for Visual Studio Express specific information"
exit(0)
msbuild_dir, tool_ver = self.find_msbuild()
if msbuild_dir is not None and tool_ver is not None:
return ('\"%smsbuild.exe\" \"%s.sln\" /p:configuration=%s /p:VisualStudioVersion=%s' %
(msbuild_dir, self.project_name, self.build_type, tool_ver)), True
# devenv.com is CLI friendly, devenv.exe... not so much.
return ('"%sdevenv.com" \"%s.sln\" /build %s' %
(self.find_visual_studio(), self.project_name, self.build_type)), None
return ('"%sdevenv.com" %s.sln /build %s' %
(self.find_visual_studio(), self.project_name, self.build_type))
def run(self, command, name=None):
'''Run a program. If the program fails, raise an exception.'''
ret = os.system('\"'+command+'\"')
ret = os.system(command)
if ret:
if name is None:
name = os.path.normpath(shlex.split(command.encode('utf8'),posix=False)[0].strip('"'))
name = command.split(None, 1)[0]
path = self.find_in_path(name)
if not path:
ret = 'was not found'
@@ -714,15 +657,10 @@ class WindowsSetup(PlatformSetup):
if prev_build == self.build_type:
# Only run vstool if the build type has changed.
continue
if(os.path.basename(os.path.normpath(os.getcwd())) == 'indra'):
tool_path = os.path.join('tools','vstool','VSTool.exe')
else:
tool_path = os.path.join('indra','tools','vstool','VSTool.exe')
vstool_cmd = (tool_path +
' --solution \"' +
os.path.join(build_dir,'%s.sln' % self.project_name) +
'\" --config ' + self.build_type +
vstool_cmd = (os.path.join('tools','vstool','VSTool.exe') +
' --solution ' +
os.path.join(build_dir,'Singularity.sln') +
' --config ' + self.build_type +
' --startup secondlife-bin')
print 'Running vstool %r in %r' % (vstool_cmd, getcwd())
self.run(vstool_cmd)
@@ -730,21 +668,16 @@ class WindowsSetup(PlatformSetup):
def run_build(self, opts, targets):
cwd = getcwd()
build_cmd, msbuild = self.get_build_cmd()
build_cmd = self.get_build_cmd()
for d in self.build_dirs():
try:
os.chdir(d)
if targets:
if msbuild:
cmd = '%s /target:%s %s' % (build_cmd, ';'.join(targets), ' '.join(opts))
for t in targets:
cmd = '%s /project %s %s' % (build_cmd, t, ' '.join(opts))
print 'Running build(targets) %r in %r' % (cmd, d)
self.run(cmd)
else:
for t in targets:
cmd = '%s /project %s %s' % (build_cmd, t, ' '.join(opts))
print 'Running build(targets) %r in %r' % (cmd, d)
self.run(cmd)
else:
cmd = '%s %s' % (build_cmd, ' '.join(opts))
print 'Running build %r in %r' % (cmd, d)
@@ -815,12 +748,10 @@ Commands:
Command-options for "configure":
We use cmake variables to change the build configuration.
-DPACKAGE:BOOL=ON Create "package" target to make installers
-DLOCALIZESETUP:BOOL=ON Create one win_setup target per supported language
-DLL_TESTS:BOOL=OFF Don't generate unit test projects
-DEXAMPLEPLUGIN:BOOL=OFF Don't generate example plugin project
-DDISABLE_TCMALLOC:BOOL=ON Disable linkage of TCMalloc. (64bit builds automatically disable TCMalloc)
-DRELEASE_CRASH_REPORTING:BOOL=ON Enable Google Breakpad crash reporting
-DFMODSTUDIO:BOOL=ON Use FMOD Studio audio libraries
-DFMODEX:BOOL=ON Use FMOD Ex audio libraries
Examples:
Set up a Visual Studio 2010 project with "package" target:

View File

@@ -2,24 +2,19 @@
@file __init__.py
@brief Initialization file for the indra module.
$LicenseInfo:firstyear=2006&license=viewerlgpl$
Second Life Viewer Source Code
Copyright (C) 2006-2010, Linden Research, Inc.
$LicenseInfo:firstyear=2006&license=internal$
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.
Copyright (c) 2006-2009, Linden Research, Inc.
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.
The following source code is PROPRIETARY AND CONFIDENTIAL. Use of
this source code is governed by the Linden Lab Source Code Disclosure
Agreement ("Agreement") previously entered between you and Linden
Lab. By accessing, using, copying, modifying or distributing this
software, you acknowledge that you have been informed of your
obligations under the Agreement and agree to abide by those obligations.
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
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$
"""

View File

@@ -1,25 +1,3 @@
#!/usr/bin/python
##
## $LicenseInfo:firstyear=2011&license=viewerlgpl$
## Second Life Viewer Source Code
## Copyright (C) 2011, 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$
from indra.base import llsd, lluuid
from datetime import datetime
import cllsd
@@ -32,7 +10,7 @@ values = (
'&<>',
u'\u81acj',
llsd.uri('http://foo<'),
lluuid.UUID(),
lluuid.LLUUID(),
llsd.LLSD(['thing']),
1,
myint(31337),

View File

@@ -0,0 +1,72 @@
"""\
@file lllog.py
@brief Logging for event processing
$LicenseInfo:firstyear=2008&license=mit$
Copyright (c) 2008-2009, Linden Research, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
$/LicenseInfo$
"""
from indra.base.llsd import format_notation
try:
import syslog
except ImportError:
# Windows
import sys
class syslog(object):
_logfp = sys.stderr
def syslog(msg):
_logfp.write(msg)
if not msg.endswith('\n'):
_logfp.write('\n')
syslog = staticmethod(syslog)
class Logger(object):
def __init__(self, name='indra'):
self._sequence = 0
try:
syslog.openlog(name, syslog.LOG_CONS | syslog.LOG_PID,
syslog.LOG_LOCAL0)
except AttributeError:
# No syslog module on Windows
pass
def next(self):
self._sequence += 1
return self._sequence
def log(self, msg, llsd):
payload = 'INFO: log: LLLOGMESSAGE (%d) %s %s' % (self.next(), msg,
format_notation(llsd))
syslog.syslog(payload)
_logger = None
def log(msg, llsd):
global _logger
if _logger is None:
_logger = Logger()
_logger.log(msg, llsd)

View File

@@ -72,11 +72,8 @@ BOOL_FALSE = ('0', '0.0', 'false', '')
def format_datestr(v):
""" Formats a datetime or date object into the string format shared by xml and notation serializations."""
if hasattr(v, 'microsecond'):
return v.isoformat() + 'Z'
else:
return v.strftime('%Y-%m-%dT%H:%M:%SZ')
""" Formats a datetime object into the string format shared by xml and notation serializations."""
return v.isoformat() + 'Z'
def parse_datestr(datestr):
"""Parses a datetime object from the string format shared by xml and notation serializations."""
@@ -186,7 +183,6 @@ class LLSDXMLFormatter(object):
unicode : self.STRING,
uri : self.URI,
datetime.datetime : self.DATE,
datetime.date : self.DATE,
list : self.ARRAY,
tuple : self.ARRAY,
types.GeneratorType : self.ARRAY,
@@ -238,7 +234,7 @@ class LLSDXMLFormatter(object):
def MAP(self, v):
return self.elt(
'map',
''.join(["%s%s" % (self.elt('key', self.xml_esc(str(key))), self.generate(value))
''.join(["%s%s" % (self.elt('key', key), self.generate(value))
for key, value in v.items()]))
typeof = type
@@ -351,7 +347,6 @@ class LLSDNotationFormatter(object):
unicode : self.STRING,
uri : self.URI,
datetime.datetime : self.DATE,
datetime.date : self.DATE,
list : self.ARRAY,
tuple : self.ARRAY,
types.GeneratorType : self.ARRAY,
@@ -929,13 +924,12 @@ def _format_binary_recurse(something):
(type(something), something))
def parse_binary(binary):
if binary.startswith('<?llsd/binary?>'):
just_binary = binary.split('\n', 1)[1]
else:
just_binary = binary
return LLSDBinaryParser().parse(just_binary)
def parse_binary(something):
header = '<?llsd/binary?>\n'
if not something.startswith(header):
raise LLSDParseError('LLSD binary encoding header not found')
return LLSDBinaryParser().parse(something[len(header):])
def parse_xml(something):
try:
return to_python(fromstring(something)[0])

View File

@@ -28,12 +28,13 @@ $/LicenseInfo$
import random, socket, string, time, re
import uuid
# *HACK: Necessary for python 2.4. Consider replacing this code wart
# after python >=2.5 has deployed everywhere. 2009-10-05
try:
# Python 2.6
from hashlib import md5
except ImportError:
# Python 2.5 and earlier
from md5 import new as md5
from md5 import md5
def _int2binstr(i,l):
s=''
@@ -72,7 +73,7 @@ class UUID(object):
ip = ''
try:
ip = socket.gethostbyname(socket.gethostname())
except(socket.gaierror, socket.error):
except(socket.gaierror):
# no ip address, so just default to somewhere in 10.x.x.x
ip = '10'
for i in range(3):
@@ -163,7 +164,7 @@ class UUID(object):
def setFromMemoryDump(self, gdb_string):
"""
We expect to get gdb_string as four hex units. eg:
0x147d54db 0xc34b3f1b 0x714f989b 0x0a892fd2
0x147d54db 0xc34b3f1b 0x714f989b 0x0a892fd2
Which will be translated to:
db547d14-1b3f4bc3-9b984f71-d22f890a
Returns self.
@@ -187,7 +188,7 @@ class UUID(object):
def getAsString(self):
"""
Return a different string representation of the form
AAAAAAAA-AAAABBBB-BBBBBBBB-BBCCCCCC (a 128-bit number in hex)
AAAAAAAA-AAAABBBB-BBBBBBBB-BBCCCCCC (a 128-bit number in hex)
where A=network address, B=timestamp, C=random.
"""
i1 = _binstr2int(self._bits[0:4])
@@ -233,7 +234,7 @@ NULL = UUID()
def printTranslatedMemory(four_hex_uints):
"""
We expect to get the string as four hex units. eg:
0x147d54db 0xc34b3f1b 0x714f989b 0x0a892fd2
0x147d54db 0xc34b3f1b 0x714f989b 0x0a892fd2
Which will be translated to:
db547d14-1b3f4bc3-9b984f71-d22f890a
"""

View File

@@ -29,93 +29,25 @@ $/LicenseInfo$
"""
import sys
try:
import syslog
except ImportError:
# Windows
import sys
class syslog(object):
# wrap to a lame syslog for windows
_logfp = sys.stderr
def syslog(msg):
_logfp.write(msg)
if not msg.endswith('\n'):
_logfp.write('\n')
syslog = staticmethod(syslog)
from indra.base import llsd
from indra.base.llsd import format_notation
def record_metrics(table, stats):
"Write a standard metrics log"
_log("LLMETRICS", table, stats)
def record_event(table, data):
"Write a standard logmessage log"
_log("LLLOGMESSAGE", table, data)
def set_destination(dest):
"""Set the destination of metrics logs for this process.
If you do not call this function prior to calling a logging
method, that function will open sys.stdout as a destination.
Attempts to set dest to None will throw a RuntimeError.
@param dest a file-like object which will be the destination for logs."""
if dest is None:
raise RuntimeError("Attempt to unset metrics destination.")
global _destination
_destination = dest
def destination():
"""Get the destination of the metrics logs for this process.
Returns None if no destination is set"""
global _destination
return _destination
class SysLogger(object):
"A file-like object which writes to syslog."
def __init__(self, ident='indra', logopt = None, facility = None):
try:
if logopt is None:
logopt = syslog.LOG_CONS | syslog.LOG_PID
if facility is None:
facility = syslog.LOG_LOCAL0
syslog.openlog(ident, logopt, facility)
import atexit
atexit.register(syslog.closelog)
except AttributeError:
# No syslog module on Windows
pass
def write(str):
syslog.syslog(str)
write = staticmethod(write)
def flush():
pass
flush = staticmethod(flush)
#
# internal API
#
_sequence_id = 0
_destination = None
def _next_id():
def record_metrics(table, stats, dest=None):
"Write a standard metrics log"
_log("LLMETRICS", table, stats, dest)
def record_event(table, data, dest=None):
"Write a standard logmessage log"
_log("LLLOGMESSAGE", table, data, dest)
def _log(header, table, data, dest):
if dest is None:
# do this check here in case sys.stdout changes at some
# point. as a default parameter, it will never be
# re-evaluated.
dest = sys.stdout
global _sequence_id
next = _sequence_id
print >>dest, header, "(" + str(_sequence_id) + ")",
print >>dest, table, llsd.format_notation(data)
_sequence_id += 1
return next
def _dest():
global _destination
if _destination is None:
# this default behavior is documented in the metrics functions above.
_destination = sys.stdout
return _destination
def _log(header, table, data):
log_line = "%s (%d) %s %s" \
% (header, _next_id(), table, format_notation(data))
dest = _dest()
dest.write(log_line)
dest.flush()

View File

@@ -39,12 +39,6 @@ except:
pass
_g_builder = None
def _builder():
global _g_builder
if _g_builder is None:
_g_builder = ServiceBuilder()
return _g_builder
def build(name, context={}, **kwargs):
""" Convenience method for using a global, singleton, service builder. Pass arguments either via a dict or via python keyword arguments, or both!
@@ -62,11 +56,6 @@ def build(name, context={}, **kwargs):
_g_builder = ServiceBuilder()
return _g_builder.buildServiceURL(name, context, **kwargs)
def build_path(name, context={}, **kwargs):
context = context.copy() # shouldn't modify the caller's dictionary
context.update(kwargs)
return _builder().buildPath(name, context)
class ServiceBuilder(object):
def __init__(self, services_definition = services_config):
"""\
@@ -84,21 +73,12 @@ class ServiceBuilder(object):
continue
if isinstance(service_builder, dict):
# We will be constructing several builders
for name, builder in service_builder.iteritems():
for name, builder in service_builder.items():
full_builder_name = service['name'] + '-' + name
self.builders[full_builder_name] = builder
else:
self.builders[service['name']] = service_builder
def buildPath(self, name, context):
"""\
@brief given the environment on construction, return a service path.
@param name The name of the service.
@param context A dict of name value lookups for the service.
@returns Returns the
"""
return russ.format(self.builders[name], context)
def buildServiceURL(self, name, context={}, **kwargs):
"""\
@brief given the environment on construction, return a service URL.
@@ -128,7 +108,7 @@ def on_in(query_name, host_key, schema_key):
@param schema_key Logical name of destination schema. Will
be looked up in indra.xml.
"""
return "on/config:%s/in/config:%s/%s" % (host_key.strip('/'),
schema_key.strip('/'),
query_name.lstrip('/'))
host_name = config.get(host_key)
schema_name = config.get(schema_key)
return '/'.join( ('on', host_name, 'in', schema_name, query_name.lstrip('/')) )

View File

@@ -1,32 +1,3 @@
"""\
@file siesta.py
@brief A tiny llsd based RESTful web services framework
$LicenseInfo:firstyear=2008&license=mit$
Copyright (c) 2008, Linden Research, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
$/LicenseInfo$
"""
from indra.base import config
from indra.base import llsd
from webob import exc
import webob
@@ -66,11 +37,11 @@ def mime_type(content_type):
return content_type.split(';', 1)[0].strip().lower()
class BodyLLSD(object):
'''Give a webob Request or Response an llsd based "content" property.
'''Give a webob Request or Response an llsd property.
Getting the content property parses the body, and caches the result.
Getting the llsd property parses the body, and caches the result.
Setting the content property formats a payload, and the body property
Setting the llsd property formats a payload, and the body property
is set.'''
def _llsd__get(self):
@@ -109,7 +80,7 @@ class BodyLLSD(object):
if hasattr(self, '_llsd'):
del self._llsd
content = property(_llsd__get, _llsd__set, _llsd__del)
llsd = property(_llsd__get, _llsd__set, _llsd__del)
class Response(webob.Response, BodyLLSD):
@@ -143,10 +114,10 @@ class Request(webob.Request, BodyLLSD):
Sensible content type and accept headers are used by default.
Setting the content property also sets the body. Getting the content
Setting the llsd property also sets the body. Getting the llsd
property parses the body if necessary.
If you set the body property directly, the content property will be
If you set the body property directly, the llsd property will be
deleted.'''
default_content_type = 'application/llsd+xml'
@@ -178,11 +149,11 @@ class Request(webob.Request, BodyLLSD):
body = property(webob.Request._body__get, _body__set,
webob.Request._body__del, webob.Request._body__get.__doc__)
def create_response(self, content=None, status='200 OK',
def create_response(self, llsd=None, status='200 OK',
conditional_response=webob.NoDefault):
resp = self.ResponseClass(status=status, request=self,
conditional_response=conditional_response)
resp.content = content
resp.llsd = llsd
return resp
def curl(self):
@@ -225,18 +196,12 @@ llsd_formatters = {
'application/xml': llsd.format_xml,
}
formatter_qualities = (
('application/llsd+xml', 1.0),
('application/llsd+notation', 0.5),
('application/llsd+binary', 0.4),
('application/xml', 0.3),
('application/json', 0.2),
)
def formatter_for_mime_type(mime_type):
'''Return a formatter that encodes to the given MIME type.
The result is a pair of function and MIME type.'''
try:
return llsd_formatters[mime_type], mime_type
except KeyError:
@@ -249,19 +214,21 @@ def formatter_for_request(req):
'''Return a formatter that encodes to the preferred type of the client.
The result is a pair of function and actual MIME type.'''
ctype = req.accept.best_match(formatter_qualities)
try:
return llsd_formatters[ctype], ctype
except KeyError:
for ctype in req.accept.best_matches('application/llsd+xml'):
try:
return llsd_formatters[ctype], ctype
except KeyError:
pass
else:
raise exc.HTTPNotAcceptable().exception
def wsgi_adapter(func, environ, start_response):
'''Adapt a Siesta callable to act as a WSGI application.'''
# Process the request as appropriate.
try:
req = Request(environ)
#print req.urlvars
resp = func(req, **req.urlvars)
if not isinstance(resp, webob.Response):
try:
@@ -314,8 +281,7 @@ def llsd_class(cls):
allowed = [m for m in http11_methods
if hasattr(instance, 'handle_' + m.lower())]
raise exc.HTTPMethodNotAllowed(
headers={'Allow': ', '.join(allowed)}).exception
#print "kwargs: ", kwargs
headers={'Allowed': ', '.join(allowed)}).exception
return handler(req, **kwargs)
def replacement(environ, start_response):
@@ -370,7 +336,7 @@ def curl(reqs):
route_re = re.compile(r'''
\{ # exact character "{"
(\w*) # "config" or variable (restricted to a-z, 0-9, _)
(\w+) # variable name (restricted to a-z, 0-9, _)
(?:([:~])([^}]+))? # optional :type or ~regex part
\} # exact character "}"
''', re.VERBOSE)
@@ -378,37 +344,27 @@ route_re = re.compile(r'''
predefined_regexps = {
'uuid': r'[a-f0-9][a-f0-9-]{31,35}',
'int': r'\d+',
'host': r'[a-z0-9][a-z0-9\-\.]*',
}
def compile_route(route):
fp = StringIO()
last_pos = 0
for match in route_re.finditer(route):
#print "matches: ", match.groups()
fp.write(re.escape(route[last_pos:match.start()]))
var_name = match.group(1)
sep = match.group(2)
expr = match.group(3)
if var_name == 'config':
expr = re.escape(str(config.get(var_name)))
if expr:
if sep == ':':
expr = predefined_regexps[expr]
# otherwise, treat what follows '~' as a regexp
else:
if expr:
if sep == ':':
expr = predefined_regexps[expr]
# otherwise, treat what follows '~' as a regexp
else:
expr = '[^/]+'
if var_name != '':
expr = '(?P<%s>%s)' % (var_name, expr)
else:
expr = '(%s)' % (expr,)
expr = '[^/]+'
expr = '(?P<%s>%s)' % (var_name, expr)
fp.write(expr)
last_pos = match.end()
fp.write(re.escape(route[last_pos:]))
compiled_route = '^%s$' % fp.getvalue()
#print route, "->", compiled_route
return compiled_route
return '^%s$' % fp.getvalue()
class Router(object):
'''WSGI routing class. Parses a URL and hands off a request to
@@ -416,43 +372,21 @@ class Router(object):
responds with a 404.'''
def __init__(self):
self._new_routes = []
self._routes = []
self._paths = []
self.routes = []
self.paths = []
def add(self, route, app, methods=None):
self._new_routes.append((route, app, methods))
def _create_routes(self):
for route, app, methods in self._new_routes:
self._paths.append(route)
self._routes.append(
(re.compile(compile_route(route)),
app,
methods and dict.fromkeys(methods)))
self._new_routes = []
self.paths.append(route)
self.routes.append((re.compile(compile_route(route)), app,
methods and dict.fromkeys(methods)))
def __call__(self, environ, start_response):
# load up the config from the config file. Only needs to be
# done once per interpreter. This is the entry point of all
# siesta applications, so this is where we trap it.
_conf = config.get_config()
if _conf is None:
import os.path
fname = os.path.join(
environ.get('ll.config_dir', '/local/linden/etc'),
'indra.xml')
config.load(fname)
# proceed with handling the request
self._create_routes()
path_info = environ['PATH_INFO']
request_method = environ['REQUEST_METHOD']
allowed = []
for regex, app, methods in self._routes:
for regex, app, methods in self.routes:
m = regex.match(path_info)
if m:
#print "groupdict:",m.groupdict()
if not methods or request_method in methods:
environ['paste.urlvars'] = m.groupdict()
return app(environ, start_response)
@@ -462,7 +396,7 @@ class Router(object):
allowed = dict.fromkeys(allows).keys()
allowed.sort()
resp = exc.HTTPMethodNotAllowed(
headers={'Allow': ', '.join(allowed)})
headers={'Allowed': ', '.join(allowed)})
else:
resp = exc.HTTPNotFound()
return resp(environ, start_response)

View File

@@ -280,14 +280,13 @@ class LLManifest(object):
self.file_list = []
self.excludes = []
self.actions = []
self.src_prefix = list([args['source']])
self.artwork_prefix = list([args['artwork']])
self.build_prefix = list([args['build']])
self.alt_build_prefix = list([args['build']])
self.dst_prefix = list([args['dest']])
self.src_prefix = [args['source']]
self.artwork_prefix = [args['artwork']]
self.build_prefix = [args['build']]
self.dst_prefix = [args['dest']]
self.created_paths = []
self.package_name = "Unknown"
def default_grid(self):
return self.args.get('grid', None) == ''
def default_channel(self):
@@ -311,7 +310,7 @@ class LLManifest(object):
in the file list by path()."""
self.excludes.append(glob)
def prefix(self, src='', build=None, dst=None, alt_build=None):
def prefix(self, src='', build=None, dst=None):
""" Pushes a prefix onto the stack. Until end_prefix is
called, all relevant method calls (esp. to path()) will prefix
paths with the entire prefix stack. Source and destination
@@ -322,15 +321,10 @@ class LLManifest(object):
dst = src
if build is None:
build = src
if alt_build is None:
alt_build = build
self.src_prefix.append(src)
self.artwork_prefix.append(src)
self.build_prefix.append(build)
self.dst_prefix.append(dst)
self.alt_build_prefix.append(alt_build)
return True # so that you can wrap it in an if to get indentation
def end_prefix(self, descr=None):
@@ -343,30 +337,25 @@ class LLManifest(object):
src = self.src_prefix.pop()
artwork = self.artwork_prefix.pop()
build = self.build_prefix.pop()
alt_build_prefix = self.alt_build_prefix.pop()
dst = self.dst_prefix.pop()
if descr and not(src == descr or build == descr or dst == descr):
raise ValueError, "End prefix '" + descr + "' didn't match '" +src+ "' or '" +dst + "'"
def get_src_prefix(self):
""" Returns the current source prefix."""
return os.path.relpath(os.path.normpath(os.path.join(*self.src_prefix)))
return os.path.join(*self.src_prefix)
def get_artwork_prefix(self):
""" Returns the current artwork prefix."""
return os.path.relpath(os.path.normpath(os.path.join(*self.artwork_prefix)))
return os.path.join(*self.artwork_prefix)
def get_build_prefix(self):
""" Returns the current build prefix."""
return os.path.relpath(os.path.normpath(os.path.join(*self.build_prefix)))
def get_alt_build_prefix(self):
""" Returns the current alternate source prefix."""
return os.path.relpath(os.path.normpath(os.path.join(*self.alt_build_prefix)))
return os.path.join(*self.build_prefix)
def get_dst_prefix(self):
""" Returns the current destination prefix."""
return os.path.relpath(os.path.normpath(os.path.join(*self.dst_prefix)))
return os.path.join(*self.dst_prefix)
def src_path_of(self, relpath):
"""Returns the full path to a file or directory specified
@@ -383,6 +372,22 @@ class LLManifest(object):
relative to the destination directory."""
return os.path.join(self.get_dst_prefix(), relpath)
def ensure_src_dir(self, reldir):
"""Construct the path for a directory relative to the
source path, and ensures that it exists. Returns the
full path."""
path = os.path.join(self.get_src_prefix(), reldir)
self.cmakedirs(path)
return path
def ensure_dst_dir(self, reldir):
"""Construct the path for a directory relative to the
destination path, and ensures that it exists. Returns the
full path."""
path = os.path.join(self.get_dst_prefix(), reldir)
self.cmakedirs(path)
return path
def run_command(self, command):
""" Runs an external command, and returns the output. Raises
an exception if the command reurns a nonzero status code. For
@@ -479,30 +484,29 @@ class LLManifest(object):
if method is not None:
method(src, dst)
self.file_list.append([src, dst])
return [dst]
return 1
else:
sys.stdout.write(" (excluding %r, %r)" % (src, dst))
sys.stdout.flush()
return []
return 0
def process_directory(self, src, dst):
if not self.includes(src, dst):
sys.stdout.write(" (excluding %r, %r)" % (src, dst))
sys.stdout.flush()
return []
return 0
names = os.listdir(src)
self.cmakedirs(dst)
errors = []
found_files = []
count = 0
for name in names:
srcname = os.path.join(src, name)
dstname = os.path.join(dst, name)
if os.path.isdir(srcname):
found_files.extend(self.process_directory(srcname, dstname))
count += self.process_directory(srcname, dstname)
else:
found_files.extend(self.process_file(srcname, dstname))
return found_files
count += self.process_file(srcname, dstname)
return count
def includes(self, src, dst):
if src:
@@ -582,11 +586,25 @@ class LLManifest(object):
if os.path.exists(f):
return f
# didn't find it, return last item in list
if list:
if len(list) > 0:
return list[-1]
else:
return None
def contents_of_tar(self, src_tar, dst_dir):
""" Extracts the contents of the tarfile (specified
relative to the source prefix) into the directory
specified relative to the destination directory."""
self.check_file_exists(src_tar)
tf = tarfile.open(self.src_path_of(src_tar), 'r')
for member in tf.getmembers():
tf.extract(member, self.ensure_dst_dir(dst_dir))
# TODO get actions working on these dudes, perhaps we should extract to a temporary directory and then process_directory on it?
self.file_list.append([src_tar,
self.dst_path_of(os.path.join(dst_dir,member.name))])
tf.close()
def wildcard_regex(self, src_glob, dst_glob):
src_re = re.escape(src_glob)
src_re = src_re.replace('\*', '([-a-zA-Z0-9._ ]*)')
@@ -597,6 +615,12 @@ class LLManifest(object):
i = i+1
return re.compile(src_re), dst_temp
def check_file_exists(self, path):
if not os.path.exists(path) and not os.path.islink(path):
raise RuntimeError("Path %s doesn't exist" % (
os.path.normpath(os.path.join(os.getcwd(), path)),))
wildcard_pattern = re.compile('\*')
def expand_globs(self, src, dst):
src_list = glob.glob(src)
@@ -606,61 +630,40 @@ class LLManifest(object):
d = src_re.sub(d_template, s.replace('\\', '/'))
yield os.path.normpath(s), os.path.normpath(d)
def path2basename(self, path, file):
"""
It is a common idiom to write:
self.path(os.path.join(somedir, somefile), somefile)
So instead you can write:
self.path2basename(somedir, somefile)
Note that this is NOT the same as:
self.path(os.path.join(somedir, somefile))
which is the same as:
temppath = os.path.join(somedir, somefile)
self.path(temppath, temppath)
"""
return self.path(os.path.join(path, file), file)
def path(self, src, dst=None):
sys.stdout.write("Processing %s => %s ... " % (src, dst))
sys.stdout.flush()
if src == None:
raise RuntimeError("No source file, dst is " + dst)
if dst == None:
dst = src
dst = os.path.join(self.get_dst_prefix(), dst)
sys.stdout.write("Processing %s => %s ... " % (src, dst))
count = 0
is_glob = False
found_files = []
# look under each prefix for matching paths. Paths are normalized so './../blah' will match '../blah/../blah/'
paths = set([os.path.normpath(os.path.join(self.get_src_prefix(), src)),
os.path.normpath(os.path.join(self.get_artwork_prefix(), src)),
os.path.normpath(os.path.join(self.get_build_prefix(), src)),
os.path.normpath(os.path.join(self.get_alt_build_prefix(), src))]
)
# look under each prefix for matching paths
paths = set([os.path.join(self.get_src_prefix(), src),
os.path.join(self.get_artwork_prefix(), src),
os.path.join(self.get_build_prefix(), src)])
for path in paths:
if self.wildcard_pattern.search(path):
is_glob = True
for s,d in self.expand_globs(path, dst):
assert(s != d)
found_files.extend(self.process_file(s, d))
count += self.process_file(s, d)
else:
# if it's a directory, recurse through it
if os.path.isdir(path):
found_files.extend(self.process_directory(path, dst))
count += self.process_directory(path, dst)
elif os.path.exists(path):
found_files.extend(self.process_file(path, dst))
count += self.process_file(path, dst)
# if we're specifying a single path (not a glob),
# we should error out if it doesn't exist
if not found_files and not is_glob:
if count == 0 and not is_glob:
raise RuntimeError("No files match %s\n" % str(paths))
print "%d files" % len(found_files)
return found_files
print "%d files" % count
def do(self, *actions):
self.actions = actions

View File

@@ -1,28 +1,4 @@
#!/usr/bin/env python
"""\
@file llperformance.py
$LicenseInfo:firstyear=2010&license=viewerlgpl$
Second Life Viewer Source Code
Copyright (C) 2010-2011, 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$
"""
#!/usr/bin/python
# ------------------------------------------------
# Sim metrics utility functions.

View File

@@ -90,17 +90,6 @@ all the output, and get the result.
child.tochild.close()
result = child.poll()
if result != -1:
# At this point, the child process has exited and result
# is the return value from the process. Between the time
# we called select() and poll() the process may have
# exited so read all the data left on the child process
# stdout and stderr.
last = child.fromchild.read()
if last:
out.append(last)
last = child.childerr.read()
if last:
err.append(last)
child.tochild.close()
child.fromchild.close()
child.childerr.close()

View File

@@ -0,0 +1,95 @@
"""@file llversion.py
@brief Utility for parsing llcommon/llversion${server}.h
for the version string and channel string
Utility that parses svn info for branch and revision
$LicenseInfo:firstyear=2006&license=mit$
Copyright (c) 2006-2009, Linden Research, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
$/LicenseInfo$
"""
import re, sys, os, commands
# Methods for gathering version information from
# llversionviewer.h and llversionserver.h
def get_src_root():
indra_lib_python_indra_path = os.path.dirname(__file__)
return os.path.abspath(os.path.realpath(indra_lib_python_indra_path + "/../../../../../"))
def get_version_file_contents(version_type):
filepath = get_src_root() + '/indra/llcommon/llversion%s.h' % version_type
file = open(filepath,"r")
file_str = file.read()
file.close()
return file_str
def get_version(version_type):
file_str = get_version_file_contents(version_type)
m = re.search('const S32 LL_VERSION_MAJOR = (\d+);', file_str)
VER_MAJOR = m.group(1)
m = re.search('const S32 LL_VERSION_MINOR = (\d+);', file_str)
VER_MINOR = m.group(1)
m = re.search('const S32 LL_VERSION_PATCH = (\d+);', file_str)
VER_PATCH = m.group(1)
m = re.search('const S32 LL_VERSION_BUILD = (\d+);', file_str)
VER_BUILD = m.group(1)
version = "%(VER_MAJOR)s.%(VER_MINOR)s.%(VER_PATCH)s.%(VER_BUILD)s" % locals()
return version
def get_channel(version_type):
file_str = get_version_file_contents(version_type)
m = re.search('const char \* const LL_CHANNEL = "(.+)";', file_str)
return m.group(1)
def get_viewer_version():
return get_version('viewer')
def get_server_version():
return get_version('server')
def get_viewer_channel():
return get_channel('viewer')
def get_server_channel():
return get_channel('server')
# Methods for gathering subversion information
def get_svn_status_matching(regular_expression):
# Get the subversion info from the working source tree
status, output = commands.getstatusoutput('svn info %s' % get_src_root())
m = regular_expression.search(output)
if not m:
print "Failed to parse svn info output, resultfollows:"
print output
raise Exception, "No matching svn status in "+src_root
return m.group(1)
def get_svn_branch():
branch_re = re.compile('URL: (\S+)')
return get_svn_status_matching(branch_re)
def get_svn_revision():
last_rev_re = re.compile('Last Changed Rev: (\d+)')
return get_svn_status_matching(last_rev_re)

View File

@@ -40,6 +40,7 @@ from indra.base import llsd
from indra.base import config
DEBUG = False
NQ_FILE_SUFFIX = config.get('named-query-file-suffix', '.nq')
NQ_FILE_SUFFIX_LEN = len(NQ_FILE_SUFFIX)
@@ -51,11 +52,6 @@ def _init_g_named_manager(sql_dir = None):
This function is intended entirely for testing purposes,
because it's tricky to control the config from inside a test."""
global NQ_FILE_SUFFIX
NQ_FILE_SUFFIX = config.get('named-query-file-suffix', '.nq')
global NQ_FILE_SUFFIX_LEN
NQ_FILE_SUFFIX_LEN = len(NQ_FILE_SUFFIX)
if sql_dir is None:
sql_dir = config.get('named-query-base-dir')
@@ -69,11 +65,11 @@ def _init_g_named_manager(sql_dir = None):
_g_named_manager = NamedQueryManager(
os.path.abspath(os.path.realpath(sql_dir)))
def get(name, schema = None):
def get(name):
"Get the named query object to be used to perform queries"
if _g_named_manager is None:
_init_g_named_manager()
return _g_named_manager.get(name).for_schema(schema)
return _g_named_manager.get(name)
def sql(connection, name, params):
# use module-global NamedQuery object to perform default substitution
@@ -284,10 +280,7 @@ class NamedQuery(object):
So, we need a vendor (or extention) for LIKE_STRING. Anyone
want to write it?"""
if isinstance(value, unicode):
utf8_value = value
else:
utf8_value = unicode(value, "utf-8")
utf8_value = unicode(value, "utf-8")
esc_list = []
remove_chars = set(u"%_")
for glyph in utf8_value:
@@ -324,8 +317,6 @@ class NamedQuery(object):
def for_schema(self, db_name):
"Look trough the alternates and return the correct query"
if db_name is None:
return self
try:
return self._alternative[db_name]
except KeyError, e:
@@ -350,21 +341,21 @@ class NamedQuery(object):
cursor = connection.cursor(MySQLdb.cursors.DictCursor)
else:
cursor = connection.cursor()
full_query, params = self._construct_sql(params)
statement = self.sql(connection, params)
if DEBUG:
print "SQL:", self.sql(connection, params)
rows = cursor.execute(full_query, params)
print "SQL:", statement
rows = cursor.execute(statement)
# *NOTE: the expect_rows argument is a very cheesy way to get some
# validation on the result set. If you want to add more expectation
# logic, do something more object-oriented and flexible. Or use an ORM.
# logic, do something more object-oriented and flexible. Or use an ORM.
if(self._return_as_map):
expect_rows = 1
if expect_rows is not None and rows != expect_rows:
cursor.close()
raise ExpectationFailed("Statement expected %s rows, got %s. Sql: '%s' %s" % (
expect_rows, rows, full_query, params))
raise ExpectationFailed("Statement expected %s rows, got %s. Sql: %s" % (
expect_rows, rows, statement))
# convert to dicts manually if we're not using a dictcursor
if use_dictcursor:
@@ -390,9 +381,11 @@ class NamedQuery(object):
return result_set[0]
return result_set
def _construct_sql(self, params):
""" Returns a query string and a dictionary of parameters,
suitable for directly passing to the execute() method."""
def sql(self, connection, params):
""" Generates an SQL statement from the named query document
and a dictionary of parameters.
"""
self.refresh()
# build the query from the options available and the params
@@ -438,23 +431,10 @@ class NamedQuery(object):
new_params[self._build_integer_key(key)] = int(params[key])
params.update(new_params)
return full_query, params
def sql(self, connection, params):
""" Generates an SQL statement from the named query document
and a dictionary of parameters.
*NOTE: Only use for debugging, because it uses the
non-standard MySQLdb 'literal' method.
"""
if not DEBUG:
import warnings
warnings.warn("Don't use named_query.sql() when not debugging. Used on %s" % self._location)
# do substitution using the mysql (non-standard) 'literal'
# function to do the escaping.
full_query, params = self._construct_sql(params)
return full_query % connection.literal(params)
sql = full_query % connection.literal(params)
return sql
def refresh(self):
""" Refresh self from the file on the filesystem.

View File

@@ -3,27 +3,20 @@
@file simperf_oprof_interface.py
@brief Manage OProfile data collection on a host
$LicenseInfo:firstyear=2008&license=mit$
$LicenseInfo:firstyear=2008&license=internal$
Copyright (c) 2008-2009, Linden Research, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The following source code is PROPRIETARY AND CONFIDENTIAL. Use of
this source code is governed by the Linden Lab Source Code Disclosure
Agreement ("Agreement") previously entered between you and Linden
Lab. By accessing, using, copying, modifying or distributing this
software, you acknowledge that you have been informed of your
obligations under the Agreement and agree to abide by those obligations.
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
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$
"""

View File

@@ -1,31 +1,4 @@
#!/usr/bin/env python
"""\
@file simperf_proc_interface.py
@brief Utility to extract log messages from *.<pid>.llsd files containing performance statistics.
$LicenseInfo:firstyear=2008&license=mit$
Copyright (c) 2008-2009, Linden Research, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
$/LicenseInfo$
"""
#!/usr/bin/python
# ----------------------------------------------------
# Utility to extract log messages from *.<pid>.llsd

View File

@@ -1,146 +0,0 @@
#!/usr/bin/env python
"""\
@file test_win32_manifest.py
@brief Test an assembly binding version and uniqueness in a windows dll or exe.
$LicenseInfo:firstyear=2009&license=viewerlgpl$
Second Life Viewer Source Code
Copyright (C) 2009-2011, 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$
"""
import sys, os
import tempfile
from xml.dom.minidom import parse
class AssemblyTestException(Exception):
pass
class NoManifestException(AssemblyTestException):
pass
class MultipleBindingsException(AssemblyTestException):
pass
class UnexpectedVersionException(AssemblyTestException):
pass
class NoMatchingAssemblyException(AssemblyTestException):
pass
def get_HKLM_registry_value(key_str, value_str):
import _winreg
reg = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE)
key = _winreg.OpenKey(reg, key_str)
value = _winreg.QueryValueEx(key, value_str)[0]
#print 'Found: %s' % value
return value
def find_vc_dir():
supported_versions = (r'8.0', r'9.0')
supported_products = (r'VisualStudio', r'VCExpress')
value_str = (r'ProductDir')
for product in supported_products:
for version in supported_versions:
key_str = (r'SOFTWARE\Microsoft\%s\%s\Setup\VC' %
(product, version))
try:
return get_HKLM_registry_value(key_str, value_str)
except WindowsError, err:
x64_key_str = (r'SOFTWARE\Wow6432Node\Microsoft\VisualStudio\%s\Setup\VS' %
version)
try:
return get_HKLM_registry_value(x64_key_str, value_str)
except:
print >> sys.stderr, "Didn't find MS %s version %s " % (product,version)
raise
def find_mt_path():
vc_dir = find_vc_dir()
mt_path = '\"%sbin\\mt.exe\"' % vc_dir
return mt_path
def test_assembly_binding(src_filename, assembly_name, assembly_ver):
print "checking %s dependency %s..." % (src_filename, assembly_name)
(tmp_file_fd, tmp_file_name) = tempfile.mkstemp(suffix='.xml')
tmp_file = os.fdopen(tmp_file_fd)
tmp_file.close()
mt_path = find_mt_path()
resource_id = ""
if os.path.splitext(src_filename)[1].lower() == ".dll":
resource_id = ";#2"
system_call = '%s -nologo -inputresource:%s%s -out:%s > NUL' % (mt_path, src_filename, resource_id, tmp_file_name)
print "Executing: %s" % system_call
mt_result = os.system(system_call)
if mt_result == 31:
print "No manifest found in %s" % src_filename
raise NoManifestException()
manifest_dom = parse(tmp_file_name)
nodes = manifest_dom.getElementsByTagName('assemblyIdentity')
versions = list()
for node in nodes:
if node.getAttribute('name') == assembly_name:
versions.append(node.getAttribute('version'))
if len(versions) == 0:
print "No matching assemblies found in %s" % src_filename
raise NoMatchingAssemblyException()
elif len(versions) > 1:
print "Multiple bindings to %s found:" % assembly_name
print versions
print
raise MultipleBindingsException(versions)
elif versions[0] != assembly_ver:
print "Unexpected version found for %s:" % assembly_name
print "Wanted %s, found %s" % (assembly_ver, versions[0])
print
raise UnexpectedVersionException(assembly_ver, versions[0])
os.remove(tmp_file_name)
print "SUCCESS: %s OK!" % src_filename
print
if __name__ == '__main__':
print
print "Running test_win32_manifest.py..."
usage = 'test_win32_manfest <srcFileName> <assemblyName> <assemblyVersion>'
try:
src_filename = sys.argv[1]
assembly_name = sys.argv[2]
assembly_ver = sys.argv[3]
except:
print "Usage:"
print usage
print
raise
test_assembly_binding(src_filename, assembly_name, assembly_ver)

View File

@@ -45,6 +45,13 @@ Typical usage:
This module works with Python 2.3 or higher."""
# *HACK: Necessary for python 2.4. Consider replacing this code wart
# after python >=2.5 has deployed everywhere. 2009-10-05
try:
from hashlib import md5
except ImportError:
from md5 import md5
__author__ = 'Ka-Ping Yee <ping@zesty.ca>'
__date__ = '$Date: 2006/06/12 23:15:40 $'.split()[1].replace('/', '-')
__version__ = '$Revision: 1.30 $'.split()[1]
@@ -446,13 +453,6 @@ def uuid1(node=None, clock_seq=None):
def uuid3(namespace, name):
"""Generate a UUID from the MD5 hash of a namespace UUID and a name."""
try:
# Python 2.6
from hashlib import md5
except ImportError:
# Python 2.5 and earlier
from md5 import new as md5
hash = md5(namespace.bytes + name).digest()
return UUID(bytes=hash[:16], version=3)

View File

@@ -17,10 +17,6 @@
#include <assert.h>
#include <limits>
#include "hacdManifoldMesh.h"
#if _MSC_VER >= 1800
#include <algorithm>
#endif
namespace HACD
{
bool BBox::Raycast(const Vec3<Float> & origin, const Vec3<Float> & dir, Float & distMin) const

View File

@@ -182,6 +182,9 @@ LLAvatarAppearance::LLAvatarAppearance(LLWearableData* wearable_data) :
}
mIsBuilt = FALSE;
mNumCollisionVolumes = 0;
mCollisionVolumes = NULL;
}
// virtual
@@ -291,7 +294,7 @@ LLAvatarAppearance::~LLAvatarAppearance()
mJointMap.clear();
clearSkeleton();
clearCollisionVolumes();
deleteAndClearArray(mCollisionVolumes);
std::for_each(mPolyMeshes.begin(), mPolyMeshes.end(), DeletePairedPointer());
mPolyMeshes.clear();
@@ -572,12 +575,12 @@ BOOL LLAvatarAppearance::setupBone(const LLAvatarBoneInfo* info, LLJoint* parent
}
else // collision volume
{
if (volume_num >= (S32)mCollisionVolumes.size())
if (volume_num >= (S32)mNumCollisionVolumes)
{
llwarns << "Too many bones" << llendl;
return FALSE;
}
joint = (mCollisionVolumes[volume_num]);
joint = (&mCollisionVolumes[volume_num]);
joint->setName( info->mName );
}
@@ -1247,12 +1250,12 @@ LLVector3 LLAvatarAppearance::getVolumePos(S32 joint_index, LLVector3& volume_of
return LLVector3::zero;
}
if (joint_index > (S32)mCollisionVolumes.size())
if (joint_index > mNumCollisionVolumes)
{
return LLVector3::zero;
}
return mCollisionVolumes[joint_index]->getVolumePos(volume_offset);
return mCollisionVolumes[joint_index].getVolumePos(volume_offset);
}
//-----------------------------------------------------------------------------
@@ -1263,12 +1266,12 @@ LLJoint* LLAvatarAppearance::findCollisionVolume(U32 volume_id)
//SNOW-488: As mNumCollisionVolumes is a S32 and we are casting from a U32 to a S32
//to compare we also need to be sure of the wrap around case producing (S32) <0
//or in terms of the U32 an out of bounds index in the array.
if ((S32)volume_id > (S32)mCollisionVolumes.size() || (S32)volume_id<0)
if ((S32)volume_id > mNumCollisionVolumes || (S32)volume_id<0)
{
return NULL;
}
return mCollisionVolumes[volume_id];
return &mCollisionVolumes[volume_id];
}
//-----------------------------------------------------------------------------
@@ -1276,9 +1279,9 @@ LLJoint* LLAvatarAppearance::findCollisionVolume(U32 volume_id)
//-----------------------------------------------------------------------------
S32 LLAvatarAppearance::getCollisionVolumeID(std::string &name)
{
for (S32 i = 0; i < (S32)mCollisionVolumes.size(); i++)
for (S32 i = 0; i < mNumCollisionVolumes; i++)
{
if (mCollisionVolumes[i]->getName() == name)
if (mCollisionVolumes[i].getName() == name)
{
return i;
}
@@ -1527,34 +1530,21 @@ LLTexLayerSet* LLAvatarAppearance::getAvatarLayerSet(EBakedTextureIndex baked_in
return mBakedTextureDatas[baked_index].mTexLayerSet;
}
void LLAvatarAppearance::clearCollisionVolumes()
{
std::for_each(mCollisionVolumes.begin(), mCollisionVolumes.end(),
DeletePointer());
mCollisionVolumes.clear();
}
//-----------------------------------------------------------------------------
// allocateCollisionVolumes()
//-----------------------------------------------------------------------------
BOOL LLAvatarAppearance::allocateCollisionVolumes( U32 num )
{
mCollisionVolumes.reserve(num);
deleteAndClearArray(mCollisionVolumes);
mNumCollisionVolumes = 0;
LLAvatarJointCollisionVolume* cv;
for (U32 i = 0; i < num; ++i)
mCollisionVolumes = new LLAvatarJointCollisionVolume[num];
if (!mCollisionVolumes)
{
cv = new LLAvatarJointCollisionVolume();
if (cv)
{
mCollisionVolumes.push_back(cv);
}
else
{
clearCollisionVolumes();
return false;
}
return FALSE;
}
mNumCollisionVolumes = num;
return TRUE;
}

View File

@@ -337,9 +337,9 @@ protected:
// Collision volumes
//--------------------------------------------------------------------
public:
std::vector<LLAvatarJointCollisionVolume*> mCollisionVolumes;
S32 mNumCollisionVolumes;
LLAvatarJointCollisionVolume* mCollisionVolumes;
protected:
void clearCollisionVolumes();
BOOL allocateCollisionVolumes(U32 num);
/** Physics

View File

@@ -127,16 +127,6 @@ public:
LLAvatarJointCollisionVolume();
virtual ~LLAvatarJointCollisionVolume() {};
void* operator new(size_t size)
{
return ll_aligned_malloc_16(size);
}
void operator delete(void* ptr)
{
ll_aligned_free_16(ptr);
}
/*virtual*/ BOOL inheritScale() { return TRUE; }
/*virtual*/ U32 render( F32 pixelArea, BOOL first_pass = TRUE, BOOL is_dummy = FALSE );

View File

@@ -647,11 +647,11 @@ BOOL LLPolyMorphTarget::setInfo(LLPolyMorphTargetInfo* info)
for (iter = getInfo()->mVolumeInfoList.begin(); iter != getInfo()->mVolumeInfoList.end(); iter++)
{
LLPolyVolumeMorphInfo *volume_info = &(*iter);
for (S32 i = 0; i < (S32)avatarp->mCollisionVolumes.size(); i++)
for (S32 i = 0; i < avatarp->mNumCollisionVolumes; i++)
{
if (avatarp->mCollisionVolumes[i]->getName() == volume_info->mName)
if (avatarp->mCollisionVolumes[i].getName() == volume_info->mName)
{
mVolumeMorphs.push_back(LLPolyVolumeMorph(avatarp->mCollisionVolumes[i],
mVolumeMorphs.push_back(LLPolyVolumeMorph(&avatarp->mCollisionVolumes[i],
volume_info->mScale,
volume_info->mPos));
break;

View File

@@ -163,16 +163,6 @@ public:
LLPolyMorphTarget(LLPolyMesh *poly_mesh);
~LLPolyMorphTarget();
void* operator new(size_t size)
{
return ll_aligned_malloc_16(size);
}
void operator delete(void* ptr)
{
ll_aligned_free_16(ptr);
}
// Special: These functions are overridden by child classes
LLPolyMorphTargetInfo* getInfo() const { return (LLPolyMorphTargetInfo*)mInfo; }
// This sets mInfo and calls initialization functions

View File

@@ -5,21 +5,25 @@ project(llaudio)
include(00-Common)
include(Audio)
include(LLAudio)
if (FMODSTUDIO)
include(FMODSTUDIO)
endif (FMODSTUDIO)
if (FMODEX)
include(FMODEX)
set(FMOD OFF)
endif (FMODEX)
if (NOT FMODEX)
include(FMOD)
endif (NOT FMODEX)
include(OPENAL)
include(LLCommon)
include(LLMath)
include(LLMessage)
include(LLVFS)
if (FMOD)
if (FMODEX)
include_directories(${FMODEX_INCLUDE_DIR})
endif(FMODEX)
if(FMOD)
include_directories(${FMOD_INCLUDE_DIR})
endif(FMOD)
endif (FMOD)
include_directories(
${LLAUDIO_INCLUDE_DIRS}
@@ -54,20 +58,6 @@ set(llaudio_HEADER_FILES
llwindgen.h
)
if (FMODSTUDIO)
list(APPEND llaudio_SOURCE_FILES
llaudioengine_fmodstudio.cpp
lllistener_fmodstudio.cpp
llstreamingaudio_fmodstudio.cpp
)
list(APPEND llaudio_HEADER_FILES
llaudioengine_fmodstudio.h
lllistener_fmodstudio.h
llstreamingaudio_fmodstudio.h
)
endif (FMODSTUDIO)
if (FMODEX)
list(APPEND llaudio_SOURCE_FILES
llaudioengine_fmodex.cpp
@@ -81,6 +71,26 @@ if (FMODEX)
llstreamingaudio_fmodex.h
)
endif (FMODEX)
if (FMOD)
list(APPEND llaudio_SOURCE_FILES
llaudioengine_fmod.cpp
lllistener_fmod.cpp
llstreamingaudio_fmod.cpp
)
list(APPEND llaudio_HEADER_FILES
llaudioengine_fmod.h
lllistener_fmod.h
llstreamingaudio_fmod.h
)
if (LINUX)
if (${CXX_VERSION} MATCHES "4.[23]")
set_source_files_properties(llaudioengine_fmod.cpp
COMPILE_FLAGS -Wno-error=write-strings)
endif (${CXX_VERSION} MATCHES "4.[23]")
endif (LINUX)
endif (FMOD)
if (OPENAL)
list(APPEND llaudio_SOURCE_FILES

View File

@@ -174,9 +174,6 @@ void LLAudioEngine::shutdown()
delete mBuffers[i];
mBuffers[i] = NULL;
}
delete mStreamingAudioImpl;
mStreamingAudioImpl = NULL;
}

View File

@@ -0,0 +1,789 @@
/**
* @file audioengine_fmod.cpp
* @brief Implementation of LLAudioEngine class abstracting the audio support as a FMOD 3D 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 "llstreamingaudio.h"
#include "llstreamingaudio_fmod.h"
#include "llaudioengine_fmod.h"
#include "lllistener_fmod.h"
#include "llerror.h"
#include "llmath.h"
#include "llrand.h"
#include "fmod.h"
#include "fmod_errors.h"
#include "lldir.h"
#include "llapr.h"
#include "sound_ids.h"
extern "C" {
void * F_CALLBACKAPI windCallback(void *originalbuffer, void *newbuffer, int length, void* userdata);
}
LLAudioEngine_FMOD::LLAudioEngine_FMOD()
{
mInited = false;
mWindGen = NULL;
mWindDSP = NULL;
}
LLAudioEngine_FMOD::~LLAudioEngine_FMOD()
{
}
bool LLAudioEngine_FMOD::init(const S32 num_channels, void* userdata)
{
LLAudioEngine::init(num_channels, userdata);
// Reserve one extra channel for the http stream.
if (!FSOUND_SetMinHardwareChannels(num_channels + 1))
{
LL_WARNS("AppInit") << "FMOD::init[0](), error: " << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL;
}
LL_DEBUGS("AppInit") << "LLAudioEngine_FMOD::init() initializing FMOD" << LL_ENDL;
F32 version = FSOUND_GetVersion();
if (version < FMOD_VERSION)
{
LL_WARNS("AppInit") << "Error : You are using the wrong FMOD version (" << version
<< ")! You should be using FMOD " << FMOD_VERSION << LL_ENDL;
//return false;
}
U32 fmod_flags = 0x0;
#if LL_WINDOWS
// Windows needs to know which window is frontmost.
// This must be called before FSOUND_Init() per the FMOD docs.
// This could be used to let FMOD handle muting when we lose focus,
// but we don't actually want to do that because we want to distinguish
// between minimized and not-focused states.
if (!FSOUND_SetHWND(userdata))
{
LL_WARNS("AppInit") << "Error setting FMOD window: "
<< FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL;
return false;
}
// Play audio when we don't have focus.
// (For example, IM client on top of us.)
// This means we also try to play audio when minimized,
// so we manually handle muting in that case. JC
fmod_flags |= FSOUND_INIT_GLOBALFOCUS;
fmod_flags |= FSOUND_INIT_DSOUND_HRTF_FULL;
#endif
#if LL_LINUX
// initialize the FMOD engine
// This is a hack to use only FMOD's basic FPU mixer
// when the LL_VALGRIND environmental variable is set,
// otherwise valgrind will fall over on FMOD's MMX detection
if (getenv("LL_VALGRIND")) /*Flawfinder: ignore*/
{
LL_INFOS("AppInit") << "Pacifying valgrind in FMOD init." << LL_ENDL;
FSOUND_SetMixer(FSOUND_MIXER_QUALITY_FPU);
}
// If we don't set an output method, Linux FMOD always
// decides on OSS and fails otherwise. So we'll manually
// try ESD, then OSS, then ALSA.
// Why this order? See SL-13250, but in short, OSS emulated
// on top of ALSA is ironically more reliable than raw ALSA.
// Ack, and ESD has more reliable failure modes - but has worse
// latency - than all of them, so wins for now.
bool audio_ok = false;
if (!audio_ok)
{
if (NULL == getenv("LL_BAD_FMOD_ESD")) /*Flawfinder: ignore*/
{
LL_DEBUGS("AppInit") << "Trying ESD audio output..." << LL_ENDL;
if(FSOUND_SetOutput(FSOUND_OUTPUT_ESD) &&
FSOUND_Init(44100, num_channels, fmod_flags))
{
LL_DEBUGS("AppInit") << "ESD audio output initialized OKAY"
<< LL_ENDL;
audio_ok = true;
} else {
LL_WARNS("AppInit") << "ESD audio output FAILED to initialize: "
<< FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL;
}
} else {
LL_DEBUGS("AppInit") << "ESD audio output SKIPPED" << LL_ENDL;
}
}
if (!audio_ok)
{
if (NULL == getenv("LL_BAD_FMOD_OSS")) /*Flawfinder: ignore*/
{
LL_DEBUGS("AppInit") << "Trying OSS audio output..." << LL_ENDL;
if(FSOUND_SetOutput(FSOUND_OUTPUT_OSS) &&
FSOUND_Init(44100, num_channels, fmod_flags))
{
LL_DEBUGS("AppInit") << "OSS audio output initialized OKAY" << LL_ENDL;
audio_ok = true;
} else {
LL_WARNS("AppInit") << "OSS audio output FAILED to initialize: "
<< FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL;
}
} else {
LL_DEBUGS("AppInit") << "OSS audio output SKIPPED" << LL_ENDL;
}
}
if (!audio_ok)
{
if (NULL == getenv("LL_BAD_FMOD_ALSA")) /*Flawfinder: ignore*/
{
LL_DEBUGS("AppInit") << "Trying ALSA audio output..." << LL_ENDL;
if(FSOUND_SetOutput(FSOUND_OUTPUT_ALSA) &&
FSOUND_Init(44100, num_channels, fmod_flags))
{
LL_DEBUGS("AppInit") << "ALSA audio output initialized OKAY" << LL_ENDL;
audio_ok = true;
} else {
LL_WARNS("AppInit") << "ALSA audio output FAILED to initialize: "
<< FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL;
}
} else {
LL_DEBUGS("AppInit") << "OSS audio output SKIPPED" << LL_ENDL;
}
}
if (!audio_ok)
{
LL_WARNS("AppInit") << "Overall audio init failure." << LL_ENDL;
return false;
}
// On Linux, FMOD causes a SIGPIPE for some netstream error
// conditions (an FMOD bug); ignore SIGPIPE so it doesn't crash us.
// NOW FIXED in FMOD 3.x since 2006-10-01.
//signal(SIGPIPE, SIG_IGN);
// We're interested in logging which output method we
// ended up with, for QA purposes.
switch (FSOUND_GetOutput())
{
case FSOUND_OUTPUT_NOSOUND: LL_DEBUGS("AppInit") << "Audio output: NoSound" << LL_ENDL; break;
case FSOUND_OUTPUT_OSS: LL_DEBUGS("AppInit") << "Audio output: OSS" << LL_ENDL; break;
case FSOUND_OUTPUT_ESD: LL_DEBUGS("AppInit") << "Audio output: ESD" << LL_ENDL; break;
case FSOUND_OUTPUT_ALSA: LL_DEBUGS("AppInit") << "Audio output: ALSA" << LL_ENDL; break;
default: LL_INFOS("AppInit") << "Audio output: Unknown!" << LL_ENDL; break;
};
#else // LL_LINUX
// initialize the FMOD engine
if (!FSOUND_Init(44100, num_channels, fmod_flags))
{
LL_WARNS("AppInit") << "Error initializing FMOD: "
<< FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL;
return false;
}
#endif
// set up our favourite FMOD-native streaming audio implementation if none has already been added
if (!getStreamingAudioImpl()) // no existing implementation added
setStreamingAudioImpl(new LLStreamingAudio_FMOD());
LL_DEBUGS("AppInit") << "LLAudioEngine_FMOD::init() FMOD initialized correctly" << LL_ENDL;
mInited = true;
return true;
}
std::string LLAudioEngine_FMOD::getDriverName(bool verbose)
{
if (verbose)
{
F32 version = FSOUND_GetVersion();
return llformat("FMOD version %f", version);
}
else
{
return "FMOD";
}
}
void LLAudioEngine_FMOD::allocateListener(void)
{
mListenerp = (LLListener *) new LLListener_FMOD();
if (!mListenerp)
{
llwarns << "Listener creation failed" << llendl;
}
}
void LLAudioEngine_FMOD::shutdown()
{
if (mWindDSP)
{
FSOUND_DSP_SetActive(mWindDSP,false);
FSOUND_DSP_Free(mWindDSP);
}
stopInternetStream();
LLAudioEngine::shutdown();
llinfos << "LLAudioEngine_FMOD::shutdown() closing FMOD" << llendl;
FSOUND_Close();
llinfos << "LLAudioEngine_FMOD::shutdown() done closing FMOD" << llendl;
delete mListenerp;
mListenerp = NULL;
}
LLAudioBuffer * LLAudioEngine_FMOD::createBuffer()
{
return new LLAudioBufferFMOD();
}
LLAudioChannel * LLAudioEngine_FMOD::createChannel()
{
return new LLAudioChannelFMOD();
}
bool LLAudioEngine_FMOD::initWind()
{
if (!mWindGen)
{
bool enable;
switch (FSOUND_GetMixer())
{
case FSOUND_MIXER_MMXP5:
case FSOUND_MIXER_MMXP6:
case FSOUND_MIXER_QUALITY_MMXP5:
case FSOUND_MIXER_QUALITY_MMXP6:
enable = (typeid(MIXBUFFERFORMAT) == typeid(S16));
break;
case FSOUND_MIXER_BLENDMODE:
enable = (typeid(MIXBUFFERFORMAT) == typeid(S32));
break;
case FSOUND_MIXER_QUALITY_FPU:
enable = (typeid(MIXBUFFERFORMAT) == typeid(F32));
break;
default:
// FSOUND_GetMixer() does not return a valid mixer type on Darwin
LL_INFOS("AppInit") << "Unknown FMOD mixer type, assuming default" << LL_ENDL;
enable = true;
break;
}
if (enable)
{
mWindGen = new LLWindGen<MIXBUFFERFORMAT>(FSOUND_GetOutputRate());
}
else
{
LL_WARNS("AppInit") << "Incompatible FMOD mixer type, wind noise disabled" << LL_ENDL;
}
}
mNextWindUpdate = 0.0;
if (mWindGen && !mWindDSP)
{
mWindDSP = FSOUND_DSP_Create(&windCallback, FSOUND_DSP_DEFAULTPRIORITY_CLEARUNIT + 20, mWindGen);
}
if (mWindDSP)
{
FSOUND_DSP_SetActive(mWindDSP, true);
return true;
}
return false;
}
void LLAudioEngine_FMOD::cleanupWind()
{
if (mWindDSP)
{
FSOUND_DSP_SetActive(mWindDSP, false);
FSOUND_DSP_Free(mWindDSP);
mWindDSP = NULL;
}
delete mWindGen;
mWindGen = NULL;
}
//-----------------------------------------------------------------------
void LLAudioEngine_FMOD::updateWind(LLVector3 wind_vec, F32 camera_height_above_water)
{
LLVector3 wind_pos;
F64 pitch;
F64 center_freq;
if (!mEnableWind)
{
return;
}
if (mWindUpdateTimer.checkExpirationAndReset(LL_WIND_UPDATE_INTERVAL))
{
// wind comes in as Linden coordinate (+X = forward, +Y = left, +Z = up)
// need to convert this to the conventional orientation DS3D and OpenAL use
// where +X = right, +Y = up, +Z = backwards
wind_vec.setVec(-wind_vec.mV[1], wind_vec.mV[2], -wind_vec.mV[0]);
// cerr << "Wind update" << endl;
pitch = 1.0 + mapWindVecToPitch(wind_vec);
center_freq = 80.0 * pow(pitch,2.5*(mapWindVecToGain(wind_vec)+1.0));
mWindGen->mTargetFreq = (F32)center_freq;
mWindGen->mTargetGain = (F32)mapWindVecToGain(wind_vec) * mMaxWindGain;
mWindGen->mTargetPanGainR = (F32)mapWindVecToPan(wind_vec);
}
}
/*
//-----------------------------------------------------------------------
void LLAudioEngine_FMOD::setSourceMinDistance(U16 source_num, F64 distance)
{
if (!mInited)
{
return;
}
if (mBuffer[source_num])
{
mMinDistance[source_num] = (F32) distance;
if (!FSOUND_Sample_SetMinMaxDistance(mBuffer[source_num],mMinDistance[source_num], mMaxDistance[source_num]))
{
llwarns << "FMOD::setSourceMinDistance(" << source_num << "), error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl;
}
}
}
//-----------------------------------------------------------------------
void LLAudioEngine_FMOD::setSourceMaxDistance(U16 source_num, F64 distance)
{
if (!mInited)
{
return;
}
if (mBuffer[source_num])
{
mMaxDistance[source_num] = (F32) distance;
if (!FSOUND_Sample_SetMinMaxDistance(mBuffer[source_num],mMinDistance[source_num], mMaxDistance[source_num]))
{
llwarns << "FMOD::setSourceMaxDistance(" << source_num << "), error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl;
}
}
}
//-----------------------------------------------------------------------
void LLAudioEngine_FMOD::get3DParams(S32 source_num, S32 *volume, S32 *freq, S32 *inside, S32 *outside, LLVector3 *orient, S32 *out_volume, F32 *min_dist, F32 *max_dist)
{
*volume = 0;
*freq = 0;
*inside = 0;
*outside = 0;
*orient = LLVector3::zero;
*out_volume = 0;
*min_dist = 0.f;
*max_dist = 0.f;
}
*/
//-----------------------------------------------------------------------
void LLAudioEngine_FMOD::setInternalGain(F32 gain)
{
if (!mInited)
{
return;
}
gain = llclamp( gain, 0.0f, 1.0f );
FSOUND_SetSFXMasterVolume( llround( 255.0f * gain ) );
LLStreamingAudioInterface *saimpl = getStreamingAudioImpl();
if ( saimpl )
{
// fmod likes its streaming audio channel gain re-asserted after
// master volume change.
saimpl->setGain(saimpl->getGain());
}
}
//
// LLAudioChannelFMOD implementation
//
LLAudioChannelFMOD::LLAudioChannelFMOD() : LLAudioChannel(), mChannelID(0), mLastSamplePos(0)
{
}
LLAudioChannelFMOD::~LLAudioChannelFMOD()
{
cleanup();
}
bool LLAudioChannelFMOD::updateBuffer()
{
if (LLAudioChannel::updateBuffer())
{
// Base class update returned true, which means that we need to actually
// set up the channel for a different buffer.
LLAudioBufferFMOD *bufferp = (LLAudioBufferFMOD *)mCurrentSourcep->getCurrentBuffer();
// Grab the FMOD sample associated with the buffer
FSOUND_SAMPLE *samplep = bufferp->getSample();
if (!samplep)
{
// This is bad, there should ALWAYS be a sample associated with a legit
// buffer.
llerrs << "No FMOD sample!" << llendl;
return false;
}
// Actually play the sound. Start it off paused so we can do all the necessary
// setup.
mChannelID = FSOUND_PlaySoundEx(FSOUND_FREE, samplep, FSOUND_DSP_GetSFXUnit(), true);
//llinfos << "Setting up channel " << std::hex << mChannelID << std::dec << llendl;
}
// If we have a source for the channel, we need to update its gain.
if (mCurrentSourcep)
{
// SJB: warnings can spam and hurt framerate, disabling
if (!FSOUND_SetVolume(mChannelID, llround(getSecondaryGain() * mCurrentSourcep->getGain() * 255.0f)))
{
// llwarns << "LLAudioChannelFMOD::updateBuffer error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl;
}
if (!FSOUND_SetLoopMode(mChannelID, mCurrentSourcep->isLoop() ? FSOUND_LOOP_NORMAL : FSOUND_LOOP_OFF))
{
// llwarns << "Channel " << mChannelID << "Source ID: " << mCurrentSourcep->getID()
// << " at " << mCurrentSourcep->getPositionGlobal() << llendl;
// llwarns << "LLAudioChannelFMOD::updateBuffer error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl;
}
}
return true;
}
void LLAudioChannelFMOD::update3DPosition()
{
if (!mChannelID)
{
// We're not actually a live channel (i.e., we're not playing back anything)
return;
}
LLAudioBufferFMOD *bufferp = (LLAudioBufferFMOD *)mCurrentBufferp;
if (!bufferp)
{
// We don't have a buffer associated with us (should really have been picked up
// by the above if.
return;
}
if (mCurrentSourcep->isAmbient())
{
// Ambient sound, don't need to do any positional updates.
bufferp->set3DMode(false);
}
else
{
// Localized sound. Update the position and velocity of the sound.
bufferp->set3DMode(true);
LLVector3 float_pos;
float_pos.setVec(mCurrentSourcep->getPositionGlobal());
if (!FSOUND_3D_SetAttributes(mChannelID, float_pos.mV, mCurrentSourcep->getVelocity().mV))
{
LL_DEBUGS("FMOD") << "LLAudioChannelFMOD::update3DPosition error: " << FMOD_ErrorString(FSOUND_GetError()) << LL_ENDL;
}
}
}
void LLAudioChannelFMOD::updateLoop()
{
if (!mChannelID)
{
// May want to clear up the loop/sample counters.
return;
}
//
// Hack: We keep track of whether we looped or not by seeing when the
// sample position looks like it's going backwards. Not reliable; may
// yield false negatives.
//
U32 cur_pos = FSOUND_GetCurrentPosition(mChannelID);
if (cur_pos < (U32)mLastSamplePos)
{
mLoopedThisFrame = true;
}
mLastSamplePos = cur_pos;
}
void LLAudioChannelFMOD::cleanup()
{
LLAudioChannel::cleanup();
if (!mChannelID)
{
//llinfos << "Aborting cleanup with no channelID." << llendl;
return;
}
//llinfos << "Cleaning up channel: " << mChannelID << llendl;
if (!FSOUND_StopSound(mChannelID))
{
LL_DEBUGS("FMOD") << "LLAudioChannelFMOD::cleanup error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl;
}
mChannelID = 0;
mLastSamplePos = 0;
}
void LLAudioChannelFMOD::play()
{
if (!mChannelID)
{
llwarns << "Playing without a channelID, aborting" << llendl;
return;
}
if(!FSOUND_IsPaused(mChannelID))
{
FSOUND_SetPaused(mChannelID, true);
FSOUND_SetCurrentPosition(mChannelID, 0);
}
if (!FSOUND_SetPaused(mChannelID, false))
{
llwarns << "LLAudioChannelFMOD::play error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl;
}
getSource()->setPlayedOnce(true);
}
void LLAudioChannelFMOD::playSynced(LLAudioChannel *channelp)
{
LLAudioChannelFMOD *fmod_channelp = (LLAudioChannelFMOD*)channelp;
if (!(fmod_channelp->mChannelID && mChannelID))
{
// Don't have channels allocated to both the master and the slave
return;
}
U32 position = FSOUND_GetCurrentPosition(fmod_channelp->mChannelID) % mCurrentBufferp->getLength();
// Try to match the position of our sync master
if (!FSOUND_SetCurrentPosition(mChannelID, position))
{
llwarns << "LLAudioChannelFMOD::playSynced unable to set current position" << llendl;
}
// Start us playing
play();
}
bool LLAudioChannelFMOD::isPlaying()
{
if (!mChannelID)
{
return false;
}
return FSOUND_IsPlaying(mChannelID) && (!FSOUND_GetPaused(mChannelID));
}
//
// LLAudioBufferFMOD implementation
//
LLAudioBufferFMOD::LLAudioBufferFMOD() : LLAudioBuffer()
{
mSamplep = NULL;
}
LLAudioBufferFMOD::~LLAudioBufferFMOD()
{
if (mSamplep)
{
// Clean up the associated FMOD sample if it exists.
FSOUND_Sample_Free(mSamplep);
mSamplep = NULL;
}
}
bool LLAudioBufferFMOD::loadWAV(const std::string& filename)
{
// Try to open a wav file from disk. This will eventually go away, as we don't
// really want to block doing this.
if (filename.empty())
{
// invalid filename, abort.
return false;
}
if (!LLAPRFile::isExist(filename, LL_APR_RPB))
{
// File not found, abort.
return false;
}
if (mSamplep)
{
// If there's already something loaded in this buffer, clean it up.
FSOUND_Sample_Free(mSamplep);
mSamplep = NULL;
}
// Load up the wav file into an fmod sample
#if LL_WINDOWS
// MikeS. - Loading the sound file manually and then handing it over to FMOD,
// since FMOD uses posix IO internally,
// which doesn't work with unicode file paths.
LLFILE* sound_file = LLFile::fopen(filename,"rb"); /* Flawfinder: ignore */
if (sound_file)
{
fseek(sound_file,0,SEEK_END);
U32 file_length = ftell(sound_file); //Find the length of the file by seeking to the end and getting the offset
size_t read_count;
fseek(sound_file,0,SEEK_SET); //Seek back to the beginning
char* buffer = new char[file_length];
llassert(buffer);
read_count = fread((void*)buffer,file_length,1,sound_file);//Load it..
if(ferror(sound_file)==0 && (read_count == 1)){//No read error, and we got 1 chunk of our size...
unsigned int mode_flags = FSOUND_LOOP_NORMAL | FSOUND_LOADMEMORY;
//FSOUND_16BITS | FSOUND_MONO | FSOUND_LOADMEMORY | FSOUND_LOOP_NORMAL;
mSamplep = FSOUND_Sample_Load(FSOUND_UNMANAGED, buffer, mode_flags , 0, file_length);
}
delete[] buffer;
fclose(sound_file);
}
#else
mSamplep = FSOUND_Sample_Load(FSOUND_UNMANAGED, filename.c_str(), FSOUND_LOOP_NORMAL, 0, 0);
#endif
if (!mSamplep)
{
// We failed to load the file for some reason.
llwarns << "Could not load data '" << filename << "': "
<< FMOD_ErrorString(FSOUND_GetError()) << llendl;
//
// If we EVER want to load wav files provided by end users, we need
// to rethink this!
//
// file is probably corrupt - remove it.
LLFile::remove(filename);
return false;
}
// Everything went well, return true
return true;
}
U32 LLAudioBufferFMOD::getLength()
{
if (!mSamplep)
{
return 0;
}
return FSOUND_Sample_GetLength(mSamplep);
}
void LLAudioBufferFMOD::set3DMode(bool use3d)
{
U16 current_mode = FSOUND_Sample_GetMode(mSamplep);
if (use3d)
{
if (!FSOUND_Sample_SetMode(mSamplep, (current_mode & (~FSOUND_2D))))
{
llwarns << "LLAudioBufferFMOD::set3DMode error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl;
}
}
else
{
if (!FSOUND_Sample_SetMode(mSamplep, current_mode | FSOUND_2D))
{
llwarns << "LLAudioBufferFMOD::set3DMode error: " << FMOD_ErrorString(FSOUND_GetError()) << llendl;
}
}
}
void * F_CALLBACKAPI windCallback(void *originalbuffer, void *newbuffer, int length, void* userdata)
{
// originalbuffer = fmod's original mixbuffer.
// newbuffer = the buffer passed from the previous DSP unit.
// length = length in samples at this mix time.
// userdata = user parameter passed through in FSOUND_DSP_Create.
LLWindGen<LLAudioEngine_FMOD::MIXBUFFERFORMAT> *windgen =
(LLWindGen<LLAudioEngine_FMOD::MIXBUFFERFORMAT> *)userdata;
newbuffer = windgen->windGenerate((LLAudioEngine_FMOD::MIXBUFFERFORMAT *)newbuffer, length);
return newbuffer;
}

View File

@@ -0,0 +1,124 @@
/**
* @file audioengine_fmod.h
* @brief Definition of LLAudioEngine class abstracting the audio
* support as a FMOD 3D implementation
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_AUDIOENGINE_FMOD_H
#define LL_AUDIOENGINE_FMOD_H
#include "llaudioengine.h"
#include "lllistener_fmod.h"
#include "llwindgen.h"
#include "fmod.h"
class LLAudioStreamManagerFMOD;
class LLAudioEngine_FMOD : public LLAudioEngine
{
public:
LLAudioEngine_FMOD();
virtual ~LLAudioEngine_FMOD();
// 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);
#if LL_DARWIN
typedef S32 MIXBUFFERFORMAT;
#else
typedef S16 MIXBUFFERFORMAT;
#endif
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);
protected:
static signed char F_CALLBACKAPI callbackMetaData(char* name, char* value, void* userdata);
//F32 mMinDistance[MAX_BUFFERS];
//F32 mMaxDistance[MAX_BUFFERS];
bool mInited;
// On Windows, userdata is the HWND of the application window.
void* mUserData;
LLWindGen<MIXBUFFERFORMAT> *mWindGen;
FSOUND_DSPUNIT *mWindDSP;
};
class LLAudioChannelFMOD : public LLAudioChannel
{
public:
LLAudioChannelFMOD();
virtual ~LLAudioChannelFMOD();
protected:
/*virtual*/ void play();
/*virtual*/ void playSynced(LLAudioChannel *channelp);
/*virtual*/ void cleanup();
/*virtual*/ bool isPlaying();
/*virtual*/ bool updateBuffer();
/*virtual*/ void update3DPosition();
/*virtual*/ void updateLoop();
protected:
int mChannelID;
S32 mLastSamplePos;
};
class LLAudioBufferFMOD : public LLAudioBuffer
{
public:
LLAudioBufferFMOD();
virtual ~LLAudioBufferFMOD();
/*virtual*/ bool loadWAV(const std::string& filename);
/*virtual*/ U32 getLength();
friend class LLAudioChannelFMOD;
void set3DMode(bool use3d);
protected:
FSOUND_SAMPLE *getSample() { return mSamplep; }
protected:
FSOUND_SAMPLE *mSamplep;
};
#endif // LL_AUDIOENGINE_FMOD_H

View File

@@ -285,7 +285,7 @@ bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata)
return false;
#endif
U32 version = 0;
U32 version;
FMOD_RESULT result;
LL_DEBUGS("AppInit") << "LLAudioEngine_FMODEX::init() initializing FMOD" << LL_ENDL;
@@ -321,6 +321,10 @@ bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata)
if(mEnableProfiler)
{
fmod_flags |= FMOD_INIT_ENABLE_PROFILE;
mSystem->createChannelGroup("None", &mChannelGroups[AUDIO_TYPE_NONE]);
mSystem->createChannelGroup("SFX", &mChannelGroups[AUDIO_TYPE_SFX]);
mSystem->createChannelGroup("UI", &mChannelGroups[AUDIO_TYPE_UI]);
mSystem->createChannelGroup("Ambient", &mChannelGroups[AUDIO_TYPE_AMBIENT]);
}
#if LL_LINUX
@@ -331,7 +335,7 @@ bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata)
if (NULL == getenv("LL_BAD_FMOD_PULSEAUDIO")) /*Flawfinder: ignore*/
{
LL_DEBUGS("AppInit") << "Trying PulseAudio audio output..." << LL_ENDL;
if((result = mSystem->setOutput(FMOD_OUTPUTTYPE_PULSEAUDIO)) == FMOD_OK &&
if(mSystem->setOutput(FMOD_OUTPUTTYPE_PULSEAUDIO) == FMOD_OK &&
(result = mSystem->init(num_channels + 2, fmod_flags, 0)) == FMOD_OK)
{
LL_DEBUGS("AppInit") << "PulseAudio output initialized OKAY" << LL_ENDL;
@@ -352,7 +356,7 @@ bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata)
if (NULL == getenv("LL_BAD_FMOD_ALSA")) /*Flawfinder: ignore*/
{
LL_DEBUGS("AppInit") << "Trying ALSA audio output..." << LL_ENDL;
if((result = mSystem->setOutput(FMOD_OUTPUTTYPE_ALSA)) == FMOD_OK &&
if(mSystem->setOutput(FMOD_OUTPUTTYPE_ALSA) == FMOD_OK &&
(result = mSystem->init(num_channels + 2, fmod_flags, 0)) == FMOD_OK)
{
LL_DEBUGS("AppInit") << "ALSA audio output initialized OKAY" << LL_ENDL;
@@ -373,7 +377,7 @@ bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata)
if (NULL == getenv("LL_BAD_FMOD_OSS")) /*Flawfinder: ignore*/
{
LL_DEBUGS("AppInit") << "Trying OSS audio output..." << LL_ENDL;
if((result = mSystem->setOutput(FMOD_OUTPUTTYPE_OSS)) == FMOD_OK &&
if(mSystem->setOutput(FMOD_OUTPUTTYPE_OSS) == FMOD_OK &&
(result = mSystem->init(num_channels + 2, fmod_flags, 0)) == FMOD_OK)
{
LL_DEBUGS("AppInit") << "OSS audio output initialized OKAY" << LL_ENDL;
@@ -398,22 +402,20 @@ bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata)
// We're interested in logging which output method we
// ended up with, for QA purposes.
FMOD_OUTPUTTYPE output_type;
if(!Check_FMOD_Error(mSystem->getOutput(&output_type), "FMOD::System::getOutput"))
mSystem->getOutput(&output_type);
switch (output_type)
{
switch (output_type)
{
case FMOD_OUTPUTTYPE_NOSOUND:
LL_INFOS("AppInit") << "Audio output: NoSound" << LL_ENDL; break;
case FMOD_OUTPUTTYPE_PULSEAUDIO:
LL_INFOS("AppInit") << "Audio output: PulseAudio" << LL_ENDL; break;
case FMOD_OUTPUTTYPE_ALSA:
LL_INFOS("AppInit") << "Audio output: ALSA" << LL_ENDL; break;
case FMOD_OUTPUTTYPE_OSS:
LL_INFOS("AppInit") << "Audio output: OSS" << LL_ENDL; break;
default:
LL_INFOS("AppInit") << "Audio output: Unknown!" << LL_ENDL; break;
};
}
case FMOD_OUTPUTTYPE_NOSOUND:
LL_INFOS("AppInit") << "Audio output: NoSound" << LL_ENDL; break;
case FMOD_OUTPUTTYPE_PULSEAUDIO:
LL_INFOS("AppInit") << "Audio output: PulseAudio" << LL_ENDL; break;
case FMOD_OUTPUTTYPE_ALSA:
LL_INFOS("AppInit") << "Audio output: ALSA" << LL_ENDL; break;
case FMOD_OUTPUTTYPE_OSS:
LL_INFOS("AppInit") << "Audio output: OSS" << LL_ENDL; break;
default:
LL_INFOS("AppInit") << "Audio output: Unknown!" << LL_ENDL; break;
};
#else // LL_LINUX
// initialize the FMOD engine
@@ -435,14 +437,6 @@ bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata)
return false;
#endif
if (mEnableProfiler)
{
Check_FMOD_Error(mSystem->createChannelGroup("None", &mChannelGroups[AUDIO_TYPE_NONE]), "FMOD::System::createChannelGroup");
Check_FMOD_Error(mSystem->createChannelGroup("SFX", &mChannelGroups[AUDIO_TYPE_SFX]), "FMOD::System::createChannelGroup");
Check_FMOD_Error(mSystem->createChannelGroup("UI", &mChannelGroups[AUDIO_TYPE_UI]), "FMOD::System::createChannelGroup");
Check_FMOD_Error(mSystem->createChannelGroup("Ambient", &mChannelGroups[AUDIO_TYPE_AMBIENT]), "FMOD::System::createChannelGroup");
}
// set up our favourite FMOD-native streaming audio implementation if none has already been added
if (!getStreamingAudioImpl()) // no existing implementation added
setStreamingAudioImpl(new LLStreamingAudio_FMODEX(mSystem));
@@ -453,40 +447,35 @@ bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata)
unsigned int r_bufferlength;
char r_name[256];
FMOD_SPEAKERMODE speaker_mode;
if (!Check_FMOD_Error(mSystem->getDSPBufferSize(&r_bufferlength, &r_numbuffers), "FMOD::System::getDSPBufferSize") &&
!Check_FMOD_Error(mSystem->getSoftwareFormat(&r_samplerate, NULL, &r_channels, NULL, NULL, &r_bits), "FMOD::System::getSoftwareFormat") &&
!Check_FMOD_Error(mSystem->getDriverInfo(0, r_name, 255, 0), "FMOD::System::getDriverInfo") &&
!Check_FMOD_Error(mSystem->getSpeakerMode(&speaker_mode), "FMOD::System::getSpeakerMode"))
mSystem->getDSPBufferSize(&r_bufferlength, &r_numbuffers);
mSystem->getSoftwareFormat(&r_samplerate, NULL, &r_channels, NULL, NULL, &r_bits);
mSystem->getDriverInfo(0, r_name, 255, 0);
mSystem->getSpeakerMode(&speaker_mode);
std::string speaker_mode_str = "unknown";
switch(speaker_mode)
{
std::string speaker_mode_str = "unknown";
switch(speaker_mode)
{
#define SPEAKER_MODE_CASE(MODE) case MODE: speaker_mode_str = #MODE; break;
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_RAW)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_MONO)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_STEREO)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_QUAD)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_SURROUND)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_5POINT1)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_7POINT1)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_SRS5_1_MATRIX)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_MYEARS)
default:;
#undef SPEAKER_MODE_CASE
}
r_name[255] = '\0';
int latency = 1000.0 * r_bufferlength * r_numbuffers /r_samplerate;
LL_INFOS("AppInit") << "FMOD device: "<< r_name << "\n"
<< "Output mode: "<< speaker_mode_str << "\n"
<< "FMOD Ex parameters: " << r_samplerate << " Hz * " << r_channels << " * " <<r_bits <<" bit\n"
<< "\tbuffer " << r_bufferlength << " * " << r_numbuffers << " (" << latency <<"ms)" << LL_ENDL;
}
else
{
LL_WARNS("AppInit") << "Failed to retrieve FMOD device info!" << LL_ENDL;
#define SPEAKER_MODE_CASE(MODE) case MODE: speaker_mode_str = #MODE; break;
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_RAW)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_MONO)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_STEREO)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_QUAD)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_SURROUND)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_5POINT1)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_7POINT1)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_SRS5_1_MATRIX)
SPEAKER_MODE_CASE(FMOD_SPEAKERMODE_MYEARS)
default:;
#undef SPEAKER_MODE_CASE
}
r_name[255] = '\0';
int latency = 1000.0 * r_bufferlength * r_numbuffers /r_samplerate;
LL_INFOS("AppInit") << "FMOD device: "<< r_name << "\n"
<< "Output mode: "<< speaker_mode_str << "\n"
<< "FMOD Ex parameters: " << r_samplerate << " Hz * " << r_channels << " * " <<r_bits <<" bit\n"
<< "\tbuffer " << r_bufferlength << " * " << r_numbuffers << " (" << latency <<"ms)" << LL_ENDL;
mInited = true;
return true;
@@ -520,6 +509,8 @@ void LLAudioEngine_FMODEX::allocateListener(void)
void LLAudioEngine_FMODEX::shutdown()
{
stopInternetStream();
LL_INFOS("AudioImpl") << "About to LLAudioEngine::shutdown()" << LL_ENDL;
LLAudioEngine::shutdown();
@@ -527,9 +518,9 @@ void LLAudioEngine_FMODEX::shutdown()
if ( mSystem ) // speculative fix for MAINT-2657
{
LL_INFOS("AudioImpl") << "LLAudioEngine_FMODEX::shutdown() Requesting FMOD Ex system closure" << LL_ENDL;
Check_FMOD_Error(mSystem->close(), "FMOD::System::close");
mSystem->close();
LL_INFOS("AudioImpl") << "LLAudioEngine_FMODEX::shutdown() Requesting FMOD Ex system release" << LL_ENDL;
Check_FMOD_Error(mSystem->release(), "FMOD::System::release");
mSystem->release();
}
LL_INFOS("AudioImpl") << "LLAudioEngine_FMODEX::shutdown() done closing FMOD Ex" << LL_ENDL;
@@ -553,27 +544,30 @@ bool LLAudioEngine_FMODEX::initWind()
{
mNextWindUpdate = 0.0;
cleanupWind();
FMOD_DSP_DESCRIPTION dspdesc;
memset(&dspdesc, 0, sizeof(FMOD_DSP_DESCRIPTION)); //Set everything to zero
strncpy(dspdesc.name,"Wind Unit", sizeof(dspdesc.name)); //Set name to "Wind Unit"
dspdesc.channels=2;
dspdesc.read = &windCallback; //Assign callback.
if(Check_FMOD_Error(mSystem->createDSP(&dspdesc, &mWindDSP), "FMOD::createDSP") || !mWindDSP)
return false;
float frequency = 44100;
if (!Check_FMOD_Error(mWindDSP->getDefaults(&frequency,0,0,0), "FMOD::DSP::getDefaults"))
if (!mWindDSP)
{
FMOD_DSP_DESCRIPTION dspdesc;
memset(&dspdesc, 0, sizeof(FMOD_DSP_DESCRIPTION)); //Set everything to zero
strncpy(dspdesc.name,"Wind Unit", sizeof(dspdesc.name)); //Set name to "Wind Unit"
dspdesc.channels=2;
dspdesc.read = &windCallback; //Assign callback.
if(Check_FMOD_Error(mSystem->createDSP(&dspdesc, &mWindDSP), "FMOD::createDSP"))
return false;
if(mWindGen)
delete mWindGen;
float frequency = 44100;
mWindDSP->getDefaults(&frequency,0,0,0);
mWindGen = new LLWindGen<MIXBUFFERFORMAT>((U32)frequency);
if (!Check_FMOD_Error(mWindDSP->setUserData((void*)mWindGen), "FMOD::DSP::setUserData") &&
!Check_FMOD_Error(mSystem->playDSP(FMOD_CHANNEL_FREE, mWindDSP, false, 0), "FMOD::System::playDSP"))
return true; //Success
mWindDSP->setUserData((void*)mWindGen);
}
cleanupWind();
if (mWindDSP)
{
mSystem->playDSP(FMOD_CHANNEL_FREE, mWindDSP, false, 0);
return true;
}
return false;
}
@@ -582,8 +576,8 @@ void LLAudioEngine_FMODEX::cleanupWind()
{
if (mWindDSP)
{
Check_FMOD_Error(mWindDSP->remove(), "FMOD::DSP::remove");
Check_FMOD_Error(mWindDSP->release(), "FMOD::DSP::release");
mWindDSP->remove();
mWindDSP->release();
mWindDSP = NULL;
}
@@ -635,8 +629,8 @@ void LLAudioEngine_FMODEX::setInternalGain(F32 gain)
gain = llclamp( gain, 0.0f, 1.0f );
FMOD::ChannelGroup *master_group;
if(Check_FMOD_Error(mSystem->getMasterChannelGroup(&master_group), "FMOD::System::getMasterChannelGroup"))
return;
mSystem->getMasterChannelGroup(&master_group);
master_group->setVolume(gain);
LLStreamingAudioInterface *saimpl = getStreamingAudioImpl();
@@ -1019,9 +1013,10 @@ FMOD_RESULT F_CALLBACK windCallback(FMOD_DSP_STATE *dsp_state, float *originalbu
FMOD::DSP *thisdsp = (FMOD::DSP *)dsp_state->instance;
thisdsp->getUserData((void **)&windgen);
S32 channels, configwidth, configheight;
thisdsp->getInfo(0, 0, &channels, &configwidth, &configheight);
if (windgen)
windgen->windGenerate((LLAudioEngine_FMODEX::MIXBUFFERFORMAT *)newbuffer, length);
windgen->windGenerate((LLAudioEngine_FMODEX::MIXBUFFERFORMAT *)newbuffer, length);
return FMOD_OK;
}

View File

@@ -35,7 +35,7 @@
#define LL_AUDIOENGINE_FMODEX_H
#include "llaudioengine.h"
#include "lllistener_fmodex.h"
#include "lllistener_fmod.h"
#include "llwindgen.h"
//Stubs

File diff suppressed because it is too large Load Diff

View File

@@ -1,139 +0,0 @@
/**
* @file audioengine_FMODSTUDIO.h
* @brief Definition of LLAudioEngine class abstracting the audio
* support as a FMOD Studio 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_FMODSTUDIO_H
#define LL_AUDIOENGINE_FMODSTUDIO_H
#include "llaudioengine.h"
#include "lllistener_fmodstudio.h"
#include "llwindgen.h"
//Stubs
class LLAudioStreamManagerFMODSTUDIO;
namespace FMOD
{
class System;
class Channel;
class ChannelGroup;
class Sound;
class DSP;
}
//Interfaces
class LLAudioEngine_FMODSTUDIO : public LLAudioEngine
{
public:
LLAudioEngine_FMODSTUDIO(bool enable_profiler, bool verbose_debugging);
virtual ~LLAudioEngine_FMODSTUDIO();
// 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 LLAudioChannelFMODSTUDIO : public LLAudioChannel
{
public:
LLAudioChannelFMODSTUDIO(FMOD::System *audioengine);
virtual ~LLAudioChannelFMODSTUDIO();
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 LLAudioBufferFMODSTUDIO : public LLAudioBuffer
{
public:
LLAudioBufferFMODSTUDIO(FMOD::System *audioengine);
virtual ~LLAudioBufferFMODSTUDIO();
/*virtual*/ bool loadWAV(const std::string& filename);
/*virtual*/ U32 getLength();
friend class LLAudioChannelFMODSTUDIO;
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_FMODSTUDIO_H

View File

@@ -0,0 +1,125 @@
/**
* @file listener_fmod.cpp
* @brief implementation of LISTENER class abstracting the audio
* support as a FMOD 3D implementation (windows only)
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "llaudioengine.h"
#include "lllistener_fmod.h"
#include "fmod.h"
//-----------------------------------------------------------------------
// constructor
//-----------------------------------------------------------------------
LLListener_FMOD::LLListener_FMOD()
{
init();
}
//-----------------------------------------------------------------------
LLListener_FMOD::~LLListener_FMOD()
{
}
//-----------------------------------------------------------------------
void LLListener_FMOD::init(void)
{
// do inherited
LLListener::init();
mDopplerFactor = 1.0f;
mRolloffFactor = 1.0f;
}
//-----------------------------------------------------------------------
void LLListener_FMOD::translate(LLVector3 offset)
{
LLListener::translate(offset);
FSOUND_3D_Listener_SetAttributes(mPosition.mV, NULL, mListenAt.mV[0],mListenAt.mV[1],mListenAt.mV[2], mListenUp.mV[0],mListenUp.mV[1],mListenUp.mV[2]);
}
//-----------------------------------------------------------------------
void LLListener_FMOD::setPosition(LLVector3 pos)
{
LLListener::setPosition(pos);
FSOUND_3D_Listener_SetAttributes(pos.mV, NULL, mListenAt.mV[0],mListenAt.mV[1],mListenAt.mV[2], mListenUp.mV[0],mListenUp.mV[1],mListenUp.mV[2]);
}
//-----------------------------------------------------------------------
void LLListener_FMOD::setVelocity(LLVector3 vel)
{
LLListener::setVelocity(vel);
FSOUND_3D_Listener_SetAttributes(NULL, vel.mV, mListenAt.mV[0],mListenAt.mV[1],mListenAt.mV[2], mListenUp.mV[0],mListenUp.mV[1],mListenUp.mV[2]);
}
//-----------------------------------------------------------------------
void LLListener_FMOD::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;
FSOUND_3D_Listener_SetAttributes(NULL, NULL, at.mV[0],at.mV[1],at.mV[2], up.mV[0],up.mV[1],up.mV[2]);
}
//-----------------------------------------------------------------------
void LLListener_FMOD::commitDeferredChanges()
{
FSOUND_Update();
}
void LLListener_FMOD::setRolloffFactor(F32 factor)
{
mRolloffFactor = factor;
FSOUND_3D_SetRolloffFactor(factor);
}
F32 LLListener_FMOD::getRolloffFactor()
{
return mRolloffFactor;
}
void LLListener_FMOD::setDopplerFactor(F32 factor)
{
mDopplerFactor = factor;
FSOUND_3D_SetDopplerFactor(factor);
}
F32 LLListener_FMOD::getDopplerFactor()
{
return mDopplerFactor;
}

View File

@@ -0,0 +1,58 @@
/**
* @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=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_LISTENER_FMOD_H
#define LL_LISTENER_FMOD_H
#include "lllistener.h"
class LLListener_FMOD : public LLListener
{
public:
LLListener_FMOD();
virtual ~LLListener_FMOD();
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:
F32 mDopplerFactor;
F32 mRolloffFactor;
};
#endif

View File

@@ -1,135 +0,0 @@
/**
* @file listener_fmodstudio.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_fmodstudio.h"
#include "fmod.hpp"
//-----------------------------------------------------------------------
// constructor
//-----------------------------------------------------------------------
LLListener_FMODSTUDIO::LLListener_FMODSTUDIO(FMOD::System *system)
{
mSystem = system;
init();
}
//-----------------------------------------------------------------------
LLListener_FMODSTUDIO::~LLListener_FMODSTUDIO()
{
}
//-----------------------------------------------------------------------
void LLListener_FMODSTUDIO::init(void)
{
// do inherited
LLListener::init();
mDopplerFactor = 1.0f;
mRolloffFactor = 1.0f;
}
//-----------------------------------------------------------------------
void LLListener_FMODSTUDIO::translate(LLVector3 offset)
{
LLListener::translate(offset);
mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)mPosition.mV, NULL, (FMOD_VECTOR*)mListenAt.mV, (FMOD_VECTOR*)mListenUp.mV);
}
//-----------------------------------------------------------------------
void LLListener_FMODSTUDIO::setPosition(LLVector3 pos)
{
LLListener::setPosition(pos);
mSystem->set3DListenerAttributes(0, (FMOD_VECTOR*)mPosition.mV, NULL, (FMOD_VECTOR*)mListenAt.mV, (FMOD_VECTOR*)mListenUp.mV);
}
//-----------------------------------------------------------------------
void LLListener_FMODSTUDIO::setVelocity(LLVector3 vel)
{
LLListener::setVelocity(vel);
mSystem->set3DListenerAttributes(0, NULL, (FMOD_VECTOR*)mVelocity.mV, (FMOD_VECTOR*)mListenAt.mV, (FMOD_VECTOR*)mListenUp.mV);
}
//-----------------------------------------------------------------------
void LLListener_FMODSTUDIO::orient(LLVector3 up, LLVector3 at)
{
LLListener::orient(up, at);
mSystem->set3DListenerAttributes(0, NULL, NULL, (FMOD_VECTOR*)at.mV, (FMOD_VECTOR*)up.mV);
}
//-----------------------------------------------------------------------
void LLListener_FMODSTUDIO::commitDeferredChanges()
{
mSystem->update();
}
void LLListener_FMODSTUDIO::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 fmodstudio, 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_FMODSTUDIO::getRolloffFactor()
{
return mRolloffFactor;
}
void LLListener_FMODSTUDIO::setDopplerFactor(F32 factor)
{
mDopplerFactor = factor;
mSystem->set3DSettings(mDopplerFactor, 1.f, mRolloffFactor);
}
F32 LLListener_FMODSTUDIO::getDopplerFactor()
{
return mDopplerFactor;
}

View File

@@ -1,71 +0,0 @@
/**
* @file listener_fmodstudio.h
* @brief Description of LISTENER class abstracting the audio support
* as an FMOD Studio 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_FMODSTUDIO_H
#define LL_LISTENER_FMODSTUDIO_H
#include "lllistener.h"
//Stubs
namespace FMOD
{
class System;
}
//Interfaces
class LLListener_FMODSTUDIO : public LLListener
{
public:
LLListener_FMODSTUDIO(FMOD::System *system);
virtual ~LLListener_FMODSTUDIO();
virtual void init();
virtual void translate(LLVector3 offset);
virtual void setPosition(LLVector3 pos);
virtual void setVelocity(LLVector3 vel);
virtual void orient(LLVector3 up, LLVector3 at);
virtual void commitDeferredChanges();
virtual void setDopplerFactor(F32 factor);
virtual F32 getDopplerFactor();
virtual void setRolloffFactor(F32 factor);
virtual F32 getRolloffFactor();
protected:
FMOD::System *mSystem;
F32 mDopplerFactor;
F32 mRolloffFactor;
};
#endif

View File

@@ -0,0 +1,385 @@
/**
* @file streamingaudio_fmod.cpp
* @brief LLStreamingAudio_FMOD implementation
*
* $LicenseInfo:firstyear=2009&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.h"
#include "fmod_errors.h"
#include "llstreamingaudio_fmod.h"
class LLAudioStreamManagerFMOD
{
public:
LLAudioStreamManagerFMOD(const std::string& url);
int startStream();
bool stopStream(); // Returns true if the stream was successfully stopped.
bool ready();
const std::string& getURL() { return mInternetStreamURL; }
int getOpenState();
FSOUND_STREAM* getStream() { return mInternetStream; }
protected:
FSOUND_STREAM* mInternetStream;
bool mReady;
std::string mInternetStreamURL;
};
//---------------------------------------------------------------------------
// Internet Streaming
//---------------------------------------------------------------------------
LLStreamingAudio_FMOD::LLStreamingAudio_FMOD() :
mCurrentInternetStreamp(NULL),
mFMODInternetStreamChannel(-1),
mGain(1.0f),
mMetaData(NULL)
{
// Number of milliseconds of audio to buffer for the audio card.
// Must be larger than the usual Second Life frame stutter time.
FSOUND_Stream_SetBufferSize(200);
// 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_FMOD::~LLStreamingAudio_FMOD()
{
// nothing interesting/safe to do.
}
signed char F_CALLBACKAPI MetaDataCallback(char *name, char *value, void *userdata)
{
std::string szName(name);
if(szName == "TITLE" || szName=="TIT2" || szName=="Title")
(*(LLSD*)userdata)["TITLE"] = value;
if(szName == "ARTIST" || szName=="TPE1" || szName =="WM/AlbumTitle")
(*(LLSD*)userdata)["ARTIST"] = value;
else
(*(LLSD*)userdata)[std::string(name)] = value;
return true;
}
void LLStreamingAudio_FMOD::start(const std::string& url)
{
//if (!mInited)
//{
// llwarns << "startInternetStream before audio initialized" << llendl;
// return;
//}
// "stop" stream but don't clear url, etc. in case url == mInternetStreamURL
stop();
if (!url.empty())
{
llinfos << "Starting internet stream: " << url << llendl;
mCurrentInternetStreamp = new LLAudioStreamManagerFMOD(url);
mURL = url;
if(mCurrentInternetStreamp->getStream())
{
mMetaData = new LLSD;
}
}
else
{
llinfos << "Set internet stream to null" << llendl;
mURL.clear();
}
}
void LLStreamingAudio_FMOD::update()
{
// Kill dead internet streams, if possible
std::list<LLAudioStreamManagerFMOD *>::iterator iter;
for (iter = mDeadStreams.begin(); iter != mDeadStreams.end();)
{
LLAudioStreamManagerFMOD *streamp = *iter;
if (streamp->stopStream())
{
llinfos << "Closed dead stream" << llendl;
delete streamp;
mDeadStreams.erase(iter++);
}
else
{
iter++;
}
}
// Don't do anything if there are no streams playing
if (!mCurrentInternetStreamp)
{
return;
}
int open_state = mCurrentInternetStreamp->getOpenState();
if (!open_state)
{
// Stream is live
// start the stream if it's ready
if (mFMODInternetStreamChannel < 0)
{
mFMODInternetStreamChannel = mCurrentInternetStreamp->startStream();
if (mFMODInternetStreamChannel != -1)
{
// Reset volume to previously set volume
setGain(getGain());
FSOUND_SetPaused(mFMODInternetStreamChannel, false);
if(mCurrentInternetStreamp->getStream() && mMetaData)
{
FSOUND_Stream_Net_SetMetadataCallback(mCurrentInternetStreamp->getStream(),&MetaDataCallback, mMetaData);
}
}
}
}
switch(open_state)
{
default:
case 0:
// success
break;
case -1:
// stream handle is invalid
llwarns << "InternetStream - invalid handle" << llendl;
stop();
return;
case -2:
// opening
break;
case -3:
// failed to open, file not found, perhaps
llwarns << "InternetStream - failed to open" << llendl;
stop();
return;
case -4:
// connecting
break;
case -5:
// buffering
break;
}
}
void LLStreamingAudio_FMOD::stop()
{
if(mMetaData)
{
if(mCurrentInternetStreamp && mCurrentInternetStreamp->getStream())
FSOUND_Stream_Net_SetMetadataCallback(mCurrentInternetStreamp->getStream(),NULL,NULL);
delete mMetaData;
mMetaData = NULL;
}
if (mFMODInternetStreamChannel != -1)
{
FSOUND_SetPaused(mFMODInternetStreamChannel, true);
FSOUND_SetPriority(mFMODInternetStreamChannel, 0);
mFMODInternetStreamChannel = -1;
}
if (mCurrentInternetStreamp)
{
llinfos << "Stopping internet stream: " << mCurrentInternetStreamp->getURL() << llendl;
if (mCurrentInternetStreamp->stopStream())
{
delete mCurrentInternetStreamp;
}
else
{
llwarns << "Pushing stream to dead list: " << mCurrentInternetStreamp->getURL() << llendl;
mDeadStreams.push_back(mCurrentInternetStreamp);
}
mCurrentInternetStreamp = NULL;
//mURL.clear();
}
}
void LLStreamingAudio_FMOD::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_FMOD::isPlaying()
{
if (mCurrentInternetStreamp)
{
return 1; // Active and playing
}
else if (!mURL.empty())
{
return 2; // "Paused"
}
else
{
return 0;
}
}
F32 LLStreamingAudio_FMOD::getGain()
{
return mGain;
}
std::string LLStreamingAudio_FMOD::getURL()
{
return mURL;
}
void LLStreamingAudio_FMOD::setGain(F32 vol)
{
mGain = vol;
if (mFMODInternetStreamChannel != -1)
{
vol = llclamp(vol * vol, 0.f, 1.f);
int vol_int = llround(vol * 255.f);
FSOUND_SetVolumeAbsolute(mFMODInternetStreamChannel, vol_int);
}
}
///////////////////////////////////////////////////////
// manager of possibly-multiple internet audio streams
LLAudioStreamManagerFMOD::LLAudioStreamManagerFMOD(const std::string& url) :
mInternetStream(NULL),
mReady(false)
{
mInternetStreamURL = url;
mInternetStream = FSOUND_Stream_Open(url.c_str(), FSOUND_NORMAL | FSOUND_NONBLOCKING, 0, 0);
if (!mInternetStream)
{
llwarns << "Couldn't open fmod stream, error "
<< FMOD_ErrorString(FSOUND_GetError())
<< llendl;
mReady = false;
return;
}
mReady = true;
}
int LLAudioStreamManagerFMOD::startStream()
{
// We need a live and opened stream before we try and play it.
if (!mInternetStream || getOpenState())
{
llwarns << "No internet stream to start playing!" << llendl;
return -1;
}
// Make sure the stream is set to 2D mode.
FSOUND_Stream_SetMode(mInternetStream, FSOUND_2D);
return FSOUND_Stream_PlayEx(FSOUND_FREE, mInternetStream, NULL, true);
}
bool LLAudioStreamManagerFMOD::stopStream()
{
if (mInternetStream)
{
int read_percent = 0;
int status = 0;
int bitrate = 0;
unsigned int flags = 0x0;
FSOUND_Stream_Net_GetStatus(mInternetStream, &status, &read_percent, &bitrate, &flags);
bool close = true;
switch (status)
{
case FSOUND_STREAM_NET_CONNECTING:
close = false;
break;
case FSOUND_STREAM_NET_NOTCONNECTED:
case FSOUND_STREAM_NET_BUFFERING:
case FSOUND_STREAM_NET_READY:
case FSOUND_STREAM_NET_ERROR:
default:
close = true;
}
if (close)
{
FSOUND_Stream_Close(mInternetStream);
mInternetStream = NULL;
return true;
}
else
{
return false;
}
}
else
{
return true;
}
}
int LLAudioStreamManagerFMOD::getOpenState()
{
int open_state = FSOUND_Stream_GetOpenState(mInternetStream);
return open_state;
}

View File

@@ -0,0 +1,68 @@
/**
* @file streamingaudio_fmod.h
* @author Tofu Linden
* @brief Definition of LLStreamingAudio_FMOD implementation
*
* $LicenseInfo:firstyear=2009&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_STREAMINGAUDIO_FMOD_H
#define LL_STREAMINGAUDIO_FMOD_H
#include "stdtypes.h" // from llcommon
#include "llstreamingaudio.h"
class LLAudioStreamManagerFMOD;
class LLStreamingAudio_FMOD : public LLStreamingAudioInterface
{
public:
LLStreamingAudio_FMOD();
/*virtual*/ ~LLStreamingAudio_FMOD();
/*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 false;}
/*virtual*/ bool getWaveData(float* arr, S32 count, S32 stride = 1){return false;}
private:
LLAudioStreamManagerFMOD *mCurrentInternetStreamp;
int mFMODInternetStreamChannel;
std::list<LLAudioStreamManagerFMOD *> mDeadStreams;
std::string mURL;
F32 mGain;
LLSD *mMetaData;
};
#endif // LL_STREAMINGAUDIO_FMOD_H

View File

@@ -39,13 +39,6 @@
#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
{
@@ -57,7 +50,7 @@ public:
const std::string& getURL() { return mInternetStreamURL; }
FMOD_RESULT getOpenState(FMOD_OPENSTATE& openstate, unsigned int* percentbuffered=NULL, bool* starving=NULL, bool* diskbusy=NULL);
FMOD_OPENSTATE getOpenState(unsigned int* percentbuffered=NULL, bool* starving=NULL, bool* diskbusy=NULL);
protected:
FMOD::System* mSystem;
FMOD::Channel* mStreamChannel;
@@ -79,14 +72,11 @@ LLStreamingAudio_FMODEX::LLStreamingAudio_FMODEX(FMOD::System *system) :
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");
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
@@ -100,13 +90,7 @@ LLStreamingAudio_FMODEX::LLStreamingAudio_FMODEX(FMOD::System *system) :
LLStreamingAudio_FMODEX::~LLStreamingAudio_FMODEX()
{
stop();
for (U32 i = 0; i < 100; ++i)
{
if (releaseDeadStreams())
break;
ms_sleep(10);
}
// nothing interesting/safe to do.
}
@@ -143,49 +127,27 @@ void LLStreamingAudio_FMODEX::start(const std::string& url)
}
}
enum utf_endian_type_t
{
UTF16LE,
UTF16BE,
UTF16
};
std::string utf16input_to_utf8(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())
// Kill dead internet streams, if possible
std::list<LLAudioStreamManagerFMODEX *>::iterator iter;
for (iter = mDeadStreams.begin(); iter != mDeadStreams.end();)
{
LLAudioStreamManagerFMODEX *streamp = *iter;
if (streamp->stopStream())
{
llinfos << "Closed dead stream" << llendl;
delete streamp;
mDeadStreams.erase(iter++);
}
else
{
iter++;
}
}
if(!mDeadStreams.empty())
{
llassert_always(mCurrentInternetStreamp == NULL);
return;
@@ -210,15 +172,9 @@ void LLStreamingAudio_FMODEX::update()
unsigned int progress;
bool starving;
bool diskbusy;
FMOD_OPENSTATE open_state;
FMOD_RESULT res = mCurrentInternetStreamp->getOpenState(open_state, &progress, &starving, &diskbusy);
FMOD_OPENSTATE open_state = mCurrentInternetStreamp->getOpenState(&progress, &starving, &diskbusy);
if (res != FMOD_OK || open_state == FMOD_OPENSTATE_ERROR)
{
stop();
return;
}
else if (open_state == FMOD_OPENSTATE_READY)
if (open_state == FMOD_OPENSTATE_READY)
{
// Stream is live
@@ -228,9 +184,14 @@ void LLStreamingAudio_FMODEX::update()
{
// Reset volume to previously set volume
setGain(getGain());
Check_FMOD_Error(mFMODInternetStreamChannelp->setPaused(false), "FMOD::Channel::setPaused");
mFMODInternetStreamChannelp->setPaused(false);
}
}
else if(open_state == FMOD_OPENSTATE_ERROR)
{
stop();
return;
}
if(mFMODInternetStreamChannelp)
{
@@ -255,27 +216,23 @@ void LLStreamingAudio_FMODEX::update()
switch(tag.type) //Crappy tag translate table.
{
case(FMOD_TAGTYPE_ID3V2):
if (!LLStringUtil::compareInsensitive(name, "TIT2")) name = "TITLE";
if(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";
if(name == "Title") name = "TITLE";
else if(name == "WM/AlbumArtist") name = "ARTIST";
break;
case(FMOD_TAGTYPE_FMOD):
if (!LLStringUtil::compareInsensitive(name, "Sample Rate Change"))
if (!strcmp(tag.name, "Sample Rate Change"))
{
llinfos << "Stream forced changing sample rate to " << *((float *)tag.data) << llendl;
Check_FMOD_Error(mFMODInternetStreamChannelp->setFrequency(*((float *)tag.data)), "FMOD::Channel::setFrequency");
mFMODInternetStreamChannelp->setFrequency(*((float *)tag.data));
}
continue;
default:
if (!LLStringUtil::compareInsensitive(name, "TITLE") ||
!LLStringUtil::compareInsensitive(name, "ARTIST"))
LLStringUtil::toUpper(name);
break;
}
switch(tag.datatype)
{
case(FMOD_TAGDATATYPE_INT):
@@ -289,40 +246,25 @@ void LLStreamingAudio_FMODEX::update()
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;
llinfos << tag.name << "(RAW): " << out << llendl;
}
break;
case(FMOD_TAGDATATYPE_STRING_UTF8) :
{
U8 offs = 0;
if (tag.datalen > 3 && ((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;
llinfos << tag.name << "(UTF8): " << out << llendl;
llinfos << tag.name << ": " << out << llendl;
}
break;
case(FMOD_TAGDATATYPE_STRING_UTF16):
{
std::string out = utf16input_to_utf8((char*)tag.data, tag.datalen, UTF16);
if (out.length() && out[out.size() - 1] == 0)
out.erase(out.size() - 1);
(*mMetaData)[name] = out;
llinfos << tag.name << "(UTF16): " << out << llendl;
std::string out((char*)tag.data,tag.datalen);
(*mMetaData)[std::string(tag.name)]=out;
llinfos << tag.name << ": " << out << llendl;
}
break;
case(FMOD_TAGDATATYPE_STRING_UTF16BE):
{
std::string out = utf16input_to_utf8((char*)tag.data, tag.datalen, UTF16BE);
if (out.length() && out[out.size() - 1] == 0)
out.erase(out.size() - 1);
(*mMetaData)[name] = out;
llinfos << tag.name << "(UTF16BE): " << out << llendl;
std::string out((char*)tag.data,tag.datalen);
U16* buf = (U16*)out.c_str();
for(U32 j = 0; j < out.size()/2; ++j)
(((buf[j] & 0xff)<<8) | ((buf[j] & 0xff00)>>8));
(*mMetaData)[std::string(tag.name)]=out;
llinfos << tag.name << ": " << out << llendl;
}
default:
break;
@@ -332,17 +274,18 @@ void LLStreamingAudio_FMODEX::update()
if(starving)
{
bool paused = false;
if (mFMODInternetStreamChannelp->getPaused(&paused) == FMOD_OK && !paused)
mFMODInternetStreamChannelp->getPaused(&paused);
if(!paused)
{
llinfos << "Stream starvation detected! Pausing stream until buffer nearly full." << llendl;
llinfos << " (diskbusy="<<diskbusy<<")" << llendl;
llinfos << " (progress="<<progress<<")" << llendl;
Check_FMOD_Error(mFMODInternetStreamChannelp->setPaused(true), "FMOD::Channel::setPaused");
mFMODInternetStreamChannelp->setPaused(true);
}
}
else if(progress > 80)
{
Check_FMOD_Error(mFMODInternetStreamChannelp->setPaused(false), "FMOD::Channel::setPaused");
mFMODInternetStreamChannelp->setPaused(false);
}
}
}
@@ -359,8 +302,8 @@ void LLStreamingAudio_FMODEX::stop()
}
if (mFMODInternetStreamChannelp)
{
Check_FMOD_Error(mFMODInternetStreamChannelp->setPaused(true), "FMOD::Channel::setPaused");
Check_FMOD_Error(mFMODInternetStreamChannelp->setPriority(0), "FMOD::Channel::setPriority");
mFMODInternetStreamChannelp->setPaused(true);
mFMODInternetStreamChannelp->setPriority(0);
mFMODInternetStreamChannelp = NULL;
}
@@ -441,7 +384,7 @@ void LLStreamingAudio_FMODEX::setGain(F32 vol)
{
vol = llclamp(vol * vol, 0.f, 1.f); //should vol be squared here?
Check_FMOD_Error(mFMODInternetStreamChannelp->setVolume(vol), "FMOD::Channel::setVolume");
mFMODInternetStreamChannelp->setVolume(vol);
}
}
@@ -451,8 +394,8 @@ void LLStreamingAudio_FMODEX::setGain(F32 vol)
return false;
bool muted=false;
FMOD_RESULT res = mFMODInternetStreamChannelp->getMute(&muted);
if(res != FMOD_OK || muted)
mFMODInternetStreamChannelp->getMute(&muted);
if(muted)
return false;
static std::vector<float> local_array(count); //Have to have an extra buffer to mix channels. Bleh.
@@ -505,8 +448,7 @@ LLAudioStreamManagerFMODEX::LLAudioStreamManagerFMODEX(FMOD::System *system, con
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)
if (!mInternetStream || getOpenState() != FMOD_OPENSTATE_READY)
{
llwarns << "No internet stream to start playing!" << llendl;
return NULL;
@@ -515,7 +457,7 @@ FMOD::Channel *LLAudioStreamManagerFMODEX::startStream()
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");
mSystem->playSound(FMOD_CHANNEL_FREE, mInternetStream, true, &mStreamChannel);
return mStreamChannel;
}
@@ -524,17 +466,17 @@ bool LLAudioStreamManagerFMODEX::stopStream()
if (mInternetStream)
{
bool close = true;
FMOD_OPENSTATE open_state;
if (getOpenState(open_state) == FMOD_OK)
switch (getOpenState())
{
switch (open_state)
{
case FMOD_OPENSTATE_CONNECTING:
close = false;
break;
default:
close = true;
}
case FMOD_OPENSTATE_CONNECTING:
close = false;
break;
/*case FSOUND_STREAM_NET_NOTCONNECTED:
case FSOUND_STREAM_NET_BUFFERING:
case FSOUND_STREAM_NET_READY:
case FSOUND_STREAM_NET_ERROR:*/
default:
close = true;
}
if (close && mInternetStream->release() == FMOD_OK)
@@ -554,43 +496,19 @@ bool LLAudioStreamManagerFMODEX::stopStream()
}
}
FMOD_RESULT LLAudioStreamManagerFMODEX::getOpenState(FMOD_OPENSTATE& state, unsigned int* percentbuffered, bool* starving, bool* diskbusy)
FMOD_OPENSTATE LLAudioStreamManagerFMODEX::getOpenState(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;
FMOD_OPENSTATE state;
mInternetStream->getOpenState(&state,percentbuffered,starving,diskbusy);
return state;
}
void LLStreamingAudio_FMODEX::setBufferSizes(U32 streambuffertime, U32 decodebuffertime)
{
Check_FMOD_Error(mSystem->setStreamBufferSize(streambuffertime / 1000 * 128 * 128, FMOD_TIMEUNIT_RAWBYTES), "FMOD::System::setStreamBufferSize");
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
Check_FMOD_Error(mSystem->setAdvancedSettings(&settings), "FMOD::System::setAdvancedSettings");
mSystem->setAdvancedSettings(&settings);
}
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())
{
llinfos << "Closed dead stream" << llendl;
delete streamp;
mDeadStreams.erase(iter++);
}
else
{
iter++;
}
}
return mDeadStreams.empty();
}

View File

@@ -70,8 +70,6 @@ class LLStreamingAudio_FMODEX : public LLStreamingAudioInterface
/*virtual*/ bool supportsAdjustableBufferSizes(){return true;}
/*virtual*/ void setBufferSizes(U32 streambuffertime, U32 decodebuffertime);
private:
bool releaseDeadStreams();
FMOD::System *mSystem;
LLAudioStreamManagerFMODEX *mCurrentInternetStreamp;

View File

@@ -1,675 +0,0 @@
/**
* @file streamingaudio_fmodstudio.cpp
* @brief LLStreamingAudio_FMODSTUDIO 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 "llthread.h"
#include "fmod.hpp"
#include "fmod_errors.h"
#include "llstreamingaudio_fmodstudio.h"
inline bool Check_FMOD_Error(FMOD_RESULT result, const char *string)
{
if (result == FMOD_OK)
return false;
LL_WARNS("AudioImpl") << string << " Error: " << FMOD_ErrorString(result) << LL_ENDL;
return true;
}
class LLAudioStreamManagerFMODSTUDIO
{
public:
LLAudioStreamManagerFMODSTUDIO(FMOD::System *system, FMOD::ChannelGroup *group, const std::string& url);
FMOD::Channel* startStream();
bool stopStream(); // Returns true if the stream was successfully stopped.
bool ready();
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;
FMOD::ChannelGroup* mChannelGroup;
bool mReady;
std::string mInternetStreamURL;
};
LLGlobalMutex gWaveDataMutex; //Just to be extra strict.
const U32 WAVE_BUFFER_SIZE = 1024;
U32 gWaveBufferMinSize = 0;
F32 gWaveDataBuffer[WAVE_BUFFER_SIZE] = { 0.f };
U32 gWaveDataBufferSize = 0;
FMOD_RESULT F_CALLBACK waveDataCallback(FMOD_DSP_STATE *dsp_state, float *inbuffer, float *outbuffer, unsigned int length, int inchannels, int *outchannels)
{
if (!length || !inchannels)
return FMOD_OK;
memcpy(outbuffer, inbuffer, length * inchannels * sizeof(float));
static std::vector<F32> local_buf;
if (local_buf.size() < length)
local_buf.resize(length, 0.f);
for (U32 i = 0; i < length; ++i)
{
F32 total = 0.f;
for (S32 j = 0; j < inchannels; ++j)
{
total += inbuffer[i*inchannels + j];
}
local_buf[i] = total / inchannels;
}
{
LLMutexLock lock(gWaveDataMutex);
for (U32 i = length; i > 0; --i)
{
if (++gWaveDataBufferSize > WAVE_BUFFER_SIZE)
{
if (gWaveBufferMinSize)
memcpy(gWaveDataBuffer + WAVE_BUFFER_SIZE - gWaveBufferMinSize, gWaveDataBuffer, gWaveBufferMinSize * sizeof(float));
gWaveDataBufferSize = 1 + gWaveBufferMinSize;
}
gWaveDataBuffer[WAVE_BUFFER_SIZE - gWaveDataBufferSize] = local_buf[i - 1];
}
}
return FMOD_OK;
}
//---------------------------------------------------------------------------
// Internet Streaming
//---------------------------------------------------------------------------
LLStreamingAudio_FMODSTUDIO::LLStreamingAudio_FMODSTUDIO(FMOD::System *system) :
mSystem(system),
mCurrentInternetStreamp(NULL),
mFMODInternetStreamChannelp(NULL),
mGain(1.0f),
mMetaData(NULL),
mStreamGroup(NULL),
mStreamDSP(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);
Check_FMOD_Error(mSystem->createChannelGroup("stream", &mStreamGroup), "FMOD::System::createChannelGroup");
FMOD_DSP_DESCRIPTION dspdesc;
memset(&dspdesc, 0, sizeof(FMOD_DSP_DESCRIPTION)); //Zero out everything
dspdesc.pluginsdkversion = FMOD_PLUGIN_SDK_VERSION;
strncpy(dspdesc.name, "Waveform", sizeof(dspdesc.name));
dspdesc.numoutputbuffers = 1;
dspdesc.read = &waveDataCallback; //Assign callback.
Check_FMOD_Error(system->createDSP(&dspdesc, &mStreamDSP), "FMOD::System::createDSP");
}
LLStreamingAudio_FMODSTUDIO::~LLStreamingAudio_FMODSTUDIO()
{
stop();
for (U32 i = 0; i < 100; ++i)
{
if (releaseDeadStreams())
break;
ms_sleep(10);
}
cleanupWaveData();
}
void LLStreamingAudio_FMODSTUDIO::start(const std::string& url)
{
//if (!mInited)
//{
// llwarns << "startInternetStream before audio initialized" << llendl;
// return;
//}
// "stop" stream but don't clear url, etc. in case url == mInternetStreamURL
stop();
if (!url.empty())
{
if(mDeadStreams.empty())
{
llinfos << "Starting internet stream: " << url << llendl;
mCurrentInternetStreamp = new LLAudioStreamManagerFMODSTUDIO(mSystem, mStreamGroup, url);
mURL = url;
mMetaData = new LLSD;
}
else
{
llinfos << "Deferring stream load until buffer release: " << url << llendl;
mPendingURL = url;
}
}
else
{
llinfos << "Set internet stream to null" << llendl;
mURL.clear();
}
}
enum utf_endian_type_t
{
UTF16LE,
UTF16BE,
UTF16
};
std::string utf16input_to_utf8(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_FMODSTUDIO::update()
{
if (!releaseDeadStreams())
{
llassert_always(mCurrentInternetStreamp == NULL);
return;
}
if(!mPendingURL.empty())
{
llassert_always(mCurrentInternetStreamp == NULL);
llinfos << "Starting internet stream: " << mPendingURL << llendl;
mCurrentInternetStreamp = new LLAudioStreamManagerFMODSTUDIO(mSystem,mStreamGroup, 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 result = mCurrentInternetStreamp->getOpenState(open_state, &progress, &starving, &diskbusy);
if (result != FMOD_OK || open_state == FMOD_OPENSTATE_ERROR)
{
stop();
return;
}
else if (open_state == FMOD_OPENSTATE_READY)
{
// Stream is live
// start the stream if it's ready
if (!mFMODInternetStreamChannelp &&
(mFMODInternetStreamChannelp = mCurrentInternetStreamp->startStream()))
{
// Reset volume to previously set volume
setGain(getGain());
if (mStreamDSP)
{
Check_FMOD_Error(mFMODInternetStreamChannelp->addDSP(FMOD_CHANNELCONTROL_DSP_TAIL, mStreamDSP), "FMOD::Channel::addDSP");
}
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"))
{
llinfos << "Stream forced changing sample rate to " << *((float *)tag.data) << llendl;
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);
llinfos << tag.name << ": " << *(int*)(tag.data) << llendl;
break;
case(FMOD_TAGDATATYPE_FLOAT):
(*mMetaData)[name]=*(LLSD::Float*)(tag.data);
llinfos << tag.name << ": " << *(float*)(tag.data) << llendl;
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;
llinfos << tag.name << "(RAW): " << out << llendl;
}
break;
case(FMOD_TAGDATATYPE_STRING_UTF8) :
{
U8 offs = 0;
if (tag.datalen > 3 && ((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;
llinfos << tag.name << "(UTF8): " << out << llendl;
}
break;
case(FMOD_TAGDATATYPE_STRING_UTF16):
{
std::string out = utf16input_to_utf8((char*)tag.data, tag.datalen, UTF16);
if (out.length() && out[out.size() - 1] == 0)
out.erase(out.size() - 1);
(*mMetaData)[name] = out;
llinfos << tag.name << "(UTF16): " << out << llendl;
}
break;
case(FMOD_TAGDATATYPE_STRING_UTF16BE):
{
std::string out = utf16input_to_utf8((char*)tag.data, tag.datalen, UTF16BE);
if (out.length() && out[out.size() - 1] == 0)
out.erase(out.size() - 1);
(*mMetaData)[name] = out;
llinfos << tag.name << "(UTF16BE): " << out << llendl;
}
default:
break;
}
}
}
if(starving)
{
bool paused = false;
if (mFMODInternetStreamChannelp->getPaused(&paused) == FMOD_OK && !paused)
{
llinfos << "Stream starvation detected! Pausing stream until buffer nearly full." << llendl;
llinfos << " (diskbusy="<<diskbusy<<")" << llendl;
llinfos << " (progress="<<progress<<")" << llendl;
Check_FMOD_Error(mFMODInternetStreamChannelp->setPaused(true), "FMOD::Channel::setPaused");
}
}
else if(progress > 80)
{
Check_FMOD_Error(mFMODInternetStreamChannelp->setPaused(false), "FMOD::Channel::setPaused");
}
}
}
}
void LLStreamingAudio_FMODSTUDIO::stop()
{
mPendingURL.clear();
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");
if (mStreamDSP)
{
Check_FMOD_Error(mFMODInternetStreamChannelp->removeDSP(mStreamDSP), "FMOD::Channel::removeDSP");
}
mFMODInternetStreamChannelp = NULL;
}
if (mCurrentInternetStreamp)
{
llinfos << "Stopping internet stream: " << mCurrentInternetStreamp->getURL() << llendl;
if (mCurrentInternetStreamp->stopStream())
{
delete mCurrentInternetStreamp;
}
else
{
llwarns << "Pushing stream to dead list: " << mCurrentInternetStreamp->getURL() << llendl;
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() || !mPendingURL.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?
Check_FMOD_Error(mFMODInternetStreamChannelp->setVolume(vol), "FMOD::Channel::setVolume");
}
}
/*virtual*/ bool LLStreamingAudio_FMODSTUDIO::getWaveData(float* arr, S32 count, S32 stride/*=1*/)
{
if (count > (WAVE_BUFFER_SIZE / 2))
LL_ERRS("AudioImpl") << "Count=" << count << " exceeds WAVE_BUFFER_SIZE/2=" << WAVE_BUFFER_SIZE << LL_ENDL;
if(!mFMODInternetStreamChannelp || !mCurrentInternetStreamp)
return false;
bool muted = false;
FMOD_RESULT res = mFMODInternetStreamChannelp->getMute(&muted);
if(res != FMOD_OK || muted)
return false;
{
U32 buff_size;
{
LLMutexLock lock(gWaveDataMutex);
gWaveBufferMinSize = count;
buff_size = gWaveDataBufferSize;
if (!buff_size)
return false;
memcpy(arr, gWaveDataBuffer + WAVE_BUFFER_SIZE - buff_size, llmin(U32(count), buff_size) * sizeof(float));
}
if (buff_size < U32(count))
memset(arr + buff_size, 0, (count - buff_size) * sizeof(float));
}
return true;
}
///////////////////////////////////////////////////////
// manager of possibly-multiple internet audio streams
LLAudioStreamManagerFMODSTUDIO::LLAudioStreamManagerFMODSTUDIO(FMOD::System *system, FMOD::ChannelGroup *group, const std::string& url) :
mSystem(system),
mStreamChannel(NULL),
mInternetStream(NULL),
mChannelGroup(group),
mReady(false)
{
mInternetStreamURL = url;
FMOD_RESULT result = mSystem->createStream(url.c_str(), FMOD_2D | FMOD_NONBLOCKING | FMOD_IGNORETAGS, 0, &mInternetStream);
if (result!= FMOD_OK)
{
llwarns << "Couldn't open fmod stream, error "
<< FMOD_ErrorString(result)
<< llendl;
mReady = false;
return;
}
mReady = true;
}
FMOD::Channel *LLAudioStreamManagerFMODSTUDIO::startStream()
{
// We need a live and opened stream before we try and play it.
FMOD_OPENSTATE open_state;
if (getOpenState(open_state) != FMOD_OK || open_state != FMOD_OPENSTATE_READY)
{
llwarns << "No internet stream to start playing!" << llendl;
return NULL;
}
if(mStreamChannel)
return mStreamChannel; //Already have a channel for this stream.
Check_FMOD_Error(mSystem->playSound(mInternetStream, mChannelGroup, true, &mStreamChannel), "FMOD::System::playSound");
return mStreamChannel;
}
bool LLAudioStreamManagerFMODSTUDIO::stopStream()
{
if (mInternetStream)
{
bool close = true;
FMOD_OPENSTATE open_state;
if (getOpenState(open_state) == FMOD_OK)
{
switch (open_state)
{
case FMOD_OPENSTATE_CONNECTING:
close = false;
break;
default:
close = true;
}
}
if (close && mInternetStream->release() == FMOD_OK)
{
mStreamChannel = NULL;
mInternetStream = NULL;
return true;
}
else
{
return false;
}
}
else
{
return true;
}
}
FMOD_RESULT LLAudioStreamManagerFMODSTUDIO::getOpenState(FMOD_OPENSTATE& state, unsigned int* percentbuffered, bool* starving, bool* diskbusy)
{
if (!mInternetStream)
return FMOD_ERR_INVALID_HANDLE;
FMOD_RESULT result = mInternetStream->getOpenState(&state, percentbuffered, starving, diskbusy);
Check_FMOD_Error(result, "FMOD::Sound::getOpenState");
return result;
}
void LLStreamingAudio_FMODSTUDIO::setBufferSizes(U32 streambuffertime, U32 decodebuffertime)
{
Check_FMOD_Error(mSystem->setStreamBufferSize(streambuffertime / 1000 * 128 * 128, FMOD_TIMEUNIT_RAWBYTES), "FMOD::System::setStreamBufferSize");
FMOD_ADVANCEDSETTINGS settings;
memset(&settings,0,sizeof(settings));
settings.cbSize=sizeof(settings);
settings.defaultDecodeBufferSize = decodebuffertime;//ms
Check_FMOD_Error(mSystem->setAdvancedSettings(&settings), "FMOD::System::setAdvancedSettings");
}
bool LLStreamingAudio_FMODSTUDIO::releaseDeadStreams()
{
// Kill dead internet streams, if possible
std::list<LLAudioStreamManagerFMODSTUDIO *>::iterator iter;
for (iter = mDeadStreams.begin(); iter != mDeadStreams.end();)
{
LLAudioStreamManagerFMODSTUDIO *streamp = *iter;
if (streamp->stopStream())
{
llinfos << "Closed dead stream" << llendl;
delete streamp;
mDeadStreams.erase(iter++);
}
else
{
iter++;
}
}
return mDeadStreams.empty();
}
void LLStreamingAudio_FMODSTUDIO::cleanupWaveData()
{
if (mStreamGroup)
{
Check_FMOD_Error(mStreamGroup->release(), "FMOD::ChannelGroup::release");
mStreamGroup = NULL;
}
if(mStreamDSP)
Check_FMOD_Error(mStreamDSP->release(), "FMOD::DSP::release");
mStreamDSP = NULL;
}

View File

@@ -1,97 +0,0 @@
/**
* @file streamingaudio_fmodstudio.h
* @author Tofu Linden
* @brief Definition of LLStreamingAudio_FMODSTUDIO 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_FMODSTUDIO_H
#define LL_STREAMINGAUDIO_FMODSTUDIO_H
#include "stdtypes.h" // from llcommon
#include "llstreamingaudio.h"
#include "lltimer.h"
//Stubs
class LLAudioStreamManagerFMODSTUDIO;
namespace FMOD
{
class System;
class Channel;
class ChannelGroup;
class ChannelGroup;
class DSP;
}
//Interfaces
class LLStreamingAudio_FMODSTUDIO : public LLStreamingAudioInterface
{
public:
LLStreamingAudio_FMODSTUDIO(FMOD::System *system);
/*virtual*/ ~LLStreamingAudio_FMODSTUDIO();
/*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();
void cleanupWaveData();
FMOD::System *mSystem;
LLAudioStreamManagerFMODSTUDIO *mCurrentInternetStreamp;
FMOD::Channel *mFMODInternetStreamChannelp;
std::list<LLAudioStreamManagerFMODSTUDIO *> mDeadStreams;
std::string mURL;
std::string mPendingURL;
F32 mGain;
LLSD *mMetaData;
FMOD::ChannelGroup* mStreamGroup;
FMOD::DSP* mStreamDSP;
};
#endif // LL_STREAMINGAUDIO_FMOD_H

View File

@@ -58,16 +58,6 @@ public:
// Destructor
virtual ~LLEditingMotion();
void* operator new(size_t size)
{
return ll_aligned_malloc_16(size);
}
void operator delete(void* ptr)
{
ll_aligned_free_16(ptr);
}
public:
//-------------------------------------------------------------------------
// functions to support MotionController and MotionRegistry

View File

@@ -1111,7 +1111,7 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8
LLVector3 source_to_target = target_pos - keyframe_source_pos;
S32 max_iteration_count = llmath::llround(clamp_rescale(
S32 max_iteration_count = llround(clamp_rescale(
mCharacter->getPixelArea(),
MAX_PIXEL_AREA_CONSTRAINTS,
MIN_PIXEL_AREA_CONSTRAINTS,

View File

@@ -53,16 +53,6 @@ public:
// Destructor
virtual ~LLKeyframeStandMotion();
void* operator new(size_t size)
{
return ll_aligned_malloc_16(size);
}
void operator delete(void* ptr)
{
ll_aligned_free_16(ptr);
}
public:
//-------------------------------------------------------------------------
// functions to support MotionController and MotionRegistry

View File

@@ -876,12 +876,12 @@ void LLMotionController::updateMotions(bool force_update)
//<singu>
// This old code is nonsense.
//S32 quantum_count = llmax(0, llmath::llround((update_time - time_interval) / mTimeStep)) + 1;
//S32 quantum_count = llmax(0, llround((update_time - time_interval) / mTimeStep)) + 1;
// (update_time - time_interval) / mTimeStep is an integer! We need llround to get rid of floating point errors, not llfloor.
// Moreover, just rounding off to the nearest integer with llmath::llround(update_time / mTimeStep) makes a lot more sense:
// Moreover, just rounding off to the nearest integer with llround(update_time / mTimeStep) makes a lot more sense:
// it is the best we can do to get as close to what we should draw as possible.
// However, mAnimTime may only be incremented; therefore make sure of that with the llmax.
S32 quantum_count = llmax(llmath::llround(update_time / mTimeStep), llceil(mAnimTime / mTimeStep));
S32 quantum_count = llmax(llround(update_time / mTimeStep), llceil(mAnimTime / mTimeStep));
//</singu>
if (quantum_count == mTimeStepCount)
{

View File

@@ -96,16 +96,6 @@ protected:
public:
LLJointStateBlender();
~LLJointStateBlender();
void* operator new(size_t size)
{
return ll_aligned_malloc_16(size);
}
void operator delete(void* ptr)
{
ll_aligned_free_16(ptr);
}
void blendJointStates(BOOL apply_now = TRUE);
BOOL addJointState(const LLPointer<LLJointState>& joint_state, S32 priority, BOOL additive_blend);
void interpolate(F32 u);

View File

@@ -31,6 +31,7 @@ set(llcommon_SOURCE_FILES
llapr.cpp
llaprpool.cpp
llassettype.cpp
llavatarname.cpp
llbase32.cpp
llbase64.cpp
llcommon.cpp
@@ -55,6 +56,7 @@ set(llcommon_SOURCE_FILES
llfile.cpp
llfindlocale.cpp
llfixedbuffer.cpp
llfoldertype.cpp
llformat.cpp
llframetimer.cpp
llheartbeat.cpp
@@ -133,6 +135,7 @@ set(llcommon_HEADER_FILES
llassoclist.h
llatomic.h
llavatarconstants.h
llavatarname.h
llbase32.h
llbase64.h
llboost.h
@@ -174,6 +177,7 @@ set(llcommon_HEADER_FILES
llfile.h
llfindlocale.h
llfixedbuffer.h
llfoldertype.h
llformat.h
llframetimer.h
llhandle.h
@@ -280,8 +284,6 @@ target_link_libraries(
${WINDOWS_LIBRARIES}
${Boost_CONTEXT_LIBRARY}
${Boost_REGEX_LIBRARY}
${Boost_THREAD_LIBRARY}
${Boost_SYSTEM_LIBRARY}
${CORESERVICES_LIBRARY}
)

View File

@@ -65,7 +65,7 @@ static F64 const NEVER = 1e16; // 317 million years.
F64 AIFrameTimer::sNextExpiration;
AIFrameTimer::timer_list_type AIFrameTimer::sTimerList;
LLGlobalMutex AIFrameTimer::sMutex;
LLMutex AIFrameTimer::sMutex;
// Notes on thread-safety of AIRunningFrameTimer (continued from aiframetimer.h)
//
@@ -80,10 +80,11 @@ LLGlobalMutex AIFrameTimer::sMutex;
void AIFrameTimer::create(F64 expiration, signal_type::slot_type const& slot)
{
AIRunningFrameTimer new_timer(expiration, this);
LLMutexLock lock(sMutex);
sMutex.lock();
llassert(mHandle.mRunningTimer == sTimerList.end()); // Create may only be called when the timer isn't already running.
mHandle.init(sTimerList.insert(new_timer), slot);
sNextExpiration = sTimerList.begin()->expiration();
sMutex.unlock();
}
void AIFrameTimer::cancel(void)
@@ -94,19 +95,18 @@ void AIFrameTimer::cancel(void)
// mHandle.mMutex lock), we start with trying to obtain
// it here and as such wait till the callback function
// returned.
mHandle.mMutex.lock();
mHandle.mMutex.lock();
// Next we have to grab this lock in order to stop
// AIFrameTimer::handleExpiration from even entering
// in the case we manage to get it first.
sMutex.lock();
if (mHandle.mRunningTimer != sTimerList.end())
{
LLMutexLock lock(sMutex);
if (mHandle.mRunningTimer != sTimerList.end())
{
sTimerList.erase(mHandle.mRunningTimer);
mHandle.mRunningTimer = sTimerList.end();
sNextExpiration = sTimerList.empty() ? NEVER : sTimerList.begin()->expiration();
}
sTimerList.erase(mHandle.mRunningTimer);
mHandle.mRunningTimer = sTimerList.end();
sNextExpiration = sTimerList.empty() ? NEVER : sTimerList.begin()->expiration();
}
sMutex.unlock();
mHandle.mMutex.unlock();
}
@@ -164,7 +164,7 @@ void AIFrameTimer::handleExpiration(F64 current_frame_time)
//
// Note that if the other thread actually obtained the sMutex then we
// can't be here: this is still inside the critical area of sMutex.
if (handle.mMutex.try_lock()) // If this fails then another thread is in the process of cancelling this timer, so do nothing.
if (handle.mMutex.tryLock()) // If this fails then another thread is in the process of cancelling this timer, so do nothing.
{
sMutex.unlock();
running_timer->do_callback(); // May not throw exceptions.

View File

@@ -96,7 +96,7 @@ class LL_COMMON_API AIFrameTimer
typedef std::multiset<AIRunningFrameTimer> timer_list_type;
static LLGlobalMutex sMutex; // Mutex for the two global variables below.
static LLMutex sMutex; // Mutex for the two global variables below.
static timer_list_type sTimerList; // List with all running timers.
static F64 sNextExpiration; // Cache of smallest value in sTimerList.
friend class LLFrameTimer; // Access to sNextExpiration.

View File

@@ -239,7 +239,7 @@ protected:
// For use by AIThreadSafeDC
AIThreadSafe(void) { }
MUTEX_POOL(AIThreadSafe(LLAPRPool& parent) : mRWLock(parent){ })
AIThreadSafe(LLAPRPool& parent) : mRWLock(parent) { }
public:
// Only for use by AITHREADSAFE, see below.
@@ -473,7 +473,7 @@ protected:
friend struct AIRegisteredStateMachinesList;
// For use by AIThreadSafeSimpleDC and AIRegisteredStateMachinesList.
AIThreadSafeSimple(void) { }
MUTEX_POOL(AIThreadSafeSimple(LLAPRPool& parent) : mMutex(parent) { })
AIThreadSafeSimple(LLAPRPool& parent) : mMutex(parent) { }
public:
// Only for use by AITHREADSAFESIMPLE, see below.
@@ -551,7 +551,7 @@ public:
protected:
// For use by AIThreadSafeSimpleDCRootPool
AIThreadSafeSimpleDC(LLAPRRootPool& parent) : AIThreadSafeSimple<T, MUTEX>(MUTEX_POOL(parent)) { new (AIThreadSafeSimple<T, MUTEX>::ptr()) T; }
AIThreadSafeSimpleDC(LLAPRRootPool& parent) : AIThreadSafeSimple<T, MUTEX>(parent) { new (AIThreadSafeSimple<T, MUTEX>::ptr()) T; }
};
// Helper class for AIThreadSafeSimpleDCRootPool to assure initialization of
@@ -585,7 +585,7 @@ public:
// as opposed to allocated from the current threads root pool.
AIThreadSafeSimpleDCRootPool(void) :
AIThreadSafeSimpleDCRootPool_pbase(),
AIThreadSafeSimpleDC<T>(MUTEX_POOL(mRootPool)) { }
AIThreadSafeSimpleDC<T>(mRootPool) { }
};
/**

View File

@@ -66,7 +66,6 @@ bool windows_post_minidump_callback(const wchar_t* dump_path,
#else
# include <signal.h>
# include <unistd.h> // for fork()
# include "apr_signal.h" // for apr_signal_description_get(int signum)
void setup_signals();
void default_unix_signal_handler(int signum, siginfo_t *info, void *);
@@ -386,12 +385,12 @@ void LLApp::setupErrorHandling()
// installing the handler.
installHandler = true;
}
#endif
if(installHandler && (mExceptionHandler == 0))
{
mExceptionHandler = new google_breakpad::ExceptionHandler(mDumpPath, clear_CrashLoggerReserve_callback, &unix_post_minidump_callback, 0, true, 0);
}
#endif
#elif LL_LINUX
if(installHandler && (mExceptionHandler == 0))
{

Some files were not shown because too many files have changed in this diff Show More