diff --git a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp index 0def6405ba..67fd473b3a 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp @@ -73,8 +73,6 @@ s32 cellAudioInit() squeue_t out_queue; - std::vector keys; - thread_t iat("Internal Audio Thread", true /* autojoin */, [&out_queue]() { const bool use_u16 = Ini.AudioConvertToU16.GetValue(); @@ -374,11 +372,13 @@ s32 cellAudioInit() //const u64 stamp2 = get_system_time(); - // send aftermix event (normal audio event) { std::lock_guard lock(g_audio.mutex); - // update indexes: + + // update indices: + auto indexes = vm::ptr::make(g_audio.indexes); + for (u32 i = 0; i < AUDIO_PORT_COUNT; i++) { AudioPortConfig& port = g_audio.ports[i]; @@ -390,16 +390,14 @@ s32 cellAudioInit() port.tag++; // absolute index of block that will be read indexes[i] = (position + 1) % port.block; // write new value } - // load keys: - keys.resize(g_audio.keys.size()); - memcpy(keys.data(), g_audio.keys.data(), sizeof(u64) * keys.size()); - } - { + + // send aftermix event (normal audio event) + LV2_LOCK; - for (u32 i = 0; i < keys.size(); i++) + for (auto key : g_audio.keys) { - if (std::shared_ptr queue = Emu.GetEventManager().GetEventQueue(keys[i])) + if (std::shared_ptr queue = Emu.GetEventManager().GetEventQueue(key)) { queue->push(0, 0, 0, 0); // TODO: check arguments } @@ -455,7 +453,7 @@ s32 cellAudioQuit() s32 cellAudioPortOpen(vm::ptr audioParam, vm::ptr portNum) { - cellAudio.Warning("cellAudioPortOpen(audioParam=0x%x, portNum=0x%x)", audioParam, portNum); + cellAudio.Warning("cellAudioPortOpen(audioParam=*0x%x, portNum=*0x%x)", audioParam, portNum); if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) { @@ -519,7 +517,7 @@ s32 cellAudioPortOpen(vm::ptr audioParam, vm::ptr portN } if (attr & 0xFFFFFFFFF0EFEFEEULL) { - cellAudio.Todo("cellAudioPortOpen(): unknown attributes set (0x%llx)", attr); + cellAudio.Todo("cellAudioPortOpen(): unknown attributes (0x%llx)", attr); } // open audio port @@ -560,7 +558,7 @@ s32 cellAudioPortOpen(vm::ptr audioParam, vm::ptr portN s32 cellAudioGetPortConfig(u32 portNum, vm::ptr portConfig) { - cellAudio.Warning("cellAudioGetPortConfig(portNum=0x%x, portConfig=0x%x)", portNum, portConfig); + cellAudio.Warning("cellAudioGetPortConfig(portNum=%d, portConfig=*0x%x)", portNum, portConfig); if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) { @@ -581,7 +579,7 @@ s32 cellAudioGetPortConfig(u32 portNum, vm::ptr portConfig) case AUDIO_PORT_STATE_CLOSED: portConfig->status = CELL_AUDIO_STATUS_CLOSE; break; case AUDIO_PORT_STATE_OPENED: portConfig->status = CELL_AUDIO_STATUS_READY; break; case AUDIO_PORT_STATE_STARTED: portConfig->status = CELL_AUDIO_STATUS_RUN; break; - default: throw fmt::format("cellAudioGetPortConfig(%d): invalid port state (0x%x)", portNum, state); + default: throw fmt::format("cellAudioGetPortConfig(%d): invalid port state (%d)", portNum, state); } portConfig->nChannel = port.channel; @@ -593,7 +591,7 @@ s32 cellAudioGetPortConfig(u32 portNum, vm::ptr portConfig) s32 cellAudioPortStart(u32 portNum) { - cellAudio.Warning("cellAudioPortStart(portNum=0x%x)", portNum); + cellAudio.Warning("cellAudioPortStart(portNum=%d)", portNum); if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) { @@ -610,13 +608,13 @@ s32 cellAudioPortStart(u32 portNum) case AUDIO_PORT_STATE_CLOSED: return CELL_AUDIO_ERROR_PORT_NOT_OPEN; case AUDIO_PORT_STATE_STARTED: return CELL_AUDIO_ERROR_PORT_ALREADY_RUN; case AUDIO_PORT_STATE_OPENED: return CELL_OK; - default: throw fmt::format("cellAudioPortStart(%d): invalid port state (0x%x)", portNum, state); + default: throw fmt::format("cellAudioPortStart(%d): invalid port state (%d)", portNum, state); } } s32 cellAudioPortClose(u32 portNum) { - cellAudio.Warning("cellAudioPortClose(portNum=0x%x)", portNum); + cellAudio.Warning("cellAudioPortClose(portNum=%d)", portNum); if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) { @@ -633,13 +631,13 @@ s32 cellAudioPortClose(u32 portNum) case AUDIO_PORT_STATE_CLOSED: return CELL_AUDIO_ERROR_PORT_NOT_OPEN; case AUDIO_PORT_STATE_STARTED: return CELL_OK; case AUDIO_PORT_STATE_OPENED: return CELL_OK; - default: throw fmt::format("cellAudioPortClose(%d): invalid port state (0x%x)", portNum, state); + default: throw fmt::format("cellAudioPortClose(%d): invalid port state (%d)", portNum, state); } } s32 cellAudioPortStop(u32 portNum) { - cellAudio.Warning("cellAudioPortStop(portNum=0x%x)", portNum); + cellAudio.Warning("cellAudioPortStop(portNum=%d)", portNum); if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) { @@ -656,13 +654,13 @@ s32 cellAudioPortStop(u32 portNum) case AUDIO_PORT_STATE_CLOSED: return CELL_AUDIO_ERROR_PORT_NOT_RUN; case AUDIO_PORT_STATE_STARTED: return CELL_OK; case AUDIO_PORT_STATE_OPENED: return CELL_AUDIO_ERROR_PORT_NOT_RUN; - default: throw fmt::format("cellAudioPortStop(%d): invalid port state (0x%x)", portNum, state); + default: throw fmt::format("cellAudioPortStop(%d): invalid port state (%d)", portNum, state); } } s32 cellAudioGetPortTimestamp(u32 portNum, u64 tag, vm::ptr stamp) { - cellAudio.Log("cellAudioGetPortTimestamp(portNum=0x%x, tag=0x%llx, stamp=0x%x)", portNum, tag, stamp); + cellAudio.Log("cellAudioGetPortTimestamp(portNum=%d, tag=0x%llx, stamp=*0x%x)", portNum, tag, stamp); if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) { @@ -692,7 +690,7 @@ s32 cellAudioGetPortTimestamp(u32 portNum, u64 tag, vm::ptr stamp) s32 cellAudioGetPortBlockTag(u32 portNum, u64 blockNo, vm::ptr tag) { - cellAudio.Log("cellAudioGetPortBlockTag(portNum=0x%x, blockNo=0x%llx, tag=0x%x)", portNum, blockNo, tag); + cellAudio.Log("cellAudioGetPortBlockTag(portNum=%d, blockNo=0x%llx, tag=*0x%x)", portNum, blockNo, tag); if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) { @@ -735,7 +733,7 @@ s32 cellAudioGetPortBlockTag(u32 portNum, u64 blockNo, vm::ptr tag) s32 cellAudioSetPortLevel(u32 portNum, float level) { - cellAudio.Log("cellAudioSetPortLevel(portNum=0x%x, level=%f)", portNum, level); + cellAudio.Log("cellAudioSetPortLevel(portNum=%d, level=%f)", portNum, level); if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) { @@ -763,121 +761,118 @@ s32 cellAudioSetPortLevel(u32 portNum, float level) } else { - cellAudio.Todo("cellAudioSetPortLevel(portNum=0x%x): negative level value (%f)", portNum, level); + cellAudio.Todo("cellAudioSetPortLevel(%d): negative level value (%f)", portNum, level); } return CELL_OK; } -// Utility Functions -int cellAudioCreateNotifyEventQueue(vm::ptr id, vm::ptr key) +s32 cellAudioCreateNotifyEventQueue(vm::ptr id, vm::ptr key) { - cellAudio.Warning("cellAudioCreateNotifyEventQueue(id_addr=0x%x, key_addr=0x%x)", id.addr(), key.addr()); + cellAudio.Warning("cellAudioCreateNotifyEventQueue(id=*0x%x, key=*0x%x)", id, key); - std::lock_guard lock(g_audio.mutex); - - u64 event_key = 0; - while (Emu.GetEventManager().CheckKey((event_key << 48) | 0x80004d494f323221)) + for (u64 k = 0; k < 100; k++) { - event_key++; // experimental - //return CELL_AUDIO_ERROR_EVENT_QUEUE; - } - event_key = (event_key << 48) | 0x80004d494f323221; // left part: 0x8000, 0x8001, 0x8002 ... + const u64 key_value = 0x80004d494f323221ull + k; - std::shared_ptr eq(new event_queue_t(SYS_SYNC_FIFO, SYS_PPU_QUEUE, event_key, event_key, 32)); + std::shared_ptr queue(new event_queue_t(SYS_SYNC_FIFO, SYS_PPU_QUEUE, 0, key_value, 32)); - if (!Emu.GetEventManager().RegisterKey(eq, event_key)) - { - return CELL_AUDIO_ERROR_EVENT_QUEUE; - } - - *id = Emu.GetIdManager().GetNewID(eq); - *key = event_key; - - return CELL_OK; -} - -int cellAudioCreateNotifyEventQueueEx(vm::ptr id, vm::ptr key, u32 iFlags) -{ - cellAudio.Todo("cellAudioCreateNotifyEventQueueEx(id_addr=0x%x, key_addr=0x%x, iFlags=0x%x)", id.addr(), key.addr(), iFlags); - return CELL_OK; -} - -int cellAudioSetNotifyEventQueue(u64 key) -{ - cellAudio.Warning("cellAudioSetNotifyEventQueue(key=0x%llx)", key); - - std::lock_guard lock(g_audio.mutex); - - for (u32 i = 0; i < g_audio.keys.size(); i++) // check for duplicates - { - if (g_audio.keys[i] == key) + // register key if not used yet + if (Emu.GetEventManager().RegisterKey(queue, key_value)) { - return CELL_AUDIO_ERROR_PARAM; - } - } - g_audio.keys.push_back(key); + *id = Emu.GetIdManager().GetNewID(queue, TYPE_EVENT_QUEUE); + *key = key_value; - /*EventQueue* eq; - if (!Emu.GetEventManager().GetEventQueue(key, eq)) - { - return CELL_AUDIO_ERROR_PARAM; - }*/ - - // TODO: connect port (?????) - - return CELL_OK; -} - -int cellAudioSetNotifyEventQueueEx(u64 key, u32 iFlags) -{ - cellAudio.Todo("cellAudioSetNotifyEventQueueEx(key=0x%llx, iFlags=0x%x)", key, iFlags); - return CELL_OK; -} - -int cellAudioRemoveNotifyEventQueue(u64 key) -{ - cellAudio.Warning("cellAudioRemoveNotifyEventQueue(key=0x%llx)", key); - - std::lock_guard lock(g_audio.mutex); - - bool found = false; - for (u32 i = 0; i < g_audio.keys.size(); i++) - { - if (g_audio.keys[i] == key) - { - g_audio.keys.erase(g_audio.keys.begin() + i); - found = true; - break; + return CELL_OK; } } - if (!found) + return CELL_AUDIO_ERROR_EVENT_QUEUE; +} + +s32 cellAudioCreateNotifyEventQueueEx(vm::ptr id, vm::ptr key, u32 iFlags) +{ + cellAudio.Todo("cellAudioCreateNotifyEventQueueEx(id=*0x%x, key=*0x%x, iFlags=0x%x)", id, key, iFlags); + + if (iFlags & ~CELL_AUDIO_CREATEEVENTFLAG_SPU) { - // ??? return CELL_AUDIO_ERROR_PARAM; } - /*EventQueue* eq; - if (!Emu.GetEventManager().GetEventQueue(key, eq)) - { - return CELL_AUDIO_ERROR_PARAM; - }*/ + // TODO - // TODO: disconnect port + return CELL_AUDIO_ERROR_EVENT_QUEUE; +} + +s32 cellAudioSetNotifyEventQueue(u64 key) +{ + cellAudio.Warning("cellAudioSetNotifyEventQueue(key=0x%llx)", key); + + if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) + { + 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) + { + return CELL_AUDIO_ERROR_TRANS_EVENT; + } + } + + g_audio.keys.emplace_back(key); return CELL_OK; } -int cellAudioRemoveNotifyEventQueueEx(u64 key, u32 iFlags) +s32 cellAudioSetNotifyEventQueueEx(u64 key, u32 iFlags) +{ + cellAudio.Todo("cellAudioSetNotifyEventQueueEx(key=0x%llx, iFlags=0x%x)", key, iFlags); + + // TODO + + return CELL_OK; +} + +s32 cellAudioRemoveNotifyEventQueue(u64 key) +{ + cellAudio.Warning("cellAudioRemoveNotifyEventQueue(key=0x%llx)", key); + + if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) + { + 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) + { + g_audio.keys.erase(i); + + return CELL_OK; + } + } + + return CELL_AUDIO_ERROR_TRANS_EVENT; +} + +s32 cellAudioRemoveNotifyEventQueueEx(u64 key, u32 iFlags) { cellAudio.Todo("cellAudioRemoveNotifyEventQueueEx(key=0x%llx, iFlags=0x%x)", key, iFlags); + + // TODO + return CELL_OK; } s32 cellAudioAddData(u32 portNum, vm::ptr src, u32 samples, float volume) { - cellAudio.Log("cellAudioAddData(portNum=%d, src=0x%x, samples=%d, volume=%f)", portNum, src, samples, volume); + cellAudio.Log("cellAudioAddData(portNum=%d, src=*0x%x, samples=%d, volume=%f)", portNum, src, samples, volume); if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) { @@ -892,7 +887,7 @@ s32 cellAudioAddData(u32 portNum, vm::ptr src, u32 samples, float volume) if (samples != 256) { // despite the docs, seems that only fixed value is supported - cellAudio.Error("cellAudioAddData(): invalid samples value (0x%x)", samples); + cellAudio.Error("cellAudioAddData(): invalid samples value (%d)", samples); return CELL_AUDIO_ERROR_PARAM; } @@ -910,7 +905,7 @@ s32 cellAudioAddData(u32 portNum, vm::ptr src, u32 samples, float volume) s32 cellAudioAdd2chData(u32 portNum, vm::ptr src, u32 samples, float volume) { - cellAudio.Log("cellAudioAdd2chData(portNum=%d, src=0x%x, samples=%d, volume=%f)", portNum, src, samples, volume); + cellAudio.Log("cellAudioAdd2chData(portNum=%d, src=*0x%x, samples=%d, volume=%f)", portNum, src, samples, volume); if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) { @@ -925,7 +920,7 @@ s32 cellAudioAdd2chData(u32 portNum, vm::ptr src, u32 samples, float volu if (samples != 256) { // despite the docs, seems that only fixed value is supported - cellAudio.Error("cellAudioAdd2chData(): invalid samples value (0x%x)", samples); + cellAudio.Error("cellAudioAdd2chData(): invalid samples value (%d)", samples); return CELL_AUDIO_ERROR_PARAM; } @@ -973,7 +968,7 @@ s32 cellAudioAdd2chData(u32 portNum, vm::ptr src, u32 samples, float volu s32 cellAudioAdd6chData(u32 portNum, vm::ptr src, float volume) { - cellAudio.Log("cellAudioAdd6chData(portNum=%d, src=0x%x, volume=%f)", portNum, src, volume); + cellAudio.Log("cellAudioAdd6chData(portNum=%d, src=*0x%x, volume=%f)", portNum, src, volume); if (g_audio.state.read_relaxed() != AUDIO_STATE_INITIALIZED) { @@ -1015,27 +1010,27 @@ s32 cellAudioAdd6chData(u32 portNum, vm::ptr src, float volume) return CELL_OK; } -int cellAudioMiscSetAccessoryVolume(u32 devNum, float volume) +s32 cellAudioMiscSetAccessoryVolume(u32 devNum, float volume) { - cellAudio.Todo("cellAudioMiscSetAccessoryVolume(devNum=0x%x, volume=%f)", devNum, volume); + cellAudio.Todo("cellAudioMiscSetAccessoryVolume(devNum=%d, volume=%f)", devNum, volume); return CELL_OK; } -int cellAudioSendAck(u64 data3) +s32 cellAudioSendAck(u64 data3) { cellAudio.Todo("cellAudioSendAck(data3=0x%llx)", data3); return CELL_OK; } -int cellAudioSetPersonalDevice(int iPersonalStream, int iDevice) +s32 cellAudioSetPersonalDevice(s32 iPersonalStream, s32 iDevice) { - cellAudio.Todo("cellAudioSetPersonalDevice(iPersonalStream=0x%x, iDevice=0x%x)", iPersonalStream, iDevice); + cellAudio.Todo("cellAudioSetPersonalDevice(iPersonalStream=%d, iDevice=%d)", iPersonalStream, iDevice); return CELL_OK; } -int cellAudioUnsetPersonalDevice(int iPersonalStream) +s32 cellAudioUnsetPersonalDevice(s32 iPersonalStream) { - cellAudio.Todo("cellAudioUnsetPersonalDevice(iPersonalStream=0x%x)", iPersonalStream); + cellAudio.Todo("cellAudioUnsetPersonalDevice(iPersonalStream=%d)", iPersonalStream); return CELL_OK; }