2020-07-23 20:32:26 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
# pragma once
2021-03-02 21:39:09 -04:00
# include "EdGraph/EdGraph.h"
2022-12-13 18:25:01 -05:00
# include "HAL/CriticalSection.h"
2021-08-30 14:08:45 -04:00
# include "IAudioParameterTransmitter.h"
2023-03-07 17:01:52 -05:00
# include "Interfaces/MetasoundOutputFormatInterfaces.h"
2021-06-16 11:21:13 -04:00
# include "Metasound.h"
2021-01-22 03:05:22 -04:00
# include "MetasoundAssetBase.h"
2020-07-23 20:32:26 -04:00
# include "MetasoundFrontend.h"
2021-01-13 10:48:59 -04:00
# include "MetasoundFrontendDocument.h"
2021-08-18 15:16:57 -04:00
# include "MetasoundFrontendRegistries.h"
2021-02-16 01:26:50 -04:00
# include "MetasoundOperatorSettings.h"
2021-08-30 14:08:45 -04:00
# include "MetasoundParameterTransmitter.h"
2021-01-22 03:05:22 -04:00
# include "MetasoundRouter.h"
2023-10-03 12:17:13 -04:00
# include "MetasoundVertex.h"
2020-07-23 20:32:26 -04:00
# include "Sound/SoundWaveProcedural.h"
2021-06-16 11:21:13 -04:00
# include "UObject/MetaData.h"
2020-07-23 20:32:26 -04:00
2023-10-03 12:17:13 -04:00
# include <atomic>
2020-07-23 20:32:26 -04:00
# include "MetasoundSource.generated.h"
2023-03-07 17:01:52 -05:00
// Forward Declarations
2023-12-01 12:57:59 -05:00
class UMetaSoundSettings ;
2020-07-23 20:32:26 -04:00
2023-04-05 17:38:47 -04:00
namespace Audio
{
using DeviceID = uint32 ;
2023-12-01 12:57:59 -05:00
} // namespace Audio
2023-09-21 18:46:14 -04:00
2023-10-13 17:49:56 -04:00
namespace Metasound
{
2023-12-01 12:57:59 -05:00
struct FMetaSoundEngineAssetHelper ;
2023-10-13 17:49:56 -04:00
struct FMetasoundGeneratorInitParams ;
2023-12-01 12:57:59 -05:00
class FMetasoundGenerator ;
namespace Frontend
{
class IDataTypeRegistry ;
} // namespace Frontend
namespace SourcePrivate
{
class FParameterRouter ;
} // namespace SourcePrivate
namespace DynamicGraph
{
class FDynamicOperatorTransactor ;
} // namespace DynamicGraph
2023-10-13 17:49:56 -04:00
} // namespace Metasound
2023-12-01 12:57:59 -05:00
2023-04-03 23:30:36 -04:00
DECLARE_TS_MULTICAST_DELEGATE_TwoParams ( FOnGeneratorInstanceCreated , uint64 , TSharedPtr < Metasound : : FMetasoundGenerator > ) ;
DECLARE_TS_MULTICAST_DELEGATE_TwoParams ( FOnGeneratorInstanceDestroyed , uint64 , TSharedPtr < Metasound : : FMetasoundGenerator > ) ;
2022-12-13 18:25:01 -05:00
2020-07-23 20:32:26 -04:00
/**
2020-07-28 16:32:56 -04:00
* This Metasound type can be played as an audio source .
2020-07-23 20:32:26 -04:00
*/
2023-09-21 18:46:14 -04:00
UCLASS ( hidecategories = object , BlueprintType , config = Metasound , defaultconfig )
2023-03-07 17:01:52 -05:00
class METASOUNDENGINE_API UMetaSoundSource : public USoundWaveProcedural , public FMetasoundAssetBase , public IMetaSoundDocumentInterface
2020-07-23 20:32:26 -04:00
{
GENERATED_BODY ( )
2022-10-13 17:38:11 -04:00
friend struct Metasound : : FMetaSoundEngineAssetHelper ;
2023-06-16 17:48:20 -04:00
friend class UMetaSoundSourceBuilder ;
2023-10-03 12:17:13 -04:00
// FRuntimeInput represents an input to a MetaSound which can be manipulated.
struct FRuntimeInput
{
// Name of input vertex
FName Name ;
// Data type name of input vertex.
FName TypeName ;
// Access type of input vertex.
EMetasoundFrontendVertexAccessType AccessType ;
2023-11-02 18:41:29 -04:00
// Default parameter of input vertex.
FAudioParameter DefaultParameter ;
2023-10-03 12:17:13 -04:00
// True if the data type is transmittable. False otherwise.
bool bIsTransmittable ;
} ;
struct FRuntimeInputData
{
std : : atomic < bool > bIsValid = false ;
Metasound : : TSortedVertexNameMap < FRuntimeInput > InputMap ;
} ;
2020-07-23 20:32:26 -04:00
protected :
2020-08-05 12:47:19 -04:00
UPROPERTY ( EditAnywhere , Category = CustomView )
2021-01-13 10:48:59 -04:00
FMetasoundFrontendDocument RootMetasoundDocument ;
2020-12-14 15:48:27 -04:00
2021-07-27 15:36:03 -04:00
UPROPERTY ( )
2021-08-18 15:16:57 -04:00
TSet < FString > ReferencedAssetClassKeys ;
2022-10-13 17:38:11 -04:00
UPROPERTY ( )
TSet < TObjectPtr < UObject > > ReferencedAssetClassObjects ;
2021-11-07 23:43:01 -05:00
UPROPERTY ( )
TSet < FSoftObjectPath > ReferenceAssetClassCache ;
2021-07-27 15:36:03 -04:00
2020-07-23 20:32:26 -04:00
# if WITH_EDITORONLY_DATA
2021-05-14 11:31:26 -04:00
UPROPERTY ( )
2022-05-26 15:06:53 -04:00
TObjectPtr < UMetasoundEditorGraphBase > Graph ;
2020-07-23 20:32:26 -04:00
# endif // WITH_EDITORONLY_DATA
public :
2021-04-02 02:09:50 -04:00
UMetaSoundSource ( const FObjectInitializer & ObjectInitializer ) ;
2020-07-23 20:32:26 -04:00
2020-12-14 15:48:27 -04:00
// The output audio format of the metasound source.
2021-03-24 16:42:25 -04:00
UPROPERTY ( EditAnywhere , BlueprintReadOnly , Category = Metasound )
2023-03-07 17:01:52 -05:00
EMetaSoundOutputAudioFormat OutputFormat ;
2020-12-14 15:48:27 -04:00
2023-09-21 18:46:14 -04:00
// The Quality this Metasound will use. These are defined in the MetaSounds project settings.
UPROPERTY ( config , EditAnywhere , BlueprintReadWrite , meta = ( GetOptions = " MetasoundEngine.MetaSoundQuality.GetQualityList " ) , Category = " Metasound " )
FName QualitySetting ;
# if WITH_EDITORONLY_DATA
// This a editor only look up for the Quality Setting above. Preventing orphaning of the original name.
UPROPERTY ( )
FGuid QualitySettingGuid ;
# endif //WITH_EDITOR_DATA
2023-10-11 19:55:59 -04:00
// Override the BlockRate for this Sound (overrides Quality). NOTE: A Zero value will have no effect and use either the Quality setting (if set), or the defaults.
2023-10-10 13:37:20 -04:00
UPROPERTY ( EditAnywhere , BlueprintReadOnly , AdvancedDisplay , Category = Metasound , meta = ( UIMin = 0 , UIMax = 1000.0 , DisplayAfter = " OutputFormat " , DisplayName = " Override Block Rate (in Hz) " ) )
2023-09-21 18:46:14 -04:00
FPerPlatformFloat BlockRateOverride = 0.f ;
2023-10-11 19:55:59 -04:00
// Override the SampleRate for this Sound (overrides Quality). NOTE: A Zero value will have no effect and use either the Quality setting (if set), or the Device Rate
2023-10-10 13:37:20 -04:00
UPROPERTY ( EditAnywhere , BlueprintReadOnly , AdvancedDisplay , Category = Metasound , meta = ( UIMin = 0 , UIMax = 96000 , DisplayName = " Override Sample Rate (in Hz) " ) )
2023-09-21 18:46:14 -04:00
FPerPlatformInt SampleRateOverride = 0 ;
2021-06-16 11:21:13 -04:00
UPROPERTY ( AssetRegistrySearchable )
FGuid AssetClassID ;
2021-06-08 10:52:31 -04:00
# if WITH_EDITORONLY_DATA
2021-06-16 11:21:13 -04:00
UPROPERTY ( AssetRegistrySearchable )
FString RegistryInputTypes ;
UPROPERTY ( AssetRegistrySearchable )
FString RegistryOutputTypes ;
UPROPERTY ( AssetRegistrySearchable )
int32 RegistryVersionMajor = 0 ;
UPROPERTY ( AssetRegistrySearchable )
int32 RegistryVersionMinor = 0 ;
2022-10-26 15:28:04 -04:00
UPROPERTY ( AssetRegistrySearchable )
bool bIsPreset = false ;
2022-02-25 15:48:47 -05:00
2021-06-16 11:21:13 -04:00
// Sets Asset Registry Metadata associated with this MetaSoundSource
virtual void SetRegistryAssetClassInfo ( const Metasound : : Frontend : : FNodeClassInfo & InNodeInfo ) override ;
2020-07-30 16:57:04 -04:00
// Returns document name (for editor purposes, and avoids making document public for edit
// while allowing editor to reference directly)
static FName GetDocumentPropertyName ( )
{
2021-04-02 02:09:50 -04:00
return GET_MEMBER_NAME_CHECKED ( UMetaSoundSource , RootMetasoundDocument ) ;
2020-07-30 16:57:04 -04:00
}
2020-07-23 20:32:26 -04:00
2021-06-08 10:52:31 -04:00
// Name to display in editors
virtual FText GetDisplayName ( ) const override ;
2021-03-02 21:39:09 -04:00
2020-07-23 20:32:26 -04:00
// Returns the graph associated with this Metasound. Graph is required to be referenced on
// Metasound UObject for editor serialization purposes.
2021-04-02 02:09:50 -04:00
// @return Editor graph associated with UMetaSoundSource.
2021-06-08 10:52:31 -04:00
virtual UEdGraph * GetGraph ( ) override ;
virtual const UEdGraph * GetGraph ( ) const override ;
virtual UEdGraph & GetGraphChecked ( ) override ;
virtual const UEdGraph & GetGraphChecked ( ) const override ;
2020-07-23 20:32:26 -04:00
// Sets the graph associated with this Metasound. Graph is required to be referenced on
// Metasound UObject for editor serialization purposes.
2021-04-02 02:09:50 -04:00
// @param Editor graph associated with UMetaSoundSource.
2020-07-23 20:32:26 -04:00
virtual void SetGraph ( UEdGraph * InGraph ) override
{
2021-03-02 21:39:09 -04:00
Graph = CastChecked < UMetasoundEditorGraphBase > ( InGraph ) ;
2020-07-23 20:32:26 -04:00
}
2021-06-08 10:52:31 -04:00
# endif // #if WITH_EDITORONLY_DATA
2022-10-13 17:38:11 -04:00
2021-06-08 10:52:31 -04:00
# if WITH_EDITOR
virtual void PostEditUndo ( ) override ;
2020-07-23 20:32:26 -04:00
2021-04-02 02:09:50 -04:00
virtual bool GetRedrawThumbnail ( ) const override
{
return false ;
}
virtual void SetRedrawThumbnail ( bool bInRedraw ) override
{
}
virtual bool CanVisualizeAsset ( ) const override
{
return false ;
}
2021-07-28 16:21:39 -04:00
virtual void PostDuplicate ( EDuplicateMode : : Type InDuplicateMode ) override ;
2021-06-08 10:52:31 -04:00
virtual void PostEditChangeProperty ( FPropertyChangedEvent & InEvent ) override ;
2022-08-15 10:49:30 -04:00
2023-09-21 18:46:14 -04:00
virtual bool CanEditChange ( const FProperty * InProperty ) const override ;
2022-08-15 10:49:30 -04:00
private :
void PostEditChangeOutputFormat ( ) ;
2023-09-21 18:46:14 -04:00
void PostEditChangeQualitySettings ( ) ;
2022-08-15 10:49:30 -04:00
public :
2020-12-14 15:48:27 -04:00
# endif // WITH_EDITOR
2020-07-23 20:32:26 -04:00
2021-08-18 15:16:57 -04:00
virtual const TSet < FString > & GetReferencedAssetClassKeys ( ) const override
{
return ReferencedAssetClassKeys ;
}
2022-10-13 17:38:11 -04:00
virtual TArray < FMetasoundAssetBase * > GetReferencedAssets ( ) override ;
virtual const TSet < FSoftObjectPath > & GetAsyncReferencedAssetClassPaths ( ) const override ;
virtual void OnAsyncReferencedAssetsLoaded ( const TArray < FMetasoundAssetBase * > & InAsyncReferences ) override ;
2021-08-18 15:16:57 -04:00
2021-07-27 15:36:03 -04:00
virtual void BeginDestroy ( ) override ;
virtual void PreSave ( FObjectPreSaveContext InSaveContext ) override ;
virtual void Serialize ( FArchive & Ar ) override ;
2022-10-13 17:38:11 -04:00
virtual void PostLoad ( ) override ;
2021-07-27 15:36:03 -04:00
2023-09-21 18:46:14 -04:00
void PostLoadQualitySettings ( ) ;
void ResolveQualitySettings ( const UMetaSoundSettings * Settings ) ;
2021-11-22 15:55:50 -05:00
virtual bool ConformObjectDataToInterfaces ( ) override ;
2021-08-18 15:16:57 -04:00
2021-02-01 15:59:27 -04:00
UObject * GetOwningAsset ( ) override
2020-07-23 20:32:26 -04:00
{
2021-02-01 15:59:27 -04:00
return this ;
2020-07-23 20:32:26 -04:00
}
2021-02-01 15:59:27 -04:00
const UObject * GetOwningAsset ( ) const override
{
return this ;
}
2022-09-28 22:19:31 -04:00
virtual void InitParameters ( TArray < FAudioParameter > & ParametersToInit , FName InFeatureName ) override ;
2023-04-04 19:14:26 -04:00
2021-08-18 15:16:57 -04:00
virtual void InitResources ( ) override ;
2023-10-03 12:17:13 -04:00
virtual void RegisterGraphWithFrontend ( Metasound : : Frontend : : FMetaSoundAssetRegistrationOptions InRegistrationOptions = Metasound : : Frontend : : FMetaSoundAssetRegistrationOptions ( ) ) override ;
2021-08-18 15:16:57 -04:00
2021-06-08 10:52:31 -04:00
virtual bool IsPlayable ( ) const override ;
2022-01-18 18:05:56 -05:00
virtual float GetDuration ( ) const override ;
2021-12-10 20:37:31 -05:00
virtual bool ImplementsParameterInterface ( Audio : : FParameterInterfacePtr InInterface ) const override ;
2022-08-18 13:55:13 -04:00
virtual ISoundGeneratorPtr CreateSoundGenerator ( const FSoundGeneratorInitParams & InParams , TArray < FAudioParameter > & & InDefaultParameters ) override ;
2022-12-13 18:25:01 -05:00
virtual void OnEndGenerate ( ISoundGeneratorPtr Generator ) override ;
2022-09-28 22:19:31 -04:00
virtual TSharedPtr < Audio : : IParameterTransmitter > CreateParameterTransmitter ( Audio : : FParameterTransmitterInitParams & & InParams ) const override ;
2021-08-30 14:08:45 -04:00
virtual bool IsParameterValid ( const FAudioParameter & InParameter ) const override ;
2022-01-18 18:05:56 -05:00
virtual bool IsLooping ( ) const override ;
virtual bool IsOneShot ( ) const override ;
2022-03-04 03:24:13 -05:00
virtual bool EnableSubmixSendsOnPreview ( ) const override { return true ; }
2022-12-13 18:25:01 -05:00
TWeakPtr < Metasound : : FMetasoundGenerator > GetGeneratorForAudioComponent ( uint64 ComponentId ) const ;
2023-10-13 17:49:56 -04:00
bool IsDynamic ( ) const ;
2022-12-13 18:25:01 -05:00
FOnGeneratorInstanceCreated OnGeneratorInstanceCreated ;
FOnGeneratorInstanceDestroyed OnGeneratorInstanceDestroyed ;
2023-10-11 19:55:59 -04:00
Metasound : : FOperatorSettings GetOperatorSettings ( Metasound : : FSampleRate InDeviceSampleRate ) const ;
2022-12-13 18:25:01 -05:00
2023-10-03 08:47:53 -04:00
virtual const FMetasoundFrontendDocument & GetConstDocument ( ) const override ;
2020-12-14 15:48:27 -04:00
protected :
2023-09-14 16:54:36 -04:00
Metasound : : Frontend : : FDocumentAccessPtr GetDocumentAccessPtr ( ) override ;
Metasound : : Frontend : : FConstDocumentAccessPtr GetDocumentConstAccessPtr ( ) const override ;
2020-07-23 20:32:26 -04:00
2023-05-10 20:28:39 -04:00
virtual const UClass & GetBaseMetaSoundUClass ( ) const final override ;
2023-04-04 19:14:26 -04:00
2022-08-18 13:55:13 -04:00
/** Gets all the default parameters for this Asset. */
virtual bool GetAllDefaultParameters ( TArray < FAudioParameter > & OutParameters ) const override ;
2022-10-13 17:38:11 -04:00
# if WITH_EDITOR
virtual void SetReferencedAssetClasses ( TSet < Metasound : : Frontend : : IMetaSoundAssetManager : : FAssetInfo > & & InAssetClasses ) override ;
# endif // #if WITH_EDITOR
2022-08-18 13:55:13 -04:00
2020-07-23 20:32:26 -04:00
private :
2023-03-07 17:01:52 -05:00
virtual FMetasoundFrontendDocument & GetDocument ( ) override
{
return RootMetasoundDocument ;
}
2022-08-15 10:49:30 -04:00
2023-09-22 15:01:07 -04:00
virtual bool IsBuilderActive ( ) const override ;
virtual void OnBeginActiveBuilder ( ) override ;
virtual void OnFinishActiveBuilder ( ) override ;
2023-06-14 17:01:59 -04:00
2023-10-03 12:17:13 -04:00
void InitParametersInternal ( const Metasound : : TSortedVertexNameMap < FRuntimeInput > & InputMap , TArray < FAudioParameter > & ParametersToInit , FName InFeatureName ) const ;
bool IsParameterValidInternal ( const FAudioParameter & InParameter , const FName & InTypeName , Metasound : : Frontend : : IDataTypeRegistry & InDataTypeRegistry ) const ;
2022-08-18 13:55:13 -04:00
2023-04-05 17:38:47 -04:00
static Metasound : : SourcePrivate : : FParameterRouter & GetParameterRouter ( ) ;
2023-10-13 17:49:56 -04:00
public :
Metasound : : FMetasoundEnvironment CreateEnvironment ( const FSoundGeneratorInitParams & InParams ) const ;
const TArray < Metasound : : FVertexName > & GetOutputAudioChannelOrder ( ) const ;
2023-11-01 12:17:48 -04:00
2023-12-01 12:57:59 -05:00
private :
2023-11-01 12:17:48 -04:00
TSharedPtr < const Metasound : : IGraph > TryGetMetaSoundPresetBaseGraph ( ) const ;
void MergePresetOverridesAndSuppliedDefaults ( const TArray < FAudioParameter > & InSuppliedDefaults , TArray < FAudioParameter > & OutMerged ) ;
2023-10-10 13:37:20 -04:00
2021-07-28 17:12:57 -04:00
Metasound : : FMetasoundEnvironment CreateEnvironment ( ) const ;
2021-08-30 14:08:45 -04:00
Metasound : : FMetasoundEnvironment CreateEnvironment ( const Audio : : FParameterTransmitterInitParams & InParams ) const ;
2022-12-13 18:25:01 -05:00
mutable FCriticalSection GeneratorMapCriticalSection ;
TSortedMap < uint64 , TWeakPtr < Metasound : : FMetasoundGenerator > > Generators ;
void TrackGenerator ( uint64 Id , TSharedPtr < Metasound : : FMetasoundGenerator > Generator ) ;
void ForgetGenerator ( ISoundGeneratorPtr Generator ) ;
2023-06-14 17:01:59 -04:00
2023-12-01 12:57:59 -05:00
static FRuntimeInput CreateRuntimeInput ( const Metasound : : Frontend : : IDataTypeRegistry & Registry , const FMetasoundFrontendClassInput & Input , bool bCreateUObjectProxies ) ;
2023-11-02 18:41:29 -04:00
Metasound : : TSortedVertexNameMap < FRuntimeInput > CreateRuntimeInputMap ( bool bCreateUObjectProxies ) const ;
2023-10-03 12:17:13 -04:00
void CacheRuntimeInputData ( ) ;
void InvalidateCachedRuntimeInputData ( ) ;
FRuntimeInputData RuntimeInputData ;
2023-08-09 16:45:21 -04:00
/** Enable/disable dynamic generator.
2023-06-14 17:01:59 -04:00
*
* Once a dynamic generator is enabled , all changes to the MetaSound should be applied to the
* FDynamicOperatorTransactor in order to keep parity between the document and active graph .
*
* Note : Disabling the dynamic generator will sever the communication between any active generators
2023-08-09 16:45:21 -04:00
* even if the dynamic generator is re - enabled during the lifetime of the active generators
2023-06-14 17:01:59 -04:00
*/
2023-08-09 16:45:21 -04:00
TSharedPtr < Metasound : : DynamicGraph : : FDynamicOperatorTransactor > SetDynamicGeneratorEnabled ( bool bInIsEnabled ) ;
2023-06-14 17:01:59 -04:00
/** Get dynamic transactor
*
2023-08-09 16:45:21 -04:00
* If dynamic generators are enabled , this will return a valid pointer to a dynamic transactor .
2023-06-14 17:01:59 -04:00
* Changes to this transactor will be forwarded to any active Dynamic MetaSound Generators .
*/
TSharedPtr < Metasound : : DynamicGraph : : FDynamicOperatorTransactor > GetDynamicGeneratorTransactor ( ) const ;
TSharedPtr < Metasound : : DynamicGraph : : FDynamicOperatorTransactor > DynamicTransactor ;
2023-09-21 18:46:14 -04:00
/*
* Lazy ( Cached ) Operator Settings . Built in GetOperatorSettings
*/
mutable TOptional < Metasound : : FOperatorSettings > OperatorSettings ;
2023-10-11 19:55:59 -04:00
// Cache the AudioDevice Samplerate. (so that if we have to regenerate operator settings without the device rate we can use this).
mutable Metasound : : FSampleRate CachedAudioDeviceSampleRate = 0 ;
2023-09-22 15:01:07 -04:00
bool bIsBuilderActive = false ;
2023-11-03 19:38:58 -04:00
// Preset graph inflation is a performance optimization intended for use with the MetaSoundOperatorPool. If multiple presets
// utilize the same base MetaSound, they may be able to share their operators in the operator pool. This makes for a more
// efficient use of the operator pool.
bool bIsPresetGraphInflationSupported = false ;
2020-11-17 17:52:08 -04:00
} ;