aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2012-01-26 16:49:11 -0800
committerChris Robinson <[email protected]>2012-01-26 16:53:21 -0800
commit3fda804217aff2ed3a4437013425f3fab7628e6a (patch)
tree6939286e9165ffd6eb3a5e7239b63175f9bf4f3a
parent1d1440ac645806ccba68bd1150404eeb98b1af1f (diff)
Pass the uncompressed sample count to LoadData and ConvertData for IMA4
-rw-r--r--OpenAL32/alBuffer.c97
1 files changed, 56 insertions, 41 deletions
diff --git a/OpenAL32/alBuffer.c b/OpenAL32/alBuffer.c
index a803eea7..b7f034be 100644
--- a/OpenAL32/alBuffer.c
+++ b/OpenAL32/alBuffer.c
@@ -330,6 +330,8 @@ AL_API ALvoid AL_APIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid
enum UserFmtType SrcType;
ALCcontext *Context;
ALCdevice *device;
+ ALuint FrameSize;
+ ALenum NewFormat;
ALbuffer *ALBuf;
ALenum err;
@@ -351,8 +353,8 @@ AL_API ALvoid AL_APIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid
case UserFmtUShort:
case UserFmtInt:
case UserFmtUInt:
- case UserFmtFloat: {
- ALuint FrameSize = FrameSizeFromUserFmt(SrcChannels, SrcType);
+ case UserFmtFloat:
+ FrameSize = FrameSizeFromUserFmt(SrcChannels, SrcType);
if((size%FrameSize) != 0)
err = AL_INVALID_VALUE;
else
@@ -360,13 +362,13 @@ AL_API ALvoid AL_APIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid
SrcChannels, SrcType, data, AL_TRUE);
if(err != AL_NO_ERROR)
alSetError(Context, err);
- } break;
+ break;
case UserFmtByte3:
case UserFmtUByte3:
- case UserFmtDouble: {
- ALuint FrameSize = FrameSizeFromUserFmt(SrcChannels, SrcType);
- ALenum NewFormat = AL_FORMAT_MONO_FLOAT32;
+ case UserFmtDouble:
+ FrameSize = FrameSizeFromUserFmt(SrcChannels, SrcType);
+ NewFormat = AL_FORMAT_MONO_FLOAT32;
switch(SrcChannels)
{
case UserFmtMono: NewFormat = AL_FORMAT_MONO_FLOAT32; break;
@@ -384,18 +386,37 @@ AL_API ALvoid AL_APIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid
SrcChannels, SrcType, data, AL_TRUE);
if(err != AL_NO_ERROR)
alSetError(Context, err);
- } break;
+ break;
case UserFmtMulaw:
case UserFmtAlaw:
+ FrameSize = FrameSizeFromUserFmt(SrcChannels, SrcType);
+ NewFormat = AL_FORMAT_MONO16;
+ switch(SrcChannels)
+ {
+ case UserFmtMono: NewFormat = AL_FORMAT_MONO16; break;
+ case UserFmtStereo: NewFormat = AL_FORMAT_STEREO16; break;
+ case UserFmtRear: NewFormat = AL_FORMAT_REAR16; break;
+ case UserFmtQuad: NewFormat = AL_FORMAT_QUAD16; break;
+ case UserFmtX51: NewFormat = AL_FORMAT_51CHN16; break;
+ case UserFmtX61: NewFormat = AL_FORMAT_61CHN16; break;
+ case UserFmtX71: NewFormat = AL_FORMAT_71CHN16; break;
+ }
+ if((size%FrameSize) != 0)
+ err = AL_INVALID_VALUE;
+ else
+ err = LoadData(ALBuf, freq, NewFormat, size/FrameSize,
+ SrcChannels, SrcType, data, AL_TRUE);
+ if(err != AL_NO_ERROR)
+ alSetError(Context, err);
+ break;
+
case UserFmtIMA4: {
/* Here is where things vary:
* nVidia and Apple use 64+1 sample frames per block -> block_size=36 bytes per channel
* Most PC sound software uses 2040+1 sample frames per block -> block_size=1024 bytes per channel
*/
- ALuint FrameSize = (SrcType == UserFmtIMA4) ?
- (ChannelsFromUserFmt(SrcChannels) * 36) :
- FrameSizeFromUserFmt(SrcChannels, SrcType);
+ ALuint FrameSize = ChannelsFromUserFmt(SrcChannels) * 36;
ALenum NewFormat = AL_FORMAT_MONO16;
switch(SrcChannels)
{
@@ -410,7 +431,7 @@ AL_API ALvoid AL_APIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid
if((size%FrameSize) != 0)
err = AL_INVALID_VALUE;
else
- err = LoadData(ALBuf, freq, NewFormat, size/FrameSize,
+ err = LoadData(ALBuf, freq, NewFormat, size/FrameSize*65,
SrcChannels, SrcType, data, AL_TRUE);
if(err != AL_NO_ERROR)
alSetError(Context, err);
@@ -468,11 +489,12 @@ AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(ALuint buffer,ALenum format,const
ALuint Bytes = BytesFromFmt(ALBuf->FmtType);
if(SrcType == UserFmtIMA4)
{
- /* offset -> byte offset, length -> block count */
+ /* offset -> byte offset, length -> sample count */
offset /= 36;
offset *= 65;
offset *= Bytes;
length /= original_align;
+ length *= 65;
}
else
{
@@ -513,15 +535,8 @@ AL_API void AL_APIENTRY alBufferSamplesSOFT(ALuint buffer,
alSetError(Context, AL_INVALID_ENUM);
else
{
- err = AL_NO_ERROR;
- if(type == UserFmtIMA4)
- {
- if((samples%65) == 0) samples /= 65;
- else err = AL_INVALID_VALUE;
- }
- if(err == AL_NO_ERROR)
- err = LoadData(ALBuf, samplerate, internalformat, samples,
- channels, type, data, AL_FALSE);
+ err = LoadData(ALBuf, samplerate, internalformat, samples,
+ channels, type, data, AL_FALSE);
if(err != AL_NO_ERROR)
alSetError(Context, err);
}
@@ -557,14 +572,10 @@ AL_API void AL_APIENTRY alBufferSubSamplesSOFT(ALuint buffer,
alSetError(Context, AL_INVALID_ENUM);
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);
else
{
/* offset -> byte offset */
offset *= FrameSize;
- /* samples -> IMA4 block count */
- if(type == UserFmtIMA4) samples /= 65;
ConvertData(&((ALubyte*)ALBuf->data)[offset], ALBuf->FmtType,
data, type,
ChannelsFromFmt(ALBuf->FmtChannels), samples);
@@ -609,8 +620,6 @@ AL_API void AL_APIENTRY alGetBufferSamplesSOFT(ALuint buffer,
{
/* offset -> byte offset */
offset *= FrameSize;
- /* samples -> IMA4 block count */
- if(type == UserFmtIMA4) samples /= 65;
ConvertData(data, type,
&((ALubyte*)ALBuf->data)[offset], ALBuf->FmtType,
ChannelsFromFmt(ALBuf->FmtChannels), samples);
@@ -1784,16 +1793,22 @@ DECL_TEMPLATE(ALubyte3, ALubyte3)
#define DECL_TEMPLATE(T) \
static void Convert_##T##_ALima4(T *dst, const ALima4 *src, ALuint numchans, \
- ALuint numblocks) \
+ ALuint len) \
{ \
- ALuint i, j; \
ALshort tmp[65*MAXCHANNELS]; /* Max samples an IMA4 frame can be */ \
- for(i = 0;i < numblocks;i++) \
+ ALuint i, j, k; \
+ \
+ i = 0; \
+ while(i < len) \
{ \
DecodeIMA4Block(tmp, src, numchans); \
src += 36*numchans; \
- for(j = 0;j < 65*numchans;j++) \
- *(dst++) = Conv_##T##_ALshort(tmp[j]); \
+ \
+ for(j = 0;j < 65 && i < len;j++,i++) \
+ { \
+ for(k = 0;k < numchans;k++) \
+ *(dst++) = Conv_##T##_ALshort(tmp[j*numchans + k]); \
+ } \
} \
}
@@ -1814,13 +1829,14 @@ DECL_TEMPLATE(ALubyte3)
#define DECL_TEMPLATE(T) \
static void Convert_ALima4_##T(ALima4 *dst, const T *src, ALuint numchans, \
- ALuint numblocks) \
+ ALuint len) \
{ \
- ALuint i, j; \
ALshort tmp[65*MAXCHANNELS]; /* Max samples an IMA4 frame can be */ \
ALint sample[MAXCHANNELS] = {0,0,0,0,0,0,0,0}; \
ALint index[MAXCHANNELS] = {0,0,0,0,0,0,0,0}; \
- for(i = 0;i < numblocks;i++) \
+ ALuint i, j; \
+ \
+ for(i = 0;i < len;i += 65) \
{ \
for(j = 0;j < 65*numchans;j++) \
tmp[j] = Conv_ALshort_##T(*(src++)); \
@@ -1982,8 +1998,6 @@ static ALenum LoadData(ALbuffer *ALBuf, ALuint freq, ALenum NewFormat, ALsizei f
NewBytes = BytesFromFmt(DstType);
newsize = frames;
- if(SrcType == UserFmtIMA4)
- newsize *= 65;
newsize *= NewBytes;
newsize *= NewChannels;
if(newsize > INT_MAX)
@@ -2011,9 +2025,10 @@ static ALenum LoadData(ALbuffer *ALBuf, ALuint freq, ALenum NewFormat, ALsizei f
{
ALBuf->OriginalChannels = SrcChannels;
ALBuf->OriginalType = SrcType;
- ALBuf->OriginalSize = frames * ((SrcType == UserFmtIMA4) ? 36 :
- BytesFromUserFmt(SrcType)) *
- ChannelsFromUserFmt(SrcChannels);
+ if(SrcType == UserFmtIMA4)
+ ALBuf->OriginalSize = frames / 65 * 36 * ChannelsFromUserFmt(SrcChannels);
+ else
+ ALBuf->OriginalSize = frames * FrameSizeFromUserFmt(SrcChannels, SrcType);
}
else
{
@@ -2027,7 +2042,7 @@ static ALenum LoadData(ALbuffer *ALBuf, ALuint freq, ALenum NewFormat, ALsizei f
ALBuf->FmtType = DstType;
ALBuf->Format = NewFormat;
- ALBuf->SampleLen = frames * ((SrcType == UserFmtIMA4) ? 65 : 1);
+ ALBuf->SampleLen = frames;
ALBuf->LoopStart = 0;
ALBuf->LoopEnd = ALBuf->SampleLen;