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: