RMS Level of an FMOD EventInstance

    If we want to get the exact RMS level of an EventInstance, we have to work with FMOD.DSP, FMOD.DSP_METERING_INFO and FMOD.ChannelGroup.

    We declare the FMOD.DSP, FMOD.DSP_METERING_INFO and FMOD.ChannelGroup together with the EventInstance and the event path first:

    FMOD.Studio.EventInstance instance;
    
    [FMODUnity.EventRef]
    public string fmodEvent;
    
    FMOD.DSP dsp = new FMOD.DSP();
    FMOD.DSP_METERING_INFO meterInfo = new FMOD.DSP_METERING_INFO();
    FMOD.ChannelGroup channelGroup;

    In Unity’s Start() method we start the instance:

    void Start()
     {
            instance = FMODUnity.RuntimeManager.CreateInstance(fmodEvent);
            instance.start();
            StartCoroutine(GetChannelGroup());
    }

    We execute the GetChannelGroup() coroutine to get the ChannelGroup of the instance:

     IEnumerator GetChannelGroup()
        {
            if (instance.isValid())
            {
                while (instance.getChannelGroup(out channelGroup) != FMOD.RESULT.OK)
                {
                    yield return new WaitForEndOfFrame();
                }
    
                channelGroup.getDSP(0, out dsp);
                dsp.setMeteringEnabled(false, true);
    
            }
            else
            {
                Debug.Log("There is no instance");
                yield return null;
            }
        }

    It is not possible to get the ChannelGroup until the event instance is successfully loaded. Accordingly, we loop getChannelGroup() until we get the return value FMOD.RESULT.OK. With channelGroup.getDSP() we get the address of a variable to receive a pointer to the requested DSP unit. With setMeteringEnabled() we activate the output metering.

    The next step is to create a method that returns the RMS level as a float variable:

    float GetRMS() 
    {
      float rms = 0f;
    
      dsp.getMeteringInfo(IntPtr.Zero, out meterInfo);
      for (int i = 0; i < meterInfo.numchannels; i++) {
        rms += meterInfo.rmslevel[i] * meterInfo.rmslevel[i];
      }
    
      rms = Mathf.Sqrt(rms / (float) meterInfo.numchannels);
    
      float dB = rms > 0 ? 20.0f * Mathf.Log10(rms * Mathf.Sqrt(2.0f)) : -80.0f;
      if (dB > 10.0f) dB = 10.0f;
      return dB;
    }

    Now we can access the RMS level in the code using GetRMS(). In the Unity project I visualized the value by using a canvas and a text element:

    FMOD RMS level visualized in Unity
    FMOD RMS level visualized in Unity

    ↑ To the Top