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
# 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"
# include "MetasoundStandardNodesNames.h"
# include "MetasoundTrigger.h"
# include "MetasoundTime.h"
# include "DSP/VolumeFader.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 ) ;
FInterpToOperator ( const FOperatorSettings & InSettings , const FFloatReadRef & InTargetValue , const FTimeReadRef & InInterpTime ) ;
virtual FDataReferenceCollection GetInputs ( ) const override ;
virtual FDataReferenceCollection GetOutputs ( ) const override ;
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 ;
} ;
FInterpToOperator : : FInterpToOperator ( const FOperatorSettings & InSettings , const FFloatReadRef & InTargetValue , const FTimeReadRef & InInterpTime )
: TargetValue ( InTargetValue )
, InterpTime ( InInterpTime )
, ValueOutput ( FFloatWriteRef : : CreateNew ( * TargetValue ) )
{
// Set the fade to start at the value specified in the current value
VolumeFader . SetVolume ( * TargetValue ) ;
float BlockRate = InSettings . GetActualBlockRate ( ) ;
BlockTimeDelta = 1.0f / BlockRate ;
PreviousTargetValue = * TargetValue ;
2021-12-13 13:14:24 -05:00
* ValueOutput = * TargetValue ;
2021-02-19 19:45:59 -04:00
}
FDataReferenceCollection FInterpToOperator : : GetInputs ( ) const
{
2022-03-17 13:14:50 -04:00
using namespace InterpToVertexNames ;
2021-02-19 19:45:59 -04:00
FDataReferenceCollection InputDataReferences ;
2022-03-17 13:14:50 -04:00
InputDataReferences . AddDataReadReference ( METASOUND_GET_PARAM_NAME ( InParamTarget ) , FFloatReadRef ( TargetValue ) ) ;
InputDataReferences . AddDataReadReference ( METASOUND_GET_PARAM_NAME ( InParamInterpTime ) , FTimeReadRef ( InterpTime ) ) ;
2021-02-19 19:45:59 -04:00
return InputDataReferences ;
}
FDataReferenceCollection FInterpToOperator : : GetOutputs ( ) const
{
2022-03-17 13:14:50 -04:00
using namespace InterpToVertexNames ;
2021-02-19 19:45:59 -04:00
FDataReferenceCollection OutputDataReferences ;
2022-03-17 13:14:50 -04:00
OutputDataReferences . AddDataReadReference ( METASOUND_GET_PARAM_NAME ( OutParamValue ) , FFloatReadRef ( ValueOutput ) ) ;
2021-02-19 19:45:59 -04:00
return OutputDataReferences ;
}
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 ;
Info . DefaultInterface = GetVertexInterface ( ) ;
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
return MakeUnique < FInterpToOperator > ( InParams . OperatorSettings , TargetValue , InterpTime ) ;
}
METASOUND_REGISTER_NODE ( FInterpToNode )
}
2021-04-06 18:56:44 -04:00
# undef LOCTEXT_NAMESPACE //MetasoundStandardNodes_InterpNode