diff options
author | Chris Robinson <[email protected]> | 2021-01-24 09:29:56 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2021-01-24 09:29:56 -0800 |
commit | f7acc30c22447565a0ab0fb1d5f553fe060217fb (patch) | |
tree | fddbf7b72b1a8c0251570543e368b1533ab65ea0 | |
parent | 13c1d7efb7141aee93d32a60c0e609e61a64f550 (diff) |
Store the callback in the buffer list item
-rw-r--r-- | al/source.cpp | 4 | ||||
-rw-r--r-- | alc/buffer_storage.h | 5 | ||||
-rw-r--r-- | alc/voice.cpp | 115 | ||||
-rw-r--r-- | alc/voice.h | 1 |
4 files changed, 64 insertions, 61 deletions
diff --git a/al/source.cpp b/al/source.cpp index ecaf4069..2005d25e 100644 --- a/al/source.cpp +++ b/al/source.cpp @@ -447,6 +447,7 @@ void InitVoice(Voice *voice, ALsource *source, BufferlistItem *BufferList, ALCco ALuint num_channels{buffer->channelsFromFmt()}; voice->mFrequency = buffer->mSampleRate; voice->mFmtChannels = buffer->mChannels; + voice->mFmtType = buffer->mType; voice->mSampleSize = buffer->bytesFromFmt(); voice->mAmbiLayout = buffer->mAmbiLayout; voice->mAmbiScaling = buffer->mAmbiScaling; @@ -1397,6 +1398,8 @@ bool SetSourceiv(ALsource *Source, ALCcontext *Context, SourceProp prop, const a /* Add the selected buffer to a one-item queue */ auto newlist = new BufferlistItem{}; + newlist->mCallback = buffer->mCallback; + newlist->mUserData = buffer->mUserData; newlist->mSampleLen = buffer->mSampleLen; newlist->mLoopStart = buffer->mLoopStart; newlist->mLoopEnd = buffer->mLoopEnd; @@ -3302,7 +3305,6 @@ START_API_FUNC } if(!buffer) continue; BufferList->mSampleLen = buffer->mSampleLen; - BufferList->mLoopStart = 0; BufferList->mLoopEnd = buffer->mSampleLen; BufferList->mSamples = buffer->mData; BufferList->mBuffer = buffer; diff --git a/alc/buffer_storage.h b/alc/buffer_storage.h index d6518bc0..48717503 100644 --- a/alc/buffer_storage.h +++ b/alc/buffer_storage.h @@ -74,9 +74,14 @@ struct BufferStorage { struct BufferlistItem { std::atomic<BufferlistItem*> mNext{nullptr}; + + CallbackType mCallback{nullptr}; + void *mUserData{nullptr}; + uint mSampleLen{0u}; uint mLoopStart{0u}; uint mLoopEnd{0u}; + al::span<al::byte> mSamples; BufferStorage *mBuffer{nullptr}; diff --git a/alc/voice.cpp b/alc/voice.cpp index 397f1ed9..634643e0 100644 --- a/alc/voice.cpp +++ b/alc/voice.cpp @@ -234,103 +234,99 @@ void LoadSamples(float *RESTRICT dst, const al::byte *src, const size_t srcstep, #undef HANDLE_FMT } -float *LoadBufferStatic(BufferlistItem *BufferListItem, BufferlistItem *&BufferLoopItem, - const size_t NumChannels, const size_t SampleSize, const size_t chan, size_t DataPosInt, - al::span<float> SrcBuffer) +float *LoadBufferStatic(BufferlistItem *buffer, BufferlistItem *&bufferLoopItem, + const size_t numChannels, const FmtType sampleType, const size_t sampleSize, const size_t chan, + size_t dataPosInt, al::span<float> srcBuffer) { - const BufferStorage &Buffer = *BufferListItem->mBuffer; - const uint LoopStart{BufferListItem->mLoopStart}; - const uint LoopEnd{BufferListItem->mLoopEnd}; + const uint LoopStart{buffer->mLoopStart}; + const uint LoopEnd{buffer->mLoopEnd}; ASSUME(LoopEnd > LoopStart); /* If current pos is beyond the loop range, do not loop */ - if(!BufferLoopItem || DataPosInt >= LoopEnd) + if(!bufferLoopItem || dataPosInt >= LoopEnd) { - BufferLoopItem = nullptr; + bufferLoopItem = nullptr; /* Load what's left to play from the buffer */ - const size_t DataRem{minz(SrcBuffer.size(), BufferListItem->mSampleLen-DataPosInt)}; + const size_t DataRem{minz(srcBuffer.size(), buffer->mSampleLen-dataPosInt)}; - const al::byte *Data{BufferListItem->mSamples.data()}; - Data += (DataPosInt*NumChannels + chan)*SampleSize; + const al::byte *Data{buffer->mSamples.data()}; + Data += (dataPosInt*numChannels + chan)*sampleSize; - LoadSamples(SrcBuffer.data(), Data, NumChannels, Buffer.mType, DataRem); - SrcBuffer = SrcBuffer.subspan(DataRem); + LoadSamples(srcBuffer.data(), Data, numChannels, sampleType, DataRem); + srcBuffer = srcBuffer.subspan(DataRem); } else { /* Load what's left of this loop iteration */ - const size_t DataRem{minz(SrcBuffer.size(), LoopEnd-DataPosInt)}; + const size_t DataRem{minz(srcBuffer.size(), LoopEnd-dataPosInt)}; - const al::byte *Data{BufferListItem->mSamples.data()}; - Data += (DataPosInt*NumChannels + chan)*SampleSize; + const al::byte *Data{buffer->mSamples.data()}; + Data += (dataPosInt*numChannels + chan)*sampleSize; - LoadSamples(SrcBuffer.data(), Data, NumChannels, Buffer.mType, DataRem); - SrcBuffer = SrcBuffer.subspan(DataRem); + LoadSamples(srcBuffer.data(), Data, numChannels, sampleType, DataRem); + srcBuffer = srcBuffer.subspan(DataRem); /* Load any repeats of the loop we can to fill the buffer. */ const auto LoopSize = static_cast<size_t>(LoopEnd - LoopStart); - while(!SrcBuffer.empty()) + while(!srcBuffer.empty()) { - const size_t DataSize{minz(SrcBuffer.size(), LoopSize)}; + const size_t DataSize{minz(srcBuffer.size(), LoopSize)}; - Data = BufferListItem->mSamples.data() + (LoopStart*NumChannels + chan)*SampleSize; + Data = buffer->mSamples.data() + (LoopStart*numChannels + chan)*sampleSize; - LoadSamples(SrcBuffer.data(), Data, NumChannels, Buffer.mType, DataSize); - SrcBuffer = SrcBuffer.subspan(DataSize); + LoadSamples(srcBuffer.data(), Data, numChannels, sampleType, DataSize); + srcBuffer = srcBuffer.subspan(DataSize); } } - return SrcBuffer.begin(); + return srcBuffer.begin(); } -float *LoadBufferCallback(BufferlistItem *BufferListItem, const size_t NumChannels, - const size_t SampleSize, const size_t chan, size_t NumCallbackSamples, - al::span<float> SrcBuffer) +float *LoadBufferCallback(BufferlistItem *buffer, const size_t numChannels, + const FmtType sampleType, const size_t sampleSize, const size_t chan, + size_t numCallbackSamples, al::span<float> srcBuffer) { - const BufferStorage &Buffer = *BufferListItem->mBuffer; - /* Load what's left to play from the buffer */ - const size_t DataRem{minz(SrcBuffer.size(), NumCallbackSamples)}; + const size_t DataRem{minz(srcBuffer.size(), numCallbackSamples)}; - const al::byte *Data{BufferListItem->mSamples.data() + chan*SampleSize}; + const al::byte *Data{buffer->mSamples.data() + chan*sampleSize}; - LoadSamples(SrcBuffer.data(), Data, NumChannels, Buffer.mType, DataRem); - SrcBuffer = SrcBuffer.subspan(DataRem); + LoadSamples(srcBuffer.data(), Data, numChannels, sampleType, DataRem); + srcBuffer = srcBuffer.subspan(DataRem); - return SrcBuffer.begin(); + return srcBuffer.begin(); } -float *LoadBufferQueue(BufferlistItem *BufferListItem, BufferlistItem *BufferLoopItem, - const size_t NumChannels, const size_t SampleSize, const size_t chan, size_t DataPosInt, - al::span<float> SrcBuffer) +float *LoadBufferQueue(BufferlistItem *buffer, BufferlistItem *bufferLoopItem, + const size_t numChannels, const FmtType sampleType, const size_t sampleSize, const size_t chan, + size_t dataPosInt, al::span<float> srcBuffer) { /* Crawl the buffer queue to fill in the temp buffer */ - while(BufferListItem && !SrcBuffer.empty()) + while(buffer && !srcBuffer.empty()) { - if(DataPosInt >= BufferListItem->mSampleLen) + if(dataPosInt >= buffer->mSampleLen) { - DataPosInt -= BufferListItem->mSampleLen; - BufferListItem = BufferListItem->mNext.load(std::memory_order_acquire); - if(!BufferListItem) BufferListItem = BufferLoopItem; + dataPosInt -= buffer->mSampleLen; + buffer = buffer->mNext.load(std::memory_order_acquire); + if(!buffer) buffer = bufferLoopItem; continue; } - BufferStorage *Buffer{BufferListItem->mBuffer}; - const size_t DataSize{minz(SrcBuffer.size(), BufferListItem->mSampleLen-DataPosInt)}; + const size_t DataSize{minz(srcBuffer.size(), buffer->mSampleLen-dataPosInt)}; - const al::byte *Data{BufferListItem->mSamples.data()}; - Data += (DataPosInt*NumChannels + chan)*SampleSize; + const al::byte *Data{buffer->mSamples.data()}; + Data += (dataPosInt*numChannels + chan)*sampleSize; - LoadSamples(SrcBuffer.data(), Data, NumChannels, Buffer->mType, DataSize); - SrcBuffer = SrcBuffer.subspan(DataSize); - if(SrcBuffer.empty()) break; + LoadSamples(srcBuffer.data(), Data, numChannels, sampleType, DataSize); + srcBuffer = srcBuffer.subspan(DataSize); + if(srcBuffer.empty()) break; - DataPosInt = 0; - BufferListItem = BufferListItem->mNext.load(std::memory_order_acquire); - if(!BufferListItem) BufferListItem = BufferLoopItem; + dataPosInt = 0; + buffer = buffer->mNext.load(std::memory_order_acquire); + if(!buffer) buffer = bufferLoopItem; } - return SrcBuffer.begin(); + return srcBuffer.begin(); } @@ -449,6 +445,7 @@ void Voice::mix(const State vstate, ALCcontext *Context, const uint SamplesToDo) uint DataPosFrac{mPositionFrac.load(std::memory_order_relaxed)}; BufferlistItem *BufferListItem{mCurrentBuffer.load(std::memory_order_relaxed)}; BufferlistItem *BufferLoopItem{mLoopBuffer.load(std::memory_order_relaxed)}; + const FmtType SampleType{mFmtType}; const uint SampleSize{mSampleSize}; const uint increment{mStep}; if UNLIKELY(increment < 1) @@ -557,8 +554,6 @@ void Voice::mix(const State vstate, ALCcontext *Context, const uint SamplesToDo) if((mFlags&(VoiceIsCallback|VoiceCallbackStopped)) == VoiceIsCallback && BufferListItem) { - BufferStorage *buffer{BufferListItem->mBuffer}; - /* Exclude resampler pre-padding from the needed size. */ const uint toLoad{SrcBufferSize - (MaxResamplerPadding>>1)}; if(toLoad > mNumCallbackSamples) @@ -566,7 +561,7 @@ void Voice::mix(const State vstate, ALCcontext *Context, const uint SamplesToDo) const size_t byteOffset{mNumCallbackSamples*FrameSize}; const size_t needBytes{toLoad*FrameSize - byteOffset}; - const int gotBytes{buffer->mCallback(buffer->mUserData, + const int gotBytes{BufferListItem->mCallback(BufferListItem->mUserData, &BufferListItem->mSamples[byteOffset], static_cast<int>(needBytes))}; if(gotBytes < 1) mFlags |= VoiceCallbackStopped; @@ -599,13 +594,13 @@ void Voice::mix(const State vstate, ALCcontext *Context, const uint SamplesToDo) srciter = std::copy(chandata.mPrevSamples.begin()+(MaxResamplerPadding>>1), chandata.mPrevSamples.end(), srciter); else if((mFlags&VoiceIsStatic)) - srciter = LoadBufferStatic(BufferListItem, BufferLoopItem, num_chans, + srciter = LoadBufferStatic(BufferListItem, BufferLoopItem, num_chans, SampleType, SampleSize, chan_idx, DataPosInt, {srciter, SrcData.end()}); else if((mFlags&VoiceIsCallback)) - srciter = LoadBufferCallback(BufferListItem, num_chans, SampleSize, chan_idx, - mNumCallbackSamples, {srciter, SrcData.end()}); + srciter = LoadBufferCallback(BufferListItem, num_chans, SampleType, SampleSize, + chan_idx, mNumCallbackSamples, {srciter, SrcData.end()}); else - srciter = LoadBufferQueue(BufferListItem, BufferLoopItem, num_chans, + srciter = LoadBufferQueue(BufferListItem, BufferLoopItem, num_chans, SampleType, SampleSize, chan_idx, DataPosInt, {srciter, SrcData.end()}); if UNLIKELY(srciter != SrcData.end()) diff --git a/alc/voice.h b/alc/voice.h index 07260c3e..84d19ed0 100644 --- a/alc/voice.h +++ b/alc/voice.h @@ -175,6 +175,7 @@ struct Voice { /* Properties for the attached buffer(s). */ FmtChannels mFmtChannels; + FmtType mFmtType; uint mFrequency; uint mSampleSize; AmbiLayout mAmbiLayout; |