aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2008-11-02 01:24:57 -0700
committerChris Robinson <[email protected]>2008-11-02 01:24:57 -0700
commitffa42ff22c21019e5b1b0c152a6d72aa9e558870 (patch)
treed54a1e268857331f903afbea686962bbffe0367b
parenta7c62dbabc19a115577b1015e835b82ac21904f8 (diff)
Seperate data converters into reusable functions
-rw-r--r--OpenAL32/alBuffer.c389
1 files changed, 173 insertions, 216 deletions
diff --git a/OpenAL32/alBuffer.c b/OpenAL32/alBuffer.c
index 54fce5f8..7f955ad1 100644
--- a/OpenAL32/alBuffer.c
+++ b/OpenAL32/alBuffer.c
@@ -34,6 +34,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);
/*
* AL Buffer Functions
@@ -255,15 +258,9 @@ ALAPI ALboolean ALAPIENTRY alIsBuffer(ALuint uiBuffer)
*/
ALAPI ALvoid ALAPIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *data,ALsizei size,ALsizei freq)
{
- ALuint *IMAData,IMACode;
ALCcontext *Context;
- ALint Sample,Index;
- ALint LeftSample,LeftIndex;
- ALint RightSample,RightIndex;
- ALuint LeftIMACode,RightIMACode;
ALsizei padding = 2;
ALbuffer *ALBuf;
- ALsizei i,j,k;
ALvoid *temp;
Context = alcGetCurrentContext();
@@ -296,11 +293,10 @@ ALAPI ALvoid ALAPIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *d
ALuint OrigBytes = ((format==AL_FORMAT_REAR8) ? 1 :
((format==AL_FORMAT_REAR16) ? 2 :
4));
- ALsizei i;
assert(aluBytesFromFormat(NewFormat) == 2);
- if ((size%(OrigBytes*2)) != 0)
+ if((size%(OrigBytes*2)) != 0)
{
alSetError(AL_INVALID_VALUE);
break;
@@ -314,48 +310,8 @@ ALAPI ALvoid ALAPIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *d
if(temp)
{
ALBuf->data = temp;
- switch(OrigBytes)
- {
- case 1:
- for(i = 0;i < size;i+=4)
- {
- ALBuf->data[i+0] = 0;
- ALBuf->data[i+1] = 0;
- ALBuf->data[i+2] = (ALshort)((((ALubyte*)data)[i/2+0]-128) << 8);
- ALBuf->data[i+3] = (ALshort)((((ALubyte*)data)[i/2+1]-128) << 8);
- }
- break;
-
- case 2:
- for(i = 0;i < size;i+=4)
- {
- ALBuf->data[i+0] = 0;
- ALBuf->data[i+1] = 0;
- ALBuf->data[i+2] = ((ALshort*)data)[i/2+0];
- ALBuf->data[i+3] = ((ALshort*)data)[i/2+1];
- }
- break;
-
- case 4:
- for(i = 0;i < size;i+=4)
- {
- ALint smp;
- ALBuf->data[i+0] = 0;
- ALBuf->data[i+1] = 0;
- smp = (((ALfloat*)data)[i/2+0] * 32767.5f - 0.5);
- smp = min(smp, 32767);
- smp = max(smp, -32768);
- ALBuf->data[i+2] = (ALshort)smp;
- smp = (((ALfloat*)data)[i/2+1] * 32767.5f - 0.5);
- smp = min(smp, 32767);
- smp = max(smp, -32768);
- ALBuf->data[i+3] = (ALshort)smp;
- }
- break;
-
- default:
- assert(0);
- }
+ ConvertDataRear(ALBuf->data, data, OrigBytes, size);
+
memset(&(ALBuf->data[size]), 0, padding*NewChannels*sizeof(ALshort));
ALBuf->format = NewFormat;
@@ -395,161 +351,39 @@ ALAPI ALvoid ALAPIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *d
break;
case AL_FORMAT_MONO_IMA4:
+ case AL_FORMAT_STEREO_IMA4: {
+ int OrigChans = ((format==AL_FORMAT_MONO_IMA4) ? 1 : 2);
+
// Here is where things vary:
- // nVidia and Apple use 64+1 samples per block => block_size=36 bytes
- // Most PC sound software uses 2040+1 samples per block -> block_size=1024 bytes
- if ((size%36) == 0)
+ // nVidia and Apple use 64+1 samples per channel per block => block_size=36*chans bytes
+ // Most PC sound software uses 2040+1 samples per channel per block -> block_size=1024*chans bytes
+ if((size%(36*OrigChans)) != 0)
{
- // Allocate extra padding samples
- temp=realloc(ALBuf->data,padding*2+(size/36)*(65*sizeof(ALshort)));
- if (temp)
- {
- ALBuf->data = temp;
- ALBuf->format = AL_FORMAT_MONO16;
- ALBuf->eOriginalFormat = AL_FORMAT_MONO_IMA4;
- IMAData=(ALuint *)data;
- for (i=0;i<size/36;i++)
- {
- Sample=((ALshort *)IMAData)[0];
- Index=((ALshort *)IMAData)[1];
-
- Index=Index<0?0:Index;
- Index=Index>88?88:Index;
-
- ALBuf->data[i*65]=(short)Sample;
-
- IMAData++;
-
- for (j=1;j<65;j+=8)
- {
- IMACode=*IMAData;
- for (k=0;k<8;k+=2)
- {
- Sample+=((g_IMAStep_size[Index]*g_IMACodeword_4[IMACode&15])/8);
- Index+=g_IMAIndex_adjust_4[IMACode&15];
- if (Sample<-32768) Sample=-32768;
- else if (Sample>32767) Sample=32767;
- if (Index<0) Index=0;
- else if (Index>88) Index=88;
- ALBuf->data[i*65+j+k]=(short)Sample;
- IMACode>>=4;
-
- Sample+=((g_IMAStep_size[Index]*g_IMACodeword_4[IMACode&15])/8);
- Index+=g_IMAIndex_adjust_4[IMACode&15];
- if (Sample<-32768) Sample=-32768;
- else if (Sample>32767) Sample=32767;
- if (Index<0) Index=0;
- else if (Index>88) Index=88;
- ALBuf->data[i*65+j+k+1]=(short)Sample;
- IMACode>>=4;
- }
- IMAData++;
- }
- }
- memset(&(ALBuf->data[(size/36*65)]), 0, padding*2);
- ALBuf->size=size/36*65*sizeof(ALshort);
- ALBuf->frequency=freq;
- ALBuf->padding=padding;
- }
- else
- alSetError(AL_OUT_OF_MEMORY);
+ alSetError(AL_INVALID_VALUE);
+ break;
}
- else
- alSetError(AL_INVALID_VALUE);
- break;
- case AL_FORMAT_STEREO_IMA4:
- // Here is where things vary:
- // nVidia and Apple use 64+1 samples per channel per block => block_size=72 bytes
- // Most PC sound software uses 2040+1 samples per channel per block -> block_size=2048 bytes
- if ((size%72) == 0)
+ size /= 36;
+ size *= 65;
+
+ // Allocate extra padding samples
+ temp = realloc(ALBuf->data, (padding*OrigChans + size)*sizeof(ALshort));
+ if(temp)
{
- // Allocate extra padding samples
- temp=realloc(ALBuf->data,padding*2*2+(size/72)*(2*65*sizeof(ALshort)));
- if (temp)
- {
- ALBuf->data = temp;
- ALBuf->format = AL_FORMAT_STEREO16;
- ALBuf->eOriginalFormat = AL_FORMAT_STEREO_IMA4;
- IMAData=(ALuint *)data;
- for (i=0;i<size/72;i++)
- {
- LeftSample=((ALshort *)IMAData)[0];
- LeftIndex=((ALshort *)IMAData)[1];
-
- LeftIndex=LeftIndex<0?0:LeftIndex;
- LeftIndex=LeftIndex>88?88:LeftIndex;
-
- ALBuf->data[i*2*65]=(short)LeftSample;
-
- IMAData++;
-
- RightSample=((ALshort *)IMAData)[0];
- RightIndex=((ALshort *)IMAData)[1];
-
- RightIndex=RightIndex<0?0:RightIndex;
- RightIndex=RightIndex>88?88:RightIndex;
-
- ALBuf->data[i*2*65+1]=(short)RightSample;
-
- IMAData++;
-
- for (j=2;j<130;j+=16)
- {
- LeftIMACode=IMAData[0];
- RightIMACode=IMAData[1];
- for (k=0;k<16;k+=4)
- {
- LeftSample+=((g_IMAStep_size[LeftIndex]*g_IMACodeword_4[LeftIMACode&15])/8);
- LeftIndex+=g_IMAIndex_adjust_4[LeftIMACode&15];
- if (LeftSample<-32768) LeftSample=-32768;
- else if (LeftSample>32767) LeftSample=32767;
- if (LeftIndex<0) LeftIndex=0;
- else if (LeftIndex>88) LeftIndex=88;
- ALBuf->data[i*2*65+j+k]=(short)LeftSample;
- LeftIMACode>>=4;
-
- RightSample+=((g_IMAStep_size[RightIndex]*g_IMACodeword_4[RightIMACode&15])/8);
- RightIndex+=g_IMAIndex_adjust_4[RightIMACode&15];
- if (RightSample<-32768) RightSample=-32768;
- else if (RightSample>32767) RightSample=32767;
- if (RightIndex<0) RightIndex=0;
- else if (RightIndex>88) RightIndex=88;
- ALBuf->data[i*2*65+j+k+1]=(short)RightSample;
- RightIMACode>>=4;
-
- LeftSample+=((g_IMAStep_size[LeftIndex]*g_IMACodeword_4[LeftIMACode&15])/8);
- LeftIndex+=g_IMAIndex_adjust_4[LeftIMACode&15];
- if (LeftSample<-32768) LeftSample=-32768;
- else if (LeftSample>32767) LeftSample=32767;
- if (LeftIndex<0) LeftIndex=0;
- else if (LeftIndex>88) LeftIndex=88;
- ALBuf->data[i*2*65+j+k+2]=(short)LeftSample;
- LeftIMACode>>=4;
-
- RightSample+=((g_IMAStep_size[RightIndex]*g_IMACodeword_4[RightIMACode&15])/8);
- RightIndex+=g_IMAIndex_adjust_4[RightIMACode&15];
- if (RightSample<-32768) RightSample=-32768;
- else if (RightSample>32767) RightSample=32767;
- if (RightIndex<0) RightIndex=0;
- else if (RightIndex>88) RightIndex=88;
- ALBuf->data[i*2*65+j+k+3]=(short)RightSample;
- RightIMACode>>=4;
- }
- IMAData+=2;
- }
- }
- memset(&(ALBuf->data[(size/72*2*65)]), 0, padding*2*2);
- ALBuf->size=size/72*2*65*sizeof(ALshort);
- ALBuf->frequency=freq;
- ALBuf->padding=padding;
- }
- else
- alSetError(AL_OUT_OF_MEMORY);
+ ALBuf->data = temp;
+ ConvertDataIMA4(ALBuf->data, data, OrigChans, size/65);
+
+ memset(&(ALBuf->data[size]), 0, padding*sizeof(ALshort)*OrigChans);
+
+ ALBuf->format = ((OrigChans==1) ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16);
+ ALBuf->eOriginalFormat = format;
+ ALBuf->size = size*sizeof(ALshort);
+ ALBuf->frequency = freq;
+ ALBuf->padding = padding;
}
else
- alSetError(AL_INVALID_VALUE);
- break;
+ alSetError(AL_OUT_OF_MEMORY);
+ } break;
default:
alSetError(AL_INVALID_ENUM);
@@ -970,7 +804,6 @@ static void LoadData(ALbuffer *ALBuf, const ALubyte *data, ALsizei size, ALuint
ALuint OrigChannels = aluChannelsFromFormat(OrigFormat);
ALsizei padding = 2;
ALvoid *temp;
- ALsizei i;
assert(aluBytesFromFormat(NewFormat) == 2);
assert(NewChannels == OrigChannels);
@@ -987,45 +820,169 @@ static void LoadData(ALbuffer *ALBuf, const ALubyte *data, ALsizei size, ALuint
if(temp)
{
ALBuf->data = temp;
+ ConvertData(ALBuf->data, data, OrigBytes, size);
- switch(OrigBytes)
- {
+ memset(&(ALBuf->data[size]), 0, padding*NewChannels*sizeof(ALshort));
+
+ ALBuf->format = NewFormat;
+ ALBuf->eOriginalFormat = OrigFormat;
+ ALBuf->size = size*sizeof(ALshort);
+ ALBuf->frequency = freq;
+ ALBuf->padding = padding;
+ }
+ else
+ alSetError(AL_OUT_OF_MEMORY);
+}
+
+static void ConvertData(ALshort *dst, const ALvoid *src, ALint origBytes, ALsizei len)
+{
+ ALsizei i;
+ switch(origBytes)
+ {
case 1:
- for(i = 0;i < size;i++)
- ALBuf->data[i] = (ALshort)((data[i]-128) << 8);
+ for(i = 0;i < len;i++)
+ dst[i] = ((ALshort)((ALubyte*)src)[i] - 128) << 8;
break;
case 2:
- memcpy(ALBuf->data, data, size*sizeof(ALshort));
+ memcpy(dst, src, len*sizeof(ALshort));
break;
case 4:
- for(i = 0;i < size;i++)
+ for(i = 0;i < len;i++)
{
ALint smp;
- smp = (((ALfloat*)data)[i] * 32767.5f - 0.5f);
+ smp = (((ALfloat*)src)[i] * 32767.5f - 0.5f);
smp = min(smp, 32767);
smp = max(smp, -32768);
- ALBuf->data[i] = (ALshort)smp;
+ dst[i] = (ALshort)smp;
}
break;
default:
assert(0);
- }
+ }
+}
- memset(&(ALBuf->data[size]), 0, padding*NewChannels*sizeof(ALshort));
+static void ConvertDataRear(ALshort *dst, const ALvoid *src, ALint origBytes, ALsizei len)
+{
+ ALsizei i;
+ switch(origBytes)
+ {
+ case 1:
+ for(i = 0;i < len;i+=4)
+ {
+ 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;
+ }
+ break;
- ALBuf->format = NewFormat;
- ALBuf->eOriginalFormat = OrigFormat;
- ALBuf->size = size*sizeof(ALshort);
- ALBuf->frequency = freq;
- ALBuf->padding = padding;
+ case 2:
+ for(i = 0;i < len;i+=4)
+ {
+ dst[i+0] = 0;
+ dst[i+1] = 0;
+ dst[i+2] = ((ALshort*)src)[i/2+0];
+ dst[i+3] = ((ALshort*)src)[i/2+1];
+ }
+ 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;
+ }
+ break;
+
+ default:
+ assert(0);
}
- else
- alSetError(AL_OUT_OF_MEMORY);
}
+static void ConvertDataIMA4(ALshort *dst, const ALvoid *src, ALint origChans, ALsizei len)
+{
+ const ALuint *IMAData;
+ ALint LeftSample=0,LeftIndex=0;
+ ALint RightSample=0,RightIndex=0;
+ ALuint LeftIMACode=0,RightIMACode=0;
+ ALsizei i,j,k;
+
+ IMAData = src;
+ for(i = 0;i < len/origChans;i++)
+ {
+ LeftSample = ((ALshort*)IMAData)[0];
+ LeftIndex = ((ALshort*)IMAData)[1];
+
+ LeftIndex = ((LeftIndex<0) ? 0 : LeftIndex);
+ LeftIndex = ((LeftIndex>88) ? 88 : LeftIndex);
+
+ dst[i*65*origChans] = (short)LeftSample;
+
+ IMAData++;
+
+ if(origChans > 1)
+ {
+ RightSample = ((ALshort*)IMAData)[0];
+ RightIndex = ((ALshort*)IMAData)[1];
+
+ RightIndex = ((RightIndex<0) ? 0 : RightIndex);
+ RightIndex = ((RightIndex>88) ? 88 : RightIndex);
+
+ dst[i*65*origChans + 1] = (short)RightSample;
+
+ IMAData++;
+ }
+
+ for(j = 1;j < 65;j += 8)
+ {
+ LeftIMACode = *(IMAData++);
+ if(origChans > 1)
+ RightIMACode = *(IMAData++);
+
+ for(k = 0;k < 8;k++)
+ {
+ LeftSample += ((g_IMAStep_size[LeftIndex]*g_IMACodeword_4[LeftIMACode&15])/8);
+ LeftIndex += g_IMAIndex_adjust_4[LeftIMACode&15];
+
+ if(LeftSample < -32768) LeftSample = -32768;
+ else if(LeftSample > 32767) LeftSample = 32767;
+
+ if(LeftIndex<0) LeftIndex = 0;
+ else if(LeftIndex>88) LeftIndex = 88;
+
+ dst[(i*65+j+k)*origChans] = (short)LeftSample;
+ LeftIMACode >>= 4;
+
+ if(origChans > 1)
+ {
+ RightSample += ((g_IMAStep_size[RightIndex]*g_IMACodeword_4[RightIMACode&15])/8);
+ RightIndex += g_IMAIndex_adjust_4[RightIMACode&15];
+
+ if(RightSample < -32768) RightSample = -32768;
+ else if(RightSample > 32767) RightSample = 32767;
+
+ if(RightIndex < 0) RightIndex = 0;
+ else if(RightIndex > 88) RightIndex = 88;
+
+ dst[(i*65+j+k)*origChans + 1] = (short)RightSample;
+ RightIMACode >>= 4;
+ }
+ }
+ }
+ }
+}
/*
* ReleaseALBuffers()