#include #include #include "audio_player.h" #include #include static int audio_open = 0; static Mix_Music *music = NULL; static int next_track = 0; SDL_AudioSpec spec; static ThreadSafeQueue g_audioQueue; void music_finished() { Mix_FreeMusic(music); music = NULL; g_audioQueue.push({"end", ""}); } AudioPlayer::AudioPlayer(IAudioEvent &event) : m_event(event) { m_audioThread = std::thread( std::bind(&AudioPlayer::AudioThread, this) ); } void AudioPlayer::Initialize() { /* Initialize variables */ spec.freq = MIX_DEFAULT_FREQUENCY; spec.format = MIX_DEFAULT_FORMAT; spec.channels = MIX_DEFAULT_CHANNELS; if (Mix_Init(MIX_INIT_FLAC | MIX_INIT_MP3 | MIX_INIT_OGG) < 0) { return ; } if (Mix_OpenAudio(0, &spec) < 0) { SDL_Log("Couldn't open audio: %s\n", SDL_GetError()); return; } else { Mix_QuerySpec(&spec.freq, &spec.format, &spec.channels); SDL_Log("Opened audio at %d Hz %d bit%s %s audio buffer\n", spec.freq, (spec.format&0xFF), (SDL_AUDIO_ISFLOAT(spec.format) ? " (float)" : ""), (spec.channels > 2) ? "surround" : (spec.channels > 1) ? "stereo" : "mono"); } audio_open = 1; Mix_HookMusicFinished(music_finished); } void AudioPlayer::Play(const std::string &filename) { // On coupe le son en cours g_audioQueue.clear(); Mix_HaltMusic(); Mix_FreeMusic(music); g_audioQueue.push({"play", filename}); } AudioPlayer::~AudioPlayer() { // Quit audio thread g_audioQueue.clear(); g_audioQueue.push({"quit", ""}); if (m_audioThread.joinable()) { m_audioThread.join(); } } void AudioPlayer::Stop() { g_audioQueue.clear(); g_audioQueue.push({"end", ""}); } #define AUDIO_STATE_WAIT_PLAY 1 #define AUDIO_STATE_WAIT_END 2 void AudioPlayer::AudioThread() { int state = AUDIO_STATE_WAIT_PLAY; for (;;) { auto cmd = g_audioQueue.front(); g_audioQueue.pop(); if (cmd.order == "quit") { return; } else if (cmd.order == "play") { if (state == AUDIO_STATE_WAIT_PLAY) { state = AUDIO_STATE_WAIT_END; music = Mix_LoadMUS(cmd.filename.c_str()); if (music) { Mix_PlayMusic(music, 0); } } } else if (cmd.order == "end") { if (state == AUDIO_STATE_WAIT_END) { state = AUDIO_STATE_WAIT_PLAY; Mix_HaltMusic(); Mix_FreeMusic(music); m_event.EndOfAudio(); } } } }