Refactor Audio Backend to not depend on AudioListener object

This commit is contained in:
Wojtek Figat
2024-05-04 22:16:20 +02:00
parent f604503566
commit 5b2af6b3d5
10 changed files with 53 additions and 164 deletions

View File

@@ -2,6 +2,7 @@
#include "Audio.h" #include "Audio.h"
#include "AudioBackend.h" #include "AudioBackend.h"
#include "AudioListener.h"
#include "AudioSettings.h" #include "AudioSettings.h"
#include "FlaxEngine.Gen.h" #include "FlaxEngine.Gen.h"
#include "Engine/Scripting/ScriptingType.h" #include "Engine/Scripting/ScriptingType.h"
@@ -159,14 +160,15 @@ void Audio::OnAddListener(AudioListener* listener)
} }
Listeners.Add(listener); Listeners.Add(listener);
AudioBackend::Listener::OnAdd(listener); AudioBackend::Listener::Reset();
AudioBackend::Listener::TransformChanged(listener->GetPosition(), listener->GetOrientation());
} }
void Audio::OnRemoveListener(AudioListener* listener) void Audio::OnRemoveListener(AudioListener* listener)
{ {
if (!Listeners.Remove(listener)) if (!Listeners.Remove(listener))
{ {
AudioBackend::Listener::OnRemove(listener); AudioBackend::Listener::Reset();
} }
} }

View File

@@ -15,7 +15,6 @@ class AudioBackend
friend class AudioService; friend class AudioService;
public: public:
enum class FeatureFlags enum class FeatureFlags
{ {
None = 0, None = 0,
@@ -26,12 +25,10 @@ public:
static AudioBackend* Instance; static AudioBackend* Instance;
private: private:
// Listener // Listener
virtual void Listener_OnAdd(AudioListener* listener) = 0; virtual void Listener_Reset() = 0;
virtual void Listener_OnRemove(AudioListener* listener) = 0; virtual void Listener_VelocityChanged(const Vector3& velocity) = 0;
virtual void Listener_VelocityChanged(AudioListener* listener) = 0; virtual void Listener_TransformChanged(const Vector3& position, const Quaternion& orientation) = 0;
virtual void Listener_TransformChanged(AudioListener* listener) = 0;
virtual void Listener_ReinitializeAll() = 0; virtual void Listener_ReinitializeAll() = 0;
// Source // Source
@@ -73,35 +70,27 @@ private:
virtual void Base_Dispose() = 0; virtual void Base_Dispose() = 0;
public: public:
virtual ~AudioBackend() virtual ~AudioBackend()
{ {
} }
public: public:
class Listener class Listener
{ {
public: public:
FORCE_INLINE static void Reset()
FORCE_INLINE static void OnAdd(AudioListener* listener)
{ {
Instance->Listener_OnAdd(listener); Instance->Listener_Reset();
} }
FORCE_INLINE static void OnRemove(AudioListener* listener) FORCE_INLINE static void VelocityChanged(const Vector3& velocity)
{ {
Instance->Listener_OnRemove(listener); Instance->Listener_VelocityChanged(velocity);
} }
FORCE_INLINE static void VelocityChanged(AudioListener* listener) FORCE_INLINE static void TransformChanged(const Vector3& position, const Quaternion& orientation)
{ {
Instance->Listener_VelocityChanged(listener); Instance->Listener_TransformChanged(position, orientation);
}
FORCE_INLINE static void TransformChanged(AudioListener* listener)
{
Instance->Listener_TransformChanged(listener);
} }
FORCE_INLINE static void ReinitializeAll() FORCE_INLINE static void ReinitializeAll()
@@ -113,7 +102,6 @@ public:
class Source class Source
{ {
public: public:
FORCE_INLINE static void OnAdd(AudioSource* source) FORCE_INLINE static void OnAdd(AudioSource* source)
{ {
Instance->Source_OnAdd(source); Instance->Source_OnAdd(source);
@@ -223,7 +211,6 @@ public:
class Buffer class Buffer
{ {
public: public:
FORCE_INLINE static uint32 Create() FORCE_INLINE static uint32 Create()
{ {
return Instance->Buffer_Create(); return Instance->Buffer_Create();

View File

@@ -21,6 +21,13 @@ public:
Vector3 Velocity; Vector3 Velocity;
Vector3 Position; Vector3 Position;
Quaternion Orientation; Quaternion Orientation;
void Reset()
{
Velocity = Vector3::Zero;
Position = Vector3::Zero;
Orientation = Quaternion::Identity;
}
}; };
struct Source struct Source

View File

@@ -9,6 +9,7 @@
AudioListener::AudioListener(const SpawnParams& params) AudioListener::AudioListener(const SpawnParams& params)
: Actor(params) : Actor(params)
, _velocity(Vector3::Zero) , _velocity(Vector3::Zero)
, _prevPos(Vector3::Zero)
{ {
} }
@@ -27,7 +28,7 @@ void AudioListener::Update()
_prevPos = pos; _prevPos = pos;
if (_velocity != prevVelocity) if (_velocity != prevVelocity)
{ {
AudioBackend::Listener::VelocityChanged(this); AudioBackend::Listener::VelocityChanged(_velocity);
} }
} }
@@ -68,6 +69,6 @@ void AudioListener::OnTransformChanged()
if (IsActiveInHierarchy() && IsDuringPlay()) if (IsActiveInHierarchy() && IsDuringPlay())
{ {
AudioBackend::Listener::TransformChanged(this); AudioBackend::Listener::TransformChanged(GetPosition(), GetOrientation());
} }
} }

View File

@@ -6,19 +6,15 @@
#include "Engine/Audio/Audio.h" #include "Engine/Audio/Audio.h"
#include "Engine/Audio/AudioSource.h" #include "Engine/Audio/AudioSource.h"
void AudioBackendNone::Listener_OnAdd(AudioListener* listener) void AudioBackendNone::Listener_Reset()
{ {
} }
void AudioBackendNone::Listener_OnRemove(AudioListener* listener) void AudioBackendNone::Listener_VelocityChanged(const Vector3& velocity)
{ {
} }
void AudioBackendNone::Listener_VelocityChanged(AudioListener* listener) void AudioBackendNone::Listener_TransformChanged(const Vector3& position, const Quaternion& orientation)
{
}
void AudioBackendNone::Listener_TransformChanged(AudioListener* listener)
{ {
} }

View File

@@ -12,12 +12,10 @@
class AudioBackendNone : public AudioBackend class AudioBackendNone : public AudioBackend
{ {
public: public:
// [AudioBackend] // [AudioBackend]
void Listener_OnAdd(AudioListener* listener) override; void Listener_Reset() override;
void Listener_OnRemove(AudioListener* listener) override; void Listener_VelocityChanged(const Vector3& velocity) override;
void Listener_VelocityChanged(AudioListener* listener) override; void Listener_TransformChanged(const Vector3& position, const Quaternion& orientation) override;
void Listener_TransformChanged(AudioListener* listener) override;
void Listener_ReinitializeAll() override; void Listener_ReinitializeAll() override;
void Source_OnAdd(AudioSource* source) override; void Source_OnAdd(AudioSource* source) override;
void Source_OnRemove(AudioSource* source) override; void Source_OnRemove(AudioSource* source) override;

View File

@@ -65,13 +65,11 @@ namespace ALC
namespace Listener namespace Listener
{ {
void Rebuild(AudioListener* listener) void Rebuild(const AudioListener* listener)
{ {
AudioBackend::Listener::TransformChanged(listener); AudioBackend::Listener::Reset();
AudioBackend::Listener::TransformChanged(listener->GetPosition(), listener->GetOrientation());
const Float3 velocity = listener->GetVelocity(); AudioBackend::Listener::VelocityChanged(listener->GetVelocity());
alListener3f(AL_VELOCITY, FLAX_VEL_TO_OAL(velocity));
alListenerf(AL_GAIN, Audio::GetVolume());
} }
} }
@@ -244,35 +242,24 @@ const Char* GetOpenALErrorString(int error)
return TEXT("???"); return TEXT("???");
} }
void AudioBackendOAL::Listener_OnAdd(AudioListener* listener) void AudioBackendOAL::Listener_Reset()
{ {
AudioBackend::Listener::TransformChanged(listener);
alListenerf(AL_GAIN, Audio::GetVolume()); alListenerf(AL_GAIN, Audio::GetVolume());
} }
void AudioBackendOAL::Listener_OnRemove(AudioListener* listener) void AudioBackendOAL::Listener_VelocityChanged(const Vector3& velocity)
{ {
}
void AudioBackendOAL::Listener_VelocityChanged(AudioListener* listener)
{
const Float3 velocity = listener->GetVelocity();
alListener3f(AL_VELOCITY, FLAX_VEL_TO_OAL(velocity)); alListener3f(AL_VELOCITY, FLAX_VEL_TO_OAL(velocity));
} }
void AudioBackendOAL::Listener_TransformChanged(AudioListener* listener) void AudioBackendOAL::Listener_TransformChanged(const Vector3& position, const Quaternion& orientation)
{ {
const Float3 position = listener->GetPosition();
const Quaternion orientation = listener->GetOrientation();
const Float3 flipX(-1, 1, 1); const Float3 flipX(-1, 1, 1);
const Float3 alOrientation[2] = const Float3 alOrientation[2] =
{ {
// Forward
orientation * Float3::Forward * flipX, orientation * Float3::Forward * flipX,
// Up
orientation * Float3::Up * flipX orientation * Float3::Up * flipX
}; };
alListenerfv(AL_ORIENTATION, (float*)alOrientation); alListenerfv(AL_ORIENTATION, (float*)alOrientation);
alListener3f(AL_POSITION, FLAX_POS_TO_OAL(position)); alListener3f(AL_POSITION, FLAX_POS_TO_OAL(position));
} }

View File

@@ -12,12 +12,10 @@
class AudioBackendOAL : public AudioBackend class AudioBackendOAL : public AudioBackend
{ {
public: public:
// [AudioBackend] // [AudioBackend]
void Listener_OnAdd(AudioListener* listener) override; void Listener_Reset() override;
void Listener_OnRemove(AudioListener* listener) override; void Listener_VelocityChanged(const Vector3& velocity) override;
void Listener_VelocityChanged(AudioListener* listener) override; void Listener_TransformChanged(const Vector3& position, const Quaternion& orientation) override;
void Listener_TransformChanged(AudioListener* listener) override;
void Listener_ReinitializeAll() override; void Listener_ReinitializeAll() override;
void Source_OnAdd(AudioSource* source) override; void Source_OnAdd(AudioSource* source) override;
void Source_OnRemove(AudioSource* source) override; void Source_OnRemove(AudioSource* source) override;

View File

@@ -9,7 +9,6 @@
#include "Engine/Core/Log.h" #include "Engine/Core/Log.h"
#include "Engine/Audio/Audio.h" #include "Engine/Audio/Audio.h"
#include "Engine/Audio/AudioSource.h" #include "Engine/Audio/AudioSource.h"
#include "Engine/Audio/AudioListener.h"
#include "Engine/Threading/Threading.h" #include "Engine/Threading/Threading.h"
#if PLATFORM_WINDOWS #if PLATFORM_WINDOWS
@@ -42,33 +41,6 @@ namespace XAudio2
{ {
struct Listener : AudioBackendTools::Listener struct Listener : AudioBackendTools::Listener
{ {
AudioListener* AudioListener;
Listener()
{
Init();
}
void Init()
{
AudioListener = nullptr;
}
bool IsFree() const
{
return AudioListener == nullptr;
}
void UpdateTransform()
{
Position = AudioListener->GetPosition();
Orientation = AudioListener->GetOrientation();
}
void UpdateVelocity()
{
Velocity = AudioListener->GetVelocity();
}
}; };
class VoiceCallback : public IXAudio2VoiceCallback class VoiceCallback : public IXAudio2VoiceCallback
@@ -188,41 +160,17 @@ namespace XAudio2
int32 Channels; int32 Channels;
bool ForceDirty = true; bool ForceDirty = true;
AudioBackendTools::Settings Settings; AudioBackendTools::Settings Settings;
Listener Listeners[AUDIO_MAX_LISTENERS]; Listener Listener;
CriticalSection Locker; CriticalSection Locker;
ChunkedArray<Source, 32> Sources; ChunkedArray<Source, 32> Sources;
ChunkedArray<Buffer*, 64> Buffers; // TODO: use ChunkedArray for better performance or use buffers pool? ChunkedArray<Buffer*, 64> Buffers; // TODO: use ChunkedArray for better performance or use buffers pool?
EngineCallback Callback; EngineCallback Callback;
Listener* GetListener()
{
for (int32 i = 0; i < AUDIO_MAX_LISTENERS; i++)
{
if (Listeners[i].AudioListener)
return &Listeners[i];
}
return nullptr;
}
Listener* GetListener(const AudioListener* listener)
{
for (int32 i = 0; i < AUDIO_MAX_LISTENERS; i++)
{
if (Listeners[i].AudioListener == listener)
return &Listeners[i];
}
return nullptr;
}
Source* GetSource(const AudioSource* source) Source* GetSource(const AudioSource* source)
{ {
if (source->SourceID == 0) if (source->SourceID == 0)
return nullptr; return nullptr;
const uint32 sourceId = source->SourceID; return &Sources[source->SourceID - 1]; // 0 is invalid ID so shift them
// 0 is invalid ID so shift them
return &Sources[sourceId - 1];
} }
void MarkAllDirty() void MarkAllDirty()
@@ -266,56 +214,23 @@ namespace XAudio2
} }
} }
void AudioBackendXAudio2::Listener_OnAdd(AudioListener* listener) void AudioBackendXAudio2::Listener_Reset()
{ {
// Get first free listener XAudio2::Listener->Reset();
XAudio2::Listener* aListener = nullptr;
for (int32 i = 0; i < AUDIO_MAX_LISTENERS; i++)
{
if (XAudio2::Listeners[i].IsFree())
{
aListener = &XAudio2::Listeners[i];
break;
}
}
ASSERT(aListener);
// Setup
aListener->AudioListener = listener;
aListener->UpdateTransform();
aListener->UpdateVelocity();
XAudio2::MarkAllDirty(); XAudio2::MarkAllDirty();
} }
void AudioBackendXAudio2::Listener_OnRemove(AudioListener* listener) void AudioBackendXAudio2::Listener_VelocityChanged(const Vector3& velocity)
{ {
XAudio2::Listener* aListener = XAudio2::GetListener(listener); XAudio2::Listener.Velocity = velocity;
if (aListener) XAudio2::MarkAllDirty();
{
aListener->Init();
XAudio2::MarkAllDirty();
}
} }
void AudioBackendXAudio2::Listener_VelocityChanged(AudioListener* listener) void AudioBackendXAudio2::Listener_TransformChanged(const Vector3& position, const Quaternion& orientation)
{ {
XAudio2::Listener* aListener = XAudio2::GetListener(listener); XAudio2::Listener.Position = position;
if (aListener) XAudio2::Listener.Orientation = orientation;
{ XAudio2::MarkAllDirty();
aListener->UpdateVelocity();
XAudio2::MarkAllDirty();
}
}
void AudioBackendXAudio2::Listener_TransformChanged(AudioListener* listener)
{
XAudio2::Listener* aListener = XAudio2::GetListener(listener);
if (aListener)
{
aListener->UpdateTransform();
XAudio2::MarkAllDirty();
}
} }
void AudioBackendXAudio2::Listener_ReinitializeAll() void AudioBackendXAudio2::Listener_ReinitializeAll()

View File

@@ -12,12 +12,10 @@
class AudioBackendXAudio2 : public AudioBackend class AudioBackendXAudio2 : public AudioBackend
{ {
public: public:
// [AudioBackend] // [AudioBackend]
void Listener_OnAdd(AudioListener* listener) override; void Listener_Reset() override;
void Listener_OnRemove(AudioListener* listener) override; void Listener_VelocityChanged(const Vector3& velocity) override;
void Listener_VelocityChanged(AudioListener* listener) override; void Listener_TransformChanged(const Vector3& position, const Quaternion& orientation) override;
void Listener_TransformChanged(AudioListener* listener) override;
void Listener_ReinitializeAll() override; void Listener_ReinitializeAll() override;
void Source_OnAdd(AudioSource* source) override; void Source_OnAdd(AudioSource* source) override;
void Source_OnRemove(AudioSource* source) override; void Source_OnRemove(AudioSource* source) override;