mirror of
https://github.com/GTAmodding/re3.git
synced 2024-11-16 02:29:00 +00:00
Handle stereo panning in OAL manually for streams
This commit is contained in:
parent
601f77b5c8
commit
7adac51152
3 changed files with 195 additions and 70 deletions
|
@ -19,6 +19,64 @@
|
||||||
#include "crossplatform.h"
|
#include "crossplatform.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
As we ran onto an issue of having different volume levels for mono streams
|
||||||
|
and stereo streams we are now handling all the stereo panning ourselves.
|
||||||
|
Each stream now has two sources - one panned to the left and one to the right,
|
||||||
|
and uses two separate buffers to store data for each individual channel.
|
||||||
|
For that we also have to reshuffle all decoded PCM stereo data from LRLRLRLR to
|
||||||
|
LLLLRRRR (handled by CSortStereoBuffer).
|
||||||
|
*/
|
||||||
|
|
||||||
|
class CSortStereoBuffer
|
||||||
|
{
|
||||||
|
uint16* PcmBuf;
|
||||||
|
size_t BufSize;
|
||||||
|
public:
|
||||||
|
CSortStereoBuffer() : PcmBuf(nil), BufSize(0) {}
|
||||||
|
~CSortStereoBuffer()
|
||||||
|
{
|
||||||
|
if (PcmBuf)
|
||||||
|
free(PcmBuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16* GetBuffer(size_t size)
|
||||||
|
{
|
||||||
|
if (size == 0) return nil;
|
||||||
|
if (!PcmBuf)
|
||||||
|
{
|
||||||
|
BufSize = size;
|
||||||
|
PcmBuf = (uint16*)malloc(BufSize);
|
||||||
|
}
|
||||||
|
else if (BufSize < size)
|
||||||
|
{
|
||||||
|
BufSize = size;
|
||||||
|
PcmBuf = (uint16*)realloc(PcmBuf, size);
|
||||||
|
}
|
||||||
|
return PcmBuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SortStereo(void* buf, size_t size)
|
||||||
|
{
|
||||||
|
uint16* InBuf = (uint16*)buf;
|
||||||
|
uint16* OutBuf = GetBuffer(size);
|
||||||
|
|
||||||
|
if (!OutBuf) return;
|
||||||
|
|
||||||
|
size_t rightStart = size / 4;
|
||||||
|
for (size_t i = 0; i < size / 4; i++)
|
||||||
|
{
|
||||||
|
OutBuf[i] = InBuf[i*2];
|
||||||
|
OutBuf[i+rightStart] = InBuf[i*2+1];
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(InBuf, OutBuf, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
CSortStereoBuffer SortStereoBuffer;
|
||||||
|
|
||||||
#ifndef AUDIO_OPUS
|
#ifndef AUDIO_OPUS
|
||||||
class CSndFile : public IDecoder
|
class CSndFile : public IDecoder
|
||||||
{
|
{
|
||||||
|
@ -81,7 +139,11 @@ public:
|
||||||
uint32 Decode(void *buffer)
|
uint32 Decode(void *buffer)
|
||||||
{
|
{
|
||||||
if ( !IsOpened() ) return 0;
|
if ( !IsOpened() ) return 0;
|
||||||
return sf_read_short(m_pfSound, (short *)buffer, GetBufferSamples()) * GetSampleSize();
|
|
||||||
|
size_t size = sf_read_short(m_pfSound, (short*)buffer, GetBufferSamples()) * GetSampleSize();
|
||||||
|
if (GetChannels()==2)
|
||||||
|
SortStereoBuffer.SortStereo(buffer, size);
|
||||||
|
return size;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -108,6 +170,8 @@ public:
|
||||||
m_pMH = mpg123_new(nil, nil);
|
m_pMH = mpg123_new(nil, nil);
|
||||||
if ( m_pMH )
|
if ( m_pMH )
|
||||||
{
|
{
|
||||||
|
mpg123_param(m_pMH, MPG123_FLAGS, MPG123_FUZZY | MPG123_SEEKBUFFER | MPG123_GAPLESS, 0.0);
|
||||||
|
|
||||||
long rate = 0;
|
long rate = 0;
|
||||||
int channels = 0;
|
int channels = 0;
|
||||||
int encoding = 0;
|
int encoding = 0;
|
||||||
|
@ -183,6 +247,8 @@ public:
|
||||||
assert("We can't handle audio files more then 2 GB yet :shrug:" && (size < UINT32_MAX));
|
assert("We can't handle audio files more then 2 GB yet :shrug:" && (size < UINT32_MAX));
|
||||||
#endif
|
#endif
|
||||||
if (err != MPG123_OK && err != MPG123_DONE) return 0;
|
if (err != MPG123_OK && err != MPG123_DONE) return 0;
|
||||||
|
if (GetChannels() == 2)
|
||||||
|
SortStereoBuffer.SortStereo(buffer, size);
|
||||||
return (uint32)size;
|
return (uint32)size;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -274,6 +340,9 @@ public:
|
||||||
if (size < 0)
|
if (size < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (GetChannels() == 2)
|
||||||
|
SortStereoBuffer.SortStereo(buffer, size * m_nChannels * GetSampleSize());
|
||||||
|
|
||||||
return size * m_nChannels * GetSampleSize();
|
return size * m_nChannels * GetSampleSize();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -285,7 +354,7 @@ class CADFFile : public CMP3File
|
||||||
{
|
{
|
||||||
size_t bytesRead = fread(buf, 1, size, (FILE*)fh);
|
size_t bytesRead = fread(buf, 1, size, (FILE*)fh);
|
||||||
uint8* _buf = (uint8*)buf;
|
uint8* _buf = (uint8*)buf;
|
||||||
for (int i = 0; i < size; i++)
|
for (size_t i = 0; i < size; i++)
|
||||||
_buf[i] ^= 0x22;
|
_buf[i] ^= 0x22;
|
||||||
return bytesRead;
|
return bytesRead;
|
||||||
}
|
}
|
||||||
|
@ -304,6 +373,7 @@ public:
|
||||||
m_pMH = mpg123_new(nil, nil);
|
m_pMH = mpg123_new(nil, nil);
|
||||||
if (m_pMH)
|
if (m_pMH)
|
||||||
{
|
{
|
||||||
|
mpg123_param(m_pMH, MPG123_FLAGS, MPG123_FUZZY | MPG123_SEEKBUFFER | MPG123_GAPLESS, 0.0);
|
||||||
long rate = 0;
|
long rate = 0;
|
||||||
int channels = 0;
|
int channels = 0;
|
||||||
int encoding = 0;
|
int encoding = 0;
|
||||||
|
@ -338,8 +408,8 @@ void CStream::Terminate()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
CStream::CStream(char *filename, ALuint &source, ALuint (&buffers)[NUM_STREAMBUFFERS]) :
|
CStream::CStream(char *filename, ALuint *sources, ALuint (&buffers)[NUM_STREAMBUFFERS]) :
|
||||||
m_alSource(source),
|
m_pAlSources(sources),
|
||||||
m_alBuffers(buffers),
|
m_alBuffers(buffers),
|
||||||
m_pBuffer(nil),
|
m_pBuffer(nil),
|
||||||
m_bPaused(false),
|
m_bPaused(false),
|
||||||
|
@ -422,7 +492,7 @@ void CStream::Delete()
|
||||||
|
|
||||||
bool CStream::HasSource()
|
bool CStream::HasSource()
|
||||||
{
|
{
|
||||||
return m_alSource != AL_NONE;
|
return (m_pAlSources[0] != AL_NONE) && (m_pAlSources[1] != AL_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CStream::IsOpened()
|
bool CStream::IsOpened()
|
||||||
|
@ -436,9 +506,10 @@ bool CStream::IsPlaying()
|
||||||
|
|
||||||
if ( !m_bPaused )
|
if ( !m_bPaused )
|
||||||
{
|
{
|
||||||
ALint sourceState;
|
ALint sourceState[2];
|
||||||
alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState);
|
alGetSourcei(m_pAlSources[0], AL_SOURCE_STATE, &sourceState[0]);
|
||||||
if ( m_bActive || sourceState == AL_PLAYING )
|
alGetSourcei(m_pAlSources[1], AL_SOURCE_STATE, &sourceState[1]);
|
||||||
|
if ( m_bActive || sourceState[0] == AL_PLAYING || sourceState[1] == AL_PLAYING)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -449,9 +520,12 @@ void CStream::Pause()
|
||||||
{
|
{
|
||||||
if ( !HasSource() ) return;
|
if ( !HasSource() ) return;
|
||||||
ALint sourceState = AL_PAUSED;
|
ALint sourceState = AL_PAUSED;
|
||||||
alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState);
|
alGetSourcei(m_pAlSources[0], AL_SOURCE_STATE, &sourceState);
|
||||||
if (sourceState != AL_PAUSED )
|
if (sourceState != AL_PAUSED )
|
||||||
alSourcePause(m_alSource);
|
alSourcePause(m_pAlSources[0]);
|
||||||
|
alGetSourcei(m_pAlSources[1], AL_SOURCE_STATE, &sourceState);
|
||||||
|
if (sourceState != AL_PAUSED)
|
||||||
|
alSourcePause(m_pAlSources[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CStream::SetPause(bool bPause)
|
void CStream::SetPause(bool bPause)
|
||||||
|
@ -473,19 +547,21 @@ void CStream::SetPause(bool bPause)
|
||||||
void CStream::SetPitch(float pitch)
|
void CStream::SetPitch(float pitch)
|
||||||
{
|
{
|
||||||
if ( !HasSource() ) return;
|
if ( !HasSource() ) return;
|
||||||
alSourcef(m_alSource, AL_PITCH, pitch);
|
alSourcef(m_pAlSources[0], AL_PITCH, pitch);
|
||||||
|
alSourcef(m_pAlSources[1], AL_PITCH, pitch);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CStream::SetGain(float gain)
|
void CStream::SetGain(float gain)
|
||||||
{
|
{
|
||||||
if ( !HasSource() ) return;
|
if ( !HasSource() ) return;
|
||||||
alSourcef(m_alSource, AL_GAIN, gain);
|
alSourcef(m_pAlSources[0], AL_GAIN, gain);
|
||||||
|
alSourcef(m_pAlSources[1], AL_GAIN, gain);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CStream::SetPosition(float x, float y, float z)
|
void CStream::SetPosition(int i, float x, float y, float z)
|
||||||
{
|
{
|
||||||
if ( !HasSource() ) return;
|
if ( !HasSource() ) return;
|
||||||
alSource3f(m_alSource, AL_POSITION, x, y, z);
|
alSource3f(m_pAlSources[i], AL_POSITION, x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CStream::SetVolume(uint32 nVol)
|
void CStream::SetVolume(uint32 nVol)
|
||||||
|
@ -496,8 +572,13 @@ void CStream::SetVolume(uint32 nVol)
|
||||||
|
|
||||||
void CStream::SetPan(uint8 nPan)
|
void CStream::SetPan(uint8 nPan)
|
||||||
{
|
{
|
||||||
|
m_nPan = clamp((int8)nPan - 63, 0, 63);
|
||||||
|
SetPosition(0, (m_nPan - 63) / 64.0f, 0.0f, Sqrt(1.0f - SQR((m_nPan - 63) / 64.0f)));
|
||||||
|
|
||||||
|
m_nPan = clamp((int8)nPan + 64, 64, 127);
|
||||||
|
SetPosition(1, (m_nPan - 63) / 64.0f, 0.0f, Sqrt(1.0f - SQR((m_nPan - 63) / 64.0f)));
|
||||||
|
|
||||||
m_nPan = nPan;
|
m_nPan = nPan;
|
||||||
SetPosition((nPan - 63)/64.0f, 0.0f, Sqrt(1.0f-SQR((nPan-63)/64.0f)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CStream::SetPosMS(uint32 nPos)
|
void CStream::SetPosMS(uint32 nPos)
|
||||||
|
@ -514,10 +595,10 @@ uint32 CStream::GetPosMS()
|
||||||
|
|
||||||
ALint offset;
|
ALint offset;
|
||||||
//alGetSourcei(m_alSource, AL_SAMPLE_OFFSET, &offset);
|
//alGetSourcei(m_alSource, AL_SAMPLE_OFFSET, &offset);
|
||||||
alGetSourcei(m_alSource, AL_BYTE_OFFSET, &offset);
|
alGetSourcei(m_pAlSources[0], AL_BYTE_OFFSET, &offset);
|
||||||
|
|
||||||
return m_pSoundFile->Tell()
|
return m_pSoundFile->Tell()
|
||||||
- m_pSoundFile->samples2ms(m_pSoundFile->GetBufferSamples() * (NUM_STREAMBUFFERS-1)) / m_pSoundFile->GetChannels()
|
- m_pSoundFile->samples2ms(m_pSoundFile->GetBufferSamples() * (NUM_STREAMBUFFERS/2-1)) / m_pSoundFile->GetChannels()
|
||||||
+ m_pSoundFile->samples2ms(offset/m_pSoundFile->GetSampleSize()) / m_pSoundFile->GetChannels();
|
+ m_pSoundFile->samples2ms(offset/m_pSoundFile->GetSampleSize()) / m_pSoundFile->GetChannels();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -527,33 +608,41 @@ uint32 CStream::GetLengthMS()
|
||||||
return m_pSoundFile->GetLength();
|
return m_pSoundFile->GetLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CStream::FillBuffer(ALuint alBuffer)
|
bool CStream::FillBuffer(ALuint *alBuffer)
|
||||||
{
|
{
|
||||||
if ( !HasSource() )
|
if ( !HasSource() )
|
||||||
return false;
|
return false;
|
||||||
if ( !IsOpened() )
|
if ( !IsOpened() )
|
||||||
return false;
|
return false;
|
||||||
if ( !(alBuffer != AL_NONE && alIsBuffer(alBuffer)) )
|
if ( !(alBuffer[0] != AL_NONE && alIsBuffer(alBuffer[0])) )
|
||||||
|
return false;
|
||||||
|
if ( !(alBuffer[1] != AL_NONE && alIsBuffer(alBuffer[1])) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
uint32 size = m_pSoundFile->Decode(m_pBuffer);
|
uint32 size = m_pSoundFile->Decode(m_pBuffer);
|
||||||
if( size == 0 )
|
if( size == 0 )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
alBufferData(alBuffer, m_pSoundFile->GetChannels() == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16,
|
uint32 channelSize = size / m_pSoundFile->GetChannels();
|
||||||
m_pBuffer, size, m_pSoundFile->GetSampleRate());
|
|
||||||
|
|
||||||
|
alBufferData(alBuffer[0], AL_FORMAT_MONO16, m_pBuffer, channelSize, m_pSoundFile->GetSampleRate());
|
||||||
|
// TODO: use just one buffer if we play mono
|
||||||
|
if (m_pSoundFile->GetChannels() == 1)
|
||||||
|
alBufferData(alBuffer[1], AL_FORMAT_MONO16, m_pBuffer, channelSize, m_pSoundFile->GetSampleRate());
|
||||||
|
else
|
||||||
|
alBufferData(alBuffer[1], AL_FORMAT_MONO16, (uint8*)m_pBuffer + channelSize, channelSize, m_pSoundFile->GetSampleRate());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 CStream::FillBuffers()
|
int32 CStream::FillBuffers()
|
||||||
{
|
{
|
||||||
int32 i = 0;
|
int32 i = 0;
|
||||||
for ( i = 0; i < NUM_STREAMBUFFERS; i++ )
|
for ( i = 0; i < NUM_STREAMBUFFERS/2; i++ )
|
||||||
{
|
{
|
||||||
if ( !FillBuffer(m_alBuffers[i]) )
|
if ( !FillBuffer(&m_alBuffers[i*2]) )
|
||||||
break;
|
break;
|
||||||
alSourceQueueBuffers(m_alSource, 1, &m_alBuffers[i]);
|
alSourceQueueBuffers(m_pAlSources[0], 1, &m_alBuffers[i*2]);
|
||||||
|
alSourceQueueBuffers(m_pAlSources[1], 1, &m_alBuffers[i*2+1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
|
@ -563,12 +652,15 @@ void CStream::ClearBuffers()
|
||||||
{
|
{
|
||||||
if ( !HasSource() ) return;
|
if ( !HasSource() ) return;
|
||||||
|
|
||||||
ALint buffersQueued;
|
ALint buffersQueued[2];
|
||||||
alGetSourcei(m_alSource, AL_BUFFERS_QUEUED, &buffersQueued);
|
alGetSourcei(m_pAlSources[0], AL_BUFFERS_QUEUED, &buffersQueued[0]);
|
||||||
|
alGetSourcei(m_pAlSources[1], AL_BUFFERS_QUEUED, &buffersQueued[1]);
|
||||||
|
|
||||||
ALuint value;
|
ALuint value;
|
||||||
while (buffersQueued--)
|
while (buffersQueued[0]--)
|
||||||
alSourceUnqueueBuffers(m_alSource, 1, &value);
|
alSourceUnqueueBuffers(m_pAlSources[0], 1, &value);
|
||||||
|
while (buffersQueued[1]--)
|
||||||
|
alSourceUnqueueBuffers(m_pAlSources[1], 1, &value);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CStream::Setup()
|
bool CStream::Setup()
|
||||||
|
@ -576,7 +668,6 @@ bool CStream::Setup()
|
||||||
if ( IsOpened() )
|
if ( IsOpened() )
|
||||||
{
|
{
|
||||||
m_pSoundFile->Seek(0);
|
m_pSoundFile->Seek(0);
|
||||||
alSourcei(m_alSource, AL_SOURCE_RELATIVE, AL_TRUE);
|
|
||||||
//SetPosition(0.0f, 0.0f, 0.0f);
|
//SetPosition(0.0f, 0.0f, 0.0f);
|
||||||
SetPitch(1.0f);
|
SetPitch(1.0f);
|
||||||
//SetPan(m_nPan);
|
//SetPan(m_nPan);
|
||||||
|
@ -592,17 +683,29 @@ void CStream::SetPlay(bool state)
|
||||||
if ( state )
|
if ( state )
|
||||||
{
|
{
|
||||||
ALint sourceState = AL_PLAYING;
|
ALint sourceState = AL_PLAYING;
|
||||||
alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState);
|
alGetSourcei(m_pAlSources[0], AL_SOURCE_STATE, &sourceState);
|
||||||
if (sourceState != AL_PLAYING )
|
if (sourceState != AL_PLAYING )
|
||||||
alSourcePlay(m_alSource);
|
alSourcePlay(m_pAlSources[0]);
|
||||||
|
|
||||||
|
sourceState = AL_PLAYING;
|
||||||
|
alGetSourcei(m_pAlSources[1], AL_SOURCE_STATE, &sourceState);
|
||||||
|
if (sourceState != AL_PLAYING)
|
||||||
|
alSourcePlay(m_pAlSources[1]);
|
||||||
|
|
||||||
m_bActive = true;
|
m_bActive = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ALint sourceState = AL_STOPPED;
|
ALint sourceState = AL_STOPPED;
|
||||||
alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState);
|
alGetSourcei(m_pAlSources[0], AL_SOURCE_STATE, &sourceState);
|
||||||
if (sourceState != AL_STOPPED )
|
if (sourceState != AL_STOPPED )
|
||||||
alSourceStop(m_alSource);
|
alSourceStop(m_pAlSources[0]);
|
||||||
|
|
||||||
|
sourceState = AL_STOPPED;
|
||||||
|
alGetSourcei(m_pAlSources[1], AL_SOURCE_STATE, &sourceState);
|
||||||
|
if (sourceState != AL_STOPPED)
|
||||||
|
alSourceStop(m_pAlSources[1]);
|
||||||
|
|
||||||
m_bActive = false;
|
m_bActive = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -633,35 +736,48 @@ void CStream::Update()
|
||||||
|
|
||||||
if ( !m_bPaused )
|
if ( !m_bPaused )
|
||||||
{
|
{
|
||||||
ALint sourceState;
|
ALint sourceState[2];
|
||||||
ALint buffersProcessed = 0;
|
ALint buffersProcessed[2] = { 0, 0 };
|
||||||
|
|
||||||
alGetSourcei(m_alSource, AL_SOURCE_STATE, &sourceState);
|
// Relying a lot on left buffer states in here
|
||||||
alGetSourcei(m_alSource, AL_BUFFERS_PROCESSED, &buffersProcessed);
|
|
||||||
|
//alSourcef(m_pAlSources[0], AL_ROLLOFF_FACTOR, 0.0f);
|
||||||
|
alGetSourcei(m_pAlSources[0], AL_SOURCE_STATE, &sourceState[0]);
|
||||||
|
alGetSourcei(m_pAlSources[0], AL_BUFFERS_PROCESSED, &buffersProcessed[0]);
|
||||||
|
//alSourcef(m_pAlSources[1], AL_ROLLOFF_FACTOR, 0.0f);
|
||||||
|
alGetSourcei(m_pAlSources[1], AL_SOURCE_STATE, &sourceState[1]);
|
||||||
|
alGetSourcei(m_pAlSources[1], AL_BUFFERS_PROCESSED, &buffersProcessed[1]);
|
||||||
|
|
||||||
ALint looping = AL_FALSE;
|
ALint looping = AL_FALSE;
|
||||||
alGetSourcei(m_alSource, AL_LOOPING, &looping);
|
alGetSourcei(m_pAlSources[0], AL_LOOPING, &looping);
|
||||||
|
|
||||||
if ( looping == AL_TRUE )
|
if ( looping == AL_TRUE )
|
||||||
{
|
{
|
||||||
TRACE("stream set looping");
|
TRACE("stream set looping");
|
||||||
alSourcei(m_alSource, AL_LOOPING, AL_TRUE);
|
alSourcei(m_pAlSources[0], AL_LOOPING, AL_TRUE);
|
||||||
|
alSourcei(m_pAlSources[1], AL_LOOPING, AL_TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
while( buffersProcessed-- )
|
assert(buffersProcessed[0] == buffersProcessed[1]);
|
||||||
{
|
|
||||||
ALuint buffer;
|
|
||||||
|
|
||||||
alSourceUnqueueBuffers(m_alSource, 1, &buffer);
|
while( buffersProcessed[0]-- )
|
||||||
|
{
|
||||||
|
ALuint buffer[2];
|
||||||
|
|
||||||
|
alSourceUnqueueBuffers(m_pAlSources[0], 1, &buffer[0]);
|
||||||
|
alSourceUnqueueBuffers(m_pAlSources[1], 1, &buffer[1]);
|
||||||
|
|
||||||
if (m_bActive && FillBuffer(buffer))
|
if (m_bActive && FillBuffer(buffer))
|
||||||
alSourceQueueBuffers(m_alSource, 1, &buffer);
|
{
|
||||||
|
alSourceQueueBuffers(m_pAlSources[0], 1, &buffer[0]);
|
||||||
|
alSourceQueueBuffers(m_pAlSources[1], 1, &buffer[1]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( sourceState != AL_PLAYING )
|
if ( sourceState[0] != AL_PLAYING )
|
||||||
{
|
{
|
||||||
alGetSourcei(m_alSource, AL_BUFFERS_PROCESSED, &buffersProcessed);
|
alGetSourcei(m_pAlSources[0], AL_BUFFERS_PROCESSED, &buffersProcessed[0]);
|
||||||
SetPlay(buffersProcessed!=0);
|
SetPlay(buffersProcessed[0]!=0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ public:
|
||||||
class CStream
|
class CStream
|
||||||
{
|
{
|
||||||
char m_aFilename[128];
|
char m_aFilename[128];
|
||||||
ALuint &m_alSource;
|
ALuint *m_pAlSources;
|
||||||
ALuint (&m_alBuffers)[NUM_STREAMBUFFERS];
|
ALuint (&m_alBuffers)[NUM_STREAMBUFFERS];
|
||||||
|
|
||||||
bool m_bPaused;
|
bool m_bPaused;
|
||||||
|
@ -73,20 +73,20 @@ class CStream
|
||||||
IDecoder *m_pSoundFile;
|
IDecoder *m_pSoundFile;
|
||||||
|
|
||||||
bool HasSource();
|
bool HasSource();
|
||||||
void SetPosition(float x, float y, float z);
|
void SetPosition(int i, float x, float y, float z);
|
||||||
void SetPitch(float pitch);
|
void SetPitch(float pitch);
|
||||||
void SetGain(float gain);
|
void SetGain(float gain);
|
||||||
void Pause();
|
void Pause();
|
||||||
void SetPlay(bool state);
|
void SetPlay(bool state);
|
||||||
|
|
||||||
bool FillBuffer(ALuint alBuffer);
|
bool FillBuffer(ALuint *alBuffer);
|
||||||
int32 FillBuffers();
|
int32 FillBuffers();
|
||||||
void ClearBuffers();
|
void ClearBuffers();
|
||||||
public:
|
public:
|
||||||
static void Initialise();
|
static void Initialise();
|
||||||
static void Terminate();
|
static void Terminate();
|
||||||
|
|
||||||
CStream(char *filename, ALuint &source, ALuint (&buffers)[NUM_STREAMBUFFERS]);
|
CStream(char *filename, ALuint *sources, ALuint (&buffers)[NUM_STREAMBUFFERS]);
|
||||||
~CStream();
|
~CStream();
|
||||||
void Delete();
|
void Delete();
|
||||||
|
|
||||||
|
|
|
@ -102,7 +102,7 @@ CChannel aChannel[MAXCHANNELS+MAX2DCHANNELS];
|
||||||
uint8 nChannelVolume[MAXCHANNELS+MAX2DCHANNELS];
|
uint8 nChannelVolume[MAXCHANNELS+MAX2DCHANNELS];
|
||||||
|
|
||||||
uint32 nStreamLength[TOTAL_STREAMED_SOUNDS];
|
uint32 nStreamLength[TOTAL_STREAMED_SOUNDS];
|
||||||
ALuint ALStreamSources[MAX_STREAMS];
|
ALuint ALStreamSources[MAX_STREAMS*2];
|
||||||
ALuint ALStreamBuffers[MAX_STREAMS][NUM_STREAMBUFFERS];
|
ALuint ALStreamBuffers[MAX_STREAMS][NUM_STREAMBUFFERS];
|
||||||
|
|
||||||
struct tMP3Entry
|
struct tMP3Entry
|
||||||
|
@ -245,9 +245,9 @@ release_existing()
|
||||||
if (stream)
|
if (stream)
|
||||||
stream->ProviderTerm();
|
stream->ProviderTerm();
|
||||||
|
|
||||||
alDeleteSources(1, &ALStreamSources[i]);
|
|
||||||
alDeleteBuffers(NUM_STREAMBUFFERS, ALStreamBuffers[i]);
|
alDeleteBuffers(NUM_STREAMBUFFERS, ALStreamBuffers[i]);
|
||||||
}
|
}
|
||||||
|
alDeleteSources(MAX_STREAMS*2, ALStreamSources);
|
||||||
|
|
||||||
CChannel::DestroyChannels();
|
CChannel::DestroyChannels();
|
||||||
|
|
||||||
|
@ -287,7 +287,10 @@ set_new_provider(int index)
|
||||||
//TODO:
|
//TODO:
|
||||||
_maxSamples = MAXCHANNELS;
|
_maxSamples = MAXCHANNELS;
|
||||||
|
|
||||||
ALCint attr[] = {ALC_FREQUENCY,MAX_FREQ,0};
|
ALCint attr[] = {ALC_FREQUENCY,MAX_FREQ,
|
||||||
|
ALC_MONO_SOURCES, MAX_STREAMS * 2 + MAXCHANNELS,
|
||||||
|
0,
|
||||||
|
};
|
||||||
|
|
||||||
ALDevice = alcOpenDevice(providers[index].id);
|
ALDevice = alcOpenDevice(providers[index].id);
|
||||||
ASSERT(ALDevice != NULL);
|
ASSERT(ALDevice != NULL);
|
||||||
|
@ -320,10 +323,16 @@ set_new_provider(int index)
|
||||||
alGenEffects(1, &ALEffect);
|
alGenEffects(1, &ALEffect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
alGenSources(MAX_STREAMS*2, ALStreamSources);
|
||||||
for ( int32 i = 0; i < MAX_STREAMS; i++ )
|
for ( int32 i = 0; i < MAX_STREAMS; i++ )
|
||||||
{
|
{
|
||||||
alGenSources(1, &ALStreamSources[i]);
|
|
||||||
alGenBuffers(NUM_STREAMBUFFERS, ALStreamBuffers[i]);
|
alGenBuffers(NUM_STREAMBUFFERS, ALStreamBuffers[i]);
|
||||||
|
alSourcei(ALStreamSources[i*2], AL_SOURCE_RELATIVE, AL_TRUE);
|
||||||
|
alSource3f(ALStreamSources[i*2], AL_POSITION, 0.0f, 0.0f, 0.0f);
|
||||||
|
alSourcef(ALStreamSources[i*2], AL_GAIN, 1.0f);
|
||||||
|
alSourcei(ALStreamSources[i*2+1], AL_SOURCE_RELATIVE, AL_TRUE);
|
||||||
|
alSource3f(ALStreamSources[i*2+1], AL_POSITION, 0.0f, 0.0f, 0.0f);
|
||||||
|
alSourcef(ALStreamSources[i*2+1], AL_GAIN, 1.0f);
|
||||||
|
|
||||||
CStream *stream = aStream[i];
|
CStream *stream = aStream[i];
|
||||||
if (stream)
|
if (stream)
|
||||||
|
@ -603,7 +612,7 @@ _FindMP3s(void)
|
||||||
} else
|
} else
|
||||||
bShortcut = false;
|
bShortcut = false;
|
||||||
|
|
||||||
aStream[0] = new CStream(filepath, ALStreamSources[0], ALStreamBuffers[0]);
|
aStream[0] = new CStream(filepath, &ALStreamSources[0], ALStreamBuffers[0]);
|
||||||
|
|
||||||
if (aStream[0] && aStream[0]->IsOpened())
|
if (aStream[0] && aStream[0]->IsOpened())
|
||||||
{
|
{
|
||||||
|
@ -677,7 +686,7 @@ _FindMP3s(void)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
aStream[0] = new CStream(filepath, ALStreamSources[0], ALStreamBuffers[0]);
|
aStream[0] = new CStream(filepath, &ALStreamSources[0], ALStreamBuffers[0]);
|
||||||
|
|
||||||
if (aStream[0] && aStream[0]->IsOpened())
|
if (aStream[0] && aStream[0]->IsOpened())
|
||||||
{
|
{
|
||||||
|
@ -737,7 +746,7 @@ _FindMP3s(void)
|
||||||
} else
|
} else
|
||||||
bShortcut = false;
|
bShortcut = false;
|
||||||
|
|
||||||
aStream[0] = new CStream(filepath, ALStreamSources[0], ALStreamBuffers[0]);
|
aStream[0] = new CStream(filepath, &ALStreamSources[0], ALStreamBuffers[0]);
|
||||||
|
|
||||||
if (aStream[0] && aStream[0]->IsOpened())
|
if (aStream[0] && aStream[0]->IsOpened())
|
||||||
{
|
{
|
||||||
|
@ -989,7 +998,7 @@ cSampleManager::Initialise(void)
|
||||||
|
|
||||||
for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ )
|
for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ )
|
||||||
{
|
{
|
||||||
aStream[0] = new CStream(StreamedNameTable[i], ALStreamSources[0], ALStreamBuffers[0]);
|
aStream[0] = new CStream(StreamedNameTable[i], &ALStreamSources[0], ALStreamBuffers[0]);
|
||||||
|
|
||||||
if ( aStream[0] && aStream[0]->IsOpened() )
|
if ( aStream[0] && aStream[0]->IsOpened() )
|
||||||
{
|
{
|
||||||
|
@ -1672,7 +1681,7 @@ cSampleManager::PreloadStreamedFile(uint32 nFile, uint8 nStream)
|
||||||
|
|
||||||
strcpy(filename, StreamedNameTable[nFile]);
|
strcpy(filename, StreamedNameTable[nFile]);
|
||||||
|
|
||||||
CStream *stream = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]);
|
CStream *stream = new CStream(filename, &ALStreamSources[nStream*2], ALStreamBuffers[nStream]);
|
||||||
ASSERT(stream != NULL);
|
ASSERT(stream != NULL);
|
||||||
|
|
||||||
aStream[nStream] = stream;
|
aStream[nStream] = stream;
|
||||||
|
@ -1747,7 +1756,7 @@ cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream)
|
||||||
nFile = 0;
|
nFile = 0;
|
||||||
strcat(filename, StreamedNameTable[nFile]);
|
strcat(filename, StreamedNameTable[nFile]);
|
||||||
|
|
||||||
CStream* stream = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]);
|
CStream* stream = new CStream(filename, &ALStreamSources[nStream*2], ALStreamBuffers[nStream]);
|
||||||
ASSERT(stream != NULL);
|
ASSERT(stream != NULL);
|
||||||
|
|
||||||
aStream[nStream] = stream;
|
aStream[nStream] = stream;
|
||||||
|
@ -1771,12 +1780,12 @@ cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mp3->pLinkPath != NULL)
|
if (mp3->pLinkPath != NULL)
|
||||||
aStream[nStream] = new CStream(mp3->pLinkPath, ALStreamSources[nStream], ALStreamBuffers[nStream]);
|
aStream[nStream] = new CStream(mp3->pLinkPath, &ALStreamSources[nStream*2], ALStreamBuffers[nStream]);
|
||||||
else {
|
else {
|
||||||
strcpy(filename, _mp3DirectoryPath);
|
strcpy(filename, _mp3DirectoryPath);
|
||||||
strcat(filename, mp3->aFilename);
|
strcat(filename, mp3->aFilename);
|
||||||
|
|
||||||
aStream[nStream] = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]);
|
aStream[nStream] = new CStream(filename, &ALStreamSources[nStream*2], ALStreamBuffers[nStream]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aStream[nStream]->IsOpened()) {
|
if (aStream[nStream]->IsOpened()) {
|
||||||
|
@ -1803,7 +1812,7 @@ cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream)
|
||||||
{
|
{
|
||||||
nFile = 0;
|
nFile = 0;
|
||||||
strcat(filename, StreamedNameTable[nFile]);
|
strcat(filename, StreamedNameTable[nFile]);
|
||||||
CStream* stream = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]);
|
CStream* stream = new CStream(filename, &ALStreamSources[nStream*2], ALStreamBuffers[nStream]);
|
||||||
ASSERT(stream != NULL);
|
ASSERT(stream != NULL);
|
||||||
|
|
||||||
aStream[nStream] = stream;
|
aStream[nStream] = stream;
|
||||||
|
@ -1827,12 +1836,12 @@ cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e->pLinkPath != NULL)
|
if (e->pLinkPath != NULL)
|
||||||
aStream[nStream] = new CStream(e->pLinkPath, ALStreamSources[nStream], ALStreamBuffers[nStream]);
|
aStream[nStream] = new CStream(e->pLinkPath, &ALStreamSources[nStream*2], ALStreamBuffers[nStream]);
|
||||||
else {
|
else {
|
||||||
strcpy(filename, _mp3DirectoryPath);
|
strcpy(filename, _mp3DirectoryPath);
|
||||||
strcat(filename, e->aFilename);
|
strcat(filename, e->aFilename);
|
||||||
|
|
||||||
aStream[nStream] = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]);
|
aStream[nStream] = new CStream(filename, &ALStreamSources[nStream*2], ALStreamBuffers[nStream]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aStream[nStream]->IsOpened()) {
|
if (aStream[nStream]->IsOpened()) {
|
||||||
|
@ -1860,7 +1869,7 @@ cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream)
|
||||||
|
|
||||||
strcpy(filename, StreamedNameTable[nFile]);
|
strcpy(filename, StreamedNameTable[nFile]);
|
||||||
|
|
||||||
CStream *stream = new CStream(filename, ALStreamSources[nStream], ALStreamBuffers[nStream]);
|
CStream *stream = new CStream(filename, &ALStreamSources[nStream*2], ALStreamBuffers[nStream]);
|
||||||
ASSERT(stream != NULL);
|
ASSERT(stream != NULL);
|
||||||
|
|
||||||
aStream[nStream] = stream;
|
aStream[nStream] = stream;
|
||||||
|
@ -1937,7 +1946,7 @@ cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffect
|
||||||
{
|
{
|
||||||
if ( nEffectFlag ) {
|
if ( nEffectFlag ) {
|
||||||
if ( nStream == 1 || nStream == 2 )
|
if ( nStream == 1 || nStream == 2 )
|
||||||
stream->SetVolume(2*128*nVolume*m_nEffectsVolume >> 14); // double the volume for now as it plays too quiet
|
stream->SetVolume(128*nVolume*m_nEffectsVolume >> 14);
|
||||||
else
|
else
|
||||||
stream->SetVolume(m_nEffectsFadeVolume*nVolume*m_nEffectsVolume >> 14);
|
stream->SetVolume(m_nEffectsFadeVolume*nVolume*m_nEffectsVolume >> 14);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue