mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-01-19 20:24:49 +00:00
The FMOD include files are now assumed to be located outside of the Torque 3D directory structure. See Tools/projectGenerator/modules/fmod.inc for the various methods to tell the Project Generator how to find FMOD. If FMOD is installed in its default location then nothing special is required.
582 lines
20 KiB
C++
582 lines
20 KiB
C++
//-----------------------------------------------------------------------------
|
|
// Copyright (c) 2012 GarageGames, LLC
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
// of this software and associated documentation files (the "Software"), to
|
|
// deal in the Software without restriction, including without limitation the
|
|
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
// sell copies of the Software, and to permit persons to whom the Software is
|
|
// furnished to do so, subject to the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included in
|
|
// all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
// IN THE SOFTWARE.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#include "platform/platform.h"
|
|
#include "platform/threads/mutex.h"
|
|
#include "sfx/fmod/sfxFMODDevice.h"
|
|
#include "sfx/fmod/sfxFMODBuffer.h"
|
|
#include "sfx/sfxSystem.h"
|
|
#include "platform/async/asyncUpdate.h"
|
|
#include "console/consoleTypes.h"
|
|
#include "core/volume.h"
|
|
|
|
|
|
bool SFXFMODDevice::smPrefDisableSoftware = false;
|
|
bool SFXFMODDevice::smPrefUseSoftwareOcclusion = true;
|
|
bool SFXFMODDevice::smPrefUseSoftwareHRTF = true;
|
|
bool SFXFMODDevice::smPrefUseSoftwareReverbLowmem = false;
|
|
bool SFXFMODDevice::smPrefEnableProfile = false;
|
|
bool SFXFMODDevice::smPrefGeometryUseClosest = false;
|
|
const char* SFXFMODDevice::smPrefDSoundHRTF = "full";
|
|
const char* SFXFMODDevice::smPrefPluginPath = "";
|
|
U32 SFXFMODDevice::smStatMemUsageCore;
|
|
U32 SFXFMODDevice::smStatMemUsageEvents;
|
|
U32 SFXFMODDevice::smStatNumEventSources;
|
|
SFXFMODDevice* SFXFMODDevice::smInstance;
|
|
FMOD_SYSTEM* SFXFMODDevice::smSystem;
|
|
FMOD_EVENTSYSTEM* SFXFMODDevice::smEventSystem;
|
|
FModFNTable* SFXFMODDevice::smFunc;
|
|
Mutex* FModFNTable::mutex;
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
String FMODResultToString( FMOD_RESULT result )
|
|
{
|
|
switch( result )
|
|
{
|
|
#define FMOD_ERROR( n ) case n: return #n;
|
|
#include "fmodErrors.h"
|
|
#undef FMOD_ERROR
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return String();
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
// FMOD filesystem wrappers.
|
|
//FIXME: these are not thread-safe and cannot be used as such
|
|
|
|
FMOD_RESULT F_CALLBACK fmodFileOpenCallback( const char* name, int unicode, unsigned int* filesize, void** handle, void** userdata )
|
|
{
|
|
String fileName;
|
|
if( unicode )
|
|
fileName = String( ( UTF16* ) name );
|
|
else
|
|
fileName = String( name );
|
|
|
|
Torque::FS::FileRef file = Torque::FS::OpenFile( fileName, Torque::FS::File::Read );
|
|
if( !file )
|
|
return FMOD_ERR_FILE_NOTFOUND;
|
|
else if( file->getStatus() != Torque::FS::File::Open )
|
|
return FMOD_ERR_FILE_BAD;
|
|
|
|
// Add a reference so we can pass it into FMOD.
|
|
file->incRefCount();
|
|
|
|
*filesize = U32( file->getSize() );
|
|
*handle = file.getPointer();
|
|
|
|
return FMOD_OK;
|
|
}
|
|
|
|
FMOD_RESULT F_CALLBACK fmodFileCloseCallback( void* handle, void* userdata )
|
|
{
|
|
Torque::FS::File* file = reinterpret_cast< Torque::FS::File* >( handle );
|
|
file->decRefCount();
|
|
return FMOD_OK;
|
|
}
|
|
|
|
FMOD_RESULT F_CALLBACK fmodFileReadCallback( void* handle, void* buffer, unsigned int sizebytes, unsigned int* bytesread, void* userdata )
|
|
{
|
|
Torque::FS::File* file = reinterpret_cast< Torque::FS::File* >( handle );
|
|
|
|
U32 numRead = file->read( buffer, sizebytes );
|
|
*bytesread = numRead;
|
|
|
|
if( file->getStatus() == Torque::FS::File::EndOfFile )
|
|
return FMOD_ERR_FILE_EOF;
|
|
else if( file->getStatus() != Torque::FS::File::Open )
|
|
return FMOD_ERR_FILE_BAD;
|
|
|
|
return FMOD_OK;
|
|
}
|
|
|
|
FMOD_RESULT F_CALLBACK fmodFileSeekCallback( void* handle, unsigned int pos, void* userdata )
|
|
{
|
|
Torque::FS::File* file = reinterpret_cast< Torque::FS::File* >( handle );
|
|
|
|
if( file->setPosition( pos, Torque::FS::File::Begin ) != pos )
|
|
return FMOD_ERR_FILE_COULDNOTSEEK;
|
|
|
|
return FMOD_OK;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
SFXFMODDevice::SFXFMODDevice( SFXProvider* provider,
|
|
FModFNTable *fmodFnTbl,
|
|
int deviceIdx,
|
|
String name )
|
|
: SFXDevice( name, provider, false, 32 ),
|
|
m3drolloffmode( FMOD_3D_INVERSEROLLOFF ),
|
|
mDeviceIndex( deviceIdx )
|
|
{
|
|
// Store off the function pointers for later use.
|
|
smFunc = fmodFnTbl;
|
|
|
|
smStatMemUsageCore = 0;
|
|
smStatMemUsageEvents = 0;
|
|
smStatNumEventSources = 0;
|
|
|
|
// Register our SFXSystem plugin.
|
|
|
|
SFX->addPlugin( &mPlugin );
|
|
|
|
smInstance = this;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
SFXFMODDevice::~SFXFMODDevice()
|
|
{
|
|
_releaseAllResources();
|
|
|
|
SFX->removePlugin( &mPlugin );
|
|
|
|
if( smEventSystem )
|
|
{
|
|
smFunc->FMOD_EventSystem_Release( smEventSystem );
|
|
smEventSystem = NULL;
|
|
smSystem = NULL;
|
|
}
|
|
else
|
|
smFunc->FMOD_System_Close( smSystem );
|
|
|
|
smInstance = NULL;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
bool SFXFMODDevice::_init()
|
|
{
|
|
#define FMOD_CHECK( message ) \
|
|
if( result != FMOD_OK ) \
|
|
{ \
|
|
Con::errorf( "SFXFMODDevice::_init() - %s (%s)", \
|
|
message, \
|
|
FMOD_ErrorString( result ) ); \
|
|
return false; \
|
|
}
|
|
|
|
AssertISV(smSystem,
|
|
"SFXFMODDevice::_init() - can't init w/o an existing FMOD system handle!");
|
|
|
|
FMOD_RESULT result;
|
|
|
|
// Get some prefs.
|
|
|
|
if( smPrefPluginPath && smPrefPluginPath[ 0 ] )
|
|
{
|
|
char fullPath[ 4096 ];
|
|
Platform::makeFullPathName( smPrefPluginPath, fullPath, sizeof( fullPath ) );
|
|
|
|
smFunc->FMOD_System_SetPluginPath( smSystem, fullPath );
|
|
}
|
|
else
|
|
{
|
|
smFunc->FMOD_System_SetPluginPath( smSystem, Platform::getExecutablePath() );
|
|
}
|
|
|
|
// Initialize everything from fmod.
|
|
FMOD_SPEAKERMODE speakermode;
|
|
FMOD_CAPS caps;
|
|
result = smFunc->FMOD_System_GetDriverCaps(smSystem, 0, &caps, ( int* ) 0, &speakermode);
|
|
FMOD_CHECK( "SFXFMODDevice::init - Failed to get driver caps" );
|
|
|
|
result = smFunc->FMOD_System_SetDriver(smSystem, mDeviceIndex);
|
|
FMOD_CHECK( "SFXFMODDevice::init - Failed to set driver" );
|
|
|
|
result = smFunc->FMOD_System_SetSpeakerMode(smSystem, speakermode);
|
|
FMOD_CHECK( "SFXFMODDevice::init - Failed to set the user selected speaker mode" );
|
|
|
|
if (caps & FMOD_CAPS_HARDWARE_EMULATED) /* The user has the 'Acceleration' slider set to off! This is really bad for latency!. */
|
|
{ /* You might want to warn the user about this. */
|
|
result = smFunc->FMOD_System_SetDSPBufferSize(smSystem, 1024, 10);
|
|
FMOD_CHECK( "SFXFMODDevice::init - Failed to set DSP buffer size" );
|
|
}
|
|
|
|
Con::printf( "\nFMOD Device caps:" );
|
|
#define PRINT_CAP( name ) \
|
|
if( caps & FMOD_CAPS_ ## name ) \
|
|
Con::printf( #name );
|
|
|
|
PRINT_CAP( HARDWARE );
|
|
PRINT_CAP( HARDWARE_EMULATED );
|
|
PRINT_CAP( OUTPUT_MULTICHANNEL );
|
|
PRINT_CAP( OUTPUT_FORMAT_PCM8 );
|
|
PRINT_CAP( OUTPUT_FORMAT_PCM16 );
|
|
PRINT_CAP( OUTPUT_FORMAT_PCM24 );
|
|
PRINT_CAP( OUTPUT_FORMAT_PCM32 );
|
|
PRINT_CAP( OUTPUT_FORMAT_PCMFLOAT );
|
|
PRINT_CAP( REVERB_LIMITED );
|
|
|
|
Con::printf( "" );
|
|
|
|
bool tryAgain;
|
|
do
|
|
{
|
|
tryAgain = false;
|
|
|
|
FMOD_INITFLAGS flags = FMOD_INIT_NORMAL | FMOD_INIT_VOL0_BECOMES_VIRTUAL;
|
|
|
|
if( smPrefDisableSoftware )
|
|
flags |= FMOD_INIT_SOFTWARE_DISABLE;
|
|
if( smPrefUseSoftwareOcclusion )
|
|
flags |= FMOD_INIT_OCCLUSION_LOWPASS;
|
|
if( smPrefUseSoftwareHRTF )
|
|
flags |= FMOD_INIT_HRTF_LOWPASS;
|
|
if( smPrefUseSoftwareReverbLowmem )
|
|
flags |= FMOD_INIT_SOFTWARE_REVERB_LOWMEM;
|
|
if( smPrefEnableProfile )
|
|
flags |= FMOD_INIT_ENABLE_PROFILE;
|
|
if( smPrefGeometryUseClosest )
|
|
flags |= FMOD_INIT_GEOMETRY_USECLOSEST;
|
|
|
|
if( smEventSystem )
|
|
result = smFunc->FMOD_EventSystem_Init( smEventSystem, 100, flags, ( void* ) 0, FMOD_EVENT_INIT_NORMAL );
|
|
else
|
|
result = smFunc->FMOD_System_Init( smSystem, 100, flags, ( void* ) 0 );
|
|
|
|
if( result == FMOD_ERR_OUTPUT_CREATEBUFFER ) /* Ok, the speaker mode selected isn't supported by this soundcard. Switch it back to stereo... */
|
|
{
|
|
result = smFunc->FMOD_System_SetSpeakerMode( smSystem, FMOD_SPEAKERMODE_STEREO );
|
|
FMOD_CHECK( "SFXFMODDevice::init - failed on fallback speaker mode setup" );
|
|
tryAgain = true;
|
|
}
|
|
} while( tryAgain );
|
|
FMOD_CHECK( "SFXFMODDevice::init - failed to init system" );
|
|
|
|
// Print hardware channel info.
|
|
|
|
if( caps & FMOD_CAPS_HARDWARE )
|
|
{
|
|
int num3D, num2D, numTotal;
|
|
|
|
if( smFunc->FMOD_System_GetHardwareChannels( smSystem, &num2D, &num3D, &numTotal ) == FMOD_OK )
|
|
Con::printf( "FMOD Hardware channels: 2d=%i, 3d=%i, total=%i", num2D, num3D, numTotal );
|
|
}
|
|
|
|
// Set up filesystem.
|
|
|
|
//FIXME: Don't do this for now. Crashes on Windows.
|
|
#if 0
|
|
smFunc->FMOD_System_SetFileSystem( smSystem, fmodFileOpenCallback, fmodFileCloseCallback, fmodFileReadCallback, fmodFileSeekCallback, -1 );
|
|
#endif
|
|
|
|
// Set capabilities.
|
|
|
|
mCaps = CAPS_Reverb | CAPS_VoiceManagement;
|
|
if( smEventSystem )
|
|
mCaps |= CAPS_FMODDesigner;
|
|
|
|
// Start the update thread.
|
|
|
|
#ifndef TORQUE_DEDICATED // Avoid dependency on platform/async for Linx dedicated.
|
|
|
|
if( !Con::getBoolVariable( "$_forceAllMainThread" ) )
|
|
{
|
|
SFXInternal::gUpdateThread = new AsyncPeriodicUpdateThread
|
|
( "FMOD Update Thread", SFXInternal::gBufferUpdateList,
|
|
Con::getIntVariable( "$pref::SFX::updateInterval", SFXInternal::DEFAULT_UPDATE_INTERVAL ) );
|
|
SFXInternal::gUpdateThread->start();
|
|
}
|
|
|
|
#endif
|
|
|
|
return true;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
SFXBuffer* SFXFMODDevice::createBuffer( const ThreadSafeRef< SFXStream >& stream, SFXDescription* description )
|
|
{
|
|
AssertFatal( stream, "SFXFMODDevice::createBuffer() - Got a null stream!" );
|
|
AssertFatal( description, "SFXFMODDevice::createBuffer() - Got null description!" );
|
|
|
|
SFXFMODBuffer *buffer = SFXFMODBuffer::create( stream, description );
|
|
if ( buffer )
|
|
_addBuffer( buffer );
|
|
|
|
return buffer;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
SFXBuffer* SFXFMODDevice::createBuffer( const String& filename, SFXDescription* description )
|
|
{
|
|
AssertFatal( filename.isNotEmpty(), "SFXFMODDevice::createBuffer() - Got an empty filename!" );
|
|
AssertFatal( description, "SFXFMODDevice::createBuffer() - Got null description!" );
|
|
|
|
SFXFMODBuffer* buffer = SFXFMODBuffer::create( filename, description );
|
|
if( buffer )
|
|
_addBuffer( buffer );
|
|
|
|
return buffer;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
SFXVoice* SFXFMODDevice::createVoice( bool is3D, SFXBuffer* buffer )
|
|
{
|
|
AssertFatal( buffer, "SFXFMODDevice::createVoice() - Got null buffer!" );
|
|
|
|
SFXFMODBuffer* fmodBuffer = dynamic_cast<SFXFMODBuffer*>( buffer );
|
|
AssertFatal( fmodBuffer, "SFXFMODDevice::createVoice() - Got bad buffer!" );
|
|
|
|
SFXFMODVoice* voice = SFXFMODVoice::create( this, fmodBuffer );
|
|
if ( !voice )
|
|
return NULL;
|
|
|
|
_addVoice( voice );
|
|
return voice;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void SFXFMODDevice::update()
|
|
{
|
|
Parent::update();
|
|
|
|
if( smEventSystem )
|
|
{
|
|
FModAssert( smFunc->FMOD_EventSystem_Update( smEventSystem ), "Failed to update event system!" );
|
|
}
|
|
else
|
|
{
|
|
FModAssert(smFunc->FMOD_System_Update(smSystem), "Failed to update system!");
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void SFXFMODDevice::setNumListeners( U32 num )
|
|
{
|
|
smFunc->FMOD_System_Set3DNumListeners( smSystem, num );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void SFXFMODDevice::setListener( U32 index, const SFXListenerProperties& listener )
|
|
{
|
|
FMOD_VECTOR position, forward, up, velocity;
|
|
|
|
TorqueTransformToFMODVectors( listener.getTransform(), position, forward, up );
|
|
TorqueVectorToFMODVector( listener.getVelocity(), velocity );
|
|
|
|
// Do the listener state update, then update!
|
|
smFunc->FMOD_System_Set3DListenerAttributes( smSystem, index, &position, &velocity, &forward, &up );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void SFXFMODDevice::setDistanceModel( SFXDistanceModel model )
|
|
{
|
|
switch( model )
|
|
{
|
|
case SFXDistanceModelLinear:
|
|
m3drolloffmode = FMOD_3D_LINEARROLLOFF;
|
|
break;
|
|
|
|
case SFXDistanceModelLogarithmic:
|
|
m3drolloffmode = FMOD_3D_INVERSEROLLOFF;
|
|
break;
|
|
|
|
default:
|
|
AssertWarn( false, "SFXFMODDevice::setDistanceModel - model not implemented" );
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void SFXFMODDevice::setDopplerFactor( F32 factor )
|
|
{
|
|
F32 dopplerFactor;
|
|
F32 distanceFactor;
|
|
F32 rolloffFactor;
|
|
|
|
smFunc->FMOD_System_Get3DSettings( smSystem, &dopplerFactor, &distanceFactor, &rolloffFactor );
|
|
dopplerFactor = factor;
|
|
smFunc->FMOD_System_Set3DSettings( smSystem, dopplerFactor, distanceFactor, rolloffFactor );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void SFXFMODDevice::setRolloffFactor( F32 factor )
|
|
{
|
|
F32 dopplerFactor;
|
|
F32 distanceFactor;
|
|
F32 rolloffFactor;
|
|
|
|
smFunc->FMOD_System_Get3DSettings( smSystem, &dopplerFactor, &distanceFactor, &rolloffFactor );
|
|
rolloffFactor = factor;
|
|
smFunc->FMOD_System_Set3DSettings( smSystem, dopplerFactor, distanceFactor, rolloffFactor );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void SFXFMODDevice::setReverb( const SFXReverbProperties& reverb )
|
|
{
|
|
FMOD_REVERB_PROPERTIES prop = FMOD_PRESET_GENERIC;
|
|
|
|
prop.Environment = 0;
|
|
prop.EnvDiffusion = reverb.mEnvDiffusion;
|
|
prop.Room = reverb.mRoom;
|
|
prop.RoomHF = reverb.mRoomHF;
|
|
prop.RoomLF = reverb.mRoomLF;
|
|
prop.DecayTime = reverb.mDecayTime;
|
|
prop.DecayLFRatio = reverb.mDecayLFRatio;
|
|
prop.DecayHFRatio = reverb.mDecayHFRatio;
|
|
prop.Reflections = reverb.mReflections;
|
|
prop.ReflectionsDelay = reverb.mReflectionsDelay;
|
|
prop.Reverb = reverb.mReverb;
|
|
prop.ReverbDelay = reverb.mReverbDelay;
|
|
prop.ModulationTime = reverb.mModulationTime;
|
|
prop.ModulationDepth = reverb.mModulationDepth;
|
|
prop.HFReference = reverb.mHFReference;
|
|
prop.LFReference = reverb.mLFReference;
|
|
prop.Diffusion = reverb.mDiffusion;
|
|
prop.Density = reverb.mDensity;
|
|
prop.Flags = reverb.mFlags;
|
|
|
|
// Here we only want to affect 3D sounds. While not quite obvious from the docs,
|
|
// SetReverbProperties sets the global reverb environment for 2D sounds whereas
|
|
// SetAmbientReverbProperties sets the global reverb environment for 3D sounds.
|
|
|
|
FMOD_RESULT result = smFunc->FMOD_System_SetReverbAmbientProperties( smSystem, &prop );
|
|
if( result != FMOD_OK )
|
|
Con::errorf( "SFXFMODDevice::setReverb - Failed to set reverb (%s)", FMODResultToString( result ).c_str() );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void SFXFMODDevice::resetReverb()
|
|
{
|
|
FMOD_REVERB_PROPERTIES prop = FMOD_PRESET_OFF;
|
|
smFunc->FMOD_System_SetReverbProperties( smSystem, &prop );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void SFXFMODDevice::updateMemUsageStats()
|
|
{
|
|
smFunc->FMOD_System_GetMemoryInfo( smSystem, ( unsigned int ) FMOD_MEMBITS_ALL,
|
|
( unsigned int ) 0, ( unsigned int* ) &smStatMemUsageCore, ( unsigned int* ) 0 );
|
|
|
|
if( smEventSystem )
|
|
smFunc->FMOD_EventSystem_GetMemoryInfo( smEventSystem, ( unsigned int ) 0,
|
|
( unsigned int ) FMOD_EVENT_MEMBITS_ALL, ( unsigned int* ) &smStatMemUsageEvents, ( unsigned int* ) 0 );
|
|
}
|
|
|
|
//=============================================================================
|
|
// Console Functions.
|
|
//=============================================================================
|
|
// MARK: ---- Console Functions ----
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
ConsoleFunction( fmodDumpDSPInfo, void, 1, 1, "()"
|
|
"@brief Dump information about the standard DSP effects.\n\n"
|
|
"@ingroup SFXFMOD")
|
|
{
|
|
if( !SFXFMODDevice::smFunc )
|
|
return;
|
|
|
|
const U32 firstDSPType = FMOD_DSP_TYPE_MIXER;
|
|
const U32 lastDSPType = FMOD_DSP_TYPE_TREMOLO;
|
|
|
|
for( U32 i = firstDSPType; i <= lastDSPType; ++ i )
|
|
{
|
|
FMOD_DSP* dsp;
|
|
if( SFXFMODDevice::smFunc->FMOD_System_CreateDSPByType( SFXFMODDevice::smSystem, ( FMOD_DSP_TYPE ) i, &dsp ) == FMOD_OK )
|
|
{
|
|
// Print general info.
|
|
|
|
char name[ 33 ];
|
|
unsigned int version;
|
|
int channels;
|
|
int numParameters;
|
|
|
|
dMemset( name, 0, sizeof( name ) );
|
|
SFXFMODDevice::smFunc->FMOD_DSP_GetInfo( dsp, name, &version, &channels, ( int* ) NULL, ( int* ) NULL );
|
|
SFXFMODDevice::smFunc->FMOD_DSP_GetNumParameters( dsp, &numParameters );
|
|
|
|
Con::printf( "----------------------------------------------------------------" );
|
|
Con::printf( "DSP: %s", name );
|
|
Con::printf( "Version: %i.%i", ( version & 0xffff0000 ) >> 16, version & 0xffff );
|
|
Con::printf( "Channels: %i", channels );
|
|
Con::printf( "Parameters: %i", numParameters );
|
|
Con::printf( "" );
|
|
|
|
// Print parameter info.
|
|
|
|
for( U32 n = 0; n < numParameters; ++ n )
|
|
{
|
|
char name[ 17 ];
|
|
char label[ 17 ];
|
|
char description[ 1024 ];
|
|
float minValue, maxValue;
|
|
float value;
|
|
char valueString[ 256 ];
|
|
|
|
dMemset( name, 0, sizeof( name ) );
|
|
dMemset( label, 0, sizeof( label ) );
|
|
dMemset( description, 0, sizeof( description ) );
|
|
dMemset( valueString, 0, sizeof( valueString ) );
|
|
|
|
SFXFMODDevice::smFunc->FMOD_DSP_GetParameterInfo( dsp, n, name, label, description, sizeof( description ) - 1, &minValue, &maxValue );
|
|
SFXFMODDevice::smFunc->FMOD_DSP_GetParameter( dsp, n, &value, valueString, sizeof( valueString ) - 1 );
|
|
|
|
Con::printf( "* Parameter %i", n );
|
|
Con::printf( "Name: %s", name );
|
|
Con::printf( "Label: %s", label );
|
|
Con::printf( "Description: %s", description );
|
|
Con::printf( "Min: %f", minValue );
|
|
Con::printf( "Max: %f", maxValue );
|
|
Con::printf( "Value: %f (%s)", value, valueString );
|
|
Con::printf( "" );
|
|
}
|
|
|
|
// Release the DSP.
|
|
|
|
SFXFMODDevice::smFunc->FMOD_DSP_Release( dsp );
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
ConsoleFunction( fmodDumpMemoryStats, void, 1, 1, "()"
|
|
"@return Prints the current memory consumption of the FMOD module\n\n"
|
|
"@ingroup SFXFMOD")
|
|
{
|
|
int current = 0;
|
|
int max = 0;
|
|
|
|
if (SFXFMODDevice::smFunc && SFXFMODDevice::smFunc->FMOD_Memory_GetStats.fn)
|
|
SFXFMODDevice::smFunc->FMOD_Memory_GetStats(¤t, &max);
|
|
Con::printf("Fmod current: %d, max: %d", current, max);
|
|
}
|