2021-03-04 20:00:39 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
# include "MetasoundNoiseGenerator.h"
# include "MetasoundAudioBuffer.h"
2021-04-05 20:22:19 -04:00
# include "MetasoundEnumRegistrationMacro.h"
2021-03-04 20:00:39 -04:00
# include "MetasoundExecutableOperator.h"
# include "MetasoundFacade.h"
# include "MetasoundNodeRegistrationMacro.h"
# include "MetasoundDataTypeRegistrationMacro.h"
# include "MetasoundOperatorSettings.h"
2022-03-02 17:22:27 -05:00
# include "MetasoundParamHelper.h"
2021-03-04 20:00:39 -04:00
# include "MetasoundPrimitives.h"
# include "MetasoundStandardNodesNames.h"
# include "MetasoundTrigger.h"
# include "MetasoundVertex.h"
# include "DSP/Noise.h"
2021-03-05 23:03:16 -04:00
# include "MetasoundStandardNodesCategories.h"
2021-03-04 20:00:39 -04:00
2021-04-07 02:57:54 -04:00
# define LOCTEXT_NAMESPACE "MetasoundStandardNodes_GeneratorNodes"
2021-03-04 20:00:39 -04:00
namespace Metasound
{
enum class ENoiseType
{
Pink ,
White
} ;
DECLARE_METASOUND_ENUM ( ENoiseType , ENoiseType : : Pink , METASOUNDSTANDARDNODES_API ,
FEnumNoiseType , FEnumNoiseTypeInfo , FEnumNoiseTypeReadRef , FEnumNoiseTypeWriteRef ) ;
DEFINE_METASOUND_ENUM_BEGIN ( ENoiseType , FEnumNoiseType , " NoiseType " )
2022-03-30 14:31:53 -04:00
DEFINE_METASOUND_ENUM_ENTRY ( ENoiseType : : Pink , " PinkDescription " , " Pink Noise " , " PinkDescriptionTT " , " Pink noise or 1/f noise, spectral density is inversely proportional to the frequency of the signal " ) ,
2022-02-10 18:36:47 -05:00
DEFINE_METASOUND_ENUM_ENTRY ( ENoiseType : : White , " WhiteDescription " , " White Noise " , " WhiteDescriptionTT " , " A random signal having equal intensity at different frequencies " ) ,
2021-03-04 20:00:39 -04:00
DEFINE_METASOUND_ENUM_END ( )
2022-03-02 17:22:27 -05:00
namespace NoiseGeneratorVertexNames
{
METASOUND_PARAM ( OutAudio , " Audio " , " Audio output. " )
METASOUND_PARAM ( InputType , " Type " , " Type of Noise to Generate. " )
METASOUND_PARAM ( InputSeed , " Seed " , " Seed for seeding the Random Number Generator, -1 (default) will use current time. " )
}
2021-03-04 20:00:39 -04:00
class FNoiseOperator : public IOperator
{
public :
static constexpr int32 DefaultSeed = INDEX_NONE ;
2023-10-13 19:29:51 -04:00
static TUniquePtr < IOperator > CreateOperator ( const FBuildOperatorParams & InParams , FBuildResults & OutResults ) ;
2021-03-04 20:00:39 -04:00
static const FNodeClassMetadata & GetNodeInfo ( ) ;
static FVertexInterface DeclareVertexInterface ( ) ;
2023-07-21 11:39:50 -04:00
FNoiseOperator ( const FOperatorSettings & InSettings , FInt32ReadRef & & InSeedReadRef , FEnumNoiseTypeReadRef & & InNoiseTypeReadRef ) ;
2023-05-22 13:28:27 -04:00
virtual void BindInputs ( FInputVertexInterfaceData & InOutVertexData ) override ;
virtual void BindOutputs ( FOutputVertexInterfaceData & InOutVertexData ) override ;
2021-03-04 20:00:39 -04:00
2023-04-05 17:38:47 -04:00
virtual IOperator : : FPostExecuteFunction GetPostExecuteFunction ( ) override { return nullptr ; }
2023-02-22 17:54:26 -05:00
2021-03-04 20:00:39 -04:00
protected :
FInt32ReadRef Seed ;
2023-07-21 11:39:50 -04:00
FEnumNoiseTypeReadRef NoiseType ;
2021-03-04 20:00:39 -04:00
FAudioBufferWriteRef Out ;
int32 OldSeed ;
template < typename T >
static T MakeGenerator ( int32 InSeed )
{
// If we the default seed, use the default noise generator constructor.
if ( InSeed = = DefaultSeed )
{
return T { } ;
}
else
{
return T { InSeed } ;
}
}
2023-02-22 17:54:26 -05:00
template < typename T >
void ResetNoiseOperator ( T & InOutGenerator )
{
InOutGenerator = MakeGenerator < T > ( * Seed ) ;
OldSeed = * Seed ;
}
2021-03-04 20:00:39 -04:00
template < typename T >
FORCEINLINE void CheckAndReseed ( T & InOutGenerator )
{
// Reseed?
int32 NewSeed = * Seed ;
if ( OldSeed ! = NewSeed )
{
InOutGenerator = MakeGenerator < T > ( NewSeed ) ;
OldSeed = NewSeed ;
}
}
template < typename T >
FORCEINLINE void Generate ( T & InGenerator )
{
float * WritePtr = Out - > GetData ( ) ;
for ( int32 i = Out - > Num ( ) ; i > 0 ; - - i )
{
* WritePtr + + = InGenerator . Generate ( ) ;
}
}
} ;
2021-03-04 20:38:06 -04:00
constexpr int32 FNoiseOperator : : DefaultSeed ;
2021-03-04 20:00:39 -04:00
struct FNoiseOperator_White final : public FNoiseOperator
{
Audio : : FWhiteNoise Generator ;
2023-07-21 11:39:50 -04:00
FNoiseOperator_White ( const FOperatorSettings & InSettings , FInt32ReadRef & & InSeed , FEnumNoiseTypeReadRef & & InNoiseTypeReadRef )
: FNoiseOperator { InSettings , MoveTemp ( InSeed ) , MoveTemp ( InNoiseTypeReadRef ) }
2021-03-04 20:00:39 -04:00
, Generator { MakeGenerator < Audio : : FWhiteNoise > ( * Seed ) }
{ }
2023-02-22 17:54:26 -05:00
void Reset ( const IOperator : : FResetParams & InParams )
{
ResetNoiseOperator ( Generator ) ;
Out - > Zero ( ) ;
}
2021-03-04 20:00:39 -04:00
void Execute ( )
{
// Reseed if necessary.
CheckAndReseed ( Generator ) ;
// Generate a block.
Generate ( Generator ) ;
}
2023-02-22 17:54:26 -05:00
virtual FResetFunction GetResetFunction ( ) override { return & FNoiseOperator_White : : ResetFunction ; }
static void ResetFunction ( IOperator * InOperator , const IOperator : : FResetParams & InParams ) { static_cast < FNoiseOperator_White * > ( InOperator ) - > Reset ( InParams ) ; }
2021-03-04 20:00:39 -04:00
static void ExecuteFunction ( IOperator * InOperator ) { static_cast < FNoiseOperator_White * > ( InOperator ) - > Execute ( ) ; }
FExecuteFunction GetExecuteFunction ( ) override { return & FNoiseOperator_White : : ExecuteFunction ; }
2023-02-22 17:54:26 -05:00
2021-03-04 20:00:39 -04:00
} ;
struct FNoiseOperator_Pink final : public FNoiseOperator
{
using FNoiseOperator : : FNoiseOperator ;
Audio : : FPinkNoise Generator ;
2023-07-21 11:39:50 -04:00
FNoiseOperator_Pink ( const FOperatorSettings & InSettings , FInt32ReadRef & & InSeed , FEnumNoiseTypeReadRef & & InNoiseTypeReadRef )
: FNoiseOperator { InSettings , MoveTemp ( InSeed ) , MoveTemp ( InNoiseTypeReadRef ) }
2021-03-04 20:00:39 -04:00
, Generator { MakeGenerator < Audio : : FPinkNoise > ( * Seed ) }
{ }
static void ExecuteFunction ( IOperator * InOperator ) { static_cast < FNoiseOperator_Pink * > ( InOperator ) - > Execute ( ) ; }
FExecuteFunction GetExecuteFunction ( ) override { return & FNoiseOperator_Pink : : ExecuteFunction ; }
2023-02-22 17:54:26 -05:00
virtual FResetFunction GetResetFunction ( ) override { return & FNoiseOperator_Pink : : ResetFunction ; }
static void ResetFunction ( IOperator * InOperator , const IOperator : : FResetParams & InParams ) { static_cast < FNoiseOperator_Pink * > ( InOperator ) - > Reset ( InParams ) ; }
void Reset ( const IOperator : : FResetParams & InParams )
{
ResetNoiseOperator ( Generator ) ;
Out - > Zero ( ) ;
}
2021-03-04 20:00:39 -04:00
void Execute ( )
{
// Reseed if necessary.
CheckAndReseed ( Generator ) ;
// Generate a block.
Generate ( Generator ) ;
}
} ;
2023-07-21 11:39:50 -04:00
FNoiseOperator : : FNoiseOperator ( const FOperatorSettings & InSettings , FInt32ReadRef & & InSeedReadRef , FEnumNoiseTypeReadRef & & InNoiseTypeReadRef )
: Seed { MoveTemp ( InSeedReadRef ) }
, NoiseType { MoveTemp ( InNoiseTypeReadRef ) }
2021-03-04 20:00:39 -04:00
, Out { FAudioBufferWriteRef : : CreateNew ( InSettings ) }
, OldSeed ( * Seed )
{ }
2023-05-22 13:28:27 -04:00
void FNoiseOperator : : BindInputs ( FInputVertexInterfaceData & InOutVertexData )
2021-03-04 20:00:39 -04:00
{
2022-03-02 17:22:27 -05:00
using namespace NoiseGeneratorVertexNames ;
2023-05-22 13:28:27 -04:00
InOutVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( InputSeed ) , Seed ) ;
2023-07-21 11:39:50 -04:00
InOutVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( InputType ) , NoiseType ) ;
2023-05-22 13:28:27 -04:00
}
2022-03-02 17:22:27 -05:00
2023-05-22 13:28:27 -04:00
void FNoiseOperator : : BindOutputs ( FOutputVertexInterfaceData & InOutVertexData )
{
using namespace NoiseGeneratorVertexNames ;
InOutVertexData . BindReadVertex ( METASOUND_GET_PARAM_NAME ( OutAudio ) , Out ) ;
}
2021-03-04 20:00:39 -04:00
FVertexInterface FNoiseOperator : : DeclareVertexInterface ( )
{
2022-03-02 17:22:27 -05:00
using namespace NoiseGeneratorVertexNames ;
2021-03-04 20:00:39 -04:00
static const FVertexInterface Interface (
FInputVertexInterface (
2022-03-31 16:49:59 -04:00
TInputDataVertex < int32 > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( InputSeed ) , FNoiseOperator : : DefaultSeed ) ,
2023-05-25 18:13:32 -04:00
TInputDataVertex < FEnumNoiseType > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( InputType ) , ( int32 ) ENoiseType : : Pink )
2021-03-04 20:00:39 -04:00
) ,
FOutputVertexInterface (
2022-03-31 16:49:59 -04:00
TOutputDataVertex < FAudioBuffer > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( OutAudio ) )
2021-03-04 20:00:39 -04:00
)
) ;
return Interface ;
}
const FNodeClassMetadata & FNoiseOperator : : GetNodeInfo ( )
{
auto InitNodeInfo = [ ] ( ) - > FNodeClassMetadata
{
FNodeClassMetadata Info ;
2021-08-09 15:08:37 -04:00
Info . ClassName = { StandardNodes : : Namespace , TEXT ( " Noise " ) , StandardNodes : : AudioVariant } ;
2021-03-04 20:00:39 -04:00
Info . MajorVersion = 1 ;
Info . MinorVersion = 0 ;
2022-02-10 18:36:47 -05:00
Info . DisplayName = METASOUND_LOCTEXT ( " Metasound_NoiseNodeDisplayNameX " , " Noise " ) ;
Info . Description = METASOUND_LOCTEXT ( " Metasound_NoiseNodeDescription " , " Noise Generator that produces different types of noise " ) ;
2021-03-04 20:00:39 -04:00
Info . Author = PluginAuthor ;
Info . PromptIfMissing = PluginNodeMissingPrompt ;
Info . DefaultInterface = DeclareVertexInterface ( ) ;
2021-08-09 15:08:37 -04:00
Info . CategoryHierarchy . Emplace ( NodeCategories : : Generators ) ;
2021-03-04 20:00:39 -04:00
return Info ;
} ;
static const FNodeClassMetadata Info = InitNodeInfo ( ) ;
return Info ;
}
2021-09-13 14:13:39 -04:00
FNoiseNode : : FNoiseNode ( const FVertexName & InName , const FGuid & InInstanceID , int32 InDefaultSeed )
2021-03-04 20:00:39 -04:00
: FNodeFacade ( InName , InInstanceID , TFacadeOperatorClass < FNoiseOperator > ( ) )
, DefaultSeed ( InDefaultSeed )
{ }
FNoiseNode : : FNoiseNode ( const FNodeInitData & InInitData )
: FNoiseNode ( InInitData . InstanceName , InInitData . InstanceID , FNoiseOperator : : DefaultSeed )
{ }
2023-10-13 19:29:51 -04:00
TUniquePtr < IOperator > FNoiseOperator : : CreateOperator ( const FBuildOperatorParams & InParams , FBuildResults & OutResults )
2021-03-04 20:00:39 -04:00
{
2022-03-02 17:22:27 -05:00
using namespace NoiseGeneratorVertexNames ;
2021-03-04 20:00:39 -04:00
const FOperatorSettings & Settings = InParams . OperatorSettings ;
2023-10-13 19:29:51 -04:00
const FInputVertexInterfaceData & InputData = InParams . InputData ;
2021-03-04 20:00:39 -04:00
// Static property pin, only used for factory.
2023-10-13 19:29:51 -04:00
FEnumNoiseTypeReadRef Type = InputData . GetOrCreateDefaultDataReadReference < FEnumNoiseType > ( METASOUND_GET_PARAM_NAME ( InputType ) , Settings ) ;
2021-03-04 20:00:39 -04:00
// Seed.
2023-10-13 19:29:51 -04:00
FInt32ReadRef Seed = InputData . GetOrCreateDefaultDataReadReference < int32 > ( METASOUND_GET_PARAM_NAME ( InputSeed ) , Settings ) ;
2021-03-04 20:00:39 -04:00
switch ( * Type )
{
default :
case ENoiseType : : White :
2023-07-21 11:39:50 -04:00
return MakeUnique < FNoiseOperator_White > ( InParams . OperatorSettings , MoveTemp ( Seed ) , MoveTemp ( Type ) ) ;
2021-03-04 20:00:39 -04:00
case ENoiseType : : Pink :
2023-07-21 11:39:50 -04:00
return MakeUnique < FNoiseOperator_Pink > ( InParams . OperatorSettings , MoveTemp ( Seed ) , MoveTemp ( Type ) ) ;
2021-03-04 20:00:39 -04:00
}
}
METASOUND_REGISTER_NODE ( FNoiseNode ) ;
}
# undef LOCTEXT_NAMESPACE //MetasoundStandardNodes