From ad6de93cba100f8acc1fcda74e5af4adeeae7794 Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Wed, 9 Jul 2025 14:42:26 +0300 Subject: [PATCH 1/9] initial drafts --- src/core/libraries/audio/audioin.cpp | 3 ++- src/core/libraries/audio/audioin.h | 8 +++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/core/libraries/audio/audioin.cpp b/src/core/libraries/audio/audioin.cpp index 0a2489740..0f3ac4a20 100644 --- a/src/core/libraries/audio/audioin.cpp +++ b/src/core/libraries/audio/audioin.cpp @@ -123,7 +123,8 @@ int PS4_SYSV_ABI sceAudioInIsSharedDevice() { return ORBIS_OK; } -int PS4_SYSV_ABI sceAudioInOpen() { +int PS4_SYSV_ABI sceAudioInOpen(Libraries::UserService::OrbisUserServiceUserId userId, u32 type, + u32 index, u32 len, u32 freq, u32 param) { LOG_ERROR(Lib_AudioIn, "(DUMMY) called"); return 0x80260005; // ports are full return } diff --git a/src/core/libraries/audio/audioin.h b/src/core/libraries/audio/audioin.h index 28162d464..96fbc6f3e 100644 --- a/src/core/libraries/audio/audioin.h +++ b/src/core/libraries/audio/audioin.h @@ -3,6 +3,7 @@ #pragma once +#include #include "common/types.h" namespace Core::Loader { @@ -11,6 +12,10 @@ class SymbolsResolver; namespace Libraries::AudioIn { +enum class OrbisAudioInParamFormat : u32 { S16Mono = 0, S16Stereo = 2 }; + +enum class OrbisAudioInType : u32 { VoiceChat = 0, General = 1, VoiceRecognition = 5 }; + int PS4_SYSV_ABI sceAudioInChangeAppModuleState(); int PS4_SYSV_ABI sceAudioInClose(); int PS4_SYSV_ABI sceAudioInCountPorts(); @@ -34,7 +39,8 @@ int PS4_SYSV_ABI sceAudioInInit(); int PS4_SYSV_ABI sceAudioInInput(); int PS4_SYSV_ABI sceAudioInInputs(); int PS4_SYSV_ABI sceAudioInIsSharedDevice(); -int PS4_SYSV_ABI sceAudioInOpen(); +int PS4_SYSV_ABI sceAudioInOpen(Libraries::UserService::OrbisUserServiceUserId userId, u32 type, + u32 index, u32 len, u32 freq, u32 param); int PS4_SYSV_ABI sceAudioInOpenEx(); int PS4_SYSV_ABI sceAudioInSetAllMute(); int PS4_SYSV_ABI sceAudioInSetCompressorPreGain(); From 5c53ca8b61667b7fd4c469186abdc59d35dbdca5 Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Thu, 10 Jul 2025 20:02:22 +0300 Subject: [PATCH 2/9] initial implementation --- CMakeLists.txt | 2 + src/core/libraries/audio/audioin.cpp | 21 ++++-- src/core/libraries/audio/audioin.h | 4 +- src/core/libraries/audio/sdl_in.cpp | 97 ++++++++++++++++++++++++++++ src/core/libraries/audio/sdl_in.h | 39 +++++++++++ 5 files changed, 155 insertions(+), 8 deletions(-) create mode 100644 src/core/libraries/audio/sdl_in.cpp create mode 100644 src/core/libraries/audio/sdl_in.h diff --git a/CMakeLists.txt b/CMakeLists.txt index adff454b8..900be80df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -300,6 +300,8 @@ set(AJM_LIB src/core/libraries/ajm/ajm.cpp set(AUDIO_LIB src/core/libraries/audio/audioin.cpp src/core/libraries/audio/audioin.h + src/core/libraries/audio/sdl_in.h + src/core/libraries/audio/sdl_in.cpp src/core/libraries/voice/voice.cpp src/core/libraries/voice/voice.h src/core/libraries/audio/audioout.cpp diff --git a/src/core/libraries/audio/audioin.cpp b/src/core/libraries/audio/audioin.cpp index 0f3ac4a20..93793f5b7 100644 --- a/src/core/libraries/audio/audioin.cpp +++ b/src/core/libraries/audio/audioin.cpp @@ -5,15 +5,20 @@ #include "core/libraries/audio/audioin.h" #include "core/libraries/error_codes.h" #include "core/libraries/libs.h" +#include "core/libraries/audio/sdl_in.h" namespace Libraries::AudioIn { +static std::unique_ptr audio = std::make_unique(); + int PS4_SYSV_ABI sceAudioInChangeAppModuleState() { LOG_ERROR(Lib_AudioIn, "(STUBBED) called"); return ORBIS_OK; } -int PS4_SYSV_ABI sceAudioInClose() { +int PS4_SYSV_ABI sceAudioInClose(s32 handle) + { + audio->AudioInClose(handle); LOG_ERROR(Lib_AudioIn, "(STUBBED) called"); return ORBIS_OK; } @@ -108,9 +113,8 @@ int PS4_SYSV_ABI sceAudioInInit() { return ORBIS_OK; } -int PS4_SYSV_ABI sceAudioInInput() { - LOG_ERROR(Lib_AudioIn, "(STUBBED) called"); - return ORBIS_OK; +int PS4_SYSV_ABI sceAudioInInput(s32 handle, void* dest) { + return audio->AudioInInput(handle, dest); } int PS4_SYSV_ABI sceAudioInInputs() { @@ -125,8 +129,13 @@ int PS4_SYSV_ABI sceAudioInIsSharedDevice() { int PS4_SYSV_ABI sceAudioInOpen(Libraries::UserService::OrbisUserServiceUserId userId, u32 type, u32 index, u32 len, u32 freq, u32 param) { - LOG_ERROR(Lib_AudioIn, "(DUMMY) called"); - return 0x80260005; // ports are full return + int result = audio->AudioInOpen(type, len, freq, param); + if (result == -1) { + LOG_ERROR(Lib_AudioOut, "Audio ports are full"); + return 0x80260005; + } + return result; + LOG_ERROR(Lib_AudioIn, "called"); } int PS4_SYSV_ABI sceAudioInOpenEx() { diff --git a/src/core/libraries/audio/audioin.h b/src/core/libraries/audio/audioin.h index 96fbc6f3e..596df95fc 100644 --- a/src/core/libraries/audio/audioin.h +++ b/src/core/libraries/audio/audioin.h @@ -17,7 +17,7 @@ enum class OrbisAudioInParamFormat : u32 { S16Mono = 0, S16Stereo = 2 }; enum class OrbisAudioInType : u32 { VoiceChat = 0, General = 1, VoiceRecognition = 5 }; int PS4_SYSV_ABI sceAudioInChangeAppModuleState(); -int PS4_SYSV_ABI sceAudioInClose(); +int PS4_SYSV_ABI sceAudioInClose(s32 handle); int PS4_SYSV_ABI sceAudioInCountPorts(); int PS4_SYSV_ABI sceAudioInDeviceHqOpen(); int PS4_SYSV_ABI sceAudioInDeviceIdHqOpen(); @@ -36,7 +36,7 @@ int PS4_SYSV_ABI sceAudioInGetSilentState(); int PS4_SYSV_ABI sceAudioInHqOpen(); int PS4_SYSV_ABI sceAudioInHqOpenEx(); int PS4_SYSV_ABI sceAudioInInit(); -int PS4_SYSV_ABI sceAudioInInput(); +int PS4_SYSV_ABI sceAudioInInput(s32 handle, void* dest); int PS4_SYSV_ABI sceAudioInInputs(); int PS4_SYSV_ABI sceAudioInIsSharedDevice(); int PS4_SYSV_ABI sceAudioInOpen(Libraries::UserService::OrbisUserServiceUserId userId, u32 type, diff --git a/src/core/libraries/audio/sdl_in.cpp b/src/core/libraries/audio/sdl_in.cpp new file mode 100644 index 000000000..fb534f0c8 --- /dev/null +++ b/src/core/libraries/audio/sdl_in.cpp @@ -0,0 +1,97 @@ +#include +#include "sdl_in.h" + +int SDLAudioIn::AudioInit() { + return SDL_InitSubSystem(SDL_INIT_AUDIO); +} + +int SDLAudioIn::AudioInOpen(int type, uint32_t samples_num, uint32_t freq, uint32_t format) { + using Libraries::AudioIn::OrbisAudioInParam; + std::scoped_lock lock{m_mutex}; + + for (int id = 0; id < portsIn.size(); id++) { + auto& port = portsIn[id]; + if (!port.isOpen) { + port.isOpen = true; + port.type = type; + port.samples_num = samples_num; + port.freq = freq; + port.format = format; + + SDL_AudioFormat sampleFormat; + switch (format) { + case 0: + sampleFormat = SDL_AUDIO_S16; + port.channels_num = 1; + port.sample_size = 2; + break; + case 2: + sampleFormat = SDL_AUDIO_S16; + port.channels_num = 2; + port.sample_size = 2; + break; + default: + port.isOpen = false; + return ORBIS_AUDIO_IN_ERROR_INVALID_PORT; + } + + SDL_AudioSpec fmt; + SDL_zero(fmt); + fmt.format = sampleFormat; + fmt.channels = port.channels_num; + fmt.freq = port.freq; + + port.stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_RECORDING, &fmt, + nullptr, nullptr); + if (!port.stream) { + port.isOpen = false; + return -1; + } + + SDL_ResumeAudioDevice(SDL_GetAudioStreamDevice(port.stream)); + return id + 1; + } + } + + return -1; +} + +int SDLAudioIn::AudioInInput(int handle, void* out_buffer) { + std::scoped_lock lock{m_mutex}; + if (handle < 1 || handle > portsIn.size()) + return ORBIS_AUDIO_IN_ERROR_INVALID_PORT; + + auto& port = portsIn[handle - 1]; + if (!port.isOpen || out_buffer == nullptr) { + return ORBIS_AUDIO_IN_ERROR_INVALID_PORT; + } + + const int bytesToRead = port.samples_num * port.sample_size * port.channels_num; + + int attempts = 0; + while (SDL_GetAudioStreamAvailable(port.stream) < bytesToRead) { + SDL_Delay(1); + if (++attempts > 1000) { + return ORBIS_AUDIO_IN_ERROR_TIMEOUT; + } + } + + if (SDL_GetAudioStreamData(port.stream, out_buffer, bytesToRead) != 0) { + return ORBIS_AUDIO_IN_ERROR_STREAM_FAIL; + } + + return bytesToRead; +} + +void SDLAudioIn::AudioInClose(int handle) { + std::scoped_lock lock{m_mutex}; + if (handle < 1 || handle > portsIn.size()) + return; + + auto& port = portsIn[handle - 1]; + if (!port.isOpen) + return; + + SDL_DestroyAudioStream(port.stream); + port.isOpen = false; +} diff --git a/src/core/libraries/audio/sdl_in.h b/src/core/libraries/audio/sdl_in.h new file mode 100644 index 000000000..fca9c8bee --- /dev/null +++ b/src/core/libraries/audio/sdl_in.h @@ -0,0 +1,39 @@ +#pragma once + +#include +#include +#include + +namespace Libraries::AudioIn { +enum OrbisAudioInParam { + ORBIS_AUDIO_IN_PARAM_FORMAT_S16_MONO = 0, + ORBIS_AUDIO_IN_PARAM_FORMAT_S16_STEREO=2 +}; +} + +#define ORBIS_AUDIO_IN_ERROR_INVALID_PORT -1 +#define ORBIS_AUDIO_IN_ERROR_TIMEOUT -2 +#define ORBIS_AUDIO_IN_ERROR_STREAM_FAIL -3 + +class SDLAudioIn { +public: + int AudioInit(); + int AudioInOpen(int type, uint32_t samples_num, uint32_t freq, uint32_t format); + int AudioInInput(int handle, void* out_buffer); + void AudioInClose(int handle); + +private: + struct AudioInPort { + bool isOpen = false; + int type = 0; + uint32_t samples_num = 0; + uint32_t freq = 0; + int channels_num = 0; + int sample_size = 0; + uint32_t format; + SDL_AudioStream* stream = nullptr; + }; + + std::array portsIn; + std::mutex m_mutex; +}; \ No newline at end of file From eb5dc68d596b110ca1a27328f7dbbf32e74fd145 Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Thu, 10 Jul 2025 21:07:34 +0300 Subject: [PATCH 3/9] clang+reuse --- src/core/libraries/audio/audioin.cpp | 5 ++--- src/core/libraries/audio/sdl_in.cpp | 3 +++ src/core/libraries/audio/sdl_in.h | 5 ++++- src/main.cpp | 5 +++-- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/core/libraries/audio/audioin.cpp b/src/core/libraries/audio/audioin.cpp index 93793f5b7..c2d84054a 100644 --- a/src/core/libraries/audio/audioin.cpp +++ b/src/core/libraries/audio/audioin.cpp @@ -3,9 +3,9 @@ #include "common/logging/log.h" #include "core/libraries/audio/audioin.h" +#include "core/libraries/audio/sdl_in.h" #include "core/libraries/error_codes.h" #include "core/libraries/libs.h" -#include "core/libraries/audio/sdl_in.h" namespace Libraries::AudioIn { @@ -16,8 +16,7 @@ int PS4_SYSV_ABI sceAudioInChangeAppModuleState() { return ORBIS_OK; } -int PS4_SYSV_ABI sceAudioInClose(s32 handle) - { +int PS4_SYSV_ABI sceAudioInClose(s32 handle) { audio->AudioInClose(handle); LOG_ERROR(Lib_AudioIn, "(STUBBED) called"); return ORBIS_OK; diff --git a/src/core/libraries/audio/sdl_in.cpp b/src/core/libraries/audio/sdl_in.cpp index fb534f0c8..c7fea3184 100644 --- a/src/core/libraries/audio/sdl_in.cpp +++ b/src/core/libraries/audio/sdl_in.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + #include #include "sdl_in.h" diff --git a/src/core/libraries/audio/sdl_in.h b/src/core/libraries/audio/sdl_in.h index fca9c8bee..b60db7602 100644 --- a/src/core/libraries/audio/sdl_in.h +++ b/src/core/libraries/audio/sdl_in.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + #pragma once #include @@ -7,7 +10,7 @@ namespace Libraries::AudioIn { enum OrbisAudioInParam { ORBIS_AUDIO_IN_PARAM_FORMAT_S16_MONO = 0, - ORBIS_AUDIO_IN_PARAM_FORMAT_S16_STEREO=2 + ORBIS_AUDIO_IN_PARAM_FORMAT_S16_STEREO = 2 }; } diff --git a/src/main.cpp b/src/main.cpp index fe245d104..52fd748b2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -30,7 +30,7 @@ int main(int argc, char* argv[]) { bool has_game_argument = false; std::string game_path; std::vector game_args{}; - +#if 0 // Map of argument strings to lambda functions std::unordered_map> arg_map = { {"-h", @@ -204,7 +204,8 @@ int main(int argc, char* argv[]) { return 1; } } - +#endif + const char* const eboot_path = "D:/ps4/sdk-samples/memrec.elf"; // Run the emulator with the resolved eboot path Core::Emulator emulator; emulator.Run(eboot_path, game_args); From d24ca9d73d8a1bdfd2bcf02bc9a9ff46f6053794 Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Thu, 10 Jul 2025 21:13:57 +0300 Subject: [PATCH 4/9] restore main --- src/main.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 52fd748b2..fe245d104 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -30,7 +30,7 @@ int main(int argc, char* argv[]) { bool has_game_argument = false; std::string game_path; std::vector game_args{}; -#if 0 + // Map of argument strings to lambda functions std::unordered_map> arg_map = { {"-h", @@ -204,8 +204,7 @@ int main(int argc, char* argv[]) { return 1; } } -#endif - const char* const eboot_path = "D:/ps4/sdk-samples/memrec.elf"; + // Run the emulator with the resolved eboot path Core::Emulator emulator; emulator.Run(eboot_path, game_args); From 32f643ca9573d123bcf9449cf8b9a4dbfb488899 Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Mon, 14 Jul 2025 23:06:09 +0300 Subject: [PATCH 5/9] improved AudioInInput --- src/core/libraries/audio/sdl_in.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/core/libraries/audio/sdl_in.cpp b/src/core/libraries/audio/sdl_in.cpp index c7fea3184..4b8fb6c6e 100644 --- a/src/core/libraries/audio/sdl_in.cpp +++ b/src/core/libraries/audio/sdl_in.cpp @@ -71,6 +71,17 @@ int SDLAudioIn::AudioInInput(int handle, void* out_buffer) { const int bytesToRead = port.samples_num * port.sample_size * port.channels_num; + if (out_buffer == nullptr) { + int attempts = 0; + while (SDL_GetAudioStreamAvailable(port.stream) > 0) { + SDL_Delay(1); + if (++attempts > 1000) { + return ORBIS_AUDIO_IN_ERROR_TIMEOUT; + } + } + return 0; // done + } + int attempts = 0; while (SDL_GetAudioStreamAvailable(port.stream) < bytesToRead) { SDL_Delay(1); @@ -79,11 +90,14 @@ int SDLAudioIn::AudioInInput(int handle, void* out_buffer) { } } - if (SDL_GetAudioStreamData(port.stream, out_buffer, bytesToRead) != 0) { + int result = SDL_GetAudioStreamData(port.stream, out_buffer, bytesToRead); + if (result < 0) { + // SDL_GetAudioStreamData failed + SDL_Log("AudioInInput error: %s", SDL_GetError()); return ORBIS_AUDIO_IN_ERROR_STREAM_FAIL; } - return bytesToRead; + return result; } void SDLAudioIn::AudioInClose(int handle) { From 84e8c2c884bec0fc196352542b5ee4c4f3b510b7 Mon Sep 17 00:00:00 2001 From: DanielSvoboda Date: Tue, 15 Jul 2025 23:21:57 -0300 Subject: [PATCH 6/9] fix microphone --- src/core/libraries/audio/sdl_in.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/libraries/audio/sdl_in.h b/src/core/libraries/audio/sdl_in.h index b60db7602..e1b2a4682 100644 --- a/src/core/libraries/audio/sdl_in.h +++ b/src/core/libraries/audio/sdl_in.h @@ -33,10 +33,10 @@ private: uint32_t freq = 0; int channels_num = 0; int sample_size = 0; - uint32_t format; + uint32_t format = 0; SDL_AudioStream* stream = nullptr; }; std::array portsIn; std::mutex m_mutex; -}; \ No newline at end of file +}; From 2116c1dae41dde2869b1817713e411a2219d848d Mon Sep 17 00:00:00 2001 From: DanielSvoboda Date: Tue, 15 Jul 2025 23:23:15 -0300 Subject: [PATCH 7/9] + --- src/core/libraries/audio/audioin.cpp | 14 +++++++--- src/core/libraries/audio/audioin.h | 3 ++- src/core/libraries/audio/sdl_in.cpp | 38 +++++++++++++++------------- src/core/libraries/network/http.cpp | 2 +- 4 files changed, 34 insertions(+), 23 deletions(-) diff --git a/src/core/libraries/audio/audioin.cpp b/src/core/libraries/audio/audioin.cpp index c2d84054a..26cfccd8f 100644 --- a/src/core/libraries/audio/audioin.cpp +++ b/src/core/libraries/audio/audioin.cpp @@ -97,9 +97,15 @@ int PS4_SYSV_ABI sceAudioInGetSilentState() { return ORBIS_OK; } -int PS4_SYSV_ABI sceAudioInHqOpen() { - LOG_ERROR(Lib_AudioIn, "(STUBBED) called"); - return ORBIS_OK; +int PS4_SYSV_ABI sceAudioInHqOpen(Libraries::UserService::OrbisUserServiceUserId userId, u32 type, + u32 index, u32 len, u32 freq, u32 param) { + LOG_ERROR(Lib_AudioIn, "called"); + int result = audio->AudioInOpen(type, len, freq, param); + if (result == -1) { + LOG_ERROR(Lib_AudioOut, "Audio ports are full"); + return 0x80260005; + } + return result; } int PS4_SYSV_ABI sceAudioInHqOpenEx() { @@ -128,13 +134,13 @@ int PS4_SYSV_ABI sceAudioInIsSharedDevice() { int PS4_SYSV_ABI sceAudioInOpen(Libraries::UserService::OrbisUserServiceUserId userId, u32 type, u32 index, u32 len, u32 freq, u32 param) { + LOG_ERROR(Lib_AudioIn, "called"); int result = audio->AudioInOpen(type, len, freq, param); if (result == -1) { LOG_ERROR(Lib_AudioOut, "Audio ports are full"); return 0x80260005; } return result; - LOG_ERROR(Lib_AudioIn, "called"); } int PS4_SYSV_ABI sceAudioInOpenEx() { diff --git a/src/core/libraries/audio/audioin.h b/src/core/libraries/audio/audioin.h index 596df95fc..4b53acfd1 100644 --- a/src/core/libraries/audio/audioin.h +++ b/src/core/libraries/audio/audioin.h @@ -33,7 +33,8 @@ int PS4_SYSV_ABI sceAudioInGetGain(); int PS4_SYSV_ABI sceAudioInGetHandleStatusInfo(); int PS4_SYSV_ABI sceAudioInGetRerouteCount(); int PS4_SYSV_ABI sceAudioInGetSilentState(); -int PS4_SYSV_ABI sceAudioInHqOpen(); +int PS4_SYSV_ABI sceAudioInHqOpen(Libraries::UserService::OrbisUserServiceUserId userId, u32 type, + u32 index, u32 len, u32 freq, u32 param); int PS4_SYSV_ABI sceAudioInHqOpenEx(); int PS4_SYSV_ABI sceAudioInInit(); int PS4_SYSV_ABI sceAudioInInput(s32 handle, void* dest); diff --git a/src/core/libraries/audio/sdl_in.cpp b/src/core/libraries/audio/sdl_in.cpp index 4b8fb6c6e..0f2484c74 100644 --- a/src/core/libraries/audio/sdl_in.cpp +++ b/src/core/libraries/audio/sdl_in.cpp @@ -9,10 +9,9 @@ int SDLAudioIn::AudioInit() { } int SDLAudioIn::AudioInOpen(int type, uint32_t samples_num, uint32_t freq, uint32_t format) { - using Libraries::AudioIn::OrbisAudioInParam; std::scoped_lock lock{m_mutex}; - for (int id = 0; id < portsIn.size(); id++) { + for (int id = 0; id < static_cast(portsIn.size()); ++id) { auto& port = portsIn[id]; if (!port.isOpen) { port.isOpen = true; @@ -23,12 +22,12 @@ int SDLAudioIn::AudioInOpen(int type, uint32_t samples_num, uint32_t freq, uint3 SDL_AudioFormat sampleFormat; switch (format) { - case 0: + case Libraries::AudioIn::ORBIS_AUDIO_IN_PARAM_FORMAT_S16_MONO: sampleFormat = SDL_AUDIO_S16; port.channels_num = 1; port.sample_size = 2; break; - case 2: + case Libraries::AudioIn::ORBIS_AUDIO_IN_PARAM_FORMAT_S16_STEREO: sampleFormat = SDL_AUDIO_S16; port.channels_num = 2; port.sample_size = 2; @@ -48,26 +47,31 @@ int SDLAudioIn::AudioInOpen(int type, uint32_t samples_num, uint32_t freq, uint3 nullptr, nullptr); if (!port.stream) { port.isOpen = false; - return -1; + return ORBIS_AUDIO_IN_ERROR_INVALID_PORT; + } + + if (SDL_ResumeAudioStreamDevice(port.stream) == false) { + SDL_DestroyAudioStream(port.stream); + port = {}; + return ORBIS_AUDIO_IN_ERROR_STREAM_FAIL; } - SDL_ResumeAudioDevice(SDL_GetAudioStreamDevice(port.stream)); return id + 1; } } - return -1; + return ORBIS_AUDIO_IN_ERROR_INVALID_PORT; } int SDLAudioIn::AudioInInput(int handle, void* out_buffer) { std::scoped_lock lock{m_mutex}; - if (handle < 1 || handle > portsIn.size()) + + if (handle < 1 || handle > static_cast(portsIn.size()) || !out_buffer) return ORBIS_AUDIO_IN_ERROR_INVALID_PORT; auto& port = portsIn[handle - 1]; - if (!port.isOpen || out_buffer == nullptr) { + if (!port.isOpen) return ORBIS_AUDIO_IN_ERROR_INVALID_PORT; - } const int bytesToRead = port.samples_num * port.sample_size * port.channels_num; @@ -90,19 +94,19 @@ int SDLAudioIn::AudioInInput(int handle, void* out_buffer) { } } - int result = SDL_GetAudioStreamData(port.stream, out_buffer, bytesToRead); - if (result < 0) { + const int bytesRead = SDL_GetAudioStreamData(port.stream, out_buffer, bytesToRead); + if (bytesRead < 0) { // SDL_GetAudioStreamData failed SDL_Log("AudioInInput error: %s", SDL_GetError()); return ORBIS_AUDIO_IN_ERROR_STREAM_FAIL; } - - return result; + const int framesRead = bytesRead / (port.sample_size * port.channels_num); + return framesRead; } void SDLAudioIn::AudioInClose(int handle) { std::scoped_lock lock{m_mutex}; - if (handle < 1 || handle > portsIn.size()) + if (handle < 1 || handle > (int)portsIn.size()) return; auto& port = portsIn[handle - 1]; @@ -110,5 +114,5 @@ void SDLAudioIn::AudioInClose(int handle) { return; SDL_DestroyAudioStream(port.stream); - port.isOpen = false; -} + port = {}; +} \ No newline at end of file diff --git a/src/core/libraries/network/http.cpp b/src/core/libraries/network/http.cpp index dbb5b096a..db73b90ec 100644 --- a/src/core/libraries/network/http.cpp +++ b/src/core/libraries/network/http.cpp @@ -186,7 +186,7 @@ int PS4_SYSV_ABI sceHttpGetAcceptEncodingGZIPEnabled() { int PS4_SYSV_ABI sceHttpGetAllResponseHeaders() { LOG_ERROR(Lib_Http, "(STUBBED) called"); - return ORBIS_OK; + return ORBIS_FAIL; } int PS4_SYSV_ABI sceHttpGetAuthEnabled() { From b0a86ce6a46d68b8c70739d4348b711ccb55491b Mon Sep 17 00:00:00 2001 From: DanielSvoboda Date: Wed, 16 Jul 2025 18:25:26 -0300 Subject: [PATCH 8/9] + --- src/common/config.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/common/config.h b/src/common/config.h index e54425676..c683dd1f2 100644 --- a/src/common/config.h +++ b/src/common/config.h @@ -83,7 +83,9 @@ void setLogFilter(const std::string& type); double getTrophyNotificationDuration(); void setTrophyNotificationDuration(double newTrophyNotificationDuration); int getCursorHideTimeout(); +std::string getMicDevice(); void setCursorHideTimeout(int newcursorHideTimeout); +void setMicDevice(std::string device); void setSeparateLogFilesEnabled(bool enabled); bool getSeparateLogFilesEnabled(); u32 GetLanguage(); From 9d5c0794e5bff9fae67aaf767632aaf85a957634 Mon Sep 17 00:00:00 2001 From: DanielSvoboda Date: Wed, 16 Jul 2025 18:28:34 -0300 Subject: [PATCH 9/9] adds microphone selection to the interface --- src/common/config.cpp | 12 +++ src/core/libraries/audio/sdl_in.cpp | 20 +++- src/qt_gui/settings_dialog.cpp | 32 +++++++ src/qt_gui/settings_dialog.ui | 140 ++++++++++++++++------------ src/qt_gui/translations/en_US.ts | 12 +++ 5 files changed, 156 insertions(+), 60 deletions(-) diff --git a/src/common/config.cpp b/src/common/config.cpp index 6f8563377..898aa72c4 100644 --- a/src/common/config.cpp +++ b/src/common/config.cpp @@ -54,6 +54,7 @@ static bool useSpecialPad = false; static int specialPadClass = 1; static bool isMotionControlsEnabled = true; static bool useUnifiedInputConfig = true; +static std::string micDevice = "Default Device"; // These two entries aren't stored in the config static bool overrideControllerColor = false; @@ -193,6 +194,10 @@ int getCursorHideTimeout() { return cursorHideTimeout; } +std::string getMicDevice() { + return micDevice; +} + double getTrophyNotificationDuration() { return trophyNotificationDuration; } @@ -445,6 +450,10 @@ void setCursorHideTimeout(int newcursorHideTimeout) { cursorHideTimeout = newcursorHideTimeout; } +void setMicDevice(std::string device) { + micDevice = device; +} + void setTrophyNotificationDuration(double newTrophyNotificationDuration) { trophyNotificationDuration = newTrophyNotificationDuration; } @@ -643,6 +652,7 @@ void load(const std::filesystem::path& path) { toml::find_or(input, "isMotionControlsEnabled", isMotionControlsEnabled); useUnifiedInputConfig = toml::find_or(input, "useUnifiedInputConfig", useUnifiedInputConfig); + micDevice = toml::find_or(input, "micDevice", micDevice); entry_count += input.size(); } @@ -826,6 +836,7 @@ void save(const std::filesystem::path& path) { data["Input"]["specialPadClass"] = specialPadClass; data["Input"]["isMotionControlsEnabled"] = isMotionControlsEnabled; data["Input"]["useUnifiedInputConfig"] = useUnifiedInputConfig; + data["Input"]["micDevice"] = micDevice; data["GPU"]["screenWidth"] = windowWidth; data["GPU"]["screenHeight"] = windowHeight; data["GPU"]["internalScreenWidth"] = internalScreenWidth; @@ -927,6 +938,7 @@ void setDefaultValues() { controllerCustomColorRGB[0] = 0; controllerCustomColorRGB[1] = 0; controllerCustomColorRGB[2] = 255; + micDevice = "Default Device"; // GPU windowWidth = 1280; diff --git a/src/core/libraries/audio/sdl_in.cpp b/src/core/libraries/audio/sdl_in.cpp index 0f2484c74..0ea34ecfa 100644 --- a/src/core/libraries/audio/sdl_in.cpp +++ b/src/core/libraries/audio/sdl_in.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include +#include #include "sdl_in.h" int SDLAudioIn::AudioInit() { @@ -43,8 +44,23 @@ int SDLAudioIn::AudioInOpen(int type, uint32_t samples_num, uint32_t freq, uint3 fmt.channels = port.channels_num; fmt.freq = port.freq; - port.stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_RECORDING, &fmt, - nullptr, nullptr); + std::string micDevStr = Config::getMicDevice(); + uint32_t devId; + + if (micDevStr == "None") { + return ORBIS_AUDIO_IN_ERROR_INVALID_PORT; + } else if (micDevStr == "Default Device") { + devId = SDL_AUDIO_DEVICE_DEFAULT_RECORDING; + } else { + try { + devId = static_cast(std::stoul(micDevStr)); + } catch (const std::exception& e) { + return ORBIS_AUDIO_IN_ERROR_INVALID_PORT; + } + } + + port.stream = SDL_OpenAudioDeviceStream(devId, &fmt, nullptr, nullptr); + if (!port.stream) { port.isOpen = false; return ORBIS_AUDIO_IN_ERROR_INVALID_PORT; diff --git a/src/qt_gui/settings_dialog.cpp b/src/qt_gui/settings_dialog.cpp index ed2a17e25..f47bcd700 100644 --- a/src/qt_gui/settings_dialog.cpp +++ b/src/qt_gui/settings_dialog.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include "common/config.h" @@ -27,6 +28,7 @@ #include "settings_dialog.h" #include "ui_settings_dialog.h" #include "video_core/renderer_vulkan/vk_instance.h" + QStringList languageNames = {"Arabic", "Czech", "Danish", @@ -65,6 +67,7 @@ QMap channelMap; QMap logTypeMap; QMap screenModeMap; QMap chooseHomeTabMap; +QMap micMap; int backgroundImageOpacitySlider_backup; int bgm_volume_backup; @@ -92,6 +95,7 @@ SettingsDialog::SettingsDialog(std::shared_ptr gui_settings, {tr("Graphics"), "Graphics"}, {tr("User"), "User"}, {tr("Input"), "Input"}, {tr("Paths"), "Paths"}, {tr("Debug"), "Debug"}}; + micMap = {{tr("None"), "None"}, {tr("Default Device"), "Default Device"}}; if (m_physical_devices.empty()) { // Populate cache of physical devices. @@ -123,6 +127,25 @@ SettingsDialog::SettingsDialog(std::shared_ptr gui_settings, ui->hideCursorComboBox->addItem(tr("Idle")); ui->hideCursorComboBox->addItem(tr("Always")); + ui->micComboBox->addItem(micMap.key("None"), "None"); + ui->micComboBox->addItem(micMap.key("Default Device"), "Default Device"); + SDL_InitSubSystem(SDL_INIT_AUDIO); + int count = 0; + SDL_AudioDeviceID* devices = SDL_GetAudioRecordingDevices(&count); + if (devices) { + for (int i = 0; i < count; ++i) { + SDL_AudioDeviceID devId = devices[i]; + const char* name = SDL_GetAudioDeviceName(devId); + if (name) { + QString qname = QString::fromUtf8(name); + ui->micComboBox->addItem(qname, QString::number(devId)); + } + } + SDL_free(devices); + } else { + qDebug() << "Erro SDL_GetAudioRecordingDevices:" << SDL_GetError(); + } + InitializeEmulatorLanguages(); LoadValuesFromConfig(); @@ -441,6 +464,14 @@ void SettingsDialog::LoadValuesFromConfig() { ui->hideCursorComboBox->setCurrentIndex(toml::find_or(data, "Input", "cursorState", 1)); OnCursorStateChanged(toml::find_or(data, "Input", "cursorState", 1)); ui->idleTimeoutSpinBox->setValue(toml::find_or(data, "Input", "cursorHideTimeout", 5)); + + QString micValue = QString::fromStdString(Config::getMicDevice()); + int micIndex = ui->micComboBox->findData(micValue); + if (micIndex != -1) { + ui->micComboBox->setCurrentIndex(micIndex); + } else { + ui->micComboBox->setCurrentIndex(0); + } // First options is auto selection -1, so gpuId on the GUI will always have to subtract 1 // when setting and add 1 when getting to select the correct gpu in Qt ui->graphicsAdapterBox->setCurrentIndex(toml::find_or(data, "Vulkan", "gpuId", -1) + 1); @@ -753,6 +784,7 @@ void SettingsDialog::UpdateSettings() { m_gui_settings->SetValue(gui::gl_playBackgroundMusic, ui->playBGMCheckBox->isChecked()); Config::setAllowHDR(ui->enableHDRCheckBox->isChecked()); Config::setLogType(logTypeMap.value(ui->logTypeComboBox->currentText()).toStdString()); + Config::setMicDevice(ui->micComboBox->currentData().toString().toStdString()); Config::setLogFilter(ui->logFilterLineEdit->text().toStdString()); Config::setUserName(ui->userNameLineEdit->text().toStdString()); Config::setTrophyKey(ui->trophyKeyLineEdit->text().toStdString()); diff --git a/src/qt_gui/settings_dialog.ui b/src/qt_gui/settings_dialog.ui index 8d239b58c..cfd330e90 100644 --- a/src/qt_gui/settings_dialog.ui +++ b/src/qt_gui/settings_dialog.ui @@ -59,7 +59,7 @@ - 5 + 4 @@ -149,6 +149,19 @@ + + + + Qt::Orientation::Vertical + + + + 20 + 40 + + + + @@ -309,6 +322,32 @@ 80 + + + + + 0 + 0 + + + + + 11 + false + + + + Check for Updates at Startup + + + + + + + Always Show Changelog + + + @@ -396,32 +435,6 @@ - - - - - 0 - 0 - - - - - 11 - false - - - - Check for Updates at Startup - - - - - - - Always Show Changelog - - - @@ -1440,7 +1453,7 @@ - 7 + 6 0 @@ -1603,6 +1616,12 @@ Controller + + Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop + + + false + 0 @@ -1615,27 +1634,14 @@ - - Enable Motion Controls - - - - - - - true - - + 0 0 - - - 0 - 0 - + + Enable Motion Controls @@ -1652,20 +1658,38 @@ 0 - - - Qt::Orientation::Vertical - - - QSizePolicy::Policy::MinimumExpanding - - - - 20 - 20 - - - + + + + + Microphone + + + + + 14 + 33 + 431 + 31 + + + + + + + + + Qt::Orientation::Vertical + + + + 0 + 40 + + + + + diff --git a/src/qt_gui/translations/en_US.ts b/src/qt_gui/translations/en_US.ts index c2e35f4ee..99a72589f 100644 --- a/src/qt_gui/translations/en_US.ts +++ b/src/qt_gui/translations/en_US.ts @@ -1582,6 +1582,18 @@ Hide Cursor Idle Timeout Hide Cursor Idle Timeout + + Microphone + Microphone + + + None + None + + + Default Device + Default Device + s s