diff options
-rw-r--r-- | Alc/ALc.c | 52 | ||||
-rw-r--r-- | Alc/ALu.c | 16 | ||||
-rw-r--r-- | OpenAL32/Include/alMain.h | 5 |
3 files changed, 55 insertions, 18 deletions
@@ -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)); @@ -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; diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h index 861019ef..f10744ed 100644 --- a/OpenAL32/Include/alMain.h +++ b/OpenAL32/Include/alMain.h @@ -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 |