sfxFMODEventSource.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "platform/platform.h"
  23. #include "sfx/fmod/sfxFMODEventSource.h"
  24. #include "sfx/fmod/sfxFMODEvent.h"
  25. #include "sfx/fmod/sfxFMODEventGroup.h"
  26. #include "sfx/fmod/sfxFMODDevice.h"
  27. #include "sfx/sfxDescription.h"
  28. IMPLEMENT_CONOBJECT( SFXFMODEventSource );
  29. ConsoleDocClass( SFXFMODEventSource,
  30. "@brief A sound source controller playing an %FMOD Designer event (SFXFMODEvent).\n\n"
  31. "%FMOD event sources are internally created by the sound system to play events from imported %FMOD Designer projects.\n\n"
  32. "@note This class cannot be instantiated directly by the user. Instead, instances of SFXFMODEventSource will be "
  33. "implicitly created by the sound system when playing an SFXFMODEvent.\n\n"
  34. "@ingroup SFXFMOD\n"
  35. );
  36. //-----------------------------------------------------------------------------
  37. SFXFMODEventSource::SFXFMODEventSource()
  38. : mHandle( NULL )
  39. {
  40. SFXFMODDevice::instance()->smStatNumEventSources ++;
  41. }
  42. //-----------------------------------------------------------------------------
  43. SFXFMODEventSource::SFXFMODEventSource( SFXFMODEvent* event )
  44. : Parent( event ),
  45. mHandle( NULL )
  46. {
  47. SFXFMODDevice::instance()->smStatNumEventSources ++;
  48. // Make sure the group has its data loaded.
  49. SFXFMODEventGroup* group = event->getEventGroup();
  50. if( !group->loadData() )
  51. return;
  52. // Create an event instance.
  53. if( SFXFMODDevice::smFunc->FMOD_EventGroup_GetEvent(
  54. event->getEventGroup()->mHandle,
  55. event->getEventName(),
  56. FMOD_EVENT_DEFAULT,
  57. &mHandle ) != FMOD_OK )
  58. {
  59. Con::errorf( "SFXFMODEventSource::SFXFMODEventSource - failed to open event '%s'", event->getQualifiedName().c_str() );
  60. mHandle = NULL;
  61. }
  62. }
  63. //-----------------------------------------------------------------------------
  64. SFXFMODEventSource::~SFXFMODEventSource()
  65. {
  66. SFXFMODDevice::instance()->smStatNumEventSources --;
  67. if( mHandle )
  68. SFXFMODDevice::smFunc->FMOD_Event_Release( mHandle, true, true );
  69. if( getEvent() )
  70. getEvent()->getEventGroup()->freeData();
  71. }
  72. //-----------------------------------------------------------------------------
  73. SFXFMODEventSource* SFXFMODEventSource::create( SFXFMODEvent* event )
  74. {
  75. AssertFatal( event != NULL, "SFXFMODEventSource::create - got a NULL event!" );
  76. // Create the source.
  77. SFXFMODEventSource* source = new SFXFMODEventSource( event );
  78. if( source->mHandle )
  79. source->registerObject();
  80. else
  81. {
  82. delete source;
  83. source = NULL;
  84. }
  85. return source;
  86. }
  87. //-----------------------------------------------------------------------------
  88. void SFXFMODEventSource::play( F32 fadeInTime )
  89. {
  90. if( getStatus() == SFXStatusPlaying )
  91. return;
  92. if( isPaused() )
  93. SFXFMODDevice::smFunc->FMOD_Event_SetPaused( mHandle, false );
  94. else
  95. {
  96. AssertFatal( getEvent()->getEventGroup()->isDataLoaded(), "SFXFMODEventSource::play() - event data for group not loaded" );
  97. if( fadeInTime != -1.f )
  98. {
  99. U32 fade = U32( fadeInTime * 1000.f );
  100. SFXFMODDevice::smFunc->FMOD_Event_SetPropertyByIndex(
  101. mHandle, FMOD_EVENTPROPERTY_FADEIN,
  102. &fade, true
  103. );
  104. }
  105. FMOD_RESULT result = SFXFMODDevice::smFunc->FMOD_Event_Start( mHandle );
  106. if( result != FMOD_OK )
  107. {
  108. Con::errorf( "SFXFMODEventSoure::play() - failed to start event: %s", FMODResultToString( result ).c_str() );
  109. return;
  110. }
  111. }
  112. mPlayTimer.start();
  113. _setStatus( SFXStatusPlaying );
  114. _play();
  115. }
  116. //-----------------------------------------------------------------------------
  117. void SFXFMODEventSource::stop( F32 fadeOutTime )
  118. {
  119. if( getStatus() == SFXStatusStopped )
  120. return;
  121. AssertFatal( mHandle, "SFXFMODEvent::stop() - event not acquired" );
  122. bool immediate = ( fadeOutTime == 0.f );
  123. FMOD_RESULT result = SFXFMODDevice::smFunc->FMOD_Event_Stop( mHandle, immediate );
  124. if( result != FMOD_OK )
  125. Con::errorf( "SFXFMODEventSource::stop() - failed to stop event: %s", FMODResultToString( result ).c_str() );
  126. mPlayTimer.stop();
  127. _setStatus( SFXStatusStopped );
  128. // Reset fade-in to default in case it got overwritten
  129. // in play().
  130. U32 fade = U32( mFadeInTime * 1000.f );
  131. SFXFMODDevice::smFunc->FMOD_Event_SetPropertyByIndex(
  132. mHandle, FMOD_EVENTPROPERTY_FADEIN,
  133. &fade, true
  134. );
  135. _stop();
  136. }
  137. //-----------------------------------------------------------------------------
  138. void SFXFMODEventSource::pause( F32 fadeOutTime )
  139. {
  140. if( getStatus() != SFXStatusPlaying )
  141. return;
  142. SFXFMODDevice::smFunc->FMOD_Event_SetPaused( mHandle, true );
  143. mPlayTimer.pause();
  144. _setStatus( SFXStatusPaused );
  145. _pause();
  146. }
  147. //-----------------------------------------------------------------------------
  148. void SFXFMODEventSource::setTransform( const MatrixF& transform )
  149. {
  150. Parent::setTransform( transform );
  151. _update3DAttributes();
  152. }
  153. //-----------------------------------------------------------------------------
  154. void SFXFMODEventSource::setVelocity( const VectorF& velocity )
  155. {
  156. Parent::setVelocity( velocity );
  157. _update3DAttributes();
  158. }
  159. //-----------------------------------------------------------------------------
  160. void SFXFMODEventSource::_update3DAttributes()
  161. {
  162. FMOD_VECTOR position;
  163. FMOD_VECTOR velocity;
  164. FMOD_VECTOR orientation;
  165. Point3F direction;
  166. getTransform().getColumn( 1, &direction );
  167. TorqueVectorToFMODVector( getTransform().getPosition(), position );
  168. TorqueVectorToFMODVector( getVelocity(), velocity );
  169. TorqueVectorToFMODVector( direction, orientation );
  170. SFXFMODDevice::smFunc->FMOD_Event_Set3DAttributes( mHandle, &position, &velocity, &orientation );
  171. }
  172. //-----------------------------------------------------------------------------
  173. void SFXFMODEventSource::_updateStatus()
  174. {
  175. if( mStatus == SFXStatusPlaying )
  176. {
  177. if( !getEvent() )
  178. _setStatus( SFXStatusStopped );
  179. else
  180. {
  181. FMOD_EVENT_STATE state;
  182. SFXFMODDevice::smFunc->FMOD_Event_GetState( mHandle, &state );
  183. if( !( state & FMOD_EVENT_STATE_PLAYING ) )
  184. _setStatus( SFXStatusStopped );
  185. }
  186. }
  187. }
  188. //-----------------------------------------------------------------------------
  189. void SFXFMODEventSource::_updateVolume( const MatrixF& listener )
  190. {
  191. F32 oldPreAttenuatedVolume = mPreAttenuatedVolume;
  192. Parent::_updateVolume( listener );
  193. if( oldPreAttenuatedVolume != mPreAttenuatedVolume )
  194. SFXFMODDevice::smFunc->FMOD_Event_SetVolume( mHandle, mPreAttenuatedVolume );
  195. }
  196. //-----------------------------------------------------------------------------
  197. void SFXFMODEventSource::_updatePitch()
  198. {
  199. F32 oldEffectivePitch = mEffectivePitch;
  200. Parent::_updatePitch();
  201. if( mEffectivePitch != oldEffectivePitch )
  202. SFXFMODDevice::smFunc->FMOD_Event_SetPitch( mHandle, mEffectivePitch - 1.0f, FMOD_EVENT_PITCHUNITS_RAW );
  203. }
  204. //-----------------------------------------------------------------------------
  205. void SFXFMODEventSource::_updatePriority()
  206. {
  207. //TODO
  208. Parent::_updatePriority();
  209. }
  210. //-----------------------------------------------------------------------------
  211. void SFXFMODEventSource::_setMinMaxDistance( F32 min, F32 max )
  212. {
  213. Parent::_setMinMaxDistance( min, max );
  214. _update3DAttributes();
  215. }
  216. //-----------------------------------------------------------------------------
  217. void SFXFMODEventSource::_setFadeTimes( F32 fadeInTime, F32 fadeOutTime )
  218. {
  219. Parent::_setFadeTimes( fadeInTime, fadeOutTime );
  220. U32 fadeIn = U32( mFadeInTime * 1000.f );
  221. SFXFMODDevice::smFunc->FMOD_Event_SetPropertyByIndex(
  222. mHandle, FMOD_EVENTPROPERTY_FADEIN,
  223. &fadeIn, true
  224. );
  225. U32 fadeOut = U32( mFadeOutTime * 1000.f );
  226. SFXFMODDevice::smFunc->FMOD_Event_SetPropertyByIndex(
  227. mHandle, FMOD_EVENTPROPERTY_FADEOUT,
  228. &fadeOut, true
  229. );
  230. }
  231. //-----------------------------------------------------------------------------
  232. void SFXFMODEventSource::_setCone( F32 innerAngle, F32 outerAngle, F32 outerVolume )
  233. {
  234. Parent::_setCone( innerAngle, outerAngle, outerVolume );
  235. _update3DAttributes();
  236. }
  237. //-----------------------------------------------------------------------------
  238. void SFXFMODEventSource::_onParameterEvent( SFXParameter* parameter, SFXParameterEvent event )
  239. {
  240. Parent::_onParameterEvent( parameter, event );
  241. // If it's a value-change on a custom parameter,
  242. // pass it along to FMOD.
  243. if( getEvent()
  244. && event == SFXParameterEvent_ValueChanged
  245. && parameter->getChannel() == SFXChannelUser0 )
  246. {
  247. const char* name = parameter->getInternalName();
  248. FMOD_EVENTPARAMETER* fmodParameter;
  249. if( SFXFMODDevice::smFunc->FMOD_Event_GetParameter( mHandle, name, &fmodParameter ) != FMOD_OK )
  250. {
  251. Con::errorf( "SFXFMODEventSource::_onParameterEvent - could not access parameter '%s' of event '%s'",
  252. name, getEvent()->getQualifiedName().c_str() );
  253. return;
  254. }
  255. SFXFMODDevice::smFunc->FMOD_EventParameter_SetValue( fmodParameter, parameter->getValue() );
  256. }
  257. }