aboutsummaryrefslogtreecommitdiffstats
path: root/OpenAL32/alSource.c
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2011-10-03 10:07:50 -0700
committerChris Robinson <[email protected]>2011-10-04 02:08:45 -0700
commit11caba9807550a01ec5b81f50a6c744b3506115d (patch)
tree46f060fbea6f49ac1e8c269ee55ce61f6aa8cc52 /OpenAL32/alSource.c
parent35b4b31d57205f0f358202d9e41b594b9465b22b (diff)
Use sample frames when handling the buffer length
Diffstat (limited to 'OpenAL32/alSource.c')
-rw-r--r--OpenAL32/alSource.c116
1 files changed, 53 insertions, 63 deletions
diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c
index 80c5a91b..9080b46b 100644
--- a/OpenAL32/alSource.c
+++ b/OpenAL32/alSource.c
@@ -48,7 +48,7 @@ const ALsizei ResamplerPrePadding[RESAMPLER_MAX] = {
static ALvoid InitSourceParams(ALsource *Source);
static ALvoid GetSourceOffset(ALsource *Source, ALenum eName, ALdouble *Offsets, ALdouble updateLen);
-static ALint GetByteOffset(ALsource *Source);
+static ALint GetSampleOffset(ALsource *Source);
AL_API ALvoid AL_APIENTRY alGenSources(ALsizei n,ALuint *sources)
@@ -1866,7 +1866,7 @@ ALvoid SetSourceState(ALsource *Source, ALCcontext *Context, ALenum state)
BufferList = Source->queue;
while(BufferList)
{
- if(BufferList->buffer != NULL && BufferList->buffer->size)
+ if(BufferList->buffer != NULL && BufferList->buffer->SampleLen)
break;
BufferList = BufferList->next;
}
@@ -1960,11 +1960,9 @@ static ALvoid GetSourceOffset(ALsource *Source, ALenum name, ALdouble *offset, A
{
const ALbufferlistitem *BufferList;
const ALbuffer *Buffer = NULL;
- enum UserFmtType OriginalType;
- ALsizei BufferFreq;
- ALint Channels, Bytes;
+ ALuint BufferFreq = 0;
ALuint readPos, writePos;
- ALuint TotalBufferDataSize;
+ ALuint totalBufferLen;
ALuint i;
// Find the first non-NULL Buffer in the Queue
@@ -1974,6 +1972,7 @@ static ALvoid GetSourceOffset(ALsource *Source, ALenum name, ALdouble *offset, A
if(BufferList->buffer)
{
Buffer = BufferList->buffer;
+ BufferFreq = Buffer->Frequency;
break;
}
BufferList = BufferList->next;
@@ -1986,64 +1985,58 @@ static ALvoid GetSourceOffset(ALsource *Source, ALenum name, ALdouble *offset, A
return;
}
- // Get Current Buffer Size and frequency (in milliseconds)
- BufferFreq = Buffer->Frequency;
- OriginalType = Buffer->OriginalType;
- Channels = ChannelsFromFmt(Buffer->FmtChannels);
- Bytes = BytesFromFmt(Buffer->FmtType);
-
- // Get Current BytesPlayed (NOTE : This is the byte offset into the *current* buffer)
- readPos = Source->position * Channels * Bytes;
- // Add byte length of any processed buffers in the queue
- TotalBufferDataSize = 0;
+ // Get Current SamplesPlayed (NOTE : This is the offset into the *current* buffer)
+ readPos = Source->position;
+ // Add length of any processed buffers in the queue
+ totalBufferLen = 0;
BufferList = Source->queue;
for(i = 0;BufferList;i++)
{
if(BufferList->buffer)
{
if(i < Source->BuffersPlayed)
- readPos += BufferList->buffer->size;
- TotalBufferDataSize += BufferList->buffer->size;
+ readPos += BufferList->buffer->SampleLen;
+ totalBufferLen += BufferList->buffer->SampleLen;
}
BufferList = BufferList->next;
}
if(Source->state == AL_PLAYING)
- writePos = readPos + ((ALuint)(updateLen*BufferFreq) * Channels * Bytes);
+ writePos = readPos + (ALuint)(updateLen*BufferFreq);
else
writePos = readPos;
if(Source->bLooping)
{
- readPos %= TotalBufferDataSize;
- writePos %= TotalBufferDataSize;
+ readPos %= totalBufferLen;
+ writePos %= totalBufferLen;
}
else
{
// Wrap positions back to 0
- if(readPos >= TotalBufferDataSize)
+ if(readPos >= totalBufferLen)
readPos = 0;
- if(writePos >= TotalBufferDataSize)
+ if(writePos >= totalBufferLen)
writePos = 0;
}
switch(name)
{
case AL_SEC_OFFSET:
- offset[0] = (ALdouble)readPos / (Channels * Bytes * BufferFreq);
- offset[1] = (ALdouble)writePos / (Channels * Bytes * BufferFreq);
+ offset[0] = (ALdouble)readPos / Buffer->Frequency;
+ offset[1] = (ALdouble)writePos / Buffer->Frequency;
break;
case AL_SAMPLE_OFFSET:
case AL_SAMPLE_RW_OFFSETS_SOFT:
- offset[0] = (ALdouble)(readPos / (Channels * Bytes));
- offset[1] = (ALdouble)(writePos / (Channels * Bytes));
+ offset[0] = (ALdouble)readPos;
+ offset[1] = (ALdouble)writePos;
break;
case AL_BYTE_OFFSET:
case AL_BYTE_RW_OFFSETS_SOFT:
// Take into account the original format of the Buffer
- if(OriginalType == UserFmtIMA4)
+ if(Buffer->OriginalType == UserFmtIMA4)
{
- ALuint FrameBlockSize = 65 * Bytes * Channels;
- ALuint BlockSize = 36 * Channels;
+ ALuint BlockSize = 36 * ChannelsFromFmt(Buffer->FmtChannels);
+ ALuint FrameBlockSize = 65;
// Round down to nearest ADPCM block
offset[0] = (ALdouble)(readPos / FrameBlockSize * BlockSize);
@@ -2058,9 +2051,9 @@ static ALvoid GetSourceOffset(ALsource *Source, ALenum name, ALdouble *offset, A
}
else
{
- ALuint OrigBytes = BytesFromUserFmt(OriginalType);
- offset[0] = (ALdouble)(readPos / Bytes * OrigBytes);
- offset[1] = (ALdouble)(writePos / Bytes * OrigBytes);
+ ALuint FrameSize = FrameSizeFromUserFmt(Buffer->OriginalChannels, Buffer->OriginalType);
+ offset[0] = (ALdouble)(readPos * FrameSize);
+ offset[1] = (ALdouble)(writePos * FrameSize);
}
break;
}
@@ -2077,45 +2070,44 @@ ALboolean ApplyOffset(ALsource *Source)
{
const ALbufferlistitem *BufferList;
const ALbuffer *Buffer;
- ALint lBufferSize, lTotalBufferSize;
- ALint BuffersPlayed;
- ALint lByteOffset;
+ ALint bufferLen, totalBufferLen;
+ ALint buffersPlayed;
+ ALint offset;
// Get true byte offset
- lByteOffset = GetByteOffset(Source);
+ offset = GetSampleOffset(Source);
// If the offset is invalid, don't apply it
- if(lByteOffset == -1)
+ if(offset == -1)
return AL_FALSE;
// Sort out the queue (pending and processed states)
BufferList = Source->queue;
- lTotalBufferSize = 0;
- BuffersPlayed = 0;
+ totalBufferLen = 0;
+ buffersPlayed = 0;
while(BufferList)
{
Buffer = BufferList->buffer;
- lBufferSize = Buffer ? Buffer->size : 0;
+ bufferLen = Buffer ? Buffer->SampleLen : 0;
- if(lBufferSize <= lByteOffset-lTotalBufferSize)
+ if(bufferLen <= offset-totalBufferLen)
{
// Offset is past this buffer so increment BuffersPlayed
- BuffersPlayed++;
+ buffersPlayed++;
}
- else if(lTotalBufferSize <= lByteOffset)
+ else if(totalBufferLen <= offset)
{
// Offset is within this buffer
- Source->BuffersPlayed = BuffersPlayed;
+ Source->BuffersPlayed = buffersPlayed;
// SW Mixer Positions are in Samples
- Source->position = (lByteOffset - lTotalBufferSize) /
- FrameSizeFromFmt(Buffer->FmtChannels, Buffer->FmtType);
+ Source->position = offset - totalBufferLen;
return AL_TRUE;
}
// Increment the TotalBufferSize
- lTotalBufferSize += lBufferSize;
+ totalBufferLen += bufferLen;
// Move on to next buffer in the Queue
BufferList = BufferList->next;
@@ -2126,17 +2118,17 @@ ALboolean ApplyOffset(ALsource *Source)
/*
- GetByteOffset
+ GetSampleOffset
- Returns the 'true' byte offset into the Source's queue (from the Sample, Byte or Millisecond
- offset supplied by the application). This takes into account the fact that the buffer format
- may have been modifed by AL (e.g 8bit samples are converted to float)
+ Returns the sample offset into the Source's queue (from the Sample, Byte or Millisecond offset
+ supplied by the application). This takes into account the fact that the buffer format may have
+ been modifed by AL
*/
-static ALint GetByteOffset(ALsource *Source)
+static ALint GetSampleOffset(ALsource *Source)
{
const ALbuffer *Buffer = NULL;
const ALbufferlistitem *BufferList;
- ALint ByteOffset = -1;
+ ALint Offset = -1;
// Find the first non-NULL Buffer in the Queue
BufferList = Source->queue;
@@ -2161,33 +2153,31 @@ static ALint GetByteOffset(ALsource *Source)
{
case AL_BYTE_OFFSET:
// Take into consideration the original format
- ByteOffset = Source->lOffset;
+ Offset = Source->lOffset;
if(Buffer->OriginalType == UserFmtIMA4)
{
// Round down to nearest ADPCM block
- ByteOffset /= 36 * ChannelsFromUserFmt(Buffer->OriginalChannels);
+ Offset /= 36 * ChannelsFromUserFmt(Buffer->OriginalChannels);
// Multiply by compression rate (65 sample frames per block)
- ByteOffset *= 65;
+ Offset *= 65;
}
else
- ByteOffset /= FrameSizeFromUserFmt(Buffer->OriginalChannels, Buffer->OriginalType);
- ByteOffset *= FrameSizeFromFmt(Buffer->FmtChannels, Buffer->FmtType);
+ Offset /= FrameSizeFromUserFmt(Buffer->OriginalChannels, Buffer->OriginalType);
break;
case AL_SAMPLE_OFFSET:
- ByteOffset = Source->lOffset * FrameSizeFromFmt(Buffer->FmtChannels, Buffer->FmtType);
+ Offset = Source->lOffset;
break;
case AL_SEC_OFFSET:
// Note - lOffset is internally stored as Milliseconds
- ByteOffset = (ALint)(Source->lOffset / 1000.0 * Buffer->Frequency);
- ByteOffset *= FrameSizeFromFmt(Buffer->FmtChannels, Buffer->FmtType);
+ Offset = (ALint)(Source->lOffset / 1000.0 * Buffer->Frequency);
break;
}
// Clear Offset
Source->lOffset = -1;
- return ByteOffset;
+ return Offset;
}