Use function pointers to call the source mixer
parent
38db4115fc
commit
2972de1047
151
Alc/mixer.c
151
Alc/mixer.c
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue