diff options
author | Chris Robinson <[email protected]> | 2010-11-27 15:33:33 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2010-11-27 15:33:33 -0800 |
commit | 9495cf71fd909fbbe6381c4d7d15cf69de1fded4 (patch) | |
tree | f681167c9a86effb556a97a9a447e49243080dd7 /OpenAL32 | |
parent | 4d0f70439c18f1034d1375a331bbd28e1f1adeff (diff) |
Decompose input buffer formats and use it when converting uncompressed data
Diffstat (limited to 'OpenAL32')
-rw-r--r-- | OpenAL32/Include/alBuffer.h | 23 | ||||
-rw-r--r-- | OpenAL32/alBuffer.c | 140 |
2 files changed, 150 insertions, 13 deletions
diff --git a/OpenAL32/Include/alBuffer.h b/OpenAL32/Include/alBuffer.h index f47685ce..ff247b4f 100644 --- a/OpenAL32/Include/alBuffer.h +++ b/OpenAL32/Include/alBuffer.h @@ -7,6 +7,29 @@ extern "C" { #endif +/* Input formats (some are currently theoretical) */ +enum SrcFmtType { + SrcFmtByte, /* AL_BYTE */ + SrcFmtUByte, /* AL_UNSIGNED_BYTE */ + SrcFmtShort, /* AL_SHORT */ + SrcFmtUShort, /* AL_UNSIGNED_SHORT */ + SrcFmtFloat, /* AL_FLOAT */ + SrcFmtDouble, /* AL_DOUBLE */ +}; +enum SrcFmtChannels { + SrcFmtMono, /* AL_MONO */ + SrcFmtStereo, /* AL_STEREO */ + SrcFmtRear, /* AL_REAR */ + SrcFmtQuad, /* AL_QUAD */ + SrcFmtX51, /* AL_5POINT1 (WFX order) */ + SrcFmtX61, /* AL_6POINT1 (WFX order) */ + SrcFmtX71, /* AL_7POINT1 (WFX order) */ +}; + +void DecomposeInputFormat(ALenum format, enum SrcFmtType *type, + enum SrcFmtChannels *order); + +/* Storable formats */ enum FmtType { FmtUByte, FmtShort, diff --git a/OpenAL32/alBuffer.c b/OpenAL32/alBuffer.c index 8f9dcc6e..bbab73d2 100644 --- a/OpenAL32/alBuffer.c +++ b/OpenAL32/alBuffer.c @@ -35,7 +35,7 @@ static ALenum LoadData(ALbuffer *ALBuf, const ALvoid *data, ALsizei size, ALuint freq, ALenum OrigFormat, ALenum NewFormat); -static void ConvertData(ALvoid *dst, const ALvoid *src, ALint origBytes, ALsizei len); +static void ConvertData(ALvoid *dst, const ALvoid *src, enum SrcFmtType srcType, ALsizei len); static void ConvertDataRear(ALvoid *dst, const ALvoid *src, ALint origBytes, ALsizei len); static void ConvertDataIMA4(ALvoid *dst, const ALvoid *src, ALint origChans, ALsizei len); static void ConvertDataMULaw(ALvoid *dst, const ALvoid *src, ALsizei len); @@ -43,6 +43,7 @@ static void ConvertDataMULawRear(ALvoid *dst, const ALvoid *src, ALsizei len); #define LookupBuffer(m, k) ((ALbuffer*)LookupUIntMapKey(&(m), (k))) + /* * Global Variables */ @@ -584,12 +585,15 @@ AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(ALuint buffer,ALenum format,const case AL_FORMAT_71CHN32: { ALuint OldBytes = aluBytesFromFormat(format); ALuint Bytes = aluBytesFromFormat(ALBuf->format); + enum SrcFmtChannels SrcChannels; + enum SrcFmtType SrcType; offset /= OldBytes; offset *= Bytes; length /= OldBytes; - ConvertData(&((ALubyte*)ALBuf->data)[offset], data, Bytes, length); + DecomposeInputFormat(format, &SrcType, &SrcChannels); + ConvertData(&((ALubyte*)ALBuf->data)[offset], data, SrcType, length); } break; case AL_FORMAT_REAR8: @@ -1051,12 +1055,19 @@ static ALenum LoadData(ALbuffer *ALBuf, const ALvoid *data, ALsizei size, ALuint ALuint NewChannels = aluChannelsFromFormat(NewFormat); ALuint OrigBytes = aluBytesFromFormat(OrigFormat); ALuint OrigChannels = aluChannelsFromFormat(OrigFormat); + enum SrcFmtChannels SrcChannels; + enum FmtChannels DstChannels; + enum SrcFmtType SrcType; + enum FmtType DstType; ALuint64 newsize; ALvoid *temp; assert(NewChannels == OrigChannels); assert(NewBytes == OrigBytes); + DecomposeInputFormat(OrigFormat, &SrcType, &SrcChannels); + DecomposeFormat(NewFormat, &DstType, &DstChannels); + if((size%(OrigBytes*OrigChannels)) != 0) return AL_INVALID_VALUE; @@ -1070,7 +1081,7 @@ static ALenum LoadData(ALbuffer *ALBuf, const ALvoid *data, ALsizei size, ALuint ALBuf->data = temp; // Samples are converted here - ConvertData(ALBuf->data, data, OrigBytes, newsize/NewBytes); + ConvertData(ALBuf->data, data, SrcType, newsize/NewBytes); ALBuf->format = NewFormat; ALBuf->eOriginalFormat = OrigFormat; @@ -1080,7 +1091,8 @@ static ALenum LoadData(ALbuffer *ALBuf, const ALvoid *data, ALsizei size, ALuint ALBuf->LoopStart = 0; ALBuf->LoopEnd = newsize / NewChannels / NewBytes; - DecomposeFormat(NewFormat, &ALBuf->FmtType, &ALBuf->FmtChannels); + ALBuf->FmtType = DstType; + ALBuf->FmtChannels = DstChannels; ALBuf->OriginalSize = size; ALBuf->OriginalAlign = OrigBytes * OrigChannels; @@ -1088,35 +1100,42 @@ static ALenum LoadData(ALbuffer *ALBuf, const ALvoid *data, ALsizei size, ALuint return AL_NO_ERROR; } -static void ConvertData(ALvoid *dst, const ALvoid *src, ALint origBytes, ALsizei len) +static void ConvertData(ALvoid *dst, const ALvoid *src, enum SrcFmtType srcType, ALsizei len) { ALsizei i; if(src == NULL) return; - switch(origBytes) + switch(srcType) { - case 1: + case SrcFmtByte: /* signed byte -> unsigned byte */ + for(i = 0;i < len;i++) + ((ALubyte*)dst)[i] = ((ALbyte*)src)[i] ^ 0x80; + break; + + case SrcFmtUByte: for(i = 0;i < len;i++) ((ALubyte*)dst)[i] = ((ALubyte*)src)[i]; break; - case 2: + case SrcFmtShort: for(i = 0;i < len;i++) ((ALshort*)dst)[i] = ((ALshort*)src)[i]; break; - case 4: + case SrcFmtUShort: /* unsigned short -> signed short */ + for(i = 0;i < len;i++) + ((ALshort*)dst)[i] = ((ALushort*)src)[i] ^ 0x8000; + break; + + case SrcFmtFloat: for(i = 0;i < len;i++) ((ALfloat*)dst)[i] = ((ALfloat*)src)[i]; break; - case 8: + case SrcFmtDouble: for(i = 0;i < len;i++) ((ALdouble*)dst)[i] = ((ALdouble*)src)[i]; break; - - default: - assert(0); } } @@ -1244,6 +1263,101 @@ static void ConvertDataMULawRear(ALvoid *dst, const ALvoid *src, ALsizei len) } } + +void DecomposeInputFormat(ALenum format, enum SrcFmtType *type, + enum SrcFmtChannels *order) +{ + switch(format) + { + case AL_FORMAT_MONO8: + *type = SrcFmtUByte; + *order = SrcFmtMono; + break; + case AL_FORMAT_MONO16: + *type = SrcFmtShort; + *order = SrcFmtMono; + break; + case AL_FORMAT_MONO_FLOAT32: + *type = SrcFmtFloat; + *order = SrcFmtMono; + break; + case AL_FORMAT_MONO_DOUBLE_EXT: + *type = SrcFmtDouble; + *order = SrcFmtMono; + break; + case AL_FORMAT_STEREO8: + *type = SrcFmtUByte; + *order = SrcFmtStereo; + break; + case AL_FORMAT_STEREO16: + *type = SrcFmtShort; + *order = SrcFmtStereo; + break; + case AL_FORMAT_STEREO_FLOAT32: + *type = SrcFmtFloat; + *order = SrcFmtStereo; + break; + case AL_FORMAT_STEREO_DOUBLE_EXT: + *type = SrcFmtDouble; + *order = SrcFmtStereo; + break; + case AL_FORMAT_QUAD8_LOKI: + case AL_FORMAT_QUAD8: + *type = SrcFmtUByte; + *order = SrcFmtQuad; + break; + case AL_FORMAT_QUAD16_LOKI: + case AL_FORMAT_QUAD16: + *type = SrcFmtShort; + *order = SrcFmtQuad; + break; + case AL_FORMAT_QUAD32: + *type = SrcFmtFloat; + *order = SrcFmtQuad; + break; + case AL_FORMAT_51CHN8: + *type = SrcFmtUByte; + *order = SrcFmtX51; + break; + case AL_FORMAT_51CHN16: + *type = SrcFmtShort; + *order = SrcFmtX51; + break; + case AL_FORMAT_51CHN32: + *type = SrcFmtFloat; + *order = SrcFmtX51; + break; + case AL_FORMAT_61CHN8: + *type = SrcFmtUByte; + *order = SrcFmtX61; + break; + case AL_FORMAT_61CHN16: + *type = SrcFmtShort; + *order = SrcFmtX61; + break; + case AL_FORMAT_61CHN32: + *type = SrcFmtFloat; + *order = SrcFmtX61; + break; + case AL_FORMAT_71CHN8: + *type = SrcFmtUByte; + *order = SrcFmtX71; + break; + case AL_FORMAT_71CHN16: + *type = SrcFmtShort; + *order = SrcFmtX71; + break; + case AL_FORMAT_71CHN32: + *type = SrcFmtFloat; + *order = SrcFmtX71; + break; + + default: + AL_PRINT("Unhandled format specified: 0x%X\n", format); + abort(); + } +} + /* * ReleaseALBuffers() * |