Fix sceAudioOutOpen not handling audio param attributes
and returning error incorrectly when some mask is applied
This commit is contained in:
parent
f8c2dc0a18
commit
574b8a458c
|
@ -11,8 +11,8 @@
|
||||||
namespace Audio {
|
namespace Audio {
|
||||||
|
|
||||||
int SDLAudio::AudioOutOpen(int type, u32 samples_num, u32 freq,
|
int SDLAudio::AudioOutOpen(int type, u32 samples_num, u32 freq,
|
||||||
Libraries::AudioOut::OrbisAudioOutParam format) {
|
Libraries::AudioOut::OrbisAudioOutParamFormat format) {
|
||||||
using Libraries::AudioOut::OrbisAudioOutParam;
|
using Libraries::AudioOut::OrbisAudioOutParamFormat;
|
||||||
std::scoped_lock lock{m_mutex};
|
std::scoped_lock lock{m_mutex};
|
||||||
for (int id = 0; id < portsOut.size(); id++) {
|
for (int id = 0; id < portsOut.size(); id++) {
|
||||||
auto& port = portsOut[id];
|
auto& port = portsOut[id];
|
||||||
|
@ -24,42 +24,42 @@ int SDLAudio::AudioOutOpen(int type, u32 samples_num, u32 freq,
|
||||||
port.format = format;
|
port.format = format;
|
||||||
SDL_AudioFormat sampleFormat;
|
SDL_AudioFormat sampleFormat;
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case OrbisAudioOutParam::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_MONO:
|
case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_MONO:
|
||||||
sampleFormat = SDL_AUDIO_S16;
|
sampleFormat = SDL_AUDIO_S16;
|
||||||
port.channels_num = 1;
|
port.channels_num = 1;
|
||||||
port.sample_size = 2;
|
port.sample_size = 2;
|
||||||
break;
|
break;
|
||||||
case OrbisAudioOutParam::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_MONO:
|
case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_MONO:
|
||||||
sampleFormat = SDL_AUDIO_F32;
|
sampleFormat = SDL_AUDIO_F32;
|
||||||
port.channels_num = 1;
|
port.channels_num = 1;
|
||||||
port.sample_size = 4;
|
port.sample_size = 4;
|
||||||
break;
|
break;
|
||||||
case OrbisAudioOutParam::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_STEREO:
|
case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_STEREO:
|
||||||
sampleFormat = SDL_AUDIO_S16;
|
sampleFormat = SDL_AUDIO_S16;
|
||||||
port.channels_num = 2;
|
port.channels_num = 2;
|
||||||
port.sample_size = 2;
|
port.sample_size = 2;
|
||||||
break;
|
break;
|
||||||
case OrbisAudioOutParam::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_STEREO:
|
case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_STEREO:
|
||||||
sampleFormat = SDL_AUDIO_F32;
|
sampleFormat = SDL_AUDIO_F32;
|
||||||
port.channels_num = 2;
|
port.channels_num = 2;
|
||||||
port.sample_size = 4;
|
port.sample_size = 4;
|
||||||
break;
|
break;
|
||||||
case OrbisAudioOutParam::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_8CH:
|
case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_8CH:
|
||||||
sampleFormat = SDL_AUDIO_S16;
|
sampleFormat = SDL_AUDIO_S16;
|
||||||
port.channels_num = 8;
|
port.channels_num = 8;
|
||||||
port.sample_size = 2;
|
port.sample_size = 2;
|
||||||
break;
|
break;
|
||||||
case OrbisAudioOutParam::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_8CH:
|
case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_8CH:
|
||||||
sampleFormat = SDL_AUDIO_F32;
|
sampleFormat = SDL_AUDIO_F32;
|
||||||
port.channels_num = 8;
|
port.channels_num = 8;
|
||||||
port.sample_size = 4;
|
port.sample_size = 4;
|
||||||
break;
|
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;
|
sampleFormat = SDL_AUDIO_S16;
|
||||||
port.channels_num = 8;
|
port.channels_num = 8;
|
||||||
port.sample_size = 2;
|
port.sample_size = 2;
|
||||||
break;
|
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;
|
sampleFormat = SDL_AUDIO_F32;
|
||||||
port.channels_num = 8;
|
port.channels_num = 8;
|
||||||
port.sample_size = 4;
|
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) {
|
bool SDLAudio::AudioOutSetVolume(s32 handle, s32 bitflag, s32* volume) {
|
||||||
using Libraries::AudioOut::OrbisAudioOutParam;
|
using Libraries::AudioOut::OrbisAudioOutParamFormat;
|
||||||
std::scoped_lock lock{m_mutex};
|
std::scoped_lock lock{m_mutex};
|
||||||
auto& port = portsOut[handle - 1];
|
auto& port = portsOut[handle - 1];
|
||||||
if (!port.isOpen) {
|
if (!port.isOpen) {
|
||||||
|
@ -119,8 +119,9 @@ bool SDLAudio::AudioOutSetVolume(s32 handle, s32 bitflag, s32* volume) {
|
||||||
|
|
||||||
if (bit == 1) {
|
if (bit == 1) {
|
||||||
int src_index = i;
|
int src_index = i;
|
||||||
if (port.format == OrbisAudioOutParam::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_8CH_STD ||
|
if (port.format ==
|
||||||
port.format == OrbisAudioOutParam::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_8CH_STD) {
|
OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_8CH_STD ||
|
||||||
|
port.format == OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_8CH_STD) {
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case 4:
|
case 4:
|
||||||
src_index = 6;
|
src_index = 6;
|
||||||
|
|
|
@ -15,7 +15,7 @@ public:
|
||||||
virtual ~SDLAudio() = default;
|
virtual ~SDLAudio() = default;
|
||||||
|
|
||||||
int AudioOutOpen(int type, u32 samples_num, u32 freq,
|
int AudioOutOpen(int type, u32 samples_num, u32 freq,
|
||||||
Libraries::AudioOut::OrbisAudioOutParam format);
|
Libraries::AudioOut::OrbisAudioOutParamFormat format);
|
||||||
s32 AudioOutOutput(s32 handle, const void* ptr);
|
s32 AudioOutOutput(s32 handle, const void* ptr);
|
||||||
bool AudioOutSetVolume(s32 handle, s32 bitflag, s32* volume);
|
bool AudioOutSetVolume(s32 handle, s32 bitflag, s32* volume);
|
||||||
bool AudioOutGetStatus(s32 handle, int* type, int* channels_num);
|
bool AudioOutGetStatus(s32 handle, int* type, int* channels_num);
|
||||||
|
|
|
@ -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) {
|
switch (param) {
|
||||||
case ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_MONO:
|
case ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_MONO:
|
||||||
return "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() {
|
int PS4_SYSV_ABI sceAudioOutDeviceIdOpen() {
|
||||||
LOG_ERROR(Lib_AudioOut, "(STUBBED) called");
|
LOG_ERROR(Lib_AudioOut, "(STUBBED) called");
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
|
@ -259,12 +272,14 @@ int PS4_SYSV_ABI sceAudioOutMbusInit() {
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceAudioOutOpen(UserService::OrbisUserServiceUserId user_id,
|
s32 PS4_SYSV_ABI sceAudioOutOpen(UserService::OrbisUserServiceUserId user_id,
|
||||||
OrbisAudioOutPort port_type, s32 index, u32 length,
|
OrbisAudioOutPort port_type, s32 index, u32 length,
|
||||||
u32 sample_rate, OrbisAudioOutParam param_type) {
|
u32 sample_rate,
|
||||||
|
OrbisAudioOutParamExtendedInformation param_type) {
|
||||||
LOG_INFO(Lib_AudioOut,
|
LOG_INFO(Lib_AudioOut,
|
||||||
"AudioOutOpen id = {} port_type = {} index = {} lenght= {} sample_rate = {} "
|
"AudioOutOpen id = {} port_type = {} index = {} lenght= {} sample_rate = {} "
|
||||||
"param_type = {}",
|
"param_type = {} attr = {}",
|
||||||
user_id, GetAudioOutPort(port_type), index, length, sample_rate,
|
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)) {
|
if ((port_type < 0 || port_type > 4) && (port_type != 127)) {
|
||||||
LOG_ERROR(Lib_AudioOut, "Invalid port type");
|
LOG_ERROR(Lib_AudioOut, "Invalid port type");
|
||||||
return ORBIS_AUDIO_OUT_ERROR_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");
|
LOG_ERROR(Lib_AudioOut, "Invalid sample rate");
|
||||||
return ORBIS_AUDIO_OUT_ERROR_INVALID_SAMPLE_FREQ;
|
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 &&
|
if (length != 256 && length != 512 && length != 768 && length != 1024 && length != 1280 &&
|
||||||
length != 1536 && length != 1792 && length != 2048) {
|
length != 1536 && length != 1792 && length != 2048) {
|
||||||
LOG_ERROR(Lib_AudioOut, "Invalid length");
|
LOG_ERROR(Lib_AudioOut, "Invalid length");
|
||||||
|
@ -285,7 +296,18 @@ s32 PS4_SYSV_ABI sceAudioOutOpen(UserService::OrbisUserServiceUserId user_id,
|
||||||
if (index != 0) {
|
if (index != 0) {
|
||||||
LOG_ERROR(Lib_AudioOut, "index is not valid !=0 {}", index);
|
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) {
|
if (result == -1) {
|
||||||
LOG_ERROR(Lib_AudioOut, "Audio ports are full");
|
LOG_ERROR(Lib_AudioOut, "Audio ports are full");
|
||||||
return ORBIS_AUDIO_OUT_ERROR_PORT_FULL;
|
return ORBIS_AUDIO_OUT_ERROR_PORT_FULL;
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "common/bit_field.h"
|
||||||
|
|
||||||
#include "core/libraries/system/userservice.h"
|
#include "core/libraries/system/userservice.h"
|
||||||
|
|
||||||
namespace Libraries::AudioOut {
|
namespace Libraries::AudioOut {
|
||||||
|
@ -18,7 +20,7 @@ enum OrbisAudioOutPort {
|
||||||
ORBIS_AUDIO_OUT_PORT_TYPE_AUX = 127
|
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_MONO = 0,
|
||||||
ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_STEREO = 1,
|
ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_STEREO = 1,
|
||||||
ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_8CH = 2,
|
ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_8CH = 2,
|
||||||
|
@ -29,6 +31,22 @@ enum OrbisAudioOutParam {
|
||||||
ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_8CH_STD = 7
|
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 {
|
struct OrbisAudioOutOutputParam {
|
||||||
s32 handle;
|
s32 handle;
|
||||||
const void* ptr;
|
const void* ptr;
|
||||||
|
@ -80,7 +98,7 @@ int PS4_SYSV_ABI sceAudioOutMasteringTerm();
|
||||||
int PS4_SYSV_ABI sceAudioOutMbusInit();
|
int PS4_SYSV_ABI sceAudioOutMbusInit();
|
||||||
s32 PS4_SYSV_ABI sceAudioOutOpen(UserService::OrbisUserServiceUserId user_id,
|
s32 PS4_SYSV_ABI sceAudioOutOpen(UserService::OrbisUserServiceUserId user_id,
|
||||||
OrbisAudioOutPort port_type, s32 index, u32 length,
|
OrbisAudioOutPort port_type, s32 index, u32 length,
|
||||||
u32 sample_rate, OrbisAudioOutParam param_type);
|
u32 sample_rate, OrbisAudioOutParamExtendedInformation param_type);
|
||||||
int PS4_SYSV_ABI sceAudioOutOpenEx();
|
int PS4_SYSV_ABI sceAudioOutOpenEx();
|
||||||
s32 PS4_SYSV_ABI sceAudioOutOutput(s32 handle, const void* ptr);
|
s32 PS4_SYSV_ABI sceAudioOutOutput(s32 handle, const void* ptr);
|
||||||
s32 PS4_SYSV_ABI sceAudioOutOutputs(OrbisAudioOutOutputParam* param, u32 num);
|
s32 PS4_SYSV_ABI sceAudioOutOutputs(OrbisAudioOutOutputParam* param, u32 num);
|
||||||
|
|
Loading…
Reference in New Issue