|
|
@@ -492,6 +492,7 @@ class CMP3File : public IDecoder |
|
|
|
|
|
m_bOpened = mpg123_open(m_pMH, path) == MPG123_OK
|
|
m_bOpened = mpg123_open(m_pMH, path) == MPG123_OK
|
|
&& mpg123_getformat(m_pMH, &rate, &channels, &encoding) == MPG123_OK;
|
|
&& mpg123_getformat(m_pMH, &rate, &channels, &encoding) == MPG123_OK;
|
|
|
|
|
|
m_nRate = rate;
|
|
m_nRate = rate;
|
|
m_nChannels = channels;
|
|
m_nChannels = channels;
|
|
|
|
|
|
|
@@ -925,7 +926,8 @@ CStream::CStream(char *filename, ALuint *sources, ALuint (&buffers)[NUM_STREAMBU |
|
m_bReset(false),
|
|
m_bReset(false),
|
|
m_nVolume(0),
|
|
m_nVolume(0),
|
|
m_nPan(0),
|
|
m_nPan(0),
|
|
m_nPosBeforeReset(0)
|
|
m_nPosBeforeReset(0),
|
|
|
|
m_nLoopCount(1)
|
|
|
|
|
|
{
|
|
{
|
|
// Be case-insensitive on linux (from https://github.com/OneSadCookie/fcaseopen/)
|
|
// Be case-insensitive on linux (from https://github.com/OneSadCookie/fcaseopen/)
|
|
|
@@ -1021,7 +1023,7 @@ bool CStream::IsPlaying() |
|
ALint sourceState[2];
|
|
ALint sourceState[2];
|
|
alGetSourcei(m_pAlSources[0], AL_SOURCE_STATE, &sourceState[0]);
|
|
alGetSourcei(m_pAlSources[0], AL_SOURCE_STATE, &sourceState[0]);
|
|
alGetSourcei(m_pAlSources[1], AL_SOURCE_STATE, &sourceState[1]);
|
|
alGetSourcei(m_pAlSources[1], AL_SOURCE_STATE, &sourceState[1]);
|
|
if ( m_bActive || sourceState[0] == AL_PLAYING || sourceState[1] == AL_PLAYING)
|
|
if (sourceState[0] == AL_PLAYING || sourceState[1] == AL_PLAYING)
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1179,6 +1181,8 @@ bool CStream::Setup() |
|
{
|
|
{
|
|
if ( IsOpened() )
|
|
if ( IsOpened() )
|
|
{
|
|
{
|
|
|
|
alSourcei(m_pAlSources[0], AL_LOOPING, AL_FALSE);
|
|
|
|
alSourcei(m_pAlSources[1], AL_LOOPING, AL_FALSE);
|
|
m_pSoundFile->Seek(0);
|
|
m_pSoundFile->Seek(0);
|
|
//SetPosition(0.0f, 0.0f, 0.0f);
|
|
//SetPosition(0.0f, 0.0f, 0.0f);
|
|
SetPitch(1.0f);
|
|
SetPitch(1.0f);
|
|
|
@@ -1189,6 +1193,13 @@ bool CStream::Setup() |
|
return IsOpened();
|
|
return IsOpened();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void CStream::SetLoopCount(int32 count)
|
|
|
|
{
|
|
|
|
if ( !HasSource() ) return;
|
|
|
|
|
|
|
|
m_nLoopCount = count;
|
|
|
|
}
|
|
|
|
|
|
void CStream::SetPlay(bool state)
|
|
void CStream::SetPlay(bool state)
|
|
{
|
|
{
|
|
if ( !HasSource() ) return;
|
|
if ( !HasSource() ) return;
|
|
|
@@ -1248,52 +1259,59 @@ void CStream::Update() |
|
|
|
|
|
if ( !m_bPaused )
|
|
if ( !m_bPaused )
|
|
{
|
|
{
|
|
ALint sourceState[2];
|
|
ALint totalBuffers[2] = { 0, 0 };
|
|
ALint buffersProcessed[2] = { 0, 0 };
|
|
ALint buffersProcessed[2] = { 0, 0 };
|
|
|
|
|
|
// Relying a lot on left buffer states in here
|
|
// Relying a lot on left buffer states in here
|
|
|
|
|
|
do
|
|
do
|
|
{
|
|
{
|
|
//alSourcef(m_pAlSources[0], AL_ROLLOFF_FACTOR, 0.0f);
|
|
//alSourcef(m_pAlSources[0], AL_ROLLOFF_FACTOR, 0.0f);
|
|
alGetSourcei(m_pAlSources[0], AL_SOURCE_STATE, &sourceState[0]);
|
|
alGetSourcei(m_pAlSources[0], AL_BUFFERS_QUEUED, &totalBuffers[0]);
|
|
alGetSourcei(m_pAlSources[0], AL_BUFFERS_PROCESSED, &buffersProcessed[0]);
|
|
alGetSourcei(m_pAlSources[0], AL_BUFFERS_PROCESSED, &buffersProcessed[0]);
|
|
//alSourcef(m_pAlSources[1], AL_ROLLOFF_FACTOR, 0.0f);
|
|
//alSourcef(m_pAlSources[1], AL_ROLLOFF_FACTOR, 0.0f);
|
|
alGetSourcei(m_pAlSources[1], AL_SOURCE_STATE, &sourceState[1]);
|
|
alGetSourcei(m_pAlSources[1], AL_BUFFERS_QUEUED, &totalBuffers[1]);
|
|
alGetSourcei(m_pAlSources[1], AL_BUFFERS_PROCESSED, &buffersProcessed[1]);
|
|
alGetSourcei(m_pAlSources[1], AL_BUFFERS_PROCESSED, &buffersProcessed[1]);
|
|
} while (buffersProcessed[0] != buffersProcessed[1]);
|
|
} while (buffersProcessed[0] != buffersProcessed[1]);
|
|
|
|
|
|
ALint looping = AL_FALSE;
|
|
assert(buffersProcessed[0] == buffersProcessed[1]);
|
|
alGetSourcei(m_pAlSources[0], AL_LOOPING, &looping);
|
|
|
|
|
|
// Correcting OpenAL concepts here:
|
|
if ( looping == AL_TRUE )
|
|
// AL_BUFFERS_QUEUED = Number of *all* buffers in queue, including processed, processing and pending
|
|
|
|
// AL_BUFFERS_PROCESSED = Index of the buffer being processing right now. Buffers coming after that(have greater index) are pending buffers.
|
|
|
|
// which means: totalBuffers[0] - buffersProcessed[0] = pending buffers
|
|
|
|
|
|
|
|
bool buffersRefilled = false;
|
|
|
|
|
|
|
|
// We should wait queue to be cleared to loop track, because position calculation relies on queue.
|
|
|
|
if (m_nLoopCount != 1 && m_bActive && totalBuffers[0] == 0)
|
|
{
|
|
{
|
|
TRACE("stream set looping");
|
|
Setup();
|
|
alSourcei(m_pAlSources[0], AL_LOOPING, AL_TRUE);
|
|
buffersRefilled = FillBuffers() != 0;
|
|
alSourcei(m_pAlSources[1], AL_LOOPING, AL_TRUE);
|
|
if (m_nLoopCount != 0)
|
|
|
|
m_nLoopCount--;
|
|
}
|
|
}
|
|
|
|
else
|
|
assert(buffersProcessed[0] == buffersProcessed[1]);
|
|
|
|
|
|
|
|
while( buffersProcessed[0]-- )
|
|
|
|
{
|
|
{
|
|
ALuint buffer[2];
|
|
while( buffersProcessed[0]-- )
|
|
|
|
|
|
alSourceUnqueueBuffers(m_pAlSources[0], 1, &buffer[0]);
|
|
|
|
alSourceUnqueueBuffers(m_pAlSources[1], 1, &buffer[1]);
|
|
|
|
|
|
|
|
if (m_bActive && FillBuffer(buffer))
|
|
|
|
{
|
|
{
|
|
alSourceQueueBuffers(m_pAlSources[0], 1, &buffer[0]);
|
|
ALuint buffer[2];
|
|
alSourceQueueBuffers(m_pAlSources[1], 1, &buffer[1]);
|
|
|
|
|
|
alSourceUnqueueBuffers(m_pAlSources[0], 1, &buffer[0]);
|
|
|
|
alSourceUnqueueBuffers(m_pAlSources[1], 1, &buffer[1]);
|
|
|
|
|
|
|
|
if (m_bActive && FillBuffer(buffer))
|
|
|
|
{
|
|
|
|
buffersRefilled = true;
|
|
|
|
alSourceQueueBuffers(m_pAlSources[0], 1, &buffer[0]);
|
|
|
|
alSourceQueueBuffers(m_pAlSources[1], 1, &buffer[1]);
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if ( sourceState[0] != AL_PLAYING )
|
|
// Two reasons: 1-Source may be starved to audio and stopped itself, 2- We're already waiting it to starve and die for looping track!
|
|
{
|
|
if (m_bActive && (buffersRefilled || (totalBuffers[1] - buffersProcessed[1] != 0)))
|
|
alGetSourcei(m_pAlSources[0], AL_BUFFERS_PROCESSED, &buffersProcessed[0]);
|
|
SetPlay(true);
|
|
SetPlay(buffersProcessed[0]!=0);
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1305,6 +1323,7 @@ void CStream::ProviderInit() |
|
{
|
|
{
|
|
SetPan(m_nPan);
|
|
SetPan(m_nPan);
|
|
SetVolume(m_nVolume);
|
|
SetVolume(m_nVolume);
|
|
|
|
SetLoopCount(m_nLoopCount);
|
|
SetPosMS(m_nPosBeforeReset);
|
|
SetPosMS(m_nPosBeforeReset);
|
|
if (m_bActive)
|
|
if (m_bActive)
|
|
FillBuffers();
|
|
FillBuffers();
|
|
|
|