How can I get the output level of an event in unity?

(Veli-Pekka Oksanen) #1

I’m new to FMOD and we’re creating a game where we need to get the output levels (how loud the sound is) of certain events to dynamically change a light component’s values in a gameobject according to the sound coming out of a FMOD StudioEventEmitter. I have been able to access the emitter and event instance as an asset of that emitter. Using .getVolume(out volume) and .getPitch(out pitch) return 1 every time.

(Nicholas Wilcox) #2

Get the instances channel group, then get the DSP head. then use DSP.setMeteringEnabled to turn on metering. This will let you call DSP.getMeteringInfo() every frame.

I think this has been asked on the Q&A before. You might be able to find code if you search.

(Veli-Pekka Oksanen) #3

Thx for your reply, I was finally able to figure it out (at some level). This is the code that got it working for me, it’s propably not very clean and full of unnecessary stuff but it works and I’m glad. The idea is that I have a gameobject that handles collecting sound output levels from a bunch of other gameobjects with FMOD emitters. There’s a spotlight attached to the gameobject and it’s range and intensity change according to the sum of sound output coming from those emitters.

// Code starts here
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using FMOD.Studio;

public class AmbientSoundScript : MonoBehaviour
// Attributes for the lights that we want to change
private Light light;
private float lightIntensity;
private float lightRange;

// FMOD stuff
float sum = 0;
public List<GameObject> sounds;
public List<FMOD_StudioEventEmitter> emitters;
public List<EventDescription> eventDescriptions;
List<FMOD.Studio.EventInstance> events;
List<FMOD.ChannelGroup> channelgroups;
List<FMOD.DSP> dsps;
public FMOD.Studio.System system;

// Use this for initialization
void Start()
    // Get the light stuff
    light = GetComponent<Light>();
    lightIntensity = light.intensity;
    lightRange = light.range;

    // Make variables for FMOD
    output = new FMOD.DSP_METERING_INFO();
    events = new List<EventInstance>();
    channelgroups = new List<FMOD.ChannelGroup>();
    dsps = new List<FMOD.DSP>();
    system = FMOD_StudioSystem.instance.System;
    FMOD.ChannelGroup group;
    FMOD.Studio.EventInstance evt1;
    FMOD.Studio.EventDescription evtDesrcription;

    // The hard part
    foreach (GameObject s in sounds)
    foreach (FMOD_StudioEventEmitter emitter in emitters)
        system.getEvent(emitter.asset.path, out evtDesrcription);
        evtDesrcription.createInstance(out evt1);

    foreach (FMOD.Studio.EventInstance evt in events)
        evt.getChannelGroup(out group);

    FMOD.DSP dsp;
    foreach (FMOD.ChannelGroup cg in channelgroups)
        cg.getDSP(0, out dsp);
        dsp.setMeteringEnabled(true, true);

// Update is called once per frame
void Update()
    // Get the output for all the DSPS in the list and sum them
    foreach (FMOD.DSP dsp in dsps)
        dsp.getMeteringInfo(null, output);
        float outpeaks = output.peaklevel[0] + output.peaklevel[1];
        float rmss = output.rmslevel[0] + output.rmslevel[1];
        sum += outpeaks + rmss;

    // Modify the lighting according to meter readings
    light.range = lightRange + sum * 3;
    light.intensity = lightIntensity + sum * 3;
    sum = 0;

// Code ends here

Through elimination I figured out that only output.peaklevel[0] and [1]
and rmslevel[0] and [1] have values > 0 in my case so I didn’t bother collecting them all. This might vary so if you try this code you might have to change that. Hope this will be of any use to someone.