ATLUtils.h 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #pragma once
  9. #include <AudioAllocators.h>
  10. #include <AzCore/Console/ILogger.h>
  11. #include <AzCore/Math/MathUtils.h>
  12. #include <AzCore/Math/Random.h>
  13. #include <AzCore/std/string/string_view.h>
  14. #include <AzCore/std/typetraits/is_integral.h>
  15. #include <AzCore/std/typetraits/is_unsigned.h>
  16. #include <AzCore/std/time.h>
  17. #define ATL_FLOAT_EPSILON (1.0e-6)
  18. namespace Audio
  19. {
  20. ///////////////////////////////////////////////////////////////////////////////////////////////////
  21. inline float frand_symm()
  22. {
  23. static AZ::SimpleLcgRandom rand(AZStd::GetTimeNowMicroSecond());
  24. // return random float [-1.f, 1.f)
  25. return rand.GetRandomFloat() * 2.f - 1.f;
  26. }
  27. ///////////////////////////////////////////////////////////////////////////////////////////////////
  28. template<typename TMap, typename TKey>
  29. bool FindPlace(TMap& map, const TKey& key, typename TMap::iterator& iPlace)
  30. {
  31. iPlace = map.find(key);
  32. return (iPlace != map.end());
  33. }
  34. ///////////////////////////////////////////////////////////////////////////////////////////////////
  35. template<typename TMap, typename TKey>
  36. bool FindPlaceConst(const TMap& map, const TKey& key, typename TMap::const_iterator& iPlace)
  37. {
  38. iPlace = map.find(key);
  39. return (iPlace != map.end());
  40. }
  41. #if !defined(AUDIO_RELEASE)
  42. bool AudioDebugDrawFilter(const AZStd::string_view objectName, const AZStd::string_view filter);
  43. #endif // !AUDIO_RELEASE
  44. ///////////////////////////////////////////////////////////////////////////////////////////////////
  45. template <typename ObjType, typename IDType = size_t>
  46. class CInstanceManager
  47. {
  48. public:
  49. ~CInstanceManager() {}
  50. using TPointerContainer = AZStd::vector<ObjType*, Audio::AudioSystemStdAllocator>;
  51. TPointerContainer m_cReserved;
  52. IDType m_nIDCounter;
  53. const size_t m_nReserveSize;
  54. const IDType m_nMinCounterValue;
  55. CInstanceManager(const size_t nReserveSize, const IDType nMinCounterValue)
  56. : m_nIDCounter(nMinCounterValue)
  57. , m_nReserveSize(nReserveSize)
  58. , m_nMinCounterValue(nMinCounterValue)
  59. {
  60. m_cReserved.reserve(m_nReserveSize);
  61. }
  62. IDType GetNextID()
  63. {
  64. if (m_nIDCounter >= m_nMinCounterValue)
  65. {
  66. return m_nIDCounter++;
  67. }
  68. else
  69. {
  70. AZLOG_WARN("InstanceManager ID counter wrapped around");
  71. m_nIDCounter = m_nMinCounterValue;
  72. return m_nIDCounter;
  73. }
  74. }
  75. };
  76. ///////////////////////////////////////////////////////////////////////////////////////////////////
  77. class CSmoothFloat
  78. {
  79. public:
  80. explicit CSmoothFloat(const float smoothFactor, const float precision, const float initialValue = 0.0f)
  81. : m_value(initialValue)
  82. , m_target(initialValue)
  83. , m_isActive(false)
  84. , m_smoothFactor(AZ::GetAbs(smoothFactor))
  85. , m_precision(AZ::GetAbs(precision))
  86. {}
  87. ~CSmoothFloat() {}
  88. void Update(const float smoothFactorOverride = -1.f)
  89. {
  90. if (m_isActive)
  91. {
  92. if (AZ::GetAbs(m_target - m_value) > m_precision)
  93. {
  94. // still haven't reached the target within the specified precision, smooth towards it.
  95. const float smoothFactor = (smoothFactorOverride < 0.f) ? m_smoothFactor : smoothFactorOverride;
  96. m_value += (m_target - m_value) / (smoothFactor * smoothFactor + 1.f);
  97. }
  98. else
  99. {
  100. // reached the target (within precision) this update, disable smoothing until a new target is set.
  101. m_value = m_target;
  102. m_isActive = false;
  103. }
  104. }
  105. }
  106. float GetCurrent() const
  107. {
  108. return m_value;
  109. }
  110. void SetNewTarget(const float newTarget, const bool reset = false)
  111. {
  112. if (reset)
  113. {
  114. Reset(newTarget);
  115. }
  116. else if (AZ::GetAbs(newTarget - m_target) > m_precision)
  117. {
  118. m_target = newTarget;
  119. m_isActive = true;
  120. }
  121. }
  122. void Reset(const float initialValue = 0.0f)
  123. {
  124. m_value = m_target = initialValue;
  125. m_isActive = false;
  126. }
  127. private:
  128. float m_value;
  129. float m_target;
  130. bool m_isActive;
  131. const float m_smoothFactor;
  132. const float m_precision;
  133. };
  134. /*!
  135. * Flags
  136. * Used for storing, checking, setting, and clearing related bits together.
  137. */
  138. template<typename StoredType,
  139. typename = AZStd::enable_if_t<AZStd::is_integral<StoredType>::value
  140. && AZStd::is_unsigned<StoredType>::value>>
  141. class Flags
  142. {
  143. public:
  144. Flags(const StoredType flags = 0)
  145. : m_storedFlags(flags)
  146. {}
  147. void AddFlags(const StoredType flags)
  148. {
  149. m_storedFlags |= flags;
  150. }
  151. void ClearFlags(const StoredType flags)
  152. {
  153. m_storedFlags &= ~flags;
  154. }
  155. bool AreAllFlagsActive(const StoredType flags) const
  156. {
  157. return (m_storedFlags & flags) == flags;
  158. }
  159. bool AreAnyFlagsActive(const StoredType flags) const
  160. {
  161. return (m_storedFlags & flags) != 0;
  162. }
  163. bool AreMultipleFlagsActive() const
  164. {
  165. return (m_storedFlags & (m_storedFlags - 1)) != 0;
  166. }
  167. bool IsOneFlagActive() const
  168. {
  169. return m_storedFlags != 0 && !AreMultipleFlagsActive();
  170. }
  171. void ClearAllFlags()
  172. {
  173. m_storedFlags = 0;
  174. }
  175. void SetFlags(StoredType flags, const bool enable)
  176. {
  177. enable ? AddFlags(flags) : ClearFlags(flags);
  178. }
  179. StoredType GetRawFlags() const
  180. {
  181. return m_storedFlags;
  182. }
  183. bool operator==(const Flags& other) const
  184. {
  185. return m_storedFlags == other.m_storedFlags;
  186. }
  187. bool operator!=(const Flags& other) const
  188. {
  189. return m_storedFlags != other.m_storedFlags;
  190. }
  191. private:
  192. StoredType m_storedFlags = 0;
  193. };
  194. } // namespace Audio