diff options
author | Chris Robinson <[email protected]> | 2011-03-16 12:13:17 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2011-03-16 12:13:17 -0700 |
commit | f5c4e67aef6c630d748ce3100428b9c6ce372715 (patch) | |
tree | ebdeada29e0257de679c6da46ec0c01951e33ab6 | |
parent | 2f7de9d696fc58f31c4caf7ee6ee36428235aea7 (diff) |
Add alBufferSubSamplesSOFT
-rw-r--r-- | OpenAL32/Include/alMain.h | 4 | ||||
-rw-r--r-- | OpenAL32/alBuffer.c | 64 |
2 files changed, 68 insertions, 0 deletions
diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index e684d999..f84c6c24 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -48,10 +48,14 @@ ALC_API void ALC_APIENTRY alcRenderSamples(ALCdevice *device, ALCvoid *buffer, A #ifndef AL_SOFT_buffer_samples #define AL_SOFT_buffer_samples 1 typedef void (AL_APIENTRY*LPALBUFFERSAMPLESSOFT)(ALuint,ALuint,ALenum,ALsizei,ALenum,ALenum,const ALvoid*); +typedef void (AL_APIENTRY*LPALBUFFERSUBSAMPLESSOFT)(ALuint,ALsizei,ALsizei,ALenum,ALenum,const ALvoid*); #ifdef AL_ALEXT_PROTOTYPES AL_API void AL_APIENTRY alBufferSamplesSOFT(ALuint buffer, ALuint samplerate, ALenum internalformat, ALsizei frames, ALenum channels, ALenum type, const ALvoid *data); +AL_API void AL_APIENTRY alBufferSubSamplesSOFT(ALuint buffer, + ALsizei offset, ALsizei frames, + ALenum channels, ALenum type, const ALvoid *data); #endif #endif diff --git a/OpenAL32/alBuffer.c b/OpenAL32/alBuffer.c index 6ffa58f9..b9bada1f 100644 --- a/OpenAL32/alBuffer.c +++ b/OpenAL32/alBuffer.c @@ -531,6 +531,70 @@ AL_API void AL_APIENTRY alBufferSamplesSOFT(ALuint buffer, ProcessContext(Context); } +AL_API void AL_APIENTRY alBufferSubSamplesSOFT(ALuint buffer, + ALsizei offset, ALsizei frames, + ALenum channels, ALenum type, const ALvoid *data) +{ + ALCcontext *Context; + ALCdevice *device; + ALbuffer *ALBuf; + + 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 if(frames < 0 || offset < 0 || (frames > 0 && data == NULL)) + alSetError(Context, AL_INVALID_VALUE); + else if(channels != (ALenum)ALBuf->FmtChannels || + IsValidType(type) == AL_FALSE) + alSetError(Context, AL_INVALID_ENUM); + else + { + ALuint FrameSize = FrameSizeFromFmt(ALBuf->FmtChannels, ALBuf->FmtType); + ALuint FrameCount = ALBuf->size / FrameSize; + if((ALuint)offset > FrameCount || (ALuint)frames > FrameCount-offset) + alSetError(Context, AL_INVALID_VALUE); + else if(type == UserFmtIMA4 && (frames%65) != 0) + alSetError(Context, AL_INVALID_VALUE); + else if(type == UserFmtIMA4) + { + /* offset -> byte offset, length -> block count */ + offset *= FrameSize; + frames /= 65; + ConvertInputIMA4(&((ALubyte*)ALBuf->data)[offset], + ALBuf->FmtType, data, + ChannelsFromFmt(ALBuf->FmtChannels), + frames); + } + else + { + /* offset -> byte offset */ + offset *= FrameSize; + ConvertInput(&((ALubyte*)ALBuf->data)[offset], ALBuf->FmtType, + data, type, frames*ChannelsFromUserFmt(channels)); + } + } + + ProcessContext(Context); +} + AL_API void AL_APIENTRY alBufferf(ALuint buffer, ALenum eParam, ALfloat flValue) { |