mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-06 00:40:11 +00:00
commit
1efa137f8f
@ -7,6 +7,8 @@ ALCenum g_last_alc_error = ALC_NO_ERROR;
|
||||
#define checkForAlError(sit) if((g_last_al_error = alGetError()) != AL_NO_ERROR) printAlError(g_last_al_error, sit)
|
||||
#define checkForAlcError(sit) if((g_last_alc_error = alcGetError(m_device)) != ALC_NO_ERROR) printAlcError(g_last_alc_error, sit)
|
||||
|
||||
static const ALenum g_audio_format = Ini.AudioConvertToU16.GetValue() ? AL_FORMAT_STEREO16 : AL_FORMAT_STEREO_FLOAT32;
|
||||
|
||||
void printAlError(ALenum err, const char* situation)
|
||||
{
|
||||
if(err != AL_NO_ERROR)
|
||||
@ -142,11 +144,11 @@ void OpenALThread::AddData(const void* src, ALsizei size)
|
||||
Play();
|
||||
}
|
||||
|
||||
bool OpenALThread::AddBlock(const ALuint buffer_id, ALsizei size, const void* src)
|
||||
bool OpenALThread::AddBlock(const ALuint buffer_id, const ALsizei size, const void* src)
|
||||
{
|
||||
if (size < 1) return false;
|
||||
|
||||
alBufferData(buffer_id, AL_FORMAT_STEREO_FLOAT32, src, size, 48000);
|
||||
alBufferData(buffer_id, g_audio_format, src, size, 48000);
|
||||
checkForAlError("alBufferData");
|
||||
|
||||
return true;
|
||||
|
@ -13,6 +13,8 @@ static SMutexGeneral audioMutex;
|
||||
|
||||
AudioConfig m_config;
|
||||
|
||||
static const bool g_is_u16 = Ini.AudioConvertToU16.GetValue();
|
||||
|
||||
// libaudio Functions
|
||||
|
||||
int cellAudioInit()
|
||||
@ -55,43 +57,80 @@ int cellAudioInit()
|
||||
float buf8ch[8 * 256]; // intermediate buffer for 8 channels
|
||||
|
||||
uint oal_buffer_offset = 0;
|
||||
uint oal_buffer_size = sizeof(buf2ch) / sizeof(float);
|
||||
std::unique_ptr<float[]> oal_buffer[32];
|
||||
SQueue<float*, 31> queue;
|
||||
const uint oal_buffer_size = sizeof(buf2ch) / sizeof(float);
|
||||
|
||||
std::unique_ptr<s16[]> oal_buffer[32];
|
||||
SQueue<s16*, 31> queue;
|
||||
|
||||
std::unique_ptr<float[]> oal_buffer_float[32];
|
||||
SQueue<float*, 31> queue_float;
|
||||
|
||||
for (u32 i = 0; i < sizeof(oal_buffer) / sizeof(oal_buffer[0]); i++)
|
||||
{
|
||||
oal_buffer[i] = std::unique_ptr<float[]>(new float[oal_buffer_size]);
|
||||
memset(oal_buffer[i].get(), 0, oal_buffer_size * sizeof(float));
|
||||
oal_buffer[i] = std::unique_ptr<s16[]>(new s16[oal_buffer_size]);
|
||||
memset(oal_buffer[i].get(), 0, oal_buffer_size * sizeof(s16));
|
||||
}
|
||||
queue.Clear();
|
||||
|
||||
for (u32 i = 0; i < sizeof(oal_buffer_float) / sizeof(oal_buffer_float[0]); i++)
|
||||
{
|
||||
oal_buffer_float[i] = std::unique_ptr<float[]>(new float[oal_buffer_size]);
|
||||
memset(oal_buffer_float[i].get(), 0, oal_buffer_size * sizeof(float));
|
||||
}
|
||||
queue_float.Clear();
|
||||
|
||||
std::vector<u64> keys;
|
||||
|
||||
if(m_audio_out)
|
||||
{
|
||||
m_audio_out->Init();
|
||||
m_audio_out->Open(oal_buffer[0].get(), oal_buffer_size * sizeof(float));
|
||||
|
||||
if (g_is_u16)
|
||||
m_audio_out->Open(oal_buffer[0].get(), oal_buffer_size * sizeof(s16));
|
||||
|
||||
m_audio_out->Open(oal_buffer_float[0].get(), oal_buffer_size * sizeof(float));
|
||||
}
|
||||
|
||||
m_config.start_time = get_system_time();
|
||||
|
||||
volatile bool internal_finished = false;
|
||||
|
||||
thread iat("Internal Audio Thread", [oal_buffer_size, &queue, &internal_finished]()
|
||||
thread iat("Internal Audio Thread", [oal_buffer_size, &queue, &queue_float, &internal_finished]()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
float* oal_buffer = nullptr;
|
||||
queue.Pop(oal_buffer);
|
||||
s16* oal_buffer = nullptr;
|
||||
float* oal_buffer_float = nullptr;
|
||||
|
||||
if (g_is_u16)
|
||||
queue.Pop(oal_buffer);
|
||||
|
||||
queue_float.Pop(oal_buffer_float);
|
||||
|
||||
if (oal_buffer)
|
||||
if (g_is_u16)
|
||||
{
|
||||
m_audio_out->AddData(oal_buffer, oal_buffer_size * sizeof(float));
|
||||
if (oal_buffer)
|
||||
{
|
||||
m_audio_out->AddData(oal_buffer, oal_buffer_size * sizeof(s16));
|
||||
}
|
||||
else
|
||||
{
|
||||
internal_finished = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
internal_finished = true;
|
||||
return;
|
||||
if (oal_buffer_float)
|
||||
{
|
||||
m_audio_out->AddData(oal_buffer_float, oal_buffer_size * sizeof(float));
|
||||
}
|
||||
else
|
||||
{
|
||||
internal_finished = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -119,6 +158,7 @@ int cellAudioInit()
|
||||
m_config.counter++;
|
||||
|
||||
const u32 oal_pos = m_config.counter % (sizeof(oal_buffer) / sizeof(oal_buffer[0]));
|
||||
const u32 oal_pos_float = m_config.counter % (sizeof(oal_buffer_float) / sizeof(oal_buffer_float[0]));
|
||||
|
||||
if (Emu.IsPaused())
|
||||
{
|
||||
@ -299,38 +339,45 @@ int cellAudioInit()
|
||||
// convert the data from float to u16 with clipping:
|
||||
if (!first_mix)
|
||||
{
|
||||
|
||||
#ifndef _M_X64
|
||||
for (u32 i = 0; i < (sizeof(buf2ch) / sizeof(float)); i++)
|
||||
{
|
||||
// Probably, use later?
|
||||
/*
|
||||
// for x86
|
||||
//oal_buffer[oal_pos][oal_buffer_offset + i] = (s16)(min<float>(max<float>(buf2ch[i] * 0x8000, -0x8000), 0x7fff));
|
||||
if (g_is_u16)
|
||||
oal_buffer[oal_pos][oal_buffer_offset + i] = (s16)(min<float>(max<float>(buf2ch[i] * 0x8000, -0x8000), 0x7fff));
|
||||
|
||||
oal_buffer_float[oal_pos_float][oal_buffer_offset + i] = buf2ch[i];
|
||||
}
|
||||
#else
|
||||
// 2x MULPS
|
||||
// 2x MAXPS (optional)
|
||||
// 2x MINPS (optional)
|
||||
// 2x CVTPS2DQ (converts float to s32)
|
||||
// PACKSSDW (converts s32 to s16 with clipping)
|
||||
|
||||
// for x64
|
||||
// 2x MULPS
|
||||
// 2x MAXPS (optional)
|
||||
// 2x MINPS (optional)
|
||||
// 2x CVTPS2DQ (converts float to s32)
|
||||
// PACKSSDW (converts s32 to s16 with clipping)
|
||||
if (g_is_u16)
|
||||
{
|
||||
for (u32 i = 0; i < (sizeof(buf2ch) / sizeof(float)); i += 8)
|
||||
{
|
||||
static const __m128 float2u16 = { 0x8000, 0x8000, 0x8000, 0x8000 };
|
||||
(__m128i&)(oal_buffer[oal_pos][oal_buffer_offset + i]) = _mm_packs_epi32(
|
||||
_mm_cvtps_epi32(_mm_mul_ps((__m128&)(buf2ch[i]), float2u16)),
|
||||
_mm_cvtps_epi32(_mm_mul_ps((__m128&)(buf2ch[i + 4]), float2u16)));
|
||||
}*/
|
||||
|
||||
oal_buffer[oal_pos][oal_buffer_offset + i] = buf2ch[i];
|
||||
}
|
||||
}
|
||||
|
||||
for (u32 i = 0; i < (sizeof(buf2ch) / sizeof(float)); i++)
|
||||
{
|
||||
oal_buffer_float[oal_pos_float][oal_buffer_offset + i] = buf2ch[i];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
const u64 stamp1 = get_system_time();
|
||||
|
||||
if (first_mix)
|
||||
{
|
||||
memset(&oal_buffer[oal_pos][0], 0, oal_buffer_size * sizeof(float));
|
||||
memset(&oal_buffer[oal_pos][0], 0, oal_buffer_size * sizeof(s16));
|
||||
memset(&oal_buffer_float[oal_pos_float][0], 0, oal_buffer_size * sizeof(float));
|
||||
}
|
||||
oal_buffer_offset += sizeof(buf2ch) / sizeof(float);
|
||||
|
||||
@ -338,7 +385,10 @@ int cellAudioInit()
|
||||
{
|
||||
if(m_audio_out)
|
||||
{
|
||||
queue.Push(&oal_buffer[oal_pos][0]);
|
||||
if (g_is_u16)
|
||||
queue.Push(&oal_buffer[oal_pos][0]);
|
||||
|
||||
queue_float.Push(&oal_buffer_float[oal_pos_float][0]);
|
||||
}
|
||||
|
||||
oal_buffer_offset = 0;
|
||||
@ -405,6 +455,7 @@ int cellAudioInit()
|
||||
ConLog.Write("Audio finished");
|
||||
abort:
|
||||
queue.Push(nullptr);
|
||||
queue_float.Push(nullptr);
|
||||
|
||||
if(do_dump)
|
||||
m_dump.Finalize();
|
||||
|
@ -372,9 +372,10 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event))
|
||||
wxCheckBox* chbox_gs_log_prog = new wxCheckBox(p_graphics, wxID_ANY, "Log vertex/fragment programs");
|
||||
wxCheckBox* chbox_gs_dump_depth = new wxCheckBox(p_graphics, wxID_ANY, "Write Depth Buffer");
|
||||
wxCheckBox* chbox_gs_dump_color = new wxCheckBox(p_graphics, wxID_ANY, "Write Color Buffers");
|
||||
wxCheckBox* chbox_skip_pamf = new wxCheckBox(p_graphics, wxID_ANY, "Skip Pamf");
|
||||
wxCheckBox* chbox_skip_pamf = new wxCheckBox(p_graphics, wxID_ANY, "Skip Pamf");
|
||||
wxCheckBox* chbox_gs_vsync = new wxCheckBox(p_graphics, wxID_ANY, "VSync");
|
||||
wxCheckBox* chbox_audio_dump = new wxCheckBox(p_audio, wxID_ANY, "Dump to file");
|
||||
wxCheckBox* chbox_audio_conv = new wxCheckBox(p_audio, wxID_ANY, "Convert to 16 bit");
|
||||
wxCheckBox* chbox_hle_logging = new wxCheckBox(p_hle, wxID_ANY, "Log all SysCalls");
|
||||
wxCheckBox* chbox_hle_hook_stfunc = new wxCheckBox(p_hle, wxID_ANY, "Hook static functions");
|
||||
wxCheckBox* chbox_hle_savetty = new wxCheckBox(p_hle, wxID_ANY, "Save TTY output to file");
|
||||
@ -452,6 +453,7 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event))
|
||||
chbox_skip_pamf ->SetValue(Ini.SkipPamf.GetValue());
|
||||
chbox_gs_vsync ->SetValue(Ini.GSVSyncEnable.GetValue());
|
||||
chbox_audio_dump ->SetValue(Ini.AudioDumpToFile.GetValue());
|
||||
chbox_audio_conv ->SetValue(Ini.AudioConvertToU16.GetValue());
|
||||
chbox_hle_logging ->SetValue(Ini.HLELogging.GetValue());
|
||||
chbox_hle_hook_stfunc ->SetValue(Ini.HLEHookStFunc.GetValue());
|
||||
chbox_hle_savetty ->SetValue(Ini.HLESaveTTY.GetValue());
|
||||
@ -473,6 +475,7 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event))
|
||||
|
||||
// Enable / Disable parameters
|
||||
chbox_audio_dump->Enable(Emu.IsStopped());
|
||||
chbox_audio_conv->Enable(Emu.IsStopped());
|
||||
chbox_hle_logging->Enable(Emu.IsStopped());
|
||||
chbox_hle_hook_stfunc->Enable(Emu.IsStopped());
|
||||
|
||||
@ -517,6 +520,7 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event))
|
||||
// Audio
|
||||
s_subpanel_audio->Add(s_round_audio_out, wxSizerFlags().Border(wxALL, 5).Expand());
|
||||
s_subpanel_audio->Add(chbox_audio_dump, wxSizerFlags().Border(wxALL, 5).Expand());
|
||||
s_subpanel_audio->Add(chbox_audio_conv, wxSizerFlags().Border(wxALL, 5).Expand());
|
||||
|
||||
// HLE / Misc.
|
||||
s_subpanel_hle->Add(s_round_hle_log_lvl, wxSizerFlags().Border(wxALL, 5).Expand());
|
||||
@ -563,6 +567,7 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event))
|
||||
Ini.MouseHandlerMode.SetValue(cbox_mouse_handler->GetSelection());
|
||||
Ini.AudioOutMode.SetValue(cbox_audio_out->GetSelection());
|
||||
Ini.AudioDumpToFile.SetValue(chbox_audio_dump->GetValue());
|
||||
Ini.AudioConvertToU16.SetValue(chbox_audio_conv->GetValue());
|
||||
Ini.HLELogging.SetValue(chbox_hle_logging->GetValue());
|
||||
Ini.HLEHookStFunc.SetValue(chbox_hle_hook_stfunc->GetValue());
|
||||
Ini.HLESaveTTY.SetValue(chbox_hle_savetty->GetValue());
|
||||
|
@ -111,6 +111,7 @@ public:
|
||||
IniEntry<u8> MouseHandlerMode;
|
||||
IniEntry<u8> AudioOutMode;
|
||||
IniEntry<bool> AudioDumpToFile;
|
||||
IniEntry<bool> AudioConvertToU16;
|
||||
IniEntry<bool> HLELogging;
|
||||
IniEntry<bool> HLEHookStFunc;
|
||||
IniEntry<bool> HLESaveTTY;
|
||||
@ -200,6 +201,7 @@ public:
|
||||
path = DefPath + "/" + "Audio";
|
||||
AudioOutMode.Init("AudioOutMode", path);
|
||||
AudioDumpToFile.Init("AudioDumpToFile", path);
|
||||
AudioConvertToU16.Init("AudioConvertToU16", path);
|
||||
|
||||
path = DefPath + "/" + "HLE";
|
||||
HLELogging.Init("HLELogging", path);
|
||||
@ -230,7 +232,8 @@ public:
|
||||
KeyboardHandlerMode.Load(0);
|
||||
MouseHandlerMode.Load(0);
|
||||
AudioOutMode.Load(1);
|
||||
AudioDumpToFile.Load(0);
|
||||
AudioDumpToFile.Load(false);
|
||||
AudioConvertToU16.Load(false);
|
||||
HLELogging.Load(false);
|
||||
HLEHookStFunc.Load(false);
|
||||
HLESaveTTY.Load(false);
|
||||
@ -283,6 +286,7 @@ public:
|
||||
MouseHandlerMode.Save();
|
||||
AudioOutMode.Save();
|
||||
AudioDumpToFile.Save();
|
||||
AudioConvertToU16.Save();
|
||||
HLELogging.Save();
|
||||
HLEHookStFunc.Save();
|
||||
HLESaveTTY.Save();
|
||||
|
Loading…
x
Reference in New Issue
Block a user