mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-22 10:04:39 +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
|
||||
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
|
||||
|
@ -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<SDLAudioIn> audio = std::make_unique<SDLAudioIn>();
|
||||
|
||||
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() {
|
||||
|
@ -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,
|
||||
|
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