aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Alc/ALc.c15
-rw-r--r--Alc/ALu.c32
-rw-r--r--OpenAL32/Include/alMain.h4
-rw-r--r--OpenAL32/alSource.c45
4 files changed, 82 insertions, 14 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index 8156b272..3c4880bd 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -892,6 +892,7 @@ static ALvoid InitContext(ALCcontext *pContext)
//Validate pContext
pContext->LastError = AL_NO_ERROR;
pContext->Suspended = AL_FALSE;
+ pContext->ActiveSourceCount = 0;
InitUIntMap(&pContext->SourceMap);
//Set globals
@@ -1613,8 +1614,15 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin
device->Contexts = temp;
ALContext = calloc(1, sizeof(ALCcontext));
- if(!ALContext)
+ if(ALContext)
{
+ ALContext->MaxActiveSources = 256;
+ ALContext->ActiveSources = malloc(sizeof(*ALContext->ActiveSources) *
+ ALContext->MaxActiveSources);
+ }
+ if(!ALContext || !ALContext->ActiveSources)
+ {
+ free(ALContext);
alcSetError(device, ALC_OUT_OF_MEMORY);
ProcessContext(NULL);
return NULL;
@@ -1693,6 +1701,11 @@ ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context)
}
ResetUIntMap(&context->EffectSlotMap);
+ free(context->ActiveSources);
+ context->ActiveSources = NULL;
+ context->MaxActiveSources = 0;
+ context->ActiveSourceCount = 0;
+
list = &g_pContextList;
while(*list != context)
list = &(*list)->next;
diff --git a/Alc/ALu.c b/Alc/ALu.c
index 817e7d6e..15de0abe 100644
--- a/Alc/ALu.c
+++ b/Alc/ALu.c
@@ -939,23 +939,27 @@ static void MixSomeSources(ALCcontext *ALContext, float (*DryBuffer)[OUTPUTCHANN
ALenum State;
ALsizei pos;
- if(ALContext->SourceMap.size <= 0)
- return;
-
DuplicateStereo = ALContext->Device->DuplicateStereo;
DeviceFreq = ALContext->Device->Frequency;
rampLength = DeviceFreq * MIN_RAMP_LENGTH / 1000;
rampLength = max(rampLength, SamplesToDo);
- pos = ALContext->SourceMap.size;
+ pos = 0;
next_source:
- do {
- if(pos-- <= 0)
- return;
- ALSource = ALContext->SourceMap.array[pos].value;
- } while(ALSource->state != AL_PLAYING);
- j = 0;
+ while(ALContext->ActiveSourceCount > pos)
+ {
+ ALsizei end;
+
+ ALSource = ALContext->ActiveSources[pos];
+ if(ALSource->state == AL_PLAYING)
+ break;
+
+ end = --(ALContext->ActiveSourceCount);
+ ALContext->ActiveSources[pos] = ALContext->ActiveSources[end];
+ }
+ if(pos >= ALContext->ActiveSourceCount)
+ return;
/* Find buffer format */
Frequency = 0;
@@ -1028,8 +1032,8 @@ next_source:
for(i = 0;i < BuffersPlayed && BufferListItem;i++)
BufferListItem = BufferListItem->next;
- while(State == AL_PLAYING && j < SamplesToDo)
- {
+ j = 0;
+ do {
ALfloat *Data = NULL;
ALuint LoopStart = 0;
ALuint LoopEnd = 0;
@@ -1397,7 +1401,7 @@ next_source:
DataPosFrac = 0;
}
}
- }
+ } while(State == AL_PLAYING && j < SamplesToDo);
/* Update source info */
ALSource->state = State;
@@ -1413,6 +1417,8 @@ next_source:
ALSource->FirstStart = AL_FALSE;
+ if(ALSource->state == AL_PLAYING)
+ pos++;
goto next_source;
}
diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h
index afc94da2..4d963563 100644
--- a/OpenAL32/Include/alMain.h
+++ b/OpenAL32/Include/alMain.h
@@ -433,6 +433,10 @@ struct ALCcontext_struct
ALfloat DopplerVelocity;
ALfloat flSpeedOfSound;
+ struct ALsource **ActiveSources;
+ ALsizei ActiveSourceCount;
+ ALsizei MaxActiveSources;
+
ALCdevice *Device;
const ALCchar *ExtensionList;
diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c
index d470f027..5d7ceced 100644
--- a/OpenAL32/alSource.c
+++ b/OpenAL32/alSource.c
@@ -145,6 +145,16 @@ AL_API ALvoid AL_APIENTRY alDeleteSources(ALsizei n, const ALuint *sources)
// Recheck that the Source is valid, because there could be duplicated Source names
if((Source=LookupSource(Context->SourceMap, sources[i])) != NULL)
{
+ for(j = 0;j < Context->ActiveSourceCount;j++)
+ {
+ if(Context->ActiveSources[j] == Source)
+ {
+ ALsizei end = --(Context->ActiveSourceCount);
+ Context->ActiveSources[j] = Context->ActiveSources[end];
+ break;
+ }
+ }
+
// For each buffer in the source's queue, decrement its reference counter and remove it
while(Source->queue != NULL)
{
@@ -1310,6 +1320,31 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources)
}
}
+ if(Context->ActiveSourceCount+n < n)
+ {
+ alSetError(Context, AL_OUT_OF_MEMORY);
+ goto done;
+ }
+
+ while(Context->MaxActiveSources < Context->ActiveSourceCount+n)
+ {
+ void *temp = NULL;
+ ALsizei newcount;
+
+ newcount = Context->MaxActiveSources << 1;
+ if(newcount > 0)
+ temp = realloc(Context->ActiveSources,
+ sizeof(*Context->ActiveSources) * newcount);
+ if(!temp)
+ {
+ alSetError(Context, AL_OUT_OF_MEMORY);
+ goto done;
+ }
+
+ Context->ActiveSources = temp;
+ Context->MaxActiveSources = newcount;
+ }
+
for(i = 0;i < n;i++)
{
Source = (ALsource*)ALTHUNK_LOOKUPENTRY(sources[i]);
@@ -1364,6 +1399,16 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources)
Source->position = 0;
Source->position_fraction = 0;
}
+ else
+ {
+ for(j = 0;j < Context->ActiveSourceCount;j++)
+ {
+ if(Context->ActiveSources[j] == Source)
+ break;
+ }
+ if(j == Context->ActiveSourceCount)
+ Context->ActiveSources[Context->ActiveSourceCount++] = Source;
+ }
}
done: