So I’m quite new to FMOD. I’m working in a video encoder for a game, basically I send the frame buffer and audio buffer to my native dll which encodes it via ffmpeg. Now, I’m trying to get the audio buffer each “audio frame” and the way to do that as I understand it is by creating a custom DSP, attach it to the head (or just before) and copy the buffer over.
So here is my code (it’s c#):
Custom DSP:
public class FMOD_AudioRecodingDSP
{
public static DSP_DESCRIPTION CreateDSPDesc(out FMOD_AudioRecodingDSP dspObj)
{
dspObj = new FMOD_AudioRecodingDSP();
var desc = new DSP_DESCRIPTION()
{
name = "AudioExport".ToCharArray(),
version = 1,
numinputbuffers = 1,
numoutputbuffers = 1,
read = dspObj.ReadAudioData,
};
return desc;
}
public RESULT ReadAudioData(ref DSP_STATE dsp_state, IntPtr inbuffer, IntPtr outbuffer, uint length, int inchannels, ref int outchannels)
{
UnityEngine.Debug.Log("Working???");
outbuffer = inbuffer;
outchannels = inchannels;
return RESULT.OK;
}
}
My “add DSP” code:
FMOD.ChannelGroup master;
lowlevelSystem.getMasterChannelGroup(out master);
master.getDSP(0, out mixerHead);
mixerHead.setMeteringEnabled(false, true);
// Trying to get a custom DSP in to FMOD to record audio for video
FMOD.RESULT res = FMOD.RESULT.OK;
uint dspHandle;
FMOD.DSP_DESCRIPTION dspDesc = FMOD_AudioRecodingDSP.CreateDSPDesc(out DSPObject);
res = lowlevelSystem.registerDSP(ref dspDesc, out dspHandle);
res = lowlevelSystem.createDSP(ref dspDesc, out AudioRecordingDSP);
// Try 1
//res = master.addDSP(0, AudioRecordingDSP);
//
// Try 2
FMOD.DSP limiterDSP;
res = master.getDSP(1, out limiterDSP);
FMOD.DSPConnection conType;
res = AudioRecordingDSP.addInput(limiterDSP, out conType, FMOD.DSPCONNECTION_TYPE.SIDECHAIN);
res = AudioRecordingDSP.setActive(true);
res = AudioRecordingDSP.setBypass(false);
You can se my “Try 1” and “Try 2″… When I use “Try 1” I get it to call my DSP for a few times at startup, then it stops calling it. (This is the most confusing thing to me) With “Try 2” my DSP never gets called…
I've tried all the different connection types (STANDARD, SIDE_CHAIN, SEND...)
So what am I missing? Do I understand it correct?
Thanks In Advance!!
So I found the problem. The DSP was defined as a object in managed memory (in C#):
public class FMOD_AudioRecodingDSP
{
public static DSP_DESCRIPTION CreateDSPDesc(out FMOD_AudioRecodingDSP dspObj)
{
dspObj = new FMOD_AudioRecodingDSP();
var desc = new DSP_DESCRIPTION();
return desc;
}
}
But the call to FMOD is a native call and I did not keep a reference to my FMOD_AudioRecodingDSP object instance. So the GC eventually removed the instance. The solution was to make the class static and just pass the function pointer to the static function.