diff --git a/src/xenia/apu/audio_system.cc b/src/xenia/apu/audio_system.cc index aa9eb8dac..0f34c4dd0 100644 --- a/src/xenia/apu/audio_system.cc +++ b/src/xenia/apu/audio_system.cc @@ -22,7 +22,8 @@ using namespace xe::cpu; AudioSystem::AudioSystem(Emulator* emulator) : emulator_(emulator), memory_(emulator->memory()), - thread_(0), running_(false), driver_(0) { + thread_(0), running_(false), driver_(0), + client_({ 0 }) { // Create the run loop used for any windows/etc. // This must be done on the thread we create the driver. run_loop_ = xe_run_loop_create(); @@ -86,16 +87,16 @@ void AudioSystem::ThreadStart() { } // Pump worker. - // mehhh xe_mutex_lock(lock_); - auto clients = clients_; + uint32_t client_callback = client_.callback; + uint32_t client_callback_arg = client_.wrapped_callback_arg; xe_mutex_unlock(lock_); - for (auto it = clients.begin(); it != clients.end(); ++it) { + if (client_callback) { processor->Execute( - thread_state_, it->callback, it->wrapped_callback_arg, 0); + thread_state_, client_callback, client_callback_arg, 0); + } else { + Sleep(500); } - //worker_->Pump(); - Sleep(1000); if (!running_) { break; @@ -127,11 +128,21 @@ void AudioSystem::Shutdown() { void AudioSystem::RegisterClient( uint32_t callback, uint32_t callback_arg) { + // Only support one client for now. + XEASSERTZERO(client_.callback); + uint32_t ptr = (uint32_t)memory()->HeapAlloc(0, 0x4, 0); auto mem = memory()->membase(); XESETUINT32BE(mem + ptr, callback_arg); + xe_mutex_lock(lock_); - clients_.push_back({ callback, callback_arg, ptr }); + client_ = { callback, callback_arg, ptr }; + xe_mutex_unlock(lock_); +} + +void AudioSystem::UnregisterClient() { + xe_mutex_lock(lock_); + client_ = { 0 }; xe_mutex_unlock(lock_); } diff --git a/src/xenia/apu/audio_system.h b/src/xenia/apu/audio_system.h index c4e87f046..e8d3907b1 100644 --- a/src/xenia/apu/audio_system.h +++ b/src/xenia/apu/audio_system.h @@ -37,7 +37,8 @@ public: virtual void Shutdown(); void RegisterClient(uint32_t callback, uint32_t callback_arg); - //void UnregisterClient(); + void UnregisterClient(); + virtual void SubmitFrame(uint32_t samples_ptr) = 0; bool HandlesRegister(uint64_t addr); virtual uint64_t ReadRegister(uint64_t addr); @@ -76,14 +77,13 @@ protected: cpu::XenonThreadState* thread_state_; uint32_t thread_block_; bool running_; - xe_mutex_t* lock_; - typedef struct { + xe_mutex_t* lock_; + struct { uint32_t callback; uint32_t callback_arg; uint32_t wrapped_callback_arg; - } RenderDriverClient; - std::vector clients_; + } client_; AudioDriver* driver_; }; diff --git a/src/xenia/apu/nop/nop_audio_system.cc b/src/xenia/apu/nop/nop_audio_system.cc index 3354229af..f4d0caaa6 100644 --- a/src/xenia/apu/nop/nop_audio_system.cc +++ b/src/xenia/apu/nop/nop_audio_system.cc @@ -36,6 +36,10 @@ void NopAudioSystem::Pump() { // } +void NopAudioSystem::SubmitFrame(uint32_t samples_ptr) { + // Process samples! They are big-endian floats. +} + void NopAudioSystem::Shutdown() { AudioSystem::Shutdown(); } diff --git a/src/xenia/apu/nop/nop_audio_system.h b/src/xenia/apu/nop/nop_audio_system.h index ca82975bd..5a71aaf7d 100644 --- a/src/xenia/apu/nop/nop_audio_system.h +++ b/src/xenia/apu/nop/nop_audio_system.h @@ -28,6 +28,8 @@ public: virtual void Shutdown(); + virtual void SubmitFrame(uint32_t samples_ptr); + protected: virtual void Initialize(); virtual void Pump(); diff --git a/src/xenia/kernel/xboxkrnl_audio.cc b/src/xenia/kernel/xboxkrnl_audio.cc index 68f47a6b2..6ea55ea6f 100644 --- a/src/xenia/kernel/xboxkrnl_audio.cc +++ b/src/xenia/kernel/xboxkrnl_audio.cc @@ -111,8 +111,10 @@ SHIM_CALL XAudioUnregisterRenderDriverClient_shim( "XAudioUnregisterRenderDriverClient(%.8X)", driver_ptr); + XEASSERT(driver_ptr == 0xAADD1100); + auto audio_system = state->emulator()->audio_system(); - //audio_system->UnregisterClient(...); + audio_system->UnregisterClient(); SHIM_SET_RETURN(X_ERROR_SUCCESS); } @@ -127,8 +129,10 @@ SHIM_CALL XAudioSubmitRenderDriverFrame_shim( "XAudioSubmitRenderDriverFrame(%.8X, %.8X)", driver_ptr, samples_ptr); + XEASSERT(driver_ptr == 0xAADD1100); + auto audio_system = state->emulator()->audio_system(); - //audio_system->SubmitFrame(); + audio_system->SubmitFrame(samples_ptr); SHIM_SET_RETURN(X_ERROR_SUCCESS); }