我正在尝试使用 portaudio 库和 ASIO sdk 从我的吉他获取输入以通过我的计算机播放。
我一直在关注官方网站上的一些教程来设置基础知识。目前我让它工作了,所以 portaudio 正在监听正确的输入和输出设备,我有回调设置来输出输入并且像这样不做任何事情:
static int paTestCallback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *userData)
{
float *out = (float*)outputBuffer;
float* in = (float*)inputBuffer;
for (int i = 0; i<framesPerBuffer; i++)
{
*out++ = *in++; /* left */
*out++ = *in++; /* right */
}
return 0;
}
这个回调是通过调用这个来设置的:
PaError error = Pa_OpenDefaultStream(&stream, 2, 2, paFloat32, 44100, paFramesPerBufferUnspecified, paTestCallback, &data);
Pa_StartStream(stream);
现在,这确实有效,但是当我在吉他上敲弦并通过监视器听到它时,我有很多延迟(大约 0.5 秒)。
有没有办法解决这个延迟?我需要重写回调方法吗?
编辑:
因此,使用此代码而不是基本代码,我得到了更好的延迟Pa_OpenDefaultStream()
int defaultIn = Pa_GetDefaultInputDevice();
int defaultOut = Pa_GetDefaultOutputDevice();
PaStreamParameters *inParam = new PaStreamParameters();
inParam->channelCount = 2;
inParam->device = defaultIn;
inParam->sampleFormat = paFloat32;
inParam->suggestedLatency = 0.05;
PaStreamParameters *outParam = new PaStreamParameters();
outParam->channelCount = 2;
outParam->device = defaultOut;
outParam->sampleFormat = paFloat32;
outParam->suggestedLatency = 0;
error = Pa_OpenStream(&stream, inParam, outParam, 44100, paFramesPerBufferUnspecified, paNoFlag, paTestCallback, &data);
if (error != paNoError) {
Logger::log("[PortAudioManager] Could not open default stream. Exiting function...");
return;
}
Pa_StartStream(stream);
虽然仍然有一点延迟,但在演奏多于一个音符时最明显。
编辑:
我在 Ross-Bencina 的帮助下发现 Windows 默认输入设备和输出设备不会对 PortAudio 中的主机 api 的索引进行任何更改。我似乎一直在使用 MME。我执行了以下操作以获得 ASIO 设备的正确索引:
int hostNr = Pa_GetHostApiCount();
std::vector<const PaHostApiInfo*> infoVertex;
for (int t = 0; t < hostNr; ++t) {
infoVertex.push_back(Pa_GetHostApiInfo(t));
}
然后我检查了哪个是带有 ASIO 的,并将建议的延迟都设置PaStreamParameters
为 0,延迟现在消失了,声音很好(虽然现在是单声道)。