mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-22 18:15:14 +00:00
initial implementation
This commit is contained in:
parent
9bece01cc7
commit
5c53ca8b61
@ -300,6 +300,8 @@ set(AJM_LIB src/core/libraries/ajm/ajm.cpp
|
|||||||
|
|
||||||
set(AUDIO_LIB src/core/libraries/audio/audioin.cpp
|
set(AUDIO_LIB src/core/libraries/audio/audioin.cpp
|
||||||
src/core/libraries/audio/audioin.h
|
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.cpp
|
||||||
src/core/libraries/voice/voice.h
|
src/core/libraries/voice/voice.h
|
||||||
src/core/libraries/audio/audioout.cpp
|
src/core/libraries/audio/audioout.cpp
|
||||||
|
@ -5,15 +5,20 @@
|
|||||||
#include "core/libraries/audio/audioin.h"
|
#include "core/libraries/audio/audioin.h"
|
||||||
#include "core/libraries/error_codes.h"
|
#include "core/libraries/error_codes.h"
|
||||||
#include "core/libraries/libs.h"
|
#include "core/libraries/libs.h"
|
||||||
|
#include "core/libraries/audio/sdl_in.h"
|
||||||
|
|
||||||
namespace Libraries::AudioIn {
|
namespace Libraries::AudioIn {
|
||||||
|
|
||||||
|
static std::unique_ptr<SDLAudioIn> audio = std::make_unique<SDLAudioIn>();
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceAudioInChangeAppModuleState() {
|
int PS4_SYSV_ABI sceAudioInChangeAppModuleState() {
|
||||||
LOG_ERROR(Lib_AudioIn, "(STUBBED) called");
|
LOG_ERROR(Lib_AudioIn, "(STUBBED) called");
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceAudioInClose() {
|
int PS4_SYSV_ABI sceAudioInClose(s32 handle)
|
||||||
|
{
|
||||||
|
audio->AudioInClose(handle);
|
||||||
LOG_ERROR(Lib_AudioIn, "(STUBBED) called");
|
LOG_ERROR(Lib_AudioIn, "(STUBBED) called");
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
@ -108,9 +113,8 @@ int PS4_SYSV_ABI sceAudioInInit() {
|
|||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceAudioInInput() {
|
int PS4_SYSV_ABI sceAudioInInput(s32 handle, void* dest) {
|
||||||
LOG_ERROR(Lib_AudioIn, "(STUBBED) called");
|
return audio->AudioInInput(handle, dest);
|
||||||
return ORBIS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceAudioInInputs() {
|
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,
|
int PS4_SYSV_ABI sceAudioInOpen(Libraries::UserService::OrbisUserServiceUserId userId, u32 type,
|
||||||
u32 index, u32 len, u32 freq, u32 param) {
|
u32 index, u32 len, u32 freq, u32 param) {
|
||||||
LOG_ERROR(Lib_AudioIn, "(DUMMY) called");
|
int result = audio->AudioInOpen(type, len, freq, param);
|
||||||
return 0x80260005; // ports are full return
|
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() {
|
int PS4_SYSV_ABI sceAudioInOpenEx() {
|
||||||
|
@ -17,7 +17,7 @@ enum class OrbisAudioInParamFormat : u32 { S16Mono = 0, S16Stereo = 2 };
|
|||||||
enum class OrbisAudioInType : u32 { VoiceChat = 0, General = 1, VoiceRecognition = 5 };
|
enum class OrbisAudioInType : u32 { VoiceChat = 0, General = 1, VoiceRecognition = 5 };
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceAudioInChangeAppModuleState();
|
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 sceAudioInCountPorts();
|
||||||
int PS4_SYSV_ABI sceAudioInDeviceHqOpen();
|
int PS4_SYSV_ABI sceAudioInDeviceHqOpen();
|
||||||
int PS4_SYSV_ABI sceAudioInDeviceIdHqOpen();
|
int PS4_SYSV_ABI sceAudioInDeviceIdHqOpen();
|
||||||
@ -36,7 +36,7 @@ int PS4_SYSV_ABI sceAudioInGetSilentState();
|
|||||||
int PS4_SYSV_ABI sceAudioInHqOpen();
|
int PS4_SYSV_ABI sceAudioInHqOpen();
|
||||||
int PS4_SYSV_ABI sceAudioInHqOpenEx();
|
int PS4_SYSV_ABI sceAudioInHqOpenEx();
|
||||||
int PS4_SYSV_ABI sceAudioInInit();
|
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 sceAudioInInputs();
|
||||||
int PS4_SYSV_ABI sceAudioInIsSharedDevice();
|
int PS4_SYSV_ABI sceAudioInIsSharedDevice();
|
||||||
int PS4_SYSV_ABI sceAudioInOpen(Libraries::UserService::OrbisUserServiceUserId userId, u32 type,
|
int PS4_SYSV_ABI sceAudioInOpen(Libraries::UserService::OrbisUserServiceUserId userId, u32 type,
|
||||||
|
97
src/core/libraries/audio/sdl_in.cpp
Normal file
97
src/core/libraries/audio/sdl_in.cpp
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
#include <cstring>
|
||||||
|
#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;
|
||||||
|
}
|
39
src/core/libraries/audio/sdl_in.h
Normal file
39
src/core/libraries/audio/sdl_in.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <mutex>
|
||||||
|
#include <SDL3/SDL.h>
|
||||||
|
|
||||||
|
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<AudioInPort, 8> portsIn;
|
||||||
|
std::mutex m_mutex;
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user