2021-11-22 15:55:50 -05:00
|
|
|
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
|
#include "MetasoundInterface.h"
|
|
|
|
|
|
2021-12-10 20:37:31 -05:00
|
|
|
#include "Algo/Transform.h"
|
|
|
|
|
#include "AudioParameterControllerInterface.h"
|
|
|
|
|
#include "IAudioParameterInterfaceRegistry.h"
|
2021-11-22 15:55:50 -05:00
|
|
|
#include "IAudioParameterTransmitter.h"
|
2023-03-07 17:01:52 -05:00
|
|
|
#include "Interfaces/MetasoundInputFormatInterfaces.h"
|
|
|
|
|
#include "Interfaces/MetasoundOutputFormatInterfaces.h"
|
2022-08-19 12:14:31 -04:00
|
|
|
#include "Interfaces/MetasoundFrontendSourceInterface.h"
|
2023-03-07 17:01:52 -05:00
|
|
|
#include "Metasound.h"
|
2021-12-10 20:37:31 -05:00
|
|
|
#include "MetasoundEngineArchetypes.h"
|
2023-03-07 17:01:52 -05:00
|
|
|
#include "MetasoundFrontendArchetypeRegistry.h"
|
2021-12-10 20:37:31 -05:00
|
|
|
#include "MetasoundFrontendDataTypeRegistry.h"
|
|
|
|
|
#include "MetasoundFrontendDocument.h"
|
|
|
|
|
#include "MetasoundFrontendTransform.h"
|
|
|
|
|
#include "MetasoundLog.h"
|
|
|
|
|
#include "MetasoundParameterTransmitter.h"
|
|
|
|
|
#include "MetasoundSource.h"
|
|
|
|
|
#include "MetasoundUObjectRegistry.h"
|
|
|
|
|
#include "Templates/SharedPointer.h"
|
|
|
|
|
#include "Templates/UniquePtr.h"
|
|
|
|
|
#include "UObject/Class.h"
|
|
|
|
|
#include "UObject/NoExportTypes.h"
|
2021-11-22 15:55:50 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace Metasound
|
|
|
|
|
{
|
|
|
|
|
namespace Engine
|
|
|
|
|
{
|
2023-03-07 17:01:52 -05:00
|
|
|
struct FInterfaceRegistryUClassOptions
|
|
|
|
|
{
|
|
|
|
|
FName ClassName;
|
|
|
|
|
bool bIsDefault = false;
|
|
|
|
|
bool bEditorCanAddOrRemove = false;
|
|
|
|
|
};
|
|
|
|
|
|
2021-12-10 20:37:31 -05:00
|
|
|
struct FInterfaceRegistryOptions
|
2021-11-22 15:55:50 -05:00
|
|
|
{
|
2021-12-10 20:37:31 -05:00
|
|
|
FName InputSystemName;
|
2023-03-07 17:01:52 -05:00
|
|
|
TArray<FInterfaceRegistryUClassOptions> UClassOptions;
|
2021-12-10 20:37:31 -05:00
|
|
|
};
|
2021-11-22 15:55:50 -05:00
|
|
|
|
2021-12-10 20:37:31 -05:00
|
|
|
// Entry for registered interface.
|
|
|
|
|
class FInterfaceRegistryEntry : public Frontend::IInterfaceRegistryEntry
|
|
|
|
|
{
|
2023-03-07 17:01:52 -05:00
|
|
|
const FInterfaceRegistryUClassOptions* FindOptionsByClassName(FName ClassName) const
|
|
|
|
|
{
|
|
|
|
|
auto NameIsEqual = [&ClassName](const FInterfaceRegistryUClassOptions& InOptions)
|
|
|
|
|
{
|
|
|
|
|
return InOptions.ClassName == ClassName;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return Options.UClassOptions.FindByPredicate(NameIsEqual);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool SortBindingsByConnectionPriorityPredicate(const FMetasoundFrontendInterfaceBinding& A, const FMetasoundFrontendInterfaceBinding& B)
|
|
|
|
|
{
|
|
|
|
|
return A.ConnectionPriority < B.ConnectionPriority;
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-10 20:37:31 -05:00
|
|
|
public:
|
|
|
|
|
FInterfaceRegistryEntry(
|
|
|
|
|
const FMetasoundFrontendInterface& InInterface,
|
|
|
|
|
TUniquePtr<Frontend::IDocumentTransform>&& InUpdateTransform,
|
|
|
|
|
FInterfaceRegistryOptions&& InOptions
|
|
|
|
|
)
|
|
|
|
|
: Interface(InInterface)
|
|
|
|
|
, UpdateTransform(MoveTemp(InUpdateTransform))
|
|
|
|
|
, Options(MoveTemp(InOptions))
|
2021-11-22 15:55:50 -05:00
|
|
|
{
|
2021-12-10 20:37:31 -05:00
|
|
|
}
|
|
|
|
|
|
2023-03-07 17:01:52 -05:00
|
|
|
virtual void AddOutputBindings(TArray<FMetasoundFrontendInterfaceBinding>&& InBindings) override
|
2021-12-15 23:11:10 -05:00
|
|
|
{
|
2023-03-07 17:01:52 -05:00
|
|
|
OutputBindings.Append(MoveTemp(InBindings));
|
|
|
|
|
OutputBindings.Sort(&SortBindingsByConnectionPriorityPredicate);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual bool EditorCanAddOrRemove(FName InUClassName) const override
|
|
|
|
|
{
|
|
|
|
|
if (const FInterfaceRegistryUClassOptions* UClassOptions = FindOptionsByClassName(InUClassName))
|
|
|
|
|
{
|
|
|
|
|
return UClassOptions->bEditorCanAddOrRemove;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
2021-12-15 23:11:10 -05:00
|
|
|
}
|
|
|
|
|
|
2021-12-10 20:37:31 -05:00
|
|
|
virtual bool UClassIsSupported(FName InUClassName) const override
|
|
|
|
|
{
|
2023-03-07 17:01:52 -05:00
|
|
|
if (const FInterfaceRegistryUClassOptions* UClassOptions = FindOptionsByClassName(InUClassName))
|
2021-11-22 15:55:50 -05:00
|
|
|
{
|
2021-12-10 20:37:31 -05:00
|
|
|
return true;
|
2021-12-01 15:59:03 -05:00
|
|
|
}
|
2021-12-10 20:37:31 -05:00
|
|
|
|
|
|
|
|
// TODO: Support child asset class types.
|
2023-03-07 17:01:52 -05:00
|
|
|
return false;
|
2021-12-10 20:37:31 -05:00
|
|
|
}
|
|
|
|
|
|
2023-03-07 17:01:52 -05:00
|
|
|
virtual bool IsDefault(FName InUClassName) const override
|
2021-12-10 20:37:31 -05:00
|
|
|
{
|
2023-03-07 17:01:52 -05:00
|
|
|
if (const FInterfaceRegistryUClassOptions* UClassOptions = FindOptionsByClassName(InUClassName))
|
|
|
|
|
{
|
|
|
|
|
return UClassOptions->bIsDefault;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
2021-12-10 20:37:31 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual FName GetRouterName() const override
|
|
|
|
|
{
|
|
|
|
|
return Options.InputSystemName;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual const FMetasoundFrontendInterface& GetInterface() const override
|
|
|
|
|
{
|
|
|
|
|
return Interface;
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-07 17:01:52 -05:00
|
|
|
virtual const TArray<FMetasoundFrontendInterfaceBinding>& GetOutputBindings() const override
|
|
|
|
|
{
|
|
|
|
|
return OutputBindings;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual bool RemoveOutputBinding(const FMetasoundFrontendVersion& InInterfaceVersion) override
|
|
|
|
|
{
|
|
|
|
|
return OutputBindings.RemoveAll([&InInterfaceVersion](const FMetasoundFrontendInterfaceBinding& Binding)
|
|
|
|
|
{
|
|
|
|
|
return Binding.Version == InInterfaceVersion;
|
|
|
|
|
}) > 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual void ResetOutputBindings()
|
|
|
|
|
{
|
|
|
|
|
OutputBindings.Reset();
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-10 20:37:31 -05:00
|
|
|
virtual bool UpdateRootGraphInterface(Frontend::FDocumentHandle InDocument) const override
|
|
|
|
|
{
|
|
|
|
|
if (UpdateTransform.IsValid())
|
|
|
|
|
{
|
|
|
|
|
return UpdateTransform->Transform(InDocument);
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
FMetasoundFrontendInterface Interface;
|
2023-03-07 17:01:52 -05:00
|
|
|
TArray<FMetasoundFrontendInterfaceBinding> OutputBindings;
|
2021-12-10 20:37:31 -05:00
|
|
|
TUniquePtr<Frontend::IDocumentTransform> UpdateTransform;
|
|
|
|
|
FInterfaceRegistryOptions Options;
|
|
|
|
|
};
|
|
|
|
|
|
2023-03-07 17:01:52 -05:00
|
|
|
FMetasoundFrontendInterface ConvertParameterToFrontendInterface(const Audio::FParameterInterface& InInterface)
|
2021-12-10 20:37:31 -05:00
|
|
|
{
|
|
|
|
|
using namespace Frontend;
|
|
|
|
|
|
|
|
|
|
auto ResolveMemberDataType = [](FName DataType, EAudioParameterType ParamType)
|
|
|
|
|
{
|
|
|
|
|
if (!DataType.IsNone())
|
|
|
|
|
{
|
|
|
|
|
const bool bIsRegisteredType = Frontend::IDataTypeRegistry::Get().IsRegistered(DataType);
|
|
|
|
|
if (ensureAlwaysMsgf(bIsRegisteredType, TEXT("Attempting to register Interface member with unregistered DataType '%s'."), *DataType.ToString()))
|
|
|
|
|
{
|
|
|
|
|
return DataType;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ConvertParameterToDataType(ParamType);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
FMetasoundFrontendInterface FrontendInterface;
|
2023-03-07 17:01:52 -05:00
|
|
|
FrontendInterface.Version = { InInterface.GetName(), FMetasoundFrontendVersionNumber { InInterface.GetVersion().Major, InInterface.GetVersion().Minor } };
|
2021-12-10 20:37:31 -05:00
|
|
|
|
2022-03-01 16:31:55 -05:00
|
|
|
// Transfer all input data from AudioExtension interface struct to FrontendInterface
|
2021-12-10 20:37:31 -05:00
|
|
|
{
|
2023-03-07 17:01:52 -05:00
|
|
|
Algo::Transform(InInterface.GetInputs(), FrontendInterface.Inputs, [&](const Audio::FParameterInterface::FInput& Input)
|
2022-02-25 09:45:49 -05:00
|
|
|
{
|
2022-03-01 16:31:55 -05:00
|
|
|
FMetasoundFrontendClassInput ClassInput;
|
|
|
|
|
ClassInput.Name = Input.InitValue.ParamName;
|
|
|
|
|
ClassInput.DefaultLiteral = FMetasoundFrontendLiteral(Input.InitValue);
|
|
|
|
|
ClassInput.TypeName = ResolveMemberDataType(Input.DataType, Input.InitValue.ParamType);
|
2022-01-26 18:11:52 -05:00
|
|
|
|
2022-02-10 15:07:39 -05:00
|
|
|
#if WITH_EDITOR
|
2022-03-01 16:31:55 -05:00
|
|
|
// Interfaces should never serialize text to avoid desync between
|
|
|
|
|
// copied versions serialized in assets and those defined in code.
|
|
|
|
|
ClassInput.Metadata.SetSerializeText(false);
|
|
|
|
|
ClassInput.Metadata.SetDisplayName(Input.DisplayName);
|
|
|
|
|
ClassInput.Metadata.SetDescription(Input.Description);
|
|
|
|
|
ClassInput.Metadata.SortOrderIndex = Input.SortOrderIndex;
|
|
|
|
|
|
2022-03-02 16:52:01 -05:00
|
|
|
FrontendInterface.AddSortOrderToInputStyle(Input.SortOrderIndex);
|
2022-03-01 16:31:55 -05:00
|
|
|
|
|
|
|
|
// Setup required inputs by telling the style that the input is required
|
|
|
|
|
// This will later be validated against.
|
|
|
|
|
if (!Input.RequiredText.IsEmpty())
|
|
|
|
|
{
|
|
|
|
|
FrontendInterface.AddRequiredInputToStyle(Input.InitValue.ParamName, Input.RequiredText);
|
|
|
|
|
}
|
2022-02-10 15:07:39 -05:00
|
|
|
#endif // WITH_EDITOR
|
2022-01-26 18:11:52 -05:00
|
|
|
|
2022-03-01 16:31:55 -05:00
|
|
|
ClassInput.VertexID = FGuid::NewGuid();
|
2021-12-10 20:37:31 -05:00
|
|
|
|
2022-03-01 16:31:55 -05:00
|
|
|
return ClassInput;
|
|
|
|
|
});
|
|
|
|
|
}
|
2021-12-10 20:37:31 -05:00
|
|
|
|
2022-03-01 16:31:55 -05:00
|
|
|
// Transfer all output data from AudioExtension interface struct to FrontendInterface
|
2021-12-10 20:37:31 -05:00
|
|
|
{
|
2023-03-07 17:01:52 -05:00
|
|
|
Algo::Transform(InInterface.GetOutputs(), FrontendInterface.Outputs, [&](const Audio::FParameterInterface::FOutput& Output)
|
2022-02-25 09:45:49 -05:00
|
|
|
{
|
2022-03-01 16:31:55 -05:00
|
|
|
FMetasoundFrontendClassOutput ClassOutput;
|
|
|
|
|
ClassOutput.Name = Output.ParamName;
|
|
|
|
|
ClassOutput.TypeName = ResolveMemberDataType(Output.DataType, Output.ParamType);
|
2021-12-10 20:37:31 -05:00
|
|
|
|
2022-02-10 15:07:39 -05:00
|
|
|
#if WITH_EDITOR
|
2022-03-01 16:31:55 -05:00
|
|
|
// Interfaces should never serialize text to avoid desync between
|
|
|
|
|
// copied versions serialized in assets and those defined in code.
|
|
|
|
|
ClassOutput.Metadata.SetSerializeText(false);
|
|
|
|
|
ClassOutput.Metadata.SetDisplayName(Output.DisplayName);
|
|
|
|
|
ClassOutput.Metadata.SetDescription(Output.Description);
|
|
|
|
|
ClassOutput.Metadata.SortOrderIndex = Output.SortOrderIndex;
|
|
|
|
|
|
2022-03-02 16:52:01 -05:00
|
|
|
FrontendInterface.AddSortOrderToOutputStyle(Output.SortOrderIndex);
|
2022-03-01 16:31:55 -05:00
|
|
|
|
|
|
|
|
// Setup required outputs by telling the style that the output is required
|
|
|
|
|
// This will later be validated against.
|
|
|
|
|
if (!Output.RequiredText.IsEmpty())
|
|
|
|
|
{
|
|
|
|
|
FrontendInterface.AddRequiredOutputToStyle(Output.ParamName, Output.RequiredText);
|
|
|
|
|
}
|
2022-02-10 15:07:39 -05:00
|
|
|
#endif // WITH_EDITOR
|
|
|
|
|
|
2022-03-01 16:31:55 -05:00
|
|
|
ClassOutput.VertexID = FGuid::NewGuid();
|
2022-01-26 18:11:52 -05:00
|
|
|
|
2022-03-01 16:31:55 -05:00
|
|
|
return ClassOutput;
|
|
|
|
|
});
|
|
|
|
|
}
|
2021-12-10 20:37:31 -05:00
|
|
|
|
2023-03-07 17:01:52 -05:00
|
|
|
Algo::Transform(InInterface.GetEnvironment(), FrontendInterface.Environment, [&](const Audio::FParameterInterface::FEnvironmentVariable& Environment)
|
2021-12-10 20:37:31 -05:00
|
|
|
{
|
|
|
|
|
FMetasoundFrontendClassEnvironmentVariable EnvironmentVariable;
|
|
|
|
|
EnvironmentVariable.Name = Environment.ParamName;
|
|
|
|
|
|
|
|
|
|
// Disabled as it isn't used to infer type when getting/setting at a lower level.
|
|
|
|
|
// TODO: Either remove type info for environment variables all together or enforce type.
|
|
|
|
|
// EnvironmentVariable.TypeName = ResolveMemberDataType(Environment.DataType, Environment.ParamType);
|
|
|
|
|
|
|
|
|
|
return EnvironmentVariable;
|
|
|
|
|
});
|
|
|
|
|
|
2023-03-07 17:01:52 -05:00
|
|
|
return FrontendInterface;
|
2021-12-10 20:37:31 -05:00
|
|
|
}
|
|
|
|
|
|
2023-03-07 17:01:52 -05:00
|
|
|
void RegisterUClasses()
|
|
|
|
|
{
|
|
|
|
|
IMetasoundUObjectRegistry::Get().RegisterUClass(MakeUnique<TMetasoundUObjectRegistryEntry<UMetaSoundPatch>>());
|
|
|
|
|
IMetasoundUObjectRegistry::Get().RegisterUClass(MakeUnique<TMetasoundUObjectRegistryEntry<UMetaSoundSource>>());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RegisterInterface(Audio::FParameterInterfacePtr Interface, TUniquePtr<Frontend::IDocumentTransform>&& InUpdateTransform, FInterfaceRegistryOptions&& InOptions)
|
2021-12-10 20:37:31 -05:00
|
|
|
{
|
|
|
|
|
using namespace Frontend;
|
|
|
|
|
|
2023-03-07 17:01:52 -05:00
|
|
|
const FMetasoundFrontendInterface FrontendInterface = ConvertParameterToFrontendInterface(*Interface);
|
|
|
|
|
IInterfaceRegistry::Get().RegisterInterface(MakeUnique<FInterfaceRegistryEntry>(FrontendInterface, MoveTemp(InUpdateTransform), MoveTemp(InOptions)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RegisterInterface(const FMetasoundFrontendInterface& InInterface, TUniquePtr<Frontend::IDocumentTransform>&& InUpdateTransform, FInterfaceRegistryOptions&& InOptions)
|
|
|
|
|
{
|
|
|
|
|
using namespace Frontend;
|
|
|
|
|
IInterfaceRegistry::Get().RegisterInterface(MakeUnique<FInterfaceRegistryEntry>(InInterface, MoveTemp(InUpdateTransform), MoveTemp(InOptions)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template <typename UClassType>
|
|
|
|
|
void RegisterInterfaceForSingleClass(Audio::FParameterInterfacePtr Interface, TUniquePtr<Frontend::IDocumentTransform>&& InUpdateTransform, bool bInIsDefault = false, bool bInEditorCanAddOrRemove = false, FName InRouterName = IDataReference::RouterName)
|
|
|
|
|
{
|
|
|
|
|
using namespace Frontend;
|
|
|
|
|
|
|
|
|
|
const FMetasoundFrontendInterface FrontendInterface = ConvertParameterToFrontendInterface(*Interface);
|
|
|
|
|
RegisterInterface(FrontendInterface, MoveTemp(InUpdateTransform), FInterfaceRegistryOptions
|
2021-12-10 20:37:31 -05:00
|
|
|
{
|
2023-03-07 17:01:52 -05:00
|
|
|
InRouterName,
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
UClassType::StaticClass()->GetFName(),
|
|
|
|
|
bInIsDefault,
|
|
|
|
|
bInEditorCanAddOrRemove
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
2021-12-10 20:37:31 -05:00
|
|
|
|
2023-03-07 17:01:52 -05:00
|
|
|
template <typename UClassType>
|
|
|
|
|
void RegisterInterfaceForSingleClass(const FMetasoundFrontendInterface& InInterface, TUniquePtr<Frontend::IDocumentTransform>&& InUpdateTransform, bool bInIsDefault = false, bool bInEditorCanAddOrRemove = false, FName InRouterName = IDataReference::RouterName)
|
|
|
|
|
{
|
|
|
|
|
using namespace Frontend;
|
2022-02-25 09:45:49 -05:00
|
|
|
|
2023-03-07 17:01:52 -05:00
|
|
|
RegisterInterface(InInterface, MoveTemp(InUpdateTransform), FInterfaceRegistryOptions
|
|
|
|
|
{
|
|
|
|
|
InRouterName,
|
|
|
|
|
{
|
|
|
|
|
{
|
|
|
|
|
UClassType::StaticClass()->GetFName(),
|
|
|
|
|
bInIsDefault,
|
|
|
|
|
bInEditorCanAddOrRemove
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RegisterAudioFormatInterfaces()
|
|
|
|
|
{
|
|
|
|
|
using namespace Frontend;
|
|
|
|
|
|
|
|
|
|
const FName SourceClassName = UMetaSoundSource::StaticClass()->GetFName();
|
|
|
|
|
const FName PatchClassName = UMetaSoundPatch::StaticClass()->GetFName();
|
|
|
|
|
|
|
|
|
|
// Input Formats
|
|
|
|
|
{
|
|
|
|
|
RegisterInterface(InputFormatMonoInterface::CreateInterface(), nullptr, FInterfaceRegistryOptions
|
|
|
|
|
{
|
|
|
|
|
IDataReference::RouterName,
|
|
|
|
|
{
|
|
|
|
|
{ PatchClassName, false /* bIsDefault */, true /* bEditorCanAddOrRemove */ },
|
|
|
|
|
{ SourceClassName },
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
IInterfaceRegistry::Get().AddInterfaceOutputBindings(InputFormatMonoInterface::GetVersion(), InputFormatMonoInterface::CreateOutputBindings());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
RegisterInterface(InputFormatStereoInterface::CreateInterface(), nullptr, FInterfaceRegistryOptions
|
|
|
|
|
{
|
|
|
|
|
IDataReference::RouterName,
|
|
|
|
|
{
|
|
|
|
|
{ PatchClassName, false /* bIsDefault */, true /* bEditorCanAddOrRemove */ },
|
|
|
|
|
{ SourceClassName },
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
IInterfaceRegistry::Get().AddInterfaceOutputBindings(InputFormatStereoInterface::GetVersion(), InputFormatStereoInterface::CreateOutputBindings());
|
2021-12-10 20:37:31 -05:00
|
|
|
}
|
|
|
|
|
|
2023-03-07 17:01:52 -05:00
|
|
|
// Output Formats
|
2021-12-10 20:37:31 -05:00
|
|
|
{
|
2023-03-07 17:01:52 -05:00
|
|
|
RegisterInterface(OutputFormatMonoInterface::CreateInterface(), nullptr, FInterfaceRegistryOptions
|
|
|
|
|
{
|
|
|
|
|
IDataReference::RouterName,
|
|
|
|
|
{
|
|
|
|
|
{ PatchClassName, false /* bIsDefault */, true /* bEditorCanAddOrRemove */ },
|
|
|
|
|
{ SourceClassName, true /* bIsDefault */, false /* bEditorCanAddOrRemove */ },
|
|
|
|
|
}
|
|
|
|
|
});
|
2021-12-10 20:37:31 -05:00
|
|
|
|
2023-03-07 17:01:52 -05:00
|
|
|
RegisterInterface(OutputFormatStereoInterface::CreateInterface(), nullptr, FInterfaceRegistryOptions
|
|
|
|
|
{
|
|
|
|
|
IDataReference::RouterName,
|
|
|
|
|
{
|
|
|
|
|
{ PatchClassName, false /* bIsDefault */, true /* bEditorCanAddOrRemove */ },
|
|
|
|
|
{ SourceClassName },
|
|
|
|
|
}
|
|
|
|
|
});
|
2021-12-10 20:37:31 -05:00
|
|
|
|
2023-03-07 17:01:52 -05:00
|
|
|
RegisterInterface(OutputFormatQuadInterface::CreateInterface(), nullptr, FInterfaceRegistryOptions
|
|
|
|
|
{
|
|
|
|
|
IDataReference::RouterName,
|
|
|
|
|
{
|
|
|
|
|
{ PatchClassName, false /* bIsDefault */, true /* bEditorCanAddOrRemove */ },
|
|
|
|
|
{ SourceClassName },
|
|
|
|
|
}
|
|
|
|
|
});
|
2021-12-10 20:37:31 -05:00
|
|
|
|
2023-03-07 17:01:52 -05:00
|
|
|
RegisterInterface(OutputFormatFiveDotOneInterface::CreateInterface(), nullptr, FInterfaceRegistryOptions
|
|
|
|
|
{
|
|
|
|
|
IDataReference::RouterName,
|
|
|
|
|
{
|
|
|
|
|
{ PatchClassName, false /* bIsDefault */, true /* bEditorCanAddOrRemove */ },
|
|
|
|
|
{ SourceClassName },
|
|
|
|
|
}
|
|
|
|
|
});
|
2021-12-10 20:37:31 -05:00
|
|
|
|
2023-03-07 17:01:52 -05:00
|
|
|
RegisterInterface(OutputFormatSevenDotOneInterface::CreateInterface(), nullptr, FInterfaceRegistryOptions
|
|
|
|
|
{
|
|
|
|
|
IDataReference::RouterName,
|
|
|
|
|
{
|
|
|
|
|
{ PatchClassName, false /* bIsDefault */, true /* bEditorCanAddOrRemove */ },
|
|
|
|
|
{ SourceClassName },
|
|
|
|
|
}
|
|
|
|
|
});
|
2021-12-10 20:37:31 -05:00
|
|
|
}
|
2023-03-07 17:01:52 -05:00
|
|
|
}
|
2021-12-10 20:37:31 -05:00
|
|
|
|
2023-03-07 17:01:52 -05:00
|
|
|
void RegisterDeprecatedInterfaces()
|
|
|
|
|
{
|
|
|
|
|
using namespace Frontend;
|
|
|
|
|
|
|
|
|
|
RegisterInterfaceForSingleClass<UMetaSoundSource>(SourceInterfaceV1_0::CreateInterface(), nullptr);
|
|
|
|
|
|
|
|
|
|
// Set default interface with unset version to use base UMetaSoundPatch class implementation (legacy requirement for 5.0 alpha).
|
|
|
|
|
RegisterInterfaceForSingleClass<UMetaSoundPatch>(FMetasoundFrontendInterface(), nullptr);
|
|
|
|
|
|
|
|
|
|
RegisterInterfaceForSingleClass<UMetaSoundSource>(MetasoundOutputFormatStereoV1_0::GetInterface(), nullptr);
|
|
|
|
|
RegisterInterfaceForSingleClass<UMetaSoundSource>(MetasoundOutputFormatStereoV1_1::GetInterface(), MakeUnique<MetasoundOutputFormatStereoV1_1::FUpdateInterface>());
|
|
|
|
|
RegisterInterfaceForSingleClass<UMetaSoundSource>(MetasoundOutputFormatStereoV1_2::GetInterface(), MakeUnique<MetasoundOutputFormatStereoV1_2::FUpdateInterface>());
|
|
|
|
|
|
|
|
|
|
RegisterInterfaceForSingleClass<UMetaSoundSource>(MetasoundOutputFormatMonoV1_0::GetInterface(), nullptr);
|
|
|
|
|
RegisterInterfaceForSingleClass<UMetaSoundSource>(MetasoundOutputFormatMonoV1_1::GetInterface(), MakeUnique<MetasoundOutputFormatMonoV1_1::FUpdateInterface>());
|
|
|
|
|
RegisterInterfaceForSingleClass<UMetaSoundSource>(MetasoundOutputFormatMonoV1_2::GetInterface(), MakeUnique<MetasoundOutputFormatMonoV1_2::FUpdateInterface>());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RegisterExternalInterfaces()
|
|
|
|
|
{
|
2021-12-10 20:37:31 -05:00
|
|
|
// Register External Interfaces (Interfaces defined externally & can be managed directly by end-user).
|
|
|
|
|
auto RegisterExternalInterface = [](Audio::FParameterInterfacePtr Interface)
|
|
|
|
|
{
|
2023-03-07 17:01:52 -05:00
|
|
|
FInterfaceRegistryOptions Options { Audio::IParameterTransmitter::RouterName };
|
|
|
|
|
|
2021-12-10 20:37:31 -05:00
|
|
|
// Currently, no externally defined interfaces can be added as default for protection against undesired
|
2021-12-15 23:11:10 -05:00
|
|
|
// interfaces automatically being added when creating a new MetaSound asset through the editor. Also,
|
|
|
|
|
// all parameter interfaces are enabled in the editor for addition/removal.
|
2021-12-10 20:37:31 -05:00
|
|
|
constexpr bool bIsDefault = false;
|
2021-12-15 23:11:10 -05:00
|
|
|
constexpr bool bEditorCanAddOrRemove = true;
|
|
|
|
|
|
2023-03-07 17:01:52 -05:00
|
|
|
bool bInterfaceSupportsPatch = true;
|
|
|
|
|
bool bInterfaceSupportsSource = true;
|
|
|
|
|
const TArray<const UClass*> SupportedUClasses = Interface->FindSupportedUClasses();
|
|
|
|
|
for (const UClass* SupportedUClass : SupportedUClasses )
|
|
|
|
|
{
|
|
|
|
|
const UClass* PatchClass = UMetaSoundPatch::StaticClass();
|
|
|
|
|
check(PatchClass);
|
|
|
|
|
bInterfaceSupportsPatch |= PatchClass->IsChildOf(SupportedUClass);
|
|
|
|
|
|
|
|
|
|
const UClass* SourceClass = UMetaSoundSource::StaticClass();
|
|
|
|
|
check(SourceClass);
|
|
|
|
|
bInterfaceSupportsSource |= SourceClass->IsChildOf(SupportedUClass);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const bool bSupported = bInterfaceSupportsSource || bInterfaceSupportsPatch;
|
|
|
|
|
if (ensureAlwaysMsgf(bSupported, TEXT("Parameter interface '%s' type not supported by MetaSounds"), *Interface->GetName().ToString()))
|
|
|
|
|
{
|
|
|
|
|
const FMetasoundFrontendInterface FrontendInterface = ConvertParameterToFrontendInterface(*Interface);
|
|
|
|
|
if (bInterfaceSupportsPatch)
|
|
|
|
|
{
|
|
|
|
|
const FName ClassName = UMetaSoundPatch::StaticClass()->GetFName();
|
|
|
|
|
Options.UClassOptions.Add(FInterfaceRegistryUClassOptions { ClassName, bIsDefault, bEditorCanAddOrRemove });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (bInterfaceSupportsSource)
|
|
|
|
|
{
|
|
|
|
|
const FName ClassName = UMetaSoundSource::StaticClass()->GetFName();
|
|
|
|
|
Options.UClassOptions.Add(FInterfaceRegistryUClassOptions { ClassName, bIsDefault, bEditorCanAddOrRemove });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RegisterInterface(FrontendInterface, nullptr, MoveTemp(Options));
|
|
|
|
|
}
|
2021-12-10 20:37:31 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Audio::IAudioParameterInterfaceRegistry::Get().IterateInterfaces(RegisterExternalInterface);
|
|
|
|
|
Audio::IAudioParameterInterfaceRegistry::Get().OnRegistration(MoveTemp(RegisterExternalInterface));
|
2021-11-22 15:55:50 -05:00
|
|
|
}
|
2023-03-07 17:01:52 -05:00
|
|
|
|
|
|
|
|
void RegisterInterfaces()
|
|
|
|
|
{
|
|
|
|
|
using namespace Frontend;
|
|
|
|
|
|
|
|
|
|
// Default Patch Interfaces (legacy)
|
|
|
|
|
{
|
|
|
|
|
RegisterInterfaceForSingleClass<UMetaSoundPatch>(MetasoundV1_0::GetInterface(), nullptr, true, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Default Source Interfaces
|
|
|
|
|
{
|
|
|
|
|
RegisterInterfaceForSingleClass<UMetaSoundSource>(SourceInterface::CreateInterface(), MakeUnique<SourceInterface::FUpdateInterface>(), true, false);
|
|
|
|
|
RegisterInterfaceForSingleClass<UMetaSoundSource>(SourceOneShotInterface::CreateInterface(), nullptr, true, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RegisterAudioFormatInterfaces();
|
|
|
|
|
RegisterDeprecatedInterfaces();
|
|
|
|
|
RegisterExternalInterfaces();
|
|
|
|
|
}
|
2021-11-22 15:55:50 -05:00
|
|
|
} // namespace Engine
|
|
|
|
|
} // namespace Metasound
|