Skip to content

Commit

Permalink
Improved OpenAL audio output
Browse files Browse the repository at this point in the history
Implemented LDBRX PPU instruction
Enabled FRSQRTE PPU instruction
Improved Fragment Program Decompiler
Implemented Log lvl selection
  • Loading branch information
DHrpcs3 committed Mar 13, 2014
1 parent 80cfb2e commit 0e43731
Show file tree
Hide file tree
Showing 16 changed files with 167 additions and 138 deletions.
136 changes: 70 additions & 66 deletions rpcs3/Emu/Audio/AL/OpenALThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
ALenum g_last_al_error = AL_NO_ERROR;
ALCenum g_last_alc_error = ALC_NO_ERROR;

ALCdevice* pDevice;
ALCcontext* pContext;
#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)

void printAlError(ALenum err, const char* situation)
{
Expand All @@ -25,120 +25,124 @@ void printAlcError(ALCenum err, const char* situation)
}
}

OpenALThread::~OpenALThread()
{
Quit();
}

void OpenALThread::Init()
{
pDevice = alcOpenDevice(NULL);
m_device = alcOpenDevice(nullptr);
checkForAlcError("alcOpenDevice");

pContext = alcCreateContext(pDevice, NULL);
m_context = alcCreateContext(m_device, nullptr);
checkForAlcError("alcCreateContext");

alcMakeContextCurrent(pContext);
alcMakeContextCurrent(m_context);
checkForAlcError("alcMakeContextCurrent");
}

void OpenALThread::Quit()
{
for (SampleBuffer::iterator i = mBuffers.begin(); i != mBuffers.end(); i++)
alDeleteBuffers(1, &i->second.mBufferID);

alcMakeContextCurrent(NULL);
alcDestroyContext(pContext);
alcCloseDevice(pDevice);
alcMakeContextCurrent(nullptr);
alcDestroyContext(m_context);
alcCloseDevice(m_device);
}

void OpenALThread::Play()
{
alSourcePlay(mSource);
checkForAlError("alSourcePlay");
ALint state;
alGetSourcei(m_source, AL_SOURCE_STATE, &state);
checkForAlError("alGetSourcei");

if(state != AL_PLAYING)
{
alSourcePlay(m_source);
checkForAlError("alSourcePlay");
}
}

void OpenALThread::Close()
{
alSourceStop(mSource);
alSourceStop(m_source);
checkForAlError("alSourceStop");
if (alIsSource(mSource))
alDeleteSources(1, &mSource);
if (alIsSource(m_source))
alDeleteSources(1, &m_source);

alDeleteBuffers(g_al_buffers_count, m_buffers);
checkForAlError("alDeleteBuffers");
}

void OpenALThread::Stop()
{
alSourceStop(mSource);
alSourceStop(m_source);
checkForAlError("alSourceStop");
}

void OpenALThread::Open(const void* src, ALsizei size)
{
alGenSources(1, &mSource);
alGenSources(1, &m_source);
checkForAlError("alGenSources");

alSourcei(mSource, AL_LOOPING, AL_FALSE);
alGenBuffers(g_al_buffers_count, m_buffers);
checkForAlError("alGenBuffers");

alSourcei(m_source, AL_LOOPING, AL_FALSE);
checkForAlError("alSourcei");

mProcessed = 0;
mBuffer.mFreq = 48000;
mBuffer.mFormat = AL_FORMAT_STEREO16;
m_buffer_size = size;

for (int i = 0; i < NUM_OF_BUFFERS; i++)
for(uint i=0; i<g_al_buffers_count; ++i)
{
AddData(src, size);
AddBlock(m_buffers[i], m_buffer_size, src);
}

alSourceQueueBuffers(m_source, g_al_buffers_count, m_buffers);
checkForAlError("alSourceQueueBuffers");
Play();
}

void OpenALThread::AddData(const void* src, ALsizei size)
{
alGenBuffers(1, &mBuffer.mBufferID);
checkForAlError("alGenBuffers");

mBuffers[mBuffer.mBufferID] = mBuffer;

AddBlock(mBuffer.mBufferID, size, src);

alSourceQueueBuffers(mSource, 1, &mBuffer.mBufferID);
checkForAlError("alSourceQueueBuffers");
const char* bsrc = (const char*)src;
ALuint buffer;
ALint buffers_count;
alGetSourcei(m_source, AL_BUFFERS_PROCESSED, &buffers_count);
checkForAlError("alGetSourcei");

alGetSourcei(mSource, AL_BUFFERS_PROCESSED, &mProcessed);

while (mProcessed--)
while(size)
{
alSourceUnqueueBuffers(mSource, 1, &mBuffer.mBufferID);
if(buffers_count-- <= 0)
{
Play();

alGetSourcei(m_source, AL_BUFFERS_PROCESSED, &buffers_count);
checkForAlError("alGetSourcei");
continue;
}

alSourceUnqueueBuffers(m_source, 1, &buffer);
checkForAlError("alSourceUnqueueBuffers");

alDeleteBuffers(1, &mBuffer.mBufferID);
checkForAlError("alDeleteBuffers");
int bsize = size < m_buffer_size ? size : m_buffer_size;
AddBlock(buffer, bsize, bsrc);

alSourceQueueBuffers(m_source, 1, &buffer);
checkForAlError("alSourceQueueBuffers");

size -= bsize;
bsrc += bsize;
}

Play();
}

bool OpenALThread::AddBlock(ALuint bufferID, ALsizei size, const void* src)
bool OpenALThread::AddBlock(const ALuint buffer_id, ALsizei size, const void* src)
{
memset(&mTempBuffer, 0, sizeof(mTempBuffer));
memcpy(mTempBuffer, src, size);

long TotalRet = 0, ret;

if (size < 1) return false;

while (TotalRet < size)
{
ret = size;

// if buffer is empty
if (ret == 0) break;
else if (ret < 0)
{
ConLog.Error("Error in bitstream!");
}
else
{
TotalRet += ret;
}
}
if (TotalRet > 0)
{
alBufferData(bufferID, mBuffers[bufferID].mFormat, mTempBuffer,
TotalRet, mBuffers[bufferID].mFreq);
alBufferData(buffer_id, AL_FORMAT_STEREO16, src, size, 48000);
checkForAlError("alBufferData");
}

return (ret > 0);
return true;
}
41 changes: 10 additions & 31 deletions rpcs3/Emu/Audio/AL/OpenALThread.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,49 +2,28 @@

#include "OpenAL/include/al.h"
#include "OpenAL/include/alc.h"
#include <map>

extern ALenum g_last_al_error;
extern ALCenum g_last_alc_error;

void printAlError(ALenum err, const char* situation);
void printAlcError(ALCenum err, const char* situation);

#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(pDevice)) != ALC_NO_ERROR) printAlcError(g_last_alc_error, sit)

struct SampleInfo
{
uint mBufferID;
uint mFreq;
uint mFormat;
};

typedef std::map<ALuint, SampleInfo> SampleBuffer;

#define NUM_OF_BUFFERS 16


extern ALCdevice* pDevice;
extern ALCcontext* pContext;

class OpenALThread
{
private:
ALuint mSource;
SampleBuffer mBuffers;
SampleInfo mBuffer;
ALint mProcessed;
u16 mTempBuffer[512];
static const uint g_al_buffers_count = 16;

ALuint m_source;
ALuint m_buffers[g_al_buffers_count];
ALCdevice* m_device;
ALCcontext* m_context;
u32 m_buffer_size;

public:
~OpenALThread();

void Init();
void Quit();
void Play();
void Open(const void* src, ALsizei size);
void Close();
void Stop();
bool AddBlock(ALuint bufferID, ALsizei size, const void* src);
bool AddBlock(const ALuint buffer_id, ALsizei size, const void* src);
void AddData(const void* src, ALsizei size);
};

4 changes: 4 additions & 0 deletions rpcs3/Emu/Cell/PPUDisAsm.h
Original file line number Diff line number Diff line change
Expand Up @@ -1606,6 +1606,10 @@ class PPUDisAsm
{
DisAsm_V1_R2("lvlx", vd, ra, rb);
}
void LDBRX(u32 rd, u32 ra, u32 rb)
{
DisAsm_R3("ldbrx", rd, ra, rb);
}
void LWBRX(u32 rd, u32 ra, u32 rb)
{
DisAsm_R3("lwbrx", rd, ra, rb);
Expand Down
1 change: 1 addition & 0 deletions rpcs3/Emu/Cell/PPUInstrTable.h
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,7 @@ namespace PPU_instr
/*0x1e9*/bind_instr(g1f_list, DIVD, RD, RA, RB, OE, RC);
/*0x1eb*/bind_instr(g1f_list, DIVW, RD, RA, RB, OE, RC);
/*0x207*/bind_instr(g1f_list, LVLX, VD, RA, RB);
/*0x214*/bind_instr(g1f_list, LDBRX, RD, RA, RB);
/*0x216*/bind_instr(g1f_list, LWBRX, RD, RA, RB);
/*0x217*/bind_instr(g1f_list, LFSX, FRD, RA, RB);
/*0x218*/bind_instr(g1f_list, SRW, RA, RS, RB, RC);
Expand Down
7 changes: 5 additions & 2 deletions rpcs3/Emu/Cell/PPUInterpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -2981,6 +2981,10 @@ class PPUInterpreter : public PPUOpcodes

Memory.ReadLeft(CPU.VPR[vd]._u8 + eb, addr, 16 - eb);
}
void LDBRX(u32 rd, u32 ra, u32 rb)
{
CPU.GPR[rd] = (u64&)Memory[ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]];
}
void LWBRX(u32 rd, u32 ra, u32 rb)
{
CPU.GPR[rd] = (u32&)Memory[ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]];
Expand Down Expand Up @@ -3758,8 +3762,7 @@ class PPUInterpreter : public PPUOpcodes
}
void FRSQRTE(u32 frd, u32 frb, bool rc)
{
UNIMPLEMENTED();
//CPU.FPR[frd] = 1.0f / (float)sqrt(CPU.FPR[frb]);
CPU.FPR[frd] = 1.0f / (float)sqrt(CPU.FPR[frb]);
}
void FMSUB(u32 frd, u32 fra, u32 frc, u32 frb, bool rc)
{
Expand Down
2 changes: 2 additions & 0 deletions rpcs3/Emu/Cell/PPUOpcodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,7 @@ namespace PPU_opcodes
DIVD = 0x1e9,
DIVW = 0x1eb,
LVLX = 0x207, //Load Vector Left Indexed
LDBRX = 0x214,
LWBRX = 0x216,
LFSX = 0x217,
SRW = 0x218,
Expand Down Expand Up @@ -729,6 +730,7 @@ class PPUOpcodes
virtual void DIVD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) = 0;
virtual void DIVW(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) = 0;
virtual void LVLX(u32 vd, u32 ra, u32 rb) = 0;
virtual void LDBRX(u32 rd, u32 ra, u32 rb) = 0;
virtual void LWBRX(u32 rd, u32 ra, u32 rb) = 0;
virtual void LFSX(u32 frd, u32 ra, u32 rb) = 0;
virtual void SRW(u32 ra, u32 rs, u32 rb, bool rc) = 0;
Expand Down
4 changes: 2 additions & 2 deletions rpcs3/Emu/GS/GL/GLFragmentProgram.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ void GLFragmentDecompilerThread::AddCode(std::string code, bool append_mask)
{
if(!src0.exec_if_eq && !src0.exec_if_gr && !src0.exec_if_lt) return;

const std::string mask = GetMask().c_str();
const std::string mask = GetMask();
std::string cond;

if(!src0.exec_if_gr || !src0.exec_if_lt || !src0.exec_if_eq)
Expand Down Expand Up @@ -227,7 +227,7 @@ std::string GLFragmentDecompilerThread::BuildCode()
main += "\t" + m_parr.AddParam(PARAM_OUT, "vec4", "ocol", 0) + " = " + (m_ctrl & 0x40 ? "r0" : "h0") + ";\n";
if(m_ctrl & 0xe) main += "\tgl_FragDepth = r1.z;\n";

std::string p = "";
std::string p;

for(u32 i=0; i<m_parr.params.GetCount(); ++i)
{
Expand Down
16 changes: 11 additions & 5 deletions rpcs3/Emu/GS/GL/GLVertexProgram.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,8 @@ wxString GLVertexDecompilerThread::BuildCode()

wxString f = wxEmptyString;

f += wxString::Format("void %s()\n{\n\tgl_Position = vec4(0.0f, 0.0f, 0.0f, 1.0f);\n%s\tgl_Position = gl_Position * scaleOffsetMat;\n}\n", m_funcs[0].name.wx_str(), BuildFuncBody(m_funcs[0]).wx_str());
f += wxString::Format("void %s()\n{\n\tgl_Position = vec4(0.0f, 0.0f, 0.0f, 1.0f);\n\t%s();\n\tgl_Position = gl_Position * scaleOffsetMat;\n}\n",
m_funcs[0].name.wx_str(), m_funcs[1].name.wx_str());

for(uint i=1; i<m_funcs.GetCount(); ++i)
{
Expand Down Expand Up @@ -354,6 +355,11 @@ void GLVertexDecompilerThread::Task()
src[2].src2l = d3.src2l;
src[2].src2h = d2.src2h;

if(!d1.sca_opcode && !d1.vec_opcode)
{
m_body.Add("//nop");
}

switch(d1.sca_opcode)
{
case 0x00: break; // NOP
Expand All @@ -364,11 +370,11 @@ void GLVertexDecompilerThread::Task()
case 0x05: AddScaCode("exp(" + GetSRC(2, true) + ")"); break; // EXP
case 0x06: AddScaCode("log(" + GetSRC(2, true) + ")"); break; // LOG
//case 0x07: break; // LIT
case 0x08: AddScaCode("{ /*BRA*/ " + GetFunc() + "; " + wxString(m_funcs.GetCount() == 1 || m_funcs[1].offset > intsCount ? "gl_Position = gl_Position * scaleOffsetMat;" : "") + " return; }", false, true); break; // BRA
case 0x09: AddScaCode("{ " + GetFunc() + "; " + wxString(m_funcs.GetCount() == 1 || m_funcs[1].offset > intsCount ? "gl_Position = gl_Position * scaleOffsetMat;" : "") + " return; }", false, true); break; // BRI : works differently (BRI o[1].x(TR) L0;)
case 0x08: AddScaCode("{ /*BRA*/ " + GetFunc() + "; return; }", false, true); break; // BRA
case 0x09: AddScaCode("{ " + GetFunc() + "; return; }", false, true); break; // BRI : works differently (BRI o[1].x(TR) L0;)
case 0x0a: AddScaCode("/*CAL*/ " + GetFunc(), false, true); break; // CAL : works same as BRI
case 0x0b: AddScaCode("/*CLI*/ " + GetFunc(), false, true); break; // CLI : works same as BRI
case 0x0c: AddScaCode("{ " + wxString(m_funcs.GetCount() == 1 || m_funcs[1].offset > intsCount ? "gl_Position = gl_Position * scaleOffsetMat;" : "") + "return; }", false, true); break; // RET : works like BRI but shorter (RET o[1].x(TR);)
case 0x0c: AddScaCode("return", false, true); break; // RET : works like BRI but shorter (RET o[1].x(TR);)
case 0x0d: AddScaCode("log2(" + GetSRC(2, true) + ")"); break; // LG2
case 0x0e: AddScaCode("exp2(" + GetSRC(2, true) + ")"); break; // EX2
case 0x0f: AddScaCode("sin(" + GetSRC(2, true) + ")"); break; // SIN
Expand Down Expand Up @@ -429,7 +435,7 @@ void GLVertexDecompilerThread::Task()
m_shader = BuildCode();

m_body.Clear();
m_funcs.RemoveAt(1, m_funcs.GetCount() - 1);
m_funcs.RemoveAt(2, m_funcs.GetCount() - 2);
}

GLVertexProgram::GLVertexProgram()
Expand Down
3 changes: 3 additions & 0 deletions rpcs3/Emu/GS/GL/GLVertexProgram.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,9 @@ struct GLVertexDecompilerThread : public ThreadBase
m_funcs.Add(new FuncInfo());
m_funcs[0].offset = 0;
m_funcs[0].name = "main";
m_funcs.Add(new FuncInfo());
m_funcs[1].offset = 0;
m_funcs[1].name = "func0";
//m_cur_func->body = "\tgl_Position = vec4(0.0f, 0.0f, 0.0f, 1.0f);\n";
}

Expand Down
2 changes: 0 additions & 2 deletions rpcs3/Emu/SysCalls/Modules/cellAdec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,6 @@ u32 adecOpen(AudioDecoder* data)

case adecDecodeAu:
{
int err;

adec.reader.addr = task.au.addr;
adec.reader.size = task.au.size;

Expand Down
Loading

0 comments on commit 0e43731

Please sign in to comment.