Feature: Allow choosing audio backend (#1588)

* Fix X11 being searched for on macOS

* Add ability to switch audio backends

* Fix issues with c arrays of std dynamic size items

* Fix old uses of sizeof()

* Remove current selected option from list

* Don’t show items if we only have one option
This commit is contained in:
David Chavez 2022-09-27 01:48:47 +02:00 committed by GitHub
parent 0e1248f840
commit dbc4d8199e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 116 additions and 40 deletions

View File

@ -19,6 +19,6 @@ namespace Ship {
#include "WasapiAudioPlayer.h"
#elif defined(__linux)
#include "PulseAudioPlayer.h"
#else
#include "SDLAudioPlayer.h"
#endif
#include "SDLAudioPlayer.h"

View File

@ -530,27 +530,25 @@ endif()
################################################################################
# Compile and link options
################################################################################
if (NOT CMAKE_SYSTEM_NAME MATCHES "Windows|NintendoSwitch|CafeOS")
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
find_package(SDL2)
find_package(GLEW)
find_package(X11)
if (NOT GLEW_FOUND)
if (NOT CMAKE_SYSTEM_NAME MATCHES "Windows|Darwin")
include (FetchContent)
FetchContent_Declare(
glew
GIT_REPOSITORY https://github.com/Perlmint/glew-cmake.git
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../external/glew
)
FetchContent_MakeAvailable(glew)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../../external/glew/build/cmake ${CMAKE_BINARY_DIR}/glew EXCLUDE_FROM_ALL)
endif()
include (FetchContent)
FetchContent_Declare(
glew
GIT_REPOSITORY https://github.com/Perlmint/glew-cmake.git
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../external/glew
)
FetchContent_MakeAvailable(glew)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../../external/glew/build/cmake ${CMAKE_BINARY_DIR}/glew EXCLUDE_FROM_ALL)
endif()
if (NOT GLEW_FOUND)
set(GLEW-INCLUDE ${CMAKE_CURRENT_SOURCE_DIR}/../../external/glew/include)
else()
set(GLEW-INCLUDE ${GLEW_INCLUDE_DIRS})
set(GLEW-INCLUDE ${GLEW_INCLUDE_DIRS})
endif()
set(SDL2-INCLUDE ${SDL2_INCLUDE_DIRS})
elseif (CMAKE_SYSTEM_NAME MATCHES "NintendoSwitch|CafeOS")

View File

@ -84,7 +84,8 @@ namespace SohImGui {
std::function<void(void)> clientSetupHooks;
bool needs_save = false;
int lastBackendID = 0;
int lastRenderingBackendID = 0;
int lastAudioBackendID = 0;
bool statsWindowOpen;
const char* filters[3] = {
@ -97,7 +98,7 @@ namespace SohImGui {
"None"
};
std::pair<const char*, const char*> backends[] = {
std::vector<std::pair<const char*, const char*>> renderingBackends = {
#ifdef _WIN32
{ "dx11", "DirectX" },
#endif
@ -108,6 +109,16 @@ namespace SohImGui {
#endif
};
std::vector<std::pair<const char*, const char*>> audioBackends = {
#ifdef _WIN32
{ "wasapi", "Windows Audio Session API" },
#endif
#if defined(__linux)
{ "pulse", "PulseAudio" },
#endif
{ "sdl", "SDL Audio" }
};
std::map<std::string, std::vector<std::string>> hiddenwindowCategories;
std::map<std::string, std::vector<std::string>> windowCategories;
std::map<std::string, CustomWindow> customWindows;
@ -130,19 +141,30 @@ namespace SohImGui {
});
}
int GetBackendID(std::shared_ptr<Mercury> cfg) {
std::string backend = cfg->getString("Window.GfxBackend");
if (backend.empty()) {
return 0;
void PopulateBackendIds(std::shared_ptr<Mercury> cfg) {
std::string renderingBackend = cfg->getString("Window.GfxBackend");
if (renderingBackend.empty()) {
lastRenderingBackendID = 0;
} else {
for (size_t i = 0; i < renderingBackends.size(); i++) {
if(renderingBackend == renderingBackends[i].first) {
lastRenderingBackendID = i;
break;
}
}
}
for (size_t i = 0; i < (sizeof(backends) / sizeof(backends[0])); i++) {
if(backend == backends[i].first) {
return i;
}
std::string audioBackend = cfg->getString("Window.AudioBackend");
if (audioBackend.empty()) {
lastAudioBackendID = 0;
} else {
for (size_t i = 0; i < audioBackends.size(); i++) {
if(audioBackend == audioBackends[i].first) {
lastAudioBackendID = i;
break;
}
}
}
return 0;
}
void ImGuiWMInit() {
@ -344,7 +366,8 @@ namespace SohImGui {
io->DisplaySize.y = window_impl.gx2.height;
#endif
lastBackendID = GetBackendID(Window::GetInstance()->GetConfig());
PopulateBackendIds(Window::GetInstance()->GetConfig());
if (CVar_GetS32("gOpenMenuBar", 0) != 1) {
#if defined(__SWITCH__) || defined(__WIIU__)
SohImGui::overlay->TextDrawNotification(30.0f, true, "Press - to access enhancements menu");
@ -726,17 +749,30 @@ namespace SohImGui {
return gfx_get_detected_hz();
}
std::pair<const char*, const char*>* GetAvailableRenderingBackends() {
return backends;
std::vector<std::pair<const char*, const char*>> GetAvailableRenderingBackends() {
return renderingBackends;
}
std::vector<std::pair<const char*, const char*>> GetAvailableAudioBackends() {
return audioBackends;
}
std::pair<const char*, const char*> GetCurrentRenderingBackend() {
return backends[lastBackendID];
return renderingBackends[lastRenderingBackendID];
}
std::pair<const char*, const char*> GetCurrentAudioBackend() {
return audioBackends[lastAudioBackendID];
}
void SetCurrentRenderingBackend(uint8_t index, std::pair<const char*, const char*> backend) {
Window::GetInstance()->GetConfig()->setString("Window.GfxBackend", backend.first);
lastBackendID = index;
lastRenderingBackendID = index;
}
void SetCurrentAudioBackend(uint8_t index, std::pair<const char*, const char*> backend) {
Window::GetInstance()->GetConfig()->setString("Window.AudioBackend", backend.first);
lastAudioBackendID = index;
}
const char** GetSupportedTextureFilters() {

View File

@ -80,13 +80,17 @@ namespace SohImGui {
Backend WindowBackend();
float WindowRefreshRate();
std::pair<const char*, const char*>* GetAvailableRenderingBackends();
std::vector<std::pair<const char*, const char*>> GetAvailableRenderingBackends();
std::pair<const char*, const char*> GetCurrentRenderingBackend();
void SetCurrentRenderingBackend(uint8_t index, std::pair<const char*, const char*>);
const char** GetSupportedTextureFilters();
void SetResolutionMultiplier(float multiplier);
void SetMSAALevel(uint32_t value);
std::vector<std::pair<const char*, const char*>> GetAvailableAudioBackends();
std::pair<const char*, const char*> GetCurrentAudioBackend();
void SetCurrentAudioBackend(uint8_t index, std::pair<const char*, const char*>);
void AddWindow(const std::string& category, const std::string& name, WindowDrawFunc drawFunc, bool isEnabled = false, bool isHidden = false);
void EnableWindow(const std::string& name, bool isEnabled = true);

View File

@ -263,6 +263,7 @@ namespace Ship {
GetConfig()->setInt("Window.Height", 480);
GetConfig()->setBool("Window.Options", false);
GetConfig()->setString("Window.GfxBackend", "");
GetConfig()->setString("Window.AudioBackend", "");
GetConfig()->setBool("Window.Fullscreen.Enabled", false);
GetConfig()->setInt("Window.Fullscreen.Width", 1920);
@ -283,7 +284,6 @@ namespace Ship {
InitializeConfiguration();
InitializeResourceManager();
CreateDefaults();
InitializeAudioPlayer();
InitializeControlDeck();
bIsFullscreen = GetConfig()->getBool("Window.Fullscreen.Enabled", false);
@ -297,9 +297,13 @@ namespace Ship {
}
dwMenubar = GetConfig()->getBool("Window.Options", false);
const std::string& gfx_backend = GetConfig()->getString("Window.GfxBackend");
gfxBackend = GetConfig()->getString("Window.GfxBackend");
InitializeWindowManager();
audioBackend = GetConfig()->getString("Window.AudioBackend");
InitializeAudioPlayer();
gfx_init(WmApi, RenderingApi, GetName().c_str(), bIsFullscreen, dwWidth, dwHeight);
WmApi->set_fullscreen_changed_callback(OnFullscreenChanged);
WmApi->set_keyboard_callbacks(KeyDown, KeyUp, AllKeysUp);
@ -442,6 +446,21 @@ namespace Ship {
#else
APlayer = std::make_shared<SDLAudioPlayer>();
#endif
// Config can override
#ifdef _WIN32
if (audioBackend == "wasapi") {
APlayer = std::make_shared<WasapiAudioPlayer>();
}
#endif
#if defined(__linux)
if (audioBackend == "pulse") {
APlayer = std::make_shared<PulseAudioPlayer>();
}
#endif
if (audioBackend == "sdl") {
APlayer = std::make_shared<SDLAudioPlayer>();
}
}
void Window::InitializeWindowManager() {

View File

@ -74,6 +74,7 @@ namespace Ship {
std::shared_ptr<ControlDeck> ControllerApi;
std::string gfxBackend;
std::string audioBackend;
GfxRenderingAPI* RenderingApi;
GfxWindowManagerAPI* WmApi;
bool bIsFullscreen;

View File

@ -502,6 +502,22 @@ namespace GameMenuBar {
UIWidgets::Spacer(0);
BindAudioSlider("Fanfare Volume: %d %%", "gFanfareVolume", 1.0f, SEQ_FANFARE);
ImGui::Text("Audio API (Needs reload)");
auto audioBackends = SohImGui::GetAvailableAudioBackends();
auto currentAudioBackend = SohImGui::GetCurrentAudioBackend();
if (ImGui::BeginCombo("##AApi", currentAudioBackend.second)) {
if (audioBackends.size() > 1) {
for (uint8_t i = 0; i < audioBackends.size(); i++) {
if (ImGui::Selectable(audioBackends[i].second, audioBackends[i] == currentAudioBackend)) {
SohImGui::SetCurrentAudioBackend(i, audioBackends[i]);
}
}
}
ImGui::EndCombo();
}
ImGui::EndMenu();
}
@ -609,13 +625,15 @@ namespace GameMenuBar {
}
ImGui::Text("Renderer API (Needs reload)");
auto backends = SohImGui::GetAvailableRenderingBackends();
auto currentBackend = SohImGui::GetCurrentRenderingBackend();
auto renderingBackends = SohImGui::GetAvailableRenderingBackends();
auto currentRenderingBackend = SohImGui::GetCurrentRenderingBackend();
if (ImGui::BeginCombo("##RApi", currentBackend.second)) {
for (uint8_t i = 0; i < sizeof(backends) / sizeof(backends[0]); i++) {
if (ImGui::Selectable(backends[i].second, backends[i] == currentBackend)) {
SohImGui::SetCurrentRenderingBackend(i, backends[i]);
if (ImGui::BeginCombo("##RApi", currentRenderingBackend.second)) {
if (renderingBackends.size() > 1) {
for (uint8_t i = 0; i < renderingBackends.size(); i++) {
if (ImGui::Selectable(renderingBackends[i].second, renderingBackends[i] == currentRenderingBackend)) {
SohImGui::SetCurrentRenderingBackend(i, renderingBackends[i]);
}
}
}