aboutsummaryrefslogtreecommitdiffstats
path: root/OpenAL32
diff options
context:
space:
mode:
Diffstat (limited to 'OpenAL32')
-rw-r--r--OpenAL32/Include/alMain.h4
-rw-r--r--OpenAL32/alBuffer.c64
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)
{