我试图基于这个帖子创建一个VSTstream类:http://vstnet.codeplex.com/discussions/228692。
使用AsioOut
对象录制和播放声音,使我可以在回调函数IntPtr[]
中输入OnAudioAvailable()
缓冲区。
为此,我创建了VSTstream
类,从链接的线程中获取示例,进行适当修改以直接处理IntPtr[]
缓冲区。
在各种投射过程中,它会给我一个" AccessViolationException "的错误,可能是因为投射错误。
我正在测试打开 Jacobi.Vst.Samples.Delay.dll
的VSTstream
类
编辑:此行发生错误:
Marshal.Copy(sourceBuffer[1], rightBuf, 0, sampleCount/channels);
有谁知道我做错了什么?如果您需要我可用的其他信息或代码。
感谢所有人。
OnAudioAvailable():
private void OnAudioAvailable(object sender, AsioAudioAvailableEventArgs e)
{
//No Effect
for (int i = 0; i < e.InputBuffers.Length; i++)
{
MoveMemory(e.OutputBuffers[i], e.InputBuffers[i], e.SamplesPerBuffer * e.InputBuffers.Length * 2);
}
//Effect
if (Parametri.effetto)
{
//Accendo i plugin
for (int i = 0; i < plugins.Count; i++)
{
plugins[i].MainsChanged(true);
plugins[i].StartProcess();
}
//Processo i sample
vstStream.ProcessSample(e.OutputBuffers, 0, e.SamplesPerBuffer * e.InputBuffers.Length * 2, e.InputBuffers);
//Spengo i plugin
for (int i = 0; i < plugins.Count; i++)
{
plugins[i].StopProcess();
plugins[i].MainsChanged(false);
}
}
e.WrittenToOutputBuffers = true;
}
VSTstream类:
class VSTstream
{
public List<IVstPluginCommandStub> plugins;
VstAudioBufferManager vstBufManIn, vstBufManOut;
private VstAudioBuffer[] vstBufIn = null;
private VstAudioBuffer[] vstBufOut = null;
private int sampleRate, channels, blockSize;
private float[] leftBuf, rightBuf;
public VSTstream(int sampleRate, int channels, int blockSize, List<IVstPluginCommandStub> plugins)
{
this.plugins = plugins;
this.sampleRate = sampleRate;
this.channels = channels;
this.blockSize = blockSize;
plugins[0].SetBlockSize(blockSize);
plugins[0].SetSampleRate((float)sampleRate);
vstBufManIn = new VstAudioBufferManager(channels, blockSize); //*channels
vstBufManOut = new VstAudioBufferManager(channels, blockSize);
//vstBufIn = vstBufManIn.ToArray();
//vstBufOut = vstBufManOut.ToArray();
vstBufIn = vstBufManIn.Cast<VstAudioBuffer>().ToArray();
vstBufOut = vstBufManOut.Cast<VstAudioBuffer>().ToArray();
leftBuf = new float[(blockSize * 4)/channels];
rightBuf = new float[(blockSize * 4)/channels];
}
public int ProcessSample(IntPtr[] destBuffer, int offset, int sampleCount, IntPtr[] sourceBuffer)
{
//da IntPtr[L][R] a Lfloat[]+Rfloat[]
Marshal.Copy(sourceBuffer[0], leftBuf, 0, sampleCount/channels);// (/channels)
Marshal.Copy(sourceBuffer[1], rightBuf, 0, sampleCount/channels);
unsafe
{
fixed (float* Lfloat = &leftBuf[0])
{
fixed (float* Rfloat = &rightBuf[0])
{
for (int i = 0; i < sampleCount / channels; i++)
{
vstBufIn[0][i] = *(Lfloat + i);
vstBufIn[1][i] = *(Rfloat + i);
}
}
}
}
//Qui dovrà rimanere solo 'ProcessReplacing();'
//plugins[0].MainsChanged(true);
//plugins[0].StartProcess();
plugins[0].ProcessReplacing(vstBufIn, vstBufOut);
//plugins[0].StopProcess();
//plugins[0].MainsChanged(false);
unsafe
{
float* tmpBufL = ((IDirectBufferAccess32)vstBufOut[0]).Buffer;
float* tmpBufR = ((IDirectBufferAccess32)vstBufOut[1]).Buffer;
for (int i = 0; i < (sampleCount / channels); i++)
{
leftBuf[i] = *(tmpBufL + i);
rightBuf[i] = *(tmpBufR + i);
}
}
//da Lfloat[]+Rfloat[] a IntPtr[L][R]
Marshal.Copy(leftBuf, 0, destBuffer[0], sampleCount/channels);
Marshal.Copy(rightBuf, 0, destBuffer[1], sampleCount/channels);
return sampleCount;
}
}