Retrieving the Volume after attenuation of an Event in a AudioComponent

,

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:

  1. Get the underlying event instance from the UFMODEvent
  2. Access the event instance’s channel group using EventInstance::getChannelGroup
  3. Get the head, tail or fader DSP object using Channel::getDSP, depending on which point you want to access the metering info
  4. Enable metering on your chosen DSP object with DSP::setMeteringEnabled
  5. Retrieve the metering info with DSP::getMeteringInfo
  6. 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.
image

Hopefully that all makes sense, let me know if you have any issues!