Answered
0
0

Hey all! I’m new to FMOD and I’m using it to create an audio visualizer in Unity (so I’m using c#). I have the visualizer working using the getSpectrum function from Unity’s native audio engine, but I’d like to switch to FMOD. Unfortunately, I’m unsure of how exactly to do this.

From what I understand, I need to create a custom DSP, add it to my master channel, and then use the getParameterData function on it in update in order to get the frequency spectrum at every frame.

I suppose my question is…where exactly in my code am I supposed to add the DSP? From looking through the code, it seems the system created by FMOD is only accessible in some editor scripts (from which I cannot call functions), and in a script called “RuntimeManager.cs.” Is RuntimeManager.cs where I’m supposed to add the DSP? Thanks in advanced!

  • You must to post comments
Best Answer
1
0

Here’s an example I wrote but never included in the docs due to lack of polish

using System;
using UnityEngine;
using System.Runtime.InteropServices;

class ScriptUsageLowLevel : MonoBehaviour
{
    FMOD.Studio.EventInstance musicInstance;
    FMOD.DSP fft;

    LineRenderer lineRenderer;

    const int WindowSize = 1024;

    void Start()
    {        
        lineRenderer = gameObject.AddComponent<LineRenderer>();
        lineRenderer.SetVertexCount(WindowSize);
        lineRenderer.SetWidth(.1f, .1f);

        musicInstance = FMODUnity.RuntimeManager.CreateInstance("event:/Music/Basic/Random Layered");


        FMODUnity.RuntimeManager.LowlevelSystem.createDSPByType(FMOD.DSP_TYPE.FFT, out fft);
        fft.setParameterInt((int)FMOD.DSP_FFT.WINDOWTYPE, (int)FMOD.DSP_FFT_WINDOW.HANNING);
        fft.setParameterInt((int)FMOD.DSP_FFT.WINDOWSIZE, WindowSize * 2);

        FMOD.ChannelGroup channelGroup;
        FMODUnity.RuntimeManager.LowlevelSystem.getMasterChannelGroup(out channelGroup);
        channelGroup.addDSP(FMOD.CHANNELCONTROL_DSP_INDEX.HEAD, fft);

        musicInstance.start();
    }

    const float WIDTH = 10.0f;
    const float HEIGHT = 0.1f;

    void Update()
    {
        IntPtr unmanagedData;
        uint length;
        fft.getParameterData((int)FMOD.DSP_FFT.SPECTRUMDATA, out unmanagedData, out length);
        FMOD.DSP_PARAMETER_FFT fftData = (FMOD.DSP_PARAMETER_FFT)Marshal.PtrToStructure(unmanagedData, typeof(FMOD.DSP_PARAMETER_FFT));
        var spectrum = fftData.spectrum;

        if (fftData.numchannels > 0)
        {
            var pos = Vector3.zero;
            pos.x = WIDTH * -0.5f;

            for (int i = 0; i < WindowSize; ++i)
            {
                pos.x += (WIDTH / WindowSize);

                float level = lin2dB(spectrum[0][i]);
                pos.y = (80 + level) * HEIGHT;

                lineRenderer.SetPosition(i, pos);
            }
        }
    }

    float lin2dB(float linear)
    {
        return Mathf.Clamp(Mathf.Log10(linear) * 20.0f, -80.0f, 0.0f);
    }
}
  • Thomas

    You are a lifesaver! Thanks a bunch :)

  • You must to post comments
0
0

Hey @NicholasWilcox I keep getting 0 channels listed for my fft spectrum, any idea why that may be?

–edit : nvm, I think it was because I was creating a song instead of an instance

  • Cameron Baron

    Check the return of the FMOD functions, most will return a FMOD_RESULT.
    Specifically check addDSP().
    Also, it may sound obvious but make sure the sound is playing before trying to read the data.

  • Karen

    Hey Cameron thanks yeah, it was playing, but I was also just using a stand alone song which didn’t seem to read anything. As soon as I created an instance it worked perfectly! ?

  • You must to post comments
Showing 2 results
Your Answer

Please first to submit.