29 #include <SDL_audio.h>
31 #include "eng3d/audio.hpp"
32 #include "eng3d/utils.hpp"
33 #include "eng3d/log.hpp"
34 #include "eng3d/state.hpp"
46 if(this->
stream ==
nullptr)
63 fmt.format = AUDIO_S16;
66 fmt.callback = &Eng3D::AudioManager::mixaudio;
68 SDL_AudioSpec new_fmt{};
69 this->audio_dev_id = SDL_OpenAudioDevice(NULL, 0, &fmt, &new_fmt, 0);
70 if(this->audio_dev_id < 0)
72 SDL_PauseAudioDevice(this->audio_dev_id, 0);
76 SDL_PauseAudioDevice(this->audio_dev_id, 1);
77 SDL_CloseAudioDevice(this->audio_dev_id);
78 SDL_QuitSubSystem(SDL_INIT_AUDIO);
81 void Eng3D::AudioManager::mixaudio(
void* userdata, uint8_t* stream,
int len) {
83 SDL_memset(stream, 0, len);
85 auto audiobuf = std::unique_ptr<uint8_t[]>(
new uint8_t[len]);
87 const std::scoped_lock lock(audio_man.sound_lock);
88 if(!audio_man.sound_queue.empty()) {
89 auto& audio = **audio_man.sound_queue.begin();
90 auto* audio_stream =
static_cast<stb_vorbis*
>(audio.stream);
95 audio_man.sound_queue.erase(audio_man.sound_queue.begin());
97 for(
size_t i = 0; i < len /
sizeof(int16_t); i++) {
98 auto sample =
static_cast<float>(((int16_t *)audiobuf.get())[i]);
99 ((int16_t *)stream)[i] += (int16_t)(sample * audio_man.sound_volume);
103 if(!audio_man.music_queue.empty()) {
104 auto& audio = **audio_man.music_queue.begin();
105 auto* audio_stream =
static_cast<stb_vorbis*
>(audio.stream);
110 audio_man.music_queue.erase(audio_man.music_queue.begin());
112 for(
size_t i = 0; i < len /
sizeof(int16_t); i++) {
113 auto sample =
static_cast<float>(((int16_t *)audiobuf.get())[i]);
114 ((int16_t *)stream)[i] += (int16_t)(sample * audio_man.music_volume);
121 auto it = sounds.find(path);
122 if(it != sounds.cend())
return (*it).second;
124 sounds[path] = std::make_shared<Eng3D::Audio>(path);
const std::shared_ptr< Audio > load(const std::string &path)
std::string translate(const std::string_view str)
void debug(const std::string_view category, const std::string_view msg)
std::string translate_format(const std::string_view format, Args &&... args)
String formatter, with translation.
stb_vorbis_info stb_vorbis_get_info(stb_vorbis *f)
int stb_vorbis_seek_start(stb_vorbis *f)
void stb_vorbis_close(stb_vorbis *f)
int stb_vorbis_get_samples_short_interleaved(stb_vorbis *f, int channels, short *buffer, int num_shorts)
stb_vorbis * stb_vorbis_open_filename(const char *filename, int *error, const stb_vorbis_alloc *alloc_buffer)
#define CXX_THROW(class,...)