Files
UnrealEngine/Engine/Plugins/Runtime/MicrosoftSpatialAudio/Source/MicrosoftSpatialSound/Public/MicrosoftSpatialSoundPlugin.h
2025-05-18 13:04:45 +08:00

140 lines
3.8 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "Modules/ModuleManager.h"
#include "IAudioExtensionPlugin.h"
#include "DSP/Dsp.h"
#include "HAL/Runnable.h"
#include "HAL/RunnableThread.h"
#include "Templates/Function.h"
#include "Containers/Queue.h"
#include "SpatialAudioClientInterop.h"
// Struct to hold dynamic object data for Microsoft Spatial Sound API
struct FSpatialSoundSourceObjectData
{
FSpatialSoundSourceObjectData()
: StartingPosition(FVector::ZeroVector)
, CurrentPosition(FVector::ZeroVector)
, TargetPosition(FVector::ZeroVector)
, CurrentFrameLerpPosition(0)
, NumberOfLerpFrames(0)
, AudioBuffer(4096*50)
, ObjectHandle(nullptr)
, bActive(false)
, bBuffering(false)
{
}
// The position of the spatial sound source
FVector StartingPosition;
FVector CurrentPosition;
FVector TargetPosition;
int32 CurrentFrameLerpPosition;
int32 NumberOfLerpFrames;
// A circular buffer to hold audio data from the source.
Audio::TCircularAudioBuffer<float> AudioBuffer;
// The handle to the source
ISpatialAudioObject* ObjectHandle;
FCriticalSection ObjectCritSect;
// Whether or not this source data is active (playing sound)
bool bActive;
bool bBuffering;
};
// Implementation of IAudioSpatialization for Microsoft Spatial Sound API
class FMicrosoftSpatialSound :
public IAudioSpatialization,
protected FRunnable
{
public:
FMicrosoftSpatialSound();
~FMicrosoftSpatialSound();
/** Begin IAudioSpatialization interface */
virtual void Initialize(const FAudioPluginInitializationParams InitializationParams) override;
virtual void Shutdown() override;
virtual bool IsSpatializationEffectInitialized() const override { return bIsInitialized; };
virtual void OnInitSource(const uint32 SourceId, const FName& AudioComponentUserId, USpatializationPluginSourceSettingsBase* InSettings) override;
virtual void OnReleaseSource(const uint32 SourceId) override;
virtual void ProcessAudio(const FAudioPluginSourceInputData& InputData, FAudioPluginSourceOutputData& OutputData);
/** End of IAudioSpatialization interface */
/** Begin FRunnable */
virtual uint32 Run() override;
/** End FRunnable */
private:
void FreeResources();
FAudioPluginInitializationParams InitializationParams;
// Command queue
TQueue<TFunction<void()>> CommandQueue;
// The minimum amount of frames which need to be queued before processing audio objects
uint32 MinFramesRequiredPerObjectUpdate;
// Array of spatial sound source objects
TArray<FSpatialSoundSourceObjectData> Objects;
// The max dynamic objects
uint32 MaxDynamicObjects;
// The spatial audio render thread
FRunnableThread* SpatialAudioRenderThread;
// The rendering critical section
FCriticalSection SpatialSoundCritSect;
// If the spatial audio render thread is running
FThreadSafeBool bIsRendering;
SpatialAudioClient* SAC;
bool bIsInitialized;
};
class FMicrosoftSpatialSoundPluginFactory : public IAudioSpatializationFactory
{
public:
virtual FString GetDisplayName() override
{
static FString DisplayName = FString(TEXT("Microsoft Spatial Sound"));
return DisplayName;
}
virtual bool SupportsPlatform(const FString& PlatformName) override
{
return (PlatformName == TEXT("Windows")) || (PlatformName == TEXT("XboxOne"));
}
// Microsoft spatial sound dynamic objects render objects externally from the audio renderer
virtual bool IsExternalSend() override { return true; };
virtual TAudioSpatializationPtr CreateNewSpatializationPlugin(FAudioDevice* OwningDevice) override
{
return TAudioSpatializationPtr(new FMicrosoftSpatialSound());
};
};
class FMicrosoftSpatialSoundModule : public IModuleInterface
{
public:
virtual void StartupModule() override;
virtual void ShutdownModule() override;
private:
void* LibraryHandle = nullptr;
FMicrosoftSpatialSoundPluginFactory PluginFactory;
};