diff options
-rw-r--r-- | Alc/mixer.c | 47 | ||||
-rw-r--r-- | OpenAL32/Include/alBuffer.h | 2 | ||||
-rw-r--r-- | OpenAL32/alBuffer.c | 716 |
3 files changed, 379 insertions, 386 deletions
diff --git a/Alc/mixer.c b/Alc/mixer.c index 1a89737a..6460e658 100644 --- a/Alc/mixer.c +++ b/Alc/mixer.c @@ -81,7 +81,7 @@ static __inline ALfloat cos_lerp(ALfloat val1, ALfloat val2, ALint frac) #define DO_MIX_MONO(resampler) do { \ if(j == 0) \ { \ - value = (resampler)(Data[DataPosInt], Data[DataPosInt+1], \ + value = (resampler)(Data.f32[DataPosInt], Data.f32[DataPosInt+1], \ DataPosFrac); \ \ outsamp = lpFilter4PC(DryFilter, 0, value); \ @@ -103,7 +103,7 @@ static __inline ALfloat cos_lerp(ALfloat val1, ALfloat val2, ALint frac) while(BufferSize--) \ { \ /* First order interpolator */ \ - value = (resampler)(Data[DataPosInt], Data[DataPosInt+1], \ + value = (resampler)(Data.f32[DataPosInt], Data.f32[DataPosInt+1], \ DataPosFrac); \ \ /* Direct path final mix buffer and panning */ \ @@ -134,7 +134,7 @@ static __inline ALfloat cos_lerp(ALfloat val1, ALfloat val2, ALint frac) ALuint pos = ((DataPosInt < DataSize) ? DataPosInt : (DataPosInt-1)); \ ALuint frac = ((DataPosInt < DataSize) ? DataPosFrac : \ ((DataPosFrac-increment)&FRACTIONMASK)); \ - value = (resampler)(Data[pos], Data[pos+1], frac); \ + value = (resampler)(Data.f32[pos], Data.f32[pos+1], frac); \ \ outsamp = lpFilter4PC(DryFilter, 0, value); \ PendingClicks[FRONT_LEFT] += outsamp*DrySend[FRONT_LEFT]; \ @@ -160,8 +160,8 @@ static __inline ALfloat cos_lerp(ALfloat val1, ALfloat val2, ALint frac) { \ for(i = 0;i < Channels;i++) \ { \ - value = (resampler)(Data[DataPosInt*Channels + i], \ - Data[(DataPosInt+1)*Channels + i], \ + value = (resampler)(Data.f32[DataPosInt*Channels + i], \ + Data.f32[(DataPosInt+1)*Channels + i], \ DataPosFrac); \ \ outsamp = lpFilter2PC(DryFilter, chans[i]*2, value); \ @@ -180,8 +180,8 @@ static __inline ALfloat cos_lerp(ALfloat val1, ALfloat val2, ALint frac) { \ for(i = 0;i < Channels;i++) \ { \ - value = (resampler)(Data[DataPosInt*Channels + i], \ - Data[(DataPosInt+1)*Channels + i], \ + value = (resampler)(Data.f32[DataPosInt*Channels + i], \ + Data.f32[(DataPosInt+1)*Channels + i], \ DataPosFrac); \ \ outsamp = lpFilter2P(DryFilter, chans[i]*2, value); \ @@ -208,8 +208,8 @@ static __inline ALfloat cos_lerp(ALfloat val1, ALfloat val2, ALint frac) ((DataPosFrac-increment)&FRACTIONMASK)); \ for(i = 0;i < Channels;i++) \ { \ - value = (resampler)(Data[pos*Channels + i], \ - Data[(pos+1)*Channels + i], \ + value = (resampler)(Data.f32[pos*Channels + i], \ + Data.f32[(pos+1)*Channels + i], \ frac); \ \ outsamp = lpFilter2PC(DryFilter, chans[i]*2, value); \ @@ -232,8 +232,8 @@ static __inline ALfloat cos_lerp(ALfloat val1, ALfloat val2, ALint frac) { \ for(i = 0;i < Channels;i++) \ { \ - value = (resampler)(Data[DataPosInt*Channels + i], \ - Data[(DataPosInt+1)*Channels + i], \ + value = (resampler)(Data.f32[DataPosInt*Channels + i], \ + Data.f32[(DataPosInt+1)*Channels + i], \ DataPosFrac); \ \ outsamp = lpFilter2PC(DryFilter, chans[i]*2, value); \ @@ -250,8 +250,8 @@ static __inline ALfloat cos_lerp(ALfloat val1, ALfloat val2, ALint frac) { \ for(i = 0;i < Channels;i++) \ { \ - value = (resampler)(Data[DataPosInt*Channels + i], \ - Data[(DataPosInt+1)*Channels + i], \ + value = (resampler)(Data.f32[DataPosInt*Channels + i], \ + Data.f32[(DataPosInt+1)*Channels + i], \ DataPosFrac); \ \ outsamp = lpFilter2P(DryFilter, chans[i]*2, value); \ @@ -276,8 +276,8 @@ static __inline ALfloat cos_lerp(ALfloat val1, ALfloat val2, ALint frac) ((DataPosFrac-increment)&FRACTIONMASK)); \ for(i = 0;i < Channels;i++) \ { \ - value = (resampler)(Data[pos*Channels + i], \ - Data[(pos+1)*Channels + i], \ + value = (resampler)(Data.f32[pos*Channels + i], \ + Data.f32[(pos+1)*Channels + i], \ frac); \ \ outsamp = lpFilter2PC(DryFilter, chans[i]*2, value); \ @@ -364,7 +364,11 @@ static void MixSource(ALsource *ALSource, ALCcontext *ALContext, j = 0; do { const ALbuffer *ALBuffer; - ALfloat *Data = NULL; + union { + ALfloat *f32; + ALshort *s16; + ALubyte *u8; + } Data = { NULL }; ALuint DataSize = 0; ALuint LoopStart = 0; ALuint LoopEnd = 0; @@ -374,7 +378,7 @@ static void MixSource(ALsource *ALSource, ALCcontext *ALContext, /* Get buffer info */ if((ALBuffer=BufferListItem->buffer) != NULL) { - Data = ALBuffer->data; + Data.u8 = ALBuffer->data; DataSize = ALBuffer->size; DataSize /= aluFrameSizeFromFormat(ALBuffer->format); Channels = aluChannelsFromFormat(ALBuffer->format); @@ -405,7 +409,8 @@ static void MixSource(ALsource *ALSource, ALCcontext *ALContext, { ALint ulExtraSamples = BUFFER_PADDING*Channels*Bytes; ulExtraSamples = min(NextBuf->size, ulExtraSamples); - memcpy(&Data[DataSize*Channels], NextBuf->data, ulExtraSamples); + memcpy(&Data.u8[DataSize*Channels*Bytes], + NextBuf->data, ulExtraSamples); } } else if(Looping) @@ -415,11 +420,13 @@ static void MixSource(ALsource *ALSource, ALCcontext *ALContext, { ALint ulExtraSamples = BUFFER_PADDING*Channels*Bytes; ulExtraSamples = min(NextBuf->size, ulExtraSamples); - memcpy(&Data[DataSize*Channels], &NextBuf->data[LoopStart*Channels], ulExtraSamples); + memcpy(&Data.u8[DataSize*Channels*Bytes], + &((ALubyte*)NextBuf->data)[LoopStart*Channels*Bytes], + ulExtraSamples); } } else - memset(&Data[DataSize*Channels], 0, (BUFFER_PADDING*Channels*Bytes)); + memset(&Data.u8[DataSize*Channels*Bytes], 0, (BUFFER_PADDING*Channels*Bytes)); /* Figure out how many samples we can mix. */ DataSize64 = LoopEnd; diff --git a/OpenAL32/Include/alBuffer.h b/OpenAL32/Include/alBuffer.h index 7d3d59ac..5676e337 100644 --- a/OpenAL32/Include/alBuffer.h +++ b/OpenAL32/Include/alBuffer.h @@ -11,7 +11,7 @@ extern "C" { typedef struct ALbuffer { - ALfloat *data; + ALvoid *data; ALsizei size; ALenum format; diff --git a/OpenAL32/alBuffer.c b/OpenAL32/alBuffer.c index 00920794..d4e6c7ee 100644 --- a/OpenAL32/alBuffer.c +++ b/OpenAL32/alBuffer.c @@ -261,279 +261,272 @@ AL_API ALvoid AL_APIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid Context = GetContextSuspended(); if(!Context) return; + if(Context->SampleSource) + { + ALintptrEXT offset; + + if(Context->SampleSource->state == MAPPED) + { + alSetError(Context, AL_INVALID_OPERATION); + ProcessContext(Context); + return; + } + + offset = (const ALubyte*)data - (ALubyte*)NULL; + data = Context->SampleSource->data + offset; + } + device = Context->Device; if((ALBuf=LookupBuffer(device->BufferMap, buffer)) == NULL) alSetError(Context, AL_INVALID_NAME); /* Invalid Buffer Name */ - else + else if(size < 0 || freq < 0) + alSetError(Context, AL_INVALID_VALUE); + else if(ALBuf->refcount != 0) + alSetError(Context, AL_INVALID_VALUE); + else switch(format) { - if(Context->SampleSource) - { - ALintptrEXT offset; + case AL_FORMAT_MONO8: + case AL_FORMAT_MONO16: + case AL_FORMAT_MONO_FLOAT32: + case AL_FORMAT_MONO_DOUBLE_EXT: + err = LoadData(ALBuf, data, size, freq, format, AL_FORMAT_MONO_FLOAT32); + if(err != AL_NO_ERROR) + alSetError(Context, err); + break; + + case AL_FORMAT_STEREO8: + case AL_FORMAT_STEREO16: + case AL_FORMAT_STEREO_FLOAT32: + case AL_FORMAT_STEREO_DOUBLE_EXT: + err = LoadData(ALBuf, data, size, freq, format, AL_FORMAT_STEREO_FLOAT32); + if(err != AL_NO_ERROR) + alSetError(Context, err); + break; - if(Context->SampleSource->state == MAPPED) + case AL_FORMAT_REAR8: + case AL_FORMAT_REAR16: + case AL_FORMAT_REAR32: { + ALenum NewFormat = AL_FORMAT_QUAD32; + ALuint NewChannels = aluChannelsFromFormat(NewFormat); + ALuint NewBytes = aluBytesFromFormat(NewFormat); + ALuint OrigBytes = ((format==AL_FORMAT_REAR8) ? 1 : + ((format==AL_FORMAT_REAR16) ? 2 : 4)); + ALuint64 newsize, allocsize; + + if((size%(OrigBytes*2)) != 0) { - alSetError(Context, AL_INVALID_OPERATION); - ProcessContext(Context); - return; + alSetError(Context, AL_INVALID_VALUE); + break; } - offset = (const ALubyte*)data - (ALubyte*)NULL; - data = Context->SampleSource->data + offset; - } + newsize = size / OrigBytes; + newsize *= 2; - if(size < 0 || freq < 0) - alSetError(Context, AL_INVALID_VALUE); - else if(ALBuf->refcount != 0) - alSetError(Context, AL_INVALID_VALUE); - else - { - switch(format) + allocsize = (BUFFER_PADDING*NewChannels + newsize)*NewBytes; + if(allocsize > INT_MAX) + { + alSetError(Context, AL_OUT_OF_MEMORY); + break; + } + temp = realloc(ALBuf->data, allocsize); + if(temp) { - case AL_FORMAT_MONO8: - case AL_FORMAT_MONO16: - case AL_FORMAT_MONO_FLOAT32: - case AL_FORMAT_MONO_DOUBLE_EXT: - err = LoadData(ALBuf, data, size, freq, format, AL_FORMAT_MONO_FLOAT32); - if(err != AL_NO_ERROR) - alSetError(Context, err); - break; - - case AL_FORMAT_STEREO8: - case AL_FORMAT_STEREO16: - case AL_FORMAT_STEREO_FLOAT32: - case AL_FORMAT_STEREO_DOUBLE_EXT: - err = LoadData(ALBuf, data, size, freq, format, AL_FORMAT_STEREO_FLOAT32); - if(err != AL_NO_ERROR) - alSetError(Context, err); - break; - - case AL_FORMAT_REAR8: - case AL_FORMAT_REAR16: - case AL_FORMAT_REAR32: { - ALenum NewFormat = AL_FORMAT_QUAD32; - ALuint NewChannels = aluChannelsFromFormat(NewFormat); - ALuint NewBytes = aluBytesFromFormat(NewFormat); - ALuint OrigBytes = ((format==AL_FORMAT_REAR8) ? 1 : - ((format==AL_FORMAT_REAR16) ? 2 : - 4)); - ALuint64 newsize, allocsize; - - if((size%(OrigBytes*2)) != 0) - { - alSetError(Context, AL_INVALID_VALUE); - break; - } - - newsize = size / OrigBytes; - newsize *= 2; - - allocsize = (BUFFER_PADDING*NewChannels + newsize)*NewBytes; - if(allocsize > INT_MAX) - { - alSetError(Context, AL_OUT_OF_MEMORY); - break; - } - temp = realloc(ALBuf->data, allocsize); - if(temp) - { - ALBuf->data = temp; - ConvertDataRear(ALBuf->data, data, OrigBytes, newsize); - - ALBuf->format = NewFormat; - ALBuf->eOriginalFormat = format; - ALBuf->size = newsize*NewBytes; - ALBuf->frequency = freq; - - ALBuf->LoopStart = 0; - ALBuf->LoopEnd = newsize / NewChannels; - - ALBuf->OriginalSize = size; - ALBuf->OriginalAlign = OrigBytes * 2; - } - else - alSetError(Context, AL_OUT_OF_MEMORY); - } break; - - case AL_FORMAT_QUAD8_LOKI: - case AL_FORMAT_QUAD16_LOKI: - case AL_FORMAT_QUAD8: - case AL_FORMAT_QUAD16: - case AL_FORMAT_QUAD32: - err = LoadData(ALBuf, data, size, freq, format, AL_FORMAT_QUAD32); - if(err != AL_NO_ERROR) - alSetError(Context, err); - break; - - case AL_FORMAT_51CHN8: - case AL_FORMAT_51CHN16: - case AL_FORMAT_51CHN32: - err = LoadData(ALBuf, data, size, freq, format, AL_FORMAT_51CHN32); - if(err != AL_NO_ERROR) - alSetError(Context, err); - break; - - case AL_FORMAT_61CHN8: - case AL_FORMAT_61CHN16: - case AL_FORMAT_61CHN32: - err = LoadData(ALBuf, data, size, freq, format, AL_FORMAT_61CHN32); - if(err != AL_NO_ERROR) - alSetError(Context, err); - break; - - case AL_FORMAT_71CHN8: - case AL_FORMAT_71CHN16: - case AL_FORMAT_71CHN32: - err = LoadData(ALBuf, data, size, freq, format, AL_FORMAT_71CHN32); - if(err != AL_NO_ERROR) - alSetError(Context, err); - break; - - case AL_FORMAT_MONO_IMA4: - case AL_FORMAT_STEREO_IMA4: { - int Channels = ((format==AL_FORMAT_MONO_IMA4) ? 1 : 2); - ALenum NewFormat = ((Channels==1) ? AL_FORMAT_MONO_FLOAT32 : - AL_FORMAT_STEREO_FLOAT32); - ALuint NewBytes = aluBytesFromFormat(NewFormat); - ALuint64 newsize, allocsize; - - // Here is where things vary: - // 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*Channels)) != 0) - { - alSetError(Context, AL_INVALID_VALUE); - break; - } - - newsize = size / 36; - newsize *= 65; - - allocsize = (BUFFER_PADDING*Channels + newsize)*NewBytes; - if(allocsize > INT_MAX) - { - alSetError(Context, AL_OUT_OF_MEMORY); - break; - } - temp = realloc(ALBuf->data, allocsize); - if(temp) - { - ALBuf->data = temp; - ConvertDataIMA4(ALBuf->data, data, Channels, newsize/(65*Channels)); - - ALBuf->format = NewFormat; - ALBuf->eOriginalFormat = format; - ALBuf->size = newsize*NewBytes; - ALBuf->frequency = freq; - - ALBuf->LoopStart = 0; - ALBuf->LoopEnd = newsize / Channels; - - ALBuf->OriginalSize = size; - ALBuf->OriginalAlign = 36 * Channels; - } - else - alSetError(Context, AL_OUT_OF_MEMORY); - } break; - - case AL_FORMAT_MONO_MULAW: - case AL_FORMAT_STEREO_MULAW: - case AL_FORMAT_QUAD_MULAW: - case AL_FORMAT_51CHN_MULAW: - case AL_FORMAT_61CHN_MULAW: - case AL_FORMAT_71CHN_MULAW: { - int Channels = ((format==AL_FORMAT_MONO_MULAW) ? 1 : - ((format==AL_FORMAT_STEREO_MULAW) ? 2 : - ((format==AL_FORMAT_QUAD_MULAW) ? 4 : - ((format==AL_FORMAT_51CHN_MULAW) ? 6 : - ((format==AL_FORMAT_61CHN_MULAW) ? 7 : 8))))); - ALenum NewFormat = ((Channels==1) ? AL_FORMAT_MONO_FLOAT32 : - ((Channels==2) ? AL_FORMAT_STEREO_FLOAT32 : - ((Channels==4) ? AL_FORMAT_QUAD32 : - ((Channels==6) ? AL_FORMAT_51CHN32 : - ((Channels==7) ? AL_FORMAT_61CHN32 : - AL_FORMAT_71CHN32))))); - ALuint NewBytes = aluBytesFromFormat(NewFormat); - ALuint64 allocsize; - - if((size%(1*Channels)) != 0) - { - alSetError(Context, AL_INVALID_VALUE); - break; - } - - allocsize = (BUFFER_PADDING*Channels + size)*NewBytes; - if(allocsize > INT_MAX) - { - alSetError(Context, AL_OUT_OF_MEMORY); - break; - } - temp = realloc(ALBuf->data, allocsize); - if(temp) - { - ALBuf->data = temp; - ConvertDataMULaw(ALBuf->data, data, size); - - ALBuf->format = NewFormat; - ALBuf->eOriginalFormat = format; - ALBuf->size = size*NewBytes; - ALBuf->frequency = freq; - - ALBuf->LoopStart = 0; - ALBuf->LoopEnd = size / Channels; - - ALBuf->OriginalSize = size; - ALBuf->OriginalAlign = 1 * Channels; - } - else - alSetError(Context, AL_OUT_OF_MEMORY); - } break; - - case AL_FORMAT_REAR_MULAW: { - ALenum NewFormat = AL_FORMAT_QUAD32; - ALuint NewChannels = aluChannelsFromFormat(NewFormat); - ALuint NewBytes = aluBytesFromFormat(NewFormat); - ALuint64 newsize, allocsize; - - if((size%(1*2)) != 0) - { - alSetError(Context, AL_INVALID_VALUE); - break; - } - - newsize = size * 2; - - allocsize = (BUFFER_PADDING*NewChannels + newsize)*NewBytes; - if(allocsize > INT_MAX) - { - alSetError(Context, AL_OUT_OF_MEMORY); - break; - } - temp = realloc(ALBuf->data, allocsize); - if(temp) - { - ALBuf->data = temp; - ConvertDataMULawRear(ALBuf->data, data, newsize); - - ALBuf->format = NewFormat; - ALBuf->eOriginalFormat = format; - ALBuf->size = newsize*NewBytes; - ALBuf->frequency = freq; - - ALBuf->LoopStart = 0; - ALBuf->LoopEnd = newsize / NewChannels; - - ALBuf->OriginalSize = size; - ALBuf->OriginalAlign = 1 * 2; - } - else - alSetError(Context, AL_OUT_OF_MEMORY); - } break; - - default: - alSetError(Context, AL_INVALID_ENUM); - break; + ALBuf->data = temp; + ConvertDataRear(ALBuf->data, data, OrigBytes, newsize); + + ALBuf->format = NewFormat; + ALBuf->eOriginalFormat = format; + ALBuf->size = newsize*NewBytes; + ALBuf->frequency = freq; + + ALBuf->LoopStart = 0; + ALBuf->LoopEnd = newsize / NewChannels; + + ALBuf->OriginalSize = size; + ALBuf->OriginalAlign = OrigBytes * 2; } - } + else + alSetError(Context, AL_OUT_OF_MEMORY); + } break; + + case AL_FORMAT_QUAD8_LOKI: + case AL_FORMAT_QUAD16_LOKI: + case AL_FORMAT_QUAD8: + case AL_FORMAT_QUAD16: + case AL_FORMAT_QUAD32: + err = LoadData(ALBuf, data, size, freq, format, AL_FORMAT_QUAD32); + if(err != AL_NO_ERROR) + alSetError(Context, err); + break; + + case AL_FORMAT_51CHN8: + case AL_FORMAT_51CHN16: + case AL_FORMAT_51CHN32: + err = LoadData(ALBuf, data, size, freq, format, AL_FORMAT_51CHN32); + if(err != AL_NO_ERROR) + alSetError(Context, err); + break; + + case AL_FORMAT_61CHN8: + case AL_FORMAT_61CHN16: + case AL_FORMAT_61CHN32: + err = LoadData(ALBuf, data, size, freq, format, AL_FORMAT_61CHN32); + if(err != AL_NO_ERROR) + alSetError(Context, err); + break; + + case AL_FORMAT_71CHN8: + case AL_FORMAT_71CHN16: + case AL_FORMAT_71CHN32: + err = LoadData(ALBuf, data, size, freq, format, AL_FORMAT_71CHN32); + if(err != AL_NO_ERROR) + alSetError(Context, err); + break; + + case AL_FORMAT_MONO_IMA4: + case AL_FORMAT_STEREO_IMA4: { + ALuint Channels = ((format==AL_FORMAT_MONO_IMA4) ? 1 : 2); + ALenum NewFormat = ((Channels==1) ? AL_FORMAT_MONO_FLOAT32 : + AL_FORMAT_STEREO_FLOAT32); + ALuint NewBytes = aluBytesFromFormat(NewFormat); + ALuint64 newsize, allocsize; + + // Here is where things vary: + // 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*Channels)) != 0) + { + alSetError(Context, AL_INVALID_VALUE); + break; + } + + newsize = size / 36; + newsize *= 65; + + allocsize = (BUFFER_PADDING*Channels + newsize)*NewBytes; + if(allocsize > INT_MAX) + { + alSetError(Context, AL_OUT_OF_MEMORY); + break; + } + temp = realloc(ALBuf->data, allocsize); + if(temp) + { + ALBuf->data = temp; + ConvertDataIMA4(ALBuf->data, data, Channels, newsize/(65*Channels)); + + ALBuf->format = NewFormat; + ALBuf->eOriginalFormat = format; + ALBuf->size = newsize*NewBytes; + ALBuf->frequency = freq; + + ALBuf->LoopStart = 0; + ALBuf->LoopEnd = newsize / Channels; + + ALBuf->OriginalSize = size; + ALBuf->OriginalAlign = 36 * Channels; + } + else + alSetError(Context, AL_OUT_OF_MEMORY); + } break; + + case AL_FORMAT_MONO_MULAW: + case AL_FORMAT_STEREO_MULAW: + case AL_FORMAT_QUAD_MULAW: + case AL_FORMAT_51CHN_MULAW: + case AL_FORMAT_61CHN_MULAW: + case AL_FORMAT_71CHN_MULAW: { + ALuint Channels = ((format==AL_FORMAT_MONO_MULAW) ? 1 : + ((format==AL_FORMAT_STEREO_MULAW) ? 2 : + ((format==AL_FORMAT_QUAD_MULAW) ? 4 : + ((format==AL_FORMAT_51CHN_MULAW) ? 6 : + ((format==AL_FORMAT_61CHN_MULAW) ? 7 : 8))))); + ALenum NewFormat = ((Channels==1) ? AL_FORMAT_MONO_FLOAT32 : + ((Channels==2) ? AL_FORMAT_STEREO_FLOAT32 : + ((Channels==4) ? AL_FORMAT_QUAD32 : + ((Channels==6) ? AL_FORMAT_51CHN32 : + ((Channels==7) ? AL_FORMAT_61CHN32 : + AL_FORMAT_71CHN32))))); + ALuint NewBytes = aluBytesFromFormat(NewFormat); + ALuint64 allocsize; + + if((size%(1*Channels)) != 0) + { + alSetError(Context, AL_INVALID_VALUE); + break; + } + + allocsize = (BUFFER_PADDING*Channels + size)*NewBytes; + if(allocsize > INT_MAX) + { + alSetError(Context, AL_OUT_OF_MEMORY); + break; + } + temp = realloc(ALBuf->data, allocsize); + if(temp) + { + ALBuf->data = temp; + ConvertDataMULaw(ALBuf->data, data, size); + + ALBuf->format = NewFormat; + ALBuf->eOriginalFormat = format; + ALBuf->size = size*NewBytes; + ALBuf->frequency = freq; + + ALBuf->LoopStart = 0; + ALBuf->LoopEnd = size / Channels; + + ALBuf->OriginalSize = size; + ALBuf->OriginalAlign = 1 * Channels; + } + else + alSetError(Context, AL_OUT_OF_MEMORY); + } break; + + case AL_FORMAT_REAR_MULAW: { + ALenum NewFormat = AL_FORMAT_QUAD32; + ALuint NewChannels = aluChannelsFromFormat(NewFormat); + ALuint NewBytes = aluBytesFromFormat(NewFormat); + ALuint64 newsize, allocsize; + + if((size%(1*2)) != 0) + { + alSetError(Context, AL_INVALID_VALUE); + break; + } + + newsize = size * 2; + + allocsize = (BUFFER_PADDING*NewChannels + newsize)*NewBytes; + if(allocsize > INT_MAX) + { + alSetError(Context, AL_OUT_OF_MEMORY); + break; + } + temp = realloc(ALBuf->data, allocsize); + if(temp) + { + ALBuf->data = temp; + ConvertDataMULawRear(ALBuf->data, data, newsize); + + ALBuf->format = NewFormat; + ALBuf->eOriginalFormat = format; + ALBuf->size = newsize*NewBytes; + ALBuf->frequency = freq; + + ALBuf->LoopStart = 0; + ALBuf->LoopEnd = newsize / NewChannels; + + ALBuf->OriginalSize = size; + ALBuf->OriginalAlign = 1 * 2; + } + else + alSetError(Context, AL_OUT_OF_MEMORY); + } break; + + default: + alSetError(Context, AL_INVALID_ENUM); + break; } ProcessContext(Context); @@ -553,116 +546,109 @@ AL_API ALvoid AL_APIENTRY alBufferSubDataSOFT(ALuint buffer,ALenum format,const Context = GetContextSuspended(); if(!Context) return; + if(Context->SampleSource) + { + ALintptrEXT offset; + + if(Context->SampleSource->state == MAPPED) + { + alSetError(Context, AL_INVALID_OPERATION); + ProcessContext(Context); + return; + } + + offset = (const ALubyte*)data - (ALubyte*)NULL; + data = Context->SampleSource->data + offset; + } + device = Context->Device; if((ALBuf=LookupBuffer(device->BufferMap, buffer)) == NULL) alSetError(Context, AL_INVALID_NAME); - else + else if(length < 0 || offset < 0 || (length > 0 && data == NULL)) + alSetError(Context, AL_INVALID_VALUE); + else if(ALBuf->eOriginalFormat != format) + alSetError(Context, AL_INVALID_ENUM); + else if(offset > ALBuf->OriginalSize || + length > ALBuf->OriginalSize-offset || + (offset%ALBuf->OriginalAlign) != 0 || + (length%ALBuf->OriginalAlign) != 0) + alSetError(Context, AL_INVALID_VALUE); + else switch(format) { - if(Context->SampleSource) - { - ALintptrEXT offset; - - if(Context->SampleSource->state == MAPPED) - { - alSetError(Context, AL_INVALID_OPERATION); - ProcessContext(Context); - return; - } + case AL_FORMAT_MONO8: + case AL_FORMAT_MONO16: + case AL_FORMAT_MONO_FLOAT32: + case AL_FORMAT_MONO_DOUBLE_EXT: + case AL_FORMAT_STEREO8: + case AL_FORMAT_STEREO16: + case AL_FORMAT_STEREO_FLOAT32: + case AL_FORMAT_STEREO_DOUBLE_EXT: + case AL_FORMAT_QUAD8_LOKI: + case AL_FORMAT_QUAD16_LOKI: + case AL_FORMAT_QUAD8: + case AL_FORMAT_QUAD16: + case AL_FORMAT_QUAD32: + case AL_FORMAT_51CHN8: + case AL_FORMAT_51CHN16: + case AL_FORMAT_51CHN32: + case AL_FORMAT_61CHN8: + case AL_FORMAT_61CHN16: + case AL_FORMAT_61CHN32: + case AL_FORMAT_71CHN8: + case AL_FORMAT_71CHN16: + case AL_FORMAT_71CHN32: { + ALuint Bytes = aluBytesFromFormat(format); + + offset /= Bytes; + length /= Bytes; + + ConvertData(&((ALfloat*)ALBuf->data)[offset], data, Bytes, length); + } break; + + case AL_FORMAT_REAR8: + case AL_FORMAT_REAR16: + case AL_FORMAT_REAR32: { + ALuint Bytes = ((format==AL_FORMAT_REAR8) ? 1 : + ((format==AL_FORMAT_REAR16) ? 2 : 4)); + + offset /= Bytes; + offset *= 2; + length /= Bytes; + length *= 2; + + ConvertDataRear(&((ALfloat*)ALBuf->data)[offset], data, Bytes, length); + } break; + + case AL_FORMAT_MONO_IMA4: + case AL_FORMAT_STEREO_IMA4: { + ALuint Channels = aluChannelsFromFormat(ALBuf->format); + + /* offset -> sample offset, length -> block count */ + offset /= 36; + offset *= 65; + length /= ALBuf->OriginalAlign; + + ConvertDataIMA4(&((ALfloat*)ALBuf->data)[offset], data, Channels, length); + } break; + + case AL_FORMAT_MONO_MULAW: + case AL_FORMAT_STEREO_MULAW: + case AL_FORMAT_QUAD_MULAW: + case AL_FORMAT_51CHN_MULAW: + case AL_FORMAT_61CHN_MULAW: + case AL_FORMAT_71CHN_MULAW: + ConvertDataMULaw(&((ALfloat*)ALBuf->data)[offset], data, length); + break; - offset = (const ALubyte*)data - (ALubyte*)NULL; - data = Context->SampleSource->data + offset; - } + case AL_FORMAT_REAR_MULAW: + offset *= 2; + length *= 2; + ConvertDataMULawRear(&((ALfloat*)ALBuf->data)[offset], data, length); + break; - if(length < 0 || offset < 0 || (length > 0 && data == NULL)) - alSetError(Context, AL_INVALID_VALUE); - else if(ALBuf->eOriginalFormat != format) + default: alSetError(Context, AL_INVALID_ENUM); - else if(offset > ALBuf->OriginalSize || - length > ALBuf->OriginalSize-offset || - (offset%ALBuf->OriginalAlign) != 0 || - (length%ALBuf->OriginalAlign) != 0) - alSetError(Context, AL_INVALID_VALUE); - else - { - switch(format) - { - case AL_FORMAT_MONO8: - case AL_FORMAT_MONO16: - case AL_FORMAT_MONO_FLOAT32: - case AL_FORMAT_MONO_DOUBLE_EXT: - case AL_FORMAT_STEREO8: - case AL_FORMAT_STEREO16: - case AL_FORMAT_STEREO_FLOAT32: - case AL_FORMAT_STEREO_DOUBLE_EXT: - case AL_FORMAT_QUAD8_LOKI: - case AL_FORMAT_QUAD16_LOKI: - case AL_FORMAT_QUAD8: - case AL_FORMAT_QUAD16: - case AL_FORMAT_QUAD32: - case AL_FORMAT_51CHN8: - case AL_FORMAT_51CHN16: - case AL_FORMAT_51CHN32: - case AL_FORMAT_61CHN8: - case AL_FORMAT_61CHN16: - case AL_FORMAT_61CHN32: - case AL_FORMAT_71CHN8: - case AL_FORMAT_71CHN16: - case AL_FORMAT_71CHN32: { - ALuint Bytes = aluBytesFromFormat(format); - - offset /= Bytes; - length /= Bytes; - - ConvertData(&ALBuf->data[offset], data, Bytes, length); - } break; - - case AL_FORMAT_REAR8: - case AL_FORMAT_REAR16: - case AL_FORMAT_REAR32: { - ALuint Bytes = ((format==AL_FORMAT_REAR8) ? 1 : - ((format==AL_FORMAT_REAR16) ? 2 : - 4)); - - offset /= Bytes; - offset *= 2; - length /= Bytes; - length *= 2; - - ConvertDataRear(&ALBuf->data[offset], data, Bytes, length); - } break; - - case AL_FORMAT_MONO_IMA4: - case AL_FORMAT_STEREO_IMA4: { - int Channels = aluChannelsFromFormat(ALBuf->format); - - // offset -> sample*channel offset, length -> block count - offset /= 36; - offset *= 65; - length /= ALBuf->OriginalAlign; - - ConvertDataIMA4(&ALBuf->data[offset], data, Channels, length); - } break; - - case AL_FORMAT_MONO_MULAW: - case AL_FORMAT_STEREO_MULAW: - case AL_FORMAT_QUAD_MULAW: - case AL_FORMAT_51CHN_MULAW: - case AL_FORMAT_61CHN_MULAW: - case AL_FORMAT_71CHN_MULAW: - ConvertDataMULaw(&ALBuf->data[offset], data, length); - break; - - case AL_FORMAT_REAR_MULAW: - offset *= 2; - length *= 2; - ConvertDataMULawRear(&ALBuf->data[offset], data, length); - break; - - default: - alSetError(Context, AL_INVALID_ENUM); - break; - } - } + break; } ProcessContext(Context); |