123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337 |
- //-----------------------------------------------------------------------------
- // 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() );
- }
- }
|