diff options
Diffstat (limited to 'OpenAL32')
-rw-r--r-- | OpenAL32/Include/alBuffer.h | 7 | ||||
-rw-r--r-- | OpenAL32/alBuffer.c | 48 | ||||
-rw-r--r-- | OpenAL32/alSource.c | 116 |
3 files changed, 73 insertions, 98 deletions
diff --git a/OpenAL32/Include/alBuffer.h b/OpenAL32/Include/alBuffer.h index 0a04316b..cacaa716 100644 --- a/OpenAL32/Include/alBuffer.h +++ b/OpenAL32/Include/alBuffer.h @@ -69,10 +69,11 @@ static __inline ALuint FrameSizeFromFmt(enum FmtChannels chans, enum FmtType typ typedef struct ALbuffer { ALvoid *data; - ALsizei size; - ALsizei Frequency; - ALenum Format; + ALsizei Frequency; + ALenum Format; + ALsizei SampleLen; + enum FmtChannels FmtChannels; enum FmtType FmtType; diff --git a/OpenAL32/alBuffer.c b/OpenAL32/alBuffer.c index 32cbbbcb..083a2fc1 100644 --- a/OpenAL32/alBuffer.c +++ b/OpenAL32/alBuffer.c @@ -550,14 +550,12 @@ AL_API void AL_APIENTRY alBufferSubSamplesSOFT(ALuint buffer, else { ALuint FrameSize; - ALsizei FrameCount; WriteLock(&ALBuf->lock); FrameSize = FrameSizeFromFmt(ALBuf->FmtChannels, ALBuf->FmtType); - FrameCount = ALBuf->size / FrameSize; if(channels != (ALenum)ALBuf->FmtChannels) alSetError(Context, AL_INVALID_ENUM); - else if(offset > FrameCount || samples > FrameCount-offset) + else if(offset > ALBuf->SampleLen || samples > ALBuf->SampleLen-offset) alSetError(Context, AL_INVALID_VALUE); else if(type == UserFmtIMA4 && (samples%65) != 0) alSetError(Context, AL_INVALID_VALUE); @@ -598,14 +596,12 @@ AL_API void AL_APIENTRY alGetBufferSamplesSOFT(ALuint buffer, else { ALuint FrameSize; - ALsizei FrameCount; ReadLock(&ALBuf->lock); FrameSize = FrameSizeFromFmt(ALBuf->FmtChannels, ALBuf->FmtType); - FrameCount = ALBuf->size / FrameSize; if(channels != (ALenum)ALBuf->FmtChannels) alSetError(Context, AL_INVALID_ENUM); - else if(offset > FrameCount || samples > FrameCount-offset) + else if(offset > ALBuf->SampleLen || samples > ALBuf->SampleLen-offset) alSetError(Context, AL_INVALID_VALUE); else if(type == UserFmtIMA4 && (samples%65) != 0) alSetError(Context, AL_INVALID_VALUE); @@ -804,20 +800,13 @@ AL_API void AL_APIENTRY alBufferiv(ALuint buffer, ALenum eParam, const ALint* pl WriteLock(&ALBuf->lock); if(ALBuf->ref != 0) alSetError(pContext, AL_INVALID_OPERATION); - else if(plValues[0] < 0 || plValues[1] < 0 || - plValues[0] >= plValues[1] || ALBuf->size == 0) + else if(plValues[0] >= plValues[1] || plValues[0] < 0 || + plValues[1] > ALBuf->SampleLen) alSetError(pContext, AL_INVALID_VALUE); else { - ALint maxlen = ALBuf->size / - FrameSizeFromFmt(ALBuf->FmtChannels, ALBuf->FmtType); - if(plValues[0] > maxlen || plValues[1] > maxlen) - alSetError(pContext, AL_INVALID_VALUE); - else - { - ALBuf->LoopStart = plValues[0]; - ALBuf->LoopEnd = plValues[1]; - } + ALBuf->LoopStart = plValues[0]; + ALBuf->LoopEnd = plValues[1]; } WriteUnlock(&ALBuf->lock); break; @@ -852,10 +841,8 @@ AL_API ALvoid AL_APIENTRY alGetBufferf(ALuint buffer, ALenum eParam, ALfloat *pf { case AL_SEC_LENGTH: ReadLock(&pBuffer->lock); - if(pBuffer->size != 0) - *pflValue = (pBuffer->size / - FrameSizeFromFmt(pBuffer->FmtChannels, pBuffer->FmtType)) / - (ALfloat)pBuffer->Frequency; + if(pBuffer->SampleLen != 0) + *pflValue = pBuffer->SampleLen / (ALfloat)pBuffer->Frequency; else *pflValue = 0.0f; ReadUnlock(&pBuffer->lock); @@ -963,7 +950,10 @@ AL_API ALvoid AL_APIENTRY alGetBufferi(ALuint buffer, ALenum eParam, ALint *plVa break; case AL_SIZE: - *plValue = pBuffer->size; + ReadLock(&pBuffer->lock); + *plValue = pBuffer->SampleLen * + FrameSizeFromFmt(pBuffer->FmtChannels, pBuffer->FmtType); + ReadUnlock(&pBuffer->lock); break; case AL_INTERNAL_FORMAT: @@ -975,13 +965,7 @@ AL_API ALvoid AL_APIENTRY alGetBufferi(ALuint buffer, ALenum eParam, ALint *plVa break; case AL_SAMPLE_LENGTH: - ReadLock(&pBuffer->lock); - if(pBuffer->size != 0) - *plValue = pBuffer->size / - FrameSizeFromFmt(pBuffer->FmtChannels, pBuffer->FmtType); - else - *plValue = 0; - ReadUnlock(&pBuffer->lock); + *plValue = pBuffer->SampleLen; break; default: @@ -2028,7 +2012,7 @@ static ALenum LoadData(ALbuffer *ALBuf, ALuint freq, ALenum NewFormat, ALsizei f return AL_OUT_OF_MEMORY; } ALBuf->data = temp; - ALBuf->size = (ALsizei)newsize; + ALBuf->SampleLen = frames*65; if(data != NULL) ConvertData(ALBuf->data, DstType, data, SrcType, NewChannels, frames); @@ -2061,7 +2045,7 @@ static ALenum LoadData(ALbuffer *ALBuf, ALuint freq, ALenum NewFormat, ALsizei f return AL_OUT_OF_MEMORY; } ALBuf->data = temp; - ALBuf->size = (ALsizei)newsize; + ALBuf->SampleLen = frames; if(data != NULL) ConvertData(ALBuf->data, DstType, data, SrcType, NewChannels, frames); @@ -2086,7 +2070,7 @@ static ALenum LoadData(ALbuffer *ALBuf, ALuint freq, ALenum NewFormat, ALsizei f ALBuf->Format = NewFormat; ALBuf->LoopStart = 0; - ALBuf->LoopEnd = (ALsizei)(newsize / NewChannels / NewBytes); + ALBuf->LoopEnd = ALBuf->SampleLen; WriteUnlock(&ALBuf->lock); return AL_NO_ERROR; 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; } |