FMOD,用于录音的自定义DSP,如何?
FMOD, Custom DSP for audio recording, how to?
所以我对 FMOD 很陌生。我在游戏的视频编码器中工作,基本上我将帧缓冲区和音频缓冲区发送到我的本机 dll,它通过 ffmpeg 对其进行编码。现在,我正在尝试获取每个“音频帧”的音频缓冲区,据我所知,这样做的方法是创建一个自定义 DSP,将其附加到头部(或之前)并将缓冲区复制过来。
这是我的代码(C#):
自定义 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;
}
}
我的“添加DSP”代码:
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);
你可以看看我的“Try 1”和“Try 2”……当我使用“Try 1”时,我让它在启动时调用我的 DSP 几次,然后它停止调用它。 (这是我最困惑的事情)
使用“尝试 2”,我的 DSP 永远不会被调用......
我已经尝试了所有不同的连接类型(STANDARD、SIDE_CHAIN、SEND...)
那我错过了什么?我的理解正确吗?
提前致谢!!
所以我发现了问题。 DSP 被定义为托管内存中的对象(在 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;
}
}
但是对 FMOD 的调用是本机调用,我没有保留对 FMOD_AudioRecodingDSP 对象实例的引用。所以 GC 最终删除了该实例。解决方案是将 class 设为静态,并将函数指针传递给静态函数。
所以我对 FMOD 很陌生。我在游戏的视频编码器中工作,基本上我将帧缓冲区和音频缓冲区发送到我的本机 dll,它通过 ffmpeg 对其进行编码。现在,我正在尝试获取每个“音频帧”的音频缓冲区,据我所知,这样做的方法是创建一个自定义 DSP,将其附加到头部(或之前)并将缓冲区复制过来。
这是我的代码(C#):
自定义 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;
}
}
我的“添加DSP”代码:
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);
你可以看看我的“Try 1”和“Try 2”……当我使用“Try 1”时,我让它在启动时调用我的 DSP 几次,然后它停止调用它。 (这是我最困惑的事情) 使用“尝试 2”,我的 DSP 永远不会被调用......
我已经尝试了所有不同的连接类型(STANDARD、SIDE_CHAIN、SEND...)
那我错过了什么?我的理解正确吗?
提前致谢!!
所以我发现了问题。 DSP 被定义为托管内存中的对象(在 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;
}
}
但是对 FMOD 的调用是本机调用,我没有保留对 FMOD_AudioRecodingDSP 对象实例的引用。所以 GC 最终删除了该实例。解决方案是将 class 设为静态,并将函数指针传递给静态函数。