2021-02-23 20:16:28 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
# include "Internationalization/Text.h"
2021-04-05 20:22:19 -04:00
# include "MetasoundEnumRegistrationMacro.h"
2021-02-23 20:16:28 -04:00
# include "MetasoundExecutableOperator.h"
# include "MetasoundNodeRegistrationMacro.h"
2021-02-26 17:38:00 -04:00
# include "MetasoundDataTypeRegistrationMacro.h"
2022-03-17 13:14:50 -04:00
# include "MetasoundParamHelper.h"
2021-02-23 20:16:28 -04:00
# include "MetasoundPrimitives.h"
# include "MetasoundStandardNodesNames.h"
# include "MetasoundTrigger.h"
# include "MetasoundTime.h"
# include "MetasoundAudioBuffer.h"
# include "DSP/Delay.h"
2021-04-03 18:40:14 -04:00
# include "MetasoundStandardNodesCategories.h"
# include "MetasoundFacade.h"
2021-02-23 20:16:28 -04:00
2021-04-07 02:57:54 -04:00
# define LOCTEXT_NAMESPACE "MetasoundStandardNodes_StereoDelayNode"
2021-02-23 20:16:28 -04:00
namespace Metasound
{
namespace StereoDelay
{
2024-08-15 03:13:21 -04:00
METASOUND_PARAM ( InputResetDelay , " Reset " , " Resets the delay buffer. " ) ;
2022-03-17 13:14:50 -04:00
METASOUND_PARAM ( InAudioInputLeft , " In Left " , " Left channel audio input. " )
METASOUND_PARAM ( InAudioInputRight , " In Right " , " Right channel audio input. " )
METASOUND_PARAM ( InDelayMode , " Delay Mode " , " Delay mode. " )
METASOUND_PARAM ( InDelayTime , " Delay Time " , " The amount of time to delay the audio. " )
METASOUND_PARAM ( InDelayRatio , " Delay Ratio " , " Delay spread for left and right channels. Allows left and right channels to have differential delay amounts. Useful for stereo channel decorrelation " )
METASOUND_PARAM ( InDryLevel , " Dry Level " , " The dry level of the delay. " )
METASOUND_PARAM ( InWetLevel , " Wet Level " , " The wet level of the delay. " )
METASOUND_PARAM ( InFeedbackAmount , " Feedback " , " Feedback amount. " )
2023-10-31 19:12:26 -04:00
METASOUND_PARAM ( InParamMaxDelayTime , " Max Delay Time " , " The maximum amount of time to delay the audio. " )
2022-03-17 13:14:50 -04:00
METASOUND_PARAM ( OutAudioLeft , " Out Left " , " Left channel audio output. " )
METASOUND_PARAM ( OutAudioRight , " Out Right " , " Right channel audio output. " )
2021-02-23 20:16:28 -04:00
2023-10-31 19:12:26 -04:00
static constexpr float MinDelaySeconds = 0.001f ;
static constexpr float MaxDelaySeconds = 1000.f ;
static constexpr float DefaultMaxDelaySeconds = 2.5f ;
2021-02-23 20:16:28 -04:00
}
2021-02-26 17:38:00 -04:00
enum class EStereoDelayMode
{
Normal = 0 ,
Cross ,
PingPong ,
} ;
DECLARE_METASOUND_ENUM ( EStereoDelayMode , EStereoDelayMode : : Normal , METASOUNDSTANDARDNODES_API ,
FEnumStereoDelayMode , FEnumStereoDelayModeInfo , FStereoDelayModeReadRef , FEnumStereoDelayModeWriteRef ) ;
DEFINE_METASOUND_ENUM_BEGIN ( EStereoDelayMode , FEnumStereoDelayMode , " StereoDelayMode " )
2022-02-10 18:36:47 -05:00
DEFINE_METASOUND_ENUM_ENTRY ( EStereoDelayMode : : Normal , " StereoDelayModeNormalDescription " , " Normal " , " StereoDelayModeNormalDescriptionTT " , " Left input mixes with left delay output and feeds to left output. " ) ,
DEFINE_METASOUND_ENUM_ENTRY ( EStereoDelayMode : : Cross , " StereoDelayModeCrossDescription " , " Cross " , " StereoDelayModeCrossDescriptionTT " , " Left input mixes with right delay output and feeds to right output. " ) ,
DEFINE_METASOUND_ENUM_ENTRY ( EStereoDelayMode : : PingPong , " StereoDelayModePingPongDescription " , " Ping Pong " , " StereoDelayModePingPongDescriptionTT " , " Left input mixes with left delay output and feeds to right output. " ) ,
2021-02-26 17:38:00 -04:00
DEFINE_METASOUND_ENUM_END ( )
2021-02-23 20:16:28 -04:00
class FStereoDelayOperator : public TExecutableOperator < FStereoDelayOperator >
{
public :
static const FNodeClassMetadata & GetNodeInfo ( ) ;
static const FVertexInterface & GetVertexInterface ( ) ;
2023-10-13 19:29:51 -04:00
static TUniquePtr < IOperator > CreateOperator ( const FBuildOperatorParams & InParams , FBuildResults & OutResults ) ;
2021-02-23 20:16:28 -04:00
2024-08-15 03:13:21 -04:00
FStereoDelayOperator (
const FOperatorSettings & InSettings ,
2021-02-23 20:16:28 -04:00
const FAudioBufferReadRef & InLeftAudioInput ,
const FAudioBufferReadRef & InRightAudioInput ,
2021-02-26 17:38:00 -04:00
const FStereoDelayModeReadRef & InStereoDelayMode ,
2021-02-23 20:16:28 -04:00
const FTimeReadRef & InDelayTime ,
2021-02-26 17:38:00 -04:00
const FFloatReadRef & InDelayRatio ,
2021-02-23 20:16:28 -04:00
const FFloatReadRef & InDryLevel ,
const FFloatReadRef & InWetLevel ,
2023-10-31 19:12:26 -04:00
const FFloatReadRef & InFeedback ,
2024-08-15 03:13:21 -04:00
float InMaxDelayTimeSeconds ,
const FTriggerReadRef & InTriggerReset ) ;
2021-02-23 20:16:28 -04:00
2023-05-22 13:28:27 -04:00
virtual void BindInputs ( FInputVertexInterfaceData & InOutVertexData ) override ;
virtual void BindOutputs ( FOutputVertexInterfaceData & InOutVertexData ) override ;
2021-02-23 20:16:28 -04:00
virtual FDataReferenceCollection GetInputs ( ) const override ;
virtual FDataReferenceCollection GetOutputs ( ) const override ;
void Execute ( ) ;
2023-03-02 14:40:35 -05:00
void Reset ( const IOperator : : FResetParams & InParams ) ;
2021-02-23 20:16:28 -04:00
private :
2021-02-26 17:38:00 -04:00
float GetInputDelayTimeMsecClamped ( ) const ;
float GetInputDelayRatioClamped ( ) const ;
2021-02-23 20:16:28 -04:00
// The input audio buffer
FAudioBufferReadRef LeftAudioInput ;
FAudioBufferReadRef RightAudioInput ;
2021-02-26 17:38:00 -04:00
// Which stereo delay mode to render the audio delay with
FStereoDelayModeReadRef StereoDelayMode ;
2021-02-23 20:16:28 -04:00
// The amount of delay time
FTimeReadRef DelayTime ;
2021-02-26 17:38:00 -04:00
// The stereo delay ratio
FFloatReadRef DelayRatio ;
2021-02-23 20:16:28 -04:00
// The the dry level
FFloatReadRef DryLevel ;
// The the wet level
FFloatReadRef WetLevel ;
// The feedback amount
FFloatReadRef Feedback ;
// The audio output
FAudioBufferWriteRef LeftAudioOutput ;
FAudioBufferWriteRef RightAudioOutput ;
// The internal delay buffer
Audio : : FDelay LeftDelayBuffer ;
Audio : : FDelay RightDelayBuffer ;
2021-02-26 17:38:00 -04:00
// The current delay time and delay ratio
2021-02-23 20:16:28 -04:00
float PrevDelayTimeMsec ;
2021-02-26 17:38:00 -04:00
float PrevDelayRatio ;
2023-10-31 19:12:26 -04:00
// Maximum delay time
float MaxDelayTimeSeconds = StereoDelay : : DefaultMaxDelaySeconds ;
2024-08-15 03:13:21 -04:00
// The reset trigger
FTriggerReadRef TriggerReset ;
2021-02-23 20:16:28 -04:00
} ;
2023-10-31 19:12:26 -04:00
FStereoDelayOperator : : FStereoDelayOperator (
const FOperatorSettings & InSettings ,
2021-02-23 20:16:28 -04:00
const FAudioBufferReadRef & InLeftAudioInput ,
const FAudioBufferReadRef & InRightAudioInput ,
2021-02-26 17:38:00 -04:00
const FStereoDelayModeReadRef & InStereoDelayMode ,
2021-02-23 20:16:28 -04:00
const FTimeReadRef & InDelayTime ,
2021-02-26 17:38:00 -04:00
const FFloatReadRef & InDelayRatio ,
const FFloatReadRef & InDryLevel ,
2021-02-23 20:16:28 -04:00
const FFloatReadRef & InWetLevel ,
2023-10-31 19:12:26 -04:00
const FFloatReadRef & InFeedback ,
2024-08-15 03:13:21 -04:00
float InMaxDelayTimeSeconds ,
const FTriggerReadRef & InTriggerReset )
2021-02-23 20:16:28 -04:00
: LeftAudioInput ( InLeftAudioInput )
, RightAudioInput ( InRightAudioInput )
2021-02-26 17:38:00 -04:00
, StereoDelayMode ( InStereoDelayMode )
2021-02-23 20:16:28 -04:00
, DelayTime ( InDelayTime )
2021-02-26 17:38:00 -04:00
, DelayRatio ( InDelayRatio )
2021-02-23 20:16:28 -04:00
, DryLevel ( InDryLevel )
, WetLevel ( InWetLevel )
, Feedback ( InFeedback )
, LeftAudioOutput ( FAudioBufferWriteRef : : CreateNew ( InSettings ) )
, RightAudioOutput ( FAudioBufferWriteRef : : CreateNew ( InSettings ) )
2024-09-10 10:26:02 -04:00
, PrevDelayTimeMsec ( 0.0f )
2021-02-26 17:38:00 -04:00
, PrevDelayRatio ( GetInputDelayRatioClamped ( ) )
2023-10-31 19:12:26 -04:00
, MaxDelayTimeSeconds ( FMath : : Clamp ( InMaxDelayTimeSeconds , StereoDelay : : MinDelaySeconds , StereoDelay : : MaxDelaySeconds ) )
2024-08-15 03:13:21 -04:00
, TriggerReset ( InTriggerReset )
2021-02-23 20:16:28 -04:00
{
2024-09-10 10:26:02 -04:00
// Depends on MaxDelayTimeSeconds being set first.
PrevDelayTimeMsec = GetInputDelayTimeMsecClamped ( ) ;
2023-10-31 19:12:26 -04:00
LeftDelayBuffer . Init ( InSettings . GetSampleRate ( ) , MaxDelayTimeSeconds ) ;
2021-02-26 17:38:00 -04:00
LeftDelayBuffer . SetDelayMsec ( PrevDelayTimeMsec * ( 1.0f + PrevDelayRatio ) ) ;
2023-10-31 19:12:26 -04:00
RightDelayBuffer . Init ( InSettings . GetSampleRate ( ) , MaxDelayTimeSeconds ) ;
2021-02-26 17:38:00 -04:00
RightDelayBuffer . SetDelayMsec ( PrevDelayTimeMsec * ( 1.0f - PrevDelayRatio ) ) ;
2021-02-23 20:16:28 -04:00
}
2023-05-22 13:28:27 -04:00
void FStereoDelayOperator : : BindInputs ( FInputVertexInterfaceData & InOutVertexData )
{
using namespace StereoDelay ;
[Metasound Bind] Fixup for bind issues caught by new automated tests.
#jira UE-187406, UE-187390, UE-187404, UE-187403, UE-187405, UE-187392, UE-187391, UE-187395, UE-187399, UE-187398, UE-187389, UE-187393, UE-187394, UE-187396, UE-187397, UE-187401
#rb phil.popp
[CL 26130674 by maxwell hayes in ue5-main branch]
2023-06-20 15:08:54 -04:00
InOutVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( InAudioInputLeft ) , LeftAudioInput ) ;
InOutVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( InAudioInputRight ) , RightAudioInput ) ;
InOutVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( InDelayMode ) , StereoDelayMode ) ;
InOutVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( InDelayTime ) , DelayTime ) ;
InOutVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( InDelayRatio ) , DelayRatio ) ;
InOutVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( InDryLevel ) , DryLevel ) ;
InOutVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( InWetLevel ) , WetLevel ) ;
InOutVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( InFeedbackAmount ) , Feedback ) ;
2023-10-31 19:12:26 -04:00
InOutVertexData . SetValue ( METASOUND_GET_PARAM_NAME ( InParamMaxDelayTime ) , FTime : : FromSeconds ( MaxDelayTimeSeconds ) ) ;
2024-08-15 03:13:21 -04:00
InOutVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( InputResetDelay ) , TriggerReset ) ;
2023-05-22 13:28:27 -04:00
}
void FStereoDelayOperator : : BindOutputs ( FOutputVertexInterfaceData & InOutVertexData )
{
using namespace StereoDelay ;
[Metasound Bind] Fixup for bind issues caught by new automated tests.
#jira UE-187406, UE-187390, UE-187404, UE-187403, UE-187405, UE-187392, UE-187391, UE-187395, UE-187399, UE-187398, UE-187389, UE-187393, UE-187394, UE-187396, UE-187397, UE-187401
#rb phil.popp
[CL 26130674 by maxwell hayes in ue5-main branch]
2023-06-20 15:08:54 -04:00
InOutVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( OutAudioLeft ) , LeftAudioOutput ) ;
InOutVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( OutAudioRight ) , RightAudioOutput ) ;
2023-05-22 13:28:27 -04:00
}
2021-02-23 20:16:28 -04:00
FDataReferenceCollection FStereoDelayOperator : : GetInputs ( ) 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-23 20:16:28 -04:00
}
FDataReferenceCollection FStereoDelayOperator : : 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-23 20:16:28 -04:00
}
2021-02-26 17:38:00 -04:00
float FStereoDelayOperator : : GetInputDelayTimeMsecClamped ( ) const
2021-02-23 20:16:28 -04:00
{
// Clamp the delay time to the max delay allowed
2023-10-31 19:12:26 -04:00
return 1000.0f * FMath : : Clamp ( ( float ) DelayTime - > GetSeconds ( ) , 0.0f , MaxDelayTimeSeconds ) ;
2021-02-23 20:16:28 -04:00
}
2021-02-26 17:38:00 -04:00
float FStereoDelayOperator : : GetInputDelayRatioClamped ( ) const
{
return FMath : : Clamp ( * DelayRatio , - 1.0f , 1.0f ) ;
}
2021-02-23 20:16:28 -04:00
void FStereoDelayOperator : : Execute ( )
{
2024-08-15 03:13:21 -04:00
TriggerReset - > ExecuteBlock (
[ & ] ( int32 StartFrame , int32 EndFrame )
{
} ,
[ this ] ( int32 StartFrame , int32 EndFrame )
{
LeftDelayBuffer . Reset ( ) ;
RightDelayBuffer . Reset ( ) ;
}
) ;
2021-02-23 20:16:28 -04:00
// Get clamped delay time
2021-02-26 17:38:00 -04:00
float CurrentInputDelayTime = GetInputDelayTimeMsecClamped ( ) ;
float CurrentDelayRatio = GetInputDelayRatioClamped ( ) ;
2021-02-23 20:16:28 -04:00
// Check to see if our delay amount has changed
2021-02-26 17:38:00 -04:00
if ( ! FMath : : IsNearlyEqual ( PrevDelayTimeMsec , CurrentInputDelayTime ) | | ! FMath : : IsNearlyEqual ( PrevDelayRatio , CurrentDelayRatio ) )
2021-02-23 20:16:28 -04:00
{
PrevDelayTimeMsec = CurrentInputDelayTime ;
2021-02-26 17:38:00 -04:00
PrevDelayRatio = CurrentDelayRatio ;
LeftDelayBuffer . SetEasedDelayMsec ( PrevDelayTimeMsec * ( 1.0f + PrevDelayRatio ) ) ;
RightDelayBuffer . SetEasedDelayMsec ( PrevDelayTimeMsec * ( 1.0f - PrevDelayRatio ) ) ;
2021-02-23 20:16:28 -04:00
}
const float * LeftInput = LeftAudioInput - > GetData ( ) ;
const float * RightInput = RightAudioInput - > GetData ( ) ;
float * LeftOutput = LeftAudioOutput - > GetData ( ) ;
float * RightOutput = RightAudioOutput - > GetData ( ) ;
int32 NumFrames = LeftAudioInput - > Num ( ) ;
// Clamp the feedback amount to make sure it's bounded. Clamp to a number slightly less than 1.0
float FeedbackAmount = FMath : : Clamp ( * Feedback , 0.0f , 1.0f - SMALL_NUMBER ) ;
float CurrentDryLevel = FMath : : Clamp ( * DryLevel , 0.0f , 1.0f ) ;
float CurrentWetLevel = FMath : : Clamp ( * WetLevel , 0.0f , 1.0f ) ;
if ( FMath : : IsNearlyZero ( FeedbackAmount ) )
{
// if pingpong
2021-02-26 17:38:00 -04:00
switch ( * StereoDelayMode )
2021-02-23 20:16:28 -04:00
{
2021-02-26 17:38:00 -04:00
// Normal feeds left to left and right to right
case EStereoDelayMode : : Normal :
2021-02-23 20:16:28 -04:00
{
2021-02-26 17:38:00 -04:00
for ( int32 FrameIndex = 0 ; FrameIndex < NumFrames ; + + FrameIndex )
{
LeftOutput [ FrameIndex ] = CurrentWetLevel * LeftDelayBuffer . ProcessAudioSample ( LeftInput [ FrameIndex ] ) + CurrentDryLevel * LeftInput [ FrameIndex ] ;
RightOutput [ FrameIndex ] = CurrentWetLevel * RightDelayBuffer . ProcessAudioSample ( RightInput [ FrameIndex ] ) + CurrentDryLevel * RightInput [ FrameIndex ] ;
}
2021-02-23 20:16:28 -04:00
}
2021-02-26 17:38:00 -04:00
break ;
// No-feedback Cross and ping-pong feeds right input to left and left input to right
case EStereoDelayMode : : Cross :
case EStereoDelayMode : : PingPong :
{
for ( int32 FrameIndex = 0 ; FrameIndex < NumFrames ; + + FrameIndex )
{
// Ping pong feeds right to left and left to right
LeftOutput [ FrameIndex ] = CurrentWetLevel * LeftDelayBuffer . ProcessAudioSample ( RightInput [ FrameIndex ] ) + CurrentDryLevel * LeftInput [ FrameIndex ] ;
RightOutput [ FrameIndex ] = CurrentWetLevel * RightDelayBuffer . ProcessAudioSample ( LeftInput [ FrameIndex ] ) + CurrentDryLevel * RightInput [ FrameIndex ] ;
}
}
break ;
2021-02-23 20:16:28 -04:00
}
}
else
{
// TODO: support different delay cross-modes via enum, currently default to pingpong
2021-02-26 17:38:00 -04:00
switch ( * StereoDelayMode )
2021-02-23 20:16:28 -04:00
{
2021-02-26 17:38:00 -04:00
case EStereoDelayMode : : Normal :
2021-02-23 20:16:28 -04:00
{
2021-02-26 17:38:00 -04:00
for ( int32 FrameIndex = 0 ; FrameIndex < NumFrames ; + + FrameIndex )
{
float LeftDelayIn = LeftInput [ FrameIndex ] + FeedbackAmount * LeftDelayBuffer . Read ( ) ;
float RightDelayIn = RightInput [ FrameIndex ] + FeedbackAmount * RightDelayBuffer . Read ( ) ;
2021-02-23 20:16:28 -04:00
2021-02-26 17:38:00 -04:00
LeftOutput [ FrameIndex ] = CurrentWetLevel * LeftDelayBuffer . ProcessAudioSample ( LeftDelayIn ) + CurrentDryLevel * LeftInput [ FrameIndex ] ;
RightOutput [ FrameIndex ] = CurrentWetLevel * RightDelayBuffer . ProcessAudioSample ( RightDelayIn ) + CurrentDryLevel * RightInput [ FrameIndex ] ;
}
2021-02-23 20:16:28 -04:00
}
2021-02-26 17:38:00 -04:00
break ;
case EStereoDelayMode : : Cross :
{
for ( int32 FrameIndex = 0 ; FrameIndex < NumFrames ; + + FrameIndex )
{
float LeftDelayIn = RightInput [ FrameIndex ] + FeedbackAmount * LeftDelayBuffer . Read ( ) ;
float RightDelayIn = LeftInput [ FrameIndex ] + FeedbackAmount * RightDelayBuffer . Read ( ) ;
LeftOutput [ FrameIndex ] = CurrentWetLevel * LeftDelayBuffer . ProcessAudioSample ( LeftDelayIn ) + CurrentDryLevel * LeftInput [ FrameIndex ] ;
RightOutput [ FrameIndex ] = CurrentWetLevel * RightDelayBuffer . ProcessAudioSample ( RightDelayIn ) + CurrentDryLevel * RightInput [ FrameIndex ] ;
}
}
break ;
case EStereoDelayMode : : PingPong :
{
for ( int32 FrameIndex = 0 ; FrameIndex < NumFrames ; + + FrameIndex )
{
float LeftDelayIn = RightInput [ FrameIndex ] + FeedbackAmount * RightDelayBuffer . Read ( ) ;
float RightDelayIn = LeftInput [ FrameIndex ] + FeedbackAmount * LeftDelayBuffer . Read ( ) ;
LeftOutput [ FrameIndex ] = CurrentWetLevel * LeftDelayBuffer . ProcessAudioSample ( LeftDelayIn ) + CurrentDryLevel * LeftInput [ FrameIndex ] ;
RightOutput [ FrameIndex ] = CurrentWetLevel * RightDelayBuffer . ProcessAudioSample ( RightDelayIn ) + CurrentDryLevel * RightInput [ FrameIndex ] ;
}
}
break ;
2021-02-23 20:16:28 -04:00
}
}
}
2023-03-02 14:40:35 -05:00
void FStereoDelayOperator : : Reset ( const IOperator : : FResetParams & InParams )
{
LeftAudioOutput - > Zero ( ) ;
RightAudioOutput - > Zero ( ) ;
PrevDelayTimeMsec = GetInputDelayTimeMsecClamped ( ) ;
PrevDelayRatio = GetInputDelayRatioClamped ( ) ;
LeftDelayBuffer . Reset ( ) ;
LeftDelayBuffer . SetDelayMsec ( PrevDelayTimeMsec * ( 1.0f + PrevDelayRatio ) ) ;
RightDelayBuffer . Reset ( ) ;
RightDelayBuffer . SetDelayMsec ( PrevDelayTimeMsec * ( 1.0f - PrevDelayRatio ) ) ;
}
2021-02-23 20:16:28 -04:00
const FVertexInterface & FStereoDelayOperator : : GetVertexInterface ( )
{
2023-10-31 19:12:26 -04:00
using namespace StereoDelay ;
FDataVertexMetadata MaxDelayTimeMetadata = METASOUND_GET_PARAM_METADATA ( InParamMaxDelayTime ) ;
MaxDelayTimeMetadata . bIsAdvancedDisplay = true ;
2022-03-17 13:14:50 -04:00
2021-02-23 20:16:28 -04:00
static const FVertexInterface Interface (
FInputVertexInterface (
2022-03-31 16:49:59 -04:00
TInputDataVertex < FAudioBuffer > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( InAudioInputLeft ) ) ,
TInputDataVertex < FAudioBuffer > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( InAudioInputRight ) ) ,
2023-05-25 18:13:32 -04:00
TInputDataVertex < FEnumStereoDelayMode > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( InDelayMode ) , ( int32 ) EStereoDelayMode : : PingPong ) ,
2022-03-31 16:49:59 -04:00
TInputDataVertex < FTime > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( InDelayTime ) , 1.0f ) ,
2023-05-25 18:13:32 -04:00
TInputDataVertex < float > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( InDelayRatio ) , 0.1f ) ,
2022-03-31 16:49:59 -04:00
TInputDataVertex < float > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( InDryLevel ) , 0.0f ) ,
TInputDataVertex < float > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( InWetLevel ) , 1.0f ) ,
2023-10-31 19:12:26 -04:00
TInputDataVertex < float > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( InFeedbackAmount ) , 0.0f ) ,
2024-08-15 03:13:21 -04:00
TInputConstructorVertex < FTime > ( METASOUND_GET_PARAM_NAME ( InParamMaxDelayTime ) , MaxDelayTimeMetadata , DefaultMaxDelaySeconds ) ,
TInputDataVertex < FTrigger > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( InputResetDelay ) )
2021-02-23 20:16:28 -04:00
) ,
FOutputVertexInterface (
2022-03-31 16:49:59 -04:00
TOutputDataVertex < FAudioBuffer > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( OutAudioLeft ) ) ,
TOutputDataVertex < FAudioBuffer > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( OutAudioRight ) )
2021-02-23 20:16:28 -04:00
)
) ;
return Interface ;
}
const FNodeClassMetadata & FStereoDelayOperator : : GetNodeInfo ( )
{
auto InitNodeInfo = [ ] ( ) - > FNodeClassMetadata
{
FNodeClassMetadata Info ;
2021-08-09 15:08:37 -04:00
Info . ClassName = { StandardNodes : : Namespace , TEXT ( " Stereo Delay " ) , StandardNodes : : AudioVariant } ;
2021-02-23 20:16:28 -04:00
Info . MajorVersion = 1 ;
Info . MinorVersion = 0 ;
2022-02-10 18:36:47 -05:00
Info . DisplayName = METASOUND_LOCTEXT ( " Metasound_StereoDelayDisplayName " , " Stereo Delay " ) ;
Info . Description = METASOUND_LOCTEXT ( " Metasound_StereoDelayNodeDescription " , " Delays a stereo audio buffer by the specified amount. " ) ;
2021-02-23 20:16:28 -04:00
Info . Author = PluginAuthor ;
Info . PromptIfMissing = PluginNodeMissingPrompt ;
Info . DefaultInterface = GetVertexInterface ( ) ;
2021-08-09 15:08:37 -04:00
Info . CategoryHierarchy . Emplace ( NodeCategories : : Delays ) ;
2021-02-23 20:16:28 -04:00
return Info ;
} ;
static const FNodeClassMetadata Info = InitNodeInfo ( ) ;
return Info ;
}
2023-10-13 19:29:51 -04:00
TUniquePtr < IOperator > FStereoDelayOperator : : CreateOperator ( const FBuildOperatorParams & InParams , FBuildResults & OutResults )
2021-02-23 20:16:28 -04:00
{
2022-03-17 13:14:50 -04:00
using namespace StereoDelay ;
2023-10-13 19:29:51 -04:00
const FInputVertexInterfaceData & InputData = InParams . InputData ;
2022-03-17 13:14:50 -04:00
2023-10-13 19:29:51 -04:00
FAudioBufferReadRef LeftAudioIn = InputData . GetOrConstructDataReadReference < FAudioBuffer > ( METASOUND_GET_PARAM_NAME ( InAudioInputLeft ) , InParams . OperatorSettings ) ;
FAudioBufferReadRef RightAudioIn = InputData . GetOrConstructDataReadReference < FAudioBuffer > ( METASOUND_GET_PARAM_NAME ( InAudioInputRight ) , InParams . OperatorSettings ) ;
FStereoDelayModeReadRef StereoDelayMode = InputData . GetOrCreateDefaultDataReadReference < FEnumStereoDelayMode > ( METASOUND_GET_PARAM_NAME ( InDelayMode ) , InParams . OperatorSettings ) ;
FTimeReadRef DelayTime = InputData . GetOrCreateDefaultDataReadReference < FTime > ( METASOUND_GET_PARAM_NAME ( InDelayTime ) , InParams . OperatorSettings ) ;
FFloatReadRef DelayRatio = InputData . GetOrCreateDefaultDataReadReference < float > ( METASOUND_GET_PARAM_NAME ( InDelayRatio ) , InParams . OperatorSettings ) ;
FFloatReadRef DryLevel = InputData . GetOrCreateDefaultDataReadReference < float > ( METASOUND_GET_PARAM_NAME ( InDryLevel ) , InParams . OperatorSettings ) ;
FFloatReadRef WetLevel = InputData . GetOrCreateDefaultDataReadReference < float > ( METASOUND_GET_PARAM_NAME ( InWetLevel ) , InParams . OperatorSettings ) ;
FFloatReadRef Feedback = InputData . GetOrCreateDefaultDataReadReference < float > ( METASOUND_GET_PARAM_NAME ( InFeedbackAmount ) , InParams . OperatorSettings ) ;
2023-10-31 19:12:26 -04:00
FTime MaxDelayTime = InputData . GetOrCreateDefaultValue < FTime > ( METASOUND_GET_PARAM_NAME ( InParamMaxDelayTime ) , InParams . OperatorSettings ) ;
2024-08-15 03:13:21 -04:00
FTriggerReadRef TriggerReset = InputData . GetOrConstructDataReadReference < FTrigger > ( METASOUND_GET_PARAM_NAME ( InputResetDelay ) , InParams . OperatorSettings ) ;
2021-02-23 20:16:28 -04:00
2024-08-15 03:13:21 -04:00
return MakeUnique < FStereoDelayOperator > ( InParams . OperatorSettings , LeftAudioIn , RightAudioIn , StereoDelayMode , DelayTime , DelayRatio , DryLevel , WetLevel , Feedback , MaxDelayTime . GetSeconds ( ) , TriggerReset ) ;
2021-02-23 20:16:28 -04:00
}
2021-04-03 18:40:14 -04:00
class FStereoDelayNode : public FNodeFacade
2021-02-23 20:16:28 -04:00
{
2021-04-03 18:40:14 -04:00
public :
/**
* Constructor used by the Metasound Frontend .
*/
FStereoDelayNode ( const FNodeInitData & InitData )
: FNodeFacade ( InitData . InstanceName , InitData . InstanceID , TFacadeOperatorClass < FStereoDelayOperator > ( ) )
{
}
} ;
2021-02-23 20:16:28 -04:00
METASOUND_REGISTER_NODE ( FStereoDelayNode )
}
2021-04-06 18:56:44 -04:00
# undef LOCTEXT_NAMESPACE //MetasoundStandardNodes_DelayNode