diff --git a/src/audio_core/sdl_audio.cpp b/src/audio_core/sdl_audio.cpp index 457f8802..59e83f8f 100644 --- a/src/audio_core/sdl_audio.cpp +++ b/src/audio_core/sdl_audio.cpp @@ -108,4 +108,42 @@ s32 SDLAudio::AudioOutOutput(s32 handle, const void* ptr) { return result; } +bool SDLAudio::AudioOutSetVolume(s32 handle, s32 bitflag, s32* volume) { + using Libraries::AudioOut::OrbisAudioOutParam; + std::scoped_lock lock{m_mutex}; + auto& port = portsOut[handle - 1]; + if (!port.isOpen) { + return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT; + } + for (int i = 0; i < port.channels_num; i++, bitflag >>= 1u) { + auto bit = bitflag & 0x1u; + + if (bit == 1) { + int src_index = i; + if (port.format == OrbisAudioOutParam::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_8CH_STD || + port.format == OrbisAudioOutParam::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_8CH_STD) { + switch (i) { + case 4: + src_index = 6; + break; + case 5: + src_index = 7; + break; + case 6: + src_index = 4; + break; + case 7: + src_index = 5; + break; + default: + break; + } + } + port.volume[i] = volume[src_index]; + } + } + + return true; +} + } // namespace Audio diff --git a/src/audio_core/sdl_audio.h b/src/audio_core/sdl_audio.h index 5c29835c..e6dd903a 100644 --- a/src/audio_core/sdl_audio.h +++ b/src/audio_core/sdl_audio.h @@ -20,6 +20,7 @@ public: int AudioOutOpen(int type, u32 samples_num, u32 freq, Libraries::AudioOut::OrbisAudioOutParam format); s32 AudioOutOutput(s32 handle, const void* ptr); + bool AudioOutSetVolume(s32 handle, s32 bitflag, s32* volume); private: struct PortOut { diff --git a/src/core/libraries/libsceaudioout.cpp b/src/core/libraries/libsceaudioout.cpp index 0b64aef9..59463a67 100644 --- a/src/core/libraries/libsceaudioout.cpp +++ b/src/core/libraries/libsceaudioout.cpp @@ -272,8 +272,11 @@ s32 PS4_SYSV_ABI sceAudioOutOutput(s32 handle, const void* ptr) { return audio->AudioOutOutput(handle, ptr); } -int PS4_SYSV_ABI sceAudioOutOutputs() { - LOG_ERROR(Lib_AudioOut, "(STUBBED) called"); +int PS4_SYSV_ABI sceAudioOutOutputs(OrbisAudioOutOutputParam* param, u32 num) { + for (u32 i = 0; i < num; i++) { + if (auto err = audio->AudioOutOutput(param[i].handle, param[i].ptr); err != 0) + return err; + } return ORBIS_OK; } @@ -367,8 +370,10 @@ int PS4_SYSV_ABI sceAudioOutSetUsbVolume() { return ORBIS_OK; } -int PS4_SYSV_ABI sceAudioOutSetVolume() { - LOG_ERROR(Lib_AudioOut, "(STUBBED) called"); +s32 PS4_SYSV_ABI sceAudioOutSetVolume(s32 handle, s32 flag, s32* vol) { + if (!audio->AudioOutSetVolume(handle, flag, vol)) { + return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT; + } return ORBIS_OK; } diff --git a/src/core/libraries/libsceaudioout.h b/src/core/libraries/libsceaudioout.h index ebbb2ba8..c57dc8bd 100644 --- a/src/core/libraries/libsceaudioout.h +++ b/src/core/libraries/libsceaudioout.h @@ -30,6 +30,11 @@ enum OrbisAudioOutParam { ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_8CH_STD = 7 }; +struct OrbisAudioOutOutputParam { + s32 handle; + const void* ptr; +}; + int PS4_SYSV_ABI sceAudioOutDeviceIdOpen(); int PS4_SYSV_ABI sceAudioDeviceControlGet(); int PS4_SYSV_ABI sceAudioDeviceControlSet(); @@ -69,7 +74,7 @@ s32 PS4_SYSV_ABI sceAudioOutOpen(UserService::OrbisUserServiceUserId user_id, u32 sample_rate, OrbisAudioOutParam param_type); int PS4_SYSV_ABI sceAudioOutOpenEx(); s32 PS4_SYSV_ABI sceAudioOutOutput(s32 handle, const void* ptr); -int PS4_SYSV_ABI sceAudioOutOutputs(); +s32 PS4_SYSV_ABI sceAudioOutOutputs(OrbisAudioOutOutputParam* param, u32 num); int PS4_SYSV_ABI sceAudioOutPtClose(); int PS4_SYSV_ABI sceAudioOutPtGetLastOutputTime(); int PS4_SYSV_ABI sceAudioOutPtOpen(); @@ -88,7 +93,7 @@ int PS4_SYSV_ABI sceAudioOutSetPortStatuses(); int PS4_SYSV_ABI sceAudioOutSetRecMode(); int PS4_SYSV_ABI sceAudioOutSetSparkParam(); int PS4_SYSV_ABI sceAudioOutSetUsbVolume(); -int PS4_SYSV_ABI sceAudioOutSetVolume(); +s32 PS4_SYSV_ABI sceAudioOutSetVolume(s32 handle, s32 flag, s32* vol); int PS4_SYSV_ABI sceAudioOutSetVolumeDown(); int PS4_SYSV_ABI sceAudioOutStartAuxBroadcast(); int PS4_SYSV_ABI sceAudioOutStartSharePlay();