Use function pointers to call the source mixer

master
Chris Robinson 2011-05-06 00:20:40 -07:00
parent 38db4115fc
commit 2972de1047
4 changed files with 67 additions and 100 deletions

View File

@ -72,10 +72,11 @@ static __inline ALdouble cubic8(const ALbyte *vals, ALint step, ALint frac)
#define DECL_TEMPLATE(T, chnct, sampler) \
static void Mix_Hrtf_##T##_##chnct##_##sampler( \
ALsource *Source, ALCdevice *Device, \
const T *RESTRICT data, ALuint *DataPosInt, ALuint *DataPosFrac, \
const ALvoid *srcdata, ALuint *DataPosInt, ALuint *DataPosFrac, \
ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize) \
{ \
const ALfloat scaler = 1.0f/chnct; \
const T *RESTRICT data = srcdata; \
ALfloat (*RESTRICT DryBuffer)[MAXCHANNELS]; \
ALfloat *RESTRICT ClickRemoval, *RESTRICT PendingClicks; \
ALfloat (*RESTRICT HrtfCoeffs)[HRTF_LENGTH][2]; \
@ -310,10 +311,11 @@ DECL_TEMPLATE(ALbyte, 8, cubic8)
#define DECL_TEMPLATE(T, chnct, sampler) \
static void Mix_##T##_##chnct##_##sampler(ALsource *Source, ALCdevice *Device,\
const T *RESTRICT data, ALuint *DataPosInt, ALuint *DataPosFrac, \
const ALvoid *srcdata, ALuint *DataPosInt, ALuint *DataPosFrac, \
ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize) \
{ \
const ALfloat scaler = 1.0f/chnct; \
const T *RESTRICT data = srcdata; \
ALfloat (*DryBuffer)[MAXCHANNELS]; \
ALfloat *ClickRemoval, *PendingClicks; \
ALuint pos, frac; \
@ -521,73 +523,35 @@ DECL_TEMPLATE(ALbyte, 8, cubic8)
#define DECL_TEMPLATE(T, sampler) \
static void Mix_##T##_##sampler(ALsource *Source, ALCdevice *Device, \
enum FmtChannels FmtChannels, \
const ALvoid *RESTRICT Data, ALuint *DataPosInt, ALuint *DataPosFrac, \
ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize) \
static void Select_##T##_##sampler(ALsource *Source, \
enum FmtChannels FmtChannels) \
{ \
switch(FmtChannels) \
{ \
case FmtMono: \
if((Device->Flags&DEVICE_USE_HRTF)) \
Mix_Hrtf_##T##_1_##sampler(Source, Device, Data, \
DataPosInt, DataPosFrac, \
OutPos, SamplesToDo, BufferSize); \
else \
Mix_##T##_1_##sampler(Source, Device, Data, \
DataPosInt, DataPosFrac, \
OutPos, SamplesToDo, BufferSize); \
Source->DoMix = Mix_##T##_1_##sampler; \
Source->DoHrtfMix = Mix_Hrtf_##T##_1_##sampler; \
break; \
case FmtStereo: \
case FmtRear: \
if((Device->Flags&DEVICE_USE_HRTF)) \
Mix_Hrtf_##T##_2_##sampler(Source, Device, Data, \
DataPosInt, DataPosFrac, \
OutPos, SamplesToDo, BufferSize); \
else \
Mix_##T##_2_##sampler(Source, Device, Data, \
DataPosInt, DataPosFrac, \
OutPos, SamplesToDo, BufferSize); \
Source->DoMix = Mix_##T##_2_##sampler; \
Source->DoHrtfMix = Mix_Hrtf_##T##_2_##sampler; \
break; \
case FmtQuad: \
if((Device->Flags&DEVICE_USE_HRTF)) \
Mix_Hrtf_##T##_4_##sampler(Source, Device, Data, \
DataPosInt, DataPosFrac, \
OutPos, SamplesToDo, BufferSize); \
else \
Mix_##T##_4_##sampler(Source, Device, Data, \
DataPosInt, DataPosFrac, \
OutPos, SamplesToDo, BufferSize); \
Source->DoMix = Mix_##T##_4_##sampler; \
Source->DoHrtfMix = Mix_Hrtf_##T##_4_##sampler; \
break; \
case FmtX51: \
if((Device->Flags&DEVICE_USE_HRTF)) \
Mix_Hrtf_##T##_6_##sampler(Source, Device, Data, \
DataPosInt, DataPosFrac, \
OutPos, SamplesToDo, BufferSize); \
else \
Mix_##T##_6_##sampler(Source, Device, Data, \
DataPosInt, DataPosFrac, \
OutPos, SamplesToDo, BufferSize); \
Source->DoMix = Mix_##T##_6_##sampler; \
Source->DoHrtfMix = Mix_Hrtf_##T##_6_##sampler; \
break; \
case FmtX61: \
if((Device->Flags&DEVICE_USE_HRTF)) \
Mix_Hrtf_##T##_7_##sampler(Source, Device, Data, \
DataPosInt, DataPosFrac, \
OutPos, SamplesToDo, BufferSize); \
else \
Mix_##T##_7_##sampler(Source, Device, Data, \
DataPosInt, DataPosFrac, \
OutPos, SamplesToDo, BufferSize); \
Source->DoMix = Mix_##T##_7_##sampler; \
Source->DoHrtfMix = Mix_Hrtf_##T##_7_##sampler; \
break; \
case FmtX71: \
if((Device->Flags&DEVICE_USE_HRTF)) \
Mix_Hrtf_##T##_8_##sampler(Source, Device, Data, \
DataPosInt, DataPosFrac, \
OutPos, SamplesToDo, BufferSize); \
else \
Mix_##T##_8_##sampler(Source, Device, Data, \
DataPosInt, DataPosFrac, \
OutPos, SamplesToDo, BufferSize); \
Source->DoMix = Mix_##T##_8_##sampler; \
Source->DoHrtfMix = Mix_Hrtf_##T##_8_##sampler; \
break; \
} \
}
@ -608,29 +572,19 @@ DECL_TEMPLATE(ALbyte, cubic8)
#define DECL_TEMPLATE(sampler) \
static void Mix_##sampler(ALsource *Source, ALCdevice *Device, \
enum FmtChannels FmtChannels, enum FmtType FmtType, \
const ALvoid *RESTRICT Data, ALuint *DataPosInt, ALuint *DataPosFrac, \
ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize) \
static void Select_##sampler(ALsource *Source, \
enum FmtChannels FmtChannels, enum FmtType FmtType) \
{ \
switch(FmtType) \
{ \
case FmtByte: \
Mix_ALbyte_##sampler##8(Source, Device, FmtChannels, \
Data, DataPosInt, DataPosFrac, \
OutPos, SamplesToDo, BufferSize); \
Select_ALbyte_##sampler##8(Source, FmtChannels); \
break; \
\
case FmtShort: \
Mix_ALshort_##sampler##16(Source, Device, FmtChannels, \
Data, DataPosInt, DataPosFrac, \
OutPos, SamplesToDo, BufferSize); \
Select_ALshort_##sampler##16(Source, FmtChannels); \
break; \
\
case FmtFloat: \
Mix_ALfloat_##sampler##32(Source, Device, FmtChannels, \
Data, DataPosInt, DataPosFrac, \
OutPos, SamplesToDo, BufferSize); \
Select_ALfloat_##sampler##32(Source, FmtChannels); \
break; \
} \
}
@ -642,12 +596,30 @@ DECL_TEMPLATE(cubic)
#undef DECL_TEMPLATE
ALvoid SelectMixer(ALsource *Source, ALbuffer *Buffer)
{
switch(Source->Resampler)
{
case POINT_RESAMPLER:
Select_point(Source, Buffer->FmtChannels, Buffer->FmtType);
break;
case LINEAR_RESAMPLER:
Select_lerp(Source, Buffer->FmtChannels, Buffer->FmtType);
break;
case CUBIC_RESAMPLER:
Select_cubic(Source, Buffer->FmtChannels, Buffer->FmtType);
break;
case RESAMPLER_MIN:
case RESAMPLER_MAX:
break;
}
}
ALvoid MixSource(ALsource *Source, ALCdevice *Device, ALuint SamplesToDo)
{
ALbufferlistitem *BufferListItem;
ALuint DataPosInt, DataPosFrac;
enum FmtChannels FmtChannels;
enum FmtType FmtType;
ALuint BuffersPlayed;
ALboolean Looping;
ALuint increment;
@ -665,22 +637,18 @@ ALvoid MixSource(ALsource *Source, ALCdevice *Device, ALuint SamplesToDo)
DataPosFrac = Source->position_fraction;
Looping = Source->bLooping;
increment = Source->Params.Step;
Resampler = (increment == FRACTIONONE) ? POINT_RESAMPLER :
Source->Resampler;
Resampler = Source->Resampler;
/* Get buffer info */
FrameSize = 0;
FmtChannels = FmtMono;
FmtType = FmtByte;
BufferListItem = Source->queue;
for(i = 0;i < Source->BuffersInQueue;i++)
{
const ALbuffer *ALBuffer;
if((ALBuffer=BufferListItem->buffer) != NULL)
{
FmtChannels = ALBuffer->FmtChannels;
FmtType = ALBuffer->FmtType;
FrameSize = FrameSizeFromFmt(FmtChannels, FmtType);
FrameSize = FrameSizeFromFmt(ALBuffer->FmtChannels,
ALBuffer->FmtType);
break;
}
BufferListItem = BufferListItem->next;
@ -889,27 +857,12 @@ ALvoid MixSource(ALsource *Source, ALCdevice *Device, ALuint SamplesToDo)
BufferSize = min(BufferSize, (SamplesToDo-OutPos));
SrcData += BufferPrePadding*FrameSize;
switch(Resampler)
{
case POINT_RESAMPLER:
Mix_point(Source, Device, FmtChannels, FmtType,
SrcData, &DataPosInt, &DataPosFrac,
OutPos, SamplesToDo, BufferSize);
break;
case LINEAR_RESAMPLER:
Mix_lerp(Source, Device, FmtChannels, FmtType,
SrcData, &DataPosInt, &DataPosFrac,
OutPos, SamplesToDo, BufferSize);
break;
case CUBIC_RESAMPLER:
Mix_cubic(Source, Device, FmtChannels, FmtType,
SrcData, &DataPosInt, &DataPosFrac,
OutPos, SamplesToDo, BufferSize);
break;
case RESAMPLER_MIN:
case RESAMPLER_MAX:
break;
}
if((Device->Flags&DEVICE_USE_HRTF))
ALsource_DoHrtfMix(Source, Device, SrcData, &DataPosInt, &DataPosFrac,
OutPos, SamplesToDo, BufferSize);
else
ALsource_DoMix(Source, Device, SrcData, &DataPosInt, &DataPosFrac,
OutPos, SamplesToDo, BufferSize);
OutPos += BufferSize;
/* Handle looping sources */

View File

@ -112,11 +112,21 @@ typedef struct ALsource
} Params;
ALvoid (*Update)(struct ALsource *self, const ALCcontext *context);
ALvoid (*DoMix)(struct ALsource *self, ALCdevice *Device,
const ALvoid *RESTRICT data,
ALuint *DataPosInt, ALuint *DataPosFrac,
ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize);
ALvoid (*DoHrtfMix)(struct ALsource *self, ALCdevice *Device,
const ALvoid *RESTRICT data,
ALuint *DataPosInt, ALuint *DataPosFrac,
ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize);
// Index to itself
ALuint source;
} ALsource;
#define ALsource_Update(s,a) ((s)->Update(s,a))
#define ALsource_Update(s,a) ((s)->Update(s,a))
#define ALsource_DoMix(s,a,b,c,d,e,f,g) ((s)->DoMix(s,a,b,c,d,e,f,g))
#define ALsource_DoHrtfMix(s,a,b,c,d,e,f,g) ((s)->DoHrtfMix(s,a,b,c,d,e,f,g))
ALvoid ReleaseALSources(ALCcontext *Context);

View File

@ -111,6 +111,7 @@ static __inline ALdouble cubic(ALdouble val0, ALdouble val1, ALdouble val2, ALdo
}
struct ALsource;
struct ALbuffer;
ALvoid aluInitPanning(ALCdevice *Device);
ALint aluCart2LUTpos(ALfloat re, ALfloat im);
@ -118,6 +119,7 @@ ALint aluCart2LUTpos(ALfloat re, ALfloat im);
ALvoid CalcSourceParams(struct ALsource *ALSource, const ALCcontext *ALContext);
ALvoid CalcNonAttnSourceParams(struct ALsource *ALSource, const ALCcontext *ALContext);
ALvoid SelectMixer(struct ALsource *Source, struct ALbuffer *Buffer);
ALvoid MixSource(struct ALsource *Source, ALCdevice *Device, ALuint SamplesToDo);
ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size);

View File

@ -570,6 +570,7 @@ AL_API ALvoid AL_APIENTRY alSourcei(ALuint source,ALenum eParam,ALint lValue)
Source->Update = CalcSourceParams;
else
Source->Update = CalcNonAttnSourceParams;
SelectMixer(Source, buffer);
// Increment reference counter for buffer
buffer->refcount++;
@ -1614,6 +1615,7 @@ AL_API ALvoid AL_APIENTRY alSourceQueueBuffers(ALuint source, ALsizei n, const A
Source->Update = CalcSourceParams;
else
Source->Update = CalcNonAttnSourceParams;
SelectMixer(Source, buffer);
Source->NeedsUpdate = AL_TRUE;
}