OAL Loops, fixes

This commit is contained in:
erorcun 2021-02-02 16:39:08 +03:00
commit 713562685a
6 changed files with 143 additions and 66 deletions

View file

@ -15,6 +15,8 @@ ALuint alFilters[MAXCHANNELS+MAX2DCHANNELS];
ALuint alBuffers[MAXCHANNELS+MAX2DCHANNELS];
bool bChannelsCreated = false;
int32 CChannel::channelsThatNeedService = 0;
void
CChannel::InitChannels()
{
@ -59,7 +61,9 @@ void CChannel::SetDefault()
Position[0] = 0.0f; Position[1] = 0.0f; Position[2] = 0.0f;
Distances[0] = 0.0f; Distances[1] = FLT_MAX;
LoopCount = 1;
LoopCount = 1;
LastProcessedOffset = UINT32_MAX;
LoopPoints[0] = 0; LoopPoints[1] = -1;
Frequency = MAX_FREQ;
@ -67,6 +71,10 @@ void CChannel::SetDefault()
void CChannel::Reset()
{
// Here is safe because ctor don't call this
if (LoopCount > 1)
channelsThatNeedService--;
ClearBuffer();
SetDefault();
}
@ -165,10 +173,51 @@ void CChannel::SetCurrentFreq(uint32 freq)
SetPitch(ALfloat(freq) / Frequency);
}
void CChannel::SetLoopCount(int32 loopCount) // fake. TODO:
void CChannel::SetLoopCount(int32 count)
{
if ( !HasSource() ) return;
alSourcei(alSources[id], AL_LOOPING, loopCount == 1 ? AL_FALSE : AL_TRUE);
// 0: loop indefinitely, 1: play one time, 2: play two times etc...
// only > 1 needs manual processing
if (LoopCount > 1 && count < 2)
channelsThatNeedService--;
else if (LoopCount < 2 && count > 1)
channelsThatNeedService++;
alSourcei(alSources[id], AL_LOOPING, count == 1 ? AL_FALSE : AL_TRUE);
LoopCount = count;
}
bool CChannel::Update()
{
if (!HasSource()) return false;
if (LoopCount < 2) return false;
ALint state;
alGetSourcei(alSources[id], AL_SOURCE_STATE, &state);
if (state == AL_STOPPED) {
debug("Looping channels(%d in this case) shouldn't report AL_STOPPED, but nvm\n", id);
SetLoopCount(1);
return true;
}
assert(channelsThatNeedService > 0 && "Ref counting is broken");
ALint offset;
alGetSourcei(alSources[id], AL_SAMPLE_OFFSET, &offset);
// Rewound
if (offset < LastProcessedOffset) {
LoopCount--;
if (LoopCount == 1) {
// Playing last tune...
channelsThatNeedService--;
alSourcei(alSources[id], AL_LOOPING, AL_FALSE);
}
}
LastProcessedOffset = offset;
return true;
}
void CChannel::SetLoopPoints(ALint start, ALint end)
@ -200,6 +249,7 @@ void CChannel::SetPan(int32 pan)
void CChannel::ClearBuffer()
{
if ( !HasSource() ) return;
alSourcei(alSources[id], AL_LOOPING, AL_FALSE);
alSourcei(alSources[id], AL_BUFFER, AL_NONE);
Data = nil;
DataSize = 0;