Skip to content
Browse files

integrated fmod designer extension

  • Loading branch information...
1 parent bbb5789 commit 6472a673d7a5a25714a0ea13bd6d89ec810ed5b2 @patrickmeehan patrickmeehan committed Mar 7, 2013
Showing with 9,151 additions and 24 deletions.
  1. +0 −14 src/aku/AKU-fmod-designer.cpp
  2. +14 −1 src/hosts/GlutHost.cpp
  3. +28 −4 src/hosts/GlutHostMain.cpp
  4. +49 −0 src/moaiext-fmod-designer/AKU-fmod-designer.cpp
  5. +5 −1 src/{aku → moaiext-fmod-designer}/AKU-fmod-designer.h
  6. +578 −0 src/moaiext-fmod-designer/MOAIFmodEventInstance.cpp
  7. +69 −0 src/moaiext-fmod-designer/MOAIFmodEventInstance.h
  8. +947 −0 src/moaiext-fmod-designer/MOAIFmodEventMgr.cpp
  9. +87 −0 src/moaiext-fmod-designer/MOAIFmodEventMgr.h
  10. +79 −0 src/moaiext-fmod-designer/MOAIFmodMicrophone.cpp
  11. +40 −0 src/moaiext-fmod-designer/MOAIFmodMicrophone.h
  12. +146 −0 src/moaiext-fmod-designer/Source/Common.h
  13. +21 −0 src/moaiext-fmod-designer/Source/DuckingRequest.h
  14. +211 −0 src/moaiext-fmod-designer/Source/Event.cpp
  15. +52 −0 src/moaiext-fmod-designer/Source/Event.h
  16. +13 −0 src/moaiext-fmod-designer/Source/EventHandle.h
  17. +1,087 −0 src/moaiext-fmod-designer/Source/EventInstance.cpp
  18. +287 −0 src/moaiext-fmod-designer/Source/EventInstance.h
  19. +3,122 −0 src/moaiext-fmod-designer/Source/EventManager.cpp
  20. +604 −0 src/moaiext-fmod-designer/Source/EventManager.h
  21. +25 −0 src/moaiext-fmod-designer/Source/EventParameter.h
  22. +50 −0 src/moaiext-fmod-designer/Source/EventProperties.h
  23. +56 −0 src/moaiext-fmod-designer/Source/FMODFileSystem.cpp
  24. +36 −0 src/moaiext-fmod-designer/Source/FMODFileSystem.h
  25. +174 −0 src/moaiext-fmod-designer/Source/HandleFactory.cpp
  26. +230 −0 src/moaiext-fmod-designer/Source/HandleFactory.h
  27. +15 −0 src/moaiext-fmod-designer/Source/LineCode.cpp
  28. +120 −0 src/moaiext-fmod-designer/Source/LineCode.h
  29. +13 −0 src/moaiext-fmod-designer/Source/ReverbHandle.h
  30. +44 −0 src/moaiext-fmod-designer/Source/ReverbInstance.cpp
  31. +42 −0 src/moaiext-fmod-designer/Source/ReverbInstance.h
  32. +201 −0 src/moaiext-fmod-designer/Source/SoundDSP.cpp
  33. +98 −0 src/moaiext-fmod-designer/Source/SoundDSP.h
  34. +61 −0 src/moaiext-fmod-designer/Source/SoundInitParams.h
  35. +54 −0 src/moaiext-fmod-designer/Source/SoundOccluder.cpp
  36. +48 −0 src/moaiext-fmod-designer/Source/SoundOccluder.h
  37. +217 −0 src/moaiext-fmod-designer/Source/VoiceLRU.cpp
  38. +88 −0 src/moaiext-fmod-designer/Source/VoiceLRU.h
  39. +2 −2 vs2008/moai-fmod-designer/moai-fmod-designer.vcproj
  40. +138 −2 vs2008/moaiext-fmod-designer/moaiext-fmod-designer.vcproj
View
14 src/aku/AKU-fmod-designer.cpp
@@ -1,14 +0,0 @@
-// Copyright (c) 2010-2011 Zipline Games, Inc. All Rights Reserved.
-// http://getmoai.com
-
-#include <aku/AKU-fmod-designer.h>
-
-//================================================================//
-// AKU-fmod-ex
-//================================================================//
-
-//----------------------------------------------------------------//
-void AKUFmodDesignerInit () {
-
- //just a stub so we can compile something
-}
View
15 src/hosts/GlutHost.cpp
@@ -19,6 +19,10 @@
#include <aku/AKU-fmod.h>
#endif
+#ifdef GLUTHOST_USE_FMOD_DESIGNER
+ #include <moaiext-fmod-designer/AKU-fmod-designer.h>
+#endif
+
#ifdef GLUTHOST_USE_LUAEXT
#include <aku/AKU-luaext.h>
#endif
@@ -204,7 +208,8 @@ static void _onReshape( int w, int h ) {
static void _onTimer ( int millisec ) {
UNUSED ( millisec );
- int timerInterval = ( int )( AKUGetSimStep () * 1000.0 );
+ double fSimStep = AKUGetSimStep ();
+ int timerInterval = ( int )( fSimStep * 1000.0 );
glutTimerFunc ( timerInterval, _onTimer, timerInterval );
#ifdef GLUTHOST_USE_DEBUGGER
@@ -217,6 +222,10 @@ static void _onTimer ( int millisec ) {
AKUFmodUpdate ();
#endif
+ #ifdef GLUTHOST_USE_FMOD_DESIGNER
+ AKUFmodDesignerUpdate (( float )fSimStep );
+ #endif
+
if ( sDynamicallyReevaluateLuaFiles ) {
#ifdef _WIN32
winhostext_Query ();
@@ -398,6 +407,10 @@ void GlutRefreshContext () {
AKUFmodLoad ();
#endif
+ #ifdef GLUTHOST_USE_FMOD_DESIGNER
+ AKUFmodDesignerInit ();
+ #endif
+
#ifdef GLUTHOST_USE_LUAEXT
AKUExtLoadLuacrypto ();
AKUExtLoadLuacurl ();
View
32 src/hosts/GlutHostMain.cpp
@@ -6,13 +6,37 @@
#include <GlutHost.h>
#include <stdio.h>
+#include <stdlib.h>
+
+#if _MSC_VER
+ #include <Crtdbg.h>
+#endif
+
+#ifdef _WIN32
+ #include <Windows.h>
+#endif
//----------------------------------------------------------------//
-int main ( int argc, char** argv ) {
+#ifdef _WIN32
+ int CALLBACK WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) {
+ int argc = __argc;
+ char** argv = __argv;
+#else
+ int main ( int argc, char** argv ) {
+#endif
+
+#if _MSC_VER
+ // affects assert.h assert()
+ _set_error_mode ( _OUT_TO_MSGBOX );
+
+ // affects crtdbg.h _ASSERT, _ASSERTE, etc
+ _CrtSetReportMode ( _CRT_ASSERT, _CRTDBG_MODE_DEBUG | _CRTDBG_MODE_WNDW | _CRTDBG_MODE_FILE );
+ _CrtSetReportFile ( _CRT_ASSERT, _CRTDBG_FILE_STDERR );
+#endif
- #ifdef _DEBUG
- printf ( "MOAI-OPEN DEBUG\n" );
- #endif
+#ifdef _DEBUG
+ printf ( "MOAI-OPEN DEBUG\n" );
+#endif
return GlutHost ( argc, argv );
}
View
49 src/moaiext-fmod-designer/AKU-fmod-designer.cpp
@@ -0,0 +1,49 @@
+// Copyright (c) 2010-2011 Zipline Games, Inc. All Rights Reserved.
+// http://getmoai.com
+
+#include <aku/AKU-fmod-designer.h>
+#include <moaiext-fmod-designer/MOAIFmodEventMgr.h>
+#include <moaiext-fmod-designer/MOAIFmodEventInstance.h>
+#include <moaiext-fmod-designer/MOAIFmodMicrophone.h>
+#include <moaiext-fmod-designer/Source/EventManager.h>
+
+#ifdef MOAI_OS_IPHONE
+ #include <fmodiphone.h>
+#endif
+
+//================================================================//
+// AKU-fmod-designer
+//================================================================//
+
+//----------------------------------------------------------------//
+void AKUFmodDesignerInit () {
+
+ MOAIFmodEventMgr::Affirm ();
+
+ REGISTER_LUA_CLASS ( MOAIFmodEventMgr )
+ REGISTER_LUA_CLASS ( MOAIFmodEventInstance )
+ REGISTER_LUA_CLASS ( MOAIFmodMicrophone )
+}
+
+//----------------------------------------------------------------//
+void AKUFmodDesignerMuteSystem ( bool mute ) {
+ FMODDesigner::tEventManager.MuteAllEvents( mute );
+}
+
+//----------------------------------------------------------------//
+void AKUFmodDesignerRelease () {
+ FMODDesigner::tEventManager.Shutdown();
+}
+
+//----------------------------------------------------------------//
+void AKUFmodDesignerRestoreSession () {
+#ifdef MOAI_OS_IPHONE
+ FMOD_IPhone_RestoreAudioSession ();
+#endif
+}
+
+//----------------------------------------------------------------//
+void AKUFmodDesignerUpdate ( float fDeltaTime ) {
+
+ FMODDesigner::tEventManager.Update( fDeltaTime );
+}
View
6 src/aku/AKU-fmod-designer.h → ...moaiext-fmod-designer/AKU-fmod-designer.h
@@ -9,6 +9,10 @@
#include <aku/AKU.h>
-AKU_API void AKUFmodDesignerInit ();
+AKU_API void AKUFmodDesignerInit ();
+AKU_API void AKUFmodDesignerMuteSystem ( bool mute );
+AKU_API void AKUFmodDesignerRelease ();
+AKU_API void AKUFmodDesignerRestoreSession ();
+AKU_API void AKUFmodDesignerUpdate ( float fDeltaTime );
#endif
View
578 src/moaiext-fmod-designer/MOAIFmodEventInstance.cpp
@@ -0,0 +1,578 @@
+// Copyright (c) 2010-2011 Zipline Games, Inc. All Rights Reserved.
+// http://getmoai.com
+
+#include <moaiext-fmod-designer/MOAIFmodEventInstance.h>
+#include <fmod.hpp>
+#include <moaiext-fmod-designer/Source/EventHandle.h>
+#include <moaiext-fmod-designer/Source/EventInstance.h>
+#include <moaiext-fmod-designer/Source/EventParameter.h>
+
+#ifdef MOAI_OS_IPHONE
+ #include <fmodiphone.h>
+#endif
+
+#ifdef MOAI_OS_NACL
+#include <NaClFileSystem.h>
+#include <moai_nacl.h>
+#endif
+
+//----------------------------------------------------------------//
+/** @name isValid
+ @text Checks to see if the instance is valid (ie, currently playing)
+
+ @in MOAIFmodEventInstance self
+
+ @out bool valid True if the instance is currently playing, false otherwise
+*/
+int MOAIFmodEventInstance::_isValid ( lua_State* L ) {
+ MOAI_LUA_SETUP ( MOAIFmodEventInstance, "U" )
+
+ bool bReturnVal = false;
+
+ FMODDesigner::EventInstance* pInstance = *( self->mEventHandle );
+ if ( pInstance && pInstance->IsValid() ) {
+ bReturnVal = true;
+ }
+
+ lua_pushboolean( L, bReturnVal );
+
+ return 1;
+}
+
+//----------------------------------------------------------------//
+/** @name stop
+ @text Stops the Event Instance from playing.
+
+ @in MOAIFmodEventInstance self
+
+ @out nil
+*/
+int MOAIFmodEventInstance::_stop ( lua_State* L ) {
+ MOAI_LUA_SETUP ( MOAIFmodEventInstance, "U" )
+
+ FMODDesigner::EventInstance* pInstance = *( self->mEventHandle );
+ if ( pInstance ) {
+ pInstance->Stop();
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------//
+/** @name pause
+ @text Pauses the Event Instance currently playing.
+
+ @in MOAIFmodEventInstance self
+ @opt boolean setting Whether to pause or unpause. Defaults to true (pause).
+
+ @out nil
+*/
+int MOAIFmodEventInstance::_pause ( lua_State* L ) {
+ MOAI_LUA_SETUP ( MOAIFmodEventInstance, "U" )
+
+ FMODDesigner::EventInstance* pInstance = *( self->mEventHandle );
+ if ( pInstance ) {
+ bool bSetting = state.GetValue < bool > ( 2, true );
+ pInstance->Pause ( bSetting );
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------//
+/** @name mute
+ @text Mutes the Event Instance currently playing.
+
+ @in MOAIFmodEventInstance self
+ @opt boolean setting Whether to mute or unmute. Defaults to true (mute).
+
+ @out nil
+*/
+int MOAIFmodEventInstance::_mute ( lua_State* L ) {
+ MOAI_LUA_SETUP ( MOAIFmodEventInstance, "U" )
+
+ FMODDesigner::EventInstance* pInstance = *( self->mEventHandle );
+ if ( pInstance ) {
+ bool bSetting = state.GetValue < bool > ( 2, true );
+ pInstance->Mute ( bSetting );
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------//
+/** @name setVolume
+ @text Sets the volume of the Event Instance.
+
+ @in MOAIFmodEventInstance self
+ @in number volume Volume is a number between 0 and 1 (where 1 is at full volume).
+
+ @out nil
+*/
+int MOAIFmodEventInstance::_setVolume ( lua_State* L ) {
+ MOAI_LUA_SETUP ( MOAIFmodEventInstance, "UN" )
+
+ FMODDesigner::EventInstance* pInstance = *( self->mEventHandle );
+ if ( pInstance )
+ {
+ float fVolume = state.GetValue < float > ( 2, 0.0f );
+ pInstance->SetVolume ( fVolume );
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------//
+/** @name getVolume
+ @text Gets the volume of the Event Instance.
+
+ @in MOAIFmodEventInstance self
+
+ @out number volume of this Event Instance
+*/
+int MOAIFmodEventInstance::_getVolume ( lua_State* L ) {
+ MOAI_LUA_SETUP ( MOAIFmodEventInstance, "U" )
+
+ FMODDesigner::EventInstance* pInstance = *( self->mEventHandle );
+ if ( pInstance )
+ {
+ float fVolume = pInstance->GetVolume();
+ lua_pushnumber( L, fVolume );
+
+ return 1;
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------//
+/** @name setPitch
+ @text Sets the pitch of the Event Instance.
+
+ @in MOAIFmodEventInstance self
+ @in number pitch A pitch level, from 0.0 to 10.0 inclusive. 0.5 = half pitch, 2.0 = double pitch. Default = 1.0
+
+ @out nil
+*/
+int MOAIFmodEventInstance::_setPitch ( lua_State* L ) {
+ MOAI_LUA_SETUP ( MOAIFmodEventInstance, "UN" )
+
+ FMODDesigner::EventInstance* pInstance = *( self->mEventHandle );
+ if ( pInstance )
+ {
+ float fPitch = state.GetValue < float > ( 2, 1.0f );
+ pInstance->SetPitch ( fPitch );
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------//
+/** @name getPitch
+ @text Gets the pitch of the Event Instance.
+
+ @in MOAIFmodEventInstance self
+
+ @out number pitch of this Event Instance
+*/
+int MOAIFmodEventInstance::_getPitch ( lua_State* L ) {
+ MOAI_LUA_SETUP ( MOAIFmodEventInstance, "U" )
+
+ FMODDesigner::EventInstance* pInstance = *( self->mEventHandle );
+ if ( pInstance )
+ {
+ float fPitch = pInstance->GetPitch();
+ lua_pushnumber( L, fPitch );
+
+ return 1;
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------//
+/** @name getParameter
+ @text Gets the value (a number) of an Event parameter
+
+ @in MOAIFmodEventInstance self
+ @in string parameterName The name of the Event Parameter
+
+ @out number paramValue The value of the Event Parameter
+*/
+int MOAIFmodEventInstance::_getParameter ( lua_State* L ) {
+ MOAI_LUA_SETUP ( MOAIFmodEventInstance, "US" )
+
+ FMODDesigner::EventInstance* pInstance = *( self->mEventHandle );
+ if ( pInstance ) {
+
+ cc8* paramName = state.GetValue < cc8* > ( 2, "" );
+ if ( paramName[0] != '\0' ) {
+
+ const FMODDesigner::Event actualEvent = pInstance->GetSourceEvent();
+ FMODDesigner::EventParameter eventParam;
+ actualEvent.GetParameterIndex ( eventParam, paramName );
+ if ( eventParam.IsValid() )
+ {
+ float fReturn = pInstance->GetParameter ( eventParam );
+ lua_pushnumber ( L, fReturn );
+
+ return 1;
+ }
+
+ }
+
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------//
+/** @name setParameter
+ @text Sets the value (a number) of an Event parameter
+
+ @in MOAIFmodEventInstance self
+ @in string parameterName The name of the Event Parameter
+ @in number paramValue New value of the Event Parameter
+
+ @out nil
+*/
+int MOAIFmodEventInstance::_setParameter ( lua_State* L ) {
+ MOAI_LUA_SETUP ( MOAIFmodEventInstance, "USN" )
+
+ FMODDesigner::EventInstance* pInstance = *( self->mEventHandle );
+ if ( pInstance ) {
+
+ cc8* paramName = state.GetValue < cc8* > ( 2, "" );
+ if ( paramName[0] != '\0' ) {
+
+ const FMODDesigner::Event actualEvent = pInstance->GetSourceEvent();
+ FMODDesigner::EventParameter eventParam;
+ actualEvent.GetParameterIndex ( eventParam, paramName );
+ if ( eventParam.IsValid() )
+ {
+ float fValue = state.GetValue < float > ( 3, 0.f );
+ pInstance->SetParameter ( eventParam, fValue );
+ }
+
+ }
+
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------//
+/** @name keyOff
+ @text Sets the Event Instance to key off based on the passed in Event Parameter
+
+ @in MOAIFmodEventInstance self
+ @in string parameterName The name of the Event Parameter
+
+ @out nil
+*/
+int MOAIFmodEventInstance::_keyOff ( lua_State* L ) {
+ MOAI_LUA_SETUP ( MOAIFmodEventInstance, "US" )
+
+ FMODDesigner::EventInstance* pInstance = *( self->mEventHandle );
+ if ( pInstance ) {
+
+ cc8* paramName = state.GetValue < cc8* > ( 2, "" );
+ if ( paramName[0] != '\0' ) {
+
+ const FMODDesigner::Event actualEvent = pInstance->GetSourceEvent();
+ FMODDesigner::EventParameter eventParam;
+ actualEvent.GetParameterIndex ( eventParam, paramName );
+ if ( eventParam.IsValid() )
+ {
+ pInstance->KeyOff ( eventParam );
+ }
+
+ }
+
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------//
+/** @name unloadOnSilence
+ @text For streaming sounds -- unloads the Event from memory on silence.
+ (A good guideline to use is: for sounds that don't repeat often)
+
+ @in MOAIFmodEventInstance self
+ @opt boolean setting Whether to unload on silence or not (Default: true)
+
+ @out nil
+*/
+int MOAIFmodEventInstance::_unloadOnSilence ( lua_State* L ) {
+ MOAI_LUA_SETUP ( MOAIFmodEventInstance, "U" )
+
+ FMODDesigner::EventInstance* pInstance = *( self->mEventHandle );
+ if ( pInstance ) {
+
+ bool bSetting = state.GetValue < bool > ( 2, true );
+ pInstance->UnloadOnSilence ( bSetting );
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------//
+/** @name getName
+ @text Get the name of the Event
+
+ @in MOAIFmodEventInstance self
+
+ @out string name Name of the event
+*/
+int MOAIFmodEventInstance::_getName ( lua_State* L ) {
+ MOAI_LUA_SETUP ( MOAIFmodEventInstance, "U" )
+
+ FMODDesigner::EventInstance* pInstance = *( self->mEventHandle );
+ if ( pInstance ) {
+
+ const STLString sName = pInstance->GetName();
+ lua_pushstring ( L, sName.c_str() );
+
+ return 1;
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------//
+/** @name getNumChannels
+ @text Get the number of Channels in this Event's Channel Group
+
+ @in MOAIFmodEventInstance self
+
+ @out number channels Number of channels in Event Instance's Channel Group
+*/
+int MOAIFmodEventInstance::_getNumChannels ( lua_State* L ) {
+ MOAI_LUA_SETUP ( MOAIFmodEventInstance, "U" )
+
+ FMODDesigner::EventInstance* pInstance = *( self->mEventHandle );
+ if ( pInstance ) {
+
+ int channels = pInstance->GetNumChannels();
+ lua_pushnumber ( L, channels );
+
+ return 1;
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------//
+/** @name getTime
+ @text Returns time within the Event, or if useSubsoundTime, will return the time
+ within the *the first subsound only*
+
+ @in MOAIFmodEventInstance self
+ @opt boolean useSubsoundTime If true, will return the time within the first subsound only (Default: false)
+
+ @out number time Time within the Event
+*/
+int MOAIFmodEventInstance::_getTime ( lua_State* L ) {
+ MOAI_LUA_SETUP ( MOAIFmodEventInstance, "U" )
+
+ FMODDesigner::EventInstance* pInstance = *( self->mEventHandle );
+ if ( pInstance ) {
+
+ bool bUseSubsoundTime = state.GetValue < bool > ( 2, false );
+ float fTime = pInstance->GetTime ( bUseSubsoundTime );
+ lua_pushnumber ( L, fTime );
+
+ return 1;
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------//
+/** @name getDominantFrequency
+ @text Returns the fundamental frequency of this Event Instance.
+
+ @in MOAIFmodEventInstance self
+
+ @out number frequency Dominant frequency of this Event Instance
+*/
+int MOAIFmodEventInstance::_getDominantFrequency ( lua_State* L ) {
+ MOAI_LUA_SETUP ( MOAIFmodEventInstance, "U" )
+
+ FMODDesigner::EventInstance* pInstance = *( self->mEventHandle );
+ if ( pInstance ) {
+
+ float fFrequency = pInstance->GetDominantFrequency();
+ lua_pushnumber ( L, fFrequency );
+
+ return 1;
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------//
+/** @name getTempo
+ @text Returns the tempo of this Event Instance (useful for music, obv)
+
+ @in MOAIFmodEventInstance self
+
+ @out number tempo Tempo of this Event Instance
+*/
+int MOAIFmodEventInstance::_getTempo ( lua_State* L ) {
+ MOAI_LUA_SETUP ( MOAIFmodEventInstance, "U" )
+
+ FMODDesigner::EventInstance* pInstance = *( self->mEventHandle );
+ if ( pInstance ) {
+
+ float fTempo = pInstance->GetTempo();
+ lua_pushnumber ( L, fTempo );
+
+ return 1;
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------//
+/** @name getBeatFraction
+ @text Returns the beat fraction of this Event Instance (useful for music)
+
+ @in MOAIFmodEventInstance self
+
+ @out number beatFraction Beat Fraction of this Event Instance
+*/
+int MOAIFmodEventInstance::_getBeatFraction ( lua_State* L ) {
+ MOAI_LUA_SETUP ( MOAIFmodEventInstance, "U" )
+
+ FMODDesigner::EventInstance* pInstance = *( self->mEventHandle );
+ if ( pInstance ) {
+
+ float fBeatFraction = pInstance->GetBeatFraction();
+ lua_pushnumber ( L, fBeatFraction );
+
+ return 1;
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------//
+/** @name getMeasureFraction
+ @text Returns the measure fraction of this Event Instance (useful for music)
+
+ @in MOAIFmodEventInstance self
+
+ @out number measureFraction Measure Fraction of this Event Instance
+*/
+int MOAIFmodEventInstance::_getMeasureFraction ( lua_State* L ) {
+ MOAI_LUA_SETUP ( MOAIFmodEventInstance, "U" )
+
+ FMODDesigner::EventInstance* pInstance = *( self->mEventHandle );
+ if ( pInstance ) {
+
+ float fFraction = pInstance->GetMeasureFraction();
+ lua_pushnumber ( L, fFraction );
+
+ return 1;
+ }
+
+ return 0;
+}
+
+//================================================================//
+// MOAIFmodEventInstance
+//================================================================//
+
+//----------------------------------------------------------------//
+MOAIFmodEventInstance::MOAIFmodEventInstance () {
+ RTTI_BEGIN
+ RTTI_EXTEND ( MOAITransform )
+ RTTI_END
+}
+
+//----------------------------------------------------------------//
+MOAIFmodEventInstance::~MOAIFmodEventInstance () {
+}
+
+//----------------------------------------------------------------//
+void MOAIFmodEventInstance::RegisterLuaClass ( MOAILuaState& state ) {
+
+ MOAITransform::RegisterLuaClass ( state );
+}
+
+//----------------------------------------------------------------//
+void MOAIFmodEventInstance::RegisterLuaFuncs ( MOAILuaState& state ) {
+
+ MOAITransform::RegisterLuaFuncs ( state );
+
+ luaL_Reg regTable [] = {
+ { "isValid", _isValid },
+
+ { "stop", _stop },
+ { "pause", _pause },
+ { "mute", _mute },
+
+ { "setLoc", _setLoc },
+
+ { "setVolume", _setVolume },
+ { "setPitch", _setPitch },
+ { "getVolume", _getVolume },
+ { "getPitch", _getPitch },
+
+ { "getParameter", _getParameter },
+ { "setParameter", _setParameter },
+ { "keyOff", _keyOff },
+
+ { "unloadOnSilence", _unloadOnSilence },
+
+ { "getName", _getName },
+ { "getNumChannels", _getNumChannels },
+
+ { "getTime", _getTime },
+ { "getDominantFrequency", _getDominantFrequency },
+
+ { "getTempo", _getTempo },
+ { "getBeatFraction", _getBeatFraction },
+ { "getMeasureFraction", _getMeasureFraction },
+
+ { NULL, NULL }
+ };
+
+ luaL_register ( state, 0, regTable );
+}
+
+//----------------------------------------------------------------//
+
+void MOAIFmodEventInstance::SetInstanceLoc ( USVec3D& vPos )
+{
+ FMODDesigner::EventInstance* pInstance = *mEventHandle;
+ if ( pInstance )
+ {
+ pInstance->SetPosition ( vPos );
+ }
+}
+
+//----------------------------------------------------------------//
+bool MOAIFmodEventInstance::ApplyAttrOp ( u32 attrID, MOAIAttrOp& attrOp, u32 op ) {
+
+ bool bReturn = MOAITransform::ApplyAttrOp ( attrID, attrOp, op );
+
+ if ( MOAIFmodEventInstanceAttr::Check ( attrID ) )
+ {
+ USVec3D vPos = GetLocalToWorldMtx().GetTranslation();
+ SetInstanceLoc ( vPos );
+ }
+
+ return bReturn;
+}
+
+//----------------------------------------------------------------//
+void MOAIFmodEventInstance::OnDepNodeUpdate () {
+
+ MOAITransform::OnDepNodeUpdate ();
+
+ USVec3D vPos = GetLocalToWorldMtx().GetTranslation();
+ SetInstanceLoc ( vPos );
+}
View
69 src/moaiext-fmod-designer/MOAIFmodEventInstance.h
@@ -0,0 +1,69 @@
+// Copyright (c) 2010-2011 Zipline Games, Inc. All Rights Reserved.
+// http://getmoai.com
+
+#ifndef MOAIFMODEVENTINSTANCE_H
+#define MOAIFMODEVENTINSTANCE_H
+
+#include <moaicore/moaicore.h>
+#include <moaiext-fmod-designer/Source/EventHandle.h>
+
+//================================================================//
+// MOAIFmodEventInstance
+//================================================================//
+/** @name MOAIFmodEventInstance
+ @text An instance of an FMOD Event
+ Not to be confused with an Event, MOAIFmodEvent.
+*/
+class MOAIFmodEventInstance :
+ public MOAITransform {
+private:
+
+ FMODDesigner::EventHandle mEventHandle;
+
+ //----------------------------------------------------------------//
+ static int _isValid ( lua_State* L );
+
+ static int _stop ( lua_State* L );
+ static int _pause ( lua_State* L );
+ static int _mute ( lua_State* L );
+
+ static int _getVolume ( lua_State* L );
+ static int _setVolume ( lua_State* L );
+ static int _getPitch ( lua_State* L );
+ static int _setPitch ( lua_State* L );
+
+ static int _getParameter ( lua_State* L );
+ static int _setParameter ( lua_State* L );
+ static int _keyOff ( lua_State* L );
+
+ static int _unloadOnSilence ( lua_State* L );
+
+ static int _getName ( lua_State* L );
+ static int _getNumChannels ( lua_State* L );
+
+ static int _getTime ( lua_State* L );
+ static int _getDominantFrequency ( lua_State* L );
+
+ // music API
+ static int _getTempo ( lua_State* L );
+ static int _getBeatFraction ( lua_State* L );
+ static int _getMeasureFraction ( lua_State* L );
+
+
+public:
+
+ DECL_LUA_FACTORY ( MOAIFmodEventInstance )
+ DECL_ATTR_HELPER ( MOAIFmodEventInstance )
+
+ //----------------------------------------------------------------//
+ MOAIFmodEventInstance ();
+ virtual ~MOAIFmodEventInstance ();
+ bool ApplyAttrOp ( u32 attrID, MOAIAttrOp& attrOp, u32 op );
+ void OnDepNodeUpdate ();
+ void RegisterLuaClass ( MOAILuaState& state );
+ void RegisterLuaFuncs ( MOAILuaState& state );
+ void SetEventInstance ( FMODDesigner::EventHandle hEventHandle ) { mEventHandle = hEventHandle; }
+ void SetInstanceLoc ( USVec3D& vPos );
+};
+
+#endif
View
947 src/moaiext-fmod-designer/MOAIFmodEventMgr.cpp
@@ -0,0 +1,947 @@
+// Copyright (c) 2010-2011 Zipline Games, Inc. All Rights Reserved.
+// http://getmoai.com
+
+#include <moaiext-fmod-designer/MOAIFmodEventMgr.h>
+#include <moaiext-fmod-designer/MOAIFmodEventInstance.h>
+#include <moaiext-fmod-designer/MOAIFmodMicrophone.h>
+#include <fmod.hpp>
+#include <moaiext-fmod-designer/Source/EventManager.h>
+#include <moaiext-fmod-designer/Source/EventProperties.h>
+#include <moaiext-fmod-designer/Source/SoundInitParams.h>
+
+#ifdef MOAI_OS_NACL
+#include <fmodnacl.h>
+#include "moai_nacl.h"
+#include "ppapi/c/ppb.h"
+#include "ppapi/cpp/instance.h"
+#endif
+
+//================================================================//
+// local
+//================================================================//
+
+//----------------------------------------------------------------//
+/** @name getMemoryStats
+ @text Get memory usage.
+
+ @opt boolean blocking - Default value is 'false.'
+
+ @out number currentAlloc
+ @out number maxAlloc
+*/
+int MOAIFmodEventMgr::_getMemoryStats ( lua_State* L ) {
+ MOAILuaState state ( L );
+
+ bool blocking = state.GetValue < bool > ( 1, false );
+
+ int currentAlloc;
+ int maxAlloc;
+
+ FMOD_Memory_GetStats ( &currentAlloc, &maxAlloc, blocking );
+
+ lua_pushnumber ( state, currentAlloc );
+ lua_pushnumber ( state, maxAlloc );
+
+ return 2;
+}
+
+//----------------------------------------------------------------//
+/** @name init
+ @text Initializes the sound system.
+
+ @out boolean enabled
+*/
+int MOAIFmodEventMgr::_init ( lua_State* L ) {
+ MOAILuaState state ( L );
+
+#ifdef MOAI_OS_NACL
+ printf ( "Cannot initialize FMOD Designer on background thread\n" );
+ return 0;
+#endif
+
+ FMODDesigner::SoundInitParams params = FMODDesigner::SoundInitParams();
+
+ params.m_soundMemoryMB = state.GetField < u32 >( -1, "soundMemoryMB", 32 );
+ params.m_rsxMemoryMB = state.GetField < u32 > ( -1, "rsxMemoryMB", 0 );
+ params.m_voiceLRUBufferMB = state.GetField < u32 > ( -1, "voiceLRUBufferMB", 0 );
+ params.m_voiceLRUMaxMB = state.GetField < u32 > ( -1, "voiceLRUMaxMB", 0 );
+ params.m_nVirtualChannels = state.GetField < u32 > ( -1, "nVirtualChannels", 256 );
+ params.m_nRealChannels = state.GetField < u32 > ( -1, "nRealChannels", 32 );
+ params.m_nPCMCodecs = state.GetField < u32 > ( -1, "nPCMCodecs", 16 );
+ params.m_nADPCMCodecs = state.GetField < u32 > ( -1, "nADPCMCodecs", 32 );
+ params.m_nCompressedCodecs = state.GetField < u32 > ( -1, "nCompressedCodecs", 32 );
+ params.m_nMaxInputChannels = state.GetField < u32 > ( -1, "nMaxInputChannels", 6 );
+ params.m_enableSoundSystem = state.GetField < bool > ( -1, "enableSoundSystem", true );
+ params.m_enableDistantLowpass = state.GetField < bool > ( -1, "enableDistantLowpass", false );
+ params.m_enableEnvironmentalReverb = state.GetField < bool > ( -1, "enableEnvironmentalReverb", true );
+ params.m_enableNear2DBlend = state.GetField < bool > ( -1, "enableNear2DBlend", false );
+ params.m_enableAuditioning = state.GetField < bool > ( -1, "enableAuditioning", false );
+ params.m_enableProfiling = state.GetField < bool > ( -1, "enableProfiling", false );
+ params.m_enableFsCallbacks = state.GetField < bool > ( -1, "enableFsCallbacks", false );
+ params.m_disableSound = state.GetField < bool > ( -1, "disableSound", false );
+ params.m_dopplerScale = state.GetField < float > ( -1, "dopplerScale", 0.f );
+
+ const bool b = FMODDesigner::tEventManager.Init ( params );
+ lua_pushboolean ( L, b );
+ return 1;
+}
+
+//----------------------------------------------------------------//
+/** @name isEnabled
+ @text Returns true if the Event Manager is enabled (active).
+
+ @out boolean enabled True if the Event Manager is active, false otherwise
+*/
+
+int MOAIFmodEventMgr::_isEnabled ( lua_State* L ) {
+ MOAILuaState state ( L );
+
+ bool bEnabled = FMODDesigner::tEventManager.IsEnabled();
+ lua_pushboolean ( L, bEnabled );
+
+ return 1;
+}
+
+//----------------------------------------------------------------//
+/** @name loadProject
+ @text Loads a project from disk, but does not load any wav or instance data.
+ Projects must be loaded before sounds can be played from them.
+ For special voice projects, use loadVoiceProject()
+
+ @in string projectName The name of the .fev file (path should be relative from project root)
+
+ @out boolean loaded True if the project successfully loaded, false otherwise
+*/
+int MOAIFmodEventMgr::_loadProject ( lua_State* L ) {
+ MOAILuaState state ( L );
+
+ cc8* projectName = state.GetValue < cc8* > ( 1, "" );
+ if ( projectName[0] != '\0' )
+ {
+ bool bLoaded = FMODDesigner::tEventManager.LoadProject( projectName );
+
+ lua_pushboolean ( L, bLoaded );
+ return 1;
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------//
+/** @name unloadProject
+ @text Unloads all data associated with a particular project.
+ Completely flushes all memory associated with the project.
+ For special voice projects, use unloadVoiceProjects()
+
+ @in string projectName The name of the .fev file (path should be relative from project root)
+
+ @out boolean unloaded True if the project is no longer loaded after this call, false otherwise.
+*/
+int MOAIFmodEventMgr::_unloadProject ( lua_State* L ) {
+ MOAILuaState state ( L );
+
+ cc8* projectName = state.GetValue < cc8* > ( 1, "" );
+ if ( projectName[0] != '\0' )
+ {
+ bool bLoaded = FMODDesigner::tEventManager.UnloadProject( projectName );
+
+ lua_pushboolean ( L, bLoaded );
+ return 1;
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------//
+/** @name loadVoiceProject
+ @text Calls LoadProject and does all attendant special voice load stuff, as well.
+ For regular projects, use loadProject()
+
+ @in string projectName The name of the .fsb file (path should be relative from project root)
+ @out boolean loaded True if the voice project successfully loaded, false otherwise
+*/
+int MOAIFmodEventMgr::_loadVoiceProject ( lua_State* L ) {
+ MOAILuaState state ( L );
+
+ cc8* projectName = state.GetValue < cc8* > ( 1, "" );
+ if ( projectName[0] != '\0' )
+ {
+ // Try to load the cached line information (e.g. normalized code and line length)
+ typedef std::pair<cc8*, float> LineCodeInfo;
+ std::vector<LineCodeInfo> lineCodeInfo;
+ if ( lua_istable ( state, 2 ) ) {
+
+ u16 numLinesCodes = lua_objlen ( state, 2 );
+ for ( u16 i = 0; i < numLinesCodes; i++ ) {
+
+ lua_pushinteger ( state, i + 1 );
+ lua_gettable ( state, -2 );
+
+ if ( lua_istable ( state, -1 ) ) {
+
+ assert ( lua_objlen ( state, -1 ) == 2 );
+
+ cc8* lineCodeName = 0;
+ float lineLength = 0;
+
+ for ( u16 j = 0; j < 2; j++ ) {
+
+ lua_pushinteger ( state, j + 1 );
+ lua_gettable ( state, -2 );
+
+ if ( j == 0 ) {
+ assert ( lua_isstring ( state, -1 ) );
+ lineCodeName = lua_tostring ( state, -1 );
+ }
+ else {
+ assert ( lua_isnumber ( state, -1 ) );
+ lineLength = (float) lua_tonumber ( state, -1 );
+ }
+
+ lua_pop ( state, 1 );
+ }
+
+ lineCodeInfo.push_back ( LineCodeInfo ( lineCodeName, lineLength ) );
+ }
+
+ lua_pop ( state, 1 );
+ }
+ }
+
+ bool bLoaded = FMODDesigner::tEventManager.LoadVoiceProject( projectName, lineCodeInfo.size () > 0 ? &lineCodeInfo : 0 );
+
+ lua_pushboolean ( L, bLoaded );
+ return 1;
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------//
+/** @name unloadVoiceProjects
+ @text Calls UnloadProject and does all attendant special voice unload stuff, as well.
+ For regular projects, use unloadProject()
+
+ @out boolean unloaded True if voice projects are no longer loaded after this call, false otherwise.
+*/
+int MOAIFmodEventMgr::_unloadAllVoiceProjects ( lua_State* L ) {
+ MOAILuaState state ( L );
+
+ bool bLoaded = FMODDesigner::tEventManager.UnloadVoiceProjects();
+
+ lua_pushboolean ( L, bLoaded );
+ return 1;
+}
+
+//----------------------------------------------------------------//
+/** @name loadGroup
+ @text Loads the wave data and instance data associated with a particular group.
+ Groups are reference counted internally, with each call to LoadGroup incrementing the ref count.
+
+ @in string groupPath Should be of the form ProjectName/GroupName
+ @in boolean persistent Passing true means that this group is expected to be around for the entire
+ duration of the app
+ @in boolean blockOnLoad Passing true means that the main thread will block while loading wav data
+ for this Group.
+
+ @out boolean loaded True if the Group successfully loaded after this call, false otherwise
+*/
+
+int MOAIFmodEventMgr::_loadGroup ( lua_State* L ) {
+ MOAILuaState state ( L );
+
+ cc8* groupName = state.GetValue < cc8* > ( 1, "" );
+ if ( groupName[0] != '\0' )
+ {
+ bool bPersistent = state.GetValue ( 2, false );
+ bool bBlockOnLoad = state.GetValue ( 3, false );
+
+ bool bLoaded = FMODDesigner::tEventManager.LoadGroup ( STLString( groupName ), bPersistent, bBlockOnLoad );
+
+ lua_pushboolean ( L, bLoaded );
+
+ return 1;
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------//
+/** @name unloadGroup
+ @text Unloads the wave data and instance data associated with a particular group.
+ Groups might not be unloaded immediately either because their reference count is not zero,
+ or because the sound system is not ready to release the group.
+
+ @in string groupPath Should be of the form ProjectName/GroupName
+ @in boolean unloadImmediately If true is passed in, it'll try to unload now, but won't block.
+ Passing false will allow it to wait before trying to unload
+
+ @out boolean unloaded True if the Group is no longer loaded after this call, false otherwise
+*/
+
+int MOAIFmodEventMgr::_unloadGroup ( lua_State* L ) {
+ MOAILuaState state ( L );
+
+ cc8* groupName = state.GetValue < cc8* > ( 1, "" );
+ if ( groupName[0] != '\0' )
+ {
+ bool bUnloadImmediately = state.GetValue ( 2, false );
+
+ bool bUnloaded = FMODDesigner::tEventManager.UnloadGroup ( STLString( groupName ), bUnloadImmediately );
+
+ lua_pushboolean ( L, bUnloaded );
+
+ return 1;
+
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------//
+/** @name unloadPendingUnloads
+ @text Unloads all the pending unload groups. Use between act changes in the game.
+
+ @opt bool blockOnUnload Passing true means that the main thread will block while unloading
+ @out nil
+*/
+
+int MOAIFmodEventMgr::_unloadPendingUnloads ( lua_State* L ) {
+ MOAILuaState state ( L );
+
+ bool bBlockOnUnload = state.GetValue ( 1, false );
+ FMODDesigner::tEventManager.UnloadPendingUnloads( bBlockOnUnload );
+
+ return 0;
+}
+
+//----------------------------------------------------------------//
+/** @name setSoundCategoryVolume
+ @text Sets the volume for a sound category
+
+ @in string categoryName Name of the category whose volume you wanna modify
+ @in number newVolume New volume to set for the category
+
+ @out nil
+*/
+
+int MOAIFmodEventMgr::_setSoundCategoryVolume ( lua_State* L ) {
+ MOAILuaState state ( L );
+
+ cc8* categoryName = state.GetValue < cc8* > ( 1, "" );
+ if ( categoryName[0] != '\0' )
+ {
+ float fVolume = state.GetValue < float > ( 2, 0.f );
+
+ FMODDesigner::tEventManager.SetSoundCategoryVolume( STLString( categoryName ), fVolume );
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------//
+/** @name getSoundCategoryVolume
+ @text Gets the volume for a sound category
+
+ @in string categoryName Name of the category whose volume you wanna know
+
+ @out number categoryVolume The volume of the category
+*/
+
+int MOAIFmodEventMgr::_getSoundCategoryVolume ( lua_State* L ) {
+ MOAILuaState state ( L );
+
+ cc8* categoryName = state.GetValue < cc8* > ( 1, "" );
+ if ( categoryName[0] != '\0' )
+ {
+ float fVolume = FMODDesigner::tEventManager.GetSoundCategoryVolume( STLString( categoryName ) );
+ lua_pushnumber( L, fVolume );
+
+ return 1;
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------//
+/** @name muteSoundCategory
+ @text Mute a sound category
+
+ @in string categoryName Name of the category whose volume you wanna modify
+ @in boolean muteSetting Whether to mute the category or not (Default: true)
+
+ @out nil
+*/
+
+int MOAIFmodEventMgr::_muteSoundCategory ( lua_State* L ) {
+ MOAILuaState state ( L );
+
+ cc8* categoryName = state.GetValue < cc8* > ( 1, "" );
+ if ( categoryName[0] != '\0' )
+ {
+ bool bSetting = state.GetValue < bool > ( 2, true );
+
+ FMODDesigner::tEventManager.MuteSoundCategory( STLString( categoryName ), bSetting );
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------//
+/** @name isSoundCategoryMuted
+ @text Checks to see whether a sound category is muted
+
+ @in string categoryName Name of the category whose volume you wanna know
+
+ @out boolean isMuted Returns whether the sound category is muted
+*/
+
+int MOAIFmodEventMgr::_isSoundCategoryMuted ( lua_State* L ) {
+ MOAILuaState state ( L );
+
+ cc8* categoryName = state.GetValue < cc8* > ( 1, "" );
+ if ( categoryName[0] != '\0' )
+ {
+ bool bMuted = FMODDesigner::tEventManager.IsSoundCategoryMuted( STLString( categoryName ) );
+ lua_pushboolean( L, bMuted );
+
+ return 1;
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------//
+/** @name pauseSoundCategory
+ @text Mute a sound category
+
+ @in string categoryName Name of the category whose volume you wanna modify
+ @in boolean pauseSetting Whether to mute the category or not (Default: true)
+
+ @out nil
+*/
+
+int MOAIFmodEventMgr::_pauseSoundCategory ( lua_State* L ) {
+ MOAILuaState state ( L );
+
+ cc8* categoryName = state.GetValue < cc8* > ( 1, "" );
+ if ( categoryName[0] != '\0' )
+ {
+ bool bSetting = state.GetValue < bool > ( 2, true );
+
+ FMODDesigner::tEventManager.PauseSoundCategory( STLString( categoryName ), bSetting );
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------//
+/** @name isSoundCategoryPaused
+ @text Checks to see whether a sound category is muted
+
+ @in string categoryName Name of the category whose volume you wanna know
+
+ @out boolean isMuted Returns whether the sound category is muted
+*/
+
+int MOAIFmodEventMgr::_isSoundCategoryPaused ( lua_State* L ) {
+ MOAILuaState state ( L );
+
+ cc8* categoryName = state.GetValue < cc8* > ( 1, "" );
+ if ( categoryName[0] != '\0' )
+ {
+ bool bPaused = FMODDesigner::tEventManager.IsSoundCategoryPaused( STLString( categoryName ) );
+ lua_pushboolean( L, bPaused );
+
+ return 1;
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------//
+/** @name playEvent2D
+ @text Plays an FMOD Event in 2D. Calling this function on 3D Events is undefined.
+
+ @in string eventName Event to play
+ @opt boolean loopSound Will force the Event to loop even if it does not in the data.
+
+ @out MOAIFmodEventInstance eventInst The Event instance
+*/
+
+int MOAIFmodEventMgr::_playEvent2D ( lua_State* L ) {
+ MOAILuaState state ( L );
+
+ cc8* eventName = state.GetValue < cc8* > ( 1, "" );
+ if ( eventName[0] != '\0' ) {
+
+ const FMODDesigner::Event* pEvent = MOAIFmodEventMgr::Get().GetEvent( eventName );
+ if ( !pEvent )
+ {
+ FMODDesigner::Event actualEvent = FMODDesigner::Event( STLString( eventName ) );
+ MOAIFmodEventMgr::Get().AddEvent( eventName, actualEvent );
+ pEvent = MOAIFmodEventMgr::Get().GetEvent( eventName );
+ }
+
+
+ if ( pEvent->IsValid() ) {
+ bool bLoop = state.GetValue( 2, false );
+
+ // Try to play the sound
+ FMODDesigner::EventHandle hEventHandle = FMODDesigner::tEventManager.PlayEvent2D( *pEvent, bLoop );
+
+ // Create a MOAI Event Instance and push it out
+ MOAIFmodEventInstance* pEventInstance = new MOAIFmodEventInstance();
+ pEventInstance->SetEventInstance( hEventHandle );
+
+ pEventInstance->PushLuaUserdata ( state );
+
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------//
+/** @name playEvent3D
+ @text Plays an FMOD Event 3D. Calling this function on 2D Events is harmless, but not advised.
+
+ @in string eventName Event to play
+ @opt number x x position of this sound
+ @opt number y y position of this sound
+ @opt number z z position of this sound
+ @opt boolean loopSound Will force the Event to loop even if it does not in the data.
+
+ @out MOAIFmodEventInstance eventInst The Event instance
+*/
+
+int MOAIFmodEventMgr::_playEvent3D ( lua_State* L ) {
+ MOAILuaState state ( L );
+
+ cc8* eventName = state.GetValue < cc8* > ( 1, "" );
+ if ( eventName[0] != '\0' ) {
+
+ const FMODDesigner::Event* pEvent = MOAIFmodEventMgr::Get().GetEvent( eventName );
+ if ( !pEvent )
+ {
+ FMODDesigner::Event actualEvent = FMODDesigner::Event( STLString( eventName ) );
+ MOAIFmodEventMgr::Get().AddEvent( eventName, actualEvent );
+ pEvent = MOAIFmodEventMgr::Get().GetEvent( eventName );
+ }
+
+ if ( pEvent->IsValid() ) {
+
+ float x = state.GetValue < float > ( 2, 0.f );
+ float y = state.GetValue < float > ( 3, 0.f );
+ float z = state.GetValue < float > ( 4, 0.f );
+
+ bool bLoop = state.GetValue( 5, false );
+
+ // Try to play the sound
+ FMODDesigner::EventHandle hEventHandle = FMODDesigner::tEventManager.PlayEvent3D( *pEvent, USVec3D( x, y, z ), bLoop );
+
+ // Create a MOAI Event Instance and push it out
+ MOAIFmodEventInstance* pEventInstance = new MOAIFmodEventInstance();
+ pEventInstance->SetEventInstance( hEventHandle );
+ pEventInstance->PushLuaUserdata ( state );
+
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------//
+/** @name playVoiceLine
+ @text Plays a voice line that exists in a loaded voice project.
+ Will play it 2D or 3D based on Event settings.
+ Uses a unique identifier for the line that is not the name
+ of the Event -- although the event serves as a template
+ for how the line will play.
+
+ @in string linename Unique identifier for a voice line
+ @in string eventName The Event template to use for playing this line
+ @opt number x x position of this sound
+ @opt number y y position of this sound
+ @opt number z z position of this sound
+
+ @out MOAIFmodEventInstance eventInst The Event instance
+*/
+
+int MOAIFmodEventMgr::_playVoiceLine ( lua_State* L ) {
+ MOAILuaState state ( L );
+
+ cc8* linename = state.GetValue < cc8* >( 1, "" );
+ if ( linename[0] != '\0' ) {
+
+ FMODDesigner::LineCode lineCode = FMODDesigner::LineCode( linename );
+
+ cc8* eventName = state.GetValue < cc8* > ( 2, "" );
+ if ( eventName[0] != '\0' ) {
+
+ const FMODDesigner::Event* pEvent = MOAIFmodEventMgr::Get().GetEvent( eventName );
+ if ( !pEvent )
+ {
+ FMODDesigner::Event actualEvent = FMODDesigner::Event( STLString( eventName ) );
+ MOAIFmodEventMgr::Get().AddEvent( eventName, actualEvent );
+ pEvent = MOAIFmodEventMgr::Get().GetEvent( eventName );
+ }
+
+ if ( pEvent->IsValid() ) {
+ const FMODDesigner::EventProperties* pProperties = FMODDesigner::tEventManager.GetEventProperties( *pEvent );
+ if( pProperties )
+ {
+ FMODDesigner::EventHandle hEventHandle;
+
+ if ( !pProperties->m_is3D ) {
+ // Play the line, which should be the same as the event, at full volume
+ hEventHandle = FMODDesigner::tEventManager.PlayEvent2D( *pEvent, false, &lineCode );
+ }
+ else if ( pProperties->m_headRelative ) {
+ // Head relative sounds are basically 2D, except played as 3D w/ a zero position.
+ hEventHandle = FMODDesigner::tEventManager.PlayEvent3D( *pEvent, USVec3D( 0.f, 0.f, 0.f ), false, USVec3D( 0.f, 0.f, 0.f ), &lineCode );
+ }
+ else {
+ float x = state.GetValue < float > ( 3, 0.f );
+ float y = state.GetValue < float > ( 4, 0.f );
+ float z = state.GetValue < float > ( 5, 0.f );
+
+ hEventHandle = FMODDesigner::tEventManager.PlayEvent3D( *pEvent, USVec3D( x, y, z ), false, USVec3D( 0.f, 0.f, 0.f ), &lineCode );
+ }
+
+ if ( *hEventHandle )
+ {
+ MOAIFmodEventInstance* pEventInstance = new MOAIFmodEventInstance();
+ pEventInstance->SetEventInstance( hEventHandle );
+ pEventInstance->PushLuaUserdata ( state );
+
+ return 1;
+ }
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------//
+/** @name unloadEvent
+ @text Unloads the data associated with an Event.
+ All instances of this Event will be stopped when this call is made.
+ Returns true if the Event is no longer loaded after this call.
+
+ @in string eventName The name of the Event
+ @opt bool blockOnUnload Passing true means that the main thread will block while unloading
+
+ @out bool eventUnloaded True if the Event is no longer loaded after this call.
+*/
+
+int MOAIFmodEventMgr::_unloadEvent ( lua_State* L ) {
+ MOAILuaState state ( L );
+
+ cc8* eventName = state.GetValue < cc8* > ( 1, "" );
+ if ( eventName[0] != '\0' ) {
+ bool bBlockOnUnload = state.GetValue < bool > ( 2, false );
+ FMODDesigner::Event actualEvent = FMODDesigner::Event ( eventName );
+ bool bUnloaded = FMODDesigner::tEventManager.UnloadEvent ( actualEvent, bBlockOnUnload );
+
+ lua_pushboolean ( L, bUnloaded );
+
+ return 1;
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------//
+/** @name stopAllEvents
+ @text Stops all events/sounds from playing.
+
+ @out nil
+*/
+
+int MOAIFmodEventMgr::_stopAllEvents ( lua_State* L ) {
+ MOAILuaState state ( L );
+
+ FMODDesigner::tEventManager.StopAllEvents();
+
+ return 0;
+}
+
+//----------------------------------------------------------------//
+/** @name muteAllEvents
+ @text Stops all events/sounds from playing.
+
+ @in boolean muteSetting Whether to mute (true) or unmute (false)
+ @out nil
+*/
+
+int MOAIFmodEventMgr::_muteAllEvents ( lua_State* L ) {
+ MOAILuaState state ( L );
+
+ bool bSetting = state.GetValue < bool > ( 1, true );
+
+ FMODDesigner::tEventManager.MuteAllEvents( bSetting );
+
+ return 0;
+}
+
+//----------------------------------------------------------------//
+/** @name preloadVoiceLine
+ @text Preload a high demand voice line
+
+ @in string eventName The Event template to use for this line
+ @in string lineName The unique ID of the line to preload
+
+ @out nil
+*/
+
+int MOAIFmodEventMgr::_preloadVoiceLine ( lua_State* L ) {
+ MOAILuaState state ( L );
+
+ cc8* eventName = state.GetValue < cc8* > ( 1, "" );
+ if ( eventName[0] != '\0' ) {
+ cc8* lineName = state.GetValue < cc8* > ( 2, "" );
+ if ( lineName[0] != '\0' )
+ {
+ FMODDesigner::Event actualEvent = FMODDesigner::Event ( eventName );
+ FMODDesigner::LineCode lineCode = FMODDesigner::LineCode ( lineName );
+
+ FMODDesigner::tEventManager.AddLineToLRU ( actualEvent, lineCode );
+ }
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------//
+/** @name setDefaultReverb
+ @text Set the default regional Reverb
+
+ @in string reverbName Name of the Reverb (defined in Designer)
+
+ @out nil
+*/
+
+int MOAIFmodEventMgr::_setDefaultReverb ( lua_State* L ) {
+ MOAILuaState state ( L );
+
+ cc8* reverbName = state.GetValue < cc8* > ( 1, "" );
+ if ( reverbName[0] != '\0' ) {
+ FMODDesigner::tEventManager.SetDefaultReverb ( STLString( reverbName ) );
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------//
+/** @name setDistantOcclusion
+ @text Sets a lowpass filter on distant sounds -- a filter added to
+ everything greater than a certain distance (minRange to maxRange)
+ from the microphone to make it sound muffled/far away.
+
+ @in number minRange Minimum distance from mic
+ @in number maxRange Maximum distance from mic
+ @in number maxOcclusion Maximum occlusion value
+
+ @out nil
+*/
+
+int MOAIFmodEventMgr::_setDistantOcclusion ( lua_State* L ) {
+ MOAILuaState state ( L );
+
+ float fMinRange = state.GetValue < float > ( 1, 0.f );
+ float fMaxRange = state.GetValue < float > ( 2, 0.f );
+ float fMaxOcclusion = state.GetValue < float > ( 3, 0.f );
+ FMODDesigner::tEventManager.SetDistantOcclusion ( fMinRange, fMaxRange, fMaxOcclusion );
+
+ return 0;
+}
+
+//----------------------------------------------------------------//
+/** @name setNear2DBlend
+ @text Blend sounds near the microphone to 2D sounds.
+ When 3D Events are playing near the microphone, their
+ positioning becomes distracting rather than helpful/interesting,
+ so this is a way to blend them together as if they were all
+ taking place just at the mic.
+
+ @in number minRange Minimum distance from mic
+ @in number maxRange Maximum distance from mic
+ @in number maxLevel Maximum pan level
+
+ @out nil
+*/
+
+int MOAIFmodEventMgr::_setNear2DBlend ( lua_State* L ) {
+ MOAILuaState state ( L );
+
+ float fMinRange = state.GetValue < float > ( 1, 0.f );
+ float fMaxRange = state.GetValue < float > ( 2, 0.f );
+ float fMaxPanLevel = state.GetValue < float > ( 3, 0.f );
+ FMODDesigner::tEventManager.SetNear2DBlend( fMinRange, fMaxRange, fMaxPanLevel );
+
+ return 0;
+}
+
+//----------------------------------------------------------------//
+/** @name getEventDuration
+ @text Returns the duration of an Event. Although multiple sounds
+ can potentially be played from 1 Event, to support determinism,
+ a consistent duration will be returned for a given Event.
+
+ @in string eventName The name of the Event
+ @opt string lineName Pass this is if you want the duration of a voice line
+
+ @out number duration Duration of the Event, nil if Event is invalid
+*/
+
+int MOAIFmodEventMgr::_getEventDuration ( lua_State* L ) {
+ MOAILuaState state ( L );
+
+ cc8* eventName = state.GetValue < cc8* > ( 1, "" );
+ if ( eventName[0] != '\0' ) {
+
+ const FMODDesigner::Event* pEvent = MOAIFmodEventMgr::Get().GetEvent( eventName );
+ if ( !pEvent )
+ {
+ FMODDesigner::Event actualEvent = FMODDesigner::Event( STLString( eventName ) );
+ MOAIFmodEventMgr::Get().AddEvent( eventName, actualEvent );
+ pEvent = MOAIFmodEventMgr::Get().GetEvent( eventName );
+ }
+
+ cc8* lineName = state.GetValue < cc8* > ( 2, "" );
+
+ float fDuration = 0.f;
+ if ( lineName[0] != '\0' ) {
+ FMODDesigner::LineCode lineCode = FMODDesigner::LineCode( lineName );
+ fDuration = pEvent->GetDuration( &lineCode );
+ }
+ else {
+ fDuration = pEvent->GetDuration();
+ }
+
+ lua_pushnumber( L, fDuration );
+
+ return 1;
+ }
+
+ return 0;
+}
+
+//----------------------------------------------------------------//
+/** @name getMicrophone
+ @text Returns the game microphone.
+
+ @out MOAIFmodMicrophone mic The game microphone
+*/
+
+int MOAIFmodEventMgr::_getMicrophone ( lua_State* L ) {
+ MOAILuaState state ( L );
+
+ MOAIFmodMicrophone* pMic = MOAIFmodEventMgr::Get().AffirmMic();
+ pMic->PushLuaUserdata ( state );
+
+ return 1;
+}
+
+
+//================================================================//
+// MOAIFmodEventMgr
+//================================================================//
+
+MOAIFmodEventMgr::MOAIFmodEventMgr () : mMic ( 0 ) {
+ RTTI_SINGLE ( MOAIFmodEventMgr )
+}
+
+//----------------------------------------------------------------//
+MOAIFmodEventMgr::~MOAIFmodEventMgr () {
+}
+
+//----------------------------------------------------------------//
+MOAIFmodMicrophone* MOAIFmodEventMgr::AffirmMic () {
+
+ if ( !this->mMic ) {
+ this->mMic = new MOAIFmodMicrophone ();
+ this->LuaRetain ( this->mMic );
+ }
+ return this->mMic;
+}
+
+//----------------------------------------------------------------//
+const FMODDesigner::Event* MOAIFmodEventMgr::GetEvent ( STLString eventName ) {
+
+ STLMap < STLString, FMODDesigner::Event >::iterator it = mEventList.find ( eventName );
+ if ( it != mEventList.end() )
+ {
+ return &it->second;
+ }
+
+ return NULL;
+}
+
+//----------------------------------------------------------------//
+void MOAIFmodEventMgr::AddEvent ( STLString eventName, FMODDesigner::Event& actualEvent ) {
+
+ if ( !mEventList.contains ( eventName ) )
+ {
+ mEventList.insert ( pair < STLString, FMODDesigner::Event > ( eventName, actualEvent ) );
+ }
+}
+
+//----------------------------------------------------------------//
+void MOAIFmodEventMgr::RegisterLuaClass ( MOAILuaState& state ) {
+ UNUSED ( state );
+
+ luaL_Reg regTable [] = {
+ { "getMemoryStats", _getMemoryStats },
+ { "init", _init },
+ { "isEnabled", _isEnabled },
+
+ { "loadProject", _loadProject },
+ { "unloadProject", _unloadProject },
+ { "loadVoiceProject", _loadVoiceProject },
+ { "unloadAllVoiceProjects", _unloadAllVoiceProjects },
+
+ { "loadGroup", _loadGroup },
+ { "unloadGroup", _unloadGroup },
+ { "unloadPendingUnloads", _unloadPendingUnloads },
+
+ { "setSoundCategoryVolume", _setSoundCategoryVolume },
+ { "getSoundCategoryVolume", _getSoundCategoryVolume },
+ { "muteSoundCategory", _muteSoundCategory },
+ { "isSoundCategoryMuted", _isSoundCategoryMuted },
+ { "pauseSoundCategory", _pauseSoundCategory },
+ { "isSoundCategoryPaused", _isSoundCategoryPaused },
+
+ { "playEvent3D", _playEvent3D },
+ { "playEvent2D", _playEvent2D },
+ { "playVoiceLine", _playVoiceLine },
+ { "unloadEvent", _unloadEvent },
+ { "stopAllEvents", _stopAllEvents },
+ { "muteAllEvents", _muteAllEvents },
+ { "getEventDuration", _getEventDuration },
+
+ { "preloadVoiceLine", _preloadVoiceLine },
+
+ { "setDefaultReverb", _setDefaultReverb },
+
+ { "setDistantOcclusion", _setDistantOcclusion },
+ { "setNear2DBlend", _setNear2DBlend },
+
+ { "getMicrophone", _getMicrophone },
+
+ { NULL, NULL }
+ };
+
+ luaL_register ( state, 0, regTable );
+}
+
+//----------------------------------------------------------------//
+void MOAIFmodEventMgr::RegisterLuaFuncs ( MOAILuaState& state ) {
+ UNUSED ( state );
+}
+
View
87 src/moaiext-fmod-designer/MOAIFmodEventMgr.h
@@ -0,0 +1,87 @@
+// Copyright (c) 2010-2011 Zipline Games, Inc. All Rights Reserved.
+// http://getmoai.com
+
+#ifndef MOAIFMODEVENTMGR_H
+#define MOAIFMODEVENTMGR_H
+
+#include <moaicore/moaicore.h>
+
+class MOAIFmodMicrophone;
+
+namespace FMODDesigner {
+ class Event;
+}
+
+
+//================================================================//
+// MOAIFmodEx
+//================================================================//
+/** @name MOAIFmodEventMgr
+ @text Event Manager singleton that provides an interface to all implemented FMOD Designer features.
+*/
+class MOAIFmodEventMgr :
+ public MOAIGlobalClass < MOAIFmodEventMgr, MOAILuaObject > {
+private:
+ MOAIFmodMicrophone* mMic;
+ STLMap< STLString, FMODDesigner::Event > mEventList;
+
+ //----------------------------------------------------------------//
+ static int _getMemoryStats ( lua_State* L );
+ static int _init ( lua_State* L );
+ static int _isEnabled ( lua_State* L );
+
+ // project interface
+ static int _loadProject ( lua_State* L );
+ static int _unloadProject ( lua_State* L );
+ static int _loadVoiceProject ( lua_State* L );
+ static int _unloadAllVoiceProjects ( lua_State* L );
+
+ // group interface
+ static int _loadGroup ( lua_State* L );
+ static int _unloadGroup ( lua_State* L );
+ static int _unloadPendingUnloads ( lua_State* L );
+
+ // sound category interface
+ static int _setSoundCategoryVolume ( lua_State* L );
+ static int _getSoundCategoryVolume ( lua_State* L );
+ static int _muteSoundCategory ( lua_State* L );
+ static int _isSoundCategoryMuted ( lua_State* L );
+ static int _pauseSoundCategory ( lua_State* L );
+ static int _isSoundCategoryPaused ( lua_State* L );
+
+ // event interface
+ static int _playEvent3D ( lua_State* L );
+ static int _playEvent2D ( lua_State* L );
+ static int _playVoiceLine ( lua_State* L );
+ static int _unloadEvent ( lua_State* L );
+ static int _stopAllEvents ( lua_State* L );
+ static int _muteAllEvents ( lua_State* L );
+ static int _getEventDuration ( lua_State* L );
+
+ // voice line interface
+ static int _preloadVoiceLine ( lua_State* L );
+
+ // game mic interface
+ static int _getMicrophone ( lua_State* L );
+
+ // reverb/global processing interface
+ static int _setDefaultReverb ( lua_State* L );
+ static int _setDistantOcclusion ( lua_State* L );
+ static int _setNear2DBlend ( lua_State* L );
+
+public:
+
+ DECL_LUA_SINGLETON ( MOAIFmodEventMgr )
+
+ //----------------------------------------------------------------//
+ MOAIFmodEventMgr ();
+ virtual ~MOAIFmodEventMgr ();
+ void RegisterLuaClass ( MOAILuaState& state );
+ void RegisterLuaFuncs ( MOAILuaState& state );
+ MOAIFmodMicrophone* AffirmMic ();
+ const FMODDesigner::Event* GetEvent ( STLString eventName );
+ void AddEvent ( STLString eventName, FMODDesigner::Event& actualEvent );
+
+};
+
+#endif
View
79 src/moaiext-fmod-designer/MOAIFmodMicrophone.cpp
@@ -0,0 +1,79 @@
+// Copyright (c) 2010-2011 Zipline Games, Inc. All Rights Reserved.
+// http://getmoai.com
+
+#include <moaiext-fmod-designer/MOAIFmodMicrophone.h>
+#include <fmod.hpp>
+#include <moaiext-fmod-designer/Source/EventManager.h>
+
+#ifdef MOAI_OS_IPHONE
+ #include <fmodiphone.h>
+#endif
+
+#ifdef MOAI_OS_NACL
+#include <NaClFileSystem.h>
+#include <moai_nacl.h>
+#endif
+
+//================================================================//
+// MOAIFmodMicrophone
+//================================================================//
+
+//----------------------------------------------------------------//
+MOAIFmodMicrophone::MOAIFmodMicrophone () {
+ RTTI_BEGIN
+ RTTI_EXTEND ( MOAITransform )
+ RTTI_END
+}
+
+//----------------------------------------------------------------//
+MOAIFmodMicrophone::~MOAIFmodMicrophone () {
+}
+
+//----------------------------------------------------------------//
+void MOAIFmodMicrophone::RegisterLuaClass ( MOAILuaState& state ) {
+
+ MOAITransform::RegisterLuaClass ( state );
+}
+
+//----------------------------------------------------------------//
+void MOAIFmodMicrophone::RegisterLuaFuncs ( MOAILuaState& state ) {
+
+ MOAITransform::RegisterLuaFuncs ( state );
+
+ luaL_Reg regTable [] = {
+ { "new", MOAILogMessages::_alertNewIsUnsupported },
+ { NULL, NULL }
+ };
+
+ luaL_register ( state, 0, regTable );
+}
+
+//----------------------------------------------------------------//
+bool MOAIFmodMicrophone::ApplyAttrOp ( u32 attrID, MOAIAttrOp& attrOp, u32 op ) {
+
+ bool bReturn = MOAITransform::ApplyAttrOp ( attrID, attrOp, op );
+
+ if ( MOAIFmodMicrophoneAttr::Check ( attrID ) )
+ {
+ USVec3D vPos = GetLocalToWorldMtx().GetTranslation();
+ SetMicLoc ( vPos );
+ }
+
+ return bReturn;
+}
+
+//----------------------------------------------------------------//
+void MOAIFmodMicrophone::OnDepNodeUpdate () {
+
+ MOAITransform::OnDepNodeUpdate ();
+
+ USVec3D vPos = GetLocalToWorldMtx().GetTranslation();
+ SetMicLoc ( vPos );
+}
+
+//----------------------------------------------------------------//
+
+void MOAIFmodMicrophone::SetMicLoc ( USVec3D& vPos )
+{
+ FMODDesigner::tEventManager.SetMicrophoneTransform( vPos );
+}
View
40 src/moaiext-fmod-designer/MOAIFmodMicrophone.h
@@ -0,0 +1,40 @@
+// Copyright (c) 2010-2011 Zipline Games, Inc. All Rights Reserved.
+// http://getmoai.com
+
+#ifndef MOAIFMODMICROPHONE_H
+#define MOAIFMODMICROPHONE_H
+
+#include <moaicore/moaicore.h>
+
+//================================================================//
+// MOAIFmodMicrophone
+//================================================================//
+/** @name MOAIFmodMicrophone
+ @text The in-game Microphone, with respect to which
+ all the sounds are heard in the game. The Event Manager
+ (MOAIFmodEventManager) must be initialized before the
+ Microphone can be accessed. Should only be grabbed from
+ MOAIFmodEventMgr
+*/
+class MOAIFmodMicrophone :
+ public MOAITransform {
+private:
+
+ //----------------------------------------------------------------//
+
+public:
+
+ DECL_LUA_FACTORY ( MOAIFmodMicrophone )
+ DECL_ATTR_HELPER ( MOAIFmodMicrophone )
+
+ //----------------------------------------------------------------//
+ MOAIFmodMicrophone ();
+ virtual ~MOAIFmodMicrophone ();
+ bool ApplyAttrOp ( u32 attrID, MOAIAttrOp& attrOp, u32 op );
+ void OnDepNodeUpdate ();
+ void RegisterLuaClass ( MOAILuaState& state );
+ void RegisterLuaFuncs ( MOAILuaState& state );
+ void SetMicLoc ( USVec3D& vPos );
+};
+
+#endif
View
146 src/moaiext-fmod-designer/Source/Common.h
@@ -0,0 +1,146 @@
+#ifndef _COMMON_H
+#define _COMMON_H
+
+#include <uslscore/uslscore.h>
+#include <float.h>
+
+//-----------------------------------------------------------------------------
+// Constants
+//-----------------------------------------------------------------------------
+
+#define KILO (1024)
+#define MEG (KILO * KILO)
+#define GIG (KILO * MEG)
+#define FILE_SEP_CHAR '/'
+
+
+//-----------------------------------------------------------------------------
+// Helper Functions and Macros
+//-----------------------------------------------------------------------------
+
+# define NOINLINE(FunctionDef) __declspec(noinline) FunctionDef
+
+/// Return if _ptr is aligned to _align (which must be a power of 2)
+/// @eg
+/// ASSERT(IS_ALIGNED(ptr, 128));
+/// @endeg
+#define IS_ALIGNED(_ptr, _align) (((uintptr_t(_ptr)) & ((_align)-1)) == 0)
+
+/// Return n, constrained to be within the range [min, max].
+template <class T> inline T Pin(const T n, const T min, const T max)
+{
+ return Min(Max(n, min), max);
+}
+
+inline bool Equal(float fA, float fB, float fEpsilon)
+{
+ return fabsf(fA - fB) <= fEpsilon;
+}
+
+inline float FSel(float fComparand, float fValGE, float fValLT)
+{
+ return (fComparand >= 0.f) ? fValGE : fValLT;
+}
+
+template <class T> inline T Square(const T x)
+{
+ return x * x;
+}
+
+inline float Lerp(float fA, float fB, float fT)
+{
+ return (1.f-fT) * fA + fT * fB;
+}
+
+//-----------------------------------------------------------------------------
+// Helper Classes
+//-----------------------------------------------------------------------------
+
+/// Handy class for representing ranges of numbers.
+template< typename T >
+struct Range
+{
+ Range( T _min, T _max )
+ {
+ min = _min;
+ max = _max;
+ assert( min <= max );
+ }
+
+ Range()
+ {
+ min = 0;
+ max = 0;
+ }
+
+ static Range<T> FromUnsorted(T first, T second)
+ {
+ return Range(Min(first,second), Max(first,second));
+ }
+
+ bool operator==(const Range<T>& rhs) const
+ {
+ return (min == rhs.min && max == rhs.max);
+ }
+
+ void Set( T _min, T _max )
+ {
+ assert( _min <= _max );
+ min = _min;
+ max = _max;
+ }
+
+ bool Contains( T arg ) const
+ {
+ return arg >= min && arg <= max;
+ }
+
+ bool ContainsSquared( T arg ) const
+ {
+ return arg >= Square(min) && arg <= Square(max);
+ }
+
+ /// Scales and biases the input so that values within the range are mapped to [0, 1]
+ T ToParam( T arg ) const
+ {
+ return (arg - min) / (max - min);
+ }
+
+ bool GetOverlap( const Range<T>& Other, Range<T>* pOutResult = NULL ) const
+ {
+ float fMin = Max( min, Other.min );
+ float fMax = Min( max, Other.max );
+ if ( fMin <= fMax )
+ {
+ if ( pOutResult )
+ {
+ *pOutResult = Range<T>( fMin, fMax );
+ }
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ T Delta() const
+ {
+ return max - min;
+ }
+
+ union {
+ struct {
+ T min, max;
+ };
+
+ T m[2];
+ };
+};
+
+#define PROFILE_TIME_REGION(name)
+#define PROFILE_TIME_REGION_FAST(name)
+//#define Trace( arg1, arg2, msg, ... ) printf( msg, __VA_ARGS__ )
+#define Trace( arg1, arg2, msg, ... )
+
+#endif // _Common_H_
View
21 src/moaiext-fmod-designer/Source/DuckingRequest.h
@@ -0,0 +1,21 @@
+#ifndef _DUCKING_REQUEST_H_
+#define _DUCKING_REQUEST_H_
+
+namespace FMODDesigner
+{
+ class DuckingRequestHandle
+ {
+ public:
+ explicit DuckingRequestHandle( int id = kINVALID_HANDLE ) : m_id( id ) {}
+
+ int GetID() const { return m_id; }
+
+ private:
+ friend class EventManager;
+ int m_id;
+
+ static const int kINVALID_HANDLE = -1;
+ };
+};
+
+#endif
View
211 src/moaiext-fmod-designer/Source/Event.cpp
@@ -0,0 +1,211 @@
+#include "Event.h"
+
+#include "EventParameter.h"
+#include "EventProperties.h"
+#include "EventManager.h"
+#include "LineCode.h"
+
+using namespace FMODDesigner;
+
+Event::Event() :
+ m_pInternalData((InternalData)kINVALID_EVENT_INDEX),
+ m_rawSound(false)
+{
+}
+
+Event::Event( const STLString& eventName ) :
+ m_eventName(eventName),
+ m_pInternalData((InternalData)kINVALID_EVENT_INDEX),
+ m_rawSound(false)
+{
+}
+
+Event::Event( InternalData pData ) :
+ m_pInternalData(pData),
+ m_rawSound(true)
+{
+}
+
+float Event::GetDuration(const LineCode* pLineCode) const
+{
+ PROFILE_TIME_REGION_FAST(sg_SoundZone);
+
+ if ( IsValid() )
+ {
+ FMOD_RESULT result = FMOD_OK;
+ if (pLineCode && *pLineCode != kINVALID_LINECODE && pLineCode->GetIndex() < g_WavbankEntries.size())
+ {
+ return g_WavbankEntries[pLineCode->GetIndex()].GetLength();
+ }
+
+ if( !m_rawSound )
+ {
+ const EventProperties* pProperties = tEventManager.GetEventProperties( *this );
+ if( pProperties )
+ {
+ return pProperties->m_duration;
+ }
+ }
+ else
+ {
+ FMOD::Sound* pSound = (FMOD::Sound*)m_pInternalData;
+ u32 length = 0;
+ result = pSound->getLength( &length, FMOD_TIMEUNIT_MS );
+ if( result == FMOD_OK )
+ {
+ return length * 0.001f;
+ }
+ }
+
+ HANDLE_FMOD_ERROR( result );
+ }
+ return 0.f;
+}
+
+void Event::GetParameterIndex( EventParameter& param, const STLString& paramName ) const
+{
+ PROFILE_TIME_REGION_FAST(sg_SoundZone);
+
+ assert( !m_rawSound );
+
+ param.m_index = EventParameter::kINVALID_INDEX;
+
+ if( IsValid() && !m_rawSound )
+ {
+ const EventProperties* pProperties = tEventManager.GetEventProperties( *this );
+ if( pProperties )
+ {
+ param.m_index = EventParameter::kINVALID_INDEX;
+ STLMap<STLString, int>::const_iterator it = pProperties->m_aParams.find( paramName );
+ if( it != pProperties->m_aParams.end() )
+ {
+ param.m_index = it->second;
+ }
+ }
+ }
+}
+
+bool Event::IsValid() const
+{
+ PROFILE_TIME_REGION_FAST(sg_SoundZone);
+
+ if( !m_rawSound )
+ {
+ assert( !m_rawSound );
+
+ // This is a lazy setting of the cached ID
+ if( (int)m_pInternalData == kINVALID_EVENT_INDEX &&
+ m_eventName.length() > 0 &&
+ s_pFMODEventSystem )
+ {
+ FMOD_RESULT result = FMOD_OK;
+
+ FMOD::Event* pEvent = NULL;
+
+ const EventProperties* pProperties = tEventManager.GetEventProperties( *this );
+ if( pProperties )
+ {
+ FMOD::EventProject* pProject = NULL;
+ result = s_pFMODEventSystem->getProjectByIndex( pProperties->m_projectId, &pProject );
+ if( result == FMOD_OK )
+ {
+ result = pProject->getEventByProjectID( pProperties->m_id, FMOD_EVENT_INFOONLY, &pEvent );
+ }
+ }
+
+ if( result == FMOD_OK &&
+ pEvent )
+ {
+ int groupIndex = -1;
+ char* pszName = NULL;
+ FMOD_EVENT_INFO info;
+ memset( &info, 0, sizeof(FMOD_EVENT_INFO) );
+ result = pEvent->getInfo(&groupIndex, &pszName, &info);
+ if (result == FMOD_OK)
+ {
+ m_pInternalData = (InternalData)info.systemid;
+ }
+ }
+
+ HANDLE_FMOD_ERROR( result );
+ }
+
+ return ( (int)m_pInternalData != kINVALID_EVENT_INDEX );
+ }
+ else
+ {
+ return m_pInternalData != NULL;
+ }
+}
+
+void Event::DownsampleInto(vector<u8>& aDstBuffer, u32 targetFrequency) const
+{
+ if( m_rawSound )
+ {
+ FMOD::Sound* pSound = (FMOD::Sound*)m_pInternalData;
+
+ FMOD::System* pSystem = NULL;
+ FMOD_RESULT result = s_pFMODEventSystem->getSystemObject( &pSystem );
+ int systemSampleRate = 0;
+ result = pSystem->getSoftwareFormat( &systemSampleRate, NULL, NULL, NULL, NULL, NULL );
+
+ FMOD_SOUND_TYPE soundType = FMOD_SOUND_TYPE_UNKNOWN;
+ FMOD_SOUND_FORMAT soundFormat = FMOD_SOUND_FORMAT_NONE;
+ result = pSound->getFormat(&soundType, &soundFormat, NULL, NULL);
+ assert( soundType == FMOD_SOUND_TYPE_RAW && soundFormat == FMOD_SOUND_FORMAT_PCM16 );
+
+ u32 length = 0;
+ result = pSound->getLength( &length, FMOD_TIMEUNIT_PCM );
+ u8* pSrcBuffer = NULL;
+ u32 len1, len2;
+ result = pSound->lock(0, length * 2, (void**)&pSrcBuffer, NULL, &len1, &len2 );
+
+ u32 skipRate = systemSampleRate / targetFrequency;
+ aDstBuffer.clear();
+ aDstBuffer.resize((length / skipRate) * 2);
+ for( u32 i = 0; i < aDstBuffer.size(); i += 2 )
+ {
+ aDstBuffer[i] = pSrcBuffer[i * skipRate];
+ aDstBuffer[i+1] = pSrcBuffer[i * skipRate + 1];
+ }
+
+ result = pSound->unlock(pSrcBuffer, NULL, len1, len2);
+ }
+ else
+ {
+ Trace(TT_Sound, TL_Error, "Can only downsample raw sounds.");
+ }
+}
+
+void Event::CopyInto(vector<u8>& aDstBuffer) const
+{
+ if( m_rawSound )
+ {
+ FMOD::Sound* pSound = (FMOD::Sound*)m_pInternalData;
+
+ FMOD_SOUND_TYPE soundType = FMOD_SOUND_TYPE_UNKNOWN;
+ FMOD_SOUND_FORMAT soundFormat = FMOD_SOUND_FORMAT_NONE;
+ FMOD_RESULT result = pSound->getFormat(&soundType, &soundFormat, NULL, NULL);
+ assert( soundType == FMOD_SOUND_TYPE_RAW && soundFormat == FMOD_SOUND_FORMAT_PCM16 );
+
+ u32 length = 0;
+ result = pSound->getLength( &length, FMOD_TIMEUNIT_PCM );
+ u8* pSrcBuffer = NULL;
+ u32 len1, len2;
+ result = pSound->lock(0, length * 2, (void**)&pSrcBuffer, NULL, &len1, &len2 );
+
+ aDstBuffer.clear();
+ aDstBuffer.resize(length * 2);
+ for( u32 i = 0; i < aDstBuffer.size(); i += 2 )
+ {
+ aDstBuffer[i] = pSrcBuffer[i];
+ aDstBuffer[i+1] = pSrcBuffer[i + 1];
+ }
+
+ result = pSound->unlock(pSrcBuffer, NULL, len1, len2);
+ }
+ else
+ {
+ Trace(TT_Sound, TL_Error, "Can only copy into raw sounds.");
+ }
+}
View
52 src/moaiext-fmod-designer/Source/Event.h
@@ -0,0 +1,52 @@
+#ifndef _EVENT_H_
+#define _EVENT_H_
+
+#define kINVALID_EVENT_INDEX -1
+#include "Common.h"
+#include <uslscore/pch.h>
+#include <uslscore/STLString.h>
+
+namespace FMODDesigner
+{
+ class EventManager;
+ class EventParameter;
+ class LineCode;
+
+ /// \class Event
+ /// The definition of a sound.
+ class Event
+ {
+ friend class EventManager;
+ typedef void* InternalData;
+ public:
+ Event();
+ explicit Event( const STLString& eventName );
+ explicit Event( InternalData pData );
+ // default copy-constructor and assignment operator
+
+ bool IsValid() const;
+ float GetDuration(const LineCode* pLineCode = NULL) const; //< 0 is looping
+ void GetParameterIndex( EventParameter& param, const STLString& paramName ) const;
+
+ const STLString& GetName() const { return m_eventName; }
+ void SetName( const STLString& eventName ) { m_eventName = eventName; }
+ bool IsRawSound() const { return m_rawSound; }
+ void* GetInternals() const { return m_pInternalData; }
+
+ void DownsampleInto(vector<u8>& aDstBuffer, u32 targetFrequency) const;
+ void CopyInto(vector<u8>& aDstBuffer) const;
+
+ bool operator==( const Event& rhs ) const { return m_eventName == rhs.m_eventName; }
+ bool operator!=( const Event& rhs ) const { return m_eventName != rhs.m_eventName; }
+
+ private:
+ void _SetSoundID() const;
+
+ STLString m_eventName;
+ mutable InternalData m_pInternalData;
+ bool m_rawSound;
+ };
+};
+
+
+#endif
View
13 src/moaiext-fmod-designer/Source/EventHandle.h
@@ -0,0 +1,13 @@
+#ifndef _SOUND_HANDLE_H_
+#define _SOUND_HANDLE_H_
+
+#include "HandleFactory.h"
+
+namespace FMODDesigner
+{
+ class EventInstance;
+
+ typedef HandleFactory<EventInstance>::Handle EventHandle;
+};
+
+#endif