Template-ize the device buffer writing functions

This commit is contained in:
Chris Robinson
2010-12-01 21:50:49 -08:00
parent fa28098a83
commit 4a0bf9fd44
+144 -83
View File
@@ -781,6 +781,140 @@ static __inline ALubyte aluF2UB(ALfloat Value)
return (i>>8)+128;
}
static const Channel MonoChans[] = { FRONT_CENTER };
static const Channel StereoChans[] = { FRONT_LEFT, FRONT_RIGHT };
static const Channel QuadChans[] = { FRONT_LEFT, FRONT_RIGHT,
BACK_LEFT, BACK_RIGHT };
static const Channel X51Chans[] = { FRONT_LEFT, FRONT_RIGHT,
FRONT_CENTER, LFE,
BACK_LEFT, BACK_RIGHT };
static const Channel X61Chans[] = { FRONT_LEFT, FRONT_LEFT,
FRONT_CENTER, LFE, BACK_CENTER,
SIDE_LEFT, SIDE_RIGHT };
static const Channel X71Chans[] = { FRONT_LEFT, FRONT_RIGHT,
FRONT_CENTER, LFE,
BACK_LEFT, BACK_RIGHT,
SIDE_LEFT, SIDE_RIGHT };
#define DECL_TEMPLATE(T, chans,N, func) \
static void Write_##T##_##chans(ALCdevice *device, T *buffer, ALuint SamplesToDo)\
{ \
ALfloat (*DryBuffer)[MAXCHANNELS] = device->DryBuffer; \
ALfloat (*Matrix)[MAXCHANNELS] = device->ChannelMatrix; \
const ALuint *ChanMap = device->DevChannels; \
ALuint i, j, c; \
\
for(i = 0;i < SamplesToDo;i++) \
{ \
for(j = 0;j < N;j++) \
{ \
ALfloat samp = 0.0f; \
for(c = 0;c < MAXCHANNELS;c++) \
samp += DryBuffer[i][c] * Matrix[c][chans[j]]; \
((T*)buffer)[ChanMap[chans[j]]] = func(samp); \
} \
buffer = ((T*)buffer) + N; \
} \
}
DECL_TEMPLATE(ALfloat, MonoChans,1, aluF2F)
DECL_TEMPLATE(ALfloat, QuadChans,4, aluF2F)
DECL_TEMPLATE(ALfloat, X51Chans,6, aluF2F)
DECL_TEMPLATE(ALfloat, X61Chans,7, aluF2F)
DECL_TEMPLATE(ALfloat, X71Chans,8, aluF2F)
DECL_TEMPLATE(ALshort, MonoChans,1, aluF2S)
DECL_TEMPLATE(ALshort, QuadChans,4, aluF2S)
DECL_TEMPLATE(ALshort, X51Chans,6, aluF2S)
DECL_TEMPLATE(ALshort, X61Chans,7, aluF2S)
DECL_TEMPLATE(ALshort, X71Chans,8, aluF2S)
DECL_TEMPLATE(ALubyte, MonoChans,1, aluF2UB)
DECL_TEMPLATE(ALubyte, QuadChans,4, aluF2UB)
DECL_TEMPLATE(ALubyte, X51Chans,6, aluF2UB)
DECL_TEMPLATE(ALubyte, X61Chans,7, aluF2UB)
DECL_TEMPLATE(ALubyte, X71Chans,8, aluF2UB)
#undef DECL_TEMPLATE
#define DECL_TEMPLATE(T, chans,N, func) \
static void Write_##T##_##chans(ALCdevice *device, T *buffer, ALuint SamplesToDo)\
{ \
ALfloat (*DryBuffer)[MAXCHANNELS] = device->DryBuffer; \
ALfloat (*Matrix)[MAXCHANNELS] = device->ChannelMatrix; \
const ALuint *ChanMap = device->DevChannels; \
ALuint i, j, c; \
\
if(device->Bs2b) \
{ \
for(i = 0;i < SamplesToDo;i++) \
{ \
float samples[2] = { 0.0f, 0.0f }; \
for(c = 0;c < MAXCHANNELS;c++) \
{ \
samples[0] += DryBuffer[i][c]*Matrix[c][FRONT_LEFT]; \
samples[1] += DryBuffer[i][c]*Matrix[c][FRONT_RIGHT]; \
} \
bs2b_cross_feed(device->Bs2b, samples); \
((T*)buffer)[ChanMap[FRONT_LEFT]] = func(samples[0]); \
((T*)buffer)[ChanMap[FRONT_RIGHT]] = func(samples[1]); \
buffer = ((T*)buffer) + 2; \
} \
} \
else \
{ \
for(i = 0;i < SamplesToDo;i++) \
{ \
for(j = 0;j < N;j++) \
{ \
ALfloat samp = 0.0f; \
for(c = 0;c < MAXCHANNELS;c++) \
samp += DryBuffer[i][c] * Matrix[c][chans[j]]; \
((T*)buffer)[ChanMap[chans[j]]] = func(samp); \
} \
buffer = ((T*)buffer) + N; \
} \
} \
}
DECL_TEMPLATE(ALfloat, StereoChans,2, aluF2F)
DECL_TEMPLATE(ALshort, StereoChans,2, aluF2S)
DECL_TEMPLATE(ALubyte, StereoChans,2, aluF2UB)
#undef DECL_TEMPLATE
#define DECL_TEMPLATE(T, func) \
static void Write_##T(ALCdevice *device, T *buffer, ALuint SamplesToDo) \
{ \
switch(aluChannelsFromFormat(device->Format)) \
{ \
case 1: \
Write_##T##_MonoChans(device, buffer, SamplesToDo); \
break; \
case 2: \
Write_##T##_StereoChans(device, buffer, SamplesToDo); \
break; \
case 4: \
Write_##T##_QuadChans(device, buffer, SamplesToDo); \
break; \
case 6: \
Write_##T##_X51Chans(device, buffer, SamplesToDo); \
break; \
case 7: \
Write_##T##_X61Chans(device, buffer, SamplesToDo); \
break; \
case 8: \
Write_##T##_X71Chans(device, buffer, SamplesToDo); \
break; \
} \
}
DECL_TEMPLATE(ALfloat, aluF2F)
DECL_TEMPLATE(ALshort, aluF2S)
DECL_TEMPLATE(ALubyte, aluF2UB)
#undef DECL_TEMPLATE
ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
{
ALuint SamplesToDo;
@@ -788,7 +922,7 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
ALCcontext **ctx, **ctx_end;
ALsource **src, **src_end;
int fpuState;
ALuint i, j, c;
ALuint i, c;
ALsizei e;
#if defined(HAVE_FESETROUND)
@@ -880,89 +1014,16 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
device->PendingClicks[i] = 0.0f;
}
switch(device->Format)
switch(aluBytesFromFormat(device->Format))
{
#define DO_WRITE(T, func, N, ...) do { \
const Channel chans[] = { \
__VA_ARGS__ \
}; \
ALfloat (*DryBuffer)[MAXCHANNELS] = device->DryBuffer; \
ALfloat (*Matrix)[MAXCHANNELS] = device->ChannelMatrix; \
const ALuint *ChanMap = device->DevChannels; \
\
for(i = 0;i < SamplesToDo;i++) \
{ \
for(j = 0;j < N;j++) \
{ \
ALfloat samp = 0.0f; \
for(c = 0;c < MAXCHANNELS;c++) \
samp += DryBuffer[i][c] * Matrix[c][chans[j]]; \
((T*)buffer)[ChanMap[chans[j]]] = func(samp); \
} \
buffer = ((T*)buffer) + N; \
} \
} while(0)
#define CHECK_WRITE_FORMAT(bits, T, func) \
case AL_FORMAT_MONO##bits: \
DO_WRITE(T, func, 1, FRONT_CENTER); \
break; \
case AL_FORMAT_STEREO##bits: \
if(device->Bs2b) \
{ \
ALfloat (*DryBuffer)[MAXCHANNELS] = device->DryBuffer; \
ALfloat (*Matrix)[MAXCHANNELS] = device->ChannelMatrix; \
const ALuint *ChanMap = device->DevChannels; \
\
for(i = 0;i < SamplesToDo;i++) \
{ \
float samples[2] = { 0.0f, 0.0f }; \
for(c = 0;c < MAXCHANNELS;c++) \
{ \
samples[0] += DryBuffer[i][c]*Matrix[c][FRONT_LEFT]; \
samples[1] += DryBuffer[i][c]*Matrix[c][FRONT_RIGHT]; \
} \
bs2b_cross_feed(device->Bs2b, samples); \
((T*)buffer)[ChanMap[FRONT_LEFT]] = func(samples[0]); \
((T*)buffer)[ChanMap[FRONT_RIGHT]] = func(samples[1]); \
buffer = ((T*)buffer) + 2; \
} \
} \
else \
DO_WRITE(T, func, 2, FRONT_LEFT, FRONT_RIGHT); \
break; \
case AL_FORMAT_QUAD##bits: \
DO_WRITE(T, func, 4, FRONT_LEFT, FRONT_RIGHT, \
BACK_LEFT, BACK_RIGHT); \
break; \
case AL_FORMAT_51CHN##bits: \
DO_WRITE(T, func, 6, FRONT_LEFT, FRONT_RIGHT, \
FRONT_CENTER, LFE, \
BACK_LEFT, BACK_RIGHT); \
break; \
case AL_FORMAT_61CHN##bits: \
DO_WRITE(T, func, 7, FRONT_LEFT, FRONT_RIGHT, \
FRONT_CENTER, LFE, BACK_CENTER, \
SIDE_LEFT, SIDE_RIGHT); \
break; \
case AL_FORMAT_71CHN##bits: \
DO_WRITE(T, func, 8, FRONT_LEFT, FRONT_RIGHT, \
FRONT_CENTER, LFE, \
BACK_LEFT, BACK_RIGHT, \
SIDE_LEFT, SIDE_RIGHT); \
break;
#define AL_FORMAT_MONO32 AL_FORMAT_MONO_FLOAT32
#define AL_FORMAT_STEREO32 AL_FORMAT_STEREO_FLOAT32
CHECK_WRITE_FORMAT(8, ALubyte, aluF2UB)
CHECK_WRITE_FORMAT(16, ALshort, aluF2S)
CHECK_WRITE_FORMAT(32, ALfloat, aluF2F)
#undef AL_FORMAT_STEREO32
#undef AL_FORMAT_MONO32
#undef CHECK_WRITE_FORMAT
#undef DO_WRITE
default:
case 1:
Write_ALubyte(device, buffer, SamplesToDo);
break;
case 2:
Write_ALshort(device, buffer, SamplesToDo);
break;
case 4:
Write_ALfloat(device, buffer, SamplesToDo);
break;
}