diff --git a/Audio/SoundCommon.cpp b/Audio/SoundCommon.cpp index ca462597..17bf06eb 100644 --- a/Audio/SoundCommon.cpp +++ b/Audio/SoundCommon.cpp @@ -869,6 +869,33 @@ namespace return true; } + + inline bool IsValid(const X3DAUDIO_DISTANCE_CURVE& curve) noexcept + { + // These match the validation ranges in X3DAudio. + if (!curve.pPoints) + return false; + + if (curve.PointCount < 2) + return false; + + if (curve.pPoints[0].Distance != 0.f) + return false; + + if (curve.pPoints[curve.PointCount - 1].Distance != 1.f) + return false; + + for (uint32_t j = 0; j < curve.PointCount; ++j) + { + if (curve.pPoints[j].Distance < 0.f || curve.pPoints[j].Distance > 1.f) + return false; + + if (!std::isfinite(curve.pPoints[j].DSPSetting)) + return false; + } + + return true; + } } void AudioListener::SetCone(const X3DAUDIO_CONE& listenerCone) @@ -880,6 +907,44 @@ void AudioListener::SetCone(const X3DAUDIO_CONE& listenerCone) pCone = &ListenerCone; } +bool AudioListener::IsValid() const +{ + if (!std::isfinite(OrientFront.x)) + return false; + if (!std::isfinite(OrientFront.y)) + return false; + if (!std::isfinite(OrientFront.z)) + return false; + + if (!std::isfinite(OrientTop.x)) + return false; + if (!std::isfinite(OrientTop.y)) + return false; + if (!std::isfinite(OrientTop.z)) + return false; + + if (!std::isfinite(Position.x)) + return false; + if (!std::isfinite(Position.y)) + return false; + if (!std::isfinite(Position.z)) + + if (!std::isfinite(Velocity.x)) + return false; + if (!std::isfinite(Velocity.y)) + return false; + if (!std::isfinite(Velocity.z)) + return false; + + if (pCone) + { + if (!::IsValid(*pCone)) + return false; + } + + return true; +} + void AudioEmitter::SetCone(const X3DAUDIO_CONE& emitterCone) { if (!::IsValid(emitterCone)) @@ -889,6 +954,101 @@ void AudioEmitter::SetCone(const X3DAUDIO_CONE& emitterCone) pCone = &EmitterCone; } +bool AudioEmitter::IsValid() const +{ + if (!std::isfinite(OrientFront.x)) + return false; + if (!std::isfinite(OrientFront.y)) + return false; + if (!std::isfinite(OrientFront.z)) + return false; + + if (!std::isfinite(OrientTop.x)) + return false; + if (!std::isfinite(OrientTop.y)) + return false; + if (!std::isfinite(OrientTop.z)) + return false; + + if (!std::isfinite(Position.x)) + return false; + if (!std::isfinite(Position.y)) + return false; + if (!std::isfinite(Position.z)) + + if (!std::isfinite(Velocity.x)) + return false; + if (!std::isfinite(Velocity.y)) + return false; + if (!std::isfinite(Velocity.z)) + return false; + + if (pCone) + { + if (!::IsValid(*pCone)) + return false; + } + + if (!std::isfinite(InnerRadius)) + return false; + if (!std::isfinite(InnerRadiusAngle)) + return false; + + if (ChannelCount == 0 || ChannelCount > XAUDIO2_MAX_AUDIO_CHANNELS) + return false; + + if (ChannelCount > 1) + { + if (!pChannelAzimuths) + return false; + + for (uint32_t j = 0; j < ChannelCount; ++j) + { + if (pChannelAzimuths[j] < 0.f || pChannelAzimuths[j] > X3DAUDIO_2PI) + return false; + } + } + + if (!std::isfinite(ChannelRadius)) + return false; + if (!std::isfinite(CurveDistanceScaler)) + return false; + if (!std::isfinite(DopplerScaler)) + return false; + + if (pVolumeCurve) + { + if (!::IsValid(*pVolumeCurve)) + return false; + } + + if (pLFECurve) + { + if (!::IsValid(*pLFECurve)) + return false; + } + + if (pLPFDirectCurve) + { + if (!::IsValid(*pLPFDirectCurve)) + return false; + } + + if (pLPFReverbCurve) + { + if (!::IsValid(*pLPFReverbCurve)) + return false; + } + + if (pReverbCurve) + { + if (!::IsValid(*pReverbCurve)) + return false; + } + + return true; +} + namespace { // **Note these constants came from xact3d3.h in the legacy DirectX SDK** diff --git a/Inc/Audio.h b/Inc/Audio.h index 9b39c792..2877bcac 100644 --- a/Inc/Audio.h +++ b/Inc/Audio.h @@ -547,6 +547,8 @@ namespace DirectX } void __cdecl SetCone(const X3DAUDIO_CONE& listenerCone); + + bool __cdecl IsValid() const; }; @@ -666,6 +668,8 @@ namespace DirectX pLPFReverbCurve = nullptr; pReverbCurve = nullptr; } + + bool __cdecl IsValid() const; };