From ffa42ff22c21019e5b1b0c152a6d72aa9e558870 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 2 Nov 2008 01:24:57 -0700 Subject: [PATCH] Seperate data converters into reusable functions --- OpenAL32/alBuffer.c | 389 +++++++++++++++++++++++----------------------------- 1 file 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;i88?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;i88?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() -- 2.11.4.GIT