diff options
author | erorcun <erorcunerorcun@hotmail.com.tr> | 2021-02-02 14:39:08 +0100 |
---|---|---|
committer | erorcun <erorcunerorcun@hotmail.com.tr> | 2021-02-03 13:10:27 +0100 |
commit | 7ff899bd22f20c53d067529140aeb466612e8bbc (patch) | |
tree | cc53cf98a1ad746e5ff9c090a6193d8ceb06bc90 /src/audio/oal/channel.cpp | |
parent | MusicManager fixes (diff) | |
download | re3-7ff899bd22f20c53d067529140aeb466612e8bbc.tar re3-7ff899bd22f20c53d067529140aeb466612e8bbc.tar.gz re3-7ff899bd22f20c53d067529140aeb466612e8bbc.tar.bz2 re3-7ff899bd22f20c53d067529140aeb466612e8bbc.tar.lz re3-7ff899bd22f20c53d067529140aeb466612e8bbc.tar.xz re3-7ff899bd22f20c53d067529140aeb466612e8bbc.tar.zst re3-7ff899bd22f20c53d067529140aeb466612e8bbc.zip |
Diffstat (limited to 'src/audio/oal/channel.cpp')
-rw-r--r-- | src/audio/oal/channel.cpp | 56 |
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; |