Store the decomposed source format in the buffer

This commit is contained in:
Chris Robinson 2010-11-29 19:27:33 -08:00
parent 547f356131
commit e4869b447c
3 changed files with 60 additions and 54 deletions

View File

@ -75,9 +75,10 @@ typedef struct ALbuffer
enum FmtChannels FmtChannels;
enum FmtType FmtType;
ALenum OriginalFormat;
ALsizei OriginalSize;
ALsizei OriginalAlign;
enum SrcFmtChannels OriginalChannels;
enum SrcFmtType OriginalType;
ALsizei OriginalSize;
ALsizei OriginalAlign;
ALsizei LoopStart;
ALsizei LoopEnd;

View File

@ -390,9 +390,11 @@ AL_API ALvoid AL_APIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid
ALBuf->LoopStart = 0;
ALBuf->LoopEnd = newsize / Channels / NewBytes;
ALBuf->OriginalFormat = format;
ALBuf->OriginalSize = size;
ALBuf->OriginalAlign = 36 * Channels;
ALBuf->OriginalChannels = ((Channels==1) ? SrcFmtMono :
SrcFmtStereo);
ALBuf->OriginalType = SrcFmtIMA4;
ALBuf->OriginalSize = size;
ALBuf->OriginalAlign = 36 * Channels;
}
else
alSetError(Context, AL_OUT_OF_MEMORY);
@ -440,8 +442,6 @@ AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(ALuint buffer,ALenum format,const
alSetError(Context, AL_INVALID_NAME);
else if(length < 0 || offset < 0 || (length > 0 && data == NULL))
alSetError(Context, AL_INVALID_VALUE);
else if(ALBuf->OriginalFormat != format)
alSetError(Context, AL_INVALID_ENUM);
else if(offset > ALBuf->OriginalSize ||
length > ALBuf->OriginalSize-offset ||
(offset%ALBuf->OriginalAlign) != 0 ||
@ -481,32 +481,47 @@ AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(ALuint buffer,ALenum format,const
case AL_FORMAT_71CHN16:
case AL_FORMAT_71CHN32:
case AL_FORMAT_71CHN_MULAW: {
ALuint OldBytes = aluBytesFromFormat(format);
ALuint Bytes = BytesFromFmt(ALBuf->FmtType);
enum SrcFmtChannels SrcChannels;
enum SrcFmtType SrcType;
offset /= OldBytes;
offset *= Bytes;
length /= OldBytes;
DecomposeInputFormat(format, &SrcChannels, &SrcType);
ConvertData(&((ALubyte*)ALBuf->data)[offset], ALBuf->FmtType,
data, SrcType, length);
if(SrcChannels != ALBuf->OriginalChannels || SrcType != ALBuf->OriginalType)
alSetError(Context, AL_INVALID_ENUM);
else
{
ALuint OldBytes = BytesFromFmt(SrcType);
ALuint Bytes = BytesFromFmt(ALBuf->FmtType);
offset /= OldBytes;
offset *= Bytes;
length /= OldBytes;
ConvertData(&((ALubyte*)ALBuf->data)[offset], ALBuf->FmtType,
data, SrcType, length);
}
} break;
case AL_FORMAT_MONO_IMA4:
case AL_FORMAT_STEREO_IMA4: {
ALuint Channels = ChannelsFromFmt(ALBuf->FmtChannels);
ALuint Bytes = BytesFromFmt(ALBuf->FmtType);
enum SrcFmtChannels SrcChannels;
enum SrcFmtType SrcType;
/* offset -> byte offset, length -> block count */
offset /= 36;
offset *= 65;
offset *= Bytes;
length /= ALBuf->OriginalAlign;
DecomposeInputFormat(format, &SrcChannels, &SrcType);
if(SrcChannels != ALBuf->OriginalChannels || SrcType != SrcFmtIMA4)
alSetError(Context, AL_INVALID_ENUM);
else
{
ALuint Channels = ChannelsFromFmt(ALBuf->FmtChannels);
ALuint Bytes = BytesFromFmt(ALBuf->FmtType);
ConvertDataIMA4(&((ALubyte*)ALBuf->data)[offset], data, Channels, length);
/* offset -> byte offset, length -> block count */
offset /= 36;
offset *= 65;
offset *= Bytes;
length /= ALBuf->OriginalAlign;
ConvertDataIMA4(&((ALubyte*)ALBuf->data)[offset], data, Channels, length);
}
} break;
default:
@ -1356,9 +1371,10 @@ static ALenum LoadData(ALbuffer *ALBuf, const ALvoid *data, ALsizei size, ALuint
ALBuf->LoopStart = 0;
ALBuf->LoopEnd = newsize / NewChannels / NewBytes;
ALBuf->OriginalFormat = OrigFormat;
ALBuf->OriginalSize = size;
ALBuf->OriginalAlign = OrigBytes * OrigChannels;
ALBuf->OriginalChannels = SrcChannels;
ALBuf->OriginalType = SrcType;
ALBuf->OriginalSize = size;
ALBuf->OriginalAlign = OrigBytes * OrigChannels;
return AL_NO_ERROR;
}

View File

@ -50,7 +50,6 @@ static ALvoid InitSourceParams(ALsource *Source);
static ALvoid GetSourceOffset(ALsource *Source, ALenum eName, ALdouble *Offsets, ALdouble updateLen);
static ALboolean ApplyOffset(ALsource *Source);
static ALint GetByteOffset(ALsource *Source);
static ALint FramesFromBytes(ALint offset, ALenum format);
#define LookupSource(m, k) ((ALsource*)LookupUIntMapKey(&(m), (k)))
#define LookupBuffer(m, k) ((ALbuffer*)LookupUIntMapKey(&(m), (k)))
@ -1613,7 +1612,8 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint source, ALsizei n, const A
Source->NeedsUpdate = AL_TRUE;
}
else if(BufferFmt->Frequency != buffer->Frequency ||
BufferFmt->OriginalFormat != buffer->OriginalFormat)
BufferFmt->OriginalChannels != buffer->OriginalChannels ||
BufferFmt->OriginalType != buffer->OriginalType)
{
alSetError(Context, AL_INVALID_OPERATION);
goto done;
@ -1804,7 +1804,7 @@ static ALvoid GetSourceOffset(ALsource *Source, ALenum name, ALdouble *offset, A
ALfloat BufferFreq;
ALint Channels, Bytes;
ALuint readPos, writePos;
ALenum OriginalFormat;
enum SrcFmtType OriginalType;
ALuint TotalBufferDataSize;
ALuint i;
@ -1829,7 +1829,7 @@ static ALvoid GetSourceOffset(ALsource *Source, ALenum name, ALdouble *offset, A
// Get Current Buffer Size and frequency (in milliseconds)
BufferFreq = (ALfloat)Buffer->Frequency;
OriginalFormat = Buffer->OriginalFormat;
OriginalType = Buffer->OriginalType;
Channels = ChannelsFromFmt(Buffer->FmtChannels);
Bytes = BytesFromFmt(Buffer->FmtType);
@ -1881,8 +1881,7 @@ static ALvoid GetSourceOffset(ALsource *Source, ALenum name, ALdouble *offset, A
case AL_BYTE_OFFSET:
case AL_BYTE_RW_OFFSETS_SOFT:
// Take into account the original format of the Buffer
if((OriginalFormat == AL_FORMAT_MONO_IMA4) ||
(OriginalFormat == AL_FORMAT_STEREO_IMA4))
if(OriginalType == SrcFmtIMA4)
{
ALuint FrameBlockSize = 65 * Bytes * Channels;
ALuint BlockSize = 36 * Channels;
@ -1900,7 +1899,7 @@ static ALvoid GetSourceOffset(ALsource *Source, ALenum name, ALdouble *offset, A
}
else
{
ALuint OrigBytes = aluBytesFromFormat(OriginalFormat);
ALuint OrigBytes = BytesFromSrcFmt(OriginalType);
offset[0] = (ALdouble)(readPos / Bytes * OrigBytes);
offset[1] = (ALdouble)(writePos / Bytes * OrigBytes);
}
@ -2005,7 +2004,16 @@ static ALint GetByteOffset(ALsource *Source)
{
case AL_BYTE_OFFSET:
// Take into consideration the original format
ByteOffset = FramesFromBytes(Source->lOffset, Buffer->OriginalFormat);
ByteOffset = Source->lOffset;
if(Buffer->OriginalType == SrcFmtIMA4)
{
// Round down to nearest ADPCM block
ByteOffset /= 36 * ChannelsFromSrcFmt(Buffer->OriginalChannels);
// Multiply by compression rate (65 sample frames per block)
ByteOffset *= 65;
}
else
ByteOffset /= FrameSizeFromSrcFmt(Buffer->OriginalChannels, Buffer->OriginalType);
ByteOffset *= FrameSizeFromFmt(Buffer->FmtType, Buffer->FmtChannels);
break;
@ -2025,25 +2033,6 @@ static ALint GetByteOffset(ALsource *Source)
return ByteOffset;
}
static ALint FramesFromBytes(ALint offset, ALenum format)
{
if(format==AL_FORMAT_MONO_IMA4)
{
// Round down to nearest ADPCM block
offset /= 36;
// Multiply by compression rate (65 sample frames per block)
offset *= 65;
}
else if(format==AL_FORMAT_STEREO_IMA4)
{
offset /= 36 * 2;
offset *= 65;
}
else
offset /= aluFrameSizeFromFormat(format);
return offset;
}
ALvoid ReleaseALSources(ALCcontext *Context)
{