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 ;
static TUniquePtr < IOperator > CreateOperator ( const FCreateOperatorParams & InParams , FBuildErrorArray & OutErrors ) ;
static const FNodeClassMetadata & GetNodeInfo ( ) ;
static FVertexInterface DeclareVertexInterface ( ) ;
FNoiseOperator ( const FOperatorSettings & InSettings , FInt32ReadRef & & InReadRef ) ;
virtual FDataReferenceCollection GetInputs ( ) const override ;
virtual FDataReferenceCollection GetOutputs ( ) const override ;
protected :
FInt32ReadRef Seed ;
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 } ;
}
}
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 ;
FNoiseOperator_White ( const FOperatorSettings & InSettings , FInt32ReadRef & & InSeed )
: FNoiseOperator { InSettings , MoveTemp ( InSeed ) }
, Generator { MakeGenerator < Audio : : FWhiteNoise > ( * Seed ) }
{ }
void Execute ( )
{
// Reseed if necessary.
CheckAndReseed ( Generator ) ;
// Generate a block.
Generate ( Generator ) ;
}
static void ExecuteFunction ( IOperator * InOperator ) { static_cast < FNoiseOperator_White * > ( InOperator ) - > Execute ( ) ; }
FExecuteFunction GetExecuteFunction ( ) override { return & FNoiseOperator_White : : ExecuteFunction ; }
} ;
struct FNoiseOperator_Pink final : public FNoiseOperator
{
using FNoiseOperator : : FNoiseOperator ;
Audio : : FPinkNoise Generator ;
FNoiseOperator_Pink ( const FOperatorSettings & InSettings , FInt32ReadRef & & InSeed )
: FNoiseOperator { InSettings , MoveTemp ( InSeed ) }
, Generator { MakeGenerator < Audio : : FPinkNoise > ( * Seed ) }
{ }
static void ExecuteFunction ( IOperator * InOperator ) { static_cast < FNoiseOperator_Pink * > ( InOperator ) - > Execute ( ) ; }
FExecuteFunction GetExecuteFunction ( ) override { return & FNoiseOperator_Pink : : ExecuteFunction ; }
void Execute ( )
{
// Reseed if necessary.
CheckAndReseed ( Generator ) ;
// Generate a block.
Generate ( Generator ) ;
}
} ;
FNoiseOperator : : FNoiseOperator ( const FOperatorSettings & InSettings , FInt32ReadRef & & InReadRef )
: Seed { MoveTemp ( InReadRef ) }
, Out { FAudioBufferWriteRef : : CreateNew ( InSettings ) }
, OldSeed ( * Seed )
{ }
FDataReferenceCollection FNoiseOperator : : GetInputs ( ) const
{
2022-03-02 17:22:27 -05:00
using namespace NoiseGeneratorVertexNames ;
2021-03-04 20:00:39 -04:00
FDataReferenceCollection InputDataReferences ;
2022-03-02 17:22:27 -05:00
InputDataReferences . AddDataReadReference ( METASOUND_GET_PARAM_NAME ( InputSeed ) , FInt32ReadRef ( Seed ) ) ;
2021-03-04 20:00:39 -04:00
return InputDataReferences ;
}
FDataReferenceCollection FNoiseOperator : : GetOutputs ( ) const
{
2022-03-02 17:22:27 -05:00
using namespace NoiseGeneratorVertexNames ;
2021-03-04 20:00:39 -04:00
FDataReferenceCollection OutputDataReferences ;
2022-03-02 17:22:27 -05:00
OutputDataReferences . AddDataReadReference ( METASOUND_GET_PARAM_NAME ( OutAudio ) , FAudioBufferReadRef ( Out ) ) ;
2021-03-04 20:00:39 -04:00
return OutputDataReferences ;
}
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 ) ,
TInputDataVertex < FEnumNoiseType > ( METASOUND_GET_PARAM_NAME_AND_METADATA ( InputType ) )
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 )
{ }
TUniquePtr < IOperator > FNoiseOperator : : CreateOperator ( const FCreateOperatorParams & InParams , FBuildErrorArray & OutErrors )
{
2022-03-02 17:22:27 -05:00
using namespace NoiseGeneratorVertexNames ;
2021-03-04 20:00:39 -04:00
const FNoiseNode & Node = static_cast < const FNoiseNode & > ( InParams . Node ) ;
const FDataReferenceCollection & InputCol = InParams . InputDataReferences ;
const FOperatorSettings & Settings = InParams . OperatorSettings ;
// Static property pin, only used for factory.
2022-03-02 17:22:27 -05:00
FEnumNoiseTypeReadRef Type = InputCol . GetDataReadReferenceOrConstruct < FEnumNoiseType > ( METASOUND_GET_PARAM_NAME ( InputType ) ) ;
2021-03-04 20:00:39 -04:00
// Seed.
2022-03-02 17:22:27 -05:00
FInt32ReadRef Seed = InputCol . GetDataReadReferenceOrConstruct < int32 > ( METASOUND_GET_PARAM_NAME ( InputSeed ) , Node . GetDefaultSeed ( ) ) ;
2021-03-04 20:00:39 -04:00
switch ( * Type )
{
default :
case ENoiseType : : White :
return MakeUnique < FNoiseOperator_White > ( InParams . OperatorSettings , MoveTemp ( Seed ) ) ;
case ENoiseType : : Pink :
return MakeUnique < FNoiseOperator_Pink > ( InParams . OperatorSettings , MoveTemp ( Seed ) ) ;
}
checkNoEntry ( ) ;
return nullptr ;
}
METASOUND_REGISTER_NODE ( FNoiseNode ) ;
}
# undef LOCTEXT_NAMESPACE //MetasoundStandardNodes