Files
UnrealEngineUWP/Engine/Plugins/Runtime/Metasound/Source/MetasoundEngine/Private/MetasoundOutputSubsystem.cpp
robert rouhani 3f492576f2 [Metasound] Add native delegate option for WatchOutput in FMetasoundGeneratorHandle and related classes.
- Updated StressTest_MetasoundOutputs to optionally use the new native delegates.
- In local testing the native delegates were ~40% faster on average than dynamic delegates, when measuring FMetasoundGeneratorHandle::UpdateOutputWatchers.

#rb charlie.huguenard phil.popp
#tests EngineTest - PIE, Standalone


#virtualized

[CL 29067112 by robert rouhani in ue5-main branch]
2023-10-25 00:54:11 -04:00

108 lines
2.8 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "MetasoundOutputSubsystem.h"
#include "MetasoundGenerator.h"
#include "MetasoundGeneratorHandle.h"
#include "MetasoundSource.h"
#include "MetasoundTrace.h"
#include "Components/AudioComponent.h"
#include "ProfilingDebugging/CpuProfilerTrace.h"
bool UMetaSoundOutputSubsystem::WatchOutput(
UAudioComponent* AudioComponent,
const FName OutputName,
const FOnMetasoundOutputValueChanged& OnOutputValueChanged,
const FName AnalyzerName,
const FName AnalyzerOutputName)
{
METASOUND_TRACE_CPUPROFILER_EVENT_SCOPE(UMetasoundOutputSubsystem::WatchOutput_Dynamic);
UMetasoundGeneratorHandle* Handle = GetOrCreateGeneratorHandle(AudioComponent);
if (nullptr == Handle)
{
return false;
}
return Handle->WatchOutput(OutputName, OnOutputValueChanged, AnalyzerName, AnalyzerOutputName);
}
bool UMetaSoundOutputSubsystem::WatchOutput(
UAudioComponent* AudioComponent,
const FName OutputName,
const FOnMetasoundOutputValueChangedNative& OnOutputValueChanged,
const FName AnalyzerName,
const FName AnalyzerOutputName)
{
METASOUND_TRACE_CPUPROFILER_EVENT_SCOPE(UMetasoundOutputSubsystem::WatchOutput_Native);
UMetasoundGeneratorHandle* Handle = GetOrCreateGeneratorHandle(AudioComponent);
if (nullptr == Handle)
{
return false;
}
return Handle->WatchOutput(OutputName, OnOutputValueChanged, AnalyzerName, AnalyzerOutputName);
}
bool UMetaSoundOutputSubsystem::IsTickable() const
{
return TrackedGenerators.Num() > 0;
}
void UMetaSoundOutputSubsystem::Tick(float DeltaTime)
{
METASOUND_TRACE_CPUPROFILER_EVENT_SCOPE(UMetasoundOutputSubsystem::Tick);
for (auto It = TrackedGenerators.CreateIterator(); It; ++It)
{
if (!(*It)->IsValid())
{
It.RemoveCurrent();
}
else
{
(*It)->UpdateWatchers();
}
}
}
TStatId UMetaSoundOutputSubsystem::GetStatId() const
{
RETURN_QUICK_DECLARE_CYCLE_STAT(UMetasoundGeneratorAccessSubsystem, STATGROUP_Tickables);
}
UMetasoundGeneratorHandle* UMetaSoundOutputSubsystem::GetOrCreateGeneratorHandle(UAudioComponent* AudioComponent)
{
if (nullptr == AudioComponent)
{
return nullptr;
}
UMetasoundGeneratorHandle* Handle = nullptr;
// Try to find an existing handle
const uint64 AudioComponentId = AudioComponent->GetAudioComponentID();
if (const TObjectPtr<UMetasoundGeneratorHandle>* FoundHandle = TrackedGenerators.FindByPredicate(
[AudioComponentId](const TObjectPtr<UMetasoundGeneratorHandle> ExistingHandle)
{
return ExistingHandle->IsValid() && ExistingHandle->GetAudioComponentId() == AudioComponentId;
}))
{
Handle = *FoundHandle;
}
// Create a new one
else
{
Handle = UMetasoundGeneratorHandle::CreateMetaSoundGeneratorHandle(AudioComponent);
if (nullptr != Handle && Handle->IsValid())
{
TrackedGenerators.Add(Handle);
}
}
return Handle;
}