AudioWwiseLoader.cpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  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 <AudioWwiseLoader.h>
  9. #include <IAudioSystemControl.h>
  10. #include <IAudioSystemEditor.h>
  11. #include <AudioSystemEditor_wwise.h>
  12. #include <AudioFileUtils.h>
  13. #include <Config_wwise.h>
  14. namespace AudioControls
  15. {
  16. namespace WwiseStrings
  17. {
  18. // Wwise Project Folders
  19. static constexpr const char GameParametersFolder[] = "Game Parameters";
  20. static constexpr const char GameStatesFolder[] = "States";
  21. static constexpr const char SwitchesFolder[] = "Switches";
  22. static constexpr const char EventsFolder[] = "Events";
  23. static constexpr const char EnvironmentsFolder[] = "Master-Mixer Hierarchy";
  24. // Wwise Xml Tags
  25. static constexpr const char GameParameterTag[] = "GameParameter";
  26. static constexpr const char EventTag[] = "Event";
  27. static constexpr const char AuxBusTag[] = "AuxBus";
  28. static constexpr const char SwitchGroupTag[] = "SwitchGroup";
  29. static constexpr const char StateGroupTag[] = "StateGroup";
  30. static constexpr const char ChildrenListTag[] = "ChildrenList";
  31. static constexpr const char NameAttribute[] = "Name";
  32. } // namespace WwiseStrings
  33. //-------------------------------------------------------------------------------------------//
  34. void CAudioWwiseLoader::Load(CAudioSystemEditor_wwise* audioSystemImpl)
  35. {
  36. m_audioSystemImpl = audioSystemImpl;
  37. const AZ::IO::FixedMaxPath wwiseProjectFullPath{ m_audioSystemImpl->GetDataPath() };
  38. LoadControlsInFolder(AZ::IO::FixedMaxPath{ wwiseProjectFullPath / WwiseStrings::GameParametersFolder }.Native());
  39. LoadControlsInFolder(AZ::IO::FixedMaxPath{ wwiseProjectFullPath / WwiseStrings::GameStatesFolder }.Native());
  40. LoadControlsInFolder(AZ::IO::FixedMaxPath{ wwiseProjectFullPath / WwiseStrings::SwitchesFolder }.Native());
  41. LoadControlsInFolder(AZ::IO::FixedMaxPath{ wwiseProjectFullPath / WwiseStrings::EventsFolder }.Native());
  42. LoadControlsInFolder(AZ::IO::FixedMaxPath{ wwiseProjectFullPath / WwiseStrings::EnvironmentsFolder }.Native());
  43. LoadSoundBanks(Audio::Wwise::GetBanksRootPath(), "", false);
  44. }
  45. //-------------------------------------------------------------------------------------------//
  46. void CAudioWwiseLoader::LoadSoundBanks(const AZStd::string_view rootFolder, const AZStd::string_view subPath, bool isLocalized)
  47. {
  48. AZ::IO::FixedMaxPath searchPath(rootFolder);
  49. searchPath /= subPath;
  50. auto foundFiles = Audio::FindFilesInPath(searchPath.Native(), "*");
  51. bool isLocalizedLoaded = isLocalized;
  52. for (const auto& filePath : foundFiles)
  53. {
  54. AZ_Assert(AZ::IO::FileIOBase::GetInstance()->Exists(filePath.c_str()), "FindFiles found file '%s' but FileIO says it doesn't exist!", filePath.c_str());
  55. AZ::IO::PathView fileName = filePath.Filename();
  56. if (AZ::IO::FileIOBase::GetInstance()->IsDirectory(filePath.c_str()))
  57. {
  58. if (fileName != Audio::Wwise::ExternalSourcesPath && !isLocalizedLoaded)
  59. {
  60. // each sub-folder represents a different language,
  61. // we load only one as all of them should have the
  62. // same content (in the future we want to have a
  63. // consistency report to highlight if this is not the case)
  64. m_localizationFolder.assign(fileName.Native().data(), fileName.Native().size());
  65. LoadSoundBanks(searchPath.Native(), m_localizationFolder, true);
  66. isLocalizedLoaded = true;
  67. }
  68. }
  69. else if (fileName.Extension() == Audio::Wwise::BankExtension && fileName != Audio::Wwise::InitBank)
  70. {
  71. m_audioSystemImpl->CreateControl(
  72. SControlDef(AZStd::string{ fileName.Native() }, eWCT_WWISE_SOUND_BANK, isLocalized, nullptr, subPath));
  73. }
  74. }
  75. }
  76. //-------------------------------------------------------------------------------------------//
  77. void CAudioWwiseLoader::LoadControlsInFolder(const AZStd::string_view folderPath)
  78. {
  79. auto foundFiles = Audio::FindFilesInPath(folderPath, "*");
  80. for (const auto& filePath : foundFiles)
  81. {
  82. AZ_Assert(AZ::IO::FileIOBase::GetInstance()->Exists(filePath.c_str()), "FindFiles found file '%s' but FileIO says it doesn't exist!", filePath.c_str());
  83. if (AZ::IO::FileIOBase::GetInstance()->IsDirectory(filePath.c_str()))
  84. {
  85. LoadControlsInFolder(filePath.Native());
  86. }
  87. else
  88. {
  89. // Open the file, read into an xmlDoc, and call LoadControls with the root xml node...
  90. AZ_TracePrintf("AudioWwiseLoader", "Loading Xml from '%s'", filePath.c_str());
  91. Audio::ScopedXmlLoader xmlFileLoader(filePath.Native());
  92. if (!xmlFileLoader.HasError())
  93. {
  94. LoadControl(xmlFileLoader.GetRootNode());
  95. }
  96. }
  97. }
  98. }
  99. //-------------------------------------------------------------------------------------------//
  100. void CAudioWwiseLoader::ExtractControlsFromXML(const AZ::rapidxml::xml_node<char>* xmlNode, EWwiseControlTypes type, const AZStd::string_view controlTag, const AZStd::string_view controlNameAttribute)
  101. {
  102. AZStd::string_view xmlTag(xmlNode->name());
  103. if (xmlTag == controlTag)
  104. {
  105. if (auto nameAttr = xmlNode->first_attribute(controlNameAttribute.data()))
  106. {
  107. m_audioSystemImpl->CreateControl(SControlDef(nameAttr->value(), type));
  108. }
  109. }
  110. }
  111. //-------------------------------------------------------------------------------------------//
  112. void CAudioWwiseLoader::LoadControl(const AZ::rapidxml::xml_node<char>* xmlNode)
  113. {
  114. if (!xmlNode)
  115. {
  116. return;
  117. }
  118. ExtractControlsFromXML(xmlNode, eWCT_WWISE_RTPC, WwiseStrings::GameParameterTag, WwiseStrings::NameAttribute);
  119. ExtractControlsFromXML(xmlNode, eWCT_WWISE_EVENT, WwiseStrings::EventTag, WwiseStrings::NameAttribute);
  120. ExtractControlsFromXML(xmlNode, eWCT_WWISE_AUX_BUS, WwiseStrings::AuxBusTag, WwiseStrings::NameAttribute);
  121. AZStd::string_view xmlTag(xmlNode->name());
  122. bool isSwitchTag = (xmlTag == WwiseStrings::SwitchGroupTag);
  123. bool isStateTag = (xmlTag == WwiseStrings::StateGroupTag);
  124. if (isSwitchTag || isStateTag)
  125. {
  126. if (auto nameAttr = xmlNode->first_attribute(WwiseStrings::NameAttribute))
  127. {
  128. const AZStd::string parentName(nameAttr->value());
  129. IAudioSystemControl* group = m_audioSystemImpl->GetControlByName(parentName);
  130. if (!group)
  131. {
  132. group = m_audioSystemImpl->CreateControl(SControlDef(parentName, isSwitchTag ? eWCT_WWISE_SWITCH_GROUP : eWCT_WWISE_GAME_STATE_GROUP));
  133. }
  134. auto childrenNode = xmlNode->first_node(WwiseStrings::ChildrenListTag);
  135. if (childrenNode)
  136. {
  137. auto childNode = childrenNode->first_node();
  138. while (childNode)
  139. {
  140. if (auto childNameAttr = childNode->first_attribute(WwiseStrings::NameAttribute))
  141. {
  142. m_audioSystemImpl->CreateControl(SControlDef(childNameAttr->value(), isSwitchTag ? eWCT_WWISE_SWITCH : eWCT_WWISE_GAME_STATE, false, group));
  143. }
  144. childNode = childNode->next_sibling();
  145. }
  146. }
  147. }
  148. }
  149. auto childNode = xmlNode->first_node();
  150. while (childNode)
  151. {
  152. LoadControl(childNode);
  153. childNode = childNode->next_sibling();
  154. }
  155. }
  156. //-------------------------------------------------------------------------------------------//
  157. const AZStd::string& CAudioWwiseLoader::GetLocalizationFolder() const
  158. {
  159. return m_localizationFolder;
  160. }
  161. } // namespace AudioControls