newly updated FMODStudio plugin for UE5.3 migration
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#pragma once
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#pragma once
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#pragma once
|
||||
|
||||
@ -139,6 +139,7 @@ class FMODSTUDIO_API UFMODAudioComponent : public USceneComponent
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
friend struct FFMODEventControlExecutionToken;
|
||||
friend struct FPlayingToken;
|
||||
friend FMOD_RESULT F_CALLBACK UFMODAudioComponent_EventCallback(FMOD_STUDIO_EVENT_CALLBACK_TYPE type, FMOD_STUDIO_EVENTINSTANCE *event, void *parameters);
|
||||
|
||||
public:
|
||||
@ -223,6 +224,10 @@ public:
|
||||
UFUNCTION(BlueprintCallable, Category = "Audio|FMOD|Components")
|
||||
void SetPaused(bool paused);
|
||||
|
||||
/** Get the paused state of the audio component. Returns false if internal getPaused query fails. */
|
||||
UFUNCTION(BlueprintCallable, Category = "Audio|FMOD|Components")
|
||||
bool GetPaused();
|
||||
|
||||
/** Set a parameter of the Event. */
|
||||
UFUNCTION(BlueprintCallable, Category = "Audio|FMOD|Components")
|
||||
void SetParameter(FName Name, float Value);
|
||||
@ -279,36 +284,67 @@ public:
|
||||
/** Actual Studio instance handle. */
|
||||
FMOD::Studio::EventInstance *StudioInstance;
|
||||
|
||||
// Begin UObject interface.
|
||||
// Begin UObject interface.
|
||||
#if WITH_EDITOR
|
||||
virtual void PostEditChangeProperty(FPropertyChangedEvent &e) override;
|
||||
#endif // WITH_EDITOR
|
||||
virtual void PostLoad() override;
|
||||
// End UObject interface.
|
||||
// End UObject interface.
|
||||
|
||||
// Begin USceneComponent Interface
|
||||
// Begin USceneComponent Interface
|
||||
virtual void Activate(bool bReset = false) override;
|
||||
virtual void Deactivate() override;
|
||||
// End USceneComponent Interface
|
||||
/** Called when a component is registered, after Scene is set, but before CreateRenderState_Concurrent or OnCreatePhysicsState are called. */
|
||||
virtual void OnRegister() override;
|
||||
/** Called when a component is unregistered. Called after DestroyRenderState_Concurrent and OnDestroyPhysicsState are called. */
|
||||
virtual void OnUnregister() override;
|
||||
// End USceneComponent Interface
|
||||
|
||||
// Begin ActorComponent interface.
|
||||
/** Overridable native event for when play begins for this actor. */
|
||||
virtual void BeginPlay() override;
|
||||
/** Overridable function called whenever this actor is being removed from a level. */
|
||||
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
|
||||
/** Function called every frame on this ActorComponent. Only executes if the component is registered, and also PrimaryComponentTick.bCanEverTick must be set to true. */
|
||||
virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
|
||||
// End ActorComponent interface.
|
||||
|
||||
protected:
|
||||
// Begin UObject interface.
|
||||
// Begin UObject interface.
|
||||
virtual void OnUpdateTransform(EUpdateTransformFlags UpdateTransformFlags, ETeleportType Teleport = ETeleportType::None) override;
|
||||
// End UObject interface.
|
||||
// End UObject interface.
|
||||
|
||||
// Begin USceneComponent Interface
|
||||
// Begin USceneComponent Interface
|
||||
virtual FString GetDetailedInfoInternal() const override;
|
||||
// End USceneComponent Interface
|
||||
// End USceneComponent Interface
|
||||
|
||||
private:
|
||||
bool bDefaultParameterValuesCached;
|
||||
|
||||
enum PauseContext
|
||||
{
|
||||
Explicit,
|
||||
Implicit
|
||||
};
|
||||
|
||||
/** Used for pausing from sequencer. */
|
||||
bool bImplicitlyPaused = false;
|
||||
|
||||
/** Used for pausing from a direct call to pause. */
|
||||
bool bExplicitlyPaused = false;
|
||||
|
||||
/** Stored properties to apply next time we create an instance. */
|
||||
float StoredProperties[EFMODEventProperty::Count];
|
||||
|
||||
/** Internal play function which can play events in the editor. */
|
||||
void PlayInternal(EFMODSystemContext::Type Context, bool bReset = false);
|
||||
|
||||
/** Pause the audio component from a sequencer call. */
|
||||
void PauseInternal(PauseContext Pauser);
|
||||
|
||||
/** Resume the audio component from a sequencer call. */
|
||||
void ResumeInternal(PauseContext Pauser);
|
||||
|
||||
/** Cache default event parameter values. */
|
||||
void CacheDefaultParameterValues();
|
||||
|
||||
@ -342,24 +378,15 @@ private:
|
||||
void EventCallbackSoundStopped();
|
||||
bool TriggerSoundStoppedDelegate;
|
||||
|
||||
// Begin ActorComponent interface.
|
||||
/** Called when a component is registered, after Scene is set, but before CreateRenderState_Concurrent or OnCreatePhysicsState are called. */
|
||||
virtual void OnRegister() override;
|
||||
|
||||
/** Called when a component is unregistered. Called after DestroyRenderState_Concurrent and OnDestroyPhysicsState are called. */
|
||||
virtual void OnUnregister() override;
|
||||
|
||||
/** Overridable function called whenever this actor is being removed from a level. */
|
||||
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
|
||||
|
||||
/** Function called every frame on this ActorComponent. Only executes if the component is registered, and also PrimaryComponentTick.bCanEverTick must be set to true. */
|
||||
virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override;
|
||||
// End ActorComponent interface.
|
||||
|
||||
#if WITH_EDITORONLY_DATA
|
||||
void UpdateSpriteTexture();
|
||||
#endif
|
||||
|
||||
#if WITH_EDITOR
|
||||
/** Function assigned to the FMODStudioModule PreShutdown delegate to clean up before the Studio System is released. */
|
||||
void Shutdown();
|
||||
#endif
|
||||
|
||||
/** Release any cached parameters then the Studio Instance. */
|
||||
void ReleaseEventCache();
|
||||
|
||||
@ -422,4 +449,10 @@ private:
|
||||
bool NeedDestroyProgrammerSoundCallback;
|
||||
/** The length of the current Event in milliseconds. */
|
||||
int32 EventLength;
|
||||
|
||||
/** To prevent restarting by delayed state restore from sequencer. */
|
||||
bool bPlayEnded;
|
||||
|
||||
FVector Velocity;
|
||||
FVector LastLocation;
|
||||
};
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#pragma once
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#pragma once
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#pragma once
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#pragma once
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#pragma once
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#pragma once
|
||||
|
||||
@ -232,7 +232,7 @@ public:
|
||||
/**
|
||||
* Enable live update in Editor for Auditioning. *Requires Restart*
|
||||
*/
|
||||
UPROPERTY(Config, EditAnywhere, Category = Basic)
|
||||
UPROPERTY(Config, EditAnywhere, Category = Basic, meta = (ConfigRestartRequired = true))
|
||||
bool bEnableEditorLiveUpdate;
|
||||
|
||||
/**
|
||||
@ -258,13 +258,7 @@ public:
|
||||
TArray<FFMODProjectLocale> Locales;
|
||||
|
||||
/**
|
||||
* Whether to enable vol0virtual, which means voices with low volume will automatically go virtual to save CPU.
|
||||
*/
|
||||
UPROPERTY(config, EditAnywhere, Category = InitSettings)
|
||||
bool bVol0Virtual;
|
||||
|
||||
/**
|
||||
* If vol0virtual is enabled, the signal level at which to make channels virtual.
|
||||
* The signal level at which channels are virtualized. Virtual channels are processed, but do not produce any output.
|
||||
*/
|
||||
UPROPERTY(config, EditAnywhere, Category = InitSettings)
|
||||
float Vol0VirtualLevel;
|
||||
@ -348,7 +342,7 @@ public:
|
||||
/**
|
||||
* Live update port to use while in editor for auditioning. *Requires Restart*
|
||||
*/
|
||||
UPROPERTY(config, EditAnywhere, Category = Advanced, meta = (EditCondition = "bEnableEditorLiveUpdate"))
|
||||
UPROPERTY(config, EditAnywhere, Category = Advanced, meta = (EditCondition = "bEnableEditorLiveUpdate", ConfigRestartRequired = true))
|
||||
int32 EditorLiveUpdatePort;
|
||||
|
||||
/**
|
||||
@ -439,6 +433,12 @@ public:
|
||||
UPROPERTY(config, EditAnywhere, Category = Advanced)
|
||||
FString AmbientLPFParameter;
|
||||
|
||||
/**
|
||||
* Enables/Disables the FMODAudioLink modules.
|
||||
*/
|
||||
UPROPERTY(config, EditAnywhere, Category = Advanced, meta = (ConfigRestartRequired=true))
|
||||
bool bFMODAudioLinkEnabled;
|
||||
|
||||
/*
|
||||
* Used to specify platform specific settings.
|
||||
*/
|
||||
@ -505,5 +505,7 @@ private:
|
||||
};
|
||||
|
||||
EProblem Check() const;
|
||||
|
||||
virtual void PostEditChangeProperty(FPropertyChangedEvent& e) override;
|
||||
#endif // WITH_EDITOR
|
||||
};
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#pragma once
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#pragma once
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#pragma once
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
using UnrealBuildTool;
|
||||
using System;
|
||||
using System.IO;
|
||||
@ -229,6 +229,9 @@ namespace UnrealBuildTool.Rules
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FMODAudioLink.Apply(this, Target);
|
||||
FMODAudioLinkEditor.Apply(this, Target);
|
||||
}
|
||||
|
||||
private System.Collections.Generic.List<string> GetPlugins(string BasePath)
|
||||
@ -255,5 +258,18 @@ namespace UnrealBuildTool.Rules
|
||||
}
|
||||
return AllPlugins;
|
||||
}
|
||||
|
||||
public void AddModule(string Module, bool AddPublic = true)
|
||||
{
|
||||
ConditionalAddModuleDirectory(
|
||||
EpicGames.Core.DirectoryReference.Combine(new EpicGames.Core.DirectoryReference(ModuleDirectory), "..", Module));
|
||||
|
||||
ExternalDependencies.Add(Path.Combine(ModuleDirectory, "..", Module, Module + ".Build.cs"));
|
||||
if (AddPublic)
|
||||
{
|
||||
PublicIncludePaths.Add(Path.Combine(ModuleDirectory, "..", Module, "Public"));
|
||||
}
|
||||
PrivateIncludePaths.Add(Path.Combine(ModuleDirectory, "..", Module, "Private"));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#include "FMODAmbientSound.h"
|
||||
#include "FMODEvent.h"
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#include "FMODAsset.h"
|
||||
#include "FMODStudioModule.h"
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#include "FMODAssetTable.h"
|
||||
|
||||
@ -20,7 +20,8 @@
|
||||
#include "UObject/Package.h"
|
||||
|
||||
FFMODAssetTable::FFMODAssetTable()
|
||||
: BankLookup(nullptr),
|
||||
: ActiveLocale(FString()),
|
||||
BankLookup(nullptr),
|
||||
AssetLookup(nullptr)
|
||||
{
|
||||
}
|
||||
@ -56,17 +57,16 @@ void FFMODAssetTable::Load()
|
||||
}
|
||||
else
|
||||
{
|
||||
TCHAR msg[] = TEXT("Failed to load bank lookup");
|
||||
if (IsRunningCommandlet())
|
||||
{
|
||||
// If we're running in a commandlet (maybe we're cooking or running FMODGenerateAssets
|
||||
// commandlet) Display a message but don't cause the build to Error out.
|
||||
UE_LOG(LogFMOD, Display, msg);
|
||||
UE_LOG(LogFMOD, Display, TEXT("Failed to load bank lookup"));
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we're running in game or in editor, log this as an Error
|
||||
UE_LOG(LogFMOD, Error, msg);
|
||||
UE_LOG(LogFMOD, Error, TEXT("Failed to load bank lookup"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -81,17 +81,16 @@ void FFMODAssetTable::Load()
|
||||
}
|
||||
else
|
||||
{
|
||||
TCHAR msg[] = TEXT("Failed to load asset lookup");
|
||||
if (IsRunningCommandlet())
|
||||
{
|
||||
// If we're running in a commandlet (maybe we're cooking or running FMODGenerateAssets
|
||||
// commandlet) Display a message but don't cause the build to Error out.
|
||||
UE_LOG(LogFMOD, Display, msg);
|
||||
UE_LOG(LogFMOD, Display, TEXT("Failed to load asset lookup"));
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we're running in game or in editor, log this as an Error
|
||||
UE_LOG(LogFMOD, Error, msg);
|
||||
UE_LOG(LogFMOD, Error, TEXT("Failed to load asset lookup"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#pragma once
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#include "FMODAudioComponent.h"
|
||||
#include "FMODStudioModule.h"
|
||||
@ -43,6 +43,9 @@ UFMODAudioComponent::UFMODAudioComponent(const FObjectInitializer &ObjectInitial
|
||||
, ProgrammerSound(nullptr)
|
||||
, NeedDestroyProgrammerSoundCallback(false)
|
||||
, EventLength(0)
|
||||
, bPlayEnded(false)
|
||||
, Velocity(ForceInit)
|
||||
, LastLocation(ForceInit)
|
||||
{
|
||||
bAutoActivate = true;
|
||||
bNeverNeedsRenderUpdate = true;
|
||||
@ -160,7 +163,7 @@ void UFMODAudioComponent::OnUpdateTransform(EUpdateTransformFlags UpdateTransfor
|
||||
attr.position = FMODUtils::ConvertWorldVector(GetComponentTransform().GetLocation());
|
||||
attr.up = FMODUtils::ConvertUnitVector(GetComponentTransform().GetUnitAxis(EAxis::Z));
|
||||
attr.forward = FMODUtils::ConvertUnitVector(GetComponentTransform().GetUnitAxis(EAxis::X));
|
||||
attr.velocity = FMODUtils::ConvertWorldVector(GetOwner()->GetVelocity());
|
||||
attr.velocity = FMODUtils::ConvertWorldVector(Velocity);
|
||||
|
||||
StudioInstance->set3DAttributes(&attr);
|
||||
|
||||
@ -185,7 +188,7 @@ void UFMODAudioComponent::UpdateInteriorVolumes()
|
||||
|
||||
FInteriorSettings *Ambient =
|
||||
(FInteriorSettings *)alloca(sizeof(FInteriorSettings)); // FinteriorSetting::FInteriorSettings() isn't exposed (possible UE4 bug???)
|
||||
const FVector &Location = GetOwner()->GetTransform().GetTranslation();
|
||||
const FVector &Location = GetComponentLocation();
|
||||
AAudioVolume *AudioVolume = GetWorld()->GetAudioSettings(Location, NULL, Ambient);
|
||||
|
||||
const FFMODListener &Listener = GetStudioModule().GetNearestListener(Location);
|
||||
@ -275,7 +278,7 @@ void UFMODAudioComponent::UpdateAttenuation()
|
||||
static FName NAME_SoundOcclusion = FName(TEXT("SoundOcclusion"));
|
||||
FCollisionQueryParams Params(NAME_SoundOcclusion, OcclusionDetails.bUseComplexCollisionForOcclusion, GetOwner());
|
||||
|
||||
const FVector &Location = GetOwner()->GetTransform().GetTranslation();
|
||||
const FVector &Location = GetComponentLocation();
|
||||
const FFMODListener &Listener = GetStudioModule().GetNearestListener(Location);
|
||||
|
||||
bool bIsOccluded = GWorld->LineTraceTestByChannel(Location, Listener.Transform.GetLocation(), OcclusionDetails.OcclusionTraceChannel, Params);
|
||||
@ -340,7 +343,7 @@ void UFMODAudioComponent::CacheDefaultParameterValues()
|
||||
Event->GetParameterDescriptions(ParameterDescriptions);
|
||||
for (const FMOD_STUDIO_PARAMETER_DESCRIPTION &ParameterDescription : ParameterDescriptions)
|
||||
{
|
||||
if (ShouldCacheParameter(ParameterDescription))
|
||||
if (!ParameterCache.Find(ParameterDescription.name) && ShouldCacheParameter(ParameterDescription))
|
||||
{
|
||||
ParameterCache.Add(ParameterDescription.name, ParameterDescription.defaultvalue);
|
||||
}
|
||||
@ -377,8 +380,19 @@ void UFMODAudioComponent::OnUnregister()
|
||||
Super::OnUnregister();
|
||||
}
|
||||
|
||||
void UFMODAudioComponent::BeginPlay()
|
||||
{
|
||||
#if WITH_EDITOR
|
||||
IFMODStudioModule::Get().PreEndPIEEvent().AddUObject(this, &UFMODAudioComponent::Shutdown);
|
||||
#endif
|
||||
Super::BeginPlay();
|
||||
}
|
||||
|
||||
void UFMODAudioComponent::EndPlay(const EEndPlayReason::Type EndPlayReason)
|
||||
{
|
||||
#if WITH_EDITOR
|
||||
IFMODStudioModule::Get().PreEndPIEEvent().RemoveAll(this);
|
||||
#endif
|
||||
Super::EndPlay(EndPlayReason);
|
||||
bool shouldStop = false;
|
||||
|
||||
@ -407,12 +421,24 @@ void UFMODAudioComponent::EndPlay(const EEndPlayReason::Type EndPlayReason)
|
||||
OnEventStopped.Broadcast();
|
||||
}
|
||||
Release();
|
||||
|
||||
bPlayEnded = true;
|
||||
}
|
||||
|
||||
void UFMODAudioComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction)
|
||||
{
|
||||
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
|
||||
|
||||
if (DeltaTime > 0.f)
|
||||
{
|
||||
FVector pos = GetComponentTransform().GetTranslation();
|
||||
if (LastLocation != FVector::ZeroVector)
|
||||
{
|
||||
Velocity = (pos - LastLocation) / DeltaTime;
|
||||
}
|
||||
LastLocation = pos;
|
||||
}
|
||||
|
||||
if (IsActive())
|
||||
{
|
||||
FMOD_STUDIO_PLAYBACK_STATE state = FMOD_STUDIO_PLAYBACK_STOPPED;
|
||||
@ -709,7 +735,8 @@ void UFMODAudioComponent::PlayInternal(EFMODSystemContext::Type Context, bool bR
|
||||
{
|
||||
Stop();
|
||||
|
||||
if (!FMODUtils::IsWorldAudible(GetWorld(), Context == EFMODSystemContext::Editor))
|
||||
if (!FMODUtils::IsWorldAudible(GetWorld(), Context == EFMODSystemContext::Editor
|
||||
|| Context == EFMODSystemContext::Auditioning))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -802,6 +829,37 @@ void UFMODAudioComponent::PlayInternal(EFMODSystemContext::Type Context, bool bR
|
||||
}
|
||||
}
|
||||
|
||||
void UFMODAudioComponent::PauseInternal(PauseContext Pauser)
|
||||
{
|
||||
if (Pauser == Implicit)
|
||||
{
|
||||
bImplicitlyPaused = true;
|
||||
}
|
||||
if (Pauser == Explicit)
|
||||
{
|
||||
bExplicitlyPaused = true;
|
||||
}
|
||||
|
||||
SetPaused(true);
|
||||
}
|
||||
|
||||
void UFMODAudioComponent::ResumeInternal(PauseContext Pauser)
|
||||
{
|
||||
if (GetPaused())
|
||||
{
|
||||
if (Pauser == Implicit)
|
||||
{
|
||||
bImplicitlyPaused = false;
|
||||
}
|
||||
if (Pauser == Explicit)
|
||||
{
|
||||
bExplicitlyPaused = false;
|
||||
}
|
||||
|
||||
SetPaused(bImplicitlyPaused || bExplicitlyPaused);
|
||||
}
|
||||
}
|
||||
|
||||
void UFMODAudioComponent::Stop()
|
||||
{
|
||||
UE_LOG(LogFMOD, Verbose, TEXT("UFMODAudioComponent %p Stop"), this);
|
||||
@ -818,6 +876,14 @@ void UFMODAudioComponent::Release()
|
||||
ReleaseEventInstance();
|
||||
}
|
||||
|
||||
#if WITH_EDITOR
|
||||
void UFMODAudioComponent::Shutdown()
|
||||
{
|
||||
Stop();
|
||||
Release();
|
||||
}
|
||||
#endif
|
||||
|
||||
void UFMODAudioComponent::ReleaseEventCache()
|
||||
{
|
||||
ParameterCache.Empty();
|
||||
@ -917,6 +983,20 @@ void UFMODAudioComponent::SetPaused(bool Paused)
|
||||
}
|
||||
}
|
||||
|
||||
bool UFMODAudioComponent::GetPaused()
|
||||
{
|
||||
bool Paused = false;
|
||||
if (StudioInstance)
|
||||
{
|
||||
FMOD_RESULT Result = StudioInstance->getPaused(&Paused);
|
||||
if (Result != FMOD_OK)
|
||||
{
|
||||
UE_LOG(LogFMOD, Warning, TEXT("Failed to get paused state"));
|
||||
}
|
||||
}
|
||||
return Paused;
|
||||
}
|
||||
|
||||
void UFMODAudioComponent::SetParameter(FName Name, float Value)
|
||||
{
|
||||
if (StudioInstance)
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#include "FMODBank.h"
|
||||
#include "FMODStudioModule.h"
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#include "FMODBlueprintStatics.h"
|
||||
#include "FMODAudioComponent.h"
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#include "FMODBus.h"
|
||||
#include "FMODStudioModule.h"
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#include "FMODEvent.h"
|
||||
#include "FMODStudioModule.h"
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#pragma once
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#include "FMODListener.h"
|
||||
#include "Misc/App.h"
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#pragma once
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
#pragma once
|
||||
|
||||
#include "Containers/UnrealString.h"
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#include "FMODPort.h"
|
||||
#include "FMODStudioModule.h"
|
||||
|
@ -1,10 +1,11 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#include "FMODSettings.h"
|
||||
#include "Misc/Paths.h"
|
||||
|
||||
#if WITH_EDITOR
|
||||
#include "Settings/ProjectPackagingSettings.h"
|
||||
#include <ObjectTools.h>
|
||||
#endif
|
||||
|
||||
#ifdef FMOD_PLATFORM_HEADER
|
||||
@ -43,7 +44,6 @@ UFMODSettings::UFMODSettings(const FObjectInitializer &ObjectInitializer)
|
||||
, bEnableEditorLiveUpdate(false)
|
||||
, OutputFormat(EFMODSpeakerMode::Surround_5_1)
|
||||
, OutputType(EFMODOutput::TYPE_AUTODETECT)
|
||||
, bVol0Virtual(true)
|
||||
, Vol0VirtualLevel(0.001f)
|
||||
, SampleRate(0)
|
||||
, bMatchHardwareSampleRate(true)
|
||||
@ -62,6 +62,7 @@ UFMODSettings::UFMODSettings(const FObjectInitializer &ObjectInitializer)
|
||||
, ContentBrowserPrefix(TEXT("/Game/FMOD/"))
|
||||
, MasterBankName(TEXT("Master"))
|
||||
, LoggingLevel(LEVEL_WARNING)
|
||||
, bFMODAudioLinkEnabled(false)
|
||||
{
|
||||
BankOutputDirectory.Path = TEXT("FMOD");
|
||||
}
|
||||
@ -187,6 +188,56 @@ UFMODSettings::EProblem UFMODSettings::Check() const
|
||||
|
||||
return Okay;
|
||||
}
|
||||
|
||||
void UFMODSettings::PostEditChangeProperty(FPropertyChangedEvent& e)
|
||||
{
|
||||
FName PropertyName = (e.Property != NULL) ? e.Property->GetFName() : NAME_None;
|
||||
// Validate ContentBrowserPrefix, as Unreal can crash if the prefix is improperly configured
|
||||
if (PropertyName == GET_MEMBER_NAME_CHECKED(UFMODSettings, ContentBrowserPrefix))
|
||||
{
|
||||
FStrProperty* prop = CastField<FStrProperty>(e.Property);
|
||||
void* propertyAddress = e.Property->ContainerPtrToValuePtr<void>(this);
|
||||
FString contentBrowserPrefix = prop->GetPropertyValue(propertyAddress);
|
||||
|
||||
// Check for empty prefix
|
||||
if (contentBrowserPrefix.IsEmpty()) {
|
||||
contentBrowserPrefix = "/";
|
||||
}
|
||||
else {
|
||||
|
||||
// FName's max length is 1023, but FMOD needs to append additional directories
|
||||
// 512 is an arbitary length that should cover most prefix lengths
|
||||
const int ContentBrowserPrefixMaxLength = 512;
|
||||
|
||||
// Ensure that length doesn't exceed max prefix length
|
||||
if (contentBrowserPrefix.Len() > ContentBrowserPrefixMaxLength) {
|
||||
contentBrowserPrefix.LeftChopInline(ContentBrowserPrefixMaxLength);
|
||||
}
|
||||
|
||||
// Remove invalid long package characters
|
||||
contentBrowserPrefix = ObjectTools::SanitizeInvalidChars(contentBrowserPrefix, INVALID_LONGPACKAGE_CHARACTERS);
|
||||
|
||||
// Remove double slashes
|
||||
int32 index = contentBrowserPrefix.Find(FString("//"));
|
||||
while (index != INDEX_NONE) {
|
||||
contentBrowserPrefix.RemoveAt(index);
|
||||
index = contentBrowserPrefix.Find(FString("//"));
|
||||
}
|
||||
|
||||
// Check for starting and ending with slash
|
||||
if (!contentBrowserPrefix.StartsWith("/")) {
|
||||
contentBrowserPrefix = "/" + contentBrowserPrefix;
|
||||
}
|
||||
if (!contentBrowserPrefix.EndsWith("/")) {
|
||||
contentBrowserPrefix += "/";
|
||||
}
|
||||
}
|
||||
|
||||
prop->SetPropertyValue(propertyAddress, contentBrowserPrefix);
|
||||
|
||||
}
|
||||
Super::PostEditChangeProperty(e);
|
||||
}
|
||||
#endif // WITH_EDITOR
|
||||
|
||||
EFMODSpeakerMode::Type UFMODSettings::GetSpeakerMode() const
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#include "FMODSnapshot.h"
|
||||
#include "FMODStudioModule.h"
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#include "FMODSnapshotReverb.h"
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#include "FMODStudioModule.h"
|
||||
#include "FMODSettings.h"
|
||||
@ -11,6 +11,11 @@
|
||||
#include "FMODListener.h"
|
||||
#include "FMODSnapshotReverb.h"
|
||||
|
||||
#include "FMODAudioLinkModule.h"
|
||||
#if WITH_EDITOR
|
||||
#include "FMODAudioLinkEditorModule.h"
|
||||
#endif
|
||||
|
||||
#include "Async/Async.h"
|
||||
#include "Interfaces/IPluginManager.h"
|
||||
#include "Misc/App.h"
|
||||
@ -149,6 +154,10 @@ public:
|
||||
|
||||
class FFMODStudioModule : public IFMODStudioModule
|
||||
{
|
||||
TUniquePtr<FFMODAudioLinkModule> FMODAudioLinkModule;
|
||||
#if WITH_EDITOR
|
||||
TUniquePtr<FFMODAudioLinkEditorModule> FMODAudioLinkEditorModule;
|
||||
#endif
|
||||
public:
|
||||
/** IModuleInterface implementation */
|
||||
FFMODStudioModule()
|
||||
@ -178,10 +187,6 @@ public:
|
||||
|
||||
void HandleApplicationHasReactivated()
|
||||
{
|
||||
#if PLATFORM_IOS || PLATFORM_TVOS
|
||||
ActivateAudioSession();
|
||||
#endif
|
||||
|
||||
AsyncTask(ENamedThreads::GameThread, [&]() { SetSystemPaused(false); });
|
||||
}
|
||||
|
||||
@ -197,7 +202,12 @@ public:
|
||||
void UnloadBanks(EFMODSystemContext::Type Type);
|
||||
|
||||
#if WITH_EDITOR
|
||||
FSimpleMulticastDelegate PreEndPIEDelegate;
|
||||
FSimpleMulticastDelegate &PreEndPIEEvent() override { return PreEndPIEDelegate; };
|
||||
virtual void PreEndPIE() override;
|
||||
void ReloadBanks();
|
||||
void LoadEditorBanks();
|
||||
void UnloadEditorBanks();
|
||||
#endif
|
||||
|
||||
void CreateStudioSystem(EFMODSystemContext::Type Type);
|
||||
@ -220,8 +230,6 @@ public:
|
||||
|
||||
virtual bool HasListenerMoved() override;
|
||||
|
||||
virtual void RefreshSettings();
|
||||
|
||||
virtual void SetSystemPaused(bool paused) override;
|
||||
|
||||
virtual void SetInPIE(bool bInPIE, bool simulating) override;
|
||||
@ -255,11 +263,12 @@ public:
|
||||
|
||||
virtual FString GetLocale() override;
|
||||
|
||||
virtual FString GetDefaultLocale() override;
|
||||
|
||||
void ResetInterpolation();
|
||||
|
||||
#if PLATFORM_IOS || PLATFORM_TVOS
|
||||
void InitializeAudioSession();
|
||||
void ActivateAudioSession();
|
||||
#endif
|
||||
|
||||
/** The studio system handle. */
|
||||
@ -497,10 +506,10 @@ void FFMODStudioModule::StartupModule()
|
||||
|
||||
AcquireFMODFileSystem();
|
||||
|
||||
RefreshSettings();
|
||||
|
||||
if (GIsEditor)
|
||||
{
|
||||
AssetTable.Load();
|
||||
AssetTable.SetLocale(GetDefaultLocale());
|
||||
CreateStudioSystem(EFMODSystemContext::Auditioning);
|
||||
CreateStudioSystem(EFMODSystemContext::Editor);
|
||||
}
|
||||
@ -508,6 +517,18 @@ void FFMODStudioModule::StartupModule()
|
||||
{
|
||||
SetInPIE(true, false);
|
||||
}
|
||||
|
||||
// Load AudioLink module
|
||||
bool bFMODAudioLinkEnabled = Settings.bFMODAudioLinkEnabled;
|
||||
if (bFMODAudioLinkEnabled)
|
||||
{
|
||||
UE_LOG(LogFMOD, Log, TEXT("FFMODAudioLinkModule startup"));
|
||||
FMODAudioLinkModule = MakeUnique<FFMODAudioLinkModule>();
|
||||
#if WITH_EDITOR
|
||||
UE_LOG(LogFMOD, Log, TEXT("FFMODAudioLinkEditorModule startup"));
|
||||
FMODAudioLinkEditorModule = MakeUnique<FFMODAudioLinkEditorModule>();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
OnTick = FTickerDelegate::CreateRaw(this, &FFMODStudioModule::Tick);
|
||||
@ -679,11 +700,7 @@ void FFMODStudioModule::CreateStudioSystem(EFMODSystemContext::Type Type)
|
||||
|
||||
FMOD_ADVANCEDSETTINGS advSettings = { 0 };
|
||||
advSettings.cbSize = sizeof(FMOD_ADVANCEDSETTINGS);
|
||||
if (Settings.bVol0Virtual)
|
||||
{
|
||||
advSettings.vol0virtualvol = Settings.Vol0VirtualLevel;
|
||||
InitFlags |= FMOD_INIT_VOL0_BECOMES_VIRTUAL;
|
||||
}
|
||||
advSettings.vol0virtualvol = Settings.Vol0VirtualLevel;
|
||||
|
||||
if (!Settings.SetCodecs(advSettings))
|
||||
{
|
||||
@ -776,10 +793,13 @@ void FFMODStudioModule::DestroyStudioSystem(EFMODSystemContext::Type Type)
|
||||
ClockSinks[Type].Reset();
|
||||
}
|
||||
|
||||
UnloadBanks(Type);
|
||||
|
||||
if (StudioSystem[Type])
|
||||
{
|
||||
FMOD::Studio::Bus* mBus;
|
||||
StudioSystem[Type]->getBus("bus:/", &mBus);
|
||||
mBus->setMute(true);
|
||||
StudioSystem[Type]->flushCommands();
|
||||
|
||||
verifyfmod(StudioSystem[Type]->release());
|
||||
StudioSystem[Type] = nullptr;
|
||||
}
|
||||
@ -1007,19 +1027,19 @@ void FFMODStudioModule::FinishSetListenerPosition(int NumListeners)
|
||||
}
|
||||
|
||||
// Apply a reverb snapshot from the listener position(s)
|
||||
AAudioVolume *BestVolume = nullptr;
|
||||
TWeakObjectPtr<AAudioVolume> BestVolume = nullptr;
|
||||
for (int i = 0; i < ListenerCount; ++i)
|
||||
{
|
||||
AAudioVolume *CandidateVolume = Listeners[i].Volume;
|
||||
|
||||
if (BestVolume == nullptr || (IsValid(CandidateVolume) && IsValid(BestVolume) && CandidateVolume->GetPriority() > BestVolume->GetPriority()))
|
||||
if (BestVolume == nullptr || (IsValid(CandidateVolume) && BestVolume.IsValid() && CandidateVolume->GetPriority() > BestVolume->GetPriority()))
|
||||
{
|
||||
BestVolume = CandidateVolume;
|
||||
}
|
||||
}
|
||||
UFMODSnapshotReverb *NewSnapshot = nullptr;
|
||||
|
||||
if (IsValid(BestVolume) && BestVolume->GetReverbSettings().bApplyReverb)
|
||||
if (BestVolume.IsValid() && BestVolume->GetReverbSettings().bApplyReverb)
|
||||
{
|
||||
NewSnapshot = Cast<UFMODSnapshotReverb>(BestVolume->GetReverbSettings().ReverbEffect);
|
||||
}
|
||||
@ -1097,12 +1117,6 @@ void FFMODStudioModule::FinishSetListenerPosition(int NumListeners)
|
||||
}
|
||||
}
|
||||
|
||||
void FFMODStudioModule::RefreshSettings()
|
||||
{
|
||||
AssetTable.Load();
|
||||
AssetTable.SetLocale(GetLocale());
|
||||
}
|
||||
|
||||
void FFMODStudioModule::SetInPIE(bool bInPIE, bool simulating)
|
||||
{
|
||||
bIsInPIE = bInPIE;
|
||||
@ -1129,6 +1143,9 @@ void FFMODStudioModule::SetInPIE(bool bInPIE, bool simulating)
|
||||
// TODO: Stop sounds for the Editor system? What should happen if the user previews a sequence with transport
|
||||
// controls then starts a PIE session? What does happen?
|
||||
|
||||
AssetTable.Load();
|
||||
AssetTable.SetLocale(GetDefaultLocale());
|
||||
|
||||
ListenerCount = 1;
|
||||
CreateStudioSystem(EFMODSystemContext::Runtime);
|
||||
LoadBanks(EFMODSystemContext::Runtime);
|
||||
@ -1205,6 +1222,17 @@ void FFMODStudioModule::SetSystemPaused(bool paused)
|
||||
}
|
||||
}
|
||||
|
||||
#if WITH_EDITOR
|
||||
void FFMODStudioModule::PreEndPIE()
|
||||
{
|
||||
UE_LOG(LogFMOD, Verbose, TEXT("PreEndPIE"));
|
||||
if (PreEndPIEDelegate.IsBound())
|
||||
{
|
||||
PreEndPIEDelegate.Broadcast();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void FFMODStudioModule::ShutdownModule()
|
||||
{
|
||||
UE_LOG(LogFMOD, Verbose, TEXT("FFMODStudioModule shutdown"));
|
||||
@ -1213,6 +1241,17 @@ void FFMODStudioModule::ShutdownModule()
|
||||
DestroyStudioSystem(EFMODSystemContext::Runtime);
|
||||
DestroyStudioSystem(EFMODSystemContext::Editor);
|
||||
|
||||
if (FMODAudioLinkModule)
|
||||
{
|
||||
FMODAudioLinkModule.Reset();
|
||||
}
|
||||
#if WITH_EDITOR
|
||||
if (FMODAudioLinkEditorModule)
|
||||
{
|
||||
FMODAudioLinkEditorModule.Reset();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (StudioLibHandle && LowLevelLibHandle)
|
||||
{
|
||||
ReleaseFMODFileSystem();
|
||||
@ -1282,6 +1321,11 @@ bool FFMODStudioModule::SetLocale(const FString& LocaleName)
|
||||
}
|
||||
|
||||
FString FFMODStudioModule::GetLocale()
|
||||
{
|
||||
return AssetTable.GetLocale();
|
||||
}
|
||||
|
||||
FString FFMODStudioModule::GetDefaultLocale()
|
||||
{
|
||||
FString LocaleCode = "";
|
||||
const UFMODSettings& Settings = *GetDefault<UFMODSettings>();
|
||||
@ -1456,11 +1500,21 @@ void FFMODStudioModule::ReloadBanks()
|
||||
UnloadBanks(EFMODSystemContext::Auditioning);
|
||||
DestroyStudioSystem(EFMODSystemContext::Editor);
|
||||
|
||||
RefreshSettings();
|
||||
AssetTable.Load();
|
||||
|
||||
LoadBanks(EFMODSystemContext::Auditioning);
|
||||
CreateStudioSystem(EFMODSystemContext::Editor);
|
||||
}
|
||||
|
||||
void FFMODStudioModule::LoadEditorBanks()
|
||||
{
|
||||
LoadBanks(EFMODSystemContext::Editor);
|
||||
}
|
||||
|
||||
void FFMODStudioModule::UnloadEditorBanks()
|
||||
{
|
||||
UnloadBanks(EFMODSystemContext::Editor);
|
||||
}
|
||||
#endif
|
||||
|
||||
FMOD::Studio::System *FFMODStudioModule::GetStudioSystem(EFMODSystemContext::Type Context)
|
||||
@ -1518,57 +1572,120 @@ void FFMODStudioModule::StopAuditioningInstance()
|
||||
}
|
||||
|
||||
#if PLATFORM_IOS || PLATFORM_TVOS
|
||||
static bool gIsSuspended = false;
|
||||
static bool gNeedsReset = false;
|
||||
|
||||
void FFMODStudioModule::InitializeAudioSession()
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] addObserverForName:AVAudioSessionInterruptionNotification object:nil queue:nil usingBlock:^(NSNotification *notification)
|
||||
{
|
||||
switch ([[notification.userInfo valueForKey:AVAudioSessionInterruptionTypeKey] unsignedIntegerValue])
|
||||
AVAudioSessionInterruptionType type = (AVAudioSessionInterruptionType)[[notification.userInfo valueForKey:AVAudioSessionInterruptionTypeKey] unsignedIntegerValue];
|
||||
if (type == AVAudioSessionInterruptionTypeBegan)
|
||||
{
|
||||
case AVAudioSessionInterruptionTypeBegan:
|
||||
UE_LOG(LogFMOD, Log, TEXT("Interruption Began"));
|
||||
// Ignore deprecated warnings regarding AVAudioSessionInterruptionReasonAppWasSuspended and
|
||||
// AVAudioSessionInterruptionWasSuspendedKey, we protect usage for the versions where they are available
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
|
||||
// If the audio session was deactivated while the app was in the background, the app receives the
|
||||
// notification when relaunched. Identify this reason for interruption and ignore it.
|
||||
if (@available(iOS 16.0, tvOS 14.5, *))
|
||||
{
|
||||
if (@available(iOS 10.3, *))
|
||||
// Delayed suspend-in-background notifications no longer exist, this must be a real interruption
|
||||
}
|
||||
#if !PLATFORM_TVOS // tvOS never supported "AVAudioSessionInterruptionReasonAppWasSuspended"
|
||||
else if (@available(iOS 14.5, *))
|
||||
{
|
||||
if ([[notification.userInfo valueForKey:AVAudioSessionInterruptionReasonKey] intValue] == AVAudioSessionInterruptionReasonAppWasSuspended)
|
||||
{
|
||||
if ([[notification.userInfo valueForKey:AVAudioSessionInterruptionWasSuspendedKey] boolValue])
|
||||
{
|
||||
// If the system suspended the app process and deactivated the audio session then we get a delayed
|
||||
// interruption notification when the app is re-activated. Just ignore that here.
|
||||
return;
|
||||
}
|
||||
return; // Ignore delayed suspend-in-background notification
|
||||
}
|
||||
SetSystemPaused(true);
|
||||
break;
|
||||
}
|
||||
case AVAudioSessionInterruptionTypeEnded:
|
||||
#endif
|
||||
else
|
||||
{
|
||||
ActivateAudioSession();
|
||||
SetSystemPaused(false);
|
||||
break;
|
||||
if ([[notification.userInfo valueForKey:AVAudioSessionInterruptionWasSuspendedKey] boolValue])
|
||||
{
|
||||
return; // Ignore delayed suspend-in-background notification
|
||||
}
|
||||
}
|
||||
|
||||
SetSystemPaused(true);
|
||||
gIsSuspended = true;
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
else if (type == AVAudioSessionInterruptionTypeEnded)
|
||||
{
|
||||
UE_LOG(LogFMOD, Log, TEXT("Interruption Ended"));
|
||||
NSError *ActiveError = nil;
|
||||
if (![[AVAudioSession sharedInstance] setActive:TRUE error:&ActiveError])
|
||||
{
|
||||
// Interruption like Siri can prevent session activation, wait for did-become-active notification
|
||||
UE_LOG(LogFMOD, Error, TEXT("Failed to set audio session to active = %d [Error = %s]"), TRUE, *FString([ActiveError description]));
|
||||
return;
|
||||
}
|
||||
|
||||
SetSystemPaused(false);
|
||||
gIsSuspended = false;
|
||||
}
|
||||
}];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidBecomeActiveNotification object:nil queue:nil usingBlock:^(NSNotification *notification)
|
||||
{
|
||||
#if PLATFORM_TVOS
|
||||
SetSystemPaused(true);
|
||||
#endif
|
||||
ActivateAudioSession();
|
||||
SetSystemPaused(false);
|
||||
// If the Media Services were reset while we were in the background we need to reset
|
||||
// To reset we need to suspend so that we can resume.
|
||||
if (gNeedsReset)
|
||||
{
|
||||
SetSystemPaused(true);
|
||||
gIsSuspended = true;
|
||||
}
|
||||
|
||||
NSError *ActiveError = nil;
|
||||
if (![[AVAudioSession sharedInstance] setActive:TRUE error:&ActiveError])
|
||||
{
|
||||
if ([ActiveError code] == AVAudioSessionErrorCodeCannotStartPlaying)
|
||||
{
|
||||
// Interruption like Screen Time can prevent session activation, but will not trigger an interruption-ended notification.
|
||||
// There is no other callback or trigger to hook into after this point, we are not in the background and there is no other audio playing.
|
||||
// Our only option is to have a sleep loop until the Audio Session can be activated again.
|
||||
while (![[AVAudioSession sharedInstance] setActive:TRUE error:nil])
|
||||
{
|
||||
FPlatformProcess::Sleep(0.02f);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Interruption like Siri can prevent session activation, wait for interruption-ended notification.
|
||||
UE_LOG(LogFMOD, Warning, TEXT("UIApplicationDidBecomeActiveNotification: Failed to set audio session to active = %d [Error = %s]"), TRUE, *FString([ActiveError description]));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// It's possible the system missed sending us an interruption end, so recover here
|
||||
if (gIsSuspended)
|
||||
{
|
||||
SetSystemPaused(false);
|
||||
gNeedsReset = false;
|
||||
gIsSuspended = false;
|
||||
}
|
||||
}];
|
||||
|
||||
ActivateAudioSession();
|
||||
}
|
||||
|
||||
void FFMODStudioModule::ActivateAudioSession()
|
||||
{
|
||||
NSError* ActiveError = nil;
|
||||
[[AVAudioSession sharedInstance] setActive:TRUE error:&ActiveError];
|
||||
|
||||
if (ActiveError)
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserverForName:AVAudioSessionMediaServicesWereResetNotification object:nil queue:nil usingBlock:^(NSNotification *notification)
|
||||
{
|
||||
UE_LOG(LogFMOD, Error, TEXT("Failed to set audio session to active = %d [Error = %s]"), TRUE, *FString([ActiveError description]));
|
||||
}
|
||||
if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground || gIsSuspended)
|
||||
{
|
||||
// Received the reset notification while in the background, need to reset the AudioUnit when we come back to foreground.
|
||||
gNeedsReset = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// In the foregound but something chopped the media services, need to do a reset.
|
||||
SetSystemPaused(true);
|
||||
SetSystemPaused(false);
|
||||
}
|
||||
}];
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#include "FMODVCA.h"
|
||||
#include "FMODStudioModule.h"
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#include "FMODEventControlSection.h"
|
||||
#include "Channels/MovieSceneChannelProxy.h"
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#pragma once
|
||||
|
||||
@ -15,7 +15,8 @@ UENUM()
|
||||
enum class EFMODEventControlKey : uint8
|
||||
{
|
||||
Stop = 0,
|
||||
Play = 1
|
||||
Play = 1,
|
||||
Pause = 2
|
||||
};
|
||||
|
||||
USTRUCT()
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#include "FMODEventControlSectionTemplate.h"
|
||||
#include "FMODAmbientSound.h"
|
||||
@ -6,30 +6,62 @@
|
||||
#include "Evaluation/MovieSceneEvaluation.h"
|
||||
#include "IMovieScenePlayer.h"
|
||||
|
||||
enum EventControlKeyInternal
|
||||
{
|
||||
Stop,
|
||||
Play,
|
||||
Pause,
|
||||
SequencePause,
|
||||
SequenceResume,
|
||||
MAX
|
||||
};
|
||||
|
||||
EventControlKeyInternal MapControlKey(EFMODEventControlKey key)
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case EFMODEventControlKey::Stop:
|
||||
return EventControlKeyInternal::Stop;
|
||||
break;
|
||||
case EFMODEventControlKey::Play:
|
||||
return EventControlKeyInternal::Play;
|
||||
break;
|
||||
case EFMODEventControlKey::Pause:
|
||||
return EventControlKeyInternal::Pause;
|
||||
break;
|
||||
default:
|
||||
return EventControlKeyInternal::MAX;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
struct FPlayingToken : IMovieScenePreAnimatedToken
|
||||
{
|
||||
FPlayingToken(UObject &InObject)
|
||||
{
|
||||
bPlaying = false;
|
||||
TimelinePosition = 0;
|
||||
|
||||
if (UFMODAudioComponent *AudioComponent = Cast<UFMODAudioComponent>(&InObject))
|
||||
{
|
||||
if (IsValid(AudioComponent))
|
||||
{
|
||||
bPlaying = AudioComponent->IsPlaying();
|
||||
TimelinePosition = AudioComponent->GetTimelinePosition();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void RestoreState(UObject &Object, const UE::MovieScene::FRestoreStateParams& Params) override
|
||||
virtual void RestoreState(UObject &Object, const UE::MovieScene::FRestoreStateParams &Params) override
|
||||
{
|
||||
UFMODAudioComponent *AudioComponent = CastChecked<UFMODAudioComponent>(&Object);
|
||||
|
||||
if (AudioComponent)
|
||||
{
|
||||
if (bPlaying)
|
||||
if (bPlaying && !AudioComponent->bPlayEnded)
|
||||
{
|
||||
AudioComponent->Play();
|
||||
AudioComponent->SetTimelinePosition(TimelinePosition);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -40,6 +72,7 @@ struct FPlayingToken : IMovieScenePreAnimatedToken
|
||||
|
||||
private:
|
||||
bool bPlaying;
|
||||
int32 TimelinePosition;
|
||||
};
|
||||
|
||||
struct FPlayingTokenProducer : IMovieScenePreAnimatedTokenProducer
|
||||
@ -50,15 +83,9 @@ private:
|
||||
virtual IMovieScenePreAnimatedTokenPtr CacheExistingState(UObject &Object) const override { return FPlayingToken(Object); }
|
||||
};
|
||||
|
||||
struct FFMODEventKeyState : IPersistentEvaluationData
|
||||
{
|
||||
FKeyHandle LastKeyHandle;
|
||||
FKeyHandle InvalidKeyHandle;
|
||||
};
|
||||
|
||||
struct FFMODEventControlExecutionToken : IMovieSceneExecutionToken
|
||||
{
|
||||
FFMODEventControlExecutionToken(EFMODEventControlKey InEventControlKey, FFrameTime InKeyTime)
|
||||
FFMODEventControlExecutionToken(EventControlKeyInternal InEventControlKey, FFrameTime InKeyTime)
|
||||
: EventControlKey(InEventControlKey)
|
||||
, KeyTime(InKeyTime)
|
||||
{
|
||||
@ -80,45 +107,119 @@ struct FFMODEventControlExecutionToken : IMovieSceneExecutionToken
|
||||
|
||||
if (IsValid(AudioComponent))
|
||||
{
|
||||
Player.SavePreAnimatedState(*AudioComponent, FPlayingTokenProducer::GetAnimTypeID(), FPlayingTokenProducer());
|
||||
EFMODSystemContext::Type SystemContext =
|
||||
(GWorld && GWorld->WorldType == EWorldType::Editor) ? EFMODSystemContext::Editor : EFMODSystemContext::Runtime;
|
||||
|
||||
if (EventControlKey == EFMODEventControlKey::Play)
|
||||
if (EventControlKey == EventControlKeyInternal::Stop && KeyTime == 0 && SystemContext == EFMODSystemContext::Editor)
|
||||
{
|
||||
if (AudioComponent->IsPlaying())
|
||||
{
|
||||
AudioComponent->Stop();
|
||||
}
|
||||
|
||||
EFMODSystemContext::Type SystemContext =
|
||||
(GWorld && GWorld->WorldType == EWorldType::Editor) ? EFMODSystemContext::Editor : EFMODSystemContext::Runtime;
|
||||
AudioComponent->PlayInternal(SystemContext);
|
||||
// Skip state saving when auditioning sequencer
|
||||
}
|
||||
else if (EventControlKey == EFMODEventControlKey::Stop)
|
||||
else
|
||||
{
|
||||
Player.SavePreAnimatedState(*AudioComponent, FPlayingTokenProducer::GetAnimTypeID(), FPlayingTokenProducer());
|
||||
}
|
||||
|
||||
if (EventControlKey == EventControlKeyInternal::Play)
|
||||
{
|
||||
if (AudioComponent->GetPaused())
|
||||
{
|
||||
AudioComponent->ResumeInternal(UFMODAudioComponent::PauseContext::Explicit);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (AudioComponent->IsPlaying())
|
||||
{
|
||||
AudioComponent->Stop();
|
||||
}
|
||||
AudioComponent->PlayInternal(SystemContext);
|
||||
}
|
||||
}
|
||||
else if (EventControlKey == EventControlKeyInternal::Stop)
|
||||
{
|
||||
AudioComponent->Stop();
|
||||
}
|
||||
else if (EventControlKey == EventControlKeyInternal::Pause)
|
||||
{
|
||||
AudioComponent->PauseInternal(UFMODAudioComponent::PauseContext::Explicit);
|
||||
}
|
||||
else if (EventControlKey == EventControlKeyInternal::SequencePause)
|
||||
{
|
||||
AudioComponent->PauseInternal(UFMODAudioComponent::PauseContext::Implicit);
|
||||
}
|
||||
else if (EventControlKey == EventControlKeyInternal::SequenceResume)
|
||||
{
|
||||
AudioComponent->ResumeInternal(UFMODAudioComponent::PauseContext::Implicit);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EFMODEventControlKey EventControlKey;
|
||||
EventControlKeyInternal EventControlKey;
|
||||
FFrameTime KeyTime;
|
||||
};
|
||||
|
||||
static bool RuntimeSequenceSetup = false;
|
||||
|
||||
FFMODEventControlSectionTemplate::FFMODEventControlSectionTemplate(const UFMODEventControlSection &Section)
|
||||
: ControlKeys(Section.ControlKeys)
|
||||
{
|
||||
EnableOverrides(FMovieSceneEvalTemplateBase::EOverrideMask::RequiresSetupFlag);
|
||||
EnableOverrides(FMovieSceneEvalTemplateBase::EOverrideMask::RequiresTearDownFlag);
|
||||
}
|
||||
|
||||
void FFMODEventControlSectionTemplate::Setup(FPersistentEvaluationData &PersistentData, IMovieScenePlayer &Player) const
|
||||
{
|
||||
IsEditorSequence = GWorld && GWorld->WorldType == EWorldType::Editor;
|
||||
if (!IsEditorSequence)
|
||||
{
|
||||
RuntimeSequenceSetup = true;
|
||||
}
|
||||
#if WITH_EDITOR
|
||||
if (!RuntimeSequenceSetup)
|
||||
{
|
||||
IFMODStudioModule::Get().LoadEditorBanks();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void FFMODEventControlSectionTemplate::TearDown(FPersistentEvaluationData &PersistentData, IMovieScenePlayer &Player) const
|
||||
{
|
||||
if (!IsEditorSequence)
|
||||
{
|
||||
RuntimeSequenceSetup = false;
|
||||
}
|
||||
#if WITH_EDITOR
|
||||
if (!RuntimeSequenceSetup)
|
||||
{
|
||||
IFMODStudioModule::Get().UnloadEditorBanks();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void FFMODEventControlSectionTemplate::Evaluate(const FMovieSceneEvaluationOperand &Operand, const FMovieSceneContext &Context,
|
||||
const FPersistentEvaluationData &PersistentData, FMovieSceneExecutionTokens &ExecutionTokens) const
|
||||
{
|
||||
if (IsEditorSequence && RuntimeSequenceSetup)
|
||||
{
|
||||
// If the Sequence Editor is open during PIE, it will also try to play its Sequence.
|
||||
// Don't let it, otherwise Execution Tokens will be double-issued.
|
||||
return;
|
||||
}
|
||||
|
||||
const bool bPlaying = Context.IsSilent() == false && Context.GetDirection() == EPlayDirection::Forwards &&
|
||||
Context.GetRange().Size<FFrameTime>() >= FFrameTime(0) && Context.GetStatus() == EMovieScenePlayerStatus::Playing;
|
||||
|
||||
if (!bPlaying)
|
||||
if (!bPlaying && IsEditorSequence && !RuntimeSequenceSetup)
|
||||
{
|
||||
ExecutionTokens.Add(FFMODEventControlExecutionToken(EFMODEventControlKey::Stop, FFrameTime(0)));
|
||||
if (Context.GetStatus() == EMovieScenePlayerStatus::Paused)
|
||||
{
|
||||
ExecutionTokens.Add(FFMODEventControlExecutionToken(EventControlKeyInternal::Pause, FFrameTime(0)));
|
||||
}
|
||||
else
|
||||
{
|
||||
ExecutionTokens.Add(FFMODEventControlExecutionToken(EventControlKeyInternal::Stop, FFrameTime(0)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -132,8 +233,18 @@ void FFMODEventControlSectionTemplate::Evaluate(const FMovieSceneEvaluationOpera
|
||||
const int32 LastKeyIndex = Algo::UpperBound(Times, PlaybackRange.GetUpperBoundValue()) - 1;
|
||||
if (LastKeyIndex >= 0 && PlaybackRange.Contains(Times[LastKeyIndex]))
|
||||
{
|
||||
FFMODEventControlExecutionToken NewToken((EFMODEventControlKey)Values[LastKeyIndex], Times[LastKeyIndex]);
|
||||
FFMODEventControlExecutionToken NewToken(MapControlKey((EFMODEventControlKey)Values[LastKeyIndex]), Times[LastKeyIndex]);
|
||||
ExecutionTokens.Add(MoveTemp(NewToken));
|
||||
}
|
||||
}
|
||||
|
||||
// Handle direct pause/unpause calls on sequence
|
||||
if (Context.GetStatus() == EMovieScenePlayerStatus::Stopped)
|
||||
{
|
||||
ExecutionTokens.Add(FFMODEventControlExecutionToken(EventControlKeyInternal::SequencePause, FFrameTime(0)));
|
||||
}
|
||||
else
|
||||
{
|
||||
ExecutionTokens.Add(FFMODEventControlExecutionToken(EventControlKeyInternal::SequenceResume, FFrameTime(0)));
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#pragma once
|
||||
|
||||
@ -21,6 +21,10 @@ struct FFMODEventControlSectionTemplate : public FMovieSceneEvalTemplate
|
||||
|
||||
private:
|
||||
virtual UScriptStruct &GetScriptStructImpl() const override { return *StaticStruct(); }
|
||||
virtual void Setup(FPersistentEvaluationData &PersistentData, IMovieScenePlayer &Player) const override;
|
||||
virtual void TearDown(FPersistentEvaluationData &PersistentData, IMovieScenePlayer &Player) const override;
|
||||
virtual void Evaluate(const FMovieSceneEvaluationOperand &Operand, const FMovieSceneContext &Context,
|
||||
const FPersistentEvaluationData &PersistentData, FMovieSceneExecutionTokens &ExecutionTokens) const override;
|
||||
};
|
||||
|
||||
mutable bool IsEditorSequence;
|
||||
};
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#include "FMODEventControlTrack.h"
|
||||
#include "FMODEventControlSection.h"
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#pragma once
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#pragma once
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#include "FMODEventParameterTrack.h"
|
||||
#include "FMODEventParameterSectionTemplate.h"
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#pragma once
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* ======================================================================================== */
|
||||
/* FMOD Core API - C header file. */
|
||||
/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2023. */
|
||||
/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2024. */
|
||||
/* */
|
||||
/* Use this header in conjunction with fmod_common.h (which contains all the constants / */
|
||||
/* callbacks) to develop using the C interface */
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* ======================================================================================== */
|
||||
/* FMOD Core API - C++ header file. */
|
||||
/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2023. */
|
||||
/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2024. */
|
||||
/* */
|
||||
/* Use this header in conjunction with fmod_common.h (which contains all the constants / */
|
||||
/* callbacks) to develop using the C++ language. */
|
||||
|
@ -1 +1,7 @@
|
||||
/* Placeholder */
|
||||
#pragma once
|
||||
|
||||
#include "fmod_common.h"
|
||||
#include <jni.h>
|
||||
|
||||
extern "C" FMOD_RESULT F_API FMOD_Android_JNI_Init(JavaVM *vm, jobject javaActivity);
|
||||
extern "C" FMOD_RESULT F_API FMOD_Android_JNI_Close();
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* ======================================================================================== */
|
||||
/* FMOD Core API - Codec development header file. */
|
||||
/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2023. */
|
||||
/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2024. */
|
||||
/* */
|
||||
/* Use this header if you are wanting to develop your own file format plugin to use with */
|
||||
/* FMOD's codec system. With this header you can make your own fileformat plugin that FMOD */
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* ======================================================================================== */
|
||||
/* FMOD Core API - Common C/C++ header file. */
|
||||
/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2023. */
|
||||
/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2024. */
|
||||
/* */
|
||||
/* This header is included by fmod.hpp (C++ interface) and fmod.h (C interface) */
|
||||
/* */
|
||||
@ -56,7 +56,7 @@ typedef struct FMOD_ASYNCREADINFO FMOD_ASYNCREADINFO;
|
||||
/*
|
||||
FMOD constants
|
||||
*/
|
||||
#define FMOD_VERSION 0x00020214 /* 0xaaaabbcc -> aaaa = product version, bb = major version, cc = minor version.*/
|
||||
#define FMOD_VERSION 0x00020226 /* 0xaaaabbcc -> aaaa = product version, bb = major version, cc = minor version.*/
|
||||
|
||||
typedef unsigned int FMOD_DEBUG_FLAGS;
|
||||
#define FMOD_DEBUG_LEVEL_NONE 0x00000000
|
||||
@ -439,6 +439,7 @@ typedef enum FMOD_OUTPUTTYPE
|
||||
FMOD_OUTPUTTYPE_AAUDIO,
|
||||
FMOD_OUTPUTTYPE_AUDIOWORKLET,
|
||||
FMOD_OUTPUTTYPE_PHASE,
|
||||
FMOD_OUTPUTTYPE_OHAUDIO,
|
||||
|
||||
FMOD_OUTPUTTYPE_MAX,
|
||||
FMOD_OUTPUTTYPE_FORCEINT = 65536
|
||||
@ -795,6 +796,7 @@ typedef struct FMOD_ADVANCEDSETTINGS
|
||||
unsigned int randomSeed;
|
||||
int maxConvolutionThreads;
|
||||
int maxOpusCodecs;
|
||||
int maxSpatialObjects;
|
||||
} FMOD_ADVANCEDSETTINGS;
|
||||
|
||||
typedef struct FMOD_TAG
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* ======================================================================================== */
|
||||
/* FMOD Core API - DSP header file. */
|
||||
/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2023. */
|
||||
/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2024. */
|
||||
/* */
|
||||
/* Use this header if you are wanting to develop your own DSP plugin to use with FMODs */
|
||||
/* dsp system. With this header you can make your own DSP plugin that FMOD can */
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* ============================================================================================================= */
|
||||
/* FMOD Core API - Built-in effects header file. */
|
||||
/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2023. */
|
||||
/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2024. */
|
||||
/* */
|
||||
/* In this header you can find parameter structures for FMOD system registered DSP effects */
|
||||
/* and generators. */
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* ============================================================================================== */
|
||||
/* FMOD Core / Studio API - Error string header file. */
|
||||
/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2023. */
|
||||
/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2024. */
|
||||
/* */
|
||||
/* Use this header if you want to store or display a string version / english explanation */
|
||||
/* of the FMOD error codes. */
|
||||
@ -49,7 +49,7 @@ static const char *FMOD_ErrorString(FMOD_RESULT errcode)
|
||||
case FMOD_ERR_HTTP_TIMEOUT: return "The HTTP request timed out.";
|
||||
case FMOD_ERR_INITIALIZATION: return "FMOD was not initialized correctly to support this function.";
|
||||
case FMOD_ERR_INITIALIZED: return "Cannot call this command after System::init.";
|
||||
case FMOD_ERR_INTERNAL: return "An error occurred that wasn't supposed to. Contact support.";
|
||||
case FMOD_ERR_INTERNAL: return "An error occured in the FMOD system. Use the logging version of FMOD for more information.";
|
||||
case FMOD_ERR_INVALID_FLOAT: return "Value passed in was a NaN, Inf or denormalized float.";
|
||||
case FMOD_ERR_INVALID_HANDLE: return "An invalid object handle was used.";
|
||||
case FMOD_ERR_INVALID_PARAM: return "An invalid parameter was passed to this function.";
|
||||
@ -87,7 +87,7 @@ static const char *FMOD_ErrorString(FMOD_RESULT errcode)
|
||||
case FMOD_ERR_TAGNOTFOUND: return "The specified tag could not be found or there are no tags.";
|
||||
case FMOD_ERR_TOOMANYCHANNELS: return "The sound created exceeds the allowable input channel count. This can be increased using the 'maxinputchannels' parameter in System::setSoftwareFormat.";
|
||||
case FMOD_ERR_TRUNCATED: return "The retrieved string is too long to fit in the supplied buffer and has been truncated.";
|
||||
case FMOD_ERR_UNIMPLEMENTED: return "Something in FMOD hasn't been implemented when it should be! contact support!";
|
||||
case FMOD_ERR_UNIMPLEMENTED: return "Something in FMOD hasn't been implemented when it should be. Contact support.";
|
||||
case FMOD_ERR_UNINITIALIZED: return "This command failed because System::init or System::setDriver was not called.";
|
||||
case FMOD_ERR_UNSUPPORTED: return "A command issued was not supported by this object. Possibly a plugin without certain callbacks specified.";
|
||||
case FMOD_ERR_VERSION: return "The version number of this file format is not supported.";
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* ======================================================================================== */
|
||||
/* FMOD Core API - output development header file. */
|
||||
/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2023. */
|
||||
/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2024. */
|
||||
/* */
|
||||
/* Use this header if you are wanting to develop your own output plugin to use with */
|
||||
/* FMOD's output system. With this header you can make your own output plugin that FMOD */
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* ======================================================================================== */
|
||||
/* FMOD Studio API - C header file. */
|
||||
/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2023. */
|
||||
/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2024. */
|
||||
/* */
|
||||
/* Use this header in conjunction with fmod_studio_common.h (which contains all the */
|
||||
/* constants / callbacks) to develop using the C language. */
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* ======================================================================================== */
|
||||
/* FMOD Studio API - C++ header file. */
|
||||
/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2023. */
|
||||
/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2024. */
|
||||
/* */
|
||||
/* Use this header in conjunction with fmod_studio_common.h (which contains all the */
|
||||
/* constants / callbacks) to develop using the C++ language. */
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* ======================================================================================== */
|
||||
/* FMOD Studio API - Common C/C++ header file. */
|
||||
/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2023. */
|
||||
/* Copyright (c), Firelight Technologies Pty, Ltd. 2004-2024. */
|
||||
/* */
|
||||
/* This header defines common enumerations, structs and callbacks that are shared between */
|
||||
/* the C and C++ interfaces. */
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#pragma once
|
||||
|
||||
@ -72,11 +72,6 @@ public:
|
||||
*/
|
||||
virtual void SetSystemPaused(bool paused) = 0;
|
||||
|
||||
/**
|
||||
* Called when user changes any studio settings
|
||||
*/
|
||||
virtual void RefreshSettings() = 0;
|
||||
|
||||
/**
|
||||
* Called when we enter of leave PIE mode
|
||||
*/
|
||||
@ -163,12 +158,25 @@ public:
|
||||
/** Set active locale. Locale must be the locale name of one of the configured project locales */
|
||||
virtual bool SetLocale(const FString& Locale) = 0;
|
||||
|
||||
/** Get ative locale. */
|
||||
/** Get active locale. */
|
||||
virtual FString GetLocale() = 0;
|
||||
|
||||
/** Get default locale. */
|
||||
virtual FString GetDefaultLocale() = 0;
|
||||
|
||||
#if WITH_EDITOR
|
||||
/** Multicast delegate that is triggered before the module is shutdown. */
|
||||
virtual FSimpleMulticastDelegate &PreEndPIEEvent() = 0;
|
||||
|
||||
virtual void PreEndPIE() = 0;
|
||||
|
||||
/** Called by the editor module when banks have been modified on disk */
|
||||
virtual void ReloadBanks() = 0;
|
||||
|
||||
/** Load Editor banks for auditioning in Sequnecer. */
|
||||
virtual void LoadEditorBanks() = 0;
|
||||
|
||||
/** Unload Editor banks. */
|
||||
virtual void UnloadEditorBanks() = 0;
|
||||
#endif
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#pragma once
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#pragma once
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
using System.IO;
|
||||
|
||||
namespace UnrealBuildTool.Rules
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#include "AssetTypeActions_FMODEvent.h"
|
||||
#include "AssetTypeActions_Base.h"
|
||||
@ -7,9 +7,9 @@
|
||||
#include "FMODUtils.h"
|
||||
#include "FMODStudioModule.h"
|
||||
#include "FMODStudioEditorModule.h"
|
||||
#include "UnrealEd/Public/Editor.h"
|
||||
#include "Editor.h"
|
||||
#include "Framework/MultiBox/MultiBoxBuilder.h"
|
||||
#include "EditorStyle/Public/EditorStyleSet.h"
|
||||
#include "Editor/EditorStyle/Public/EditorStyleSet.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "AssetTypeActions"
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#pragma once
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#include "FMODAmbientSoundActorFactory.h"
|
||||
#include "FMODStudioEditorPrivatePCH.h"
|
||||
#include "FMODAmbientSound.h"
|
||||
#include "FMODEvent.h"
|
||||
#include "AssetRegistry/Public/AssetData.h"
|
||||
#include "AssetRegistry/AssetData.h"
|
||||
#include "Editor/EditorEngine.h"
|
||||
|
||||
UFMODAmbientSoundActorFactory::UFMODAmbientSoundActorFactory(const FObjectInitializer &ObjectInitializer)
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#pragma once
|
||||
|
||||
|
@ -209,8 +209,6 @@ void FFMODAssetBuilder::BuildAssets(const UFMODSettings& InSettings, const FStri
|
||||
}
|
||||
}
|
||||
|
||||
const FString BankExtensions[] = { TEXT(".assets"), TEXT(".streams"), TEXT(".bank")};
|
||||
|
||||
void FFMODAssetBuilder::BuildBankLookup(const FString &AssetName, const FString &PackagePath, const UFMODSettings &InSettings,
|
||||
TArray<UObject*>& AssetsToSave)
|
||||
{
|
||||
@ -245,56 +243,29 @@ void FFMODAssetBuilder::BuildBankLookup(const FString &AssetName, const FString
|
||||
return;
|
||||
}
|
||||
|
||||
TMap<FString, FString> BankGuids;
|
||||
TArray<FString> LocalizedEntriesVisited;
|
||||
|
||||
for (FString BankPath : BankPaths)
|
||||
{
|
||||
FMOD::Studio::Bank* Bank;
|
||||
FMOD_RESULT result = StudioSystem->loadBankFile(TCHAR_TO_UTF8(*BankPath), FMOD_STUDIO_LOAD_BANK_NORMAL, &Bank);
|
||||
FMOD_GUID BankID;
|
||||
|
||||
FMOD_RESULT result = StudioSystem->loadBankFile(TCHAR_TO_UTF8(*BankPath), FMOD_STUDIO_LOAD_BANK_NORMAL, &Bank);
|
||||
if (result == FMOD_OK)
|
||||
{
|
||||
result = Bank->getID(&BankID);
|
||||
Bank->unload();
|
||||
}
|
||||
|
||||
if (result == FMOD_OK)
|
||||
{
|
||||
FString GUID = FMODUtils::ConvertGuid(BankID).ToString(EGuidFormats::DigitsWithHyphensInBraces);
|
||||
|
||||
FString* otherBankPath = BankGuids.Find(GUID);
|
||||
if (otherBankPath != nullptr)
|
||||
{
|
||||
bool foundLocale = false;
|
||||
for (const FFMODProjectLocale& Locale : InSettings.Locales)
|
||||
{
|
||||
if (Locale.bDefault && BankPath.EndsWith(FString("_") + Locale.LocaleCode + FString(".bank")))
|
||||
{
|
||||
foundLocale = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundLocale)
|
||||
{
|
||||
UE_LOG(LogFMOD, Warning, TEXT("Ignoring bank %s as another bank with the same GUID is already being used.\n"
|
||||
"Bank %s does not match any locales in the FMOD Studio plugin settings."), *BankPath, *BankPath);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
BankGuids.Add(GUID, BankPath);
|
||||
}
|
||||
else
|
||||
if (result != FMOD_OK)
|
||||
{
|
||||
UE_LOG(LogFMOD, Error, TEXT("Failed to add bank %s to lookup."), *BankPath);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
FString GUID = FMODUtils::ConvertGuid(BankID).ToString(EGuidFormats::DigitsWithHyphensInBraces);
|
||||
FName OuterRowName(*GUID);
|
||||
|
||||
for (TPair<FString,FString> GUIDPath : BankGuids)
|
||||
{
|
||||
FName OuterRowName(*GUIDPath.Key);
|
||||
FFMODLocalizedBankTable* Row = BankLookup->DataTable->FindRow<FFMODLocalizedBankTable>(OuterRowName, nullptr, false);
|
||||
|
||||
if (Row)
|
||||
{
|
||||
StaleBanks.RemoveSingle(OuterRowName);
|
||||
@ -302,33 +273,48 @@ void FFMODAssetBuilder::BuildBankLookup(const FString &AssetName, const FString
|
||||
else
|
||||
{
|
||||
FFMODLocalizedBankTable NewRow{};
|
||||
NewRow.Banks = NewObject<UDataTable>(BankLookup->DataTable, *GUIDPath.Key, RF_NoFlags);
|
||||
NewRow.Banks = NewObject<UDataTable>(BankLookup->DataTable, *BankPath, RF_NoFlags);
|
||||
NewRow.Banks->RowStruct = FFMODLocalizedBankRow::StaticStruct();
|
||||
BankLookup->DataTable->AddRow(OuterRowName, NewRow);
|
||||
Row = BankLookup->DataTable->FindRow<FFMODLocalizedBankTable>(OuterRowName, nullptr, false);
|
||||
bModified = true;
|
||||
}
|
||||
|
||||
FString CurFilename = FPaths::GetCleanFilename(GUIDPath.Value);
|
||||
FString FilenamePart = CurFilename;
|
||||
|
||||
for (const FString& extension : BankExtensions)
|
||||
{
|
||||
FilenamePart.ReplaceInline(*extension, TEXT(""));
|
||||
}
|
||||
|
||||
FString InnerRowName("<NON-LOCALIZED>");
|
||||
// Set InnerRowName to either "<NON-LOCALIZED>" or a locale code based on the BankPath e.g. "JP"
|
||||
FName InnerRowName("<NON-LOCALIZED>");
|
||||
for (const FFMODProjectLocale& Locale : InSettings.Locales)
|
||||
{
|
||||
if (FilenamePart.EndsWith(FString("_") + Locale.LocaleCode))
|
||||
// Remove all expected extensions from end of filename before checking for locale code.
|
||||
// Note, we may encounter multiple extensions e.g. "Dialogue.assets.bank"
|
||||
const FString BankExtensions[] = { TEXT(".assets"), TEXT(".streams"), TEXT(".strings") };
|
||||
FString Filename = FPaths::GetCleanFilename(BankPath);
|
||||
Filename.RemoveFromEnd(TEXT(".bank"));
|
||||
for (const FString& extension : BankExtensions)
|
||||
{
|
||||
InnerRowName = Locale.LocaleCode;
|
||||
Filename.RemoveFromEnd(extension);
|
||||
}
|
||||
|
||||
if (Filename.EndsWith(FString("_") + Locale.LocaleCode))
|
||||
{
|
||||
InnerRowName = FName(*Locale.LocaleCode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
FFMODLocalizedBankRow* InnerRow = Row->Banks->FindRow<FFMODLocalizedBankRow>(FName(*InnerRowName), nullptr, false);
|
||||
FString RelativeBankPath = GUIDPath.Value.RightChop(InSettings.GetFullBankPath().Len() + 1);
|
||||
// See if we've visited this OuterRowName + InnerRowName already and skip it if so. This is mainly to
|
||||
// avoid setting "<NON-LOCALIZED>" multiple times (and causing BankLookup to be modified) when no
|
||||
// locales are set up in Unreal.
|
||||
FString LocalizedEntryKey = OuterRowName.ToString() + InnerRowName.ToString();
|
||||
if (LocalizedEntriesVisited.Find(LocalizedEntryKey) != INDEX_NONE)
|
||||
{
|
||||
UE_LOG(LogFMOD, Warning, TEXT("Ignoring bank %s as another bank with the same GUID is already being used.\n"
|
||||
"Bank %s does not match any locales in the FMOD Studio plugin settings."), *BankPath, *BankPath);
|
||||
continue;
|
||||
}
|
||||
LocalizedEntriesVisited.Add(LocalizedEntryKey);
|
||||
|
||||
FFMODLocalizedBankRow* InnerRow = Row->Banks->FindRow<FFMODLocalizedBankRow>(InnerRowName, nullptr, false);
|
||||
FString RelativeBankPath = BankPath.RightChop(InSettings.GetFullBankPath().Len() + 1);
|
||||
|
||||
if (InnerRow)
|
||||
{
|
||||
@ -342,10 +328,12 @@ void FFMODAssetBuilder::BuildBankLookup(const FString &AssetName, const FString
|
||||
{
|
||||
FFMODLocalizedBankRow NewRow{};
|
||||
NewRow.Path = RelativeBankPath;
|
||||
Row->Banks->AddRow(FName(*InnerRowName), NewRow);
|
||||
Row->Banks->AddRow(InnerRowName, NewRow);
|
||||
bModified = true;
|
||||
}
|
||||
|
||||
FString CurFilename = FPaths::GetCleanFilename(BankPath);
|
||||
|
||||
if (CurFilename == InSettings.GetMasterBankFilename() && BankLookup->MasterBankPath != RelativeBankPath)
|
||||
{
|
||||
BankLookup->MasterBankPath = RelativeBankPath;
|
||||
@ -376,15 +364,54 @@ void FFMODAssetBuilder::BuildBankLookup(const FString &AssetName, const FString
|
||||
bModified = true;
|
||||
}
|
||||
|
||||
// Remove stale localized bank entries from lookup
|
||||
for (auto& outer : BankLookup->DataTable->GetRowMap())
|
||||
{
|
||||
FName outerrowname = outer.Key;
|
||||
FFMODLocalizedBankTable* outerrow = reinterpret_cast<FFMODLocalizedBankTable*>(outer.Value);
|
||||
TArray<FName> RowsToRemove;
|
||||
for (auto& inner : outerrow->Banks->GetRowMap())
|
||||
{
|
||||
FName innerrowname = inner.Key;
|
||||
FFMODLocalizedBankRow* innerrow = reinterpret_cast<FFMODLocalizedBankRow*>(inner.Value);
|
||||
FString LocalizedEntryKey = outerrowname.ToString() + innerrowname.ToString();
|
||||
if (LocalizedEntriesVisited.Find(LocalizedEntryKey) == INDEX_NONE)
|
||||
{
|
||||
RowsToRemove.Add(innerrowname);
|
||||
}
|
||||
}
|
||||
for (auto& rowname : RowsToRemove)
|
||||
{
|
||||
outerrow->Banks->RemoveRow(rowname);
|
||||
bModified = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (bCreated)
|
||||
{
|
||||
UE_LOG(LogFMOD, Log, TEXT("BankLookup created.\n"));
|
||||
FAssetRegistryModule::AssetCreated(BankLookup);
|
||||
}
|
||||
|
||||
if (bCreated || bModified)
|
||||
{
|
||||
UE_LOG(LogFMOD, Log, TEXT("BankLookup modified.\n"));
|
||||
AssetsToSave.Add(BankLookup);
|
||||
}
|
||||
|
||||
UE_LOG(LogFMOD, Log, TEXT("===== BankLookup =====\n"));
|
||||
for (auto& outer : BankLookup->DataTable->GetRowMap())
|
||||
{
|
||||
FName outerrowname = outer.Key;
|
||||
FFMODLocalizedBankTable* outerrow = reinterpret_cast<FFMODLocalizedBankTable*>(outer.Value);
|
||||
UE_LOG(LogFMOD, Log, TEXT("GUID: %s\n"), *(outerrowname.ToString()));
|
||||
for (auto& inner : outerrow->Banks->GetRowMap())
|
||||
{
|
||||
FName innerrowname = inner.Key;
|
||||
FFMODLocalizedBankRow* innerrow = reinterpret_cast<FFMODLocalizedBankRow*>(inner.Value);
|
||||
UE_LOG(LogFMOD, Log, TEXT(" Locale: %s Path: %s\n"), *(innerrowname.ToString()), *innerrow->Path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FString FFMODAssetBuilder::GetAssetClassName(UClass* AssetClass)
|
||||
@ -501,7 +528,7 @@ UFMODAsset *FFMODAssetBuilder::CreateAsset(const AssetCreateInfo& CreateInfo, TA
|
||||
}
|
||||
else
|
||||
{
|
||||
SanitizedPackagePath = ObjectTools::SanitizeInvalidChars(PackagePath, INVALID_OBJECTPATH_CHARACTERS);
|
||||
SanitizedPackagePath = ObjectTools::SanitizeInvalidChars(PackagePath, INVALID_LONGPACKAGE_CHARACTERS);
|
||||
UE_LOG(LogFMOD, Log, TEXT("'%s' cannot be used as a UE4 asset path. %s. Using '%s' instead."), *PackagePath, *OutReason.ToString(),
|
||||
*SanitizedPackagePath);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#include "FMODAudioComponentDetails.h"
|
||||
#include "Subsystems/AssetEditorSubsystem.h"
|
||||
@ -6,10 +6,10 @@
|
||||
#include "FMODStudioModule.h"
|
||||
#include "FMODEvent.h"
|
||||
#include "fmod_studio.hpp"
|
||||
#include "UnrealEd/Public/Editor.h"
|
||||
#include "Editor.h"
|
||||
#include "Widgets/Input/SButton.h"
|
||||
#include "PropertyEditor/Public/DetailLayoutBuilder.h"
|
||||
#include "PropertyEditor/Public/DetailCategoryBuilder.h"
|
||||
#include "Editor/PropertyEditor/Public/DetailLayoutBuilder.h"
|
||||
#include "Editor/PropertyEditor/Public/DetailCategoryBuilder.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "FMODStudio"
|
||||
|
||||
|
@ -1,10 +1,12 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#pragma once
|
||||
|
||||
//#include "PropertyEditing.h"
|
||||
#include "PropertyCustomizationHelpers.h"
|
||||
#include "PropertyEditor/Public/IDetailCustomization.h"
|
||||
#include "IDetailCustomization.h"
|
||||
|
||||
class IDetailLayoutBuilder;
|
||||
|
||||
class FFMODAudioComponentDetails : public IDetailCustomization
|
||||
{
|
||||
|
@ -1,12 +1,12 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#include "FMODAudioComponentVisualizer.h"
|
||||
#include "FMODAudioComponent.h"
|
||||
#include "FMODUtils.h"
|
||||
#include "FMODEvent.h"
|
||||
#include "fmod_studio.hpp"
|
||||
#include "Engine/Public/SceneView.h"
|
||||
#include "Engine/Public/SceneManagement.h"
|
||||
#include "SceneView.h"
|
||||
#include "SceneManagement.h"
|
||||
|
||||
void FFMODAudioComponentVisualizer::DrawVisualization(const UActorComponent *Component, const FSceneView *View, FPrimitiveDrawInterface *PDI)
|
||||
{
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#pragma once
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#include "FMODBankUpdateNotifier.h"
|
||||
#include "FMODSettings.h"
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#pragma once
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#include "FMODEventEditor.h"
|
||||
#include "FMODEvent.h"
|
||||
@ -8,7 +8,7 @@
|
||||
#include "SFMODEventEditorPanel.h"
|
||||
#include "Widgets/Docking/SDockTab.h"
|
||||
#include "fmod_studio.hpp"
|
||||
#include "UnrealEd/Public/Editor.h"
|
||||
#include "Editor.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "FMODEventEditor"
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#pragma once
|
||||
|
||||
|
@ -36,11 +36,21 @@ int32 UFMODGenerateAssetsCommandlet::Main(const FString& CommandLine)
|
||||
// Rebuild switch
|
||||
if (Switches.Contains(RebuildSwitch))
|
||||
{
|
||||
FString FolderToDelete;
|
||||
IPlatformFile& FileManager = FPlatformFileManager::Get().GetPlatformFile();
|
||||
|
||||
/*
|
||||
Combine the ProjectContentDir + ContentBrowserPrefix to make a filesystem path
|
||||
to where the FMOD generated assets directories live e.g.
|
||||
../../../../UnrealProjects/MyProject/Content/FMOD
|
||||
Should work for non-default values of ContentBrowserPrefix e.g. /Game/foo/bar/baz/
|
||||
*/
|
||||
FString folderPath = Settings.ContentBrowserPrefix.TrimChar('/'); // /Game/FMOD/ -> Game/FMOD
|
||||
folderPath.Split(TEXT("/"), 0, &folderPath); // Game/FMOD -> FMOD
|
||||
folderPath = FPaths::ProjectContentDir() + folderPath + "/"; // FMOD -> ../../../../UnrealProjects/MyProject/Content/FMOD/
|
||||
|
||||
for (FString folder : Settings.GeneratedFolders)
|
||||
{
|
||||
FolderToDelete = FPaths::ProjectContentDir() + Settings.ContentBrowserPrefix + folder;
|
||||
FString FolderToDelete = folderPath + folder;
|
||||
bool removed = FileManager.DeleteDirectoryRecursively(*FolderToDelete);
|
||||
if (!removed)
|
||||
{
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2024.
|
||||
|
||||
#include "FMODSettingsCustomization.h"
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2024.
|
||||
|
||||
#pragma once
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#include "FMODStudioEditorModule.h"
|
||||
#include "FMODStudioModule.h"
|
||||
@ -20,31 +20,32 @@
|
||||
#include "Sequencer/FMODEventParameterTrackEditor.h"
|
||||
#include "AssetTypeActions_FMODEvent.h"
|
||||
|
||||
#include "Framework/Application/SlateApplication.h"
|
||||
#include "AssetRegistry/AssetRegistryModule.h"
|
||||
#include "UnrealEd/Public/AssetSelection.h"
|
||||
#include "Slate/Public/Framework/Notifications/NotificationManager.h"
|
||||
#include "Slate/Public/Widgets/Notifications/SNotificationList.h"
|
||||
#include "AssetSelection.h"
|
||||
#include "Framework/Notifications/NotificationManager.h"
|
||||
#include "Widgets/Notifications/SNotificationList.h"
|
||||
#include "Developer/Settings/Public/ISettingsModule.h"
|
||||
#include "Developer/Settings/Public/ISettingsSection.h"
|
||||
#include "UnrealEd/Public/Editor.h"
|
||||
#include "Editor.h"
|
||||
#include "Slate/SceneViewport.h"
|
||||
#include "LevelEditor/Public/LevelEditor.h"
|
||||
#include "Sockets/Public/SocketSubsystem.h"
|
||||
#include "Sockets/Public/Sockets.h"
|
||||
#include "Sockets/Public/IPAddress.h"
|
||||
#include "UnrealEd/Public/FileHelpers.h"
|
||||
#include "Sequencer/Public/ISequencerModule.h"
|
||||
#include "Sequencer/Public/SequencerChannelInterface.h"
|
||||
#include "MovieSceneTools/Public/ClipboardTypes.h"
|
||||
#include "Engine/Public/DebugRenderSceneProxy.h"
|
||||
#include "Engine/Classes/Debug/DebugDrawService.h"
|
||||
#include "Editor/LevelEditor/Public/LevelEditor.h"
|
||||
#include "SocketSubsystem.h"
|
||||
#include "Sockets.h"
|
||||
#include "IPAddress.h"
|
||||
#include "FileHelpers.h"
|
||||
#include "ISequencerModule.h"
|
||||
#include "SequencerChannelInterface.h"
|
||||
#include "ClipboardTypes.h"
|
||||
#include "DebugRenderSceneProxy.h"
|
||||
#include "Debug/DebugDrawService.h"
|
||||
#include "Settings/ProjectPackagingSettings.h"
|
||||
#include "UnrealEdGlobals.h"
|
||||
#include "UnrealEd/Public/LevelEditorViewport.h"
|
||||
#include "LevelEditorViewport.h"
|
||||
#include "ActorFactories/ActorFactory.h"
|
||||
#include "Engine/Canvas.h"
|
||||
#include "Editor/UnrealEdEngine.h"
|
||||
#include "Slate/Public/Framework/MultiBox/MultiBoxBuilder.h"
|
||||
#include "Framework/MultiBox/MultiBoxBuilder.h"
|
||||
#include "Misc/MessageDialog.h"
|
||||
#include "HAL/FileManager.h"
|
||||
#include "Interfaces/IMainFrameModule.h"
|
||||
@ -333,7 +334,7 @@ void FFMODStudioEditorModule::OnPostEngineInit()
|
||||
{
|
||||
RegisterHelpMenuEntries();
|
||||
MainMenuExtender = MakeShareable(new FExtender);
|
||||
MainMenuExtender->AddMenuExtension("FileLoadAndSave", EExtensionHook::After, NULL,
|
||||
MainMenuExtender->AddMenuExtension("FileOpen", EExtensionHook::After, NULL,
|
||||
FMenuExtensionDelegate::CreateRaw(this, &FFMODStudioEditorModule::AddFileMenuExtension));
|
||||
LevelEditor->GetMenuExtensibilityManager()->AddExtender(MainMenuExtender);
|
||||
}
|
||||
@ -388,8 +389,6 @@ void FFMODStudioEditorModule::ProcessBanks()
|
||||
BankUpdateNotifier.SetFilePath(Settings.GetFullBankPath());
|
||||
|
||||
BankUpdateNotifier.EnableUpdate(true);
|
||||
|
||||
IFMODStudioModule::Get().RefreshSettings();
|
||||
}
|
||||
}
|
||||
|
||||
@ -791,9 +790,12 @@ void FFMODStudioEditorModule::ValidateFMOD()
|
||||
if (FMessageDialog::Open(EAppMsgType::YesNo, Message) == EAppReturnType::Yes)
|
||||
{
|
||||
Settings.Locales = StudioLocales;
|
||||
Settings.Locales[0].bDefault = true;
|
||||
if (Settings.Locales.Num() > 0)
|
||||
{
|
||||
Settings.Locales[0].bDefault = true;
|
||||
}
|
||||
SettingsSection->Save();
|
||||
IFMODStudioModule::Get().RefreshSettings();
|
||||
IFMODStudioModule::Get().ReloadBanks();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1109,6 +1111,7 @@ void FFMODStudioEditorModule::BeginPIE(bool simulating)
|
||||
|
||||
void FFMODStudioEditorModule::EndPIE(bool simulating)
|
||||
{
|
||||
IFMODStudioModule::Get().PreEndPIE();
|
||||
UE_LOG(LogFMOD, Verbose, TEXT("FFMODStudioEditorModule EndPIE: %d"), simulating);
|
||||
bSimulating = false;
|
||||
bIsInPIE = false;
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
#pragma once
|
||||
|
||||
#include "Runtime/Engine/Classes/Components/SceneComponent.h"
|
||||
|
@ -1,8 +1,8 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#include "FMODStudioStyle.h"
|
||||
#include "Styling/SlateStyleRegistry.h"
|
||||
#include "EditorStyle/Public/Interfaces/IEditorStyleModule.h"
|
||||
#include "Editor/EditorStyle/Public/Interfaces/IEditorStyleModule.h"
|
||||
#include "Modules/ModuleManager.h"
|
||||
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#pragma once
|
||||
#include "SlateCore/Public/Styling/SlateStyle.h"
|
||||
#include "EditorStyle/Public/EditorStyleSet.h"
|
||||
#include "Styling/SlateStyle.h"
|
||||
#include "EditorStyleSet.h"
|
||||
|
||||
class FFMODStudioStyle
|
||||
{
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#include "SFMODEventEditorPanel.h"
|
||||
#include "FMODStudioModule.h"
|
||||
@ -6,7 +6,7 @@
|
||||
#include "Input/Reply.h"
|
||||
#include "Widgets/Input/SNumericEntryBox.h"
|
||||
#include "Widgets/Layout/SExpandableArea.h"
|
||||
#include "EditorStyle/Public/EditorStyleSet.h"
|
||||
#include "Editor/EditorStyle/Public/EditorStyleSet.h"
|
||||
#include "Widgets/Input/SButton.h"
|
||||
#include "Widgets/Layout/SScrollBox.h"
|
||||
#include "fmod_studio.hpp"
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#pragma once
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#include "Sequencer/FMODChannelEditors.h"
|
||||
#include "ISequencerChannelInterface.h"
|
||||
@ -7,7 +7,7 @@
|
||||
#include "MovieSceneTimeHelpers.h"
|
||||
#include "MovieSceneToolHelpers.h"
|
||||
#include "ScopedTransaction.h"
|
||||
#include "EditorWidgets/Public/SEnumCombo.h"
|
||||
#include "Editor/EditorWidgets/Public/SEnumCombo.h"
|
||||
#include "EditorStyleSet.h"
|
||||
#include "Channels/MovieSceneChannelTraits.h"
|
||||
|
||||
|
@ -1,16 +1,17 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#include "FMODEventControlTrackEditor.h"
|
||||
#include "FMODAmbientSound.h"
|
||||
#include "Sequencer/FMODEventControlSection.h"
|
||||
#include "Sequencer/FMODEventControlTrack.h"
|
||||
#include "AnimatedRange.h"
|
||||
#include "Rendering/DrawElements.h"
|
||||
#include "Framework/MultiBox/MultiBoxBuilder.h"
|
||||
#include "Curves/IntegralCurve.h"
|
||||
#include "SequencerSectionPainter.h"
|
||||
#include "EditorStyleSet.h"
|
||||
#include "Editor/UnrealEdEngine.h"
|
||||
#include "Sequencer/FMODEventControlSection.h"
|
||||
#include "Sequencer/FMODEventControlTrack.h"
|
||||
#include "ISectionLayoutBuilder.h"
|
||||
#include "FMODAmbientSound.h"
|
||||
#include "CommonMovieSceneTools.h"
|
||||
#include "Channels/MovieSceneChannelProxy.h"
|
||||
#include "Channels/MovieSceneChannelEditorData.h"
|
||||
@ -103,13 +104,13 @@ int32 FFMODEventControlSection::OnPaintSection(FSequencerSectionPainter &InPaint
|
||||
float XSize = TimeToPixelConverter.SecondsToPixel(DrawRange.GetUpperBoundValue()) - XOffset;
|
||||
FSlateDrawElement::MakeBox(InPainter.DrawElements, InPainter.LayerId,
|
||||
InPainter.SectionGeometry.ToPaintGeometry(
|
||||
FVector2D(XOffset, (InPainter.SectionGeometry.GetLocalSize().Y - SequencerSectionConstants::KeySize.Y) / 2),
|
||||
FVector2D(XSize, SequencerSectionConstants::KeySize.Y)),
|
||||
FVector2D(XSize, SequencerSectionConstants::KeySize.Y),
|
||||
FSlateLayoutTransform(1.0f, FVector2D(XOffset, (InPainter.SectionGeometry.GetLocalSize().Y - SequencerSectionConstants::KeySize.Y) / 2))),
|
||||
FAppStyle::GetBrush("Sequencer.Section.Background"), DrawEffects);
|
||||
FSlateDrawElement::MakeBox(InPainter.DrawElements, InPainter.LayerId,
|
||||
InPainter.SectionGeometry.ToPaintGeometry(
|
||||
FVector2D(XOffset, (InPainter.SectionGeometry.GetLocalSize().Y - SequencerSectionConstants::KeySize.Y) / 2),
|
||||
FVector2D(XSize, SequencerSectionConstants::KeySize.Y)),
|
||||
FVector2D(XSize, SequencerSectionConstants::KeySize.Y),
|
||||
FSlateLayoutTransform(1.0f, FVector2D(XOffset, (InPainter.SectionGeometry.GetLocalSize().Y - SequencerSectionConstants::KeySize.Y) / 2))),
|
||||
FAppStyle::GetBrush("Sequencer.Section.BackgroundTint"), DrawEffects, TrackColor);
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#pragma once
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#include "FMODEventParameterTrackEditor.h"
|
||||
#include "FMODAmbientSound.h"
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#include "FMODParameterSection.h"
|
||||
#include "ISectionLayoutBuilder.h"
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#pragma once
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2023.
|
||||
// Copyright (c), Firelight Technologies Pty, Ltd. 2012-2024.
|
||||
|
||||
#pragma once
|
||||
|
||||
|
Reference in New Issue
Block a user