From c219811a542e0d6aae38b920ae9e257c5c2286c1 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 17 Apr 2017 01:06:54 +0200 Subject: [PATCH] - removed FMod as the last remaining piece of code that is not GPL compatible. Please consider GZDoom as licensed under the GPL starting with this commit, even though the license headers have not been changed yet. --- CMakeLists.txt | 1 - src/CMakeLists.txt | 180 +- src/menu/menudef.cpp | 4 - src/s_sound.cpp | 1 + src/sound/fmod_wrap.h | 624 ------ src/sound/fmodsound.cpp | 3527 --------------------------------- src/sound/fmodsound.h | 141 -- src/sound/i_music.cpp | 3 - src/sound/i_musicinterns.h | 1 - src/sound/i_sound.cpp | 33 +- src/sound/i_sound.h | 1 - src/sound/music_midi_base.cpp | 17 - src/sound/oalsound.cpp | 2 +- wadsrc/static/language.enu | 13 - wadsrc/static/menudef.txt | 63 +- 15 files changed, 6 insertions(+), 4605 deletions(-) delete mode 100644 src/sound/fmod_wrap.h delete mode 100644 src/sound/fmodsound.cpp delete mode 100644 src/sound/fmodsound.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e96249ff3..f426119c2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -150,7 +150,6 @@ endif() set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}") -option( NO_FMOD "Disable FMODEx sound support" OFF ) option( NO_OPENAL "Disable OpenAL sound support" OFF ) find_package( BZip2 ) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 54dce36ca..d303102b0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -34,56 +34,6 @@ if( CMAKE_SIZEOF_VOID_P MATCHES "8" ) set( X64 64 ) endif() -# You can either use "make install" on the FMOD distribution to put it -# in standard system locations, or you can unpack the FMOD distribution -# in the root of the zdoom tree. e.g.: -# zdoom -# docs -# fmodapilinux[64] -or simply- fmod -# jpeg-6b -# ... -# The recommended method is to put it in the zdoom tree, since its -# headers are unversioned. Especially now that we can't work properly -# with anything newer than 4.26.xx, you probably don't want to use -# a system-wide version. - -# Construct version numbers for searching for the FMOD library on Linux. -set( MINOR_VERSIONS "61" "50" "49" "48" "47" "46" "45" "44" "43" "42" "41" - "40" "39" "38" "37" "36" "35" "34" "33" "32" "31" "30" "29" "28" - "27" "26" "25" "24" "23" "22" "21" "20" "21" "19" "18" "17" "16" - "15" "14" "13" "12" "11" "10" "09" "08" "07" "06" "05" "04" "03" - "02" "01" "00" ) -set( MAJOR_VERSIONS "44" "34" "28" "26" "24" "22" "20" ) - -if( NOT FMOD_DIR_VERSIONS ) - set( FMOD_DIR_VERSIONS "" ) -endif() -if( NOT FMOD_VERSIONS ) - set( FMOD_VERSIONS "" ) -endif() -if( NOT FMOD_LOCAL_INC_DIRS ) - set( FMOD_LOCAL_INC_DIRS "" ) -endif() -if( NOT FMOD_LOCAL_LIB_DIRS ) - set( FMOD_LOCAL_LIB_DIRS "" ) -endif() - -set( FMOD_DIR_VERSIONS ${FMOD_DIR_VERSIONS} "../fmod" ) -foreach( majver ${MAJOR_VERSIONS} ) - foreach( minver ${MINOR_VERSIONS} ) - set( FMOD_VERSIONS ${FMOD_VERSIONS} "fmodex${X64}-4.${majver}.${minver}" ) - # FMOD Ex version 4.44 unified 32-bit and 64-bit linux packages into one. - if( NOT majver EQUAL "44" ) - set( FMOD_DIR_VERSIONS ${FMOD_DIR_VERSIONS} "${CMAKE_HOME_DIRECTORY}/fmodapi4${majver}${minver}linux${X64}" ) - else() - set( FMOD_DIR_VERSIONS ${FMOD_DIR_VERSIONS} "${CMAKE_HOME_DIRECTORY}/fmodapi4${majver}${minver}linux" ) - endif() - endforeach() - foreach( dir ${FMOD_DIR_VERSIONS} ) - set( FMOD_LOCAL_INC_DIRS ${FMOD_LOCAL_INC_DIRS} "${dir}/api/inc" ) - set( FMOD_LOCAL_LIB_DIRS ${FMOD_LOCAL_LIB_DIRS} "${dir}/api/lib" ) - endforeach() -endforeach() if( NOT ZDOOM_LIBS ) set( ZDOOM_LIBS "" ) @@ -100,15 +50,9 @@ if( WIN32 ) add_definitions( -D_WIN32 ) - set( FMOD_SEARCH_PATHS - "C:/Program Files/FMOD SoundSystem/FMOD Programmers API ${WIN_TYPE}/api" - "C:/Program Files (x86)/FMOD SoundSystem/FMOD Programmers API ${WIN_TYPE}/api" - ) - set( FMOD_INC_PATH_SUFFIXES PATH_SUFFIXES inc ) - set( FMOD_LIB_PATH_SUFFIXES PATH_SUFFIXES lib ) if( ( MSVC14 AND NOT CMAKE_GENERATOR_TOOLSET STREQUAL "v140_xp" ) OR # For VS 2015. - ( MSVC15 AND NOT CMAKE_GENERATOR_TOOLSET STREQUAL "v150_xp" ) ) # For VS 2017. + ( MSVC15 AND NOT CMAKE_GENERATOR_TOOLSET STREQUAL "v141_xp" ) ) # For VS 2017. # for modern Windows SDKs the DirectX headers should be available by default. set( DX_dinput8_LIBRARY dinput8 ) set( DX_dxguid_LIBRARY dxguid ) @@ -189,9 +133,6 @@ if( WIN32 ) endif() else() if( APPLE ) - set( FMOD_SEARCH_PATHS "/Developer/FMOD Programmers API Mac/api" ) - set( FMOD_INC_PATH_SUFFIXES PATH_SUFFIXES inc ) - set( FMOD_LIB_PATH_SUFFIXES PATH_SUFFIXES lib ) set( NO_GTK ON ) set( DYN_GTK OFF ) @@ -204,17 +145,6 @@ else() option( NO_GTK "Disable GTK+ dialogs (Not applicable to Windows)" ) option( DYN_GTK "Load GTK+ at runtime instead of compile time" ON ) - set( FMOD_SEARCH_PATHS - /usr/local/include - /usr/local/include/fmodex - /usr/include - /usr/include/fmodex - /opt/local/include - /opt/local/include/fmodex - /opt/include - /opt/include/fmodex ) - set( FMOD_INC_PATH_SUFFIXES PATH_SUFFIXES fmodex ) - # Use GTK+ for the IWAD picker, if available. if( NOT NO_GTK ) pkg_check_modules( GTK3 gtk+-3.0 ) @@ -281,82 +211,6 @@ if( NOT NO_OPENAL ) endif() endif() -if( NOT NO_FMOD ) - # Search for FMOD include files - if( NOT WIN32 ) - find_path( FMOD_INCLUDE_DIR fmod.hpp - PATHS ${FMOD_LOCAL_INC_DIRS} ) - endif() - - if( NOT FMOD_INCLUDE_DIR ) - find_path( FMOD_INCLUDE_DIR fmod.hpp - PATHS ${FMOD_SEARCH_PATHS} - ${FMOD_INC_PATH_SUFFIXES} ) - endif() - - if( FMOD_INCLUDE_DIR ) - message( STATUS "FMOD include files found at ${FMOD_INCLUDE_DIR}" ) - include_directories( "${FMOD_INCLUDE_DIR}" ) - - if( EXISTS "${FMOD_INCLUDE_DIR}/fmod_common.h" ) - set( FMOD_STUDIO YES ) - set( FMOD_VERSION_FILE "fmod_common.h" ) - else() - set( FMOD_STUDIO NO ) - set( FMOD_VERSION_FILE "fmod.h" ) - endif() - - file( STRINGS "${FMOD_INCLUDE_DIR}/${FMOD_VERSION_FILE}" FMOD_VERSION_LINE REGEX "^#define[ \t]+FMOD_VERSION[ \t]+0x[0-9]+$" ) - string( REGEX REPLACE "^#define[ \t]+FMOD_VERSION[ \t]+0x([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])$" "\\1.\\2.\\3" FMOD_VERSION "${FMOD_VERSION_LINE}" ) - message( STATUS "FMOD version: ${FMOD_VERSION}" ) - - # FMOD Ex didn't hide xiph symbols in the past (not applicable to Win32 since symbols are hidden by default there). - if( NOT WIN32 AND NOT FMOD_STUDIO AND NOT NO_OPENAL AND "${FMOD_VERSION}" VERSION_LESS "4.36.00") - message( SEND_ERROR "Use of FMOD Ex ${FMOD_VERSION} with OpenAL will result in crashes. Either update FMOD to 4.36 or later or set NO_OPENAL." ) - endif() - else() - message( STATUS "Could not find FMOD include files" ) - set( NO_FMOD ON ) - endif() -endif() - -if( NOT NO_FMOD ) - # Decide on the name of the FMOD library we want to use. - if( NOT FMOD_LIB_NAME AND MSVC ) - set( FMOD_LIB_NAME fmodex${X64}_vc ) - endif() - - if( NOT FMOD_LIB_NAME AND BORLAND ) - set( FMOD_LIB_NAME fmodex${X64}_bc ) - endif() - - if( NOT FMOD_LIB_NAME ) - set( FMOD_LIB_NAME fmodex${X64} ) - endif() - - # Search for FMOD library - if( WIN32 OR APPLE ) - find_library( FMOD_LIBRARY ${FMOD_LIB_NAME} - PATHS ${FMOD_SEARCH_PATHS} - ${FMOD_LIB_PATH_SUFFIXES} ) - else() - find_library( FMOD_LIBRARY - NAMES ${FMOD_VERSIONS} - PATHS ${FMOD_LOCAL_LIB_DIRS} ) - endif() - - if( FMOD_LIBRARY ) - message( STATUS "FMOD library found at ${FMOD_LIBRARY}" ) - set( ZDOOM_LIBS ${ZDOOM_LIBS} "${FMOD_LIBRARY}" ) - else() - message( STATUS "Could not find FMOD library" ) - set( NO_FMOD ON ) - endif() -endif() - -if( NO_FMOD ) - add_definitions( -DNO_FMOD=1 ) -endif() if( NO_OPENAL ) add_definitions( -DNO_OPENAL=1 ) @@ -683,10 +537,9 @@ elseif( APPLE ) set( OTHER_SYSTEM_SOURCES ${PLAT_WIN32_SOURCES} ${PLAT_COCOA_SOURCES} ${PLAT_UNIX_SOURCES} ) endif() - set( SYSTEM_SOURCES ${SYSTEM_SOURCES} ${PLAT_POSIX_SOURCES} ${PLAT_OSX_SOURCES} "${FMOD_LIBRARY}" ) + set( SYSTEM_SOURCES ${SYSTEM_SOURCES} ${PLAT_POSIX_SOURCES} ${PLAT_OSX_SOURCES} ) set_source_files_properties( posix/osx/zdoom.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources ) - set_source_files_properties( "${FMOD_LIBRARY}" PROPERTIES MACOSX_PACKAGE_LOCATION Frameworks ) set_source_files_properties( posix/osx/iwadpicker_cocoa.mm PROPERTIES COMPILE_FLAGS -fobjc-exceptions ) else() set( SYSTEM_SOURCES_DIR posix posix/sdl ) @@ -901,7 +754,6 @@ set( FASTMATH_SOURCES swrenderer/r_all.cpp polyrenderer/poly_all.cpp sound/oplsynth/opl_mus_player.cpp - sound/fmodsound.cpp sound/mpg123_decoder.cpp sound/music_midi_base.cpp sound/oalsound.cpp @@ -1372,14 +1224,6 @@ if( MSVC ) option( ZDOOM_GENERATE_MAPFILE "Generate .map file for debugging." OFF ) set( LINKERSTUFF "/MANIFEST:NO" ) - if( NOT NO_FMOD ) - if( FMOD_STUDIO ) - set( LINKERSTUFF "${LINKERSTUFF} /DELAYLOAD:\"fmod${X64}.dll\"" ) - else() - set( LINKERSTUFF "${LINKERSTUFF} /DELAYLOAD:\"fmodex${X64}.dll\"" ) - endif() - endif() - if( ZDOOM_GENERATE_MAPFILE ) set( LINKERSTUFF "${LINKERSTUFF} /MAP" ) endif() @@ -1418,26 +1262,6 @@ if( APPLE ) LINK_FLAGS "-framework AudioToolbox -framework AudioUnit -framework Carbon -framework Cocoa -framework IOKit -framework OpenGL" MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/posix/osx/zdoom-info.plist" ) - if( NOT NO_FMOD ) - if( FMOD_STUDIO ) - set( FMOD_DYLIB libfmod.dylib ) - else() - set( FMOD_DYLIB libfmodex.dylib ) - endif() - - # Fix fmod link so that it can be found in the app bundle. - find_program( OTOOL otool HINTS "/usr/bin" "${OSX_DEVELOPER_ROOT}/usr/bin" ) - find_program( INSTALL_NAME_TOOL install_name_tool HINTS "/usr/bin" "${OSX_DEVELOPER_ROOT}/usr/bin" ) - execute_process( COMMAND "${OTOOL}" -L "${FMOD_LIBRARY}" - COMMAND grep "${FMOD_DYLIB} (compat" - COMMAND head -n1 - COMMAND awk "{print $1}" - OUTPUT_VARIABLE FMOD_LINK - OUTPUT_STRIP_TRAILING_WHITESPACE ) - add_custom_command( TARGET zdoom POST_BUILD - COMMAND "${INSTALL_NAME_TOOL}" -change "${FMOD_LINK}" @executable_path/../Frameworks/${FMOD_DYLIB} "$" - COMMENT "Relinking FMOD Ex" ) - endif() endif() if( WIN32 ) diff --git a/src/menu/menudef.cpp b/src/menu/menudef.cpp index a14ac25b3..d3a2ee49f 100644 --- a/src/menu/menudef.cpp +++ b/src/menu/menudef.cpp @@ -247,10 +247,6 @@ static bool CheckSkipOptionBlock(FScanner &sc) { filter |= IsOpenALPresent(); } - else if (sc.Compare("FModEx")) - { - filter |= IsFModExPresent(); - } } while (sc.CheckString(",")); sc.MustGetStringName(")"); diff --git a/src/s_sound.cpp b/src/s_sound.cpp index 75f6a68a8..f5fc2ed13 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -140,6 +140,7 @@ CUSTOM_CVAR (Int, snd_channels, 128, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) // number o if (self < 64) self = 64; } CVAR (Bool, snd_flipstereo, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +CVAR(Bool, snd_waterreverb, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) // CODE -------------------------------------------------------------------- diff --git a/src/sound/fmod_wrap.h b/src/sound/fmod_wrap.h deleted file mode 100644 index 02d6a56ae..000000000 --- a/src/sound/fmod_wrap.h +++ /dev/null @@ -1,624 +0,0 @@ - -#ifndef FMOD_WRAP_H -#define FMOD_WRAP_H - -#ifndef NO_FMOD - -#if !defined(_WIN32) || defined(_MSC_VER) -// Use the real C++ interface if it's supported on this platform. -#include "fmod.hpp" -#else -// Use a wrapper C++ interface for non-Microsoft compilers on Windows. - -#include "fmod.h" - -// Create fake definitions for these structs so they can be subclassed. -struct FMOD_SYSTEM {}; -struct FMOD_SOUND {}; -struct FMOD_CHANNEL {}; -struct FMOD_CHANNELGROUP {}; -struct FMOD_SOUNDGROUP {}; -struct FMOD_REVERB {}; -struct FMOD_DSP {}; -struct FMOD_DSPCONNECTION {}; -struct FMOD_POLYGON {}; -struct FMOD_GEOMETRY {}; -struct FMOD_SYNCPOINT {}; -/* - Constant and defines -*/ - -/* - FMOD Namespace -*/ - -namespace FMOD -{ - - class System; - class Sound; - class Channel; - class ChannelGroup; - class SoundGroup; - class Reverb; - class DSP; - class DSPConnection; - class Geometry; - - /* - FMOD global system functions (optional). - */ - inline FMOD_RESULT Memory_Initialize(void *poolmem, int poollen, FMOD_MEMORY_ALLOCCALLBACK useralloc, FMOD_MEMORY_REALLOCCALLBACK userrealloc, FMOD_MEMORY_FREECALLBACK userfree, FMOD_MEMORY_TYPE memtypeflags = (FMOD_MEMORY_NORMAL | FMOD_MEMORY_XBOX360_PHYSICAL)) { return FMOD_Memory_Initialize(poolmem, poollen, useralloc, userrealloc, userfree, memtypeflags); } - //inline FMOD_RESULT Memory_GetStats (int *currentalloced, int *maxalloced) { return FMOD_Memory_GetStats(currentalloced, maxalloced); } - inline FMOD_RESULT Debug_SetLevel(FMOD_DEBUGLEVEL level) { return FMOD_Debug_SetLevel(level); } - inline FMOD_RESULT Debug_GetLevel(FMOD_DEBUGLEVEL *level) { return FMOD_Debug_GetLevel(level); } - inline FMOD_RESULT File_SetDiskBusy(int busy) { return FMOD_File_SetDiskBusy(busy); } - inline FMOD_RESULT File_GetDiskBusy(int *busy) { return FMOD_File_GetDiskBusy(busy); } - - /* - FMOD System factory functions. - */ - inline FMOD_RESULT System_Create(System **system) { return FMOD_System_Create((FMOD_SYSTEM **)system); } - - /* - 'System' API - */ - - class System : FMOD_SYSTEM - { - private: - - System(); /* Constructor made private so user cannot statically instance a System class. - System_Create must be used. */ - public: - - FMOD_RESULT release () { return FMOD_System_Release(this); } - - // Pre-init functions. - FMOD_RESULT setOutput (FMOD_OUTPUTTYPE output) { return FMOD_System_SetOutput(this, output); } - FMOD_RESULT getOutput (FMOD_OUTPUTTYPE *output) { return FMOD_System_GetOutput(this, output); } - FMOD_RESULT getNumDrivers (int *numdrivers) { return FMOD_System_GetNumDrivers(this, numdrivers); } - FMOD_RESULT getDriverInfo (int id, char *name, int namelen, FMOD_GUID *guid) { return FMOD_System_GetDriverInfo(this, id, name, namelen, guid); } - FMOD_RESULT getDriverCaps (int id, FMOD_CAPS *caps, int *minfrequency, int *maxfrequency, FMOD_SPEAKERMODE *controlpanelspeakermode) { return FMOD_System_GetDriverCaps(this, id, caps, minfrequency, maxfrequency, controlpanelspeakermode); } - FMOD_RESULT setDriver (int driver) { return FMOD_System_SetDriver(this, driver); } - FMOD_RESULT getDriver (int *driver) { return FMOD_System_GetDriver(this, driver); } - FMOD_RESULT setHardwareChannels (int min2d, int max2d, int min3d, int max3d) { return FMOD_System_SetHardwareChannels(this, min2d, max2d, min3d, max3d); } - FMOD_RESULT setSoftwareChannels (int numsoftwarechannels) { return FMOD_System_SetSoftwareChannels(this, numsoftwarechannels); } - FMOD_RESULT getSoftwareChannels (int *numsoftwarechannels) { return FMOD_System_GetSoftwareChannels(this, numsoftwarechannels); } - FMOD_RESULT setSoftwareFormat (int samplerate, FMOD_SOUND_FORMAT format, int numoutputchannels, int maxinputchannels, FMOD_DSP_RESAMPLER resamplemethod) { return FMOD_System_SetSoftwareFormat(this, samplerate, format, numoutputchannels, maxinputchannels, resamplemethod); } - FMOD_RESULT getSoftwareFormat (int *samplerate, FMOD_SOUND_FORMAT *format, int *numoutputchannels, int *maxinputchannels, FMOD_DSP_RESAMPLER *resamplemethod, int *bits) { return FMOD_System_GetSoftwareFormat(this, samplerate, format, numoutputchannels, maxinputchannels, resamplemethod, bits); } - FMOD_RESULT setDSPBufferSize (unsigned int bufferlength, int numbuffers) { return FMOD_System_SetDSPBufferSize(this, bufferlength, numbuffers); } - FMOD_RESULT getDSPBufferSize (unsigned int *bufferlength, int *numbuffers) { return FMOD_System_GetDSPBufferSize(this, bufferlength, numbuffers); } - FMOD_RESULT setFileSystem (FMOD_FILE_OPENCALLBACK useropen, FMOD_FILE_CLOSECALLBACK userclose, FMOD_FILE_READCALLBACK userread, FMOD_FILE_SEEKCALLBACK userseek, int blockalign) { return FMOD_System_SetFileSystem(this, useropen, userclose, userread, userseek, blockalign); } - FMOD_RESULT attachFileSystem (FMOD_FILE_OPENCALLBACK useropen, FMOD_FILE_CLOSECALLBACK userclose, FMOD_FILE_READCALLBACK userread, FMOD_FILE_SEEKCALLBACK userseek) { return FMOD_System_AttachFileSystem(this, useropen, userclose, userread, userseek); } - FMOD_RESULT setAdvancedSettings (FMOD_ADVANCEDSETTINGS *settings) { return FMOD_System_SetAdvancedSettings(this, settings); } - FMOD_RESULT getAdvancedSettings (FMOD_ADVANCEDSETTINGS *settings) { return FMOD_System_GetAdvancedSettings(this, settings); } - FMOD_RESULT setSpeakerMode (FMOD_SPEAKERMODE speakermode) { return FMOD_System_SetSpeakerMode(this, speakermode); } - FMOD_RESULT getSpeakerMode (FMOD_SPEAKERMODE *speakermode) { return FMOD_System_GetSpeakerMode(this, speakermode); } - FMOD_RESULT setCallback (FMOD_SYSTEM_CALLBACK callback) { return FMOD_System_SetCallback(this, callback); } - - // Plug-in support - FMOD_RESULT setPluginPath (const char *path) { return FMOD_System_SetPluginPath(this, path); } - FMOD_RESULT loadPlugin (const char *filename, unsigned int *handle, unsigned int priority = 0) { return FMOD_System_LoadPlugin(this, filename, handle, priority); } - FMOD_RESULT unloadPlugin (unsigned int handle) { return FMOD_System_UnloadPlugin(this, handle); } - FMOD_RESULT getNumPlugins (FMOD_PLUGINTYPE plugintype, int *numplugins) { return FMOD_System_GetNumPlugins(this, plugintype, numplugins); } - FMOD_RESULT getPluginHandle (FMOD_PLUGINTYPE plugintype, int index, unsigned int *handle) { return FMOD_System_GetPluginHandle(this, plugintype, index, handle); } - FMOD_RESULT getPluginInfo (unsigned int handle, FMOD_PLUGINTYPE *plugintype, char *name, int namelen, unsigned int *version) { return FMOD_System_GetPluginInfo(this, handle, plugintype, name, namelen, version); } - FMOD_RESULT setOutputByPlugin (unsigned int handle) { return FMOD_System_SetOutputByPlugin(this, handle); } - FMOD_RESULT getOutputByPlugin (unsigned int *handle) { return FMOD_System_GetOutputByPlugin(this, handle); } - FMOD_RESULT createCodec (FMOD_CODEC_DESCRIPTION *description, unsigned int priority = 0) { return FMOD_System_CreateCodec(this, description, priority); } - - // Init/Close - FMOD_RESULT init (int maxchannels, FMOD_INITFLAGS flags, void *extradriverdata) { return FMOD_System_Init(this, maxchannels, flags, extradriverdata); } - FMOD_RESULT close () { return FMOD_System_Close(this); } - - // General post-init system functions - FMOD_RESULT update () /* IMPORTANT! CALL THIS ONCE PER FRAME! */ { return FMOD_System_Update(this); } - - FMOD_RESULT set3DSettings (float dopplerscale, float distancefactor, float rolloffscale) { return FMOD_System_Set3DSettings(this, dopplerscale, distancefactor, rolloffscale); } - FMOD_RESULT get3DSettings (float *dopplerscale, float *distancefactor, float *rolloffscale) { return FMOD_System_Get3DSettings(this, dopplerscale, distancefactor, rolloffscale); } - FMOD_RESULT set3DNumListeners (int numlisteners) { return FMOD_System_Set3DNumListeners(this, numlisteners); } - FMOD_RESULT get3DNumListeners (int *numlisteners) { return FMOD_System_Get3DNumListeners(this, numlisteners); } - FMOD_RESULT set3DListenerAttributes(int listener, const FMOD_VECTOR *pos, const FMOD_VECTOR *vel, const FMOD_VECTOR *forward, const FMOD_VECTOR *up) { return FMOD_System_Set3DListenerAttributes(this, listener, pos, vel, forward, up); } - FMOD_RESULT get3DListenerAttributes(int listener, FMOD_VECTOR *pos, FMOD_VECTOR *vel, FMOD_VECTOR *forward, FMOD_VECTOR *up) { return FMOD_System_Get3DListenerAttributes(this, listener, pos, vel, forward, up); } - FMOD_RESULT set3DRolloffCallback (FMOD_3D_ROLLOFFCALLBACK callback) { return FMOD_System_Set3DRolloffCallback(this, callback); } - FMOD_RESULT set3DSpeakerPosition (FMOD_SPEAKER speaker, float x, float y, bool active) { return FMOD_System_Set3DSpeakerPosition(this, speaker, x, y, active); } - FMOD_RESULT get3DSpeakerPosition (FMOD_SPEAKER speaker, float *x, float *y, bool *active) { FMOD_BOOL b; FMOD_RESULT res = FMOD_System_Get3DSpeakerPosition(this, speaker, x, y, &b); *active = b; return res; } - - FMOD_RESULT setStreamBufferSize (unsigned int filebuffersize, FMOD_TIMEUNIT filebuffersizetype) { return FMOD_System_SetStreamBufferSize(this, filebuffersize, filebuffersizetype); } - FMOD_RESULT getStreamBufferSize (unsigned int *filebuffersize, FMOD_TIMEUNIT *filebuffersizetype) { return FMOD_System_GetStreamBufferSize(this, filebuffersize, filebuffersizetype); } - - // System information functions. - FMOD_RESULT getVersion (unsigned int *version) { return FMOD_System_GetVersion(this, version); } - FMOD_RESULT getOutputHandle (void **handle) { return FMOD_System_GetOutputHandle(this, handle); } - FMOD_RESULT getChannelsPlaying (int *channels) { return FMOD_System_GetChannelsPlaying(this, channels); } - FMOD_RESULT getHardwareChannels (int *num2d, int *num3d, int *total) { return FMOD_System_GetHardwareChannels(this, num2d, num3d, total); } -#if FMOD_VERSION < 0x42501 - FMOD_RESULT getCPUUsage (float *dsp, float *stream, float *update, float *total) { return FMOD_System_GetCPUUsage(this, dsp, stream, update, total); } -#else - FMOD_RESULT getCPUUsage (float *dsp, float *stream, float *geometry, float *update, float *total) { return FMOD_System_GetCPUUsage(this, dsp, stream, geometry, update, total); } -#endif - FMOD_RESULT getSoundRAM (int *currentalloced, int *maxalloced, int *total) { return FMOD_System_GetSoundRAM(this, currentalloced, maxalloced, total); } - FMOD_RESULT getNumCDROMDrives (int *numdrives) { return FMOD_System_GetNumCDROMDrives(this, numdrives); } - FMOD_RESULT getCDROMDriveName (int drive, char *drivename, int drivenamelen, char *scsiname, int scsinamelen, char *devicename, int devicenamelen) { return FMOD_System_GetCDROMDriveName(this, drive, drivename, drivenamelen, scsiname, scsinamelen, devicename, devicenamelen); } - FMOD_RESULT getSpectrum (float *spectrumarray, int numvalues, int channeloffset, FMOD_DSP_FFT_WINDOW windowtype) { return FMOD_System_GetSpectrum(this, spectrumarray, numvalues, channeloffset, windowtype); } - FMOD_RESULT getWaveData (float *wavearray, int numvalues, int channeloffset) { return FMOD_System_GetWaveData(this, wavearray, numvalues, channeloffset); } - - // Sound/DSP/Channel/FX creation and retrieval. - FMOD_RESULT createSound (const char *name_or_data, FMOD_MODE mode, FMOD_CREATESOUNDEXINFO *exinfo, Sound **sound) { return FMOD_System_CreateSound(this, name_or_data, mode, exinfo, (FMOD_SOUND **)sound); } - FMOD_RESULT createStream (const char *name_or_data, FMOD_MODE mode, FMOD_CREATESOUNDEXINFO *exinfo, Sound **sound) { return FMOD_System_CreateStream(this, name_or_data, mode, exinfo, (FMOD_SOUND **)sound); } - FMOD_RESULT createDSP (FMOD_DSP_DESCRIPTION *description, DSP **dsp) { return FMOD_System_CreateDSP(this, description, (FMOD_DSP **)dsp); } - FMOD_RESULT createDSPByType (FMOD_DSP_TYPE type, DSP **dsp) { return FMOD_System_CreateDSPByType(this, type, (FMOD_DSP **)dsp); } - FMOD_RESULT createChannelGroup (const char *name, ChannelGroup **channelgroup) { return FMOD_System_CreateChannelGroup(this, name, (FMOD_CHANNELGROUP **)channelgroup); } - FMOD_RESULT createSoundGroup (const char *name, SoundGroup **soundgroup) { return FMOD_System_CreateSoundGroup(this, name, (FMOD_SOUNDGROUP **)soundgroup); } - FMOD_RESULT createReverb (Reverb **reverb) { return FMOD_System_CreateReverb(this, (FMOD_REVERB **)reverb); } - - FMOD_RESULT playSound (FMOD_CHANNELINDEX channelid, Sound *sound, bool paused, Channel **channel) { return FMOD_System_PlaySound(this, channelid, (FMOD_SOUND *)sound, paused, (FMOD_CHANNEL **)channel); } - FMOD_RESULT playDSP (FMOD_CHANNELINDEX channelid, DSP *dsp, bool paused, Channel **channel) { return FMOD_System_PlayDSP(this, channelid, (FMOD_DSP *)dsp, paused, (FMOD_CHANNEL **)channel); } - FMOD_RESULT getChannel (int channelid, Channel **channel) { return FMOD_System_GetChannel(this, channelid, (FMOD_CHANNEL **)channel); } - FMOD_RESULT getMasterChannelGroup (ChannelGroup **channelgroup) { return FMOD_System_GetMasterChannelGroup(this, (FMOD_CHANNELGROUP **)channelgroup); } - FMOD_RESULT getMasterSoundGroup (SoundGroup **soundgroup) { return FMOD_System_GetMasterSoundGroup(this, (FMOD_SOUNDGROUP **)soundgroup); } - - // Reverb API - FMOD_RESULT setReverbProperties (const FMOD_REVERB_PROPERTIES *prop) { return FMOD_System_SetReverbProperties(this, prop); } - FMOD_RESULT getReverbProperties (FMOD_REVERB_PROPERTIES *prop) { return FMOD_System_GetReverbProperties(this, prop); } - FMOD_RESULT setReverbAmbientProperties(FMOD_REVERB_PROPERTIES *prop) { return FMOD_System_SetReverbAmbientProperties(this, prop); } - FMOD_RESULT getReverbAmbientProperties(FMOD_REVERB_PROPERTIES *prop) { return FMOD_System_GetReverbAmbientProperties(this, prop); } - - // System level DSP access. - FMOD_RESULT getDSPHead (DSP **dsp) { return FMOD_System_GetDSPHead(this, (FMOD_DSP **)dsp); } - FMOD_RESULT addDSP (DSP *dsp, DSPConnection **connection) { return FMOD_System_AddDSP(this, (FMOD_DSP *)dsp, (FMOD_DSPCONNECTION**)dsp); } - FMOD_RESULT lockDSP () { return FMOD_System_LockDSP(this); } - FMOD_RESULT unlockDSP () { return FMOD_System_UnlockDSP(this); } - FMOD_RESULT getDSPClock (unsigned int *hi, unsigned int *lo) { return FMOD_System_GetDSPClock(this, hi, lo); } - - // Recording API. - FMOD_RESULT getRecordNumDrivers (int *numdrivers) { return FMOD_System_GetRecordNumDrivers(this, numdrivers); } - FMOD_RESULT getRecordDriverInfo (int id, char *name, int namelen, FMOD_GUID *guid) { return FMOD_System_GetRecordDriverInfo(this, id, name, namelen, guid); } - FMOD_RESULT getRecordDriverCaps (int id, FMOD_CAPS *caps, int *minfrequency, int *maxfrequency) { return FMOD_System_GetRecordDriverCaps(this, id, caps, minfrequency, maxfrequency); } - FMOD_RESULT getRecordPosition (int id, unsigned int *position) { return FMOD_System_GetRecordPosition(this, id, position); } - - FMOD_RESULT recordStart (int id, Sound *sound, bool loop) { return FMOD_System_RecordStart(this, id, (FMOD_SOUND *)sound, loop); } - FMOD_RESULT recordStop (int id) { return FMOD_System_RecordStop(this, id); } - FMOD_RESULT isRecording (int id, bool *recording) { FMOD_BOOL b; FMOD_RESULT res = FMOD_System_IsRecording(this, id, &b); *recording = b; return res; } - - // Geometry API. - FMOD_RESULT createGeometry (int maxpolygons, int maxvertices, Geometry **geometry) { return FMOD_System_CreateGeometry(this, maxpolygons, maxvertices, (FMOD_GEOMETRY **)geometry); } - FMOD_RESULT setGeometrySettings (float maxworldsize) { return FMOD_System_SetGeometrySettings(this, maxworldsize); } - FMOD_RESULT getGeometrySettings (float *maxworldsize) { return FMOD_System_GetGeometrySettings(this, maxworldsize); } - FMOD_RESULT loadGeometry (const void *data, int datasize, Geometry **geometry) { return FMOD_System_LoadGeometry(this, data, datasize, (FMOD_GEOMETRY **)geometry); } - - // Network functions. - FMOD_RESULT setNetworkProxy (const char *proxy) { return FMOD_System_SetNetworkProxy(this, proxy); } - FMOD_RESULT getNetworkProxy (char *proxy, int proxylen) { return FMOD_System_GetNetworkProxy(this, proxy, proxylen); } - FMOD_RESULT setNetworkTimeout (int timeout) { return FMOD_System_SetNetworkTimeout(this, timeout); } - FMOD_RESULT getNetworkTimeout (int *timeout) { return FMOD_System_GetNetworkTimeout(this, timeout); } - - // Userdata set/get. - FMOD_RESULT setUserData (void *userdata) { return FMOD_System_SetUserData(this, userdata); } - FMOD_RESULT getUserData (void **userdata) { return FMOD_System_GetUserData(this, userdata); } - - FMOD_RESULT getMemoryInfo (unsigned int memorybits, unsigned int event_memorybits, unsigned int *memoryused, unsigned int *memoryused_array) { return FMOD_System_GetMemoryInfo(this, memorybits, event_memorybits, memoryused, memoryused_array); } - }; - - /* - 'Sound' API - */ - class Sound : FMOD_SOUND - { - private: - - Sound(); /* Constructor made private so user cannot statically instance a Sound class. - Appropriate Sound creation or retrieval function must be used. */ - public: - - FMOD_RESULT release () { return FMOD_Sound_Release(this); } - FMOD_RESULT getSystemObject (System **system) { return FMOD_Sound_GetSystemObject(this, (FMOD_SYSTEM **)system); } - - // Standard sound manipulation functions. - FMOD_RESULT lock (unsigned int offset, unsigned int length, void **ptr1, void **ptr2, unsigned int *len1, unsigned int *len2) { return FMOD_Sound_Lock(this, offset, length, ptr1, ptr2, len1, len2); } - FMOD_RESULT unlock (void *ptr1, void *ptr2, unsigned int len1, unsigned int len2) { return FMOD_Sound_Unlock(this, ptr1, ptr2, len1, len2); } - FMOD_RESULT setDefaults (float frequency, float volume, float pan, int priority) { return FMOD_Sound_SetDefaults(this, frequency, volume, pan, priority); } - FMOD_RESULT getDefaults (float *frequency, float *volume, float *pan, int *priority) { return FMOD_Sound_GetDefaults(this, frequency, volume, pan, priority); } - FMOD_RESULT setVariations (float frequencyvar, float volumevar, float panvar) { return FMOD_Sound_SetVariations(this, frequencyvar, volumevar, panvar); } - FMOD_RESULT getVariations (float *frequencyvar, float *volumevar, float *panvar) { return FMOD_Sound_GetVariations(this, frequencyvar, volumevar, panvar); } - FMOD_RESULT set3DMinMaxDistance (float min, float max) { return FMOD_Sound_Set3DMinMaxDistance(this, min, max); } - FMOD_RESULT get3DMinMaxDistance (float *min, float *max) { return FMOD_Sound_Get3DMinMaxDistance(this, min, max); } - FMOD_RESULT set3DConeSettings (float insideconeangle, float outsideconeangle, float outsidevolume) { return FMOD_Sound_Set3DConeSettings(this, insideconeangle, outsideconeangle, outsidevolume); } - FMOD_RESULT get3DConeSettings (float *insideconeangle, float *outsideconeangle, float *outsidevolume) { return FMOD_Sound_Get3DConeSettings(this, insideconeangle, outsideconeangle, outsidevolume); } - FMOD_RESULT set3DCustomRolloff (FMOD_VECTOR *points, int numpoints) { return FMOD_Sound_Set3DCustomRolloff(this, points, numpoints); } - FMOD_RESULT get3DCustomRolloff (FMOD_VECTOR **points, int *numpoints) { return FMOD_Sound_Get3DCustomRolloff(this, points, numpoints); } - FMOD_RESULT setSubSound (int index, Sound *subsound) { return FMOD_Sound_SetSubSound(this, index, subsound); } - FMOD_RESULT getSubSound (int index, Sound **subsound) { return FMOD_Sound_GetSubSound(this, index, (FMOD_SOUND **)subsound); } - FMOD_RESULT setSubSoundSentence (int *subsoundlist, int numsubsounds) { return FMOD_Sound_SetSubSoundSentence(this, subsoundlist, numsubsounds); } - FMOD_RESULT getName (char *name, int namelen) { return FMOD_Sound_GetName(this, name, namelen); } - FMOD_RESULT getLength (unsigned int *length, FMOD_TIMEUNIT lengthtype) { return FMOD_Sound_GetLength(this, length, lengthtype); } - FMOD_RESULT getFormat (FMOD_SOUND_TYPE *type, FMOD_SOUND_FORMAT *format, int *channels, int *bits) { return FMOD_Sound_GetFormat(this, type, format, channels, bits); } - FMOD_RESULT getNumSubSounds (int *numsubsounds) { return FMOD_Sound_GetNumSubSounds(this, numsubsounds); } - FMOD_RESULT getNumTags (int *numtags, int *numtagsupdated) { return FMOD_Sound_GetNumTags(this, numtags, numtagsupdated); } - FMOD_RESULT getTag (const char *name, int index, FMOD_TAG *tag) { return FMOD_Sound_GetTag(this, name, index, tag); } - FMOD_RESULT getOpenState (FMOD_OPENSTATE *openstate, unsigned int *percentbuffered, bool *starving) { FMOD_BOOL b; FMOD_RESULT res = FMOD_Sound_GetOpenState(this, openstate, percentbuffered, &b); *starving = b; return res; } - FMOD_RESULT readData (void *buffer, unsigned int lenbytes, unsigned int *read) { return FMOD_Sound_ReadData(this, buffer, lenbytes, read); } - FMOD_RESULT seekData (unsigned int pcm) { return FMOD_Sound_SeekData(this, pcm); } - - FMOD_RESULT setSoundGroup (SoundGroup *soundgroup) { return FMOD_Sound_SetSoundGroup(this, (FMOD_SOUNDGROUP *)soundgroup); } - FMOD_RESULT getSoundGroup (SoundGroup **soundgroup) { return FMOD_Sound_GetSoundGroup(this, (FMOD_SOUNDGROUP **)soundgroup); } - - // Synchronization point API. These points can come from markers embedded in wav files, and can also generate channel callbacks. - FMOD_RESULT getNumSyncPoints (int *numsyncpoints) { return FMOD_Sound_GetNumSyncPoints(this, numsyncpoints); } - FMOD_RESULT getSyncPoint (int index, FMOD_SYNCPOINT **point) { return FMOD_Sound_GetSyncPoint(this, index, point); } - FMOD_RESULT getSyncPointInfo (FMOD_SYNCPOINT *point, char *name, int namelen, unsigned int *offset, FMOD_TIMEUNIT offsettype) { return FMOD_Sound_GetSyncPointInfo(this, point, name, namelen, offset, offsettype); } - FMOD_RESULT addSyncPoint (unsigned int offset, FMOD_TIMEUNIT offsettype, const char *name, FMOD_SYNCPOINT **point) { return FMOD_Sound_AddSyncPoint(this, offset, offsettype, name, point); } - FMOD_RESULT deleteSyncPoint (FMOD_SYNCPOINT *point) { return FMOD_Sound_DeleteSyncPoint(this, point); } - - // Functions also in Channel class but here they are the 'default' to save having to change it in Channel all the time. - FMOD_RESULT setMode (FMOD_MODE mode) { return FMOD_Sound_SetMode(this, mode); } - FMOD_RESULT getMode (FMOD_MODE *mode) { return FMOD_Sound_GetMode(this, mode); } - FMOD_RESULT setLoopCount (int loopcount) { return FMOD_Sound_SetLoopCount(this, loopcount); } - FMOD_RESULT getLoopCount (int *loopcount) { return FMOD_Sound_GetLoopCount(this, loopcount); } - FMOD_RESULT setLoopPoints (unsigned int loopstart, FMOD_TIMEUNIT loopstarttype, unsigned int loopend, FMOD_TIMEUNIT loopendtype) { return FMOD_Sound_SetLoopPoints(this, loopstart, loopstarttype, loopend, loopendtype); } - FMOD_RESULT getLoopPoints (unsigned int *loopstart, FMOD_TIMEUNIT loopstarttype, unsigned int *loopend, FMOD_TIMEUNIT loopendtype) { return FMOD_Sound_GetLoopPoints(this, loopstart, loopstarttype, loopend, loopendtype); } - - // Userdata set/get. - FMOD_RESULT setUserData (void *userdata) { return FMOD_Sound_SetUserData(this, userdata); } - FMOD_RESULT getUserData (void **userdata) { return FMOD_Sound_GetUserData(this, userdata); } - - FMOD_RESULT getMemoryInfo (unsigned int memorybits, unsigned int event_memorybits, unsigned int *memoryused, unsigned int *memoryused_array) { return FMOD_Sound_GetMemoryInfo(this, memorybits, event_memorybits, memoryused, memoryused_array); } - }; - - /* - 'Channel' API. - */ - class Channel : FMOD_CHANNEL - { - private: - - Channel(); /* Constructor made private so user cannot statically instance a Channel class. - Appropriate Channel creation or retrieval function must be used. */ - public: - - FMOD_RESULT getSystemObject (System **system) { return FMOD_Channel_GetSystemObject(this, (FMOD_SYSTEM **)system); } - - FMOD_RESULT stop () { return FMOD_Channel_Stop(this); } - FMOD_RESULT setPaused (bool paused) { return FMOD_Channel_SetPaused(this, paused); } - FMOD_RESULT getPaused (bool *paused) { FMOD_BOOL b; FMOD_RESULT res = FMOD_Channel_GetPaused(this, &b); *paused = b; return res; } - FMOD_RESULT setVolume (float volume) { return FMOD_Channel_SetVolume(this, volume); } - FMOD_RESULT getVolume (float *volume) { return FMOD_Channel_GetVolume(this, volume); } - FMOD_RESULT setFrequency (float frequency) { return FMOD_Channel_SetFrequency(this, frequency); } - FMOD_RESULT getFrequency (float *frequency) { return FMOD_Channel_GetFrequency(this, frequency); } - FMOD_RESULT setPan (float pan) { return FMOD_Channel_SetPan(this, pan); } - FMOD_RESULT getPan (float *pan) { return FMOD_Channel_GetPan(this, pan); } - FMOD_RESULT setDelay (FMOD_DELAYTYPE delaytype, unsigned int delayhi, unsigned int delaylo) { return FMOD_Channel_SetDelay(this, delaytype, delayhi, delaylo); } - FMOD_RESULT getDelay (FMOD_DELAYTYPE delaytype, unsigned int *delayhi, unsigned int *delaylo) { return FMOD_Channel_GetDelay(this, delaytype, delayhi, delaylo); } - FMOD_RESULT setSpeakerMix (float frontleft, float frontright, float center, float lfe, float backleft, float backright, float sideleft, float sideright) { return FMOD_Channel_SetSpeakerMix(this, frontleft, frontright, center, lfe, backleft, backright, sideleft, sideright); } - FMOD_RESULT getSpeakerMix (float *frontleft, float *frontright, float *center, float *lfe, float *backleft, float *backright, float *sideleft, float *sideright) { return FMOD_Channel_GetSpeakerMix(this, frontleft, frontright, center, lfe, backleft, backright, sideleft, sideright); } - FMOD_RESULT setSpeakerLevels (FMOD_SPEAKER speaker, float *levels, int numlevels) { return FMOD_Channel_SetSpeakerLevels(this, speaker, levels, numlevels); } - FMOD_RESULT getSpeakerLevels (FMOD_SPEAKER speaker, float *levels, int numlevels) { return FMOD_Channel_GetSpeakerLevels(this, speaker, levels, numlevels); } - FMOD_RESULT setInputChannelMix (float *levels, int numlevels) { return FMOD_Channel_SetInputChannelMix(this, levels, numlevels); } - FMOD_RESULT getInputChannelMix (float *levels, int numlevels) { return FMOD_Channel_GetInputChannelMix(this, levels, numlevels); } - FMOD_RESULT setMute (bool mute) { return FMOD_Channel_SetMute(this, mute); } - FMOD_RESULT getMute (bool *mute) { FMOD_BOOL b; FMOD_RESULT res = FMOD_Channel_GetMute(this, &b); *mute = b; return res; } - FMOD_RESULT setPriority (int priority) { return FMOD_Channel_SetPriority(this, priority); } - FMOD_RESULT getPriority (int *priority) { return FMOD_Channel_GetPriority(this, priority); } - FMOD_RESULT setPosition (unsigned int position, FMOD_TIMEUNIT postype) { return FMOD_Channel_SetPosition(this, position, postype); } - FMOD_RESULT getPosition (unsigned int *position, FMOD_TIMEUNIT postype) { return FMOD_Channel_GetPosition(this, position, postype); } - FMOD_RESULT setReverbProperties (const FMOD_REVERB_CHANNELPROPERTIES *prop) { return FMOD_Channel_SetReverbProperties(this, prop); } - FMOD_RESULT getReverbProperties (FMOD_REVERB_CHANNELPROPERTIES *prop) { return FMOD_Channel_GetReverbProperties(this, prop); } - - FMOD_RESULT setChannelGroup (ChannelGroup *channelgroup) { return FMOD_Channel_SetChannelGroup(this, (FMOD_CHANNELGROUP *)channelgroup); } - FMOD_RESULT getChannelGroup (ChannelGroup **channelgroup) { return FMOD_Channel_GetChannelGroup(this, (FMOD_CHANNELGROUP **)channelgroup); } - FMOD_RESULT setCallback (FMOD_CHANNEL_CALLBACK callback) { return FMOD_Channel_SetCallback(this, callback); } - FMOD_RESULT setLowPassGain (float gain) { return FMOD_Channel_SetLowPassGain(this, gain); } - FMOD_RESULT getLowPassGain (float *gain) { return FMOD_Channel_GetLowPassGain(this, gain); } - - // 3D functionality. - FMOD_RESULT set3DAttributes (const FMOD_VECTOR *pos, const FMOD_VECTOR *vel) { return FMOD_Channel_Set3DAttributes(this, pos, vel); } - FMOD_RESULT get3DAttributes (FMOD_VECTOR *pos, FMOD_VECTOR *vel) { return FMOD_Channel_Get3DAttributes(this, pos, vel); } - FMOD_RESULT set3DMinMaxDistance (float mindistance, float maxdistance) { return FMOD_Channel_Set3DMinMaxDistance(this, mindistance, maxdistance); } - FMOD_RESULT get3DMinMaxDistance (float *mindistance, float *maxdistance) { return FMOD_Channel_Get3DMinMaxDistance(this, mindistance, maxdistance); } - FMOD_RESULT set3DConeSettings (float insideconeangle, float outsideconeangle, float outsidevolume) { return FMOD_Channel_Set3DConeSettings(this, insideconeangle, outsideconeangle, outsidevolume); } - FMOD_RESULT get3DConeSettings (float *insideconeangle, float *outsideconeangle, float *outsidevolume) { return FMOD_Channel_Get3DConeSettings(this, insideconeangle, outsideconeangle, outsidevolume); } - FMOD_RESULT set3DConeOrientation (FMOD_VECTOR *orientation) { return FMOD_Channel_Set3DConeOrientation(this, orientation); } - FMOD_RESULT get3DConeOrientation (FMOD_VECTOR *orientation) { return FMOD_Channel_Get3DConeOrientation(this, orientation); } - FMOD_RESULT set3DCustomRolloff (FMOD_VECTOR *points, int numpoints) { return FMOD_Channel_Set3DCustomRolloff(this, points, numpoints); } - FMOD_RESULT get3DCustomRolloff (FMOD_VECTOR **points, int *numpoints) { return FMOD_Channel_Get3DCustomRolloff(this, points, numpoints); } - FMOD_RESULT set3DOcclusion (float directocclusion, float reverbocclusion) { return FMOD_Channel_Set3DOcclusion(this, directocclusion, reverbocclusion); } - FMOD_RESULT get3DOcclusion (float *directocclusion, float *reverbocclusion) { return FMOD_Channel_Get3DOcclusion(this, directocclusion, reverbocclusion); } - FMOD_RESULT set3DSpread (float angle) { return FMOD_Channel_Set3DSpread(this, angle); } - FMOD_RESULT get3DSpread (float *angle) { return FMOD_Channel_Get3DSpread(this, angle); } - FMOD_RESULT set3DPanLevel (float level) { return FMOD_Channel_Set3DPanLevel(this, level); } - FMOD_RESULT get3DPanLevel (float *level) { return FMOD_Channel_Get3DPanLevel(this, level); } - FMOD_RESULT set3DDopplerLevel (float level) { return FMOD_Channel_Set3DDopplerLevel(this, level); } - FMOD_RESULT get3DDopplerLevel (float *level) { return FMOD_Channel_Get3DDopplerLevel(this, level); } - - // DSP functionality only for channels playing sounds created with FMOD_SOFTWARE. - FMOD_RESULT getDSPHead (DSP **dsp) { return FMOD_Channel_GetDSPHead(this, (FMOD_DSP **)dsp); } - FMOD_RESULT addDSP (DSP *dsp, DSPConnection **connection) { return FMOD_Channel_AddDSP(this, (FMOD_DSP *)dsp, (FMOD_DSPCONNECTION **)connection); } - - // Information only functions. - FMOD_RESULT isPlaying (bool *isplaying) { FMOD_BOOL b; FMOD_RESULT res = FMOD_Channel_IsPlaying(this, &b); *isplaying = b; return res; } - FMOD_RESULT isVirtual (bool *isvirtual) { FMOD_BOOL b; FMOD_RESULT res = FMOD_Channel_IsVirtual(this, &b); *isvirtual = b; return res; } - FMOD_RESULT getAudibility (float *audibility) { return FMOD_Channel_GetAudibility(this, audibility); } - FMOD_RESULT getCurrentSound (Sound **sound) { return FMOD_Channel_GetCurrentSound(this, (FMOD_SOUND **)sound); } - FMOD_RESULT getSpectrum (float *spectrumarray, int numvalues, int channeloffset, FMOD_DSP_FFT_WINDOW windowtype) { return FMOD_Channel_GetSpectrum(this, spectrumarray, numvalues, channeloffset, windowtype); } - FMOD_RESULT getWaveData (float *wavearray, int numvalues, int channeloffset) { return FMOD_Channel_GetWaveData(this, wavearray, numvalues, channeloffset); } - FMOD_RESULT getIndex (int *index) { return FMOD_Channel_GetIndex(this, index); } - - // Functions also found in Sound class but here they can be set per channel. - FMOD_RESULT setMode (FMOD_MODE mode) { return FMOD_Channel_SetMode(this, mode); } - FMOD_RESULT getMode (FMOD_MODE *mode) { return FMOD_Channel_GetMode(this, mode); } - FMOD_RESULT setLoopCount (int loopcount) { return FMOD_Channel_SetLoopCount(this, loopcount); } - FMOD_RESULT getLoopCount (int *loopcount) { return FMOD_Channel_GetLoopCount(this, loopcount); } - FMOD_RESULT setLoopPoints (unsigned int loopstart, FMOD_TIMEUNIT loopstarttype, unsigned int loopend, FMOD_TIMEUNIT loopendtype) { return FMOD_Channel_SetLoopPoints(this, loopstart, loopstarttype, loopend, loopendtype); } - FMOD_RESULT getLoopPoints (unsigned int *loopstart, FMOD_TIMEUNIT loopstarttype, unsigned int *loopend, FMOD_TIMEUNIT loopendtype) { return FMOD_Channel_GetLoopPoints(this, loopstart, loopstarttype, loopend, loopendtype); } - - // Userdata set/get. - FMOD_RESULT setUserData (void *userdata) { return FMOD_Channel_SetUserData(this, userdata); } - FMOD_RESULT getUserData (void **userdata) { return FMOD_Channel_GetUserData(this, userdata); } - - FMOD_RESULT getMemoryInfo (unsigned int memorybits, unsigned int event_memorybits, unsigned int *memoryused, unsigned int *memoryused_array) { return FMOD_Channel_GetMemoryInfo(this, memorybits, event_memorybits, memoryused, memoryused_array); } - }; - - /* - 'ChannelGroup' API - */ - class ChannelGroup : FMOD_CHANNELGROUP - { - private: - - ChannelGroup(); /* Constructor made private so user cannot statically instance a ChannelGroup class. - Appropriate ChannelGroup creation or retrieval function must be used. */ - public: - - FMOD_RESULT release () { return FMOD_ChannelGroup_Release(this); } - FMOD_RESULT getSystemObject (System **system) { return FMOD_ChannelGroup_GetSystemObject(this, (FMOD_SYSTEM **)system); } - - // Channelgroup scale values. (changes attributes relative to the channels, doesn't overwrite them) - FMOD_RESULT setVolume (float volume) { return FMOD_ChannelGroup_SetVolume(this, volume); } - FMOD_RESULT getVolume (float *volume) { return FMOD_ChannelGroup_GetVolume(this, volume); } - FMOD_RESULT setPitch (float pitch) { return FMOD_ChannelGroup_SetPitch(this, pitch); } - FMOD_RESULT getPitch (float *pitch) { return FMOD_ChannelGroup_GetPitch(this, pitch); } - FMOD_RESULT set3DOcclusion (float directocclusion, float reverbocclusion) { return FMOD_ChannelGroup_Set3DOcclusion(this, directocclusion, reverbocclusion); } - FMOD_RESULT get3DOcclusion (float *directocclusion, float *reverbocclusion) { return FMOD_ChannelGroup_Get3DOcclusion(this, directocclusion, reverbocclusion); } - FMOD_RESULT setPaused (bool paused) { return FMOD_ChannelGroup_SetPaused(this, paused); } - FMOD_RESULT getPaused (bool *paused) { FMOD_BOOL b; FMOD_RESULT res = FMOD_ChannelGroup_GetPaused(this, &b); *paused = b; return res; } - FMOD_RESULT setMute (bool mute) { return FMOD_ChannelGroup_SetMute(this, mute); } - FMOD_RESULT getMute (bool *mute) { FMOD_BOOL b; FMOD_RESULT res = FMOD_ChannelGroup_GetMute(this, &b); *mute = b; return res; } - - // Channelgroup override values. (recursively overwrites whatever settings the channels had) - FMOD_RESULT stop () { return FMOD_ChannelGroup_Stop(this); } - FMOD_RESULT overrideVolume (float volume) { return FMOD_ChannelGroup_OverrideVolume(this, volume); } - FMOD_RESULT overrideFrequency (float frequency) { return FMOD_ChannelGroup_OverrideFrequency(this, frequency); } - FMOD_RESULT overridePan (float pan) { return FMOD_ChannelGroup_OverridePan(this, pan); } - FMOD_RESULT overrideReverbProperties(const FMOD_REVERB_CHANNELPROPERTIES *prop) { return FMOD_ChannelGroup_OverrideReverbProperties(this, prop); } - FMOD_RESULT override3DAttributes (const FMOD_VECTOR *pos, const FMOD_VECTOR *vel) { return FMOD_ChannelGroup_Override3DAttributes(this, pos, vel); } - FMOD_RESULT overrideSpeakerMix (float frontleft, float frontright, float center, float lfe, float backleft, float backright, float sideleft, float sideright) { return FMOD_ChannelGroup_OverrideSpeakerMix(this, frontleft, frontright, center, lfe, backleft, backright, sideleft, sideright); } - - // Nested channel groups. - FMOD_RESULT addGroup (ChannelGroup *group) { return FMOD_ChannelGroup_AddGroup(this, group); } - FMOD_RESULT getNumGroups (int *numgroups) { return FMOD_ChannelGroup_GetNumGroups(this, numgroups); } - FMOD_RESULT getGroup (int index, ChannelGroup **group) { return FMOD_ChannelGroup_GetGroup(this, index, (FMOD_CHANNELGROUP **)group); } - FMOD_RESULT getParentGroup (ChannelGroup **group) { return FMOD_ChannelGroup_GetParentGroup(this, (FMOD_CHANNELGROUP **)group); } - - // DSP functionality only for channel groups playing sounds created with FMOD_SOFTWARE. - FMOD_RESULT getDSPHead (DSP **dsp) { return FMOD_ChannelGroup_GetDSPHead(this, (FMOD_DSP **)dsp); } - FMOD_RESULT addDSP (DSP *dsp, DSPConnection **connection) { return FMOD_ChannelGroup_AddDSP(this, (FMOD_DSP *)dsp, (FMOD_DSPCONNECTION **)connection); } - - // Information only functions. - FMOD_RESULT getName (char *name, int namelen) { return FMOD_ChannelGroup_GetName(this, name, namelen); } - FMOD_RESULT getNumChannels (int *numchannels) { return FMOD_ChannelGroup_GetNumChannels(this, numchannels); } - FMOD_RESULT getChannel (int index, Channel **channel) { return FMOD_ChannelGroup_GetChannel(this, index, (FMOD_CHANNEL **)channel); } - FMOD_RESULT getSpectrum (float *spectrumarray, int numvalues, int channeloffset, FMOD_DSP_FFT_WINDOW windowtype) { return FMOD_ChannelGroup_GetSpectrum(this, spectrumarray, numvalues, channeloffset, windowtype); } - FMOD_RESULT getWaveData (float *wavearray, int numvalues, int channeloffset) { return FMOD_ChannelGroup_GetWaveData(this, wavearray, numvalues, channeloffset) ;} - - // Userdata set/get. - FMOD_RESULT setUserData (void *userdata) { return FMOD_ChannelGroup_SetUserData(this, userdata); } - FMOD_RESULT getUserData (void **userdata) { return FMOD_ChannelGroup_GetUserData(this, userdata); } - - FMOD_RESULT getMemoryInfo (unsigned int memorybits, unsigned int event_memorybits, unsigned int *memoryused, unsigned int *memoryused_array) { return FMOD_ChannelGroup_GetMemoryInfo(this, memorybits, event_memorybits, memoryused, memoryused_array); } - }; - - /* - 'SoundGroup' API - */ - class SoundGroup : FMOD_SOUNDGROUP - { - private: - - SoundGroup(); /* Constructor made private so user cannot statically instance a SoundGroup class. - Appropriate SoundGroup creation or retrieval function must be used. */ - public: - - FMOD_RESULT release () { return FMOD_SoundGroup_Release(this); } - FMOD_RESULT getSystemObject (System **system) { return FMOD_SoundGroup_GetSystemObject(this, (FMOD_SYSTEM **)system); } - - // SoundGroup control functions. - FMOD_RESULT setMaxAudible (int maxaudible) { return FMOD_SoundGroup_SetMaxAudible(this, maxaudible); } - FMOD_RESULT getMaxAudible (int *maxaudible) { return FMOD_SoundGroup_GetMaxAudible(this, maxaudible); } - FMOD_RESULT setMaxAudibleBehavior (FMOD_SOUNDGROUP_BEHAVIOR behavior) { return FMOD_SoundGroup_SetMaxAudibleBehavior(this, behavior); } - FMOD_RESULT getMaxAudibleBehavior (FMOD_SOUNDGROUP_BEHAVIOR *behavior) { return FMOD_SoundGroup_GetMaxAudibleBehavior(this, behavior); } - FMOD_RESULT setMuteFadeSpeed (float speed) { return FMOD_SoundGroup_SetMuteFadeSpeed(this, speed); } - FMOD_RESULT getMuteFadeSpeed (float *speed) { return FMOD_SoundGroup_GetMuteFadeSpeed(this, speed); } - FMOD_RESULT setVolume (float volume) { return FMOD_SoundGroup_SetVolume(this, volume); } - FMOD_RESULT getVolume (float *volume) { return FMOD_SoundGroup_GetVolume(this, volume); } - FMOD_RESULT stop () { return FMOD_SoundGroup_Stop(this); } - - // Information only functions. - FMOD_RESULT getName (char *name, int namelen) { return FMOD_SoundGroup_GetName(this, name, namelen); } - FMOD_RESULT getNumSounds (int *numsounds) { return FMOD_SoundGroup_GetNumSounds(this, numsounds); } - FMOD_RESULT getSound (int index, Sound **sound) { return FMOD_SoundGroup_GetSound(this, index, (FMOD_SOUND **)sound); } - FMOD_RESULT getNumPlaying (int *numplaying) { return FMOD_SoundGroup_GetNumPlaying(this, numplaying); } - - // Userdata set/get. - FMOD_RESULT setUserData (void *userdata) { return FMOD_SoundGroup_SetUserData(this, userdata); } - FMOD_RESULT getUserData (void **userdata) { return FMOD_SoundGroup_GetUserData(this, userdata); } - - FMOD_RESULT getMemoryInfo (unsigned int memorybits, unsigned int event_memorybits, unsigned int *memoryused, unsigned int *memoryused_array) { return FMOD_SoundGroup_GetMemoryInfo(this, memorybits, event_memorybits, memoryused, memoryused_array); } - }; - - /* - 'DSP' API - */ - class DSP : FMOD_DSP - { - private: - - DSP(); /* Constructor made private so user cannot statically instance a DSP class. - Appropriate DSP creation or retrieval function must be used. */ - public: - - FMOD_RESULT release () { return FMOD_DSP_Release(this); } - FMOD_RESULT getSystemObject (System **system) { return FMOD_DSP_GetSystemObject(this, (FMOD_SYSTEM **)system); } - - // Connection / disconnection / input and output enumeration. - FMOD_RESULT addInput (DSP *target, DSPConnection **connection) { return FMOD_DSP_AddInput(this, target, (FMOD_DSPCONNECTION **)connection); } - FMOD_RESULT disconnectFrom (DSP *target) { return FMOD_DSP_DisconnectFrom(this, target); } - FMOD_RESULT disconnectAll (bool inputs, bool outputs) { return FMOD_DSP_DisconnectAll(this, inputs, outputs); } - FMOD_RESULT remove () { return FMOD_DSP_Remove(this); } - FMOD_RESULT getNumInputs (int *numinputs) { return FMOD_DSP_GetNumInputs(this, numinputs); } - FMOD_RESULT getNumOutputs (int *numoutputs) { return FMOD_DSP_GetNumOutputs(this, numoutputs); } - FMOD_RESULT getInput (int index, DSP **input, DSPConnection **inputconnection) { return FMOD_DSP_GetInput(this, index, (FMOD_DSP **)input, (FMOD_DSPCONNECTION **)inputconnection); } - FMOD_RESULT getOutput (int index, DSP **output, DSPConnection **outputconnection) { return FMOD_DSP_GetOutput(this, index, (FMOD_DSP **)output, (FMOD_DSPCONNECTION **)outputconnection); } - - // DSP unit control. - FMOD_RESULT setActive (bool active) { return FMOD_DSP_SetActive(this, active); } - FMOD_RESULT getActive (bool *active) { FMOD_BOOL b; FMOD_RESULT res = FMOD_DSP_GetActive(this, &b); *active = b; return res; } - FMOD_RESULT setBypass (bool bypass) { return FMOD_DSP_SetBypass(this, bypass); } - FMOD_RESULT getBypass (bool *bypass) { FMOD_BOOL b; FMOD_RESULT res = FMOD_DSP_GetBypass(this, &b); *bypass = b; return res; } - FMOD_RESULT setSpeakerActive (FMOD_SPEAKER speaker, bool active) { return FMOD_DSP_SetSpeakerActive(this, speaker, active); } - FMOD_RESULT getSpeakerActive (FMOD_SPEAKER speaker, bool *active) { FMOD_BOOL b; FMOD_RESULT res = FMOD_DSP_GetSpeakerActive(this, speaker, &b); *active = b; return res; } - FMOD_RESULT reset () { return FMOD_DSP_Reset(this); } - - // DSP parameter control. - FMOD_RESULT setParameter (int index, float value) { return FMOD_DSP_SetParameter(this, index, value); } - FMOD_RESULT getParameter (int index, float *value, char *valuestr, int valuestrlen) { return FMOD_DSP_GetParameter(this, index, value, valuestr, valuestrlen); } - FMOD_RESULT getNumParameters (int *numparams) { return FMOD_DSP_GetNumParameters(this, numparams); } - FMOD_RESULT getParameterInfo (int index, char *name, char *label, char *description, int descriptionlen, float *min, float *max) { return FMOD_DSP_GetParameterInfo(this, index, name, label, description, descriptionlen, min, max); } - FMOD_RESULT showConfigDialog (void *hwnd, bool show) { return FMOD_DSP_ShowConfigDialog(this, hwnd, show); } - - // DSP attributes. - FMOD_RESULT getInfo (char *name, unsigned int *version, int *channels, int *configwidth, int *configheight) { return FMOD_DSP_GetInfo(this, name, version, channels, configwidth, configheight); } - FMOD_RESULT getType (FMOD_DSP_TYPE *type) { return FMOD_DSP_GetType(this, type); } - FMOD_RESULT setDefaults (float frequency, float volume, float pan, int priority) { return FMOD_DSP_SetDefaults(this, frequency, volume, pan, priority); } - FMOD_RESULT getDefaults (float *frequency, float *volume, float *pan, int *priority) { return FMOD_DSP_GetDefaults(this, frequency, volume, pan, priority) ;} - - // Userdata set/get. - FMOD_RESULT setUserData (void *userdata) { return FMOD_DSP_SetUserData(this, userdata); } - FMOD_RESULT getUserData (void **userdata) { return FMOD_DSP_GetUserData(this, userdata); } - - FMOD_RESULT getMemoryInfo (unsigned int memorybits, unsigned int event_memorybits, unsigned int *memoryused, unsigned int *memoryused_array) { return FMOD_DSP_GetMemoryInfo(this, memorybits, event_memorybits, memoryused, memoryused_array); } - }; - - - /* - 'DSPConnection' API - */ - class DSPConnection : FMOD_DSPCONNECTION - { - private: - - DSPConnection(); /* Constructor made private so user cannot statically instance a DSPConnection class. - Appropriate DSPConnection creation or retrieval function must be used. */ - - public: - - FMOD_RESULT getInput (DSP **input) { return FMOD_DSPConnection_GetInput(this, (FMOD_DSP **)input); } - FMOD_RESULT getOutput (DSP **output) { return FMOD_DSPConnection_GetOutput(this, (FMOD_DSP **)output); } - FMOD_RESULT setMix (float volume) { return FMOD_DSPConnection_SetMix(this, volume); } - FMOD_RESULT getMix (float *volume) { return FMOD_DSPConnection_GetMix(this, volume); } - FMOD_RESULT setLevels (FMOD_SPEAKER speaker, float *levels, int numlevels) { return FMOD_DSPConnection_SetLevels(this, speaker, levels, numlevels); } - FMOD_RESULT getLevels (FMOD_SPEAKER speaker, float *levels, int numlevels) { return FMOD_DSPConnection_GetLevels(this, speaker, levels, numlevels); } - - // Userdata set/get. - FMOD_RESULT setUserData (void *userdata) { return FMOD_DSPConnection_SetUserData(this, userdata); } - FMOD_RESULT getUserData (void **userdata) { return FMOD_DSPConnection_GetUserData(this, userdata); } - - FMOD_RESULT getMemoryInfo (unsigned int memorybits, unsigned int event_memorybits, unsigned int *memoryused, unsigned int *memoryused_array) { return FMOD_DSPConnection_GetMemoryInfo(this, memorybits, event_memorybits, memoryused, memoryused_array); } - }; - - - /* - 'Geometry' API - */ - class Geometry : FMOD_GEOMETRY - { - private: - - Geometry(); /* Constructor made private so user cannot statically instance a Geometry class. - Appropriate Geometry creation or retrieval function must be used. */ - - public: - - FMOD_RESULT release () { return FMOD_Geometry_Release(this); } - - // Polygon manipulation. - FMOD_RESULT addPolygon (float directocclusion, float reverbocclusion, bool doublesided, int numvertices, const FMOD_VECTOR *vertices, int *polygonindex) { return FMOD_Geometry_AddPolygon(this, directocclusion, reverbocclusion, doublesided, numvertices, vertices, polygonindex); } - FMOD_RESULT getNumPolygons (int *numpolygons) { return FMOD_Geometry_GetNumPolygons(this, numpolygons); } - FMOD_RESULT getMaxPolygons (int *maxpolygons, int *maxvertices) { return FMOD_Geometry_GetMaxPolygons(this, maxpolygons, maxvertices); } - FMOD_RESULT getPolygonNumVertices (int index, int *numvertices) { return FMOD_Geometry_GetPolygonNumVertices(this, index, numvertices); } - FMOD_RESULT setPolygonVertex (int index, int vertexindex, const FMOD_VECTOR *vertex) { return FMOD_Geometry_SetPolygonVertex(this, index, vertexindex, vertex); } - FMOD_RESULT getPolygonVertex (int index, int vertexindex, FMOD_VECTOR *vertex) { return FMOD_Geometry_GetPolygonVertex(this, index, vertexindex, vertex); } - FMOD_RESULT setPolygonAttributes (int index, float directocclusion, float reverbocclusion, bool doublesided) { return FMOD_Geometry_SetPolygonAttributes(this, index, directocclusion, reverbocclusion, doublesided); } - FMOD_RESULT getPolygonAttributes (int index, float *directocclusion, float *reverbocclusion, bool *doublesided) { FMOD_BOOL b; FMOD_RESULT res = FMOD_Geometry_GetPolygonAttributes(this, index, directocclusion, reverbocclusion, &b); *doublesided = b; return res; } - - // Object manipulation. - FMOD_RESULT setActive (bool active) { return FMOD_Geometry_SetActive(this, active); } - FMOD_RESULT getActive (bool *active) { FMOD_BOOL b; FMOD_RESULT res = FMOD_Geometry_GetActive(this, &b); *active = b; return res; } - FMOD_RESULT setRotation (const FMOD_VECTOR *forward, const FMOD_VECTOR *up) { return FMOD_Geometry_SetRotation(this, forward, up); } - FMOD_RESULT getRotation (FMOD_VECTOR *forward, FMOD_VECTOR *up) { return FMOD_Geometry_GetRotation(this, forward, up); } - FMOD_RESULT setPosition (const FMOD_VECTOR *position) { return FMOD_Geometry_SetPosition(this, position); } - FMOD_RESULT getPosition (FMOD_VECTOR *position) { return FMOD_Geometry_GetPosition(this, position); } - FMOD_RESULT setScale (const FMOD_VECTOR *scale) { return FMOD_Geometry_SetScale(this, scale); } - FMOD_RESULT getScale (FMOD_VECTOR *scale) { return FMOD_Geometry_GetScale(this, scale); } - FMOD_RESULT save (void *data, int *datasize) { return FMOD_Geometry_Save(this, data, datasize); } - - // Userdata set/get. - FMOD_RESULT setUserData (void *userdata) { return FMOD_Geometry_SetUserData(this, userdata); } - FMOD_RESULT getUserData (void **userdata) { return FMOD_Geometry_GetUserData(this, userdata); } - - FMOD_RESULT getMemoryInfo (unsigned int memorybits, unsigned int event_memorybits, unsigned int *memoryused, unsigned int *memoryused_array) { return FMOD_Geometry_GetMemoryInfo(this, memorybits, event_memorybits, memoryused, memoryused_array); } - }; - - - /* - 'Reverb' API - */ - class Reverb : FMOD_REVERB - { - private: - - Reverb(); /* Constructor made private so user cannot statically instance a Reverb class. - Appropriate Reverb creation or retrieval function must be used. */ - - public: - - FMOD_RESULT release () { return FMOD_Reverb_Release(this); } - - // Reverb manipulation. - FMOD_RESULT set3DAttributes (const FMOD_VECTOR *position, float mindistance, float maxdistance) { return FMOD_Reverb_Set3DAttributes(this, position, mindistance, maxdistance); } - FMOD_RESULT get3DAttributes (FMOD_VECTOR *position, float *mindistance, float *maxdistance) { return FMOD_Reverb_Get3DAttributes(this, position, mindistance, maxdistance); } - FMOD_RESULT setProperties (const FMOD_REVERB_PROPERTIES *properties) { return FMOD_Reverb_SetProperties(this, properties); } - FMOD_RESULT getProperties (FMOD_REVERB_PROPERTIES *properties) { return FMOD_Reverb_GetProperties(this, properties); } - FMOD_RESULT setActive (bool active) { return FMOD_Reverb_SetActive(this, active); } - FMOD_RESULT getActive (bool *active) { FMOD_BOOL b; FMOD_RESULT res = FMOD_Reverb_GetActive(this, &b); *active = b; return res; } - - // Userdata set/get. - FMOD_RESULT setUserData (void *userdata) { return FMOD_Reverb_SetUserData(this, userdata); } - FMOD_RESULT getUserData (void **userdata) { return FMOD_Reverb_GetUserData(this, userdata); } - - FMOD_RESULT getMemoryInfo (unsigned int memorybits, unsigned int event_memorybits, unsigned int *memoryused, unsigned int *memoryused_array) { return FMOD_Reverb_GetMemoryInfo(this, memorybits, event_memorybits, memoryused, memoryused_array); } - }; -} - -#endif - -// FMOD Ex vs FMOD Studio -#if FMOD_VERSION >= 0x00040000 && FMOD_VERSION <= 0x0004FFFF -#define FMOD_STUDIO 0 -#else -#define FMOD_STUDIO 1 -#define FMOD_SOFTWARE 0 -#endif - -#endif -#endif diff --git a/src/sound/fmodsound.cpp b/src/sound/fmodsound.cpp deleted file mode 100644 index a5972dceb..000000000 --- a/src/sound/fmodsound.cpp +++ /dev/null @@ -1,3527 +0,0 @@ -/* -** fmodsound.cpp -** System interface for sound; uses FMOD Ex. -** -**--------------------------------------------------------------------------- -** Copyright 1998-2009 Randy Heit -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -*/ - -// HEADER FILES ------------------------------------------------------------ - -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN -#include -#include -extern HWND Window; -#else -#define FALSE 0 -#define TRUE 1 -#endif -#if defined(__FreeBSD__) || defined(__APPLE__) -#include -#elif __sun -#include -#else -#include -#endif - -#include "except.h" -#include "templates.h" -#include "fmodsound.h" -#include "c_cvars.h" -#include "i_system.h" -#include "i_music.h" -#include "v_text.h" -#include "v_video.h" -#include "v_palette.h" -#include "cmdlib.h" -#include "s_sound.h" -#include "files.h" -#include "i_musicinterns.h" - -#if FMOD_VERSION > 0x42899 && FMOD_VERSION < 0x43400 -#error You are trying to compile with an unsupported version of FMOD. -#endif - -// MACROS ------------------------------------------------------------------ - -// killough 2/21/98: optionally use varying pitched sounds -#define PITCH(freq,pitch) (snd_pitched ? ((freq)*(pitch))/128.f : float(freq)) - -// Just some extra for music and whatever -#define NUM_EXTRA_SOFTWARE_CHANNELS 1 - -#define MAX_CHANNELS 256 - -#define SPECTRUM_SIZE 256 - -// PUBLIC DATA DEFINITIONS ------------------------------------------------- - -ReverbContainer *ForcedEnvironment; - -CVAR (Int, snd_driver, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -CVAR (Int, snd_buffercount, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -CVAR (Bool, snd_hrtf, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -CVAR (Bool, snd_waterreverb, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -CVAR (String, snd_resampler, "Linear", CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -CVAR (String, snd_speakermode, "Auto", CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -CVAR (String, snd_output_format, "PCM-16", CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -CVAR (String, snd_midipatchset, "", CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -CVAR (Bool, snd_profile, false, 0) - -// Underwater low-pass filter cutoff frequency. Set to 0 to disable the filter. -CUSTOM_CVAR (Float, snd_waterlp, 250, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -{ - // Clamp to the DSP unit's limits. - if (*self < 10 && *self != 0) - { - self = 10; - } - else if (*self > 22000) - { - self = 22000; - } -} - -CUSTOM_CVAR (Int, snd_streambuffersize, 64, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -{ - if (self < 16) - { - self = 16; - } - else if (self > 1024) - { - self = 1024; - } -} - -#ifndef NO_FMOD -#if !FMOD_STUDIO && FMOD_VERSION < 0x43400 -#define FMOD_OPENSTATE_PLAYING FMOD_OPENSTATE_STREAMING -#endif - -#if !FMOD_STUDIO -#define setParameterFloat setParameter -#endif - -// TYPES ------------------------------------------------------------------- - -struct FEnumList -{ - const char *Name; - int Value; -}; - -// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- - -// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- - -// PRIVATE FUNCTION PROTOTYPES --------------------------------------------- - -static int Enum_NumForName(const FEnumList *list, const char *name); -static const char *Enum_NameForNum(const FEnumList *list, int num); - -// EXTERNAL DATA DECLARATIONS ---------------------------------------------- - -EXTERN_CVAR (String, snd_output) -EXTERN_CVAR (Float, snd_sfxvolume) -EXTERN_CVAR (Float, snd_musicvolume) -EXTERN_CVAR (Int, snd_buffersize) -EXTERN_CVAR (Int, snd_samplerate) -EXTERN_CVAR (Bool, snd_pitched) -EXTERN_CVAR (Int, snd_channels) - -extern int sfx_empty; - -// PRIVATE DATA DEFINITIONS ------------------------------------------------ - -static const ReverbContainer *PrevEnvironment; -static bool ShowedBanner; - -// The rolloff callback is called during FMOD::Sound::play, so we need this -// global variable to contain the sound info during that time for the -// callback. -static FRolloffInfo *GRolloff; -static float GDistScale; - -// In the below lists, duplicate entries are for user selection. When -// queried, only the first one for the particular value is shown. -static const FEnumList OutputNames[] = -{ - { "Auto", FMOD_OUTPUTTYPE_AUTODETECT }, - { "Default", FMOD_OUTPUTTYPE_AUTODETECT }, - { "No sound", FMOD_OUTPUTTYPE_NOSOUND }, - - // Windows - { "DirectSound", FMOD_OUTPUTTYPE_DSOUND }, - { "DSound", FMOD_OUTPUTTYPE_DSOUND }, - { "Windows Multimedia", FMOD_OUTPUTTYPE_WINMM }, - { "WinMM", FMOD_OUTPUTTYPE_WINMM }, - { "WaveOut", FMOD_OUTPUTTYPE_WINMM }, - { "WASAPI", FMOD_OUTPUTTYPE_WASAPI }, - { "ASIO", FMOD_OUTPUTTYPE_ASIO }, - -#if FMOD_STUDIO - //Android - - { "OPENSL", FMOD_OUTPUTTYPE_OPENSL }, - { "Android Audio Track", FMOD_OUTPUTTYPE_AUDIOTRACK }, -#endif - - // Linux -#if !FMOD_STUDIO - { "OSS", FMOD_OUTPUTTYPE_OSS }, -#endif - { "ALSA", FMOD_OUTPUTTYPE_ALSA }, -#if !FMOD_STUDIO - { "ESD", FMOD_OUTPUTTYPE_ESD }, -#endif -#if FMOD_STUDIO || FMOD_VERSION >= 0x43400 - { "PulseAudio", FMOD_OUTPUTTYPE_PULSEAUDIO }, - { "Pulse", FMOD_OUTPUTTYPE_PULSEAUDIO }, -#endif -#if !FMOD_STUDIO - { "SDL", 666 }, -#endif - - // Mac - { "Core Audio", FMOD_OUTPUTTYPE_COREAUDIO }, - - { NULL, 0 } -}; - -static const FEnumList SpeakerModeNames[] = -{ - { "Mono", FMOD_SPEAKERMODE_MONO }, - { "Stereo", FMOD_SPEAKERMODE_STEREO }, - { "Quad", FMOD_SPEAKERMODE_QUAD }, - { "Surround", FMOD_SPEAKERMODE_SURROUND }, - { "5.1", FMOD_SPEAKERMODE_5POINT1 }, - { "7.1", FMOD_SPEAKERMODE_7POINT1 }, -#if !FMOD_STUDIO && FMOD_VERSION < 0x44000 - { "Prologic", FMOD_SPEAKERMODE_PROLOGIC }, -#endif - { "1", FMOD_SPEAKERMODE_MONO }, - { "2", FMOD_SPEAKERMODE_STEREO }, - { "4", FMOD_SPEAKERMODE_QUAD }, - { NULL, 0 } -}; - -static const FEnumList ResamplerNames[] = -{ - { "No Interpolation", FMOD_DSP_RESAMPLER_NOINTERP }, - { "NoInterp", FMOD_DSP_RESAMPLER_NOINTERP }, - { "Linear", FMOD_DSP_RESAMPLER_LINEAR }, - // [BL] 64-bit versions of FMOD Ex between 4.24 and 4.26 crash with these resamplers. -#if FMOD_STUDIO || !(defined(_M_X64) || defined(__amd64__)) || !(FMOD_VERSION >= 0x42400 && FMOD_VERSION <= 0x426FF) - { "Cubic", FMOD_DSP_RESAMPLER_CUBIC }, - { "Spline", FMOD_DSP_RESAMPLER_SPLINE }, -#endif - { NULL, 0 } -}; - -static const FEnumList SoundFormatNames[] = -{ - { "None", FMOD_SOUND_FORMAT_NONE }, - { "PCM-8", FMOD_SOUND_FORMAT_PCM8 }, - { "PCM-16", FMOD_SOUND_FORMAT_PCM16 }, - { "PCM-24", FMOD_SOUND_FORMAT_PCM24 }, - { "PCM-32", FMOD_SOUND_FORMAT_PCM32 }, - { "PCM-Float", FMOD_SOUND_FORMAT_PCMFLOAT }, -#if FMOD_STUDIO && FMOD_VERSION < 0x10700 - { "GCADPCM", FMOD_SOUND_FORMAT_GCADPCM }, - { "IMAADPCM", FMOD_SOUND_FORMAT_IMAADPCM }, - { "VAG", FMOD_SOUND_FORMAT_VAG }, - { "XMA", FMOD_SOUND_FORMAT_XMA }, - { "MPEG", FMOD_SOUND_FORMAT_MPEG }, -#endif - { NULL, 0 } -}; - -static const char *OpenStateNames[] = -{ - "Ready", - "Loading", - "Error", - "Connecting", - "Buffering", - "Seeking", - "Streaming" -}; - -const FMODSoundRenderer::spk FMODSoundRenderer::SpeakerNames4[4] = { "L", "R", "BL", "BR" }; -const FMODSoundRenderer::spk FMODSoundRenderer::SpeakerNamesMore[8] = { "L", "R", "C", "LFE", "BL", "BR", "SL", "SR" }; - -// CODE -------------------------------------------------------------------- - -//========================================================================== -// -// Enum_NumForName -// -// Returns the value of an enum name, or -1 if not found. -// -//========================================================================== - -static int Enum_NumForName(const FEnumList *list, const char *name) -{ - while (list->Name != NULL) - { - if (stricmp(list->Name, name) == 0) - { - return list->Value; - } - list++; - } - return -1; -} - -//========================================================================== -// -// Enum_NameForNum -// -// Returns the name of an enum value. If there is more than one name for a -// value, on the first one in the list is returned. Returns NULL if there -// was no match. -// -//========================================================================== - -static const char *Enum_NameForNum(const FEnumList *list, int num) -{ - while (list->Name != NULL) - { - if (list->Value == num) - { - return list->Name; - } - list++; - } - return NULL; -} - -//========================================================================== -// -// The container for a streaming FMOD::Sound, for playing music. -// -//========================================================================== - -class FMODStreamCapsule : public SoundStream -{ -public: - FMODStreamCapsule(FMOD::Sound *stream, FMODSoundRenderer *owner, const char *url) - : Owner(owner), Stream(NULL), Channel(NULL), - UserData(NULL), Callback(NULL), Reader(NULL), URL(url), Ended(false) - { - SetStream(stream); - } - - FMODStreamCapsule(FMOD::Sound *stream, FMODSoundRenderer *owner, FileReader *reader) - : Owner(owner), Stream(NULL), Channel(NULL), - UserData(NULL), Callback(NULL), Reader(reader), Ended(false) - { - SetStream(stream); - } - - FMODStreamCapsule(void *udata, SoundStreamCallback callback, FMODSoundRenderer *owner) - : Owner(owner), Stream(NULL), Channel(NULL), - UserData(udata), Callback(callback), Reader(NULL), Ended(false) - {} - - ~FMODStreamCapsule() - { - if (Channel != NULL) - { - Channel->stop(); - } - if (Stream != NULL) - { - Stream->release(); - } - if (Reader != NULL) - { - delete Reader; - } - } - - void SetStream(FMOD::Sound *stream) - { - float frequency; - - Stream = stream; - - // As this interface is for music, make it super-high priority. -#if FMOD_STUDIO - if (FMOD_OK == stream->getDefaults(&frequency, NULL)) - stream->setDefaults(frequency, 1); -#else - if (FMOD_OK == stream->getDefaults(&frequency, NULL, NULL, NULL)) - stream->setDefaults(frequency, 1, 0, 0); -#endif - } - - bool Play(bool looping, float volume) - { - FMOD_RESULT result; - - if (URL.IsNotEmpty()) - { // Net streams cannot be looped, because they cannot be seeked. - looping = false; - } - Stream->setMode((looping ? FMOD_LOOP_NORMAL : FMOD_LOOP_OFF) | FMOD_SOFTWARE | FMOD_2D); -#if FMOD_STUDIO - result = Owner->Sys->playSound(Stream,0, true, &Channel); -#else - result = Owner->Sys->playSound(FMOD_CHANNEL_FREE, Stream, true, &Channel); -#endif - if (result != FMOD_OK) - { - return false; - } - Channel->setChannelGroup(Owner->MusicGroup); -#if FMOD_STUDIO - Channel->setMixLevelsOutput(1, 1, 1, 1, 1, 1, 1, 1); -#else - Channel->setSpeakerMix(1, 1, 1, 1, 1, 1, 1, 1); -#endif - Channel->setVolume(volume); - // Ensure reverb is disabled. -#if FMOD_STUDIO - Channel->setReverbProperties(0,0.f); -#else - FMOD_REVERB_CHANNELPROPERTIES reverb = { 0, }; - if (FMOD_OK == Channel->getReverbProperties(&reverb)) - { - reverb.Room = -10000; - Channel->setReverbProperties(&reverb); - } -#endif - Channel->setPaused(false); - Ended = false; - JustStarted = true; - Starved = false; - Loop = looping; - Volume = volume; - return true; - } - - void Stop() - { - if (Channel != NULL) - { - Channel->stop(); - Channel = NULL; - } - } - - bool SetPaused(bool paused) - { - if (Channel != NULL) - { - return FMOD_OK == Channel->setPaused(paused); - } - return false; - } - - unsigned int GetPosition() - { - unsigned int pos; - - if (Channel != NULL && FMOD_OK == Channel->getPosition(&pos, FMOD_TIMEUNIT_MS)) - { - return pos; - } - return 0; - } - - bool IsEnded() - { - bool is; - FMOD_OPENSTATE openstate = FMOD_OPENSTATE_MAX; - bool starving; -#if FMOD_STUDIO || FMOD_VERSION >= 0x43400 - bool diskbusy; -#endif - - if (Stream == NULL) - { - return true; - } -#if !FMOD_STUDIO && FMOD_VERSION < 0x43400 - if (FMOD_OK != Stream->getOpenState(&openstate, NULL, &starving)) -#else - if (FMOD_OK != Stream->getOpenState(&openstate, NULL, &starving, &diskbusy)) -#endif - { - openstate = FMOD_OPENSTATE_ERROR; - } - if (openstate == FMOD_OPENSTATE_ERROR) - { - if (Channel != NULL) - { - Channel->stop(); - Channel = NULL; - } - return true; - } - if (Channel != NULL && (FMOD_OK != Channel->isPlaying(&is) || is == false)) - { - return true; - } - if (Ended) - { - Channel->stop(); - Channel = NULL; - return true; - } - if (URL.IsNotEmpty() && !JustStarted && openstate == FMOD_OPENSTATE_READY) - { - // Reconnect the stream, since it seems to have stalled. - // The only way to do this appears to be to completely recreate it. - FMOD_RESULT result; - - Channel->stop(); - Stream->release(); - Channel = NULL; - Stream = NULL; - // Open the stream asynchronously, so we don't hang the game while trying to reconnect. - // (It would be nice to do the initial open asynchronously as well, but I'd need to rethink - // the music system design to pull that off.) - result = Owner->Sys->createSound(URL, (Loop ? FMOD_LOOP_NORMAL : FMOD_LOOP_OFF) | FMOD_SOFTWARE | FMOD_2D | - FMOD_CREATESTREAM | FMOD_NONBLOCKING, NULL, &Stream); - JustStarted = true; - return result != FMOD_OK; - } - if (JustStarted && openstate == FMOD_OPENSTATE_PLAYING) - { - JustStarted = false; - } - if (JustStarted && Channel == NULL && openstate == FMOD_OPENSTATE_READY) - { - return !Play(Loop, Volume); - } - if (starving != Starved) - { // Mute the sound if it's starving. - Channel->setVolume(starving ? 0 : Volume); - Starved = starving; - } - return false; - } - - void SetVolume(float volume) - { - if (Channel != NULL && !Starved) - { - Channel->setVolume(volume); - } - Volume = volume; - } - - // Sets the position in ms. - bool SetPosition(unsigned int ms_pos) - { - return FMOD_OK == Channel->setPosition(ms_pos, FMOD_TIMEUNIT_MS); - } - - // Sets the order number for MOD formats. - bool SetOrder(int order_pos) - { - return FMOD_OK == Channel->setPosition(order_pos, FMOD_TIMEUNIT_MODORDER); - } - - FString GetStats() - { - FString stats; - FMOD_OPENSTATE openstate; - unsigned int percentbuffered; - unsigned int position; - bool starving; -#if FMOD_STUDIO || FMOD_VERSION >= 0x43400 - bool diskbusy; -#endif - float volume; - float frequency; - bool paused; - bool isplaying; - -#if !FMOD_STUDIO && FMOD_VERSION < 0x43400 - if (FMOD_OK == Stream->getOpenState(&openstate, &percentbuffered, &starving)) -#else - if (FMOD_OK == Stream->getOpenState(&openstate, &percentbuffered, &starving, &diskbusy)) -#endif - { - stats = (openstate <= FMOD_OPENSTATE_PLAYING ? OpenStateNames[openstate] : "Unknown state"); - stats.AppendFormat(",%3d%% buffered, %s", percentbuffered, starving ? "Starving" : "Well-fed"); - } - if (Channel == NULL) - { - stats += ", not playing"; - } - if (Channel != NULL && FMOD_OK == Channel->getPosition(&position, FMOD_TIMEUNIT_MS)) - { - stats.AppendFormat(", %d", position); - if (FMOD_OK == Stream->getLength(&position, FMOD_TIMEUNIT_MS)) - { - stats.AppendFormat("/%d", position); - } - stats += " ms"; - } - if (Channel != NULL && FMOD_OK == Channel->getVolume(&volume)) - { - stats.AppendFormat(", %d%%", int(volume * 100)); - } - if (Channel != NULL && FMOD_OK == Channel->getPaused(&paused) && paused) - { - stats += ", paused"; - } - if (Channel != NULL && FMOD_OK == Channel->isPlaying(&isplaying) && isplaying) - { - stats += ", playing"; - } - if (Channel != NULL && FMOD_OK == Channel->getFrequency(&frequency)) - { - stats.AppendFormat(", %g Hz", frequency); - } - if (JustStarted) - { - stats += " JS"; - } - if (Ended) - { - stats += " XX"; - } - return stats; - } - - static FMOD_RESULT F_CALLBACK PCMReadCallback(FMOD_SOUND *sound, void *data, unsigned int datalen) - { - FMOD_RESULT result; - FMODStreamCapsule *self; - - result = ((FMOD::Sound *)sound)->getUserData((void **)&self); - if (result != FMOD_OK || self == NULL || self->Callback == NULL || self->Ended) - { - // Contrary to the docs, this return value is completely ignored. - return FMOD_OK; - } - if (!self->Callback(self, data, datalen, self->UserData)) - { - self->Ended = true; - } - return FMOD_OK; - } - - static FMOD_RESULT F_CALLBACK PCMSetPosCallback(FMOD_SOUND *sound, int subsound, unsigned int position, FMOD_TIMEUNIT postype) - { - // This is useful if the user calls Channel::setPosition and you want - // to seek your data accordingly. - return FMOD_OK; - } - -private: - FMODSoundRenderer *Owner; - FMOD::Sound *Stream; - FMOD::Channel *Channel; - void *UserData; - SoundStreamCallback Callback; - FileReader *Reader; - FString URL; - bool Ended; - bool JustStarted; - bool Starved; - bool Loop; - float Volume; -}; - -//========================================================================== -// -// The interface the game uses to talk to FMOD. -// -//========================================================================== - -FMODSoundRenderer::FMODSoundRenderer() -{ - InitSuccess = Init(); -} - -FMODSoundRenderer::~FMODSoundRenderer() -{ - Shutdown(); -} - -bool FMODSoundRenderer::IsValid() -{ - return InitSuccess; -} - -//========================================================================== -// -// FMODSoundRenderer :: Init -// -//========================================================================== - -bool FMODSoundRenderer::Init() -{ - FMOD_RESULT result; - unsigned int version; - FMOD_SPEAKERMODE speakermode; - FMOD_SOUND_FORMAT format; - FMOD_DSP_RESAMPLER resampler; - FMOD_INITFLAGS initflags; - int samplerate; - int driver; - - int eval; - - SFXPaused = 0; - DSPLocked = false; - MusicGroup = NULL; - SfxGroup = NULL; - PausableSfx = NULL; - SfxConnection = NULL; - WaterLP = NULL; - WaterReverb = NULL; - PrevEnvironment = DefaultEnvironments[0]; - DSPClock.AsOne = 0; - ChannelGroupTargetUnit = NULL; - ChannelGroupTargetUnitOutput = NULL; - SfxReverbHooked = false; - SfxReverbPlaceholder = NULL; - OutputPlugin = 0; - - Printf("I_InitSound: Initializing FMOD\n"); - - // This is just for safety. Normally this should never be called if FMod Ex cannot be found. - if (!IsFModExPresent()) - { - Sys = NULL; - Printf(TEXTCOLOR_ORANGE"Failed to load fmodex" -#ifdef _WIN64 - "64" -#endif - ".dll\n"); - return false; - } - - // Create a System object and initialize. - result = FMOD::System_Create(&Sys); - if (result != FMOD_OK) - { - Sys = NULL; - Printf(TEXTCOLOR_ORANGE"Failed to create FMOD system object: Error %d\n", result); - return false; - } - - result = Sys->getVersion(&version); - if (result != FMOD_OK) - { - Printf(TEXTCOLOR_ORANGE"Could not validate FMOD version: Error %d\n", result); - return false; - } - - const char *wrongver = NULL; -#if FMOD_STUDIO - if (version < (FMOD_VERSION & 0xFFFF00)) -#elif FMOD_VERSION >= 0x43600 - if (version < 0x43600) -#else - if (version < 0x42000) -#endif - { - wrongver = "an old"; - } -#if !FMOD_STUDIO && FMOD_VERSION < 0x42700 - else if ((version & 0xFFFF00) > 0x42600) -#else - else if ((version & 0xFFFF00) > (FMOD_VERSION & 0xFFFF00)) -#endif - { - wrongver = "a new"; - } - if (wrongver != NULL) - { - Printf (" " TEXTCOLOR_ORANGE "Error! You are using %s version of FMOD (%x.%02x.%02x).\n" - " " TEXTCOLOR_ORANGE "This program was built for version %x.%02x.%02x\n", - wrongver, - version >> 16, (version >> 8) & 255, version & 255, - FMOD_VERSION >> 16, (FMOD_VERSION >> 8) & 255, FMOD_VERSION & 255); - return false; - } - ActiveFMODVersion = version; - - if (!ShowedBanner) - { - // '\xa9' is the copyright symbol in the Windows-1252 code page. - Printf("FMOD Sound System, copyright \xa9 Firelight Technologies Pty, Ltd., 1994-2009.\n"); - Printf("Loaded FMOD version %x.%02x.%02x\n", version >> 16, (version >> 8) & 255, version & 255); - ShowedBanner = true; - } -#if defined(_WIN32) && !FMOD_STUDIO - if (OSPlatform == os_WinNT4) - { - // The following was true as of FMOD 3. I don't know if it still - // applies to FMOD Ex, nor do I have an NT 4 install anymore, but - // there's no reason to get rid of it yet. - // - // If running Windows NT 4, we need to initialize DirectSound before - // using WinMM. If we don't, then FSOUND_Close will corrupt a - // heap. This might just be the Audigy's drivers--I don't know why - // it happens. At least the fix is simple enough. I only need to - // initialize DirectSound once, and then I can initialize/close - // WinMM as many times as I want. - // - // Yes, using WinMM under NT 4 is a good idea. I can get latencies as - // low as 20 ms with WinMM, but with DirectSound I need to have the - // latency as high as 120 ms to avoid crackling--quite the opposite - // from the other Windows versions with real DirectSound support. - - static bool inited_dsound = false; - - if (!inited_dsound) - { - if (Sys->setOutput(FMOD_OUTPUTTYPE_DSOUND) == FMOD_OK) - { - if (Sys->init(1, FMOD_INIT_NORMAL, 0) == FMOD_OK) - { - inited_dsound = true; - Sleep(50); - Sys->close(); - } - Sys->setOutput(FMOD_OUTPUTTYPE_WINMM); - } - } - } -#endif - -#if !defined _WIN32 && !defined __APPLE__ && !FMOD_STUDIO - // Try to load SDL output plugin - result = Sys->setPluginPath(progdir); // Should we really look for it in the program directory? - result = Sys->loadPlugin("liboutput_sdl.so", &OutputPlugin); - if (result != FMOD_OK) - { - OutputPlugin = 0; - } -#endif - - // Set the user specified output mode. - eval = Enum_NumForName(OutputNames, snd_output); - if (eval >= 0) - { - if (eval == 666 && OutputPlugin != 0) - { - result = Sys->setOutputByPlugin(OutputPlugin); - } - else - { - result = Sys->setOutput(FMOD_OUTPUTTYPE(eval)); - } - if (result != FMOD_OK) - { - Printf(TEXTCOLOR_BLUE"Setting output type '%s' failed. Using default instead. (Error %d)\n", *snd_output, result); - eval = FMOD_OUTPUTTYPE_AUTODETECT; - Sys->setOutput(FMOD_OUTPUTTYPE_AUTODETECT); - } - } - - result = Sys->getNumDrivers(&driver); -#if defined(__unix__) && !FMOD_STUDIO - if (result == FMOD_OK) - { - // On Linux, FMOD defaults to OSS. If OSS is not present, it doesn't - // try ALSA; it just fails. We'll try for it, but only if OSS wasn't - // explicitly specified for snd_output. - if (driver == 0 && eval == FMOD_OUTPUTTYPE_AUTODETECT) - { - FMOD_OUTPUTTYPE output; - if (FMOD_OK == Sys->getOutput(&output)) - { - if (output == FMOD_OUTPUTTYPE_OSS) - { - Printf(TEXTCOLOR_BLUE"OSS could not be initialized. Trying ALSA.\n"); - Sys->setOutput(FMOD_OUTPUTTYPE_ALSA); - result = Sys->getNumDrivers(&driver); - } - } - } - } -#endif - if (result == FMOD_OK) - { - if (driver == 0) - { - Printf(TEXTCOLOR_ORANGE"No working sound devices found. Try a different snd_output?\n"); - return false; - } - if (snd_driver >= driver) - { - Printf(TEXTCOLOR_BLUE"Driver %d does not exist. Using 0.\n", *snd_driver); - driver = 0; - } - else - { - driver = snd_driver; - } - result = Sys->setDriver(driver); - } - result = Sys->getDriver(&driver); -#if FMOD_STUDIO - // We were built with an FMOD Studio that only returns the control panel frequency - result = Sys->getDriverInfo(driver, nullptr, 0, nullptr, &Driver_MinFrequency, &speakermode, nullptr); - Driver_MaxFrequency = Driver_MinFrequency; -#elif FMOD_VERSION >= 0x43600 - // We were built with an FMOD that only returns the control panel frequency - result = Sys->getDriverCaps(driver, &Driver_Caps, &Driver_MinFrequency, &speakermode); - Driver_MaxFrequency = Driver_MinFrequency; -#else - // We were built with an FMOD that returns a frequency range - result = Sys->getDriverCaps(driver, &Driver_Caps, &Driver_MinFrequency, &Driver_MaxFrequency, &speakermode); -#endif - if (result != FMOD_OK) - { - Printf(TEXTCOLOR_BLUE"Could not ascertain driver capabilities. Some things may be weird. (Error %d)\n", result); - // Fill in some default to pretend it worked. (But as long as we specify a valid driver, - // can this call actually fail?) -#if !FMOD_STUDIO - Driver_Caps = 0; -#endif - Driver_MinFrequency = 4000; - Driver_MaxFrequency = 48000; - speakermode = FMOD_SPEAKERMODE_STEREO; - } - - // Set the user selected speaker mode. - eval = Enum_NumForName(SpeakerModeNames, snd_speakermode); - if (eval >= 0) - { - speakermode = FMOD_SPEAKERMODE(eval); - } -#if !FMOD_STUDIO - result = Sys->setSpeakerMode(speakermode); - if (result != FMOD_OK) - { - Printf(TEXTCOLOR_BLUE"Could not set speaker mode to '%s'. (Error %d)\n", *snd_speakermode, result); - } -#endif - - // Set software format - eval = Enum_NumForName(SoundFormatNames, snd_output_format); - format = eval >= 0 ? FMOD_SOUND_FORMAT(eval) : FMOD_SOUND_FORMAT_PCM16; - if (format == FMOD_SOUND_FORMAT_PCM8) - { - // PCM-8 sounds like garbage with anything but DirectSound. - FMOD_OUTPUTTYPE output; - if (FMOD_OK != Sys->getOutput(&output) || output != FMOD_OUTPUTTYPE_DSOUND) - { - format = FMOD_SOUND_FORMAT_PCM16; - } - } - eval = Enum_NumForName(ResamplerNames, snd_resampler); - resampler = eval >= 0 ? FMOD_DSP_RESAMPLER(eval) : FMOD_DSP_RESAMPLER_LINEAR; - // These represented the frequency limits for hardware channels, which we never used anyway. -// samplerate = clamp(snd_samplerate, Driver_MinFrequency, Driver_MaxFrequency); - samplerate = snd_samplerate; - if (samplerate == 0 || snd_samplerate == 0) - { // Creative's ASIO drivers report the only supported frequency as 0! -#if FMOD_STUDIO - if (FMOD_OK != Sys->getSoftwareFormat(&samplerate, NULL, NULL)) -#else - if (FMOD_OK != Sys->getSoftwareFormat(&samplerate, NULL, NULL, NULL, NULL, NULL)) -#endif - { - samplerate = 48000; - } - } - if (samplerate != snd_samplerate && snd_samplerate != 0) - { - Printf(TEXTCOLOR_BLUE"Sample rate %d is unsupported. Trying %d.\n", *snd_samplerate, samplerate); - } -#if FMOD_STUDIO - result = Sys->setSoftwareFormat(samplerate, speakermode, 0); -#else - result = Sys->setSoftwareFormat(samplerate, format, 0, 0, resampler); -#endif - if (result != FMOD_OK) - { - Printf(TEXTCOLOR_BLUE"Could not set mixing format. Defaults will be used. (Error %d)\n", result); - } - -#if FMOD_STUDIO - FMOD_ADVANCEDSETTINGS advSettings = {}; - advSettings.cbSize = sizeof advSettings; - advSettings.resamplerMethod = resampler; - result = Sys->setAdvancedSettings(&advSettings); - if (result != FMOD_OK) - { - Printf(TEXTCOLOR_BLUE"Could not set resampler method. Defaults will be used. (Error %d)\n", result); - } -#endif - - // Set software channels according to snd_channels - result = Sys->setSoftwareChannels(snd_channels + NUM_EXTRA_SOFTWARE_CHANNELS); - if (result != FMOD_OK) - { - Printf(TEXTCOLOR_BLUE"Failed to set the preferred number of channels. (Error %d)\n", result); - } - -#if !FMOD_STUDIO - if (Driver_Caps & FMOD_CAPS_HARDWARE_EMULATED) - { // The user has the 'Acceleration' slider set to off! - // This is really bad for latency! - Printf (TEXTCOLOR_BLUE"Warning: The sound acceleration slider has been set to off.\n"); - Printf (TEXTCOLOR_BLUE"Please turn it back on if you want decent sound.\n"); - result = Sys->setDSPBufferSize(1024, 10); // At 48khz, the latency between issuing an fmod command and hearing it will now be about 213ms. - } - else -#endif - if (snd_buffersize != 0 || snd_buffercount != 0) - { - int buffersize = snd_buffersize ? snd_buffersize : 1024; - int buffercount = snd_buffercount ? snd_buffercount : 4; - result = Sys->setDSPBufferSize(buffersize, buffercount); - } - else - { - result = FMOD_OK; - } - if (result != FMOD_OK) - { - Printf(TEXTCOLOR_BLUE"Setting DSP buffer size failed. (Error %d)\n", result); - } - - // Try to init - initflags = FMOD_INIT_NORMAL; - if (snd_hrtf) - { - // These flags are the same thing, just with different names. -#ifdef FMOD_INIT_CHANNEL_LOWPASS - initflags |= FMOD_INIT_CHANNEL_LOWPASS; -#elif defined(FMOD_INIT_SOFTWARE_HRTF) - initflags |= FMOD_INIT_SOFTWARE_HRTF; -#else - initflags |= FMOD_INIT_HRTF_LOWPASS; -#endif - } - if (snd_profile) - { -#ifdef FMOD_INIT_PROFILE_ENABLE - initflags |= FMOD_INIT_PROFILE_ENABLE; -#else - initflags |= FMOD_INIT_ENABLE_PROFILE; -#endif - } - for (;;) - { - result = Sys->init(MAX(*snd_channels, MAX_CHANNELS), initflags, 0); - if (result == FMOD_ERR_OUTPUT_CREATEBUFFER) - { - // Possible causes of a buffer creation failure: - // 1. The speaker mode selected isn't supported by this soundcard. Force it to stereo. - // 2. The output format is unsupported. Force it to 16-bit PCM. - // 3. ??? -#if FMOD_STUDIO - result = Sys->getSoftwareFormat(nullptr, &speakermode, nullptr); -#else - result = Sys->getSpeakerMode(&speakermode); -#endif - if (result == FMOD_OK && - speakermode != FMOD_SPEAKERMODE_STEREO && -#if FMOD_STUDIO - FMOD_OK == Sys->setSoftwareFormat(samplerate, FMOD_SPEAKERMODE_STEREO, 0)) -#else - FMOD_OK == Sys->setSpeakerMode(FMOD_SPEAKERMODE_STEREO)) -#endif - { - Printf(TEXTCOLOR_RED" Buffer creation failed. Retrying with stereo output.\n"); - continue; - } -#if !FMOD_STUDIO - result = Sys->getSoftwareFormat(&samplerate, &format, NULL, NULL, &resampler, NULL); - if (result == FMOD_OK && - format != FMOD_SOUND_FORMAT_PCM16 && - FMOD_OK == Sys->setSoftwareFormat(samplerate, FMOD_SOUND_FORMAT_PCM16, 0, 0, resampler)) - { - Printf(TEXTCOLOR_RED" Buffer creation failed. Retrying with PCM-16 output.\n"); - continue; - } -#endif - } - else if (result == FMOD_ERR_NET_SOCKET_ERROR && -#ifdef FMOD_INIT_PROFILE_ENABLE - (initflags & FMOD_INIT_PROFILE_ENABLE)) -#else - (initflags & FMOD_INIT_ENABLE_PROFILE)) -#endif - { - Printf(TEXTCOLOR_RED" Could not create socket. Retrying without profiling.\n"); -#ifdef FMOD_INIT_PROFILE_ENABLE - initflags &= ~FMOD_INIT_PROFILE_ENABLE; -#else - initflags &= ~FMOD_INIT_ENABLE_PROFILE; -#endif - continue; - } -#ifdef _WIN32 - else if (result == FMOD_ERR_OUTPUT_INIT) - { - FMOD_OUTPUTTYPE output; - result = Sys->getOutput(&output); - if (result == FMOD_OK && output != FMOD_OUTPUTTYPE_DSOUND) - { - Printf(TEXTCOLOR_BLUE" Init failed for output type %s. Retrying with DirectSound.\n", - Enum_NameForNum(OutputNames, output)); - if (FMOD_OK == Sys->setOutput(FMOD_OUTPUTTYPE_DSOUND)) - { - continue; - } - } - } -#endif - break; - } - if (result != FMOD_OK) - { // Initializing FMOD failed. Cry cry. - Printf(TEXTCOLOR_ORANGE" System::init returned error code %d\n", result); - return false; - } - - // Create channel groups - result = Sys->createChannelGroup("Music", &MusicGroup); - if (result != FMOD_OK) - { - Printf(TEXTCOLOR_ORANGE" Could not create music channel group. (Error %d)\n", result); - return false; - } - - result = Sys->createChannelGroup("SFX", &SfxGroup); - if (result != FMOD_OK) - { - Printf(TEXTCOLOR_ORANGE" Could not create sfx channel group. (Error %d)\n", result); - return false; - } - - result = Sys->createChannelGroup("Pausable SFX", &PausableSfx); - if (result != FMOD_OK) - { - Printf(TEXTCOLOR_ORANGE" Could not create pausable sfx channel group. (Error %d)\n", result); - return false; - } - - result = SfxGroup->addGroup(PausableSfx); - if (result != FMOD_OK) - { - Printf(TEXTCOLOR_BLUE" Could not attach pausable sfx to sfx channel group. (Error %d)\n", result); - } - - // Create DSP units for underwater effect - result = Sys->createDSPByType(FMOD_DSP_TYPE_LOWPASS, &WaterLP); - if (result != FMOD_OK) - { - Printf(TEXTCOLOR_BLUE" Could not create underwater lowpass unit. (Error %d)\n", result); - } - else - { - result = Sys->createDSPByType(FMOD_DSP_TYPE_SFXREVERB, &WaterReverb); - if (result != FMOD_OK) - { - Printf(TEXTCOLOR_BLUE" Could not create underwater reverb unit. (Error %d)\n", result); - } - } - - // Connect underwater DSP unit between PausableSFX and SFX groups, while - // retaining the connection established by SfxGroup->addGroup(). - if (WaterLP != NULL) - { - FMOD::DSP *sfx_head, *pausable_head; - -#if FMOD_STUDIO - result = SfxGroup->getDSP(FMOD_CHANNELCONTROL_DSP_HEAD, &sfx_head); -#else - result = SfxGroup->getDSPHead(&sfx_head); -#endif - if (result == FMOD_OK) - { - result = sfx_head->getInput(0, &pausable_head, &SfxConnection); - if (result == FMOD_OK) - { - // The placeholder mixer is for reference to where to connect the SFX - // reverb unit once it gets created. - result = Sys->createDSPByType(FMOD_DSP_TYPE_MIXER, &SfxReverbPlaceholder); - if (result == FMOD_OK) - { - // Replace the PausableSFX->SFX connection with - // PausableSFX->ReverbPlaceholder->SFX. - result = SfxReverbPlaceholder->addInput(pausable_head, NULL); - if (result == FMOD_OK) - { - FMOD::DSPConnection *connection; - result = sfx_head->addInput(SfxReverbPlaceholder, &connection); - if (result == FMOD_OK) - { - sfx_head->disconnectFrom(pausable_head); - SfxReverbPlaceholder->setActive(true); - SfxReverbPlaceholder->setBypass(true); - // The placeholder now takes the place of the pausable_head - // for the following connections. - pausable_head = SfxReverbPlaceholder; - SfxConnection = connection; - } - } - else - { - SfxReverbPlaceholder->release(); - SfxReverbPlaceholder = NULL; - } - } - result = WaterLP->addInput(pausable_head, NULL); - WaterLP->setActive(false); - WaterLP->setParameterFloat(FMOD_DSP_LOWPASS_CUTOFF, snd_waterlp); - WaterLP->setParameterFloat(FMOD_DSP_LOWPASS_RESONANCE, 2); - - if (WaterReverb != NULL) - { - result = WaterReverb->addInput(WaterLP, NULL); - if (result == FMOD_OK) - { - result = sfx_head->addInput(WaterReverb, NULL); - if (result == FMOD_OK) - { -// WaterReverb->setParameter(FMOD_DSP_REVERB_ROOMSIZE, 0.001f); -// WaterReverb->setParameter(FMOD_DSP_REVERB_DAMP, 0.2f); - - // These parameters are entirely empirical and can probably - // stand some improvement, but it sounds remarkably close - // to the old reverb unit's output. -#if FMOD_STUDIO - WaterReverb->setParameterFloat(FMOD_DSP_SFXREVERB_LOWSHELFFREQUENCY, 150); -#else - WaterReverb->setParameterFloat(FMOD_DSP_SFXREVERB_LFREFERENCE, 150); -#endif - WaterReverb->setParameterFloat(FMOD_DSP_SFXREVERB_HFREFERENCE, 10000); -#if !FMOD_STUDIO - WaterReverb->setParameterFloat(FMOD_DSP_SFXREVERB_ROOM, 0); - WaterReverb->setParameterFloat(FMOD_DSP_SFXREVERB_ROOMHF, -5000); -#endif - WaterReverb->setParameterFloat(FMOD_DSP_SFXREVERB_DRYLEVEL, 0); -#if FMOD_STUDIO - WaterReverb->setParameterFloat(FMOD_DSP_SFXREVERB_HFDECAYRATIO, 100); -#else - WaterReverb->setParameterFloat(FMOD_DSP_SFXREVERB_DECAYHFRATIO, 1); -#endif - WaterReverb->setParameterFloat(FMOD_DSP_SFXREVERB_DECAYTIME, 0.25f); - WaterReverb->setParameterFloat(FMOD_DSP_SFXREVERB_DENSITY, 100); - WaterReverb->setParameterFloat(FMOD_DSP_SFXREVERB_DIFFUSION, 100); - WaterReverb->setActive(false); - } - } - } - else - { - result = sfx_head->addInput(WaterLP, NULL); - } - } - } - } - LastWaterLP = snd_waterlp; - - // Find the FMOD Channel Group Target Unit. To completely eliminate sound - // while the program is deactivated, we can deactivate this DSP unit, and - // all audio processing will cease. This is not directly exposed by the - // API but can be easily located by getting the master channel group and - // tracing its single output, since it is known to hook up directly to the - // Channel Group Target Unit. (See FMOD Profiler for proof.) - FMOD::ChannelGroup *master_group; - result = Sys->getMasterChannelGroup(&master_group); - if (result == FMOD_OK) - { - FMOD::DSP *master_head; - -#if FMOD_STUDIO - result = master_group->getDSP(FMOD_CHANNELCONTROL_DSP_HEAD, &master_head); -#else - result = master_group->getDSPHead(&master_head); -#endif - if (result == FMOD_OK) - { - result = master_head->getOutput(0, &ChannelGroupTargetUnit, NULL); - if (result != FMOD_OK) - { - ChannelGroupTargetUnit = NULL; - } - else - { - FMOD::DSP *dontcare; - result = ChannelGroupTargetUnit->getOutput(0, &dontcare, &ChannelGroupTargetUnitOutput); - if (result != FMOD_OK) - { - ChannelGroupTargetUnitOutput = NULL; - } - } - } - } - -#if FMOD_STUDIO - if (FMOD_OK != Sys->getSoftwareFormat(&OutputRate, NULL, NULL)) -#else - if (FMOD_OK != Sys->getSoftwareFormat(&OutputRate, NULL, NULL, NULL, NULL, NULL)) -#endif - { - OutputRate = 48000; // Guess, but this should never happen. - } - Sys->set3DSettings(0.5f, 96.f, 1.f); - Sys->set3DRolloffCallback(RolloffCallback); - Sys->setStreamBufferSize(snd_streambuffersize * 1024, FMOD_TIMEUNIT_RAWBYTES); - snd_sfxvolume.Callback (); - return true; -} - -//========================================================================== -// -// FMODSoundRenderer :: Shutdown -// -//========================================================================== - -void FMODSoundRenderer::Shutdown() -{ - if (Sys != NULL) - { - if (MusicGroup != NULL) - { - MusicGroup->release(); - MusicGroup = NULL; - } - if (PausableSfx != NULL) - { - PausableSfx->release(); - PausableSfx = NULL; - } - if (SfxGroup != NULL) - { - SfxGroup->release(); - SfxGroup = NULL; - } - if (WaterLP != NULL) - { - WaterLP->release(); - WaterLP = NULL; - } - if (WaterReverb != NULL) - { - WaterReverb->release(); - WaterReverb = NULL; - } - if (SfxReverbPlaceholder != NULL) - { - SfxReverbPlaceholder->release(); - SfxReverbPlaceholder = NULL; - } - - Sys->close(); - if (OutputPlugin != 0) - { - Sys->unloadPlugin(OutputPlugin); - OutputPlugin = 0; - } - Sys->release(); - Sys = NULL; - } -} - -//========================================================================== -// -// FMODSoundRenderer :: GetOutputRate -// -//========================================================================== - -float FMODSoundRenderer::GetOutputRate() -{ - return (float)OutputRate; -} - -//========================================================================== -// -// FMODSoundRenderer :: PrintStatus -// -//========================================================================== - -void FMODSoundRenderer::PrintStatus() -{ - FMOD_OUTPUTTYPE output; - FMOD_SPEAKERMODE speakermode; - int driver; - int samplerate; - unsigned int bufferlength; - int numbuffers; - - Printf ("Loaded FMOD version: " TEXTCOLOR_GREEN "%x.%02x.%02x\n", ActiveFMODVersion >> 16, - (ActiveFMODVersion >> 8) & 255, ActiveFMODVersion & 255); - if (FMOD_OK == Sys->getOutput(&output)) - { - Printf ("Output type: " TEXTCOLOR_GREEN "%s\n", Enum_NameForNum(OutputNames, output)); - } -#if FMOD_STUDIO - if (FMOD_OK == Sys->getSoftwareFormat(&samplerate, &speakermode, nullptr)) - { - Printf ("Speaker mode: " TEXTCOLOR_GREEN "%s\n", Enum_NameForNum(SpeakerModeNames, speakermode)); - Printf (TEXTCOLOR_LIGHTBLUE "Software mixer sample rate: " TEXTCOLOR_GREEN "%d\n", samplerate); - } -#else - if (FMOD_OK == Sys->getSpeakerMode(&speakermode)) - { - Printf ("Speaker mode: " TEXTCOLOR_GREEN "%s\n", Enum_NameForNum(SpeakerModeNames, speakermode)); - } -#endif - if (FMOD_OK == Sys->getDriver(&driver)) - { - char name[256]; -#if FMOD_STUDIO - if (FMOD_OK != Sys->getDriverInfo(driver, name, sizeof(name), nullptr, nullptr, nullptr, nullptr)) -#else - if (FMOD_OK != Sys->getDriverInfo(driver, name, sizeof(name), NULL)) -#endif - { - strcpy(name, "Unknown"); - } - Printf ("Driver: " TEXTCOLOR_GREEN "%d" TEXTCOLOR_NORMAL " (" TEXTCOLOR_ORANGE "%s" TEXTCOLOR_NORMAL ")\n", driver, name); -#if !FMOD_STUDIO - DumpDriverCaps(Driver_Caps, Driver_MinFrequency, Driver_MaxFrequency); -#endif - } -#if !FMOD_STUDIO - FMOD_SOUND_FORMAT format; - FMOD_DSP_RESAMPLER resampler; - int numoutputchannels; - if (FMOD_OK == Sys->getSoftwareFormat(&samplerate, &format, &numoutputchannels, NULL, &resampler, NULL)) - { - Printf (TEXTCOLOR_LIGHTBLUE "Software mixer sample rate: " TEXTCOLOR_GREEN "%d\n", samplerate); - Printf (TEXTCOLOR_LIGHTBLUE "Software mixer format: " TEXTCOLOR_GREEN "%s\n", Enum_NameForNum(SoundFormatNames, format)); - Printf (TEXTCOLOR_LIGHTBLUE "Software mixer channels: " TEXTCOLOR_GREEN "%d\n", numoutputchannels); - Printf (TEXTCOLOR_LIGHTBLUE "Software mixer resampler: " TEXTCOLOR_GREEN "%s\n", Enum_NameForNum(ResamplerNames, resampler)); - } -#endif - if (FMOD_OK == Sys->getDSPBufferSize(&bufferlength, &numbuffers)) - { - Printf (TEXTCOLOR_LIGHTBLUE "DSP buffers: " TEXTCOLOR_GREEN "%u samples x %d\n", bufferlength, numbuffers); - } -} - -//========================================================================== -// -// FMODSoundRenderer :: DumpDriverCaps -// -//========================================================================== - -#if !FMOD_STUDIO -void FMODSoundRenderer::DumpDriverCaps(FMOD_CAPS caps, int minfrequency, int maxfrequency) -{ - Printf (TEXTCOLOR_OLIVE " Min. frequency: " TEXTCOLOR_GREEN "%d\n", minfrequency); - Printf (TEXTCOLOR_OLIVE " Max. frequency: " TEXTCOLOR_GREEN "%d\n", maxfrequency); - Printf (" Features:\n"); - if (caps == 0) Printf(TEXTCOLOR_OLIVE " None\n"); - if (caps & FMOD_CAPS_HARDWARE) Printf(TEXTCOLOR_OLIVE " Hardware mixing\n"); - if (caps & FMOD_CAPS_HARDWARE_EMULATED) Printf(TEXTCOLOR_OLIVE " Hardware acceleration is turned off!\n"); - if (caps & FMOD_CAPS_OUTPUT_MULTICHANNEL) Printf(TEXTCOLOR_OLIVE " Multichannel\n"); - if (caps & FMOD_CAPS_OUTPUT_FORMAT_PCM8) Printf(TEXTCOLOR_OLIVE " PCM-8"); - if (caps & FMOD_CAPS_OUTPUT_FORMAT_PCM16) Printf(TEXTCOLOR_OLIVE " PCM-16"); - if (caps & FMOD_CAPS_OUTPUT_FORMAT_PCM24) Printf(TEXTCOLOR_OLIVE " PCM-24"); - if (caps & FMOD_CAPS_OUTPUT_FORMAT_PCM32) Printf(TEXTCOLOR_OLIVE " PCM-32"); - if (caps & FMOD_CAPS_OUTPUT_FORMAT_PCMFLOAT) Printf(TEXTCOLOR_OLIVE " PCM-Float"); - if (caps & (FMOD_CAPS_OUTPUT_FORMAT_PCM8 | FMOD_CAPS_OUTPUT_FORMAT_PCM16 | FMOD_CAPS_OUTPUT_FORMAT_PCM24 | FMOD_CAPS_OUTPUT_FORMAT_PCM32 | FMOD_CAPS_OUTPUT_FORMAT_PCMFLOAT)) - { - Printf("\n"); - } - if (caps & FMOD_CAPS_REVERB_LIMITED) Printf(TEXTCOLOR_OLIVE " Limited reverb\n"); -} -#endif - -//========================================================================== -// -// FMODSoundRenderer :: PrintDriversList -// -//========================================================================== - -void FMODSoundRenderer::PrintDriversList() -{ - int numdrivers; - int i; - char name[256]; - - if (FMOD_OK == Sys->getNumDrivers(&numdrivers)) - { - for (i = 0; i < numdrivers; ++i) - { -#if FMOD_STUDIO - if (FMOD_OK == Sys->getDriverInfo(i, name, sizeof(name), nullptr, nullptr, nullptr, nullptr)) -#else - if (FMOD_OK == Sys->getDriverInfo(i, name, sizeof(name), NULL)) -#endif - { - Printf("%d. %s\n", i, name); - } - } - } -} - -//========================================================================== -// -// FMODSoundRenderer :: GatherStats -// -//========================================================================== - -FString FMODSoundRenderer::GatherStats() -{ - int channels; - float dsp, stream, update, geometry, total; - FString out; - - channels = 0; - total = update = geometry = stream = dsp = 0; - Sys->getChannelsPlaying(&channels); -#if FMOD_STUDIO || FMOD_VERSION >= 0x42501 - // We were built with an FMOD with the geometry parameter. - if (ActiveFMODVersion >= 0x42501) - { // And we are running with an FMOD that includes it. - FMOD_System_GetCPUUsage((FMOD_SYSTEM *)Sys, &dsp, &stream, &geometry, &update, &total); - } - else - { // And we are running with an FMOD that does not include it. - // Cast the function to the appropriate type and call through the cast, - // since the headers are for the newer version. - ((FMOD_RESULT (F_API *)(FMOD_SYSTEM *, float *, float *, float *, float *)) - FMOD_System_GetCPUUsage)((FMOD_SYSTEM *)Sys, &dsp, &stream, &update, &total); - } -#else - // Same as above, except the headers we used do not include the geometry parameter. - if (ActiveFMODVersion >= 0x42501) - { - ((FMOD_RESULT (F_API *)(FMOD_SYSTEM *, float *, float *, float *, float *, float *)) - FMOD_System_GetCPUUsage)((FMOD_SYSTEM *)Sys, &dsp, &stream, &geometry, &update, &total); - } - else - { - FMOD_System_GetCPUUsage((FMOD_SYSTEM *)Sys, &dsp, &stream, &update, &total); - } -#endif - - out.Format ("%d channels," TEXTCOLOR_YELLOW "%5.2f" TEXTCOLOR_NORMAL "%% CPU " - "(DSP:" TEXTCOLOR_YELLOW "%5.2f" TEXTCOLOR_NORMAL "%% " - "Stream:" TEXTCOLOR_YELLOW "%5.2f" TEXTCOLOR_NORMAL "%% " - "Geometry:" TEXTCOLOR_YELLOW "%5.2f" TEXTCOLOR_NORMAL "%% " - "Update:" TEXTCOLOR_YELLOW "%5.2f" TEXTCOLOR_NORMAL "%%)", - channels, total, dsp, stream, geometry, update); - return out; -} - -//========================================================================== -// -// FMODSoundRenderer :: SetSfxVolume -// -//========================================================================== - -void FMODSoundRenderer::SetSfxVolume(float volume) -{ - SfxGroup->setVolume(volume); -} - -//========================================================================== -// -// FMODSoundRenderer :: SetMusicVolume -// -//========================================================================== - -void FMODSoundRenderer::SetMusicVolume(float volume) -{ - MusicGroup->setVolume(volume); -} - -//========================================================================== -// -// FMODSoundRenderer :: CreateStream -// -// Creates a streaming sound that receives PCM data through a callback. -// -//========================================================================== - -SoundStream *FMODSoundRenderer::CreateStream (SoundStreamCallback callback, int buffbytes, int flags, int samplerate, void *userdata) -{ - FMODStreamCapsule *capsule; - FMOD::Sound *sound; - FMOD_RESULT result; - FMOD_CREATESOUNDEXINFO exinfo; - FMOD_MODE mode; - int sample_shift; - int channel_shift; - - InitCreateSoundExInfo(&exinfo); - capsule = new FMODStreamCapsule (userdata, callback, this); - - mode = FMOD_2D | FMOD_OPENUSER | FMOD_LOOP_NORMAL | FMOD_SOFTWARE | FMOD_CREATESTREAM | FMOD_OPENONLY; - sample_shift = (flags & (SoundStream::Bits32 | SoundStream::Float)) ? 2 : (flags & SoundStream::Bits8) ? 0 : 1; - channel_shift = (flags & SoundStream::Mono) ? 0 : 1; - - // Chunk size of stream update in samples. This will be the amount of data - // passed to the user callback. - exinfo.decodebuffersize = buffbytes >> (sample_shift + channel_shift); - - // Number of channels in the sound. - exinfo.numchannels = 1 << channel_shift; - - // Length of PCM data in bytes of whole song (for Sound::getLength). - // This pretends it's extremely long. - exinfo.length = ~0u; - - // Default playback rate of sound. */ - exinfo.defaultfrequency = samplerate; - - // Data format of sound. - if (flags & SoundStream::Float) - { - exinfo.format = FMOD_SOUND_FORMAT_PCMFLOAT; - } - else if (flags & SoundStream::Bits32) - { - exinfo.format = FMOD_SOUND_FORMAT_PCM32; - } - else if (flags & SoundStream::Bits8) - { - exinfo.format = FMOD_SOUND_FORMAT_PCM8; - } - else - { - exinfo.format = FMOD_SOUND_FORMAT_PCM16; - } - - // User callback for reading. - exinfo.pcmreadcallback = FMODStreamCapsule::PCMReadCallback; - - // User callback for seeking. - exinfo.pcmsetposcallback = FMODStreamCapsule::PCMSetPosCallback; - - // User data to be attached to the sound during creation. Access via Sound::getUserData. - exinfo.userdata = capsule; - - result = Sys->createSound(NULL, mode, &exinfo, &sound); - if (result != FMOD_OK) - { - delete capsule; - return NULL; - } - capsule->SetStream(sound); - return capsule; -} - -//========================================================================== -// -// GetTagData -// -// Checks for a string-type tag, and returns its data. -// -//========================================================================== - -const char *GetTagData(FMOD::Sound *sound, const char *tag_name) -{ - FMOD_TAG tag; - - if (FMOD_OK == sound->getTag(tag_name, 0, &tag) && - (tag.datatype == FMOD_TAGDATATYPE_STRING || tag.datatype == FMOD_TAGDATATYPE_STRING_UTF8)) - { - return (const char *)tag.data; - } - return NULL; -} - -//========================================================================== -// -// SetCustomLoopPts -// -// Sets up custom sound loops by checking for these tags: -// LOOP_START -// LOOP_END -// LOOP_BIDI -// -//========================================================================== - -static void SetCustomLoopPts(FMOD::Sound *sound) -{ -#if 0 - FMOD_TAG tag; - int numtags; - if (FMOD_OK == stream->getNumTags(&numtags, NULL)) - { - for (int i = 0; i < numtags; ++i) - { - if (FMOD_OK == sound->getTag(NULL, i, &tag)) - { - Printf("Tag %2d. %d %s = %s\n", i, tag.datatype, tag.name, tag.data); - } - } - } -#endif - const char *tag_data; - unsigned int looppt[2]; - bool looppt_as_samples[2], have_looppt[2] = { false }; - static const char *const loop_tags[2] = { "LOOP_START", "LOOP_END" }; - - for (int i = 0; i < 2; ++i) - { - if (NULL != (tag_data = GetTagData(sound, loop_tags[i]))) - { - if (S_ParseTimeTag(tag_data, &looppt_as_samples[i], &looppt[i])) - { - have_looppt[i] = true; - } - else - { - Printf("Invalid %s tag: '%s'\n", loop_tags[i], tag_data); - } - } - } - if (have_looppt[0] && !have_looppt[1]) - { // Have a start tag, but not an end tag: End at the end of the song. - have_looppt[1] = (FMOD_OK == sound->getLength(&looppt[1], FMOD_TIMEUNIT_PCM)); - looppt_as_samples[1] = true; - } - else if (!have_looppt[0] && have_looppt[1]) - { // Have an end tag, but no start tag: Start at beginning of the song. - looppt[0] = 0; - looppt_as_samples[0] = true; - have_looppt[0] = true; - } - if (have_looppt[0] && have_looppt[1]) - { // Have both loop points: Try to set the loop. - FMOD_RESULT res = sound->setLoopPoints( - looppt[0], looppt_as_samples[0] ? FMOD_TIMEUNIT_PCM : FMOD_TIMEUNIT_MS, - looppt[1] - 1, looppt_as_samples[1] ? FMOD_TIMEUNIT_PCM : FMOD_TIMEUNIT_MS); - if (res != FMOD_OK) - { - Printf("Setting custom loop points failed. Error %d\n", res); - } - } - // Check for a bi-directional loop. - if (NULL != (tag_data = GetTagData(sound, "LOOP_BIDI")) && - (stricmp(tag_data, "on") == 0 || - stricmp(tag_data, "true") == 0 || - stricmp(tag_data, "yes") == 0 || - stricmp(tag_data, "1") == 0)) - { - FMOD_MODE mode; - if (FMOD_OK == (sound->getMode(&mode))) - { - sound->setMode((mode & ~(FMOD_LOOP_OFF | FMOD_LOOP_NORMAL)) | FMOD_LOOP_BIDI); - } - } -} - -//========================================================================== -// -// open_reader_callback -// close_reader_callback -// read_reader_callback -// seek_reader_callback -// -// FMOD_CREATESOUNDEXINFO callbacks to handle reading resource data from a -// FileReader. -// -//========================================================================== - -#if FMOD_STUDIO -static FMOD_RESULT F_CALLBACK open_reader_callback(const char *name, unsigned int *filesize, void **handle, void *userdata) -#else -static FMOD_RESULT F_CALLBACK open_reader_callback(const char *name, int unicode, unsigned int *filesize, void **handle, void **userdata) -#endif -{ - FileReader *reader = NULL; - if(sscanf(name, "_FileReader_%p", &reader) != 1) - { - Printf("Invalid name in callback: %s\n", name); - return FMOD_ERR_FILE_NOTFOUND; - } - - *filesize = reader->GetLength(); - *handle = reader; -#if !FMOD_STUDIO - *userdata = reader; -#endif - return FMOD_OK; -} - -static FMOD_RESULT F_CALLBACK close_reader_callback(void *handle, void *userdata) -{ - return FMOD_OK; -} - -static FMOD_RESULT F_CALLBACK read_reader_callback(void *handle, void *buffer, unsigned int sizebytes, unsigned int *bytesread, void *userdata) -{ - FileReader *reader = reinterpret_cast(handle); - *bytesread = reader->Read(buffer, sizebytes); - if(*bytesread > 0) return FMOD_OK; - return FMOD_ERR_FILE_EOF; -} - -static FMOD_RESULT F_CALLBACK seek_reader_callback(void *handle, unsigned int pos, void *userdata) -{ - FileReader *reader = reinterpret_cast(handle); - if(reader->Seek(pos, SEEK_SET) == 0) - return FMOD_OK; - return FMOD_ERR_FILE_COULDNOTSEEK; -} - - -//========================================================================== -// -// FMODSoundRenderer :: OpenStream -// -// Creates a streaming sound from a FileReader. -// -//========================================================================== - -SoundStream *FMODSoundRenderer::OpenStream(FileReader *reader, int flags) -{ - FMOD_MODE mode; - FMOD_CREATESOUNDEXINFO exinfo; - FMOD::Sound *stream; - FMOD_RESULT result; - FString patches; - FString name; - - InitCreateSoundExInfo(&exinfo); -#if FMOD_STUDIO - exinfo.fileuseropen = open_reader_callback; - exinfo.fileuserclose = close_reader_callback; - exinfo.fileuserread = read_reader_callback; - exinfo.fileuserseek = seek_reader_callback; -#else - exinfo.useropen = open_reader_callback; - exinfo.userclose = close_reader_callback; - exinfo.userread = read_reader_callback; - exinfo.userseek = seek_reader_callback; -#endif - - mode = FMOD_SOFTWARE | FMOD_2D | FMOD_CREATESTREAM; - if(flags & SoundStream::Loop) - mode |= FMOD_LOOP_NORMAL; - if((*snd_midipatchset)[0] != '\0') - { -#ifdef _WIN32 - // If the path does not contain any path separators, automatically - // prepend $PROGDIR to the path. - if (strcspn(snd_midipatchset, ":/\\") == strlen(snd_midipatchset)) - { - patches << "$PROGDIR/" << snd_midipatchset; - patches = NicePath(patches); - } - else -#endif - { - patches = NicePath(snd_midipatchset); - } - exinfo.dlsname = patches; - } - - name.Format("_FileReader_%p", reader); - result = Sys->createSound(name, mode, &exinfo, &stream); - if(result == FMOD_ERR_FORMAT && exinfo.dlsname != NULL) - { - // FMOD_ERR_FORMAT could refer to either the main sound file or - // to the DLS instrument set. Try again without special DLS - // instruments to see if that lets it succeed. - exinfo.dlsname = NULL; - result = Sys->createSound(name, mode, &exinfo, &stream); - if (result == FMOD_OK) - { - Printf("%s is an unsupported format.\n", *snd_midipatchset); - } - } - if(result != FMOD_OK) - return NULL; - - SetCustomLoopPts(stream); - return new FMODStreamCapsule(stream, this, reader); -} - -SoundStream *FMODSoundRenderer::OpenStream(const char *url, int flags) -{ - FMOD_MODE mode; - FMOD_CREATESOUNDEXINFO exinfo; - FMOD::Sound *stream; - FMOD_RESULT result; - FString patches; - - InitCreateSoundExInfo(&exinfo); - mode = FMOD_SOFTWARE | FMOD_2D | FMOD_CREATESTREAM; - if(flags & SoundStream::Loop) - mode |= FMOD_LOOP_NORMAL; - if((*snd_midipatchset)[0] != '\0') - { -#ifdef _WIN32 - // If the path does not contain any path separators, automatically - // prepend $PROGDIR to the path. - if (strcspn(snd_midipatchset, ":/\\") == strlen(snd_midipatchset)) - { - patches << "$PROGDIR/" << snd_midipatchset; - patches = NicePath(patches); - } - else -#endif - { - patches = NicePath(snd_midipatchset); - } - exinfo.dlsname = patches; - } - - result = Sys->createSound(url, mode, &exinfo, &stream); - if(result == FMOD_ERR_FORMAT && exinfo.dlsname != NULL) - { - exinfo.dlsname = NULL; - result = Sys->createSound(url, mode, &exinfo, &stream); - if(result == FMOD_OK) - { - Printf("%s is an unsupported format.\n", *snd_midipatchset); - } - } - - if(result != FMOD_OK) - return NULL; - - SetCustomLoopPts(stream); - return new FMODStreamCapsule(stream, this, url); -} - -//========================================================================== -// -// FMODSoundRenderer :: StartSound -// -//========================================================================== - -FISoundChannel *FMODSoundRenderer::StartSound(SoundHandle sfx, float vol, int pitch, int flags, FISoundChannel *reuse_chan) -{ - FMOD_RESULT result; - FMOD_MODE mode; - FMOD::Channel *chan; - float freq; - -#if FMOD_STUDIO - if (FMOD_OK == ((FMOD::Sound *)sfx.data)->getDefaults(&freq, NULL)) -#else - if (FMOD_OK == ((FMOD::Sound *)sfx.data)->getDefaults(&freq, NULL, NULL, NULL)) -#endif - { - freq = PITCH(freq, pitch); - } - else - { - freq = 0; - } - - GRolloff = NULL; // Do 2D sounds need rolloff? -#if FMOD_STUDIO - result = Sys->playSound((FMOD::Sound *)sfx.data, (flags & SNDF_NOPAUSE) ? SfxGroup : PausableSfx, true, &chan); -#else - result = Sys->playSound(FMOD_CHANNEL_FREE, (FMOD::Sound *)sfx.data, true, &chan); -#endif - if (FMOD_OK == result) - { - result = chan->getMode(&mode); - - if (result != FMOD_OK) - { - assert(0); - mode = FMOD_SOFTWARE; - } - mode = (mode & ~FMOD_3D) | FMOD_2D; - if (flags & SNDF_LOOP) - { - mode &= ~FMOD_LOOP_OFF; - if (!(mode & (FMOD_LOOP_NORMAL | FMOD_LOOP_BIDI))) - { - mode |= FMOD_LOOP_NORMAL; - } - } - else - { - mode |= FMOD_LOOP_OFF; - } - chan->setMode(mode); -#if !FMOD_STUDIO - chan->setChannelGroup((flags & SNDF_NOPAUSE) ? SfxGroup : PausableSfx); -#endif - if (freq != 0) - { - chan->setFrequency(freq); - } - chan->setVolume(vol); - if (!HandleChannelDelay(chan, reuse_chan, flags & (SNDF_ABSTIME | SNDF_LOOP), freq)) - { - chan->stop(); - return NULL; - } - if (flags & SNDF_NOREVERB) - { -#if FMOD_STUDIO - chan->setReverbProperties(0,0.f); -#else - FMOD_REVERB_CHANNELPROPERTIES reverb = { 0, }; - if (FMOD_OK == chan->getReverbProperties(&reverb)) - { - reverb.Room = -10000; - chan->setReverbProperties(&reverb); - } -#endif - } - chan->setPaused(false); - return CommonChannelSetup(chan, reuse_chan); - } - - //DPrintf (DMSG_WARNING, "Sound %s failed to play: %d\n", sfx->name.GetChars(), result); - return NULL; -} - -//========================================================================== -// -// FMODSoundRenderer :: StartSound3D -// -//========================================================================== - -FISoundChannel *FMODSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener *listener, float vol, - FRolloffInfo *rolloff, float distscale, - int pitch, int priority, const FVector3 &pos, const FVector3 &vel, - int channum, int flags, FISoundChannel *reuse_chan) -{ - FMOD_RESULT result; - FMOD_MODE mode; - FMOD::Channel *chan; - float freq; - float def_freq; -#if !FMOD_STUDIO - float def_vol, def_pan; -#endif - int numchans; - int def_priority; - -#if FMOD_STUDIO - if (FMOD_OK == ((FMOD::Sound *)sfx.data)->getDefaults(&def_freq, &def_priority)) -#else - if (FMOD_OK == ((FMOD::Sound *)sfx.data)->getDefaults(&def_freq, &def_vol, &def_pan, &def_priority)) -#endif - { - freq = PITCH(def_freq, pitch); - // Change the sound's default priority before playing it. -#if FMOD_STUDIO - ((FMOD::Sound *)sfx.data)->setDefaults(def_freq, clamp(def_priority - priority, 1, 256)); -#else - ((FMOD::Sound *)sfx.data)->setDefaults(def_freq, def_vol, def_pan, clamp(def_priority - priority, 1, 256)); -#endif - } - else - { - freq = 0; - def_priority = -1; - } - - // Play it. - GRolloff = rolloff; - GDistScale = distscale; - - // Experiments indicate that playSound will ignore priorities and always succeed - // as long as the parameters are set properly. It will first try to kick out sounds - // with the same priority level but has no problem with kicking out sounds at - // higher priority levels if it needs to. -#if FMOD_STUDIO - result = Sys->playSound((FMOD::Sound *)sfx.data, (flags & SNDF_NOPAUSE) ? SfxGroup : PausableSfx, true, &chan); -#else - result = Sys->playSound(FMOD_CHANNEL_FREE, (FMOD::Sound *)sfx.data, true, &chan); -#endif - - // Then set the priority back. - if (def_priority >= 0) - { -#if FMOD_STUDIO - ((FMOD::Sound *)sfx.data)->setDefaults(def_freq, def_priority); -#else - ((FMOD::Sound *)sfx.data)->setDefaults(def_freq, def_vol, def_pan, def_priority); -#endif - } - - if (FMOD_OK == result) - { - result = chan->getMode(&mode); - if (result != FMOD_OK) - { - mode = FMOD_3D | FMOD_SOFTWARE; - } - if (flags & SNDF_LOOP) - { - mode &= ~FMOD_LOOP_OFF; - if (!(mode & (FMOD_LOOP_NORMAL | FMOD_LOOP_BIDI))) - { - mode |= FMOD_LOOP_NORMAL; - } - } - else - { - // FMOD_LOOP_OFF overrides FMOD_LOOP_NORMAL and FMOD_LOOP_BIDI - mode |= FMOD_LOOP_OFF; - } - mode = SetChanHeadSettings(listener, chan, pos, !!(flags & SNDF_AREA), mode); - chan->setMode(mode); -#if !FMOD_STUDIO - chan->setChannelGroup((flags & SNDF_NOPAUSE) ? SfxGroup : PausableSfx); -#endif - - if (mode & FMOD_3D) - { - // Reduce volume of stereo sounds, because each channel will be summed together - // and is likely to be very similar, resulting in an amplitude twice what it - // would have been had it been mixed to mono. - if (FMOD_OK == ((FMOD::Sound *)sfx.data)->getFormat(NULL, NULL, &numchans, NULL)) - { - if (numchans > 1) - { - vol *= 0.5f; - } - } - } - if (freq != 0) - { - chan->setFrequency(freq); - } - chan->setVolume(vol); - if (mode & FMOD_3D) - { - chan->set3DAttributes((FMOD_VECTOR *)&pos[0], (FMOD_VECTOR *)&vel[0]); - } - if (!HandleChannelDelay(chan, reuse_chan, flags & (SNDF_ABSTIME | SNDF_LOOP), freq)) - { - // FMOD seems to get confused if you stop a channel right after - // starting it, so hopefully this function will never fail. - // (Presumably you need an update between them, but I haven't - // tested this hypothesis.) - chan->stop(); - return NULL; - } - if (flags & SNDF_NOREVERB) - { -#if FMOD_STUDIO - chan->setReverbProperties(0,0.f); -#else - FMOD_REVERB_CHANNELPROPERTIES reverb = { 0, }; - if (FMOD_OK == chan->getReverbProperties(&reverb)) - { - reverb.Room = -10000; - chan->setReverbProperties(&reverb); - } -#endif - } - chan->setPaused(false); - chan->getPriority(&def_priority); - FISoundChannel *schan = CommonChannelSetup(chan, reuse_chan); - schan->Rolloff = *rolloff; - return schan; - } - - GRolloff = NULL; - //DPrintf (DMSG_WARNING, "Sound %s failed to play: %d\n", sfx->name.GetChars(), result); - return 0; -} - -//========================================================================== -// -// FMODSoundRenderer :: MarkStartTime -// -// Marks a channel's start time without actually playing it. -// -//========================================================================== - -void FMODSoundRenderer::MarkStartTime(FISoundChannel *chan) -{ -#if FMOD_STUDIO - uint64_t dsp_time; - ((FMOD::Channel *)chan->SysChannel)->getDSPClock(&dsp_time,NULL); - chan->StartTime.Lo = dsp_time & 0xFFFFFFFF; - chan->StartTime.Hi = dsp_time >> 32; -#else - Sys->getDSPClock(&chan->StartTime.Hi, &chan->StartTime.Lo); -#endif -} - -//========================================================================== -// -// FMODSoundRenderer :: HandleChannelDelay -// -// If the sound is restarting, seek it to its proper place. Returns false -// if the sound would have ended. -// -// Otherwise, record its starting time, and return true. -// -//========================================================================== - -bool FMODSoundRenderer::HandleChannelDelay(FMOD::Channel *chan, FISoundChannel *reuse_chan, int flags, float freq) const -{ - if (reuse_chan != NULL) - { // Sound is being restarted, so seek it to the position - // it would be in now if it had never been evicted. - QWORD_UNION nowtime; -#if FMOD_STUDIO - uint64_t delay; - chan->getDelay(&delay,NULL,NULL); - nowtime.Lo = delay & 0xFFFFFFFF; - nowtime.Hi = delay >> 32; -#else - chan->getDelay(FMOD_DELAYTYPE_DSPCLOCK_START, &nowtime.Hi, &nowtime.Lo); -#endif - - // If abstime is set, the sound is being restored, and - // the channel's start time is actually its seek position. - if (flags & SNDF_ABSTIME) - { - unsigned int seekpos = reuse_chan->StartTime.Lo; - if (seekpos > 0) - { - chan->setPosition(seekpos, FMOD_TIMEUNIT_PCM); - } - reuse_chan->StartTime.AsOne = uint64_t(nowtime.AsOne - seekpos * OutputRate / freq); - } - else if (reuse_chan->StartTime.AsOne != 0) - { - uint64_t difftime = nowtime.AsOne - reuse_chan->StartTime.AsOne; - if (difftime > 0) - { - // Clamp the position of looping sounds to be within the sound. - // If we try to start it several minutes past its normal end, - // FMOD doesn't like that. - // FIXME: Clamp this right for loops that don't cover the whole sound. - if (flags & SNDF_LOOP) - { - FMOD::Sound *sound; - if (FMOD_OK == chan->getCurrentSound(&sound)) - { - unsigned int len; - if (FMOD_OK == sound->getLength(&len, FMOD_TIMEUNIT_MS) && len != 0) - { - difftime %= len; - } - } - } - return chan->setPosition((unsigned int)(difftime / OutputRate), FMOD_TIMEUNIT_MS) == FMOD_OK; - } - } - } - else - { -// chan->setDelay(FMOD_DELAYTYPE_DSPCLOCK_START, DSPClock.Hi, DSPClock.Lo); - } - return true; -} - -//========================================================================== -// -// FMODSoundRenderer :: SetChanHeadSettings -// -// If this sound is played at the same coordinates as the listener, make -// it head relative. Also, area sounds should use no 3D panning if close -// enough to the listener. -// -//========================================================================== - -FMOD_MODE FMODSoundRenderer::SetChanHeadSettings(SoundListener *listener, FMOD::Channel *chan, - const FVector3 &pos, bool areasound, - FMOD_MODE oldmode) const -{ - if (!listener->valid) - { - return oldmode; - } - FVector3 cpos, mpos; - - cpos = listener->position; - - if (areasound) - { - float level, old_level; - - // How far are we from the perceived sound origin? Within a certain - // short distance, we interpolate between 2D panning and full 3D panning. - const double interp_range = 32.0; - double dist_sqr = (cpos - pos).LengthSquared(); - - if (dist_sqr == 0) - { - level = 0; - } - else if (dist_sqr <= interp_range * interp_range) - { // Within interp_range: Interpolate between none and full 3D panning. - level = float(1 - (interp_range - sqrt(dist_sqr)) / interp_range); - } - else - { // Beyond interp_range: Normal 3D panning. - level = 1; - } -#if FMOD_STUDIO - if (chan->get3DLevel(&old_level) == FMOD_OK && old_level != level) - { // Only set it if it's different. - chan->set3DLevel(level); -#else - if (chan->get3DPanLevel(&old_level) == FMOD_OK && old_level != level) - { // Only set it if it's different. - chan->set3DPanLevel(level); -#endif - if (level < 1) - { // Let the noise come from all speakers, not just the front ones. - // A centered 3D sound does not play at full volume, so neither should the 2D-panned one. - // This is sqrt(0.5), which is the result for a centered equal power panning. -#if FMOD_STUDIO - chan->setMixLevelsOutput(0.70711f,0.70711f,0.70711f,0.70711f,0.70711f,0.70711f,0.70711f,0.70711f); -#else - chan->setSpeakerMix(0.70711f,0.70711f,0.70711f,0.70711f,0.70711f,0.70711f,0.70711f,0.70711f); -#endif - } - } - return oldmode; - } - else if ((cpos - pos).LengthSquared() < (0.0004 * 0.0004)) - { // Head relative - return (oldmode & ~FMOD_3D) | FMOD_2D; - } - // World relative - return (oldmode & ~FMOD_2D) | FMOD_3D; -} - -//========================================================================== -// -// FMODSoundRenderer :: CommonChannelSetup -// -// Assign an end callback to the channel and allocates a game channel for -// it. -// -//========================================================================== - -FISoundChannel *FMODSoundRenderer::CommonChannelSetup(FMOD::Channel *chan, FISoundChannel *reuse_chan) const -{ - FISoundChannel *schan; - - if (reuse_chan != NULL) - { - schan = reuse_chan; - schan->SysChannel = chan; - } - else - { - schan = S_GetChannel(chan); -#if FMOD_STUDIO - uint64_t time; - chan->getDelay(&time,NULL,NULL); - schan->StartTime.Lo = time & 0xFFFFFFFF; - schan->StartTime.Hi = time >> 32; -#else - chan->getDelay(FMOD_DELAYTYPE_DSPCLOCK_START, &schan->StartTime.Hi, &schan->StartTime.Lo); -#endif - } - chan->setUserData(schan); - chan->setCallback(ChannelCallback); - GRolloff = NULL; - return schan; -} - -//========================================================================== -// -// FMODSoundRenderer :: StopChannel -// -//========================================================================== - -void FMODSoundRenderer::StopChannel(FISoundChannel *chan) -{ - if (chan != NULL && chan->SysChannel != NULL) - { - if (((FMOD::Channel *)chan->SysChannel)->stop() == FMOD_ERR_INVALID_HANDLE) - { // The channel handle was invalid; pretend it ended. - S_ChannelEnded(chan); - } - } -} - -//========================================================================== -// -// FMODSoundRenderer :: ChannelVolume -// -//========================================================================== - -void FMODSoundRenderer::ChannelVolume(FISoundChannel *chan, float volume) -{ - if (chan != NULL && chan->SysChannel != NULL) - { - ((FMOD::Channel *)chan->SysChannel)->setVolume(volume); - } -} - -//========================================================================== -// -// FMODSoundRenderer :: GetPosition -// -// Returns position of sound on this channel, in samples. -// -//========================================================================== - -unsigned int FMODSoundRenderer::GetPosition(FISoundChannel *chan) -{ - unsigned int pos; - - if (chan == NULL || chan->SysChannel == NULL) - { - return 0; - } - ((FMOD::Channel *)chan->SysChannel)->getPosition(&pos, FMOD_TIMEUNIT_PCM); - return pos; -} - -//========================================================================== -// -// FMODSoundRenderer :: GetAudibility -// -// Returns the audible volume of the channel, after rollof and any other -// factors are applied. -// -//========================================================================== - -float FMODSoundRenderer::GetAudibility(FISoundChannel *chan) -{ - float aud; - - if (chan == NULL || chan->SysChannel == NULL) - { - return 0; - } - ((FMOD::Channel *)chan->SysChannel)->getAudibility(&aud); - return aud; -} - -//========================================================================== -// -// FMODSoundRenderer :: SetSfxPaused -// -//========================================================================== - -void FMODSoundRenderer::SetSfxPaused(bool paused, int slot) -{ - int oldslots = SFXPaused; - - if (paused) - { - SFXPaused |= 1 << slot; - } - else - { - SFXPaused &= ~(1 << slot); - } - //Printf("%d\n", SFXPaused); - if (oldslots != 0 && SFXPaused == 0) - { - PausableSfx->setPaused(false); - } - else if (oldslots == 0 && SFXPaused != 0) - { - PausableSfx->setPaused(true); - } -} - -//========================================================================== -// -// FMODSoundRenderer :: SetInactive -// -// This is similar to SetSfxPaused but will *pause* everything, including -// the global reverb effect. This is meant to be used only when the -// game is deactivated, not for general sound pausing. -// -//========================================================================== - -void FMODSoundRenderer::SetInactive(SoundRenderer::EInactiveState inactive) -{ - float mix; - bool active; - - if (inactive == INACTIVE_Active) - { - mix = 1; - active = true; - } - else if (inactive == INACTIVE_Complete) - { - mix = 1; - active = false; - } - else // inactive == INACTIVE_Mute - { - mix = 0; - active = true; - } - if (ChannelGroupTargetUnitOutput != NULL) - { - ChannelGroupTargetUnitOutput->setMix(mix); - } - if (ChannelGroupTargetUnit != NULL) - { - ChannelGroupTargetUnit->setActive(active); - } -} - -//========================================================================== -// -// FMODSoundRenderer :: UpdateSoundParams3D -// -//========================================================================== - -void FMODSoundRenderer::UpdateSoundParams3D(SoundListener *listener, FISoundChannel *chan, bool areasound, const FVector3 &pos, const FVector3 &vel) -{ - if (chan == NULL || chan->SysChannel == NULL) - return; - - FMOD::Channel *fchan = (FMOD::Channel *)chan->SysChannel; - FMOD_MODE oldmode, mode; - - if (fchan->getMode(&oldmode) != FMOD_OK) - { - oldmode = FMOD_3D | FMOD_SOFTWARE; - } - mode = SetChanHeadSettings(listener, fchan, pos, areasound, oldmode); - if (mode != oldmode) - { // Only set the mode if it changed. - fchan->setMode(mode); - } - fchan->set3DAttributes((FMOD_VECTOR *)&pos[0], (FMOD_VECTOR *)&vel[0]); -} - -//========================================================================== -// -// FMODSoundRenderer :: UpdateListener -// -//========================================================================== - -void FMODSoundRenderer::UpdateListener(SoundListener *listener) -{ - FMOD_VECTOR pos, vel; - FMOD_VECTOR forward; - FMOD_VECTOR up; - - if (!listener->valid) - { - return; - } - - // Set velocity to 0 to prevent crazy doppler shifts just from running. - - vel.x = listener->velocity.X; - vel.y = listener->velocity.Y; - vel.z = listener->velocity.Z; - pos.x = listener->position.X; - pos.y = listener->position.Y; - pos.z = listener->position.Z; - - float angle = listener->angle; - forward.x = cosf(angle); - forward.y = 0; - forward.z = sinf(angle); - - up.x = 0; - up.y = 1; - up.z = 0; - - Sys->set3DListenerAttributes(0, &pos, &vel, &forward, &up); - - bool underwater = false; - const ReverbContainer *env; - - underwater = (listener->underwater && snd_waterlp); - if (ForcedEnvironment) - { - env = ForcedEnvironment; - } - else - { - env = listener->Environment; - if (env == NULL) - { - env = DefaultEnvironments[0]; - } - } - if (env != PrevEnvironment || env->Modified) - { - DPrintf (DMSG_NOTIFY, "Reverb Environment %s\n", env->Name); - const_cast(env)->Modified = false; - SetSystemReverbProperties(&env->Properties); - PrevEnvironment = env; - - if (!SfxReverbHooked) - { - SfxReverbHooked = ReconnectSFXReverbUnit(); - } - } - - if (underwater || env->SoftwareWater) - { - //PausableSfx->setPitch(0.64171f); // This appears to be what Duke 3D uses - PausableSfx->setPitch(0.7937005f); // Approx. 4 semitones lower; what Nash suggested - if (WaterLP != NULL) - { - if (LastWaterLP != snd_waterlp) - { - LastWaterLP = snd_waterlp; - WaterLP->setParameterFloat(FMOD_DSP_LOWPASS_CUTOFF, snd_waterlp); - } - WaterLP->setActive(true); - if (WaterReverb != NULL && snd_waterreverb) - { - WaterReverb->setActive(true); - WaterReverb->setBypass(false); - SfxConnection->setMix(0); - } - else - { - // Let some of the original mix through so that high frequencies are - // not completely lost. The reverb unit has its own connection and - // preserves dry sounds itself if used. - SfxConnection->setMix(0.1f); - if (WaterReverb != NULL) - { - WaterReverb->setActive(true); - WaterReverb->setBypass(true); - } - } - } - } - else - { - PausableSfx->setPitch(1); - if (WaterLP != NULL) - { - SfxConnection->setMix(1); - WaterLP->setActive(false); - if (WaterReverb != NULL) - { - WaterReverb->setActive(false); - } - } - } -} - -//========================================================================== -// -// FMODSoundRenderer :: ReconnectSFXReverbUnit -// -// Locates the DSP unit responsible for software 3D reverb. There is only -// one, and it by default is connected directly to the ChannelGroup Target -// Unit. Older versions of FMOD created this at startup; newer versions -// delay creating it until the first call to setReverbProperties, at which -// point it persists until the system is closed. -// -// Upon locating the proper DSP unit, reconnects it to serve as an input to -// our water DSP chain after the Pausable SFX ChannelGroup. -// -//========================================================================== - -bool FMODSoundRenderer::ReconnectSFXReverbUnit() -{ - FMOD::DSP *unit; - FMOD_DSP_TYPE type; - int numinputs, i; - - if (ChannelGroupTargetUnit == NULL || SfxReverbPlaceholder == NULL) - { - return false; - } - // Look for SFX Reverb unit - if (FMOD_OK != ChannelGroupTargetUnit->getNumInputs(&numinputs)) - { - return false; - } - for (i = numinputs - 1; i >= 0; --i) - { - if (FMOD_OK == ChannelGroupTargetUnit->getInput(i, &unit, NULL) && - FMOD_OK == unit->getType(&type)) - { - if (type == FMOD_DSP_TYPE_SFXREVERB) - { - break; - } - } - } - if (i < 0) - { - return false; - } - - // Found it! Now move it in the DSP graph to be done before the water - // effect. - if (FMOD_OK != ChannelGroupTargetUnit->disconnectFrom(unit)) - { - return false; - } - if (FMOD_OK != SfxReverbPlaceholder->addInput(unit, NULL)) - { - return false; - } - return true; -} - -//========================================================================== -// -// FMODSoundRenderer :: Sync -// -// Used by the save/load code to restart sounds at the same position they -// were in at the time of saving. Must not be nested. -// -//========================================================================== - -void FMODSoundRenderer::Sync(bool sync) -{ - DSPLocked = sync; - if (sync) - { - Sys->lockDSP(); -#if FMOD_STUDIO - uint64_t clock; - SfxGroup->getDSPClock(&clock,NULL); - DSPClock.Lo = clock & 0xFFFFFFFF; - DSPClock.Hi = clock >> 32; -#else - Sys->getDSPClock(&DSPClock.Hi, &DSPClock.Lo); -#endif - } - else - { - Sys->unlockDSP(); - } -} - -//========================================================================== -// -// FMODSoundRenderer :: UpdateSounds -// -//========================================================================== - -void FMODSoundRenderer::UpdateSounds() -{ - // Any sounds played between now and the next call to this function - // will start exactly one tic from now. -#if FMOD_STUDIO - uint64_t clock; - SfxGroup->getDSPClock(&clock,NULL); - DSPClock.Lo = clock & 0xFFFFFFFF; - DSPClock.Hi = clock >> 32; -#else - Sys->getDSPClock(&DSPClock.Hi, &DSPClock.Lo); -#endif - DSPClock.AsOne += OutputRate / TICRATE; - Sys->update(); -} - -//========================================================================== -// -// FMODSoundRenderer :: LoadSoundRaw -// -//========================================================================== - -std::pair FMODSoundRenderer::LoadSoundRaw(uint8_t *sfxdata, int length, int frequency, int channels, int bits, int loopstart, int loopend, bool monoize) -{ - FMOD_CREATESOUNDEXINFO exinfo; - SoundHandle retval = { NULL }; - int numsamples; - - if (length <= 0) - { - return std::make_pair(retval, true); - } - - InitCreateSoundExInfo(&exinfo); - exinfo.length = length; - exinfo.numchannels = channels; - exinfo.defaultfrequency = frequency; - switch (bits) - { -#if FMOD_STUDIO - case -8: - // Need to convert sample data from signed to unsigned. - for (int i = 0; i < length; i++) - { - sfxdata[i] ^= 0x80; - } - - case 8: -#else // !FMOD_STUDIO - case 8: - // Need to convert sample data from unsigned to signed. - for (int i = 0; i < length; ++i) - { - sfxdata[i] = sfxdata[i] - 128; - } - - case -8: -#endif // FMOD_STUDIO - exinfo.format = FMOD_SOUND_FORMAT_PCM8; - numsamples = length; - break; - - case 16: - exinfo.format = FMOD_SOUND_FORMAT_PCM16; - numsamples = length >> 1; - break; - - case 32: - exinfo.format = FMOD_SOUND_FORMAT_PCM32; - numsamples = length >> 2; - break; - - default: - return std::make_pair(retval, true); - } - - const FMOD_MODE samplemode = FMOD_3D | FMOD_OPENMEMORY | FMOD_SOFTWARE | FMOD_OPENRAW; - FMOD::Sound *sample; - FMOD_RESULT result; - - result = Sys->createSound((char *)sfxdata, samplemode, &exinfo, &sample); - if (result != FMOD_OK) - { - DPrintf(DMSG_ERROR, "Failed to allocate sample: Error %d\n", result); - return std::make_pair(retval, true); - } - - if (loopstart >= 0) - { - if (loopend == -1) - loopend = numsamples - 1; - sample->setLoopPoints(loopstart, FMOD_TIMEUNIT_PCM, loopend, FMOD_TIMEUNIT_PCM); - } - - retval.data = sample; - return std::make_pair(retval, true); -} - -//========================================================================== -// -// FMODSoundRenderer :: LoadSound -// -//========================================================================== - -std::pair FMODSoundRenderer::LoadSound(uint8_t *sfxdata, int length, bool monoize) -{ - FMOD_CREATESOUNDEXINFO exinfo; - SoundHandle retval = { NULL }; - - if (length == 0) return std::make_pair(retval, true); - - InitCreateSoundExInfo(&exinfo); - exinfo.length = length; - - const FMOD_MODE samplemode = FMOD_3D | FMOD_OPENMEMORY | FMOD_SOFTWARE; - FMOD::Sound *sample; - FMOD_RESULT result; - - result = Sys->createSound((char *)sfxdata, samplemode, &exinfo, &sample); - if (result != FMOD_OK) - { - DPrintf(DMSG_ERROR, "Failed to allocate sample: Error %d\n", result); - return std::make_pair(retval, true); - } - SetCustomLoopPts(sample); - retval.data = sample; - return std::make_pair(retval, true); -} - -//========================================================================== -// -// FMODSoundRenderer :: UnloadSound -// -//========================================================================== - -void FMODSoundRenderer::UnloadSound(SoundHandle sfx) -{ - if (sfx.data != NULL) - { - ((FMOD::Sound *)sfx.data)->release(); - } -} - -//========================================================================== -// -// FMODSoundRenderer :: GetMSLength -// -//========================================================================== - -unsigned int FMODSoundRenderer::GetMSLength(SoundHandle sfx) -{ - if (sfx.data != NULL) - { - unsigned int length; - - if (((FMOD::Sound *)sfx.data)->getLength(&length, FMOD_TIMEUNIT_MS) == FMOD_OK) - { - return length; - } - } - return 0; // Don't know. -} - - -//========================================================================== -// -// FMODSoundRenderer :: GetMSLength -// -//========================================================================== - -unsigned int FMODSoundRenderer::GetSampleLength(SoundHandle sfx) -{ - if (sfx.data != NULL) - { - unsigned int length; - - if (((FMOD::Sound *)sfx.data)->getLength(&length, FMOD_TIMEUNIT_PCM) == FMOD_OK) - { - return length; - } - } - return 0; // Don't know. -} - - -//========================================================================== -// -// FMODSoundRenderer :: ChannelCallback static -// -// Handles when a channel finishes playing. This is only called when -// System::update is called and is therefore asynchronous with the actual -// end of the channel. -// -//========================================================================== - -FMOD_RESULT F_CALLBACK FMODSoundRenderer::ChannelCallback -#if FMOD_STUDIO - (FMOD_CHANNELCONTROL *channel, FMOD_CHANNELCONTROL_TYPE controltype, FMOD_CHANNELCONTROL_CALLBACK_TYPE type, void *data1, void *data2) -#else - (FMOD_CHANNEL *channel, FMOD_CHANNEL_CALLBACKTYPE type, void *data1, void *data2) -#endif -{ -#if FMOD_STUDIO - FMOD::ChannelControl *chan = (FMOD::ChannelControl *)channel; -#else - FMOD::Channel *chan = (FMOD::Channel *)channel; -#endif - FISoundChannel *schan; - - if (chan->getUserData((void **)&schan) == FMOD_OK && schan != NULL) - { -#if FMOD_STUDIO - if (type == FMOD_CHANNELCONTROL_CALLBACK_END) -#else - if (type == FMOD_CHANNEL_CALLBACKTYPE_END) -#endif - { - S_ChannelEnded(schan); - } -#if FMOD_STUDIO - else if (type == FMOD_CHANNELCONTROL_CALLBACK_VIRTUALVOICE) -#else - else if (type == FMOD_CHANNEL_CALLBACKTYPE_VIRTUALVOICE) -#endif - { - S_ChannelVirtualChanged(schan, data1 != 0); - } - } - return FMOD_OK; -} - - -//========================================================================== -// -// FMODSoundRenderer :: RolloffCallback static -// -// Calculates a volume for the sound based on distance. -// -//========================================================================== - -#if FMOD_STUDIO -float F_CALLBACK FMODSoundRenderer::RolloffCallback(FMOD_CHANNELCONTROL *channel, float distance) -#else -float F_CALLBACK FMODSoundRenderer::RolloffCallback(FMOD_CHANNEL *channel, float distance) -#endif -{ -#if FMOD_STUDIO - FMOD::ChannelControl *chan = (FMOD::ChannelControl *)channel; -#else - FMOD::Channel *chan = (FMOD::Channel *)channel; -#endif - FISoundChannel *schan; - - if (GRolloff != NULL) - { - return S_GetRolloff(GRolloff, distance * GDistScale, true); - } - else if (chan->getUserData((void **)&schan) == FMOD_OK && schan != NULL) - { - return S_GetRolloff(&schan->Rolloff, distance * schan->DistanceScale, true); - } - else - { - return 0; - } -} - -//========================================================================== -// -// FMODSoundRenderer :: DrawWaveDebug -// -// Bit 0: ( 1) Show oscilloscope for sfx. -// Bit 1: ( 2) Show spectrum for sfx. -// Bit 2: ( 4) Show oscilloscope for music. -// Bit 3: ( 8) Show spectrum for music. -// Bit 4: (16) Show oscilloscope for all sounds. -// Bit 5: (32) Show spectrum for all sounds. -// -//========================================================================== - -void FMODSoundRenderer::DrawWaveDebug(int mode) -{ - const int window_height = 100; - int window_size; - int numoutchans; - int y, yy; - const spk *labels; - int labelcount; - -#if FMOD_STUDIO - if (FMOD_OK != Sys->getSoftwareFormat(NULL, NULL, &numoutchans)) -#else - if (FMOD_OK != Sys->getSoftwareFormat(NULL, NULL, &numoutchans, NULL, NULL, NULL)) -#endif - { - return; - } - - // Decide on which set of labels to use. - labels = (numoutchans == 4) ? SpeakerNames4 : SpeakerNamesMore; - labelcount = MIN(numoutchans, countof(SpeakerNamesMore)); - - // Scale all the channel windows so one group fits completely on one row, with - // 16 pixels of padding between each window. - window_size = (screen->GetWidth() - 16) / numoutchans - 16; - - float *wavearray = (float*)alloca(MAX(SPECTRUM_SIZE,window_size)*sizeof(float)); - y = 16; - - yy = DrawChannelGroupOutput(SfxGroup, wavearray, window_size, window_height, y, mode); - if (y != yy) - { - DrawSpeakerLabels(labels, yy-14, window_size, labelcount); - } - y = DrawChannelGroupOutput(MusicGroup, wavearray, window_size, window_height, yy, mode >> 2); - if (y != yy) - { - DrawSpeakerLabels(labels, y-14, window_size, labelcount); - } - yy = DrawSystemOutput(wavearray, window_size, window_height, y, mode >> 4); - if (y != yy) - { - DrawSpeakerLabels(labels, yy-14, window_size, labelcount); - } -} - -//========================================================================== -// -// FMODSoundRenderer :: DrawSpeakerLabels -// -//========================================================================== - -void FMODSoundRenderer::DrawSpeakerLabels(const spk *labels, int y, int width, int count) -{ - if (labels == NULL) - { - return; - } - for (int i = 0, x = 16; i < count; ++i) - { - screen->DrawText(SmallFont, CR_LIGHTBLUE, x, y, labels[i], TAG_DONE); - x += width + 16; - } -} - -//========================================================================== -// -// FMODSoundRenderer :: DrawChannelGroupOutput -// -// Draws an oscilloscope and/or a spectrum for a channel group. -// -//========================================================================== - -int FMODSoundRenderer::DrawChannelGroupOutput(FMOD::ChannelGroup *group, float *wavearray, int width, int height, int y, int mode) -{ - int y1, y2; - - switch (mode & 0x03) - { - case 0x01: // Oscilloscope only - return DrawChannelGroupWaveData(group, wavearray, width, height, y, false); - - case 0x02: // Spectrum only - return DrawChannelGroupSpectrum(group, wavearray, width, height, y, false); - - case 0x03: // Oscilloscope + Spectrum - width = (width + 16) / 2 - 16; - y1 = DrawChannelGroupSpectrum(group, wavearray, width, height, y, true); - y2 = DrawChannelGroupWaveData(group, wavearray, width, height, y, true); - return MAX(y1, y2); - } - return y; -} - -//========================================================================== -// -// FMODSoundRenderer :: DrawSystemOutput -// -// Like DrawChannelGroupOutput(), but uses the system object. -// -//========================================================================== - -int FMODSoundRenderer::DrawSystemOutput(float *wavearray, int width, int height, int y, int mode) -{ - int y1, y2; - - switch (mode & 0x03) - { - case 0x01: // Oscilloscope only - return DrawSystemWaveData(wavearray, width, height, y, false); - - case 0x02: // Spectrum only - return DrawSystemSpectrum(wavearray, width, height, y, false); - - case 0x03: // Oscilloscope + Spectrum - width = (width + 16) / 2 - 16; - y1 = DrawSystemSpectrum(wavearray, width, height, y, true); - y2 = DrawSystemWaveData(wavearray, width, height, y, true); - return MAX(y1, y2); - } - return y; -} - -//========================================================================== -// -// FMODSoundRenderer :: DrawChannelGroupWaveData -// -// Draws all the output channels for a specified channel group. -// Setting skip to true causes it to skip every other window. -// -//========================================================================== - -int FMODSoundRenderer::DrawChannelGroupWaveData(FMOD::ChannelGroup *group, float *wavearray, int width, int height, int y, bool skip) -{ - int drawn = 0; - int x = 16; - -#if !FMOD_STUDIO - while (FMOD_OK == group->getWaveData(wavearray, width, drawn)) - { - drawn++; - DrawWave(wavearray, x, y, width, height); - x += (width + 16) << int(skip); - } -#endif - if (drawn) - { - y += height + 16; - } - return y; -} - -//========================================================================== -// -// FMODSoundRenderer::DrawSystemWaveData -// -// Like DrawChannelGroupWaveData, but it uses the system object to get the -// complete output. -// -//========================================================================== - -int FMODSoundRenderer::DrawSystemWaveData(float *wavearray, int width, int height, int y, bool skip) -{ - int drawn = 0; - int x = 16; - -#if !FMOD_STUDIO - while (FMOD_OK == Sys->getWaveData(wavearray, width, drawn)) - { - drawn++; - DrawWave(wavearray, x, y, width, height); - x += (width + 16) << int(skip); - } -#endif - if (drawn) - { - y += height + 16; - } - return y; -} - -//========================================================================== -// -// FMODSoundRenderer :: DrawWave -// -// Draws an oscilloscope at the specified coordinates on the screen. Each -// entry in the wavearray buffer has its own column. IOW, there are -// entries in wavearray. -// -//========================================================================== - -void FMODSoundRenderer::DrawWave(float *wavearray, int x, int y, int width, int height) -{ - float scale = height / 2.f; - float mid = y + scale; - int i; - - // Draw a box around the oscilloscope. - screen->DrawLine(x - 1, y - 1, x + width, y - 1, -1, MAKEARGB(160, 0, 40, 200)); - screen->DrawLine(x + width, y - 1, x + width, y + height, -1, MAKEARGB(160, 0, 40, 200)); - screen->DrawLine(x + width, y + height, x - 1, y + height, -1, MAKEARGB(160, 0, 40, 200)); - screen->DrawLine(x - 1, y + height, x - 1, y - 1, -1, MAKEARGB(160, 0, 40, 200)); - - // Draw the actual oscilloscope. - if (screen->Accel2D) - { // Drawing this with lines is super-slow without hardware acceleration, at least with - // the debug build. - float lasty = mid - wavearray[0] * scale; - float newy; - for (i = 1; i < width; ++i) - { - newy = mid - wavearray[i] * scale; - screen->DrawLine(x + i - 1, int(lasty), x + i, int(newy), -1, MAKEARGB(255,255,248,248)); - lasty = newy; - } - } - else - { - for (i = 0; i < width; ++i) - { - float y = wavearray[i] * scale + mid; - screen->DrawPixel(x + i, int(y), -1, MAKEARGB(255,255,255,255)); - } - } -} - -//========================================================================== -// -// FMODSoundRenderer :: DrawChannelGroupSpectrum -// -// Draws all the spectrum for a specified channel group. -// Setting skip to true causes it to skip every other window, starting at -// the second one. -// -//========================================================================== - -int FMODSoundRenderer::DrawChannelGroupSpectrum(FMOD::ChannelGroup *group, float *spectrumarray, int width, int height, int y, bool skip) -{ - int drawn = 0; - int x = 16; - - if (skip) - { - x += width + 16; - } - // TODO: FMOD Studio: Grab from DSP -#if !FMOD_STUDIO - while (FMOD_OK == group->getSpectrum(spectrumarray, SPECTRUM_SIZE, drawn, FMOD_DSP_FFT_WINDOW_TRIANGLE)) - { - drawn++; - DrawSpectrum(spectrumarray, x, y, width, height); - x += (width + 16) << int(skip); - } -#endif - if (drawn) - { - y += height + 16; - } - return y; -} - -//========================================================================== -// -// FMODSoundRenderer::DrawSystemSpectrum -// -// Like DrawChannelGroupSpectrum, but it uses the system object to get the -// complete output. -// -//========================================================================== - -int FMODSoundRenderer::DrawSystemSpectrum(float *spectrumarray, int width, int height, int y, bool skip) -{ - int drawn = 0; - int x = 16; - - if (skip) - { - x += width + 16; - } - // TODO: FMOD Studio: Grab from DSP -#if !FMOD_STUDIO - while (FMOD_OK == Sys->getSpectrum(spectrumarray, SPECTRUM_SIZE, drawn, FMOD_DSP_FFT_WINDOW_TRIANGLE)) - { - drawn++; - DrawSpectrum(spectrumarray, x, y, width, height); - x += (width + 16) << int(skip); - } -#endif - if (drawn) - { - y += height + 16; - } - return y; -} - -//========================================================================== -// -// FMODSoundRenderer :: DrawSpectrum -// -// Draws a spectrum at the specified coordinates on the screen. -// -//========================================================================== - -void FMODSoundRenderer::DrawSpectrum(float *spectrumarray, int x, int y, int width, int height) -{ - float scale = height / 2.f; - float mid = y + scale; - float db; - int top; - - // Draw a border and dark background for the spectrum. - screen->DrawLine(x - 1, y - 1, x + width, y - 1, -1, MAKEARGB(160, 0, 40, 200)); - screen->DrawLine(x + width, y - 1, x + width, y + height, -1, MAKEARGB(160, 0, 40, 200)); - screen->DrawLine(x + width, y + height, x - 1, y + height, -1, MAKEARGB(160, 0, 40, 200)); - screen->DrawLine(x - 1, y + height, x - 1, y - 1, -1, MAKEARGB(160, 0, 40, 200)); - screen->Dim(MAKERGB(0,0,0), 0.3f, x, y, width, height); - - // Draw the actual spectrum. - for (int i = 0; i < width; ++i) - { - db = spectrumarray[i * (SPECTRUM_SIZE - 2) / width + 1]; - db = MAX(-150.f, 10 * log10f(db) * 2); // Convert to decibels and clamp - db = 1.f - (db / -150.f); - db *= height; - top = (int)db; - if (top >= height) - { - top = height - 1; - } -// screen->Clear(x + i, int(y + height - db), x + i + 1, y + height, -1, MAKEARGB(255, 255, 255, 40)); - screen->Dim(MAKERGB(255,255,40), 0.65f, x + i, y + height - top, 1, top); - } -} - -//========================================================================== -// -// FMODSoundRenderer :: DecodeSample -// -// Uses FMOD to decode a compressed sample to a 16-bit buffer. This is used -// by the DUMB XM reader to handle FMOD's OggMods. -// -//========================================================================== - -short *FMODSoundRenderer::DecodeSample(int outlen, const void *coded, int sizebytes, ECodecType type) -{ - FMOD_CREATESOUNDEXINFO exinfo; - FMOD::Sound *sound; - FMOD_SOUND_FORMAT format; - int channels; - unsigned int len, amt_read; - FMOD_RESULT result; - short *outbuf; - - InitCreateSoundExInfo(&exinfo); - if (type == CODEC_Vorbis) - { - exinfo.suggestedsoundtype = FMOD_SOUND_TYPE_OGGVORBIS; - } - exinfo.length = sizebytes; - result = Sys->createSound((const char *)coded, - FMOD_2D | FMOD_SOFTWARE | FMOD_CREATESTREAM | - FMOD_OPENMEMORY_POINT | FMOD_OPENONLY | FMOD_LOWMEM, - &exinfo, &sound); - if (result != FMOD_OK) - { - return NULL; - } - result = sound->getFormat(NULL, &format, &channels, NULL); - // TODO: Handle more formats if it proves necessary. - if (result != FMOD_OK || format != FMOD_SOUND_FORMAT_PCM16 || channels != 1) - { - sound->release(); - return NULL; - } - len = outlen; - // Must be malloc'ed for DUMB, which is C. - outbuf = (short *)malloc(len); - result = sound->readData(outbuf, len, &amt_read); - sound->release(); - if (result == FMOD_ERR_FILE_EOF) - { - memset((uint8_t *)outbuf + amt_read, 0, len - amt_read); - } - else if (result != FMOD_OK || amt_read != len) - { - free(outbuf); - return NULL; - } - return outbuf; -} - -//========================================================================== -// -// FMODSoundRenderer :: InitCreateSoundExInfo -// -// Allow for compiling with 4.26 APIs while still running with older DLLs. -// -//========================================================================== - -void FMODSoundRenderer::InitCreateSoundExInfo(FMOD_CREATESOUNDEXINFO *exinfo) const -{ - memset(exinfo, 0, sizeof(*exinfo)); -#if !FMOD_STUDIO && FMOD_VERSION >= 0x42600 && FMOD_VERSION < 0x43800 - if (ActiveFMODVersion < 0x42600) - { - // This parameter was added for 4.26.00, and trying to pass it to older - // DLLs will fail. - exinfo->cbsize = myoffsetof(FMOD_CREATESOUNDEXINFO, ignoresetfilesystem); - } - else -#endif - { - exinfo->cbsize = sizeof(*exinfo); - } -} - -//========================================================================== -// -// FMODSoundRenderer :: SetSystemReverbProperties -// -// Set the global reverb properties. -// -//========================================================================== - -FMOD_RESULT FMODSoundRenderer::SetSystemReverbProperties(const REVERB_PROPERTIES *props) -{ -#if !FMOD_STUDIO && FMOD_VERSION < 0x43600 - return Sys->setReverbProperties((const FMOD_REVERB_PROPERTIES *)props); -#else - // The reverb format changed when hardware mixing support was dropped, because - // all EAX-only properties were removed from the structure. - FMOD_REVERB_PROPERTIES fr; - -#if FMOD_STUDIO - const float LateEarlyRatio = powf(10.f, (props->Reverb - props->Reflections)/2000.f); - const float EarlyAndLatePower = powf(10.f, props->Reflections/1000.f) + powf(10, props->Reverb/1000.f); - const float HFGain = powf(10.f, props->RoomHF/2000.f); - fr.DecayTime = props->DecayTime*1000.f; - fr.EarlyDelay = props->ReflectionsDelay*1000.f; - fr.LateDelay = props->ReverbDelay*1000.f; - fr.HFReference = props->HFReference; - fr.HFDecayRatio = clamp(props->DecayHFRatio*100.f, 0.f, 100.f); - fr.Diffusion = props->Diffusion; - fr.Density = props->Density; - fr.LowShelfFrequency = props->DecayLFRatio; - fr.LowShelfGain = clamp(props->RoomLF/100.f, -48.f, 12.f); - fr.HighCut = clamp(props->RoomLF < 0 ? props->HFReference/sqrtf((1.f-HFGain)/HFGain) : 20000.f, 20.f, 20000.f); - fr.EarlyLateMix = props->Reflections > -10000.f ? LateEarlyRatio/(LateEarlyRatio + 1)*100.f : 100.f; - fr.WetLevel = clamp(10*log10f(EarlyAndLatePower)+props->Room/100.f, -80.f, 20.f); - - return Sys->setReverbProperties(0, &fr); -#else - fr.Instance = props->Instance; - fr.Environment = props->Environment; - fr.EnvDiffusion = props->EnvDiffusion; - fr.Room = props->Room; - fr.RoomHF = props->RoomHF; - fr.RoomLF = props->RoomLF; - fr.DecayTime = props->DecayTime; - fr.DecayHFRatio = props->DecayHFRatio; - fr.DecayLFRatio = props->DecayLFRatio; - fr.Reflections = props->Reflections; - fr.ReflectionsDelay = props->ReflectionsDelay; - fr.Reverb = props->Reverb; - fr.ReverbDelay = props->ReverbDelay; - fr.ModulationTime = props->ModulationTime; - fr.ModulationDepth = props->ModulationDepth; - fr.HFReference = props->HFReference; - fr.LFReference = props->LFReference; - fr.Diffusion = props->Diffusion; - fr.Density = props->Density; - fr.Flags = props->Flags; - - return Sys->setReverbProperties(&fr); -#endif -#endif -} - -MIDIDevice* FMODSoundRenderer::CreateMIDIDevice() const -{ - return new SndSysMIDIDevice; -} - -#endif // NO_FMOD - - -//========================================================================== -// -// IsFModExPresent -// -// Check if FMod can be used -// -//========================================================================== - -bool IsFModExPresent() -{ -#ifdef NO_FMOD - return false; -#elif !defined _MSC_VER - return true; // on non-MSVC we cannot delay load the library so it has to be present. -#else - static bool cached_result; - static bool done = false; - - if (!done) - { - done = true; - - FMOD::System *Sys; - FMOD_RESULT result; - __try - { - result = FMOD::System_Create(&Sys); - } - __except (CheckException(GetExceptionCode())) - { - // FMod could not be delay loaded - return false; - } - if (result == FMOD_OK) Sys->release(); - cached_result = true; - } - return cached_result; -#endif -} diff --git a/src/sound/fmodsound.h b/src/sound/fmodsound.h deleted file mode 100644 index d80423ebd..000000000 --- a/src/sound/fmodsound.h +++ /dev/null @@ -1,141 +0,0 @@ -#ifndef FMODSOUND_H -#define FMODSOUND_H - -#include "i_sound.h" - -#ifndef NO_FMOD -#include "fmod_wrap.h" - -class FMODSoundRenderer : public SoundRenderer -{ -public: - FMODSoundRenderer (); - ~FMODSoundRenderer (); - bool IsValid (); - - void SetSfxVolume (float volume); - void SetMusicVolume (float volume); - std::pair LoadSound(uint8_t *sfxdata, int length, bool monoize); - std::pair LoadSoundRaw(uint8_t *sfxdata, int length, int frequency, int channels, int bits, int loopstart, int loopend = -1, bool monoize = false); - void UnloadSound (SoundHandle sfx); - unsigned int GetMSLength(SoundHandle sfx); - unsigned int GetSampleLength(SoundHandle sfx); - float GetOutputRate(); - - // Streaming sounds. - SoundStream *CreateStream (SoundStreamCallback callback, int buffsamples, int flags, int samplerate, void *userdata); - SoundStream *OpenStream (FileReader *reader, int flags); - SoundStream *OpenStream (const char *url, int flags); - - // Starts a sound. - FISoundChannel *StartSound (SoundHandle sfx, float vol, int pitch, int chanflags, FISoundChannel *reuse_chan); - FISoundChannel *StartSound3D (SoundHandle sfx, SoundListener *listener, float vol, FRolloffInfo *rolloff, float distscale, int pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FISoundChannel *reuse_chan); - - // Stops a sound channel. - void StopChannel (FISoundChannel *chan); - - // Changes a channel's volume. - void ChannelVolume (FISoundChannel *chan, float volume); - - // Marks a channel's start time without actually playing it. - void MarkStartTime (FISoundChannel *chan); - - // Returns position of sound on this channel, in samples. - unsigned int GetPosition(FISoundChannel *chan); - - // Gets a channel's audibility (real volume). - float GetAudibility(FISoundChannel *chan); - - // Synchronizes following sound startups. - void Sync (bool sync); - - // Pauses or resumes all sound effect channels. - void SetSfxPaused (bool paused, int slot); - - // Pauses or resumes *every* channel, including environmental reverb. - void SetInactive (EInactiveState inactive); - - // Updates the position of a sound channel. - void UpdateSoundParams3D (SoundListener *listener, FISoundChannel *chan, bool areasound, const FVector3 &pos, const FVector3 &vel); - - void UpdateListener (SoundListener *listener); - void UpdateSounds (); - - void PrintStatus (); - void PrintDriversList (); - FString GatherStats (); - short *DecodeSample(int outlen, const void *coded, int sizebytes, ECodecType type); - - void DrawWaveDebug(int mode); - - virtual MIDIDevice* CreateMIDIDevice() const override; - -private: - uint32_t ActiveFMODVersion; - int SFXPaused; - bool InitSuccess; - bool DSPLocked; - QWORD_UNION DSPClock; - int OutputRate; - -#if FMOD_STUDIO - static FMOD_RESULT F_CALLBACK ChannelCallback(FMOD_CHANNELCONTROL *channel, FMOD_CHANNELCONTROL_TYPE controltype, FMOD_CHANNELCONTROL_CALLBACK_TYPE type, void *data1, void *data2); - static float F_CALLBACK RolloffCallback(FMOD_CHANNELCONTROL *channel, float distance); -#else - static FMOD_RESULT F_CALLBACK ChannelCallback(FMOD_CHANNEL *channel, FMOD_CHANNEL_CALLBACKTYPE type, void *data1, void *data2); - static float F_CALLBACK RolloffCallback(FMOD_CHANNEL *channel, float distance); -#endif - - bool HandleChannelDelay(FMOD::Channel *chan, FISoundChannel *reuse_chan, int flags, float freq) const; - FISoundChannel *CommonChannelSetup(FMOD::Channel *chan, FISoundChannel *reuse_chan) const; - FMOD_MODE SetChanHeadSettings(SoundListener *listener, FMOD::Channel *chan, const FVector3 &pos, bool areasound, FMOD_MODE oldmode) const; - - bool ReconnectSFXReverbUnit(); - void InitCreateSoundExInfo(FMOD_CREATESOUNDEXINFO *exinfo) const; - FMOD_RESULT SetSystemReverbProperties(const REVERB_PROPERTIES *props); - - bool Init (); - void Shutdown (); -#if !FMOD_STUDIO - void DumpDriverCaps(FMOD_CAPS caps, int minfrequency, int maxfrequency); -#endif - - int DrawChannelGroupOutput(FMOD::ChannelGroup *group, float *wavearray, int width, int height, int y, int mode); - int DrawSystemOutput(float *wavearray, int width, int height, int y, int mode); - - int DrawChannelGroupWaveData(FMOD::ChannelGroup *group, float *wavearray, int width, int height, int y, bool skip); - int DrawSystemWaveData(float *wavearray, int width, int height, int y, bool skip); - void DrawWave(float *wavearray, int x, int y, int width, int height); - - int DrawChannelGroupSpectrum(FMOD::ChannelGroup *group, float *wavearray, int width, int height, int y, bool skip); - int DrawSystemSpectrum(float *wavearray, int width, int height, int y, bool skip); - void DrawSpectrum(float *spectrumarray, int x, int y, int width, int height); - - typedef char spk[4]; - static const spk SpeakerNames4[4], SpeakerNamesMore[8]; - void DrawSpeakerLabels(const spk *labels, int y, int width, int count); - - FMOD::System *Sys; - FMOD::ChannelGroup *SfxGroup, *PausableSfx; - FMOD::ChannelGroup *MusicGroup; - FMOD::DSP *WaterLP, *WaterReverb; - FMOD::DSPConnection *SfxConnection; - FMOD::DSPConnection *ChannelGroupTargetUnitOutput; - FMOD::DSP *ChannelGroupTargetUnit; - FMOD::DSP *SfxReverbPlaceholder; - bool SfxReverbHooked; - float LastWaterLP; - unsigned int OutputPlugin; - - // Just for snd_status display - int Driver_MinFrequency; - int Driver_MaxFrequency; -#if !FMOD_STUDIO - FMOD_CAPS Driver_Caps; -#endif - - friend class FMODStreamCapsule; -}; - -#endif -#endif diff --git a/src/sound/i_music.cpp b/src/sound/i_music.cpp index af848cbeb..a31c4de74 100644 --- a/src/sound/i_music.cpp +++ b/src/sound/i_music.cpp @@ -184,9 +184,6 @@ void I_ShutdownMusic(bool onexit) } Timidity::FreeAll(); if (onexit) WildMidi_Shutdown(); -#ifdef _WIN32 - I_ShutdownMusicWin32(); -#endif // _WIN32 } void I_ShutdownMusicExit() diff --git a/src/sound/i_musicinterns.h b/src/sound/i_musicinterns.h index 227464c11..6cb2e05a2 100644 --- a/src/sound/i_musicinterns.h +++ b/src/sound/i_musicinterns.h @@ -10,7 +10,6 @@ #include "wildmidi/wildmidi_lib.h" void I_InitMusicWin32 (); -void I_ShutdownMusicWin32 (); extern float relative_volume; diff --git a/src/sound/i_sound.cpp b/src/sound/i_sound.cpp index 42e5a8d7d..74445a98c 100644 --- a/src/sound/i_sound.cpp +++ b/src/sound/i_sound.cpp @@ -39,7 +39,6 @@ #include "doomtype.h" #include -#include "fmodsound.h" #include "oalsound.h" #include "mpg123_decoder.h" @@ -68,9 +67,7 @@ CVAR (Int, snd_samplerate, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR (Int, snd_buffersize, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR (String, snd_output, "default", CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -#ifndef NO_FMOD -#define DEF_BACKEND "fmod" -#elif !defined(NO_OPENAL) +#if !defined(NO_OPENAL) #define DEF_BACKEND "openal" #else #define DEF_BACKEND "null" @@ -259,29 +256,10 @@ void I_InitSound () return; } - // This has been extended to allow falling back from FMod to OpenAL and vice versa if the currently active sound system cannot be found. if (stricmp(snd_backend, "null") == 0) { GSnd = new NullSoundRenderer; } - else if(stricmp(snd_backend, "fmod") == 0) - { - #ifndef NO_FMOD - if (IsFModExPresent()) - { - GSnd = new FMODSoundRenderer; - } - #endif - #ifndef NO_OPENAL - if ((!GSnd || !GSnd->IsValid()) && IsOpenALPresent()) - { - Printf (TEXTCOLOR_RED"FMod Ex Sound init failed. Trying OpenAL.\n"); - I_CloseSound(); - GSnd = new OpenALSoundRenderer; - snd_backend = "openal"; - } - #endif - } else if(stricmp(snd_backend, "openal") == 0) { #ifndef NO_OPENAL @@ -290,15 +268,6 @@ void I_InitSound () GSnd = new OpenALSoundRenderer; } #endif - #ifndef NO_FMOD - if ((!GSnd || !GSnd->IsValid()) && IsFModExPresent()) - { - Printf (TEXTCOLOR_RED"OpenAL Sound init failed. Trying FMod Ex.\n"); - I_CloseSound(); - GSnd = new FMODSoundRenderer; - snd_backend = "fmod"; - } - #endif } else { diff --git a/src/sound/i_sound.h b/src/sound/i_sound.h index 5f1917d68..97d81d9dc 100644 --- a/src/sound/i_sound.h +++ b/src/sound/i_sound.h @@ -177,7 +177,6 @@ FISoundChannel *S_GetChannel(void *syschan); extern ReverbContainer *DefaultEnvironments[26]; -bool IsFModExPresent(); bool IsOpenALPresent(); #endif diff --git a/src/sound/music_midi_base.cpp b/src/sound/music_midi_base.cpp index 4e3708eb4..42e8ab863 100644 --- a/src/sound/music_midi_base.cpp +++ b/src/sound/music_midi_base.cpp @@ -96,23 +96,6 @@ void I_InitMusicWin32 () snd_mididevice.Callback (); } -void I_ShutdownMusicWin32 () -{ - // Ancient bug a saw on NT 4.0 and an old version of FMOD 3: If waveout - // is used for sound and a MIDI is also played, then when I quit, the OS - // tells me a free block was modified after being freed. This is - // apparently a synchronization issue between two threads, because if I - // put this Sleep here after stopping the music but before shutting down - // the entire sound system, the error does not happen. Observed with a - // Vortex 2 (may Aureal rest in peace) and an Audigy (damn you, Creative!). - // I no longer have a system with NT4 drivers, so I don't know if this - // workaround is still needed or not. - if (OSPlatform == os_WinNT4) - { - Sleep(50); - } -} - void I_BuildMIDIMenuList (FOptionValues *opt) { AddDefaultMidiDevices(opt); diff --git a/src/sound/oalsound.cpp b/src/sound/oalsound.cpp index d38435be1..f173903ec 100644 --- a/src/sound/oalsound.cpp +++ b/src/sound/oalsound.cpp @@ -630,7 +630,7 @@ public: }; -extern ReverbContainer *ForcedEnvironment; +ReverbContainer *ForcedEnvironment; #define AREA_SOUND_RADIUS (32.f) diff --git a/wadsrc/static/language.enu b/wadsrc/static/language.enu index 550a94634..8e8572b2f 100644 --- a/wadsrc/static/language.enu +++ b/wadsrc/static/language.enu @@ -2128,23 +2128,11 @@ SNDMNU_UNDERWATERREVERB = "Underwater reverb"; SNDMNU_RANDOMIZEPITCHES = "Randomize pitches"; SNDMNU_CHANNELS = "Sound channels"; SNDMNU_BACKEND = "Sound backend"; -SNDMNU_FMOD = "FMOD options"; SNDMNU_OPENAL = "OpenAL options"; SNDMNU_RESTART = "Restart sound"; SNDMNU_ADVANCED = "Advanced options"; SNDMNU_MODREPLAYER = "Module replayer options"; -// Fmod Options -FMODMNU_TITLE = "FMOD OPTIONS"; -FMODMNU_WATERCUTOFF = "Underwater cutoff"; -FMODMNU_OUTPUTSYSTEM = "Output system"; -FMODMNU_OUTPUTFORMAT = "Output format"; -FMODMNU_SPEAKERMODE = "Speaker mode"; -FMODMNU_RESAMPLER = "Resampler"; -FMODMNU_HRTFFILTER = "HRTF filter"; -FMODMNU_BUFFERSIZE = "Buffer size"; -FMODMNU_BUFFERCOUNT = "Buffer count"; - // OpenAL Options OPENALMNU_TITLE = "OPENAL OPTIONS"; OPENALMNU_PLAYBACKDEVICE = "Playback device"; @@ -2428,7 +2416,6 @@ OPTSTR_5POINT1 = "5.1 speakers"; OPTSTR_7POINT1 = "7.1 speakers"; OPTSTR_NOINTERPOLATION = "No interpolation"; OPTSTR_SPLINE = "Spline"; -OPTSTR_FMOD = "FMOD Ex"; OPTSTR_OPENAL = "OpenAL"; diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index 3c9c88759..c5e3820af 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -1557,51 +1557,12 @@ OptionString Resamplers } -OptionString SoundBackends -{ - "fmod", "$OPTSTR_FMOD" - "openal", "$OPTSTR_OPENAL" - "null", "$OPTSTR_NOSOUND" -} - -OptionString SoundBackendsFModOnly -{ - "fmod", "$OPTSTR_FMOD" - "null", "$OPTSTR_NOSOUND" -} - OptionString SoundBackendsOpenALOnly { "openal", "$OPTSTR_OPENAL" "null", "$OPTSTR_NOSOUND" } -OptionMenu FMODSoundItems -{ - Title "$FMODMNU_TITLE" - Slider "$FMODMNU_WATERCUTOFF", "snd_waterlp", 0.0, 2000.0, 50.0, 0 - IfOption(Windows) - { - Option "$FMODMNU_OUTPUTSYSTEM", "snd_output", "SoundOutputsWindows" - } - IfOption(Unix) - { - Option "$FMODMNU_OUTPUTSYSTEM", "snd_output", "SoundOutputsUnix" - } - IfOption(Mac) - { - Option "$FMODMNU_OUTPUTSYSTEM", "snd_output", "SoundOutputsMac" - } - Option "$FMODMNU_OUTPUTFORMAT", "snd_output_format", "OutputFormats" - Option "$FMODMNU_SPEAKERMODE", "snd_speakermode", "SpeakerModes" - Option "$FMODMNU_RESAMPLER", "snd_resampler", "Resamplers" - Option "$FMODMNU_HRTFFILTER", "snd_hrtf", "OnOff" - StaticText " " - Option "$FMODMNU_BUFFERSIZE", "snd_buffersize", "BufferSizes" - Option "$FMODMNU_BUFFERCOUNT", "snd_buffercount", "BufferCounts" -} - - OptionMenu OpenALSoundItems { Title "$OPENALMNU_TITLE" @@ -1628,31 +1589,9 @@ OptionMenu SoundOptions Slider "$SNDMNU_CHANNELS", "snd_channels", 64, 256, 8, 0 StaticText " " - ifoption(fmodex) - { - ifoption(openal) - { - Option "$SNDMNU_BACKEND", "snd_backend", "SoundBackends" - } - else - { - Option "$SNDMNU_BACKEND", "snd_backend", "SoundBackendsFModOnly" - } - } - else - { - ifoption(openal) - { - Option "$SNDMNU_BACKEND", "snd_backend", "SoundBackendsOpenALOnly" - } - } - - ifoption(fmodex) - { - Submenu "$SNDMNU_FMOD", "FMODSoundItems" - } ifoption(openal) { + Option "$SNDMNU_BACKEND", "snd_backend", "SoundBackendsOpenALOnly" Submenu "$SNDMNU_OPENAL", "OpenALSoundItems" } StaticText " "