Retreive and store source params once per mix update
This commit is contained in:
parent
1665595138
commit
c003d6032d
233
Alc/ALu.c
233
Alc/ALu.c
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user