ReaWwise

REAPER extension
Log | Files | Refs | Submodules

WwiseHelper.h (8877B)


      1 /*----------------------------------------------------------------------------------------
      2 
      3 Copyright (c) 2023 AUDIOKINETIC Inc.
      4 
      5 This file is licensed to use under the license available at:
      6 https://github.com/audiokinetic/ReaWwise/blob/main/License.txt (the "License").
      7 You may not use this file except in compliance with the License.
      8 
      9 Unless required by applicable law or agreed to in writing, software distributed
     10 under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
     11 CONDITIONS OF ANY KIND, either express or implied.  See the License for the
     12 specific language governing permissions and limitations under the License.
     13 
     14 ----------------------------------------------------------------------------------------*/
     15 
     16 #pragma once
     17 
     18 #include "Model/IDs.h"
     19 #include "Model/Wwise.h"
     20 
     21 #include <juce_gui_basics/juce_gui_basics.h>
     22 #include <regex>
     23 
     24 namespace AK::WwiseTransfer::WwiseHelper
     25 {
     26 	inline bool validateObjectTypeParentChildRelationShip(Wwise::ObjectType parent, Wwise::ObjectType child)
     27 	{
     28 		using namespace Wwise;
     29 
     30 		switch(parent)
     31 		{
     32 		case ObjectType::BlendContainer:
     33 		case ObjectType::RandomContainer:
     34 		case ObjectType::SequenceContainer:
     35 		case ObjectType::SwitchContainer:
     36 		{
     37 			static constexpr std::initializer_list<ObjectType> children{
     38 				ObjectType::SwitchContainer,
     39 				ObjectType::RandomContainer,
     40 				ObjectType::SequenceContainer,
     41 				ObjectType::BlendContainer,
     42 				ObjectType::SoundSFX,
     43 				ObjectType::SoundVoice,
     44 			};
     45 
     46 			return std::find(children.begin(), children.end(), child) != children.end();
     47 		};
     48 		case ObjectType::ActorMixer:
     49 		case ObjectType::VirtualFolder:
     50 		case ObjectType::WorkUnit:
     51 		{
     52 			static constexpr std::initializer_list<ObjectType> children{
     53 				ObjectType::WorkUnit,
     54 				ObjectType::VirtualFolder,
     55 				ObjectType::ActorMixer,
     56 				ObjectType::SwitchContainer,
     57 				ObjectType::RandomContainer,
     58 				ObjectType::SequenceContainer,
     59 				ObjectType::BlendContainer,
     60 				ObjectType::SoundSFX,
     61 				ObjectType::SoundVoice,
     62 			};
     63 
     64 			return std::find(children.begin(), children.end(), child) != children.end();
     65 		};
     66 		case ObjectType::PhysicalFolder:
     67 		{
     68 			static constexpr std::initializer_list<ObjectType> children{
     69 				ObjectType::PhysicalFolder,
     70 				ObjectType::WorkUnit,
     71 			};
     72 
     73 			return std::find(children.begin(), children.end(), child) != children.end();
     74 		};
     75 		default:
     76 			return false;
     77 		}
     78 	};
     79 
     80 	inline juce::String objectTypeToReadableString(Wwise::ObjectType objectType)
     81 	{
     82 		using namespace Wwise;
     83 
     84 		switch(objectType)
     85 		{
     86 		case ObjectType::ActorMixer:
     87 			return "Actor-Mixer";
     88 		case ObjectType::AudioFileSource:
     89 			return "Audio File Source";
     90 		case ObjectType::BlendContainer:
     91 			return "Blend Container";
     92 		case ObjectType::PhysicalFolder:
     93 			return "Physical Folder";
     94 		case ObjectType::RandomContainer:
     95 			return "Random Container";
     96 		case ObjectType::SequenceContainer:
     97 			return "Sequence Container";
     98 		case ObjectType::SoundSFX:
     99 			return "Sound SFX";
    100 		case ObjectType::SoundVoice:
    101 			return "Sound Voice";
    102 		case ObjectType::SwitchContainer:
    103 			return "Switch Container";
    104 		case ObjectType::VirtualFolder:
    105 			return "Virtual Folder";
    106 		case ObjectType::WorkUnit:
    107 			return "Work Unit";
    108 		case ObjectType::Sound:
    109 			return "Sound";
    110 		default:
    111 			return "Unknown";
    112 		}
    113 	};
    114 
    115 	inline Wwise::ObjectType stringToObjectType(const juce::String& objectTypeAsString)
    116 	{
    117 		using namespace Wwise;
    118 
    119 		if(objectTypeAsString == "AudioFileSource" || objectTypeAsString == "Audio File Source")
    120 			return ObjectType::AudioFileSource;
    121 		else if(objectTypeAsString == "ActorMixer" || objectTypeAsString == "Actor Mixer" || objectTypeAsString == "Actor-Mixer")
    122 			return ObjectType::ActorMixer;
    123 		else if(objectTypeAsString == "BlendContainer" || objectTypeAsString == "Blend Container")
    124 			return ObjectType::BlendContainer;
    125 		else if(objectTypeAsString == "Folder")
    126 			return ObjectType::VirtualFolder;
    127 		else if(objectTypeAsString == "RandomSequenceContainer" || objectTypeAsString == "Random Container")
    128 			return ObjectType::RandomContainer;
    129 		else if(objectTypeAsString == "SequenceContainer" || objectTypeAsString == "Sequence Container")
    130 			return ObjectType::SequenceContainer;
    131 		else if(objectTypeAsString == "Sound")
    132 			return ObjectType::Sound;
    133 		else if(objectTypeAsString == "SoundSFX" || objectTypeAsString == "Sound SFX")
    134 			return ObjectType::SoundSFX;
    135 		else if(objectTypeAsString == "Sound Voice")
    136 			return ObjectType::SoundVoice;
    137 		else if(objectTypeAsString == "SwitchContainer" || objectTypeAsString == "Switch Container")
    138 			return ObjectType::SwitchContainer;
    139 		else if(objectTypeAsString == "WorkUnit" || objectTypeAsString == "Work Unit")
    140 			return ObjectType::WorkUnit;
    141 		else if(objectTypeAsString == "Virtual Folder")
    142 			return ObjectType::VirtualFolder;
    143 		else if(objectTypeAsString == "Physical Folder")
    144 			return ObjectType::PhysicalFolder;
    145 		else
    146 			return ObjectType::Unknown;
    147 	};
    148 
    149 	inline juce::String buildObjectPathNode(Wwise::ObjectType objectType, const juce::String& name)
    150 	{
    151 		return "\\<" + objectTypeToReadableString(objectType) + ">" + name;
    152 	}
    153 
    154 	inline juce::String pathToPathWithoutObjectTypes(const juce::String& objectPath)
    155 	{
    156 		static std::regex pattern("<.+?>");
    157 		auto result = std::regex_replace(objectPath.toStdString(), pattern, "");
    158 		return juce::String(result);
    159 	}
    160 
    161 	inline std::vector<juce::String> pathToPathParts(const juce::String& objectPath)
    162 	{
    163 		juce::StringArray parts;
    164 		parts.addTokens(objectPath.trimCharactersAtStart("\\"), "\\", "");
    165 
    166 		std::vector<juce::String> objectPathParts;
    167 		for(auto& part : parts)
    168 		{
    169 			objectPathParts.emplace_back(part);
    170 		}
    171 
    172 		return objectPathParts;
    173 	}
    174 
    175 	inline std::vector<juce::String> pathToAncestorPaths(const juce::String& objectPath)
    176 	{
    177 		std::vector<juce::String> ancestors;
    178 
    179 		auto parts = pathToPathParts(objectPath);
    180 
    181 		juce::String current;
    182 		for(int i = 0; i < parts.size() - 1; ++i)
    183 		{
    184 			current << "\\" << parts[i];
    185 			ancestors.emplace_back(current);
    186 		}
    187 
    188 		return ancestors;
    189 	}
    190 
    191 	inline juce::String pathToObjectName(const juce::String& objectPath)
    192 	{
    193 		auto lastIndexGreaterThan = objectPath.lastIndexOf(">");
    194 		auto lastIndexOfPathSeperator = objectPath.lastIndexOf("\\");
    195 
    196 		if(lastIndexGreaterThan > lastIndexOfPathSeperator)
    197 			return objectPath.substring(lastIndexGreaterThan + 1);
    198 		else
    199 			return objectPath.substring(lastIndexOfPathSeperator + 1);
    200 	}
    201 
    202 	inline Wwise::ObjectType pathToObjectType(const juce::String& objectPath)
    203 	{
    204 		if(objectPath == "\\Actor-Mixer Hierarchy")
    205 			return Wwise::ObjectType::ActorMixer;
    206 
    207 		auto lastIndexLessThan = objectPath.lastIndexOf("<");
    208 		auto lastIndexGreaterThan = objectPath.lastIndexOf(">");
    209 
    210 		return WwiseHelper::stringToObjectType(objectPath.substring(lastIndexLessThan + 1, lastIndexGreaterThan));
    211 	}
    212 
    213 	inline juce::ValueTree versionToValueTree(const Wwise::Version& version)
    214 	{
    215 		juce::ValueTree valueTree(IDs::version);
    216 
    217 		valueTree.setProperty(IDs::year, version.year, nullptr);
    218 		valueTree.setProperty(IDs::major, version.major, nullptr);
    219 		valueTree.setProperty(IDs::minor, version.minor, nullptr);
    220 		valueTree.setProperty(IDs::build, version.build, nullptr);
    221 
    222 		return valueTree;
    223 	}
    224 
    225 	inline Wwise::Version valueTreeToVersion(juce::ValueTree valueTree)
    226 	{
    227 		return {
    228 			valueTree[IDs::year],
    229 			valueTree[IDs::major],
    230 			valueTree[IDs::minor],
    231 			valueTree[IDs::build],
    232 		};
    233 	}
    234 
    235 	inline juce::ValueTree languagesToValueTree(const std::vector<juce::String>& languages)
    236 	{
    237 		juce::ValueTree languagesValueTree(IDs::languages);
    238 
    239 		for(const auto& language : languages)
    240 		{
    241 			juce::ValueTree languageValueTree(IDs::language);
    242 			languageValueTree.setProperty(IDs::languageName, language, nullptr);
    243 
    244 			languagesValueTree.appendChild(languageValueTree, nullptr);
    245 		}
    246 
    247 		return languagesValueTree;
    248 	}
    249 
    250 	inline std::vector<juce::String> valueTreeToLanguages(juce::ValueTree valueTree)
    251 	{
    252 		std::vector<juce::String> languages;
    253 
    254 		for(int i = 0; i < valueTree.getNumChildren(); ++i)
    255 		{
    256 			languages.emplace_back(valueTree.getChild(i)[IDs::languageName].toString());
    257 		}
    258 
    259 		return languages;
    260 	}
    261 
    262 	inline juce::String getCommonAncestor(const juce::String& firstPath, const juce::String& secondPath)
    263 	{
    264 		auto firstAsParts = WwiseHelper::pathToPathParts(firstPath);
    265 		auto lastAsParts = WwiseHelper::pathToPathParts(secondPath);
    266 
    267 		juce::String commonAncestorPath;
    268 		for(int i = 0; i < firstAsParts.size() && i < lastAsParts.size(); ++i)
    269 		{
    270 			if(firstAsParts[i] == lastAsParts[i])
    271 				commonAncestorPath << "\\" << firstAsParts[i];
    272 			else
    273 				break;
    274 		}
    275 
    276 		return commonAncestorPath;
    277 	}
    278 
    279 	inline bool isPathComplete(const juce::String path)
    280 	{
    281 		for(int i = 1; i < path.length(); ++i)
    282 		{
    283 			if(path[i] == '\\' && (path[i - 1] == '\\' || path[i - 1] == '>'))
    284 				return false;
    285 
    286 			if(i == path.length() - 1 && (path[i] == '>' || path[i] == '\\'))
    287 				return false;
    288 		}
    289 
    290 		return true;
    291 	}
    292 } // namespace AK::WwiseTransfer::WwiseHelper