2020-07-23 20:32:26 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
# include "MetasoundSource.h"
2020-12-14 15:48:27 -04:00
# include "AssetRegistryModule.h"
2020-07-23 20:32:26 -04:00
# include "CoreMinimal.h"
# include "Internationalization/Text.h"
# include "MetasoundAssetBase.h"
2020-12-14 15:48:27 -04:00
# include "MetasoundAudioFormats.h"
2021-06-23 20:08:21 -04:00
# include "MetasoundEngineArchetypes.h"
2020-11-17 17:52:08 -04:00
# include "MetasoundEngineEnvironment.h"
2021-06-08 10:52:31 -04:00
# include "MetasoundEnvironment.h"
2021-01-22 03:05:22 -04:00
# include "MetasoundFrontendController.h"
2021-08-30 14:08:45 -04:00
# include "MetasoundFrontendDataTypeRegistry.h"
2021-07-28 17:12:57 -04:00
# include "MetasoundFrontendInjectReceiveNodes.h"
2021-01-22 03:05:22 -04:00
# include "MetasoundFrontendQuery.h"
# include "MetasoundFrontendQuerySteps.h"
2021-05-28 16:17:48 -04:00
# include "MetasoundFrontendTransform.h"
2020-07-23 20:32:26 -04:00
# include "MetasoundGenerator.h"
2020-12-14 15:48:27 -04:00
# include "MetasoundLog.h"
2021-02-16 01:26:50 -04:00
# include "MetasoundOperatorSettings.h"
2021-08-30 14:08:45 -04:00
# include "MetasoundParameterTransmitter.h"
2020-07-23 20:32:26 -04:00
# include "MetasoundPrimitives.h"
2021-01-22 03:05:22 -04:00
# include "MetasoundReceiveNode.h"
2021-08-11 15:22:01 -04:00
# include "MetasoundTrace.h"
2021-01-27 15:54:01 -04:00
# include "MetasoundTrigger.h"
2021-06-08 10:52:31 -04:00
# include "MetasoundUObjectRegistry.h"
# include "UObject/ObjectSaveContext.h"
2020-07-23 20:32:26 -04:00
# if WITH_EDITORONLY_DATA
# include "EdGraph/EdGraph.h"
# endif // WITH_EDITORONLY_DATA
2021-05-28 16:17:48 -04:00
# define LOCTEXT_NAMESPACE "MetaSoundSource"
2021-04-02 02:09:50 -04:00
2021-07-28 17:12:57 -04:00
namespace MetaSoundSourcePrivate
{
using FFormatOutputVertexKeyMap = TMap < EMetasoundSourceAudioFormat , TArray < Metasound : : FVertexKey > > ;
const FFormatOutputVertexKeyMap & GetFormatOutputVertexKeys ( )
{
using namespace Metasound ;
using namespace Metasound : : Engine ;
static const FFormatOutputVertexKeyMap Map
(
{
{
2021-08-30 14:08:45 -04:00
EMetasoundSourceAudioFormat : : Mono ,
2021-07-28 17:12:57 -04:00
{ MetasoundSourceMono : : GetAudioOutputName ( ) }
} ,
{
2021-08-30 14:08:45 -04:00
EMetasoundSourceAudioFormat : : Stereo ,
{
MetasoundSourceStereo : : GetLeftAudioOutputName ( ) ,
MetasoundSourceStereo : : GetRightAudioOutputName ( )
2021-07-28 17:12:57 -04:00
}
}
}
) ;
return Map ;
}
}
2021-04-02 02:09:50 -04:00
2021-02-19 18:30:53 -04:00
FAutoConsoleVariableRef CVarMetaSoundBlockRate (
TEXT ( " au.MetaSound.BlockRate " ) ,
2021-06-08 10:52:31 -04:00
Metasound : : ConsoleVariables : : BlockRate ,
2021-02-19 18:30:53 -04:00
TEXT ( " Sets block rate (blocks per second) of MetaSounds. \n " )
TEXT ( " Default: 100.0f " ) ,
ECVF_Default ) ;
2021-04-02 02:09:50 -04:00
UMetaSoundSource : : UMetaSoundSource ( const FObjectInitializer & ObjectInitializer )
2020-07-23 20:32:26 -04:00
: Super ( ObjectInitializer )
2021-06-08 10:52:31 -04:00
, FMetasoundAssetBase ( )
2020-07-23 20:32:26 -04:00
{
2021-01-11 14:18:46 -04:00
bRequiresStopFade = true ;
2020-07-23 20:32:26 -04:00
NumChannels = 1 ;
Duration = INDEFINITELY_LOOPING_DURATION ;
bLooping = true ;
2021-04-02 02:09:50 -04:00
// todo: ensure that we have a method so that the audio engine can be authoritative over the sample rate the UMetaSoundSource runs at.
2021-02-16 01:26:50 -04:00
SampleRate = 48000.f ;
2020-07-23 20:32:26 -04:00
}
2020-12-14 15:48:27 -04:00
# if WITH_EDITOR
2021-04-02 02:09:50 -04:00
void UMetaSoundSource : : PostEditUndo ( )
2021-03-02 21:39:09 -04:00
{
Super : : PostEditUndo ( ) ;
2021-07-27 15:36:03 -04:00
Metasound : : PostAssetUndo ( * this ) ;
2021-03-02 21:39:09 -04:00
}
2021-07-28 16:21:39 -04:00
void UMetaSoundSource : : PostDuplicate ( EDuplicateMode : : Type InDuplicateMode )
{
Super : : PostDuplicate ( InDuplicateMode ) ;
Metasound : : PostDuplicate ( * this , InDuplicateMode ) ;
}
2021-04-02 02:09:50 -04:00
void UMetaSoundSource : : PostEditChangeProperty ( FPropertyChangedEvent & InEvent )
2020-12-14 15:48:27 -04:00
{
2021-06-08 10:52:31 -04:00
using namespace Metasound ;
using namespace Metasound : : Frontend ;
2020-12-14 15:48:27 -04:00
Super : : PostEditChangeProperty ( InEvent ) ;
2021-06-16 11:21:13 -04:00
Metasound : : PostEditChangeProperty ( * this , InEvent ) ;
2020-12-14 15:48:27 -04:00
2021-06-08 10:52:31 -04:00
if ( InEvent . GetPropertyName ( ) = = GET_MEMBER_NAME_CHECKED ( UMetaSoundSource , OutputFormat ) )
2020-12-14 15:48:27 -04:00
{
2021-06-08 10:52:31 -04:00
ConvertFromPreset ( ) ;
2021-06-23 20:08:21 -04:00
bool bDidModifyDocument = false ;
2020-12-14 15:48:27 -04:00
switch ( OutputFormat )
{
case EMetasoundSourceAudioFormat : : Mono :
2021-06-08 10:52:31 -04:00
{
2021-06-23 20:08:21 -04:00
// TODO: utilize latest version `MetasoudnSourceMono`
bDidModifyDocument = Metasound : : Frontend : : FMatchRootGraphToArchetype ( Metasound : : Engine : : MetasoundSourceMono : : GetVersion ( ) ) . Transform ( GetDocumentHandle ( ) ) ;
2021-06-08 10:52:31 -04:00
}
break ;
2020-12-14 15:48:27 -04:00
2021-06-08 10:52:31 -04:00
case EMetasoundSourceAudioFormat : : Stereo :
{
2021-06-23 20:08:21 -04:00
bDidModifyDocument = Metasound : : Frontend : : FMatchRootGraphToArchetype ( Metasound : : Engine : : MetasoundSourceStereo : : GetVersion ( ) ) . Transform ( GetDocumentHandle ( ) ) ;
2021-06-08 10:52:31 -04:00
}
break ;
default :
{
static_assert ( static_cast < int32 > ( EMetasoundSourceAudioFormat : : COUNT ) = = 2 , " Possible missing format switch case coverage. " ) ;
}
break ;
}
2021-06-23 20:08:21 -04:00
if ( bDidModifyDocument )
2021-06-08 10:52:31 -04:00
{
2021-08-18 15:16:57 -04:00
ConformObjectDataToArchetype ( ) ;
// Use the editor form of register to ensure other editors'
// MetaSounds are auto-updated if they are referencing this graph.
if ( Graph )
{
Graph - > RegisterGraphWithFrontend ( ) ;
}
2021-06-23 20:08:21 -04:00
MarkMetasoundDocumentDirty ( ) ;
2020-12-14 15:48:27 -04:00
}
}
}
2021-06-08 10:52:31 -04:00
# endif // WITH_EDITOR
2020-12-14 15:48:27 -04:00
2021-08-18 15:16:57 -04:00
bool UMetaSoundSource : : ConformObjectDataToArchetype ( )
{
const FMetasoundFrontendVersion & ArchetypeVersion = GetDocumentHandle ( ) - > GetArchetypeVersion ( ) ;
if ( ArchetypeVersion = = Metasound : : Engine : : MetasoundSourceMono : : GetVersion ( ) )
{
if ( OutputFormat ! = EMetasoundSourceAudioFormat : : Mono | | NumChannels ! = 1 )
{
OutputFormat = EMetasoundSourceAudioFormat : : Mono ;
NumChannels = 1 ;
return true ;
}
}
if ( ArchetypeVersion = = Metasound : : Engine : : MetasoundSourceStereo : : GetVersion ( ) )
{
if ( OutputFormat ! = EMetasoundSourceAudioFormat : : Stereo | | NumChannels ! = 2 )
{
OutputFormat = EMetasoundSourceAudioFormat : : Stereo ;
NumChannels = 2 ;
return true ;
}
}
return false ;
}
2021-07-27 15:36:03 -04:00
void UMetaSoundSource : : BeginDestroy ( )
{
UnregisterGraphWithFrontend ( ) ;
Super : : BeginDestroy ( ) ;
}
void UMetaSoundSource : : PreSave ( FObjectPreSaveContext InSaveContext )
{
Super : : PreSave ( InSaveContext ) ;
2021-08-31 16:07:45 -04:00
Metasound : : PreSaveAsset ( * this , InSaveContext ) ;
2021-07-27 15:36:03 -04:00
}
void UMetaSoundSource : : Serialize ( FArchive & InArchive )
{
Super : : Serialize ( InArchive ) ;
Metasound : : SerializeToArchive ( * this , InArchive ) ;
}
2021-08-18 15:16:57 -04:00
void UMetaSoundSource : : SetReferencedAssetClassKeys ( TSet < Metasound : : Frontend : : FNodeRegistryKey > & & InKeys )
{
ReferencedAssetClassKeys = MoveTemp ( InKeys ) ;
}
TSet < UObject * > & UMetaSoundSource : : GetReferencedAssetClassCache ( )
{
return ReferenceAssetClassCache ;
}
2021-06-08 10:52:31 -04:00
# if WITH_EDITORONLY_DATA
UEdGraph * UMetaSoundSource : : GetGraph ( )
{
return Graph ;
}
const UEdGraph * UMetaSoundSource : : GetGraph ( ) const
{
return Graph ;
}
UEdGraph & UMetaSoundSource : : GetGraphChecked ( )
{
check ( Graph ) ;
return * Graph ;
}
const UEdGraph & UMetaSoundSource : : GetGraphChecked ( ) const
{
check ( Graph ) ;
return * Graph ;
}
FText UMetaSoundSource : : GetDisplayName ( ) const
{
FString TypeName = UMetaSoundSource : : StaticClass ( ) - > GetName ( ) ;
return FMetasoundAssetBase : : GetDisplayName ( MoveTemp ( TypeName ) ) ;
}
2021-06-16 11:21:13 -04:00
void UMetaSoundSource : : SetRegistryAssetClassInfo ( const Metasound : : Frontend : : FNodeClassInfo & InNodeInfo )
{
Metasound : : SetMetaSoundRegistryAssetClassInfo ( * this , InNodeInfo ) ;
}
2021-06-08 10:52:31 -04:00
# endif // WITH_EDITORONLY_DATA
2021-08-30 14:08:45 -04:00
void UMetaSoundSource : : InitParameters ( TArray < FAudioParameter > & InParametersToInit , FName InFeatureName )
{
auto Sanitize = [ ] ( FAudioParameter & Parameter )
{
switch ( Parameter . ParamType )
{
case EAudioParameterType : : Boolean :
{
Parameter = FAudioParameter ( Parameter . ParamName , Parameter . BoolParam ) ;
}
break ;
case EAudioParameterType : : BooleanArray :
{
TArray < bool > TempArray = Parameter . ArrayBoolParam ;
Parameter = FAudioParameter ( Parameter . ParamName , MoveTemp ( TempArray ) ) ;
}
break ;
case EAudioParameterType : : Float :
{
Parameter = FAudioParameter ( Parameter . ParamName , Parameter . FloatParam ) ;
}
break ;
case EAudioParameterType : : FloatArray :
{
TArray < float > TempArray = Parameter . ArrayFloatParam ;
Parameter = FAudioParameter ( Parameter . ParamName , MoveTemp ( TempArray ) ) ;
}
break ;
case EAudioParameterType : : Integer :
{
Parameter = FAudioParameter ( Parameter . ParamName , Parameter . IntParam ) ;
}
break ;
case EAudioParameterType : : IntegerArray :
{
TArray < int32 > TempArray = Parameter . ArrayIntParam ;
Parameter = FAudioParameter ( Parameter . ParamName , MoveTemp ( TempArray ) ) ;
}
break ;
case EAudioParameterType : : Object :
{
Parameter = FAudioParameter ( Parameter . ParamName , Parameter . ObjectParam ) ;
}
break ;
case EAudioParameterType : : ObjectArray :
{
TArray < UObject * > TempArray = Parameter . ArrayObjectParam ;
Parameter = FAudioParameter ( Parameter . ParamName , MoveTemp ( TempArray ) ) ;
}
break ;
case EAudioParameterType : : String :
{
Parameter = FAudioParameter ( Parameter . ParamName , Parameter . StringParam ) ;
}
break ;
case EAudioParameterType : : StringArray :
{
TArray < FString > TempArray = Parameter . ArrayStringParam ;
Parameter = FAudioParameter ( Parameter . ParamName , MoveTemp ( TempArray ) ) ;
}
break ;
case EAudioParameterType : : None :
default :
break ;
}
} ;
auto ConstructProxies = [ this , FeatureName = InFeatureName ] ( FAudioParameter & OutParamToInit )
{
using namespace Metasound ;
using namespace Metasound : : Frontend ;
const Audio : : FProxyDataInitParams ProxyInitParams { FeatureName } ;
if ( ! IsParameterValid ( OutParamToInit ) )
{
UE_LOG ( LogMetaSound , Error , TEXT ( " Failed to set invalid parameter '%s': Either does not exist or is invalid type " ) , * OutParamToInit . ParamName . ToString ( ) ) ;
return ;
}
switch ( OutParamToInit . ParamType )
{
case EAudioParameterType : : Object :
{
FDataTypeRegistryInfo DataTypeInfo ;
if ( IDataTypeRegistry : : Get ( ) . GetDataTypeInfo ( OutParamToInit . ObjectParam , DataTypeInfo ) )
{
Audio : : IProxyDataPtr ProxyPtr = IDataTypeRegistry : : Get ( ) . CreateProxyFromUObject ( DataTypeInfo . DataTypeName , OutParamToInit . ObjectParam ) ;
OutParamToInit . ObjectProxies . Emplace ( MoveTemp ( ProxyPtr ) ) ;
// Null out param as it is no longer needed (nor desired to be accessed once passed to the Audio Thread)
OutParamToInit . ObjectParam = nullptr ;
}
}
break ;
case EAudioParameterType : : ObjectArray :
{
for ( TObjectPtr < UObject > & Object : OutParamToInit . ArrayObjectParam )
{
FDataTypeRegistryInfo DataTypeInfo ;
if ( IDataTypeRegistry : : Get ( ) . GetDataTypeInfo ( Object , DataTypeInfo ) )
{
Audio : : IProxyDataPtr ProxyPtr = IDataTypeRegistry : : Get ( ) . CreateProxyFromUObject ( DataTypeInfo . DataTypeName , Object ) ;
OutParamToInit . ObjectProxies . Emplace ( MoveTemp ( ProxyPtr ) ) ;
}
}
// Reset param array as it is no longer needed (nor desired to be accessed once passed to the Audio Thread).
// All object manipulation hereafter should be done via proxies
OutParamToInit . ArrayObjectParam . Reset ( ) ;
}
break ;
default :
break ;
}
} ;
for ( FAudioParameter & Parameter : InParametersToInit )
{
Sanitize ( Parameter ) ;
ConstructProxies ( Parameter ) ;
}
}
2021-08-18 15:16:57 -04:00
void UMetaSoundSource : : InitResources ( )
{
2021-08-30 14:08:45 -04:00
using namespace Metasound : : Frontend ;
METASOUND_TRACE_CPUPROFILER_EVENT_SCOPE ( UMetaSoundSource : : InitResources ) ;
2021-08-18 15:16:57 -04:00
FMetaSoundAssetRegistrationOptions RegOptions ;
RegOptions . bForceReregister = false ;
RegOptions . bRegisterDependencies = true ;
RegisterGraphWithFrontend ( RegOptions ) ;
}
2021-06-16 11:21:13 -04:00
Metasound : : Frontend : : FNodeClassInfo UMetaSoundSource : : GetAssetClassInfo ( ) const
2021-06-08 10:52:31 -04:00
{
2021-06-16 11:21:13 -04:00
return { GetDocumentChecked ( ) . RootGraph , * GetPathName ( ) } ;
2021-06-08 10:52:31 -04:00
}
2020-12-14 15:48:27 -04:00
2021-04-02 02:09:50 -04:00
bool UMetaSoundSource : : IsPlayable ( ) const
2020-07-23 20:32:26 -04:00
{
// todo: cache off whether this metasound is buildable to an operator.
return true ;
}
2021-04-02 02:09:50 -04:00
bool UMetaSoundSource : : SupportsSubtitles ( ) const
2020-07-23 20:32:26 -04:00
{
return Super : : SupportsSubtitles ( ) ;
}
2021-06-23 20:08:21 -04:00
const FMetasoundFrontendVersion & UMetaSoundSource : : GetDefaultArchetypeVersion ( ) const
2021-06-08 10:52:31 -04:00
{
2021-06-23 20:08:21 -04:00
static const FMetasoundFrontendVersion DefaultVersion = Metasound : : Engine : : MetasoundSourceMono : : GetVersion ( ) ;
2021-06-08 10:52:31 -04:00
2021-06-23 20:08:21 -04:00
return DefaultVersion ;
2021-06-08 10:52:31 -04:00
}
2021-04-02 02:09:50 -04:00
float UMetaSoundSource : : GetDuration ( )
2020-07-23 20:32:26 -04:00
{
// eh? this is kind of a weird field anyways.
return Super : : GetDuration ( ) ;
}
2021-04-02 02:09:50 -04:00
ISoundGeneratorPtr UMetaSoundSource : : CreateSoundGenerator ( const FSoundGeneratorInitParams & InParams )
2020-07-23 20:32:26 -04:00
{
2020-11-17 17:52:08 -04:00
using namespace Metasound ;
2021-05-10 19:52:56 -04:00
using namespace Metasound : : Frontend ;
2021-06-23 20:08:21 -04:00
using namespace Metasound : : Engine ;
2020-11-17 17:52:08 -04:00
2021-08-18 15:16:57 -04:00
METASOUND_TRACE_CPUPROFILER_EVENT_SCOPE ( UMetaSoundSource : : CreateSoundGenerator ) ;
2021-08-11 15:22:01 -04:00
2020-07-23 20:32:26 -04:00
Duration = INDEFINITELY_LOOPING_DURATION ;
bLooping = true ;
2021-01-11 14:18:46 -04:00
2020-07-23 20:32:26 -04:00
SampleRate = InParams . SampleRate ;
2021-02-16 01:26:50 -04:00
FOperatorSettings InSettings = GetOperatorSettings ( static_cast < FSampleRate > ( SampleRate ) ) ;
2021-07-28 17:12:57 -04:00
FMetasoundEnvironment Environment = CreateEnvironment ( InParams ) ;
2020-07-23 20:32:26 -04:00
2021-07-28 17:12:57 -04:00
// TODO: cache graph to avoid having to create it every call to `CreateSoundGenerator(...)`
TUniquePtr < IGraph > MetasoundGraph = BuildMetasoundDocument ( ) ;
if ( ! MetasoundGraph . IsValid ( ) )
2020-11-17 17:52:08 -04:00
{
2021-07-28 17:12:57 -04:00
UE_LOG ( LogMetaSound , Error , TEXT ( " Cannot create UMetaSoundSource SoundGenerator [Name:%s]. Failed to create MetaSound Graph " ) , * GetName ( ) ) ;
2021-01-22 03:05:22 -04:00
return ISoundGeneratorPtr ( nullptr ) ;
}
2021-03-23 22:43:04 -04:00
FMetasoundGeneratorInitParams InitParams =
2021-02-10 21:43:31 -04:00
{
2021-03-23 22:43:04 -04:00
InSettings ,
2021-07-28 17:12:57 -04:00
MoveTemp ( MetasoundGraph ) ,
2021-03-23 22:43:04 -04:00
Environment ,
GetName ( ) ,
2021-07-28 17:12:57 -04:00
GetAudioOutputVertexKeys ( ) ,
2021-06-23 20:08:21 -04:00
MetasoundSource : : GetOnPlayInputName ( ) ,
MetasoundSource : : GetIsFinishedOutputName ( )
2021-03-23 22:43:04 -04:00
} ;
2020-07-23 20:32:26 -04:00
2021-03-23 22:43:04 -04:00
return ISoundGeneratorPtr ( new FMetasoundGenerator ( MoveTemp ( InitParams ) ) ) ;
2020-07-23 20:32:26 -04:00
}
2021-08-30 14:08:45 -04:00
bool UMetaSoundSource : : IsParameterValid ( const FAudioParameter & InParameter ) const
2021-01-22 03:05:22 -04:00
{
2021-08-30 14:08:45 -04:00
using namespace Metasound ;
using namespace Metasound : : Frontend ;
bool bIsValid = false ;
GetRootGraphHandle ( ) - > IterateConstNodes ( [ Param = & InParameter , bValid = & bIsValid ] ( FConstNodeHandle NodeHandle )
{
using namespace Metasound ;
using namespace Metasound : : Frontend ;
// TODO: Fix this. NodeHandles should use FNames, not display names (this is broken in other languages)
if ( Param - > ParamName = = * NodeHandle - > GetDisplayName ( ) . ToString ( ) )
{
TArray < FConstInputHandle > InputHandles = NodeHandle - > GetConstInputs ( ) ;
if ( InputHandles . IsEmpty ( ) )
{
return ;
}
const FName DataTypeName = InputHandles [ 0 ] - > GetDataType ( ) ;
switch ( Param - > ParamType )
{
case EAudioParameterType : : Boolean :
{
FDataTypeRegistryInfo DataTypeInfo ;
* bValid = IDataTypeRegistry : : Get ( ) . GetDataTypeInfo ( DataTypeName , DataTypeInfo ) ;
* bValid & = DataTypeInfo . bIsBoolParsable ;
}
break ;
case EAudioParameterType : : BooleanArray :
{
FDataTypeRegistryInfo DataTypeInfo ;
* bValid = IDataTypeRegistry : : Get ( ) . GetDataTypeInfo ( DataTypeName , DataTypeInfo ) ;
* bValid & = DataTypeInfo . bIsBoolArrayParsable ;
}
break ;
case EAudioParameterType : : Float :
{
FDataTypeRegistryInfo DataTypeInfo ;
* bValid = IDataTypeRegistry : : Get ( ) . GetDataTypeInfo ( DataTypeName , DataTypeInfo ) ;
* bValid & = DataTypeInfo . bIsFloatParsable ;
}
break ;
case EAudioParameterType : : FloatArray :
{
FDataTypeRegistryInfo DataTypeInfo ;
* bValid = IDataTypeRegistry : : Get ( ) . GetDataTypeInfo ( DataTypeName , DataTypeInfo ) ;
* bValid & = DataTypeInfo . bIsFloatArrayParsable ;
}
break ;
case EAudioParameterType : : Integer :
{
FDataTypeRegistryInfo DataTypeInfo ;
* bValid = IDataTypeRegistry : : Get ( ) . GetDataTypeInfo ( DataTypeName , DataTypeInfo ) ;
* bValid & = DataTypeInfo . bIsIntParsable ;
}
break ;
case EAudioParameterType : : IntegerArray :
{
FDataTypeRegistryInfo DataTypeInfo ;
* bValid = IDataTypeRegistry : : Get ( ) . GetDataTypeInfo ( DataTypeName , DataTypeInfo ) ;
* bValid & = DataTypeInfo . bIsIntArrayParsable ;
}
break ;
case EAudioParameterType : : Object :
{
FDataTypeRegistryInfo DataTypeInfo ;
* bValid = IDataTypeRegistry : : Get ( ) . GetDataTypeInfo ( Param - > ObjectParam , DataTypeInfo ) ;
* bValid & = DataTypeInfo . bIsProxyParsable ;
* bValid & = DataTypeInfo . DataTypeName = = DataTypeName ;
}
break ;
case EAudioParameterType : : ObjectArray :
{
* bValid = true ;
for ( UObject * Object : Param - > ArrayObjectParam )
{
FDataTypeRegistryInfo DataTypeInfo ;
* bValid = IDataTypeRegistry : : Get ( ) . GetDataTypeInfo ( Param - > ObjectParam , DataTypeInfo ) ;
* bValid & = DataTypeInfo . bIsProxyParsable ;
* bValid & = DataTypeInfo . DataTypeName = = DataTypeName ;
if ( ! * bValid )
{
break ;
}
}
}
break ;
case EAudioParameterType : : String :
{
FDataTypeRegistryInfo DataTypeInfo ;
* bValid = IDataTypeRegistry : : Get ( ) . GetDataTypeInfo ( DataTypeName , DataTypeInfo ) ;
* bValid & = DataTypeInfo . bIsStringParsable ;
}
break ;
case EAudioParameterType : : StringArray :
{
FDataTypeRegistryInfo DataTypeInfo ;
* bValid = IDataTypeRegistry : : Get ( ) . GetDataTypeInfo ( DataTypeName , DataTypeInfo ) ;
* bValid & = DataTypeInfo . bIsStringArrayParsable ;
}
break ;
case EAudioParameterType : : NoneArray :
{
FDataTypeRegistryInfo DataTypeInfo ;
* bValid = IDataTypeRegistry : : Get ( ) . GetDataTypeInfo ( DataTypeName , DataTypeInfo ) ;
* bValid & = DataTypeInfo . bIsDefaultArrayParsable ;
}
case EAudioParameterType : : None :
default :
{
FDataTypeRegistryInfo DataTypeInfo ;
* bValid = IDataTypeRegistry : : Get ( ) . GetDataTypeInfo ( DataTypeName , DataTypeInfo ) ;
* bValid & = DataTypeInfo . bIsDefaultParsable ;
}
break ;
}
}
} , EMetasoundFrontendClassType : : Input ) ;
return bIsValid ;
}
TUniquePtr < Audio : : IParameterTransmitter > UMetaSoundSource : : CreateParameterTransmitter ( Audio : : FParameterTransmitterInitParams & & InParams ) const
{
Metasound : : FMetaSoundParameterTransmitter : : FInitParams InitParams ( GetOperatorSettings ( InParams . SampleRate ) , InParams . InstanceID ) ;
2021-01-22 03:05:22 -04:00
2021-06-08 10:52:31 -04:00
for ( const FSendInfoAndVertexName & InfoAndName : FMetasoundAssetBase : : GetSendInfos ( InParams . InstanceID ) )
2021-01-22 03:05:22 -04:00
{
InitParams . Infos . Add ( InfoAndName . SendInfo ) ;
}
2021-08-30 14:08:45 -04:00
TUniquePtr < Audio : : IParameterTransmitter > NewTransmitter = MakeUnique < Metasound : : FMetaSoundParameterTransmitter > ( InitParams ) ;
for ( FAudioParameter & AudioParam : InParams . DefaultParams )
{
NewTransmitter - > SetParameter ( MoveTemp ( AudioParam ) ) ;
}
InParams . DefaultParams . Reset ( ) ;
return NewTransmitter ;
2021-01-22 03:05:22 -04:00
}
2021-04-02 02:09:50 -04:00
Metasound : : FOperatorSettings UMetaSoundSource : : GetOperatorSettings ( Metasound : : FSampleRate InSampleRate ) const
2021-01-22 03:05:22 -04:00
{
2021-06-08 10:52:31 -04:00
const float BlockRate = FMath : : Clamp ( Metasound : : ConsoleVariables : : BlockRate , 1.0f , 1000.0f ) ;
2021-01-22 03:05:22 -04:00
return Metasound : : FOperatorSettings ( InSampleRate , BlockRate ) ;
}
2021-06-23 20:08:21 -04:00
const TArray < FMetasoundFrontendVersion > & UMetaSoundSource : : GetSupportedArchetypeVersions ( ) const
2020-12-14 15:48:27 -04:00
{
2021-06-23 20:08:21 -04:00
static const TArray < FMetasoundFrontendVersion > Supported (
2021-08-18 15:16:57 -04:00
{
Metasound : : Engine : : MetasoundSourceMono : : GetVersion ( ) ,
Metasound : : Engine : : MetasoundSourceStereo : : GetVersion ( )
} ) ;
2021-01-13 10:48:59 -04:00
2021-06-23 20:08:21 -04:00
return Supported ;
2020-12-14 15:48:27 -04:00
}
2021-07-28 17:12:57 -04:00
Metasound : : FMetasoundEnvironment UMetaSoundSource : : CreateEnvironment ( ) const
{
using namespace Metasound ;
using namespace Metasound : : Engine ;
FMetasoundEnvironment Environment ;
// Add audio device ID to environment.
2021-08-23 15:24:06 -04:00
Audio : : FDeviceId AudioDeviceID = INDEX_NONE ;
2021-07-28 17:12:57 -04:00
if ( UWorld * World = GetWorld ( ) )
{
2021-08-23 15:24:06 -04:00
FAudioDeviceHandle DeviceHandle = World - > GetAudioDevice ( ) ;
if ( DeviceHandle . IsValid ( ) )
2021-07-28 17:12:57 -04:00
{
2021-08-23 15:24:06 -04:00
AudioDeviceID = DeviceHandle . GetDeviceID ( ) ;
2021-07-28 17:12:57 -04:00
}
}
2021-08-23 15:24:06 -04:00
if ( INDEX_NONE = = AudioDeviceID )
{
if ( FAudioDeviceManager * DeviceManager = FAudioDeviceManager : : Get ( ) )
{
AudioDeviceID = DeviceManager - > GetMainAudioDeviceID ( ) ;
}
}
Environment . SetValue < Audio : : FDeviceId > ( MetasoundSource : : GetAudioDeviceIDVariableName ( ) , AudioDeviceID ) ;
2021-07-28 17:12:57 -04:00
Environment . SetValue < uint32 > ( MetasoundSource : : GetSoundUniqueIdName ( ) , GetUniqueID ( ) ) ;
return Environment ;
}
Metasound : : FMetasoundEnvironment UMetaSoundSource : : CreateEnvironment ( const FSoundGeneratorInitParams & InParams ) const
{
using namespace Metasound ;
using namespace Metasound : : Engine ;
FMetasoundEnvironment Environment = CreateEnvironment ( ) ;
Environment . SetValue < bool > ( MetasoundSource : : GetIsPreviewSoundName ( ) , InParams . bIsPreviewSound ) ;
Environment . SetValue < uint64 > ( MetasoundSource : : GetInstanceIDName ( ) , InParams . InstanceID ) ;
2021-08-09 15:13:40 -04:00
# if WITH_METASOUND_DEBUG_ENVIRONMENT
Environment . SetValue < FString > ( MetasoundSource : : GetGraphName ( ) , GetFullName ( ) ) ;
# endif // WITH_METASOUND_DEBUG_ENVIRONMENT
2021-07-28 17:12:57 -04:00
return Environment ;
}
2021-08-30 14:08:45 -04:00
Metasound : : FMetasoundEnvironment UMetaSoundSource : : CreateEnvironment ( const Audio : : FParameterTransmitterInitParams & InParams ) const
2021-07-28 17:12:57 -04:00
{
using namespace Metasound ;
using namespace Metasound : : Engine ;
FMetasoundEnvironment Environment = CreateEnvironment ( ) ;
Environment . SetValue < uint64 > ( MetasoundSource : : GetInstanceIDName ( ) , InParams . InstanceID ) ;
return Environment ;
}
const TArray < Metasound : : FVertexKey > & UMetaSoundSource : : GetAudioOutputVertexKeys ( ) const
{
using namespace MetaSoundSourcePrivate ;
if ( const TArray < Metasound : : FVertexKey > * ArrayKeys = GetFormatOutputVertexKeys ( ) . Find ( OutputFormat ) )
{
return * ArrayKeys ;
}
else
{
// Unhandled audio format. Need to update audio output format vertex key map.
checkNoEntry ( ) ;
static const TArray < Metasound : : FVertexKey > Empty ;
return Empty ;
}
}
2021-05-28 16:17:48 -04:00
# undef LOCTEXT_NAMESPACE // MetaSoundSource