我需要使用 PaStreamCallbackDelegate 将回调函数传递给 Pa_OpenDefaultStream ,以便我可以启动Stream。 我像你一样在互联网上查看,但也按照描述进行操作,它给了我这个错误:
对应于委托PortAudio.PaStreamCallbackDelegate
的StreamCallback没有重载我不知道如何解决它。我对 C#语言知之甚少,我现在才开始使用库 PortAudio 。
我在这里发布我的代码:
unsafe public PortAudio.PaStreamCallbackResult StreamCallback(
IntPtr* input,
IntPtr* output,
uint frameCount,
ref PortAudio.PaStreamCallbackTimeInfo timeInfo,
PortAudio.PaStreamCallbackFlags statusFlags,
IntPtr* userData)
{
//Aggiungi roba
int i;
for (i = 0; i < frameCount; i++)
{
output++; //LEFT
output = input++;
output++; //RIGHT
output = input++;
}
return PortAudio.PaStreamCallbackResult.paContinue;
}
unsafe private void btnStream_Click(object sender, EventArgs e)
{
//Dichiarazioni
IntPtr* input;
IntPtr* output;
uint frameCount;
PortAudio.PaStreamCallbackTimeInfo timeInfo;
PortAudio.PaStreamCallbackFlags statusFlags;
IntPtr* userData;
IntPtr stream;
PortAudio.PaError err = PortAudio.Pa_Initialize();
if (err != PortAudio.PaError.paNoError)
PortAudio.Pa_Terminate();
err = PortAudio.Pa_OpenDefaultStream(out stream,
1,
1,
(uint)PortAudio.PaSampleFormat.paFloat32,
44100,
PortAudio.paFramesPerBufferUnspecified,
new PortAudio.PaStreamCallbackDelegate(StreamCallback), //In this row it gives me the error
(IntPtr)null);
如果有人知道如何帮助我,我将非常感激,谢谢。
答案 0 :(得分:1)
您的输入,输出和用户数据参数应为IntPtr
类型,而不是IntPtr*
此外,我认为你并没有在你的回调方法中制作副本。我真的认为你应该使用一些IntPtr
方法。我从未在.Net中使用不安全的类型,但是查看copy sample我相信你的算法会是这样的:
unsafe public PortAudio.PaStreamCallbackResult StreamCallback(
IntPtr input, IntPtr output, uint frameCount,
ref PortAudio.PaStreamCallbackTimeInfo timeInfo,
PortAudio.PaStreamCallbackFlags statusFlags,
IntPtr userData)
{
byte *src = (byte *)input.ToPointer();
byte *dst = (byte *)output.ToPointer();
for (int i = 0; i < frameCount; i++)
{
*dst++ = *src++;//in c this could be written dst[i] = src[i] maybe you can try that.
}
return PortAudio.PaStreamCallbackResult.paContinue;
}
编辑:根据Hans Passant的说法,您还应该将您的代理人保存在一个字段中,这样就不会收集垃圾。但 AFAIK 将它存储在变量中就足够了,因为只要至少有一个对象的引用,垃圾收集就不会清理你的对象。这仅适用于回调发生在定义它的同一方法中,否则您应该存储在他声明的字段中。
unsafe private void btnStream_Click(object sender, EventArgs e)
{
//Dichiarazioni
IntPtr* input;
IntPtr* output;
uint frameCount;
PortAudio.PaStreamCallbackTimeInfo timeInfo;
PortAudio.PaStreamCallbackFlags statusFlags;
IntPtr* userData;
IntPtr stream;
PortAudio.PaError err = PortAudio.Pa_Initialize();
var callback = new PortAudio.PaStreamCallbackDelegate(StreamCallback);
if (err != PortAudio.PaError.paNoError)
PortAudio.Pa_Terminate();
err = PortAudio.Pa_OpenDefaultStream(out stream, 1, 1,
(uint)PortAudio.PaSampleFormat.paFloat32,
44100,
PortAudio.paFramesPerBufferUnspecified,
callback,
(IntPtr)null);