diff --git a/src/audio_core/sdl_audio.cpp b/src/audio_core/sdl_audio.cpp index 6a2a70e3..0d494707 100644 --- a/src/audio_core/sdl_audio.cpp +++ b/src/audio_core/sdl_audio.cpp @@ -11,8 +11,8 @@ namespace Audio { int SDLAudio::AudioOutOpen(int type, u32 samples_num, u32 freq, - Libraries::AudioOut::OrbisAudioOutParam format) { - using Libraries::AudioOut::OrbisAudioOutParam; + Libraries::AudioOut::OrbisAudioOutParamFormat format) { + using Libraries::AudioOut::OrbisAudioOutParamFormat; std::scoped_lock lock{m_mutex}; for (int id = 0; id < portsOut.size(); id++) { auto& port = portsOut[id]; @@ -24,42 +24,42 @@ int SDLAudio::AudioOutOpen(int type, u32 samples_num, u32 freq, port.format = format; SDL_AudioFormat sampleFormat; switch (format) { - case OrbisAudioOutParam::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_MONO: + case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_MONO: sampleFormat = SDL_AUDIO_S16; port.channels_num = 1; port.sample_size = 2; break; - case OrbisAudioOutParam::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_MONO: + case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_MONO: sampleFormat = SDL_AUDIO_F32; port.channels_num = 1; port.sample_size = 4; break; - case OrbisAudioOutParam::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_STEREO: + case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_STEREO: sampleFormat = SDL_AUDIO_S16; port.channels_num = 2; port.sample_size = 2; break; - case OrbisAudioOutParam::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_STEREO: + case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_STEREO: sampleFormat = SDL_AUDIO_F32; port.channels_num = 2; port.sample_size = 4; break; - case OrbisAudioOutParam::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_8CH: + case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_8CH: sampleFormat = SDL_AUDIO_S16; port.channels_num = 8; port.sample_size = 2; break; - case OrbisAudioOutParam::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_8CH: + case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_8CH: sampleFormat = SDL_AUDIO_F32; port.channels_num = 8; port.sample_size = 4; break; - case OrbisAudioOutParam::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_8CH_STD: + case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_8CH_STD: sampleFormat = SDL_AUDIO_S16; port.channels_num = 8; port.sample_size = 2; break; - case OrbisAudioOutParam::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_8CH_STD: + case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_8CH_STD: sampleFormat = SDL_AUDIO_F32; port.channels_num = 8; port.sample_size = 4; @@ -108,7 +108,7 @@ s32 SDLAudio::AudioOutOutput(s32 handle, const void* ptr) { } bool SDLAudio::AudioOutSetVolume(s32 handle, s32 bitflag, s32* volume) { - using Libraries::AudioOut::OrbisAudioOutParam; + using Libraries::AudioOut::OrbisAudioOutParamFormat; std::scoped_lock lock{m_mutex}; auto& port = portsOut[handle - 1]; if (!port.isOpen) { @@ -119,8 +119,9 @@ bool SDLAudio::AudioOutSetVolume(s32 handle, s32 bitflag, s32* volume) { 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) { + if (port.format == + OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_8CH_STD || + port.format == OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_8CH_STD) { switch (i) { case 4: src_index = 6; diff --git a/src/audio_core/sdl_audio.h b/src/audio_core/sdl_audio.h index 7d0b0b80..d20c4455 100644 --- a/src/audio_core/sdl_audio.h +++ b/src/audio_core/sdl_audio.h @@ -15,7 +15,7 @@ public: virtual ~SDLAudio() = default; int AudioOutOpen(int type, u32 samples_num, u32 freq, - Libraries::AudioOut::OrbisAudioOutParam format); + Libraries::AudioOut::OrbisAudioOutParamFormat format); s32 AudioOutOutput(s32 handle, const void* ptr); bool AudioOutSetVolume(s32 handle, s32 bitflag, s32* volume); bool AudioOutGetStatus(s32 handle, int* type, int* channels_num); diff --git a/src/core/libraries/audio/audioout.cpp b/src/core/libraries/audio/audioout.cpp index 0ec4fe15..cc7ce342 100644 --- a/src/core/libraries/audio/audioout.cpp +++ b/src/core/libraries/audio/audioout.cpp @@ -33,7 +33,7 @@ static std::string_view GetAudioOutPort(u32 port) { } } -static std::string_view GetAudioOutParam(u32 param) { +static std::string_view GetAudioOutParamFormat(OrbisAudioOutParamFormat param) { switch (param) { case ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_MONO: return "S16_MONO"; @@ -56,6 +56,19 @@ static std::string_view GetAudioOutParam(u32 param) { } } +static std::string_view GetAudioOutParamAttr(OrbisAudioOutParamAttr attr) { + switch (attr) { + case ORBIS_AUDIO_OUT_PARAM_ATTR_NONE: + return "NONE"; + case ORBIS_AUDIO_OUT_PARAM_ATTR_RESTRICTED: + return "RESTRICTED"; + case ORBIS_AUDIO_OUT_PARAM_ATTR_MIX_TO_MAIN: + return "MIX_TO_MAIN"; + default: + return "INVALID"; + } +} + int PS4_SYSV_ABI sceAudioOutDeviceIdOpen() { LOG_ERROR(Lib_AudioOut, "(STUBBED) called"); return ORBIS_OK; @@ -259,12 +272,14 @@ int PS4_SYSV_ABI sceAudioOutMbusInit() { s32 PS4_SYSV_ABI sceAudioOutOpen(UserService::OrbisUserServiceUserId user_id, OrbisAudioOutPort port_type, s32 index, u32 length, - u32 sample_rate, OrbisAudioOutParam param_type) { + u32 sample_rate, + OrbisAudioOutParamExtendedInformation param_type) { LOG_INFO(Lib_AudioOut, "AudioOutOpen id = {} port_type = {} index = {} lenght= {} sample_rate = {} " - "param_type = {}", + "param_type = {} attr = {}", user_id, GetAudioOutPort(port_type), index, length, sample_rate, - GetAudioOutParam(param_type)); + GetAudioOutParamFormat(param_type.data_format), + GetAudioOutParamAttr(param_type.attributes)); if ((port_type < 0 || port_type > 4) && (port_type != 127)) { LOG_ERROR(Lib_AudioOut, "Invalid port type"); return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT_TYPE; @@ -273,10 +288,6 @@ s32 PS4_SYSV_ABI sceAudioOutOpen(UserService::OrbisUserServiceUserId user_id, LOG_ERROR(Lib_AudioOut, "Invalid sample rate"); return ORBIS_AUDIO_OUT_ERROR_INVALID_SAMPLE_FREQ; } - if (param_type < 0 || param_type > 7) { - LOG_ERROR(Lib_AudioOut, "Invalid format"); - return ORBIS_AUDIO_OUT_ERROR_INVALID_FORMAT; - } if (length != 256 && length != 512 && length != 768 && length != 1024 && length != 1280 && length != 1536 && length != 1792 && length != 2048) { LOG_ERROR(Lib_AudioOut, "Invalid length"); @@ -285,7 +296,18 @@ s32 PS4_SYSV_ABI sceAudioOutOpen(UserService::OrbisUserServiceUserId user_id, if (index != 0) { LOG_ERROR(Lib_AudioOut, "index is not valid !=0 {}", index); } - int result = audio->AudioOutOpen(port_type, length, sample_rate, param_type); + OrbisAudioOutParamFormat format = param_type.data_format; + if (format < 0 || format > 7) { + LOG_ERROR(Lib_AudioOut, "Invalid format"); + return ORBIS_AUDIO_OUT_ERROR_INVALID_FORMAT; + } + OrbisAudioOutParamAttr attr = param_type.attributes; + if (attr < 0 || attr > 2) { + // TODO Handle attributes in output audio device + LOG_ERROR(Lib_AudioOut, "Invalid format attribute"); + return ORBIS_AUDIO_OUT_ERROR_INVALID_FORMAT; + } + int result = audio->AudioOutOpen(port_type, length, sample_rate, format); if (result == -1) { LOG_ERROR(Lib_AudioOut, "Audio ports are full"); return ORBIS_AUDIO_OUT_ERROR_PORT_FULL; diff --git a/src/core/libraries/audio/audioout.h b/src/core/libraries/audio/audioout.h index c5a62dc6..d29eea7c 100644 --- a/src/core/libraries/audio/audioout.h +++ b/src/core/libraries/audio/audioout.h @@ -3,6 +3,8 @@ #pragma once +#include "common/bit_field.h" + #include "core/libraries/system/userservice.h" namespace Libraries::AudioOut { @@ -18,7 +20,7 @@ enum OrbisAudioOutPort { ORBIS_AUDIO_OUT_PORT_TYPE_AUX = 127 }; -enum OrbisAudioOutParam { +enum OrbisAudioOutParamFormat { ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_MONO = 0, ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_STEREO = 1, ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_8CH = 2, @@ -29,6 +31,22 @@ enum OrbisAudioOutParam { ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_8CH_STD = 7 }; +enum OrbisAudioOutParamAttr { + ORBIS_AUDIO_OUT_PARAM_ATTR_NONE = 0, + ORBIS_AUDIO_OUT_PARAM_ATTR_RESTRICTED = 1, + ORBIS_AUDIO_OUT_PARAM_ATTR_MIX_TO_MAIN = 2, +}; + +struct OrbisAudioOutParamExtendedInformation { + union { + BitField<0, 8, OrbisAudioOutParamFormat> data_format; + BitField<8, 8, u32> reserve0; + BitField<16, 4, OrbisAudioOutParamAttr> attributes; + BitField<20, 10, u32> reserve1; + BitField<31, 1, u32> unused; + }; +}; + struct OrbisAudioOutOutputParam { s32 handle; const void* ptr; @@ -80,7 +98,7 @@ int PS4_SYSV_ABI sceAudioOutMasteringTerm(); int PS4_SYSV_ABI sceAudioOutMbusInit(); s32 PS4_SYSV_ABI sceAudioOutOpen(UserService::OrbisUserServiceUserId user_id, OrbisAudioOutPort port_type, s32 index, u32 length, - u32 sample_rate, OrbisAudioOutParam param_type); + u32 sample_rate, OrbisAudioOutParamExtendedInformation param_type); int PS4_SYSV_ABI sceAudioOutOpenEx(); s32 PS4_SYSV_ABI sceAudioOutOutput(s32 handle, const void* ptr); s32 PS4_SYSV_ABI sceAudioOutOutputs(OrbisAudioOutOutputParam* param, u32 num);