mirror of
https://github.com/RPCSX/rpcsx.git
synced 2025-12-06 07:12:14 +01:00
144 lines
2.8 KiB
C++
144 lines
2.8 KiB
C++
#include "stdafx.h"
|
|
#include "OpenALThread.h"
|
|
|
|
ALenum g_last_al_error = AL_NO_ERROR;
|
|
ALCenum g_last_alc_error = ALC_NO_ERROR;
|
|
|
|
ALCdevice* pDevice;
|
|
ALCcontext* pContext;
|
|
|
|
void printAlError(ALenum err, const char* situation)
|
|
{
|
|
if(err != AL_NO_ERROR)
|
|
{
|
|
ConLog.Error("%s: OpenAL error 0x%04x", wxString(situation).wx_str(), err);
|
|
Emu.Pause();
|
|
}
|
|
}
|
|
|
|
void printAlcError(ALCenum err, const char* situation)
|
|
{
|
|
if(err != ALC_NO_ERROR)
|
|
{
|
|
ConLog.Error("%s: OpenALC error 0x%04x", wxString(situation).wx_str(), err);
|
|
Emu.Pause();
|
|
}
|
|
}
|
|
|
|
void OpenALThread::Init()
|
|
{
|
|
pDevice = alcOpenDevice(NULL);
|
|
checkForAlcError("alcOpenDevice");
|
|
|
|
pContext = alcCreateContext(pDevice, NULL);
|
|
checkForAlcError("alcCreateContext");
|
|
|
|
alcMakeContextCurrent(pContext);
|
|
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);
|
|
}
|
|
|
|
void OpenALThread::Play()
|
|
{
|
|
alSourcePlay(mSource);
|
|
checkForAlError("alSourcePlay");
|
|
}
|
|
|
|
void OpenALThread::Close()
|
|
{
|
|
alSourceStop(mSource);
|
|
checkForAlError("alSourceStop");
|
|
if (alIsSource(mSource))
|
|
alDeleteSources(1, &mSource);
|
|
}
|
|
|
|
void OpenALThread::Stop()
|
|
{
|
|
alSourceStop(mSource);
|
|
checkForAlError("alSourceStop");
|
|
}
|
|
|
|
void OpenALThread::Open(const void* src, ALsizei size)
|
|
{
|
|
alGenSources(1, &mSource);
|
|
checkForAlError("alGenSources");
|
|
|
|
alSourcei(mSource, AL_LOOPING, AL_FALSE);
|
|
checkForAlError("alSourcei");
|
|
|
|
mProcessed = 0;
|
|
mBuffer.mFreq = 48000;
|
|
mBuffer.mFormat = AL_FORMAT_STEREO16;
|
|
|
|
for (int i = 0; i < NUM_OF_BUFFERS; i++)
|
|
{
|
|
AddData(src, size);
|
|
}
|
|
}
|
|
|
|
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");
|
|
|
|
alGetSourcei(mSource, AL_BUFFERS_PROCESSED, &mProcessed);
|
|
|
|
while (mProcessed--)
|
|
{
|
|
alSourceUnqueueBuffers(mSource, 1, &mBuffer.mBufferID);
|
|
checkForAlError("alSourceUnqueueBuffers");
|
|
|
|
alDeleteBuffers(1, &mBuffer.mBufferID);
|
|
checkForAlError("alDeleteBuffers");
|
|
}
|
|
}
|
|
|
|
bool OpenALThread::AddBlock(ALuint bufferID, 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);
|
|
checkForAlError("alBufferData");
|
|
}
|
|
|
|
return (ret > 0);
|
|
} |