audio: share decoded clip cache across sources
This commit is contained in:
@@ -2,7 +2,10 @@
|
||||
|
||||
#include <XCEngine/Components/Component.h>
|
||||
#include <XCEngine/Components/TransformComponent.h>
|
||||
#include <XCEngine/Audio/HRTF.h>
|
||||
#include <XCEngine/Audio/AudioTypes.h>
|
||||
#include <XCEngine/Core/Asset/AssetRef.h>
|
||||
#include <XCEngine/Core/Asset/ResourceHandle.h>
|
||||
#include <XCEngine/Resources/AudioClip/AudioClip.h>
|
||||
#include <XCEngine/Core/Math/Vector3.h>
|
||||
#include <XCEngine/Core/Math/Quaternion.h>
|
||||
@@ -30,6 +33,10 @@ public:
|
||||
|
||||
void SetClip(Resources::AudioClip* clip);
|
||||
Resources::AudioClip* GetClip() const { return m_clip; }
|
||||
void SetClipPath(const std::string& clipPath);
|
||||
void ClearClip();
|
||||
const std::string& GetClipPath() const { return m_clipPath; }
|
||||
const Resources::AssetRef& GetClipAssetRef() const { return m_clipRef; }
|
||||
|
||||
void SetVolume(float volume);
|
||||
float GetVolume() const { return m_volume; }
|
||||
@@ -40,6 +47,13 @@ public:
|
||||
void SetPan(float pan);
|
||||
float GetPan() const { return m_pan; }
|
||||
|
||||
void SetHRTFEnabled(bool enabled);
|
||||
bool IsHRTFEnabled() const { return m_useHRTF; }
|
||||
void SetHRTFCrossFeed(float crossFeed);
|
||||
float GetHRTFCrossFeed() const { return m_hrtf.GetCrossFeed(); }
|
||||
void SetHRTFQuality(Audio::uint32 level);
|
||||
Audio::uint32 GetHRTFQuality() const { return m_hrtf.GetQualityLevel(); }
|
||||
|
||||
void SetLooping(bool loop);
|
||||
bool IsLooping() const { return m_isLooping; }
|
||||
|
||||
@@ -74,20 +88,34 @@ public:
|
||||
void OnEnable() override;
|
||||
void OnDisable() override;
|
||||
void OnDestroy() override;
|
||||
void Serialize(std::ostream& os) const override;
|
||||
void Deserialize(std::istream& is) override;
|
||||
|
||||
void ProcessAudio(float* buffer, Audio::uint32 sampleCount, Audio::uint32 channels,
|
||||
void ProcessAudio(float* buffer, Audio::uint32 frameCount, Audio::uint32 channels,
|
||||
const Math::Vector3& listenerPosition,
|
||||
const Math::Quaternion& listenerRotation);
|
||||
const Math::Quaternion& listenerRotation,
|
||||
const Math::Vector3& listenerVelocity = Math::Vector3::Zero(),
|
||||
float listenerDopplerLevel = 1.0f,
|
||||
float speedOfSound = 343.0f,
|
||||
Audio::uint32 outputSampleRate = 0);
|
||||
|
||||
std::string GetName() const override { return "AudioSource"; }
|
||||
|
||||
private:
|
||||
void DecodeAudioData();
|
||||
void Apply3DAttenuation(const Math::Vector3& listenerPosition);
|
||||
float Compute3DAttenuation(const Math::Vector3& listenerPosition) const;
|
||||
float ComputeSpatialPan(const Math::Vector3& listenerPosition,
|
||||
const Math::Quaternion& listenerRotation) const;
|
||||
double ComputeDopplerFactor(const Math::Vector3& listenerPosition,
|
||||
const Math::Vector3& listenerVelocity,
|
||||
float listenerDopplerLevel,
|
||||
float speedOfSound) const;
|
||||
void UpdateEnergy(const float* buffer, Audio::uint32 sampleCount);
|
||||
|
||||
private:
|
||||
Resources::ResourceHandle<Resources::AudioClip> m_clipHandle;
|
||||
Resources::AudioClip* m_clip = nullptr;
|
||||
std::string m_clipPath;
|
||||
Resources::AssetRef m_clipRef;
|
||||
Audio::AudioMixer* m_outputMixer = nullptr;
|
||||
|
||||
Audio::PlayState m_playState = Audio::PlayState::Stopped;
|
||||
@@ -97,21 +125,22 @@ private:
|
||||
float m_pitch = 1.0f;
|
||||
float m_pan = 0.0f;
|
||||
bool m_spatialize = true;
|
||||
bool m_useHRTF = false;
|
||||
|
||||
Audio::Audio3DParams m_3DParams;
|
||||
Audio::HRTF m_hrtf;
|
||||
|
||||
Audio::uint64 m_samplePosition = 0;
|
||||
double m_playbackPosition = 0.0;
|
||||
double m_lastingTime = 0.0;
|
||||
Math::Vector3 m_velocity = Math::Vector3::Zero();
|
||||
Math::Vector3 m_lastPosition = Math::Vector3::Zero();
|
||||
bool m_hasLastPosition = false;
|
||||
|
||||
bool m_isEnergyDetecting = false;
|
||||
float m_energy = 0.0f;
|
||||
float m_maxEnergy = 5.0f;
|
||||
std::deque<float> m_energyHistory;
|
||||
|
||||
static constexpr size_t BufferSize = 8192;
|
||||
std::vector<float> m_outputBuffer;
|
||||
std::vector<float> m_decodedData;
|
||||
bool m_isDecoded = false;
|
||||
};
|
||||
|
||||
} // namespace Components
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <XCEngine/Core/Asset/IResource.h>
|
||||
#include <XCEngine/Core/Containers/Array.h>
|
||||
#include <XCEngine/Core/Types.h>
|
||||
#include <vector>
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Resources {
|
||||
@@ -35,20 +36,31 @@ public:
|
||||
size_t GetMemorySize() const override { return m_memorySize; }
|
||||
void Release() override;
|
||||
|
||||
void SetAudioData(const Containers::Array<Core::uint8>& data);
|
||||
const Containers::Array<Core::uint8>& GetAudioData() const { return m_audioData; }
|
||||
void SetPCMData(const Containers::Array<Core::uint8>& data);
|
||||
const Containers::Array<Core::uint8>& GetPCMData() const { return m_pcmData; }
|
||||
size_t GetPCMDataSize() const { return m_pcmData.Size(); }
|
||||
|
||||
// Legacy compatibility: audio data now means decoded/interpretable PCM bytes.
|
||||
void SetAudioData(const Containers::Array<Core::uint8>& data) { SetPCMData(data); }
|
||||
const Containers::Array<Core::uint8>& GetAudioData() const { return GetPCMData(); }
|
||||
|
||||
void SetSampleRate(Core::uint32 rate) { m_sampleRate = rate; }
|
||||
void SetSampleRate(Core::uint32 rate);
|
||||
Core::uint32 GetSampleRate() const { return m_sampleRate; }
|
||||
|
||||
void SetChannels(Core::uint32 channels) { m_channels = channels; }
|
||||
void SetChannels(Core::uint32 channels);
|
||||
Core::uint32 GetChannels() const { return m_channels; }
|
||||
|
||||
void SetBitsPerSample(Core::uint32 bits) { m_bitsPerSample = bits; }
|
||||
void SetBitsPerSample(Core::uint32 bits);
|
||||
Core::uint32 GetBitsPerSample() const { return m_bitsPerSample; }
|
||||
|
||||
void SetDuration(float seconds) { m_duration = seconds; }
|
||||
float GetDuration() const { return m_duration; }
|
||||
|
||||
const std::vector<float>& GetDecodedPCMData() const;
|
||||
bool HasDecodedPCMData() const { return m_decodedPCMValid; }
|
||||
|
||||
Core::uint64 GetFrameCount() const;
|
||||
Core::uint64 GetSampleCount() const;
|
||||
|
||||
void SetAudioFormat(AudioFormat format) { m_format = format; }
|
||||
AudioFormat GetAudioFormat() const { return m_format; }
|
||||
@@ -66,7 +78,14 @@ public:
|
||||
void SetRHIResource(class IRHIAudioBuffer* resource);
|
||||
|
||||
private:
|
||||
Containers::Array<Core::uint8> m_audioData;
|
||||
void RefreshDerivedData();
|
||||
void RefreshMemorySize();
|
||||
void InvalidateDecodedPCMData();
|
||||
void BuildDecodedPCMData() const;
|
||||
|
||||
Containers::Array<Core::uint8> m_pcmData;
|
||||
mutable std::vector<float> m_decodedPCMData;
|
||||
mutable bool m_decodedPCMValid = false;
|
||||
|
||||
Core::uint32 m_sampleRate = 44100;
|
||||
Core::uint32 m_channels = 2;
|
||||
|
||||
Reference in New Issue
Block a user