Remove some assumptions of 16-bit internal storage
This commit is contained in:
+21
-13
@@ -303,6 +303,7 @@ ALAPI ALvoid ALAPIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *d
|
||||
case AL_FORMAT_REAR32: {
|
||||
ALuint NewFormat = AL_FORMAT_QUAD16;
|
||||
ALuint NewChannels = aluChannelsFromFormat(NewFormat);
|
||||
ALuint NewBytes = aluBytesFromFormat(NewFormat);
|
||||
ALuint OrigBytes = ((format==AL_FORMAT_REAR8) ? 1 :
|
||||
((format==AL_FORMAT_REAR16) ? 2 :
|
||||
4));
|
||||
@@ -319,17 +320,17 @@ ALAPI ALvoid ALAPIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *d
|
||||
size *= 2;
|
||||
|
||||
// Samples are converted to 16 bit here
|
||||
temp = realloc(ALBuf->data, (BUFFER_PADDING*NewChannels + size) * sizeof(ALshort));
|
||||
temp = realloc(ALBuf->data, (BUFFER_PADDING*NewChannels + size) * NewBytes);
|
||||
if(temp)
|
||||
{
|
||||
ALBuf->data = temp;
|
||||
ConvertDataRear(ALBuf->data, data, OrigBytes, size);
|
||||
|
||||
memset(&(ALBuf->data[size]), 0, BUFFER_PADDING*NewChannels*sizeof(ALshort));
|
||||
memset(&(ALBuf->data[size]), 0, BUFFER_PADDING*NewChannels*NewBytes);
|
||||
|
||||
ALBuf->format = NewFormat;
|
||||
ALBuf->eOriginalFormat = format;
|
||||
ALBuf->size = size*sizeof(ALshort);
|
||||
ALBuf->size = size*NewBytes;
|
||||
ALBuf->frequency = freq;
|
||||
}
|
||||
else
|
||||
@@ -365,6 +366,9 @@ ALAPI ALvoid ALAPIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *d
|
||||
case AL_FORMAT_MONO_IMA4:
|
||||
case AL_FORMAT_STEREO_IMA4: {
|
||||
int OrigChans = ((format==AL_FORMAT_MONO_IMA4) ? 1 : 2);
|
||||
ALuint NewFormat = ((OrigChans==1) ? AL_FORMAT_MONO16 :
|
||||
AL_FORMAT_STEREO16);
|
||||
ALuint NewBytes = aluBytesFromFormat(NewFormat);
|
||||
|
||||
// Here is where things vary:
|
||||
// nVidia and Apple use 64+1 samples per channel per block => block_size=36*chans bytes
|
||||
@@ -379,17 +383,17 @@ ALAPI ALvoid ALAPIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *d
|
||||
size *= 65;
|
||||
|
||||
// Allocate extra padding samples
|
||||
temp = realloc(ALBuf->data, (BUFFER_PADDING*OrigChans + size)*sizeof(ALshort));
|
||||
temp = realloc(ALBuf->data, (BUFFER_PADDING*OrigChans + size)*NewBytes);
|
||||
if(temp)
|
||||
{
|
||||
ALBuf->data = temp;
|
||||
ConvertDataIMA4(ALBuf->data, data, OrigChans, size/65);
|
||||
|
||||
memset(&(ALBuf->data[size]), 0, BUFFER_PADDING*sizeof(ALshort)*OrigChans);
|
||||
memset(&(ALBuf->data[size]), 0, BUFFER_PADDING*NewBytes*OrigChans);
|
||||
|
||||
ALBuf->format = ((OrigChans==1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16);
|
||||
ALBuf->eOriginalFormat = format;
|
||||
ALBuf->size = size*sizeof(ALshort);
|
||||
ALBuf->size = size*NewBytes;
|
||||
ALBuf->frequency = freq;
|
||||
}
|
||||
else
|
||||
@@ -468,6 +472,7 @@ ALvoid ALAPIENTRY alBufferSubDataEXT(ALuint buffer,ALenum format,const ALvoid *d
|
||||
ALuint OrigBytes = ((format==AL_FORMAT_REAR8) ? 1 :
|
||||
((format==AL_FORMAT_REAR16) ? 2 :
|
||||
4));
|
||||
ALuint NewBytes = aluBytesFromFormat(ALBuf->format);
|
||||
|
||||
if(ALBuf->eOriginalFormat != AL_FORMAT_REAR8 &&
|
||||
ALBuf->eOriginalFormat != AL_FORMAT_REAR16 &&
|
||||
@@ -477,7 +482,7 @@ ALvoid ALAPIENTRY alBufferSubDataEXT(ALuint buffer,ALenum format,const ALvoid *d
|
||||
break;
|
||||
}
|
||||
|
||||
if(ALBuf->size/4/sizeof(ALshort) < (ALuint)offset+length)
|
||||
if(ALBuf->size/4/NewBytes < (ALuint)offset+length)
|
||||
{
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
break;
|
||||
@@ -489,6 +494,7 @@ ALvoid ALAPIENTRY alBufferSubDataEXT(ALuint buffer,ALenum format,const ALvoid *d
|
||||
case AL_FORMAT_MONO_IMA4:
|
||||
case AL_FORMAT_STEREO_IMA4: {
|
||||
int Channels = aluChannelsFromFormat(ALBuf->format);
|
||||
ALuint Bytes = aluBytesFromFormat(ALBuf->format);
|
||||
|
||||
if(ALBuf->eOriginalFormat != format)
|
||||
{
|
||||
@@ -497,7 +503,7 @@ ALvoid ALAPIENTRY alBufferSubDataEXT(ALuint buffer,ALenum format,const ALvoid *d
|
||||
}
|
||||
|
||||
if((offset%65) != 0 || (length%65) != 0 ||
|
||||
ALBuf->size/Channels/sizeof(ALshort) < (ALuint)offset+length)
|
||||
ALBuf->size/Channels/Bytes < (ALuint)offset+length)
|
||||
{
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
break;
|
||||
@@ -509,6 +515,7 @@ ALvoid ALAPIENTRY alBufferSubDataEXT(ALuint buffer,ALenum format,const ALvoid *d
|
||||
default: {
|
||||
ALuint Channels = aluChannelsFromFormat(format);
|
||||
ALuint Bytes = aluBytesFromFormat(format);
|
||||
ALuint NewBytes = aluChannelsFromFormat(ALBuf->format);
|
||||
|
||||
if(Channels != aluChannelsFromFormat(ALBuf->format))
|
||||
{
|
||||
@@ -516,7 +523,7 @@ ALvoid ALAPIENTRY alBufferSubDataEXT(ALuint buffer,ALenum format,const ALvoid *d
|
||||
break;
|
||||
}
|
||||
|
||||
if(ALBuf->size/Channels/sizeof(ALshort) < (ALuint)offset+length)
|
||||
if(ALBuf->size/Channels/NewBytes < (ALuint)offset+length)
|
||||
{
|
||||
alSetError(AL_INVALID_VALUE);
|
||||
break;
|
||||
@@ -930,12 +937,13 @@ ALAPI void ALAPIENTRY alGetBufferiv(ALuint buffer, ALenum eParam, ALint* plValue
|
||||
*/
|
||||
static void LoadData(ALbuffer *ALBuf, const ALubyte *data, ALsizei size, ALuint freq, ALenum OrigFormat, ALenum NewFormat)
|
||||
{
|
||||
ALuint NewBytes = aluBytesFromFormat(NewFormat);
|
||||
ALuint NewChannels = aluChannelsFromFormat(NewFormat);
|
||||
ALuint OrigBytes = aluBytesFromFormat(OrigFormat);
|
||||
ALuint OrigChannels = aluChannelsFromFormat(OrigFormat);
|
||||
ALvoid *temp;
|
||||
|
||||
assert(aluBytesFromFormat(NewFormat) == 2);
|
||||
assert(NewBytes == 2);
|
||||
assert(NewChannels == OrigChannels);
|
||||
|
||||
if ((size%(OrigBytes*OrigChannels)) != 0)
|
||||
@@ -946,17 +954,17 @@ static void LoadData(ALbuffer *ALBuf, const ALubyte *data, ALsizei size, ALuint
|
||||
|
||||
// Samples are converted to 16 bit here
|
||||
size /= OrigBytes;
|
||||
temp = realloc(ALBuf->data, (BUFFER_PADDING*NewChannels + size) * sizeof(ALshort));
|
||||
temp = realloc(ALBuf->data, (BUFFER_PADDING*NewChannels + size) * NewBytes);
|
||||
if(temp)
|
||||
{
|
||||
ALBuf->data = temp;
|
||||
ConvertData(ALBuf->data, data, OrigBytes, size);
|
||||
|
||||
memset(&(ALBuf->data[size]), 0, BUFFER_PADDING*NewChannels*sizeof(ALshort));
|
||||
memset(&(ALBuf->data[size]), 0, BUFFER_PADDING*NewChannels*NewBytes);
|
||||
|
||||
ALBuf->format = NewFormat;
|
||||
ALBuf->eOriginalFormat = OrigFormat;
|
||||
ALBuf->size = size*sizeof(ALshort);
|
||||
ALBuf->size = size*NewBytes;
|
||||
ALBuf->frequency = freq;
|
||||
}
|
||||
else
|
||||
|
||||
+53
-31
@@ -1831,7 +1831,7 @@ static ALboolean GetSourceOffset(ALsource *pSource, ALenum eName, ALfloat *pflOf
|
||||
ALbufferlistitem *pBufferList;
|
||||
ALbuffer *pBuffer;
|
||||
ALfloat flBufferFreq;
|
||||
ALint lChannels;
|
||||
ALint lChannels, lBytes;
|
||||
ALint readPos, writePos;
|
||||
ALenum eOriginalFormat;
|
||||
ALboolean bReturn = AL_TRUE;
|
||||
@@ -1845,9 +1845,10 @@ static ALboolean GetSourceOffset(ALsource *pSource, ALenum eName, ALfloat *pflOf
|
||||
flBufferFreq = (ALfloat)pBuffer->frequency;
|
||||
eOriginalFormat = pBuffer->eOriginalFormat;
|
||||
lChannels = aluChannelsFromFormat(pBuffer->format);
|
||||
lBytes = aluBytesFromFormat(pBuffer->format);
|
||||
|
||||
// Get Current BytesPlayed
|
||||
readPos = pSource->position * lChannels * 2; // NOTE : This is the byte offset into the *current* buffer
|
||||
readPos = pSource->position * lChannels * lBytes; // NOTE : This is the byte offset into the *current* buffer
|
||||
// Add byte length of any processed buffers in the queue
|
||||
pBufferList = pSource->queue;
|
||||
for(i = 0;i < pSource->BuffersPlayed && pBufferList;i++)
|
||||
@@ -1857,7 +1858,7 @@ static ALboolean GetSourceOffset(ALsource *pSource, ALenum eName, ALfloat *pflOf
|
||||
}
|
||||
|
||||
if(pSource->state == AL_PLAYING)
|
||||
writePos = readPos + (updateSize * lChannels * 2);
|
||||
writePos = readPos + (updateSize * lChannels * lBytes);
|
||||
else
|
||||
writePos = readPos;
|
||||
|
||||
@@ -1898,13 +1899,13 @@ static ALboolean GetSourceOffset(ALsource *pSource, ALenum eName, ALfloat *pflOf
|
||||
{
|
||||
case AL_SEC_OFFSET:
|
||||
case AL_SEC_RW_OFFSETS_EXT:
|
||||
pflOffset[0] = (ALfloat)readPos / (lChannels * 2.0f * flBufferFreq);
|
||||
pflOffset[1] = (ALfloat)writePos / (lChannels * 2.0f * flBufferFreq);
|
||||
pflOffset[0] = (ALfloat)readPos / (lChannels * lBytes * flBufferFreq);
|
||||
pflOffset[1] = (ALfloat)writePos / (lChannels * lBytes * flBufferFreq);
|
||||
break;
|
||||
case AL_SAMPLE_OFFSET:
|
||||
case AL_SAMPLE_RW_OFFSETS_EXT:
|
||||
pflOffset[0] = (ALfloat)(readPos / (lChannels * 2));
|
||||
pflOffset[1] = (ALfloat)(writePos / (lChannels * 2));
|
||||
pflOffset[0] = (ALfloat)(readPos / (lChannels * lBytes));
|
||||
pflOffset[1] = (ALfloat)(writePos / (lChannels * lBytes));
|
||||
break;
|
||||
case AL_BYTE_OFFSET:
|
||||
case AL_BYTE_RW_OFFSETS_EXT:
|
||||
@@ -1913,34 +1914,44 @@ static ALboolean GetSourceOffset(ALsource *pSource, ALenum eName, ALfloat *pflOf
|
||||
(eOriginalFormat == AL_FORMAT_STEREO_IMA4))
|
||||
{
|
||||
// Round down to nearest ADPCM block
|
||||
pflOffset[0] = (ALfloat)((readPos / (65 * 2 * lChannels)) * 36 * lChannels);
|
||||
pflOffset[0] = (ALfloat)((readPos / (65 * lBytes * lChannels)) * 36 * lChannels);
|
||||
if(pSource->state == AL_PLAYING)
|
||||
{
|
||||
// Round up to nearest ADPCM block
|
||||
pflOffset[1] = (ALfloat)(((writePos + (65 * 2 * lChannels) - 1) / (65 * 2 * lChannels)) * 36 * lChannels);
|
||||
pflOffset[1] = (ALfloat)(((writePos + (65 * lBytes * lChannels) - 1) / (65 * lBytes * lChannels)) * 36 * lChannels);
|
||||
}
|
||||
else
|
||||
pflOffset[1] = pflOffset[0];
|
||||
}
|
||||
else if (eOriginalFormat == AL_FORMAT_REAR8)
|
||||
{
|
||||
pflOffset[0] = (ALfloat)(readPos >> 2);
|
||||
pflOffset[1] = (ALfloat)(writePos >> 2);
|
||||
pflOffset[0] = (ALfloat)(readPos / 2 / lBytes * 1);
|
||||
pflOffset[1] = (ALfloat)(writePos / 2 / lBytes * 1);
|
||||
}
|
||||
else if (eOriginalFormat == AL_FORMAT_REAR16)
|
||||
{
|
||||
pflOffset[0] = (ALfloat)(readPos >> 1);
|
||||
pflOffset[1] = (ALfloat)(writePos >> 1);
|
||||
pflOffset[0] = (ALfloat)(readPos / 2 / lBytes * 2);
|
||||
pflOffset[1] = (ALfloat)(writePos / 2 / lBytes * 2);
|
||||
}
|
||||
else if (eOriginalFormat == AL_FORMAT_REAR32)
|
||||
{
|
||||
pflOffset[0] = (ALfloat)(readPos / 2 / lBytes * 4);
|
||||
pflOffset[1] = (ALfloat)(writePos / 2 / lBytes * 4);
|
||||
}
|
||||
else if (aluBytesFromFormat(eOriginalFormat) == 1)
|
||||
{
|
||||
pflOffset[0] = (ALfloat)(readPos >> 1);
|
||||
pflOffset[1] = (ALfloat)(writePos >> 1);
|
||||
pflOffset[0] = (ALfloat)(readPos / lBytes * 1);
|
||||
pflOffset[1] = (ALfloat)(writePos / lBytes * 1);
|
||||
}
|
||||
else if (aluBytesFromFormat(eOriginalFormat) == 2)
|
||||
{
|
||||
pflOffset[0] = (ALfloat)(readPos / lBytes * 2);
|
||||
pflOffset[1] = (ALfloat)(writePos / lBytes * 2);
|
||||
}
|
||||
else if (aluBytesFromFormat(eOriginalFormat) == 4)
|
||||
{
|
||||
pflOffset[0] = (ALfloat)(readPos << 1);
|
||||
pflOffset[1] = (ALfloat)(writePos << 1);
|
||||
pflOffset[0] = (ALfloat)(readPos / lBytes * 4);
|
||||
pflOffset[1] = (ALfloat)(writePos / lBytes * 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2035,7 +2046,7 @@ static ALint GetByteOffset(ALsource *pSource)
|
||||
ALbuffer *pBuffer = NULL;
|
||||
ALbufferlistitem *pBufferList;
|
||||
ALfloat flBufferFreq;
|
||||
ALint lChannels;
|
||||
ALint lChannels, lBytes;
|
||||
ALint lByteOffset = -1;
|
||||
ALint lTotalBufferDataSize;
|
||||
|
||||
@@ -2055,6 +2066,7 @@ static ALint GetByteOffset(ALsource *pSource)
|
||||
{
|
||||
flBufferFreq = ((ALfloat)pBuffer->frequency);
|
||||
lChannels = aluChannelsFromFormat(pBuffer->format);
|
||||
lBytes = aluBytesFromFormat(pBuffer->format);
|
||||
|
||||
// Determine the ByteOffset (and ensure it is block aligned)
|
||||
switch (pSource->lOffsetType)
|
||||
@@ -2068,43 +2080,53 @@ static ALint GetByteOffset(ALsource *pSource)
|
||||
lByteOffset = (pSource->lOffset / (36 * lChannels)) * 36 * lChannels;
|
||||
// Multiply by compression rate
|
||||
lByteOffset = (ALint)(3.6111f * (ALfloat)lByteOffset);
|
||||
lByteOffset -= (lByteOffset % (lChannels * 2));
|
||||
lByteOffset -= (lByteOffset % (lChannels * lBytes));
|
||||
}
|
||||
else if (pBuffer->eOriginalFormat == AL_FORMAT_REAR8)
|
||||
{
|
||||
lByteOffset = pSource->lOffset * 4;
|
||||
lByteOffset -= (lByteOffset % (lChannels * 2));
|
||||
lByteOffset = pSource->lOffset / 1 * lBytes * 2;
|
||||
lByteOffset -= (lByteOffset % (lChannels * lBytes));
|
||||
}
|
||||
else if (pBuffer->eOriginalFormat == AL_FORMAT_REAR16)
|
||||
{
|
||||
lByteOffset = pSource->lOffset * 2;
|
||||
lByteOffset -= (lByteOffset % (lChannels * 2));
|
||||
lByteOffset = pSource->lOffset / 2 * lBytes * 2;
|
||||
lByteOffset -= (lByteOffset % (lChannels * lBytes));
|
||||
}
|
||||
else if (pBuffer->eOriginalFormat == AL_FORMAT_REAR32)
|
||||
{
|
||||
lByteOffset = pSource->lOffset / 4 * lBytes * 2;
|
||||
lByteOffset -= (lByteOffset % (lChannels * lBytes));
|
||||
}
|
||||
else if (aluBytesFromFormat(pBuffer->eOriginalFormat) == 1)
|
||||
{
|
||||
lByteOffset = pSource->lOffset * 2;
|
||||
lByteOffset -= (lByteOffset % (lChannels * 2));
|
||||
lByteOffset = pSource->lOffset / 1 * lBytes;
|
||||
lByteOffset -= (lByteOffset % (lChannels * lBytes));
|
||||
}
|
||||
else if (aluBytesFromFormat(pBuffer->eOriginalFormat) == 2)
|
||||
{
|
||||
lByteOffset = pSource->lOffset / 2 * lBytes;
|
||||
lByteOffset -= (lByteOffset % (lChannels * lBytes));
|
||||
}
|
||||
else if (aluBytesFromFormat(pBuffer->eOriginalFormat) == 4)
|
||||
{
|
||||
lByteOffset = pSource->lOffset / 2;
|
||||
lByteOffset -= (lByteOffset % (lChannels * 2));
|
||||
lByteOffset = pSource->lOffset / 4 * lBytes;
|
||||
lByteOffset -= (lByteOffset % (lChannels * lBytes));
|
||||
}
|
||||
else
|
||||
{
|
||||
lByteOffset = pSource->lOffset;
|
||||
lByteOffset -= (lByteOffset % (lChannels * 2));
|
||||
lByteOffset -= (lByteOffset % (lChannels * lBytes));
|
||||
}
|
||||
break;
|
||||
|
||||
case AL_SAMPLE_OFFSET:
|
||||
lByteOffset = pSource->lOffset * lChannels * 2;
|
||||
lByteOffset = pSource->lOffset * lChannels * lBytes;
|
||||
break;
|
||||
|
||||
case AL_SEC_OFFSET:
|
||||
// Note - lOffset is internally stored as Milliseconds
|
||||
lByteOffset = (ALint)(pSource->lOffset * lChannels * 2.0f * flBufferFreq / 1000.0f);
|
||||
lByteOffset -= (lByteOffset % (lChannels * 2));
|
||||
lByteOffset = (ALint)(pSource->lOffset * lChannels * lBytes * flBufferFreq / 1000.0f);
|
||||
lByteOffset -= (lByteOffset % (lChannels * lBytes));
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user