2021-02-19 19:45:59 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
2021-04-06 18:56:44 -04:00
# include "MetasoundFacade.h"
2021-02-19 19:45:59 -04:00
2023-08-02 14:38:51 -04:00
# include "DSP/VolumeFader.h"
2021-02-19 19:45:59 -04:00
# include "Internationalization/Text.h"
# include "MetasoundExecutableOperator.h"
# include "MetasoundNodeRegistrationMacro.h"
2022-03-17 13:14:50 -04:00
# include "MetasoundParamHelper.h"
2021-02-19 19:45:59 -04:00
# include "MetasoundPrimitives.h"
2023-08-02 14:38:51 -04:00
# include "MetasoundStandardNodesCategories.h"
2021-02-19 19:45:59 -04:00
# include "MetasoundStandardNodesNames.h"
# include "MetasoundTrigger.h"
# include "MetasoundTime.h"
2021-04-06 18:56:44 -04:00
# define LOCTEXT_NAMESPACE "MetasoundStandardNodes_InterpNode"
2021-02-19 19:45:59 -04:00
namespace Metasound
{
2022-03-17 13:14:50 -04:00
namespace InterpToVertexNames
2021-02-19 19:45:59 -04:00
{
2022-03-17 13:14:50 -04:00
METASOUND_PARAM ( InParamTarget , " Target " , " Target value. " )
METASOUND_PARAM ( InParamInterpTime , " Interp Time " , " The time to interpolate from the current value to the target value. " )
METASOUND_PARAM ( OutParamValue , " Value " , " The current value. " )
2021-02-19 19:45:59 -04:00
}
2021-04-06 18:56:44 -04:00
/** FInterpToNode
*
* Interpolates to a target value over a given time .
*/
class METASOUNDSTANDARDNODES_API FInterpToNode : public FNodeFacade
{
public :
/**
* Constructor used by the Metasound Frontend .
*/
FInterpToNode ( const FNodeInitData & InitData ) ;
} ;
2021-02-19 19:45:59 -04:00
class FInterpToOperator : public TExecutableOperator < FInterpToOperator >
{
public :
static const FNodeClassMetadata & GetNodeInfo ( ) ;
static const FVertexInterface & GetVertexInterface ( ) ;
static TUniquePtr < IOperator > CreateOperator ( const FCreateOperatorParams & InParams , FBuildErrorArray & OutErrors ) ;
2023-03-02 14:40:35 -05:00
FInterpToOperator ( const FCreateOperatorParams & InSettings , const FFloatReadRef & InTargetValue , const FTimeReadRef & InInterpTime ) ;
2021-02-19 19:45:59 -04:00
2023-05-22 13:28:27 -04:00
virtual void BindInputs ( FInputVertexInterfaceData & InOutVertexData ) override ;
virtual void BindOutputs ( FOutputVertexInterfaceData & InOutVertexData ) override ;
2021-02-19 19:45:59 -04:00
virtual FDataReferenceCollection GetInputs ( ) const override ;
virtual FDataReferenceCollection GetOutputs ( ) const override ;
2023-03-02 14:40:35 -05:00
void Reset ( const IOperator : : FResetParams & InParams ) ;
2021-02-19 19:45:59 -04:00
void Execute ( ) ;
private :
// The target value of the lerp. The output will lerp from it's current value to the output value.
FFloatReadRef TargetValue ;
// The amount of time to do lerp
FTimeReadRef InterpTime ;
// The current output value.
FFloatWriteRef ValueOutput ;
// Volume fader object which performs the interpolating
Audio : : FVolumeFader VolumeFader ;
// The time-delta per block
float BlockTimeDelta = 0.0f ;
// The previous target value
float PreviousTargetValue = 0.0f ;
} ;
2023-03-02 14:40:35 -05:00
FInterpToOperator : : FInterpToOperator ( const FCreateOperatorParams & InParams , const FFloatReadRef & InTargetValue , const FTimeReadRef & InInterpTime )
2021-02-19 19:45:59 -04:00
: TargetValue ( InTargetValue )
, InterpTime ( InInterpTime )
, ValueOutput ( FFloatWriteRef : : CreateNew ( * TargetValue ) )
{
2023-03-02 14:40:35 -05:00
Reset ( InParams ) ;
2021-02-19 19:45:59 -04:00
}
2023-05-22 13:28:27 -04:00
void FInterpToOperator : : BindInputs ( FInputVertexInterfaceData & InOutVertexData )
2021-02-19 19:45:59 -04:00
{
2022-03-17 13:14:50 -04:00
using namespace InterpToVertexNames ;
2023-05-22 13:28:27 -04:00
InOutVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( InParamTarget ) , TargetValue ) ;
InOutVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( InParamInterpTime ) , InterpTime ) ;
}
2021-02-19 19:45:59 -04:00
2023-05-22 13:28:27 -04:00
void FInterpToOperator : : BindOutputs ( FOutputVertexInterfaceData & InOutVertexData )
{
using namespace InterpToVertexNames ;
InOutVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( OutParamValue ) , ValueOutput ) ;
}
FDataReferenceCollection FInterpToOperator : : GetInputs ( ) const
{
// This should never be called. Bind(...) is called instead. This method
// exists as a stop-gap until the API can be deprecated and removed.
checkNoEntry ( ) ;
return { } ;
2021-02-19 19:45:59 -04:00
}
FDataReferenceCollection FInterpToOperator : : GetOutputs ( ) const
{
2023-05-22 13:28:27 -04:00
// This should never be called. Bind(...) is called instead. This method
// exists as a stop-gap until the API can be deprecated and removed.
checkNoEntry ( ) ;
return { } ;
2021-02-19 19:45:59 -04:00
}
2023-03-02 14:40:35 -05:00
void FInterpToOperator : : Reset ( const IOperator : : FResetParams & InParams )
{
// Set the fade to start at the value specified in the current value
VolumeFader . SetVolume ( * TargetValue ) ;
float BlockRate = InParams . OperatorSettings . GetActualBlockRate ( ) ;
BlockTimeDelta = 1.0f / BlockRate ;
PreviousTargetValue = * TargetValue ;
* ValueOutput = * TargetValue ;
}
2021-02-19 19:45:59 -04:00
void FInterpToOperator : : Execute ( )
{
// Update the value output with the current value in case it was changed
if ( ! FMath : : IsNearlyEqual ( PreviousTargetValue , * TargetValue ) )
{
PreviousTargetValue = * TargetValue ;
// Start the volume fader on the interp trigger
float FadeSeconds = ( float ) InterpTime - > GetSeconds ( ) ;
VolumeFader . StartFade ( * TargetValue , FadeSeconds , Audio : : EFaderCurve : : Linear ) ;
}
// Perform the fading
if ( VolumeFader . IsFading ( ) )
{
VolumeFader . Update ( BlockTimeDelta ) ;
}
// Update the fader w/ the current volume
* ValueOutput = VolumeFader . GetVolume ( ) ;
}
const FVertexInterface & FInterpToOperator : : GetVertexInterface ( )
{
2022-03-17 13:14:50 -04:00
using namespace InterpToVertexNames ;
2021-02-19 19:45:59 -04:00
static const FVertexInterface Interface (
FInputVertexInterface (
2022-03-31 16:49:59 -04:00
TInputDataVertex < FTime > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( InParamInterpTime ) , 0.1f ) ,
TInputDataVertex < float > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( InParamTarget ) , 1.0f )
2021-02-19 19:45:59 -04:00
) ,
FOutputVertexInterface (
2022-03-31 16:49:59 -04:00
TOutputDataVertex < float > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( OutParamValue ) )
2021-02-19 19:45:59 -04:00
)
) ;
return Interface ;
}
const FNodeClassMetadata & FInterpToOperator : : GetNodeInfo ( )
{
auto InitNodeInfo = [ ] ( ) - > FNodeClassMetadata
{
FNodeClassMetadata Info ;
2021-08-09 15:13:40 -04:00
Info . ClassName = { StandardNodes : : Namespace , TEXT ( " InterpTo " ) , StandardNodes : : AudioVariant } ;
2021-02-19 19:45:59 -04:00
Info . MajorVersion = 1 ;
Info . MinorVersion = 0 ;
2022-02-10 18:36:47 -05:00
Info . DisplayName = METASOUND_LOCTEXT ( " Metasound_InterpDisplayName " , " InterpTo " ) ;
Info . Description = METASOUND_LOCTEXT ( " Metasound_InterpNodeDescription " , " Interpolates between the current value and a target value over the specified time. " ) ;
2021-02-19 19:45:59 -04:00
Info . Author = PluginAuthor ;
Info . PromptIfMissing = PluginNodeMissingPrompt ;
2023-08-02 14:38:51 -04:00
Info . CategoryHierarchy = { NodeCategories : : Math } ;
2021-02-19 19:45:59 -04:00
Info . DefaultInterface = GetVertexInterface ( ) ;
2022-08-17 16:42:56 -04:00
Info . Keywords . Add ( METASOUND_LOCTEXT ( " LerpKeyword " , " Lerp " ) ) ;
2021-02-19 19:45:59 -04:00
return Info ;
} ;
static const FNodeClassMetadata Info = InitNodeInfo ( ) ;
return Info ;
}
2021-04-06 18:56:44 -04:00
FInterpToNode : : FInterpToNode ( const FNodeInitData & InitData )
: FNodeFacade ( InitData . InstanceName , InitData . InstanceID , TFacadeOperatorClass < FInterpToOperator > ( ) )
{
}
2021-02-19 19:45:59 -04:00
TUniquePtr < IOperator > FInterpToOperator : : CreateOperator ( const FCreateOperatorParams & InParams , FBuildErrorArray & OutErrors )
{
2022-03-17 13:14:50 -04:00
using namespace InterpToVertexNames ;
2021-02-19 19:45:59 -04:00
const FInterpToNode & InterpToNode = static_cast < const FInterpToNode & > ( InParams . Node ) ;
const FDataReferenceCollection & InputCollection = InParams . InputDataReferences ;
const FInputVertexInterface & InputInterface = GetVertexInterface ( ) . GetInputInterface ( ) ;
2022-03-17 13:14:50 -04:00
FFloatReadRef TargetValue = InputCollection . GetDataReadReferenceOrConstructWithVertexDefault < float > ( InputInterface , METASOUND_GET_PARAM_NAME ( InParamTarget ) , InParams . OperatorSettings ) ;
FTimeReadRef InterpTime = InputCollection . GetDataReadReferenceOrConstructWithVertexDefault < FTime > ( InputInterface , METASOUND_GET_PARAM_NAME ( InParamInterpTime ) , InParams . OperatorSettings ) ;
2021-02-19 19:45:59 -04:00
2023-03-02 14:40:35 -05:00
return MakeUnique < FInterpToOperator > ( InParams , TargetValue , InterpTime ) ;
2021-02-19 19:45:59 -04:00
}
METASOUND_REGISTER_NODE ( FInterpToNode )
}
2021-04-06 18:56:44 -04:00
# undef LOCTEXT_NAMESPACE //MetasoundStandardNodes_InterpNode