Store a device's contexts in a dynamic array

This commit is contained in:
Chris Robinson
2009-10-20 11:54:04 -07:00
parent 50f963f6c6
commit 93361118b7
3 changed files with 55 additions and 18 deletions
+43 -9
View File
@@ -1123,6 +1123,7 @@ ALCAPI ALCcontext* ALCAPIENTRY alcCreateContext(ALCdevice *device, const ALCint
{
ALuint attrIdx, reqStereoSources;
ALCcontext *ALContext;
void *temp;
SuspendContext(NULL);
@@ -1137,7 +1138,7 @@ ALCAPI ALCcontext* ALCAPIENTRY alcCreateContext(ALCdevice *device, const ALCint
g_eLastContextError = ALC_NO_ERROR;
// Current implementation only allows one Context per Device
if(device->Context)
if(device->NumContexts > 0)
{
alcSetError(ALC_INVALID_VALUE);
ProcessContext(NULL);
@@ -1214,6 +1215,15 @@ ALCAPI ALCcontext* ALCAPIENTRY alcCreateContext(ALCdevice *device, const ALCint
device->Bs2b = NULL;
}
temp = realloc(device->Contexts, (device->NumContexts+1) * sizeof(*device->Contexts));
if(!temp)
{
alcSetError(ALC_OUT_OF_MEMORY);
ProcessContext(NULL);
return NULL;
}
device->Contexts = temp;
ALContext = calloc(1, sizeof(ALCcontext));
if(!ALContext)
{
@@ -1222,10 +1232,10 @@ ALCAPI ALCcontext* ALCAPIENTRY alcCreateContext(ALCdevice *device, const ALCint
return NULL;
}
device->Contexts[device->NumContexts++] = ALContext;
ALContext->Device = device;
InitContext(ALContext);
device->Context = ALContext;
InitContext(ALContext);
ALContext->next = g_pContextList;
g_pContextList = ALContext;
@@ -1245,10 +1255,27 @@ ALCAPI ALCcontext* ALCAPIENTRY alcCreateContext(ALCdevice *device, const ALCint
ALCAPI ALCvoid ALCAPIENTRY alcDestroyContext(ALCcontext *context)
{
ALCcontext **list;
ALuint i;
if (IsContext(context))
{
ALCdevice_StopPlayback(context->Device);
ALCdevice *Device = context->Device;
if(Device->NumContexts == 1)
ALCdevice_StopPlayback(Device);
SuspendContext(NULL);
for(i = 0;i < Device->NumContexts-1;i++)
{
if(Device->Contexts[i] == context)
{
memmove(&Device->Contexts[i], &Device->Contexts[i+1],
(Device->NumContexts-i-1) * sizeof(*Device->Contexts));
break;
}
}
Device->NumContexts--;
// Lock context
SuspendContext(context);
@@ -1268,8 +1295,6 @@ ALCAPI ALCvoid ALCAPIENTRY alcDestroyContext(ALCcontext *context)
ReleaseALAuxiliaryEffectSlots(context);
}
context->Device->Context = NULL;
list = &g_pContextList;
while(*list != context)
list = &(*list)->next;
@@ -1279,6 +1304,7 @@ ALCAPI ALCvoid ALCAPIENTRY alcDestroyContext(ALCcontext *context)
// Unlock context
ProcessContext(context);
ProcessContext(NULL);
ExitContext(context);
@@ -1473,6 +1499,9 @@ ALCAPI ALCdevice* ALCAPIENTRY alcOpenDevice(const ALCchar *deviceName)
device->Bs2b = NULL;
device->szDeviceName = NULL;
device->Contexts = NULL;
device->NumContexts = 0;
//Set output format
device->Frequency = GetConfigValueInt(NULL, "frequency", SWMIXER_OUTPUT_RATE);
if(device->Frequency == 0)
@@ -1564,12 +1593,13 @@ ALCAPI ALCboolean ALCAPIENTRY alcCloseDevice(ALCdevice *pDevice)
ProcessContext(NULL);
if(pDevice->Context)
if(pDevice->NumContexts > 0)
{
#ifdef _DEBUG
AL_PRINT("alcCloseDevice(): destroying 1 Context\n");
AL_PRINT("alcCloseDevice(): destroying %u Context(s)\n", pDevice->NumContexts);
#endif
alcDestroyContext(pDevice->Context);
while(pDevice->NumContexts > 0)
alcDestroyContext(pDevice->Contexts[0]);
}
ALCdevice_ClosePlayback(pDevice);
@@ -1606,6 +1636,10 @@ ALCAPI ALCboolean ALCAPIENTRY alcCloseDevice(ALCdevice *pDevice)
pDevice->Bs2b = NULL;
free(pDevice->szDeviceName);
pDevice->szDeviceName = NULL;
free(pDevice->Contexts);
pDevice->Contexts = NULL;
//Release device structure
memset(pDevice, 0, sizeof(ALCdevice));
+9 -7
View File
@@ -1203,7 +1203,7 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
ALeffectslot *ALEffectSlot;
ALCcontext *ALContext;
int fpuState;
ALuint i;
ALuint i, c;
SuspendContext(NULL);
@@ -1226,9 +1226,9 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
/* Clear mixing buffer */
memset(DryBuffer, 0, SamplesToDo*OUTPUTCHANNELS*sizeof(ALfloat));
ALContext = device->Context;
if(ALContext)
for(c = 0;c < device->NumContexts;c++)
{
ALContext = device->Contexts[c];
MixSomeSources(ALContext, DryBuffer, SamplesToDo);
/* effect slot processing */
@@ -1378,13 +1378,15 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
ALvoid aluHandleDisconnect(ALCdevice *device)
{
if(device->Context)
ALuint i;
for(i = 0;i < device->NumContexts;i++)
{
ALsource *source;
SuspendContext(device->Context);
SuspendContext(device->Contexts[i]);
source = device->Context->Source;
source = device->Contexts[i]->Source;
while(source)
{
if(source->state == AL_PLAYING)
@@ -1405,7 +1407,7 @@ ALvoid aluHandleDisconnect(ALCdevice *device)
}
source = source->next;
}
ProcessContext(device->Context);
ProcessContext(device->Contexts[i]);
}
device->Connected = ALC_FALSE;
+3 -2
View File
@@ -247,8 +247,9 @@ struct ALCdevice_struct
// Dry path buffer mix
float DryBuffer[BUFFERSIZE][OUTPUTCHANNELS];
// Context created on this device
ALCcontext *Context;
// Contexts created on this device
ALCcontext **Contexts;
ALuint NumContexts;
BackendFuncs *Funcs;
void *ExtraData; // For the backend's use