diff --git a/rpcs3/Emu/Cell/Modules/cellAudio.cpp b/rpcs3/Emu/Cell/Modules/cellAudio.cpp index a4a35a50a7..b40578a146 100644 --- a/rpcs3/Emu/Cell/Modules/cellAudio.cpp +++ b/rpcs3/Emu/Cell/Modules/cellAudio.cpp @@ -38,7 +38,7 @@ void fmt_class_string::format(std::string& out, u64 arg) }); } -std::pair audio_thread::operator()() +void audio_thread::operator()() { thread_ctrl::set_native_priority(1); @@ -59,7 +59,7 @@ std::pair audio_thread::operator()() const auto audio = Emu.GetCallbacks().get_audio(); audio->Open(buf8ch, buf_sz); - while (fxm::check() == this && !Emu.IsStopped()) + while (thread_ctrl::state() != thread_state::aborting && !Emu.IsStopped()) { if (Emu.IsPaused()) { @@ -303,10 +303,11 @@ std::pair audio_thread::operator()() // send aftermix event (normal audio event) - std::lock_guard lock(mutex); + auto _locked = g_idm->lock>(0); for (u64 key : keys) { + // TODO: move out of the lock scope if (auto queue = lv2_event_queue::find(key)) { queue->send(0, 0, 0, 0); // TODO: check arguments @@ -326,7 +327,8 @@ std::pair audio_thread::operator()() stamp1 - stamp0, stamp2 - stamp1, stamp3 - stamp2, get_system_time() - stamp3); } - return {m_buffer.addr(), m_indexes.addr()}; + vm::dealloc(m_buffer.addr()); + vm::dealloc(m_indexes.addr()); } error_code cellAudioInit() @@ -337,7 +339,7 @@ error_code cellAudioInit() const auto ind = vm::cast(vm::alloc(sizeof(u64) * AUDIO_PORT_COUNT, vm::main)); // Start audio thread - const auto g_audio = fxm::make("Audio Thread", buf, ind); + auto g_audio = g_idm->lock>(id_new); if (!g_audio) { @@ -346,6 +348,7 @@ error_code cellAudioInit() return CELL_AUDIO_ERROR_ALREADY_INIT; } + g_audio.create("Audio Thread", buf, ind); return CELL_OK; } @@ -354,17 +357,30 @@ error_code cellAudioQuit() cellAudio.warning("cellAudioQuit()"); // Stop audio thread - const auto g_audio = fxm::withdraw(); + auto g_audio = g_idm->lock>(0); if (!g_audio) { return CELL_AUDIO_ERROR_NOT_INIT; } - // Join and dealloc - auto [buf, ind] = g_audio->operator()(); - vm::dealloc(buf); - vm::dealloc(ind); + // Signal to abort, release lock + *g_audio.get() = thread_state::aborting; + g_audio.unlock(); + + while (true) + { + thread_ctrl::wait_for(1000); + + auto g_audio = g_idm->lock>(0); + + if (*g_audio.get() == thread_state::finished) + { + g_audio.destroy(); + break; + } + } + return CELL_OK; } @@ -372,7 +388,7 @@ error_code cellAudioPortOpen(vm::ptr audioParam, vm::ptr(); + const auto g_audio = g_idm->lock>(0); if (!g_audio) { @@ -472,7 +488,7 @@ error_code cellAudioGetPortConfig(u32 portNum, vm::ptr port { cellAudio.warning("cellAudioGetPortConfig(portNum=%d, portConfig=*0x%x)", portNum, portConfig); - const auto g_audio = fxm::get(); + const auto g_audio = g_idm->lock>(0); if (!g_audio) { @@ -507,7 +523,7 @@ error_code cellAudioPortStart(u32 portNum) { cellAudio.warning("cellAudioPortStart(portNum=%d)", portNum); - const auto g_audio = fxm::get(); + const auto g_audio = g_idm->lock>(0); if (!g_audio) { @@ -532,7 +548,7 @@ error_code cellAudioPortClose(u32 portNum) { cellAudio.warning("cellAudioPortClose(portNum=%d)", portNum); - const auto g_audio = fxm::get(); + const auto g_audio = g_idm->lock>(0); if (!g_audio) { @@ -557,7 +573,7 @@ error_code cellAudioPortStop(u32 portNum) { cellAudio.warning("cellAudioPortStop(portNum=%d)", portNum); - const auto g_audio = fxm::get(); + const auto g_audio = g_idm->lock>(0); if (!g_audio) { @@ -582,7 +598,7 @@ error_code cellAudioGetPortTimestamp(u32 portNum, u64 tag, vm::ptr stamp) { cellAudio.trace("cellAudioGetPortTimestamp(portNum=%d, tag=0x%llx, stamp=*0x%x)", portNum, tag, stamp); - const auto g_audio = fxm::get(); + const auto g_audio = g_idm->lock>(0); if (!g_audio) { @@ -612,7 +628,7 @@ error_code cellAudioGetPortBlockTag(u32 portNum, u64 blockNo, vm::ptr tag) { cellAudio.trace("cellAudioGetPortBlockTag(portNum=%d, blockNo=0x%llx, tag=*0x%x)", portNum, blockNo, tag); - const auto g_audio = fxm::get(); + const auto g_audio = g_idm->lock>(0); if (!g_audio) { @@ -655,7 +671,7 @@ error_code cellAudioSetPortLevel(u32 portNum, float level) { cellAudio.trace("cellAudioSetPortLevel(portNum=%d, level=%f)", portNum, level); - const auto g_audio = fxm::get(); + const auto g_audio = g_idm->lock>(0); if (!g_audio) { @@ -735,15 +751,13 @@ error_code cellAudioSetNotifyEventQueue(u64 key) { cellAudio.warning("cellAudioSetNotifyEventQueue(key=0x%llx)", key); - const auto g_audio = fxm::get(); + const auto g_audio = g_idm->lock>(0); if (!g_audio) { return CELL_AUDIO_ERROR_NOT_INIT; } - std::lock_guard lock(g_audio->mutex); - for (auto k : g_audio->keys) // check for duplicates { if (k == key) @@ -770,15 +784,13 @@ error_code cellAudioRemoveNotifyEventQueue(u64 key) { cellAudio.warning("cellAudioRemoveNotifyEventQueue(key=0x%llx)", key); - const auto g_audio = fxm::get(); + const auto g_audio = g_idm->lock>(0); if (!g_audio) { return CELL_AUDIO_ERROR_NOT_INIT; } - std::lock_guard lock(g_audio->mutex); - for (auto i = g_audio->keys.begin(); i != g_audio->keys.end(); i++) { if (*i == key) @@ -805,7 +817,7 @@ error_code cellAudioAddData(u32 portNum, vm::ptr src, u32 samples, float { cellAudio.trace("cellAudioAddData(portNum=%d, src=*0x%x, samples=%d, volume=%f)", portNum, src, samples, volume); - const auto g_audio = fxm::get(); + auto g_audio = g_idm->lock>(0); if (!g_audio) { @@ -828,6 +840,8 @@ error_code cellAudioAddData(u32 portNum, vm::ptr src, u32 samples, float const auto dst = vm::ptr::make(port.addr.addr() + u32(port.tag % port.block) * port.channel * 256 * u32{sizeof(float)}); + g_audio.unlock(); + for (u32 i = 0; i < samples * port.channel; i++) { dst[i] += src[i] * volume; // mix all channels @@ -840,7 +854,7 @@ error_code cellAudioAdd2chData(u32 portNum, vm::ptr src, u32 samples, flo { cellAudio.trace("cellAudioAdd2chData(portNum=%d, src=*0x%x, samples=%d, volume=%f)", portNum, src, samples, volume); - const auto g_audio = fxm::get(); + auto g_audio = g_idm->lock>(0); if (!g_audio) { @@ -863,6 +877,8 @@ error_code cellAudioAdd2chData(u32 portNum, vm::ptr src, u32 samples, flo const auto dst = vm::ptr::make(port.addr.addr() + s32(port.tag % port.block) * port.channel * 256 * u32{sizeof(float)}); + g_audio.unlock(); + if (port.channel == 2) { for (u32 i = 0; i < samples; i++) @@ -909,7 +925,7 @@ error_code cellAudioAdd6chData(u32 portNum, vm::ptr src, float volume) { cellAudio.trace("cellAudioAdd6chData(portNum=%d, src=*0x%x, volume=%f)", portNum, src, volume); - const auto g_audio = fxm::get(); + auto g_audio = g_idm->lock>(0); if (!g_audio) { @@ -925,6 +941,8 @@ error_code cellAudioAdd6chData(u32 portNum, vm::ptr src, float volume) const auto dst = vm::ptr::make(port.addr.addr() + s32(port.tag % port.block) * port.channel * 256 * u32{sizeof(float)}); + g_audio.unlock(); + if (port.channel == 6) { for (u32 i = 0; i < 256; i++) diff --git a/rpcs3/Emu/Cell/Modules/cellAudio.h b/rpcs3/Emu/Cell/Modules/cellAudio.h index 4314e6b433..ffe9367f34 100644 --- a/rpcs3/Emu/Cell/Modules/cellAudio.h +++ b/rpcs3/Emu/Cell/Modules/cellAudio.h @@ -129,7 +129,7 @@ public: std::vector keys; - shared_mutex mutex; + void operator()(); audio_thread(vm::ptr buf, vm::ptr ind) : m_buffer(buf) @@ -143,8 +143,6 @@ public: } } - std::pair operator()(); - audio_port* open_port() { for (u32 i = 0; i < AUDIO_PORT_COUNT; i++)