Skip to content

Commit

Permalink
feat: support choosing OpenAL devices (yvt#1003)
Browse files Browse the repository at this point in the history
  • Loading branch information
yvt authored Aug 13, 2022
2 parents 282c7ae + 4fee99e commit 2fca03c
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 22 deletions.
76 changes: 76 additions & 0 deletions Resources/Scripts/Gui/StartupScreen/ConfigViewTabs.as
Original file line number Diff line number Diff line change
Expand Up @@ -473,8 +473,11 @@ namespace spades {
StartupScreenConfigView @configViewOpenAL;
StartupScreenConfigView @configViewYSR;

StartupScreenAudioOpenALEditor @editOpenAL;

private ConfigItem s_audioDriver("s_audioDriver");
private ConfigItem s_eax("s_eax");
private ConfigItem s_openalDevice("s_openalDevice");

StartupScreenAudioTab(StartupScreenUI @ui, Vector2 size) {
super(ui.manager);
Expand Down Expand Up @@ -536,6 +539,7 @@ namespace spades {
{
StartupScreenConfigView cfg(Manager);


cfg.AddRow(StartupScreenConfigSliderItemEditor(
ui, StartupScreenConfig(ui, "s_maxPolyphonics"), 16.0, 256.0, 8.0,
_Tr("StartupScreen", "Polyphonics"),
Expand All @@ -547,6 +551,13 @@ namespace spades {
ui, StartupScreenConfig(ui, "s_eax"), "0", "1", _Tr("StartupScreen", "EAX"),
_Tr("StartupScreen",
"Enables extended features provided by the OpenAL driver to create " "more ambience.")));
AddLabel(0.f, 90.f, 20.f, _Tr("StartupScreen", "Devices"));
{
StartupScreenAudioOpenALEditor e(ui);
AddChild(e);
@editOpenAL = e;
cfg.AddRow(editOpenAL);
}

cfg.Finalize();
cfg.SetHelpTextHandler(HelpTextHandler(this.HandleHelpText));
Expand Down Expand Up @@ -609,6 +620,71 @@ namespace spades {
ui.helper.CheckConfigCapability("s_audioDriver", "null").length == 0;
configViewOpenAL.LoadConfig();
configViewYSR.LoadConfig();
editOpenAL.LoadConfig();

s_openalDevice.StringValue = editOpenAL.openal.StringValue;
}
}

class StartupScreenAudioOpenALEditor : spades::ui::UIElement, LabelAddable {
StartupScreenUI @ui;
StartupScreenHelper @helper;
ConfigItem openal("openal");

spades::ui::Button @dropdownButton;

StartupScreenAudioOpenALEditor(StartupScreenUI @ui) {
super(ui.manager);
@this.ui = ui;
@helper = ui.helper;
{
StartupScreenDropdownListDropdownButton e(Manager);
AddChild(e);
e.Bounds = AABB2(80.f, 0.f, 400.f, 20.f);
@e.Activated = spades::ui::EventHandler(this.ShowDropdown);
@dropdownButton = e;
}
}

void LoadConfig() {
string drivername = openal.StringValue;
string name = _Tr("StartupScreen", "Default device", drivername);
if (drivername == "") {
name = _Tr("StartupScreen", "Default device");
}

int cnt = helper.GetNumAudioOpenALDevices();
for (int i = 0; i < cnt; i++) {
if (drivername == helper.GetAudioOpenALDevice(i)) {
name = helper.GetAudioOpenALDevice(i);
}
}

dropdownButton.Caption = name;
}

private void ShowDropdown(spades::ui::UIElement @) {
string[] items = {_Tr("StartupScreen", "Default device")};
int cnt = helper.GetNumAudioOpenALDevices();
for (int i = 0; i < cnt; i++) {
string s = helper.GetAudioOpenALDevice(i);
items.insertLast(s);
}
spades::ui::ShowDropDownList(this, items,
spades::ui::DropDownListHandler(this.DropdownHandler));
}

private void DropdownHandler(int index) {
if (index >= 0) {
if (index == 0) {
openal = "default";
} else {
openal = helper.GetAudioOpenALDevice(index - 1);
}

// Reload the startup screen so the language config takes effect
ui.Reload();
}
}
}

Expand Down
44 changes: 22 additions & 22 deletions Sources/Audio/ALDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ DEFINE_SPADES_SETTING(s_maxPolyphonics, "96");
DEFINE_SPADES_SETTING(s_eax, "1");
DEFINE_SPADES_SETTING(s_alPreciseErrorCheck, "1");
DEFINE_SPADES_SETTING(s_gain, "1");
DEFINE_SPADES_SETTING(s_openalDevice, "");

// lm: seems to be missing for me..
#ifndef ALC_ALL_DEVICES_SPECIFIER
Expand Down Expand Up @@ -421,6 +422,7 @@ namespace spades {

Internal() {
SPADES_MARK_FUNCTION();
const char *ext, *dev;

if (al::qalGetString(AL_EXTENSIONS)) {
std::vector<std::string> strs = Split(al::qalGetString(AL_EXTENSIONS), " ");
Expand All @@ -430,27 +432,12 @@ namespace spades {
}
}

SPLog("--- All devices ---");
const ALCchar *ext = al::qalcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER);
while (ext && *ext) {
SPLog("%s", ext);
ext += (std::strlen(ext) + 1);
}
SPLog("-------------------");

SPLog("--- Devices ---");
ext = al::qalcGetString(NULL, ALC_DEVICE_SPECIFIER);
while (ext && *ext) {
SPLog("%s", ext);
ext += (std::strlen(ext) + 1);
}
SPLog("---------------");
const ALCchar *dev = al::qalcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
if (dev && *dev) {
SPLog("Default device: %s", dev);
}
dev = s_openalDevice.CString();
SPLog("OpenAL opening device: %s", dev);
if (!strcmp(dev, "default"))
dev = NULL;
alDevice = al::qalcOpenDevice(dev);

alDevice = al::qalcOpenDevice(NULL);
if (UNLIKELY(!alDevice)) {
if ((ext = al::qalcGetString(NULL, ALC_EXTENSIONS))) {
std::vector<std::string> strs = Split(ext, " ");
Expand Down Expand Up @@ -558,15 +545,15 @@ namespace spades {
ALSrc *AllocChunk() {
SPADES_MARK_FUNCTION();

size_t start = SampleRandomInt<std::size_t>(0, srcs.size() - 1);
size_t start = SampleRandomInt<std::size_t>(0, srcs.size() - 1);
for (size_t i = 0; i < srcs.size(); i++) {
ALSrc *src = srcs[(i + start) % srcs.size()];
if (src->IsPlaying())
continue;
return src;
}

ALSrc *src = SampleRandomElement(srcs);
ALSrc *src = SampleRandomElement(srcs);
src->Terminate();
return src;
}
Expand Down Expand Up @@ -755,6 +742,19 @@ namespace spades {
d = new Internal();
}

std::vector<std::string> ALDevice::DeviceList() {
std::vector<std::string> devs;
const ALCchar *ext = al::qalcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER);
if (!ext || *ext == '\0')
ext = al::qalcGetString(NULL, ALC_DEVICE_SPECIFIER);
while (ext && *ext) {
devs.push_back(ext);
ext += std::strlen(ext) + 1;
}

return devs;
}

bool ALDevice::TryLoad() {
try {
al::Link();
Expand Down
2 changes: 2 additions & 0 deletions Sources/Audio/ALDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ namespace spades {

client::IAudioChunk *RegisterSound(const char *name) override;

static std::vector<std::string> DeviceList();

void ClearCache() override;

void SetGameMap(client::GameMap *) override;
Expand Down
14 changes: 14 additions & 0 deletions Sources/Gui/StartupScreenHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,13 @@ namespace spades {
}));
}

// check openAL drivers
SPLog("Checking OpenAL available drivers");
openalDevices = audio::ALDevice::DeviceList();
for (const auto &d: openalDevices) {
SPLog("%s", d.c_str());
}

// check GL capabilities

SPLog("Performing ecapability query");
Expand Down Expand Up @@ -754,6 +761,13 @@ namespace spades {
report += '\n';
}

int StartupScreenHelper::GetNumAudioOpenALDevices() { return static_cast<int>(openalDevices.size()); }
std::string StartupScreenHelper::GetAudioOpenALDevice(int index) {
if (index < 0 || index >= GetNumAudioOpenALDevices())
SPInvalidArgument("index");
return openalDevices[index];
}

int StartupScreenHelper::GetNumLocales() { return static_cast<int>(locales.size()); }
std::string StartupScreenHelper::GetLocale(int index) {
if (index < 0 || index >= GetNumLocales())
Expand Down
4 changes: 4 additions & 0 deletions Sources/Gui/StartupScreenHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ namespace spades {
void AddReport(const std::string &text = std::string(),
Vector4 color = Vector4::Make(1.f, 1.f, 1.f, 1.f));

std::vector<std::string> openalDevices;
struct LocaleInfo {
std::string name;
std::string descriptionNative;
Expand Down Expand Up @@ -78,6 +79,9 @@ namespace spades {
int GetVideoModeWidth(int index);
int GetVideoModeHeight(int index);

int GetNumAudioOpenALDevices();
std::string GetAudioOpenALDevice(int index);

int GetNumReportLines();
std::string GetReport() { return report; }
std::string GetReportLineText(int line);
Expand Down
10 changes: 10 additions & 0 deletions Sources/ScriptBindings/StartupScreenHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,16 @@ namespace spades {
asMETHOD(gui::StartupScreenHelper, GetVideoModeHeight),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod("StartupScreenHelper",
"int GetNumAudioOpenALDevices()",
asMETHOD(gui::StartupScreenHelper, GetNumAudioOpenALDevices),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod("StartupScreenHelper",
"string GetAudioOpenALDevice(int)",
asMETHOD(gui::StartupScreenHelper, GetAudioOpenALDevice),
asCALL_THISCALL);
manager->CheckError(r);
r = eng->RegisterObjectMethod("StartupScreenHelper",
"int GetNumReportLines()",
asMETHOD(gui::StartupScreenHelper, GetNumReportLines),
Expand Down

0 comments on commit 2fca03c

Please sign in to comment.