update openal-soft to 1.24.3

keeping the alt 87514151c4 (diff-73a8dc1ce58605f6c5ea53548454c3bae516ec5132a29c9d7ff7edf9730c75be)
This commit is contained in:
AzaezelX 2025-09-03 11:09:27 -05:00
parent 12db0500e8
commit ba32094b7b
276 changed files with 49304 additions and 8712 deletions

View file

@ -17,12 +17,16 @@
#include "almalloc.h"
#include "router.h"
#include "strutils.h"
namespace {
using namespace std::string_view_literals;
std::once_flag InitOnce;
void LoadDrivers() { std::call_once(InitOnce, []{ LoadDriverList(); }); }
struct FuncExportEntry {
const char *funcName;
void *address;
@ -337,7 +341,7 @@ void EnumeratedList::AppendDeviceList(const ALCchar* names, ALCuint idx)
size_t count{0};
while(*name_end)
{
TRACE("Enumerated \"%s\", driver %u\n", name_end, idx);
TRACE("Enumerated \"{}\", driver {}", name_end, idx);
++count;
name_end += strlen(name_end)+1; /* NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) */
}
@ -375,8 +379,8 @@ void InitCtxFuncs(DriverIface &iface)
#define LOAD_PROC(x) do { \
iface.x = reinterpret_cast<decltype(iface.x)>(iface.alGetProcAddress(#x));\
if(!iface.x) \
ERR("Failed to find entry point for %s in %ls\n", #x, \
iface.Name.c_str()); \
ERR("Failed to find entry point for {} in {}", #x, \
wstr_to_utf8(iface.Name)); \
} while(0)
if(iface.alcIsExtensionPresent(device, "ALC_EXT_EFX"))
{
@ -422,6 +426,8 @@ void InitCtxFuncs(DriverIface &iface)
ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *devicename) noexcept
{
LoadDrivers();
ALCdevice *device{nullptr};
std::optional<ALCuint> idx;
@ -448,10 +454,10 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *devicename) noexcep
if(!idx)
{
LastError.store(ALC_INVALID_VALUE);
TRACE("Failed to find driver for name \"%s\"\n", devicename);
TRACE("Failed to find driver for name \"{}\"", devicename);
return nullptr;
}
TRACE("Found driver %u for name \"%s\"\n", *idx, devicename);
TRACE("Found driver {} for name \"{}\"", *idx, devicename);
device = DriverList[*idx]->alcOpenDevice(devicename);
}
else
@ -459,10 +465,10 @@ ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *devicename) noexcep
ALCuint drvidx{0};
for(const auto &drv : DriverList)
{
if(drv->ALCVer >= MAKE_ALC_VER(1, 1)
if(drv->ALCVer >= MakeALCVer(1, 1)
|| drv->alcIsExtensionPresent(nullptr, "ALC_ENUMERATION_EXT"))
{
TRACE("Using default device from driver %u\n", drvidx);
TRACE("Using default device from driver {}", drvidx);
device = drv->alcOpenDevice(nullptr);
idx = drvidx;
break;
@ -685,6 +691,8 @@ ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *e
ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *device, ALCenum param) noexcept
{
LoadDrivers();
if(device)
{
if(const auto idx = maybe_get(DeviceIfaceMap, device))
@ -712,7 +720,7 @@ ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *device, ALCenum para
for(const auto &drv : DriverList)
{
/* Only enumerate names from drivers that support it. */
if(drv->ALCVer >= MAKE_ALC_VER(1, 1)
if(drv->ALCVer >= MakeALCVer(1, 1)
|| drv->alcIsExtensionPresent(nullptr, "ALC_ENUMERATION_EXT"))
DevicesList.AppendDeviceList(drv->alcGetString(nullptr,ALC_DEVICE_SPECIFIER), idx);
++idx;
@ -737,7 +745,7 @@ ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *device, ALCenum para
if(drv->alcIsExtensionPresent(nullptr, "ALC_ENUMERATE_ALL_EXT"))
AllDevicesList.AppendDeviceList(
drv->alcGetString(nullptr, ALC_ALL_DEVICES_SPECIFIER), idx);
else if(drv->ALCVer >= MAKE_ALC_VER(1, 1)
else if(drv->ALCVer >= MakeALCVer(1, 1)
|| drv->alcIsExtensionPresent(nullptr, "ALC_ENUMERATION_EXT"))
AllDevicesList.AppendDeviceList(
drv->alcGetString(nullptr, ALC_DEVICE_SPECIFIER), idx);
@ -757,7 +765,7 @@ ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *device, ALCenum para
ALCuint idx{0};
for(const auto &drv : DriverList)
{
if(drv->ALCVer >= MAKE_ALC_VER(1, 1)
if(drv->ALCVer >= MakeALCVer(1, 1)
|| drv->alcIsExtensionPresent(nullptr, "ALC_EXT_CAPTURE"))
CaptureDevicesList.AppendDeviceList(
drv->alcGetString(nullptr, ALC_CAPTURE_DEVICE_SPECIFIER), idx);
@ -774,7 +782,7 @@ ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *device, ALCenum para
{
for(const auto &drv : DriverList)
{
if(drv->ALCVer >= MAKE_ALC_VER(1, 1)
if(drv->ALCVer >= MakeALCVer(1, 1)
|| drv->alcIsExtensionPresent(nullptr, "ALC_ENUMERATION_EXT"))
return drv->alcGetString(nullptr, ALC_DEFAULT_DEVICE_SPECIFIER);
}
@ -795,7 +803,7 @@ ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *device, ALCenum para
{
for(const auto &drv : DriverList)
{
if(drv->ALCVer >= MAKE_ALC_VER(1, 1)
if(drv->ALCVer >= MakeALCVer(1, 1)
|| drv->alcIsExtensionPresent(nullptr, "ALC_EXT_CAPTURE"))
return drv->alcGetString(nullptr, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER);
}
@ -866,6 +874,8 @@ ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsi
ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *devicename, ALCuint frequency,
ALCenum format, ALCsizei buffersize) noexcept
{
LoadDrivers();
ALCdevice *device{nullptr};
std::optional<ALCuint> idx;
@ -881,10 +891,10 @@ ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *devicename,
if(!idx)
{
LastError.store(ALC_INVALID_VALUE);
TRACE("Failed to find driver for name \"%s\"\n", devicename);
TRACE("Failed to find driver for name \"{}\"", devicename);
return nullptr;
}
TRACE("Found driver %u for name \"%s\"\n", *idx, devicename);
TRACE("Found driver {} for name \"{}\"", *idx, devicename);
device = DriverList[*idx]->alcCaptureOpenDevice(devicename, frequency, format, buffersize);
}
else
@ -892,10 +902,10 @@ ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *devicename,
ALCuint drvidx{0};
for(const auto &drv : DriverList)
{
if(drv->ALCVer >= MAKE_ALC_VER(1, 1)
if(drv->ALCVer >= MakeALCVer(1, 1)
|| drv->alcIsExtensionPresent(nullptr, "ALC_EXT_CAPTURE"))
{
TRACE("Using default capture device from driver %u\n", drvidx);
TRACE("Using default capture device from driver {}", drvidx);
device = drv->alcCaptureOpenDevice(nullptr, frequency, format, buffersize);
idx = drvidx;
break;

View file

@ -15,6 +15,7 @@
#include "AL/alc.h"
#include "AL/al.h"
#include "albit.h"
#include "alstring.h"
#include "opthelpers.h"
#include "strutils.h"
@ -37,13 +38,13 @@ void AddModule(HMODULE module, const std::wstring_view name)
{
if(drv->Module == module)
{
TRACE("Skipping already-loaded module %p\n", decltype(std::declval<void*>()){module});
TRACE("Skipping already-loaded module {}", decltype(std::declval<void*>()){module});
FreeLibrary(module);
return;
}
if(drv->Name == name)
{
TRACE("Skipping similarly-named module %.*ls\n", al::sizei(name), name.data());
TRACE("Skipping similarly-named module {}", wstr_to_utf8(name));
FreeLibrary(module);
return;
}
@ -55,7 +56,7 @@ void AddModule(HMODULE module, const std::wstring_view name)
{ return al::case_compare(name, accept) == 0; });
if(iter == gAcceptList.cend())
{
TRACE("%.*ls not found in ALROUTER_ACCEPT, skipping\n", al::sizei(name), name.data());
TRACE("{} not found in ALROUTER_ACCEPT, skipping", wstr_to_utf8(name));
FreeLibrary(module);
return;
}
@ -67,7 +68,7 @@ void AddModule(HMODULE module, const std::wstring_view name)
{ return al::case_compare(name, accept) == 0; });
if(iter != gRejectList.cend())
{
TRACE("%.*ls found in ALROUTER_REJECT, skipping\n", al::sizei(name), name.data());
TRACE("{} found in ALROUTER_REJECT, skipping", wstr_to_utf8(name));
FreeLibrary(module);
return;
}
@ -83,12 +84,11 @@ void AddModule(HMODULE module, const std::wstring_view name)
auto ptr = GetProcAddress(module, fname);
if(!ptr)
{
ERR("Failed to find entry point for %s in %.*ls\n", fname, al::sizei(name),
name.data());
ERR("Failed to find entry point for {} in {}", fname, wstr_to_utf8(name));
return false;
}
func = reinterpret_cast<func_t>(reinterpret_cast<void*>(ptr));
func = al::bit_cast<func_t>(ptr);
return true;
};
#define LOAD_PROC(x) loadok &= do_load(newdrv.x, #x)
@ -181,12 +181,11 @@ void AddModule(HMODULE module, const std::wstring_view name)
newdrv.alcGetIntegerv(nullptr, ALC_MAJOR_VERSION, 1, &alc_ver[0]);
newdrv.alcGetIntegerv(nullptr, ALC_MINOR_VERSION, 1, &alc_ver[1]);
if(newdrv.alcGetError(nullptr) == ALC_NO_ERROR)
newdrv.ALCVer = MAKE_ALC_VER(alc_ver[0], alc_ver[1]);
newdrv.ALCVer = MakeALCVer(alc_ver[0], alc_ver[1]);
else
{
WARN("Failed to query ALC version for %.*ls, assuming 1.0\n", al::sizei(name),
name.data());
newdrv.ALCVer = MAKE_ALC_VER(1, 0);
WARN("Failed to query ALC version for {}, assuming 1.0", wstr_to_utf8(name));
newdrv.ALCVer = MakeALCVer(1, 0);
}
auto do_load2 = [module,name](auto &func, const char *fname) -> void
@ -194,10 +193,10 @@ void AddModule(HMODULE module, const std::wstring_view name)
using func_t = std::remove_reference_t<decltype(func)>;
auto ptr = GetProcAddress(module, fname);
if(!ptr)
WARN("Failed to find optional entry point for %s in %.*ls\n", fname,
al::sizei(name), name.data());
WARN("Failed to find optional entry point for {} in {}", fname,
wstr_to_utf8(name));
else
func = reinterpret_cast<func_t>(reinterpret_cast<void*>(ptr));
func = al::bit_cast<func_t>(ptr);
};
#define LOAD_PROC(x) do_load2(newdrv.x, #x)
LOAD_PROC(alBufferf);
@ -220,8 +219,7 @@ void AddModule(HMODULE module, const std::wstring_view name)
auto ptr = newdrv.alcGetProcAddress(nullptr, fname);
if(!ptr)
{
ERR("Failed to find entry point for %s in %.*ls\n", fname, al::sizei(name),
name.data());
ERR("Failed to find entry point for {} in {}", fname, wstr_to_utf8(name));
return false;
}
@ -242,13 +240,13 @@ void AddModule(HMODULE module, const std::wstring_view name)
DriverList.pop_back();
return;
}
TRACE("Loaded module %p, %.*ls, ALC %d.%d\n", decltype(std::declval<void*>()){module},
al::sizei(name), name.data(), newdrv.ALCVer>>8, newdrv.ALCVer&255);
TRACE("Loaded module {}, {}, ALC {}.{}", decltype(std::declval<void*>()){module},
wstr_to_utf8(name), newdrv.ALCVer>>8, newdrv.ALCVer&255);
}
void SearchDrivers(const std::wstring_view path)
{
TRACE("Searching for drivers in %.*ls...\n", al::sizei(path), path.data());
TRACE("Searching for drivers in {}...", wstr_to_utf8(path));
std::wstring srchPath{path};
srchPath += L"\\*oal.dll";
@ -260,11 +258,11 @@ void SearchDrivers(const std::wstring_view path)
srchPath = path;
srchPath += L"\\";
srchPath += std::data(fdata.cFileName);
TRACE("Found %ls\n", srchPath.c_str());
TRACE("Found {}", wstr_to_utf8(srchPath));
HMODULE mod{LoadLibraryW(srchPath.c_str())};
if(!mod)
WARN("Could not load %ls\n", srchPath.c_str());
WARN("Could not load {}", wstr_to_utf8(srchPath));
else
AddModule(mod, std::data(fdata.cFileName));
} while(FindNextFileW(srchHdl, &fdata));
@ -306,8 +304,12 @@ bool GetLoadedModuleDirectory(const WCHAR *name, std::wstring *moddir)
return !moddir->empty();
}
} // namespace
void LoadDriverList()
{
TRACE("Initializing router v0.1-{} {}", ALSOFT_GIT_COMMIT_HASH, ALSOFT_GIT_BRANCH);
if(auto list = al::getenv(L"ALROUTER_ACCEPT"))
{
std::wstring_view namelist{*list};
@ -339,7 +341,7 @@ void LoadDriverList()
std::wstring dll_path;
if(GetLoadedModuleDirectory(L"OpenAL32.dll", &dll_path))
TRACE("Got DLL path %ls\n", dll_path.c_str());
TRACE("Got DLL path {}", wstr_to_utf8(dll_path));
std::wstring cwd_path;
if(DWORD pathlen{GetCurrentDirectoryW(0, nullptr)})
@ -353,11 +355,11 @@ void LoadDriverList()
if(!cwd_path.empty() && (cwd_path.back() == '\\' || cwd_path.back() == '/'))
cwd_path.pop_back();
if(!cwd_path.empty())
TRACE("Got current working directory %ls\n", cwd_path.c_str());
TRACE("Got current working directory {}", wstr_to_utf8(cwd_path));
std::wstring proc_path;
if(GetLoadedModuleDirectory(nullptr, &proc_path))
TRACE("Got proc path %ls\n", proc_path.c_str());
TRACE("Got proc path {}", wstr_to_utf8(proc_path));
std::wstring sys_path;
if(UINT pathlen{GetSystemDirectoryW(nullptr, 0)})
@ -371,39 +373,55 @@ void LoadDriverList()
if(!sys_path.empty() && (sys_path.back() == '\\' || sys_path.back() == '/'))
sys_path.pop_back();
if(!sys_path.empty())
TRACE("Got system path %ls\n", sys_path.c_str());
TRACE("Got system path {}", wstr_to_utf8(sys_path));
/* Don't search the DLL's path if it is the same as the current working
* directory, app's path, or system path (don't want to do duplicate
* searches, or increase the priority of the app or system path).
*/
if(!dll_path.empty() &&
(cwd_path.empty() || dll_path != cwd_path) &&
(proc_path.empty() || dll_path != proc_path) &&
(sys_path.empty() || dll_path != sys_path))
if(!dll_path.empty() && (cwd_path.empty() || dll_path != cwd_path)
&& (proc_path.empty() || dll_path != proc_path)
&& (sys_path.empty() || dll_path != sys_path))
SearchDrivers(dll_path);
if(!cwd_path.empty() &&
(proc_path.empty() || cwd_path != proc_path) &&
(sys_path.empty() || cwd_path != sys_path))
if(!cwd_path.empty() && (proc_path.empty() || cwd_path != proc_path)
&& (sys_path.empty() || cwd_path != sys_path))
SearchDrivers(cwd_path);
if(!proc_path.empty() && (sys_path.empty() || proc_path != sys_path))
SearchDrivers(proc_path);
if(!sys_path.empty())
SearchDrivers(sys_path);
}
} // namespace
/* Sort drivers that can enumerate device names to the front. */
static constexpr auto is_enumerable = [](DriverIfacePtr &drv)
{
return drv->ALCVer >= MakeALCVer(1, 1)
|| drv->alcIsExtensionPresent(nullptr, "ALC_ENUMERATE_ALL_EXT")
|| drv->alcIsExtensionPresent(nullptr, "ALC_ENUMERATION_EXT");
};
std::stable_partition(DriverList.begin(), DriverList.end(), is_enumerable);
/* HACK: rapture3d_oal.dll isn't likely to work if it's one distributed for
* specific games licensed to use it. It will enumerate a Rapture3D device
* but fail to open. This isn't much of a problem, the device just won't
* work for users not allowed to use it. But if it's the first in the list
* where it gets used for the default device, the default device will fail
* to open. Move it down so it's not used for the default device.
*/
if(DriverList.size() > 1
&& al::case_compare(DriverList.front()->Name, L"rapture3d_oal.dll") == 0)
std::swap(*DriverList.begin(), *(DriverList.begin()+1));
}
BOOL APIENTRY DllMain(HINSTANCE, DWORD reason, void*)
{
switch(reason)
{
case DLL_PROCESS_ATTACH:
if(auto logfname = al::getenv("ALROUTER_LOGFILE"))
if(auto logfname = al::getenv(L"ALROUTER_LOGFILE"))
{
gsl::owner<std::FILE*> f{fopen(logfname->c_str(), "w")};
gsl::owner<std::FILE*> f{_wfopen(logfname->c_str(), L"w")};
if(f == nullptr)
ERR("Could not open log file: %s\n", logfname->c_str());
ERR("Could not open log file: {}", wstr_to_utf8(*logfname));
else
LogFile = f;
}
@ -412,16 +430,13 @@ BOOL APIENTRY DllMain(HINSTANCE, DWORD reason, void*)
char *end = nullptr;
long l{strtol(loglev->c_str(), &end, 0)};
if(!end || *end != '\0')
ERR("Invalid log level value: %s\n", loglev->c_str());
ERR("Invalid log level value: {}", *loglev);
else if(l < al::to_underlying(eLogLevel::None)
|| l > al::to_underlying(eLogLevel::Trace))
ERR("Log level out of range: %s\n", loglev->c_str());
ERR("Log level out of range: {}", *loglev);
else
LogLevel = static_cast<eLogLevel>(l);
}
TRACE("Initializing router v0.1-%s %s\n", ALSOFT_GIT_COMMIT_HASH, ALSOFT_GIT_BRANCH);
LoadDriverList();
break;
case DLL_THREAD_ATTACH:

View file

@ -18,9 +18,10 @@
#include "AL/alext.h"
#include "almalloc.h"
#include "fmt/core.h"
#define MAKE_ALC_VER(major, minor) (((major)<<8) | (minor))
constexpr auto MakeALCVer(int major, int minor) noexcept -> int { return (major<<8) | minor; }
struct DriverIface {
LPALCCREATECONTEXT alcCreateContext{nullptr};
@ -159,7 +160,7 @@ struct DriverIface {
std::wstring Name;
HMODULE Module{nullptr};
int ALCVer{0};
std::once_flag InitOnceCtx{};
std::once_flag InitOnceCtx;
template<typename T>
DriverIface(T&& name, HMODULE mod) : Name(std::forward<T>(name)), Module(mod) { }
@ -190,29 +191,32 @@ enum class eLogLevel {
extern eLogLevel LogLevel;
extern gsl::owner<std::FILE*> LogFile;
#define TRACE(...) do { \
if(LogLevel >= eLogLevel::Trace) \
{ \
std::FILE *file{LogFile ? LogFile : stderr}; \
fprintf(file, "AL Router (II): " __VA_ARGS__); \
fflush(file); \
} \
#define TRACE(...) do { \
if(LogLevel >= eLogLevel::Trace) \
{ \
std::FILE *file{LogFile ? LogFile : stderr}; \
fmt::println(file, "AL Router (II): " __VA_ARGS__); \
fflush(file); \
} \
} while(0)
#define WARN(...) do { \
if(LogLevel >= eLogLevel::Warn) \
{ \
std::FILE *file{LogFile ? LogFile : stderr}; \
fprintf(file, "AL Router (WW): " __VA_ARGS__); \
fflush(file); \
} \
#define WARN(...) do { \
if(LogLevel >= eLogLevel::Warn) \
{ \
std::FILE *file{LogFile ? LogFile : stderr}; \
fmt::println(file, "AL Router (WW): " __VA_ARGS__); \
fflush(file); \
} \
} while(0)
#define ERR(...) do { \
if(LogLevel >= eLogLevel::Error) \
{ \
std::FILE *file{LogFile ? LogFile : stderr}; \
fprintf(file, "AL Router (EE): " __VA_ARGS__); \
fflush(file); \
} \
#define ERR(...) do { \
if(LogLevel >= eLogLevel::Error) \
{ \
std::FILE *file{LogFile ? LogFile : stderr}; \
fmt::println(file, "AL Router (EE): " __VA_ARGS__); \
fflush(file); \
} \
} while(0)
void LoadDriverList();
#endif /* ROUTER_ROUTER_H */