Refactor audio_thread (g_idm)

This commit is contained in:
Nekotekina 2018-10-02 11:40:37 +03:00
parent a8a9c11bf8
commit 1b740995a4
2 changed files with 46 additions and 30 deletions

View file

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

View file

@ -129,7 +129,7 @@ public:
std::vector<u64> keys; std::vector<u64> keys;
shared_mutex mutex; void operator()();
audio_thread(vm::ptr<char> buf, vm::ptr<u64> ind) audio_thread(vm::ptr<char> buf, vm::ptr<u64> ind)
: m_buffer(buf) : m_buffer(buf)
@ -143,8 +143,6 @@ public:
} }
} }
std::pair<u32, u32> operator()();
audio_port* open_port() audio_port* open_port()
{ {
for (u32 i = 0; i < AUDIO_PORT_COUNT; i++) for (u32 i = 0; i < AUDIO_PORT_COUNT; i++)