• Skip to primary navigation
  • Skip to main content

Alessandro Famà

  • Portfolio
  • Tutorials
  • Wiki
  • Über Mich
  • Impressum
  • Alessandro Famà
  • Tutorials
  • FMOD + Unity Tutorials
  • RMS-Pegel einer FMOD Instanz erhalten

    Wenn wir den genauen RMS-Pegel einer Instanz erhalten möchten, dann müssen wir im Code mit FMOD.DSP, FMOD.DSP_METERING_INFO und FMOD.ChannelGroup arbeiten.

    Lade dir das Unity & FMOD Projekt zu diesem Tutorial herunter.

    Wir deklarieren diese Structs zusammen mit der FMOD EventInstance und dem Eventpfad:

    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;
    bool loaded;

    Die Bool-Variable loaded hilft uns später dabei zu prüfen, ob die Instanz geladen wurde. In Unitys Start()-Methode starten wir die Instanz:

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

    Wir führen die Coroutine GetChannelGroup() aus, um die ChannelGroup der Instanz zu erhalten:

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

    Es ist nicht möglich, die ChannelGroup zu erhalten, bis die Event Instance erfolgreich geladen wurde. Dementsprechend loopen wir getChannelGroup(), bis wir den Rückgabewert FMOD.RESULT.OK erhalten. Mit channelGroup.getDSP() holen wir uns die Adresse einer Variable, um einen Pointer auf die angeforderte DSP-Einheit zu empfangen. Mit setMeteringEnabled() aktivieren wir das Output-Metering.

    Im nächsten Schritt erstellen wir eine Methode, die den RMS-Pegel als Float-Variable zurückgibt:

    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;
        }

    Nun können wir im Code über GetRMS() auf den RMS-Pegel zugreifen. Ich habe im Unity-Projekt den Wert wieder einfach per Text visualisiert:

    FMOD RMS in Unity visualisiert
    FMOD RMS in Unity visualisiert