aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2009-12-02 04:03:51 -0800
committerChris Robinson <[email protected]>2009-12-02 04:03:51 -0800
commitb5270e0bb300f090c159803e79b50ba15b821b2e (patch)
tree3acfd1add6598701dbb4350649339fcf1a853b8a
parent6cfc31777b7cca6714cf926fbc6e491c00a3f836 (diff)
Use a channel-map to specify the output device channel order
-rw-r--r--Alc/ALu.c93
-rw-r--r--Alc/alsa.c2
-rw-r--r--Alc/dsound.c1
-rw-r--r--Alc/oss.c2
-rw-r--r--Alc/portaudio.c2
-rw-r--r--Alc/pulseaudio.c29
-rw-r--r--Alc/solaris.c2
-rw-r--r--Alc/wave.c2
-rw-r--r--OpenAL32/Include/alMain.h81
-rw-r--r--OpenAL32/Include/alu.h4
10 files changed, 132 insertions, 86 deletions
diff --git a/Alc/ALu.c b/Alc/ALu.c
index ce0f841c..36cc4046 100644
--- a/Alc/ALu.c
+++ b/Alc/ALu.c
@@ -1231,6 +1231,7 @@ another_source:
ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
{
float (*DryBuffer)[OUTPUTCHANNELS];
+ const Channel *ChanMap;
ALuint SamplesToDo;
ALeffectslot *ALEffectSlot;
ALCcontext *ALContext;
@@ -1280,14 +1281,15 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
}
//Post processing loop
+ ChanMap = device->DevChannels;
switch(device->Format)
{
-#define CHECK_WRITE_FORMAT(bits, type, func, isWin) \
+#define CHECK_WRITE_FORMAT(bits, type, func) \
case AL_FORMAT_MONO##bits: \
for(i = 0;i < SamplesToDo;i++) \
{ \
- ((type*)buffer)[0] = (func)(DryBuffer[i][FRONT_LEFT] + \
- DryBuffer[i][FRONT_RIGHT]); \
+ ((type*)buffer)[0] = (func)(DryBuffer[i][ChanMap[0]] + \
+ DryBuffer[i][ChanMap[1]]); \
buffer = ((type*)buffer) + 1; \
} \
break; \
@@ -1297,8 +1299,8 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
for(i = 0;i < SamplesToDo;i++) \
{ \
float samples[2]; \
- samples[0] = DryBuffer[i][FRONT_LEFT]; \
- samples[1] = DryBuffer[i][FRONT_RIGHT]; \
+ samples[0] = DryBuffer[i][ChanMap[0]]; \
+ samples[1] = DryBuffer[i][ChanMap[1]]; \
bs2b_cross_feed(device->Bs2b, samples); \
((type*)buffer)[0] = (func)(samples[0]); \
((type*)buffer)[1] = (func)(samples[1]); \
@@ -1309,8 +1311,8 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
{ \
for(i = 0;i < SamplesToDo;i++) \
{ \
- ((type*)buffer)[0] = (func)(DryBuffer[i][FRONT_LEFT]); \
- ((type*)buffer)[1] = (func)(DryBuffer[i][FRONT_RIGHT]); \
+ ((type*)buffer)[0] = (func)(DryBuffer[i][ChanMap[0]]); \
+ ((type*)buffer)[1] = (func)(DryBuffer[i][ChanMap[1]]); \
buffer = ((type*)buffer) + 2; \
} \
} \
@@ -1318,79 +1320,58 @@ ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
case AL_FORMAT_QUAD##bits: \
for(i = 0;i < SamplesToDo;i++) \
{ \
- ((type*)buffer)[0] = (func)(DryBuffer[i][FRONT_LEFT]); \
- ((type*)buffer)[1] = (func)(DryBuffer[i][FRONT_RIGHT]); \
- ((type*)buffer)[2] = (func)(DryBuffer[i][BACK_LEFT]); \
- ((type*)buffer)[3] = (func)(DryBuffer[i][BACK_RIGHT]); \
+ ((type*)buffer)[0] = (func)(DryBuffer[i][ChanMap[0]]); \
+ ((type*)buffer)[1] = (func)(DryBuffer[i][ChanMap[1]]); \
+ ((type*)buffer)[2] = (func)(DryBuffer[i][ChanMap[2]]); \
+ ((type*)buffer)[3] = (func)(DryBuffer[i][ChanMap[3]]); \
buffer = ((type*)buffer) + 4; \
} \
break; \
case AL_FORMAT_51CHN##bits: \
for(i = 0;i < SamplesToDo;i++) \
{ \
- ((type*)buffer)[0] = (func)(DryBuffer[i][FRONT_LEFT]); \
- ((type*)buffer)[1] = (func)(DryBuffer[i][FRONT_RIGHT]); \
- if(isWin) { \
- /* Of course, Windows can't use the same ordering... */ \
- ((type*)buffer)[2] = (func)(DryBuffer[i][FRONT_CENTER]); \
- ((type*)buffer)[3] = (func)(DryBuffer[i][LFE]); \
- ((type*)buffer)[4] = (func)(DryBuffer[i][BACK_LEFT]); \
- ((type*)buffer)[5] = (func)(DryBuffer[i][BACK_RIGHT]); \
- } else { \
- ((type*)buffer)[2] = (func)(DryBuffer[i][BACK_LEFT]); \
- ((type*)buffer)[3] = (func)(DryBuffer[i][BACK_RIGHT]); \
- ((type*)buffer)[4] = (func)(DryBuffer[i][FRONT_CENTER]); \
- ((type*)buffer)[5] = (func)(DryBuffer[i][LFE]); \
- } \
+ ((type*)buffer)[0] = (func)(DryBuffer[i][ChanMap[0]]); \
+ ((type*)buffer)[1] = (func)(DryBuffer[i][ChanMap[1]]); \
+ ((type*)buffer)[2] = (func)(DryBuffer[i][ChanMap[2]]); \
+ ((type*)buffer)[3] = (func)(DryBuffer[i][ChanMap[3]]); \
+ ((type*)buffer)[4] = (func)(DryBuffer[i][ChanMap[4]]); \
+ ((type*)buffer)[5] = (func)(DryBuffer[i][ChanMap[5]]); \
buffer = ((type*)buffer) + 6; \
} \
break; \
case AL_FORMAT_61CHN##bits: \
for(i = 0;i < SamplesToDo;i++) \
{ \
- ((type*)buffer)[0] = (func)(DryBuffer[i][FRONT_LEFT]); \
- ((type*)buffer)[1] = (func)(DryBuffer[i][FRONT_RIGHT]); \
- ((type*)buffer)[2] = (func)(DryBuffer[i][FRONT_CENTER]); \
- ((type*)buffer)[3] = (func)(DryBuffer[i][LFE]); \
- ((type*)buffer)[4] = (func)(DryBuffer[i][BACK_CENTER]); \
- ((type*)buffer)[5] = (func)(DryBuffer[i][SIDE_LEFT]); \
- ((type*)buffer)[6] = (func)(DryBuffer[i][SIDE_RIGHT]); \
+ ((type*)buffer)[0] = (func)(DryBuffer[i][ChanMap[0]]); \
+ ((type*)buffer)[1] = (func)(DryBuffer[i][ChanMap[1]]); \
+ ((type*)buffer)[2] = (func)(DryBuffer[i][ChanMap[2]]); \
+ ((type*)buffer)[3] = (func)(DryBuffer[i][ChanMap[3]]); \
+ ((type*)buffer)[4] = (func)(DryBuffer[i][ChanMap[4]]); \
+ ((type*)buffer)[5] = (func)(DryBuffer[i][ChanMap[5]]); \
+ ((type*)buffer)[6] = (func)(DryBuffer[i][ChanMap[6]]); \
buffer = ((type*)buffer) + 7; \
} \
break; \
case AL_FORMAT_71CHN##bits: \
for(i = 0;i < SamplesToDo;i++) \
{ \
- ((type*)buffer)[0] = (func)(DryBuffer[i][FRONT_LEFT]); \
- ((type*)buffer)[1] = (func)(DryBuffer[i][FRONT_RIGHT]); \
- if(isWin) { \
- ((type*)buffer)[2] = (func)(DryBuffer[i][FRONT_CENTER]); \
- ((type*)buffer)[3] = (func)(DryBuffer[i][LFE]); \
- ((type*)buffer)[4] = (func)(DryBuffer[i][BACK_LEFT]); \
- ((type*)buffer)[5] = (func)(DryBuffer[i][BACK_RIGHT]); \
- } else { \
- ((type*)buffer)[2] = (func)(DryBuffer[i][BACK_LEFT]); \
- ((type*)buffer)[3] = (func)(DryBuffer[i][BACK_RIGHT]); \
- ((type*)buffer)[4] = (func)(DryBuffer[i][FRONT_CENTER]); \
- ((type*)buffer)[5] = (func)(DryBuffer[i][LFE]); \
- } \
- ((type*)buffer)[6] = (func)(DryBuffer[i][SIDE_LEFT]); \
- ((type*)buffer)[7] = (func)(DryBuffer[i][SIDE_RIGHT]); \
+ ((type*)buffer)[0] = (func)(DryBuffer[i][ChanMap[0]]); \
+ ((type*)buffer)[1] = (func)(DryBuffer[i][ChanMap[1]]); \
+ ((type*)buffer)[2] = (func)(DryBuffer[i][ChanMap[2]]); \
+ ((type*)buffer)[3] = (func)(DryBuffer[i][ChanMap[3]]); \
+ ((type*)buffer)[4] = (func)(DryBuffer[i][ChanMap[4]]); \
+ ((type*)buffer)[5] = (func)(DryBuffer[i][ChanMap[5]]); \
+ ((type*)buffer)[6] = (func)(DryBuffer[i][ChanMap[6]]); \
+ ((type*)buffer)[7] = (func)(DryBuffer[i][ChanMap[7]]); \
buffer = ((type*)buffer) + 8; \
} \
break;
#define AL_FORMAT_MONO32 AL_FORMAT_MONO_FLOAT32
#define AL_FORMAT_STEREO32 AL_FORMAT_STEREO_FLOAT32
-#ifdef _WIN32
- CHECK_WRITE_FORMAT(8, ALubyte, aluF2UB, 1)
- CHECK_WRITE_FORMAT(16, ALshort, aluF2S, 1)
- CHECK_WRITE_FORMAT(32, ALfloat, aluF2F, 1)
-#else
- CHECK_WRITE_FORMAT(8, ALubyte, aluF2UB, 0)
- CHECK_WRITE_FORMAT(16, ALshort, aluF2S, 0)
- CHECK_WRITE_FORMAT(32, ALfloat, aluF2F, 0)
-#endif
+ 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
diff --git a/Alc/alsa.c b/Alc/alsa.c
index 85092ceb..25956746 100644
--- a/Alc/alsa.c
+++ b/Alc/alsa.c
@@ -663,6 +663,8 @@ static ALCboolean alsa_reset_playback(ALCdevice *device)
psnd_pcm_sw_params_free(sp);
+ SetDefaultChannelOrder(device);
+
data->size = psnd_pcm_frames_to_bytes(data->pcmHandle, periodSizeInFrames);
if(access == SND_PCM_ACCESS_RW_INTERLEAVED)
{
diff --git a/Alc/dsound.c b/Alc/dsound.c
index e6294a43..966b6236 100644
--- a/Alc/dsound.c
+++ b/Alc/dsound.c
@@ -415,6 +415,7 @@ static ALCboolean DSoundResetPlayback(ALCdevice *device)
if(SUCCEEDED(hr))
{
device->Format = format;
+ SetDefaultWFXChannelOrder(device);
pData->thread = StartThread(DSoundProc, device);
if(!pData->thread)
hr = E_FAIL;
diff --git a/Alc/oss.c b/Alc/oss.c
index 94380fde..64cf23c6 100644
--- a/Alc/oss.c
+++ b/Alc/oss.c
@@ -274,6 +274,8 @@ static ALCboolean oss_reset_playback(ALCdevice *device)
data->data_size = device->UpdateSize * frameSize;
data->mix_data = calloc(1, data->data_size);
+ SetDefaultChannelOrder(device);
+
data->thread = StartThread(OSSProc, device);
if(data->thread == NULL)
{
diff --git a/Alc/portaudio.c b/Alc/portaudio.c
index 5c90f611..580cc4fb 100644
--- a/Alc/portaudio.c
+++ b/Alc/portaudio.c
@@ -189,6 +189,8 @@ static ALCboolean pa_open_playback(ALCdevice *device, const ALCchar *deviceName)
}
outParams.channelCount = aluChannelsFromFormat(device->Format);
+ SetDefaultChannelOrder(device);
+
err = pPa_OpenStream(&data->stream, NULL, &outParams, device->Frequency,
device->UpdateSize, paNoFlag, pa_callback, device);
if(err != paNoError)
diff --git a/Alc/pulseaudio.c b/Alc/pulseaudio.c
index 42ed84f3..3b83d127 100644
--- a/Alc/pulseaudio.c
+++ b/Alc/pulseaudio.c
@@ -518,40 +518,13 @@ static ALCboolean pulse_reset_playback(ALCdevice *device) //{{{
return ALC_FALSE;
}
-#ifdef _WIN32
if(!ppa_channel_map_init_auto(&chanmap, data->spec.channels, PA_CHANNEL_MAP_WAVEEX))
{
AL_PRINT("Couldn't build map for channel count (%d)!", data->spec.channels);
ppa_threaded_mainloop_unlock(data->loop);
return ALC_FALSE;
}
-#else
- switch(data->spec.channels)
- {
- case 1:
- ppa_channel_map_parse(&chanmap, "mono");
- break;
- case 2:
- ppa_channel_map_parse(&chanmap, "front-left,front-right");
- break;
- case 4:
- ppa_channel_map_parse(&chanmap, "front-left,front-right,rear-left,rear-right");
- break;
- case 6:
- ppa_channel_map_parse(&chanmap, "front-left,front-right,rear-left,rear-right,front-center,lfe");
- break;
- case 7:
- ppa_channel_map_parse(&chanmap, "front-left,front-right,front-center,lfe,rear-center,side-left,side-right");
- break;
- case 8:
- ppa_channel_map_parse(&chanmap, "front-left,front-right,rear-left,rear-right,front-center,lfe,side-left,side-right");
- break;
- default:
- AL_PRINT("Got unhandled channel count (%d)!", data->spec.channels);
- ppa_threaded_mainloop_unlock(data->loop);
- return ALC_FALSE;
- }
-#endif
+ SetDefaultWFXChannelOrder(device);
data->stream = ppa_stream_new(data->context, data->stream_name, &data->spec, &chanmap);
if(!data->stream)
diff --git a/Alc/solaris.c b/Alc/solaris.c
index a6a0dda4..4504a680 100644
--- a/Alc/solaris.c
+++ b/Alc/solaris.c
@@ -197,6 +197,8 @@ static ALCboolean solaris_reset_playback(ALCdevice *device)
data->data_size = device->UpdateSize * frameSize;
data->mix_data = calloc(1, data->data_size);
+ SetDefaultChannelOrder(device);
+
data->thread = StartThread(SolarisProc, device);
if(data->thread == NULL)
{
diff --git a/Alc/wave.c b/Alc/wave.c
index 8de3a623..1d2a39d2 100644
--- a/Alc/wave.c
+++ b/Alc/wave.c
@@ -227,6 +227,8 @@ static ALCboolean wave_reset_playback(ALCdevice *device)
return ALC_FALSE;
}
+ SetDefaultWFXChannelOrder(device);
+
data->thread = StartThread(WaveProc, device);
if(data->thread == NULL)
{
diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h
index 69bd9d5b..4094d894 100644
--- a/OpenAL32/Include/alMain.h
+++ b/OpenAL32/Include/alMain.h
@@ -272,6 +272,8 @@ struct ALCdevice_struct
// Dry path buffer mix
float DryBuffer[BUFFERSIZE][OUTPUTCHANNELS];
+ Channel DevChannels[OUTPUTCHANNELS];
+
// Contexts created on this device
ALCcontext **Contexts;
ALuint NumContexts;
@@ -364,6 +366,85 @@ void EnableRTPrio(ALint level);
ALCboolean ALCAPIENTRY alcMakeCurrent(ALCcontext *context);
ALCcontext* ALCAPIENTRY alcGetThreadContext(void);
+// Sets the default channel order used by most non-WaveFormatEx-based APIs
+static __inline void SetDefaultChannelOrder(ALCdevice *device)
+{
+ switch(aluChannelsFromFormat(device->Format))
+ {
+ case 1: /* Mono is rendered as stereo; fall-through... */
+ case 2: device->DevChannels[0] = FRONT_LEFT;
+ device->DevChannels[1] = FRONT_RIGHT; break;
+
+ case 4: device->DevChannels[0] = FRONT_LEFT;
+ device->DevChannels[1] = FRONT_RIGHT;
+ device->DevChannels[2] = BACK_LEFT;
+ device->DevChannels[3] = BACK_RIGHT; break;
+
+ case 6: device->DevChannels[0] = FRONT_LEFT;
+ device->DevChannels[1] = FRONT_RIGHT;
+ device->DevChannels[2] = BACK_LEFT;
+ device->DevChannels[3] = BACK_RIGHT;
+ device->DevChannels[4] = FRONT_CENTER;
+ device->DevChannels[5] = LFE; break;
+
+ case 7: device->DevChannels[0] = FRONT_LEFT;
+ device->DevChannels[1] = FRONT_RIGHT;
+ device->DevChannels[2] = FRONT_CENTER;
+ device->DevChannels[3] = LFE;
+ device->DevChannels[4] = FRONT_CENTER;
+ device->DevChannels[5] = SIDE_LEFT;
+ device->DevChannels[6] = SIDE_RIGHT; break;
+
+ case 8: device->DevChannels[0] = FRONT_LEFT;
+ device->DevChannels[1] = FRONT_RIGHT;
+ device->DevChannels[2] = BACK_LEFT;
+ device->DevChannels[3] = BACK_RIGHT;
+ device->DevChannels[4] = FRONT_CENTER;
+ device->DevChannels[5] = LFE;
+ device->DevChannels[6] = SIDE_LEFT;
+ device->DevChannels[7] = SIDE_RIGHT; break;
+ }
+}
+// Sets the default order used by WaveFormatEx
+static __inline void SetDefaultWFXChannelOrder(ALCdevice *device)
+{
+ switch(aluChannelsFromFormat(device->Format))
+ {
+ case 1: /* Mono is rendered as stereo; fall-through... */
+ case 2: device->DevChannels[0] = FRONT_LEFT;
+ device->DevChannels[1] = FRONT_RIGHT; break;
+
+ case 4: device->DevChannels[0] = FRONT_LEFT;
+ device->DevChannels[1] = FRONT_RIGHT;
+ device->DevChannels[2] = BACK_LEFT;
+ device->DevChannels[3] = BACK_RIGHT; break;
+
+ case 6: device->DevChannels[0] = FRONT_LEFT;
+ device->DevChannels[1] = FRONT_RIGHT;
+ device->DevChannels[2] = FRONT_CENTER;
+ device->DevChannels[3] = LFE;
+ device->DevChannels[4] = BACK_LEFT;
+ device->DevChannels[5] = BACK_RIGHT; break;
+
+ case 7: device->DevChannels[0] = FRONT_LEFT;
+ device->DevChannels[1] = FRONT_RIGHT;
+ device->DevChannels[2] = FRONT_CENTER;
+ device->DevChannels[3] = LFE;
+ device->DevChannels[4] = FRONT_CENTER;
+ device->DevChannels[5] = SIDE_LEFT;
+ device->DevChannels[6] = SIDE_RIGHT; break;
+
+ case 8: device->DevChannels[0] = FRONT_LEFT;
+ device->DevChannels[1] = FRONT_RIGHT;
+ device->DevChannels[2] = FRONT_CENTER;
+ device->DevChannels[3] = LFE;
+ device->DevChannels[4] = BACK_LEFT;
+ device->DevChannels[5] = BACK_RIGHT;
+ device->DevChannels[6] = SIDE_LEFT;
+ device->DevChannels[7] = SIDE_RIGHT; break;
+ }
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h
index 978527e5..acf1b480 100644
--- a/OpenAL32/Include/alu.h
+++ b/OpenAL32/Include/alu.h
@@ -54,7 +54,7 @@
extern "C" {
#endif
-enum {
+typedef enum {
FRONT_LEFT = 0,
FRONT_RIGHT,
FRONT_CENTER,
@@ -66,7 +66,7 @@ enum {
LFE,
OUTPUTCHANNELS
-};
+} Channel;
#define BUFFERSIZE 24000