Files
Xenia-Canary/src/xenia/apu/alsa/alsa_audio_system.cc
2026-02-17 23:46:16 +09:00

95 lines
2.9 KiB
C++

/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2025. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#include "xenia/apu/alsa/alsa_audio_system.h"
#include <alsa/asoundlib.h>
#include "xenia/apu/alsa/alsa_audio_driver.h"
#include "xenia/apu/apu_flags.h"
#include "xenia/base/logging.h"
namespace xe {
namespace apu {
namespace alsa {
ALSAAudioSystem::ALSAAudioSystem(cpu::Processor* processor)
: AudioSystem(processor) {}
ALSAAudioSystem::~ALSAAudioSystem() {}
bool ALSAAudioSystem::IsAvailable() {
// Check if ALSA is available by trying to open a dummy PCM device
snd_pcm_t* pcm = nullptr;
int err =
snd_pcm_open(&pcm, "default", SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
if (err >= 0 && pcm) {
snd_pcm_close(pcm);
return true;
}
return false;
}
void ALSAAudioSystem::Initialize() {}
std::unique_ptr<AudioSystem> ALSAAudioSystem::Create(
cpu::Processor* processor) {
if (!IsAvailable()) {
XELOGE("ALSA is not available on this system");
return nullptr;
}
return std::make_unique<ALSAAudioSystem>(processor);
}
X_RESULT ALSAAudioSystem::CreateDriver(size_t index,
xe::threading::Semaphore* semaphore,
AudioDriver** out_driver) {
assert_not_null(out_driver);
XELOGI("ALSAAudioSystem::CreateDriver for client index {}", index);
// Create a new driver for each client
// ALSA's dmix plugin should handle mixing multiple streams
auto driver = new ALSAAudioDriver(semaphore);
if (!driver->Initialize()) {
XELOGE("Failed to initialize ALSA driver for client index {}", index);
delete driver;
*out_driver = nullptr;
return X_ERROR_NOT_FOUND;
}
*out_driver = driver;
XELOGI("Successfully created ALSA driver for client index {}", index);
return X_ERROR_SUCCESS;
}
AudioDriver* ALSAAudioSystem::CreateDriver(xe::threading::Semaphore* semaphore,
uint32_t frequency,
uint32_t channels,
bool need_format_conversion) {
auto driver = new ALSAAudioDriver(semaphore, frequency, channels,
need_format_conversion);
if (!driver->Initialize()) {
delete driver;
return nullptr;
}
return driver;
}
void ALSAAudioSystem::DestroyDriver(AudioDriver* driver) {
assert_not_null(driver);
ALSAAudioDriver* alsa_driver = static_cast<ALSAAudioDriver*>(driver);
alsa_driver->Shutdown();
delete alsa_driver;
}
} // namespace alsa
} // namespace apu
} // namespace xe