remove FMODex from Torque3D

The current version of FMod in Torque3D uses the legacy ex plugin, which hasn't been around for a long time.
This commit is contained in:
Jeff Hutchinson 2021-09-11 14:53:28 -04:00
parent 772c0ae25b
commit 41bd5ef6b6
34 changed files with 13 additions and 5317 deletions

View file

@ -1,115 +0,0 @@
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
FMOD_ERROR( FMOD_OK )
FMOD_ERROR( FMOD_ERR_ALREADYLOCKED )
FMOD_ERROR( FMOD_ERR_BADCOMMAND )
FMOD_ERROR( FMOD_ERR_CDDA_DRIVERS )
FMOD_ERROR( FMOD_ERR_CDDA_INIT )
FMOD_ERROR( FMOD_ERR_CDDA_INVALID_DEVICE )
FMOD_ERROR( FMOD_ERR_CDDA_NOAUDIO )
FMOD_ERROR( FMOD_ERR_CDDA_NODEVICES )
FMOD_ERROR( FMOD_ERR_CDDA_NODISC )
FMOD_ERROR( FMOD_ERR_CDDA_READ )
FMOD_ERROR( FMOD_ERR_CHANNEL_ALLOC )
FMOD_ERROR( FMOD_ERR_CHANNEL_STOLEN )
FMOD_ERROR( FMOD_ERR_COM )
FMOD_ERROR( FMOD_ERR_DMA )
FMOD_ERROR( FMOD_ERR_DSP_CONNECTION )
FMOD_ERROR( FMOD_ERR_DSP_FORMAT )
FMOD_ERROR( FMOD_ERR_DSP_NOTFOUND )
FMOD_ERROR( FMOD_ERR_DSP_RUNNING )
FMOD_ERROR( FMOD_ERR_DSP_TOOMANYCONNECTIONS )
FMOD_ERROR( FMOD_ERR_FILE_BAD )
FMOD_ERROR( FMOD_ERR_FILE_COULDNOTSEEK )
FMOD_ERROR( FMOD_ERR_FILE_DISKEJECTED )
FMOD_ERROR( FMOD_ERR_FILE_EOF )
FMOD_ERROR( FMOD_ERR_FILE_NOTFOUND )
FMOD_ERROR( FMOD_ERR_FILE_UNWANTED )
FMOD_ERROR( FMOD_ERR_FORMAT )
FMOD_ERROR( FMOD_ERR_HTTP )
FMOD_ERROR( FMOD_ERR_HTTP_ACCESS )
FMOD_ERROR( FMOD_ERR_HTTP_PROXY_AUTH )
FMOD_ERROR( FMOD_ERR_HTTP_SERVER_ERROR )
FMOD_ERROR( FMOD_ERR_HTTP_TIMEOUT )
FMOD_ERROR( FMOD_ERR_INITIALIZATION )
FMOD_ERROR( FMOD_ERR_INITIALIZED )
FMOD_ERROR( FMOD_ERR_INTERNAL )
FMOD_ERROR( FMOD_ERR_INVALID_ADDRESS )
FMOD_ERROR( FMOD_ERR_INVALID_FLOAT )
FMOD_ERROR( FMOD_ERR_INVALID_HANDLE )
FMOD_ERROR( FMOD_ERR_INVALID_PARAM )
FMOD_ERROR( FMOD_ERR_INVALID_POSITION )
FMOD_ERROR( FMOD_ERR_INVALID_SPEAKER )
FMOD_ERROR( FMOD_ERR_INVALID_SYNCPOINT )
FMOD_ERROR( FMOD_ERR_INVALID_VECTOR )
FMOD_ERROR( FMOD_ERR_MAXAUDIBLE )
FMOD_ERROR( FMOD_ERR_MEMORY )
FMOD_ERROR( FMOD_ERR_MEMORY_CANTPOINT )
FMOD_ERROR( FMOD_ERR_MEMORY_SRAM )
FMOD_ERROR( FMOD_ERR_NEEDS2D )
FMOD_ERROR( FMOD_ERR_NEEDS3D )
FMOD_ERROR( FMOD_ERR_NEEDSHARDWARE )
FMOD_ERROR( FMOD_ERR_NEEDSSOFTWARE )
FMOD_ERROR( FMOD_ERR_NET_CONNECT )
FMOD_ERROR( FMOD_ERR_NET_SOCKET_ERROR )
FMOD_ERROR( FMOD_ERR_NET_URL )
FMOD_ERROR( FMOD_ERR_NET_WOULD_BLOCK )
FMOD_ERROR( FMOD_ERR_NOTREADY )
FMOD_ERROR( FMOD_ERR_OUTPUT_ALLOCATED )
FMOD_ERROR( FMOD_ERR_OUTPUT_CREATEBUFFER )
FMOD_ERROR( FMOD_ERR_OUTPUT_DRIVERCALL )
FMOD_ERROR( FMOD_ERR_OUTPUT_ENUMERATION )
FMOD_ERROR( FMOD_ERR_OUTPUT_FORMAT )
FMOD_ERROR( FMOD_ERR_OUTPUT_INIT )
FMOD_ERROR( FMOD_ERR_OUTPUT_NOHARDWARE )
FMOD_ERROR( FMOD_ERR_OUTPUT_NOSOFTWARE )
FMOD_ERROR( FMOD_ERR_PAN )
FMOD_ERROR( FMOD_ERR_PLUGIN )
FMOD_ERROR( FMOD_ERR_PLUGIN_INSTANCES )
FMOD_ERROR( FMOD_ERR_PLUGIN_MISSING )
FMOD_ERROR( FMOD_ERR_PLUGIN_RESOURCE )
FMOD_ERROR( FMOD_ERR_RECORD )
FMOD_ERROR( FMOD_ERR_REVERB_INSTANCE )
FMOD_ERROR( FMOD_ERR_SUBSOUND_ALLOCATED )
FMOD_ERROR( FMOD_ERR_SUBSOUND_CANTMOVE )
FMOD_ERROR( FMOD_ERR_SUBSOUND_MODE )
FMOD_ERROR( FMOD_ERR_SUBSOUNDS )
FMOD_ERROR( FMOD_ERR_TAGNOTFOUND )
FMOD_ERROR( FMOD_ERR_TOOMANYCHANNELS )
FMOD_ERROR( FMOD_ERR_UNIMPLEMENTED )
FMOD_ERROR( FMOD_ERR_UNINITIALIZED )
FMOD_ERROR( FMOD_ERR_UNSUPPORTED )
FMOD_ERROR( FMOD_ERR_UPDATE )
FMOD_ERROR( FMOD_ERR_VERSION )
FMOD_ERROR( FMOD_ERR_PRELOADED )
FMOD_ERROR( FMOD_ERR_EVENT_FAILED )
FMOD_ERROR( FMOD_ERR_EVENT_INFOONLY )
FMOD_ERROR( FMOD_ERR_EVENT_INTERNAL )
FMOD_ERROR( FMOD_ERR_EVENT_MAXSTREAMS )
FMOD_ERROR( FMOD_ERR_EVENT_MISMATCH )
FMOD_ERROR( FMOD_ERR_EVENT_NAMECONFLICT )
FMOD_ERROR( FMOD_ERR_EVENT_NOTFOUND )
FMOD_ERROR( FMOD_ERR_EVENT_NEEDSSIMPLE )
FMOD_ERROR( FMOD_ERR_EVENT_GUIDCONFLICT )
FMOD_ERROR( FMOD_ERR_EVENT_ALREADY_LOADED )
FMOD_ERROR( FMOD_ERR_MUSIC_UNINITIALIZED )

View file

@ -1,157 +0,0 @@
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
// Xcode has problems properly detecting the dependencies for this file.
// If you change something here, manually recompile all the FMOD modules.
// FMOD Ex API:
FMOD_FUNCTION( FMOD_Channel_GetPaused, (FMOD_CHANNEL *channel, FMOD_BOOL *paused))
FMOD_FUNCTION( FMOD_Channel_SetPaused, (FMOD_CHANNEL *channel, FMOD_BOOL paused));
FMOD_FUNCTION( FMOD_Channel_IsPlaying, (FMOD_CHANNEL *channel, FMOD_BOOL *isplaying))
FMOD_FUNCTION( FMOD_Channel_Set3DAttributes, (FMOD_CHANNEL *channel, const FMOD_VECTOR *pos, const FMOD_VECTOR *vel))
FMOD_FUNCTION( FMOD_Channel_SetFrequency, (FMOD_CHANNEL *channel, float frequency))
FMOD_FUNCTION( FMOD_Channel_SetLoopCount, (FMOD_CHANNEL *channel, int loopcount))
FMOD_FUNCTION( FMOD_Channel_SetPosition, (FMOD_CHANNEL *channel, unsigned int position, FMOD_TIMEUNIT postype))
FMOD_FUNCTION( FMOD_Channel_GetPosition, (FMOD_CHANNEL* channel, unsigned int* position, FMOD_TIMEUNIT postype))
FMOD_FUNCTION( FMOD_Channel_SetVolume, (FMOD_CHANNEL *channel, float volume))
FMOD_FUNCTION( FMOD_Channel_GetVolume, (FMOD_CHANNEL *channel, float *volume))
FMOD_FUNCTION( FMOD_Channel_Stop, (FMOD_CHANNEL *channel))
FMOD_FUNCTION( FMOD_Channel_SetMode, (FMOD_CHANNEL *channel, FMOD_MODE mode))
FMOD_FUNCTION( FMOD_Channel_Set3DMinMaxDistance, (FMOD_CHANNEL *channel, float mindistance, float maxdistance));
FMOD_FUNCTION( FMOD_Channel_Set3DConeSettings, (FMOD_CHANNEL *channel, float insideconeangle, float outsideconeangle, float outsidevolume))
FMOD_FUNCTION( FMOD_Channel_Set3DConeOrientation, (FMOD_CHANNEL *channel, FMOD_VECTOR *orientation))
FMOD_FUNCTION( FMOD_Channel_SetReverbProperties, ( FMOD_CHANNEL* channel, const FMOD_REVERB_CHANNELPROPERTIES* prop ) )
FMOD_FUNCTION( FMOD_Channel_SetPriority, ( FMOD_CHANNEL* channel, int priority ) )
FMOD_FUNCTION( FMOD_Channel_IsVirtual, ( FMOD_CHANNEL* channel, FMOD_BOOL* isvirtual ) )
FMOD_FUNCTION( FMOD_Channel_AddDSP, ( FMOD_CHANNEL* channel, FMOD_DSP* dsp, FMOD_DSPCONNECTION** connection ) )
FMOD_FUNCTION( FMOD_Sound_Lock, (FMOD_SOUND *sound, unsigned int offset, unsigned int length, void **ptr1, void **ptr2, unsigned int *len1, unsigned int *len2))
FMOD_FUNCTION( FMOD_Sound_Unlock, (FMOD_SOUND *sound, void *ptr1, void *ptr2, unsigned int len1, unsigned int len2))
FMOD_FUNCTION( FMOD_Sound_Release, (FMOD_SOUND *sound))
FMOD_FUNCTION( FMOD_Sound_Set3DMinMaxDistance, (FMOD_SOUND *sound, float min, float max))
FMOD_FUNCTION( FMOD_Sound_SetMode, (FMOD_SOUND *sound, FMOD_MODE mode))
FMOD_FUNCTION( FMOD_Sound_GetMode, (FMOD_SOUND *sound, FMOD_MODE *mode))
FMOD_FUNCTION( FMOD_Sound_SetLoopCount, (FMOD_SOUND *sound, int loopcount))
FMOD_FUNCTION( FMOD_Sound_GetFormat, ( FMOD_SOUND* sound, FMOD_SOUND_TYPE* type, FMOD_SOUND_FORMAT* format, int* channels, int* bits ) )
FMOD_FUNCTION( FMOD_Sound_GetLength, ( FMOD_SOUND* sound, unsigned int* length, FMOD_TIMEUNIT lengthtype ) )
FMOD_FUNCTION( FMOD_Sound_GetDefaults, ( FMOD_SOUND* sound, float* frequency, float* volume, float* pan, int* priority ) )
FMOD_FUNCTION( FMOD_Sound_GetMemoryInfo, ( FMOD_SOUND* sound, unsigned int memorybits, unsigned int event_memorybits, unsigned int* memoryused, unsigned int* memoryused_array ) );
FMOD_FUNCTION( FMOD_Geometry_AddPolygon, ( FMOD_GEOMETRY* geometry, float directocclusion, float reverbocclusion, FMOD_BOOL doublesided, int numvertices, const FMOD_VECTOR* vertices, int* polygonindex ) )
FMOD_FUNCTION( FMOD_Geometry_SetPosition, ( FMOD_GEOMETRY* geometry, const FMOD_VECTOR* position ) )
FMOD_FUNCTION( FMOD_Geometry_SetRotation, ( FMOD_GEOMETRY* geometry, const FMOD_VECTOR* forward, const FMOD_VECTOR* up ) )
FMOD_FUNCTION( FMOD_Geometry_SetScale, ( FMOD_GEOMETRY* geometry, const FMOD_VECTOR* scale ) )
FMOD_FUNCTION( FMOD_Geometry_Release, ( FMOD_GEOMETRY* geometry ) )
FMOD_FUNCTION( FMOD_DSP_GetInfo, ( FMOD_DSP* dsp, char* name, unsigned int* version, int* channels, int* configwidth, int* configheight ) )
FMOD_FUNCTION( FMOD_DSP_Release, ( FMOD_DSP* dsp ) )
FMOD_FUNCTION( FMOD_DSP_GetParameterInfo, ( FMOD_DSP* dsp, int index, char* name, char* label, char* description, int descriptionlen, float* min, float* max ) )
FMOD_FUNCTION( FMOD_DSP_GetNumParameters, ( FMOD_DSP* dsp, int* numparams ) )
FMOD_FUNCTION( FMOD_DSP_GetParameter, ( FMOD_DSP* dsp, int index, float* value, char* valuestr, int valuestrlen ) )
FMOD_FUNCTION( FMOD_DSP_SetParameter, ( FMOD_DSP* dsp, int index, float value ) )
FMOD_FUNCTION( FMOD_DSP_GetNumInputs, ( FMOD_DSP* dsp, int* numinputs ) )
FMOD_FUNCTION( FMOD_DSP_GetNumOutputs, ( FMOD_DSP* dsp, int* numoutputs ) )
FMOD_FUNCTION( FMOD_System_Close, (FMOD_SYSTEM *system))
FMOD_FUNCTION( FMOD_System_Create, (FMOD_SYSTEM **system))
FMOD_FUNCTION( FMOD_System_Release, (FMOD_SYSTEM *system))
FMOD_FUNCTION( FMOD_System_CreateSound, (FMOD_SYSTEM *system, const char *name_or_data, FMOD_MODE mode, FMOD_CREATESOUNDEXINFO *exinfo, FMOD_SOUND **sound))
FMOD_FUNCTION( FMOD_System_CreateGeometry, ( FMOD_SYSTEM* system, int maxpolygons, int maxvertices, FMOD_GEOMETRY** geometry ) )
FMOD_FUNCTION( FMOD_System_SetDriver, (FMOD_SYSTEM *system, int driver))
FMOD_FUNCTION( FMOD_System_GetDriverCaps, (FMOD_SYSTEM *system, int id, FMOD_CAPS *caps, int *controlpaneloutputrate, FMOD_SPEAKERMODE *controlpanelspeakermode))
FMOD_FUNCTION( FMOD_System_GetDriverInfo, (FMOD_SYSTEM *system, int id, char *name, int namelen, FMOD_GUID *GUID))
FMOD_FUNCTION( FMOD_System_GetNumDrivers, (FMOD_SYSTEM *system, int *numdrivers))
FMOD_FUNCTION( FMOD_System_GetVersion, (FMOD_SYSTEM *system, unsigned int *version))
FMOD_FUNCTION( FMOD_System_Init, (FMOD_SYSTEM *system, int maxchannels, FMOD_INITFLAGS flags, void *extradriverdata))
FMOD_FUNCTION( FMOD_System_PlaySound, (FMOD_SYSTEM *system, FMOD_CHANNELINDEX channelid, FMOD_SOUND *sound, FMOD_BOOL paused, FMOD_CHANNEL **channel))
FMOD_FUNCTION( FMOD_System_Set3DListenerAttributes, (FMOD_SYSTEM *system, int listener, const FMOD_VECTOR *pos, const FMOD_VECTOR *vel, const FMOD_VECTOR *forward, const FMOD_VECTOR *up))
FMOD_FUNCTION( FMOD_System_Set3DNumListeners, ( FMOD_SYSTEM* system, int numlisteners ) )
FMOD_FUNCTION( FMOD_System_SetGeometrySettings, ( FMOD_SYSTEM* system, float maxworldsize ) )
FMOD_FUNCTION( FMOD_System_Get3DSettings, (FMOD_SYSTEM* system, float* dopplerFactor, float* distanceFactor, float* rolloffFactor))
FMOD_FUNCTION( FMOD_System_Set3DSettings, (FMOD_SYSTEM *system, float dopplerscale, float distancefactor, float rolloffscale))
FMOD_FUNCTION( FMOD_System_SetDSPBufferSize, (FMOD_SYSTEM *system, unsigned int bufferlength, int numbuffers))
FMOD_FUNCTION( FMOD_System_SetSpeakerMode, (FMOD_SYSTEM *system, FMOD_SPEAKERMODE speakermode))
FMOD_FUNCTION( FMOD_System_SetReverbProperties, ( FMOD_SYSTEM* system, const FMOD_REVERB_PROPERTIES* prop ) )
FMOD_FUNCTION( FMOD_System_SetReverbAmbientProperties, ( FMOD_SYSTEM* system, FMOD_REVERB_PROPERTIES* prop ) )
FMOD_FUNCTION( FMOD_System_Update, ( FMOD_SYSTEM *system ) )
FMOD_FUNCTION( FMOD_System_CreateDSPByType, ( FMOD_SYSTEM* system, FMOD_DSP_TYPE type, FMOD_DSP** dsp ) )
FMOD_FUNCTION( FMOD_System_AddDSP, ( FMOD_SYSTEM* system, FMOD_DSP* dsp, FMOD_DSPCONNECTION** connection ) )
FMOD_FUNCTION( FMOD_System_GetMemoryInfo, ( FMOD_SYSTEM* system, unsigned int memorybits, unsigned int event_memorybits, unsigned int* memoryused, unsigned int* memoryused_array ) )
FMOD_FUNCTION( FMOD_System_SetFileSystem, ( FMOD_SYSTEM* system, FMOD_FILE_OPENCALLBACK useropen, FMOD_FILE_CLOSECALLBACK userclose, FMOD_FILE_READCALLBACK userread, FMOD_FILE_SEEKCALLBACK userseek, int blockalign ) )
FMOD_FUNCTION( FMOD_System_SetPluginPath, ( FMOD_SYSTEM* system, const char* path ) )
FMOD_FUNCTION( FMOD_System_GetHardwareChannels, ( FMOD_SYSTEM* system, int* num2d, int* num3d, int* total ) )
FMOD_FUNCTION( FMOD_Memory_GetStats, ( int*, int* ) )
FMOD_FUNCTION( FMOD_Memory_Initialize, ( void *poolmem, int poollen, FMOD_MEMORY_ALLOCCALLBACK useralloc, FMOD_MEMORY_REALLOCCALLBACK userrealloc, FMOD_MEMORY_FREECALLBACK userfree ) )
// FMOD Designer API:
FMOD_EVENT_FUNCTION( FMOD_EventSystem_Create, ( FMOD_EVENTSYSTEM** eventsystem ) )
FMOD_EVENT_FUNCTION( FMOD_EventSystem_GetSystemObject, ( FMOD_EVENTSYSTEM* eventsystem, FMOD_SYSTEM** system ) )
FMOD_EVENT_FUNCTION( FMOD_EventSystem_GetVersion, ( FMOD_EVENTSYSTEM* eventsystem, unsigned int* version ) )
FMOD_EVENT_FUNCTION( FMOD_EventSystem_Init, ( FMOD_EVENTSYSTEM* eventsystem, int maxchannels, FMOD_INITFLAGS flags, void* extradriverdata, FMOD_EVENT_INITFLAGS eventflags ) )
FMOD_EVENT_FUNCTION( FMOD_EventSystem_Release, ( FMOD_EVENTSYSTEM* eventsystem ) )
FMOD_EVENT_FUNCTION( FMOD_EventSystem_Load, ( FMOD_EVENTSYSTEM* eventsystem, const char* name_or_data, FMOD_EVENT_LOADINFO* loadinfo, FMOD_EVENTPROJECT** project ) )
FMOD_EVENT_FUNCTION( FMOD_EventSystem_Update, ( FMOD_EVENTSYSTEM* eventsystem ) )
FMOD_EVENT_FUNCTION( FMOD_EventSystem_GetMemoryInfo, ( FMOD_EVENTSYSTEM* eventsystem, unsigned int memorybits, unsigned int event_memorybits, unsigned int* memoryused, unsigned int* memoryused_array ) )
FMOD_EVENT_FUNCTION( FMOD_EventSystem_SetMediaPath, ( FMOD_EVENTSYSTEM* eventsystem, const char* path ) )
FMOD_EVENT_FUNCTION( FMOD_EventProject_Release, ( FMOD_EVENTPROJECT* eventproject ) )
FMOD_EVENT_FUNCTION( FMOD_EventProject_GetInfo, ( FMOD_EVENTPROJECT* eventproject, FMOD_EVENT_PROJECTINFO* info ) )
FMOD_EVENT_FUNCTION( FMOD_EventProject_GetNumEvents, ( FMOD_EVENTPROJECT* eventproject, int* numevents ) )
FMOD_EVENT_FUNCTION( FMOD_EventProject_GetNumGroups, ( FMOD_EVENTPROJECT* eventproject, int* numgroups ) )
FMOD_EVENT_FUNCTION( FMOD_EventProject_GetGroupByIndex, ( FMOD_EVENTPROJECT* eventproject, int index, FMOD_BOOL cacheevents, FMOD_EVENTGROUP** group ) )
FMOD_EVENT_FUNCTION( FMOD_EventProject_GetGroup, ( FMOD_EVENTPROJECT* eventproject, const char* name, FMOD_BOOL cacheevents, FMOD_EVENTGROUP** group ) )
FMOD_EVENT_FUNCTION( FMOD_EventGroup_GetInfo, ( FMOD_EVENTGROUP* eventgroup, int* index, char** name ) )
FMOD_EVENT_FUNCTION( FMOD_EventGroup_LoadEventData, ( FMOD_EVENTGROUP* eventgroup, FMOD_EVENT_RESOURCE resource, FMOD_EVENT_MODE mode ) )
FMOD_EVENT_FUNCTION( FMOD_EventGroup_FreeEventData, ( FMOD_EVENTGROUP* eventgroup, FMOD_EVENT* event, FMOD_BOOL waituntilready ) )
FMOD_EVENT_FUNCTION( FMOD_EventGroup_GetNumEvents, ( FMOD_EVENTGROUP* eventgroup, int* numevents ) )
FMOD_EVENT_FUNCTION( FMOD_EventGroup_GetNumGroups, ( FMOD_EVENTGROUP* eventgroup, int* numgroups ) )
FMOD_EVENT_FUNCTION( FMOD_EventGroup_GetEventByIndex, ( FMOD_EVENTGROUP* eventgroup, int index, FMOD_EVENT_MODE mode, FMOD_EVENT** event ) )
FMOD_EVENT_FUNCTION( FMOD_EventGroup_GetEvent, ( FMOD_EVENTGROUP* eventgroup, const char* name, FMOD_EVENT_MODE mode, FMOD_EVENT** event ) )
FMOD_EVENT_FUNCTION( FMOD_EventGroup_GetGroupByIndex, ( FMOD_EVENTGROUP* eventgroup, int index, FMOD_BOOL cacheevents, FMOD_EVENTGROUP** group ) )
FMOD_EVENT_FUNCTION( FMOD_EventGroup_GetGroup, ( FMOD_EVENTGROUP* eventgroup, const char* name, FMOD_BOOL cacheevents, FMOD_EVENTGROUP** group ) )
FMOD_EVENT_FUNCTION( FMOD_Event_GetInfo, ( FMOD_EVENT* event, int* index, char** name, FMOD_EVENT_INFO* info ) )
FMOD_EVENT_FUNCTION( FMOD_Event_Release, ( FMOD_EVENT* event, FMOD_BOOL freeeventdata, FMOD_BOOL waituntilready ) )
FMOD_EVENT_FUNCTION( FMOD_Event_Start, ( FMOD_EVENT* event ) )
FMOD_EVENT_FUNCTION( FMOD_Event_Stop, ( FMOD_EVENT* event, FMOD_BOOL immediate ) )
FMOD_EVENT_FUNCTION( FMOD_Event_SetPaused, ( FMOD_EVENT* event, FMOD_BOOL paused ) )
FMOD_EVENT_FUNCTION( FMOD_Event_SetVolume, ( FMOD_EVENT* event, float volume ) )
FMOD_EVENT_FUNCTION( FMOD_Event_SetPitch, ( FMOD_EVENT* event, float pitch, FMOD_EVENT_PITCHUNITS units ) )
FMOD_EVENT_FUNCTION( FMOD_Event_Set3DAttributes, ( FMOD_EVENT* event, const FMOD_VECTOR* position, const FMOD_VECTOR* velocity, const FMOD_VECTOR* orientation ) )
FMOD_EVENT_FUNCTION( FMOD_Event_GetState, ( FMOD_EVENT* event, FMOD_EVENT_STATE* state ) )
FMOD_EVENT_FUNCTION( FMOD_Event_GetNumParameters, ( FMOD_EVENT* event, int* numparameters ) )
FMOD_EVENT_FUNCTION( FMOD_Event_GetParameter, ( FMOD_EVENT* event, const char* name, FMOD_EVENTPARAMETER** parameter ) )
FMOD_EVENT_FUNCTION( FMOD_Event_GetParameterByIndex, ( FMOD_EVENT* event, int index, FMOD_EVENTPARAMETER** parameter ) )
FMOD_EVENT_FUNCTION( FMOD_Event_GetPropertyByIndex, ( FMOD_EVENT* event, int propertyidex, void* value, FMOD_BOOL this_instance ) )
FMOD_EVENT_FUNCTION( FMOD_Event_SetPropertyByIndex, ( FMOD_EVENT* event, int propertyidex, void* value, FMOD_BOOL this_instance ) )
FMOD_EVENT_FUNCTION( FMOD_Event_GetProperty, ( FMOD_EVENT* event, const char* propertyname, void* value, FMOD_BOOL this_instance ) )
FMOD_EVENT_FUNCTION( FMOD_Event_GetPropertyInfo, ( FMOD_EVENT* event, int* propertyindex, char** propertyname, FMOD_EVENTPROPERTY_TYPE* type ) )
FMOD_EVENT_FUNCTION( FMOD_EventParameter_GetInfo, ( FMOD_EVENTPARAMETER* eventparameter, int* index, char** name ) )
FMOD_EVENT_FUNCTION( FMOD_EventParameter_GetValue, ( FMOD_EVENTPARAMETER* eventparameter, float* value ) )
FMOD_EVENT_FUNCTION( FMOD_EventParameter_SetValue, ( FMOD_EVENTPARAMETER* eventparameter, float value ) )
FMOD_EVENT_FUNCTION( FMOD_EventParameter_GetRange, ( FMOD_EVENTPARAMETER* eventparameter, float* rangemin, float* rangemax ) )

View file

@ -1,322 +0,0 @@
//-----------------------------------------------------------------------------
// 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 "sfx/fmod/sfxFMODBuffer.h"
#include "sfx/fmod/sfxFMODDevice.h"
#include "sfx/sfxDescription.h"
#include "core/util/safeDelete.h"
#include "core/volume.h"
//-----------------------------------------------------------------------------
static const char* sExtensions[] =
{
"", // First try without doing anything with the given path.
"", // Then try it without an extension but by expanding it through Torque::FS.
"aiff",
"asf",
"asx",
"dls",
"flac",
"fsb",
"it",
"m3u",
"mid",
"mod",
"mp2",
"mp3",
"ogg",
"pls",
"s3m",
"vag",
"wav",
"wax",
"wma",
"xm",
#ifdef TORQUE_OS_XENON
".xma",
#endif
NULL
};
//-----------------------------------------------------------------------------
SFXFMODBuffer* SFXFMODBuffer::create( const ThreadSafeRef< SFXStream >& stream, SFXDescription* description )
{
SFXFMODBuffer *buffer = new SFXFMODBuffer( stream, description );
if( !buffer->mSound )
SAFE_DELETE( buffer );
return buffer;
}
//-----------------------------------------------------------------------------
SFXFMODBuffer* SFXFMODBuffer::create( const String& filename, SFXDescription* description )
{
if( Con::getBoolVariable( "$pref::SFX::FMOD::noCustomFileLoading", false ) )
return NULL;
SFXFMODBuffer *buffer = new SFXFMODBuffer( filename, description );
if( !buffer->mSound )
SAFE_DELETE( buffer );
return buffer;
}
//-----------------------------------------------------------------------------
SFXFMODBuffer::SFXFMODBuffer( const String& filename, SFXDescription* description )
: Parent( description ),
mSound( NULL )
{
FMOD_MODE fMode = ( description->mUseHardware ? FMOD_HARDWARE : FMOD_SOFTWARE )
| ( description->mIs3D ? FMOD_3D : FMOD_2D );
if( description->mIsStreaming )
{
fMode |= FMOD_CREATESTREAM;
mIsUnique = true;
}
// Go through the extensions and try each with the given path. The
// first two are special. First we try without touching the filename at all
// so FMOD gets a chance to handle URLs and whatever, and then second we
// try by expanding the path but without adding an extension.
Torque::Path path = filename;
for( U32 i = 0; sExtensions[ i ]; ++ i )
{
path.setExtension( sExtensions[ i ] );
if( !i || Torque::FS::IsFile( path ) )
{
// Translate to full path.
//TODO: Remove this when hooking up the file system functions in sfxFMODDevice.cpp
String fullPath;
if( !i )
fullPath = filename;
else
{
Torque::Path realPath;
if( !Torque::FS::GetFSPath( path, realPath ) )
continue;
fullPath = realPath.getFullPath().c_str();
}
mSound = NULL;
FMOD_RESULT result = SFXFMODDevice::smFunc->FMOD_System_CreateSound(
SFXFMODDevice::smSystem,
fullPath.c_str(),
fMode,
( FMOD_CREATESOUNDEXINFO* ) NULL,
&mSound );
if( result == FMOD_OK )
{
SFXFMODDevice::smFunc->FMOD_Sound_GetMode( mSound, &mMode );
// Read out format.
int numChannels;
int bitsPerSample;
unsigned int length;
float frequency;
SFXFMODDevice::smFunc->FMOD_Sound_GetFormat( mSound, ( FMOD_SOUND_TYPE* ) NULL, ( FMOD_SOUND_FORMAT* ) NULL, &numChannels, &bitsPerSample );
SFXFMODDevice::smFunc->FMOD_Sound_GetLength( mSound, &length, FMOD_TIMEUNIT_MS );
SFXFMODDevice::smFunc->FMOD_Sound_GetDefaults( mSound, &frequency, ( float* ) NULL, ( float* ) NULL, ( int* ) NULL );
mDuration = length;
mFormat = SFXFormat( numChannels, numChannels * bitsPerSample, frequency );
break;
}
}
}
if( !mSound )
Con::errorf( "SFXFMODBuffer::SFXFMODBuffer - failed to load '%s' through FMOD", filename.c_str() );
}
//-----------------------------------------------------------------------------
SFXFMODBuffer::SFXFMODBuffer( const ThreadSafeRef< SFXStream >& stream, SFXDescription* description )
: Parent( stream, description ),
mSound( NULL )
{
FMOD_MODE fMode = ( description->mUseHardware ? FMOD_HARDWARE : FMOD_SOFTWARE )
| ( description->mIs3D ? FMOD_3D : FMOD_2D );
FMOD_CREATESOUNDEXINFO* pCreatesoundexinfo = NULL;
FMOD_CREATESOUNDEXINFO createsoundexinfo;
fMode |= FMOD_OPENUSER; // this tells fmod we are supplying the data directly
if( isStreaming() )
fMode |= FMOD_LOOP_NORMAL | FMOD_UNIQUE;
const SFXFormat& format = getFormat();
U32 channels = format.getChannels();
U32 frequency = format.getSamplesPerSecond();
U32 bitsPerChannel = format.getBitsPerSample() / channels;
U32 dataSize = mBufferSize;
FMOD_SOUND_FORMAT sfxFmt = FMOD_SOUND_FORMAT_NONE;
switch(bitsPerChannel)
{
case 8:
sfxFmt = FMOD_SOUND_FORMAT_PCM8;
break;
case 16:
sfxFmt = FMOD_SOUND_FORMAT_PCM16;
break;
case 24:
sfxFmt = FMOD_SOUND_FORMAT_PCM24;
break;
case 32:
sfxFmt = FMOD_SOUND_FORMAT_PCM32;
break;
default:
AssertISV(false, "SFXFMODBuffer::SFXFMODBuffer() - unsupported bits-per-sample (what format is it in, 15bit PCM?)");
break;
}
dMemset(&createsoundexinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO));
createsoundexinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO); /* required. */
createsoundexinfo.decodebuffersize = frequency; /* Chunk size of stream update in samples. This will be the amount of data passed to the user callback. */
createsoundexinfo.length = dataSize; /* Length of PCM data in bytes of whole sound (for Sound::getLength) */
createsoundexinfo.numchannels = channels; /* Number of channels in the sound. */
createsoundexinfo.defaultfrequency = frequency; /* Default playback rate of sound. */
createsoundexinfo.format = sfxFmt; /* Data format of sound. */
createsoundexinfo.pcmreadcallback = NULL; /* User callback for reading. */
createsoundexinfo.pcmsetposcallback = NULL; /* User callback for seeking. */
pCreatesoundexinfo = &createsoundexinfo;
FMOD_RESULT result = SFXFMODDevice::smFunc->FMOD_System_CreateSound(
SFXFMODDevice::smSystem,
( const char* ) NULL,
fMode,
pCreatesoundexinfo,
&mSound );
if( result != FMOD_OK )
{
mSound = NULL;
Con::errorf( "SFXFMODBuffer::SFXFMODBuffer - failed to create buffer (%i)", result );
}
else
SFXFMODDevice::smFunc->FMOD_Sound_GetMode( mSound, &mMode );
}
//-----------------------------------------------------------------------------
SFXFMODBuffer::~SFXFMODBuffer()
{
if( mSound )
FModAssert( SFXFMODDevice::smFunc->FMOD_Sound_Release( mSound ),
"SFXFMODBuffer::~SFXFMODBuffer - Failed to release a sound!" );
mSound = NULL;
}
//-----------------------------------------------------------------------------
void SFXFMODBuffer::_flush()
{
AssertFatal( isStreaming(), "SFXFMODBuffer::_flush() - not a streaming buffer" );
AssertFatal( SFXInternal::isSFXThread(), "SFXFMODBuffer::_flush() - not on SFX thread" );
Parent::_flush();
SFXFMODDevice::smFunc->FMOD_Channel_SetPosition
( ( ( SFXFMODVoice* ) mUniqueVoice.getPointer() )->mChannel, 0, FMOD_TIMEUNIT_PCM );
}
//-----------------------------------------------------------------------------
bool SFXFMODBuffer::_copyData( U32 offset, const U8* data, U32 length )
{
AssertFatal( data != NULL && length > 0, "Must have data!" );
// Fill the buffer with the resource data.
void* lpvWrite;
U32 dwLength;
void* lpvWrite2;
U32 dwLength2;
int res = SFXFMODDevice::smFunc->FMOD_Sound_Lock(
mSound,
offset, // Offset at which to start lock.
length, // Size of lock.
&lpvWrite, // Gets address of first part of lock.
&lpvWrite2, // Address of wraparound not needed.
&dwLength, // Gets size of first part of lock.
&dwLength2 // Size of wraparound not needed.
);
if ( res != FMOD_OK )
{
// You can remove this if it gets spammy. However since we can
// safely fail in this case it doesn't seem right to assert...
// at the same time it can be very annoying not to know why
// an upload fails!
Con::errorf("SFXFMODBuffer::_copyData - failed to lock a sound buffer! (%d)", this);
return false;
}
// Copy the first part.
dMemcpy( lpvWrite, data, dwLength );
// Do we have a wrap?
if ( lpvWrite2 )
dMemcpy( lpvWrite2, data + dwLength, dwLength2 );
// And finally, unlock.
FModAssert( SFXFMODDevice::smFunc->FMOD_Sound_Unlock(
mSound,
lpvWrite, // Address of lock start.
lpvWrite2, // No wraparound portion.
dwLength, // Size of lock.
dwLength2 ), // No wraparound size.
"Failed to unlock sound buffer!" );
return true;
}
//-----------------------------------------------------------------------------
U32 SFXFMODBuffer::getMemoryUsed() const
{
unsigned int memoryUsed;
SFXFMODDevice::smFunc->FMOD_Sound_GetMemoryInfo(
mSound,
FMOD_MEMBITS_ALL,
FMOD_EVENT_MEMBITS_ALL,
&memoryUsed,
( unsigned int* ) NULL );
return memoryUsed;
}

View file

@ -1,63 +0,0 @@
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#ifndef _SFXFMODBUFFER_H_
#define _SFXFMODBUFFER_H_
#include "fmod.h"
#ifndef _SFXINTERNAL_H_
# include "sfx/sfxInternal.h"
#endif
class SFXFMODBuffer : public SFXInternal::SFXWrapAroundBuffer
{
typedef SFXInternal::SFXWrapAroundBuffer Parent;
friend class SFXFMODDevice;
friend class SFXFMODVoice;
protected:
FMOD_SOUND *mSound;
FMOD_MODE mMode;
SFXFMODBuffer( const ThreadSafeRef< SFXStream >& stream, SFXDescription* description );
SFXFMODBuffer( const String& filename, SFXDescription* description );
// SFXWrapAroundBuffer.
virtual bool _copyData( U32 offset, const U8* data, U32 length );
virtual void _flush();
virtual ~SFXFMODBuffer();
public:
///
static SFXFMODBuffer* create( const ThreadSafeRef< SFXStream >& stream, SFXDescription* description );
static SFXFMODBuffer* create( const String& filename, SFXDescription* description );
virtual U32 getMemoryUsed() const;
};
#endif // _SFXFMODBUFFER_H_

View file

@ -1,578 +0,0 @@
//-----------------------------------------------------------------------------
// 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::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( 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(&current, &max);
Con::printf("Fmod current: %d, max: %d", current, max);
}

View file

@ -1,342 +0,0 @@
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#ifndef _SFXFMODDEVICE_H_
#define _SFXFMODDEVICE_H_
#ifndef _SFXDEVICE_H_
#include "sfx/sfxDevice.h"
#endif
#ifndef _SFXFMODVOICE_H_
#include "sfx/fmod/sfxFMODVoice.h"
#endif
#ifndef _SFXFMODBUFFER_H_
#include "sfx/fmod/sfxFMODBuffer.h"
#endif
#ifndef _SFXFMODPLUGIN_H_
#include "sfx/fmod/sfxFMODPlugin.h"
#endif
#include "core/util/tDictionary.h"
// Disable warning for unused static functions.
#ifdef TORQUE_COMPILER_VISUALC
#pragma warning( disable : 4505 )
#endif
#if defined( TORQUE_OS_XENON ) || defined( TORQUE_OS_PS3 )
#define TORQUE_FMOD_STATIC
#define TORQUE_FMOD_NO_EVENTS //TEMP
#endif
#include "fmod.h"
#include "fmod_errors.h"
#include "fmod_event.h"
#include "platform/platformDlibrary.h"
#include "platform/threads/mutex.h"
// This doesn't appear to exist in some contexts, so let's just add it.
#if defined(TORQUE_OS_WIN) || defined(TORQUE_OS_XENON)
#ifndef WINAPI
#define WINAPI __stdcall
#endif
#else
#define WINAPI
#endif
#define FModAssert(x, msg) \
{ FMOD_RESULT result = ( x ); \
AssertISV( result == FMOD_OK, String::ToString( "%s: %s", msg, FMOD_ErrorString( result ) ) ); }
#define FMOD_FN_FILE "sfx/fmod/fmodFunctions.h"
// Typedefs
#define FMOD_FUNCTION(fn_name, fn_args) \
typedef FMOD_RESULT (WINAPI *FMODFNPTR##fn_name)fn_args;
#define FMOD_EVENT_FUNCTION(fn_name, fn_args) \
typedef FMOD_RESULT (WINAPI *FMODFNPTR##fn_name)fn_args;
#include FMOD_FN_FILE
#undef FMOD_FUNCTION
#undef FMOD_EVENT_FUNCTION
/// FMOD API function table.
///
/// FMOD doesn't want to be called concurrently so in order to
/// not force everything to the main thread (where sound updates
/// would just stall during loading), we thunk all the API
/// calls and lock all API entry points to a single mutex.
struct FModFNTable
{
FModFNTable()
: isLoaded( false ),
eventIsLoaded( false ),
dllRef( NULL ),
eventDllRef( NULL )
{
AssertFatal( mutex == NULL,
"FModFNTable::FModFNTable() - this should be a singleton" );
mutex = new Mutex;
}
~FModFNTable()
{
dllRef = NULL;
eventDllRef = NULL;
delete mutex;
}
bool isLoaded;
bool eventIsLoaded;
DLibraryRef dllRef;
DLibraryRef eventDllRef;
static Mutex* mutex;
template< typename FN >
struct Thunk
{
FN fn;
template< typename A >
FMOD_RESULT operator()( A a )
{
mutex->lock();
FMOD_RESULT result = fn( a );
mutex->unlock();
return result;
}
template< typename A, typename B >
FMOD_RESULT operator()( A a, B b )
{
mutex->lock();
FMOD_RESULT result = fn( a, b );
mutex->unlock();
return result;
}
template< typename A, typename B, typename C >
FMOD_RESULT operator()( A a, B b, C c )
{
mutex->lock();
FMOD_RESULT result = fn( a, b, c );
mutex->unlock();
return result;
}
template< typename A, typename B, typename C, typename D >
FMOD_RESULT operator()( A a, B b, C c, D d )
{
mutex->lock();
FMOD_RESULT result = fn( a, b, c, d );
mutex->unlock();
return result;
}
template< typename A, typename B, typename C, typename D, typename E >
FMOD_RESULT operator()( A a, B b, C c, D d, E e )
{
mutex->lock();
FMOD_RESULT result = fn( a, b, c, d, e );
mutex->unlock();
return result;
}
template< typename A, typename B, typename C, typename D, typename E, typename F >
FMOD_RESULT operator()( A a, B b, C c, D d, E e, F f )
{
mutex->lock();
FMOD_RESULT result = fn( a, b, c, d, e, f );
mutex->unlock();
return result;
}
template< typename A, typename B, typename C, typename D, typename E, typename F, typename G >
FMOD_RESULT operator()( A a, B b, C c, D d, E e, F f, G g )
{
mutex->lock();
FMOD_RESULT result = fn( a, b, c, d, e, f, g );
mutex->unlock();
return result;
}
template< typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H >
FMOD_RESULT operator()( A a, B b, C c, D d, E e, F f, G g, H h )
{
mutex->lock();
FMOD_RESULT result = fn( a, b, c, d, e, f, g, h );
mutex->unlock();
return result;
}
};
#define FMOD_FUNCTION(fn_name, fn_args) \
Thunk< FMODFNPTR##fn_name > fn_name;
#define FMOD_EVENT_FUNCTION(fn_name, fn_args) \
Thunk< FMODFNPTR##fn_name > fn_name;
#include FMOD_FN_FILE
#undef FMOD_FUNCTION
#undef FMOD_EVENT_FUNCTION
};
inline void TorqueVectorToFMODVector( const Point3F& torque, FMOD_VECTOR& fmod )
{
fmod.x = torque.x;
fmod.y = torque.z;
fmod.z = torque.y;
}
inline void TorqueTransformToFMODVectors( const MatrixF& transform, FMOD_VECTOR& position, FMOD_VECTOR& forward, FMOD_VECTOR& up )
{
Point3F _pos, _fwd, _up;
transform.getColumn( 3, &_pos );
transform.getColumn( 1, &_fwd );
transform.getColumn( 2, &_up );
TorqueVectorToFMODVector( _pos, position );
TorqueVectorToFMODVector( _fwd, forward );
TorqueVectorToFMODVector( _up, up );
}
inline int TorquePriorityToFMODPriority( F32 priority )
{
// Map [-2,2] to [256,0].
F32 n = mClampF( priority, -2.0f, 2.0f ) + 2.0f;
return ( n * 256.0f / 4.0f );
}
inline String FMODEventPathToTorqueName( const String& path )
{
String p = path;
p.replace( '/', '_' );
p.replace( '-', '_' );
p.replace( ' ', '_' );
p.replace( '(', '_' );
p.replace( ')', '_' );
p.replace( '%', '_' );
p.replace( '$', '_' );
return p;
}
inline String FMODEventPathToTorqueName( const String& projectName, const String& path )
{
return String::ToString( "%s_%s", projectName.c_str(), FMODEventPathToTorqueName( path ).c_str() );
}
extern String FMODResultToString( FMOD_RESULT result );
class SFXProvider;
class SFXFMODPlugin;
class SFXFMODDevice : public SFXDevice
{
public:
typedef SFXDevice Parent;
friend class SFXFMODProvider; // _init
friend class SFXFMODEventSource; // smStatNumEventSources
explicit SFXFMODDevice();
SFXFMODDevice( SFXProvider* provider, FModFNTable *fmodFnTbl, int deviceIdx, String name );
virtual ~SFXFMODDevice();
protected:
FMOD_MODE m3drolloffmode;
int mDeviceIndex;
/// The FMOD SFXSystemPlugin instance.
SFXFMODPlugin mPlugin;
/// @name Console Variables
/// @{
/// Current core FMOD memory usage in bytes.
static U32 smStatMemUsageCore;
/// Current FMOD Event DLL memory usage in bytes.
static U32 smStatMemUsageEvents;
/// Current number of SFXFMODEventSource instances.
static U32 smStatNumEventSources;
///
static bool smPrefDisableSoftware;
///
static bool smPrefUseSoftwareOcclusion;
///
static bool smPrefUseSoftwareHRTF;
///
static bool smPrefEnableProfile;
///
static bool smPrefGeometryUseClosest;
///
static const char* smPrefDSoundHRTF;
///
static const char* smPrefPluginPath;
/// @}
bool _init();
static SFXFMODDevice* smInstance;
public:
static SFXFMODDevice* instance() { return smInstance; }
FMOD_MODE get3dRollOffMode() { return m3drolloffmode; }
static FMOD_SYSTEM* smSystem;
static FMOD_EVENTSYSTEM* smEventSystem;
static FModFNTable* smFunc;
// Update memory usage stats for metrics display.
void updateMemUsageStats();
// SFXDevice.
virtual SFXBuffer* createBuffer( const ThreadSafeRef< SFXStream >& stream, SFXDescription* description );
virtual SFXBuffer* createBuffer( const String& filename, SFXDescription* description );
virtual SFXVoice* createVoice( bool is3D, SFXBuffer* buffer );
virtual void update();
virtual void setNumListeners( U32 num );
virtual void setListener( U32 index, const SFXListenerProperties& listener );
virtual void setDistanceModel( SFXDistanceModel model );
virtual void setDopplerFactor( F32 factor );
virtual void setRolloffFactor( F32 factor );
virtual void setReverb( const SFXReverbProperties& reverb );
virtual void resetReverb();
};
#endif // _SFXFMODDEVICE_H_

View file

@ -1,339 +0,0 @@
//-----------------------------------------------------------------------------
// 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 "sfx/fmod/sfxFMODEvent.h"
#include "sfx/fmod/sfxFMODEventGroup.h"
#include "sfx/fmod/sfxFMODProject.h"
#include "sfx/fmod/sfxFMODDevice.h"
#include "sfx/sfxParameter.h"
#include "sfx/sfxDescription.h"
#include "core/stream/bitStream.h"
IMPLEMENT_CO_DATABLOCK_V1( SFXFMODEvent );
ConsoleDocClass( SFXFMODEvent,
"@brief A playable sound event in an FMOD Designer audio project.\n\n"
"@ingroup SFXFMOD\n"
"@ingroup Datablocks"
);
//-----------------------------------------------------------------------------
SFXFMODEvent::SFXFMODEvent()
: mGroup( NULL ),
mHandle( NULL ),
mGroupId( 0 ),
mSibling( NULL )
{
dMemset( mParameterRanges, 0, sizeof( mParameterRanges ) );
dMemset( mParameterValues, 0, sizeof( mParameterValues ) );
}
//-----------------------------------------------------------------------------
SFXFMODEvent::SFXFMODEvent( SFXFMODEventGroup* group, FMOD_EVENT* handle )
: mGroup( group ),
mHandle( handle ),
mGroupId( 0 ),
mSibling( NULL )
{
dMemset( mParameterRanges, 0, sizeof( mParameterRanges ) );
dMemset( mParameterValues, 0, sizeof( mParameterValues ) );
// Fetch name.
int index;
char* name = NULL;
SFXFMODDevice::smFunc->FMOD_Event_GetInfo( mHandle, &index, &name, ( FMOD_EVENT_INFO* ) 0 );
mName = name;
// Read out the parameter info so we can immediately create
// the events on the client-side without having to open and
// read all the project info there.
int numParameters;
SFXFMODDevice::smFunc->FMOD_Event_GetNumParameters( mHandle, &numParameters );
if( numParameters > MaxNumParameters )
{
Con::errorf( "SFXFMODEvent::SFXFMODEvent - event '%s' has more parameters (%i) than supported per SFXTrack (%i)",
getQualifiedName().c_str(),
numParameters,
MaxNumParameters );
numParameters = MaxNumParameters;
}
for( U32 i = 0; i < numParameters; ++ i )
{
FMOD_EVENTPARAMETER* parameter;
SFXFMODDevice::smFunc->FMOD_Event_GetParameterByIndex( mHandle, i, &parameter );
SFXFMODDevice::smFunc->FMOD_EventParameter_GetInfo( parameter, &index, &name );
setParameter( i, name );
// Get value and range of parameter.
SFXFMODDevice::smFunc->FMOD_EventParameter_GetValue( parameter, &mParameterValues[ i ] );
SFXFMODDevice::smFunc->FMOD_EventParameter_GetRange( parameter, &mParameterRanges[ i ].x, &mParameterRanges[ i ].y );
}
// Read out the properties and create a custom SFXDescription for the event.
mDescription = new SFXDescription;
if( !group->isClientOnly() )
mDescription->assignId();
mDescription->registerObject(
String::ToString( "%s_%s_Description",
group->getName(),
FMODEventPathToTorqueName( mName ).c_str()
)
);
if( group->isClientOnly() )
Sim::getRootGroup()->addObject( mDescription );
FMOD_MODE modeValue;
float floatValue;
if( SFXFMODDevice::smFunc->FMOD_Event_GetPropertyByIndex( mHandle, FMOD_EVENTPROPERTY_MODE, &modeValue, true ) == FMOD_OK )
mDescription->mIs3D = ( modeValue == FMOD_3D );
if( SFXFMODDevice::smFunc->FMOD_Event_GetPropertyByIndex( mHandle, FMOD_EVENTPROPERTY_VOLUME, &floatValue, true ) == FMOD_OK )
mDescription->mVolume = floatValue;
if( SFXFMODDevice::smFunc->FMOD_Event_GetPropertyByIndex( mHandle, FMOD_EVENTPROPERTY_PITCH, &floatValue, true ) == FMOD_OK )
mDescription->mPitch = floatValue;
if( SFXFMODDevice::smFunc->FMOD_Event_GetPropertyByIndex( mHandle, FMOD_EVENTPROPERTY_3D_MINDISTANCE, &floatValue, true ) == FMOD_OK )
mDescription->mMinDistance = floatValue;
if( SFXFMODDevice::smFunc->FMOD_Event_GetPropertyByIndex( mHandle, FMOD_EVENTPROPERTY_3D_MAXDISTANCE, &floatValue, true ) == FMOD_OK )
mDescription->mMaxDistance = floatValue;
if( SFXFMODDevice::smFunc->FMOD_Event_GetPropertyByIndex( mHandle, FMOD_EVENTPROPERTY_3D_CONEINSIDEANGLE, &floatValue, true ) == FMOD_OK )
mDescription->mConeInsideAngle = floatValue;
if( SFXFMODDevice::smFunc->FMOD_Event_GetPropertyByIndex( mHandle, FMOD_EVENTPROPERTY_3D_CONEOUTSIDEANGLE, &floatValue, true ) == FMOD_OK )
mDescription->mConeOutsideAngle = floatValue;
if( SFXFMODDevice::smFunc->FMOD_Event_GetPropertyByIndex( mHandle, FMOD_EVENTPROPERTY_3D_CONEOUTSIDEVOLUME, &floatValue, true ) == FMOD_OK )
mDescription->mConeOutsideVolume = floatValue;
// Don't read out fade values as we want to leave fade-effects to
// FMOD rather than having the fading system built into SFX pick
// these values up.
}
//-----------------------------------------------------------------------------
SFXFMODEvent::~SFXFMODEvent()
{
}
//-----------------------------------------------------------------------------
void SFXFMODEvent::initPersistFields()
{
addGroup( "DO NOT MODIFY!!" );
addField( "fmodGroup", TYPEID< SFXFMODEventGroup >(), Offset( mGroup, SFXFMODEvent ), "DO NOT MODIFY!!" );
addField( "fmodName", TypeRealString, Offset( mName, SFXFMODEvent ), "DO NOT MODIFY!!" );
addField( "fmodParameterRanges", TypePoint2F, Offset( mParameterRanges, SFXFMODEvent ), MaxNumParameters, "DO NOT MODIFY!!" );
addField( "fmodParameterValues", TypeF32, Offset( mParameterValues, SFXFMODEvent ), MaxNumParameters, "DO NOT MODIFY!!" );
endGroup( "DO NOT MODIFY!!" );
Parent::initPersistFields();
}
//-----------------------------------------------------------------------------
bool SFXFMODEvent::onAdd()
{
if( !Parent::onAdd() )
return false;
if( !mGroup )
{
Con::errorf( "SFXFMODEvent::onAdd - no group set; this event was not properly constructed" );
return false;
}
mGroup->_addEvent( this );
mGroup->mProject->_addEvent( this );
// For non-networked event datablocks, create the parameter
// instances now.
if( isClientOnly() )
_createParameters();
return true;
}
//-----------------------------------------------------------------------------
void SFXFMODEvent::onRemove()
{
Parent::onRemove();
if( !mGroup )
return;
release();
mGroup->_removeEvent( this );
}
//-----------------------------------------------------------------------------
bool SFXFMODEvent::preload( bool server, String& errorStr )
{
if( !Parent::preload( server, errorStr ) )
return false;
if( !server )
{
if( !Sim::findObject( mGroupId, mGroup ) )
{
errorStr = String::ToString( "SFXFMODEvent - group '%i' does not exist", mGroupId );
return false;
}
// Create parameters.
_createParameters();
}
return true;
}
//-----------------------------------------------------------------------------
void SFXFMODEvent::packData( BitStream* stream )
{
Parent::packData( stream );
stream->write( mName );
stream->writeRangedS32( mGroup->getId(), DataBlockObjectIdFirst, DataBlockObjectIdLast );
for( U32 i = 0; i < MaxNumParameters; ++ i )
if( stream->writeFlag( mParameters[ i ] ) )
{
stream->write( mParameterValues[ i ] );
stream->write( mParameterRanges[ i ].x );
stream->write( mParameterRanges[ i ].y );
}
}
//-----------------------------------------------------------------------------
void SFXFMODEvent::unpackData( BitStream* stream )
{
Parent::unpackData( stream );
stream->read( &mName );
mGroupId = stream->readRangedS32( DataBlockObjectIdFirst, DataBlockObjectIdLast );
for( U32 i = 0; i < MaxNumParameters; ++ i )
if( stream->readFlag() )
{
stream->read( &mParameterValues[ i ] );
stream->read( &mParameterRanges[ i ].x );
stream->read( &mParameterRanges[ i ].y );
}
else
{
mParameterValues[ i ] = 0.f;
mParameterRanges[ i ].x = 0.f;
mParameterRanges[ i ].y = 0.f;
}
}
//-----------------------------------------------------------------------------
void SFXFMODEvent::acquire()
{
if( mHandle )
return;
mGroup->acquire();
if( SFXFMODDevice::smFunc->FMOD_EventGroup_GetEvent(
mGroup->mHandle, mName.c_str(), FMOD_EVENT_INFOONLY, &mHandle ) != FMOD_OK )
{
Con::errorf( "SFXFMODEvent::acquire() - failed to acquire event '%s'", getQualifiedName().c_str() );
return;
}
}
//-----------------------------------------------------------------------------
void SFXFMODEvent::release()
{
if( !mHandle )
return;
SFXFMODDevice::smFunc->FMOD_Event_Release( mHandle, true, false );
mHandle = NULL;
}
//-----------------------------------------------------------------------------
String SFXFMODEvent::getQualifiedName() const
{
return String::ToString( "%s/%s", getEventGroup()->getQualifiedName().c_str(), mName.c_str() );
}
//-----------------------------------------------------------------------------
void SFXFMODEvent::_createParameters()
{
const String& projectFileName = getEventGroup()->getProject()->getFileName();
const String qualifiedGroupName = getEventGroup()->getQualifiedName();
const String description = String::ToString( "FMOD Event Parameter (%s)", projectFileName.c_str() );
for( U32 i = 0; i < MaxNumParameters; ++ i )
{
StringTableEntry name = getParameter( i );
if( !name )
continue;
SFXParameter* parameter = SFXParameter::find( name );
if( !parameter )
{
parameter = new SFXParameter();
parameter->setInternalName( name );
parameter->registerObject();
// Set up parameter.
parameter->setChannel( SFXChannelUser0 );
parameter->setRange( mParameterRanges[ i ] );
parameter->setDefaultValue( mParameterValues[ i ] );
parameter->setValue( mParameterValues[ i ] );
parameter->setDescription( description );
// Set categories for easy filtering.
static StringTableEntry sCategories = StringTable->insert( "categories" );
parameter->setDataField( sCategories, "0", "FMOD" );
parameter->setDataField( sCategories, "1", avar( "FMOD Project: %s", projectFileName.c_str() ) );
parameter->setDataField( sCategories, "2", avar( "FMOD Group: %s", qualifiedGroupName.c_str() ) );
}
}
}

View file

@ -1,135 +0,0 @@
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#ifndef _SFXFMODEVENT_H_
#define _SFXFMODEVENT_H_
#ifndef _SFXTRACK_H_
#include "sfx/sfxTrack.h"
#endif
#ifndef _CONSOLETYPES_H_
#include "console/consoleTypes.h"
#endif
#ifndef _MPOINT2_H_
#include "math/mPoint2.h"
#endif
#include "fmod_event.h"
class SFXFMODProject;
class SFXFMODEventGroup;
/// An event in an FMOD Designer project.
///
/// This class must not be manually instanced by the user. Instead, SFXFMODEvents
/// are automatically created when an SFXFMODProject is loaded.
///
/// Be aware that as all the playback happens internally within FMOD's event system,
/// this bypasses the SFX layer and will thus not work with features that rely the
/// structures there. Namely, sound occlusion (except for FMOD's own occlusion) will
/// not work with FMOD events.
///
/// The parameters of an FMOD event are automatically created and designed using the
/// information in the project.
///
class SFXFMODEvent : public SFXTrack
{
public:
typedef SFXTrack Parent;
friend class SFXFMODEventGroup;
friend class SFXFMODEventSource;
protected:
/// Name of the event in the Designer project.
String mName;
/// Event group that this event belongs to.
SFXFMODEventGroup* mGroup;
/// Next event in the group's event chain.
SFXFMODEvent* mSibling;
/// FMOD event handle when event is open. Client-side only.
FMOD_EVENT* mHandle;
///
Point2F mParameterRanges[ MaxNumParameters ];
///
F32 mParameterValues[ MaxNumParameters ];
/// Group ID for client net sync.
S32 mGroupId;
///
void _createParameters();
public:
///
SFXFMODEvent();
///
SFXFMODEvent( SFXFMODEventGroup* group, const String& name );
///
SFXFMODEvent( SFXFMODEventGroup* group, FMOD_EVENT* handle );
~SFXFMODEvent();
/// Create the event object on the FMOD device.
void acquire();
/// Release the event object on the FMOD device.
void release();
///
const String& getEventName() const { return mName; }
///
SFXFMODEventGroup* getEventGroup() const { return mGroup; }
///
String getQualifiedName() const;
///
bool isDataLoaded() const;
// SFXTrack.
virtual bool onAdd();
virtual void onRemove();
virtual bool preload( bool server, String& errorStr );
virtual void packData( BitStream* stream );
virtual void unpackData( BitStream* stream );
static void initPersistFields();
DECLARE_CONOBJECT( SFXFMODEvent );
DECLARE_CATEGORY( "SFX FMOD" );
DECLARE_DESCRIPTION( "An FMOD Designer event." );
};
#endif // !_SFXFMODEVENT_H_

View file

@ -1,510 +0,0 @@
//-----------------------------------------------------------------------------
// 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 "sfx/fmod/sfxFMODEventGroup.h"
#include "sfx/fmod/sfxFMODDevice.h"
#include "sfx/fmod/sfxFMODEvent.h"
#include "sfx/fmod/sfxFMODProject.h"
#include "core/stream/bitStream.h"
#include "console/engineAPI.h"
IMPLEMENT_CO_DATABLOCK_V1( SFXFMODEventGroup );
ConsoleDocClass( SFXFMODEventGroup,
"@brief A group of events in an imported FMOD Designer project.\n\n"
""
"@note Instances of this class \n\n"
"@ingroup SFXFMOD\n"
"@ingroup Datablocks"
);
//-----------------------------------------------------------------------------
SFXFMODEventGroup::SFXFMODEventGroup()
: mProject( NULL ),
mHandle( NULL ),
mParent( NULL ),
mChildren( NULL ),
mSibling( NULL ),
mLoadCount( 0 ),
mEvents( NULL ),
mNumEvents( 0 ),
mNumGroups( 0 ),
mParentId( 0 ),
mProjectId( 0 )
{
}
//-----------------------------------------------------------------------------
SFXFMODEventGroup::SFXFMODEventGroup( SFXFMODProject* project, FMOD_EVENTGROUP* handle, SFXFMODEventGroup* parent )
: mProject( project ),
mHandle( handle ),
mParent( parent ),
mChildren( NULL ),
mSibling( NULL ),
mLoadCount( 0 ),
mEvents( NULL ),
mNumEvents( 0 ),
mNumGroups( 0 ),
mParentId( 0 ),
mProjectId( 0 )
{
AssertFatal( project != NULL, "SFXFMODEventGroup::SFXFMODEventGroup - got a NULL project!" );
AssertFatal( handle != NULL, "SFXFMODEventGroup::SFXFMODEventGroup - got a NULL group handle!" );
// Fetch the name.
int index;
char* name = NULL;
SFXFMODDevice::smFunc->FMOD_EventGroup_GetInfo( handle, &index, &name );
mName = name;
}
//-----------------------------------------------------------------------------
SFXFMODEventGroup::~SFXFMODEventGroup()
{
AssertFatal( mEvents == NULL, "SFXFMODEventGroup::~SFXFMODEventGroup - group still has events attached" );
AssertFatal( mChildren == NULL, "SFXFMODEventGroup::~SFXFMODEventGroup - group still has subgroups attached" );
}
//-----------------------------------------------------------------------------
void SFXFMODEventGroup::initPersistFields()
{
addGroup( "DO NOT MODIFY!!" );
addField( "fmodProject", TYPEID< SFXFMODProject >(), Offset( mProject, SFXFMODEventGroup ), "DO NOT MODIFY!!" );
addField( "fmodGroup", TYPEID< SFXFMODEventGroup >(), Offset( mParent, SFXFMODEventGroup ), "DO NOT MODIFY!!" );
addField( "fmodName", TypeRealString, Offset( mName, SFXFMODEventGroup ), "DO NOT MODIFY!!" );
endGroup( "DO NOT MODIFY!!" );
Parent::initPersistFields();
}
//-----------------------------------------------------------------------------
bool SFXFMODEventGroup::onAdd()
{
if( !Parent::onAdd() )
return false;
if( !mProject )
{
Con::errorf( "SFXFMODEventGroup - not part of a project" );
return false;
}
if( mParent )
mParent->_addGroup( this );
mProject->_addGroup( this );
return true;
}
//-----------------------------------------------------------------------------
void SFXFMODEventGroup::onRemove()
{
Parent::onRemove();
if( !mProject )
return;
release();
while( mEvents )
mEvents->deleteObject();
while( mChildren )
mChildren->deleteObject();
if( mParent )
mParent->_removeGroup( this );
mProject->_removeGroup( this );
}
//-----------------------------------------------------------------------------
bool SFXFMODEventGroup::preload( bool server, String& errorStr )
{
if( !Parent::preload( server, errorStr ) )
return false;
if( !server )
{
if( mParentId != 0 && !Sim::findObject( mParentId, mParent ) )
{
errorStr = String::ToString( "SFXFMODEventGroup - parent group '%i' does not exist", mParentId );
return false;
}
if( !Sim::findObject( mProjectId, mProject ) )
{
errorStr = String::ToString( "SFXFMODEventGroup - project '%i' does not exist", mProjectId );
return false;
}
}
return true;
}
//-----------------------------------------------------------------------------
void SFXFMODEventGroup::packData( BitStream* stream )
{
Parent::packData( stream );
stream->write( mName );
stream->writeRangedS32( mProject->getId(), DataBlockObjectIdFirst, DataBlockObjectIdLast );
if( stream->writeFlag( mParent ) )
stream->writeRangedS32( mParent->getId(), DataBlockObjectIdFirst, DataBlockObjectIdLast );
}
//-----------------------------------------------------------------------------
void SFXFMODEventGroup::unpackData( BitStream* stream )
{
Parent::unpackData( stream );
stream->read( &mName );
mProjectId = stream->readRangedS32( DataBlockObjectIdFirst, DataBlockObjectIdLast );
if( stream->readFlag() )
mParentId = stream->readRangedS32( DataBlockObjectIdFirst, DataBlockObjectIdLast );
else
mParentId = 0;
}
//-----------------------------------------------------------------------------
String SFXFMODEventGroup::getQualifiedName() const
{
if( mParent )
return String::ToString( "%s/%s", mParent->getQualifiedName().c_str(), mName.c_str() );
else
return mName;
}
//-----------------------------------------------------------------------------
bool SFXFMODEventGroup::isDataLoaded() const
{
// Check whether we or any of our parents has triggered a load.
for( const SFXFMODEventGroup* group = this; group != NULL; group = group->mParent )
if( group->mLoadCount > 0 )
return true;
return false;
}
//-----------------------------------------------------------------------------
bool SFXFMODEventGroup::loadData( bool samples, bool streams )
{
if( !mHandle )
acquire();
if( !mLoadCount )
{
FMOD_EVENT_RESOURCE resource;
if( samples && streams )
resource = FMOD_EVENT_RESOURCE_STREAMS_AND_SAMPLES;
else if( samples )
resource = FMOD_EVENT_RESOURCE_SAMPLES;
else if( streams )
resource = FMOD_EVENT_RESOURCE_STREAMS;
else
return true;
FMOD_RESULT result = SFXFMODDevice::smFunc->FMOD_EventGroup_LoadEventData( mHandle, resource, FMOD_EVENT_DEFAULT );
if( result != FMOD_OK )
{
Con::errorf( "SFXFMODEventGroup::loadData - could not load data: %s", FMODResultToString( result ).c_str() );
return false;
}
SFXFMODDevice::instance()->updateMemUsageStats();
Con::printf( "SFXFMODProject - %s: Loaded data for group '%s'", mProject->getName(), getQualifiedName().c_str() );
}
mLoadCount ++;
return true;
}
//-----------------------------------------------------------------------------
void SFXFMODEventGroup::freeData( bool force )
{
bool isLoaded = ( mLoadCount > 0 );
if( !isLoaded )
isLoaded = ( mParent ? mParent->isDataLoaded() : false );
else
{
if( force )
mLoadCount = 0;
else
-- mLoadCount;
}
if( !mLoadCount && isLoaded )
{
FMOD_RESULT result = SFXFMODDevice::smFunc->FMOD_EventGroup_FreeEventData( mHandle, ( FMOD_EVENT* ) NULL, false );
if( result != FMOD_OK )
Con::errorf( "SFXFMODEventGroup - failed freeing event data: %s", FMODResultToString( result ).c_str() );
SFXFMODDevice::instance()->updateMemUsageStats();
Con::printf( "SFXFMODProject - %s: Cleared data for group '%s'", mProject->getName(), getQualifiedName().c_str() );
}
}
//-----------------------------------------------------------------------------
void SFXFMODEventGroup::acquire( bool recursive )
{
// Make sure the project is acquired.
mProject->acquire();
// Acquire the group.
if( !mHandle )
{
if( mParent )
{
mParent->acquire();
SFXFMODDevice::smFunc->FMOD_EventGroup_GetGroup( mParent->mHandle, mName, true, &mHandle );
}
else
{
mProject->acquire();
SFXFMODDevice::smFunc->FMOD_EventProject_GetGroup( mProject->mHandle, mName, true, &mHandle );
}
}
// Acquite events and subgroups.
if( recursive )
{
for( SFXFMODEvent* event = mEvents; event != NULL; event = event->mSibling )
event->acquire();
for( SFXFMODEventGroup* group = mChildren; group != NULL; group = group->mSibling )
group->acquire( true );
}
}
//-----------------------------------------------------------------------------
void SFXFMODEventGroup::release()
{
if( !mHandle )
return;
// Free the event data if we still have it loaded.
if( isDataLoaded() )
freeData( true );
// Release events.
for( SFXFMODEvent* event = mEvents; event != NULL; event = event->mSibling )
event->release();
// Release children.
for( SFXFMODEventGroup* child = mChildren; child != NULL; child = child->mSibling )
child->release();
// Release our handle.
freeData();
mHandle = NULL;
}
//-----------------------------------------------------------------------------
void SFXFMODEventGroup::_load()
{
// Make sure we have the group open.
if( !mHandle )
acquire();
// Fetch info.
int numEvents;
int numGroups;
SFXFMODDevice::smFunc->FMOD_EventGroup_GetNumEvents( mHandle, &numEvents );
SFXFMODDevice::smFunc->FMOD_EventGroup_GetNumGroups( mHandle, &numGroups );
// Load events.
for( U32 i = 0; i < numEvents; ++ i )
{
FMOD_EVENT* handle;
if( SFXFMODDevice::smFunc->FMOD_EventGroup_GetEventByIndex( mHandle, i, FMOD_EVENT_INFOONLY, &handle ) == FMOD_OK )
{
SFXFMODEvent* event = new SFXFMODEvent( this, handle );
if( !isClientOnly() )
event->assignId();
event->registerObject( String::ToString( "%s_%s", getName(), FMODEventPathToTorqueName( event->getEventName() ).c_str() ) );
if( isClientOnly() )
Sim::getRootGroup()->addObject( event );
}
}
// Load subgroups.
for( U32 i = 0; i < numGroups; ++ i )
{
FMOD_EVENTGROUP* handle;
if( SFXFMODDevice::smFunc->FMOD_EventGroup_GetGroupByIndex( mHandle, i, true, &handle ) == FMOD_OK )
{
SFXFMODEventGroup* group = new SFXFMODEventGroup( mProject, handle, this );
if( !isClientOnly() )
group->assignId();
group->registerObject( String::ToString( "%s_%s", getName(), FMODEventPathToTorqueName( group->getGroupName() ).c_str() ) );
if( isClientOnly() )
Sim::getRootGroup()->addObject( group );
group->_load();
}
}
}
//-----------------------------------------------------------------------------
void SFXFMODEventGroup::_addEvent( SFXFMODEvent* event )
{
event->mSibling = mEvents;
mEvents = event;
mNumEvents ++;
}
//-----------------------------------------------------------------------------
void SFXFMODEventGroup::_removeEvent( SFXFMODEvent* event )
{
if( mEvents == event )
{
mEvents = event->mSibling;
event->mSibling = NULL;
mNumEvents --;
}
else
{
SFXFMODEvent* p = mEvents;
while( p != NULL && p->mSibling != event )
p = p->mSibling;
if( p )
{
p->mSibling = event->mSibling;
event->mSibling = NULL;
mNumEvents --;
}
}
}
//-----------------------------------------------------------------------------
void SFXFMODEventGroup::_addGroup( SFXFMODEventGroup* group )
{
group->mSibling = mChildren;
mChildren = group;
mNumGroups ++;
}
//-----------------------------------------------------------------------------
void SFXFMODEventGroup::_removeGroup( SFXFMODEventGroup* group )
{
if( mChildren == group )
{
mChildren = group->mSibling;
group->mSibling = NULL;
mNumGroups --;
}
else
{
SFXFMODEventGroup* p = mChildren;
while( p != NULL && p->mSibling != group )
p = p->mSibling;
if( p )
{
p->mSibling = group->mSibling;
group->mSibling = NULL;
mNumGroups --;
}
}
}
//=============================================================================
// Console Methods.
//=============================================================================
// MARK: ---- Console Methods ----
//-----------------------------------------------------------------------------
DefineEngineMethod( SFXFMODEventGroup, isDataLoaded, bool, (),,
"Test whether the resource data for this group has been loaded.\n\n"
"@return True if the resource data for this group is currently loaded.\n" )
{
return object->isDataLoaded();
}
//-----------------------------------------------------------------------------
DefineEngineMethod( SFXFMODEventGroup, loadData, bool, ( bool loadStreams, bool loadSamples ), ( true, true ),
"Load the resource data for this group, if it has not already been loaded (either directly "
"or indirectly through a parent group).\n"
"This method works recursively and thus data for direct and indirect child groups to this group will be "
"loaded as well.\n\n"
"@param loadStreams Whether to open streams.\n"
"@param loadSamples Whether to load sample banks.\n"
"@return True if the data has been successfully loaded; false otherwise.\n\n"
"@see SFXFMODProject_resources" )
{
return object->loadData( loadSamples, loadStreams );
}
//-----------------------------------------------------------------------------
DefineEngineMethod( SFXFMODEventGroup, freeData, void, (),,
"Release the resource data for this group and its subgroups.\n\n"
"@see SFXFMODProject_resources" )
{
object->freeData();
}

View file

@ -1,159 +0,0 @@
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#ifndef _SFXFMODEVENTGROUP_H_
#define _SFXFMODEVENTGROUP_H_
#ifndef _SIMDATABLOCK_H_
#include "console/simDatablock.h"
#endif
#ifndef _TVECTOR_H_
#include "core/util/tVector.h"
#endif
#ifndef _CONSOLETYPES_H_
#include "console/consoleTypes.h"
#endif
#include "fmod_event.h"
class SFXFMODProject;
class SFXFMODEvent;
///
class SFXFMODEventGroup : public SimDataBlock
{
public:
typedef SimDataBlock Parent;
friend class SFXFMODProject;
friend class SFXFMODEvent; // mHandle
friend class SFXFMODEventSource; // mHandle
protected:
///
String mName;
///
U32 mNumEvents;
///
U32 mNumGroups;
///
SFXFMODProject* mProject;
///
SFXFMODEventGroup* mParent;
///
SFXFMODEventGroup* mChildren;
///
SFXFMODEventGroup* mSibling;
///
SFXFMODEvent* mEvents;
///
FMOD_EVENTGROUP* mHandle;
///
U32 mLoadCount;
/// Project ID for client net sync.
S32 mParentId;
/// Project ID for client net sync.
S32 mProjectId;
///
void _load();
///
void _addEvent( SFXFMODEvent* event );
///
void _addGroup( SFXFMODEventGroup* group );
///
void _removeEvent( SFXFMODEvent* event );
///
void _removeGroup( SFXFMODEventGroup* group );
public:
///
SFXFMODEventGroup();
///
SFXFMODEventGroup( SFXFMODProject* project, const String& name, SFXFMODEventGroup* parent = NULL );
///
SFXFMODEventGroup( SFXFMODProject* project, FMOD_EVENTGROUP* handle, SFXFMODEventGroup* parent = NULL );
~SFXFMODEventGroup();
/// Create the event group object on the FMOD device.
void acquire( bool recursive = false );
/// Release the event group object on the FMOD device.
void release();
///
const String& getGroupName() const { return mName; }
///
String getQualifiedName() const;
///
SFXFMODProject* getProject() const { return mProject; }
/// Return true if the event data for this group has been loaded.
bool isDataLoaded() const;
/// Load the event data for this group.
///
/// @note Loading is reference-counted.
bool loadData( bool samples = true, bool streams = true );
///
void freeData( bool force = false );
// SimDataBlock.
virtual bool onAdd();
virtual void onRemove();
virtual bool preload( bool server, String& errorStr );
virtual void packData( BitStream* stream );
virtual void unpackData( BitStream* stream );
static void initPersistFields();
DECLARE_CONOBJECT( SFXFMODEventGroup );
DECLARE_CATEGORY( "SFX FMOD" );
DECLARE_DESCRIPTION( "An event group in an FMOD Designer project." );
};
#endif // !_SFXFMODEVENTGROUP_H_

View file

@ -1,337 +0,0 @@
//-----------------------------------------------------------------------------
// 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 "sfx/fmod/sfxFMODEventSource.h"
#include "sfx/fmod/sfxFMODEvent.h"
#include "sfx/fmod/sfxFMODEventGroup.h"
#include "sfx/fmod/sfxFMODDevice.h"
#include "sfx/sfxDescription.h"
IMPLEMENT_CONOBJECT( SFXFMODEventSource );
ConsoleDocClass( SFXFMODEventSource,
"@brief A sound source controller playing an %FMOD Designer event (SFXFMODEvent).\n\n"
"%FMOD event sources are internally created by the sound system to play events from imported %FMOD Designer projects.\n\n"
"@note This class cannot be instantiated directly by the user. Instead, instances of SFXFMODEventSource will be "
"implicitly created by the sound system when playing an SFXFMODEvent.\n\n"
"@ingroup SFXFMOD\n"
);
//-----------------------------------------------------------------------------
SFXFMODEventSource::SFXFMODEventSource()
: mHandle( NULL )
{
SFXFMODDevice::instance()->smStatNumEventSources ++;
}
//-----------------------------------------------------------------------------
SFXFMODEventSource::SFXFMODEventSource( SFXFMODEvent* event )
: Parent( event ),
mHandle( NULL )
{
SFXFMODDevice::instance()->smStatNumEventSources ++;
// Make sure the group has its data loaded.
SFXFMODEventGroup* group = event->getEventGroup();
if( !group->loadData() )
return;
// Create an event instance.
if( SFXFMODDevice::smFunc->FMOD_EventGroup_GetEvent(
event->getEventGroup()->mHandle,
event->getEventName(),
FMOD_EVENT_DEFAULT,
&mHandle ) != FMOD_OK )
{
Con::errorf( "SFXFMODEventSource::SFXFMODEventSource - failed to open event '%s'", event->getQualifiedName().c_str() );
mHandle = NULL;
}
}
//-----------------------------------------------------------------------------
SFXFMODEventSource::~SFXFMODEventSource()
{
SFXFMODDevice::instance()->smStatNumEventSources --;
if( mHandle )
SFXFMODDevice::smFunc->FMOD_Event_Release( mHandle, true, true );
if( getEvent() )
getEvent()->getEventGroup()->freeData();
}
//-----------------------------------------------------------------------------
SFXFMODEventSource* SFXFMODEventSource::create( SFXFMODEvent* event )
{
AssertFatal( event != NULL, "SFXFMODEventSource::create - got a NULL event!" );
// Create the source.
SFXFMODEventSource* source = new SFXFMODEventSource( event );
if( source->mHandle )
source->registerObject();
else
{
delete source;
source = NULL;
}
return source;
}
//-----------------------------------------------------------------------------
void SFXFMODEventSource::play( F32 fadeInTime )
{
if( getStatus() == SFXStatusPlaying )
return;
if( isPaused() )
SFXFMODDevice::smFunc->FMOD_Event_SetPaused( mHandle, false );
else
{
AssertFatal( getEvent()->getEventGroup()->isDataLoaded(), "SFXFMODEventSource::play() - event data for group not loaded" );
if( fadeInTime != -1.f )
{
U32 fade = U32( fadeInTime * 1000.f );
SFXFMODDevice::smFunc->FMOD_Event_SetPropertyByIndex(
mHandle, FMOD_EVENTPROPERTY_FADEIN,
&fade, true
);
}
FMOD_RESULT result = SFXFMODDevice::smFunc->FMOD_Event_Start( mHandle );
if( result != FMOD_OK )
{
Con::errorf( "SFXFMODEventSoure::play() - failed to start event: %s", FMODResultToString( result ).c_str() );
return;
}
}
mPlayTimer.start();
_setStatus( SFXStatusPlaying );
_play();
}
//-----------------------------------------------------------------------------
void SFXFMODEventSource::stop( F32 fadeOutTime )
{
if( getStatus() == SFXStatusStopped )
return;
AssertFatal( mHandle, "SFXFMODEvent::stop() - event not acquired" );
bool immediate = ( fadeOutTime == 0.f );
FMOD_RESULT result = SFXFMODDevice::smFunc->FMOD_Event_Stop( mHandle, immediate );
if( result != FMOD_OK )
Con::errorf( "SFXFMODEventSource::stop() - failed to stop event: %s", FMODResultToString( result ).c_str() );
mPlayTimer.stop();
_setStatus( SFXStatusStopped );
// Reset fade-in to default in case it got overwritten
// in play().
U32 fade = U32( mFadeInTime * 1000.f );
SFXFMODDevice::smFunc->FMOD_Event_SetPropertyByIndex(
mHandle, FMOD_EVENTPROPERTY_FADEIN,
&fade, true
);
_stop();
}
//-----------------------------------------------------------------------------
void SFXFMODEventSource::pause( F32 fadeOutTime )
{
if( getStatus() != SFXStatusPlaying )
return;
SFXFMODDevice::smFunc->FMOD_Event_SetPaused( mHandle, true );
mPlayTimer.pause();
_setStatus( SFXStatusPaused );
_pause();
}
//-----------------------------------------------------------------------------
void SFXFMODEventSource::setTransform( const MatrixF& transform )
{
Parent::setTransform( transform );
_update3DAttributes();
}
//-----------------------------------------------------------------------------
void SFXFMODEventSource::setVelocity( const VectorF& velocity )
{
Parent::setVelocity( velocity );
_update3DAttributes();
}
//-----------------------------------------------------------------------------
void SFXFMODEventSource::_update3DAttributes()
{
FMOD_VECTOR position;
FMOD_VECTOR velocity;
FMOD_VECTOR orientation;
Point3F direction;
getTransform().getColumn( 1, &direction );
TorqueVectorToFMODVector( getTransform().getPosition(), position );
TorqueVectorToFMODVector( getVelocity(), velocity );
TorqueVectorToFMODVector( direction, orientation );
SFXFMODDevice::smFunc->FMOD_Event_Set3DAttributes( mHandle, &position, &velocity, &orientation );
}
//-----------------------------------------------------------------------------
void SFXFMODEventSource::_updateStatus()
{
if( mStatus == SFXStatusPlaying )
{
if( !getEvent() )
_setStatus( SFXStatusStopped );
else
{
FMOD_EVENT_STATE state;
SFXFMODDevice::smFunc->FMOD_Event_GetState( mHandle, &state );
if( !( state & FMOD_EVENT_STATE_PLAYING ) )
_setStatus( SFXStatusStopped );
}
}
}
//-----------------------------------------------------------------------------
void SFXFMODEventSource::_updateVolume( const MatrixF& listener )
{
F32 oldPreAttenuatedVolume = mPreAttenuatedVolume;
Parent::_updateVolume( listener );
if( oldPreAttenuatedVolume != mPreAttenuatedVolume )
SFXFMODDevice::smFunc->FMOD_Event_SetVolume( mHandle, mPreAttenuatedVolume );
}
//-----------------------------------------------------------------------------
void SFXFMODEventSource::_updatePitch()
{
F32 oldEffectivePitch = mEffectivePitch;
Parent::_updatePitch();
if( mEffectivePitch != oldEffectivePitch )
SFXFMODDevice::smFunc->FMOD_Event_SetPitch( mHandle, mEffectivePitch - 1.0f, FMOD_EVENT_PITCHUNITS_RAW );
}
//-----------------------------------------------------------------------------
void SFXFMODEventSource::_updatePriority()
{
//TODO
Parent::_updatePriority();
}
//-----------------------------------------------------------------------------
void SFXFMODEventSource::_setMinMaxDistance( F32 min, F32 max )
{
Parent::_setMinMaxDistance( min, max );
_update3DAttributes();
}
//-----------------------------------------------------------------------------
void SFXFMODEventSource::_setFadeTimes( F32 fadeInTime, F32 fadeOutTime )
{
Parent::_setFadeTimes( fadeInTime, fadeOutTime );
U32 fadeIn = U32( mFadeInTime * 1000.f );
SFXFMODDevice::smFunc->FMOD_Event_SetPropertyByIndex(
mHandle, FMOD_EVENTPROPERTY_FADEIN,
&fadeIn, true
);
U32 fadeOut = U32( mFadeOutTime * 1000.f );
SFXFMODDevice::smFunc->FMOD_Event_SetPropertyByIndex(
mHandle, FMOD_EVENTPROPERTY_FADEOUT,
&fadeOut, true
);
}
//-----------------------------------------------------------------------------
void SFXFMODEventSource::_setCone( F32 innerAngle, F32 outerAngle, F32 outerVolume )
{
Parent::_setCone( innerAngle, outerAngle, outerVolume );
_update3DAttributes();
}
//-----------------------------------------------------------------------------
void SFXFMODEventSource::_onParameterEvent( SFXParameter* parameter, SFXParameterEvent event )
{
Parent::_onParameterEvent( parameter, event );
// If it's a value-change on a custom parameter,
// pass it along to FMOD.
if( getEvent()
&& event == SFXParameterEvent_ValueChanged
&& parameter->getChannel() == SFXChannelUser0 )
{
const char* name = parameter->getInternalName();
FMOD_EVENTPARAMETER* fmodParameter;
if( SFXFMODDevice::smFunc->FMOD_Event_GetParameter( mHandle, name, &fmodParameter ) != FMOD_OK )
{
Con::errorf( "SFXFMODEventSource::_onParameterEvent - could not access parameter '%s' of event '%s'",
name, getEvent()->getQualifiedName().c_str() );
return;
}
SFXFMODDevice::smFunc->FMOD_EventParameter_SetValue( fmodParameter, parameter->getValue() );
}
}

View file

@ -1,101 +0,0 @@
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#ifndef _SFXFMODEVENTSOURCE_H_
#define _SFXFMODEVENTSOURCE_H_
#ifndef _SFXSOURCE_H_
#include "sfx/sfxSource.h"
#endif
#include "fmod_event.h"
class SFXFMODEvent;
/// An SFXSource that controls the playback of an SFXFMODEvent.
///
/// SFXFMODEvents can be played back directly through their console methods.
/// However, this class integrates them with the remaining SFX system and makes
/// events usable wherever SFX tracks are usable though with the important
/// distinction that there can only ever be a single source for a given event.
///
/// Note that calling playback methods directly on an event will cause a source
/// for the event to be created if there is not already one.
///
/// Be aware that using fade-outs in events in combination with play-once sources
/// does not work well at the moment.
///
class SFXFMODEventSource : public SFXSource
{
public:
typedef SFXSource Parent;
protected:
/// The event instance handle for this source.
FMOD_EVENT* mHandle;
///
SFXFMODEventSource( SFXFMODEvent* event );
/// Update 3D position, velocity, and orientation from current source transform.
void _update3DAttributes();
// SFXSource.
virtual void _updateStatus();
virtual void _updateVolume( const MatrixF& listener );
virtual void _updatePitch();
virtual void _updatePriority();
virtual void _onParameterEvent( SFXParameter* parameter, SFXParameterEvent event );
virtual void _setMinMaxDistance( F32 min, F32 max );
virtual void _setCone( F32 innerAngle, F32 outerAngle, F32 outerVolume );
virtual void _setFadeTimes( F32 fadeInTime, F32 fadeOutTime );
public:
///
SFXFMODEventSource();
virtual ~SFXFMODEventSource();
/// Return the FMOD event object that is being played back by this source.
SFXFMODEvent* getEvent() const { return ( SFXFMODEvent* ) mTrack.getPointer(); }
/// Create a new source for the given event.
static SFXFMODEventSource* create( SFXFMODEvent* event );
// SFXSource.
virtual void play( F32 fadeInTime = -1.f ); // fadeInTime ignored when resuming from paused
virtual void stop( F32 fadeOutTime = -1.f ); // fadeOutTime!=0 ignored
virtual void pause( F32 fadeOutTime = -1.f ); // fadeOutTime currently ignored
virtual void setTransform( const MatrixF& transform );
virtual void setVelocity( const VectorF& velocity );
DECLARE_CONOBJECT( SFXFMODEventSource );
DECLARE_CATEGORY( "SFX FMOD" );
DECLARE_DESCRIPTION( "An SFX source controlling the playback of an FMOD Designer event." );
};
#endif // !_SFXFMODEVENTSOURCE_H_

View file

@ -1,37 +0,0 @@
//-----------------------------------------------------------------------------
// 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 "sfx/fmod/sfxFMODPlugin.h"
#include "sfx/fmod/sfxFMODEvent.h"
#include "sfx/fmod/sfxFMODEventSource.h"
//-----------------------------------------------------------------------------
SFXSource* SFXFMODPlugin::createSource( SFXTrack* track )
{
SFXFMODEvent* event = dynamic_cast< SFXFMODEvent* >( track );
if( !event )
return NULL;
return SFXFMODEventSource::create( event );
}

View file

@ -1,48 +0,0 @@
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#ifndef _SFXFMODPLUGIN_H_
#define _SFXFMODPLUGIN_H_
#ifndef _SFXSYSTEM_H_
#include "sfx/sfxSystem.h"
#endif
/// SFXSystem plugin that adds the capability to create SFXSources for
/// Designer SFXFMODEvents.
///
/// The plugin will only be installed if an FMOD device has been created.
/// While SFXFMODEvents may be constructed without an FMOD device, trying
/// to play such an event then will result in an error.
///
class SFXFMODPlugin : public SFXSystemPlugin
{
public:
typedef SFXSystemPlugin Parent;
///
virtual SFXSource* createSource( SFXTrack* track );
};
#endif // !_SFXFMODPLUGIN_H_

View file

@ -1,493 +0,0 @@
//-----------------------------------------------------------------------------
// 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 "sfx/fmod/sfxFMODProject.h"
#include "sfx/fmod/sfxFMODDevice.h"
#include "sfx/fmod/sfxFMODEvent.h"
#include "sfx/fmod/sfxFMODEventGroup.h"
#include "sfx/sfxDescription.h"
#include "core/stringTable.h"
#include "core/volume.h"
#include "core/util/path.h"
#include "core/stream/fileStream.h"
#include "core/stream/bitStream.h"
#include "core/util/safeDelete.h"
IMPLEMENT_CO_DATABLOCK_V1( SFXFMODProject );
ConsoleDocClass( SFXFMODProject,
"@brief An FMOD Designer project loaded into Torque.\n\n"
"@section SFXFMODProject_resources Resource Loading\n\n"
"@ingroup SFXFMOD\n"
"@ingroup Datablocks"
);
//-----------------------------------------------------------------------------
SFXFMODProject::SFXFMODProject()
: mHandle( NULL ),
mRootGroups( NULL )
{
VECTOR_SET_ASSOCIATION( mGroups );
VECTOR_SET_ASSOCIATION( mEvents );
SFX->getEventSignal().notify( this, &SFXFMODProject::_onSystemEvent );
}
//-----------------------------------------------------------------------------
SFXFMODProject::~SFXFMODProject()
{
AssertFatal( mGroups.empty(), "SFXFMODProject::~SFXFMODProject - project still has groups attached" );
AssertFatal( mEvents.empty(), "SFXFMODProject::~SFXFMODProject - project still has events attached" );
if( SFX )
SFX->getEventSignal().remove( this, &SFXFMODProject::_onSystemEvent );
}
//-----------------------------------------------------------------------------
void SFXFMODProject::initPersistFields()
{
addGroup( "FMOD" );
addField( "fileName", TypeStringFilename, Offset( mFileName, SFXFMODProject ), "The compiled .fev file from FMOD Designer." );
addField( "mediaPath", TypeStringFilename, Offset( mMediaPath, SFXFMODProject ), "Path to the media files; if unset, defaults to project directory." );
endGroup( "FMOD" );
Parent::initPersistFields();
}
//-----------------------------------------------------------------------------
bool SFXFMODProject::onAdd()
{
if( !Parent::onAdd() )
return false;
// If this is a non-networked datablock, load the
// project data now.
if( isClientOnly() && !_load() )
return false;
return true;
}
//-----------------------------------------------------------------------------
void SFXFMODProject::onRemove()
{
Parent::onRemove();
_clear();
}
//-----------------------------------------------------------------------------
bool SFXFMODProject::preload( bool server, String& errorStr )
{
if( !Parent::preload( server, errorStr ) )
return false;
if( server )
{
if( mFileName.isEmpty() )
{
errorStr = String::ToString( "SFXFMODProject::preload - no filename set on %i (%s)",
getId(), getName() );
return false;
}
if( mGroups.empty() || mEvents.empty() )
_load();
release();
}
return true;
}
//-----------------------------------------------------------------------------
void SFXFMODProject::packData( BitStream* stream )
{
Parent::packData( stream );
stream->write( mFileName );
stream->write( mMediaPath );
}
//-----------------------------------------------------------------------------
void SFXFMODProject::unpackData( BitStream* stream )
{
Parent::unpackData( stream );
stream->read( &mFileName );
stream->read( &mMediaPath );
}
//-----------------------------------------------------------------------------
void SFXFMODProject::_onSystemEvent( SFXSystemEventType event )
{
switch( event )
{
case SFXSystemEvent_DestroyDevice:
// If the FMOD device is being destroyed,
// release all our data.
if( SFXFMODDevice::instance() )
release();
break;
default:
break;
}
}
//-----------------------------------------------------------------------------
void SFXFMODProject::_clear()
{
release();
for( U32 i = 0; i < mGroups.size(); ++ i )
if( !mGroups[ i ]->isRemoved() )
mGroups[ i ]->deleteObject();
mGroups.clear();
mEvents.clear();
mRootGroups = NULL;
}
//-----------------------------------------------------------------------------
bool SFXFMODProject::_load()
{
const Torque::Path eventScriptFileName = mFileName + ".cs";
const Torque::Path eventScriptFileNameDSO = eventScriptFileName + ".dso";
const bool eventScriptFileExists = Torque::FS::IsFile( eventScriptFileName );
const bool eventScriptFileDSOExists = Torque::FS::IsFile( eventScriptFileNameDSO );
// Check if we need to (re-)generate the event script file.
bool needToGenerateEventScriptFile = false;
if( ( !eventScriptFileExists && !eventScriptFileDSOExists )
|| ( Torque::FS::CompareModifiedTimes( mFileName, eventScriptFileName ) > 0
|| Torque::FS::CompareModifiedTimes( mFileName, eventScriptFileNameDSO ) > 0 ) )
needToGenerateEventScriptFile = true;
// If we need to generate, check if we can.
SFXFMODDevice* fmodDevice = SFXFMODDevice::instance();
if( needToGenerateEventScriptFile && !fmodDevice )
{
// If we have neither FMOD nor the event scripts (even if outdated),
// there's nothing we can do.
if( !eventScriptFileExists && !eventScriptFileDSOExists )
{
Con::errorf( "SFXFMODProject::_load() - event script for '%s' does not exist and device is not FMOD; load this project under FMOD first",
mFileName.c_str() );
return false;
}
// Use the oudated versions.
Con::warnf( "SFXMODProject::_load() - event script for '%s' is outdated and device is not FMOD; event data may not match .fev contents",
mFileName.c_str() );
needToGenerateEventScriptFile = false;
}
// If we don't need to regenerate, try executing the event script now.
if( !needToGenerateEventScriptFile )
{
if( ( eventScriptFileExists || eventScriptFileDSOExists )
&& !Con::evaluatef( "exec( \"%s\" );", eventScriptFileName.getFullPath().c_str() ) )
{
Con::errorf( "SFXFMODProject::_load() - failed to execute event script for '%s'%s",
mFileName.c_str(),
fmodDevice != NULL ? "; trying to regenerate" : ""
);
if( !fmodDevice )
return false;
needToGenerateEventScriptFile = true;
}
else
Con::printf( "SFXFMODProject - %s: Loaded event script", getName() );
}
// If we need to generate the event script file,
// load the FMOD project now and then emit the file.
if( needToGenerateEventScriptFile )
{
// Try to load the project.
acquire();
if( !mHandle )
return false;
// Get the project info.
FMOD_EVENT_PROJECTINFO info;
int numEvents;
int numGroups;
SFXFMODDevice::smFunc->FMOD_EventProject_GetInfo( mHandle, &info );
SFXFMODDevice::smFunc->FMOD_EventProject_GetNumEvents( mHandle, &numEvents );
SFXFMODDevice::smFunc->FMOD_EventProject_GetNumGroups( mHandle, &numGroups );
Con::printf( "SFXFMODProject - %s: Loading '%s' from '%s' (index: %i, events: %i, groups: %i)",
getName(), info.name, mFileName.c_str(), info.index, numEvents, numGroups );
// Load the root groups.
for( U32 i = 0; i < numGroups; ++ i )
{
FMOD_EVENTGROUP* group;
if( SFXFMODDevice::smFunc->FMOD_EventProject_GetGroupByIndex( mHandle, i, true, &group ) == FMOD_OK )
{
SFXFMODEventGroup* object = new SFXFMODEventGroup( this, group );
object->mSibling = mRootGroups;
mRootGroups = object;
String qualifiedName = FMODEventPathToTorqueName( object->getQualifiedName() );
if( !isClientOnly() )
object->assignId();
object->registerObject( String::ToString( "%s_%s", getName(), qualifiedName.c_str() ) );
if( isClientOnly() )
Sim::getRootGroup()->addObject( object );
object->_load();
}
}
// Create the event script file.
FileStream stream;
if( !stream.open( eventScriptFileName.getFullPath(), Torque::FS::File::Write ) )
{
Con::errorf( "SFXFMODProject::_load - could not create event script file for '%s'", mFileName.c_str() );
return true; // Don't treat as failure.
}
// Write a header.
stream.writeText( String::ToString( "// This file has been auto-generated from '%s'\n", mFileName.c_str() ) );
stream.writeText( "// Do not edit this file manually and do not move it away from the Designer file.\n\n" );
// Write the group objects.
for( U32 i = 0; i < mGroups.size(); ++ i )
{
mGroups[ i ]->write( stream, 0 );
stream.writeText( "\n" );
}
// Write the event objects along with their
// SFXDescriptions.
for( U32 i = 0; i < mEvents.size(); ++ i )
{
mEvents[ i ]->getDescription()->write( stream, 0 );
mEvents[ i ]->write( stream, 0 );
stream.writeText( "\n" );
}
Con::printf( "SFXFMODProject - %s: Generated event script '%s'", getName(), eventScriptFileName.getFullPath().c_str() );
}
return true;
}
//-----------------------------------------------------------------------------
void SFXFMODProject::acquire( bool recursive )
{
// Load the project file.
if( !mHandle )
{
FMOD_RESULT result = SFXFMODDevice::smFunc->FMOD_EventSystem_Load(
SFXFMODDevice::smEventSystem,
mFileName.c_str(),
( FMOD_EVENT_LOADINFO* ) 0,
&mHandle
);
if( result != FMOD_OK )
{
Con::errorf( "SFXFMODProject::acquire - could not load '%s' (%s)",
mFileName.c_str(), FMODResultToString( result ).c_str() );
mHandle = NULL;
return;
}
Con::printf( "SFXFMODProject - %s: Opened project '%s'", getName(), mFileName.c_str() );
// Set the media path.
String mediaPath;
if( !mMediaPath.isEmpty() )
{
mediaPath = mMediaPath;
if( mediaPath[ mediaPath.length() - 1 ] != '/' )
mediaPath += '/';
}
else
{
// Set to project directory.
Torque::Path path = mFileName;
if( path.getRoot().isEmpty() )
path.setRoot( "game" );
path.setFileName( "" );
path.setExtension( "" );
mediaPath = path.getFullPath() + '/';
}
SFXFMODDevice::smFunc->FMOD_EventSystem_SetMediaPath(
SFXFMODDevice::smEventSystem,
mediaPath.c_str()
);
}
// Acquire the root groups.
if( recursive )
for( SFXFMODEventGroup* group = mRootGroups; group != NULL; group = group->mSibling )
group->acquire( true );
SFXFMODDevice::instance()->updateMemUsageStats();
}
//-----------------------------------------------------------------------------
void SFXFMODProject::release()
{
if( !mHandle )
return;
Con::printf( "SFXFMODProject - %s: Closing project '%s'",
getName(), mFileName.c_str() );
// Clear media path.
SFXFMODDevice::smFunc->FMOD_EventSystem_SetMediaPath(
SFXFMODDevice::smEventSystem, "" );
// Release the root groups.
for( SFXFMODEventGroup* group = mRootGroups; group != NULL; group = group->mSibling )
group->release();
// Release the project.
SFXFMODDevice::smFunc->FMOD_EventProject_Release( mHandle );
mHandle = NULL;
SFXFMODDevice::instance()->updateMemUsageStats();
}
//-----------------------------------------------------------------------------
void SFXFMODProject::_addEvent( SFXFMODEvent* event )
{
mEvents.push_back( event );
}
//-----------------------------------------------------------------------------
void SFXFMODProject::_addGroup( SFXFMODEventGroup* group )
{
mGroups.push_back( group );
}
//-----------------------------------------------------------------------------
void SFXFMODProject::_removeEvent( SFXFMODEvent* event )
{
for( U32 i = 0; i < mEvents.size(); ++ i )
if( mEvents[ i ] == event )
{
mEvents.erase( i );
break;
}
}
//-----------------------------------------------------------------------------
void SFXFMODProject::_removeGroup( SFXFMODEventGroup* group )
{
// Remove from group array.
for( U32 i = 0; i < mGroups.size(); ++ i )
if( mGroups[ i ] == group )
{
mGroups.erase( i );
break;;
}
// Unlink if it's a root group.
if( !group->mParent )
{
if( group == mRootGroups )
{
mRootGroups = group->mSibling;
group->mSibling = NULL;
}
else
{
SFXFMODEventGroup* p = mRootGroups;
while( p && p->mSibling != group )
p = p->mSibling;
if( p )
{
p->mSibling = group->mSibling;
group->mSibling = NULL;
}
}
}
}

View file

@ -1,162 +0,0 @@
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#ifndef _SFXFMODPROJECT_H_
#define _SFXFMODPROJECT_H_
#ifndef _SIMDATABLOCK_H_
#include "console/simDatablock.h"
#endif
#ifndef _CONSOLETYPES_H_
#include "console/consoleTypes.h"
#endif
#ifndef _TVECTOR_H_
#include "core/util/tVector.h"
#endif
#ifndef _SFXSYSTEM_H_
#include "sfx/sfxSystem.h"
#endif
#include "fmod_event.h"
class SFXFMODEvent;
class SFXFMODEventGroup;
class SimGroup;
/// Datablock that loads an FMOD Designer project.
///
/// All events in the project are automatically made available as SFXFMODEvent track
/// datablock instances. Each event object is automatically named by substituting
/// the slashes in its fully qualified name with underscores and preprending the project
/// name to this; event 'group1/group2/event' in the SFXFMODProject instance called
/// 'project', for example, will be available as a TorqueScript object called
/// 'project_group1_group2_event'.
///
/// This class also works in a client-server environment where the server is
/// not running FMOD. The event objects are cached in an auto-generated TorqueScript
/// file alongside the .fev project file (x/y.fev -> x/y.fev.cs) which, when available
/// and up-to-date, does not require FMOD for the server-side objects to correctly
/// initialize.
///
/// To establish good loading behavior and for good memory management, it is necessary to
/// wisely distribute events to groups and to manually pre-load groups. The best solution
/// probably is to have one group of common events that is loaded during game startup and
/// then have one event group for each level in the game that is only loaded for the
/// duration of its particular level.
///
/// SFXFMODProject will propagate it's networking model to all its contents. This means
/// that if the project is a non-networked datablock, then all event groups, events, and
/// descriptions contained in the project will also be non-networked datablocks.
///
/// It usually makes the most sense to use non-networked ("client-only") datablocks as
/// otherwise the FMOD datablocks will be purged on each mission load.
///
/// @note Only one project's music data can ever be loaded at any one time.
/// Usually you wouldn't want more than a single SFXFMODProject instance in your game
/// data. Also, only a single media path can be set through the designer API so when
/// loading multiple projects, note that each project will set the media path to its
/// own directory. For data loading to work, all project thus need to be placed in
/// the same directory.
///
class SFXFMODProject : public SimDataBlock
{
public:
typedef SimDataBlock Parent;
friend class SFXFMODEventGroup; // _addGroup
friend class SFXFMODEvent; // _addEvent
protected:
///
String mFileName;
///
String mMediaPath;
///
SFXFMODEventGroup* mRootGroups;
/// A flat list of all the groups in this projet.
Vector< SFXFMODEventGroup* > mGroups;
/// A flat list of all the events in the project.
Vector< SFXFMODEvent* > mEvents;
///
FMOD_EVENTPROJECT* mHandle;
///
void _onSystemEvent( SFXSystemEventType event );
///
void _clear();
///
bool _load();
///
void _addEvent( SFXFMODEvent* event );
///
void _addGroup( SFXFMODEventGroup* group );
///
void _removeEvent( SFXFMODEvent* event );
///
void _removeGroup( SFXFMODEventGroup* group );
public:
///
SFXFMODProject();
virtual ~SFXFMODProject();
///
void acquire( bool recursive = false );
///
void release();
///
const String& getFileName() const { return mFileName; }
// SimDataBlock.
virtual bool onAdd();
virtual void onRemove();
virtual bool preload( bool server, String& errorStr );
virtual void packData( BitStream* stream );
virtual void unpackData( BitStream* stream );
static void initPersistFields();
DECLARE_CONOBJECT( SFXFMODProject );
DECLARE_CATEGORY( "SFX FMOD" );
DECLARE_DESCRIPTION( "An FMOD Designer project." );
};
#endif // !_SFXFMODPROJECT_H_

View file

@ -1,398 +0,0 @@
//-----------------------------------------------------------------------------
// 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 "sfx/sfxProvider.h"
#include "sfx/fmod/sfxFMODDevice.h"
#include "core/util/safeRelease.h"
#include "console/console.h"
#include "core/util/safeDelete.h"
#include "core/module.h"
#include "console/consoleTypes.h"
class SFXFMODProvider : public SFXProvider
{
public:
SFXFMODProvider()
: SFXProvider( "FMOD" )
{
Con::addVariable( "$SFX::Device::fmodNumEventSources", TypeS32, &SFXFMODDevice::smStatNumEventSources,
"The current number of SFXFMODEventSource instances in the system.\n"
"This tells the number of sounds in the system that are currently playing FMOD Designer events.\n\n"
"@note Only relevant if an %FMOD sound device is used.\n\n"
"@ingroup SFXFMOD" );
Con::addVariable( "$SFX::Device::fmodCoreMem", TypeS32, &SFXFMODDevice::smStatMemUsageCore,
"Current number of bytes allocated by the core %FMOD sound system.\n\n"
"@note Only relevant if an %FMOD sound device is used.\n\n"
"@ingroup SFXFMOD" );
Con::addVariable( "$SFX::Device::fmodEventMem", TypeS32, &SFXFMODDevice::smStatMemUsageEvents,
"Current number of bytes allocated by the %FMOD Designer event system.\n\n"
"@note Only relevant if an %FMOD sound device is used and the FMOD event DLL is loaded.\n\n"
"@ingroup SFXFMOD" );
Con::addVariable( "$pref::SFX::FMOD::disableSoftware", TypeBool, &SFXFMODDevice::smPrefDisableSoftware,
"Whether to disable the %FMOD software mixer to conserve memory.\n"
"All sounds not created with SFXDescription::useHardware or using DSP effects will fail to load.\n\n"
"@note Only applies when using an %FMOD sound device.\n\n"
"@ingroup SFXFMOD" );
Con::addVariable( "$pref::SFX::FMOD::useSoftwareHRTF", TypeBool, &SFXFMODDevice::smPrefUseSoftwareHRTF,
"Whether to enable HRTF in %FMOD's software mixer.\n"
"This will add a lowpass filter effect to the DSP effect chain of all sounds mixed in software.\n\n"
"@note Only applies when using an %FMOD sound device.\n\n"
"@ingroup SFXFMOD" );
Con::addVariable( "$pref::SFX::FMOD::enableProfile", TypeBool, &SFXFMODDevice::smPrefEnableProfile,
"Whether to enable support for %FMOD's profiler.\n\n"
"@note Only applies when using an %FMOD sound device.\n\n"
"@ref FMOD_profiler\n\n"
"@ingroup SFXFMOD" );
Con::addVariable( "$pref::SFX::FMOD::DSoundHRTF", TypeString, &SFXFMODDevice::smPrefDSoundHRTF,
"The type of HRTF to use for hardware-mixed 3D sounds when %FMOD is using DirectSound for sound output "
"and hardware-acceleration is not available.\n\n"
"Options are\n"
"- \"none\": simple stereo panning/doppler/attenuation\n"
"- \"light\": slightly higher quality than \"none\"\n"
"- \"full\": full quality 3D playback\n\n"
"@note Only applies when using an %FMOD sound device.\n\n"
"@ingroup SFXFMOD" );
Con::addVariable( "$pref::SFX::FMOD::pluginPath", TypeString, &SFXFMODDevice::smPrefPluginPath,
"%Path to additional %FMOD plugins.\n\n"
"@note Only applies when using an %FMOD sound device.\n\n"
"@ingroup SFXFMOD" );
}
virtual ~SFXFMODProvider();
protected:
FModFNTable mFMod;
struct FModDeviceInfo : SFXDeviceInfo
{
FMOD_CAPS mCaps;
FMOD_SPEAKERMODE mSpeakerMode;
};
void init();
bool _createSystem();
public:
SFXDevice* createDevice( const String& deviceName, bool useHardware, S32 maxBuffers );
};
MODULE_BEGIN( FMOD )
MODULE_INIT_BEFORE( SFX )
MODULE_SHUTDOWN_AFTER( SFX )
SFXFMODProvider* mProvider;
MODULE_INIT
{
mProvider = new SFXFMODProvider;
}
MODULE_SHUTDOWN
{
delete mProvider;
}
MODULE_END;
//------------------------------------------------------------------------------
// Helper
bool fmodBindFunction( DLibrary *dll, void *&fnAddress, const char* name )
{
if( !dll )
return false;
fnAddress = dll->bind( name );
if (!fnAddress)
Con::warnf( "FMOD Loader: DLL bind failed for %s", name );
return fnAddress != 0;
}
//------------------------------------------------------------------------------
void SFXFMODProvider::init()
{
#ifdef TORQUE_FMOD_STATIC
// FMOD statically linked.
mFMod.isLoaded = true;
#define FMOD_FUNCTION(fn_name, fn_args) \
(*(void**)&mFMod.fn_name.fn) = &fn_name;
#ifndef TORQUE_FMOD_NO_EVENTS
mFMod.eventIsLoaded = true;
#define FMOD_EVENT_FUNCTION(fn_name, fn_args) \
(*(void**)&mFMod.fn_name.fn) = &fn_name;
#else
#define FMOD_EVENT_FUNCTION( fn_name, fn_args )
#endif
#include FMOD_FN_FILE
#undef FMOD_FUNCTION
#undef FMOD_EVENT_FUNCTION
#else
// FMOD dynamically linked.
const char* dllName;
const char* pDllName; // plugin-based DLL
const char* eventDllName;
#ifdef _WIN64
dllName = "fmodex64.dll";
pDllName = "fmodexp64.dll";
eventDllName = "fmod_event64.dll";
#elif defined(TORQUE_OS_WIN)
dllName = "fmodex.dll";
pDllName = "fmodexp.dll";
eventDllName = "fmod_event.dll";
#elif defined( TORQUE_OS_MAC )
dllName = "libfmodex.dylib";
pDllName = "libfmodexp.dylib";
eventDllName = "libfmodevent.dylib";
#else
# warning Need to set FMOD DLL filename for platform.
return;
#endif
// Grab the functions we'll want from the fmod DLL.
mFMod.dllRef = OsLoadLibrary( dllName );
// Try the plugin-based version.
if( !mFMod.dllRef )
mFMod.dllRef = OsLoadLibrary( pDllName );
if(!mFMod.dllRef)
{
Con::warnf( "SFXFMODProvider - Could not locate '%s' or '%s' - FMOD not available.", dllName, pDllName );
return;
}
mFMod.eventDllRef = OsLoadLibrary( eventDllName );
if(!mFMod.eventDllRef)
Con::warnf( "SFXFMODProvider - Could not locate %s - FMOD Designer integration not available.", eventDllName );
mFMod.isLoaded = true;
mFMod.eventIsLoaded = true;
#define FMOD_FUNCTION(fn_name, fn_args) \
mFMod.isLoaded &= fmodBindFunction(mFMod.dllRef, *(void**)&mFMod.fn_name.fn, #fn_name);
#define FMOD_EVENT_FUNCTION(fn_name, fn_args) \
mFMod.eventIsLoaded &= fmodBindFunction(mFMod.eventDllRef, *(void**)&mFMod.fn_name.fn, #fn_name);
#include FMOD_FN_FILE
#undef FMOD_FUNCTION
#undef FMOD_EVENT_FUNCTION
if(mFMod.isLoaded == false)
{
Con::warnf("SFXFMODProvider - Could not load %s - FMOD not available.", dllName);
return;
}
if( !mFMod.eventIsLoaded && mFMod.eventDllRef )
Con::warnf("SFXFMODProvider - Could not load %s - FMOD Designer integration not available.", eventDllName);
#endif
FMOD_RESULT res;
// Create the FMOD system object.
if( !_createSystem() )
return;
// Check that the Ex API version is OK.
unsigned int version;
res = mFMod.FMOD_System_GetVersion(SFXFMODDevice::smSystem, &version);
FModAssert(res, "SFXFMODProvider - Failed to get FMOD version!");
Con::printf( "SFXFMODProvider - FMOD Ex API version: %x.%x.%x",
( version & 0xffff0000 ) >> 16,
( version & 0x0000ff00 ) >> 8,
( version & 0x000000ff )
);
if(version < FMOD_VERSION)
{
Con::warnf("SFXFMODProvider - FMOD Ex API version in DLL is too old - FMOD not available.");
return;
}
// Check that the Designer API version is ok.
if( mFMod.eventIsLoaded )
{
res = mFMod.FMOD_EventSystem_GetVersion( SFXFMODDevice::smEventSystem, &version );
FModAssert(res, "SFXFMODProvider - Failed to get FMOD version!");
Con::printf( "SFXFMODProvider - FMOD Designer API version: %x.%x.%x",
( version & 0xffff0000 ) >> 16,
( version & 0x0000ff00 ) >> 8,
( version & 0x000000ff )
);
if( version < FMOD_EVENT_VERSION )
{
Con::errorf( "SFXFMODProvider - FMOD Designer API version in DLL is too old!" );
return;
}
}
// Now, enumerate our devices.
int numDrivers;
res = mFMod.FMOD_System_GetNumDrivers(SFXFMODDevice::smSystem, &numDrivers);
FModAssert(res, "SFXFMODProvider - Failed to get driver count - FMOD not available.");
char nameBuff[256];
for(S32 i=0; i<numDrivers; i++)
{
res = mFMod.FMOD_System_GetDriverInfo(SFXFMODDevice::smSystem, i, nameBuff, 256, ( FMOD_GUID* ) NULL);
if( res != FMOD_OK )
{
Con::errorf( "SFXFMODProvider - Failed to get driver name (%s)", FMODResultToString( res ).c_str() );
continue;
}
nameBuff[ 255 ] = '\0';
FMOD_CAPS caps;
FMOD_SPEAKERMODE speakerMode;
res = mFMod.FMOD_System_GetDriverCaps( SFXFMODDevice::smSystem, i, &caps, ( int* ) 0, &speakerMode );
if( res != FMOD_OK )
{
Con::errorf( "SFXFMODProvider - Failed to get driver caps (%s)", FMODResultToString( res ).c_str() );
continue;
}
// Great - got something - so add it to the list of options.
FModDeviceInfo *fmodInfo = new FModDeviceInfo();
fmodInfo->name = String( nameBuff );
fmodInfo->hasHardware = caps & FMOD_CAPS_HARDWARE;
fmodInfo->maxBuffers = 32;
fmodInfo->driver = String();
fmodInfo->mCaps = caps;
fmodInfo->mSpeakerMode = speakerMode;
mDeviceInfo.push_back(fmodInfo);
}
// Did we get any devices?
if ( mDeviceInfo.empty() )
{
Con::warnf( "SFXFMODProvider - No valid devices found - FMOD not available." );
return;
}
// TODO: FMOD_Memory_Initialize
#ifdef TORQUE_OS_XENON
const dsize_t memSz = 5 * 1024 * 1024;
void *memBuffer = XPhysicalAlloc( memSz, MAXULONG_PTR, 0, PAGE_READWRITE );
mFMod.FMOD_Memory_Initialize( memBuffer, memSz, FMOD_MEMORY_ALLOCCALLBACK(NULL), FMOD_MEMORY_REALLOCCALLBACK(NULL), FMOD_MEMORY_FREECALLBACK(NULL) );
#endif
// Wow, we made it - register the provider.
regProvider( this );
}
SFXFMODProvider::~SFXFMODProvider()
{
if( SFXFMODDevice::smEventSystem )
{
mFMod.FMOD_EventSystem_Release( SFXFMODDevice::smEventSystem );
SFXFMODDevice::smEventSystem = NULL;
SFXFMODDevice::smSystem = NULL;
}
else if( SFXFMODDevice::smSystem )
{
mFMod.FMOD_System_Release( SFXFMODDevice::smSystem );
SFXFMODDevice::smSystem = NULL;
}
}
SFXDevice* SFXFMODProvider::createDevice( const String& deviceName, bool useHardware, S32 maxBuffers )
{
FModDeviceInfo* info = dynamic_cast< FModDeviceInfo* >
( _findDeviceInfo( deviceName ) );
if( !info )
return NULL;
if( !SFXFMODDevice::smSystem && !_createSystem() )
return false;
SFXFMODDevice* device = new SFXFMODDevice(this, &mFMod, 0, info->name );
if( !device->_init() )
SAFE_DELETE( device );
return device;
}
bool SFXFMODProvider::_createSystem()
{
AssertFatal( !SFXFMODDevice::smEventSystem, "SFXFMODProvider::_createSystem() - event system already created!" );
AssertFatal( !SFXFMODDevice::smSystem, "SFXFMODProvider::_createSystem() - system already created!" );
if( mFMod.eventIsLoaded )
{
FMOD_RESULT res = mFMod.FMOD_EventSystem_Create( &SFXFMODDevice::smEventSystem );
if( res != FMOD_OK )
{
Con::errorf( "SFXFMODProvider - could not create the FMOD event system." );
return false;
}
res = mFMod.FMOD_EventSystem_GetSystemObject( SFXFMODDevice::smEventSystem, &SFXFMODDevice::smSystem );
if( res != FMOD_OK )
{
Con::errorf( "SFXFMODProvider - could not retrieve the FMOD system object." );
return false;
}
}
else
{
// Allocate the FMod system.
FMOD_RESULT res = mFMod.FMOD_System_Create( &SFXFMODDevice::smSystem );
if( res != FMOD_OK )
{
// Failed - deal with it!
Con::errorf("SFXFMODProvider - could not create the FMOD system.");
return false;
}
}
return true;
}

View file

@ -1,303 +0,0 @@
//-----------------------------------------------------------------------------
// 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 "sfx/fmod/sfxFMODVoice.h"
#include "sfx/fmod/sfxFMODBuffer.h"
#include "sfx/fmod/sfxFMODDevice.h"
#include "core/tAlgorithm.h"
SFXFMODVoice* SFXFMODVoice::create( SFXFMODDevice *device,
SFXFMODBuffer *buffer )
{
AssertFatal( device, "SFXFMODVoice::create() - Got null device!" );
AssertFatal( buffer, "SFXFMODVoice::create() - Got null buffer!" );
return new SFXFMODVoice( device, buffer );
}
SFXFMODVoice::SFXFMODVoice( SFXFMODDevice *device,
SFXFMODBuffer *buffer )
: Parent( buffer ),
mDevice( device ),
mChannel( NULL )
{
AssertFatal( device, "SFXFMODVoice::SFXFMODVoice() - No device assigned!" );
AssertFatal( buffer, "SFXFMODVoice::SFXFMODVoice() - No buffer assigned!" );
AssertFatal( _getBuffer()->mSound != NULL, "SFXFMODVoice::SFXFMODVoice() - No sound assigned!" );
}
SFXFMODVoice::~SFXFMODVoice()
{
_stop();
}
SFXStatus SFXFMODVoice::_status() const
{
if( mChannel )
{
FMOD_BOOL isTrue = false;
SFXFMODDevice::smFunc->FMOD_Channel_GetPaused( mChannel, &isTrue );
if ( isTrue )
return SFXStatusPaused;
SFXFMODDevice::smFunc->FMOD_Channel_IsPlaying( mChannel, &isTrue );
if ( isTrue )
return SFXStatusPlaying;
}
SFXFMODDevice::smFunc->FMOD_Channel_Stop( mChannel );
mChannel = NULL;
return SFXStatusStopped;
}
void SFXFMODVoice::_play()
{
if( !mChannel )
_assignChannel();
SFXFMODDevice::smFunc->FMOD_Channel_SetPaused( mChannel, false );
}
void SFXFMODVoice::_pause()
{
if( mChannel )
SFXFMODDevice::smFunc->FMOD_Channel_SetPaused( mChannel, true );
}
void SFXFMODVoice::_stop()
{
if( mChannel )
SFXFMODDevice::smFunc->FMOD_Channel_Stop(mChannel);
mChannel = NULL;
}
void SFXFMODVoice::_seek( U32 sample )
{
if( !mChannel )
_assignChannel();
SFXFMODDevice::smFunc->FMOD_Channel_SetPosition
( mChannel, sample, FMOD_TIMEUNIT_PCM );
}
bool SFXFMODVoice::_assignChannel()
{
AssertFatal( _getBuffer()->mSound != NULL, "SFXFMODVoice::_assignChannel() - No sound assigned!" );
// we start playing it now in the paused state, so that we can immediately set attributes that
// depend on having a channel (position, volume, etc). According to the FMod docs
// it is ok to do this.
bool success = SFXFMODDevice::smFunc->FMOD_System_PlaySound(
SFXFMODDevice::smSystem,
FMOD_CHANNEL_FREE,
_getBuffer()->mSound,
true,
&mChannel ) == FMOD_OK;
if( success )
{
SFXFMODDevice::smFunc->FMOD_Channel_SetMode( mChannel, mMode );
SFXFMODDevice::smFunc->FMOD_Channel_SetLoopCount( mChannel, mMode & FMOD_LOOP_NORMAL ? -1 : 0 );
if( mSetFlags.test( SET_Velocity ) )
SFXFMODDevice::smFunc->FMOD_Channel_Set3DAttributes( mChannel, ( const FMOD_VECTOR* ) NULL, &mVelocity );
if( mSetFlags.test( SET_MinMaxDistance ) )
SFXFMODDevice::smFunc->FMOD_Channel_Set3DMinMaxDistance(mChannel, mMinDistance, mMaxDistance);
if( mSetFlags.test( SET_Transform ) )
{
SFXFMODDevice::smFunc->FMOD_Channel_Set3DAttributes( mChannel, &mPosition, ( const FMOD_VECTOR* ) NULL );
SFXFMODDevice::smFunc->FMOD_Channel_Set3DConeOrientation( mChannel, &mDirection );
}
if( mSetFlags.test( SET_Volume ) )
SFXFMODDevice::smFunc->FMOD_Channel_SetVolume(mChannel, mVolume);
if( mSetFlags.test( SET_Pitch ) )
SFXFMODDevice::smFunc->FMOD_Channel_SetFrequency( mChannel, mFrequency );
if( mSetFlags.test( SET_Cone ) )
SFXFMODDevice::smFunc->FMOD_Channel_Set3DConeSettings(
mChannel,
mConeInnerAngle,
mConeOuterAngle,
mConeOuterVolume );
if( mSetFlags.test( SET_Priority ) )
SFXFMODDevice::smFunc->FMOD_Channel_SetPriority( mChannel, TorquePriorityToFMODPriority( mPriority ) );
if( mSetFlags.test( SET_Reverb ) )
SFXFMODDevice::smFunc->FMOD_Channel_SetReverbProperties( mChannel, &mReverb );
}
return success;
}
U32 SFXFMODVoice::_tell() const
{
if( !mChannel )
return 0;
U32 pos;
SFXFMODDevice::smFunc->FMOD_Channel_GetPosition( mChannel, &pos, ( FMOD_TIMEUNIT ) FMOD_TIMEUNIT_PCMBYTES );
return _getBuffer()->getSamplePos( pos );
}
void SFXFMODVoice::setMinMaxDistance( F32 min, F32 max )
{
if ( !( _getBuffer()->mMode & FMOD_3D ) )
return;
mMinDistance = min;
mMaxDistance = max;
mSetFlags.set( SET_MinMaxDistance );
if( mChannel )
SFXFMODDevice::smFunc->FMOD_Channel_Set3DMinMaxDistance(mChannel, mMinDistance, mMaxDistance);
}
void SFXFMODVoice::play( bool looping )
{
if( mBuffer->isStreaming() )
looping = true;
mMode = mDevice->get3dRollOffMode();
mMode |= (looping ? FMOD_LOOP_NORMAL : FMOD_LOOP_OFF);
Parent::play( looping );
}
void SFXFMODVoice::setVelocity( const VectorF& velocity )
{
if( !( _getBuffer()->mMode & FMOD_3D ) )
return;
// Note we have to do a handedness swap; see the
// listener update code in SFXFMODDevice for details.
mVelocity.x = velocity.x;
mVelocity.y = velocity.z;
mVelocity.z = velocity.y;
mSetFlags.set( SET_Velocity );
if( mChannel )
SFXFMODDevice::smFunc->FMOD_Channel_Set3DAttributes( mChannel, ( const FMOD_VECTOR* ) NULL, &mVelocity );
}
void SFXFMODVoice::setTransform( const MatrixF& transform )
{
if ( !( _getBuffer()->mMode & FMOD_3D ) )
return;
transform.getColumn( 3, (Point3F*)&mPosition );
transform.getColumn( 1, (Point3F*)&mDirection );
// Note we have to do a handedness swap; see the
// listener update code in SFXFMODDevice for details.
swap( mPosition.y, mPosition.z );
swap( mDirection.y, mDirection.z );
mSetFlags.set( SET_Transform );
if( mChannel )
{
// This can fail safe, so don't assert if it fails.
SFXFMODDevice::smFunc->FMOD_Channel_Set3DAttributes( mChannel, &mPosition, ( const FMOD_VECTOR* ) NULL );
SFXFMODDevice::smFunc->FMOD_Channel_Set3DConeOrientation( mChannel, &mDirection );
}
}
void SFXFMODVoice::setVolume( F32 volume )
{
mVolume = volume;
mSetFlags.set( SET_Volume );
if( mChannel )
SFXFMODDevice::smFunc->FMOD_Channel_SetVolume( mChannel, volume );
}
void SFXFMODVoice::setPriority( F32 priority )
{
mPriority = priority;
mSetFlags.set( SET_Priority );
if( mChannel )
SFXFMODDevice::smFunc->FMOD_Channel_SetPriority( mChannel, TorquePriorityToFMODPriority( priority ) );
}
void SFXFMODVoice::setPitch( F32 pitch )
{
// if we do not know the frequency, we cannot change the pitch
F32 frequency = _getBuffer()->getFormat().getSamplesPerSecond();
if ( frequency == 0 )
return;
mFrequency = frequency * pitch;
mSetFlags.set( SET_Pitch );
// Scale the original frequency by the pitch factor.
if( mChannel )
SFXFMODDevice::smFunc->FMOD_Channel_SetFrequency(mChannel, mFrequency);
}
void SFXFMODVoice::setCone( F32 innerAngle, F32 outerAngle, F32 outerVolume )
{
mConeInnerAngle = innerAngle;
mConeOuterAngle = outerAngle;
mConeOuterVolume = outerVolume;
mSetFlags.set( SET_Cone );
if( mChannel )
SFXFMODDevice::smFunc->FMOD_Channel_Set3DConeSettings(
mChannel,
mConeInnerAngle,
mConeOuterAngle,
mConeOuterVolume );
}
void SFXFMODVoice::setReverb( const SFXSoundReverbProperties& reverb )
{
dMemset( &mReverb, 0, sizeof( mReverb ) );
mReverb.Direct = reverb.mDirect;
mReverb.Room = reverb.mRoom;
mReverb.Flags = reverb.mFlags;
mSetFlags.set( SET_Reverb );
if( mChannel )
SFXFMODDevice::smFunc->FMOD_Channel_SetReverbProperties( mChannel, &mReverb );
}
bool SFXFMODVoice::isVirtual() const
{
if( mChannel )
{
FMOD_BOOL result;
SFXFMODDevice::smFunc->FMOD_Channel_IsVirtual( mChannel, &result );
return result;
}
else
return false;
}

View file

@ -1,121 +0,0 @@
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#ifndef _SFXFMODVOICE_H_
#define _SFXFMODVOICE_H_
#ifndef _SFXDEVICE_H_
#include "sfx/sfxDevice.h"
#endif
#ifndef _SFXVOICE_H_
#include "sfx/sfxVoice.h"
#endif
#ifndef _BITSET_H_
#include "core/bitSet.h"
#endif
#include "fmod.h"
class SFXSource;
class SFXFMODBuffer;
class SFXFMODDevice;
class SFXFMODVoice : public SFXVoice
{
typedef SFXVoice Parent;
friend class SFXFMODBuffer;
protected:
SFXFMODDevice *mDevice;
mutable FMOD_CHANNEL *mChannel;
enum ESettings
{
SET_MinMaxDistance = BIT( 0 ),
SET_Velocity = BIT( 1 ),
SET_Transform = BIT( 2 ),
SET_Volume = BIT( 3 ),
SET_Pitch = BIT( 4 ),
SET_Cone = BIT( 5 ),
SET_Priority = BIT( 6 ),
SET_Reverb = BIT( 7 ),
};
BitSet32 mSetFlags;
FMOD_MODE mMode;
F32 mMinDistance;
F32 mMaxDistance;
F32 mVolume;
F32 mPriority;
F32 mFrequency;
F32 mConeInnerAngle;
F32 mConeOuterAngle;
F32 mConeOuterVolume;
FMOD_VECTOR mVelocity;
FMOD_VECTOR mPosition;
FMOD_VECTOR mDirection;
FMOD_REVERB_CHANNELPROPERTIES mReverb;
///
SFXFMODVoice( SFXFMODDevice *device,
SFXFMODBuffer *buffer );
// prep for playback
bool _assignChannel();
SFXFMODBuffer* _getBuffer() const { return ( SFXFMODBuffer* ) mBuffer.getPointer(); }
// SFXVoice.
virtual SFXStatus _status() const;
virtual void _play();
virtual void _pause();
virtual void _stop();
virtual void _seek( U32 sample );
virtual U32 _tell() const;
public:
///
static SFXFMODVoice* create( SFXFMODDevice *device,
SFXFMODBuffer *buffer );
///
virtual ~SFXFMODVoice();
/// SFXVoice
void setMinMaxDistance( F32 min, F32 max );
void play( bool looping );
void setVelocity( const VectorF& velocity );
void setTransform( const MatrixF& transform );
void setVolume( F32 volume );
void setPriority( F32 priority );
void setPitch( F32 pitch );
void setCone( F32 innerAngle, F32 outerAngle, F32 outerVolume );
void setReverb( const SFXSoundReverbProperties& reverb );
bool isVirtual() const;
};
#endif // _SFXFMODBUFFER_H_

View file

@ -247,7 +247,6 @@ void SFXDescription::initPersistFields()
"If true, the sound system will try to allocate the voice for the sound directly "
"on the sound hardware for mixing by the hardware mixer. Be aware that a hardware mixer "
"may not provide all features available to sounds mixed in software.\n\n"
"@note This flag currently only takes effect when using FMOD.\n\n"
"@note Generally, it is preferable to let sounds be mixed in software.\n\n" );
addField( "parameters", TypeSFXParameterName, Offset( mParameters, SFXDescription ), MaxNumParameters,
"Names of the parameters to which sources using this description will automatically be linked.\n\n"
@ -355,7 +354,7 @@ void SFXDescription::initPersistFields()
"@ref SFXSource_cones" );
addField( "rolloffFactor", TypeF32, Offset( mRolloffFactor, SFXDescription ),
"Scale factor to apply to logarithmic distance attenuation curve. If -1, the global rolloff setting is used.\n\n"
"@note Per-sound rolloff is only supported on OpenAL and FMOD at the moment. With other divices, the global rolloff setting "
"@note Per-sound rolloff is only supported on OpenAL at the moment. With other divices, the global rolloff setting "
"is used for all sounds.\n"
"@see LevelInfo::soundDistanceModel" );
@ -373,7 +372,6 @@ void SFXDescription::initPersistFields()
"of sample data determined by this field. The greater its value, the more sample data each "
"packet contains, the more work is done per packet.\n\n"
"@note This field only takes effect when Torque's own sound system performs the streaming. "
"When FMOD is used, this field is ignored and streaming is performed by FMOD.\n\n"
"@ref SFX_streaming" );
addField( "streamReadAhead", TypeS32, Offset( mStreamReadAhead, SFXDescription ),
"Number of sample packets to read and buffer in advance.\n"
@ -382,7 +380,6 @@ void SFXDescription::initPersistFields()
"device before the playback queue is running dry. Greater values thus allow for more lag "
"in the streaming pipeline.\n\n"
"@note This field only takes effect when Torque's own sound system performs the streaming. "
"When FMOD is used, this field is ignored and streaming is performed by FMOD.\n\n"
"@ref SFX_streaming" );
endGroup( "Streaming" );

View file

@ -63,7 +63,6 @@ class SFXDevice
CAPS_Occlusion = BIT( 2 ), ///< Device has its own sound occlusion handling (SFXOcclusionManager).
CAPS_DSPEffects = BIT( 3 ), ///< Device implements DSP effects (SFXDSPManager).
CAPS_MultiListener = BIT( 4 ), ///< Device supports multiple listeners.
CAPS_FMODDesigner = BIT( 5 ), ///< FMOD Designer support.
};
protected:

View file

@ -49,7 +49,7 @@ ConsoleDocClass( SFXProfile,
"for it to be created. However, several of the SFX functions (sfxPlayOnce(), sfxCreateSource()) perform "
"this creation internally for convenience using temporary profile objects.\n\n"
"Sound files can be in either OGG or WAV format. However, extended format support is available when using FMOD. "
"Sound files can be in either OGG or WAV format. "
"See @ref SFX_formats.\n\n"
"@section SFXProfile_loading Profile Loading\n\n"

View file

@ -158,8 +158,6 @@ ImplementEnumType( SFXChannel,
"- 3: Pause\n\n" },
{ SFXChannelUser0, "User0",
"Channel available for custom use. By default ignored by sources.\n\n"
"@note For FMOD Designer event sources (SFXFMODEventSource), this channel is used for event parameters "
"defined in FMOD Designer and should not be used otherwise.\n\n"
"@see SFXSource::onParameterValueChange" },
{ SFXChannelUser1, "User1",
"Channel available for custom use. By default ignored by sources.\n\n"
@ -179,7 +177,6 @@ static const U32 sDeviceCapsVoiceManagement = SFXDevice::CAPS_VoiceManagement;
static const U32 sDeviceCapsOcclusion = SFXDevice::CAPS_Occlusion;
static const U32 sDeviceCapsDSPEffects = SFXDevice::CAPS_DSPEffects;
static const U32 sDeviceCapsMultiListener = SFXDevice::CAPS_MultiListener;
static const U32 sDeviceCapsFMODDesigner = SFXDevice::CAPS_FMODDesigner;
static const U32 sDeviceInfoProvider = 0;
static const U32 sDeviceInfoName = 1;
@ -253,7 +250,6 @@ SFXSystem::SFXSystem()
Con::addConstant( "$SFX::DEVICE_CAPS_REVERB", TypeS32, &sDeviceCapsReverb,
"Sound device capability flag indicating that the sound device supports reverb.\n\n"
"@note Currently only FMOD implements this.\n\n"
"@see sfxGetDeviceInfo\n\n"
"@ref SFX_reverb\n\n"
"@ingroup SFX" );
@ -261,7 +257,6 @@ SFXSystem::SFXSystem()
"Sound device capability flag indicating that the sound device implements its own voice virtualization.\n\n"
"For these devices, the sound system will deactivate its own voice management and leave voice "
"virtualization entirely to the device.\n\n"
"@note Currently only FMOD implements this.\n\n"
"@see sfxGetDeviceInfo\n\n"
"@ref SFXSound_virtualization\n\n"
"@ingroup SFX" );
@ -278,16 +273,8 @@ SFXSystem::SFXSystem()
"@ingroup SFX" );
Con::addConstant( "$SFX::DEVICE_CAPS_MULTILISTENER", TypeS32, &sDeviceCapsMultiListener,
"Sound device capability flag indicating that the sound device supports multiple concurrent listeners.\n\n"
"@note Currently only FMOD implements this.\n\n"
"@see sfxGetDeviceInfo\n\n"
"@ingroup SFX" );
Con::addConstant( "$SFX::DEVICE_CAPS_FMODDESIGNER", TypeS32, &sDeviceCapsFMODDesigner,
"Sound device capability flag indicating that the sound device supports FMOD Designer audio projects.\n\n"
"@note This is exclusive to FMOD. If the FMOD Event DLLs are in place and could be successfully loaded, this "
"flag will be set after initializating an FMOD audio device.\n\n"
"@see sfxGetDeviceInfo\n\n"
"@ref FMOD_designer\n\n"
"@ingroup SFX" );
Con::addConstant( "$SFX::DEVICE_INFO_PROVIDER", TypeS32, &sDeviceInfoProvider,
"Index of sound provider field in device info string.\n\n"
@ -1241,7 +1228,7 @@ DefineEngineFunction( sfxGetAvailableDevices, const char*, (),,
"@verbatim\n"
"provider TAB device TAB hasHardware TAB numMaxBuffers\n"
"@endverbatim\n"
"- provider: The name of the device provider (e.g. \"FMOD\").\n"
"- provider: The name of the device provider (e.g. \"OpenAL\").\n"
"- device: The name of the device as returned by the device layer.\n"
"- hasHardware: Whether the device supports hardware mixing or not.\n"
"- numMaxBuffers: The maximum number of concurrent voices supported by the device's mixer. If this limit "
@ -1336,7 +1323,7 @@ DefineEngineFunction( sfxGetDeviceInfo, const char*, (),,
"@verbatim\n"
"provider TAB device TAB hasHardware TAB numMaxBuffers TAB caps\n"
"@endverbatim\n"
"- provider: The name of the device provider (e.g. \"FMOD\").\n"
"- provider: The name of the device provider (e.g. \"OpenALD\").\n"
"- device: The name of the device as returned by the device layer.\n"
"- hasHardware: Whether the device supports hardware mixing or not.\n"
"- numMaxBuffers: The maximum number of concurrent voices supported by the device's mixer. If this limit "
@ -1357,7 +1344,6 @@ DefineEngineFunction( sfxGetDeviceInfo, const char*, (),,
"@see $SFX::DEVICE_CAPS_OCCLUSION\n\n"
"@see $SFX::DEVICE_CAPS_DSPEFFECTS\n\n"
"@see $SFX::DEVICE_CAPS_MULTILISTENER\n\n"
"@see $SFX::DEVICE_CAPS_FMODDESIGNER\n\n"
"@ref SFX_devices\n"
"@ingroup SFX" )
{
@ -1379,7 +1365,7 @@ static ConsoleDocFragment _sfxCreateSource1(
"@param track The track the source should play.\n"
"@return A new SFXSource for playback of the given track or 0 if no source could be created from the given track.\n\n"
"@note Trying to create a source for a device-specific track type will fail if the currently selected device "
"does not support the type. Example: trying to create a source for an FMOD Designer event when not running FMOD.\n\n"
"does not support the type. \n\n"
"@tsexample\n"
"// Create and play a source from a pre-existing profile:\n"
"%source = sfxCreateSource( SoundFileProfile );\n"
@ -1400,7 +1386,7 @@ static ConsoleDocFragment _sfxCreateSource2(
"@param z The Z coordinate of the 3D sound position.\n"
"@return A new SFXSource for playback of the given track or 0 if no source could be created from the given track.\n\n"
"@note Trying to create a source for a device-specific track type will fail if the currently selected device "
"does not support the type. Example: trying to create a source for an FMOD Designer event when not running FMOD.\n\n"
"does not support the type. \n\n"
"@tsexample\n"
"// Create and play a source from a pre-existing profile and position it at (100, 200, 300):\n"
"%source = sfxCreateSource( SoundFileProfile, 100, 200, 300 );\n"

View file

@ -39,7 +39,7 @@ ConsoleDocClass( SFXTrack,
"The term \"track\" is used in the sound system to refer to any entity that can be played "
"back as a sound source. These can be individual files (SFXProfile), patterns of other tracks "
"(SFXPlayList), or special sound data defined by a device layer (SFXFMODEvent).\n\n"
"(SFXPlayList).\n\n"
"Any track must be paired with a SFXDescription that tells the sound system how to set up "
"playback for the track.\n\n"