diff options
-rw-r--r-- | OpenAL32/alBuffer.c | 155 |
1 files changed, 78 insertions, 77 deletions
diff --git a/OpenAL32/alBuffer.c b/OpenAL32/alBuffer.c index a5d7130f..ab5b60d8 100644 --- a/OpenAL32/alBuffer.c +++ b/OpenAL32/alBuffer.c @@ -29,6 +29,8 @@ #include "alBuffer.h" +static void LoadData(ALbuffer *ALBuf, const ALubyte *data, ALsizei size, ALuint freq, ALenum OrigFormat, ALenum NewFormat); + /* * AL Buffer Functions * @@ -273,91 +275,19 @@ ALAPI ALvoid ALAPIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *d switch(format) { case AL_FORMAT_MONO8: - if ((size%1) == 0) - { - // 8bit Samples are converted to 16 bit here - // Allocate 8 extra samples (16 bytes) - ALBuf->data=realloc(ALBuf->data,16+(size/sizeof(ALubyte))*(1*sizeof(ALshort))); - if (ALBuf->data) - { - ALBuf->format = AL_FORMAT_MONO16; - ALBuf->eOriginalFormat = AL_FORMAT_MONO8; - for (i=0;i<(ALsizei)(size/sizeof(ALubyte));i++) - ALBuf->data[i]=(ALshort)((((ALubyte *)data)[i]-128)<<8); - memset(&(ALBuf->data[size/sizeof(ALubyte)]), 0, 16); - ALBuf->size=size/sizeof(ALubyte)*1*sizeof(ALshort); - ALBuf->frequency=freq; - } - else - alSetError(AL_OUT_OF_MEMORY); - } - else - alSetError(AL_INVALID_VALUE); + LoadData(ALBuf, data, size, freq, format, AL_FORMAT_MONO16); break; case AL_FORMAT_MONO16: - if ((size%2) == 0) - { - // Allocate 8 extra samples (16 bytes) - ALBuf->data=realloc(ALBuf->data,16+(size/sizeof(ALshort))*(1*sizeof(ALshort))); - if (ALBuf->data) - { - ALBuf->format = AL_FORMAT_MONO16; - ALBuf->eOriginalFormat = AL_FORMAT_MONO16; - memcpy(ALBuf->data,data,size/sizeof(ALshort)*1*sizeof(ALshort)); - memset(&(ALBuf->data[size/sizeof(ALshort)]), 0, 16); - ALBuf->size=size/sizeof(ALshort)*1*sizeof(ALshort); - ALBuf->frequency=freq; - } - else - alSetError(AL_OUT_OF_MEMORY); - } - else - alSetError(AL_INVALID_VALUE); + LoadData(ALBuf, data, size, freq, format, AL_FORMAT_MONO16); break; case AL_FORMAT_STEREO8: - if ((size%2) == 0) - { - // 8bit Samples are converted to 16 bit here - // Allocate 8 extra samples (32 bytes) - ALBuf->data=realloc(ALBuf->data,32+(size/sizeof(ALubyte))*(1*sizeof(ALshort))); - if (ALBuf->data) - { - ALBuf->format = AL_FORMAT_STEREO16; - ALBuf->eOriginalFormat = AL_FORMAT_STEREO8; - for (i=0;i<(ALsizei)(size/sizeof(ALubyte));i++) - ALBuf->data[i]=(ALshort)((((ALubyte *)data)[i]-128)<<8); - memset(&(ALBuf->data[size/sizeof(ALubyte)]), 0, 32); - ALBuf->size=size/sizeof(ALubyte)*1*sizeof(ALshort); - ALBuf->frequency=freq; - } - else - alSetError(AL_OUT_OF_MEMORY); - } - else - alSetError(AL_INVALID_VALUE); + LoadData(ALBuf, data, size, freq, format, AL_FORMAT_STEREO16); break; case AL_FORMAT_STEREO16: - if ((size%4) == 0) - { - // Allocate 8 extra samples (32 bytes) - ALBuf->data=realloc(ALBuf->data,32+(size/sizeof(ALshort))*(1*sizeof(ALshort))); - if (ALBuf->data) - { - ALBuf->format = AL_FORMAT_STEREO16; - ALBuf->eOriginalFormat = AL_FORMAT_STEREO16; - memcpy(ALBuf->data,data,size/sizeof(ALshort)*1*sizeof(ALshort)); - memset(&(ALBuf->data[size/sizeof(ALshort)]), 0, 32); - ALBuf->size=size/sizeof(ALshort)*1*sizeof(ALshort); - ALBuf->frequency=freq; - } - else - alSetError(AL_OUT_OF_MEMORY); - } - else - alSetError(AL_INVALID_VALUE); + LoadData(ALBuf, data, size, freq, format, AL_FORMAT_STEREO16); break; case AL_FORMAT_MONO_IMA4: @@ -489,7 +419,7 @@ ALAPI ALvoid ALAPIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *d 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; @@ -917,6 +847,77 @@ ALAPI void ALAPIENTRY alGetBufferiv(ALuint buffer, ALenum eParam, ALint* plValue ProcessContext(pContext); } +/* + * 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). + */ +static void LoadData(ALbuffer *ALBuf, const ALubyte *data, ALsizei size, ALuint freq, ALenum OrigFormat, ALenum NewFormat) +{ + ALuint NewChannels = aluChannelsFromFormat(NewFormat); + ALuint OrigBytes = aluBytesFromFormat(OrigFormat); + ALuint OrigChannels = aluChannelsFromFormat(OrigFormat); + ALsizei i; + + assert(aluBytesFromFormat(NewFormat) == 2); + assert(NewChannels == OrigChannels); + + if ((size%(OrigBytes*OrigChannels)) != 0) + { + alSetError(AL_INVALID_VALUE); + return; + } + + switch(OrigBytes) + { + case 1: + size /= sizeof(ALubyte); + + // 8bit Samples are converted to 16 bit here + // Allocate 8 extra samples + ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort))); + if (ALBuf->data) + { + for (i = 0;i < size;i++) + ALBuf->data[i] = (ALshort)((data[i]-128) << 8); + memset(&(ALBuf->data[size]), 0, 16*NewChannels); + + ALBuf->format = NewFormat; + ALBuf->eOriginalFormat = OrigFormat; + ALBuf->size = size*1*sizeof(ALshort); + ALBuf->frequency = freq; + } + else + alSetError(AL_OUT_OF_MEMORY); + break; + + case 2: + size /= sizeof(ALshort); + + // Allocate 8 extra samples + ALBuf->data = realloc(ALBuf->data, (8*NewChannels + size) * (1*sizeof(ALshort))); + if (ALBuf->data) + { + memcpy(ALBuf->data, data, size*1*sizeof(ALshort)); + memset(&(ALBuf->data[size]), 0, 16*NewChannels); + + ALBuf->format = NewFormat; + ALBuf->eOriginalFormat = OrigFormat; + ALBuf->size = size*1*sizeof(ALshort); + ALBuf->frequency = freq; + } + else + alSetError(AL_OUT_OF_MEMORY); + break; + + default: + assert(0); + } +} + /* * ReleaseALBuffers() |