Retreive and store source params once per mix update

This commit is contained in:
Chris Robinson 2009-10-25 04:39:36 -07:00
parent 1665595138
commit c003d6032d

233
Alc/ALu.c
View File

@ -827,15 +827,17 @@ static void MixSomeSources(ALCcontext *ALContext, float (*DryBuffer)[OUTPUTCHANN
ALuint i, j, k, out; ALuint i, j, k, out;
ALsource *ALSource; ALsource *ALSource;
ALfloat value; ALfloat value;
ALshort *Data;
ALbufferlistitem *BufferListItem; ALbufferlistitem *BufferListItem;
ALint64 DataSize64,DataPos64; ALint64 DataSize64,DataPos64;
FILTER *DryFilter, *WetFilter[MAX_SENDS]; FILTER *DryFilter, *WetFilter[MAX_SENDS];
ALfloat WetSend[MAX_SENDS]; ALfloat WetSend[MAX_SENDS];
ALuint rampLength; ALuint rampLength;
ALuint frequency; ALuint frequency;
ALint Looping,State;
ALint increment; ALint increment;
ALuint DataPosInt, DataPosFrac;
ALboolean FirstStart;
ALuint BuffersPlayed;
ALenum State;
if(!(ALSource=ALContext->Source)) if(!(ALSource=ALContext->Source))
return; return;
@ -846,66 +848,67 @@ static void MixSomeSources(ALCcontext *ALContext, float (*DryBuffer)[OUTPUTCHANN
rampLength = max(rampLength, SamplesToDo); rampLength = max(rampLength, SamplesToDo);
another_source: another_source:
j = 0;
State = ALSource->state; State = ALSource->state;
if(State != AL_PLAYING)
{
if((ALSource=ALSource->next) != NULL)
goto another_source;
return;
}
j = 0;
/* Get source info */
BuffersPlayed = ALSource->BuffersPlayed;
DataPosInt = ALSource->position;
DataPosFrac = ALSource->position_fraction;
FirstStart = ALSource->FirstStart;
for(i = 0;i < OUTPUTCHANNELS;i++)
DrySend[i] = ALSource->DryGains[i];
for(i = 0;i < MAX_SENDS;i++)
WetSend[i] = ALSource->WetGains[i];
DryFilter = &ALSource->Params.iirFilter;
for(i = 0;i < MAX_SENDS;i++)
{
WetFilter[i] = &ALSource->Params.Send[i].iirFilter;
WetBuffer[i] = (ALSource->Send[i].Slot ?
ALSource->Send[i].Slot->WetBuffer :
DummyBuffer);
}
BufferListItem = ALSource->queue;
for(i = 0;i < BuffersPlayed && BufferListItem;i++)
BufferListItem = BufferListItem->next;
while(State == AL_PLAYING && j < SamplesToDo) while(State == AL_PLAYING && j < SamplesToDo)
{ {
ALuint DataSize = 0; ALuint DataSize = 0;
ALuint DataPosInt = 0;
ALuint DataPosFrac = 0;
ALbuffer *ALBuffer; ALbuffer *ALBuffer;
ALshort *Data;
ALuint Channels, Bytes; ALuint Channels, Bytes;
ALuint BufferSize; ALuint BufferSize;
ALfloat Pitch; ALfloat Pitch;
/* Get buffer info */ /* Get buffer info */
if(!(ALBuffer = ALSource->Buffer)) if((ALBuffer=BufferListItem->buffer) != NULL)
goto skipmix; {
Data = ALBuffer->data;
Data = ALBuffer->data; Channels = aluChannelsFromFormat(ALBuffer->format);
Channels = aluChannelsFromFormat(ALBuffer->format); Bytes = aluBytesFromFormat(ALBuffer->format);
Bytes = aluBytesFromFormat(ALBuffer->format); DataSize = ALBuffer->size;
DataSize = ALBuffer->size; DataSize /= Channels * Bytes;
DataSize /= Channels * Bytes; }
DataPosInt = ALSource->position;
DataPosFrac = ALSource->position_fraction;
if(DataPosInt >= DataSize) if(DataPosInt >= DataSize)
goto skipmix; goto skipmix;
/* Get source info */
DryFilter = &ALSource->Params.iirFilter;
for(i = 0;i < MAX_SENDS;i++)
{
WetFilter[i] = &ALSource->Params.Send[i].iirFilter;
WetBuffer[i] = (ALSource->Send[i].Slot ?
ALSource->Send[i].Slot->WetBuffer :
DummyBuffer);
}
CalcSourceParams(ALContext, ALSource, (Channels==1)?AL_TRUE:AL_FALSE); CalcSourceParams(ALContext, ALSource, (Channels==1)?AL_TRUE:AL_FALSE);
Pitch = (ALSource->Params.Pitch*ALBuffer->frequency) / frequency; Pitch = (ALSource->Params.Pitch*ALBuffer->frequency) / frequency;
if(DuplicateStereo && Channels == 2)
{
Matrix[FRONT_LEFT][SIDE_LEFT] = 1.0f;
Matrix[FRONT_RIGHT][SIDE_RIGHT] = 1.0f;
Matrix[FRONT_LEFT][BACK_LEFT] = 1.0f;
Matrix[FRONT_RIGHT][BACK_RIGHT] = 1.0f;
}
else if(DuplicateStereo)
{
Matrix[FRONT_LEFT][SIDE_LEFT] = 0.0f;
Matrix[FRONT_RIGHT][SIDE_RIGHT] = 0.0f;
Matrix[FRONT_LEFT][BACK_LEFT] = 0.0f;
Matrix[FRONT_RIGHT][BACK_RIGHT] = 0.0f;
}
/* Compute the gain steps for each output channel */ /* Compute the gain steps for each output channel */
if(ALSource->FirstStart) if(FirstStart)
{ {
ALSource->FirstStart = AL_FALSE; FirstStart = AL_FALSE;
for(i = 0;i < OUTPUTCHANNELS;i++) for(i = 0;i < OUTPUTCHANNELS;i++)
{ {
DrySend[i] = ALSource->Params.DryGains[i]; DrySend[i] = ALSource->Params.DryGains[i];
@ -920,17 +923,11 @@ another_source:
else else
{ {
for(i = 0;i < OUTPUTCHANNELS;i++) for(i = 0;i < OUTPUTCHANNELS;i++)
{
dryGainStep[i] = (ALSource->Params.DryGains[i]- dryGainStep[i] = (ALSource->Params.DryGains[i]-
ALSource->DryGains[i]) / rampLength; DrySend[i]) / rampLength;
DrySend[i] = ALSource->DryGains[i];
}
for(i = 0;i < MAX_SENDS;i++) for(i = 0;i < MAX_SENDS;i++)
{
wetGainStep[i] = (ALSource->Params.WetGains[i]- wetGainStep[i] = (ALSource->Params.WetGains[i]-
ALSource->WetGains[i]) / rampLength; WetSend[i]) / rampLength;
WetSend[i] = ALSource->WetGains[i];
}
} }
/* Compute 18.14 fixed point step */ /* Compute 18.14 fixed point step */
@ -948,37 +945,43 @@ another_source:
DataPos64 += DataPosFrac; DataPos64 += DataPosFrac;
BufferSize = (ALuint)((DataSize64-DataPos64+(increment-1)) / increment); BufferSize = (ALuint)((DataSize64-DataPos64+(increment-1)) / increment);
BufferListItem = ALSource->queue; if(BufferListItem->next)
for(i = 0;i < ALSource->BuffersPlayed && BufferListItem;i++)
BufferListItem = BufferListItem->next;
if(BufferListItem)
{ {
ALbuffer *NextBuf; ALbuffer *NextBuf = BufferListItem->next->buffer;
ALuint ulExtraSamples; if(NextBuf && NextBuf->data)
if(BufferListItem->next)
{ {
NextBuf = BufferListItem->next->buffer; ALuint ulExtraSamples = min(NextBuf->size, (ALint)(ALBuffer->padding*Channels*Bytes));
if(NextBuf && NextBuf->data) memcpy(&Data[DataSize*Channels], NextBuf->data, ulExtraSamples);
{
ulExtraSamples = min(NextBuf->size, (ALint)(ALBuffer->padding*Channels*Bytes));
memcpy(&Data[DataSize*Channels], NextBuf->data, ulExtraSamples);
}
} }
else if(ALSource->bLooping)
{
NextBuf = ALSource->queue->buffer;
if(NextBuf && NextBuf->data)
{
ulExtraSamples = min(NextBuf->size, (ALint)(ALBuffer->padding*Channels*Bytes));
memcpy(&Data[DataSize*Channels], NextBuf->data, ulExtraSamples);
}
}
else
memset(&Data[DataSize*Channels], 0, (ALBuffer->padding*Channels*Bytes));
} }
else if(ALSource->bLooping)
{
ALbuffer *NextBuf = ALSource->queue->buffer;
if(NextBuf && NextBuf->data)
{
ALuint ulExtraSamples = min(NextBuf->size, (ALint)(ALBuffer->padding*Channels*Bytes));
memcpy(&Data[DataSize*Channels], NextBuf->data, ulExtraSamples);
}
}
else
memset(&Data[DataSize*Channels], 0, (ALBuffer->padding*Channels*Bytes));
BufferSize = min(BufferSize, (SamplesToDo-j)); BufferSize = min(BufferSize, (SamplesToDo-j));
if(DuplicateStereo && Channels == 2)
{
Matrix[FRONT_LEFT][SIDE_LEFT] = 1.0f;
Matrix[FRONT_RIGHT][SIDE_RIGHT] = 1.0f;
Matrix[FRONT_LEFT][BACK_LEFT] = 1.0f;
Matrix[FRONT_RIGHT][BACK_RIGHT] = 1.0f;
}
else if(DuplicateStereo)
{
Matrix[FRONT_LEFT][SIDE_LEFT] = 0.0f;
Matrix[FRONT_RIGHT][SIDE_RIGHT] = 0.0f;
Matrix[FRONT_LEFT][BACK_LEFT] = 0.0f;
Matrix[FRONT_RIGHT][BACK_RIGHT] = 0.0f;
}
/* Actual sample mixing loop */ /* Actual sample mixing loop */
k = 0; k = 0;
Data += DataPosInt*Channels; Data += DataPosInt*Channels;
@ -1110,65 +1113,53 @@ another_source:
} }
DataPosInt += k; DataPosInt += k;
/* Update source info */
ALSource->position = DataPosInt;
ALSource->position_fraction = DataPosFrac;
for(i = 0;i < OUTPUTCHANNELS;i++)
ALSource->DryGains[i] = DrySend[i];
for(i = 0;i < MAX_SENDS;i++)
ALSource->WetGains[i] = WetSend[i];
skipmix: skipmix:
/* Handle looping sources */ /* Handle looping sources */
if(!ALBuffer || DataPosInt >= DataSize) if(DataPosInt >= DataSize)
{ {
/* Queueing */ if(BuffersPlayed < (ALSource->BuffersInQueue-1))
if(ALSource->queue)
{ {
Looping = ALSource->bLooping; BufferListItem = BufferListItem->next;
if(ALSource->BuffersPlayed < (ALSource->BuffersInQueue-1)) BuffersPlayed++;
DataPosInt -= DataSize;
}
else
{
if(!ALSource->bLooping)
{ {
State = AL_STOPPED;
BufferListItem = ALSource->queue; BufferListItem = ALSource->queue;
for(i = 0;i <= ALSource->BuffersPlayed && BufferListItem;i++) BuffersPlayed = ALSource->BuffersInQueue;
BufferListItem = BufferListItem->next; DataPosInt = 0;
if(BufferListItem) DataPosFrac = 0;
ALSource->Buffer = BufferListItem->buffer;
ALSource->position = DataPosInt-DataSize;
ALSource->position_fraction = DataPosFrac;
ALSource->BuffersPlayed++;
} }
else else
{ {
if(!Looping) BufferListItem = ALSource->queue;
{ BuffersPlayed = 0;
/* alSourceStop */ if(ALSource->BuffersInQueue == 1 && DataSize)
ALSource->state = AL_STOPPED; DataPosInt %= DataSize;
ALSource->BuffersPlayed = ALSource->BuffersInQueue;
ALSource->position = 0;
ALSource->position_fraction = 0;
}
else else
{ DataPosInt -= DataSize;
/* alSourceRewind */
/* alSourcePlay */
ALSource->state = AL_PLAYING;
ALSource->BuffersPlayed = 0;
ALSource->Buffer = ALSource->queue->buffer;
if(ALSource->BuffersInQueue == 1)
ALSource->position = DataPosInt%DataSize;
else
ALSource->position = DataPosInt-DataSize;
ALSource->position_fraction = DataPosFrac;
}
} }
} }
} }
/* Get source state */
State = ALSource->state;
} }
/* Update source info */
ALSource->state = State;
ALSource->BuffersPlayed = BuffersPlayed;
ALSource->position = DataPosInt;
ALSource->position_fraction = DataPosFrac;
ALSource->Buffer = BufferListItem->buffer;
for(i = 0;i < OUTPUTCHANNELS;i++)
ALSource->DryGains[i] = DrySend[i];
for(i = 0;i < MAX_SENDS;i++)
ALSource->WetGains[i] = WetSend[i];
ALSource->FirstStart = FirstStart;
if((ALSource=ALSource->next) != NULL) if((ALSource=ALSource->next) != NULL)
goto another_source; goto another_source;
} }