Fixed FMOD Ex support under linux

This commit is contained in:
Drake Arconis
2012-05-15 10:36:48 -04:00
parent 3d40f96dfe
commit 5a2d160ac4
6 changed files with 91 additions and 101 deletions

View File

@@ -5,27 +5,25 @@ project(llaudio)
include(00-Common) include(00-Common)
include(Audio) include(Audio)
include(LLAudio) include(LLAudio)
if(FMODEX) if (FMODEX)
include(FMODEX) include(FMODEX)
if(FMODEX) set(FMOD OFF)
set(FMOD OFF) endif (FMODEX)
endif(FMODEX) if (NOT FMODEX)
endif(FMODEX) include(FMOD)
if(NOT FMODEX) endif (NOT FMODEX)
include(FMOD)
endif(NOT FMODEX)
include(OPENAL) include(OPENAL)
include(LLCommon) include(LLCommon)
include(LLMath) include(LLMath)
include(LLMessage) include(LLMessage)
include(LLVFS) include(LLVFS)
if(FMODEX) if (FMODEX)
include_directories(${FMODEX_INCLUDE_DIR}) include_directories(${FMODEX_INCLUDE_DIR})
endif(FMODEX) endif(FMODEX)
if(FMOD) if(FMOD)
include_directories(${FMOD_INCLUDE_DIR}) include_directories(${FMOD_INCLUDE_DIR})
endif(FMOD) endif (FMOD)
include_directories( include_directories(
${LLAUDIO_INCLUDE_DIRS} ${LLAUDIO_INCLUDE_DIRS}

View File

@@ -242,8 +242,8 @@ BOOL LLVorbisDecodeState::initDecode()
llwarns << "No default bitstream found" << llendl; llwarns << "No default bitstream found" << llendl;
} }
// <edit> // <edit>
// This magic value is equivilent to 150MiB of data. // This magic value is equivalent to 150MiB of data.
// Prevents griffers from utilizin a huge xbox sound the size of god to instafry the viewer // Prevents griefers from utilizing a huge xbox sound the size of god to instafry the viewer
if(size_guess >= 157286400) if(size_guess >= 157286400)
{ {
llwarns << "Bad sound caught by zmagic" << llendl; llwarns << "Bad sound caught by zmagic" << llendl;

View File

@@ -1275,7 +1275,7 @@ void LLAudioEngine::assetCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::E
// Need to mark data as bad to avoid constant rerequests. // Need to mark data as bad to avoid constant rerequests.
LLAudioData *adp = gAudiop->getAudioData(uuid); LLAudioData *adp = gAudiop->getAudioData(uuid);
if (adp) if (adp)
{ {
adp->setHasValidData(false); adp->setHasValidData(false);
adp->setHasLocalData(false); adp->setHasLocalData(false);
adp->setHasDecodedData(false); adp->setHasDecodedData(false);
@@ -1292,8 +1292,8 @@ void LLAudioEngine::assetCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::E
else else
{ {
adp->setHasValidData(true); adp->setHasValidData(true);
adp->setHasLocalData(true); adp->setHasLocalData(true);
gAudioDecodeMgrp->addDecodeRequest(uuid); gAudioDecodeMgrp->addDecodeRequest(uuid);
} }
} }
gAudiop->mCurrentTransfer = LLUUID::null; gAudiop->mCurrentTransfer = LLUUID::null;

View File

@@ -105,10 +105,6 @@ bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata)
U32 version; U32 version;
FMOD_RESULT result; FMOD_RESULT result;
int numdrivers;
FMOD_SPEAKERMODE speakermode;
FMOD_CAPS caps;
char name[256];
LL_DEBUGS("AppInit") << "LLAudioEngine_FMODEX::init() initializing FMOD" << LL_ENDL; LL_DEBUGS("AppInit") << "LLAudioEngine_FMODEX::init() initializing FMOD" << LL_ENDL;
@@ -124,11 +120,16 @@ bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata)
if (version < FMOD_VERSION) if (version < FMOD_VERSION)
{ {
LL_WARNS("AppInit") << "Error : You are using the wrong FMOD version (" << version LL_WARNS("AppInit") << "Error : You are using the wrong FMOD Ex version (" << version
<< ")! You should be using FMOD " << FMOD_VERSION << LL_ENDL; << ")! You should be using FMOD Ex" << FMOD_VERSION << LL_ENDL;
} }
#if LL_WINDOWS #if LL_WINDOWS
int numdrivers;
FMOD_SPEAKERMODE speakermode;
FMOD_CAPS caps;
char name[256];
//Is this block applicable to linux? //Is this block applicable to linux?
{ {
result = mSystem->getNumDrivers(&numdrivers); result = mSystem->getNumDrivers(&numdrivers);
@@ -173,7 +174,7 @@ bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata)
#endif //LL_WINDOWS #endif //LL_WINDOWS
// In this case, all sounds, PLUS wind and stream will be software. // In this case, all sounds, PLUS wind and stream will be software.
result = mSystem->setSoftwareChannels(num_channels+2); result = mSystem->setSoftwareChannels(num_channels + 2);
Check_FMOD_Error(result,"FMOD::System::setSoftwareChannels"); Check_FMOD_Error(result,"FMOD::System::setSoftwareChannels");
U32 fmod_flags = FMOD_INIT_NORMAL; U32 fmod_flags = FMOD_INIT_NORMAL;
@@ -181,73 +182,67 @@ bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata)
fmod_flags |= FMOD_INIT_ENABLE_PROFILE; fmod_flags |= FMOD_INIT_ENABLE_PROFILE;
#if LL_LINUX #if LL_LINUX
// 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; bool audio_ok = false;
if (!audio_ok) if (!audio_ok)
{ {
if (NULL == getenv("LL_BAD_FMODEX_ESD")) /*Flawfinder: ignore*/ if (NULL == getenv("LL_BAD_FMOD_PULSEAUDIO")) /*Flawfinder: ignore*/
{ {
LL_DEBUGS("AppInit") << "Trying ESD audio output..." << LL_ENDL; LL_DEBUGS("AppInit") << "Trying PulseAudio audio output..." << LL_ENDL;
if(mSystem->SetOutput(FMOD_OUTPUTTYPE_ESD) == FMOD_OK && if(mSystem->setOutput(FMOD_OUTPUTTYPE_PULSEAUDIO) == FMOD_OK &&
(result = mSystem->init(num_channels, fmod_flags, 0)) == FMOD_OK) (result = mSystem->init(num_channels + 2, fmod_flags, 0)) == FMOD_OK)
{ {
LL_DEBUGS("AppInit") << "ESD audio output initialized OKAY" << LL_ENDL; LL_DEBUGS("AppInit") << "PulseAudio output initialized OKAY" << LL_ENDL;
audio_ok = true; audio_ok = true;
} }
else else
{ {
Check_FMOD_Error(result, "ESD audio output FAILED to initialize"); Check_FMOD_Error(result, "PulseAudio audio output FAILED to initialize");
} }
} }
else else
{ {
LL_DEBUGS("AppInit") << "ESD audio output SKIPPED" << LL_ENDL; LL_DEBUGS("AppInit") << "PulseAudio audio output SKIPPED" << LL_ENDL;
} }
} }
if (!audio_ok) if (!audio_ok)
{ {
if (NULL == getenv("LL_BAD_FMODEX_OSS")) /*Flawfinder: ignore*/ if (NULL == getenv("LL_BAD_FMOD_ALSA")) /*Flawfinder: ignore*/
{ {
LL_DEBUGS("AppInit") << "Trying OSS audio output..." << LL_ENDL; LL_DEBUGS("AppInit") << "Trying ALSA audio output..." << LL_ENDL;
if(mSystem->SetOutput(FMOD_OUTPUTTYPE_OSS) == FMOD_OK && if(mSystem->setOutput(FMOD_OUTPUTTYPE_ALSA) == FMOD_OK &&
(result = mSystem->init(num_channels, fmod_flags, 0)) == FMOD_OK) (result = mSystem->init(num_channels + 2, fmod_flags, 0)) == FMOD_OK)
{ {
LL_DEBUGS("AppInit") << "OSS audio output initialized OKAY" << LL_ENDL; LL_DEBUGS("AppInit") << "ALSA audio output initialized OKAY" << LL_ENDL;
audio_ok = true; audio_ok = true;
} }
else else
{ {
Check_FMOD_Error(result, "OSS audio output FAILED to initialize" << LL_ENDL; Check_FMOD_Error(result, "ALSA audio output FAILED to initialize");
} }
} }
else else
{ {
LL_DEBUGS("AppInit") << "OSS audio output SKIPPED" << LL_ENDL; LL_DEBUGS("AppInit") << "ALSA audio output SKIPPED" << LL_ENDL;
} }
} }
if (!audio_ok) if (!audio_ok)
{ {
if (NULL == getenv("LL_BAD_FMODEX_ALSA")) /*Flawfinder: ignore*/ if (NULL == getenv("LL_BAD_FMOD_OSS")) /*Flawfinder: ignore*/
{ {
LL_DEBUGS("AppInit") << "Trying ALSA audio output..." << LL_ENDL; LL_DEBUGS("AppInit") << "Trying OSS audio output..." << LL_ENDL;
if(mSystem->SetOutput(FMOD_OUTPUTTYPE_ALSA) && if(mSystem->setOutput(FMOD_OUTPUTTYPE_OSS) == FMOD_OK &&
(result = mSystem->init(num_channels, fmod_flags, 0)) == FMOD_OK) (result = mSystem->init(num_channels + 2, fmod_flags, 0)) == FMOD_OK)
{ {
LL_DEBUGS("AppInit") << "ALSA audio output initialized OKAY" << LL_ENDL; LL_DEBUGS("AppInit") << "OSS audio output initialized OKAY" << LL_ENDL;
audio_ok = true; audio_ok = true;
} }
else else
{ {
Check_FMOD_Error(result, "ALSA audio output FAILED to initialize"); Check_FMOD_Error(result, "OSS audio output FAILED to initialize");
} }
} else }
else
{ {
LL_DEBUGS("AppInit") << "OSS audio output SKIPPED" << LL_ENDL; LL_DEBUGS("AppInit") << "OSS audio output SKIPPED" << LL_ENDL;
} }
@@ -258,25 +253,20 @@ bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata)
return false; 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 // We're interested in logging which output method we
// ended up with, for QA purposes. // ended up with, for QA purposes.
FMOD_OUTPUTTYPE output_type; FMOD_OUTPUTTYPE output_type;
mSystem->getOutput(output_type); mSystem->getOutput(&output_type);
switch (output_type) switch (output_type)
{ {
case FSOUND_OUTPUT_NOSOUND: case FMOD_OUTPUTTYPE_NOSOUND:
LL_DEBUGS("AppInit") << "Audio output: NoSound" << LL_ENDL; break; LL_INFOS("AppInit") << "Audio output: NoSound" << LL_ENDL; break;
case FSOUND_OUTPUT_OSS: case FMOD_OUTPUTTYPE_PULSEAUDIO:
LL_DEBUGS("AppInit") << "Audio output: OSS" << LL_ENDL; break; LL_INFOS("AppInit") << "Audio output: PulseAudio" << LL_ENDL; break;
case FSOUND_OUTPUT_ESD: case FMOD_OUTPUTTYPE_ALSA:
LL_DEBUGS("AppInit") << "Audio output: ESD" << LL_ENDL; break; LL_INFOS("AppInit") << "Audio output: ALSA" << LL_ENDL; break;
case FSOUND_OUTPUT_ALSA: case FMOD_OUTPUTTYPE_OSS:
LL_DEBUGS("AppInit") << "Audio output: ALSA" << LL_ENDL; break; LL_INFOS("AppInit") << "Audio output: OSS" << LL_ENDL; break;
default: default:
LL_INFOS("AppInit") << "Audio output: Unknown!" << LL_ENDL; break; LL_INFOS("AppInit") << "Audio output: Unknown!" << LL_ENDL; break;
}; };
@@ -297,7 +287,7 @@ bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata)
*/ */
result = mSystem->init(100, FMOD_INIT_NORMAL, 0); result = mSystem->init(100, FMOD_INIT_NORMAL, 0);
} }
if(Check_FMOD_Error(result, "Error initializing FMOD")) if(Check_FMOD_Error(result, "Error initializing FMOD Ex"))
return false; return false;
#endif #endif
@@ -305,7 +295,7 @@ bool LLAudioEngine_FMODEX::init(const S32 num_channels, void* userdata)
if (!getStreamingAudioImpl()) // no existing implementation added if (!getStreamingAudioImpl()) // no existing implementation added
setStreamingAudioImpl(new LLStreamingAudio_FMODEX(mSystem)); setStreamingAudioImpl(new LLStreamingAudio_FMODEX(mSystem));
LL_DEBUGS("AppInit") << "LLAudioEngine_FMODEX::init() FMOD initialized correctly" << LL_ENDL; LL_INFOS("AppInit") << "LLAudioEngine_FMODEX::init() FMOD Ex initialized correctly" << LL_ENDL;
mInited = true; mInited = true;
@@ -321,10 +311,10 @@ std::string LLAudioEngine_FMODEX::getDriverName(bool verbose)
U32 version; U32 version;
if(!Check_FMOD_Error(mSystem->getVersion(&version), "FMOD::System::getVersion")) if(!Check_FMOD_Error(mSystem->getVersion(&version), "FMOD::System::getVersion"))
{ {
return llformat("FMOD version %1x.%02x.%02x", version >> 16, version >> 8 & 0x000000FF, version & 0x000000FF); return llformat("FMOD Ex %1x.%02x.%02x", version >> 16, version >> 8 & 0x000000FF, version & 0x000000FF);
} }
} }
return "FMOD"; return "FMODEx";
} }
@@ -342,12 +332,13 @@ void LLAudioEngine_FMODEX::shutdown()
{ {
stopInternetStream(); stopInternetStream();
llinfos << "About to LLAudioEngine::shutdown()" << llendl;
LLAudioEngine::shutdown(); LLAudioEngine::shutdown();
llinfos << "LLAudioEngine_FMODEX::shutdown() closing FMOD" << llendl; llinfos << "LLAudioEngine_FMODEX::shutdown() closing FMOD Ex" << llendl;
mSystem->close(); mSystem->close();
mSystem->release(); mSystem->release();
llinfos << "LLAudioEngine_FMODEX::shutdown() done closing FMOD" << llendl; llinfos << "LLAudioEngine_FMODEX::shutdown() done closing FMOD Ex" << llendl;
delete mListenerp; delete mListenerp;
mListenerp = NULL; mListenerp = NULL;

View File

@@ -89,7 +89,7 @@ S32 check_for_invalid_wav_formats(const std::string& in_fname, std::string& erro
// ******************************** // ********************************
LLAPRFile infile ; LLAPRFile infile ;
infile.open(in_fname,LL_APR_RB); infile.open(in_fname,LL_APR_RB);
// ******************************** // ********************************
if (!infile.getFileHandle()) if (!infile.getFileHandle())
{ {

View File

@@ -1352,39 +1352,40 @@ if (OPENAL)
endif (OPENAL) endif (OPENAL)
if (FMOD OR FMODEX) if (FMOD OR FMODEX)
if(FMODEX) if (FMODEX)
set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_FMODEX") set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_FMODEX")
endif(FMODEX) endif (FMODEX)
if(FMOD) if (FMOD)
set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_FMOD") set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_FMOD")
endif(FMOD) endif (FMOD)
if (NOT WINDOWS) if (DARWIN)
set(fmodwrapper_SOURCE_FILES fmodwrapper.cpp) set(fmodwrapper_SOURCE_FILES fmodwrapper.cpp)
add_library(fmodwrapper SHARED ${fmodwrapper_SOURCE_FILES}) add_library(fmodwrapper SHARED ${fmodwrapper_SOURCE_FILES})
if(FMOD AND FMODEX) if (FMODEX)
set(fmodwrapper_needed_LIBRARIES "${FMODEX_LIBRARY} ${FMOD_LIBRARY}") set(fmodwrapper_needed_LIBRARIES ${FMODEX_LIBRARY} ${CARBON_LIBRARY})
else(FMOD AND FMODEX) endif (FMODEX)
if(FMODEX) if (FMOD)
set(fmodwrapper_needed_LIBRARIES ${FMODEX_LIBRARY}) set(fmodwrapper_needed_LIBRARIES ${FMOD_LIBRARY} ${CARBON_LIBRARY})
endif(FMODEX) endif (FMOD)
if(FMOD) set_target_properties(
set(fmodwrapper_needed_LIBRARIES "${FMOD_LIBRARY}") fmodwrapper
endif(FMOD) PROPERTIES
endif(FMOD AND FMODEX) BUILD_WITH_INSTALL_RPATH 1
if (DARWIN) INSTALL_NAME_DIR "@executable_path/../Resources"
list(APPEND fmodwrapper_needed_LIBRARIES ${CARBON_LIBRARY}) LINK_FLAGS "-unexported_symbols_list ${CMAKE_CURRENT_SOURCE_DIR}/fmod_hidden_symbols.exp"
set_target_properties( )
fmodwrapper
PROPERTIES
BUILD_WITH_INSTALL_RPATH 1
INSTALL_NAME_DIR "@executable_path/../Resources"
LINK_FLAGS "-unexported_symbols_list \"${CMAKE_CURRENT_SOURCE_DIR}/fmod_hidden_symbols.exp\""
)
endif (DARWIN)
set(FMODWRAPPER_LIBRARY fmodwrapper) set(FMODWRAPPER_LIBRARY fmodwrapper)
target_link_libraries(fmodwrapper ${fmodwrapper_needed_LIBRARIES}) target_link_libraries(fmodwrapper ${fmodwrapper_needed_LIBRARIES})
endif (NOT WINDOWS) else (DARWIN)
# fmodwrapper unnecessary on linux or windows, for fmod and fmodex
if (FMODEX)
set(FMODWRAPPER_LIBRARY ${FMODEX_LIBRARY})
endif (FMODEX)
if (FMOD)
set(FMODWRAPPER_LIBRARY ${FMOD_LIBRARY})
endif (FMOD)
endif (DARWIN)
endif (FMOD OR FMODEX) endif (FMOD OR FMODEX)
set_source_files_properties(llstartup.cpp PROPERTIES COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS}") set_source_files_properties(llstartup.cpp PROPERTIES COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS}")