aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Alc/ALc.c10
-rw-r--r--CMakeLists.txt1
-rw-r--r--OpenAL32/Include/alDatabuffer.h55
-rw-r--r--OpenAL32/Include/alMain.h7
-rw-r--r--OpenAL32/alBuffer.c33
-rw-r--r--OpenAL32/alDatabuffer.c651
-rw-r--r--OpenAL32/alExtension.c19
-rw-r--r--OpenAL32/alState.c30
-rw-r--r--include/AL/alext.h35
9 files changed, 840 insertions, 1 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index 1f9fdb30..30d502d0 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -34,6 +34,7 @@
#include "alBuffer.h"
#include "alExtension.h"
#include "alAuxEffectSlot.h"
+#include "alDatabuffer.h"
#include "bs2b.h"
#include "alu.h"
@@ -490,7 +491,7 @@ static ALvoid InitContext(ALCcontext *pContext)
pContext->DopplerVelocity = 1.0f;
pContext->flSpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
- pContext->ExtensionList = "AL_EXTX_buffer_sub_data AL_EXT_EXPONENT_DISTANCE AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS AL_EXT_OFFSET AL_EXTX_source_distance_model AL_LOKI_quadriphonic";
+ pContext->ExtensionList = "AL_EXTX_buffer_sub_data AL_EXT_EXPONENT_DISTANCE AL_EXT_FLOAT32 AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS AL_EXT_OFFSET AL_EXTX_sample_buffer_object AL_EXTX_source_distance_model AL_LOKI_quadriphonic";
level = GetConfigValueInt(NULL, "cf_level", 0);
if(level > 0 && level <= 6)
@@ -1429,6 +1430,13 @@ ALCAPI ALCboolean ALCAPIENTRY alcCloseDevice(ALCdevice *pDevice)
#endif
ReleaseALFilters(pDevice);
}
+ if(pDevice->DatabufferCount > 0)
+ {
+#ifdef _DEBUG
+ AL_PRINT("alcCloseDevice(): deleting %d Databuffer(s)\n", pDevice->DatabufferCount);
+#endif
+ ReleaseALDatabuffers(pDevice);
+ }
//Release device structure
memset(pDevice, 0, sizeof(ALCdevice));
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 575f29d3..63de008a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -252,6 +252,7 @@ ENDIF()
SET(OPENAL_OBJS OpenAL32/alAuxEffectSlot.c
OpenAL32/alBuffer.c
+ OpenAL32/alDatabuffer.c
OpenAL32/alEffect.c
OpenAL32/alError.c
OpenAL32/alExtension.c
diff --git a/OpenAL32/Include/alDatabuffer.h b/OpenAL32/Include/alDatabuffer.h
new file mode 100644
index 00000000..f50450f0
--- /dev/null
+++ b/OpenAL32/Include/alDatabuffer.h
@@ -0,0 +1,55 @@
+#ifndef _AL_DATABUFFER_H_
+#define _AL_DATABUFFER_H_
+
+#include "AL/al.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define UNMAPPED 0
+#define MAPPED 1
+
+typedef struct ALdatabuffer
+{
+ ALubyte *data;
+ ALuint size;
+ ALenum state;
+
+ ALenum usage;
+
+ /* Index to self */
+ ALuint databuffer;
+
+ struct ALdatabuffer *next;
+} ALdatabuffer;
+
+ALvoid ALAPIENTRY alGenDatabuffersEXT(ALsizei n,ALuint *puiBuffers);
+ALvoid ALAPIENTRY alDeleteDatabuffersEXT(ALsizei n, const ALuint *puiBuffers);
+ALboolean ALAPIENTRY alIsDatabufferEXT(ALuint uiBuffer);
+
+ALvoid ALAPIENTRY alDatabufferDataEXT(ALuint buffer,const ALvoid *data,ALsizei size,ALenum usage);
+ALvoid ALAPIENTRY alDatabufferSubDataEXT(ALuint buffer, ALuint start, ALsizei length, const ALvoid *data);
+ALvoid ALAPIENTRY alGetDatabufferSubDataEXT(ALuint buffer, ALuint start, ALsizei length, ALvoid *data);
+
+ALvoid ALAPIENTRY alDatabufferfEXT(ALuint buffer, ALenum eParam, ALfloat flValue);
+ALvoid ALAPIENTRY alDatabufferfvEXT(ALuint buffer, ALenum eParam, const ALfloat* flValues);
+ALvoid ALAPIENTRY alDatabufferiEXT(ALuint buffer, ALenum eParam, ALint lValue);
+ALvoid ALAPIENTRY alDatabufferivEXT(ALuint buffer, ALenum eParam, const ALint* plValues);
+ALvoid ALAPIENTRY alGetDatabufferfEXT(ALuint buffer, ALenum eParam, ALfloat *pflValue);
+ALvoid ALAPIENTRY alGetDatabufferfvEXT(ALuint buffer, ALenum eParam, ALfloat* pflValues);
+ALvoid ALAPIENTRY alGetDatabufferiEXT(ALuint buffer, ALenum eParam, ALint *plValue);
+ALvoid ALAPIENTRY alGetDatabufferivEXT(ALuint buffer, ALenum eParam, ALint* plValues);
+
+ALvoid ALAPIENTRY alSelectDatabufferEXT(ALenum target, ALuint uiBuffer);
+
+ALvoid* ALAPIENTRY alMapDatabufferEXT(ALuint uiBuffer, ALuint start, ALsizei length, ALenum access);
+ALvoid ALAPIENTRY alUnmapDatabufferEXT(ALuint uiBuffer);
+
+ALvoid ReleaseALDatabuffers(ALCdevice *device);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h
index 78128c90..a375f6d1 100644
--- a/OpenAL32/Include/alMain.h
+++ b/OpenAL32/Include/alMain.h
@@ -201,6 +201,10 @@ struct ALCdevice_struct
struct ALfilter *FilterList;
ALuint FilterCount;
+ // Linked List of Databuffers for this device
+ struct ALdatabuffer *Databuffers;
+ ALuint DatabufferCount;
+
// Context created on this device
ALCcontext *Context;
@@ -231,6 +235,9 @@ struct ALCcontext_struct
struct ALeffectslot *AuxiliaryEffectSlot;
ALuint AuxiliaryEffectSlotCount;
+ struct ALdatabuffer *SampleSource;
+ struct ALdatabuffer *SampleSink;
+
ALenum LastError;
ALboolean InUse;
diff --git a/OpenAL32/alBuffer.c b/OpenAL32/alBuffer.c
index cfac55d7..ebd4cf20 100644
--- a/OpenAL32/alBuffer.c
+++ b/OpenAL32/alBuffer.c
@@ -28,6 +28,7 @@
#include "AL/alc.h"
#include "alError.h"
#include "alBuffer.h"
+#include "alDatabuffer.h"
#include "alThunk.h"
@@ -270,6 +271,22 @@ ALAPI ALvoid ALAPIENTRY alBufferData(ALuint buffer,ALenum format,const ALvoid *d
if (alIsBuffer(buffer) && (buffer != 0))
{
ALBuf=((ALbuffer *)ALTHUNK_LOOKUPENTRY(buffer));
+
+ if(Context->SampleSource)
+ {
+ ALuint offset;
+
+ if(Context->SampleSource->state == MAPPED)
+ {
+ alSetError(AL_INVALID_OPERATION);
+ ProcessContext(Context);
+ return;
+ }
+
+ offset = (ALuint)data;
+ data = Context->SampleSource->data + offset;
+ }
+
if ((ALBuf->refcount==0)&&(data))
{
switch(format)
@@ -422,6 +439,22 @@ ALvoid ALAPIENTRY alBufferSubDataEXT(ALuint buffer,ALenum format,const ALvoid *d
if(alIsBuffer(buffer) && buffer != 0)
{
ALBuf = (ALbuffer*)ALTHUNK_LOOKUPENTRY(buffer);
+
+ if(Context->SampleSource)
+ {
+ ALuint offset;
+
+ if(Context->SampleSource->state == MAPPED)
+ {
+ alSetError(AL_INVALID_OPERATION);
+ ProcessContext(Context);
+ return;
+ }
+
+ offset = (ALuint)data;
+ data = Context->SampleSource->data + offset;
+ }
+
if(ALBuf->data == NULL)
{
// buffer does not have any data
diff --git a/OpenAL32/alDatabuffer.c b/OpenAL32/alDatabuffer.c
new file mode 100644
index 00000000..5b285b8d
--- /dev/null
+++ b/OpenAL32/alDatabuffer.c
@@ -0,0 +1,651 @@
+/**
+ * OpenAL cross platform audio library
+ * Copyright (C) 1999-2007 by authors.
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ * Or go to http://www.gnu.org/copyleft/lgpl.html
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include "alMain.h"
+#include "AL/al.h"
+#include "AL/alc.h"
+#include "AL/alext.h"
+#include "alError.h"
+#include "alDatabuffer.h"
+#include "alThunk.h"
+
+
+/*
+* alGenDatabuffersEXT(ALsizei n, ALuint *puiBuffers)
+*
+* Generates n AL Databuffers, and stores the Databuffers Names in the array pointed to by puiBuffers
+*/
+ALvoid ALAPIENTRY alGenDatabuffersEXT(ALsizei n,ALuint *puiBuffers)
+{
+ ALCcontext *Context;
+ ALsizei i=0;
+
+ Context = alcGetCurrentContext();
+ if(!Context) return;
+ SuspendContext(Context);
+
+ /* Check that we are actually generation some Databuffers */
+ if(n > 0)
+ {
+ ALCdevice *device = Context->Device;
+
+ /* Check the pointer is valid (and points to enough memory to store
+ * Databuffer Names) */
+ if(!IsBadWritePtr((void*)puiBuffers, n * sizeof(ALuint)))
+ {
+ ALdatabuffer **list = &device->Databuffers;
+ while(*list)
+ list = &(*list)->next;
+
+ /* Create all the new Databuffers */
+ while(i < n)
+ {
+ *list = calloc(1, sizeof(ALdatabuffer));
+ if(!(*list))
+ {
+ alDeleteDatabuffersEXT(i, puiBuffers);
+ alSetError(AL_OUT_OF_MEMORY);
+ break;
+ }
+
+ puiBuffers[i] = (ALuint)ALTHUNK_ADDENTRY(*list);
+ (*list)->databuffer = puiBuffers[i];
+ (*list)->state = UNMAPPED;
+ device->DatabufferCount++;
+ i++;
+
+ list = &(*list)->next;
+ }
+ }
+ else
+ alSetError(AL_INVALID_VALUE);
+ }
+
+ ProcessContext(Context);
+}
+
+/*
+* alDatabeleteBuffersEXT(ALsizei n, ALuint *puiBuffers)
+*
+* Deletes the n AL Databuffers pointed to by puiBuffers
+*/
+ALvoid ALAPIENTRY alDeleteDatabuffersEXT(ALsizei n, const ALuint *puiBuffers)
+{
+ ALCcontext *Context;
+ ALdatabuffer *ALBuf;
+ ALsizei i;
+ ALboolean bFailed = AL_FALSE;
+
+ Context = alcGetCurrentContext();
+ if(!Context) return;
+ SuspendContext(Context);
+
+ /* Check we are actually Deleting some Databuffers */
+ if(n >= 0)
+ {
+ ALCdevice *device = Context->Device;
+
+ /* Check that all the databuffers are valid and can actually be
+ * deleted */
+ for(i = 0;i < n;i++)
+ {
+ /* Check for valid Buffer ID (can be NULL buffer) */
+ if(alIsDatabufferEXT(puiBuffers[i]))
+ {
+ /* If not the NULL buffer, check that it's unmapped */
+ ALBuf = ((ALdatabuffer *)ALTHUNK_LOOKUPENTRY(puiBuffers[i]));
+ if(ALBuf)
+ {
+ if(ALBuf->state != UNMAPPED)
+ {
+ /* Databuffer still in use, cannot be deleted */
+ alSetError(AL_INVALID_OPERATION);
+ bFailed = AL_TRUE;
+ }
+ }
+ }
+ else
+ {
+ /* Invalid Databuffer */
+ alSetError(AL_INVALID_NAME);
+ bFailed = AL_TRUE;
+ }
+ }
+
+ /* If all the Databuffers were valid (and unmapped), then we can
+ * delete them */
+ if(!bFailed)
+ {
+ for(i = 0;i < n;i++)
+ {
+ if(puiBuffers[i] && alIsDatabufferEXT(puiBuffers[i]))
+ {
+ ALdatabuffer **list = &device->Databuffers;
+
+ ALBuf = (ALdatabuffer*)ALTHUNK_LOOKUPENTRY(puiBuffers[i]);
+ while(*list && *list != ALBuf)
+ list = &(*list)->next;
+
+ if(*list)
+ *list = (*list)->next;
+
+ // Release the memory used to store audio data
+ free(ALBuf->data);
+
+ // Release buffer structure
+ ALTHUNK_REMOVEENTRY(puiBuffers[i]);
+ memset(ALBuf, 0, sizeof(ALdatabuffer));
+ device->DatabufferCount--;
+ free(ALBuf);
+ }
+ }
+ }
+ }
+ else
+ alSetError(AL_INVALID_VALUE);
+
+ ProcessContext(Context);
+
+ return;
+
+}
+
+/*
+* alIsDatabufferEXT(ALuint uiBuffer)
+*
+* Checks if ulBuffer is a valid Databuffer Name
+*/
+ALboolean ALAPIENTRY alIsDatabufferEXT(ALuint uiBuffer)
+{
+ ALCcontext *Context;
+ ALdatabuffer *ALBuf;
+
+ Context = alcGetCurrentContext();
+ if(!Context) return AL_FALSE;
+ SuspendContext(Context);
+
+ /* Check through list of generated databuffers for uiBuffer */
+ ALBuf = Context->Device->Databuffers;
+ while(ALBuf && ALBuf->databuffer != uiBuffer)
+ ALBuf = ALBuf->next;
+
+ ProcessContext(Context);
+
+ return ((ALBuf || !uiBuffer) ? AL_TRUE : AL_FALSE);
+}
+
+/*
+* alDatabufferDataEXT(ALuint buffer,ALvoid *data,ALsizei size,ALenum usage)
+*
+* Fill databuffer with data
+*/
+ALvoid ALAPIENTRY alDatabufferDataEXT(ALuint buffer,const ALvoid *data,ALsizei size,ALenum usage)
+{
+ ALCcontext *Context;
+ ALdatabuffer *ALBuf;
+ ALvoid *temp;
+
+ Context = alcGetCurrentContext();
+ if(!Context) return;
+ SuspendContext(Context);
+
+ if(alIsDatabufferEXT(buffer) && buffer != 0)
+ {
+ ALBuf = (ALdatabuffer*)ALTHUNK_LOOKUPENTRY(buffer);
+ if(ALBuf->state == UNMAPPED)
+ {
+ if(usage == AL_STREAM_WRITE_EXT || usage == AL_STREAM_READ_EXT ||
+ usage == AL_STREAM_COPY_EXT || usage == AL_STATIC_WRITE_EXT ||
+ usage == AL_STATIC_READ_EXT || usage == AL_STATIC_COPY_EXT ||
+ usage == AL_DYNAMIC_WRITE_EXT || usage == AL_DYNAMIC_READ_EXT ||
+ usage == AL_DYNAMIC_COPY_EXT)
+ {
+ /* (Re)allocate data */
+ temp = realloc(ALBuf->data, size);
+ if(temp)
+ {
+ ALBuf->data = temp;
+ ALBuf->size = size;
+ ALBuf->usage = usage;
+ if(data)
+ memcpy(ALBuf->data, data, size);
+ }
+ else
+ alSetError(AL_OUT_OF_MEMORY);
+ }
+ else
+ alSetError(AL_INVALID_ENUM);
+ }
+ else
+ alSetError(AL_INVALID_OPERATION);
+ }
+ else
+ alSetError(AL_INVALID_NAME);
+
+ ProcessContext(Context);
+}
+
+ALvoid ALAPIENTRY alDatabufferSubDataEXT(ALuint uiBuffer, ALuint start, ALsizei length, const ALvoid *data)
+{
+ ALCcontext *pContext;
+ ALdatabuffer *pBuffer;
+
+ pContext = alcGetCurrentContext();
+ if(!pContext) return;
+ SuspendContext(pContext);
+
+ if(alIsDatabufferEXT(uiBuffer) && uiBuffer != 0)
+ {
+ pBuffer = (ALdatabuffer*)ALTHUNK_LOOKUPENTRY(uiBuffer);
+
+ if(length >= 0 && start+length <= pBuffer->size)
+ {
+ if(pBuffer->state == UNMAPPED)
+ memcpy(pBuffer->data+start, data, length);
+ else
+ alSetError(AL_INVALID_OPERATION);
+ }
+ else
+ alSetError(AL_INVALID_VALUE);
+ }
+ else
+ alSetError(AL_INVALID_NAME);
+
+ ProcessContext(pContext);
+}
+
+ALvoid ALAPIENTRY alGetDatabufferSubDataEXT(ALuint uiBuffer, ALuint start, ALsizei length, ALvoid *data)
+{
+ ALCcontext *pContext;
+ ALdatabuffer *pBuffer;
+
+ pContext = alcGetCurrentContext();
+ if(!pContext) return;
+ SuspendContext(pContext);
+
+ if(alIsDatabufferEXT(uiBuffer) && uiBuffer != 0)
+ {
+ pBuffer = (ALdatabuffer*)ALTHUNK_LOOKUPENTRY(uiBuffer);
+
+ if(length >= 0 && start+length <= pBuffer->size)
+ {
+ if(pBuffer->state == UNMAPPED)
+ memcpy(data, pBuffer->data+start, length);
+ else
+ alSetError(AL_INVALID_OPERATION);
+ }
+ else
+ alSetError(AL_INVALID_VALUE);
+ }
+ else
+ alSetError(AL_INVALID_NAME);
+
+ ProcessContext(pContext);
+}
+
+
+ALvoid ALAPIENTRY alDatabufferfEXT(ALuint buffer, ALenum eParam, ALfloat flValue)
+{
+ ALCcontext *pContext;
+
+ (void)flValue;
+
+ pContext = alcGetCurrentContext();
+ if(!pContext) return;
+ SuspendContext(pContext);
+
+ if(alIsDatabufferEXT(buffer) && buffer != 0)
+ {
+ switch(eParam)
+ {
+ default:
+ alSetError(AL_INVALID_ENUM);
+ break;
+ }
+ }
+ else
+ alSetError(AL_INVALID_NAME);
+
+ ProcessContext(pContext);
+}
+
+ALvoid ALAPIENTRY alDatabufferfvEXT(ALuint buffer, ALenum eParam, const ALfloat* flValues)
+{
+ ALCcontext *pContext;
+
+ (void)flValues;
+
+ pContext = alcGetCurrentContext();
+ if(!pContext) return;
+ SuspendContext(pContext);
+
+ if(alIsDatabufferEXT(buffer) && buffer != 0)
+ {
+ switch(eParam)
+ {
+ default:
+ alSetError(AL_INVALID_ENUM);
+ break;
+ }
+ }
+ else
+ alSetError(AL_INVALID_NAME);
+
+ ProcessContext(pContext);
+}
+
+
+ALvoid ALAPIENTRY alDatabufferiEXT(ALuint buffer, ALenum eParam, ALint lValue)
+{
+ ALCcontext *pContext;
+
+ (void)lValue;
+
+ pContext = alcGetCurrentContext();
+ if(!pContext) return;
+ SuspendContext(pContext);
+
+ if(alIsDatabufferEXT(buffer) && buffer != 0)
+ {
+ switch(eParam)
+ {
+ default:
+ alSetError(AL_INVALID_ENUM);
+ break;
+ }
+ }
+ else
+ alSetError(AL_INVALID_NAME);
+
+ ProcessContext(pContext);
+}
+
+ALvoid ALAPIENTRY alDatabufferivEXT(ALuint buffer, ALenum eParam, const ALint* plValues)
+{
+ ALCcontext *pContext;
+
+ (void)plValues;
+
+ pContext = alcGetCurrentContext();
+ if(!pContext) return;
+ SuspendContext(pContext);
+
+ if(alIsDatabufferEXT(buffer) && buffer != 0)
+ {
+ switch(eParam)
+ {
+ default:
+ alSetError(AL_INVALID_ENUM);
+ break;
+ }
+ }
+ else
+ alSetError(AL_INVALID_NAME);
+
+ ProcessContext(pContext);
+}
+
+
+ALvoid ALAPIENTRY alGetDatabufferfEXT(ALuint buffer, ALenum eParam, ALfloat *pflValue)
+{
+ ALCcontext *pContext;
+
+ pContext = alcGetCurrentContext();
+ if(!pContext) return;
+ SuspendContext(pContext);
+
+ if(pflValue)
+ {
+ if(alIsDatabufferEXT(buffer) && buffer != 0)
+ {
+ switch(eParam)
+ {
+ default:
+ alSetError(AL_INVALID_ENUM);
+ break;
+ }
+ }
+ else
+ alSetError(AL_INVALID_NAME);
+ }
+ else
+ alSetError(AL_INVALID_VALUE);
+
+ ProcessContext(pContext);
+}
+
+ALvoid ALAPIENTRY alGetDatabufferfvEXT(ALuint buffer, ALenum eParam, ALfloat* pflValues)
+{
+ ALCcontext *pContext;
+
+ pContext = alcGetCurrentContext();
+ if(!pContext) return;
+ SuspendContext(pContext);
+
+ if(pflValues)
+ {
+ if(alIsDatabufferEXT(buffer) && buffer != 0)
+ {
+ switch(eParam)
+ {
+ default:
+ alSetError(AL_INVALID_ENUM);
+ break;
+ }
+ }
+ else
+ alSetError(AL_INVALID_NAME);
+ }
+ else
+ alSetError(AL_INVALID_VALUE);
+
+ ProcessContext(pContext);
+}
+
+ALvoid ALAPIENTRY alGetDatabufferiEXT(ALuint buffer, ALenum eParam, ALint *plValue)
+{
+ ALCcontext *pContext;
+ ALdatabuffer *pBuffer;
+
+ pContext = alcGetCurrentContext();
+ if(!pContext) return;
+ SuspendContext(pContext);
+
+ if(plValue)
+ {
+ if(alIsDatabufferEXT(buffer) && buffer != 0)
+ {
+ pBuffer = (ALdatabuffer*)ALTHUNK_LOOKUPENTRY(buffer);
+
+ switch(eParam)
+ {
+ case AL_SIZE:
+ *plValue = pBuffer->size;
+ break;
+
+ default:
+ alSetError(AL_INVALID_ENUM);
+ break;
+ }
+ }
+ else
+ alSetError(AL_INVALID_NAME);
+ }
+ else
+ alSetError(AL_INVALID_VALUE);
+
+ ProcessContext(pContext);
+}
+
+ALvoid ALAPIENTRY alGetDatabufferivEXT(ALuint buffer, ALenum eParam, ALint* plValues)
+{
+ ALCcontext *pContext;
+
+ pContext = alcGetCurrentContext();
+ if(!pContext) return;
+ SuspendContext(pContext);
+
+ if(plValues)
+ {
+ if(alIsDatabufferEXT(buffer) && buffer != 0)
+ {
+ switch (eParam)
+ {
+ case AL_SIZE:
+ alGetBufferi(buffer, eParam, plValues);
+ break;
+
+ default:
+ alSetError(AL_INVALID_ENUM);
+ break;
+ }
+ }
+ else
+ alSetError(AL_INVALID_NAME);
+ }
+ else
+ alSetError(AL_INVALID_VALUE);
+
+ ProcessContext(pContext);
+}
+
+
+ALvoid ALAPIENTRY alSelectDatabufferEXT(ALenum target, ALuint uiBuffer)
+{
+ ALCcontext *pContext;
+ ALdatabuffer *pBuffer;
+
+ pContext = alcGetCurrentContext();
+ if(!pContext) return;
+ SuspendContext(pContext);
+
+ if(alIsDatabufferEXT(uiBuffer))
+ {
+ pBuffer = (ALdatabuffer*)(uiBuffer ? ALTHUNK_LOOKUPENTRY(uiBuffer) : NULL);
+ if(target == AL_SAMPLE_SOURCE_EXT)
+ pContext->SampleSource = pBuffer;
+ else if(target == AL_SAMPLE_SINK_EXT)
+ pContext->SampleSink = pBuffer;
+ else
+ alSetError(AL_INVALID_VALUE);
+ }
+ else
+ alSetError(AL_INVALID_NAME);
+
+ ProcessContext(pContext);
+}
+
+
+ALvoid* ALAPIENTRY alMapDatabufferEXT(ALuint uiBuffer, ALuint start, ALsizei length, ALenum access)
+{
+ ALCcontext *pContext;
+ ALdatabuffer *pBuffer;
+ ALvoid *ret = NULL;
+
+ pContext = alcGetCurrentContext();
+ if(!pContext) return NULL;
+ SuspendContext(pContext);
+
+ if(alIsDatabufferEXT(uiBuffer) && uiBuffer != 0)
+ {
+ pBuffer = (ALdatabuffer*)ALTHUNK_LOOKUPENTRY(uiBuffer);
+
+ if(length >= 0 && start+length <= pBuffer->size)
+ {
+ if(access == AL_READ_ONLY_EXT || access == AL_WRITE_ONLY_EXT ||
+ access == AL_READ_WRITE_EXT)
+ {
+ if(pBuffer->state == UNMAPPED)
+ {
+ ret = pBuffer->data + start;
+ pBuffer->state = MAPPED;
+ }
+ else
+ alSetError(AL_INVALID_OPERATION);
+ }
+ else
+ alSetError(AL_INVALID_ENUM);
+ }
+ else
+ alSetError(AL_INVALID_VALUE);
+ }
+ else
+ alSetError(AL_INVALID_NAME);
+
+ ProcessContext(pContext);
+
+ return ret;
+}
+
+ALvoid ALAPIENTRY alUnmapDatabufferEXT(ALuint uiBuffer)
+{
+ ALCcontext *pContext;
+ ALdatabuffer *pBuffer;
+
+ pContext = alcGetCurrentContext();
+ if(!pContext) return;
+ SuspendContext(pContext);
+
+ if(alIsDatabufferEXT(uiBuffer) && uiBuffer != 0)
+ {
+ pBuffer = (ALdatabuffer*)ALTHUNK_LOOKUPENTRY(uiBuffer);
+
+ if(pBuffer->state == MAPPED)
+ pBuffer->state = UNMAPPED;
+ else
+ alSetError(AL_INVALID_OPERATION);
+ }
+ else
+ alSetError(AL_INVALID_NAME);
+
+ ProcessContext(pContext);
+}
+
+
+/*
+* ReleaseALDatabuffers()
+*
+* INTERNAL FN : Called by DLLMain on exit to destroy any buffers that still exist
+*/
+ALvoid ReleaseALDatabuffers(ALCdevice *device)
+{
+ ALdatabuffer *ALBuffer;
+ ALdatabuffer *ALBufferTemp;
+
+ ALBuffer = device->Databuffers;
+ while(ALBuffer)
+ {
+ // Release sample data
+ free(ALBuffer->data);
+
+ // Release Buffer structure
+ ALBufferTemp = ALBuffer;
+ ALBuffer = ALBuffer->next;
+ memset(ALBufferTemp, 0, sizeof(ALdatabuffer));
+ free(ALBufferTemp);
+ }
+ device->Databuffers = NULL;
+ device->DatabufferCount = 0;
+}
diff --git a/OpenAL32/alExtension.c b/OpenAL32/alExtension.c
index 4eef8ba5..4c1c73b6 100644
--- a/OpenAL32/alExtension.c
+++ b/OpenAL32/alExtension.c
@@ -29,6 +29,7 @@
#include "alFilter.h"
#include "alEffect.h"
#include "alAuxEffectSlot.h"
+#include "alDatabuffer.h"
#include "alSource.h"
#include "alBuffer.h"
#include "AL/al.h"
@@ -147,6 +148,24 @@ static ALfunction function[]= {
{ "alBufferSubDataEXT", (ALvoid *) alBufferSubDataEXT },
+ { "alGenDatabuffersEXT", (ALvoid *) alGenDatabuffersEXT },
+ { "alDeleteDatabuffersEXT", (ALvoid *) alDeleteDatabuffersEXT },
+ { "alIsDatabufferEXT", (ALvoid *) alIsDatabufferEXT },
+ { "alDatabufferDataEXT", (ALvoid *) alDatabufferDataEXT },
+ { "alDatabufferSubDataEXT", (ALvoid *) alDatabufferSubDataEXT },
+ { "alGetDatabufferSubDataEXT", (ALvoid *) alGetDatabufferSubDataEXT },
+ { "alDatabufferfEXT", (ALvoid *) alDatabufferfEXT },
+ { "alDatabufferfvEXT", (ALvoid *) alDatabufferfvEXT },
+ { "alDatabufferiEXT", (ALvoid *) alDatabufferiEXT },
+ { "alDatabufferivEXT", (ALvoid *) alDatabufferivEXT },
+ { "alGetDatabufferfEXT", (ALvoid *) alGetDatabufferfEXT },
+ { "alGetDatabufferfvEXT", (ALvoid *) alGetDatabufferfvEXT },
+ { "alGetDatabufferiEXT", (ALvoid *) alGetDatabufferiEXT },
+ { "alGetDatabufferivEXT", (ALvoid *) alGetDatabufferivEXT },
+ { "alSelectDatabufferEXT", (ALvoid *) alSelectDatabufferEXT },
+ { "alMapDatabufferEXT", (ALvoid *) alMapDatabufferEXT },
+ { "alUnmapDatabufferEXT", (ALvoid *) alUnmapDatabufferEXT },
+
{ NULL, (ALvoid *) NULL } };
static ALenums enumeration[]={
diff --git a/OpenAL32/alState.c b/OpenAL32/alState.c
index 8ca5a012..ec2cdfe9 100644
--- a/OpenAL32/alState.c
+++ b/OpenAL32/alState.c
@@ -23,9 +23,11 @@
#include <stdlib.h>
#include "alMain.h"
#include "AL/alc.h"
+#include "AL/alext.h"
#include "alError.h"
#include "alSource.h"
#include "alState.h"
+#include "alDatabuffer.h"
static const ALchar alVendor[] = "OpenAL Community";
static const ALchar alVersion[] = "1.1 ALSOFT "ALSOFT_VERSION;
@@ -281,6 +283,20 @@ ALAPI ALint ALAPIENTRY alGetInteger(ALenum pname)
value = (ALint)Context->flSpeedOfSound;
break;
+ case AL_SAMPLE_SOURCE_EXT:
+ if(Context->SampleSource)
+ value = (ALint)Context->SampleSource->databuffer;
+ else
+ value = 0;
+ break;
+
+ case AL_SAMPLE_SINK_EXT:
+ if(Context->SampleSink)
+ value = (ALint)Context->SampleSink->databuffer;
+ else
+ value = 0;
+ break;
+
default:
alSetError(AL_INVALID_ENUM);
break;
@@ -479,6 +495,20 @@ ALAPI ALvoid ALAPIENTRY alGetIntegerv(ALenum pname,ALint *data)
*data = (ALint)Context->flSpeedOfSound;
break;
+ case AL_SAMPLE_SOURCE_EXT:
+ if(Context->SampleSource)
+ *data = (ALint)Context->SampleSource->databuffer;
+ else
+ *data = 0;
+ break;
+
+ case AL_SAMPLE_SINK_EXT:
+ if(Context->SampleSink)
+ *data = (ALint)Context->SampleSink->databuffer;
+ else
+ *data = 0;
+ break;
+
default:
alSetError(AL_INVALID_ENUM);
break;
diff --git a/include/AL/alext.h b/include/AL/alext.h
index a4f5ace9..66edc857 100644
--- a/include/AL/alext.h
+++ b/include/AL/alext.h
@@ -104,6 +104,41 @@ typedef ALvoid (AL_APIENTRY*PFNALBUFFERSUBDATAEXTPROC)(ALuint,ALenum,const ALvoi
typedef ALvoid (AL_APIENTRY*PFNALBUFFERDATASTATICPROC)(const ALint,ALenum,ALvoid*,ALsizei,ALsizei);
#endif
+#ifndef AL_EXT_sample_buffer_object
+#define AL_EXT_sample_buffer_object 1
+#define AL_SAMPLE_SOURCE_EXT 0x1040
+#define AL_SAMPLE_SINK_EXT 0x1041
+#define AL_READ_ONLY_EXT 0x1042
+#define AL_WRITE_ONLY_EXT 0x1043
+#define AL_READ_WRITE_EXT 0x1044
+#define AL_STREAM_WRITE_EXT 0x1045
+#define AL_STREAM_READ_EXT 0x1046
+#define AL_STREAM_COPY_EXT 0x1047
+#define AL_STATIC_WRITE_EXT 0x1048
+#define AL_STATIC_READ_EXT 0x1049
+#define AL_STATIC_COPY_EXT 0x104A
+#define AL_DYNAMIC_WRITE_EXT 0x104B
+#define AL_DYNAMIC_READ_EXT 0x104C
+#define AL_DYNAMIC_COPY_EXT 0x104D
+typedef ALvoid (AL_APIENTRY*PFNALGENDATABUFFERSEXTPROC)(ALsizei n,ALuint *puiBuffers);
+typedef ALvoid (AL_APIENTRY*PFNALDELETEDATABUFFERSEXTPROC)(ALsizei n, const ALuint *puiBuffers);
+typedef ALboolean (AL_APIENTRY*PFNALISDATABUFFEREXTPROC)(ALuint uiBuffer);
+typedef ALvoid (AL_APIENTRY*PFNALDATABUFFERDATAEXTPROC)(ALuint buffer,const ALvoid *data,ALsizei size,ALenum usage);
+typedef ALvoid (AL_APIENTRY*PFNALDATABUFFERSUBDATAEXTPROC)(ALuint buffer, ALuint start, ALsizei length, const ALvoid *);
+typedef ALvoid (AL_APIENTRY*PFNALGETDATABUFFERSUBDATAEXTPROC)(ALuint buffer, ALuint start, ALsizei length, ALvoid *);
+typedef ALvoid (AL_APIENTRY*PFNALDATABUFFERFEXTPROC)(ALuint buffer, ALenum eParam, ALfloat flValue);
+typedef ALvoid (AL_APIENTRY*PFNALDATABUFFERFVEXTPROC)(ALuint buffer, ALenum eParam, const ALfloat* flValues);
+typedef ALvoid (AL_APIENTRY*PFNALDATABUFFERIEXTPROC)(ALuint buffer, ALenum eParam, ALint lValue);
+typedef ALvoid (AL_APIENTRY*PFNALDATABUFFERIVEXTPROC)(ALuint buffer, ALenum eParam, const ALint* plValues);
+typedef ALvoid (AL_APIENTRY*PFNALGETDATABUFFERFEXTPROC)(ALuint buffer, ALenum eParam, ALfloat *pflValue);
+typedef ALvoid (AL_APIENTRY*PFNALGETDATABUFFERFVEXTPROC)(ALuint buffer, ALenum eParam, ALfloat* pflValues);
+typedef ALvoid (AL_APIENTRY*PFNALGETDATABUFFERIEXTPROC)(ALuint buffer, ALenum eParam, ALint *plValue);
+typedef ALvoid (AL_APIENTRY*PFNALGETDATABUFFERIVEXTPROC)(ALuint buffer, ALenum eParam, ALint* plValues);
+typedef ALvoid (AL_APIENTRY*PFNALSELECTDATABUFFEREXTPROC)(ALenum target, ALuint uiBuffer);
+typedef ALvoid* (AL_APIENTRY*PFNALMAPDATABUFFEREXTPROC)(ALuint uiBuffer, ALuint start, ALsizei length, ALenum access);
+typedef ALvoid (AL_APIENTRY*PFNALUNMAPDATABUFFEREXTPROC)(ALuint uiBuffer);
+#endif
+
#ifdef __cplusplus
}
#endif