You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
This represents UE4/Main @ 16738161 and Dev-PerfTest @ 16737719 (and Release-17.00 @ 16658211) [CL 16763350 by aurel cordonnier in ue5-main branch]
338 lines
9.6 KiB
C++
338 lines
9.6 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "Components/SynthComponent.h"
|
|
|
|
#include "Containers/Array.h"
|
|
#include "HAL/CriticalSection.h"
|
|
#include "MediaSampleQueue.h"
|
|
#include "Misc/Timespan.h"
|
|
#include "Templates/Atomic.h"
|
|
#include "Templates/SharedPointer.h"
|
|
#include "UObject/ObjectMacros.h"
|
|
#include "UObject/ScriptMacros.h"
|
|
#include "DSP/SpectrumAnalyzer.h"
|
|
#include "DSP/BufferVectorOperations.h"
|
|
#include "DSP/EnvelopeFollower.h"
|
|
#include "Sound/SoundClass.h"
|
|
|
|
#include "MediaSoundComponent.generated.h"
|
|
|
|
class FMediaAudioResampler;
|
|
class FMediaPlayerFacade;
|
|
class FMediaSoundComponentClockSink;
|
|
class IMediaAudioSample;
|
|
class IMediaPlayer;
|
|
class UMediaPlayer;
|
|
|
|
|
|
/**
|
|
* Available media sound channel types.
|
|
*/
|
|
UENUM()
|
|
enum class EMediaSoundChannels
|
|
{
|
|
/** Mono (1 channel). */
|
|
Mono,
|
|
|
|
/** Stereo (2 channels). */
|
|
Stereo,
|
|
|
|
/** Surround sound (7.1 channels; for UI). */
|
|
Surround
|
|
};
|
|
|
|
UENUM(BlueprintType)
|
|
enum class EMediaSoundComponentFFTSize : uint8
|
|
{
|
|
Min_64,
|
|
Small_256,
|
|
Medium_512,
|
|
Large_1024,
|
|
};
|
|
|
|
USTRUCT(BlueprintType)
|
|
struct FMediaSoundComponentSpectralData
|
|
{
|
|
GENERATED_USTRUCT_BODY()
|
|
|
|
// The frequency hz of the spectrum value
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SpectralData")
|
|
float FrequencyHz = 0.0f;
|
|
|
|
// The magnitude of the spectrum at this frequency
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "SpectralData")
|
|
float Magnitude = 0.0f;
|
|
};
|
|
|
|
/**
|
|
* Implements a sound component for playing a media player's audio output.
|
|
*/
|
|
UCLASS(ClassGroup=Media, editinlinenew, meta=(BlueprintSpawnableComponent))
|
|
class MEDIAASSETS_API UMediaSoundComponent
|
|
: public USynthComponent
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
|
|
/** Media sound channel type. */
|
|
UPROPERTY(EditAnywhere, Category="Media")
|
|
EMediaSoundChannels Channels;
|
|
|
|
/** Dynamically adjust the sample rate if audio and media clock desynchronize. */
|
|
UPROPERTY(EditAnywhere, Category="Media", AdvancedDisplay)
|
|
bool DynamicRateAdjustment;
|
|
|
|
/**
|
|
* Factor for calculating the sample rate adjustment.
|
|
*
|
|
* If dynamic rate adjustment is enabled, this number is multiplied with the drift
|
|
* between the audio and media clock (in 100ns ticks) to determine the adjustment.
|
|
* that is to be multiplied into the current playrate.
|
|
*/
|
|
UPROPERTY(EditAnywhere, Category="Media", AdvancedDisplay)
|
|
float RateAdjustmentFactor;
|
|
|
|
/**
|
|
* The allowed range of dynamic rate adjustment.
|
|
*
|
|
* If dynamic rate adjustment is enabled, and the necessary adjustment
|
|
* falls outside of this range, audio samples will be dropped.
|
|
*/
|
|
UPROPERTY(EditAnywhere, Category="Media", AdvancedDisplay)
|
|
FFloatRange RateAdjustmentRange;
|
|
|
|
public:
|
|
|
|
/**
|
|
* Create and initialize a new instance.
|
|
*
|
|
* @param ObjectInitializer Initialization parameters.
|
|
*/
|
|
UMediaSoundComponent(const FObjectInitializer& ObjectInitializer);
|
|
|
|
/** Virtual destructor. */
|
|
~UMediaSoundComponent();
|
|
|
|
public:
|
|
|
|
/**
|
|
* Get the attenuation settings based on the current component settings.
|
|
*
|
|
* @param OutAttenuationSettings Will contain the attenuation settings, if available.
|
|
* @return true if attenuation settings were returned, false if attenuation is disabled.
|
|
*/
|
|
UFUNCTION(BlueprintCallable, Category="Media|MediaSoundComponent", meta=(DisplayName="Get Attenuation Settings To Apply", ScriptName="GetAttenuationSettingsToApply"))
|
|
bool BP_GetAttenuationSettingsToApply(FSoundAttenuationSettings& OutAttenuationSettings);
|
|
|
|
/**
|
|
* Get the media player that provides the audio samples.
|
|
*
|
|
* @return The component's media player, or nullptr if not set.
|
|
* @see SetMediaPlayer
|
|
*/
|
|
UFUNCTION(BlueprintCallable, Category="Media|MediaSoundComponent")
|
|
UMediaPlayer* GetMediaPlayer() const;
|
|
|
|
virtual USoundClass* GetSoundClass() override
|
|
{
|
|
if (SoundClass)
|
|
{
|
|
return SoundClass;
|
|
}
|
|
|
|
if (const UAudioSettings* AudioSettings = GetDefault<UAudioSettings>())
|
|
{
|
|
if (USoundClass* DefaultSoundClass = AudioSettings->GetDefaultMediaSoundClass())
|
|
{
|
|
return DefaultSoundClass;
|
|
}
|
|
|
|
if (USoundClass* DefaultSoundClass = AudioSettings->GetDefaultSoundClass())
|
|
{
|
|
return DefaultSoundClass;
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
/**
|
|
* Set the media player that provides the audio samples.
|
|
*
|
|
* @param NewMediaPlayer The player to set.
|
|
* @see GetMediaPlayer
|
|
*/
|
|
UFUNCTION(BlueprintCallable, Category="Media|MediaSoundComponent")
|
|
void SetMediaPlayer(UMediaPlayer* NewMediaPlayer);
|
|
|
|
/** Turns on spectral analysis of the audio generated in the media sound component. */
|
|
UFUNCTION(BlueprintCallable, Category = "Media|MediaSoundComponent")
|
|
void SetEnableSpectralAnalysis(bool bInSpectralAnalysisEnabled);
|
|
|
|
/** Sets the settings to use for spectral analysis. */
|
|
UFUNCTION(BlueprintCallable, Category = "Media|MediaSoundComponent")
|
|
void SetSpectralAnalysisSettings(TArray<float> InFrequenciesToAnalyze, EMediaSoundComponentFFTSize InFFTSize = EMediaSoundComponentFFTSize::Medium_512);
|
|
|
|
/** Retrieves the spectral data if spectral analysis is enabled. */
|
|
UFUNCTION(BlueprintCallable, Category = "TimeSynth")
|
|
TArray<FMediaSoundComponentSpectralData> GetSpectralData();
|
|
|
|
/** Retrieves and normalizes the spectral data if spectral analysis is enabled. */
|
|
UFUNCTION(BlueprintCallable, Category = "TimeSynth")
|
|
TArray<FMediaSoundComponentSpectralData> GetNormalizedSpectralData();
|
|
|
|
/** Turns on amplitude envelope following the audio in the media sound component. */
|
|
UFUNCTION(BlueprintCallable, Category = "Media|MediaSoundComponent")
|
|
void SetEnableEnvelopeFollowing(bool bInEnvelopeFollowing);
|
|
|
|
/** Sets the envelope attack and release times (in ms). */
|
|
UFUNCTION(BlueprintCallable, Category = "Media|MediaSoundComponent")
|
|
void SetEnvelopeFollowingsettings(int32 AttackTimeMsec, int32 ReleaseTimeMsec);
|
|
|
|
/** Retrieves the current amplitude envelope. */
|
|
UFUNCTION(BlueprintCallable, Category = "TimeSynth")
|
|
float GetEnvelopeValue() const;
|
|
|
|
public:
|
|
|
|
/** Adds a clock sink so this can be ticked without the world. */
|
|
void AddClockSink();
|
|
|
|
/** Removes the clock sink. */
|
|
void RemoveClockSink();
|
|
|
|
void UpdatePlayer();
|
|
|
|
#if WITH_EDITOR
|
|
/**
|
|
* Set the component's default media player property.
|
|
*
|
|
* @param NewMediaPlayer The player to set.
|
|
* @see SetMediaPlayer
|
|
*/
|
|
void SetDefaultMediaPlayer(UMediaPlayer* NewMediaPlayer);
|
|
#endif
|
|
|
|
public:
|
|
|
|
//~ TAttenuatedComponentVisualizer interface
|
|
|
|
void CollectAttenuationShapesForVisualization(TMultiMap<EAttenuationShape::Type, FBaseAttenuationSettings::AttenuationShapeDetails>& ShapeDetailsMap) const;
|
|
|
|
public:
|
|
|
|
//~ UActorComponent interface
|
|
|
|
virtual void OnRegister() override;
|
|
virtual void OnUnregister() override;
|
|
virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override;
|
|
|
|
public:
|
|
|
|
//~ USceneComponent interface
|
|
|
|
virtual void Activate(bool bReset = false) override;
|
|
virtual void Deactivate() override;
|
|
|
|
public:
|
|
|
|
//~ UObject interface
|
|
virtual void PostLoad() override;
|
|
|
|
#if WITH_EDITOR
|
|
virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
|
|
#endif
|
|
|
|
protected:
|
|
|
|
/**
|
|
* Get the attenuation settings based on the current component settings.
|
|
*
|
|
* @return Attenuation settings, or nullptr if attenuation is disabled.
|
|
*/
|
|
const FSoundAttenuationSettings* GetSelectedAttenuationSettings() const;
|
|
|
|
protected:
|
|
|
|
//~ USynthComponent interface
|
|
|
|
virtual bool Init(int32& SampleRate) override;
|
|
virtual int32 OnGenerateAudio(float* OutAudio, int32 NumSamples) override;
|
|
|
|
protected:
|
|
|
|
/**
|
|
* The media player asset associated with this component.
|
|
*
|
|
* This property is meant for design-time convenience. To change the
|
|
* associated media player at run-time, use the SetMediaPlayer method.
|
|
*
|
|
* @see SetMediaPlayer
|
|
*/
|
|
UPROPERTY(EditAnywhere, Category="Media")
|
|
TObjectPtr<UMediaPlayer> MediaPlayer;
|
|
|
|
private:
|
|
|
|
/** The player's current play rate (cached for use on audio thread). */
|
|
TAtomic<float> CachedRate;
|
|
|
|
/** The player's current time (cached for use on audio thread). */
|
|
TAtomic<FTimespan> CachedTime;
|
|
|
|
/** Critical section for synchronizing access to PlayerFacadePtr. */
|
|
FCriticalSection CriticalSection;
|
|
|
|
/** The player that is currently associated with this component. */
|
|
TWeakObjectPtr<UMediaPlayer> CurrentPlayer;
|
|
|
|
/** The player facade that's currently providing texture samples. */
|
|
TWeakPtr<FMediaPlayerFacade, ESPMode::ThreadSafe> CurrentPlayerFacade;
|
|
|
|
/** Adjusts the output sample rate to synchronize audio and media clock. */
|
|
float RateAdjustment;
|
|
|
|
/** The audio resampler. */
|
|
FMediaAudioResampler* Resampler;
|
|
|
|
/** Audio sample queue. */
|
|
TSharedPtr<FMediaAudioSampleQueue, ESPMode::ThreadSafe> SampleQueue;
|
|
|
|
/* Time of last sample played. */
|
|
TAtomic<FTimespan> LastPlaySampleTime;
|
|
|
|
/** Which frequencies to analyze. */
|
|
TArray<float> FrequenciesToAnalyze;
|
|
|
|
/** The FFT bin-size to use for FFT analysis. Smaller sizes make it more reactive but less accurate in the frequency space. */
|
|
EMediaSoundComponentFFTSize FFTSize;
|
|
|
|
/** Spectrum analyzer used for analyzing audio in media. */
|
|
Audio::FAsyncSpectrumAnalyzer SpectrumAnalyzer;
|
|
Audio::FSpectrumAnalyzerSettings SpectrumAnalyzerSettings;
|
|
|
|
Audio::FEnvelopeFollower EnvelopeFollower;
|
|
int32 EnvelopeFollowerAttackTime;
|
|
int32 EnvelopeFollowerReleaseTime;
|
|
float CurrentEnvelopeValue;
|
|
FCriticalSection EnvelopeFollowerCriticalSection;
|
|
|
|
/** Scratch buffer to mix in source audio to from decoder */
|
|
Audio::AlignedFloatBuffer AudioScratchBuffer;
|
|
|
|
/** Whether or not spectral analysis is enabled. */
|
|
bool bSpectralAnalysisEnabled;
|
|
|
|
/** Whether or not envelope following is enabled. */
|
|
bool bEnvelopeFollowingEnabled;
|
|
|
|
/** Whether or not envelope follower settings changed. */
|
|
bool bEnvelopeFollowerSettingsChanged;
|
|
|
|
/** Holds our clock sink if available. */
|
|
TSharedPtr<FMediaSoundComponentClockSink, ESPMode::ThreadSafe> ClockSink;
|
|
};
|