我制作了一个可以使用SDL的音频功能播放声音的课程。
类看起来像这样:
class AudioDevice {
public:
AudioDevice() = default;
~AudioDevice() noexcept;
AudioDevice(const AudioDevice&) = delete;
AudioDevice(AudioDevice&&) = delete;
AudioDevice& operator=(const AudioDevice&) = delete;
AudioDevice& operator=(AudioDevice&&) = delete;
void playSound(const std::string& filename);
private:
SDL_AudioSpec mAudioSpec;
SDL_AudioDeviceID mAudioDeviceId{0};
Uint32 mLength;
Uint8 *mBuffer;
bool mIsActive{false};
};
AudioDevice::~AudioDevice() noexcept {
if(mIsActive) {
SDL_FreeWAV(mBuffer);
SDL_CloseAudioDevice(mAudioDeviceId);
}
}
void AudioDevice::playSound(const std::string& filename)
{
if(mIsActive) {
std::cerr<< "free wav";
SDL_FreeWAV(mBuffer);
}
if(SDL_LoadWAV(filename.c_str(), &mAudioSpec, &mBuffer, &mLength)
== NULL) {
std::cerr<< "SLD_LoadWAV not succesfull\n"
<< SDL_GetError() << '\n';
return;
}
if(!mIsActive) {
mAudioDeviceId = SDL_OpenAudioDevice(NULL, 0, &mAudioSpec, NULL, 0);
if(mAudioDeviceId == 0) {
std::cerr << "SDL_Open Audio Not Successfull:\n"
<< std::string(SDL_GetError()) << "\n" <<
"Device ID:" << std::to_string(mAudioDeviceId) << "\n";
}
}
if(SDL_QueueAudio(mAudioDeviceId, mBuffer, mLength) == -1) {
std::cerr << "SDL_QueueAudio not succesfull\n"
<< SDL_GetError() << '\n';
SDL_FreeWAV(mBuffer);
return;
}
SDL_PauseAudioDevice(mAudioDeviceId, 0);
mIsActive = true;
}
如果我使用这样的类,则会得到以下行为:
播放声音1 然后,在播放声音1时,我要求播放声音2。 我希望声音1停止播放,声音2播放。 但是,声音1仍会播放,声音2会在延迟后播放。
我本来想避免制作新的SDL_OpenAudioDevice
,但由于创建成本高昂,整个游戏开始变得滞后。
有没有办法停止播放第一个声音并立即播放下一个即将出现的声音?
我认为SDL_FreeWAV(mBuffer)
可以解决问题,但不能解决。那我该怎么办?