Working on music cross fade and settings
This commit is contained in:
1 parent
84f9fa37a8
commit
b8d79c7b7b
13 files changed
+779
-332
No files matched your search
+129
-7
@@ -43,6 +43,12 @@ bool AudioPlayerAsync::init() {
|
||||
void AudioPlayerAsync::shutdown() {
|
||||
if (!initialized) return;
|
||||
|
||||
if (currentMusic_) {
|
||||
Mix_HaltMusic();
|
||||
Mix_FreeMusic(currentMusic_);
|
||||
currentMusic_ = nullptr;
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(soundCacheMutex);
|
||||
for (auto& pair : soundCache) {
|
||||
@@ -62,6 +68,7 @@ void AudioPlayerAsync::playSoundAsync(const std::string& filePath, int loops, in
|
||||
std::cerr << "AudioPlayerAsync not initialized" << std::endl;
|
||||
return;
|
||||
}
|
||||
if (!soundEnabled_) return;
|
||||
|
||||
auto task = [this, filePath, loops, channel]() {
|
||||
Mix_Chunk* sound = nullptr;
|
||||
@@ -99,20 +106,20 @@ void AudioPlayerAsync::playSoundAsync(const std::string& filePath, int loops, in
|
||||
}
|
||||
|
||||
void AudioPlayerAsync::playMusicAsync(const std::string& filePath, int loops) {
|
||||
std::cout << "AudioPlayerAsync::playMusicAsync called step 1" << std::endl;
|
||||
if (!initialized) return;
|
||||
std::cout << "AudioPlayerAsync::playMusicAsync called step 1" << std::endl;
|
||||
|
||||
if (filePath == currentTrack)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
currentTrack = filePath;
|
||||
if (!musicEnabled_) return;
|
||||
|
||||
auto task = [filePath, loops]() {
|
||||
std::cout << "AudioPlayerAsync::playMusicAsync called step 3" << std::endl;
|
||||
|
||||
auto task = [this, filePath, loops]() {
|
||||
Mix_HaltMusic();
|
||||
if (currentMusic_) {
|
||||
Mix_FreeMusic(currentMusic_);
|
||||
currentMusic_ = nullptr;
|
||||
}
|
||||
Mix_Music* music = Mix_LoadMUS(filePath.c_str());
|
||||
if (!music) {
|
||||
std::cerr << "Failed to load music " << filePath << ": " << Mix_GetError() << std::endl;
|
||||
@@ -121,7 +128,9 @@ void AudioPlayerAsync::playMusicAsync(const std::string& filePath, int loops) {
|
||||
if (Mix_PlayMusic(music, loops) == -1) {
|
||||
std::cerr << "Mix_PlayMusic failed: " << Mix_GetError() << std::endl;
|
||||
Mix_FreeMusic(music);
|
||||
return;
|
||||
}
|
||||
currentMusic_ = music;
|
||||
};
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
@@ -178,6 +187,7 @@ void AudioPlayerAsync::resumeMusicAsync() {
|
||||
void AudioPlayerAsync::setMusicVolume(int volume) {
|
||||
if (!initialized) return;
|
||||
volume = std::max(0, std::min(128, volume));
|
||||
musicVolume_ = volume;
|
||||
#ifdef __EMSCRIPTEN__
|
||||
Mix_VolumeMusic(volume);
|
||||
#else
|
||||
@@ -192,6 +202,7 @@ void AudioPlayerAsync::setMusicVolume(int volume) {
|
||||
void AudioPlayerAsync::setSoundVolume(int volume) {
|
||||
if (!initialized) return;
|
||||
volume = std::max(0, std::min(128, volume));
|
||||
soundVolume_ = volume;
|
||||
#ifdef __EMSCRIPTEN__
|
||||
Mix_Volume(-1, volume);
|
||||
#else
|
||||
@@ -203,6 +214,117 @@ void AudioPlayerAsync::setSoundVolume(int volume) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void AudioPlayerAsync::crossFadeMusicAsync(const std::string& filePath, int fadeDurationMs, int loops) {
|
||||
if (!initialized) return;
|
||||
if (filePath == currentTrack) return;
|
||||
currentTrack = filePath;
|
||||
if (!musicEnabled_) return;
|
||||
|
||||
auto task = [this, filePath, fadeDurationMs, loops]() {
|
||||
#ifdef __EMSCRIPTEN__
|
||||
Mix_HaltMusic();
|
||||
if (currentMusic_) { Mix_FreeMusic(currentMusic_); currentMusic_ = nullptr; }
|
||||
#else
|
||||
if (Mix_PlayingMusic()) {
|
||||
Mix_FadeOutMusic(fadeDurationMs / 2);
|
||||
SDL_Delay(fadeDurationMs / 2 + 20);
|
||||
}
|
||||
Mix_HaltMusic();
|
||||
if (currentMusic_) { Mix_FreeMusic(currentMusic_); currentMusic_ = nullptr; }
|
||||
#endif
|
||||
Mix_Music* music = Mix_LoadMUS(filePath.c_str());
|
||||
if (!music) {
|
||||
std::cerr << "Failed to load music " << filePath << ": " << Mix_GetError() << std::endl;
|
||||
return;
|
||||
}
|
||||
if (Mix_FadeInMusic(music, loops, fadeDurationMs / 2) == -1) {
|
||||
std::cerr << "Mix_FadeInMusic failed: " << Mix_GetError() << std::endl;
|
||||
Mix_FreeMusic(music);
|
||||
return;
|
||||
}
|
||||
currentMusic_ = music;
|
||||
};
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
task();
|
||||
#else
|
||||
std::unique_lock<std::mutex> lock(mtx);
|
||||
taskQueue.push(std::move(task));
|
||||
cv.notify_one();
|
||||
#endif
|
||||
}
|
||||
|
||||
void AudioPlayerAsync::crossFadeMusicFromPositionAsync(const std::string& filePath, int fadeDurationMs, int loops) {
|
||||
if (!initialized) return;
|
||||
if (filePath == currentTrack) return;
|
||||
currentTrack = filePath;
|
||||
if (!musicEnabled_) return;
|
||||
|
||||
auto task = [this, filePath, fadeDurationMs, loops]() {
|
||||
double position = 0.0;
|
||||
if (currentMusic_ && Mix_PlayingMusic()) {
|
||||
double pos = Mix_GetMusicPosition(currentMusic_);
|
||||
if (pos >= 0.0) position = pos;
|
||||
}
|
||||
#ifndef __EMSCRIPTEN__
|
||||
if (Mix_PlayingMusic()) {
|
||||
Mix_FadeOutMusic(fadeDurationMs / 2);
|
||||
SDL_Delay(fadeDurationMs / 2 + 20);
|
||||
}
|
||||
#endif
|
||||
Mix_HaltMusic();
|
||||
if (currentMusic_) { Mix_FreeMusic(currentMusic_); currentMusic_ = nullptr; }
|
||||
|
||||
Mix_Music* music = Mix_LoadMUS(filePath.c_str());
|
||||
if (!music) {
|
||||
std::cerr << "Failed to load music " << filePath << ": " << Mix_GetError() << std::endl;
|
||||
return;
|
||||
}
|
||||
if (Mix_FadeInMusicPos(music, loops, fadeDurationMs / 2, position) == -1) {
|
||||
std::cerr << "Mix_FadeInMusicPos failed: " << Mix_GetError() << std::endl;
|
||||
Mix_FreeMusic(music);
|
||||
return;
|
||||
}
|
||||
currentMusic_ = music;
|
||||
};
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
task();
|
||||
#else
|
||||
std::unique_lock<std::mutex> lock(mtx);
|
||||
taskQueue.push(std::move(task));
|
||||
cv.notify_one();
|
||||
#endif
|
||||
}
|
||||
|
||||
void AudioPlayerAsync::setMusicEnabled(bool enabled) {
|
||||
if (musicEnabled_ == enabled) return;
|
||||
musicEnabled_ = enabled;
|
||||
if (!initialized) return;
|
||||
|
||||
if (!enabled) {
|
||||
// Halt playback but keep currentTrack so we can restart it on re-enable.
|
||||
#ifdef __EMSCRIPTEN__
|
||||
Mix_HaltMusic();
|
||||
#else
|
||||
std::unique_lock<std::mutex> lock(mtx);
|
||||
taskQueue.push([]() { Mix_HaltMusic(); });
|
||||
cv.notify_one();
|
||||
#endif
|
||||
} else {
|
||||
// Restart the last requested track, if any.
|
||||
if (!currentTrack.empty()) {
|
||||
const std::string track = currentTrack;
|
||||
currentTrack = ""; // clear so crossFadeMusicAsync doesn't bail early
|
||||
crossFadeMusicAsync(track);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AudioPlayerAsync::setSoundEnabled(bool enabled) {
|
||||
soundEnabled_ = enabled;
|
||||
}
|
||||
|
||||
#ifndef __EMSCRIPTEN__
|
||||
void AudioPlayerAsync::workerThread() {
|
||||
while (true) {
|
||||
|
||||
Reference in new issue
Block a user