Runtime DSP data from Event Instance c++

Hi!

I created Fmod Event.
I want to extract DSP runtime data from the Event Instance(ex. rms level of Master Bus).

I can get runtime TimeLineBeat and TimeLineMarker.
But
numchannels, numsamples, rmslevel these gets ‘0’.
I can’t get any data from it.

How can I get these value updated?
Using Unreal 4.25

Thanks in advance

Here is the source below.


SoundManager.h

namespace FMOD
{
	class System;
	class Channel;
	class Sound;
	class DSP;
};

UCLASS()
class IDEOLOGY_API ASoundManager : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	ASoundManager();
	~ASoundManager();

protected:
	FMOD::System* pSystem;
	FMOD::ChannelGroup* pChannelGroup;
	FMOD::DSP* pDSP;
	FMOD::Studio::EventInstance* pInstance;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FMOD", meta = (AllowPrivateAccess = "true"))
	TArray<class UFMODEvent*>	EventArray;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FMOD", meta = (AllowPrivateAccess = "true"))
	TArray<FString>				EventNameArray;

	FFMODEventInstance	EventWrapper;
};

SoundManager.cpp

ASoundManager* g_pSoundManager = nullptr;

ASoundManager::ASoundManager()
{
	PrimaryActorTick.bCanEverTick = true;

	WindowSize = 512;

	pDSP = nullptr;

	pChannelGroup = nullptr;

	g_pSoundManager = this;

	bCreateInstance = false;

	bCallTimeLineBeat = false;
	bCallTimeLineMarker = false;
}

ASoundManager::~ASoundManager()
{
	if (pDSP)
	{
		if (pChannelGroup)
			pChannelGroup->removeDSP(pDSP);

		pDSP->release();
	}
		
	if (pSystem)
	{
		pSystem->close();
		pSystem->release();
	}
}

void ASoundManager::BeginPlay()
{
	Super::BeginPlay();

	InitFMOD();
}

void ASoundManager::InitFMOD()
{
	FMOD_RESULT result = FMOD::System_Create(&pSystem);

	if (result == FMOD_OK)
	{
		pSystem->init(FMOD_MAX_CHANNEL_WIDTH, FMOD_INIT_NORMAL, NULL);

		/*pSystem->getMasterChannelGroup(&pChannelGroup);
		pChannelGroup->getDSP(FMOD_CHANNELCONTROL_DSP_HEAD, &pDSP);
		pDSP->setActive(true);
		pDSP->setMeteringEnabled(false, true);*/
	}

	PlayEvent(EventNameArray[0]);

	/*pSystem->createDSPByType(FMOD_DSP_TYPE_FFT, &pDSP);
	pDSP->setParameterInt(FMOD_DSP_FFT_WINDOWTYPE, FMOD_DSP_FFT_WINDOW_HANNING);
	pDSP->setParameterInt(FMOD_DSP_FFT_WINDOWSIZE, WindowSize);

	pSystem->getMasterChannelGroup(&pChannelGroup);
	pChannelGroup->addDSP(0, pDSP);*/
}

void ASoundManager::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	pSystem->update();

	if (bCreateInstance)
	{
		bCreateInstance = false;

		pInstance->getChannelGroup(&pChannelGroup);

		FMOD_RESULT result = pChannelGroup->getDSP(0, &pDSP);
		pDSP->setMeteringEnabled(false, true);
	}

	//pInstance->getChannelGroup(&pChannelGroup);
	//pSystem->getMasterChannelGroup(&pChannelGroup);

	if (pChannelGroup)
	{
		//pChannelGroup->getDSP(FMOD_CHANNELCONTROL_DSP_HEAD, &pDSP);

		if (pDSP)
		{
			//pDSP->setActive(true);
			//pDSP->setMeteringEnabled(false, true);

			float	fVolume = 0.f;
			pChannelGroup->getVolume(&fVolume);

			int	iDSP = 0;
			pChannelGroup->getNumDSPs(&iDSP);
			//GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("Volume : %.3f"), fVolume));
			//GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("DSP : %d"), iDSP));

			FMOD_DSP_METERING_INFO Info = {};
			pDSP->getMeteringInfo(nullptr, &Info);

			//FMOD_DSP_PARAMETER_DESC* pDesc = {};
			//pDSP->getParameterInfo()

			//for (int32 i = 0; i < Info.numchannels; ++i)
			{
				GEngine->AddOnScreenDebugMessage(-1, 1.f, FColor::Red, FString::Printf(TEXT("ChannelCount : %d Sample : %d rms : %.3f"), Info.numchannels, Info.numsamples, Info.rmslevel[0]));
			}
		}
	}
}

void ASoundManager::PlayEvent(const FString& Name)
{
	int32	iIndex = -1;

	for (auto& ArrayValue : EventNameArray)
	{
		++iIndex;

		if (ArrayValue == Name)
		{
			break;
		}
	}

	if (iIndex == -1)
		return;

	if (pDSP)
	{
		/*pDSP->setActive(false);
		if (pChannelGroup)
			pChannelGroup->removeDSP(pDSP);*/
	}

	bCreateInstance = false;

	EventWrapper = UFMODBlueprintStatics::PlayEvent2D(GetWorld(), EventArray[iIndex], true);

	pInstance = EventWrapper.Instance;

	pInstance->setUserData(this);
	pInstance->setCallback(ASoundManager::OnCallback, FMOD_STUDIO_EVENT_CALLBACK_ALL);
}

void ASoundManager::CallTimeLineBeat(const FTimelineBeatProperties& prop)
{
	//GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Blue, TEXT("TimeLine Beat"));
}

void ASoundManager::CallTimeLineMarker(const FTimelineMarkerProperties& prop)
{
	//GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, TEXT("TimeLine Marker"));
}

FMOD_RESULT ASoundManager::OnCallback(FMOD_STUDIO_EVENT_CALLBACK_TYPE type,
	FMOD_STUDIO_EVENTINSTANCE* event, void* parameters)
{
	ASoundManager* pMgr = nullptr;
	FMOD::Studio::EventInstance* Instance = (FMOD::Studio::EventInstance*)event;

	Instance->getUserData((void**)&pMgr);

	switch (type)
	{
	case FMOD_STUDIO_EVENT_CALLBACK_CREATED:
		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, TEXT("Instance Create Complete"));

		g_pSoundManager->bCreateInstance = true;
		break;
	case FMOD_STUDIO_EVENT_CALLBACK_TIMELINE_MARKER:
		pMgr->CallTimeLineMarker(*((FTimelineMarkerProperties*)parameters));
		break;
	case FMOD_STUDIO_EVENT_CALLBACK_TIMELINE_BEAT:
		pMgr->CallTimeLineBeat(*((FTimelineBeatProperties*)parameters));
		break;
	default:
		break;
	}

	return FMOD_OK;
}

FMOD_RESULT ASoundManager::CreateInstanceComplete(FMOD_STUDIO_EVENT_CALLBACK_TYPE type, 
	FMOD_STUDIO_EVENTINSTANCE* event, void* parameters)
{
	FMOD::Studio::EventInstance* Instance = (FMOD::Studio::EventInstance*)event;

	switch (type)
	{
	case FMOD_STUDIO_EVENT_CALLBACK_CREATED:
		
		/*FMOD_RESULT result = Instance->getChannelGroup(&g_pSoundManager->pChannelGroup);
		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("getChannelGroup : %d"), result));

		result = g_pSoundManager->pChannelGroup->addDSP(0, g_pSoundManager->pDSP);
		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("addDSP : %d"), result));
		result = g_pSoundManager->pDSP->setActive(true);
		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("setActive : %d"), result));

		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("Intance : %d"), g_pSoundManager->pInstance));
		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("DSP : %d"), g_pSoundManager->pDSP));*/
		break;
	}

	return FMOD_OK;
}

FMOD_RESULT ASoundManager::OnTimeLineBeat(FMOD_STUDIO_EVENT_CALLBACK_TYPE type,
	FMOD_STUDIO_EVENTINSTANCE* event, void* parameters)
{
	FMOD::Studio::EventInstance* Instance = (FMOD::Studio::EventInstance*)event;
	FMOD_STUDIO_TIMELINE_BEAT_PROPERTIES* pProp = (FMOD_STUDIO_TIMELINE_BEAT_PROPERTIES*)parameters;

	GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Blue, TEXT("TimeLine Beat"));

	return FMOD_OK;
}

FMOD_RESULT ASoundManager::OnTimeLineMarker(FMOD_STUDIO_EVENT_CALLBACK_TYPE type,
	FMOD_STUDIO_EVENTINSTANCE* event, void* parameters)
{
	FMOD::Studio::EventInstance* Instance = (FMOD::Studio::EventInstance*)event;
	FMOD_STUDIO_TIMELINE_MARKER_PROPERTIES* pProp = (FMOD_STUDIO_TIMELINE_MARKER_PROPERTIES*)parameters;

	GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, TEXT("TimeLine Marker"));

	return FMOD_OK;
}

The first thing to check would be the FMOD_RESULT returned from all the FMOD functions, in particular DSP::getMeteringInfo, this can help identify what is not behaving as expected and why.

I can get TimeLinebeat and TimeLineMarker.
But can’t get data of DSP::getMeteringInfo.
Trying hard on this for 3month. But can’t yet…
Here is full testing source. this is playing event instance.
If you can help me, I can send you full Unreal project source.
Hope to get answer of it.
Thanks in advance.

SoundManager.h



#pragma once

#include "EngineMinimal.h"
#include "fmod_studio.hpp"
#include "FMODBlueprintStatics.h"
#include "GameFramework/Actor.h"
#include "SoundManager.generated.h"

namespace FMOD
{
	class System;
	class Channel;
	class Sound;
	class DSP;
};

UCLASS()
class IDEOLOGY_API ASoundManager : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	ASoundManager();
	~ASoundManager();

protected:
	FMOD::System* pSystem;
	FMOD::ChannelGroup* pChannelGroup;
	FMOD::DSP* pDSP;
	FMOD::Studio::EventInstance* pInstance;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FMOD", meta = (AllowPrivateAccess = "true"))
	int32 WindowSize;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FMOD", meta = (AllowPrivateAccess = "true"))
	TArray<class UFMODEvent*>	EventArray;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "FMOD", meta = (AllowPrivateAccess = "true"))
	TArray<FString>				EventNameArray;

	FFMODEventInstance	EventWrapper;

	bool		bCreateInstance;
	bool		bCallTimeLineBeat;
	bool		bCallTimeLineMarker;

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

private:
	void InitFMOD();

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;

public:
	UFUNCTION(BlueprintCallable)
	void PlayEvent(const FString& Name);

	void CallTimeLineBeat(const FTimelineBeatProperties& prop);
	void CallTimeLineMarker(const FTimelineMarkerProperties& prop);

	static FMOD_RESULT OnCallback(FMOD_STUDIO_EVENT_CALLBACK_TYPE type,
		FMOD_STUDIO_EVENTINSTANCE* event, void* parameters);

	static FMOD_RESULT CreateInstanceComplete(FMOD_STUDIO_EVENT_CALLBACK_TYPE type,
		FMOD_STUDIO_EVENTINSTANCE* event, void* parameters);
	static FMOD_RESULT OnTimeLineBeat(FMOD_STUDIO_EVENT_CALLBACK_TYPE type,
		FMOD_STUDIO_EVENTINSTANCE* event, void* parameters);
	static FMOD_RESULT OnTimeLineMarker(FMOD_STUDIO_EVENT_CALLBACK_TYPE type,
		FMOD_STUDIO_EVENTINSTANCE* event, void* parameters);

	void InitDSP();
};



SoundManager.cpp




#include "SoundManager.h"

ASoundManager* g_pSoundManager = nullptr;

// Sets default values
ASoundManager::ASoundManager()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

	WindowSize = 512;

	pDSP = nullptr;

	pChannelGroup = nullptr;

	g_pSoundManager = this;

	bCreateInstance = false;

	bCallTimeLineBeat = false;
	bCallTimeLineMarker = false;
}

ASoundManager::~ASoundManager()
{
	/*if (_sound)
	{
		pChannel->removeDSP(pDSP);
	}*/

	if (pDSP)
	{
		if (pChannelGroup)
			pChannelGroup->removeDSP(pDSP);

		pDSP->release();
	}
		
	if (pSystem)
	{
		pSystem->close();
		pSystem->release();
	}
}

// Called when the game starts or when spawned
void ASoundManager::BeginPlay()
{
	Super::BeginPlay();

	InitFMOD();
}

void ASoundManager::InitFMOD()
{
	//FMOD_RESULT result;
	//result = FMOD::System_Create(&pSystem);
	//FMOD::Studio::System* pSystem1 = IFMODStudioModule::Get().GetStudioSystem(EFMODSystemContext::Runtime);


	//if (result == FMOD_OK)
	{
	//	result = pSystem->init(FMOD_MAX_CHANNEL_WIDTH, FMOD_INIT_NORMAL, NULL);

		//GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
		//	*FString::Printf(TEXT("init : %d"), result));

		/*pSystem->getMasterChannelGroup(&pChannelGroup);
		pChannelGroup->getDSP(FMOD_CHANNELCONTROL_DSP_HEAD, &pDSP);
		pDSP->setActive(true);
		pDSP->setMeteringEnabled(false, true);*/
	}

	PlayEvent(EventNameArray[0]);

	/*pSystem->createDSPByType(FMOD_DSP_TYPE_FFT, &pDSP);
	pDSP->setParameterInt(FMOD_DSP_FFT_WINDOWTYPE, FMOD_DSP_FFT_WINDOW_HANNING);
	pDSP->setParameterInt(FMOD_DSP_FFT_WINDOWSIZE, WindowSize);

	pSystem->getMasterChannelGroup(&pChannelGroup);
	pChannelGroup->addDSP(0, pDSP);*/
}

// Called every frame
void ASoundManager::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	FMOD_RESULT result;

	//FMOD_RESULT result = pSystem->update();
	//GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, 
	//	*FString::Printf(TEXT("FMOD update : %d"), result));

	if (bCreateInstance)
	{
		bCreateInstance = false;

		/*result = pSystem->createDSPByType(FMOD_DSP_TYPE_FFT, &pDSP);

		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, 
			*FString::Printf(TEXT("CreateDSP : %d"), result));

		result = pDSP->setParameterInt(FMOD_DSP_FFT_WINDOWTYPE, FMOD_DSP_FFT_WINDOW_RECT);
		result = pDSP->setParameterInt(FMOD_DSP_FFT_WINDOWSIZE, 512);

		result = EventWrapper.Instance->getChannelGroup(&pChannelGroup);
		result = pChannelGroup->addDSP(0, pDSP);

		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
			*FString::Printf(TEXT("addDSP : %d"), result));*/
			
		//result = pSystem->getMasterChannelGroup(&pChannelGroup);

		//if (result != FMOD_RESULT::FMOD_OK)
		/*GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, 
			*FString::Printf(TEXT("getMasterChannelGroup : %d"), result));*/

		//result = pChannelGroup->getDSP(0, &pDSP);
		/*result = pChannelGroup->getDSP(FMOD_CHANNELCONTROL_DSP_HEAD, &pDSP);

		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
			*FString::Printf(TEXT("getDSP : %d"), result));*/

		//result = pChannelGroup->addDSP(0, pDSP);

		/*if (result != FMOD_RESULT::FMOD_OK)
			GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, TEXT("addDSP Failed"));*/

		/*result = pDSP->setMeteringEnabled(false, true);

		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
			*FString::Printf(TEXT("setMeteringEnabled : %d"), result));*/

		//pInstance->getChannelGroup(&pChannelGroup);

		//FMOD_RESULT result = pChannelGroup->getDSP(0, &pDSP);
		//pDSP->setMeteringEnabled(false, true);
	}

	//pInstance->getChannelGroup(&pChannelGroup);
	//pSystem->getMasterChannelGroup(&pChannelGroup);

	if (pChannelGroup)
	{
		//FMOD_DSP_PARAMETER_FFT	fft;
		int NumParams = 0;
		
		result = pDSP->getNumParameters(&NumParams); 
		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
			*FString::Printf(TEXT("getNumParameters : %d"), result));
		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
			*FString::Printf(TEXT("Parameter Count : %d"), NumParams));
		//pDSP->getParameterData(2, )
		//FMOD_DSP_METERING_INFO	InputInfo, OutputInfo;
		//result = pDSP->getMeteringInfo(&InputInfo, &OutputInfo);

		/*GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
			*FString::Printf(TEXT("getMeteringInfo : %d"), result));
		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
			*FString::Printf(TEXT("Input numsamples : %d"), InputInfo.numsamples));
		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
			*FString::Printf(TEXT("Input numchannels : %d"), InputInfo.numchannels));
		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
			*FString::Printf(TEXT("Output numsamples : %d"), OutputInfo.numsamples));
		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
			*FString::Printf(TEXT("Output numchannels : %d"), OutputInfo.numchannels));*/

		/*FMOD_DSP_PARAMETER_FFT* pFFT = new FMOD_DSP_PARAMETER_FFT;
		char	Test[40] = {};
		result = pDSP->getParameterData(FMOD_DSP_FFT_SPECTRUMDATA, (void**)&pFFT, 0, 0, 0);

		delete	pFFT;*/

		//GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
		//	*FString::Printf(TEXT("getParameterData : %d"), result));
		//GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, TEXT("Update Begin"));

		//GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("ChannelCount : %d"), (int32)pFFT->numchannels));
		/*for (int32 i = 0; i < pFFT->numchannels; ++i)
		{

		}*/

		//pChannelGroup->getDSP(FMOD_CHANNELCONTROL_DSP_HEAD, &pDSP);

		//if (pDSP)
		//{
		//	//pDSP->setActive(true);
		//	//pDSP->setMeteringEnabled(false, true);

		//	float	fVolume = 0.f;
		//	pChannelGroup->getVolume(&fVolume);

		//	int	iDSP = 0;
		//	pChannelGroup->getNumDSPs(&iDSP);
		//	//GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("Volume : %.3f"), fVolume));
		//	//GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("DSP : %d"), iDSP));

		//	FMOD_DSP_METERING_INFO Info = {};
		//	pDSP->getMeteringInfo(nullptr, &Info);

		//	//FMOD_DSP_PARAMETER_DESC* pDesc = {};
		//	//pDSP->getParameterInfo()

		//	//for (int32 i = 0; i < Info.numchannels; ++i)
		//	{
		//		GEngine->AddOnScreenDebugMessage(-1, 1.f, FColor::Red, FString::Printf(TEXT("ChannelCount : %d Sample : %d rms : %.3f"), Info.numchannels, Info.numsamples, Info.rmslevel[0]));
		//	}
		//}
	}
}

void ASoundManager::PlayEvent(const FString& Name)
{
	int32	iIndex = -1;

	for (auto& ArrayValue : EventNameArray)
	{
		++iIndex;

		if (ArrayValue == Name)
		{
			break;
		}
	}

	if (iIndex == -1)
		return;

	if (pDSP)
	{
		/*pDSP->setActive(false);
		if (pChannelGroup)
			pChannelGroup->removeDSP(pDSP);*/
	}

	bCreateInstance = false;
	
	EventWrapper = UFMODBlueprintStatics::PlayEvent2D(GetWorld(), EventArray[iIndex], true);

	pInstance = EventWrapper.Instance;

	pInstance->setUserData(this);
	//pInstance->setCallback(ASoundManager::OnCallback, FMOD_STUDIO_EVENT_CALLBACK_ALL);
	pInstance->setCallback(ASoundManager::OnCallback, FMOD_STUDIO_EVENT_CALLBACK_CREATED);
}

void ASoundManager::CallTimeLineBeat(const FTimelineBeatProperties& prop)
{
	//GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Blue, TEXT("TimeLine Beat"));
}

void ASoundManager::CallTimeLineMarker(const FTimelineMarkerProperties& prop)
{
	//GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, TEXT("TimeLine Marker"));
}

FMOD_RESULT ASoundManager::OnCallback(FMOD_STUDIO_EVENT_CALLBACK_TYPE type,
	FMOD_STUDIO_EVENTINSTANCE* event, void* parameters)
{
	ASoundManager* pMgr = nullptr;
	FMOD::Studio::EventInstance* Instance = (FMOD::Studio::EventInstance*)event;

	Instance->getUserData((void**)&pMgr);

	switch (type)
	{
	case FMOD_STUDIO_EVENT_CALLBACK_CREATED:
		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, TEXT("Instance Create Complete"));

		g_pSoundManager->bCreateInstance = true;
		g_pSoundManager->InitDSP();
		break;
	case FMOD_STUDIO_EVENT_CALLBACK_TIMELINE_MARKER:
		pMgr->CallTimeLineMarker(*((FTimelineMarkerProperties*)parameters));
		break;
	case FMOD_STUDIO_EVENT_CALLBACK_TIMELINE_BEAT:
		pMgr->CallTimeLineBeat(*((FTimelineBeatProperties*)parameters));
		break;
	default:
		break;
	}

	return FMOD_OK;
}

FMOD_RESULT ASoundManager::CreateInstanceComplete(FMOD_STUDIO_EVENT_CALLBACK_TYPE type, 
	FMOD_STUDIO_EVENTINSTANCE* event, void* parameters)
{
	FMOD::Studio::EventInstance* Instance = (FMOD::Studio::EventInstance*)event;

	switch (type)
	{
	case FMOD_STUDIO_EVENT_CALLBACK_CREATED:
		
		/*FMOD_RESULT result = Instance->getChannelGroup(&g_pSoundManager->pChannelGroup);
		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("getChannelGroup : %d"), result));

		result = g_pSoundManager->pChannelGroup->addDSP(0, g_pSoundManager->pDSP);
		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("addDSP : %d"), result));
		result = g_pSoundManager->pDSP->setActive(true);
		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("setActive : %d"), result));

		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("Intance : %d"), g_pSoundManager->pInstance));
		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("DSP : %d"), g_pSoundManager->pDSP));*/
		break;
	}

	return FMOD_OK;
}

FMOD_RESULT ASoundManager::OnTimeLineBeat(FMOD_STUDIO_EVENT_CALLBACK_TYPE type,
	FMOD_STUDIO_EVENTINSTANCE* event, void* parameters)
{
	FMOD::Studio::EventInstance* Instance = (FMOD::Studio::EventInstance*)event;
	FMOD_STUDIO_TIMELINE_BEAT_PROPERTIES* pProp = (FMOD_STUDIO_TIMELINE_BEAT_PROPERTIES*)parameters;

	GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Blue, TEXT("TimeLine Beat"));

	return FMOD_OK;
}

FMOD_RESULT ASoundManager::OnTimeLineMarker(FMOD_STUDIO_EVENT_CALLBACK_TYPE type,
	FMOD_STUDIO_EVENTINSTANCE* event, void* parameters)
{
	FMOD::Studio::EventInstance* Instance = (FMOD::Studio::EventInstance*)event;
	FMOD_STUDIO_TIMELINE_MARKER_PROPERTIES* pProp = (FMOD_STUDIO_TIMELINE_MARKER_PROPERTIES*)parameters;

	GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, TEXT("TimeLine Marker"));

	return FMOD_OK;
}

void ASoundManager::InitDSP()
{
	FMOD_RESULT result;
	result = FMOD::System_Create(&pSystem);
	
	if (result == FMOD_OK)
	{
		result = pSystem->init(FMOD_MAX_CHANNEL_WIDTH, FMOD_INIT_NORMAL, NULL);
	}

	result = pSystem->createDSPByType(FMOD_DSP_TYPE_FFT, &pDSP);

	GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
		*FString::Printf(TEXT("CreateDSP : %d"), result));

	result = pDSP->setParameterInt(FMOD_DSP_FFT_WINDOWTYPE, FMOD_DSP_FFT_WINDOW_RECT);
	result = pDSP->setParameterInt(FMOD_DSP_FFT_WINDOWSIZE, 512);

	result = EventWrapper.Instance->getChannelGroup(&pChannelGroup);
	result = pChannelGroup->addDSP(0, pDSP);
	//result = pChannelGroup->getDSP(0, &pDSP);
	//result = pChannelGroup->setDSPIndex(pDSP, 0);

	//result = pDSP->setParameterInt(FMOD_DSP_FFT_WINDOWTYPE, FMOD_DSP_FFT_WINDOW_RECT);
	//result = pDSP->setParameterInt(FMOD_DSP_FFT_WINDOWSIZE, 512);

	GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
		*FString::Printf(TEXT("addDSP : %d"), result));
}

DSP::getMeteringInfo

Requesting metering information when it hasn’t been enabled will result in FMOD_ERR_BADCOMMAND.

I can see that you are only setting metering enabled for the output but when you try to get the metering info you are requesting both input and output which will fail and return FMOD_ERR_BADCOMMAND.

A nicer way to check the results of the FMOD functions would be to setup an error check function, eg.

void ERRCHECK(FMOD_RESULT result)
{
    if (result != FMOD_OK)
    {
        // Log out the result
    }
}

Then you can just wrap your FMOD calls in that. Eg.

ERRCHECK(pDSP->getMeteringInfo(&InputInfo, &OutputInfo));

I’m playing sound with FMOD::Studio::EventInstance* pInstance;
When I get DSP with making System, getMeteringInfo result is FMOD_OK.

But when I get DSP with EventInstance, got FMOD_INVALID_HANDLE(30)…

this is my capture of FMOD STUDIO Project.
Hope to get rmsvolume of this bus (or master bus). How I can get it?

Thanks

It is possible that the EventInstance/Bus/ChannelGroup is trying to be accessed before it has actually been created. When Studio has been initialized in asynchronous mode, the channel group will not be created until the command has been executed in the async thread.

You may want to check Studio::EventInstance::isValid before trying to use it, especially just after it has been created.

For Buses you can use Studio::Bus::lockChannelGroup to ensure that the channelGroup of the bus is created, even before anything has started playing.

Checked Studio::EventInstance::isValid and when it is True,
ChannelGroup From EventInstance result is FMOD_OK.
and getDSP from ChannelGroup result is FMOD_OK.

But DSP::setMeteringEnabled(true, true) → FMOD_ERR_INVALID_HANDLE
Can’t get info from getMeteringInfo.

How can I get getMeteringInfo from DSP…?
Thanks for your feedback.

Here is source I’m doing…

#include "SoundManager.h"

ASoundManager* g_pSoundManager = nullptr;

// Sets default values
ASoundManager::ASoundManager()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

	WindowSize = 512;

	pDSP = nullptr;

	pChannelGroup = nullptr;

	g_pSoundManager = this;

	bCreateInstance = false;

	bCallTimeLineBeat = false;
	bCallTimeLineMarker = false;
}

ASoundManager::~ASoundManager()
{
	/*if (_sound)
	{
		pChannel->removeDSP(pDSP);
	}*/

	if (pDSP)
	{
		if (pChannelGroup)
			pChannelGroup->removeDSP(pDSP);

		pDSP->release();
	}
		
	if (pSystem)
	{
		pSystem->close();
		pSystem->release();
	}
}

// Called when the game starts or when spawned
void ASoundManager::BeginPlay()
{
	Super::BeginPlay();

	InitFMOD();
}

void ASoundManager::InitFMOD()
{
	//FMOD_RESULT result;
	//result = FMOD::System_Create(&pSystem);
	////FMOD::Studio::System* pSystem1 = IFMODStudioModule::Get().GetStudioSystem(EFMODSystemContext::Runtime);


	//if (result == FMOD_OK)
	//{
	//	result = pSystem->init(FMOD_MAX_CHANNEL_WIDTH, FMOD_INIT_NORMAL, NULL);

	//	GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
	//		*FString::Printf(TEXT("init : %d"), result));

	//	pSystem->getMasterChannelGroup(&pChannelGroup);
	//	result = pChannelGroup->getDSP(0, &pDSP);

	//	GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
	//		*FString::Printf(TEXT("getDSP : %d"), result));

	//	result = pDSP->setActive(true);

	//	GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
	//		*FString::Printf(TEXT("setActive : %d"), result));

	//	result = pDSP->setMeteringEnabled(true, true);

	//	GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
	//		*FString::Printf(TEXT("setMeteringEnabled : %d"), result));
	//}

	PlayEvent(EventNameArray[0]);

	/*pSystem->createDSPByType(FMOD_DSP_TYPE_FFT, &pDSP);
	pDSP->setParameterInt(FMOD_DSP_FFT_WINDOWTYPE, FMOD_DSP_FFT_WINDOW_HANNING);
	pDSP->setParameterInt(FMOD_DSP_FFT_WINDOWSIZE, WindowSize);

	pSystem->getMasterChannelGroup(&pChannelGroup);
	pChannelGroup->addDSP(0, pDSP);*/
}

// Called every frame
void ASoundManager::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	FMOD_RESULT result;

	//FMOD_RESULT result = pSystem->update();
	//GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, 
	//	*FString::Printf(TEXT("FMOD update : %d"), result));

	if (bCreateInstance)
	{

		if (pInstance->isValid())
		{
			result = pInstance->getChannelGroup(&pChannelGroup);
			GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
				*FString::Printf(TEXT("getChannelGroup : %d"), result));

			result = pChannelGroup->getDSP(FMOD_CHANNELCONTROL_DSP_HEAD, &pDSP);

			GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
				*FString::Printf(TEXT("getDSP : %d"), result));

			if (pChannelGroup)
				bCreateInstance = false;
		}

		//bCreateInstance = false;

		/*result = pInstance->getChannelGroup(&pChannelGroup);

		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
			*FString::Printf(TEXT("getChannelGroup : %d"), result));
		result = pChannelGroup->getDSP(0, &pDSP);

		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
			*FString::Printf(TEXT("getDSP : %d"), result));

		result = pDSP->setMeteringEnabled(true, true);

		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
			*FString::Printf(TEXT("setMeteringEnabled : %d"), result));*/

		//float	fValue = 0.f, fFinalValue = 0.f;
		////EventWrapper.Instance->getParameterByName("Timeline", &fValue, &fFinalValue);
		//FMOD::Studio::System* StudioSystem = IFMODStudioModule::Get().GetStudioSystem(EFMODSystemContext::Runtime);

		//StudioSystem->getParameterByName("Timeline", &fValue, &fFinalValue);

		//GEngine->AddOnScreenDebugMessage(-1, 30.f, FColor::Red,
		//	FString::Printf(TEXT("fValue : %.3f fFinalValue : %.3f"), fValue, fFinalValue));


		//int	iPosition = 0;
		//EventWrapper.Instance->getTimelinePosition(&iPosition);

		//GEngine->AddOnScreenDebugMessage(-1, 30.f, FColor::Red,
		//	FString::Printf(TEXT("TimelIne Position : %d"), iPosition));

		//result = EventWrapper.Instance->getChannelGroup(&pChannelGroup);
		//GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
		//	*FString::Printf(TEXT("getChannelGroup : %d"), result));

		//result = pChannelGroup->getDSP(0, &pDSP);
		//GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
		//	*FString::Printf(TEXT("getDSP : %d"), result));

		//result = pDSP->setMeteringEnabled(true, false);
		//GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
		//	*FString::Printf(TEXT("setMeteringEnabled : %d"), result));

		/*result = pDSP->setParameterInt(FMOD_DSP_FFT_WINDOWTYPE, FMOD_DSP_FFT_WINDOW_HANNING);
		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
			*FString::Printf(TEXT("FMOD_DSP_FFT_WINDOWTYPE : %d"), result));

		result = pDSP->setParameterInt(FMOD_DSP_FFT_WINDOWSIZE, WindowSize);
		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
			*FString::Printf(TEXT("FMOD_DSP_FFT_WINDOWSIZE : %d"), result));*/


		//FMOD_RESULT result;
		/*result = FMOD::System_Create(&pSystem);

		if (result == FMOD_OK)
		{
			result = pSystem->init(FMOD_MAX_CHANNEL_WIDTH, FMOD_INIT_NORMAL, NULL);
		}

		result = pSystem->createDSPByType(FMOD_DSP_TYPE_FFT, &pDSP);

		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
			*FString::Printf(TEXT("CreateDSP : %d"), result));

		result = pDSP->setParameterInt(FMOD_DSP_FFT_WINDOWTYPE, FMOD_DSP_FFT_WINDOW_RECT);
		result = pDSP->setParameterInt(FMOD_DSP_FFT_WINDOWSIZE, 512);

		result = pDSP->setMeteringEnabled(true, false);

		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
			*FString::Printf(TEXT("setMeteringEnabled : %d"), result));

		result = EventWrapper.Instance->getChannelGroup(&pChannelGroup);
		result = pChannelGroup->addDSP(0, pDSP);*/
		//result = pChannelGroup->getDSP(0, &pDSP);
		//result = pChannelGroup->setDSPIndex(pDSP, 0);

		//result = pDSP->setParameterInt(FMOD_DSP_FFT_WINDOWTYPE, FMOD_DSP_FFT_WINDOW_RECT);
		//result = pDSP->setParameterInt(FMOD_DSP_FFT_WINDOWSIZE, 512);

		/*GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
			*FString::Printf(TEXT("addDSP : %d"), result));*/

		/*result = pSystem->createDSPByType(FMOD_DSP_TYPE_FFT, &pDSP);

		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, 
			*FString::Printf(TEXT("CreateDSP : %d"), result));

		result = pDSP->setParameterInt(FMOD_DSP_FFT_WINDOWTYPE, FMOD_DSP_FFT_WINDOW_RECT);
		result = pDSP->setParameterInt(FMOD_DSP_FFT_WINDOWSIZE, 512);

		result = EventWrapper.Instance->getChannelGroup(&pChannelGroup);
		result = pChannelGroup->addDSP(0, pDSP);

		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
			*FString::Printf(TEXT("addDSP : %d"), result));*/
			
		//result = pSystem->getMasterChannelGroup(&pChannelGroup);

		//if (result != FMOD_RESULT::FMOD_OK)
		/*GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, 
			*FString::Printf(TEXT("getMasterChannelGroup : %d"), result));*/

		//result = pChannelGroup->getDSP(0, &pDSP);
		/*result = pChannelGroup->getDSP(FMOD_CHANNELCONTROL_DSP_HEAD, &pDSP);

		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
			*FString::Printf(TEXT("getDSP : %d"), result));*/

		//result = pChannelGroup->addDSP(0, pDSP);

		/*if (result != FMOD_RESULT::FMOD_OK)
			GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, TEXT("addDSP Failed"));*/

		/*result = pDSP->setMeteringEnabled(false, true);

		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
			*FString::Printf(TEXT("setMeteringEnabled : %d"), result));*/

		//pInstance->getChannelGroup(&pChannelGroup);

		//FMOD_RESULT result = pChannelGroup->getDSP(0, &pDSP);
		//pDSP->setMeteringEnabled(false, true);
	}

	//pInstance->getChannelGroup(&pChannelGroup);
	//pSystem->getMasterChannelGroup(&pChannelGroup);



	if (pChannelGroup)
	{
		result = pDSP->setMeteringEnabled(true, true);

		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
			*FString::Printf(TEXT("setMeteringEnabled : %d"), result));
		//FMOD_DSP_PARAMETER_FFT	fft;
		/*int NumParams = 0;

		FMOD_DSP_METERING_INFO	inputInfo, outputInfo;
		result = pDSP->getMeteringInfo(&inputInfo, &outputInfo);

		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
			*FString::Printf(TEXT("getMeteringInfo : %d"), result));

		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
			*FString::Printf(TEXT("numchannels : %d"), inputInfo.numchannels));

		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
			*FString::Printf(TEXT("numsamples : %d"), inputInfo.numsamples));

		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
			*FString::Printf(TEXT("rmslevel[0] : %d"), inputInfo.rmslevel[0]));*/

		/*float	fValue = 0.f, fFinalValue = 0.f;
		FMOD::Studio::System* StudioSystem = IFMODStudioModule::Get().GetStudioSystem(EFMODSystemContext::Runtime);

		result = StudioSystem->getParameterByName("Timeline", &fValue, &fFinalValue);

		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
			*FString::Printf(TEXT("getParameterByName : %d"), result));
		GEngine->AddOnScreenDebugMessage(-1, 30.f, FColor::Red,
			FString::Printf(TEXT("fValue : %.3f fFinalValue : %.3f"), fValue, fFinalValue));*/
		
		/*result = pDSP->getNumParameters(&NumParams); 
		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
			*FString::Printf(TEXT("getNumParameters : %d"), result));
		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
			*FString::Printf(TEXT("Parameter Count : %d"), NumParams));*/



		//pDSP->getParameterData(2, )
		//FMOD_DSP_METERING_INFO	InputInfo, OutputInfo;
		//result = pDSP->getMeteringInfo(&InputInfo, &OutputInfo);

		/*GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
			*FString::Printf(TEXT("getMeteringInfo : %d"), result));
		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
			*FString::Printf(TEXT("Input numsamples : %d"), InputInfo.numsamples));
		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
			*FString::Printf(TEXT("Input numchannels : %d"), InputInfo.numchannels));
		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
			*FString::Printf(TEXT("Output numsamples : %d"), OutputInfo.numsamples));
		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
			*FString::Printf(TEXT("Output numchannels : %d"), OutputInfo.numchannels));*/

		/*FMOD_DSP_PARAMETER_FFT* pFFT = new FMOD_DSP_PARAMETER_FFT;
		char	Test[40] = {};
		result = pDSP->getParameterData(FMOD_DSP_FFT_SPECTRUMDATA, (void**)&pFFT, 0, 0, 0);

		delete	pFFT;*/

		//GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
		//	*FString::Printf(TEXT("getParameterData : %d"), result));
		//GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, TEXT("Update Begin"));

		//GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("ChannelCount : %d"), (int32)pFFT->numchannels));
		/*for (int32 i = 0; i < pFFT->numchannels; ++i)
		{

		}*/

		//pChannelGroup->getDSP(FMOD_CHANNELCONTROL_DSP_HEAD, &pDSP);

		//if (pDSP)
		//{
		//	//pDSP->setActive(true);
		//	//pDSP->setMeteringEnabled(false, true);

		//	float	fVolume = 0.f;
		//	pChannelGroup->getVolume(&fVolume);

		//	int	iDSP = 0;
		//	pChannelGroup->getNumDSPs(&iDSP);
		//	//GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("Volume : %.3f"), fVolume));
		//	//GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("DSP : %d"), iDSP));

		//	FMOD_DSP_METERING_INFO Info = {};
		//	pDSP->getMeteringInfo(nullptr, &Info);

		//	//FMOD_DSP_PARAMETER_DESC* pDesc = {};
		//	//pDSP->getParameterInfo()

		//	//for (int32 i = 0; i < Info.numchannels; ++i)
		//	{
		//		GEngine->AddOnScreenDebugMessage(-1, 1.f, FColor::Red, FString::Printf(TEXT("ChannelCount : %d Sample : %d rms : %.3f"), Info.numchannels, Info.numsamples, Info.rmslevel[0]));
		//	}
		//}
	}
}

void ASoundManager::PlayEvent(const FString& Name)
{
	int32	iIndex = -1;

	for (auto& ArrayValue : EventNameArray)
	{
		++iIndex;

		if (ArrayValue == Name)
		{
			break;
		}
	}

	if (iIndex == -1)
		return;

	if (pDSP)
	{
		/*pDSP->setActive(false);
		if (pChannelGroup)
			pChannelGroup->removeDSP(pDSP);*/
	}

	bCreateInstance = false;
	
	EventWrapper = UFMODBlueprintStatics::PlayEvent2D(GetWorld(), EventArray[iIndex], true);

	pInstance = EventWrapper.Instance;

	pInstance->setUserData(this);
	pInstance->setCallback(ASoundManager::OnCallback, FMOD_STUDIO_EVENT_CALLBACK_ALL);

	//UFMODAudioComponent* AudioComponent;

	//AudioComponent->GetParameter(TEXT("Timeline"));

	//pInstance->setCallback(ASoundManager::OnCallback, FMOD_STUDIO_EVENT_CALLBACK_CREATED);
}

void ASoundManager::CallTimeLineBeat(const FTimelineBeatProperties& prop)
{
	//GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Blue, TEXT("TimeLine Beat"));
}

void ASoundManager::CallTimeLineMarker(const FTimelineMarkerProperties& prop)
{
	//GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, TEXT("TimeLine Marker"));
}

FMOD_RESULT ASoundManager::OnCallback(FMOD_STUDIO_EVENT_CALLBACK_TYPE type,
	FMOD_STUDIO_EVENTINSTANCE* event, void* parameters)
{
	ASoundManager* pMgr = nullptr;
	FMOD::Studio::EventInstance* Instance = (FMOD::Studio::EventInstance*)event;

	Instance->getUserData((void**)&pMgr);

	switch (type)
	{
	case FMOD_STUDIO_EVENT_CALLBACK_CREATED:
		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, TEXT("Instance Create Complete"));

		g_pSoundManager->bCreateInstance = true;
		g_pSoundManager->InitDSP();
		break;
	case FMOD_STUDIO_EVENT_CALLBACK_TIMELINE_MARKER:
		pMgr->CallTimeLineMarker(*((FTimelineMarkerProperties*)parameters));
		break;
	case FMOD_STUDIO_EVENT_CALLBACK_TIMELINE_BEAT:
		pMgr->CallTimeLineBeat(*((FTimelineBeatProperties*)parameters));
		break;
	default:
		break;
	}

	return FMOD_OK;
}

FMOD_RESULT ASoundManager::CreateInstanceComplete(FMOD_STUDIO_EVENT_CALLBACK_TYPE type, 
	FMOD_STUDIO_EVENTINSTANCE* event, void* parameters)
{
	FMOD::Studio::EventInstance* Instance = (FMOD::Studio::EventInstance*)event;

	switch (type)
	{
	case FMOD_STUDIO_EVENT_CALLBACK_CREATED:
		
		/*FMOD_RESULT result = Instance->getChannelGroup(&g_pSoundManager->pChannelGroup);
		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("getChannelGroup : %d"), result));

		result = g_pSoundManager->pChannelGroup->addDSP(0, g_pSoundManager->pDSP);
		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("addDSP : %d"), result));
		result = g_pSoundManager->pDSP->setActive(true);
		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("setActive : %d"), result));

		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("Intance : %d"), g_pSoundManager->pInstance));
		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, FString::Printf(TEXT("DSP : %d"), g_pSoundManager->pDSP));*/
		break;
	}

	return FMOD_OK;
}

FMOD_RESULT ASoundManager::OnTimeLineBeat(FMOD_STUDIO_EVENT_CALLBACK_TYPE type,
	FMOD_STUDIO_EVENTINSTANCE* event, void* parameters)
{
	FMOD::Studio::EventInstance* Instance = (FMOD::Studio::EventInstance*)event;
	FMOD_STUDIO_TIMELINE_BEAT_PROPERTIES* pProp = (FMOD_STUDIO_TIMELINE_BEAT_PROPERTIES*)parameters;

	GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Blue, TEXT("TimeLine Beat"));

	return FMOD_OK;
}

FMOD_RESULT ASoundManager::OnTimeLineMarker(FMOD_STUDIO_EVENT_CALLBACK_TYPE type,
	FMOD_STUDIO_EVENTINSTANCE* event, void* parameters)
{
	FMOD::Studio::EventInstance* Instance = (FMOD::Studio::EventInstance*)event;
	FMOD_STUDIO_TIMELINE_MARKER_PROPERTIES* pProp = (FMOD_STUDIO_TIMELINE_MARKER_PROPERTIES*)parameters;

	GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, TEXT("TimeLine Marker"));

	return FMOD_OK;
}

void ASoundManager::InitDSP()
{
}

You should only see this error if the DSP is invalid or queued for release. Can you check that the DSP handle is valid at that time, eg. using a null check and/or trying another function on it like DSP::getActive.

Use Core System

  1. Event Instance is created
  2. FMOD_STUDIO_EVENT_CALLBACK_CREATED on callback
  3. Studio::EventInstance::isValid is true
  4. CreateDSP is Valid
  5. DSP::getMeteringInfo ->Invalid Handle *****

Use Studio System

  1. Event Instance is created
  2. FMOD_STUDIO_EVENT_CALLBACK_CREATED on callback
  3. Studio::EventInstance::isValid is true
  4. IFMODStudioModule::Get().GetStudioSystem(EFMODSystemContext::Runtime); Success
  5. pStudioSystem->getCoreSystem(&pSystem); FMOD_OK
  6. FMOD_DSP_DESCRIPTION DSPDesc = {};
    unsigned int DPSRegisterHandle = 0;
    result = pSystem->registerDSP(&DSPDesc, &DPSRegisterHandle);
    → Invalid Handle *****
  7. result = pSystem->getMasterChannelGroup(&pChannelGroup) → Invalid Handle *****
  8. result = pChannelGroup->getDSP(FMOD_CHANNELCONTROL_DSP_HEAD, &pDSP); → Invalid Handle *****

Is there any way to get proper DSP and get value of rms level?
Thanks for your time.

Here is the test I used, which is working for me:

#include "MyActor.h"
#include "fmod.hpp"
#include "FMODBlueprintStatics.h"
#include "FMODEvent.h"

FFMODEventInstance eventInstance;
FMOD::ChannelGroup* chanG;
FMOD::DSP* mDSP;
FMOD_DSP_METERING_INFO input, output;

FMOD::Studio::System* studioSystem;
FMOD::System* coreSystem;

void ERRCHECK(FMOD_RESULT result);

FMOD_RESULT F_CALLBACK MyCallback(FMOD_STUDIO_EVENT_CALLBACK_TYPE type, FMOD_STUDIO_EVENTINSTANCE* event, void* parameters)
{
	FMOD::Studio::EventInstance* Instance = (FMOD::Studio::EventInstance*)event;
	if (type == FMOD_STUDIO_EVENT_CALLBACK_CREATED)
	{
		ERRCHECK(coreSystem->createDSPByType(FMOD_DSP_TYPE_FFT, &mDSP));
		ERRCHECK(Instance->getChannelGroup(&chanG));
		ERRCHECK(chanG->addDSP(0, mDSP));
		ERRCHECK(mDSP->setMeteringEnabled(true, true));

		ERRCHECK(Instance->start());
	}
	else if (type == FMOD_STUDIO_EVENT_CALLBACK_STOPPED)
	{
		ERRCHECK(chanG->removeDSP(mDSP));
		ERRCHECK(mDSP->release());
		ERRCHECK(eventInstance.Instance->stop(FMOD_STUDIO_STOP_IMMEDIATE));
		ERRCHECK(eventInstance.Instance->release());
	}
	return FMOD_OK;
}

// Sets default values
AMyActor::AMyActor()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;
}

// Called when the game starts or when spawned
void AMyActor::BeginPlay()
{
	Super::BeginPlay();

	studioSystem = IFMODStudioModule::Get().GetStudioSystem(EFMODSystemContext::Runtime);
	ERRCHECK(studioSystem->getCoreSystem(&coreSystem));

	UFMODEvent* fmodEvent = UFMODBlueprintStatics::FindEventByName("event:/Parent");
	UE_LOG(LogTemp, Warning, TEXT("fmodEvent : %s"), *(fmodEvent->GetDesc()));

	eventInstance = UFMODBlueprintStatics::PlayEvent2D(this, fmodEvent, false);

	ERRCHECK(eventInstance.Instance->setCallback(MyCallback, FMOD_STUDIO_EVENT_CALLBACK_CREATED | FMOD_STUDIO_EVENT_CALLBACK_STOPPED));
}

// Called every frame
void AMyActor::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	if (mDSP)
	{
		ERRCHECK(mDSP->getMeteringInfo(&input, &output));
	}
}

void ERRCHECK(FMOD_RESULT result)
{
	if (result != FMOD_OK)
	{
		UE_LOG(LogTemp, Warning, TEXT("Result = %s"), result);
	}
}

Result is Invalid Handle like before…
Here is code with same way you tested.
Is there anything wrong?
Thanks.

SoundManager.cpp

#include "SoundManager.h"

ASoundManager* g_pSoundManager = nullptr;

// Sets default values
ASoundManager::ASoundManager()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

	WindowSize = 512;

	pDSP = nullptr;

	pChannelGroup = nullptr;

	g_pSoundManager = this;

	bCreateInstance = false;

	bCallTimeLineBeat = false;
	bCallTimeLineMarker = false;
}

ASoundManager::~ASoundManager()
{
	if (pDSP)
	{
		if (pChannelGroup)
			pChannelGroup->removeDSP(pDSP);

		pDSP->release();
	}
		
	if (pSystem)
	{
		pSystem->close();
		pSystem->release();
	}
}

// Called when the game starts or when spawned
void ASoundManager::BeginPlay()
{
	Super::BeginPlay();

	InitFMOD();
}

void ASoundManager::InitFMOD()
{
	pStudioSystem = IFMODStudioModule::Get().GetStudioSystem(EFMODSystemContext::Runtime);
	ErrCheck(pStudioSystem->getCoreSystem(&pSystem),
		TEXT("getCoreSystem"));

	PlayEvent(EventNameArray[0]);
}

// Called every frame
void ASoundManager::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
}

void ASoundManager::PlayEvent(const FString& Name)
{
	int32	iIndex = -1;

	for (auto& ArrayValue : EventNameArray)
	{
		++iIndex;

		if (ArrayValue == Name)
		{
			break;
		}
	}

	if (iIndex == -1)
		return;

	bCreateInstance = false;

	/*UFMODEvent* fmodEvent = UFMODBlueprintStatics::FindEventByName(TEXT("/Game/FMOD/Events/MainTrack"));
	GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
		*FString::Printf(TEXT("fmodEvent : %s"), *(fmodEvent->GetDesc())));*/


	eventInstance = UFMODBlueprintStatics::PlayEvent2D(this, EventArray[iIndex], false);


	pInstance = eventInstance.Instance;

	ErrCheck(pInstance->setCallback(ASoundManager::OnCallback, FMOD_STUDIO_EVENT_CALLBACK_ALL),
		TEXT("setCallback"));
}

void ASoundManager::CallTimeLineBeat(const FTimelineBeatProperties& prop)
{
	//GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Blue, TEXT("TimeLine Beat"));
}

void ASoundManager::CallTimeLineMarker(const FTimelineMarkerProperties& prop)
{
	//GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, TEXT("TimeLine Marker"));
}

FMOD_RESULT F_CALLBACK ASoundManager::OnCallback(FMOD_STUDIO_EVENT_CALLBACK_TYPE type,
	FMOD_STUDIO_EVENTINSTANCE* event, void* parameters)
{
	ASoundManager* pMgr = nullptr;
	FMOD::Studio::EventInstance* Instance = (FMOD::Studio::EventInstance*)event;

	switch (type)
	{
	case FMOD_STUDIO_EVENT_CALLBACK_CREATED:
		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, TEXT("Instance Create Complete"));

		g_pSoundManager->bCreateInstance = true;
		g_pSoundManager->InitDSP(Instance);
		break;
	case FMOD_STUDIO_EVENT_CALLBACK_TIMELINE_MARKER:
		g_pSoundManager->CallTimeLineMarker(*((FTimelineMarkerProperties*)parameters));
		break;
	case FMOD_STUDIO_EVENT_CALLBACK_TIMELINE_BEAT:
		g_pSoundManager->CallTimeLineBeat(*((FTimelineBeatProperties*)parameters));
		break;
	case FMOD_STUDIO_EVENT_CALLBACK_STOPPED:
		break;
	default:
		break;
	}

	return FMOD_OK;
}

FMOD_RESULT ASoundManager::CreateInstanceComplete(FMOD_STUDIO_EVENT_CALLBACK_TYPE type, 
	FMOD_STUDIO_EVENTINSTANCE* event, void* parameters)
{
	FMOD::Studio::EventInstance* Instance = (FMOD::Studio::EventInstance*)event;

	switch (type)
	{
	case FMOD_STUDIO_EVENT_CALLBACK_CREATED:
		break;
	}

	return FMOD_OK;
}

FMOD_RESULT ASoundManager::OnTimeLineBeat(FMOD_STUDIO_EVENT_CALLBACK_TYPE type,
	FMOD_STUDIO_EVENTINSTANCE* event, void* parameters)
{
	FMOD::Studio::EventInstance* Instance = (FMOD::Studio::EventInstance*)event;
	FMOD_STUDIO_TIMELINE_BEAT_PROPERTIES* pProp = (FMOD_STUDIO_TIMELINE_BEAT_PROPERTIES*)parameters;

	GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Blue, TEXT("TimeLine Beat"));

	return FMOD_OK;
}

FMOD_RESULT ASoundManager::OnTimeLineMarker(FMOD_STUDIO_EVENT_CALLBACK_TYPE type,
	FMOD_STUDIO_EVENTINSTANCE* event, void* parameters)
{
	FMOD::Studio::EventInstance* Instance = (FMOD::Studio::EventInstance*)event;
	FMOD_STUDIO_TIMELINE_MARKER_PROPERTIES* pProp = (FMOD_STUDIO_TIMELINE_MARKER_PROPERTIES*)parameters;

	GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red, TEXT("TimeLine Marker"));

	return FMOD_OK;
}

void ASoundManager::InitDSP(FMOD::Studio::EventInstance* Instance)
{
	ErrCheck(pSystem->createDSPByType(FMOD_DSP_TYPE_FFT, &pDSP), TEXT("createDSPByType"));
	ErrCheck(Instance->getChannelGroup(&pChannelGroup), TEXT("getChannelGroup"));
	ErrCheck(pChannelGroup->addDSP(0, pDSP), TEXT("addDSP"));
	ErrCheck(pDSP->setMeteringEnabled(true, true), TEXT("setMeteringEnabled"));

	ErrCheck(Instance->start(), TEXT("start"));
}

void ASoundManager::ErrCheck(FMOD_RESULT result, const TCHAR* pName)
{
	if (result != FMOD_OK)
	{
		GEngine->AddOnScreenDebugMessage(-1, 10.f, FColor::Red,
				*FString::Printf(TEXT("%s : %d"), pName, result));
	}
}

As far as I can tell it all appears to be fine, it works for me using your code. Are you seeing any other errors or warnings in the output log at all?

Thanks for your time.
Continuosly Invalid Handle for me…
Can you look around project file? I sent by message.

Finally I got it to work by removing unnecessary code in the build.cs
Thank you so much. Now I can keep going to work. :slight_smile: :joy:

1 Like

No problem, I’m glad we were able to get to the bottom of this!