Use an array of active sources when mixing
Prevents iterating over all allocated sources during mixing updates
This commit is contained in:
parent
ed58571079
commit
7f6df7695c
15
Alc/ALc.c
15
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;
|
||||
|
32
Alc/ALu.c
32
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;
|
||||
}
|
||||
|
||||
|
@ -433,6 +433,10 @@ struct ALCcontext_struct
|
||||
ALfloat DopplerVelocity;
|
||||
ALfloat flSpeedOfSound;
|
||||
|
||||
struct ALsource **ActiveSources;
|
||||
ALsizei ActiveSourceCount;
|
||||
ALsizei MaxActiveSources;
|
||||
|
||||
ALCdevice *Device;
|
||||
const ALCchar *ExtensionList;
|
||||
|
||||
|
@ -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:
|
||||
|
Loading…
x
Reference in New Issue
Block a user