diff --git a/.gitmodules b/.gitmodules index c0d4ac8d2d..a45f065200 100644 --- a/.gitmodules +++ b/.gitmodules @@ -5,3 +5,6 @@ [submodule "rpcs3-ffmpeg"] path = ffmpeg url = https://github.com/hrydgard/ppsspp-ffmpeg +[submodule "asmjit"] + path = asmjit + url = https://github.com/kobalicekp/asmjit diff --git a/asmjit b/asmjit new file mode 160000 index 0000000000..5ac69447dc --- /dev/null +++ b/asmjit @@ -0,0 +1 @@ +Subproject commit 5ac69447dc2b7bca332be552cbe747051641f9e9 diff --git a/rpcs3/Emu/Audio/AudioDumper.cpp b/rpcs3/Emu/Audio/AudioDumper.cpp index 118ffd6623..1a2e61fea2 100644 --- a/rpcs3/Emu/Audio/AudioDumper.cpp +++ b/rpcs3/Emu/Audio/AudioDumper.cpp @@ -11,9 +11,7 @@ AudioDumper::~AudioDumper() bool AudioDumper::Init() { - if(m_output.Open("audio.wav", wxFile::write)) - return true; - return false; + return m_output.Open("audio.wav", wxFile::write); } void AudioDumper::WriteHeader() @@ -23,16 +21,18 @@ void AudioDumper::WriteHeader() size_t AudioDumper::WriteData(const void* buffer, size_t size) { - /*for (u32 i = 0; i < size / 8; i++) +#ifdef SKIP_EMPTY_AUDIO + bool do_save = false; + for (u32 i = 0; i < size / 8; i++) { - if (((u64*)buffer)[i]) goto process; + if (((u64*)buffer)[i]) do_save = true; } for (u32 i = 0; i < size % 8; i++) { - if (((u8*)buffer)[i + (size & ~7)]) goto process; + if (((u8*)buffer)[i + (size & ~7)]) do_save = true; } - return size; // ignore empty data -process:*/ + if (!do_save) return size; // ignore empty data +#endif size_t ret = m_output.Write(buffer, size); m_header.Size += ret; m_header.RIFF.Size += ret; diff --git a/rpcs3/Emu/Audio/AudioDumper.h b/rpcs3/Emu/Audio/AudioDumper.h index f9ac030476..11a2f6e7e9 100644 --- a/rpcs3/Emu/Audio/AudioDumper.h +++ b/rpcs3/Emu/Audio/AudioDumper.h @@ -65,4 +65,5 @@ public: void WriteHeader(); size_t WriteData(const void* buffer, size_t size); void Finalize(); + const u8 GetCh() const { return m_header.FMT.NumChannels; } }; diff --git a/rpcs3/Emu/Audio/cellAudio.h b/rpcs3/Emu/Audio/cellAudio.h index 07df509d7b..709b8c3907 100644 --- a/rpcs3/Emu/Audio/cellAudio.h +++ b/rpcs3/Emu/Audio/cellAudio.h @@ -1,11 +1,8 @@ #pragma once -extern u64 get_system_time(); - // Error codes enum { - //libaudio Error Codes CELL_AUDIO_ERROR_ALREADY_INIT = 0x80310701, CELL_AUDIO_ERROR_AUDIOSYSTEM = 0x80310702, CELL_AUDIO_ERROR_NOT_INIT = 0x80310703, @@ -21,29 +18,6 @@ enum CELL_AUDIO_ERROR_EVENT_QUEUE = 0x8031070d, CELL_AUDIO_ERROR_AUDIOSYSTEM_NOT_FOUND = 0x8031070e, CELL_AUDIO_ERROR_TAG_NOT_FOUND = 0x8031070f, - - //libsnd3 Error Codes - CELL_SND3_ERROR_PARAM = 0x80310301, - CELL_SND3_ERROR_CREATE_MUTEX = 0x80310302, - CELL_SND3_ERROR_SYNTH = 0x80310303, - CELL_SND3_ERROR_ALREADY = 0x80310304, - CELL_SND3_ERROR_NOTINIT = 0x80310305, - CELL_SND3_ERROR_SMFFULL = 0x80310306, - CELL_SND3_ERROR_HD3ID = 0x80310307, - CELL_SND3_ERROR_SMF = 0x80310308, - CELL_SND3_ERROR_SMFCTX = 0x80310309, - CELL_SND3_ERROR_FORMAT = 0x8031030a, - CELL_SND3_ERROR_SMFID = 0x8031030b, - CELL_SND3_ERROR_SOUNDDATAFULL = 0x8031030c, - CELL_SND3_ERROR_VOICENUM = 0x8031030d, - CELL_SND3_ERROR_RESERVEDVOICE = 0x8031030e, - CELL_SND3_ERROR_REQUESTQUEFULL = 0x8031030f, - CELL_SND3_ERROR_OUTPUTMODE = 0x80310310, - - //libsynt2 Error Codes - CELL_SOUND_SYNTH2_ERROR_FATAL = 0x80310201, - CELL_SOUND_SYNTH2_ERROR_INVALID_PARAMETER = 0x80310202, - CELL_SOUND_SYNTH2_ERROR_ALREADY_INITIALIZED = 0x80310203, }; // constants @@ -143,46 +117,3 @@ struct AudioConfig //custom structure }; extern AudioConfig m_config; - -//libsnd3 datatypes -struct CellSnd3DataCtx -{ - s8 system; //[CELL_SND3_DATA_CTX_SIZE], unknown identifier -}; - -struct CellSnd3SmfCtx -{ - s8 system; //[CELL_SND3_SMF_CTX_SIZE], unknown identifier -}; - -struct CellSnd3KeyOnParam -{ - u8 vel; - u8 pan; - u8 panEx; - be_t addPitch; -}; - -struct CellSnd3VoiceBitCtx -{ - be_t core; //[CELL_SND3_MAX_CORE], unknown identifier -}; - -struct CellSnd3RequestQueueCtx -{ - void *frontQueue; - be_t frontQueueSize; - void *rearQueue; - be_t rearQueueSize; -}; - -//libsynt2 datatypes -struct CellSoundSynth2EffectAttr -{ - be_t core; - be_t mode; - be_t depth_L; - be_t depth_R; - be_t delay; - be_t feedback; -}; diff --git a/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp b/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp index 4181430a47..8028b923a8 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp @@ -267,7 +267,7 @@ u32 adecOpen(AudioDecoder* data) if (adec.just_started) { adec.first_pts = task.au.pts; - adec.last_pts = task.au.pts /*- 3816*8*/; // hack + adec.last_pts = task.au.pts - 0x10000; // hack } struct AVPacketHolder : AVPacket diff --git a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp index 25c9f7c41c..eeca7af654 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp @@ -7,8 +7,7 @@ #include "Emu/Audio/AudioDumper.h" void cellAudio_init(); -void cellAudio_unload(); -Module cellAudio(0x0011, cellAudio_init, nullptr, cellAudio_unload); +Module cellAudio(0x0011, cellAudio_init); static SMutexGeneral audioMutex; @@ -37,13 +36,13 @@ int cellAudioInit() thread t("Audio Thread", []() { - AudioDumper m_dump(2); // WAV file header (stereo) + AudioDumper m_dump(8); // WAV file header (8 ch) bool do_dump = Ini.AudioDumpToFile.GetValue(); if (do_dump && !m_dump.Init()) { - ConLog.Error("Audio aborted: cannot create file!"); + ConLog.Error("Audio aborted: AudioDumper::Init() failed"); return; } @@ -52,13 +51,14 @@ int cellAudioInit() if (Ini.AudioDumpToFile.GetValue()) m_dump.WriteHeader(); - float buffer[2*256]; // intermediate buffer for 2 channels + float buf2ch[2 * 256]; // intermediate buffer for 2 channels + float buf8ch[8 * 256]; // intermediate buffer for 8 channels uint oal_buffer_offset = 0; - uint oal_buffer_size = sizeof(buffer) / sizeof(float); + uint oal_buffer_size = sizeof(buf2ch) / sizeof(float); std::unique_ptr oal_buffer[32]; - SQueue queue; - for (u32 i = 0; i < queue.GetSize(); i++) + SQueue queue; + for (u32 i = 0; i < sizeof(oal_buffer) / sizeof(oal_buffer[0]); i++) { oal_buffer[i] = std::unique_ptr(new u16[oal_buffer_size]); memset(oal_buffer[i].get(), 0, oal_buffer_size * sizeof(u16)); @@ -118,7 +118,7 @@ int cellAudioInit() m_config.counter++; - const u32 oal_pos = m_config.counter % queue.GetSize(); + const u32 oal_pos = m_config.counter % (sizeof(oal_buffer) / sizeof(oal_buffer[0])); if (Emu.IsPaused()) { @@ -140,25 +140,45 @@ int cellAudioInit() auto buf = (be_t*)&Memory[buf_addr]; - static const float k = 1.0f; - const float m = (port.level == 0.0f) ? 1.0f : port.level; + static const float k = 1.0f; // may be 0.5f + const float m = port.level; if (port.channel == 2) { if (first_mix) { - for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i++) + for (u32 i = 0; i < (sizeof(buf2ch) / sizeof(float)); i += 2) { // reverse byte order - buffer[i] = buf[i] * m; + const float left = buf[i + 0] * m; + const float right = buf[i + 1] * m; + + buf2ch[i + 0] = left; + buf2ch[i + 1] = right; + + buf8ch[i * 4 + 0] = left; + buf8ch[i * 4 + 1] = right; + buf8ch[i * 4 + 2] = 0.0f; + buf8ch[i * 4 + 3] = 0.0f; + buf8ch[i * 4 + 4] = 0.0f; + buf8ch[i * 4 + 5] = 0.0f; + buf8ch[i * 4 + 6] = 0.0f; + buf8ch[i * 4 + 7] = 0.0f; } first_mix = false; } else { - for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i++) + for (u32 i = 0; i < (sizeof(buf2ch) / sizeof(float)); i += 2) { - buffer[i] += buf[i] * m; + const float left = buf[i + 0] * m; + const float right = buf[i + 1] * m; + + buf2ch[i + 0] += left; + buf2ch[i + 1] += right; + + buf8ch[i * 4 + 0] += left; + buf8ch[i * 4 + 1] += right; } } } @@ -166,21 +186,51 @@ int cellAudioInit() { if (first_mix) { - for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i += 2) + for (u32 i = 0; i < (sizeof(buf2ch) / sizeof(float)); i += 2) { - const float center = (buf[i*3+2] + buf[i*3+3]) * 0.708f; - buffer[i] = (buf[i*3] + buf[i*3+4] + center) * k * m; - buffer[i+1] = (buf[i*3+1] + buf[i*3+5] + center) * k * m; + const float left = buf[i * 3 + 0] * m; + const float right = buf[i * 3 + 1] * m; + const float center = buf[i * 3 + 2] * m; + const float low_freq = buf[i * 3 + 3] * m; + const float rear_left = buf[i * 3 + 4] * m; + const float rear_right = buf[i * 3 + 5] * m; + + const float mid = (center + low_freq) * 0.708f; + buf2ch[i + 0] = (left + rear_left + mid) * k; + buf2ch[i + 1] = (right + rear_right + mid) * k; + + buf8ch[i * 4 + 0] = left; + buf8ch[i * 4 + 1] = right; + buf8ch[i * 4 + 2] = center; + buf8ch[i * 4 + 3] = low_freq; + buf8ch[i * 4 + 4] = rear_left; + buf8ch[i * 4 + 5] = rear_right; + buf8ch[i * 4 + 6] = 0.0f; + buf8ch[i * 4 + 7] = 0.0f; } first_mix = false; } else { - for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i += 2) + for (u32 i = 0; i < (sizeof(buf2ch) / sizeof(float)); i += 2) { - const float center = (buf[i*3+2] + buf[i*3+3]) * 0.708f; - buffer[i] += (buf[i*3] + buf[i*3+4] + center) * k * m; - buffer[i+1] += (buf[i*3+1] + buf[i*3+5] + center) * k * m; + const float left = buf[i * 3 + 0] * m; + const float right = buf[i * 3 + 1] * m; + const float center = buf[i * 3 + 2] * m; + const float low_freq = buf[i * 3 + 3] * m; + const float rear_left = buf[i * 3 + 4] * m; + const float rear_right = buf[i * 3 + 5] * m; + + const float mid = (center + low_freq) * 0.708f; + buf2ch[i + 0] += (left + rear_left + mid) * k; + buf2ch[i + 1] += (right + rear_right + mid) * k; + + buf8ch[i * 4 + 0] += left; + buf8ch[i * 4 + 1] += right; + buf8ch[i * 4 + 2] += center; + buf8ch[i * 4 + 3] += low_freq; + buf8ch[i * 4 + 4] += rear_left; + buf8ch[i * 4 + 5] += rear_right; } } } @@ -188,21 +238,57 @@ int cellAudioInit() { if (first_mix) { - for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i += 2) + for (u32 i = 0; i < (sizeof(buf2ch) / sizeof(float)); i += 2) { - const float center = (buf[i*4+2] + buf[i*4+3]) * 0.708f; - buffer[i] = (buf[i*4] + buf[i*4+4] + buf[i*4+6] + center) * k * m; - buffer[i+1] = (buf[i*4+1] + buf[i*4+5] + buf[i*4+7] + center) * k * m; + const float left = buf[i * 4 + 0] * m; + const float right = buf[i * 4 + 1] * m; + const float center = buf[i * 4 + 2] * m; + const float low_freq = buf[i * 4 + 3] * m; + const float rear_left = buf[i * 4 + 4] * m; + const float rear_right = buf[i * 4 + 5] * m; + const float side_left = buf[i * 4 + 6] * m; + const float side_right = buf[i * 4 + 7] * m; + + const float mid = (center + low_freq) * 0.708f; + buf2ch[i + 0] = (left + rear_left + side_left + mid) * k; + buf2ch[i + 1] = (right + rear_right + side_right + mid) * k; + + buf8ch[i * 4 + 0] = left; + buf8ch[i * 4 + 1] = right; + buf8ch[i * 4 + 2] = center; + buf8ch[i * 4 + 3] = low_freq; + buf8ch[i * 4 + 4] = rear_left; + buf8ch[i * 4 + 5] = rear_right; + buf8ch[i * 4 + 6] = side_left; + buf8ch[i * 4 + 7] = side_right; } first_mix = false; } else { - for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i += 2) + for (u32 i = 0; i < (sizeof(buf2ch) / sizeof(float)); i += 2) { - const float center = (buf[i*4+2] + buf[i*4+3]) * 0.708f; - buffer[i] += (buf[i*4] + buf[i*4+4] + buf[i*4+6] + center) * k * m; - buffer[i+1] += (buf[i*4+1] + buf[i*4+5] + buf[i*4+7] + center) * k * m; + const float left = buf[i * 4 + 0] * m; + const float right = buf[i * 4 + 1] * m; + const float center = buf[i * 4 + 2] * m; + const float low_freq = buf[i * 4 + 3] * m; + const float rear_left = buf[i * 4 + 4] * m; + const float rear_right = buf[i * 4 + 5] * m; + const float side_left = buf[i * 4 + 6] * m; + const float side_right = buf[i * 4 + 7] * m; + + const float mid = (center + low_freq) * 0.708f; + buf2ch[i + 0] += (left + rear_left + side_left + mid) * k; + buf2ch[i + 1] += (right + rear_right + side_right + mid) * k; + + buf8ch[i * 4 + 0] += left; + buf8ch[i * 4 + 1] += right; + buf8ch[i * 4 + 2] += center; + buf8ch[i * 4 + 3] += low_freq; + buf8ch[i * 4 + 4] += rear_left; + buf8ch[i * 4 + 5] += rear_right; + buf8ch[i * 4 + 6] += side_left; + buf8ch[i * 4 + 7] += side_right; } } } @@ -210,30 +296,43 @@ int cellAudioInit() memset(buf, 0, block_size * sizeof(float)); } - // convert the data from float to u16 and clip: + // convert the data from float to u16 with clipping: if (!first_mix) { - for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i++) + /*for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i++) { oal_buffer[oal_pos][oal_buffer_offset + i] = (s16)(min(max(buffer[i] * 0x8000, -0x8000), 0x7fff)); + }*/ + // 2x MULPS + // 2x MAXPS (optional) + // 2x MINPS (optional) + // 2x CVTPS2DQ (converts float to s32) + // PACKSSDW (converts s32 to s16 with clipping) + for (u32 i = 0; i < (sizeof(buf2ch) / sizeof(float)); i += 8) + { + static const __m128 float2u16 = { 0x8000, 0x8000, 0x8000, 0x8000 }; + (__m128i&)(oal_buffer[oal_pos][oal_buffer_offset + i]) = _mm_packs_epi32( + _mm_cvtps_epi32(_mm_mul_ps((__m128&)(buf2ch[i]), float2u16)), + _mm_cvtps_epi32(_mm_mul_ps((__m128&)(buf2ch[i + 4]), float2u16))); } } const u64 stamp1 = get_system_time(); - if (!first_mix) + if (first_mix) { - oal_buffer_offset += sizeof(buffer) / sizeof(float); + memset(&oal_buffer[oal_pos][0], 0, oal_buffer_size * sizeof(u16)); + } + oal_buffer_offset += sizeof(buf2ch) / sizeof(float); - if(oal_buffer_offset >= oal_buffer_size) + if(oal_buffer_offset >= oal_buffer_size) + { + if(m_audio_out) { - if(m_audio_out) - { - queue.Push(&oal_buffer[oal_pos][0]); - } - - oal_buffer_offset = 0; + queue.Push(&oal_buffer[oal_pos][0]); } + + oal_buffer_offset = 0; } const u64 stamp2 = get_system_time(); @@ -268,17 +367,31 @@ int cellAudioInit() if (do_dump && !first_mix) { - if (m_dump.WriteData(&buffer, sizeof(buffer)) != sizeof(buffer)) // write file data + if (m_dump.GetCh() == 8) { - ConLog.Error("Port aborted: cannot write file!"); + if (m_dump.WriteData(&buf8ch, sizeof(buf8ch)) != sizeof(buf8ch)) // write file data + { + ConLog.Error("Audio aborted: AudioDumper::WriteData() failed"); + goto abort; + } + } + else if (m_dump.GetCh() == 2) + { + if (m_dump.WriteData(&buf2ch, sizeof(buf2ch)) != sizeof(buf2ch)) // write file data + { + ConLog.Error("Audio aborted: AudioDumper::WriteData() failed"); + goto abort; + } + } + else + { + ConLog.Error("Audio aborted: unknown AudioDumper::GetCh() value (%d)", m_dump.GetCh()); goto abort; } } - const u64 stamp4 = get_system_time(); - //ConLog.Write("Audio perf: start=%d (access=%d, AddData=%d, events=%d, dump=%d)", - //stamp0 - m_config.start_time, stamp1-stamp0, stamp2-stamp1, stamp3-stamp2, stamp4-stamp3); + //stamp0 - m_config.start_time, stamp1 - stamp0, stamp2 - stamp1, stamp3 - stamp2, get_system_time() - stamp3); } ConLog.Write("Audio finished"); abort: @@ -375,7 +488,14 @@ int cellAudioPortOpen(mem_ptr_t audioParam, mem32_t portNum) port.channel = audioParam->nChannel; port.block = audioParam->nBlock; port.attr = audioParam->attr; - port.level = audioParam->level; + if (port.attr & CELL_AUDIO_PORTATTR_INITLEVEL) + { + port.level = audioParam->level; + } + else + { + port.level = 1.0f; + } portNum = i; cellAudio.Warning("*** audio port opened(nChannel=%d, nBlock=%d, attr=0x%llx, level=%f): port = %d", @@ -724,425 +844,6 @@ int cellAudioUnsetPersonalDevice(int iPersonalStream) return CELL_OK; } -//*libsnd3 Functions, NOT active in this moment -s32 cellSnd3Init() //u32 maxVoice, u32 samples, CellSnd3RequestQueueCtx *queue -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3Exit() -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3SetOutputMode() //u32 mode -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3Synthesis() //float *pOutL, float *pOutR -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3SynthesisEx() //float *pOutL, float *pOutR, float *pOutRL, float *pOutRR -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3VoiceSetReserveMode() //u32 voiceNum, u32 reserveMode -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3BindSoundData() //CellSnd3DataCtx *snd3Ctx, void *hd3, u32 synthMemOffset -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3UnbindSoundData(u32 hd3ID) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3NoteOnByTone() //u32 hd3ID, u32 toneIndex, u32 note, u32 keyOnID, CellSnd3KeyOnParam *keyOnParam -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO -} - -s32 cellSnd3KeyOnByTone() //u32 hd3ID, u32 toneIndex, u32 pitch,u32 keyOnID,CellSnd3KeyOnParam *keyOnParam -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO -} - -s32 cellSnd3VoiceNoteOnByTone() //u32 hd3ID, u32 voiceNum, u32 toneIndex, u32 note, u32 keyOnID, CellSnd3KeyOnParam *keyOnParam -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO -} - -s32 cellSnd3VoiceKeyOnByTone() //u32 hd3ID, u32 voiceNum, u32 toneIndex, u32 pitch, u32 keyOnID, CellSnd3KeyOnParam *keyOnParam -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO -} - -s32 cellSnd3VoiceSetSustainHold(u32 voiceNum, u32 sustainHold) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3VoiceKeyOff(u32 voiceNum) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3VoiceSetPitch(u32 voiceNum, s32 addPitch) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3VoiceSetVelocity(u32 voiceNum, u32 velocity) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3VoiceSetPanpot(u32 voiceNum, u32 panpot) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3VoiceSetPanpotEx(u32 voiceNum, u32 panpotEx) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3VoiceSetPitchBend(u32 voiceNum, u32 bendValue) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3VoiceAllKeyOff() -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3VoiceGetEnvelope(u32 voiceNum) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3VoiceGetStatus() //u32 voiceNum -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO -} - -u32 cellSnd3KeyOffByID(u32 keyOnID) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3GetVoice() //u32 midiChannel, u32 keyOnID, CellSnd3VoiceBitCtx *voiceBit -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3GetVoiceByID() //u32 keyOnID, CellSnd3VoiceBitCtx *voiceBit -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3NoteOn() //u32 hd3ID, u32 midiChannel, u32 midiProgram, u32 midiNote, u32 sustain,CellSnd3KeyOnParam *keyOnParam, u32 keyOnID -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3NoteOff(u32 midiChannel, u32 midiNote, u32 keyOnID) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3SetSustainHold(u32 midiChannel, u32 sustainHold, u32 ID) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3SetEffectType(u16 effectType, s16 returnVol, u16 delay, u16 feedback) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -u16 cellSnd3Note2Pitch() //u16 center_note, u16 center_fine, u16 note, s16 fine -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO -} - -u16 cellSnd3Pitch2Note() //u16 center_note, u16 center_fine, u16 pitch -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO -} - -s32 cellSnd3SMFBind() //CellSnd3SmfCtx *smfCtx, void *smf, u32 hd3ID -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO -} - -s32 cellSnd3SMFUnbind() //u32 smfID -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO -} - -s32 cellSnd3SMFPlay(u32 smfID, u32 playVelocity, u32 playPan, u32 playCount) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3SMFPlayEx(u32 smfID, u32 playVelocity, u32 playPan, u32 playPanEx, u32 playCount) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3SMFPause(u32 smfID) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3SMFResume(u32 smfID) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3SMFStop(u32 smfID) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3SMFAddTempo(u32 smfID, s32 addTempo) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3SMFGetTempo() //u32 smfID -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO -} - -s32 cellSnd3SMFSetPlayVelocity(u32 smfID, u32 playVelocity) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3SMFGetPlayVelocity() //u32 smfID -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO -} - -s32 cellSnd3SMFSetPlayPanpot(u32 smfID, u32 playPanpot) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3SMFSetPlayPanpotEx(u32 smfID, u32 playPanpotEx) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3SMFGetPlayPanpot() //u32 smfID -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO -} - -s32 cellSnd3SMFGetPlayPanpotEx() //u32 smfID -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO -} - -s32 cellSnd3SMFGetPlayStatus() //u32 smfID -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO -} - -s32 cellSnd3SMFSetPlayChannel(u32 smfID, u32 playChannelBit) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3SMFGetPlayChannel() //u32 smfID, u32 *playChannelBit -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3SMFGetKeyOnID() //u32 smfID, u32 midiChannel, u32 *keyOnID -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - - //*libsynth2 Functions, NON active in this moment*// - -s32 cellSoundSynth2Config(s16 param, s32 value) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -s32 cellSoundSynth2Init( s16 flag) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -s32 cellSoundSynth2Exit() -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -void cellSoundSynth2SetParam(u16 register, u16 value) -{ - UNIMPLEMENTED_FUNC(cellAudio); - //TODO -} - -u16 cellSoundSynth2GetParam() //u16 register -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO -} - -void cellSoundSynth2SetSwitch(u16 register, u32 value) -{ - UNIMPLEMENTED_FUNC(cellAudio); - //TODO -} - -u32 cellSoundSynth2GetSwitch() //u16 register -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO -} - -u32 cellSoundSynth2SetAddr(u16 register, u32 value) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -u32 cellSoundSynth2GetAddr() //u16 register -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO -} - -s32 cellSoundSynth2SetEffectAttr() //s16 bus, CellSoundSynth2EffectAttr *attr -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -s32 cellSoundSynth2SetEffectMode() //s16 bus, CellSoundSynth2EffectAttr *attr -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -void cellSoundSynth2SetCoreAttr(u16 entry, u16 value) -{ - UNIMPLEMENTED_FUNC(cellAudio); - //TODO -} - -s32 cellSoundSynth2Generate() //u16 samples, float *left_buffer, float *right_buffer, float *left_rear, float *right_rear -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -s32 cellSoundSynth2VoiceTrans() //s16 channel, u16 mode, u8 *m_addr, u32 s_addr, u32 size -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -u16 cellSoundSynth2Note2Pitch() //u16 center_note, u16 center_fine, u16 note, s16 fine -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO -} - -u16 cellSoundSynth2Pitch2Note() //u16 center_note, u16 center_fine, u16 pitch -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO -} - - void cellAudio_init() { cellAudio.AddFunc(0x0b168f92, cellAudioInit); @@ -1161,11 +862,4 @@ void cellAudio_init() cellAudio.AddFunc(0xdab029aa, cellAudioAddData); cellAudio.AddFunc(0xe4046afe, cellAudioGetPortBlockTag); cellAudio.AddFunc(0xff3626fd, cellAudioRemoveNotifyEventQueue); - - //TODO: Find addresses for libmixer, libsnd3 and libsynth2 functions -} - -void cellAudio_unload() -{ - //StaticFinalize(); } \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp b/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp index 2fac7e0bae..4b9aef7444 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp @@ -337,8 +337,13 @@ u32 dmuxOpen(Demuxer* data) cb.Branch(task.type == dmuxResetStreamAndWaitDone);*/ dmux.dmuxCb->ExecAsCallback(dmux.cbFunc, task.type == dmuxResetStreamAndWaitDone, dmux.id, dmuxMsg.GetAddr(), dmux.cbArg); + updates_signaled++; dmux.is_running = false; + if (task.type == dmuxResetStreamAndWaitDone) + { + dmux.fbSetStream.Push(0); + } } break; @@ -675,16 +680,17 @@ int cellDmuxResetStreamAndWaitDone(u32 demuxerHandle) dmux->job.Push(DemuxerTask(dmuxResetStreamAndWaitDone)); - while (dmux->is_running) + u32 addr; + if (!dmux->fbSetStream.Pop(addr)) { - if (Emu.IsStopped()) - { - ConLog.Warning("cellDmuxResetStreamAndWaitDone(%d) aborted", demuxerHandle); - break; - } - Sleep(1); + ConLog.Warning("cellDmuxResetStreamAndWaitDone(%d) aborted (fbSetStream.Pop())", demuxerHandle); + return CELL_OK; + } + if (addr != 0) + { + ConLog.Error("cellDmuxResetStreamAndWaitDone(%d): wrong stream queued (0x%x)", demuxerHandle, addr); + Emu.Pause(); } - return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp index d5035677df..7bcb9496a2 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp @@ -1,7 +1,6 @@ #include "stdafx.h" #include "Emu/SysCalls/SysCalls.h" #include "Emu/SysCalls/SC_FUNC.h" -#include void cellSync_init(); Module cellSync("cellSync", cellSync_init); @@ -23,13 +22,15 @@ enum CELL_SYNC_ERROR_NO_SPU_CONTEXT_STORAGE = 0x80410114, }; -#pragma pack(push, 1) -struct CellSyncMutex { - be_t m_freed; - be_t m_order; - volatile u32& m_data(){ - return *reinterpret_cast(this); - }; +struct CellSyncMutex +{ + be_t m_freed; + be_t m_order; + + volatile u32& m_data() + { + return *reinterpret_cast(this); + }; /* (???) Initialize: set zeros (???) Lock: increase m_order and wait until m_freed == old m_order @@ -37,7 +38,8 @@ struct CellSyncMutex { (???) TryLock: ????? */ }; -#pragma pack(pop) + +static_assert(sizeof(CellSyncMutex) == 4, "CellSyncMutex: wrong sizeof"); int cellSyncMutexInitialize(mem_ptr_t mutex) { @@ -52,16 +54,8 @@ int cellSyncMutexInitialize(mem_ptr_t mutex) return CELL_SYNC_ERROR_ALIGN; } - { - SMutexLocker lock(reservation.mutex); - if ((reservation.addr + reservation.size > mutex.GetAddr() && reservation.addr <= mutex.GetAddr() + 4) || - (mutex.GetAddr() + 4 > reservation.addr && mutex.GetAddr() <= reservation.addr + reservation.size)) - { - reservation.clear(); - } - mutex->m_data() = 0; - return CELL_OK; - } + mutex->m_data() = 0; + return CELL_OK; } int cellSyncMutexLock(mem_ptr_t mutex) @@ -78,22 +72,18 @@ int cellSyncMutexLock(mem_ptr_t mutex) } be_t old_order; + while (true) { - SMutexLocker lock(reservation.mutex); - if ((reservation.addr + reservation.size > mutex.GetAddr() && reservation.addr <= mutex.GetAddr() + 4) || - (mutex.GetAddr() + 4 > reservation.addr && mutex.GetAddr() <= reservation.addr + reservation.size)) - { - reservation.clear(); - } - old_order = mutex->m_order; - mutex->m_order = mutex->m_order + 1; - if (old_order == mutex->m_freed) - { - return CELL_OK; - } + const u32 old_data = mutex->m_data(); + CellSyncMutex new_mutex; + new_mutex.m_data() = old_data; + + old_order = new_mutex.m_order; + new_mutex.m_order++; + if (InterlockedCompareExchange(&mutex->m_data(), new_mutex.m_data(), old_data) == old_data) break; } - while (old_order != Memory.Read16(mutex.GetAddr())) + while (old_order != mutex->m_freed) { Sleep(1); if (Emu.IsStopped()) @@ -118,20 +108,28 @@ int cellSyncMutexTryLock(mem_ptr_t mutex) { return CELL_SYNC_ERROR_ALIGN; } + + int res; + + while (true) { - SMutexLocker lock(reservation.mutex); - if ((reservation.addr + reservation.size > mutex.GetAddr() && reservation.addr <= mutex.GetAddr() + 4) || - (mutex.GetAddr() + 4 > reservation.addr && mutex.GetAddr() <= reservation.addr + reservation.size)) + const u32 old_data = mutex->m_data(); + CellSyncMutex new_mutex; + new_mutex.m_data() = old_data; + + if (new_mutex.m_order != new_mutex.m_freed) { - reservation.clear(); + res = CELL_SYNC_ERROR_BUSY; } - if (mutex->m_order != mutex->m_freed) + else { - return CELL_SYNC_ERROR_BUSY; + new_mutex.m_order++; + res = CELL_OK; } - mutex->m_order = mutex->m_order + 1; - return CELL_OK; + if (InterlockedCompareExchange(&mutex->m_data(), new_mutex.m_data(), old_data) == old_data) break; } + + return res; } int cellSyncMutexUnlock(mem_ptr_t mutex) @@ -147,16 +145,17 @@ int cellSyncMutexUnlock(mem_ptr_t mutex) return CELL_SYNC_ERROR_ALIGN; } - { /* global mutex */ - SMutexLocker lock(reservation.mutex); - if ((reservation.addr + reservation.size > mutex.GetAddr() && reservation.addr <= mutex.GetAddr() + 4) || - (mutex.GetAddr() + 4 > reservation.addr && mutex.GetAddr() <= reservation.addr + reservation.size)) - { - reservation.clear(); - } - mutex->m_freed = mutex->m_freed + 1; - return CELL_OK; + while (true) + { + const u32 old_data = mutex->m_data(); + CellSyncMutex new_mutex; + new_mutex.m_data() = old_data; + + new_mutex.m_freed++; + if (InterlockedCompareExchange(&mutex->m_data(), new_mutex.m_data(), old_data) == old_data) break; } + + return CELL_OK; } void cellSync_init() diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp index 9858be8617..aa07494720 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp @@ -532,7 +532,7 @@ int cellAudioOutGetSoundAvailability(u32 audioOut, u32 type, u32 fs, u32 option) option = 0; - int available = 2; // should be at least 2 + int available = 8; // should be at least 2 switch(fs) { @@ -573,7 +573,7 @@ int cellAudioOutGetSoundAvailability2(u32 audioOut, u32 type, u32 fs, u32 ch, u3 option = 0; - int available = 2; // should be at least 2 + int available = 8; // should be at least 2 switch(fs) { diff --git a/rpcs3/Emu/SysCalls/Modules/cellVpost.cpp b/rpcs3/Emu/SysCalls/Modules/cellVpost.cpp index 31faab3f8d..557148cf61 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellVpost.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellVpost.cpp @@ -154,6 +154,8 @@ int cellVpostExec(u32 handle, const u32 inPicBuff_addr, const mem_ptr_tuserData = ctrlParam->userData; // copy picInfo->reserved1 = 0; picInfo->reserved2 = 0; + + u64 stamp0 = get_system_time(); u8* pY = (u8*)malloc(w*h); // color planes u8* pU = (u8*)malloc(w*h/4); @@ -182,8 +184,12 @@ int cellVpostExec(u32 handle, const u32 inPicBuff_addr, const mem_ptr_t 255) R = 255; - int G = Y - 0.1870f * Cb - 0.4664f * Cr; - if (G < 0) G = 0; - if (G > 255) G = 255; - int B = Y - 1.8556f * Cb; - if (B < 0) B = 0; - if (B > 255) B = 255; - res[i*w+j] = ((u32)alpha << 24) | (B << 16) | (G << 8) | (R); - }*/ + u64 stamp3 = get_system_time(); if (!Memory.CopyFromReal(outPicBuff_addr, res, ow*oh*4)) { @@ -223,6 +212,9 @@ int cellVpostExec(u32 handle, const u32 inPicBuff_addr, const mem_ptr_t> 16; + u32 type = aan_port >> 16; u32 port = aan_port & 0xffff; - switch (ch) + + switch (type) { - case 1: - if (port >= surMixer.chStrips1) ch = 0; break; - case 2: - if (port >= surMixer.chStrips2) ch = 0; break; - case 6: - /*if (port >= surMixer.chStrips6)*/ ch = 0; break; - case 8: - if (port >= surMixer.chStrips8) ch = 0; break; + case CELL_SURMIXER_CHSTRIP_TYPE1A: + if (port >= surMixer.chStrips1) type = 0; break; + case CELL_SURMIXER_CHSTRIP_TYPE2A: + if (port >= surMixer.chStrips2) type = 0; break; + case CELL_SURMIXER_CHSTRIP_TYPE6A: + if (port >= surMixer.chStrips6) type = 0; break; + case CELL_SURMIXER_CHSTRIP_TYPE8A: + if (port >= surMixer.chStrips8) type = 0; break; default: - ch = 0; break; + type = 0; break; } - if (aan_handle == 0x11111111 && samples == 256 && ch && offset == 0) + if (aan_handle == 0x11111111 && samples == 256 && type && offset == 0) { libmixer.Log("cellAANAddData(handle=0x%x, port=0x%x, offset=0x%x, addr=0x%x, samples=0x%x)", aan_handle, aan_port, offset, addr, samples); @@ -49,28 +50,28 @@ int cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, u32 addr, u32 sampl SMutexLocker lock(mixer_mutex); - if (ch == 1) + if (type == CELL_SURMIXER_CHSTRIP_TYPE1A) { // mono upmixing for (u32 i = 0; i < samples; i++) { const float center = *(be_t*)&Memory[addr + i * sizeof(float)]; - mixdata[i*8+0] += center; - mixdata[i*8+1] += center; + mixdata[i * 8 + 0] += center; + mixdata[i * 8 + 1] += center; } } - else if (ch == 2) + else if (type == CELL_SURMIXER_CHSTRIP_TYPE2A) { // stereo upmixing for (u32 i = 0; i < samples; i++) { const float left = *(be_t*)&Memory[addr + i * 2 * sizeof(float)]; const float right = *(be_t*)&Memory[addr + (i * 2 + 1) * sizeof(float)]; - mixdata[i*8+0] += left; - mixdata[i*8+1] += right; + mixdata[i * 8 + 0] += left; + mixdata[i * 8 + 1] += right; } } - else if (ch == 6) + else if (type == CELL_SURMIXER_CHSTRIP_TYPE6A) { // 5.1 upmixing for (u32 i = 0; i < samples; i++) @@ -81,15 +82,15 @@ int cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, u32 addr, u32 sampl const float low_freq = *(be_t*)&Memory[addr + (i * 6 + 3) * sizeof(float)]; const float rear_left = *(be_t*)&Memory[addr + (i * 6 + 4) * sizeof(float)]; const float rear_right = *(be_t*)&Memory[addr + (i * 6 + 5) * sizeof(float)]; - mixdata[i*8+0] += left; - mixdata[i*8+1] += right; - mixdata[i*8+2] += center; - mixdata[i*8+3] += low_freq; - mixdata[i*8+4] += rear_left; - mixdata[i*8+5] += rear_right; + mixdata[i * 8 + 0] += left; + mixdata[i * 8 + 1] += right; + mixdata[i * 8 + 2] += center; + mixdata[i * 8 + 3] += low_freq; + mixdata[i * 8 + 4] += rear_left; + mixdata[i * 8 + 5] += rear_right; } } - else if (ch == 8) + else if (type == CELL_SURMIXER_CHSTRIP_TYPE8A) { // 7.1 for (u32 i = 0; i < samples * 8; i++) @@ -103,59 +104,61 @@ int cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, u32 addr, u32 sampl int cellAANConnect(u32 receive, u32 receivePortNo, u32 source, u32 sourcePortNo) { - libmixer.Error("cellAANConnect(receive=0x%x, receivePortNo=0x%x, source=0x%x, sourcrPortNo=0x%x)", + libmixer.Error("cellAANConnect(receive=0x%x, receivePortNo=0x%x, source=0x%x, sourcePortNo=0x%x)", receive, receivePortNo, source, sourcePortNo); - return 0; + return CELL_OK; } int cellAANDisconnect(u32 receive, u32 receivePortNo, u32 source, u32 sourcePortNo) { - libmixer.Error("cellAANDisconnect(receive=0x%x, receivePortNo=0x%x, source=0x%x, sourcrPortNo=0x%x)", + libmixer.Error("cellAANDisconnect(receive=0x%x, receivePortNo=0x%x, source=0x%x, sourcePortNo=0x%x)", receive, receivePortNo, source, sourcePortNo); - return 0; + return CELL_OK; } -/*int cellSSPlayerCreate(CellAANHandle *handle, CellSSPlayerConfig *config) +int cellSSPlayerCreate(mem32_t handle, mem_ptr_t config) { - UNIMPLEMENTED_FUNC(libmixer); - return 0; + libmixer.Error("cellSSPlayerCreate(handle_addr=0x%x, config_addr=0x%x)", + handle.GetAddr(), config.GetAddr()); + return CELL_OK; } -int cellSSPlayerRemove(CellAANHandle handle) +int cellSSPlayerRemove(u32 handle) { - UNIMPLEMENTED_FUNC(libmixer); - return 0; + libmixer.Error("cellSSPlayerRemove(handle=%d)", handle); + return CELL_OK; } -int cellSSPlayerSetWave() //CellAANHandle handle, CellSSPlayerWaveParam *waveInfo, CellSSPlayerCommonParam *commonInfo //mem_class_t waveInfo +int cellSSPlayerSetWave(u32 handle, mem_ptr_t waveInfo, mem_ptr_t commonInfo) { - UNIMPLEMENTED_FUNC(libmixer); - return 0; + libmixer.Error("cellSSPlayerSetWave(handle=%d, waveInfo_addr=0x%x, commonInfo_addr=0x%x)", + handle, waveInfo.GetAddr(), commonInfo.GetAddr()); + return CELL_OK; } -int cellSSPlayerPlay() //CellAANHandle handle, CellSSPlayerRuntimeInfo *info +int cellSSPlayerPlay(u32 handle, mem_ptr_t info) { - UNIMPLEMENTED_FUNC(libmixer); - return 0; + libmixer.Error("cellSSPlayerPlay(handle=%d, info_addr=0x%x)", handle, info.GetAddr()); + return CELL_OK; } -int cellSSPlayerStop() //CellAANHandle handle, u32 mode +int cellSSPlayerStop(u32 handle, u32 mode) { - UNIMPLEMENTED_FUNC(libmixer); - return 0; + libmixer.Error("cellSSPlayerStop(handle=%d, mode=0x%x)", handle, mode); + return CELL_OK; } -int cellSSPlayerSetParam() //CellAANHandle handle, CellSSPlayerRuntimeInfo *info +int cellSSPlayerSetParam(u32 handle, mem_ptr_t info) { - UNIMPLEMENTED_FUNC(libmixer); - return 0; + libmixer.Error("cellSSPlayerSetParam(handle=%d, info_addr=0x%x)", handle, info.GetAddr()); + return CELL_OK; } -s32 cellSSPlayerGetState() //CellAANHandle handle +s32 cellSSPlayerGetState(u32 handle) { - UNIMPLEMENTED_FUNC(libmixer); - return 0; -}*/ + libmixer.Error("cellSSPlayerGetState(handle=%d) -> OFF", handle); + return CELL_SSPLAYER_STATE_OFF; +} int cellSurMixerCreate(const mem_ptr_t config) { @@ -376,7 +379,7 @@ void cellSurMixerUtilNoteToRatio(u8 refNote, u8 note) void libmixer_init() { - static const u64 cellAANAddData_table[] = { + REG_SUB(libmixer, "surmxAAN", cellAANAddData, 0xffffffff7c691b78, 0xffffffff7c0802a6, 0xfffffffff821ff91, @@ -400,11 +403,9 @@ void libmixer_init() 0xffffffff7c0803a6, 0xffffffff38210070, 0xffffffff4e800020, - 0 - }; - libmixer.AddFuncSub("surmxAAN", cellAANAddData_table, "cellAANAddData", cellAANAddData); + ); - static const u64 cellAANConnect_table[] = { + REG_SUB(libmixer, "surmxAAN", cellAANConnect, 0xfffffffff821ff71, 0xffffffff7c0802a6, 0xffffffff2f830000, @@ -443,11 +444,9 @@ void libmixer_init() 0xffffffff38210090, 0xffffffff7c0803a6, 0xffffffff4e800020, - 0, - }; - libmixer.AddFuncSub("surmxAAN", cellAANConnect_table, "cellAANConnect", cellAANConnect); + ); - static const u64 cellAANDisconnect_table[] = { + REG_SUB(libmixer, "surmxAAN", cellAANDisconnect, 0xfffffffff821ff71, 0xffffffff7c0802a6, 0xffffffff2f830000, @@ -486,11 +485,9 @@ void libmixer_init() 0xffffffff38210090, 0xffffffff7c0803a6, 0xffffffff4e800020, - 0, - }; - libmixer.AddFuncSub("surmxAAN", cellAANDisconnect_table, "cellAANDisconnect", cellAANDisconnect); + ); - static const u64 cellSurMixerCreate_table[] = { + REG_SUB(libmixer, "surmixer", cellSurMixerCreate, 0xffffffff2f830000, 0xffffffff7c0802a6, 0xfffffffff821ff51, @@ -517,12 +514,10 @@ void libmixer_init() 0xffffffffebc100a0, 0xffffffffebe100a8, 0xffffffff382100b0, - 0 - }; - libmixer.AddFuncSub("surmx___", cellSurMixerCreate_table, "cellSurMixerCreate", cellSurMixerCreate); + ); - static const u64 cellSurMixerGetAANHandle_table[] = { - // first instruction ignored + REG_SUB(libmixer, "surmixer", cellSurMixerGetAANHandle, + 0xff00000081428250, // lwz 0xffffffff3d607fce, 0xffffffff616bfffe, 0xffffffff812a0018, @@ -536,12 +531,10 @@ void libmixer_init() 0xffffffff38630002, 0xffffffff7c6307b4, 0xffffffff4e800020, - 0 - }; - libmixer.AddFuncSub("surmx___", cellSurMixerGetAANHandle_table, "cellSurMixerGetAANHandle", cellSurMixerGetAANHandle); + ); - static const u64 cellSurMixerChStripGetAANPortNo_table[] = { - // first instruction ignored + REG_SUB(libmixer, "surmixer", cellSurMixerChStripGetAANPortNo, + 0xff00000081228250, // lwz 0xffffffff7c661b78, 0xffffffff3c608031, 0xffffffff78c60020, @@ -553,12 +546,10 @@ void libmixer_init() 0xffffffff4d9e0020, 0xffffffff78030020, 0xf000000040000000, // b - 0 - }; - libmixer.AddFuncSub("surmx___", cellSurMixerChStripGetAANPortNo_table, "cellSurMixerChStripGetAANPortNo", cellSurMixerChStripGetAANPortNo); + ); - static const u64 cellSurMixerSetNotifyCallback_table[] = { - // first instruction ignored + REG_SUB(libmixer, "surmixer", cellSurMixerSetNotifyCallback, + 0xff00000081428250, // lwz 0xffffffff7c0802a6, 0xfffffffff821ff81, 0xfffffffff8010090, @@ -583,12 +574,10 @@ void libmixer_init() 0xffffffff38810070, 0xffffffff2f800000, 0xffffffff7d234b78, - 0 - }; - libmixer.AddFuncSub("surmx___", cellSurMixerSetNotifyCallback_table, "cellSurMixerSetNotifyCallback", cellSurMixerSetNotifyCallback); + ); - static const u64 cellSurMixerRemoveNotifyCallback_table[] = { - // first instruction ignored + REG_SUB(libmixer, "surmixer", cellSurMixerRemoveNotifyCallback, + 0xff00000081628250, // lwz 0xffffffff7c0802a6, 0xfffffffff821ff81, 0xfffffffff8010090, @@ -603,11 +592,9 @@ void libmixer_init() 0xffffffff38210080, 0xffffffff7c0803a6, 0xffffffff4e800020, - 0 - }; - libmixer.AddFuncSub("surmx___", cellSurMixerRemoveNotifyCallback_table, "cellSurMixerRemoveNotifyCallback", cellSurMixerRemoveNotifyCallback); + ); - static const u64 cellSurMixerStart_table[] = { + REG_SUB(libmixer, "surmixer", cellSurMixerStart, 0xfffffffff821ff71, 0xffffffff7c0802a6, 0xfffffffffbc10080, @@ -628,11 +615,9 @@ void libmixer_init() 0xffffffffebe10088, 0xffffffff38210090, 0xffffffff4e800020, - 0 - }; - libmixer.AddFuncSub("surmx___", cellSurMixerStart_table, "cellSurMixerStart", cellSurMixerStart); + ); - static const u64 cellSurMixerSetParameter_table[] = { + REG_SUB(libmixer, "surmixer", cellSurMixerSetParameter, 0xfffffffff821ff81, 0xffffffff7c0802a6, 0xfffffffffbc10070, @@ -660,11 +645,9 @@ void libmixer_init() 0xffffffff2b83002b, 0xffff000040990008, // ble 0xffff0000409d0054, // ble - 0 - }; - libmixer.AddFuncSub("surmx___", cellSurMixerSetParameter_table, "cellSurMixerSetParameter", cellSurMixerSetParameter); + ); - static const u64 cellSurMixerFinalize_table[] = { + REG_SUB(libmixer, "surmixer", cellSurMixerFinalize, 0xfffffffff821ff91, 0xffffffff7c0802a6, 0xfffffffff8010080, @@ -688,12 +671,10 @@ void libmixer_init() 0xffffffff7c0903a6, 0xffffffff804a0004, 0xffffffff4e800421, - 0 - }; - libmixer.AddFuncSub("surmx___", cellSurMixerFinalize_table, "cellSurMixerFinalize", cellSurMixerFinalize); + ); - static const u64 cellSurMixerSurBusAddData_table[] = { - 0xff00000081428250, + REG_SUB(libmixer, "surmixer", cellSurMixerSurBusAddData, + 0xff00000081428250, // lwz 0xffffffff7c0802a6, 0xfffffffff821ff91, 0xfffffffff8010080, @@ -719,12 +700,10 @@ void libmixer_init() 0xffffffff79660020, 0xffffffff78e70020, 0xffff0000419cffcc, // blt - 0 - }; - libmixer.AddFuncSub("surmx___", cellSurMixerSurBusAddData_table, "cellSurMixerSurBusAddData", cellSurMixerSurBusAddData); + ); - static const u64 cellSurMixerChStripSetParameter_table[] = { - 0xff00000081028250, + REG_SUB(libmixer, "surmixer", cellSurMixerChStripSetParameter, + 0xff00000081028250, // lwz 0xffffffff7c6b1b78, 0xffffffff3c608031, 0xffffffff7c8a2378, @@ -741,12 +720,10 @@ void libmixer_init() 0xffffffff4d9c0020, 0xffffffff79230020, 0xf000000048000000, // b - 0 - }; - libmixer.AddFuncSub("surmx___", cellSurMixerChStripSetParameter_table, "cellSurMixerChStripSetParameter", cellSurMixerChStripSetParameter); + ); - static const u64 cellSurMixerPause_table[] = { - // first instruction ignored + REG_SUB(libmixer, "surmixer", cellSurMixerPause, + 0xff00000081428250, // lwz 0xffffffff7c0802a6, 0xfffffffff821ff81, 0xfffffffff8010090, @@ -768,12 +745,10 @@ void libmixer_init() 0xffffffff800a001c, 0xffffffff2b030002, 0xffffffff2f800000, - 0 - }; - libmixer.AddFuncSub("surmx___", cellSurMixerPause_table, "cellSurMixerPause", cellSurMixerPause); + ); - static const u64 cellSurMixerGetCurrentBlockTag_table[] = { - // first instruction ignored + REG_SUB(libmixer, "surmixer", cellSurMixerGetCurrentBlockTag, + 0xff00000081628250, // lwz 0xffffffff3d208031, 0xffffffff61290002, 0xffffffff880b0020, @@ -784,12 +759,10 @@ void libmixer_init() 0xfffffffff8030000, 0xffffffff7d2307b4, 0xffffffff4e800020, - 0 - }; - libmixer.AddFuncSub("surmx___", cellSurMixerGetCurrentBlockTag_table, "cellSurMixerGetCurrentBlockTag", cellSurMixerGetCurrentBlockTag); + ); - static const u64 cellSurMixerGetTimestamp_table[] = { - // first instruction ignored + REG_SUB(libmixer, "surmixer", cellSurMixerGetTimestamp, + 0xff00000081628250, // lwz 0xffffffff7c0802a6, 0xfffffffff821ff91, 0xfffffffff8010080, @@ -808,12 +781,10 @@ void libmixer_init() 0xffffffff4e800020, 0xffffffff806b04d8, 0xf000000048000001, // bl - 0 - }; - libmixer.AddFuncSub("surmx___", cellSurMixerGetTimestamp_table, "cellSurMixerGetTimestamp", cellSurMixerGetTimestamp); + ); - static const u64 cellSurMixerBeep_table[] = { - // first instruction ignored + REG_SUB(libmixer, "surmixer", cellSurMixerBeep, + 0xff00000081228250, // lwz 0xffffffff7c641b78, 0xffffffff80690018, 0xffffffff2f830000, @@ -824,13 +795,153 @@ void libmixer_init() 0xffffffff2f800000, 0xffffffff4d9c0020, 0xf000000048000000, // b - 0 - }; - libmixer.AddFuncSub("surmx___", cellSurMixerBeep_table, "cellSurMixerBeep", cellSurMixerBeep); + ); - // TODO: SSPlayer functions - /*static const u64 cell_table[] = { - 0 - }; - libmixer.AddFuncSub("surmxSSP", cell_table, "cell", nullptr);*/ + REG_SUB(libmixer, "surmxSSP", cellSSPlayerCreate, + 0xfffffffff821ff51, + 0xffffffff7c0802a6, + 0xffffffff2f840000, + 0xfffffffff80100c0, + 0xffffffff3c008031, + 0xfffffffffb210078, + 0xfffffffffb410080, + 0xfffffffffb610088, + 0xfffffffffb810090, + 0xfffffffffba10098, + 0xfffffffffbc100a0, + 0xfffffffffbe100a8, + 0xffffffff7c9a2378, + 0xffffffff7c791b78, + 0xffffffff60000003, + 0xffff0000419e0068, // beq + 0xff00000083620000, // lwz + 0xffffffff3b800000, + 0xffffffff381b0064, + 0xffffffff901b0018, + 0xffffffff5780103a, + 0xffffffff38800010, + 0xffffffff7c0007b4, + 0xffffffff38a01c70, + 0xffffffff7fc0da14, + 0xffffffff38c00000, + 0xffffffff83be0024, + 0xffffffff2f9d0000, + 0xffffffff7ba30020, + 0xffff000041de00c0, // beq- + 0xf000000048000001, // bl + ); + + REG_SUB(libmixer, "surmxSSP", cellSSPlayerRemove, + 0xffffffff7c641b78, + 0xffffffff7c0802a6, + 0xffffffff3c608031, + 0xffffffff2f840000, + 0xfffffffff821ff51, + 0xfffffffffb010070, + 0xfffffffffb210078, + 0xfffffffffb410080, + 0xfffffffffb610088, + 0xfffffffffb810090, + 0xfffffffffba10098, + 0xfffffffffbc100a0, + 0xfffffffffbe100a8, + 0xfffffffff80100c0, + 0xffffffff60630003, + 0xffff0000419e0074, // beq + 0xffffffff81240000, + 0xffffffff78830020, + 0xffffffff83440004, + 0xffffffff83240008, + 0xffffffff7b5b0020, + 0xffffffff81690000, + 0xffffffff800b0000, + 0xfffffffff8410028, + 0xffffffff7c0903a6, + 0xffffffff804b0004, + 0xffffffff4e800421, + ); + + REG_SUB(libmixer, "surmxSSP", cellSSPlayerSetWave, + 0xffffffff7c601b78, + 0xffffffff78840020, + 0xffffffff2f800000, + 0xffffffff3c608031, + 0xffffffff78a50020, + 0xffff0000419e000c, // beq + 0xffffffff78030020, + 0xf000000048000000, // b + 0xffffffff60630003, + 0xffffffff4e800020, + ); + + REG_SUB(libmixer, "surmxSSP", cellSSPlayerPlay, + 0xffffffff7c601b78, + 0xffffffff3c608031, + 0xffffffff2f800000, + 0xffffffff60630003, + 0xffffffff78840020, + 0xffffffff4d9e0020, + 0xffffffff78030020, + 0xf000000048000000, // b + 0xfffffffff821ff81, // next func + 0xffffffff7c0802a6, + 0xfffffffffbe10078, + 0xffffffff7c7f1b78, + 0xff00000081620028, // lwz + 0xfffffffff8010090, + 0xffffffff39400000, + 0xffffffff38630010, + ); + + REG_SUB(libmixer, "surmxSSP", cellSSPlayerStop, + 0xfffffffff821ff91, + 0xffffffff7c0802a6, + 0xffffffff2f830000, + 0xfffffffff8010080, + 0xffffffff3c008031, + 0xffffffff78630020, + 0xffffffff60000003, + 0xffff0000419e0010, // beq + 0xffffffff78840020, + 0xf000000048000001, // bl + 0xffffffff38000000, + 0xffffffff7c0307b4, + 0xffffffffe8010080, + 0xffffffff38210070, + 0xffffffff7c0803a6, + 0xffffffff4e800020, + ); + + REG_SUB(libmixer, "surmxSSP", cellSSPlayerSetParam, + 0xffffffff7c601b78, + 0xffffffff3c608031, + 0xffffffff2f800000, + 0xffffffff60630003, + 0xffffffff78840020, + 0xffffffff4d9e0020, + 0xffffffff78030020, + 0xf000000048000000, // b + 0xfffffffff821ff71, // next func + 0xffffffff7c0802a6, + 0xffffffff3d608031, + 0xfffffffff80100a0, + 0xffffffff80030068, + 0xffffffff616b0002, + 0xfffffffffbc10080, + 0xffffffff2f800000, + ); + + REG_SUB(libmixer, "surmxSSP", cellSSPlayerGetState, + 0xffffffff7c601b78, + 0xffffffff3c608031, + 0xffffffff2f800000, + 0xffffffff60630003, + 0xffffffff4d9e0020, + 0xffffffff78030020, + 0xf000000048000000, // b + ); + + REG_SUB(libmixer, "surmxUti", cellSurMixerUtilGetLevelFromDB); + REG_SUB(libmixer, "surmxUti", cellSurMixerUtilGetLevelFromDBIndex); + REG_SUB(libmixer, "surmxUti", cellSurMixerUtilNoteToRatio); } \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/libmixer.h b/rpcs3/Emu/SysCalls/Modules/libmixer.h index 7e4c33a1fa..649dcda2f7 100644 --- a/rpcs3/Emu/SysCalls/Modules/libmixer.h +++ b/rpcs3/Emu/SysCalls/Modules/libmixer.h @@ -12,6 +12,103 @@ enum //libmixer Error Codes CELL_LIBMIXER_ERROR_NOT_FOUND = 0x8031000a, }; +enum +{ + CELL_SURBUS_LEFT = 0, + CELL_SURBUS_RIGHT = 1, + CELL_SURBUS_CENTER = 2, + CELL_SURBUS_LFE = 3, + CELL_SURBUS_LEFT_SUR = 4, + CELL_SURBUS_RIGHT_SUR = 5, + CELL_SURBUS_LEFT_EXT = 6, + CELL_SURBUS_RIGHT_EXT = 7, + CELL_SURBUS_REVERB_LEFT = 8, + CELL_SURBUS_REVERB_RIGHT = 9, + CELL_SURBUS_REVERB_LEFT_SUR = 10, + CELL_SURBUS_REVERB_RIGHT_SUR = 11, +}; + +enum +{ + CELL_SURMIXER_PARAM_TOTALLEVEL_LINEAR = 8, + CELL_SURMIXER_PARAM_REVERBLEVEL_LINEAR = 9, + CELL_SURMIXER_PARAM_TOTALMUTE = 12, + + CELL_SURMIXER_PARAM_TOTALLEVEL = 40, // in dB + CELL_SURMIXER_PARAM_REVERBLEVEL = 41, // in dB +}; + +static const float CELL_SURMIXER_CONT_MUTEON = 1.0; +static const float CELL_SURMIXER_CONT_MUTEOFF = 0.0; + +enum +{ + CELL_SURMIXER_CONT_DBSWITCHON = 1, + CELL_SURMIXER_CONT_DBSWITCHOFF = 0, + CELL_SURMIXER_CONT_PAUSE_OFF = 0, + CELL_SURMIXER_CONT_PAUSE_ON = 1, + CELL_SURMIXER_CONT_PAUSE_ON_IMMEDIATE = 2, +}; + +enum +{ + CELL_SURMIXER_CHSTRIP_TYPE1A = 1, + CELL_SURMIXER_CHSTRIP_TYPE2A = 2, + CELL_SURMIXER_CHSTRIP_TYPE6A = 3, + CELL_SURMIXER_CHSTRIP_TYPE8A = 4, + + CELL_SURMIXER_CH1PARAM_LEVEL = 0, + CELL_SURMIXER_CH1PARAM_EXPRESSIONLEVEL = 1, + CELL_SURMIXER_CH1PARAM_CENTERLEVEL = 2, + CELL_SURMIXER_CH1PARAM_REVERBSENDLEVEL = 3, + CELL_SURMIXER_CH1PARAM_MUTE = 4, + CELL_SURMIXER_CH1PARAM_REVSENDPOSITION = 5, + CELL_SURMIXER_CH1PARAM_POSITION = 6, + + CELL_SURMIXER_CH2PARAM_LEVEL = 0, + CELL_SURMIXER_CH2PARAM_EXPRESSIONLEVEL = 1, + CELL_SURMIXER_CH2PARAM_CENTERLEVEL = 2, + CELL_SURMIXER_CH2PARAM_REVERBSENDLEVEL = 3, + CELL_SURMIXER_CH2PARAM_MUTE = 4, + CELL_SURMIXER_CH2PARAM_REVSENDPOSITION = 5, + CELL_SURMIXER_CH2PARAM_POSITION = 6, + + CELL_SURMIXER_CH6PARAM_LEVEL = 0, + CELL_SURMIXER_CH6PARAM_EXPRESSIONLEVEL = 1, + CELL_SURMIXER_CH6PARAM_REVERBSENDLEVEL = 2, + CELL_SURMIXER_CH6PARAM_CENTER_REVERBSENDLEVEL = 3, + CELL_SURMIXER_CH6PARAM_MUTE = 4, + + CELL_SURMIXER_CH8PARAM_LEVEL = 0, + CELL_SURMIXER_CH8PARAM_EXPRESSIONLEVEL = 1, + CELL_SURMIXER_CH8PARAM_REVERBSENDLEVEL = 2, + CELL_SURMIXER_CH8PARAM_CENTER_REVERBSENDLEVEL = 3, + CELL_SURMIXER_CH8PARAM_MUTE = 4, + + CELL_SURMIXER_CH1CONT_MUTE_OFF = 0, + CELL_SURMIXER_CH1CONT_MUTE_ON = 1, + CELL_SURMIXER_CH2CONT_MUTE_OFF = 0, + CELL_SURMIXER_CH2CONT_MUTE_ON = 1, + CELL_SURMIXER_CH6CONT_MUTE_OFF = 0, + CELL_SURMIXER_CH6CONT_MUTE_ON = 1, + CELL_SURMIXER_CH8CONT_MUTE_OFF = 0, + CELL_SURMIXER_CH8CONT_MUTE_ON = 1, +}; + +enum +{ + CELL_SSPLAYER_ONESHOT = 0, + CELL_SSPLAYER_ONESHOT_CONT = 2, + CELL_SSPLAYER_LOOP_ON = 16, + + CELL_SSPLAYER_STATE_ERROR = 0xffffffff, + CELL_SSPLAYER_STATE_NOTREADY = 0x88888888, + CELL_SSPLAYER_STATE_OFF = 0x00, + CELL_SSPLAYER_STATE_PAUSE = 0x01, + CELL_SSPLAYER_STATE_CLOSING = 0x08, + CELL_SSPLAYER_STATE_ON = 0x20, +}; + typedef int (*CellSurMixerNotifyCallbackFunction)(void *arg, u32 counter, u32 samples); struct CellSSPlayerConfig diff --git a/rpcs3/Emu/SysCalls/Modules/libsnd3.cpp b/rpcs3/Emu/SysCalls/Modules/libsnd3.cpp new file mode 100644 index 0000000000..758a22b620 --- /dev/null +++ b/rpcs3/Emu/SysCalls/Modules/libsnd3.cpp @@ -0,0 +1,327 @@ +#include "stdafx.h" +#include "Emu/SysCalls/SysCalls.h" +#include "Emu/SysCalls/SC_FUNC.h" + +void libsnd3_init(); +Module libsnd3("libsnd3", libsnd3_init); + +#include "libsnd3.h" + +s32 cellSnd3Init() //u32 maxVoice, u32 samples, CellSnd3RequestQueueCtx *queue +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3Exit() +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3SetOutputMode() //u32 mode +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3Synthesis() //float *pOutL, float *pOutR +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3SynthesisEx() //float *pOutL, float *pOutR, float *pOutRL, float *pOutRR +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3VoiceSetReserveMode() //u32 voiceNum, u32 reserveMode +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3BindSoundData() //CellSnd3DataCtx *snd3Ctx, void *hd3, u32 synthMemOffset +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3UnbindSoundData(u32 hd3ID) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3NoteOnByTone() //u32 hd3ID, u32 toneIndex, u32 note, u32 keyOnID, CellSnd3KeyOnParam *keyOnParam +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; //it's NOT real value + //TODO +} + +s32 cellSnd3KeyOnByTone() //u32 hd3ID, u32 toneIndex, u32 pitch,u32 keyOnID,CellSnd3KeyOnParam *keyOnParam +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; //it's NOT real value + //TODO +} + +s32 cellSnd3VoiceNoteOnByTone() //u32 hd3ID, u32 voiceNum, u32 toneIndex, u32 note, u32 keyOnID, CellSnd3KeyOnParam *keyOnParam +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; //it's NOT real value + //TODO +} + +s32 cellSnd3VoiceKeyOnByTone() //u32 hd3ID, u32 voiceNum, u32 toneIndex, u32 pitch, u32 keyOnID, CellSnd3KeyOnParam *keyOnParam +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; //it's NOT real value + //TODO +} + +s32 cellSnd3VoiceSetSustainHold(u32 voiceNum, u32 sustainHold) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3VoiceKeyOff(u32 voiceNum) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3VoiceSetPitch(u32 voiceNum, s32 addPitch) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3VoiceSetVelocity(u32 voiceNum, u32 velocity) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3VoiceSetPanpot(u32 voiceNum, u32 panpot) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3VoiceSetPanpotEx(u32 voiceNum, u32 panpotEx) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3VoiceSetPitchBend(u32 voiceNum, u32 bendValue) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3VoiceAllKeyOff() +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3VoiceGetEnvelope(u32 voiceNum) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3VoiceGetStatus() //u32 voiceNum +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; //it's NOT real value + //TODO +} + +u32 cellSnd3KeyOffByID(u32 keyOnID) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3GetVoice() //u32 midiChannel, u32 keyOnID, CellSnd3VoiceBitCtx *voiceBit +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3GetVoiceByID() //u32 keyOnID, CellSnd3VoiceBitCtx *voiceBit +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3NoteOn() //u32 hd3ID, u32 midiChannel, u32 midiProgram, u32 midiNote, u32 sustain,CellSnd3KeyOnParam *keyOnParam, u32 keyOnID +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3NoteOff(u32 midiChannel, u32 midiNote, u32 keyOnID) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3SetSustainHold(u32 midiChannel, u32 sustainHold, u32 ID) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3SetEffectType(u16 effectType, s16 returnVol, u16 delay, u16 feedback) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +u16 cellSnd3Note2Pitch() //u16 center_note, u16 center_fine, u16 note, s16 fine +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; //it's NOT real value + //TODO +} + +u16 cellSnd3Pitch2Note() //u16 center_note, u16 center_fine, u16 pitch +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; //it's NOT real value + //TODO +} + +s32 cellSnd3SMFBind() //CellSnd3SmfCtx *smfCtx, void *smf, u32 hd3ID +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; //it's NOT real value + //TODO +} + +s32 cellSnd3SMFUnbind() //u32 smfID +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; //it's NOT real value + //TODO +} + +s32 cellSnd3SMFPlay(u32 smfID, u32 playVelocity, u32 playPan, u32 playCount) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3SMFPlayEx(u32 smfID, u32 playVelocity, u32 playPan, u32 playPanEx, u32 playCount) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3SMFPause(u32 smfID) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3SMFResume(u32 smfID) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3SMFStop(u32 smfID) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3SMFAddTempo(u32 smfID, s32 addTempo) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3SMFGetTempo() //u32 smfID +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; //it's NOT real value + //TODO +} + +s32 cellSnd3SMFSetPlayVelocity(u32 smfID, u32 playVelocity) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3SMFGetPlayVelocity() //u32 smfID +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; //it's NOT real value + //TODO +} + +s32 cellSnd3SMFSetPlayPanpot(u32 smfID, u32 playPanpot) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3SMFSetPlayPanpotEx(u32 smfID, u32 playPanpotEx) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3SMFGetPlayPanpot() //u32 smfID +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; //it's NOT real value + //TODO +} + +s32 cellSnd3SMFGetPlayPanpotEx() //u32 smfID +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; //it's NOT real value + //TODO +} + +s32 cellSnd3SMFGetPlayStatus() //u32 smfID +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; //it's NOT real value + //TODO +} + +s32 cellSnd3SMFSetPlayChannel(u32 smfID, u32 playChannelBit) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3SMFGetPlayChannel() //u32 smfID, u32 *playChannelBit +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3SMFGetKeyOnID() //u32 smfID, u32 midiChannel, u32 *keyOnID +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +void libsnd3_init() +{ + +} \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/libsnd3.h b/rpcs3/Emu/SysCalls/Modules/libsnd3.h new file mode 100644 index 0000000000..a3a49c7a0e --- /dev/null +++ b/rpcs3/Emu/SysCalls/Modules/libsnd3.h @@ -0,0 +1,54 @@ +#pragma once + +//libsnd3 Error Codes +enum +{ + CELL_SND3_ERROR_PARAM = 0x80310301, + CELL_SND3_ERROR_CREATE_MUTEX = 0x80310302, + CELL_SND3_ERROR_SYNTH = 0x80310303, + CELL_SND3_ERROR_ALREADY = 0x80310304, + CELL_SND3_ERROR_NOTINIT = 0x80310305, + CELL_SND3_ERROR_SMFFULL = 0x80310306, + CELL_SND3_ERROR_HD3ID = 0x80310307, + CELL_SND3_ERROR_SMF = 0x80310308, + CELL_SND3_ERROR_SMFCTX = 0x80310309, + CELL_SND3_ERROR_FORMAT = 0x8031030a, + CELL_SND3_ERROR_SMFID = 0x8031030b, + CELL_SND3_ERROR_SOUNDDATAFULL = 0x8031030c, + CELL_SND3_ERROR_VOICENUM = 0x8031030d, + CELL_SND3_ERROR_RESERVEDVOICE = 0x8031030e, + CELL_SND3_ERROR_REQUESTQUEFULL = 0x8031030f, + CELL_SND3_ERROR_OUTPUTMODE = 0x80310310, +}; + +//libsnd3 datatypes +struct CellSnd3DataCtx +{ + s8 system; //[CELL_SND3_DATA_CTX_SIZE], unknown identifier +}; + +struct CellSnd3SmfCtx +{ + s8 system; //[CELL_SND3_SMF_CTX_SIZE], unknown identifier +}; + +struct CellSnd3KeyOnParam +{ + u8 vel; + u8 pan; + u8 panEx; + be_t addPitch; +}; + +struct CellSnd3VoiceBitCtx +{ + be_t core; //[CELL_SND3_MAX_CORE], unknown identifier +}; + +struct CellSnd3RequestQueueCtx +{ + void *frontQueue; + be_t frontQueueSize; + void *rearQueue; + be_t rearQueueSize; +}; \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/libsynth2.cpp b/rpcs3/Emu/SysCalls/Modules/libsynth2.cpp new file mode 100644 index 0000000000..7262ddc67b --- /dev/null +++ b/rpcs3/Emu/SysCalls/Modules/libsynth2.cpp @@ -0,0 +1,159 @@ +#include "stdafx.h" +#include "Emu/SysCalls/SysCalls.h" +#include "Emu/SysCalls/SC_FUNC.h" + +void libsynth2_init(); +Module libsynth2("libsynth2", libsynth2_init); + +#include "libsynth2.h" + +int cellSoundSynth2Config(s16 param, int value) +{ + libsynth2.Error("cellSoundSynth2Config(param=%d, value=%d)", param, value); + return CELL_OK; +} + +int cellSoundSynth2Init(s16 flag) +{ + libsynth2.Error("cellSoundSynth2Init(flag=%d)", flag); + return CELL_OK; +} + +int cellSoundSynth2Exit() +{ + libsynth2.Error("cellSoundSynth2Exit()"); + return CELL_OK; +} + +void cellSoundSynth2SetParam(u16 reg, u16 value) +{ + libsynth2.Error("cellSoundSynth2SetParam(register=0x%x, value=0x%x)", reg, value); +} + +u16 cellSoundSynth2GetParam(u16 reg) +{ + libsynth2.Error("cellSoundSynth2GetParam(register=0x%x) -> 0", reg); + return 0; +} + +void cellSoundSynth2SetSwitch(u16 reg, u32 value) +{ + libsynth2.Error("cellSoundSynth2SetSwitch(register=0x%x, value=0x%x)", reg, value); +} + +u32 cellSoundSynth2GetSwitch(u16 reg) +{ + libsynth2.Error("cellSoundSynth2GetSwitch(register=0x%x) -> 0", reg); + return 0; +} + +int cellSoundSynth2SetAddr(u16 reg, u32 value) +{ + libsynth2.Error("cellSoundSynth2SetAddr(register=0x%x, value=0x%x)", reg, value); + return CELL_OK; +} + +u32 cellSoundSynth2GetAddr(u16 reg) +{ + libsynth2.Error("cellSoundSynth2GetAddr(register=0x%x) -> 0", reg); + return 0; +} + +int cellSoundSynth2SetEffectAttr(s16 bus, mem_ptr_t attr) +{ + libsynth2.Error("cellSoundSynth2SetEffectAttr(bus=%d, attr_addr=0x%x)", bus, attr.GetAddr()); + return CELL_OK; +} + +int cellSoundSynth2SetEffectMode(s16 bus, mem_ptr_t attr) +{ + libsynth2.Error("cellSoundSynth2SetEffectMode(bus=%d, attr_addr=0x%x)", bus, attr.GetAddr()); + return CELL_OK; +} + +void cellSoundSynth2SetCoreAttr(u16 entry, u16 value) +{ + libsynth2.Error("cellSoundSynth2SetCoreAttr(entry=0x%x, value=0x%x)", entry, value); +} + +int cellSoundSynth2Generate(u16 samples, u32 L_addr, u32 R_addr, u32 Lr_addr, u32 Rr_addr) +{ + libsynth2.Error("cellSoundSynth2Generate(samples=0x%x, left=0x%x, right=0x%x, left_rear=0x%x, right_rear=0x%x)", + samples, L_addr, R_addr, Lr_addr, Rr_addr); + return CELL_OK; +} + +int cellSoundSynth2VoiceTrans(s16 channel, u16 mode, u32 mem_side_addr, u32 lib_side_addr, u32 size) +{ + libsynth2.Error("cellSoundSynth2VoiceTrans(channel=%d, mode=0x%x, m_addr=0x%x, s_addr=0x%x, size=0x%x)", + channel, mode, mem_side_addr, lib_side_addr, size); + return CELL_OK; +} + +int cellSoundSynth2VoiceTransStatus(s16 channel, s16 flag) +{ + libsynth2.Error("cellSoundSynth2VoiceTransStatus(channel=%d, flag=%d)", channel, flag); + return CELL_OK; +} + +u16 cellSoundSynth2Note2Pitch(u16 center_note, u16 center_fine, u16 note, s16 fine) +{ + libsynth2.Error("cellSoundSynth2Note2Pitch(center_note=0x%x, center_fine=0x%x, note=0x%x, fine=%d) -> 0", + center_note, center_fine, note, fine); + return 0; +} + +u16 cellSoundSynth2Pitch2Note(u16 center_note, u16 center_fine, u16 pitch) +{ + libsynth2.Error("cellSoundSynth2Pitch2Note(center_note=0x%x, center_fine=0x%x, pitch=0x%x) -> 0", + center_note, center_fine, pitch); + return 0; +} + +void libsynth2_init() +{ + REG_SUB(libsynth2, "synth2", cellSoundSynth2Init, + /* + 0xffffffff7d800026, + 0xfffffffff821ff41, + 0xfffffffffb610098, + 0xff0000008362001c, // lwz + 0xfffffffffb8100a0, + 0xffffffff3f9b0008, + 0xfffffffffba100a8, + 0xffffffff3fa08031, + 0xfffffffffbe100b8, + 0xfffffffffb010080, + 0xfffffffffb210088, + 0xfffffffffb410090, + 0xfffffffffbc100b0, + 0xffffffff7c7f1b78, + 0xffffffff63bd0203, + 0xffffffff918100c8, + 0xffffffff7c0802a6, + 0xfffffffff80100d0, + 0xffffffff897c7688, + 0xffffffff2f8b0000, + 0xffffff00409e01fc, // bne + 0xffffffff38000002, + 0xffffffff39200020, + 0xffffffff3ba00000, + */ + ); + REG_SUB(libsynth2, "synth2", cellSoundSynth2Exit); + REG_SUB(libsynth2, "synth2", cellSoundSynth2Config); + REG_SUB(libsynth2, "synth2", cellSoundSynth2GetAddr); + REG_SUB(libsynth2, "synth2", cellSoundSynth2GetParam); + REG_SUB(libsynth2, "synth2", cellSoundSynth2GetSwitch); + REG_SUB(libsynth2, "synth2", cellSoundSynth2SetAddr); + REG_SUB(libsynth2, "synth2", cellSoundSynth2SetParam); + REG_SUB(libsynth2, "synth2", cellSoundSynth2SetSwitch); + REG_SUB(libsynth2, "synth2", cellSoundSynth2SetEffectMode); + REG_SUB(libsynth2, "synth2", cellSoundSynth2SetEffectAttr); + REG_SUB(libsynth2, "synth2", cellSoundSynth2Note2Pitch); + REG_SUB(libsynth2, "synth2", cellSoundSynth2Pitch2Note); + REG_SUB(libsynth2, "synth2", cellSoundSynth2VoiceTrans); + REG_SUB(libsynth2, "synth2", cellSoundSynth2VoiceTransStatus); + REG_SUB(libsynth2, "synth2", cellSoundSynth2SetCoreAttr); + REG_SUB(libsynth2, "synth2", cellSoundSynth2Generate); +} \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/libsynth2.h b/rpcs3/Emu/SysCalls/Modules/libsynth2.h new file mode 100644 index 0000000000..8b1c428855 --- /dev/null +++ b/rpcs3/Emu/SysCalls/Modules/libsynth2.h @@ -0,0 +1,19 @@ +#pragma once + +enum +{ + //libsynt2 Error Codes + CELL_SOUND_SYNTH2_ERROR_FATAL = 0x80310201, + CELL_SOUND_SYNTH2_ERROR_INVALID_PARAMETER = 0x80310202, + CELL_SOUND_SYNTH2_ERROR_ALREADY_INITIALIZED = 0x80310203, +}; + +struct CellSoundSynth2EffectAttr +{ + be_t core; + be_t mode; + be_t depth_L; + be_t depth_R; + be_t delay; + be_t feedback; +}; \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp index 5cfd8acccb..107cf36520 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp @@ -153,15 +153,6 @@ void fsAioRead(u32 fd, mem_ptr_t aio, int xid, mem_func_ptr_tGetPath(); - std::string::size_type first_slash = path.find('/'); - if (first_slash == std::string::npos) - { - path = ""; - } - else - { - path = path.substr(first_slash+1,std::string::npos); - } u64 nbytes = aio->size; u32 buf_addr = aio->buf_addr; diff --git a/rpcs3/Emu/SysCalls/Static.cpp b/rpcs3/Emu/SysCalls/Static.cpp index 3d79450cce..b635da2660 100644 --- a/rpcs3/Emu/SysCalls/Static.cpp +++ b/rpcs3/Emu/SysCalls/Static.cpp @@ -110,14 +110,14 @@ void StaticAnalyse(void* ptr, u32 size, u32 base) u32 res = GSR_SUCCESS; // analyse - for (u32 j = i; j < g_static_funcs_list.GetCount(); j++) if (g_static_funcs_list[j].group == group) + for (u32 j = 0; j < g_static_funcs_list.GetCount(); j++) if (g_static_funcs_list[j].group == group) { u32 count = g_static_funcs_list[j].found; if (count == 0) // not found { // check if this function has been found with different pattern - for (u32 k = i; k < g_static_funcs_list.GetCount(); k++) if (g_static_funcs_list[k].group == group) + for (u32 k = 0; k < g_static_funcs_list.GetCount(); k++) if (g_static_funcs_list[k].group == group) { if (k != j && g_static_funcs_list[k].ptr == g_static_funcs_list[j].ptr) { @@ -137,7 +137,7 @@ void StaticAnalyse(void* ptr, u32 size, u32 base) else if (count == 1) // found { // ensure that this function has NOT been found with different pattern - for (u32 k = i; k < g_static_funcs_list.GetCount(); k++) if (g_static_funcs_list[k].group == group) + for (u32 k = 0; k < g_static_funcs_list.GetCount(); k++) if (g_static_funcs_list[k].group == group) { if (k != j && g_static_funcs_list[k].ptr == g_static_funcs_list[j].ptr) { @@ -157,7 +157,7 @@ void StaticAnalyse(void* ptr, u32 size, u32 base) } // clear data - for (u32 j = i; j < g_static_funcs_list.GetCount(); j++) + for (u32 j = 0; j < g_static_funcs_list.GetCount(); j++) { if (g_static_funcs_list[j].group == group) g_static_funcs_list[j].found = 0; } diff --git a/rpcs3/Emu/SysCalls/SysCalls.h b/rpcs3/Emu/SysCalls/SysCalls.h index 29101d6ea2..efcc17eea8 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.h +++ b/rpcs3/Emu/SysCalls/SysCalls.h @@ -467,3 +467,9 @@ public: void StaticAnalyse(void* ptr, u32 size, u32 base); void StaticExecute(u32 code); void StaticFinalize(); + +#define REG_SUB(module, group, name,...) \ + static const u64 name ## _table[] = {__VA_ARGS__ ## 0}; \ + module.AddFuncSub(group, name ## _table, #name, name) + +extern u64 get_system_time(); \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Condition.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Condition.cpp index 8e31bb2674..cf87992ab0 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Condition.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Condition.cpp @@ -74,6 +74,7 @@ int sys_cond_signal(u32 cond_id) if (u32 target = (mutex->protocol == SYS_SYNC_PRIORITY ? cond->m_queue.pop_prio() : cond->m_queue.pop())) { + cond->signal_stamp = get_system_time(); cond->signal.lock(target); if (Emu.IsStopped()) @@ -99,6 +100,7 @@ int sys_cond_signal_all(u32 cond_id) while (u32 target = (mutex->protocol == SYS_SYNC_PRIORITY ? cond->m_queue.pop_prio() : cond->m_queue.pop())) { + cond->signal_stamp = get_system_time(); cond->signal.lock(target); if (Emu.IsStopped()) @@ -134,6 +136,7 @@ int sys_cond_signal_to(u32 cond_id, u32 thread_id) u32 target = thread_id; { + cond->signal_stamp = get_system_time(); cond->signal.lock(target); } @@ -199,7 +202,9 @@ int sys_cond_wait(u32 cond_id, u64 timeout) } } mutex->recursive = 1; + const volatile u64 stamp = cond->signal_stamp; cond->signal.unlock(tid); + //ConLog.Write("sys_cond_wait(): signal latency %d", get_system_time() - stamp); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Condition.h b/rpcs3/Emu/SysCalls/lv2/SC_Condition.h index a8d7472c63..145a20868a 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Condition.h +++ b/rpcs3/Emu/SysCalls/lv2/SC_Condition.h @@ -18,6 +18,7 @@ struct Cond Mutex* mutex; // associated with mutex SMutex signal; SleepQueue m_queue; + u64 signal_stamp; Cond(Mutex* mutex, u64 name) : mutex(mutex)