You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
- Fix return value improperly assigning value in MixModulatorNode, causing it always to be 0 or 1 based on if the modulator was registered (as return is if the value was found and assigned, and its a boolean cast when the modulator is found) - Remove unused parameter proxy ModHandle member - Don't re-register if parameter already registered - Remove duplicate validation call #rb helen.yang #rnx #jira UE-144721 #preflight 6221645ca00412627d1bfde2 #ROBOMERGE-AUTHOR: rob.gay #ROBOMERGE-SOURCE: CL 19259386 in //UE5/Release-5.0/... via CL 19260159 #ROBOMERGE-BOT: UE5 (Release-Engine-Staging -> Main) (v924-19243027) [CL 19263839 by rob gay in ue5-main branch]
292 lines
10 KiB
C++
292 lines
10 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
#pragma once
|
|
|
|
#include "AudioDefines.h"
|
|
#include "DSP/BufferVectorOperations.h"
|
|
#include "IAudioExtensionPlugin.h"
|
|
#include "IAudioProxyInitializer.h"
|
|
#include "Templates/SharedPointer.h"
|
|
#include "UObject/NameTypes.h"
|
|
|
|
#include "IAudioModulation.generated.h"
|
|
|
|
|
|
// Forward Declarations
|
|
class IAudioModulationManager;
|
|
class ISoundModulatable;
|
|
class USoundModulatorBase;
|
|
class UObject;
|
|
|
|
#if !UE_BUILD_SHIPPING
|
|
class FCanvas;
|
|
class FCommonViewportClient;
|
|
class FViewport;
|
|
class UFont;
|
|
#endif // !UE_BUILD_SHIPPING
|
|
|
|
namespace Audio
|
|
{
|
|
using FModulatorId = uint32;
|
|
using FModulatorTypeId = uint32;
|
|
using FModulatorHandleId = uint32;
|
|
|
|
using FModulationUnitConversionFunction = TFunction<void(float& /* OutValueNormalizedToUnit */)>;
|
|
using FModulationNormalizedConversionFunction = TFunction<void(float& /* OutValueUnitToNormalized */)>;
|
|
using FModulationMixFunction = TFunction<void(float& /* OutNormalizedA */, float /* InNormalizedB */)>;
|
|
|
|
|
|
struct AUDIOEXTENSIONS_API FModulationParameter
|
|
{
|
|
FModulationParameter();
|
|
FModulationParameter(const FModulationParameter& InParam);
|
|
FModulationParameter(FModulationParameter&& InParam);
|
|
|
|
FModulationParameter& operator=(FModulationParameter&& InParam);
|
|
FModulationParameter& operator=(const FModulationParameter& InParam);
|
|
|
|
FName ParameterName;
|
|
|
|
// Default value of parameter in unit space
|
|
float DefaultValue = 1.0f;
|
|
|
|
// Default minimum value of parameter in unit space
|
|
float MinValue = 0.0f;
|
|
|
|
// Default minimum value of parameter in unit space
|
|
float MaxValue = 1.0f;
|
|
|
|
// Whether or not unit conversion is required
|
|
bool bRequiresConversion = false;
|
|
|
|
#if WITH_EDITORONLY_DATA
|
|
FText UnitDisplayName;
|
|
#endif // WITH_EDITORONLY_DATA
|
|
|
|
// Function used to mix normalized values together.
|
|
FModulationMixFunction MixFunction;
|
|
|
|
// Function used to convert value buffer from normalized, unitless space [0.0f, 1.0f] to unit space.
|
|
FModulationUnitConversionFunction UnitFunction;
|
|
|
|
// Function used to convert value buffer from unit space to normalized, unitless [0.0f, 1.0f] space.
|
|
FModulationNormalizedConversionFunction NormalizedFunction;
|
|
|
|
static const FModulationMixFunction& GetDefaultMixFunction();
|
|
static const FModulationUnitConversionFunction& GetDefaultUnitConversionFunction();
|
|
static const FModulationNormalizedConversionFunction& GetDefaultNormalizedConversionFunction();
|
|
};
|
|
|
|
AUDIOEXTENSIONS_API bool IsModulationParameterRegistered(FName InName);
|
|
AUDIOEXTENSIONS_API void RegisterModulationParameter(FName InName, FModulationParameter&& InParameter);
|
|
AUDIOEXTENSIONS_API bool UnregisterModulationParameter(FName InName);
|
|
AUDIOEXTENSIONS_API void UnregisterAllModulationParameters();
|
|
AUDIOEXTENSIONS_API const FModulationParameter& GetModulationParameter(FName InName);
|
|
|
|
/** Interface for cached off Modulator UObject data used as default settings to
|
|
* be converted to instanced proxy data per AudioDevice on the AudioRenderThread.
|
|
* If proxy is already active, implementation is expected to ignore register call
|
|
* and return existing modulator proxy's type Id & set parameter accordingly.
|
|
*/
|
|
class AUDIOEXTENSIONS_API IModulatorSettings
|
|
{
|
|
public:
|
|
virtual ~IModulatorSettings() = default;
|
|
virtual TUniquePtr<IModulatorSettings> Clone() const = 0;
|
|
virtual FModulatorId GetModulatorId() const = 0;
|
|
virtual const Audio::FModulationParameter& GetOutputParameter() const = 0;
|
|
virtual Audio::FModulatorTypeId Register(
|
|
Audio::FModulatorHandleId HandleId,
|
|
IAudioModulationManager& InModulation) const = 0;
|
|
};
|
|
|
|
/** Handle to a modulator which interacts with the modulation API to manage lifetime
|
|
* of modulator proxy objects internal to modulation plugin implementation.
|
|
*/
|
|
struct AUDIOEXTENSIONS_API FModulatorHandle
|
|
{
|
|
FModulatorHandle() = default;
|
|
FModulatorHandle(Audio::FModulationParameter&& InParameter);
|
|
FModulatorHandle(IAudioModulationManager& InModulation, const Audio::IModulatorSettings& InModulatorSettings, Audio::FModulationParameter&& InParameter);
|
|
FModulatorHandle(const FModulatorHandle& InOther);
|
|
FModulatorHandle(FModulatorHandle&& InOther);
|
|
|
|
~FModulatorHandle();
|
|
|
|
FModulatorHandle& operator=(const FModulatorHandle& InOther);
|
|
FModulatorHandle& operator=(FModulatorHandle&& InOther);
|
|
|
|
FModulatorId GetModulatorId() const;
|
|
const FModulationParameter& GetParameter() const;
|
|
FModulatorTypeId GetTypeId() const;
|
|
FModulatorHandleId GetHandleId() const;
|
|
bool GetValue(float& OutValue) const;
|
|
bool GetValueThreadSafe(float& OutValue) const;
|
|
bool IsValid() const;
|
|
|
|
private:
|
|
FModulationParameter Parameter;
|
|
FModulatorHandleId HandleId = INDEX_NONE;
|
|
FModulatorTypeId ModulatorTypeId = INDEX_NONE;
|
|
FModulatorId ModulatorId = INDEX_NONE;
|
|
TWeakPtr<IAudioModulationManager> Modulation;
|
|
};
|
|
} // namespace Audio
|
|
|
|
class AUDIOEXTENSIONS_API IAudioModulationManager : public TSharedFromThis<IAudioModulationManager>
|
|
{
|
|
public:
|
|
/** Virtual destructor */
|
|
virtual ~IAudioModulationManager() { }
|
|
|
|
/** Initialize the modulation plugin with the same rate and number of sources */
|
|
virtual void Initialize(const FAudioPluginInitializationParams& InitializationParams) { }
|
|
|
|
virtual void OnAuditionEnd() { }
|
|
|
|
#if !UE_BUILD_SHIPPING
|
|
/** Request to post help from active plugin (non-shipping builds only) */
|
|
virtual bool OnPostHelp(FCommonViewportClient* ViewportClient, const TCHAR* Stream) { return false; };
|
|
|
|
/** Render stats pertaining to modulation (non-shipping builds only) */
|
|
virtual int32 OnRenderStat(FViewport* Viewport, FCanvas* Canvas, int32 X, int32 Y, const UFont& Font, const FVector* ViewLocation, const FRotator* ViewRotation) { return Y; }
|
|
|
|
/** Toggle showing render stats pertaining to modulation (non-shipping builds only) */
|
|
virtual bool OnToggleStat(FCommonViewportClient* ViewportClient, const TCHAR* Stream) { return false; }
|
|
#endif //!UE_BUILD_SHIPPING
|
|
|
|
/** Processes audio with the given input and output data structs.*/
|
|
virtual void ProcessAudio(const FAudioPluginSourceInputData& InputData, FAudioPluginSourceOutputData& OutputData) { }
|
|
|
|
/** Processes all modulators Run on the audio render thread prior to processing audio */
|
|
virtual void ProcessModulators(const double InElapsed) { }
|
|
|
|
/** Updates modulator definition on the AudioRender Thread with that provided by the UObject representation */
|
|
virtual void UpdateModulator(const USoundModulatorBase& InModulator) { }
|
|
|
|
protected:
|
|
virtual void RegisterModulator(uint32 InHandleId, Audio::FModulatorId InModulatorId) { }
|
|
|
|
// Get the modulator value from the AudioRender Thread
|
|
virtual bool GetModulatorValue(const Audio::FModulatorHandle& ModulatorHandle, float& OutValue) const { return false; }
|
|
|
|
// Get the modulator value from any thread.
|
|
virtual bool GetModulatorValueThreadSafe(const Audio::FModulatorHandle& ModulatorHandle, float& OutValue) const { return false; }
|
|
|
|
virtual void UnregisterModulator(const Audio::FModulatorHandle& InHandle) { }
|
|
|
|
friend Audio::FModulatorHandle;
|
|
};
|
|
|
|
/**
|
|
* Base class for all modulators
|
|
*/
|
|
UCLASS(config = Engine, abstract, editinlinenew, BlueprintType)
|
|
class AUDIOEXTENSIONS_API USoundModulatorBase : public UObject, public IAudioProxyDataFactory
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
virtual const Audio::FModulationParameter& GetOutputParameter() const;
|
|
|
|
virtual TUniquePtr<Audio::IProxyData> CreateNewProxyData(const Audio::FProxyDataInitParams& InitParams) override;
|
|
|
|
virtual TUniquePtr<Audio::IModulatorSettings> CreateProxySettings() const;
|
|
};
|
|
|
|
/** Proxy to modulator, allowing for modulator to be referenced by the Audio Render Thread independently
|
|
* from the implementing modulation plugin (ex. for MetaSound implementation).
|
|
*/
|
|
class AUDIOEXTENSIONS_API FSoundModulatorAssetProxy : public Audio::TProxyData<FSoundModulatorAssetProxy>, public TSharedFromThis<FSoundModulatorAssetProxy, ESPMode::ThreadSafe>
|
|
{
|
|
public:
|
|
IMPL_AUDIOPROXY_CLASS(FSoundModulatorAssetProxy);
|
|
|
|
FSoundModulatorAssetProxy(const FSoundModulatorAssetProxy& InAssetProxy)
|
|
: Parameter(InAssetProxy.Parameter)
|
|
, ModulatorSettings(InAssetProxy.ModulatorSettings.IsValid() ? InAssetProxy.ModulatorSettings->Clone() : nullptr)
|
|
{
|
|
}
|
|
|
|
FSoundModulatorAssetProxy(const USoundModulatorBase& InModulatorBase)
|
|
: Parameter(InModulatorBase.GetOutputParameter())
|
|
, ModulatorSettings(InModulatorBase.CreateProxySettings())
|
|
{
|
|
}
|
|
|
|
virtual Audio::IProxyDataPtr Clone() const
|
|
{
|
|
return MakeUnique<FSoundModulatorAssetProxy>(*this);
|
|
}
|
|
|
|
virtual Audio::FModulatorHandle CreateModulatorHandle(IAudioModulationManager& InModulation) const
|
|
{
|
|
check(ModulatorSettings.IsValid());
|
|
|
|
Audio::FModulationParameter HandleParameter = Parameter;
|
|
return Audio::FModulatorHandle(InModulation, *ModulatorSettings.Get(), MoveTemp(HandleParameter));
|
|
}
|
|
|
|
virtual Audio::FModulatorId GetModulatorId() const
|
|
{
|
|
check(ModulatorSettings.IsValid())
|
|
return ModulatorSettings->GetModulatorId();
|
|
}
|
|
|
|
protected:
|
|
Audio::FModulationParameter Parameter;
|
|
TUniquePtr<Audio::IModulatorSettings> ModulatorSettings;
|
|
};
|
|
using FSoundModulatorAssetProxyPtr = TSharedPtr<FSoundModulatorAssetProxy, ESPMode::ThreadSafe>;
|
|
|
|
/** Proxy to modulator, allowing for modulator to be referenced by the Audio Render Thread independently
|
|
* from the implementing modulation plugin (ex. for MetaSound implementation).
|
|
*/
|
|
class AUDIOEXTENSIONS_API FSoundModulationParameterAssetProxy : public Audio::TProxyData<FSoundModulationParameterAssetProxy>, public TSharedFromThis<FSoundModulationParameterAssetProxy, ESPMode::ThreadSafe>
|
|
{
|
|
public:
|
|
IMPL_AUDIOPROXY_CLASS(FSoundModulationParameterAssetProxy);
|
|
|
|
virtual Audio::IProxyDataPtr Clone() const override
|
|
{
|
|
return Audio::IProxyDataPtr();
|
|
}
|
|
|
|
virtual const Audio::FModulationParameter& GetParameter() const
|
|
{
|
|
return Parameter;
|
|
}
|
|
|
|
protected:
|
|
Audio::FModulationParameter Parameter;
|
|
};
|
|
using FSoundModulationParameterAssetProxyPtr = TSharedPtr<FSoundModulationParameterAssetProxy, ESPMode::ThreadSafe>;
|
|
|
|
/** Interface to sound that is modulatable, allowing for certain specific
|
|
* behaviors to be controlled on the sound level by the modulation system.
|
|
*/
|
|
class AUDIOEXTENSIONS_API ISoundModulatable
|
|
{
|
|
public:
|
|
virtual ~ISoundModulatable() = default;
|
|
|
|
/**
|
|
* Gets the object definition id of the given playing sound's instance
|
|
*/
|
|
virtual uint32 GetObjectId() const = 0;
|
|
|
|
/**
|
|
* Returns number of actively instances of sound playing (including virtualized instances)
|
|
*/
|
|
virtual int32 GetPlayCount() const = 0;
|
|
|
|
/**
|
|
* Returns whether or not sound is an editor preview sound
|
|
*/
|
|
virtual bool IsPreviewSound() const = 0;
|
|
|
|
/**
|
|
* Stops sound.
|
|
*/
|
|
virtual void Stop() = 0;
|
|
};
|