Ваша задержка препятствует выполнению вашего кода, задержка 50 мс - это почти 2 кадра при 33 мс на кадр или 3 кадра при 16 мс на кадр, с пропуском кадра здесь, и может не быть проблем, но вы могли видеть, как вызывать несколько звуков подряд замедлят вашу программу.
Вот так я воспроизводю звуки в своем движке, используя SDL2_mixer (короткие звуки, для музыки у вас есть другой метод, называемый Mix_PlayMusic), он может быть вам полезен. У меня нет задержки (и я не использую сон или задержки в моем коде). Как только вы вызываете play (), звук должен воспроизводиться полностью, если только ваш код не останавливает что-либо еще.
#pragma once
#include <string>
#include <memory>
#include <SDL2/SDL_mixer.h>
class sample {
public:
sample(const std::string &path, int volume);
void play();
void play(int times);
void set_volume(int volume);
private:
std::unique_ptr<Mix_Chunk, void (*)(Mix_Chunk *)> chunk;
};
и файл cpp
#include <sample.h>
sample::sample(const std::string &path, int volume)
: chunk(Mix_LoadWAV(path.c_str()), Mix_FreeChunk) {
if (!chunk.get()) {
// LOG("Couldn't load audio sample: ", path);
}
Mix_VolumeChunk(chunk.get(), volume);
}
// -1 here means we let SDL_mixer pick the first channel that is free
// If no channel is free it'll return an err code.
void sample::play() {
Mix_PlayChannel(-1, chunk.get(), 0);
}
void sample::play(int times) {
Mix_PlayChannel(-1, chunk.get(), times - 1);
}
void sample::set_volume(int volume) {
Mix_VolumeChunk(chunk.get(), volume);
}
Обратите внимание, что мне не нужно создавать потоки для моей модели, каждый раз, когда что-то вызывает воспроизведение звука, программа продолжает выполняться. (Я думаю, SDL_Mixer играет в основном потоке SDL).
Чтобы это работало, когда вы запускаете SDL, вам также нужно будет инициализировать микшер как
if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 1024) < 0) {
// Error message if can't initialize
}
// Amount of channels (Max amount of sounds playing at the same time)
Mix_AllocateChannels(32);
А примером того, как воспроизвести звук, будет
// at some point loaded a sample s with sample(path to wave mp3 or whatever)
s.play();
Несколько замечаний, вам не нужно использовать, но можете, код такой, какой он есть, это скорее простой пример использования SDL2_mixer.
Это означает, что функциональность отсутствует, вам может потребоваться более жесткая обработка звука, например, чтобы остановить звук в середине воспроизведения (по какой-то причине), вы можете сделать это, если воспроизводите свои звуки в разных каналах с помощью функции Mix_HaltChannel, и функция play () может принимать канал, на котором вы хотите его воспроизвести.
Все эти функции возвращают значения ошибок, например, если незарезервированный канал недоступен. Mix_PlayChannel возвращает код ошибки.
Еще одна вещь, которую вы должны иметь в виду, если вы играете один и тот же звук несколько раз, он начнет расплываться / вы не заметите, если тот же самый звук воспроизводится снова. Таким образом, вы можете добавить целое число к семплу, чтобы подсчитать, сколько раз семпл может быть воспроизведен.
Если вы ДЕЙСТВИТЕЛЬНО хотите записать свой микшер / аудио из основного потока SDL (и все еще используете только SDL), вы можете просто создать новый контекст SDL в потоке и каким-то образом посылать сигналы для воспроизведения аудио.