From eb613d3e8a8f49628c2b86f7251ce5485f58efe8 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Thu, 20 Apr 2023 16:01:27 +0200 Subject: [PATCH] Add `DopplerFactor` to Audio Source --- Source/Engine/Audio/AudioSource.cpp | 13 ++++++++++++- Source/Engine/Audio/AudioSource.h | 17 ++++++++++++++++- Source/Engine/Audio/OpenAL/AudioBackendOAL.cpp | 6 +++++- .../Audio/XAudio2/AudioBackendXAudio2.cpp | 5 ++++- 4 files changed, 37 insertions(+), 4 deletions(-) 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);