Re-implement custom trophy sounds using sdl3 mixer (#3805)

* re-implement custom trophy sounds using sdl3 mixer

* fix build vars

* Don't change SDL version
This commit is contained in:
rainmakerv2
2025-11-16 16:36:54 +08:00
committed by GitHub
parent 6a9f9abda0
commit ed14359c87
6 changed files with 52 additions and 45 deletions

4
.gitmodules vendored
View File

@@ -113,3 +113,7 @@
[submodule "externals/json"] [submodule "externals/json"]
path = externals/json path = externals/json
url = https://github.com/nlohmann/json.git url = https://github.com/nlohmann/json.git
[submodule "externals/sdl3_mixer"]
path = externals/sdl3_mixer
url = https://github.com/libsdl-org/SDL_mixer
shallow = true

View File

@@ -229,6 +229,7 @@ find_package(magic_enum 0.9.7 CONFIG)
find_package(PNG 1.6 MODULE) find_package(PNG 1.6 MODULE)
find_package(RenderDoc 1.6.0 MODULE) find_package(RenderDoc 1.6.0 MODULE)
find_package(SDL3 3.1.2 CONFIG) find_package(SDL3 3.1.2 CONFIG)
find_package(SDL3_mixer 2.8.1 CONFIG)
find_package(stb MODULE) find_package(stb MODULE)
find_package(toml11 4.2.0 CONFIG) find_package(toml11 4.2.0 CONFIG)
find_package(tsl-robin-map 1.3.0 CONFIG) find_package(tsl-robin-map 1.3.0 CONFIG)
@@ -1070,7 +1071,7 @@ add_executable(shadps4
create_target_directory_groups(shadps4) create_target_directory_groups(shadps4)
target_link_libraries(shadps4 PRIVATE magic_enum::magic_enum fmt::fmt toml11::toml11 tsl::robin_map xbyak::xbyak Tracy::TracyClient RenderDoc::API FFmpeg::ffmpeg Dear_ImGui gcn half::half ZLIB::ZLIB PNG::PNG) target_link_libraries(shadps4 PRIVATE magic_enum::magic_enum fmt::fmt toml11::toml11 tsl::robin_map xbyak::xbyak Tracy::TracyClient RenderDoc::API FFmpeg::ffmpeg Dear_ImGui gcn half::half ZLIB::ZLIB PNG::PNG)
target_link_libraries(shadps4 PRIVATE Boost::headers GPUOpen::VulkanMemoryAllocator LibAtrac9 sirit Vulkan::Headers xxHash::xxhash Zydis::Zydis glslang::glslang SDL3::SDL3 pugixml::pugixml stb::headers libusb::usb lfreist-hwinfo::hwinfo nlohmann_json::nlohmann_json) target_link_libraries(shadps4 PRIVATE Boost::headers GPUOpen::VulkanMemoryAllocator LibAtrac9 sirit Vulkan::Headers xxHash::xxhash Zydis::Zydis glslang::glslang SDL3::SDL3 SDL3_mixer::SDL3_mixer pugixml::pugixml stb::headers libusb::usb lfreist-hwinfo::hwinfo nlohmann_json::nlohmann_json)
target_compile_definitions(shadps4 PRIVATE IMGUI_USER_CONFIG="imgui/imgui_config.h") target_compile_definitions(shadps4 PRIVATE IMGUI_USER_CONFIG="imgui/imgui_config.h")
target_compile_definitions(Dear_ImGui PRIVATE IMGUI_USER_CONFIG="${PROJECT_SOURCE_DIR}/src/imgui/imgui_config.h") target_compile_definitions(Dear_ImGui PRIVATE IMGUI_USER_CONFIG="${PROJECT_SOURCE_DIR}/src/imgui/imgui_config.h")

View File

@@ -63,6 +63,18 @@ if (NOT TARGET SDL3::SDL3)
add_subdirectory(sdl3) add_subdirectory(sdl3)
endif() endif()
# SDL3_mixer
if (NOT TARGET SDL3_Mixer::SDL3_Mixer)
set(SDLMIXER_FLAC OFF)
set(SDLMIXER_OGG OFF)
set(SDLMIXER_MOD OFF)
set(SDLMIXER_MIDI OFF)
set(SDLMIXER_OPUS OFF)
set(SDLMIXER_WAVPACK OFF)
set(BUILD_SHARED_LIBS OFF)
add_subdirectory(sdl3_mixer)
endif()
# vulkan-headers # vulkan-headers
if (NOT TARGET Vulkan::Headers) if (NOT TARGET Vulkan::Headers)
set(VULKAN_HEADERS_ENABLE_MODULE OFF) set(VULKAN_HEADERS_ENABLE_MODULE OFF)

1
externals/sdl3_mixer vendored Submodule

Submodule externals/sdl3_mixer added at 4182794ea4

View File

@@ -5,7 +5,6 @@
#include <filesystem> #include <filesystem>
#include <fstream> #include <fstream>
#include <mutex> #include <mutex>
#include <SDL3/SDL_audio.h>
#include <cmrc/cmrc.hpp> #include <cmrc/cmrc.hpp>
#include <imgui.h> #include <imgui.h>
@@ -92,59 +91,45 @@ TrophyUI::TrophyUI(const std::filesystem::path& trophyIconPath, const std::strin
AddLayer(this); AddLayer(this);
bool customsoundplayed = false; MIX_Init();
#ifdef ENABLE_QT_GUI mixer = MIX_CreateMixerDevice(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, NULL);
QString musicPathWav = QString::fromStdString(CustomTrophy_Dir.string() + "/trophy.wav"); if (!mixer) {
QString musicPathMp3 = QString::fromStdString(CustomTrophy_Dir.string() + "/trophy.mp3"); LOG_ERROR(Lib_NpTrophy, "Could not initialize SDL Mixer, {}", SDL_GetError());
if (fs::exists(musicPathWav.toStdString())) { return;
BackgroundMusicPlayer::getInstance().setVolume(100);
BackgroundMusicPlayer::getInstance().playMusic(musicPathWav, false);
customsoundplayed = true;
} else if (fs::exists(musicPathMp3.toStdString())) {
BackgroundMusicPlayer::getInstance().setVolume(100);
BackgroundMusicPlayer::getInstance().playMusic(musicPathMp3, false);
customsoundplayed = true;
} }
#endif
if (!customsoundplayed) { MIX_SetMasterGain(mixer, static_cast<float>(Config::getVolumeSlider() / 100.f));
auto musicPathMp3 = CustomTrophy_Dir / "trophy.mp3";
auto musicPathWav = CustomTrophy_Dir / "trophy.wav";
if (std::filesystem::exists(musicPathMp3)) {
audio = MIX_LoadAudio(mixer, musicPathMp3.string().c_str(), false);
} else if (std::filesystem::exists(musicPathWav)) {
audio = MIX_LoadAudio(mixer, musicPathWav.string().c_str(), false);
} else {
auto soundFile = resource.open("src/images/trophy.wav"); auto soundFile = resource.open("src/images/trophy.wav");
std::vector<u8> soundData = std::vector<u8>(soundFile.begin(), soundFile.end()); std::vector<u8> soundData = std::vector<u8>(soundFile.begin(), soundFile.end());
audio =
MIX_LoadAudio_IO(mixer, SDL_IOFromMem(soundData.data(), soundData.size()), false, true);
// due to low volume of default sound file
MIX_SetMasterGain(mixer, MIX_GetMasterGain(mixer) * 1.3f);
}
SDL_AudioSpec spec; if (!audio) {
Uint8* audioBuf; LOG_ERROR(Lib_NpTrophy, "Could not loud audio file, {}", SDL_GetError());
Uint32 audioLen; return;
}
if (!SDL_LoadWAV_IO(SDL_IOFromMem(soundData.data(), soundData.size()), true, &spec, if (!MIX_PlayAudio(mixer, audio)) {
&audioBuf, &audioLen)) { LOG_ERROR(Lib_NpTrophy, "Could not play audio file, {}", SDL_GetError());
LOG_ERROR(Lib_NpTrophy, "Cannot load trophy sound: {}", SDL_GetError());
SDL_free(audioBuf);
return;
}
SDL_AudioStream* stream =
SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &spec, nullptr, nullptr);
if (!stream) {
LOG_ERROR(Lib_NpTrophy, "Cannot create audio stream for trophy sound: {}",
SDL_GetError());
SDL_free(audioBuf);
return;
}
if (!SDL_PutAudioStreamData(stream, audioBuf, audioLen)) {
LOG_ERROR(Lib_NpTrophy, "Cannot add trophy sound data to stream: {}", SDL_GetError());
SDL_free(audioBuf);
return;
}
// Set audio gain 20% higher since audio file itself is soft
SDL_SetAudioStreamGain(stream, Config::getVolumeSlider() / 100.0f * 1.2f);
SDL_ResumeAudioStreamDevice(stream);
SDL_free(audioBuf);
} }
} }
TrophyUI::~TrophyUI() { TrophyUI::~TrophyUI() {
MIX_DestroyAudio(audio);
MIX_DestroyMixer(mixer);
MIX_Quit();
Finish(); Finish();
} }

View File

@@ -5,6 +5,7 @@
#include <string> #include <string>
#include <variant> #include <variant>
#include <SDL3_mixer/SDL_mixer.h>
#include <queue> #include <queue>
#include "common/fixed_value.h" #include "common/fixed_value.h"
@@ -30,6 +31,9 @@ private:
std::string_view trophy_type; std::string_view trophy_type;
ImGui::RefCountedTexture trophy_icon; ImGui::RefCountedTexture trophy_icon;
ImGui::RefCountedTexture trophy_type_icon; ImGui::RefCountedTexture trophy_type_icon;
MIX_Mixer* mixer;
MIX_Audio* audio;
}; };
struct TrophyInfo { struct TrophyInfo {