feat(libSceVoice): track the port mute flag

sceVoiceSetMuteFlag was NotImplemented with an unknown signature and
sceVoiceGetMuteFlag was not exported. Signatures follow shadPS4's
voice.h: a port id and a bool, and for sceVoiceGetMuteFlag a port id
and a bool pointer. The flag is stored per port like the volume; an
unknown port throws and a null output pointer is an invalid argument.

Uncharted: Legacy of Thieves Collection (PPSA05684) imports
sceVoiceGetMuteFlag (Pc4z1QjForU), so on main it stops at startup with
"undefined symbol: Pc4z1QjForU".
This commit is contained in:
XairRrR 2026-10-09 12:32:01 +02:00
parent 57f96fd2b3
commit c7cd20e82f
2 changed files with 13 additions and 3 deletions

View File

@ -24,6 +24,7 @@ struct Port {
std::int32_t type;
float volume;
std::uint32_t bitrate;
bool muted = false;
};
struct Voice {
@ -204,8 +205,18 @@ int APS5_VABI sceVoiceWriteToIPort(uint32_t input_port_id, const void* data, uin
return 0;
}
int APS5_VABI sceVoiceSetMuteFlag() {
NotImplemented_nid_no_patch(__func__);
int APS5_VABI sceVoiceSetMuteFlag(uint32_t port_id, bool muted) {
auto& voice = State();
std::lock_guard lock(voice.mutex);
RequirePort(voice, port_id, __func__).muted = muted;
return 0;
}
int APS5_VABI sceVoiceGetMuteFlag(uint32_t port_id, bool* muted) {
if (muted == nullptr) APS5_INVALID_ARG_EX;
auto& voice = State();
std::lock_guard lock(voice.mutex);
*muted = RequirePort(voice, port_id, __func__).muted;
return 0;
}

View File

@ -234,7 +234,6 @@ Throughout the project, every function at every stage either **does exactly what
- [sceNgs2VoiceGetPortInfo](../../core/libs/prx/libSceNgs2.native/src/Voice.cpp) (libSceNgs2.native) - layout from shadPS4; the delay and destination input are zero because ports have neither yet
- [sceNgs2ParseWaveformFile](../../core/libs/prx/libSceNgs2.native/src/Atrac9.cpp) (libSceNgs2.native) - the signature `(path, offset, info)` is taken from the call site of PPSA21402, which sets only three argument registers; the file is read from `offset` to its end, the data and block offsets are taken to be relative to the start of the file, not of `offset`, and an unreadable file throws. The audio unit fields of a 16-bit PCM waveform are assumed to be one sample frame per unit and per frame; `INVALID_WAVEFORM_DATA` for a `data` chunk that runs past the buffer or ends inside a frame is assumed, and looped PCM and other PCM formats throw
- [sceSaveDataInitialize3](../../core/libs/prx/libSceSaveData.native/Export.cpp) (libSceSaveData.native) - a repeated initialize succeeds: PPSA12544's executable and its Unity SaveData plugin both initialize, and the plugin fails on any error. Initializations are counted and `sceSaveDataTerminate` ends the session at the last one; how the console pairs them is unknown
- [sceVoiceSetMuteFlag](../../core/libs/prx/libSceVoice/Export.cpp) (libSceVoice) - unknown signature
- [sceTextToSpeech2GetSystemStatus](../../core/libs/prx/libSceTextToSpeech2/Export.cpp) (libSceTextToSpeech2) - unknown signature
- [sceCoredumpAttachUserMemoryFile](../../core/libs/prx/libkernel/System/src/Coredump.cpp) (libkernel) - unknown signature
- [sceCoredumpAttachMemoryRegion](../../core/libs/prx/libkernel/System/src/Coredump.cpp) (libkernel) - unknown signature