我在 Linux 上使用 PortAudio 编写了一个小型声音播放库。因为是小游戏,所以各种事情发生的时候都会有很多小声音。我通过调用 Pa_OpenStream() 为每个要播放的 wav 文件打开一个流。在 linux 上,这个调用平均需要 10 毫秒左右。但是在 Windows 上,这通常需要 40 到 70 毫秒。更糟糕的是,第一次通话需要 1.3 秒。然后偶尔会再次需要 1.3 秒。除了每次第一次通话都会发生这种情况外,我无法找到任何一致的关于它挂起的原因。Windows 构建实际上在 Wine 上运行良好。
我认为这与不同系统中使用的底层声音 API 的差异有关。但奇怪的是,尽管进行了广泛的搜索,但我在任何地方都没有找到任何信息。
这是我的播放功能:
int play(const char * sN)
{
float threshold = .01f;
char * soundName = (char*)sN;
float g = glfwGetTime();
updatePlayer();
float g2 = glfwGetTime();
if (g2-g > threshold) printf("updatePlayer: %f/", g2 - g);
if (!paused && (int)streams.size() < maxStreams && !mute)
{
streamStr * ss = new streamStr;
g = glfwGetTime();
if (g-g2 > threshold) printf("new stream: %f/", g - g2);
PaError err;
sfData * sdata = getData(soundName);
ss->sfd = sdata;
g2 = glfwGetTime();
if (g2-g > threshold)printf("getData: %f/", g2 - g);
err = Pa_OpenStream(&(ss->stream), 0, &sdata->outputParameters, sdata->sfInfo.samplerate, paFramesPerBufferUnspecified, paNoFlag, PaCallback, ss);
if (err)
{
printf("PortAudio error opening output: %s\n", Pa_GetErrorText(err));
delete ss;
return 1;
}
g = glfwGetTime();
if (g-g2 > threshold)
printf("Pa_OpenStream: %f/", g - g2);
Pa_StartStream(ss->stream);
g2 = glfwGetTime();
if (g2-g > threshold)printf("Pa_StartStream: %f/", g2 - g);
addStreams(ss);
g = glfwGetTime();
if (g-g2 > threshold)printf("addStreams: %f", g - g2);
//Pa_SetStreamFinishedCallback(ss, finishedCallback);
printf("\n");
}
return 0;
}