123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251 |
- /*******************************************************************************
- The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
- Technology released in source code form as part of the game integration package.
- The content of this file may not be used without valid licenses to the
- AUDIOKINETIC Wwise Technology.
- Note that the use of the game engine is subject to the Unreal(R) Engine End User
- License Agreement at https://www.unrealengine.com/en-US/eula/unreal
-
- License Usage
-
- Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
- this file in accordance with the end user license agreement provided with the
- software or, alternatively, in accordance with the terms contained
- in a written agreement between you and Audiokinetic Inc.
- Copyright (c) 2023 Audiokinetic Inc.
- *******************************************************************************/
- #include "AkUnrealHelper.h"
- #include "Wwise/Stats/SoundEngine.h"
- #include "AkUEFeatures.h"
- #if UE_5_1_OR_LATER
- #include "Engine/HitResult.h"
- #endif
- #include "Misc/Paths.h"
- namespace AkUnrealHelper
- {
- const TCHAR* MediaFolderName = TEXT("Media");
- const TCHAR* ExternalSourceFolderName = TEXT("ExternalSources");
- constexpr auto SoundBankNamePrefix = TEXT("SB_");
- const FGuid InitBankID(0x701ECBBD, 0x9C7B4030, 0x8CDB749E, 0xE5D1C7B9);
- FString(*GetWwisePluginDirectoryPtr)();
- FString(*GetWwiseProjectPathPtr)();
- FString(*GetSoundBankDirectoryPtr)();
- FString(*GetStagePathPtr)();
-
- void SetHelperFunctions(FString(* GetWwisePluginDirectoryImpl)(), FString(* GetWwiseProjectPathImpl)(),
- FString(* GetSoundBankDirectoryImpl)(), FString(* GetStagePathImpl)())
- {
- GetWwisePluginDirectoryPtr = GetWwisePluginDirectoryImpl;
- GetWwiseProjectPathPtr = GetWwiseProjectPathImpl;
- GetSoundBankDirectoryPtr = GetSoundBankDirectoryImpl;
- GetStagePathPtr = GetStagePathImpl;
- }
- FString GetWwisePluginDirectory()
- {
- if (!GetWwisePluginDirectoryPtr)
- {
- UE_LOG(LogWwiseSoundEngine, Error, TEXT("AkUnrealHelper::GetWwisePluginDirectory implementation not set."));
- return {};
- }
- return GetWwisePluginDirectoryPtr();
- }
- FString GetWwiseProjectPath()
- {
- if (!GetWwiseProjectPathPtr)
- {
- UE_LOG(LogWwiseSoundEngine, Error, TEXT("AkUnrealHelper::GetWwiseProjectPath implementation not set."));
- return {};
- }
- return GetWwiseProjectPathPtr();
- }
- FString GetSoundBankDirectory()
- {
- if (!GetSoundBankDirectoryPtr)
- {
- UE_LOG(LogWwiseSoundEngine, Error, TEXT("AkUnrealHelper::GetSoundBankDirectory implementation not set."));
- return {};
- }
- return GetSoundBankDirectoryPtr();
- }
- FString GetStagePath()
- {
- if (!GetStagePathPtr)
- {
- UE_LOG(LogWwiseSoundEngine, Error, TEXT("AkUnrealHelper::GetStagePath implementation not set."));
- return {};
- }
- return GetStagePathPtr();
- }
- void TrimPath(FString& Path)
- {
- Path.TrimStartAndEndInline();
- }
- FString GetProjectDirectory()
- {
- return FPaths::ConvertRelativePathToFull(FPaths::ProjectDir());
- }
- FString GetContentDirectory()
- {
- return FPaths::ConvertRelativePathToFull(FPaths::ProjectContentDir());
- }
- FString GetThirdPartyDirectory()
- {
- return FPaths::Combine(GetWwisePluginDirectory(), TEXT("ThirdParty"));
- }
- FString GetExternalSourceDirectory()
- {
- return FPaths::Combine(GetSoundBankDirectory(), ExternalSourceFolderName);
- }
- FString GetWwiseProjectDirectoryPath()
- {
- return FPaths::GetPath(GetWwiseProjectPath()) + TEXT("/");
- }
- bool MakePathRelativeToWwiseProject(FString& AbsolutePath)
- {
- auto wwiseProjectRoot = AkUnrealHelper::GetWwiseProjectDirectoryPath();
- #if PLATFORM_WINDOWS
- AbsolutePath.ReplaceInline(TEXT("/"), TEXT("\\"));
- wwiseProjectRoot.ReplaceInline(TEXT("/"), TEXT("\\"));
- #endif
- bool success = FPaths::MakePathRelativeTo(AbsolutePath, *wwiseProjectRoot);
- #if PLATFORM_WINDOWS
- AbsolutePath.ReplaceInline(TEXT("/"), TEXT("\\"));
- #endif
- return success;
- }
- FString GetWwiseSoundBankInfoCachePath()
- {
- return FPaths::Combine(FPaths::GetPath(GetWwiseProjectPath()), TEXT(".cache"), TEXT("SoundBankInfoCache.dat"));
- }
- const TCHAR* GetResultString(AKRESULT InResult)
- {
- switch (InResult)
- {
- case AK_NotImplemented: return TEXT("This feature is not implemented.");
- case AK_Success: return TEXT("The operation was successful.");
- case AK_Fail: return TEXT("The operation failed.");
- case AK_PartialSuccess: return TEXT("The operation succeeded partially.");
- case AK_NotCompatible: return TEXT("Incompatible formats");
- case AK_AlreadyConnected: return TEXT("The stream is already connected to another node.");
- case AK_InvalidFile: return TEXT("The provided file is the wrong format or unexpected values causes the file to be invalid.");
- case AK_AudioFileHeaderTooLarge: return TEXT("The file header is too large.");
- case AK_MaxReached: return TEXT("The maximum was reached.");
- case AK_InvalidID: return TEXT("The ID is invalid.");
- case AK_IDNotFound: return TEXT("The ID was not found.");
- case AK_InvalidInstanceID: return TEXT("The InstanceID is invalid.");
- case AK_NoMoreData: return TEXT("No more data is available from the source.");
- case AK_InvalidStateGroup: return TEXT("The StateGroup is not a valid channel.");
- case AK_ChildAlreadyHasAParent: return TEXT("The child already has a parent.");
- case AK_InvalidLanguage: return TEXT("The language is invalid (applies to the Low-Level I/O).");
- case AK_CannotAddItseflAsAChild: return TEXT("It is not possible to add itself as its own child.");
- case AK_InvalidParameter: return TEXT("Something is not within bounds, check the documentation of the function returning this code.");
- case AK_ElementAlreadyInList: return TEXT("The item could not be added because it was already in the list.");
- case AK_PathNotFound: return TEXT("This path is not known.");
- case AK_PathNoVertices: return TEXT("Stuff in vertices before trying to start it");
- case AK_PathNotRunning: return TEXT("Only a running path can be paused.");
- case AK_PathNotPaused: return TEXT("Only a paused path can be resumed.");
- case AK_PathNodeAlreadyInList: return TEXT("This path is already there.");
- case AK_PathNodeNotInList: return TEXT("This path is not there.");
- case AK_DataNeeded: return TEXT("The consumer needs more.");
- case AK_NoDataNeeded: return TEXT("The consumer does not need more.");
- case AK_DataReady: return TEXT("The provider has available data.");
- case AK_NoDataReady: return TEXT("The provider does not have available data.");
- case AK_InsufficientMemory: return TEXT("Memory error.");
- case AK_Cancelled: return TEXT("The requested action was cancelled (not an error).");
- case AK_UnknownBankID: return TEXT("Trying to load a bank using an ID which is not defined.");
- case AK_BankReadError: return TEXT("Error while reading a bank.");
- case AK_InvalidSwitchType: return TEXT("Invalid switch type (used with the switch container)");
- case AK_FormatNotReady: return TEXT("Source format not known yet.");
- case AK_WrongBankVersion: return TEXT("The bank version is not compatible with the current bank reader.");
- case AK_FileNotFound: return TEXT("File not found.");
- case AK_DeviceNotReady: return TEXT("Specified ID doesn't match a valid hardware device: either the device doesn't exist or is disabled.");
- case AK_BankAlreadyLoaded: return TEXT("The bank load failed because the bank is already loaded.");
- case AK_RenderedFX: return TEXT("The effect on the node is rendered.");
- case AK_ProcessNeeded: return TEXT("A routine needs to be executed on some CPU.");
- case AK_ProcessDone: return TEXT("The executed routine has finished its execution.");
- case AK_MemManagerNotInitialized: return TEXT("The memory manager should have been initialized at this point.");
- case AK_StreamMgrNotInitialized: return TEXT("The stream manager should have been initialized at this point.");
- case AK_SSEInstructionsNotSupported: return TEXT("The machine does not support SSE instructions (required on PC).");
- case AK_Busy: return TEXT("The system is busy and could not process the request.");
- case AK_UnsupportedChannelConfig: return TEXT("Channel configuration is not supported in the current execution context.");
- case AK_PluginMediaNotAvailable: return TEXT("Plugin media is not available for effect.");
- case AK_MustBeVirtualized: return TEXT("Sound was Not Allowed to play.");
- case AK_CommandTooLarge: return TEXT("SDK command is too large to fit in the command queue.");
- case AK_RejectedByFilter: return TEXT("A play request was rejected due to the MIDI filter parameters.");
- case AK_InvalidCustomPlatformName: return TEXT("Detecting incompatibility between Custom platform of banks and custom platform of connected application");
- case AK_DLLCannotLoad: return TEXT("Plugin DLL could not be loaded, either because it is not found or one dependency is missing.");
- case AK_DLLPathNotFound: return TEXT("Plugin DLL search path could not be found.");
- case AK_NoJavaVM: return TEXT("No Java VM provided in AkInitSettings.");
- case AK_OpenSLError: return TEXT("OpenSL returned an error. Check error log for more details.");
- case AK_PluginNotRegistered: return TEXT("Plugin is not registered. Make sure to implement a AK::PluginRegistration class for it and use AK_STATIC_LINK_PLUGIN in the game binary.");
- case AK_DataAlignmentError: return TEXT("A pointer to audio data was not aligned to the platform's required alignment (check AkTypes.h in the platform-specific folder)");
- case AK_DeviceNotCompatible: return TEXT("Incompatible Audio device.");
- case AK_DuplicateUniqueID: return TEXT("Two Wwise objects share the same ID.");
- case AK_InitBankNotLoaded: return TEXT("The Init bank was not loaded yet, the sound engine isn't completely ready yet.");
- case AK_DeviceNotFound: return TEXT("The specified device ID does not match with any of the output devices that the sound engine is currently using.");
- case AK_PlayingIDNotFound: return TEXT("Calling a function with a playing ID that is not known.");
- case AK_InvalidFloatValue: return TEXT("One parameter has a invalid float value such as NaN, INF or FLT_MAX.");
- case AK_FileFormatMismatch: return TEXT("Media file format unexpected");
- case AK_NoDistinctListener: return TEXT("No distinct listener provided for AddOutput");
- case AK_ACP_Error: return TEXT("Generic XMA decoder error.");
- case AK_ResourceInUse: return TEXT("Resource is in use and cannot be released.");
- case AK_InvalidBankType: return TEXT("Invalid bank type. The bank type was either supplied through a function call (e.g. LoadBank) or obtained from a bank loaded from memory.");
- case AK_AlreadyInitialized: return TEXT("Init() was called but that element was already initialized.");
- case AK_NotInitialized: return TEXT("The component being used is not initialized. Most likely AK::SoundEngine::Init() was not called yet, or AK::SoundEngine::Term was called too early.");
- case AK_FilePermissionError: return TEXT("The file access permissions prevent opening a file.");
- case AK_UnknownFileError: return TEXT("Rare file error occured, as opposed to AK_FileNotFound or AK_FilePermissionError. This lumps all unrecognized OS file system errors.");
- default: return TEXT("Unknown Error.");
- }
- }
- #if WITH_EDITOR
- FString GuidToBankName(const FGuid& Guid)
- {
- if (Guid == InitBankID)
- {
- return TEXT("Init");
- }
- return FString(SoundBankNamePrefix) + Guid.ToString(EGuidFormats::Digits);
- }
- FGuid BankNameToGuid(const FString& BankName)
- {
- FString copy = BankName;
- copy.RemoveFromStart(SoundBankNamePrefix);
- FGuid result;
- FGuid::ParseExact(copy, EGuidFormats::Digits, result);
- return result;
- }
- FString FormatFolderPath(const FString folderPath)
- {
- auto path = folderPath.Replace(TEXT("\\"), TEXT("/"));
- if (path[0] == '/') {
- path.RemoveAt(0);
- }
- return path;
- }
- #endif
- }
|