Refactor 3d audio for good spatial sound quality
This commit is contained in:
@@ -31,19 +31,6 @@
|
||||
#include "XAudio2/AudioBackendXAudio2.h"
|
||||
#endif
|
||||
|
||||
const Char* ToString(AudioFormat value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case AudioFormat::Raw:
|
||||
return TEXT("Raw");
|
||||
case AudioFormat::Vorbis:
|
||||
return TEXT("Vorbis");
|
||||
default:
|
||||
return TEXT("");
|
||||
}
|
||||
}
|
||||
|
||||
float AudioDataInfo::GetLength() const
|
||||
{
|
||||
return (float)NumSamples / (float)Math::Max(1U, SampleRate * NumChannels);
|
||||
|
||||
@@ -35,8 +35,7 @@ private:
|
||||
virtual void Source_VolumeChanged(AudioSource* source) = 0;
|
||||
virtual void Source_PitchChanged(AudioSource* source) = 0;
|
||||
virtual void Source_IsLoopingChanged(AudioSource* source) = 0;
|
||||
virtual void Source_MinDistanceChanged(AudioSource* source) = 0;
|
||||
virtual void Source_AttenuationChanged(AudioSource* source) = 0;
|
||||
virtual void Source_SpatialSetupChanged(AudioSource* source) = 0;
|
||||
virtual void Source_ClipLoaded(AudioSource* source) = 0;
|
||||
virtual void Source_Cleanup(AudioSource* source) = 0;
|
||||
virtual void Source_Play(AudioSource* source) = 0;
|
||||
@@ -141,14 +140,9 @@ public:
|
||||
Instance->Source_IsLoopingChanged(source);
|
||||
}
|
||||
|
||||
FORCE_INLINE static void MinDistanceChanged(AudioSource* source)
|
||||
FORCE_INLINE static void SpatialSetupChanged(AudioSource* source)
|
||||
{
|
||||
Instance->Source_MinDistanceChanged(source);
|
||||
}
|
||||
|
||||
FORCE_INLINE static void AttenuationChanged(AudioSource* source)
|
||||
{
|
||||
Instance->Source_AttenuationChanged(source);
|
||||
Instance->Source_SpatialSetupChanged(source);
|
||||
}
|
||||
|
||||
FORCE_INLINE static void ClipLoaded(AudioSource* source)
|
||||
|
||||
@@ -16,7 +16,7 @@ AudioSource::AudioSource(const SpawnParams& params)
|
||||
, _velocity(Vector3::Zero)
|
||||
, _volume(1.0f)
|
||||
, _pitch(1.0f)
|
||||
, _minDistance(1.0f)
|
||||
, _minDistance(1000.0f)
|
||||
, _attenuation(1.0f)
|
||||
, _loop(false)
|
||||
, _playOnStart(false)
|
||||
@@ -30,13 +30,9 @@ void AudioSource::SetVolume(float value)
|
||||
value = Math::Saturate(value);
|
||||
if (Math::NearEqual(_volume, value))
|
||||
return;
|
||||
|
||||
_volume = value;
|
||||
|
||||
if (SourceIDs.HasItems())
|
||||
{
|
||||
AudioBackend::Source::VolumeChanged(this);
|
||||
}
|
||||
}
|
||||
|
||||
void AudioSource::SetPitch(float value)
|
||||
@@ -44,27 +40,20 @@ void AudioSource::SetPitch(float value)
|
||||
value = Math::Clamp(value, 0.5f, 2.0f);
|
||||
if (Math::NearEqual(_pitch, value))
|
||||
return;
|
||||
|
||||
_pitch = value;
|
||||
|
||||
if (SourceIDs.HasItems())
|
||||
{
|
||||
AudioBackend::Source::PitchChanged(this);
|
||||
}
|
||||
}
|
||||
|
||||
void AudioSource::SetIsLooping(bool value)
|
||||
{
|
||||
if (_loop == value)
|
||||
return;
|
||||
|
||||
_loop = value;
|
||||
|
||||
// When streaming we handle looping manually by the proper buffers submission
|
||||
if (SourceIDs.HasItems() && !UseStreaming())
|
||||
{
|
||||
AudioBackend::Source::IsLoopingChanged(this);
|
||||
}
|
||||
}
|
||||
|
||||
void AudioSource::SetPlayOnStart(bool value)
|
||||
@@ -77,13 +66,9 @@ void AudioSource::SetMinDistance(float value)
|
||||
value = Math::Max(0.0f, value);
|
||||
if (Math::NearEqual(_minDistance, value))
|
||||
return;
|
||||
|
||||
_minDistance = value;
|
||||
|
||||
if (SourceIDs.HasItems())
|
||||
{
|
||||
AudioBackend::Source::MinDistanceChanged(this);
|
||||
}
|
||||
AudioBackend::Source::SpatialSetupChanged(this);
|
||||
}
|
||||
|
||||
void AudioSource::SetAttenuation(float value)
|
||||
@@ -91,13 +76,10 @@ void AudioSource::SetAttenuation(float value)
|
||||
value = Math::Max(0.0f, value);
|
||||
if (Math::NearEqual(_attenuation, value))
|
||||
return;
|
||||
|
||||
_attenuation = value;
|
||||
|
||||
if (SourceIDs.HasItems())
|
||||
{
|
||||
AudioBackend::Source::AttenuationChanged(this);
|
||||
}
|
||||
AudioBackend::Source::SpatialSetupChanged(this);
|
||||
}
|
||||
|
||||
void AudioSource::Play()
|
||||
@@ -313,6 +295,22 @@ void AudioSource::PlayInternal()
|
||||
_isActuallyPlayingSth = true;
|
||||
}
|
||||
|
||||
#if USE_EDITOR
|
||||
|
||||
#include "Engine/Debug/DebugDraw.h"
|
||||
|
||||
void AudioSource::OnDebugDrawSelected()
|
||||
{
|
||||
// Draw influence range
|
||||
if (_allowSpatialization)
|
||||
DEBUG_DRAW_WIRE_SPHERE(BoundingSphere(_transform.Translation, _minDistance), Color::CornflowerBlue, 0, true);
|
||||
|
||||
// Base
|
||||
Actor::OnDebugDrawSelected();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void AudioSource::Serialize(SerializeStream& stream, const void* otherObj)
|
||||
{
|
||||
// Base
|
||||
|
||||
@@ -138,8 +138,7 @@ public:
|
||||
/// <summary>
|
||||
/// Gets the minimum distance at which audio attenuation starts. When the listener is closer to the source than this value, audio is heard at full volume. Once farther away the audio starts attenuating.
|
||||
/// </summary>
|
||||
/// <returns>The value.</returns>
|
||||
API_PROPERTY(Attributes="EditorOrder(60), DefaultValue(1.0f), Limit(0, float.MaxValue, 0.1f), EditorDisplay(\"Audio Source\")")
|
||||
API_PROPERTY(Attributes="EditorOrder(60), DefaultValue(1000.0f), Limit(0, float.MaxValue, 0.1f), EditorDisplay(\"Audio Source\")")
|
||||
FORCE_INLINE float GetMinDistance() const
|
||||
{
|
||||
return _minDistance;
|
||||
@@ -160,7 +159,7 @@ public:
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the attenuation that controls how quickly does audio volume drop off as the listener moves further from the source.
|
||||
/// Sets the attenuation that controls how quickly does audio volume drop off as the listener moves further from the source. At 0, no distance attenuation ever occurs.
|
||||
/// </summary>
|
||||
API_PROPERTY() void SetAttenuation(float value);
|
||||
|
||||
@@ -257,6 +256,9 @@ public:
|
||||
const Vector3 size(50);
|
||||
return BoundingBox(_transform.Translation - size, _transform.Translation + size);
|
||||
}
|
||||
#endif
|
||||
#if USE_EDITOR
|
||||
void OnDebugDrawSelected() override;
|
||||
#endif
|
||||
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
||||
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
|
||||
|
||||
@@ -56,11 +56,7 @@ void AudioBackendNone::Source_IsLoopingChanged(AudioSource* source)
|
||||
{
|
||||
}
|
||||
|
||||
void AudioBackendNone::Source_MinDistanceChanged(AudioSource* source)
|
||||
{
|
||||
}
|
||||
|
||||
void AudioBackendNone::Source_AttenuationChanged(AudioSource* source)
|
||||
void AudioBackendNone::Source_SpatialSetupChanged(AudioSource* source)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -26,8 +26,7 @@ public:
|
||||
void Source_VolumeChanged(AudioSource* source) override;
|
||||
void Source_PitchChanged(AudioSource* source) override;
|
||||
void Source_IsLoopingChanged(AudioSource* source) override;
|
||||
void Source_MinDistanceChanged(AudioSource* source) override;
|
||||
void Source_AttenuationChanged(AudioSource* source) override;
|
||||
void Source_SpatialSetupChanged(AudioSource* source) override;
|
||||
void Source_ClipLoaded(AudioSource* source) override;
|
||||
void Source_Cleanup(AudioSource* source) override;
|
||||
void Source_Play(AudioSource* source) override;
|
||||
|
||||
@@ -21,7 +21,8 @@
|
||||
|
||||
#define ALC_MULTIPLE_LISTENERS 0
|
||||
|
||||
#define FLAX_COORD_SCALE 0.01f
|
||||
#define FLAX_COORD_SCALE 0.01f // units are meters
|
||||
#define FLAX_DST_TO_OAL(x) x * FLAX_COORD_SCALE
|
||||
#define FLAX_POS_TO_OAL(vec) ((ALfloat)vec.X * -FLAX_COORD_SCALE), ((ALfloat)vec.Y * FLAX_COORD_SCALE), ((ALfloat)vec.Z * FLAX_COORD_SCALE)
|
||||
#define FLAX_VEL_TO_OAL(vec) ((ALfloat)vec.X * -(FLAX_COORD_SCALE*FLAX_COORD_SCALE)), ((ALfloat)vec.Y * (FLAX_COORD_SCALE*FLAX_COORD_SCALE)), ((ALfloat)vec.Z * (FLAX_COORD_SCALE*FLAX_COORD_SCALE))
|
||||
#if BUILD_RELEASE
|
||||
@@ -102,7 +103,7 @@ namespace ALC
|
||||
{
|
||||
alcMakeContextCurrent(nullptr);
|
||||
|
||||
for (auto& context : Contexts)
|
||||
for (ALCcontext* context : Contexts)
|
||||
alcDestroyContext(context);
|
||||
Contexts.Clear();
|
||||
}
|
||||
@@ -113,7 +114,7 @@ namespace ALC
|
||||
{
|
||||
AudioBackend::Listener::TransformChanged(listener);
|
||||
|
||||
const auto& velocity = listener->GetVelocity();
|
||||
const Vector3 velocity = listener->GetVelocity();
|
||||
alListener3f(AL_VELOCITY, FLAX_VEL_TO_OAL(velocity));
|
||||
alListenerf(AL_GAIN, Audio::GetVolume());
|
||||
}
|
||||
@@ -146,13 +147,14 @@ namespace ALC
|
||||
if (is3D)
|
||||
{
|
||||
alSourcef(sourceID, AL_ROLLOFF_FACTOR, source->GetAttenuation());
|
||||
alSourcef(sourceID, AL_REFERENCE_DISTANCE, source->GetMinDistance());
|
||||
alSourcef(sourceID, AL_REFERENCE_DISTANCE, FLAX_DST_TO_OAL(source->GetMinDistance()));
|
||||
alSource3f(sourceID, AL_POSITION, FLAX_POS_TO_OAL(source->GetPosition()));
|
||||
alSource3f(sourceID, AL_VELOCITY, FLAX_VEL_TO_OAL(source->GetVelocity()));
|
||||
}
|
||||
else
|
||||
{
|
||||
alSourcef(sourceID, AL_ROLLOFF_FACTOR, 0.0f);
|
||||
alSourcef(sourceID, AL_REFERENCE_DISTANCE, 0.0f);
|
||||
alSource3f(sourceID, AL_POSITION, 0.0f, 0.0f, 0.0f);
|
||||
alSource3f(sourceID, AL_VELOCITY, 0.0f, 0.0f, 0.0f);
|
||||
}
|
||||
@@ -169,7 +171,7 @@ namespace ALC
|
||||
|
||||
if (!isChangingDevice)
|
||||
{
|
||||
for (auto& source : Audio::Sources)
|
||||
for (AudioSource* source : Audio::Sources)
|
||||
source->Cleanup();
|
||||
}
|
||||
|
||||
@@ -204,10 +206,10 @@ namespace ALC
|
||||
// Audio listeners and sources will avoid excessive context switching in such case.
|
||||
alcMakeContextCurrent(Contexts[0]);
|
||||
|
||||
for (auto& listener : Audio::Listeners)
|
||||
for (AudioListener* listener : Audio::Listeners)
|
||||
Listener::Rebuild(listener);
|
||||
|
||||
for (auto& source : Audio::Sources)
|
||||
for (AudioSource* source : Audio::Sources)
|
||||
Source::Rebuild(source);
|
||||
}
|
||||
}
|
||||
@@ -293,7 +295,7 @@ void AudioBackendOAL::Listener_OnAdd(AudioListener* listener)
|
||||
ALC::RebuildContexts(false);
|
||||
#else
|
||||
AudioBackend::Listener::TransformChanged(listener);
|
||||
const auto& velocity = listener->GetVelocity();
|
||||
const Vector3 velocity = listener->GetVelocity();
|
||||
alListener3f(AL_VELOCITY, FLAX_VEL_TO_OAL(velocity));
|
||||
alListenerf(AL_GAIN, Audio::GetVolume());
|
||||
#endif
|
||||
@@ -310,7 +312,7 @@ void AudioBackendOAL::Listener_VelocityChanged(AudioListener* listener)
|
||||
{
|
||||
ALC_GET_LISTENER_CONTEXT(listener)
|
||||
|
||||
const auto& velocity = listener->GetVelocity();
|
||||
const Vector3 velocity = listener->GetVelocity();
|
||||
alListener3f(AL_VELOCITY, FLAX_VEL_TO_OAL(velocity));
|
||||
}
|
||||
|
||||
@@ -318,11 +320,10 @@ void AudioBackendOAL::Listener_TransformChanged(AudioListener* listener)
|
||||
{
|
||||
ALC_GET_LISTENER_CONTEXT(listener)
|
||||
|
||||
const Vector3& position = listener->GetPosition();
|
||||
const Quaternion& orientation = listener->GetOrientation();
|
||||
const Vector3& flipX = Vector3(-1, 1, 1);
|
||||
|
||||
Vector3 alOrientation[2] =
|
||||
const Vector3 position = listener->GetPosition();
|
||||
const Quaternion orientation = listener->GetOrientation();
|
||||
const Vector3 flipX(-1, 1, 1);
|
||||
const Vector3 alOrientation[2] =
|
||||
{
|
||||
// Forward
|
||||
orientation * Vector3::Forward * flipX,
|
||||
@@ -394,23 +395,22 @@ void AudioBackendOAL::Source_IsLoopingChanged(AudioSource* source)
|
||||
}
|
||||
}
|
||||
|
||||
void AudioBackendOAL::Source_MinDistanceChanged(AudioSource* source)
|
||||
void AudioBackendOAL::Source_SpatialSetupChanged(AudioSource* source)
|
||||
{
|
||||
if (!source->Is3D())
|
||||
return;
|
||||
const bool is3D = source->Is3D();
|
||||
ALC_FOR_EACH_CONTEXT()
|
||||
const uint32 sourceID = source->SourceIDs[i];
|
||||
alSourcef(sourceID, AL_REFERENCE_DISTANCE, source->GetMinDistance());
|
||||
}
|
||||
}
|
||||
|
||||
void AudioBackendOAL::Source_AttenuationChanged(AudioSource* source)
|
||||
{
|
||||
if (!source->Is3D())
|
||||
return;
|
||||
ALC_FOR_EACH_CONTEXT()
|
||||
const uint32 sourceID = source->SourceIDs[i];
|
||||
alSourcef(sourceID, AL_ROLLOFF_FACTOR, source->GetAttenuation());
|
||||
alSourcei(sourceID, AL_SOURCE_RELATIVE, !is3D);
|
||||
if (is3D)
|
||||
{
|
||||
alSourcef(sourceID, AL_ROLLOFF_FACTOR, source->GetAttenuation());
|
||||
alSourcef(sourceID, AL_REFERENCE_DISTANCE, FLAX_DST_TO_OAL(source->GetMinDistance()));
|
||||
}
|
||||
else
|
||||
{
|
||||
alSourcef(sourceID, AL_ROLLOFF_FACTOR, 0.0f);
|
||||
alSourcef(sourceID, AL_REFERENCE_DISTANCE, 0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -496,7 +496,7 @@ float AudioBackendOAL::Source_GetCurrentBufferTime(const AudioSource* source)
|
||||
alGetSourcef(source->SourceIDs[0], AL_SEC_OFFSET, &time);
|
||||
#else
|
||||
ASSERT(source->Clip && source->Clip->IsLoaded());
|
||||
const auto& clipInfo = source->Clip->AudioHeader.Info;
|
||||
const AudioDataInfo& clipInfo = source->Clip->AudioHeader.Info;
|
||||
ALint samplesPlayed;
|
||||
alGetSourcei(source->SourceIDs[0], AL_SAMPLE_OFFSET, &samplesPlayed);
|
||||
const uint32 totalSamples = clipInfo.NumSamples / clipInfo.NumChannels;
|
||||
@@ -686,7 +686,7 @@ const Char* AudioBackendOAL::Base_Name()
|
||||
void AudioBackendOAL::Base_OnActiveDeviceChanged()
|
||||
{
|
||||
// Cleanup
|
||||
for (auto& source : Audio::Sources)
|
||||
for (AudioSource* source : Audio::Sources)
|
||||
source->Cleanup();
|
||||
ALC::ClearContexts();
|
||||
if (ALC::Device != nullptr)
|
||||
@@ -696,7 +696,7 @@ void AudioBackendOAL::Base_OnActiveDeviceChanged()
|
||||
}
|
||||
|
||||
// Open device
|
||||
const auto& name = Audio::GetActiveDevice()->InternalName;
|
||||
const StringAnsi& name = Audio::GetActiveDevice()->InternalName;
|
||||
ALC::Device = alcOpenDevice(name.Get());
|
||||
if (ALC::Device == nullptr)
|
||||
{
|
||||
@@ -817,6 +817,7 @@ bool AudioBackendOAL::Base_Init()
|
||||
|
||||
// Init
|
||||
SetDopplerFactor(AudioSettings::Get()->DopplerFactor);
|
||||
alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED); // Default attenuation model
|
||||
ALC::RebuildContexts(true);
|
||||
Audio::SetActiveDeviceIndex(activeDeviceIndex);
|
||||
|
||||
|
||||
@@ -26,8 +26,7 @@ public:
|
||||
void Source_VolumeChanged(AudioSource* source) override;
|
||||
void Source_PitchChanged(AudioSource* source) override;
|
||||
void Source_IsLoopingChanged(AudioSource* source) override;
|
||||
void Source_MinDistanceChanged(AudioSource* source) override;
|
||||
void Source_AttenuationChanged(AudioSource* source) override;
|
||||
void Source_SpatialSetupChanged(AudioSource* source) override;
|
||||
void Source_ClipLoaded(AudioSource* source) override;
|
||||
void Source_Cleanup(AudioSource* source) override;
|
||||
void Source_Play(AudioSource* source) override;
|
||||
|
||||
@@ -25,8 +25,6 @@ API_ENUM() enum class AudioFormat
|
||||
Vorbis,
|
||||
};
|
||||
|
||||
const Char* ToString(AudioFormat value);
|
||||
|
||||
/// <summary>
|
||||
/// Meta-data describing a chunk of audio.
|
||||
/// </summary>
|
||||
|
||||
@@ -26,7 +26,8 @@
|
||||
#define MAX_OUTPUT_CHANNELS 8
|
||||
#define MAX_CHANNELS_MATRIX_SIZE (MAX_INPUT_CHANNELS*MAX_OUTPUT_CHANNELS)
|
||||
|
||||
#define FLAX_COORD_SCALE 0.01f
|
||||
#define FLAX_COORD_SCALE 0.01f // units are meters
|
||||
#define FLAX_DST_TO_XAUDIO(x) x * FLAX_COORD_SCALE
|
||||
#define FLAX_POS_TO_XAUDIO(vec) X3DAUDIO_VECTOR(vec.X * FLAX_COORD_SCALE, vec.Y * FLAX_COORD_SCALE, vec.Z * FLAX_COORD_SCALE)
|
||||
#define FLAX_VEL_TO_XAUDIO(vec) X3DAUDIO_VECTOR(vec.X * (FLAX_COORD_SCALE*FLAX_COORD_SCALE), vec.Y * (FLAX_COORD_SCALE*FLAX_COORD_SCALE), vec.Z * (FLAX_COORD_SCALE*FLAX_COORD_SCALE))
|
||||
#define FLAX_VEC_TO_XAUDIO(vec) (*((X3DAUDIO_VECTOR*)&vec))
|
||||
@@ -105,7 +106,6 @@ namespace XAudio2
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
AudioSource* Source;
|
||||
|
||||
void PeekSamples();
|
||||
@@ -200,13 +200,11 @@ namespace XAudio2
|
||||
DWORD ChannelMask;
|
||||
UINT32 SampleRate;
|
||||
UINT32 Channels;
|
||||
bool UseRedirectToLFE;
|
||||
bool ForceDirty = true;
|
||||
Listener Listeners[AUDIO_MAX_LISTENERS];
|
||||
Array<Source> Sources(32); // TODO: use ChunkedArray for better performance
|
||||
Array<Buffer*> Buffers(64); // TODO: use ChunkedArray for better performance or use buffers pool?
|
||||
EngineCallback Callback;
|
||||
float MatrixCoefficients[MAX_CHANNELS_MATRIX_SIZE];
|
||||
|
||||
Listener* GetListener()
|
||||
{
|
||||
@@ -397,9 +395,9 @@ void AudioBackendXAudio2::Source_OnAdd(AudioSource* source)
|
||||
aSource->Callback.Source = source;
|
||||
aSource->IsDirty = true;
|
||||
aSource->Data.ChannelCount = header.Info.NumChannels;
|
||||
aSource->Data.InnerRadius = FLAX_DST_TO_XAUDIO(source->GetMinDistance());
|
||||
aSource->Is3D = source->Is3D();
|
||||
aSource->Pitch = source->GetPitch();
|
||||
aSource->Data.InnerRadius = source->GetMinDistance();
|
||||
aSource->UpdateTransform(source);
|
||||
aSource->UpdateVelocity(source);
|
||||
|
||||
@@ -498,21 +496,17 @@ void AudioBackendXAudio2::Source_IsLoopingChanged(AudioSource* source)
|
||||
aSource->Voice->Start();
|
||||
}
|
||||
|
||||
void AudioBackendXAudio2::Source_MinDistanceChanged(AudioSource* source)
|
||||
void AudioBackendXAudio2::Source_SpatialSetupChanged(AudioSource* source)
|
||||
{
|
||||
auto aSource = XAudio2::GetSource(source);
|
||||
if (aSource)
|
||||
{
|
||||
aSource->Data.InnerRadius = source->GetMinDistance();
|
||||
// TODO: implement attenuation settings for 3d audio
|
||||
aSource->Data.InnerRadius = FLAX_DST_TO_XAUDIO(source->GetMinDistance());
|
||||
aSource->IsDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
void AudioBackendXAudio2::Source_AttenuationChanged(AudioSource* source)
|
||||
{
|
||||
// TODO: implement it
|
||||
}
|
||||
|
||||
void AudioBackendXAudio2::Source_ClipLoaded(AudioSource* source)
|
||||
{
|
||||
auto aSource = XAudio2::GetSource(source);
|
||||
@@ -769,7 +763,6 @@ bool AudioBackendXAudio2::Base_Init()
|
||||
LOG(Error, "Failed to get XAudio2 mastering voice channel mask. Error: 0x{0:x}", hr);
|
||||
return true;
|
||||
}
|
||||
XAudio2::UseRedirectToLFE = ((XAudio2::ChannelMask & SPEAKER_LOW_FREQUENCY) != 0);
|
||||
|
||||
// Initialize spatial audio subsystem
|
||||
DWORD dwChannelMask;
|
||||
@@ -794,19 +787,13 @@ bool AudioBackendXAudio2::Base_Init()
|
||||
|
||||
void AudioBackendXAudio2::Base_Update()
|
||||
{
|
||||
// Note: only one listener is supported for now
|
||||
const auto listener = XAudio2::GetListener();
|
||||
if (!listener)
|
||||
{
|
||||
// How can we play audio when no one is listening
|
||||
return;
|
||||
}
|
||||
|
||||
// Update dirty voices
|
||||
const auto listener = XAudio2::GetListener();
|
||||
const float dopplerFactor = AudioSettings::Get()->DopplerFactor;
|
||||
float matrixCoefficients[MAX_CHANNELS_MATRIX_SIZE];
|
||||
X3DAUDIO_DSP_SETTINGS dsp = { 0 };
|
||||
dsp.DstChannelCount = XAudio2::Channels;
|
||||
dsp.pMatrixCoefficients = XAudio2::MatrixCoefficients;
|
||||
dsp.pMatrixCoefficients = matrixCoefficients;
|
||||
for (int32 i = 0; i < XAudio2::Sources.Count(); i++)
|
||||
{
|
||||
auto& source = XAudio2::Sources[i];
|
||||
@@ -814,7 +801,7 @@ void AudioBackendXAudio2::Base_Update()
|
||||
continue;
|
||||
|
||||
dsp.SrcChannelCount = source.Data.ChannelCount;
|
||||
if (source.Is3D)
|
||||
if (source.Is3D && listener)
|
||||
{
|
||||
X3DAudioCalculate(XAudio2::X3DInstance, &listener->Data, &source.Data, X3DAUDIO_CALCULATE_MATRIX | X3DAUDIO_CALCULATE_DOPPLER, &dsp);
|
||||
}
|
||||
@@ -822,7 +809,7 @@ void AudioBackendXAudio2::Base_Update()
|
||||
{
|
||||
// Stereo
|
||||
dsp.DopplerFactor = 1.0f;
|
||||
Platform::MemoryClear(dsp.pMatrixCoefficients, sizeof(XAudio2::MatrixCoefficients));
|
||||
Platform::MemoryClear(dsp.pMatrixCoefficients, sizeof(matrixCoefficients));
|
||||
dsp.pMatrixCoefficients[0] = 1.0f;
|
||||
if (source.Format.nChannels == 1)
|
||||
{
|
||||
|
||||
@@ -26,8 +26,7 @@ public:
|
||||
void Source_VolumeChanged(AudioSource* source) override;
|
||||
void Source_PitchChanged(AudioSource* source) override;
|
||||
void Source_IsLoopingChanged(AudioSource* source) override;
|
||||
void Source_MinDistanceChanged(AudioSource* source) override;
|
||||
void Source_AttenuationChanged(AudioSource* source) override;
|
||||
void Source_SpatialSetupChanged(AudioSource* source) override;
|
||||
void Source_ClipLoaded(AudioSource* source) override;
|
||||
void Source_Cleanup(AudioSource* source) override;
|
||||
void Source_Play(AudioSource* source) override;
|
||||
|
||||
Reference in New Issue
Block a user