Change the mixer macros to declare functions

This commit is contained in:
Chris Robinson
2010-11-24 17:07:50 -08:00
parent 1311e051d9
commit cd87061749
+197 -77
View File
@@ -72,16 +72,23 @@ static __inline ALfloat cos_lerp16(ALfloat val1, ALfloat val2, ALint frac)
}
#define DO_MIX_MONO(data,sampler) do { \
#define DECL_MIX_MONO(T,sampler) \
static void MixMono_##T##_##sampler(ALsource *Source, ALCdevice *Device, \
const T *data, ALuint *DataPosInt, ALuint *DataPosFrac, ALuint DataEnd, \
ALuint j, ALuint SamplesToDo, ALuint BufferSize) \
{ \
ALfloat (*DryBuffer)[OUTPUTCHANNELS]; \
ALfloat *ClickRemoval, *PendingClicks; \
ALuint pos, frac; \
ALfloat DrySend[OUTPUTCHANNELS]; \
FILTER *DryFilter; \
ALuint BufferIdx; \
ALuint increment; \
ALuint i, out; \
ALfloat value; \
\
increment = Source->Params.Step; \
\
DryBuffer = Device->DryBuffer; \
ClickRemoval = Device->ClickRemoval; \
PendingClicks = Device->PendingClicks; \
@@ -89,8 +96,8 @@ static __inline ALfloat cos_lerp16(ALfloat val1, ALfloat val2, ALint frac)
for(i = 0;i < OUTPUTCHANNELS;i++) \
DrySend[i] = Source->Params.DryGains[i]; \
\
pos = DataPosInt; \
frac = DataPosFrac; \
pos = *DataPosInt; \
frac = *DataPosFrac; \
\
if(j == 0) \
{ \
@@ -131,7 +138,7 @@ static __inline ALfloat cos_lerp16(ALfloat val1, ALfloat val2, ALint frac)
{ \
ALuint p = pos; \
ALuint f = frac; \
if(p >= LoopEnd) \
if(p >= DataEnd) \
{ \
ALuint64 pos64 = pos; \
pos64 <<= FRACTIONBITS; \
@@ -171,8 +178,8 @@ static __inline ALfloat cos_lerp16(ALfloat val1, ALfloat val2, ALint frac)
WetFilter = &Source->Params.Send[out].iirFilter; \
WetSend = Source->Params.Send[out].WetGain; \
\
pos = DataPosInt; \
frac = DataPosFrac; \
pos = *DataPosInt; \
frac = *DataPosFrac; \
j -= BufferSize; \
\
if(j == 0) \
@@ -200,7 +207,7 @@ static __inline ALfloat cos_lerp16(ALfloat val1, ALfloat val2, ALint frac)
{ \
ALuint p = pos; \
ALuint f = frac; \
if(p >= LoopEnd) \
if(p >= DataEnd) \
{ \
ALuint64 pos64 = pos; \
pos64 <<= FRACTIONBITS; \
@@ -215,11 +222,30 @@ static __inline ALfloat cos_lerp16(ALfloat val1, ALfloat val2, ALint frac)
WetPendingClicks[0] += value*WetSend; \
} \
} \
DataPosInt = pos; \
DataPosFrac = frac; \
} while(0)
*DataPosInt = pos; \
*DataPosFrac = frac; \
}
#define DO_MIX_STEREO(data,sampler) do { \
DECL_MIX_MONO(ALfloat, point32)
DECL_MIX_MONO(ALfloat, lerp32)
DECL_MIX_MONO(ALfloat, cos_lerp32)
DECL_MIX_MONO(ALshort, point16)
DECL_MIX_MONO(ALshort, lerp16)
DECL_MIX_MONO(ALshort, cos_lerp16)
#define DECL_MIX_STEREO(T,sampler) \
static void MixStereo_##T##_##sampler(ALsource *Source, ALCdevice *Device, \
const T *data, ALuint *DataPosInt, ALuint *DataPosFrac, ALuint DataEnd, \
ALuint j, ALuint SamplesToDo, ALuint BufferSize) \
{ \
static const ALuint Channels = 2; \
static const Channel chans[] = { \
FRONT_LEFT, FRONT_RIGHT, \
SIDE_LEFT, SIDE_RIGHT, \
BACK_LEFT, BACK_RIGHT \
}; \
const ALfloat scaler = 1.0f/Channels; \
ALfloat (*DryBuffer)[OUTPUTCHANNELS]; \
ALfloat *ClickRemoval, *PendingClicks; \
@@ -227,9 +253,12 @@ static __inline ALfloat cos_lerp16(ALfloat val1, ALfloat val2, ALint frac)
ALfloat DrySend[OUTPUTCHANNELS]; \
FILTER *DryFilter; \
ALuint BufferIdx; \
ALuint increment; \
ALuint i, out; \
ALfloat value; \
\
increment = Source->Params.Step; \
\
DryBuffer = Device->DryBuffer; \
ClickRemoval = Device->ClickRemoval; \
PendingClicks = Device->PendingClicks; \
@@ -237,8 +266,8 @@ static __inline ALfloat cos_lerp16(ALfloat val1, ALfloat val2, ALint frac)
for(i = 0;i < OUTPUTCHANNELS;i++) \
DrySend[i] = Source->Params.DryGains[i]; \
\
pos = DataPosInt; \
frac = DataPosFrac; \
pos = *DataPosInt; \
frac = *DataPosFrac; \
\
if(j == 0) \
{ \
@@ -275,7 +304,7 @@ static __inline ALfloat cos_lerp16(ALfloat val1, ALfloat val2, ALint frac)
{ \
ALuint p = pos; \
ALuint f = frac; \
if(p >= LoopEnd) \
if(p >= DataEnd) \
{ \
ALuint64 pos64 = pos; \
pos64 <<= FRACTIONBITS; \
@@ -314,8 +343,8 @@ static __inline ALfloat cos_lerp16(ALfloat val1, ALfloat val2, ALint frac)
WetFilter = &Source->Params.Send[out].iirFilter; \
WetSend = Source->Params.Send[out].WetGain; \
\
pos = DataPosInt; \
frac = DataPosFrac; \
pos = *DataPosInt; \
frac = *DataPosFrac; \
j -= BufferSize; \
\
if(j == 0) \
@@ -349,7 +378,7 @@ static __inline ALfloat cos_lerp16(ALfloat val1, ALfloat val2, ALint frac)
{ \
ALuint p = pos; \
ALuint f = frac; \
if(p >= LoopEnd) \
if(p >= DataEnd) \
{ \
ALuint64 pos64 = pos; \
pos64 <<= FRACTIONBITS; \
@@ -368,11 +397,26 @@ static __inline ALfloat cos_lerp16(ALfloat val1, ALfloat val2, ALint frac)
} \
} \
} \
DataPosInt = pos; \
DataPosFrac = frac; \
} while(0)
*DataPosInt = pos; \
*DataPosFrac = frac; \
}
#define DO_MIX_MC(data,sampler) do { \
DECL_MIX_STEREO(ALfloat, point32)
DECL_MIX_STEREO(ALfloat, lerp32)
DECL_MIX_STEREO(ALfloat, cos_lerp32)
DECL_MIX_STEREO(ALshort, point16)
DECL_MIX_STEREO(ALshort, lerp16)
DECL_MIX_STEREO(ALshort, cos_lerp16)
#define DECL_MIX_MC(T,chans,sampler) \
static void MixMC_##T##_##chans##_##sampler(ALsource *Source, ALCdevice *Device,\
const T *data, ALuint *DataPosInt, ALuint *DataPosFrac, ALuint DataEnd, \
ALuint j, ALuint SamplesToDo, ALuint BufferSize) \
{ \
static const ALuint Channels = sizeof(chans)/sizeof(chans[0]); \
const ALfloat scaler = 1.0f/Channels; \
ALfloat (*DryBuffer)[OUTPUTCHANNELS]; \
ALfloat *ClickRemoval, *PendingClicks; \
@@ -380,9 +424,12 @@ static __inline ALfloat cos_lerp16(ALfloat val1, ALfloat val2, ALint frac)
ALfloat DrySend[OUTPUTCHANNELS]; \
FILTER *DryFilter; \
ALuint BufferIdx; \
ALuint increment; \
ALuint i, out; \
ALfloat value; \
\
increment = Source->Params.Step; \
\
DryBuffer = Device->DryBuffer; \
ClickRemoval = Device->ClickRemoval; \
PendingClicks = Device->PendingClicks; \
@@ -390,8 +437,8 @@ static __inline ALfloat cos_lerp16(ALfloat val1, ALfloat val2, ALint frac)
for(i = 0;i < OUTPUTCHANNELS;i++) \
DrySend[i] = Source->Params.DryGains[i]; \
\
pos = DataPosInt; \
frac = DataPosFrac; \
pos = *DataPosInt; \
frac = *DataPosFrac; \
\
if(j == 0) \
{ \
@@ -424,7 +471,7 @@ static __inline ALfloat cos_lerp16(ALfloat val1, ALfloat val2, ALint frac)
{ \
ALuint p = pos; \
ALuint f = frac; \
if(p >= LoopEnd) \
if(p >= DataEnd) \
{ \
ALuint64 pos64 = pos; \
pos64 <<= FRACTIONBITS; \
@@ -461,8 +508,8 @@ static __inline ALfloat cos_lerp16(ALfloat val1, ALfloat val2, ALint frac)
WetFilter = &Source->Params.Send[out].iirFilter; \
WetSend = Source->Params.Send[out].WetGain; \
\
pos = DataPosInt; \
frac = DataPosFrac; \
pos = *DataPosInt; \
frac = *DataPosFrac; \
j -= BufferSize; \
\
if(j == 0) \
@@ -496,7 +543,7 @@ static __inline ALfloat cos_lerp16(ALfloat val1, ALfloat val2, ALint frac)
{ \
ALuint p = pos; \
ALuint f = frac; \
if(p >= LoopEnd) \
if(p >= DataEnd) \
{ \
ALuint64 pos64 = pos; \
pos64 <<= FRACTIONBITS; \
@@ -515,73 +562,133 @@ static __inline ALfloat cos_lerp16(ALfloat val1, ALfloat val2, ALint frac)
} \
} \
} \
DataPosInt = pos; \
DataPosFrac = frac; \
} while(0)
*DataPosInt = pos; \
*DataPosFrac = frac; \
}
static const Channel QuadChans[] = { FRONT_LEFT, FRONT_RIGHT,
BACK_LEFT, BACK_RIGHT };
DECL_MIX_MC(ALfloat, QuadChans, point32)
DECL_MIX_MC(ALfloat, QuadChans, lerp32)
DECL_MIX_MC(ALfloat, QuadChans, cos_lerp32)
DECL_MIX_MC(ALshort, QuadChans, point16)
DECL_MIX_MC(ALshort, QuadChans, lerp16)
DECL_MIX_MC(ALshort, QuadChans, cos_lerp16)
#define MIX_MONO(sampler) do { \
if(Bytes == 4) \
DO_MIX_MONO(Data.p32,sampler##32); \
else if(Bytes == 2) \
DO_MIX_MONO(Data.p16,sampler##16); \
} while(0)
static const Channel X51Chans[] = { FRONT_LEFT, FRONT_RIGHT,
FRONT_CENTER, LFE,
BACK_LEFT, BACK_RIGHT };
DECL_MIX_MC(ALfloat, X51Chans, point32)
DECL_MIX_MC(ALfloat, X51Chans, lerp32)
DECL_MIX_MC(ALfloat, X51Chans, cos_lerp32)
#define MIX_STEREO(sampler) do { \
const int chans[] = { \
FRONT_LEFT, FRONT_RIGHT, \
SIDE_LEFT, SIDE_RIGHT, \
BACK_LEFT, BACK_RIGHT \
}; \
\
if(Bytes == 4) \
DO_MIX_STEREO(Data.p32,sampler##32); \
else if(Bytes == 2) \
DO_MIX_STEREO(Data.p16,sampler##16); \
} while(0)
#define MIX_MC(sampler,...) do { \
const int chans[] = { __VA_ARGS__ }; \
\
if(Bytes == 4) \
DO_MIX_MC(Data.p32,sampler##32); \
else if(Bytes == 2) \
DO_MIX_MC(Data.p16,sampler##16); \
} while(0)
DECL_MIX_MC(ALshort, X51Chans, point16)
DECL_MIX_MC(ALshort, X51Chans, lerp16)
DECL_MIX_MC(ALshort, X51Chans, cos_lerp16)
#define MIX(sampler) do { \
static const Channel X61Chans[] = { FRONT_LEFT, FRONT_RIGHT,
FRONT_CENTER, LFE,
BACK_CENTER,
SIDE_LEFT, SIDE_RIGHT };
DECL_MIX_MC(ALfloat, X61Chans, point32)
DECL_MIX_MC(ALfloat, X61Chans, lerp32)
DECL_MIX_MC(ALfloat, X61Chans, cos_lerp32)
DECL_MIX_MC(ALshort, X61Chans, point16)
DECL_MIX_MC(ALshort, X61Chans, lerp16)
DECL_MIX_MC(ALshort, X61Chans, cos_lerp16)
static const Channel X71Chans[] = { FRONT_LEFT, FRONT_RIGHT,
FRONT_CENTER, LFE,
BACK_LEFT, BACK_RIGHT,
SIDE_LEFT, SIDE_RIGHT };
DECL_MIX_MC(ALfloat, X71Chans, point32)
DECL_MIX_MC(ALfloat, X71Chans, lerp32)
DECL_MIX_MC(ALfloat, X71Chans, cos_lerp32)
DECL_MIX_MC(ALshort, X71Chans, point16)
DECL_MIX_MC(ALshort, X71Chans, lerp16)
DECL_MIX_MC(ALshort, X71Chans, cos_lerp16)
#define DECL_MIX(sampler) \
static void Mix_##sampler(ALsource *Source, ALCdevice *Device, \
const ALvoid *Data, ALuint *DataPosInt, ALuint *DataPosFrac, ALuint DataEnd,\
ALuint Channels, ALuint Bytes, \
ALuint j, ALuint SamplesToDo, ALuint BufferSize) \
{ \
switch(Channels) \
{ \
case 1: /* Mono */ \
MIX_MONO(sampler); \
if(Bytes == 4) \
MixMono_ALfloat_##sampler##32(Source, Device, \
Data, DataPosInt, DataPosFrac, DataEnd, \
j, SamplesToDo, BufferSize); \
else if(Bytes == 2) \
MixMono_ALshort_##sampler##16(Source, Device, \
Data, DataPosInt, DataPosFrac, DataEnd, \
j, SamplesToDo, BufferSize); \
break; \
case 2: /* Stereo */ \
MIX_STEREO(sampler); \
if(Bytes == 4) \
MixStereo_ALfloat_##sampler##32(Source, Device, \
Data, DataPosInt, DataPosFrac, DataEnd, \
j, SamplesToDo, BufferSize); \
else if(Bytes == 2) \
MixStereo_ALshort_##sampler##16(Source, Device, \
Data, DataPosInt, DataPosFrac, DataEnd, \
j, SamplesToDo, BufferSize); \
break; \
case 4: /* Quad */ \
MIX_MC(sampler, FRONT_LEFT, FRONT_RIGHT, \
BACK_LEFT, BACK_RIGHT); \
if(Bytes == 4) \
MixMC_ALfloat_QuadChans_##sampler##32(Source, Device, \
Data, DataPosInt, DataPosFrac, DataEnd, \
j, SamplesToDo, BufferSize); \
else if(Bytes == 2) \
MixMC_ALshort_QuadChans_##sampler##16(Source, Device, \
Data, DataPosInt, DataPosFrac, DataEnd, \
j, SamplesToDo, BufferSize); \
break; \
case 6: /* 5.1 */ \
MIX_MC(sampler, FRONT_LEFT, FRONT_RIGHT, \
FRONT_CENTER, LFE, \
BACK_LEFT, BACK_RIGHT); \
if(Bytes == 4) \
MixMC_ALfloat_X51Chans_##sampler##32(Source, Device, \
Data, DataPosInt, DataPosFrac, DataEnd, \
j, SamplesToDo, BufferSize); \
else if(Bytes == 2) \
MixMC_ALshort_X51Chans_##sampler##16(Source, Device, \
Data, DataPosInt, DataPosFrac, DataEnd, \
j, SamplesToDo, BufferSize); \
break; \
case 7: /* 6.1 */ \
MIX_MC(sampler, FRONT_LEFT, FRONT_RIGHT, \
FRONT_CENTER, LFE, \
BACK_CENTER, \
SIDE_LEFT, SIDE_RIGHT); \
if(Bytes == 4) \
MixMC_ALfloat_X61Chans_##sampler##32(Source, Device, \
Data, DataPosInt, DataPosFrac, DataEnd, \
j, SamplesToDo, BufferSize); \
else if(Bytes == 2) \
MixMC_ALshort_X61Chans_##sampler##16(Source, Device, \
Data, DataPosInt, DataPosFrac, DataEnd, \
j, SamplesToDo, BufferSize); \
break; \
case 8: /* 7.1 */ \
MIX_MC(sampler, FRONT_LEFT, FRONT_RIGHT, \
FRONT_CENTER, LFE, \
BACK_LEFT, BACK_RIGHT, \
SIDE_LEFT, SIDE_RIGHT); \
if(Bytes == 4) \
MixMC_ALfloat_X71Chans_##sampler##32(Source, Device, \
Data, DataPosInt, DataPosFrac, DataEnd, \
j, SamplesToDo, BufferSize); \
else if(Bytes == 2) \
MixMC_ALshort_X71Chans_##sampler##16(Source, Device, \
Data, DataPosInt, DataPosFrac, DataEnd, \
j, SamplesToDo, BufferSize); \
break; \
} \
} while(0)
}
DECL_MIX(point)
DECL_MIX(lerp)
DECL_MIX(cos_lerp)
ALvoid MixSource(ALsource *Source, ALCdevice *Device, ALuint SamplesToDo)
@@ -687,15 +794,28 @@ ALvoid MixSource(ALsource *Source, ALCdevice *Device, ALuint SamplesToDo)
switch(Source->Resampler)
{
case POINT_RESAMPLER:
MIX(point); break;
Mix_point(Source, Device,
Data.p8, &DataPosInt, &DataPosFrac, LoopEnd,
Channels, Bytes,
j, SamplesToDo, BufferSize);
break;
case LINEAR_RESAMPLER:
MIX(lerp); break;
Mix_lerp(Source, Device,
Data.p8, &DataPosInt, &DataPosFrac, LoopEnd,
Channels, Bytes,
j, SamplesToDo, BufferSize);
break;
case COSINE_RESAMPLER:
MIX(cos_lerp); break;
Mix_cos_lerp(Source, Device,
Data.p8, &DataPosInt, &DataPosFrac, LoopEnd,
Channels, Bytes,
j, SamplesToDo, BufferSize);
break;
case RESAMPLER_MIN:
case RESAMPLER_MAX:
break;
}
j += BufferSize;
skipmix:
/* Handle looping sources */