mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-01-20 04:34:48 +00:00
338 lines
10 KiB
C++
338 lines
10 KiB
C++
//-----------------------------------------------------------------------------
|
|
// Copyright (c) 2012 GarageGames, LLC
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
// of this software and associated documentation files (the "Software"), to
|
|
// deal in the Software without restriction, including without limitation the
|
|
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
// sell copies of the Software, and to permit persons to whom the Software is
|
|
// furnished to do so, subject to the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included in
|
|
// all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
// IN THE SOFTWARE.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#include "platform/platform.h"
|
|
#include "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() );
|
|
}
|
|
}
|