added device selection

This commit is contained in:
georgemoralis 2026-02-12 17:33:07 +02:00
parent 44df27bf70
commit 6ac4412155
2 changed files with 106 additions and 19 deletions

View File

@ -191,8 +191,15 @@ public:
private:
bool Initialize(OrbisAudioOutPort type) {
if (!OpenALDevice::GetInstance().IsInitialized()) {
LOG_ERROR(Lib_AudioOut, "OpenAL device not initialized");
const std::string device_name = GetDeviceName(type);
if (!OpenALDevice::GetInstance().SelectDevice(device_name)) {
if (device_name == "None") {
LOG_INFO(Lib_AudioOut, "Audio device disabled for port type {}",
static_cast<int>(type));
} else {
LOG_ERROR(Lib_AudioOut, "Failed to open OpenAL device '{}'", device_name);
}
return false;
}
@ -268,6 +275,18 @@ private:
return true;
}
std::string GetDeviceName(OrbisAudioOutPort type) const {
switch (type) {
case OrbisAudioOutPort::Main:
case OrbisAudioOutPort::Bgm:
return Config::getMainOutputDevice();
case OrbisAudioOutPort::PadSpk:
return Config::getPadSpkOutputDevice();
default:
return Config::getMainOutputDevice();
}
}
void Cleanup() {
if (!device_context->MakeCurrent()) {
return;

View File

@ -1,9 +1,9 @@
// SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <mutex>
#include <string>
#include <vector>
#include <AL/al.h>
#include <AL/alc.h>
@ -17,24 +17,25 @@ public:
}
bool IsInitialized() const {
std::lock_guard<std::mutex> lock(mutex);
return initialized;
}
ALCdevice* GetDevice() const {
std::lock_guard<std::mutex> lock(mutex);
return device;
}
ALCcontext* GetContext() const {
std::lock_guard<std::mutex> lock(mutex);
return context;
}
bool MakeCurrent() {
std::lock_guard<std::mutex> lock(mutex);
if (!initialized) {
return false;
}
return alcMakeContextCurrent(context);
}
@ -43,11 +44,57 @@ public:
alcMakeContextCurrent(nullptr);
}
private:
OpenALDevice() {
Initialize();
// Select a specific audio device
bool SelectDevice(const std::string& device_name) {
std::lock_guard<std::mutex> lock(mutex);
// If already initialized, clean up first
if (initialized) {
CleanupInternal();
}
return InitializeInternal(device_name);
}
// Get the name of the currently opened device
std::string GetCurrentDeviceName() const {
std::lock_guard<std::mutex> lock(mutex);
return current_device_name;
}
// Check if device enumeration is supported
static bool IsDeviceEnumerationSupported() {
return alcIsExtensionPresent(nullptr, "ALC_ENUMERATION_EXT") ||
alcIsExtensionPresent(nullptr, "ALC_ENUMERATE_ALL_EXT");
}
// Get list of available devices (returns empty vector if enumeration not supported)
static std::vector<std::string> GetAvailableDevices() {
std::vector<std::string> devices_list;
if (!IsDeviceEnumerationSupported()) {
return devices_list;
}
// Get device list
const ALCchar* devices = alcGetString(nullptr, ALC_DEVICE_SPECIFIER);
if (!devices) {
return devices_list;
}
// Parse null-separated list
const ALCchar* ptr = devices;
while (ptr && *ptr) {
devices_list.emplace_back(ptr);
ptr += strlen(ptr) + 1;
}
return devices_list;
}
private:
OpenALDevice() {}
~OpenALDevice() {
Cleanup();
}
@ -55,17 +102,28 @@ private:
OpenALDevice(const OpenALDevice&) = delete;
OpenALDevice& operator=(const OpenALDevice&) = delete;
void Initialize() {
std::lock_guard<std::mutex> lock(mutex);
if (initialized) {
return;
bool InitializeInternal(const std::string& device_name) {
// Handle disabled audio
if (device_name == "None") {
initialized = false;
return false;
}
// Open the requested device
if (device_name.empty() || device_name == "Default Device") {
device = alcOpenDevice(nullptr); // Default device
} else {
// Try to open specific device
device = alcOpenDevice(device_name.c_str());
if (!device) {
// Device not found, fall back to default
device = alcOpenDevice(nullptr);
}
}
// Open default device
device = alcOpenDevice(nullptr);
if (!device) {
return;
return false;
}
// Create context
@ -73,20 +131,28 @@ private:
if (!context) {
alcCloseDevice(device);
device = nullptr;
return;
return false;
}
// Get actual device name
const ALCchar* actual_name = alcGetString(device, ALC_DEVICE_SPECIFIER);
current_device_name = actual_name ? actual_name : "Unknown";
initialized = true;
return true;
}
void Cleanup() {
std::lock_guard<std::mutex> lock(mutex);
CleanupInternal();
}
void CleanupInternal() {
if (!initialized) {
return;
}
ReleaseContext();
alcMakeContextCurrent(nullptr);
if (context) {
alcDestroyContext(context);
@ -98,12 +164,14 @@ private:
device = nullptr;
}
current_device_name.clear();
initialized = false;
}
ALCdevice* device{nullptr};
ALCcontext* context{nullptr};
bool initialized{false};
std::string current_device_name;
mutable std::mutex mutex;
};