【发布时间】:2018-05-08 18:53:32
【问题描述】:
我正在用纯 C++ 开发 Asteroid 的克隆,为此,我需要为不同的事件添加声音,例如子弹发射时和爆炸发生时。但问题是我对音频库没有任何经验。
我正在使用简单的 DirectMedia 层 (SDL) 并编写了一个名为 playsound() 的函数来播放声音以防发生特定事件。然而问题在于,如果发生事件,会调用 playsound() 并且代码执行会停止,直到声音完全播放完或直到我从函数返回(我使用 delay func 延迟返回)。
我想做的是让声音在后台播放,而不会为游戏的其余部分造成任何延迟。我正在 Ubuntu 16.04 上开发,不能使用 Windows PlaySound() 来调用 ASYNC 标志。
函数如下:
void playsound(string path) {
// Initialize SDL.
if (SDL_Init(SDL_INIT_AUDIO) < 0)
return;
// local variables
Uint32 wav_length; // length of our sample
Uint8 *wav_buffer; // buffer containing our audio file
SDL_AudioSpec wav_spec;
if(SDL_LoadWAV(path.c_str(), &wav_spec, &wav_buffer, &wav_length) == NULL){
return;
}
SDL_AudioDeviceID deviceId = SDL_OpenAudioDevice(NULL, 0, &wav_spec, NULL, 0);
SDL_QueueAudio(deviceId, wav_buffer, wav_length);
SDL_PauseAudioDevice(deviceId, 0);
SDL_Delay(50);
SDL_CloseAudioDevice(deviceId);
SDL_FreeWAV(wav_buffer);
SDL_Quit();
}
【问题讨论】:
-
我建议选择一个合适的音频库,例如开放式。 SDL 音频接口相当欠缺。
-
我不明白这个问题,很明显你已经知道延迟是你的障碍。您是否认为您需要在每次播放声音时初始化 SDL、打开音频设备、关闭它并取消初始化 SDL?您是否将 SDL 用于其他事情或仅用于音频(因为
SDL_Quit在这里破坏了一切)?您需要并行播放多个声音吗?消除此操作的延迟并稍后执行清理似乎有什么问题? -
是的,我确实需要并行播放多个声音。我第一次使用 SDL,但并不知道我可以随时退出 SDL。我想我必须在我遵循的教程中告诉我之后不久就这样做。原谅我的无知。顺便说一句,我找到了一个使用 SDL_Mixer 的lazyfoo 教程,并且能够做我想做的事。无论如何,感谢您的帮助,我确实了解您的要点。如果您可以将其作为其他用户的答案,我将很乐意接受。
标签: c++ asynchronous audio sdl-2