mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-12-14 07:38:49 +00:00
core: Library cleanup (#1631)
* core: Split error codes into separate files * Reduces build times and is cleaner * core: Bring structs and enums to codebase style * core: More style changes
This commit is contained in:
@@ -4,30 +4,30 @@
|
||||
#include <memory>
|
||||
#include <magic_enum.hpp>
|
||||
|
||||
#include "audio_core/sdl_audio.h"
|
||||
#include "common/assert.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "core/libraries/audio/audioout.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
#include "core/libraries/audio/audioout_error.h"
|
||||
#include "core/libraries/audio/sdl_audio.h"
|
||||
#include "core/libraries/libs.h"
|
||||
|
||||
namespace Libraries::AudioOut {
|
||||
|
||||
static std::unique_ptr<Audio::SDLAudio> audio;
|
||||
static std::unique_ptr<SDLAudioOut> audio;
|
||||
|
||||
static std::string_view GetAudioOutPort(u32 port) {
|
||||
static std::string_view GetAudioOutPort(OrbisAudioOutPort port) {
|
||||
switch (port) {
|
||||
case ORBIS_AUDIO_OUT_PORT_TYPE_MAIN:
|
||||
case OrbisAudioOutPort::Main:
|
||||
return "MAIN";
|
||||
case ORBIS_AUDIO_OUT_PORT_TYPE_BGM:
|
||||
case OrbisAudioOutPort::Bgm:
|
||||
return "BGM";
|
||||
case ORBIS_AUDIO_OUT_PORT_TYPE_VOICE:
|
||||
case OrbisAudioOutPort::Voice:
|
||||
return "VOICE";
|
||||
case ORBIS_AUDIO_OUT_PORT_TYPE_PERSONAL:
|
||||
case OrbisAudioOutPort::Personal:
|
||||
return "PERSONAL";
|
||||
case ORBIS_AUDIO_OUT_PORT_TYPE_PADSPK:
|
||||
case OrbisAudioOutPort::Padspk:
|
||||
return "PADSPK";
|
||||
case ORBIS_AUDIO_OUT_PORT_TYPE_AUX:
|
||||
case OrbisAudioOutPort::Aux:
|
||||
return "AUX";
|
||||
default:
|
||||
return "INVALID";
|
||||
@@ -36,21 +36,21 @@ static std::string_view GetAudioOutPort(u32 port) {
|
||||
|
||||
static std::string_view GetAudioOutParamFormat(OrbisAudioOutParamFormat param) {
|
||||
switch (param) {
|
||||
case ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_MONO:
|
||||
case OrbisAudioOutParamFormat::S16Mono:
|
||||
return "S16_MONO";
|
||||
case ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_STEREO:
|
||||
case OrbisAudioOutParamFormat::S16Stereo:
|
||||
return "S16_STEREO";
|
||||
case ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_8CH:
|
||||
case OrbisAudioOutParamFormat::S16_8CH:
|
||||
return "S16_8CH";
|
||||
case ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_MONO:
|
||||
case OrbisAudioOutParamFormat::FloatMono:
|
||||
return "FLOAT_MONO";
|
||||
case ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_STEREO:
|
||||
case OrbisAudioOutParamFormat::FloatStereo:
|
||||
return "FLOAT_STEREO";
|
||||
case ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_8CH:
|
||||
case OrbisAudioOutParamFormat::Float_8CH:
|
||||
return "FLOAT_8CH";
|
||||
case ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_8CH_STD:
|
||||
case OrbisAudioOutParamFormat::S16_8CH_Std:
|
||||
return "S16_8CH_STD";
|
||||
case ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_8CH_STD:
|
||||
case OrbisAudioOutParamFormat::Float_8CH_Std:
|
||||
return "FLOAT_8CH_STD";
|
||||
default:
|
||||
return "INVALID";
|
||||
@@ -59,11 +59,11 @@ static std::string_view GetAudioOutParamFormat(OrbisAudioOutParamFormat param) {
|
||||
|
||||
static std::string_view GetAudioOutParamAttr(OrbisAudioOutParamAttr attr) {
|
||||
switch (attr) {
|
||||
case ORBIS_AUDIO_OUT_PARAM_ATTR_NONE:
|
||||
case OrbisAudioOutParamAttr::None:
|
||||
return "NONE";
|
||||
case ORBIS_AUDIO_OUT_PARAM_ATTR_RESTRICTED:
|
||||
case OrbisAudioOutParamAttr::Restricted:
|
||||
return "RESTRICTED";
|
||||
case ORBIS_AUDIO_OUT_PARAM_ATTR_MIX_TO_MAIN:
|
||||
case OrbisAudioOutParamAttr::MixToMain:
|
||||
return "MIX_TO_MAIN";
|
||||
default:
|
||||
return "INVALID";
|
||||
@@ -180,29 +180,23 @@ int PS4_SYSV_ABI sceAudioOutGetPortState(s32 handle, OrbisAudioOutPortState* sta
|
||||
return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT;
|
||||
}
|
||||
|
||||
int type = 0;
|
||||
int channels_num = 0;
|
||||
|
||||
if (const auto err = audio->AudioOutGetStatus(handle, &type, &channels_num); err != ORBIS_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
const auto [type, channels_num] = audio->GetStatus(handle);
|
||||
state->rerouteCounter = 0;
|
||||
state->volume = 127; // max volume
|
||||
state->volume = 127;
|
||||
|
||||
switch (type) {
|
||||
case ORBIS_AUDIO_OUT_PORT_TYPE_MAIN:
|
||||
case ORBIS_AUDIO_OUT_PORT_TYPE_BGM:
|
||||
case ORBIS_AUDIO_OUT_PORT_TYPE_VOICE:
|
||||
case OrbisAudioOutPort::Main:
|
||||
case OrbisAudioOutPort::Bgm:
|
||||
case OrbisAudioOutPort::Voice:
|
||||
state->output = 1;
|
||||
state->channel = (channels_num > 2 ? 2 : channels_num);
|
||||
break;
|
||||
case ORBIS_AUDIO_OUT_PORT_TYPE_PERSONAL:
|
||||
case ORBIS_AUDIO_OUT_PORT_TYPE_PADSPK:
|
||||
case OrbisAudioOutPort::Personal:
|
||||
case OrbisAudioOutPort::Padspk:
|
||||
state->output = 4;
|
||||
state->channel = 1;
|
||||
break;
|
||||
case ORBIS_AUDIO_OUT_PORT_TYPE_AUX:
|
||||
case OrbisAudioOutPort::Aux:
|
||||
state->output = 0;
|
||||
state->channel = 0;
|
||||
break;
|
||||
@@ -243,7 +237,7 @@ int PS4_SYSV_ABI sceAudioOutInit() {
|
||||
if (audio != nullptr) {
|
||||
return ORBIS_AUDIO_OUT_ERROR_ALREADY_INIT;
|
||||
}
|
||||
audio = std::make_unique<Audio::SDLAudio>();
|
||||
audio = std::make_unique<SDLAudioOut>();
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
@@ -287,7 +281,8 @@ s32 PS4_SYSV_ABI sceAudioOutOpen(UserService::OrbisUserServiceUserId user_id,
|
||||
user_id, GetAudioOutPort(port_type), index, length, sample_rate,
|
||||
GetAudioOutParamFormat(param_type.data_format),
|
||||
GetAudioOutParamAttr(param_type.attributes));
|
||||
if ((port_type < 0 || port_type > 4) && (port_type != 127)) {
|
||||
if ((port_type < OrbisAudioOutPort::Main || port_type > OrbisAudioOutPort::Padspk) &&
|
||||
(port_type != OrbisAudioOutPort::Aux)) {
|
||||
LOG_ERROR(Lib_AudioOut, "Invalid port type");
|
||||
return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT_TYPE;
|
||||
}
|
||||
@@ -303,18 +298,19 @@ s32 PS4_SYSV_ABI sceAudioOutOpen(UserService::OrbisUserServiceUserId user_id,
|
||||
if (index != 0) {
|
||||
LOG_ERROR(Lib_AudioOut, "index is not valid !=0 {}", index);
|
||||
}
|
||||
OrbisAudioOutParamFormat format = param_type.data_format;
|
||||
if (format < 0 || format > 7) {
|
||||
const auto format = param_type.data_format.Value();
|
||||
if (format < OrbisAudioOutParamFormat::S16Mono ||
|
||||
format > OrbisAudioOutParamFormat::Float_8CH_Std) {
|
||||
LOG_ERROR(Lib_AudioOut, "Invalid format");
|
||||
return ORBIS_AUDIO_OUT_ERROR_INVALID_FORMAT;
|
||||
}
|
||||
OrbisAudioOutParamAttr attr = param_type.attributes;
|
||||
if (attr < 0 || attr > 2) {
|
||||
const auto attr = param_type.attributes;
|
||||
if (attr < OrbisAudioOutParamAttr::None || attr > OrbisAudioOutParamAttr::MixToMain) {
|
||||
// TODO Handle attributes in output audio device
|
||||
LOG_ERROR(Lib_AudioOut, "Invalid format attribute");
|
||||
return ORBIS_AUDIO_OUT_ERROR_INVALID_FORMAT;
|
||||
}
|
||||
return audio->AudioOutOpen(port_type, length, sample_rate, format);
|
||||
return audio->Open(port_type, length, sample_rate, format);
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudioOutOpenEx() {
|
||||
@@ -330,7 +326,7 @@ s32 PS4_SYSV_ABI sceAudioOutOutput(s32 handle, const void* ptr) {
|
||||
// Nothing to output
|
||||
return ORBIS_OK;
|
||||
}
|
||||
return audio->AudioOutOutput(handle, ptr);
|
||||
return audio->Output(handle, ptr);
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudioOutOutputs(OrbisAudioOutOutputParam* param, u32 num) {
|
||||
@@ -435,7 +431,7 @@ s32 PS4_SYSV_ABI sceAudioOutSetVolume(s32 handle, s32 flag, s32* vol) {
|
||||
if (handle < 1 || handle > SCE_AUDIO_OUT_NUM_PORTS) {
|
||||
return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT;
|
||||
}
|
||||
return audio->AudioOutSetVolume(handle, flag, vol);
|
||||
return audio->SetVolume(handle, flag, vol);
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudioOutSetVolumeDown() {
|
||||
|
||||
@@ -9,46 +9,36 @@
|
||||
|
||||
namespace Libraries::AudioOut {
|
||||
|
||||
constexpr int SCE_AUDIO_OUT_VOLUME_0DB = 32768; // max volume value
|
||||
|
||||
// main up to 8 ports, BGM 1 port, voice up to 4 ports,
|
||||
// Main up to 8 ports, BGM 1 port, voice up to 4 ports,
|
||||
// personal up to 4 ports, padspk up to 5 ports, aux 1 port
|
||||
constexpr int SCE_AUDIO_OUT_NUM_PORTS = 22;
|
||||
constexpr int SCE_AUDIO_OUT_VOLUME_0DB = 32768; // max volume value
|
||||
|
||||
enum OrbisAudioOutPort {
|
||||
ORBIS_AUDIO_OUT_PORT_TYPE_MAIN = 0,
|
||||
ORBIS_AUDIO_OUT_PORT_TYPE_BGM = 1,
|
||||
ORBIS_AUDIO_OUT_PORT_TYPE_VOICE = 2,
|
||||
ORBIS_AUDIO_OUT_PORT_TYPE_PERSONAL = 3,
|
||||
ORBIS_AUDIO_OUT_PORT_TYPE_PADSPK = 4,
|
||||
ORBIS_AUDIO_OUT_PORT_TYPE_AUX = 127
|
||||
enum class OrbisAudioOutPort { Main = 0, Bgm = 1, Voice = 2, Personal = 3, Padspk = 4, Aux = 127 };
|
||||
|
||||
enum class OrbisAudioOutParamFormat {
|
||||
S16Mono = 0,
|
||||
S16Stereo = 1,
|
||||
S16_8CH = 2,
|
||||
FloatMono = 3,
|
||||
FloatStereo = 4,
|
||||
Float_8CH = 5,
|
||||
S16_8CH_Std = 6,
|
||||
Float_8CH_Std = 7
|
||||
};
|
||||
|
||||
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,
|
||||
ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_MONO = 3,
|
||||
ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_STEREO = 4,
|
||||
ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_8CH = 5,
|
||||
ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_8CH_STD = 6,
|
||||
ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_8CH_STD = 7
|
||||
enum class OrbisAudioOutParamAttr {
|
||||
None = 0,
|
||||
Restricted = 1,
|
||||
MixToMain = 2,
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
union OrbisAudioOutParamExtendedInformation {
|
||||
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 {
|
||||
|
||||
34
src/core/libraries/audio/audioout_error.h
Normal file
34
src/core/libraries/audio/audioout_error.h
Normal file
@@ -0,0 +1,34 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/libraries/error_codes.h"
|
||||
|
||||
// AudioOut library
|
||||
constexpr int ORBIS_AUDIO_OUT_ERROR_NOT_OPENED = 0x80260001;
|
||||
constexpr int ORBIS_AUDIO_OUT_ERROR_BUSY = 0x80260002;
|
||||
constexpr int ORBIS_AUDIO_OUT_ERROR_INVALID_PORT = 0x80260003;
|
||||
constexpr int ORBIS_AUDIO_OUT_ERROR_INVALID_POINTER = 0x80260004;
|
||||
constexpr int ORBIS_AUDIO_OUT_ERROR_PORT_FULL = 0x80260005;
|
||||
constexpr int ORBIS_AUDIO_OUT_ERROR_INVALID_SIZE = 0x80260006;
|
||||
constexpr int ORBIS_AUDIO_OUT_ERROR_INVALID_FORMAT = 0x80260007;
|
||||
constexpr int ORBIS_AUDIO_OUT_ERROR_INVALID_SAMPLE_FREQ = 0x80260008;
|
||||
constexpr int ORBIS_AUDIO_OUT_ERROR_INVALID_VOLUME = 0x80260009;
|
||||
constexpr int ORBIS_AUDIO_OUT_ERROR_INVALID_PORT_TYPE = 0x8026000A;
|
||||
constexpr int ORBIS_AUDIO_OUT_ERROR_INVALID_CONF_TYPE = 0x8026000C;
|
||||
constexpr int ORBIS_AUDIO_OUT_ERROR_OUT_OF_MEMORY = 0x8026000D;
|
||||
constexpr int ORBIS_AUDIO_OUT_ERROR_ALREADY_INIT = 0x8026000E;
|
||||
constexpr int ORBIS_AUDIO_OUT_ERROR_NOT_INIT = 0x8026000F;
|
||||
constexpr int ORBIS_AUDIO_OUT_ERROR_MEMORY = 0x80260010;
|
||||
constexpr int ORBIS_AUDIO_OUT_ERROR_SYSTEM_RESOURCE = 0x80260011;
|
||||
constexpr int ORBIS_AUDIO_OUT_ERROR_TRANS_EVENT = 0x80260012;
|
||||
constexpr int ORBIS_AUDIO_OUT_ERROR_INVALID_FLAG = 0x80260013;
|
||||
constexpr int ORBIS_AUDIO_OUT_ERROR_INVALID_MIXLEVEL = 0x80260014;
|
||||
constexpr int ORBIS_AUDIO_OUT_ERROR_INVALID_ARG = 0x80260015;
|
||||
constexpr int ORBIS_AUDIO_OUT_ERROR_INVALID_PARAM = 0x80260016;
|
||||
constexpr int ORBIS_AUDIO_OUT_ERROR_MASTERING_FATAL = 0x80260200;
|
||||
constexpr int ORBIS_AUDIO_OUT_ERROR_MASTERING_INVALID_API_PARAM = 0x80260201;
|
||||
constexpr int ORBIS_AUDIO_OUT_ERROR_MASTERING_INVALID_CONFIG = 0x80260202;
|
||||
constexpr int ORBIS_AUDIO_OUT_ERROR_MASTERING_NOT_INITIALIZED = 0x80260203;
|
||||
constexpr int ORBIS_AUDIO_OUT_ERROR_MASTERING_INVALID_STATES_ID = 0x80260204;
|
||||
141
src/core/libraries/audio/sdl_audio.cpp
Normal file
141
src/core/libraries/audio/sdl_audio.cpp
Normal file
@@ -0,0 +1,141 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <mutex>
|
||||
#include <SDL3/SDL_audio.h>
|
||||
#include <SDL3/SDL_init.h>
|
||||
#include <SDL3/SDL_timer.h>
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "core/libraries/audio/audioout_error.h"
|
||||
#include "core/libraries/audio/sdl_audio.h"
|
||||
|
||||
namespace Libraries::AudioOut {
|
||||
|
||||
constexpr int AUDIO_STREAM_BUFFER_THRESHOLD = 65536; // Define constant for buffer threshold
|
||||
|
||||
s32 SDLAudioOut::Open(OrbisAudioOutPort type, u32 samples_num, u32 freq,
|
||||
OrbisAudioOutParamFormat format) {
|
||||
std::scoped_lock lock{m_mutex};
|
||||
const auto port = std::ranges::find(ports_out, false, &PortOut::is_open);
|
||||
if (port == ports_out.end()) {
|
||||
LOG_ERROR(Lib_AudioOut, "Audio ports are full");
|
||||
return ORBIS_AUDIO_OUT_ERROR_PORT_FULL;
|
||||
}
|
||||
|
||||
port->is_open = true;
|
||||
port->type = type;
|
||||
port->samples_num = samples_num;
|
||||
port->freq = freq;
|
||||
port->format = format;
|
||||
SDL_AudioFormat sampleFormat;
|
||||
switch (format) {
|
||||
case OrbisAudioOutParamFormat::S16Mono:
|
||||
sampleFormat = SDL_AUDIO_S16;
|
||||
port->channels_num = 1;
|
||||
port->sample_size = 2;
|
||||
break;
|
||||
case OrbisAudioOutParamFormat::FloatMono:
|
||||
sampleFormat = SDL_AUDIO_F32;
|
||||
port->channels_num = 1;
|
||||
port->sample_size = 4;
|
||||
break;
|
||||
case OrbisAudioOutParamFormat::S16Stereo:
|
||||
sampleFormat = SDL_AUDIO_S16;
|
||||
port->channels_num = 2;
|
||||
port->sample_size = 2;
|
||||
break;
|
||||
case OrbisAudioOutParamFormat::FloatStereo:
|
||||
sampleFormat = SDL_AUDIO_F32;
|
||||
port->channels_num = 2;
|
||||
port->sample_size = 4;
|
||||
break;
|
||||
case OrbisAudioOutParamFormat::S16_8CH:
|
||||
sampleFormat = SDL_AUDIO_S16;
|
||||
port->channels_num = 8;
|
||||
port->sample_size = 2;
|
||||
break;
|
||||
case OrbisAudioOutParamFormat::Float_8CH:
|
||||
sampleFormat = SDL_AUDIO_F32;
|
||||
port->channels_num = 8;
|
||||
port->sample_size = 4;
|
||||
break;
|
||||
case OrbisAudioOutParamFormat::S16_8CH_Std:
|
||||
sampleFormat = SDL_AUDIO_S16;
|
||||
port->channels_num = 8;
|
||||
port->sample_size = 2;
|
||||
break;
|
||||
case OrbisAudioOutParamFormat::Float_8CH_Std:
|
||||
sampleFormat = SDL_AUDIO_F32;
|
||||
port->channels_num = 8;
|
||||
port->sample_size = 4;
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE_MSG("Unknown format");
|
||||
}
|
||||
|
||||
port->volume.fill(Libraries::AudioOut::SCE_AUDIO_OUT_VOLUME_0DB);
|
||||
|
||||
SDL_AudioSpec fmt;
|
||||
SDL_zero(fmt);
|
||||
fmt.format = sampleFormat;
|
||||
fmt.channels = port->channels_num;
|
||||
fmt.freq = freq;
|
||||
port->stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &fmt, NULL, NULL);
|
||||
SDL_ResumeAudioDevice(SDL_GetAudioStreamDevice(port->stream));
|
||||
return std::distance(ports_out.begin(), port) + 1;
|
||||
}
|
||||
|
||||
s32 SDLAudioOut::Output(s32 handle, const void* ptr) {
|
||||
auto& port = ports_out.at(handle - 1);
|
||||
if (!port.is_open) {
|
||||
return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT;
|
||||
}
|
||||
|
||||
const size_t data_size = port.samples_num * port.sample_size * port.channels_num;
|
||||
bool result = SDL_PutAudioStreamData(port.stream, ptr, data_size);
|
||||
while (SDL_GetAudioStreamAvailable(port.stream) > AUDIO_STREAM_BUFFER_THRESHOLD) {
|
||||
SDL_Delay(0);
|
||||
}
|
||||
return result ? ORBIS_OK : -1;
|
||||
}
|
||||
|
||||
s32 SDLAudioOut::SetVolume(s32 handle, s32 bitflag, s32* volume) {
|
||||
using Libraries::AudioOut::OrbisAudioOutParamFormat;
|
||||
auto& port = ports_out.at(handle - 1);
|
||||
if (!port.is_open) {
|
||||
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 == OrbisAudioOutParamFormat::Float_8CH_Std ||
|
||||
port.format == OrbisAudioOutParamFormat::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 ORBIS_OK;
|
||||
}
|
||||
|
||||
} // namespace Libraries::AudioOut
|
||||
42
src/core/libraries/audio/sdl_audio.h
Normal file
42
src/core/libraries/audio/sdl_audio.h
Normal file
@@ -0,0 +1,42 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <shared_mutex>
|
||||
#include <SDL3/SDL_audio.h>
|
||||
#include "core/libraries/audio/audioout.h"
|
||||
|
||||
namespace Libraries::AudioOut {
|
||||
|
||||
class SDLAudioOut {
|
||||
public:
|
||||
explicit SDLAudioOut() = default;
|
||||
~SDLAudioOut() = default;
|
||||
|
||||
s32 Open(OrbisAudioOutPort type, u32 samples_num, u32 freq, OrbisAudioOutParamFormat format);
|
||||
s32 Output(s32 handle, const void* ptr);
|
||||
s32 SetVolume(s32 handle, s32 bitflag, s32* volume);
|
||||
|
||||
constexpr std::pair<OrbisAudioOutPort, int> GetStatus(s32 handle) const {
|
||||
const auto& port = ports_out.at(handle - 1);
|
||||
return std::make_pair(port.type, port.channels_num);
|
||||
}
|
||||
|
||||
private:
|
||||
struct PortOut {
|
||||
SDL_AudioStream* stream;
|
||||
u32 samples_num;
|
||||
u32 freq;
|
||||
OrbisAudioOutParamFormat format;
|
||||
OrbisAudioOutPort type;
|
||||
int channels_num;
|
||||
std::array<int, 8> volume;
|
||||
u8 sample_size;
|
||||
bool is_open;
|
||||
};
|
||||
std::shared_mutex m_mutex;
|
||||
std::array<PortOut, Libraries::AudioOut::SCE_AUDIO_OUT_NUM_PORTS> ports_out{};
|
||||
};
|
||||
|
||||
} // namespace Libraries::AudioOut
|
||||
Reference in New Issue
Block a user