aboutsummaryrefslogtreecommitdiffstats
path: root/alc/mixvoice.cpp
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2019-08-11 03:34:35 -0700
committerChris Robinson <[email protected]>2019-08-11 14:01:57 -0700
commit7118733458bc388a900677da6e0d4e4244d0f536 (patch)
treee14278f4a3f6fba0899629192a23415fb229ad6a /alc/mixvoice.cpp
parent70058a8a8405a36c66235a56b482c4c0c7a46780 (diff)
Remove multiple buffers per queue item
And simplify related code
Diffstat (limited to 'alc/mixvoice.cpp')
-rw-r--r--alc/mixvoice.cpp133
1 files changed, 41 insertions, 92 deletions
diff --git a/alc/mixvoice.cpp b/alc/mixvoice.cpp
index cf3eeb50..295b1352 100644
--- a/alc/mixvoice.cpp
+++ b/alc/mixvoice.cpp
@@ -372,7 +372,7 @@ inline void LoadSampleArray(ALfloat *RESTRICT dst, const al::byte *src, ALint sr
const SampleType *RESTRICT ssrc{reinterpret_cast<const SampleType*>(src)};
for(ALsizei i{0};i < samples;i++)
- dst[i] += FmtTypeTraits<T>::to_float(ssrc[i*srcstep]);
+ dst[i] = FmtTypeTraits<T>::to_float(ssrc[i*srcstep]);
}
void LoadSamples(ALfloat *RESTRICT dst, const al::byte *src, ALint srcstep, FmtType srctype,
@@ -395,12 +395,9 @@ ALfloat *LoadBufferStatic(ALbufferlistitem *BufferListItem, ALbufferlistitem *&B
const ALsizei NumChannels, const ALsizei SampleSize, const ALsizei chan, ALuint DataPosInt,
al::span<ALfloat> SrcBuffer)
{
- /* TODO: For static sources, loop points are taken from the first buffer
- * (should be adjusted by any buffer offset, to possibly be added later).
- */
- const ALbuffer *Buffer0{BufferListItem->front()};
- const ALuint LoopStart{Buffer0->LoopStart};
- const ALuint LoopEnd{Buffer0->LoopEnd};
+ const ALbuffer *Buffer{BufferListItem->mBuffer};
+ const ALuint LoopStart{Buffer->LoopStart};
+ const ALuint LoopEnd{Buffer->LoopEnd};
ASSUME(LoopStart >= 0);
ASSUME(LoopEnd > LoopStart);
@@ -409,75 +406,37 @@ ALfloat *LoadBufferStatic(ALbufferlistitem *BufferListItem, ALbufferlistitem *&B
{
BufferLoopItem = nullptr;
- auto load_buffer = [DataPosInt,NumChannels,SampleSize,chan,SrcBuffer](size_t CompLen, const ALbuffer *buffer) -> size_t
- {
- if(DataPosInt >= buffer->SampleLen)
- return CompLen;
-
- /* Load what's left to play from the buffer */
- const size_t DataSize{std::min<size_t>(SrcBuffer.size(),
- buffer->SampleLen - DataPosInt)};
- CompLen = std::max(CompLen, DataSize);
-
- const al::byte *Data{buffer->mData.data()};
- Data += (DataPosInt*NumChannels + chan)*SampleSize;
-
- LoadSamples(SrcBuffer.data(), Data, NumChannels, buffer->mFmtType, DataSize);
- return CompLen;
- };
- /* It's impossible to have a buffer list item with no entries. */
- ASSUME(BufferListItem->mNumBuffers > 0);
- SrcBuffer = SrcBuffer.subspan(std::accumulate(BufferListItem->begin(),
- BufferListItem->end(), size_t{0u}, load_buffer));
+ /* Load what's left to play from the buffer */
+ const size_t DataSize{minz(SrcBuffer.size(), Buffer->SampleLen-DataPosInt)};
+
+ const al::byte *Data{Buffer->mData.data()};
+ Data += (DataPosInt*NumChannels + chan)*SampleSize;
+
+ LoadSamples(SrcBuffer.data(), Data, NumChannels, Buffer->mFmtType, DataSize);
+ SrcBuffer = SrcBuffer.subspan(DataSize);
}
else
{
- const al::span<ALfloat> SrcData{SrcBuffer.first(
- std::min<size_t>(SrcBuffer.size(), LoopEnd - DataPosInt))};
+ /* Load what's left of this loop iteration */
+ const size_t DataSize{minz(SrcBuffer.size(), LoopEnd-DataPosInt)};
- auto load_buffer = [DataPosInt,NumChannels,SampleSize,chan,SrcData](size_t CompLen, const ALbuffer *buffer) -> size_t
- {
- if(DataPosInt >= buffer->SampleLen)
- return CompLen;
+ const al::byte *Data{Buffer->mData.data()};
+ Data += (DataPosInt*NumChannels + chan)*SampleSize;
- /* Load what's left of this loop iteration */
- const size_t DataSize{std::min<size_t>(SrcData.size(),
- buffer->SampleLen - DataPosInt)};
- CompLen = std::max(CompLen, DataSize);
-
- const al::byte *Data{buffer->mData.data()};
- Data += (DataPosInt*NumChannels + chan)*SampleSize;
-
- LoadSamples(SrcData.data(), Data, NumChannels, buffer->mFmtType, DataSize);
- return CompLen;
- };
- ASSUME(BufferListItem->mNumBuffers > 0);
- SrcBuffer = SrcBuffer.subspan(std::accumulate(BufferListItem->begin(),
- BufferListItem->end(), size_t{0u}, load_buffer));
+ LoadSamples(SrcBuffer.data(), Data, NumChannels, Buffer->mFmtType, DataSize);
+ SrcBuffer = SrcBuffer.subspan(DataSize);
+ /* Load any repeats of the loop we can to fill the buffer. */
const auto LoopSize = static_cast<size_t>(LoopEnd - LoopStart);
while(!SrcBuffer.empty())
{
- const al::span<ALfloat> SrcData{SrcBuffer.first(
- std::min<size_t>(SrcBuffer.size(), LoopSize))};
-
- auto load_buffer_loop = [LoopStart,NumChannels,SampleSize,chan,SrcData](size_t CompLen, const ALbuffer *buffer) -> size_t
- {
- if(LoopStart >= buffer->SampleLen)
- return CompLen;
-
- const size_t DataSize{std::min<size_t>(SrcData.size(),
- buffer->SampleLen-LoopStart)};
- CompLen = std::max(CompLen, DataSize);
+ const size_t DataSize{minz(SrcBuffer.size(), LoopSize)};
- const al::byte *Data{buffer->mData.data()};
- Data += (LoopStart*NumChannels + chan)*SampleSize;
+ const al::byte *Data{Buffer->mData.data()};
+ Data += (LoopStart*NumChannels + chan)*SampleSize;
- LoadSamples(SrcData.data(), Data, NumChannels, buffer->mFmtType, DataSize);
- return CompLen;
- };
- SrcBuffer = SrcBuffer.subspan(std::accumulate(BufferListItem->begin(),
- BufferListItem->end(), size_t{0u}, load_buffer_loop));
+ LoadSamples(SrcBuffer.data(), Data, NumChannels, Buffer->mFmtType, DataSize);
+ SrcBuffer = SrcBuffer.subspan(DataSize);
}
}
return SrcBuffer.begin();
@@ -490,35 +449,24 @@ ALfloat *LoadBufferQueue(ALbufferlistitem *BufferListItem, ALbufferlistitem *Buf
/* Crawl the buffer queue to fill in the temp buffer */
while(BufferListItem && !SrcBuffer.empty())
{
- if(DataPosInt >= BufferListItem->mMaxSamples)
+ ALbuffer *Buffer{BufferListItem->mBuffer};
+ if(!(Buffer && DataPosInt < Buffer->SampleLen))
{
- DataPosInt -= BufferListItem->mMaxSamples;
+ if(Buffer) DataPosInt -= Buffer->SampleLen;
BufferListItem = BufferListItem->mNext.load(std::memory_order_acquire);
if(!BufferListItem) BufferListItem = BufferLoopItem;
continue;
}
- auto load_buffer = [DataPosInt,NumChannels,SampleSize,chan,SrcBuffer](size_t CompLen, const ALbuffer *buffer) -> size_t
- {
- if(!buffer) return CompLen;
- if(DataPosInt >= buffer->SampleLen)
- return CompLen;
+ const size_t DataSize{std::min<size_t>(SrcBuffer.size(), Buffer->SampleLen-DataPosInt)};
- const size_t DataSize{std::min<size_t>(SrcBuffer.size(), buffer->SampleLen-DataPosInt)};
- CompLen = std::max(CompLen, DataSize);
+ const al::byte *Data{Buffer->mData.data()};
+ Data += (DataPosInt*NumChannels + chan)*SampleSize;
- const al::byte *Data{buffer->mData.data()};
- Data += (DataPosInt*NumChannels + chan)*SampleSize;
+ LoadSamples(SrcBuffer.data(), Data, NumChannels, Buffer->mFmtType, DataSize);
+ SrcBuffer = SrcBuffer.subspan(DataSize);
+ if(SrcBuffer.empty()) break;
- LoadSamples(SrcBuffer.data(), Data, NumChannels, buffer->mFmtType, DataSize);
- return CompLen;
- };
- ASSUME(BufferListItem->mNumBuffers > 0);
- SrcBuffer = SrcBuffer.subspan(std::accumulate(BufferListItem->begin(),
- BufferListItem->end(), size_t{0u}, load_buffer));
-
- if(SrcBuffer.empty())
- break;
DataPosInt = 0;
BufferListItem = BufferListItem->mNext.load(std::memory_order_acquire);
if(!BufferListItem) BufferListItem = BufferLoopItem;
@@ -640,10 +588,11 @@ void MixVoice(ALvoice *voice, ALvoice::State vstate, const ALuint SourceID, ALCc
ALvoice::ChannelData &chandata = voice->mChans[chan];
const al::span<ALfloat> SrcData{Device->SourceData, SrcBufferSize};
- /* Load the previous samples into the source data first, and clear the rest. */
+ /* Load the previous samples into the source data first, then load
+ * what we can from the buffer queue.
+ */
auto srciter = std::copy_n(chandata.mPrevSamples.begin(), MAX_RESAMPLE_PADDING,
SrcData.begin());
- std::fill(srciter, SrcData.end(), 0.0f);
if UNLIKELY(!BufferListItem)
srciter = std::copy(chandata.mPrevSamples.begin()+MAX_RESAMPLE_PADDING,
@@ -875,7 +824,7 @@ void MixVoice(ALvoice *voice, ALvoice::State vstate, const ALuint SourceID, ALCc
if(BufferLoopItem)
{
/* Handle looping static source */
- const ALbuffer *Buffer{BufferListItem->front()};
+ const ALbuffer *Buffer{BufferListItem->mBuffer};
const ALuint LoopStart{Buffer->LoopStart};
const ALuint LoopEnd{Buffer->LoopEnd};
if(DataPosInt >= LoopEnd)
@@ -887,7 +836,7 @@ void MixVoice(ALvoice *voice, ALvoice::State vstate, const ALuint SourceID, ALCc
else
{
/* Handle non-looping static source */
- if(DataPosInt >= BufferListItem->mMaxSamples)
+ if(DataPosInt >= BufferListItem->mSampleLen)
{
if LIKELY(vstate == ALvoice::Playing)
vstate = ALvoice::Stopped;
@@ -899,12 +848,12 @@ void MixVoice(ALvoice *voice, ALvoice::State vstate, const ALuint SourceID, ALCc
else while(1)
{
/* Handle streaming source */
- if(BufferListItem->mMaxSamples > DataPosInt)
+ if(BufferListItem->mSampleLen > DataPosInt)
break;
- DataPosInt -= BufferListItem->mMaxSamples;
+ DataPosInt -= BufferListItem->mSampleLen;
- buffers_done += BufferListItem->mNumBuffers;
+ ++buffers_done;
BufferListItem = BufferListItem->mNext.load(std::memory_order_relaxed);
if(!BufferListItem && !(BufferListItem=BufferLoopItem))
{