Getting Current Event Waveform information/volume

Hey,

In previous Unity projects, I’ve sampled an audio source’s current waveform volume (the amplitude of the waveform at the time its currently playing essentially, post effects/ect) and piped it into a simple ‘talker’ script that basically passes that value (multiplied by a constant) to an animation to get the actor to ‘talk’ by opening its mouth when the volume is loud and closing it when its quiet.

Is there a way to access this data easily in Fmod? I dont see anything obvious in the API so i figured I’d ask here.

				sampleTime = Mathf.Min (audioSource.timeSamples + sampleOffset, audioSource.clip.samples - sampleDataLength);
                currentUpdateTime = 0f;
				audioSource.clip.GetData(clipSampleData, sampleTime); //I read 1024 samples, which is about 80 ms on a 44khz stereo clip, beginning at the current sample position of the clip.
                clipLoudness = 0f;
                i = 0;
				for (i = 0; i < clipSampleData.Length; i++)
                {
                    clipLoudness += Mathf.Abs(clipSampleData[i]);
                }

		clipLoudness /= sampleDataLength; //clipLoudness is what you are looking for

is roughly the code we use for unity audio sources if that helps clarify what type of data i’m trying to access.

1 Like

You can access peak (loudest sample in a given audio buffer) and rms (root mean squared, average sample value) volume data by enabling metering on any of the channel’s DSPs with DSP::setMeteringEnabled, and retrieve its FMOD_DSP_METERING_INFO using DSP::getMeteringInfo.
Here is a simple example of how to retrieve the left and right volumes of a playing event instance.

DisplayEventSound.cs
using System.Collections;
using UnityEngine;

public class DisplayEventSound : MonoBehaviour
{
    public FMODUnity.EventReference eventReference;

    public float leftVolume;
    public float rightVolume;

    FMOD.DSP_METERING_INFO inputInfo, outputInfo;

    FMOD.Studio.PLAYBACK_STATE playbackState;
    FMOD.DSP dsp;

    void Start()
    {
        StartCoroutine(PlayEventAsync());
    }

    IEnumerator PlayEventAsync()
    {
        FMODUnity.RuntimeManager.StudioSystem.getEvent(eventReference.Path, out FMOD.Studio.EventDescription eventDescription);
        eventDescription.createInstance(out FMOD.Studio.EventInstance eventInstance);
        eventInstance.set3DAttributes(FMODUnity.RuntimeUtils.To3DAttributes(gameObject));
        eventInstance.start();

        // Need to wait for event instance to play before getting channel group
        do
        {
            eventInstance.getPlaybackState(out playbackState);
            yield return null;
        }
        while (playbackState != FMOD.Studio.PLAYBACK_STATE.PLAYING);

        FMOD.ChannelGroup channelGroup;
        eventInstance.getChannelGroup(out channelGroup);

        channelGroup.getDSP(FMOD.CHANNELCONTROL_DSP_INDEX.FADER, out dsp);
        dsp.setMeteringEnabled(true, true);
    }

    // Update is called once per frame
    void Update()
    {
        if(playbackState == FMOD.Studio.PLAYBACK_STATE.PLAYING)
        {
            dsp.getMeteringInfo(out inputInfo, out outputInfo);
            leftVolume = outputInfo.rmslevel[0];
            rightVolume = outputInfo.rmslevel[1];
        }
    }
}