To get the instantaneous peak and rms levels of a playing event you can use DSP::getMeteringInfo
on the ChannelGroup
that the event is playing on. It’s a bit of drilling down from the UFMODEvent to get to it, but the process is as follows:
- Get the underlying event instance from the UFMODEvent
- Access the event instance’s channel group using
EventInstance::getChannelGroup
- Get the head, tail or fader DSP object using
Channel::getDSP
, depending on which point you want to access the metering info - Enable metering on your chosen DSP object with
DSP::setMeteringEnabled
- Retrieve the metering info with
DSP::getMeteringInfo
- Read the resulting peak, rms etc level info from the returned
FMOD_DSP_METERING_INFO
object
I have a basic example class here of what that would look like in the context of UE4.
#include "DisplayVolume.h"
#include <fmod_studio.hpp>
#include <FMODStudioModule.h>
#include <FMODAudioComponent.h>
#include <FMODEvent.h>
#include <FMODBlueprintStatics.h>
FMOD::ChannelGroup* Channel;
FMOD::DSP* HeadDSP;
FMOD::Studio::System* StudioSystem;
FMOD::Studio::EventInstance* Instance;
void ERRCHECK(FMOD_RESULT result, int line)
{
if (result != FMOD_OK)
{
UE_LOG(LogTemp, Warning, TEXT("Result = %d, %d"), (int)result, line);
}
}
// Sets default values for this component's properties
UDisplayVolume::UDisplayVolume()
{
PrimaryComponentTick.bCanEverTick = true;
}
UDisplayVolume::~UDisplayVolume()
{
Channel->release();
}
// Called when the game starts
void UDisplayVolume::BeginPlay()
{
Super::BeginPlay();
if (IFMODStudioModule::IsAvailable())
{
StudioSystem = IFMODStudioModule::Get().GetStudioSystem(EFMODSystemContext::Runtime);
if (StudioSystem)
{
// Create event instance
FFMODEventInstance wrapper = UFMODBlueprintStatics::PlayEvent2D(
GetOwner(),
Event, // UFMODEvent*, Declared in DisplayVolume.h
true);
Instance = wrapper.Instance;
}
}
}
// Called every frame
void UDisplayVolume::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
if (IFMODStudioModule::IsAvailable())
{
if (StudioSystem && Instance)
{
ERRCHECK(Instance->getChannelGroup(&Channel), __LINE__);
if (Channel)
{
ERRCHECK(Channel->getDSP(FMOD_CHANNELCONTROL_DSP_HEAD, &HeadDSP), __LINE__);
if (HeadDSP)
{
ERRCHECK(HeadDSP->setMeteringEnabled(false, true), __LINE__);
FMOD_DSP_METERING_INFO Info = {};
ERRCHECK(HeadDSP->getMeteringInfo(nullptr, &Info), __LINE__);
GEngine->ClearOnScreenDebugMessages();
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(
TEXT("Metering: %d channels, %d len. rms: %.3f, %.3f, %.3f, %.3f, %.3f, %.3f"),
Info.numchannels, Info.numsamples,
Info.rmslevel[0], Info.rmslevel[1],
Info.rmslevel[2], Info.rmslevel[3],
Info.rmslevel[4], Info.rmslevel[5])
);
}
}
}
}
}
And the resulting image of the volume debug info.
Hopefully that all makes sense, let me know if you have any issues!