diff --git a/Source/Engine/Audio/AudioSource.cpp b/Source/Engine/Audio/AudioSource.cpp
index dae6aaa4a..6ad80f617 100644
--- a/Source/Engine/Audio/AudioSource.cpp
+++ b/Source/Engine/Audio/AudioSource.cpp
@@ -17,7 +17,6 @@ AudioSource::AudioSource(const SpawnParams& params)
, _volume(1.0f)
, _pitch(1.0f)
, _minDistance(1000.0f)
- , _attenuation(1.0f)
, _loop(false)
, _playOnStart(false)
, _allowSpatialization(true)
@@ -82,6 +81,16 @@ void AudioSource::SetAttenuation(float value)
AudioBackend::Source::SpatialSetupChanged(this);
}
+void AudioSource::SetDopplerFactor(float value)
+{
+ value = Math::Max(0.0f, value);
+ if (Math::NearEqual(_dopplerFactor, value))
+ return;
+ _dopplerFactor = value;
+ if (SourceIDs.HasItems())
+ AudioBackend::Source::SpatialSetupChanged(this);
+}
+
void AudioSource::SetAllowSpatialization(bool value)
{
if (_allowSpatialization == value)
@@ -332,6 +341,7 @@ void AudioSource::Serialize(SerializeStream& stream, const void* otherObj)
SERIALIZE_MEMBER(Pitch, _pitch);
SERIALIZE_MEMBER(MinDistance, _minDistance);
SERIALIZE_MEMBER(Attenuation, _attenuation);
+ SERIALIZE_MEMBER(DopplerFactor, _dopplerFactor);
SERIALIZE_MEMBER(Loop, _loop);
SERIALIZE_MEMBER(PlayOnStart, _playOnStart);
SERIALIZE_MEMBER(AllowSpatialization, _allowSpatialization);
@@ -347,6 +357,7 @@ void AudioSource::Deserialize(DeserializeStream& stream, ISerializeModifier* mod
DESERIALIZE_MEMBER(Pitch, _pitch);
DESERIALIZE_MEMBER(MinDistance, _minDistance);
DESERIALIZE_MEMBER(Attenuation, _attenuation);
+ DESERIALIZE_MEMBER(DopplerFactor, _dopplerFactor);
DESERIALIZE_MEMBER(Loop, _loop);
DESERIALIZE_MEMBER(PlayOnStart, _playOnStart);
DESERIALIZE_MEMBER(AllowSpatialization, _allowSpatialization);
diff --git a/Source/Engine/Audio/AudioSource.h b/Source/Engine/Audio/AudioSource.h
index 8057fbe23..91383d00f 100644
--- a/Source/Engine/Audio/AudioSource.h
+++ b/Source/Engine/Audio/AudioSource.h
@@ -47,7 +47,8 @@ private:
float _volume;
float _pitch;
float _minDistance;
- float _attenuation;
+ float _attenuation = 1.0f;
+ float _dopplerFactor = 1.0f;
bool _loop;
bool _playOnStart;
bool _allowSpatialization;
@@ -164,6 +165,20 @@ public:
///
API_PROPERTY() void SetAttenuation(float value);
+ ///
+ /// Gets the doppler effect factor. Scale for source velocity. Default is 1.
+ ///
+ API_PROPERTY(Attributes="EditorOrder(75), DefaultValue(1.0f), Limit(0, float.MaxValue, 0.1f), EditorDisplay(\"Audio Source\")")
+ FORCE_INLINE float GetDopplerFactor() const
+ {
+ return _dopplerFactor;
+ }
+
+ ///
+ /// Sets the doppler effect factor. Scale for source velocity. Default is 1.
+ ///
+ API_PROPERTY() void SetDopplerFactor(float value);
+
///
/// If checked, source can play spatial 3d audio (when audio clip supports it), otherwise will always play as 2d sound. At 0, no distance attenuation ever occurs.
///
diff --git a/Source/Engine/Audio/OpenAL/AudioBackendOAL.cpp b/Source/Engine/Audio/OpenAL/AudioBackendOAL.cpp
index 592c58cf3..98397c17d 100644
--- a/Source/Engine/Audio/OpenAL/AudioBackendOAL.cpp
+++ b/Source/Engine/Audio/OpenAL/AudioBackendOAL.cpp
@@ -151,6 +151,7 @@ namespace ALC
alSourcei(sourceID, AL_SOURCE_SPATIALIZE_SOFT, AL_TRUE);
#endif
alSourcef(sourceID, AL_ROLLOFF_FACTOR, source->GetAttenuation());
+ alSourcef(sourceID, AL_DOPPLER_FACTOR, source->GetDopplerFactor());
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()));
@@ -158,6 +159,7 @@ namespace ALC
else
{
alSourcef(sourceID, AL_ROLLOFF_FACTOR, 0.0f);
+ alSourcef(sourceID, AL_DOPPLER_FACTOR, 1.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);
@@ -408,11 +410,13 @@ void AudioBackendOAL::Source_SpatialSetupChanged(AudioSource* source)
if (is3D)
{
alSourcef(sourceID, AL_ROLLOFF_FACTOR, source->GetAttenuation());
+ alSourcef(sourceID, AL_DOPPLER_FACTOR, source->GetDopplerFactor());
alSourcef(sourceID, AL_REFERENCE_DISTANCE, FLAX_DST_TO_OAL(source->GetMinDistance()));
}
else
{
alSourcef(sourceID, AL_ROLLOFF_FACTOR, 0.0f);
+ alSourcef(sourceID, AL_DOPPLER_FACTOR, 1.0f);
alSourcef(sourceID, AL_REFERENCE_DISTANCE, 0.0f);
}
}
@@ -825,7 +829,7 @@ bool AudioBackendOAL::Base_Init()
}
// Init
- SetDopplerFactor(AudioSettings::Get()->DopplerFactor);
+ Base_SetDopplerFactor(AudioSettings::Get()->DopplerFactor);
alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED); // Default attenuation model
ALC::RebuildContexts(true);
Audio::SetActiveDeviceIndex(activeDeviceIndex);
diff --git a/Source/Engine/Audio/XAudio2/AudioBackendXAudio2.cpp b/Source/Engine/Audio/XAudio2/AudioBackendXAudio2.cpp
index 2bdd88000..040ae5e02 100644
--- a/Source/Engine/Audio/XAudio2/AudioBackendXAudio2.cpp
+++ b/Source/Engine/Audio/XAudio2/AudioBackendXAudio2.cpp
@@ -119,6 +119,7 @@ namespace XAudio2
XAUDIO2_SEND_DESCRIPTOR Destination;
float Pitch;
float StartTime;
+ float DopplerFactor;
uint64 LastBufferStartSamplesPlayed;
int32 BuffersProcessed;
bool IsDirty;
@@ -398,6 +399,7 @@ void AudioBackendXAudio2::Source_OnAdd(AudioSource* source)
aSource->Data.InnerRadius = FLAX_DST_TO_XAUDIO(source->GetMinDistance());
aSource->Is3D = source->Is3D();
aSource->Pitch = source->GetPitch();
+ aSource->DopplerFactor = source->GetDopplerFactor();
aSource->UpdateTransform(source);
aSource->UpdateVelocity(source);
@@ -502,6 +504,7 @@ void AudioBackendXAudio2::Source_SpatialSetupChanged(AudioSource* source)
if (aSource)
{
// TODO: implement attenuation settings for 3d audio
+ aSource->DopplerFactor = source->GetDopplerFactor();
aSource->Data.InnerRadius = FLAX_DST_TO_XAUDIO(source->GetMinDistance());
aSource->IsDirty = true;
}
@@ -827,7 +830,7 @@ void AudioBackendXAudio2::Base_Update()
}
}
- const float frequencyRatio = dopplerFactor * source.Pitch * dsp.DopplerFactor;
+ const float frequencyRatio = dopplerFactor * source.Pitch * dsp.DopplerFactor * source.DopplerFactor;
source.Voice->SetFrequencyRatio(frequencyRatio);
source.Voice->SetOutputMatrix(XAudio2::MasteringVoice, dsp.SrcChannelCount, dsp.DstChannelCount, dsp.pMatrixCoefficients);