// Copyright Epic Games, Inc. All Rights Reserved. #include "Interfaces/MetasoundInterface.h" #include "Algo/Transform.h" #include "AudioParameterControllerInterface.h" #include "IAudioParameterInterfaceRegistry.h" #include "IAudioParameterTransmitter.h" #include "Interfaces/MetasoundFrontendInterfaceRegistry.h" #include "Interfaces/MetasoundFrontendSourceInterface.h" #include "Interfaces/MetasoundInputFormatInterfaces.h" #include "Interfaces/MetasoundOutputFormatInterfaces.h" #include "Metasound.h" #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" namespace Metasound::Engine { FInterfaceRegistryEntry::FInterfaceRegistryEntry(FMetasoundFrontendInterface&& InInterface, FName InRouterName, bool bInIsDeprecated) : Interface(MoveTemp(InInterface)) , RouterName(InRouterName) , bIsDeprecated(bInIsDeprecated) { } FInterfaceRegistryEntry::FInterfaceRegistryEntry(const FMetasoundFrontendInterface& InInterface, FName InRouterName, bool bInIsDeprecated) : Interface(InInterface) , RouterName(InRouterName) , bIsDeprecated(bInIsDeprecated) { } FInterfaceRegistryEntry::FInterfaceRegistryEntry(const FMetasoundFrontendInterface& InInterface, TUniquePtr&& InUpdateTransform, FName InRouterName, bool bInIsDeprecated) : Interface(InInterface) , UpdateTransform(MoveTemp(InUpdateTransform)) , RouterName(InRouterName) , bIsDeprecated(bInIsDeprecated) { } FName FInterfaceRegistryEntry::GetRouterName() const { return RouterName; } const FMetasoundFrontendInterface& FInterfaceRegistryEntry::GetInterface() const { return Interface; } bool FInterfaceRegistryEntry::IsDeprecated() const { return bIsDeprecated; } bool FInterfaceRegistryEntry::UpdateRootGraphInterface(Frontend::FDocumentHandle InDocument) const { if (UpdateTransform.IsValid()) { return UpdateTransform->Transform(InDocument); } return false; } bool FInterfaceRegistryEntry::UpdateRootGraphInterface(FMetaSoundFrontendDocumentBuilder& InDocumentBuilder) const { if (UpdateTransform.IsValid()) { return UpdateRootGraphInterface(InDocumentBuilder.GetMetasoundAsset().GetDocumentHandle()); } return InDocumentBuilder.AddInterface(GetInterface().Metadata.Version.Name); } void RegisterAudioFormatInterfaces() { using namespace Frontend; IInterfaceRegistry& Reg = IInterfaceRegistry::Get(); // Input Formats { Reg.RegisterInterface(MakeUnique(InputFormatMonoInterface::CreateInterface())); Reg.RegisterInterface(MakeUnique(InputFormatStereoInterface::CreateInterface())); Reg.RegisterInterface(MakeUnique(InputFormatQuadInterface::CreateInterface())); Reg.RegisterInterface(MakeUnique(InputFormatFiveDotOneInterface::CreateInterface())); Reg.RegisterInterface(MakeUnique(InputFormatSevenDotOneInterface::CreateInterface())); } // Output Formats { Reg.RegisterInterface(MakeUnique(OutputFormatMonoInterface::CreateInterface())); Reg.RegisterInterface(MakeUnique(OutputFormatStereoInterface::CreateInterface())); Reg.RegisterInterface(MakeUnique(OutputFormatQuadInterface::CreateInterface())); Reg.RegisterInterface(MakeUnique(OutputFormatFiveDotOneInterface::CreateInterface())); Reg.RegisterInterface(MakeUnique(OutputFormatSevenDotOneInterface::CreateInterface())); } } void RegisterExternalInterfaces() { // Register External Interfaces (Interfaces defined externally & can be managed directly by end-user). auto RegisterExternalInterface = [](Audio::FParameterInterfacePtr Interface) { using namespace Frontend; bool bSupportedInterface = false; IMetasoundUObjectRegistry::Get().IterateRegisteredUClasses([&bSupportedInterface, &Interface](UClass& InRegisteredClass) { const TArray SupportedUClasses = Interface->FindSupportedUClasses(); bSupportedInterface |= SupportedUClasses.IsEmpty(); for (const UClass* SupportedUClass : SupportedUClasses) { check(SupportedUClass); bSupportedInterface |= SupportedUClass->IsChildOf(&InRegisteredClass); } }); if (bSupportedInterface) { IInterfaceRegistry::Get().RegisterInterface(MakeUnique(FMetasoundFrontendInterface(Interface), Audio::IParameterTransmitter::RouterName)); } else { UE_LOG(LogMetaSound, Warning, TEXT("Parameter interface '%s' not supported by MetaSounds"), *Interface->GetName().ToString()); } }; Audio::IAudioParameterInterfaceRegistry::Get().IterateInterfaces(RegisterExternalInterface); Audio::IAudioParameterInterfaceRegistry::Get().OnRegistration(MoveTemp(RegisterExternalInterface)); } void RegisterInterfaces() { using namespace Frontend; IInterfaceRegistry& Reg = IInterfaceRegistry::Get(); // Default Source Interfaces { Reg.RegisterInterface(MakeUnique(SourceInterface::CreateInterface(*UMetaSoundSource::StaticClass()), MakeUnique())); Reg.RegisterInterface(MakeUnique(SourceOneShotInterface::CreateInterface(*UMetaSoundSource::StaticClass()))); Reg.RegisterInterface(MakeUnique(SourceStartTimeInterface::CreateInterface(*UMetaSoundSource::StaticClass()))); } RegisterAudioFormatInterfaces(); RegisterExternalInterfaces(); } } // namespace Metasound::Engine