AudioPreloadComponent.cpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  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. #include "AudioPreloadComponent.h"
  9. #include <ISystem.h>
  10. #include <IAudioSystem.h>
  11. #include <AzCore/Component/Entity.h>
  12. #include <AzCore/Debug/Trace.h>
  13. #include <AzCore/RTTI/BehaviorContext.h>
  14. #include <AzCore/Serialization/SerializeContext.h>
  15. namespace LmbrCentral
  16. {
  17. //=========================================================================
  18. void AudioPreloadComponent::Reflect(AZ::ReflectContext* context)
  19. {
  20. if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
  21. {
  22. serializeContext->Class<AudioPreloadComponent, AZ::Component>()
  23. ->Version(1)
  24. ->Field("Preload Name", &AudioPreloadComponent::m_defaultPreloadName)
  25. ->Field("Load Type", &AudioPreloadComponent::m_loadType)
  26. ;
  27. }
  28. if (auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
  29. {
  30. behaviorContext->Enum<static_cast<AZ::u32>(AudioPreloadComponent::LoadType::Auto)>("AudioPreloadComponentLoadType_Auto")
  31. ->Enum<static_cast<AZ::u32>(AudioPreloadComponent::LoadType::Manual)>("AudioPreloadComponentLoadType_Manual")
  32. ;
  33. behaviorContext->EBus<AudioPreloadComponentRequestBus>("AudioPreloadComponentRequestBus")
  34. ->Event("Load", &AudioPreloadComponentRequestBus::Events::Load)
  35. ->Event("Unload", &AudioPreloadComponentRequestBus::Events::Unload)
  36. ->Event("LoadPreload", &AudioPreloadComponentRequestBus::Events::LoadPreload)
  37. ->Event("UnloadPreload", &AudioPreloadComponentRequestBus::Events::UnloadPreload)
  38. ->Event("IsLoaded", &AudioPreloadComponentRequestBus::Events::IsLoaded)
  39. ;
  40. }
  41. }
  42. //=========================================================================
  43. AudioPreloadComponent::AudioPreloadComponent(AudioPreloadComponent::LoadType loadType, const AZStd::string& preloadName)
  44. : m_loadType(loadType)
  45. , m_defaultPreloadName(preloadName)
  46. {
  47. }
  48. //=========================================================================
  49. void AudioPreloadComponent::Activate()
  50. {
  51. // Connect to the preload notification bus first, we want to be notified about the default preload (if any).
  52. AudioPreloadComponentRequestBus::Handler::BusConnect(GetEntityId());
  53. if (m_loadType == AudioPreloadComponent::LoadType::Auto)
  54. {
  55. Load(); // load the default preload (if any)
  56. }
  57. }
  58. //=========================================================================
  59. void AudioPreloadComponent::Deactivate()
  60. {
  61. // Don't care about preload notifications while deactivating, disconnect from the bus first.
  62. AudioPreloadComponentRequestBus::Handler::BusDisconnect(GetEntityId());
  63. Audio::AudioPreloadNotificationBus::MultiHandler::BusDisconnect();
  64. if (m_loadType == AudioPreloadComponent::LoadType::Auto)
  65. {
  66. Unload(); // unload the default preload (if any)
  67. AZStd::lock_guard<AZStd::mutex> lock(m_loadMutex);
  68. for (auto preloadId : m_loadedPreloadIds)
  69. {
  70. UnloadPreloadById(preloadId);
  71. }
  72. m_loadedPreloadIds.clear();
  73. }
  74. else
  75. {
  76. AZStd::lock_guard<AZStd::mutex> lock(m_loadMutex);
  77. AZ_Warning("AudioPreloadComponent", m_loadedPreloadIds.empty(),
  78. "A Manual-mode AudioPreloadComponent is Deactivating and has %d remaining loaded preloads!\nBe sure to match all manual 'LoadPreload's with an 'UnloadPreload'!",
  79. m_loadedPreloadIds.size());
  80. }
  81. }
  82. //=========================================================================
  83. void AudioPreloadComponent::Load()
  84. {
  85. if (!m_defaultPreloadName.empty())
  86. {
  87. LoadPreload(m_defaultPreloadName.c_str());
  88. }
  89. }
  90. //=========================================================================
  91. void AudioPreloadComponent::Unload()
  92. {
  93. if (!m_defaultPreloadName.empty())
  94. {
  95. UnloadPreload(m_defaultPreloadName.c_str());
  96. }
  97. }
  98. //=========================================================================
  99. void AudioPreloadComponent::LoadPreload(const char* preloadName)
  100. {
  101. if (IsLoaded(preloadName))
  102. {
  103. return;
  104. }
  105. Audio::TAudioPreloadRequestID preloadRequestId = INVALID_AUDIO_PRELOAD_REQUEST_ID;
  106. if (auto audioSystem = AZ::Interface<Audio::IAudioSystem>::Get(); audioSystem != nullptr)
  107. {
  108. preloadRequestId = audioSystem->GetAudioPreloadRequestID(preloadName);
  109. }
  110. if (preloadRequestId != INVALID_AUDIO_PRELOAD_REQUEST_ID)
  111. {
  112. LoadPreloadById(preloadRequestId);
  113. }
  114. }
  115. //=========================================================================
  116. void AudioPreloadComponent::UnloadPreload(const char* preloadName)
  117. {
  118. if (!IsLoaded(preloadName))
  119. {
  120. return;
  121. }
  122. Audio::TAudioPreloadRequestID preloadRequestId = INVALID_AUDIO_PRELOAD_REQUEST_ID;
  123. if (auto audioSystem = AZ::Interface<Audio::IAudioSystem>::Get(); audioSystem != nullptr)
  124. {
  125. preloadRequestId = audioSystem->GetAudioPreloadRequestID(preloadName);
  126. }
  127. if (preloadRequestId != INVALID_AUDIO_PRELOAD_REQUEST_ID)
  128. {
  129. UnloadPreloadById(preloadRequestId);
  130. }
  131. }
  132. //=========================================================================
  133. bool AudioPreloadComponent::IsLoaded(const char* preloadName)
  134. {
  135. AZStd::lock_guard<AZStd::mutex> lock(m_loadMutex);
  136. bool loaded = (m_loadedPreloadIds.find(Audio::AudioStringToID<Audio::TAudioPreloadRequestID>(preloadName)) != m_loadedPreloadIds.end());
  137. return loaded;
  138. }
  139. //=========================================================================
  140. void AudioPreloadComponent::OnAudioPreloadCached()
  141. {
  142. const Audio::TAudioPreloadRequestID* preloadId = Audio::AudioPreloadNotificationBus::GetCurrentBusId();
  143. AZStd::lock_guard<AZStd::mutex> lock(m_loadMutex);
  144. m_loadedPreloadIds.insert(*preloadId);
  145. }
  146. //=========================================================================
  147. void AudioPreloadComponent::OnAudioPreloadUncached()
  148. {
  149. const Audio::TAudioPreloadRequestID preloadId = *Audio::AudioPreloadNotificationBus::GetCurrentBusId();
  150. Audio::AudioPreloadNotificationBus::MultiHandler::BusDisconnect(preloadId);
  151. AZStd::lock_guard<AZStd::mutex> lock(m_loadMutex);
  152. m_loadedPreloadIds.erase(preloadId);
  153. }
  154. //=========================================================================
  155. void AudioPreloadComponent::LoadPreloadById(Audio::TAudioPreloadRequestID preloadId)
  156. {
  157. Audio::AudioPreloadNotificationBus::MultiHandler::BusConnect(preloadId);
  158. if (auto audioSystem = AZ::Interface<Audio::IAudioSystem>::Get(); audioSystem != nullptr)
  159. {
  160. Audio::SystemRequest::LoadBank loadBank;
  161. loadBank.m_preloadRequestId = preloadId;
  162. loadBank.m_asyncLoad = true;
  163. audioSystem->PushRequest(AZStd::move(loadBank));
  164. }
  165. }
  166. //=========================================================================
  167. void AudioPreloadComponent::UnloadPreloadById(Audio::TAudioPreloadRequestID preloadId)
  168. {
  169. if (auto audioSystem = AZ::Interface<Audio::IAudioSystem>::Get(); audioSystem != nullptr)
  170. {
  171. Audio::SystemRequest::UnloadBank unloadBank;
  172. unloadBank.m_preloadRequestId = preloadId;
  173. audioSystem->PushRequest(AZStd::move(unloadBank));
  174. }
  175. }
  176. } // namespace LmbrCentral