summaryrefslogtreecommitdiffstats
path: root/src/audio/oal/channel.cpp
diff options
context:
space:
mode:
authorSergeanur <s.anureev@yandex.ua>2021-02-16 17:08:19 +0100
committerSergeanur <s.anureev@yandex.ua>2021-02-16 17:08:19 +0100
commite38467ef3affef25b83daf0c0c3b8a61f04e8a65 (patch)
tree3628aed1314f21147e7a46f3095fa341088d8044 /src/audio/oal/channel.cpp
parentfix mailbox particle (diff)
parentPR rules (diff)
downloadre3-e38467ef3affef25b83daf0c0c3b8a61f04e8a65.tar
re3-e38467ef3affef25b83daf0c0c3b8a61f04e8a65.tar.gz
re3-e38467ef3affef25b83daf0c0c3b8a61f04e8a65.tar.bz2
re3-e38467ef3affef25b83daf0c0c3b8a61f04e8a65.tar.lz
re3-e38467ef3affef25b83daf0c0c3b8a61f04e8a65.tar.xz
re3-e38467ef3affef25b83daf0c0c3b8a61f04e8a65.tar.zst
re3-e38467ef3affef25b83daf0c0c3b8a61f04e8a65.zip
Diffstat (limited to 'src/audio/oal/channel.cpp')
-rw-r--r--src/audio/oal/channel.cpp56
1 files changed, 53 insertions, 3 deletions
diff --git a/src/audio/oal/channel.cpp b/src/audio/oal/channel.cpp
index 673a4aed..d1fd0aea 100644
--- a/src/audio/oal/channel.cpp
+++ b/src/audio/oal/channel.cpp
@@ -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;