aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--OpenAL32/Include/alBuffer.h1
-rw-r--r--OpenAL32/alBuffer.c30
-rw-r--r--OpenAL32/alSource.c10
3 files changed, 29 insertions, 12 deletions
diff --git a/OpenAL32/Include/alBuffer.h b/OpenAL32/Include/alBuffer.h
index d22b3b9b..60f406c8 100644
--- a/OpenAL32/Include/alBuffer.h
+++ b/OpenAL32/Include/alBuffer.h
@@ -79,6 +79,7 @@ typedef struct ALbuffer {
enum UserFmtChannels OriginalChannels;
enum UserFmtType OriginalType;
ALsizei OriginalSize;
+ ALsizei OriginalAlign;
ALsizei LoopStart;
ALsizei LoopEnd;
diff --git a/OpenAL32/alBuffer.c b/OpenAL32/alBuffer.c
index d9c91c2f..669fa219 100644
--- a/OpenAL32/alBuffer.c
+++ b/OpenAL32/alBuffer.c
@@ -429,10 +429,17 @@ AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(ALuint buffer, ALenum format, cons
SET_ERROR_AND_GOTO(context, AL_INVALID_ENUM, done);
WriteLock(&albuf->lock);
- original_align = ((albuf->OriginalType == UserFmtIMA4) ?
- (ChannelsFromUserFmt(albuf->OriginalChannels)*36) :
- FrameSizeFromUserFmt(albuf->OriginalChannels,
- albuf->OriginalType));
+ if(albuf->OriginalType == UserFmtIMA4)
+ {
+ ALsizei align = (albuf->OriginalAlign-1)/2 + 4;
+ original_align = ChannelsFromUserFmt(albuf->OriginalChannels) * align;
+ }
+ else
+ {
+ original_align = FrameSizeFromUserFmt(albuf->OriginalChannels,
+ albuf->OriginalType) *
+ albuf->OriginalAlign;
+ }
if(srcchannels != albuf->OriginalChannels || srctype != albuf->OriginalType)
{
@@ -451,8 +458,8 @@ AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(ALuint buffer, ALenum format, cons
/* offset -> byte offset, length -> sample count */
if(srctype == UserFmtIMA4)
{
- offset = offset/36*65 * bytes;
- length = length/original_align * 65;
+ offset = offset/original_align * channels*bytes;
+ length = length/original_align * albuf->OriginalAlign;
}
else
{
@@ -1950,15 +1957,22 @@ static ALenum LoadData(ALbuffer *ALBuf, ALuint freq, ALenum NewFormat, ALsizei f
ALBuf->OriginalChannels = SrcChannels;
ALBuf->OriginalType = SrcType;
if(SrcType == UserFmtIMA4)
- ALBuf->OriginalSize = frames / 65 * 36 * ChannelsFromUserFmt(SrcChannels);
+ {
+ ALBuf->OriginalSize = frames / 65 * 36 * ChannelsFromUserFmt(SrcChannels);
+ ALBuf->OriginalAlign = 65;
+ }
else
- ALBuf->OriginalSize = frames * FrameSizeFromUserFmt(SrcChannels, SrcType);
+ {
+ ALBuf->OriginalSize = frames * FrameSizeFromUserFmt(SrcChannels, SrcType);
+ ALBuf->OriginalAlign = 1;
+ }
}
else
{
ALBuf->OriginalChannels = (enum UserFmtChannels)DstChannels;
ALBuf->OriginalType = (enum UserFmtType)DstType;
ALBuf->OriginalSize = frames * NewBytes * NewChannels;
+ ALBuf->OriginalAlign = 1;
}
ALBuf->Frequency = freq;
diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c
index 543910db..4a46b77e 100644
--- a/OpenAL32/alSource.c
+++ b/OpenAL32/alSource.c
@@ -2536,8 +2536,9 @@ static ALvoid GetSourceOffsets(const ALsource *Source, ALenum name, ALdouble *of
case AL_BYTE_RW_OFFSETS_SOFT:
if(Buffer->OriginalType == UserFmtIMA4)
{
- ALuint BlockSize = 36 * ChannelsFromFmt(Buffer->FmtChannels);
- ALuint FrameBlockSize = 65;
+ ALsizei align = (Buffer->OriginalAlign-1)/2 + 4;
+ ALuint BlockSize = align * ChannelsFromFmt(Buffer->FmtChannels);
+ ALuint FrameBlockSize = Buffer->OriginalAlign;
/* Round down to nearest ADPCM block */
offset[0] = (ALdouble)(readPos / FrameBlockSize * BlockSize);
@@ -2650,8 +2651,9 @@ static ALint GetSampleOffset(ALsource *Source)
Offset = (ALint)Source->Offset;
if(Buffer->OriginalType == UserFmtIMA4)
{
- Offset /= 36 * ChannelsFromUserFmt(Buffer->OriginalChannels);
- Offset *= 65;
+ ALsizei align = (Buffer->OriginalAlign-1)/2 + 4;
+ Offset /= align * ChannelsFromUserFmt(Buffer->OriginalChannels);
+ Offset *= Buffer->OriginalAlign;
}
else
Offset /= FrameSizeFromUserFmt(Buffer->OriginalChannels, Buffer->OriginalType);