Add DopplerFactor to Audio Source

This commit is contained in:
Wojtek Figat
2023-04-20 16:01:27 +02:00
parent c8dc8396f9
commit eb613d3e8a
4 changed files with 37 additions and 4 deletions

View File

@@ -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);

View File

@@ -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:
/// </summary>
API_PROPERTY() void SetAttenuation(float value);
/// <summary>
/// Gets the doppler effect factor. Scale for source velocity. Default is 1.
/// </summary>
API_PROPERTY(Attributes="EditorOrder(75), DefaultValue(1.0f), Limit(0, float.MaxValue, 0.1f), EditorDisplay(\"Audio Source\")")
FORCE_INLINE float GetDopplerFactor() const
{
return _dopplerFactor;
}
/// <summary>
/// Sets the doppler effect factor. Scale for source velocity. Default is 1.
/// </summary>
API_PROPERTY() void SetDopplerFactor(float value);
/// <summary>
/// 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.
/// </summary>

View File

@@ -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);

View File

@@ -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);