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);
@ -59,7 +59,7 @@ std::pair<u32, u32> audio_thread::operator()()
const auto audio = Emu.GetCallbacks().get_audio();
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())
{
@ -303,10 +303,11 @@ std::pair<u32, u32> audio_thread::operator()()
// 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)
{
// 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<u32, u32> 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_config>("Audio Thread", buf, ind);
auto g_audio = g_idm->lock<named_thread<audio_thread>>(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<audio_config>();
auto g_audio = g_idm->lock<named_thread<audio_thread>>(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<named_thread<audio_thread>>(0);
if (*g_audio.get() == thread_state::finished)
{
g_audio.destroy();
break;
}
}
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);
const auto g_audio = fxm::get<audio_config>();
const auto g_audio = g_idm->lock<named_thread<audio_thread>>(0);
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);
const auto g_audio = fxm::get<audio_config>();
const auto g_audio = g_idm->lock<named_thread<audio_thread>>(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<audio_config>();
const auto g_audio = g_idm->lock<named_thread<audio_thread>>(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<audio_config>();
const auto g_audio = g_idm->lock<named_thread<audio_thread>>(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<audio_config>();
const auto g_audio = g_idm->lock<named_thread<audio_thread>>(0);
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);
const auto g_audio = fxm::get<audio_config>();
const auto g_audio = g_idm->lock<named_thread<audio_thread>>(0);
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);
const auto g_audio = fxm::get<audio_config>();
const auto g_audio = g_idm->lock<named_thread<audio_thread>>(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<audio_config>();
const auto g_audio = g_idm->lock<named_thread<audio_thread>>(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<audio_config>();
const auto g_audio = g_idm->lock<named_thread<audio_thread>>(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<audio_config>();
const auto g_audio = g_idm->lock<named_thread<audio_thread>>(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<float> 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<audio_config>();
auto g_audio = g_idm->lock<named_thread<audio_thread>>(0);
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)});
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<float> 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<audio_config>();
auto g_audio = g_idm->lock<named_thread<audio_thread>>(0);
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)});
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<float> src, float 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)
{
@ -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)});
g_audio.unlock();
if (port.channel == 6)
{
for (u32 i = 0; i < 256; i++)

View File

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