673 lines
22 KiB
C++
673 lines
22 KiB
C++
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2025.
|
|
|
|
#include "FMODBlueprintStatics.h"
|
|
#include "FMODAudioComponent.h"
|
|
#include "FMODSettings.h"
|
|
#include "FMODStudioModule.h"
|
|
#include "FMODUtils.h"
|
|
#include "FMODBank.h"
|
|
#include "FMODEvent.h"
|
|
#include "FMODBus.h"
|
|
#include "FMODVCA.h"
|
|
#include "fmod_studio.hpp"
|
|
#include "fmod_errors.h"
|
|
#include "FMODStudioPrivatePCH.h"
|
|
|
|
/////////////////////////////////////////////////////
|
|
// UFMODBlueprintStatics
|
|
|
|
UFMODBlueprintStatics::UFMODBlueprintStatics(const FObjectInitializer &ObjectInitializer)
|
|
: Super(ObjectInitializer)
|
|
{
|
|
}
|
|
|
|
FFMODEventInstance UFMODBlueprintStatics::PlayEvent2D(UObject *WorldContextObject, class UFMODEvent *Event, bool bAutoPlay)
|
|
{
|
|
return PlayEventAtLocation(WorldContextObject, Event, FTransform(), bAutoPlay);
|
|
}
|
|
|
|
FFMODEventInstance UFMODBlueprintStatics::PlayEventAtLocation(
|
|
UObject *WorldContextObject, class UFMODEvent *Event, const FTransform &Location, bool bAutoPlay)
|
|
{
|
|
FFMODEventInstance Instance;
|
|
Instance.Instance = nullptr;
|
|
|
|
UWorld *ThisWorld = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::ReturnNull);
|
|
if (FMODUtils::IsWorldAudible(ThisWorld, false) && IsValid(Event))
|
|
{
|
|
FMOD::Studio::EventDescription *EventDesc = IFMODStudioModule::Get().GetEventDescription(Event);
|
|
if (EventDesc != nullptr)
|
|
{
|
|
FMOD::Studio::EventInstance *EventInst = nullptr;
|
|
EventDesc->createInstance(&EventInst);
|
|
if (EventInst != nullptr)
|
|
{
|
|
FMOD_3D_ATTRIBUTES EventAttr = { { 0 } };
|
|
FMODUtils::Assign(EventAttr, Location);
|
|
EventInst->set3DAttributes(&EventAttr);
|
|
|
|
if (bAutoPlay)
|
|
{
|
|
EventInst->start();
|
|
EventInst->release();
|
|
}
|
|
Instance.Instance = EventInst;
|
|
}
|
|
}
|
|
}
|
|
return Instance;
|
|
}
|
|
|
|
class UFMODAudioComponent *UFMODBlueprintStatics::PlayEventAttached(class UFMODEvent *Event, class USceneComponent *AttachToComponent,
|
|
FName AttachPointName, FVector Location, EAttachLocation::Type LocationType, bool bStopWhenAttachedToDestroyed, bool bAutoPlay, bool bAutoDestroy)
|
|
{
|
|
if (!IFMODStudioModule::Get().UseSound())
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
if (Event == nullptr)
|
|
{
|
|
return nullptr;
|
|
}
|
|
if (AttachToComponent == nullptr)
|
|
{
|
|
UE_LOG(LogFMOD, Warning, TEXT("UFMODBlueprintStatics::PlayEventAttached: NULL AttachComponent specified!"));
|
|
return nullptr;
|
|
}
|
|
|
|
AActor *Actor = AttachToComponent->GetOwner();
|
|
|
|
// Avoid creating component if we're trying to play a sound on an already destroyed actor.
|
|
if (!IsValid(Actor))
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
UFMODAudioComponent *AudioComponent;
|
|
if (Actor)
|
|
{
|
|
// Use actor as outer if we have one.
|
|
AudioComponent = NewObject<UFMODAudioComponent>(Actor);
|
|
}
|
|
else
|
|
{
|
|
// Let engine pick the outer (transient package).
|
|
AudioComponent = NewObject<UFMODAudioComponent>();
|
|
}
|
|
check(AudioComponent);
|
|
AudioComponent->Event = Event;
|
|
AudioComponent->bAutoActivate = false;
|
|
AudioComponent->bAutoDestroy = bAutoDestroy;
|
|
AudioComponent->bStopWhenOwnerDestroyed = bStopWhenAttachedToDestroyed;
|
|
#if WITH_EDITORONLY_DATA
|
|
AudioComponent->bVisualizeComponent = false;
|
|
#endif
|
|
AudioComponent->RegisterComponentWithWorld(AttachToComponent->GetWorld());
|
|
|
|
AudioComponent->AttachToComponent(AttachToComponent, FAttachmentTransformRules::KeepRelativeTransform, AttachPointName);
|
|
if (LocationType == EAttachLocation::KeepWorldPosition)
|
|
{
|
|
AudioComponent->SetWorldLocation(Location);
|
|
}
|
|
else
|
|
{
|
|
AudioComponent->SetRelativeLocation(Location);
|
|
}
|
|
|
|
if (bAutoPlay)
|
|
{
|
|
AudioComponent->Play();
|
|
}
|
|
return AudioComponent;
|
|
}
|
|
|
|
UFMODAsset *UFMODBlueprintStatics::FindAssetByName(const FString &Name)
|
|
{
|
|
return IFMODStudioModule::Get().FindAssetByName(Name);
|
|
}
|
|
|
|
UFMODEvent *UFMODBlueprintStatics::FindEventByName(const FString &Name)
|
|
{
|
|
return IFMODStudioModule::Get().FindEventByName(Name);
|
|
}
|
|
|
|
void UFMODBlueprintStatics::LoadBank(class UFMODBank *Bank, bool bBlocking, bool bLoadSampleData)
|
|
{
|
|
FMOD::Studio::System *StudioSystem = IFMODStudioModule::Get().GetStudioSystem(EFMODSystemContext::Runtime);
|
|
if (StudioSystem != nullptr && IsValid(Bank))
|
|
{
|
|
UE_LOG(LogFMOD, Log, TEXT("LoadBank %s"), *Bank->GetName());
|
|
|
|
FString BankPath = IFMODStudioModule::Get().GetBankPath(*Bank);
|
|
FMOD::Studio::Bank *bank = nullptr;
|
|
FMOD_STUDIO_LOAD_BANK_FLAGS flags = (bBlocking || bLoadSampleData) ? FMOD_STUDIO_LOAD_BANK_NORMAL : FMOD_STUDIO_LOAD_BANK_NONBLOCKING;
|
|
|
|
FMOD_RESULT result = StudioSystem->loadBankFile(TCHAR_TO_UTF8(*BankPath), flags, &bank);
|
|
if (result != FMOD_OK)
|
|
{
|
|
UE_LOG(LogFMOD, Error, TEXT("Failed to load bank %s: %s"), *Bank->GetName(), UTF8_TO_TCHAR(FMOD_ErrorString(result)));
|
|
}
|
|
if (result == FMOD_OK && bLoadSampleData)
|
|
{
|
|
bank->loadSampleData();
|
|
}
|
|
}
|
|
}
|
|
|
|
void UFMODBlueprintStatics::UnloadBank(class UFMODBank *Bank)
|
|
{
|
|
FMOD::Studio::System *StudioSystem = IFMODStudioModule::Get().GetStudioSystem(EFMODSystemContext::Runtime);
|
|
if (StudioSystem != nullptr && IsValid(Bank))
|
|
{
|
|
UE_LOG(LogFMOD, Log, TEXT("UnloadBank %s"), *Bank->GetName());
|
|
|
|
FMOD::Studio::ID guid = FMODUtils::ConvertGuid(Bank->AssetGuid);
|
|
FMOD::Studio::Bank *bank = nullptr;
|
|
FMOD_RESULT result = StudioSystem->getBankByID(&guid, &bank);
|
|
if (result == FMOD_OK && bank != nullptr)
|
|
{
|
|
bank->unload();
|
|
}
|
|
}
|
|
}
|
|
|
|
bool UFMODBlueprintStatics::IsBankLoaded(class UFMODBank *Bank)
|
|
{
|
|
FMOD::Studio::System *StudioSystem = IFMODStudioModule::Get().GetStudioSystem(EFMODSystemContext::Runtime);
|
|
if (StudioSystem != nullptr && IsValid(Bank))
|
|
{
|
|
FMOD::Studio::ID guid = FMODUtils::ConvertGuid(Bank->AssetGuid);
|
|
FMOD::Studio::Bank *bank = nullptr;
|
|
FMOD_RESULT result = StudioSystem->getBankByID(&guid, &bank);
|
|
if (result == FMOD_OK && bank != nullptr)
|
|
{
|
|
FMOD_STUDIO_LOADING_STATE loadingState;
|
|
if (bank->getLoadingState(&loadingState) == FMOD_OK)
|
|
{
|
|
return (loadingState == FMOD_STUDIO_LOADING_STATE_LOADED);
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void UFMODBlueprintStatics::LoadBankSampleData(class UFMODBank *Bank)
|
|
{
|
|
FMOD::Studio::System *StudioSystem = IFMODStudioModule::Get().GetStudioSystem(EFMODSystemContext::Runtime);
|
|
if (StudioSystem != nullptr && IsValid(Bank))
|
|
{
|
|
FMOD::Studio::ID guid = FMODUtils::ConvertGuid(Bank->AssetGuid);
|
|
FMOD::Studio::Bank *bank = nullptr;
|
|
FMOD_RESULT result = StudioSystem->getBankByID(&guid, &bank);
|
|
if (result == FMOD_OK && bank != nullptr)
|
|
{
|
|
bank->loadSampleData();
|
|
}
|
|
}
|
|
}
|
|
|
|
void UFMODBlueprintStatics::UnloadBankSampleData(class UFMODBank *Bank)
|
|
{
|
|
FMOD::Studio::System *StudioSystem = IFMODStudioModule::Get().GetStudioSystem(EFMODSystemContext::Runtime);
|
|
if (StudioSystem != nullptr && IsValid(Bank))
|
|
{
|
|
FMOD::Studio::ID guid = FMODUtils::ConvertGuid(Bank->AssetGuid);
|
|
FMOD::Studio::Bank *bank = nullptr;
|
|
FMOD_RESULT result = StudioSystem->getBankByID(&guid, &bank);
|
|
if (result == FMOD_OK && bank != nullptr)
|
|
{
|
|
bank->unloadSampleData();
|
|
}
|
|
}
|
|
}
|
|
|
|
void UFMODBlueprintStatics::LoadEventSampleData(UObject *WorldContextObject, class UFMODEvent *Event)
|
|
{
|
|
if (IsValid(Event))
|
|
{
|
|
FMOD::Studio::EventDescription *EventDesc = IFMODStudioModule::Get().GetEventDescription(Event);
|
|
if (EventDesc != nullptr)
|
|
{
|
|
EventDesc->loadSampleData();
|
|
}
|
|
}
|
|
}
|
|
|
|
void UFMODBlueprintStatics::UnloadEventSampleData(UObject *WorldContextObject, class UFMODEvent *Event)
|
|
{
|
|
if (IsValid(Event))
|
|
{
|
|
FMOD::Studio::EventDescription *EventDesc = IFMODStudioModule::Get().GetEventDescription(Event);
|
|
if (EventDesc != nullptr)
|
|
{
|
|
EventDesc->unloadSampleData();
|
|
}
|
|
}
|
|
}
|
|
|
|
TArray<FFMODEventInstance> UFMODBlueprintStatics::FindEventInstances(UObject *WorldContextObject, UFMODEvent *Event)
|
|
{
|
|
TArray<FFMODEventInstance> Instances;
|
|
if (IsValid(Event))
|
|
{
|
|
FMOD::Studio::EventDescription *EventDesc = IFMODStudioModule::Get().GetEventDescription(Event);
|
|
if (EventDesc != nullptr)
|
|
{
|
|
int Capacity = 0;
|
|
EventDesc->getInstanceCount(&Capacity);
|
|
if (Capacity > 0)
|
|
{
|
|
TArray<FMOD::Studio::EventInstance *> InstancePointers;
|
|
InstancePointers.SetNum(Capacity, true);
|
|
int Count = 0;
|
|
EventDesc->getInstanceList(InstancePointers.GetData(), Capacity, &Count);
|
|
Instances.SetNum(Count, true);
|
|
for (int i = 0; i < Count; ++i)
|
|
{
|
|
Instances[i].Instance = InstancePointers[i];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return Instances;
|
|
}
|
|
|
|
void UFMODBlueprintStatics::BusSetVolume(class UFMODBus *Bus, float Volume)
|
|
{
|
|
FMOD::Studio::System *StudioSystem = IFMODStudioModule::Get().GetStudioSystem(EFMODSystemContext::Runtime);
|
|
if (StudioSystem != nullptr && IsValid(Bus))
|
|
{
|
|
FMOD::Studio::ID guid = FMODUtils::ConvertGuid(Bus->AssetGuid);
|
|
FMOD::Studio::Bus *bus = nullptr;
|
|
FMOD_RESULT result = StudioSystem->getBusByID(&guid, &bus);
|
|
if (result == FMOD_OK && bus != nullptr)
|
|
{
|
|
bus->setVolume(Volume);
|
|
}
|
|
}
|
|
}
|
|
|
|
void UFMODBlueprintStatics::BusSetPaused(class UFMODBus *Bus, bool bPaused)
|
|
{
|
|
FMOD::Studio::System *StudioSystem = IFMODStudioModule::Get().GetStudioSystem(EFMODSystemContext::Runtime);
|
|
if (StudioSystem != nullptr && IsValid(Bus))
|
|
{
|
|
FMOD::Studio::ID guid = FMODUtils::ConvertGuid(Bus->AssetGuid);
|
|
FMOD::Studio::Bus *bus = nullptr;
|
|
FMOD_RESULT result = StudioSystem->getBusByID(&guid, &bus);
|
|
if (result == FMOD_OK && bus != nullptr)
|
|
{
|
|
bus->setPaused(bPaused);
|
|
}
|
|
}
|
|
}
|
|
|
|
void UFMODBlueprintStatics::BusSetMute(class UFMODBus *Bus, bool bMute)
|
|
{
|
|
FMOD::Studio::System *StudioSystem = IFMODStudioModule::Get().GetStudioSystem(EFMODSystemContext::Runtime);
|
|
if (StudioSystem != nullptr && IsValid(Bus))
|
|
{
|
|
FMOD::Studio::ID guid = FMODUtils::ConvertGuid(Bus->AssetGuid);
|
|
FMOD::Studio::Bus *bus = nullptr;
|
|
FMOD_RESULT result = StudioSystem->getBusByID(&guid, &bus);
|
|
if (result == FMOD_OK && bus != nullptr)
|
|
{
|
|
bus->setMute(bMute);
|
|
}
|
|
}
|
|
}
|
|
|
|
void UFMODBlueprintStatics::BusStopAllEvents(UFMODBus *Bus, EFMOD_STUDIO_STOP_MODE stopMode)
|
|
{
|
|
FMOD::Studio::System *StudioSystem = IFMODStudioModule::Get().GetStudioSystem(EFMODSystemContext::Runtime);
|
|
if (StudioSystem != nullptr && IsValid(Bus))
|
|
{
|
|
FMOD::Studio::ID guid = FMODUtils::ConvertGuid(Bus->AssetGuid);
|
|
FMOD::Studio::Bus *bus = nullptr;
|
|
FMOD_RESULT result = StudioSystem->getBusByID(&guid, &bus);
|
|
if (result == FMOD_OK && bus != nullptr)
|
|
{
|
|
bus->stopAllEvents((FMOD_STUDIO_STOP_MODE)stopMode);
|
|
}
|
|
}
|
|
}
|
|
|
|
void UFMODBlueprintStatics::VCASetVolume(class UFMODVCA *Vca, float Volume)
|
|
{
|
|
FMOD::Studio::System *StudioSystem = IFMODStudioModule::Get().GetStudioSystem(EFMODSystemContext::Runtime);
|
|
if (StudioSystem != nullptr && IsValid(Vca))
|
|
{
|
|
FMOD::Studio::ID guid = FMODUtils::ConvertGuid(Vca->AssetGuid);
|
|
FMOD::Studio::VCA *vca = nullptr;
|
|
FMOD_RESULT result = StudioSystem->getVCAByID(&guid, &vca);
|
|
if (result == FMOD_OK && vca != nullptr)
|
|
{
|
|
vca->setVolume(Volume);
|
|
}
|
|
}
|
|
}
|
|
|
|
void UFMODBlueprintStatics::SetGlobalParameterByName(FName Name, float Value)
|
|
{
|
|
FMOD::Studio::System *StudioSystem = IFMODStudioModule::Get().GetStudioSystem(EFMODSystemContext::Runtime);
|
|
if (StudioSystem != nullptr)
|
|
{
|
|
FMOD_RESULT Result = StudioSystem->setParameterByName(TCHAR_TO_UTF8(*Name.ToString()), Value);
|
|
if (Result != FMOD_OK)
|
|
{
|
|
UE_LOG(LogFMOD, Warning, TEXT("Failed to set parameter %s"), *Name.ToString());
|
|
}
|
|
}
|
|
}
|
|
|
|
float UFMODBlueprintStatics::GetGlobalParameterByName(FName Name)
|
|
{
|
|
FMOD::Studio::System *StudioSystem = IFMODStudioModule::Get().GetStudioSystem(EFMODSystemContext::Runtime);
|
|
float Value = 0.0f;
|
|
if (StudioSystem != nullptr)
|
|
{
|
|
FMOD_RESULT Result = StudioSystem->getParameterByName(TCHAR_TO_UTF8(*Name.ToString()), &Value);
|
|
if (Result != FMOD_OK)
|
|
{
|
|
UE_LOG(LogFMOD, Warning, TEXT("Failed to get event instance parameter %s"), *Name.ToString());
|
|
}
|
|
}
|
|
return Value;
|
|
}
|
|
|
|
void UFMODBlueprintStatics::GetGlobalParameterValueByName(FName Name, float &UserValue, float &FinalValue)
|
|
{
|
|
FMOD::Studio::System *StudioSystem = IFMODStudioModule::Get().GetStudioSystem(EFMODSystemContext::Runtime);
|
|
if (StudioSystem != nullptr)
|
|
{
|
|
FMOD_RESULT Result = StudioSystem->getParameterByName(TCHAR_TO_UTF8(*Name.ToString()), &UserValue, &FinalValue);
|
|
if (Result != FMOD_OK)
|
|
{
|
|
UserValue = FinalValue = 0.0f;
|
|
UE_LOG(LogFMOD, Warning, TEXT("Failed to get event instance parameter %s"), *Name.ToString());
|
|
}
|
|
}
|
|
}
|
|
|
|
bool UFMODBlueprintStatics::EventInstanceIsValid(FFMODEventInstance EventInstance)
|
|
{
|
|
if (EventInstance.Instance)
|
|
{
|
|
return EventInstance.Instance->isValid();
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void UFMODBlueprintStatics::EventInstanceSetVolume(FFMODEventInstance EventInstance, float Volume)
|
|
{
|
|
if (EventInstance.Instance)
|
|
{
|
|
FMOD_RESULT Result = EventInstance.Instance->setVolume(Volume);
|
|
if (Result != FMOD_OK)
|
|
{
|
|
UE_LOG(LogFMOD, Warning, TEXT("Failed to set event instance volume"));
|
|
}
|
|
}
|
|
}
|
|
|
|
void UFMODBlueprintStatics::EventInstanceSetPitch(FFMODEventInstance EventInstance, float Pitch)
|
|
{
|
|
if (EventInstance.Instance)
|
|
{
|
|
FMOD_RESULT Result = EventInstance.Instance->setPitch(Pitch);
|
|
if (Result != FMOD_OK)
|
|
{
|
|
UE_LOG(LogFMOD, Warning, TEXT("Failed to set event instance pitch"));
|
|
}
|
|
}
|
|
}
|
|
|
|
void UFMODBlueprintStatics::EventInstanceSetPaused(FFMODEventInstance EventInstance, bool Paused)
|
|
{
|
|
if (EventInstance.Instance)
|
|
{
|
|
FMOD_RESULT Result = EventInstance.Instance->setPaused(Paused);
|
|
if (Result != FMOD_OK)
|
|
{
|
|
UE_LOG(LogFMOD, Warning, TEXT("Failed to pause event instance"));
|
|
}
|
|
}
|
|
}
|
|
|
|
void UFMODBlueprintStatics::EventInstanceSetParameter(FFMODEventInstance EventInstance, FName Name, float Value)
|
|
{
|
|
if (EventInstance.Instance)
|
|
{
|
|
FMOD_RESULT Result = EventInstance.Instance->setParameterByName(TCHAR_TO_UTF8(*Name.ToString()), Value);
|
|
if (Result != FMOD_OK)
|
|
{
|
|
UE_LOG(LogFMOD, Warning, TEXT("Failed to set event instance parameter %s"), *Name.ToString());
|
|
}
|
|
}
|
|
}
|
|
|
|
float UFMODBlueprintStatics::EventInstanceGetParameter(FFMODEventInstance EventInstance, FName Name)
|
|
{
|
|
float Value = 0.0f;
|
|
if (EventInstance.Instance)
|
|
{
|
|
FMOD_RESULT Result = EventInstance.Instance->getParameterByName(TCHAR_TO_UTF8(*Name.ToString()), &Value);
|
|
if (Result != FMOD_OK)
|
|
{
|
|
UE_LOG(LogFMOD, Warning, TEXT("Failed to get event instance parameter %s"), *Name.ToString());
|
|
}
|
|
}
|
|
return Value;
|
|
}
|
|
|
|
void UFMODBlueprintStatics::EventInstanceGetParameterValue(FFMODEventInstance EventInstance, FName Name, float &UserValue, float &FinalValue)
|
|
{
|
|
if (EventInstance.Instance)
|
|
{
|
|
FMOD_RESULT Result = EventInstance.Instance->getParameterByName(TCHAR_TO_UTF8(*Name.ToString()), &UserValue, &FinalValue);
|
|
if (Result != FMOD_OK)
|
|
{
|
|
UserValue = FinalValue = 0.0f;
|
|
UE_LOG(LogFMOD, Warning, TEXT("Failed to get event instance parameter %s"), *Name.ToString());
|
|
}
|
|
}
|
|
}
|
|
|
|
void UFMODBlueprintStatics::EventInstanceSetProperty(FFMODEventInstance EventInstance, EFMODEventProperty::Type Property, float Value)
|
|
{
|
|
if (EventInstance.Instance)
|
|
{
|
|
FMOD_RESULT Result = EventInstance.Instance->setProperty((FMOD_STUDIO_EVENT_PROPERTY)Property, Value);
|
|
|
|
if (Result != FMOD_OK)
|
|
{
|
|
UE_LOG(LogFMOD, Warning, TEXT("Failed to set event instance property type %d to value %f (%s)"), (int)Property, Value,
|
|
FMOD_ErrorString(Result));
|
|
}
|
|
}
|
|
}
|
|
|
|
void UFMODBlueprintStatics::EventInstancePlay(FFMODEventInstance EventInstance)
|
|
{
|
|
if (EventInstance.Instance)
|
|
{
|
|
FMOD_RESULT Result = EventInstance.Instance->start();
|
|
if (Result != FMOD_OK)
|
|
{
|
|
UE_LOG(LogFMOD, Warning, TEXT("Failed to play event instance"));
|
|
}
|
|
// Once we start playing, allow instance to be cleaned up when it finishes
|
|
EventInstance.Instance->release();
|
|
}
|
|
}
|
|
|
|
void UFMODBlueprintStatics::EventInstanceStop(FFMODEventInstance EventInstance, bool Release)
|
|
{
|
|
if (EventInstance.Instance)
|
|
{
|
|
FMOD_RESULT Result = EventInstance.Instance->stop(FMOD_STUDIO_STOP_ALLOWFADEOUT);
|
|
if (Result != FMOD_OK)
|
|
{
|
|
UE_LOG(LogFMOD, Warning, TEXT("Failed to stop event instance"));
|
|
}
|
|
else
|
|
{
|
|
if (Release)
|
|
{
|
|
EventInstanceRelease(EventInstance);
|
|
//EventInstance.Instance->release();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void UFMODBlueprintStatics::EventInstanceRelease(FFMODEventInstance EventInstance)
|
|
{
|
|
if (EventInstance.Instance)
|
|
{
|
|
FMOD_RESULT Result = EventInstance.Instance->release();
|
|
if (Result != FMOD_OK)
|
|
{
|
|
UE_LOG(LogFMOD, Warning, TEXT("Failed to release event instance"));
|
|
}
|
|
}
|
|
}
|
|
|
|
void UFMODBlueprintStatics::EventInstanceKeyOff(FFMODEventInstance EventInstance)
|
|
{
|
|
if (EventInstance.Instance)
|
|
{
|
|
EventInstance.Instance->keyOff();
|
|
}
|
|
}
|
|
|
|
void UFMODBlueprintStatics::EventInstanceSetTransform(FFMODEventInstance EventInstance, const FTransform &Location)
|
|
{
|
|
if (EventInstance.Instance)
|
|
{
|
|
FMOD_3D_ATTRIBUTES attr = { { 0 } };
|
|
FMODUtils::Assign(attr, Location);
|
|
FMOD_RESULT Result = EventInstance.Instance->set3DAttributes(&attr);
|
|
if (Result != FMOD_OK)
|
|
{
|
|
UE_LOG(LogFMOD, Warning, TEXT("Failed to set transform on event instance"));
|
|
}
|
|
}
|
|
}
|
|
|
|
TArray<FString> UFMODBlueprintStatics::GetOutputDrivers()
|
|
{
|
|
TArray<FString> AllNames;
|
|
|
|
FMOD::Studio::System *StudioSystem = IFMODStudioModule::Get().GetStudioSystem(EFMODSystemContext::Runtime);
|
|
if (StudioSystem != nullptr)
|
|
{
|
|
FMOD::System *LowLevelSystem = nullptr;
|
|
verifyfmod(StudioSystem->getCoreSystem(&LowLevelSystem));
|
|
|
|
int DriverCount = 0;
|
|
verifyfmod(LowLevelSystem->getNumDrivers(&DriverCount));
|
|
|
|
for (int id = 0; id < DriverCount; ++id)
|
|
{
|
|
char DriverNameUTF8[256] = {};
|
|
verifyfmod(LowLevelSystem->getDriverInfo(id, DriverNameUTF8, sizeof(DriverNameUTF8), 0, 0, 0, 0));
|
|
FString DriverName(UTF8_TO_TCHAR(DriverNameUTF8));
|
|
AllNames.Add(DriverName);
|
|
}
|
|
}
|
|
|
|
return AllNames;
|
|
}
|
|
|
|
void UFMODBlueprintStatics::SetOutputDriverByName(FString NewDriverName)
|
|
{
|
|
FMOD::Studio::System *StudioSystem = IFMODStudioModule::Get().GetStudioSystem(EFMODSystemContext::Runtime);
|
|
if (StudioSystem != nullptr)
|
|
{
|
|
FMOD::System *LowLevelSystem = nullptr;
|
|
verifyfmod(StudioSystem->getCoreSystem(&LowLevelSystem));
|
|
|
|
int DriverIndex = -1;
|
|
int DriverCount = 0;
|
|
verifyfmod(LowLevelSystem->getNumDrivers(&DriverCount));
|
|
|
|
for (int id = 0; id < DriverCount; ++id)
|
|
{
|
|
char DriverNameUTF8[256] = {};
|
|
verifyfmod(LowLevelSystem->getDriverInfo(id, DriverNameUTF8, sizeof(DriverNameUTF8), 0, 0, 0, 0));
|
|
FString DriverName(UTF8_TO_TCHAR(DriverNameUTF8));
|
|
UE_LOG(LogFMOD, Log, TEXT("Driver %d: %s"), id, *DriverName);
|
|
if (DriverName.Contains(NewDriverName))
|
|
{
|
|
DriverIndex = id;
|
|
}
|
|
}
|
|
|
|
if (DriverIndex >= 0)
|
|
{
|
|
UE_LOG(LogFMOD, Log, TEXT("Selected driver %d"), DriverIndex);
|
|
verifyfmod(LowLevelSystem->setDriver(DriverIndex));
|
|
}
|
|
else
|
|
{
|
|
UE_LOG(LogFMOD, Warning, TEXT("Did not find driver of name '%s'"), *NewDriverName);
|
|
}
|
|
}
|
|
}
|
|
|
|
void UFMODBlueprintStatics::SetOutputDriverByIndex(int NewDriverIndex)
|
|
{
|
|
FMOD::Studio::System *StudioSystem = IFMODStudioModule::Get().GetStudioSystem(EFMODSystemContext::Runtime);
|
|
if (StudioSystem != nullptr)
|
|
{
|
|
FMOD::System *LowLevelSystem = nullptr;
|
|
verifyfmod(StudioSystem->getCoreSystem(&LowLevelSystem));
|
|
|
|
int DriverCount = 0;
|
|
verifyfmod(LowLevelSystem->getNumDrivers(&DriverCount));
|
|
|
|
if (NewDriverIndex >= 0 && NewDriverIndex < DriverCount)
|
|
{
|
|
UE_LOG(LogFMOD, Log, TEXT("Selected driver %d"), NewDriverIndex);
|
|
verifyfmod(LowLevelSystem->setDriver(NewDriverIndex));
|
|
}
|
|
else
|
|
{
|
|
UE_LOG(LogFMOD, Warning, TEXT("Driver %d out of range"), NewDriverIndex);
|
|
}
|
|
}
|
|
}
|
|
|
|
void UFMODBlueprintStatics::MixerSuspend()
|
|
{
|
|
UE_LOG(LogFMOD, Log, TEXT("MixerSuspend called"));
|
|
FMOD::Studio::System *StudioSystem = IFMODStudioModule::Get().GetStudioSystem(EFMODSystemContext::Runtime);
|
|
if (StudioSystem != nullptr)
|
|
{
|
|
FMOD::System *LowLevelSystem = nullptr;
|
|
verifyfmod(StudioSystem->getCoreSystem(&LowLevelSystem));
|
|
|
|
verifyfmod(LowLevelSystem->mixerSuspend());
|
|
}
|
|
}
|
|
|
|
void UFMODBlueprintStatics::MixerResume()
|
|
{
|
|
UE_LOG(LogFMOD, Log, TEXT("MixerResume called"));
|
|
FMOD::Studio::System *StudioSystem = IFMODStudioModule::Get().GetStudioSystem(EFMODSystemContext::Runtime);
|
|
if (StudioSystem != nullptr)
|
|
{
|
|
FMOD::System *LowLevelSystem = nullptr;
|
|
verifyfmod(StudioSystem->getCoreSystem(&LowLevelSystem));
|
|
|
|
verifyfmod(LowLevelSystem->mixerResume());
|
|
}
|
|
}
|
|
|
|
void UFMODBlueprintStatics::SetLocale(const FString& Locale)
|
|
{
|
|
IFMODStudioModule::Get().SetLocale(Locale);
|
|
}
|