mirror of
https://github.com/arabine/open-story-teller.git
synced 2025-12-06 17:09:06 +01:00
129 lines
2.7 KiB
C++
129 lines
2.7 KiB
C++
|
|
#include <functional>
|
|
#include <stdio.h>
|
|
#include "audio_player.h"
|
|
|
|
#include <SDL3_mixer/SDL_mixer.h>
|
|
#include <stdio.h>
|
|
|
|
|
|
static int audio_open = 0;
|
|
static Mix_Music *music = NULL;
|
|
static int next_track = 0;
|
|
|
|
SDL_AudioSpec spec;
|
|
|
|
|
|
static ThreadSafeQueue<AudioCommand> 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();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|