aboutsummaryrefslogtreecommitdiffstats
path: root/Alc
diff options
context:
space:
mode:
Diffstat (limited to 'Alc')
-rw-r--r--Alc/mixer.c98
1 files changed, 88 insertions, 10 deletions
diff --git a/Alc/mixer.c b/Alc/mixer.c
index 772ff599..3c76cd40 100644
--- a/Alc/mixer.c
+++ b/Alc/mixer.c
@@ -649,7 +649,8 @@ ALvoid MixSource(ALsource *Source, ALCdevice *Device, ALuint SamplesToDo)
j = 0;
do {
- ALubyte SrcData[STACK_DATA_SIZE];
+ ALubyte StackData[STACK_DATA_SIZE];
+ ALubyte *SrcData = StackData;
ALuint SrcDataSize = 0;
ALuint BufferSize;
@@ -658,11 +659,10 @@ ALvoid MixSource(ALsource *Source, ALCdevice *Device, ALuint SamplesToDo)
DataSize64 *= increment;
DataSize64 += DataPosFrac+FRACTIONMASK;
DataSize64 >>= FRACTIONBITS;
- DataSize64 += BUFFER_PADDING;
+ DataSize64 += BUFFER_PADDING+BUFFER_PREPADDING;
DataSize64 *= FrameSize;
- BufferSize = sizeof(SrcData) - SrcDataSize;
- BufferSize = min(DataSize64, BufferSize);
+ BufferSize = min(DataSize64, STACK_DATA_SIZE);
BufferSize -= BufferSize%FrameSize;
if(Source->lSourceType == AL_STATIC)
@@ -670,18 +670,33 @@ ALvoid MixSource(ALsource *Source, ALCdevice *Device, ALuint SamplesToDo)
const ALbuffer *ALBuffer = Source->Buffer;
const ALubyte *Data = ALBuffer->data;
ALuint DataSize;
+ ALuint pos;
/* If current pos is beyond the loop range, do not loop */
if(Looping == AL_FALSE || DataPosInt >= (ALuint)ALBuffer->LoopEnd)
{
Looping = AL_FALSE;
+ if(DataPosInt >= BUFFER_PREPADDING)
+ pos = (DataPosInt-BUFFER_PREPADDING)*FrameSize;
+ else
+ {
+ DataSize = (BUFFER_PREPADDING-DataPosInt)*FrameSize;
+ DataSize = min(BufferSize, DataSize);
+
+ memset(&SrcData[SrcDataSize], (Bytes==1)?0x80:0, DataSize);
+ SrcDataSize += DataSize;
+ BufferSize -= DataSize;
+
+ pos = 0;
+ }
+
/* Copy what's left to play in the source buffer, and clear the
* rest of the temp buffer */
- DataSize = ALBuffer->size - DataPosInt*FrameSize;
+ DataSize = ALBuffer->size - pos;
DataSize = min(BufferSize, DataSize);
- memcpy(&SrcData[SrcDataSize], &Data[DataPosInt*FrameSize], DataSize);
+ memcpy(&SrcData[SrcDataSize], &Data[pos], DataSize);
SrcDataSize += DataSize;
BufferSize -= DataSize;
@@ -694,12 +709,35 @@ ALvoid MixSource(ALsource *Source, ALCdevice *Device, ALuint SamplesToDo)
ALuint LoopStart = ALBuffer->LoopStart;
ALuint LoopEnd = ALBuffer->LoopEnd;
+ if(DataPosInt >= LoopStart)
+ {
+ pos = DataPosInt-LoopStart;
+ while(pos < BUFFER_PREPADDING)
+ pos += LoopEnd-LoopStart;
+ pos -= BUFFER_PREPADDING;
+ pos += LoopStart;
+ pos *= FrameSize;
+ }
+ else if(DataPosInt >= BUFFER_PREPADDING)
+ pos = (DataPosInt-BUFFER_PREPADDING)*FrameSize;
+ else
+ {
+ DataSize = (BUFFER_PREPADDING-DataPosInt)*FrameSize;
+ DataSize = min(BufferSize, DataSize);
+
+ memset(&SrcData[SrcDataSize], (Bytes==1)?0x80:0, DataSize);
+ SrcDataSize += DataSize;
+ BufferSize -= DataSize;
+
+ pos = 0;
+ }
+
/* Copy what's left of this loop iteration, then copy repeats
* of the loop section */
- DataSize = (LoopEnd-DataPosInt) * FrameSize;
+ DataSize = LoopEnd*FrameSize - pos;
DataSize = min(BufferSize, DataSize);
- memcpy(&SrcData[SrcDataSize], &Data[DataPosInt*FrameSize], DataSize);
+ memcpy(&SrcData[SrcDataSize], &Data[pos], DataSize);
SrcDataSize += DataSize;
BufferSize -= DataSize;
@@ -718,7 +756,46 @@ ALvoid MixSource(ALsource *Source, ALCdevice *Device, ALuint SamplesToDo)
{
/* Crawl the buffer queue to fill in the temp buffer */
ALbufferlistitem *BufferListIter = BufferListItem;
- ALuint pos = DataPosInt*FrameSize;
+ ALuint pos;
+
+ if(DataPosInt >= BUFFER_PREPADDING)
+ pos = (DataPosInt-BUFFER_PREPADDING)*FrameSize;
+ else
+ {
+ pos = (BUFFER_PREPADDING-DataPosInt)*FrameSize;
+ while(pos > 0)
+ {
+ if(!BufferListIter->prev && !Looping)
+ {
+ ALuint DataSize = min(BufferSize, pos);
+
+ memset(&SrcData[SrcDataSize], (Bytes==1)?0x80:0, DataSize);
+ SrcDataSize += DataSize;
+ BufferSize -= DataSize;
+
+ pos = 0;
+ break;
+ }
+
+ if(Looping)
+ {
+ while(BufferListIter->next)
+ BufferListIter = BufferListIter->next;
+ }
+ else
+ BufferListIter = BufferListIter->prev;
+
+ if(BufferListIter->buffer)
+ {
+ if((ALuint)BufferListIter->buffer->size > pos)
+ {
+ pos = BufferListIter->buffer->size - pos;
+ break;
+ }
+ pos -= BufferListIter->buffer->size;
+ }
+ }
+ }
while(BufferListIter && BufferSize > 0)
{
@@ -757,7 +834,7 @@ ALvoid MixSource(ALsource *Source, ALCdevice *Device, ALuint SamplesToDo)
/* Figure out how many samples we can mix. */
DataSize64 = SrcDataSize / FrameSize;
- DataSize64 -= BUFFER_PADDING;
+ DataSize64 -= BUFFER_PADDING+BUFFER_PREPADDING;
DataSize64 <<= FRACTIONBITS;
DataSize64 -= increment;
@@ -775,6 +852,7 @@ ALvoid MixSource(ALsource *Source, ALCdevice *Device, ALuint SamplesToDo)
break;
}
+ SrcData += BUFFER_PREPADDING*FrameSize;
switch(Source->Resampler)
{
case POINT_RESAMPLER: