aboutsummaryrefslogtreecommitdiffstats
path: root/Alc
diff options
context:
space:
mode:
Diffstat (limited to 'Alc')
-rw-r--r--Alc/ALu.c227
1 files changed, 144 insertions, 83 deletions
diff --git a/Alc/ALu.c b/Alc/ALu.c
index 0cd59ae9..2b263d01 100644
--- a/Alc/ALu.c
+++ b/Alc/ALu.c
@@ -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;
}