This commit is contained in:
siieo 2024-09-13 08:01:51 +00:00 committed by GitHub
commit 30ad1481fc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 60 additions and 82 deletions

View File

@ -4,6 +4,7 @@
name: Windows-Qt name: Windows-Qt
on: on:
workflow_dispatch:
push: push:
branches: [ "main" ] branches: [ "main" ]
pull_request: pull_request:

View File

@ -2,7 +2,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include "sdl_audio.h" #include "sdl_audio.h"
#include "common/assert.h" #include "common/assert.h"
#include "core/libraries/error_codes.h" #include "core/libraries/error_codes.h"
@ -10,7 +9,7 @@
#include <SDL3/SDL_init.h> #include <SDL3/SDL_init.h>
#include <SDL3/SDL_timer.h> #include <SDL3/SDL_timer.h>
#include <mutex> // std::unique_lock #include <mutex>
namespace Audio { namespace Audio {
@ -18,7 +17,8 @@ int SDLAudio::AudioOutOpen(int type, u32 samples_num, u32 freq,
Libraries::AudioOut::OrbisAudioOutParamFormat format) { Libraries::AudioOut::OrbisAudioOutParamFormat format) {
using Libraries::AudioOut::OrbisAudioOutParamFormat; using Libraries::AudioOut::OrbisAudioOutParamFormat;
std::unique_lock lock{m_mutex}; std::unique_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];
if (!port.isOpen) { if (!port.isOpen) {
port.isOpen = true; port.isOpen = true;
@ -26,65 +26,49 @@ int SDLAudio::AudioOutOpen(int type, u32 samples_num, u32 freq,
port.samples_num = samples_num; port.samples_num = samples_num;
port.freq = freq; port.freq = freq;
port.format = format; port.format = format;
SDL_AudioFormat sampleFormat; SDL_AudioFormat sampleFormat;
switch (format) { switch (format) {
case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_MONO: case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_MONO:
sampleFormat = SDL_AUDIO_S16; case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_STEREO:
port.channels_num = 1; case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_8CH:
port.sample_size = 2; case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_8CH_STD:
break; sampleFormat = SDL_AUDIO_S16;
case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_MONO: port.sample_size = 2;
sampleFormat = SDL_AUDIO_F32; break;
port.channels_num = 1; case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_MONO:
port.sample_size = 4; case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_STEREO:
break; case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_8CH:
case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_STEREO: case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_8CH_STD:
sampleFormat = SDL_AUDIO_S16; sampleFormat = SDL_AUDIO_F32;
port.channels_num = 2; port.sample_size = 4;
port.sample_size = 2; break;
break; default:
case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_STEREO: UNREACHABLE_MSG("Unknown format");
sampleFormat = SDL_AUDIO_F32;
port.channels_num = 2;
port.sample_size = 4;
break;
case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_8CH:
sampleFormat = SDL_AUDIO_S16;
port.channels_num = 8;
port.sample_size = 2;
break;
case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_8CH:
sampleFormat = SDL_AUDIO_F32;
port.channels_num = 8;
port.sample_size = 4;
break;
case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_8CH_STD:
sampleFormat = SDL_AUDIO_S16;
port.channels_num = 8;
port.sample_size = 2;
break;
case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_8CH_STD:
sampleFormat = SDL_AUDIO_F32;
port.channels_num = 8;
port.sample_size = 4;
break;
default:
UNREACHABLE_MSG("Unknown format");
} }
for (int i = 0; i < port.channels_num; i++) { port.channels_num = (format == OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_MONO ||
format == OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_MONO) ? 1 :
(format == OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_STEREO ||
format == OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_STEREO) ? 2 : 8;
for (int i = 0; i < port.channels_num; ++i) {
port.volume[i] = Libraries::AudioOut::SCE_AUDIO_OUT_VOLUME_0DB; port.volume[i] = Libraries::AudioOut::SCE_AUDIO_OUT_VOLUME_0DB;
} }
SDL_AudioSpec fmt; SDL_AudioSpec fmt{};
SDL_zero(fmt);
fmt.format = sampleFormat; fmt.format = sampleFormat;
fmt.channels = port.channels_num; fmt.channels = port.channels_num;
fmt.freq = 48000; fmt.freq = 48000;
port.stream =
SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &fmt, NULL, NULL); port.stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &fmt, nullptr, nullptr);
SDL_ResumeAudioDevice(SDL_GetAudioStreamDevice(port.stream)); if (port.stream != nullptr) {
return id + 1; SDL_ResumeAudioDevice(SDL_GetAudioStreamDevice(port.stream));
return id + 1;
}
port.isOpen = false; // Cleanup if stream open fails
return -1;
} }
} }
@ -94,16 +78,14 @@ int SDLAudio::AudioOutOpen(int type, u32 samples_num, u32 freq,
s32 SDLAudio::AudioOutOutput(s32 handle, const void* ptr) { s32 SDLAudio::AudioOutOutput(s32 handle, const void* ptr) {
std::shared_lock lock{m_mutex}; std::shared_lock lock{m_mutex};
auto& port = portsOut[handle - 1]; auto& port = portsOut[handle - 1];
if (!port.isOpen) {
if (!port.isOpen || ptr == nullptr) {
return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT; return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT;
} }
if (ptr == nullptr) {
return 0; int result = SDL_PutAudioStreamData(port.stream, ptr, port.samples_num * port.sample_size * port.channels_num);
}
// TODO mixing channels // Wait until the buffer has sufficient space
int result = SDL_PutAudioStreamData(port.stream, ptr,
port.samples_num * port.sample_size * port.channels_num);
// TODO find a correct value 8192 is estimated
while (SDL_GetAudioStreamAvailable(port.stream) > 65536) { while (SDL_GetAudioStreamAvailable(port.stream) > 65536) {
SDL_Delay(0); SDL_Delay(0);
} }
@ -115,32 +97,22 @@ bool SDLAudio::AudioOutSetVolume(s32 handle, s32 bitflag, s32* volume) {
using Libraries::AudioOut::OrbisAudioOutParamFormat; using Libraries::AudioOut::OrbisAudioOutParamFormat;
std::shared_lock lock{m_mutex}; std::shared_lock lock{m_mutex};
auto& port = portsOut[handle - 1]; 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) { if (!port.isOpen) {
return false;
}
for (int i = 0; i < port.channels_num; ++i, bitflag >>= 1u) {
if (bitflag & 0x1u) {
int src_index = i; int src_index = i;
if (port.format == if (port.format == OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_8CH_STD ||
OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_8CH_STD ||
port.format == OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_8CH_STD) { port.format == OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_8CH_STD) {
switch (i) { switch (i) {
case 4: case 4: src_index = 6; break;
src_index = 6; case 5: src_index = 7; break;
break; case 6: src_index = 4; break;
case 5: case 7: src_index = 5; break;
src_index = 7; default: break;
break;
case 6:
src_index = 4;
break;
case 7:
src_index = 5;
break;
default:
break;
} }
} }
port.volume[i] = volume[src_index]; port.volume[i] = volume[src_index];
@ -153,6 +125,11 @@ bool SDLAudio::AudioOutSetVolume(s32 handle, s32 bitflag, s32* volume) {
bool SDLAudio::AudioOutGetStatus(s32 handle, int* type, int* channels_num) { bool SDLAudio::AudioOutGetStatus(s32 handle, int* type, int* channels_num) {
std::shared_lock lock{m_mutex}; std::shared_lock lock{m_mutex};
auto& port = portsOut[handle - 1]; auto& port = portsOut[handle - 1];
if (!port.isOpen) {
return false;
}
*type = port.type; *type = port.type;
*channels_num = port.channels_num; *channels_num = port.channels_num;