mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-24 19:14:40 +00:00
first working sound output , from openorbis sound demo
This commit is contained in:
parent
de82dea7f1
commit
686cc0617e
@ -1,9 +1,8 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include <SDL.h>
|
|
||||||
#include "sdl_audio.h"
|
|
||||||
#include <common/assert.h>
|
#include <common/assert.h>
|
||||||
|
#include "sdl_audio.h"
|
||||||
|
|
||||||
namespace Audio {
|
namespace Audio {
|
||||||
|
|
||||||
@ -23,21 +22,47 @@ 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;
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case OrbisAudioOutParam::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_MONO:
|
case OrbisAudioOutParam::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_MONO:
|
||||||
case OrbisAudioOutParam::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_MONO:
|
sampleFormat = SDL_AUDIO_S16;
|
||||||
port.channels_num = 1;
|
port.channels_num = 1;
|
||||||
|
port.sample_size = 2;
|
||||||
|
break;
|
||||||
|
case OrbisAudioOutParam::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_MONO:
|
||||||
|
sampleFormat = SDL_AUDIO_F32;
|
||||||
|
port.channels_num = 1;
|
||||||
|
port.sample_size = 4;
|
||||||
break;
|
break;
|
||||||
case OrbisAudioOutParam::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_STEREO:
|
case OrbisAudioOutParam::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_STEREO:
|
||||||
case OrbisAudioOutParam::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_STEREO:
|
sampleFormat = SDL_AUDIO_S16;
|
||||||
port.channels_num = 2;
|
port.channels_num = 2;
|
||||||
|
port.sample_size = 2;
|
||||||
|
break;
|
||||||
|
case OrbisAudioOutParam::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_STEREO:
|
||||||
|
sampleFormat = SDL_AUDIO_F32;
|
||||||
|
port.channels_num = 2;
|
||||||
|
port.sample_size = 4;
|
||||||
break;
|
break;
|
||||||
case OrbisAudioOutParam::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_8CH:
|
case OrbisAudioOutParam::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_8CH:
|
||||||
case OrbisAudioOutParam::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_8CH:
|
sampleFormat = SDL_AUDIO_S16;
|
||||||
case OrbisAudioOutParam::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_8CH_STD:
|
|
||||||
case OrbisAudioOutParam::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_8CH_STD:
|
|
||||||
port.channels_num = 8;
|
port.channels_num = 8;
|
||||||
|
port.sample_size = 2;
|
||||||
|
break;
|
||||||
|
case OrbisAudioOutParam::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_8CH:
|
||||||
|
sampleFormat = SDL_AUDIO_F32;
|
||||||
|
port.channels_num = 8;
|
||||||
|
port.sample_size = 4;
|
||||||
|
break;
|
||||||
|
case OrbisAudioOutParam::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_8CH_STD:
|
||||||
|
sampleFormat = SDL_AUDIO_S16;
|
||||||
|
port.channels_num = 8;
|
||||||
|
port.sample_size = 2;
|
||||||
|
break;
|
||||||
|
case OrbisAudioOutParam::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_8CH_STD:
|
||||||
|
sampleFormat = SDL_AUDIO_F32;
|
||||||
|
port.channels_num = 8;
|
||||||
|
port.sample_size = 4;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE_MSG("Unknown format");
|
UNREACHABLE_MSG("Unknown format");
|
||||||
@ -46,12 +71,30 @@ int SDLAudio::AudioOutOpen(int type, u32 samples_num, u32 freq,
|
|||||||
for (int i = 0; i < port.channels_num; i++) {
|
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_zero(fmt);
|
||||||
|
fmt.format = sampleFormat;
|
||||||
|
fmt.channels = port.channels_num;
|
||||||
|
fmt.freq = 48000;
|
||||||
|
port.stream =
|
||||||
|
SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_OUTPUT, &fmt, NULL, NULL);
|
||||||
|
SDL_ResumeAudioDevice(SDL_GetAudioStreamDevice(port.stream));
|
||||||
return id + 1;
|
return id + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1; // all ports are used
|
return -1; // all ports are used
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s32 SDLAudio::AudioOutOutput(s32 handle, const void* ptr) {
|
||||||
|
std::scoped_lock lock{m_mutex};
|
||||||
|
auto& port = portsOut[handle - 1];
|
||||||
|
if (!port.isOpen || ptr == nullptr)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return SDL_PutAudioStreamData(port.stream, ptr,
|
||||||
|
port.samples_num * port.sample_size * port.channels_num);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Audio
|
} // namespace Audio
|
||||||
|
@ -4,9 +4,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <SDL.h>
|
||||||
|
#include <core/libraries/libsceaudioout.h>
|
||||||
|
|
||||||
#include "src/common/types.h"
|
#include "src/common/types.h"
|
||||||
#include <core/libraries/libsceaudioout.h>
|
|
||||||
|
|
||||||
namespace Audio {
|
namespace Audio {
|
||||||
|
|
||||||
@ -16,17 +17,21 @@ public:
|
|||||||
virtual ~SDLAudio() = default;
|
virtual ~SDLAudio() = default;
|
||||||
|
|
||||||
int AudioInit();
|
int AudioInit();
|
||||||
int AudioOutOpen(int type, u32 samples_num, u32 freq, Libraries::AudioOut::OrbisAudioOutParam format);
|
int AudioOutOpen(int type, u32 samples_num, u32 freq,
|
||||||
|
Libraries::AudioOut::OrbisAudioOutParam format);
|
||||||
|
s32 AudioOutOutput(s32 handle, const void* ptr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct PortOut {
|
struct PortOut {
|
||||||
bool isOpen = false;
|
bool isOpen = false;
|
||||||
int type = 0;
|
int type = 0;
|
||||||
u32 samples_num = 0;
|
u32 samples_num = 0;
|
||||||
|
u8 sample_size = 0;
|
||||||
u32 freq = 0;
|
u32 freq = 0;
|
||||||
u32 format = -1;
|
u32 format = -1;
|
||||||
int channels_num = 0;
|
int channels_num = 0;
|
||||||
int volume[8] = {};
|
int volume[8] = {};
|
||||||
|
SDL_AudioStream* stream = nullptr;
|
||||||
};
|
};
|
||||||
std::mutex m_mutex;
|
std::mutex m_mutex;
|
||||||
std::array<PortOut, 8> portsOut; // main support up to 8 ports
|
std::array<PortOut, 8> portsOut; // main support up to 8 ports
|
||||||
|
@ -235,7 +235,12 @@ s32 PS4_SYSV_ABI sceAudioOutOpen(UserService::OrbisUserServiceUserId user_id,
|
|||||||
"AudioOutOpen id = {} port_type = {} index= {} lenght= {} sample_rate= {} param_type= {}",
|
"AudioOutOpen id = {} port_type = {} index= {} lenght= {} sample_rate= {} param_type= {}",
|
||||||
user_id, GetAudioOutPort(port_type), index, length, sample_rate,
|
user_id, GetAudioOutPort(port_type), index, length, sample_rate,
|
||||||
GetAudioOutParam(param_type));
|
GetAudioOutParam(param_type));
|
||||||
return ORBIS_OK;
|
int result = audio->AudioOutOpen(port_type, length, sample_rate, param_type);
|
||||||
|
if (result == -1) {
|
||||||
|
LOG_ERROR(Lib_AudioOut, "Audio ports are full");
|
||||||
|
return ORBIS_AUDIO_OUT_ERROR_PORT_FULL;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceAudioOutOpenEx() {
|
int PS4_SYSV_ABI sceAudioOutOpenEx() {
|
||||||
@ -243,9 +248,8 @@ int PS4_SYSV_ABI sceAudioOutOpenEx() {
|
|||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceAudioOutOutput(s32 handle, const void* ptr) {
|
s32 PS4_SYSV_ABI sceAudioOutOutput(s32 handle, const void* ptr) {
|
||||||
LOG_ERROR(Lib_AudioOut, "(STUBBED) called");
|
return audio->AudioOutOutput(handle, ptr);
|
||||||
return ORBIS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceAudioOutOutputs() {
|
int PS4_SYSV_ABI sceAudioOutOutputs() {
|
||||||
|
Loading…
Reference in New Issue
Block a user