Internally store 32-bit float buffer data, and mix accordingly
This commit is contained in:
parent
9286e3984c
commit
4697e946d3
23
Alc/ALu.c
23
Alc/ALu.c
@ -61,18 +61,23 @@ ALboolean DuplicateStereo = AL_FALSE;
|
||||
|
||||
static __inline ALfloat aluF2F(ALfloat Value)
|
||||
{
|
||||
if(Value < 0.f) return Value/32768.f;
|
||||
if(Value > 0.f) return Value/32767.f;
|
||||
return 0.f;
|
||||
return Value;
|
||||
}
|
||||
|
||||
static __inline ALshort aluF2S(ALfloat Value)
|
||||
{
|
||||
ALint i;
|
||||
|
||||
i = (ALint)Value;
|
||||
i = __min( 32767, i);
|
||||
i = __max(-32768, i);
|
||||
if(Value < 0.0f)
|
||||
{
|
||||
i = (ALint)(Value*32768.0f);
|
||||
i = max(-32768, i);
|
||||
}
|
||||
else
|
||||
{
|
||||
i = (ALint)(Value*32767.0f);
|
||||
i = min( 32767, i);
|
||||
}
|
||||
return ((ALshort)i);
|
||||
}
|
||||
|
||||
@ -852,9 +857,9 @@ static ALvoid CalcSourceParams(const ALCcontext *ALContext, ALsource *ALSource,
|
||||
}
|
||||
}
|
||||
|
||||
static __inline ALshort lerp(ALshort val1, ALshort val2, ALint frac)
|
||||
static __inline ALfloat lerp(ALfloat val1, ALfloat val2, ALint frac)
|
||||
{
|
||||
return val1 + (((val2-val1)*frac)>>FRACTIONBITS);
|
||||
return val1 + ((val2-val1)*(frac * (1.0f/(1<<FRACTIONBITS))));
|
||||
}
|
||||
|
||||
static void MixSomeSources(ALCcontext *ALContext, float (*DryBuffer)[OUTPUTCHANNELS], ALuint SamplesToDo)
|
||||
@ -984,7 +989,7 @@ another_source:
|
||||
{
|
||||
ALuint DataSize = 0;
|
||||
ALbuffer *ALBuffer;
|
||||
ALshort *Data;
|
||||
ALfloat *Data;
|
||||
ALuint BufferSize;
|
||||
|
||||
/* Get buffer info */
|
||||
|
@ -11,7 +11,7 @@ extern "C" {
|
||||
|
||||
typedef struct ALbuffer
|
||||
{
|
||||
ALshort *data;
|
||||
ALfloat *data;
|
||||
ALsizei size;
|
||||
|
||||
ALenum format;
|
||||
|
@ -33,9 +33,9 @@
|
||||
|
||||
|
||||
static void LoadData(ALbuffer *ALBuf, const ALubyte *data, ALsizei size, ALuint freq, ALenum OrigFormat, ALenum NewFormat);
|
||||
static void ConvertData(ALshort *dst, const ALvoid *src, ALint origBytes, ALsizei len);
|
||||
static void ConvertDataRear(ALshort *dst, const ALvoid *src, ALint origBytes, ALsizei len);
|
||||
static void ConvertDataIMA4(ALshort *dst, const ALvoid *src, ALint origChans, ALsizei len);
|
||||
static void ConvertData(ALfloat *dst, const ALvoid *src, ALint origBytes, ALsizei len);
|
||||
static void ConvertDataRear(ALfloat *dst, const ALvoid *src, ALint origBytes, ALsizei len);
|
||||
static void ConvertDataIMA4(ALfloat *dst, const ALvoid *src, ALint origChans, ALsizei len);
|
||||
|
||||
/*
|
||||
* AL Buffer Functions
|
||||
@ -289,19 +289,19 @@ ALAPI ALvoid ALAPIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *d
|
||||
case AL_FORMAT_MONO8:
|
||||
case AL_FORMAT_MONO16:
|
||||
case AL_FORMAT_MONO_FLOAT32:
|
||||
LoadData(ALBuf, data, size, freq, format, AL_FORMAT_MONO16);
|
||||
LoadData(ALBuf, data, size, freq, format, AL_FORMAT_MONO_FLOAT32);
|
||||
break;
|
||||
|
||||
case AL_FORMAT_STEREO8:
|
||||
case AL_FORMAT_STEREO16:
|
||||
case AL_FORMAT_STEREO_FLOAT32:
|
||||
LoadData(ALBuf, data, size, freq, format, AL_FORMAT_STEREO16);
|
||||
LoadData(ALBuf, data, size, freq, format, AL_FORMAT_STEREO_FLOAT32);
|
||||
break;
|
||||
|
||||
case AL_FORMAT_REAR8:
|
||||
case AL_FORMAT_REAR16:
|
||||
case AL_FORMAT_REAR32: {
|
||||
ALuint NewFormat = AL_FORMAT_QUAD16;
|
||||
ALuint NewFormat = AL_FORMAT_QUAD32;
|
||||
ALuint NewChannels = aluChannelsFromFormat(NewFormat);
|
||||
ALuint NewBytes = aluBytesFromFormat(NewFormat);
|
||||
ALuint OrigBytes = ((format==AL_FORMAT_REAR8) ? 1 :
|
||||
@ -319,15 +319,13 @@ ALAPI ALvoid ALAPIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *d
|
||||
size /= OrigBytes;
|
||||
size *= 2;
|
||||
|
||||
// Samples are converted to 16 bit here
|
||||
// Samples are converted here
|
||||
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*NewBytes);
|
||||
|
||||
ALBuf->format = NewFormat;
|
||||
ALBuf->eOriginalFormat = format;
|
||||
ALBuf->size = size*NewBytes;
|
||||
@ -342,32 +340,32 @@ ALAPI ALvoid ALAPIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *d
|
||||
case AL_FORMAT_QUAD8:
|
||||
case AL_FORMAT_QUAD16:
|
||||
case AL_FORMAT_QUAD32:
|
||||
LoadData(ALBuf, data, size, freq, format, AL_FORMAT_QUAD16);
|
||||
LoadData(ALBuf, data, size, freq, format, AL_FORMAT_QUAD32);
|
||||
break;
|
||||
|
||||
case AL_FORMAT_51CHN8:
|
||||
case AL_FORMAT_51CHN16:
|
||||
case AL_FORMAT_51CHN32:
|
||||
LoadData(ALBuf, data, size, freq, format, AL_FORMAT_51CHN16);
|
||||
LoadData(ALBuf, data, size, freq, format, AL_FORMAT_51CHN32);
|
||||
break;
|
||||
|
||||
case AL_FORMAT_61CHN8:
|
||||
case AL_FORMAT_61CHN16:
|
||||
case AL_FORMAT_61CHN32:
|
||||
LoadData(ALBuf, data, size, freq, format, AL_FORMAT_61CHN16);
|
||||
LoadData(ALBuf, data, size, freq, format, AL_FORMAT_61CHN32);
|
||||
break;
|
||||
|
||||
case AL_FORMAT_71CHN8:
|
||||
case AL_FORMAT_71CHN16:
|
||||
case AL_FORMAT_71CHN32:
|
||||
LoadData(ALBuf, data, size, freq, format, AL_FORMAT_71CHN16);
|
||||
LoadData(ALBuf, data, size, freq, format, AL_FORMAT_71CHN32);
|
||||
break;
|
||||
|
||||
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 NewFormat = ((OrigChans==1) ? AL_FORMAT_MONO_FLOAT32 :
|
||||
AL_FORMAT_STEREO_FLOAT32);
|
||||
ALuint NewBytes = aluBytesFromFormat(NewFormat);
|
||||
|
||||
// Here is where things vary:
|
||||
@ -389,9 +387,7 @@ ALAPI ALvoid ALAPIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *d
|
||||
ALBuf->data = temp;
|
||||
ConvertDataIMA4(ALBuf->data, data, OrigChans, size/65);
|
||||
|
||||
memset(&(ALBuf->data[size]), 0, BUFFER_PADDING*NewBytes*OrigChans);
|
||||
|
||||
ALBuf->format = ((OrigChans==1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16);
|
||||
ALBuf->format = NewFormat;
|
||||
ALBuf->eOriginalFormat = format;
|
||||
ALBuf->size = size*NewBytes;
|
||||
ALBuf->frequency = freq;
|
||||
@ -515,7 +511,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);
|
||||
ALuint NewBytes = aluBytesFromFormat(ALBuf->format);
|
||||
|
||||
if(Channels != aluChannelsFromFormat(ALBuf->format))
|
||||
{
|
||||
@ -931,9 +927,9 @@ ALAPI void ALAPIENTRY alGetBufferiv(ALuint buffer, ALenum eParam, ALint* plValue
|
||||
* LoadData
|
||||
*
|
||||
* Loads the specified data into the buffer, using the specified formats.
|
||||
* Currently, the new format must be 16-bit, and must have the same channel
|
||||
* configuration as the original format. This does NOT handle compressed
|
||||
* formats (eg. IMA4).
|
||||
* Currently, the new format must be 32-bit float, and must have the same
|
||||
* channel configuration as the original format. This does NOT handle
|
||||
* compressed formats (eg. IMA4).
|
||||
*/
|
||||
static void LoadData(ALbuffer *ALBuf, const ALubyte *data, ALsizei size, ALuint freq, ALenum OrigFormat, ALenum NewFormat)
|
||||
{
|
||||
@ -943,7 +939,7 @@ static void LoadData(ALbuffer *ALBuf, const ALubyte *data, ALsizei size, ALuint
|
||||
ALuint OrigChannels = aluChannelsFromFormat(OrigFormat);
|
||||
ALvoid *temp;
|
||||
|
||||
assert(NewBytes == 2);
|
||||
assert(NewBytes == 4);
|
||||
assert(NewChannels == OrigChannels);
|
||||
|
||||
if ((size%(OrigBytes*OrigChannels)) != 0)
|
||||
@ -952,7 +948,7 @@ static void LoadData(ALbuffer *ALBuf, const ALubyte *data, ALsizei size, ALuint
|
||||
return;
|
||||
}
|
||||
|
||||
// Samples are converted to 16 bit here
|
||||
// Samples are converted here
|
||||
size /= OrigBytes;
|
||||
temp = realloc(ALBuf->data, (BUFFER_PADDING*NewChannels + size) * NewBytes);
|
||||
if(temp)
|
||||
@ -960,8 +956,6 @@ static void LoadData(ALbuffer *ALBuf, const ALubyte *data, ALsizei size, ALuint
|
||||
ALBuf->data = temp;
|
||||
ConvertData(ALBuf->data, data, OrigBytes, size);
|
||||
|
||||
memset(&(ALBuf->data[size]), 0, BUFFER_PADDING*NewChannels*NewBytes);
|
||||
|
||||
ALBuf->format = NewFormat;
|
||||
ALBuf->eOriginalFormat = OrigFormat;
|
||||
ALBuf->size = size*NewBytes;
|
||||
@ -971,29 +965,31 @@ static void LoadData(ALbuffer *ALBuf, const ALubyte *data, ALsizei size, ALuint
|
||||
alSetError(AL_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
static void ConvertData(ALshort *dst, const ALvoid *src, ALint origBytes, ALsizei len)
|
||||
static void ConvertData(ALfloat *dst, const ALvoid *src, ALint origBytes, ALsizei len)
|
||||
{
|
||||
ALsizei i;
|
||||
ALint smp;
|
||||
switch(origBytes)
|
||||
{
|
||||
case 1:
|
||||
for(i = 0;i < len;i++)
|
||||
dst[i] = ((ALshort)((ALubyte*)src)[i] - 128) << 8;
|
||||
{
|
||||
smp = ((ALubyte*)src)[i];
|
||||
dst[i] = ((smp < 0x80) ? ((smp-128)/128.0f) : ((smp-128)/127.0f));
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
memcpy(dst, src, len*sizeof(ALshort));
|
||||
for(i = 0;i < len;i++)
|
||||
{
|
||||
smp = ((ALshort*)src)[i];
|
||||
dst[i] = ((smp < 0) ? (smp/32768.0f) : (smp/32767.0f));
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
for(i = 0;i < len;i++)
|
||||
{
|
||||
ALint smp;
|
||||
smp = (((ALfloat*)src)[i] * 32767.5f - 0.5f);
|
||||
smp = min(smp, 32767);
|
||||
smp = max(smp, -32768);
|
||||
dst[i] = (ALshort)smp;
|
||||
}
|
||||
dst[i] = ((ALfloat*)src)[i];
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1001,9 +997,10 @@ static void ConvertData(ALshort *dst, const ALvoid *src, ALint origBytes, ALsize
|
||||
}
|
||||
}
|
||||
|
||||
static void ConvertDataRear(ALshort *dst, const ALvoid *src, ALint origBytes, ALsizei len)
|
||||
static void ConvertDataRear(ALfloat *dst, const ALvoid *src, ALint origBytes, ALsizei len)
|
||||
{
|
||||
ALsizei i;
|
||||
ALint smp;
|
||||
switch(origBytes)
|
||||
{
|
||||
case 1:
|
||||
@ -1011,8 +1008,10 @@ static void ConvertDataRear(ALshort *dst, const ALvoid *src, ALint origBytes, AL
|
||||
{
|
||||
dst[i+0] = 0;
|
||||
dst[i+1] = 0;
|
||||
dst[i+2] = ((ALshort)((ALubyte*)src)[i/2+0] - 128) << 8;
|
||||
dst[i+3] = ((ALshort)((ALubyte*)src)[i/2+1] - 128) << 8;
|
||||
smp = ((ALubyte*)src)[i/2+0];
|
||||
dst[i+2] = ((smp < 0x80) ? ((smp-128)/128.0f) : ((smp-128)/127.0f));
|
||||
smp = ((ALubyte*)src)[i/2+1];
|
||||
dst[i+3] = ((smp < 0x80) ? ((smp-128)/128.0f) : ((smp-128)/127.0f));
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1021,25 +1020,20 @@ static void ConvertDataRear(ALshort *dst, const ALvoid *src, ALint origBytes, AL
|
||||
{
|
||||
dst[i+0] = 0;
|
||||
dst[i+1] = 0;
|
||||
dst[i+2] = ((ALshort*)src)[i/2+0];
|
||||
dst[i+3] = ((ALshort*)src)[i/2+1];
|
||||
smp = ((ALshort*)src)[i/2+0];
|
||||
dst[i+2] = ((smp < 0) ? (smp/32768.0f) : (smp/32767.0f));
|
||||
smp = ((ALshort*)src)[i/2+1];
|
||||
dst[i+3] = ((smp < 0) ? (smp/32768.0f) : (smp/32767.0f));
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
for(i = 0;i < len;i+=4)
|
||||
{
|
||||
ALint smp;
|
||||
dst[i+0] = 0;
|
||||
dst[i+1] = 0;
|
||||
smp = (((ALfloat*)src)[i/2+0] * 32767.5f - 0.5);
|
||||
smp = min(smp, 32767);
|
||||
smp = max(smp, -32768);
|
||||
dst[i+2] = (ALshort)smp;
|
||||
smp = (((ALfloat*)src)[i/2+1] * 32767.5f - 0.5);
|
||||
smp = min(smp, 32767);
|
||||
smp = max(smp, -32768);
|
||||
dst[i+3] = (ALshort)smp;
|
||||
dst[i+2] = ((ALfloat*)src)[i/2+0];
|
||||
dst[i+3] = ((ALfloat*)src)[i/2+1];
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1048,7 +1042,7 @@ static void ConvertDataRear(ALshort *dst, const ALvoid *src, ALint origBytes, AL
|
||||
}
|
||||
}
|
||||
|
||||
static void ConvertDataIMA4(ALshort *dst, const ALvoid *src, ALint origChans, ALsizei len)
|
||||
static void ConvertDataIMA4(ALfloat *dst, const ALvoid *src, ALint origChans, ALsizei len)
|
||||
{
|
||||
const ALuint *IMAData;
|
||||
ALint Sample[2],Index[2];
|
||||
@ -1068,7 +1062,7 @@ static void ConvertDataIMA4(ALshort *dst, const ALvoid *src, ALint origChans, AL
|
||||
Index[c] = ((Index[c]<0) ? 0 : Index[c]);
|
||||
Index[c] = ((Index[c]>88) ? 88 : Index[c]);
|
||||
|
||||
dst[i*65*origChans + c] = (ALshort)Sample[c];
|
||||
dst[i*65*origChans + c] = ((Sample[c] < 0) ? (Sample[c]/32768.0f) : (Sample[c]/32767.0f));
|
||||
|
||||
IMAData++;
|
||||
}
|
||||
@ -1091,7 +1085,7 @@ static void ConvertDataIMA4(ALshort *dst, const ALvoid *src, ALint origChans, AL
|
||||
if(Index[c]<0) Index[c] = 0;
|
||||
else if(Index[c]>88) Index[c] = 88;
|
||||
|
||||
dst[(i*65+j+k)*origChans + c] = (ALshort)Sample[c];
|
||||
dst[(i*65+j+k)*origChans + c] = ((Sample[c] < 0) ? (Sample[c]/32768.0f) : (Sample[c]/32767.0f));
|
||||
IMACode[c] >>= 4;
|
||||
}
|
||||
}
|
||||
|
@ -2039,7 +2039,7 @@ static void ApplyOffset(ALsource *pSource, ALboolean bUpdateContext)
|
||||
|
||||
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 16bit)
|
||||
may have been modifed by AL (e.g 8bit samples are converted to float)
|
||||
*/
|
||||
static ALint GetByteOffset(ALsource *pSource)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user