From 8bacb5dfb8ef910586fcf5b5cd89526ec81061e8 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 16 Sep 2018 17:38:55 -0700 Subject: Fix buffer queue mixing logic In particular, the source sample position was reduced by the size of the next buffer list item when one is completed, rather than the size of the one it just completed. --- Alc/mixvoice.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/Alc/mixvoice.c b/Alc/mixvoice.c index 2d935ce5..276d5bd9 100644 --- a/Alc/mixvoice.c +++ b/Alc/mixvoice.c @@ -487,6 +487,7 @@ ALboolean MixSource(ALvoice *voice, ALuint SourceID, ALCcontext *Context, ALsize while(tmpiter && SrcBufferSize > FilledAmt) { ALsizei SizeToDo = SrcBufferSize - FilledAmt; + ALsizei CompLen = 0; ALsizei i; for(i = 0;i < tmpiter->num_buffers;i++) @@ -499,23 +500,24 @@ ALboolean MixSource(ALvoice *voice, ALuint SourceID, ALCcontext *Context, ALsize const ALubyte *Data = ALBuffer->data; Data += (pos*NumChannels + chan)*SampleSize; - DataSize = minu(SizeToDo, DataSize - pos); + DataSize = mini(SizeToDo, DataSize - pos); + CompLen = maxi(CompLen, DataSize); + LoadSamples(&SrcData[FilledAmt], Data, NumChannels, ALBuffer->FmtType, DataSize); } } - if(pos > tmpiter->max_samples) + if(UNLIKELY(!CompLen)) pos -= tmpiter->max_samples; else { - FilledAmt += tmpiter->max_samples - pos; + FilledAmt += CompLen; + if(SrcBufferSize <= FilledAmt) + break; pos = 0; } - if(SrcBufferSize > FilledAmt) - { - tmpiter = ATOMIC_LOAD(&tmpiter->next, almemory_order_acquire); - if(!tmpiter) tmpiter = BufferLoopItem; - } + tmpiter = ATOMIC_LOAD(&tmpiter->next, almemory_order_acquire); + if(!tmpiter) tmpiter = BufferLoopItem; } } @@ -729,8 +731,10 @@ ALboolean MixSource(ALvoice *voice, ALuint SourceID, ALCcontext *Context, ALsize if(BufferListItem->max_samples > DataPosInt) break; + DataPosInt -= BufferListItem->max_samples; + buffers_done += BufferListItem->num_buffers; - BufferListItem = ATOMIC_LOAD(&BufferListItem->next, almemory_order_acquire); + BufferListItem = ATOMIC_LOAD(&BufferListItem->next, almemory_order_relaxed); if(!BufferListItem && !(BufferListItem=BufferLoopItem)) { isplaying = false; @@ -738,8 +742,6 @@ ALboolean MixSource(ALvoice *voice, ALuint SourceID, ALCcontext *Context, ALsize DataPosFrac = 0; break; } - - DataPosInt -= BufferListItem->max_samples; } } while(isplaying && OutPos < SamplesToDo); -- cgit v1.2.3