Ok, so I’ve been trying to work this out. No full luck yet, but I’m a little further than before.
I’ve compared the script that analyses the event sound and puts the data in an array, and I figured out how to properly pass thru the unmanaged data with the mic. The thing now is that I keep on getting an “Out of Bounds error” when it tries to parse it over to an readable array.
using UnityEngine;
using System;
using System.Text;
using System.Runtime.InteropServices;
using System.Collections;
public class MicSound : MonoBehaviour
{
// mic decs
public bool m_isrecording;
public FMOD.Sound m_Sound;
public string mic;
public int systemRate, speakerModeChannels;
public FMOD.SPEAKERMODE speakerMode = FMOD.SPEAKERMODE.RAW;
public FMOD.DRIVER_STATE driverState = FMOD.DRIVER_STATE.DEFAULT;
public int numDriv, numCon;
FMOD.RESULT m_Result;
FMOD.MODE soundMode = FMOD.MODE.OPENUSER | FMOD.MODE.LOOP_NORMAL;
FMOD.CREATESOUNDEXINFO exinfo;
// data decs
public float m_fftArray;
[FMODUnity.EventRef] public string m_eventRef;
FMOD.Studio.EventInstance m_eventInstance;
public FMOD.ChannelGroup m_channelGroup;
public FMOD.Channel channel;
FMOD.DSP m_fftDsp;
public bool m_dspAdded;
// general
public bool playSound;
public float delayTime = .05f;
public bool makingSound;
public int WINDOWSIZE = 1024;
void Awake()
{
// * instance event
m_eventInstance = FMODUnity.RuntimeManager.CreateInstance(m_eventRef);
// set up mic
FMODUnity.RuntimeManager.CoreSystem.getRecordDriverInfo(0, out mic, 1, out Guid guid, out systemRate, out speakerMode, out speakerModeChannels, out driverState);
FMODUnity.RuntimeManager.CoreSystem.getRecordNumDrivers(out numDriv, out numCon);
exinfo.cbsize = Marshal.SizeOf(exinfo);
exinfo.numchannels = speakerModeChannels;
exinfo.format = FMOD.SOUND_FORMAT.PCM16;
exinfo.defaultfrequency = systemRate;
exinfo.length = (uint)(exinfo.defaultfrequency * exinfo.numchannels * sizeof(short)) * 8;
// * data array to be filled
m_fftArray = new float[WINDOWSIZE];
// making the mic sound
m_Result = FMODUnity.RuntimeManager.CoreSystem.createSound(mic, soundMode, ref exinfo, out m_Sound);
if (m_Result != FMOD.RESULT.OK)
{
UnityEngine.Debug.Log("failed to createSound: " + m_Result);
return;
}
m_Result = FMODUnity.RuntimeManager.CoreSystem.recordStart(0, m_Sound, true);
if (m_Result != FMOD.RESULT.OK)
{
UnityEngine.Debug.Log("failed to startrecord: " + m_Result);
}
else
{
m_isrecording = true;
UnityEngine.Debug.Log("Recording " + m_Result);
}
// starting the event instance
StartEventInstance();
// adding a delay
StartCoroutine(AddDelay(delayTime));
}
void Update()
{
// dsp
if (m_dspAdded && speakerModeChannels > 0)
{
IntPtr unmanagedData;
uint length;
m_Result = m_fftDsp.getParameterData((int)FMOD.DSP_FFT.SPECTRUMDATA, out unmanagedData, out length);
Debug.Log("unmanData " + unmanagedData + " length " + length + " channels " + speakerModeChannels); //passes
FMOD.DSP_PARAMETER_FFT m_DataParam = (FMOD.DSP_PARAMETER_FFT)Marshal.PtrToStructure(unmanagedData, typeof(FMOD.DSP_PARAMETER_FFT));
if (m_DataParam.numchannels > 0)
{
Debug.Log("Failure");
return;
}
// Debug.Log("DataParam " + m_DataParam.spectrum[0][0]); //error
for (int bin = 0; bin < WINDOWSIZE; bin++)
{
float temp = lin2DB(m_DataParam.spectrum[0][bin]);
temp = ((temp + 80.0f) * (1 / 80.0f));
m_fftArray[bin] = Mathf.Lerp(m_fftArray[bin], temp, 0.6f);
}
}
}
bool StartEventInstance()
{
m_eventInstance.start();
return true;
}
IEnumerator AddDelay(float seconds)
{
yield return new WaitForSeconds(seconds);
if (playSound)
{
FMODUnity.RuntimeManager.CoreSystem.playSound(m_Sound, m_channelGroup, false, out channel);
}
// dsp
StartCoroutine(AddDspToChannel());
m_eventInstance = FMODUnity.RuntimeManager.CreateInstance(m_eventRef);
}
float lin2DB(float linear)
{
return (Mathf.Clamp(Mathf.Log10(linear) * 20, -80.0f, 0.0f));
}
IEnumerator AddDspToChannel()
{
while (!m_channelGroup.hasHandle())
{
m_eventInstance.getChannelGroup(out m_channelGroup);
yield return null;
}
FMODUnity.RuntimeManager.CoreSystem.createDSPByType(FMOD.DSP_TYPE.FFT, out m_fftDsp);
m_fftDsp.setParameterInt((int)FMOD.DSP_FFT.WINDOWTYPE, (int)FMOD.DSP_FFT_WINDOW.RECT);
m_fftDsp.setParameterInt((int)FMOD.DSP_FFT.WINDOWSIZE, WINDOWSIZE * 2);
m_channelGroup.addDSP(FMOD.CHANNELCONTROL_DSP_INDEX.TAIL, m_fftDsp);
m_dspAdded = true;
}
void OnDestroy()
{
m_eventInstance.stop(FMOD.Studio.STOP_MODE.IMMEDIATE);
m_eventInstance.release();
}}
Here’s a video where I notice the difference. In the script you’ve made, the parsing works perfectly fine, but when I try to do the same, with the (as far as I can tell) same declarations and code used, it just doesnt parse. Debugging the raw data also works on the code you’ve written, but not on mine.
Hope to hear from you soon,
Niels ![]()