aboutsummaryrefslogtreecommitdiffstats
path: root/Alc
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2009-08-15 13:20:35 -0700
committerChris Robinson <[email protected]>2009-08-15 13:20:35 -0700
commitdc26261065a7ff78657ac79accc993c78069deca (patch)
tree2b9696d7aedc196acce6f1b05409c0f8237abf13 /Alc
parent9bea67fb1c99698ccdf9cfa695a09036846163c6 (diff)
Support 32-bit float output
Diffstat (limited to 'Alc')
-rw-r--r--Alc/ALc.c7
-rw-r--r--Alc/ALu.c300
-rw-r--r--Alc/alsa.c3
-rw-r--r--Alc/dsound.c28
-rw-r--r--Alc/oss.c11
-rw-r--r--Alc/portaudio.c3
-rw-r--r--Alc/pulseaudio.c3
-rw-r--r--Alc/wave.c1
8 files changed, 164 insertions, 192 deletions
diff --git a/Alc/ALc.c b/Alc/ALc.c
index 396103e3..1f9fdb30 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -1265,6 +1265,13 @@ ALCAPI ALCboolean ALCAPIENTRY alcMakeContextCurrent(ALCcontext *context)
static ALenum GetFormatFromString(const char *str)
{
+ if(strcasecmp(str, "AL_FORMAT_MONO32") == 0) return AL_FORMAT_MONO_FLOAT32;
+ if(strcasecmp(str, "AL_FORMAT_STEREO32") == 0) return AL_FORMAT_STEREO_FLOAT32;
+ if(strcasecmp(str, "AL_FORMAT_QUAD32") == 0) return AL_FORMAT_QUAD32;
+ if(strcasecmp(str, "AL_FORMAT_51CHN32") == 0) return AL_FORMAT_51CHN32;
+ if(strcasecmp(str, "AL_FORMAT_61CHN32") == 0) return AL_FORMAT_61CHN32;
+ if(strcasecmp(str, "AL_FORMAT_71CHN32") == 0) return AL_FORMAT_71CHN32;
+
if(strcasecmp(str, "AL_FORMAT_MONO16") == 0) return AL_FORMAT_MONO16;
if(strcasecmp(str, "AL_FORMAT_STEREO16") == 0) return AL_FORMAT_STEREO16;
if(strcasecmp(str, "AL_FORMAT_QUAD16") == 0) return AL_FORMAT_QUAD16;
diff --git a/Alc/ALu.c b/Alc/ALu.c
index d2c63e1d..ba45f67f 100644
--- a/Alc/ALu.c
+++ b/Alc/ALu.c
@@ -59,6 +59,13 @@ typedef long long ALint64;
ALboolean DuplicateStereo = AL_FALSE;
+static __inline ALfloat aluF2F(ALfloat Value)
+{
+ if(Value < 0.f) Value /= 32768.f;
+ else Value /= 32767.f;
+ return Value;
+}
+
static __inline ALshort aluF2S(ALfloat Value)
{
ALint i;
@@ -1250,195 +1257,118 @@ ALvoid aluMixData(ALCcontext *ALContext,ALvoid *buffer,ALsizei size,ALenum forma
//Post processing loop
switch(format)
{
- case AL_FORMAT_MONO8:
- for(i = 0;i < SamplesToDo;i++)
- {
- ((ALubyte*)buffer)[0] = aluF2UB(DryBuffer[i][FRONT_LEFT]+DryBuffer[i][FRONT_RIGHT]);
- buffer = ((ALubyte*)buffer) + 1;
- }
- break;
- case AL_FORMAT_STEREO8:
- if(ALContext && ALContext->bs2b)
- {
- for(i = 0;i < SamplesToDo;i++)
- {
- float samples[2];
- samples[0] = DryBuffer[i][FRONT_LEFT];
- samples[1] = DryBuffer[i][FRONT_RIGHT];
- bs2b_cross_feed(ALContext->bs2b, samples);
- ((ALubyte*)buffer)[0] = aluF2UB(samples[0]);
- ((ALubyte*)buffer)[1] = aluF2UB(samples[1]);
- buffer = ((ALubyte*)buffer) + 2;
- }
- }
- else
- {
- for(i = 0;i < SamplesToDo;i++)
- {
- ((ALubyte*)buffer)[0] = aluF2UB(DryBuffer[i][FRONT_LEFT]);
- ((ALubyte*)buffer)[1] = aluF2UB(DryBuffer[i][FRONT_RIGHT]);
- buffer = ((ALubyte*)buffer) + 2;
- }
- }
- break;
- case AL_FORMAT_QUAD8:
- for(i = 0;i < SamplesToDo;i++)
- {
- ((ALubyte*)buffer)[0] = aluF2UB(DryBuffer[i][FRONT_LEFT]);
- ((ALubyte*)buffer)[1] = aluF2UB(DryBuffer[i][FRONT_RIGHT]);
- ((ALubyte*)buffer)[2] = aluF2UB(DryBuffer[i][BACK_LEFT]);
- ((ALubyte*)buffer)[3] = aluF2UB(DryBuffer[i][BACK_RIGHT]);
- buffer = ((ALubyte*)buffer) + 4;
- }
- break;
- case AL_FORMAT_51CHN8:
- for(i = 0;i < SamplesToDo;i++)
- {
- ((ALubyte*)buffer)[0] = aluF2UB(DryBuffer[i][FRONT_LEFT]);
- ((ALubyte*)buffer)[1] = aluF2UB(DryBuffer[i][FRONT_RIGHT]);
-#ifdef _WIN32 /* Of course, Windows can't use the same ordering... */
- ((ALubyte*)buffer)[2] = aluF2UB(DryBuffer[i][FRONT_CENTER]);
- ((ALubyte*)buffer)[3] = aluF2UB(DryBuffer[i][LFE]);
- ((ALubyte*)buffer)[4] = aluF2UB(DryBuffer[i][BACK_LEFT]);
- ((ALubyte*)buffer)[5] = aluF2UB(DryBuffer[i][BACK_RIGHT]);
-#else
- ((ALubyte*)buffer)[2] = aluF2UB(DryBuffer[i][BACK_LEFT]);
- ((ALubyte*)buffer)[3] = aluF2UB(DryBuffer[i][BACK_RIGHT]);
- ((ALubyte*)buffer)[4] = aluF2UB(DryBuffer[i][FRONT_CENTER]);
- ((ALubyte*)buffer)[5] = aluF2UB(DryBuffer[i][LFE]);
-#endif
- buffer = ((ALubyte*)buffer) + 6;
- }
- break;
- case AL_FORMAT_61CHN8:
- for(i = 0;i < SamplesToDo;i++)
- {
- ((ALubyte*)buffer)[0] = aluF2UB(DryBuffer[i][FRONT_LEFT]);
- ((ALubyte*)buffer)[1] = aluF2UB(DryBuffer[i][FRONT_RIGHT]);
- ((ALubyte*)buffer)[2] = aluF2UB(DryBuffer[i][FRONT_CENTER]);
- ((ALubyte*)buffer)[3] = aluF2UB(DryBuffer[i][LFE]);
- ((ALubyte*)buffer)[4] = aluF2UB(DryBuffer[i][BACK_CENTER]);
- ((ALubyte*)buffer)[5] = aluF2UB(DryBuffer[i][SIDE_LEFT]);
- ((ALubyte*)buffer)[6] = aluF2UB(DryBuffer[i][SIDE_RIGHT]);
- buffer = ((ALubyte*)buffer) + 7;
- }
- break;
- case AL_FORMAT_71CHN8:
- for(i = 0;i < SamplesToDo;i++)
- {
- ((ALubyte*)buffer)[0] = aluF2UB(DryBuffer[i][FRONT_LEFT]);
- ((ALubyte*)buffer)[1] = aluF2UB(DryBuffer[i][FRONT_RIGHT]);
-#ifdef _WIN32
- ((ALubyte*)buffer)[2] = aluF2UB(DryBuffer[i][FRONT_CENTER]);
- ((ALubyte*)buffer)[3] = aluF2UB(DryBuffer[i][LFE]);
- ((ALubyte*)buffer)[4] = aluF2UB(DryBuffer[i][BACK_LEFT]);
- ((ALubyte*)buffer)[5] = aluF2UB(DryBuffer[i][BACK_RIGHT]);
-#else
- ((ALubyte*)buffer)[2] = aluF2UB(DryBuffer[i][BACK_LEFT]);
- ((ALubyte*)buffer)[3] = aluF2UB(DryBuffer[i][BACK_RIGHT]);
- ((ALubyte*)buffer)[4] = aluF2UB(DryBuffer[i][FRONT_CENTER]);
- ((ALubyte*)buffer)[5] = aluF2UB(DryBuffer[i][LFE]);
-#endif
- ((ALubyte*)buffer)[6] = aluF2UB(DryBuffer[i][SIDE_LEFT]);
- ((ALubyte*)buffer)[7] = aluF2UB(DryBuffer[i][SIDE_RIGHT]);
- buffer = ((ALubyte*)buffer) + 8;
- }
- break;
+#define CHECK_WRITE_FORMAT(bits, type, func, isWin) \
+ case AL_FORMAT_MONO##bits: \
+ for(i = 0;i < SamplesToDo;i++) \
+ { \
+ ((type*)buffer)[0] = (func)(DryBuffer[i][FRONT_LEFT] + \
+ DryBuffer[i][FRONT_RIGHT]); \
+ buffer = ((type*)buffer) + 1; \
+ } \
+ break; \
+ case AL_FORMAT_STEREO##bits: \
+ if(ALContext && ALContext->bs2b) \
+ { \
+ for(i = 0;i < SamplesToDo;i++) \
+ { \
+ float samples[2]; \
+ samples[0] = DryBuffer[i][FRONT_LEFT]; \
+ samples[1] = DryBuffer[i][FRONT_RIGHT]; \
+ bs2b_cross_feed(ALContext->bs2b, samples); \
+ ((type*)buffer)[0] = (func)(samples[0]); \
+ ((type*)buffer)[1] = (func)(samples[1]); \
+ buffer = ((type*)buffer) + 2; \
+ } \
+ } \
+ else \
+ { \
+ for(i = 0;i < SamplesToDo;i++) \
+ { \
+ ((type*)buffer)[0] = (func)(DryBuffer[i][FRONT_LEFT]); \
+ ((type*)buffer)[1] = (func)(DryBuffer[i][FRONT_RIGHT]); \
+ buffer = ((type*)buffer) + 2; \
+ } \
+ } \
+ break; \
+ 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]); \
+ 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]); \
+ } \
+ 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]); \
+ 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]); \
+ } \
+ ((ALubyte*)buffer)[6] = (func)(DryBuffer[i][SIDE_LEFT]); \
+ ((ALubyte*)buffer)[7] = (func)(DryBuffer[i][SIDE_RIGHT]); \
+ buffer = ((type*)buffer) + 8; \
+ } \
+ break;
- case AL_FORMAT_MONO16:
- for(i = 0;i < SamplesToDo;i++)
- {
- ((ALshort*)buffer)[0] = aluF2S(DryBuffer[i][FRONT_LEFT]+DryBuffer[i][FRONT_RIGHT]);
- buffer = ((ALshort*)buffer) + 1;
- }
- break;
- case AL_FORMAT_STEREO16:
- if(ALContext && ALContext->bs2b)
- {
- for(i = 0;i < SamplesToDo;i++)
- {
- float samples[2];
- samples[0] = DryBuffer[i][FRONT_LEFT];
- samples[1] = DryBuffer[i][FRONT_RIGHT];
- bs2b_cross_feed(ALContext->bs2b, samples);
- ((ALshort*)buffer)[0] = aluF2S(samples[0]);
- ((ALshort*)buffer)[1] = aluF2S(samples[1]);
- buffer = ((ALshort*)buffer) + 2;
- }
- }
- else
- {
- for(i = 0;i < SamplesToDo;i++)
- {
- ((ALshort*)buffer)[0] = aluF2S(DryBuffer[i][FRONT_LEFT]);
- ((ALshort*)buffer)[1] = aluF2S(DryBuffer[i][FRONT_RIGHT]);
- buffer = ((ALshort*)buffer) + 2;
- }
- }
- break;
- case AL_FORMAT_QUAD16:
- for(i = 0;i < SamplesToDo;i++)
- {
- ((ALshort*)buffer)[0] = aluF2S(DryBuffer[i][FRONT_LEFT]);
- ((ALshort*)buffer)[1] = aluF2S(DryBuffer[i][FRONT_RIGHT]);
- ((ALshort*)buffer)[2] = aluF2S(DryBuffer[i][BACK_LEFT]);
- ((ALshort*)buffer)[3] = aluF2S(DryBuffer[i][BACK_RIGHT]);
- buffer = ((ALshort*)buffer) + 4;
- }
- break;
- case AL_FORMAT_51CHN16:
- for(i = 0;i < SamplesToDo;i++)
- {
- ((ALshort*)buffer)[0] = aluF2S(DryBuffer[i][FRONT_LEFT]);
- ((ALshort*)buffer)[1] = aluF2S(DryBuffer[i][FRONT_RIGHT]);
+#define AL_FORMAT_MONO32 AL_FORMAT_MONO_FLOAT32
+#define AL_FORMAT_STEREO32 AL_FORMAT_STEREO_FLOAT32
#ifdef _WIN32
- ((ALshort*)buffer)[2] = aluF2S(DryBuffer[i][FRONT_CENTER]);
- ((ALshort*)buffer)[3] = aluF2S(DryBuffer[i][LFE]);
- ((ALshort*)buffer)[4] = aluF2S(DryBuffer[i][BACK_LEFT]);
- ((ALshort*)buffer)[5] = aluF2S(DryBuffer[i][BACK_RIGHT]);
+ CHECK_WRITE_FORMAT(8, ALubyte, aluF2UB, 1)
+ CHECK_WRITE_FORMAT(16, ALshort, aluF2S, 1)
+ CHECK_WRITE_FORMAT(32, ALfloat, aluF2F, 1)
#else
- ((ALshort*)buffer)[2] = aluF2S(DryBuffer[i][BACK_LEFT]);
- ((ALshort*)buffer)[3] = aluF2S(DryBuffer[i][BACK_RIGHT]);
- ((ALshort*)buffer)[4] = aluF2S(DryBuffer[i][FRONT_CENTER]);
- ((ALshort*)buffer)[5] = aluF2S(DryBuffer[i][LFE]);
+ CHECK_WRITE_FORMAT(8, ALubyte, aluF2UB, 0)
+ CHECK_WRITE_FORMAT(16, ALshort, aluF2S, 0)
+ CHECK_WRITE_FORMAT(32, ALfloat, aluF2F, 0)
#endif
- buffer = ((ALshort*)buffer) + 6;
- }
- break;
- case AL_FORMAT_61CHN16:
- for(i = 0;i < SamplesToDo;i++)
- {
- ((ALshort*)buffer)[0] = aluF2S(DryBuffer[i][FRONT_LEFT]);
- ((ALshort*)buffer)[1] = aluF2S(DryBuffer[i][FRONT_RIGHT]);
- ((ALshort*)buffer)[2] = aluF2S(DryBuffer[i][FRONT_CENTER]);
- ((ALshort*)buffer)[3] = aluF2S(DryBuffer[i][LFE]);
- ((ALshort*)buffer)[4] = aluF2S(DryBuffer[i][BACK_CENTER]);
- ((ALshort*)buffer)[5] = aluF2S(DryBuffer[i][SIDE_LEFT]);
- ((ALshort*)buffer)[6] = aluF2S(DryBuffer[i][SIDE_RIGHT]);
- buffer = ((ALshort*)buffer) + 7;
- }
- break;
- case AL_FORMAT_71CHN16:
- for(i = 0;i < SamplesToDo;i++)
- {
- ((ALshort*)buffer)[0] = aluF2S(DryBuffer[i][FRONT_LEFT]);
- ((ALshort*)buffer)[1] = aluF2S(DryBuffer[i][FRONT_RIGHT]);
-#ifdef _WIN32
- ((ALshort*)buffer)[2] = aluF2S(DryBuffer[i][FRONT_CENTER]);
- ((ALshort*)buffer)[3] = aluF2S(DryBuffer[i][LFE]);
- ((ALshort*)buffer)[4] = aluF2S(DryBuffer[i][BACK_LEFT]);
- ((ALshort*)buffer)[5] = aluF2S(DryBuffer[i][BACK_RIGHT]);
-#else
- ((ALshort*)buffer)[2] = aluF2S(DryBuffer[i][BACK_LEFT]);
- ((ALshort*)buffer)[3] = aluF2S(DryBuffer[i][BACK_RIGHT]);
- ((ALshort*)buffer)[4] = aluF2S(DryBuffer[i][FRONT_CENTER]);
- ((ALshort*)buffer)[5] = aluF2S(DryBuffer[i][LFE]);
-#endif
- ((ALshort*)buffer)[6] = aluF2S(DryBuffer[i][SIDE_LEFT]);
- ((ALshort*)buffer)[7] = aluF2S(DryBuffer[i][SIDE_RIGHT]);
- buffer = ((ALshort*)buffer) + 8;
- }
- break;
+#undef AL_FORMAT_STEREO32
+#undef AL_FORMAT_MONO32
+#undef CHECK_WRITE_FORMAT
default:
break;
diff --git a/Alc/alsa.c b/Alc/alsa.c
index 2e33dd3f..bfac8be5 100644
--- a/Alc/alsa.c
+++ b/Alc/alsa.c
@@ -417,6 +417,9 @@ static ALCboolean alsa_start_context(ALCdevice *device, ALCcontext *context)
case 2:
data->format = SND_PCM_FORMAT_S16;
break;
+ case 4:
+ data->format = SND_PCM_FORMAT_FLOAT;
+ break;
default:
data->format = SND_PCM_FORMAT_UNKNOWN;
AL_PRINT("Unknown format?! %x\n", device->Format);
diff --git a/Alc/dsound.c b/Alc/dsound.c
index d9ca73e6..ce628665 100644
--- a/Alc/dsound.c
+++ b/Alc/dsound.c
@@ -45,6 +45,7 @@
#endif
DEFINE_GUID(KSDATAFORMAT_SUBTYPE_PCM, 0x00000001, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
+DEFINE_GUID(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, 0x00000003, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
static void *ds_handle;
static HRESULT (WINAPI *pDirectSoundCreate)(LPCGUID pcGuidDevice, LPDIRECTSOUND *ppDS, LPUNKNOWN pUnkOuter);
@@ -242,22 +243,28 @@ static ALCboolean DSoundStartContext(ALCdevice *device, ALCcontext *context)
{
if(aluBytesFromFormat(device->Format) == 1)
format = AL_FORMAT_MONO8;
- else
+ else if(aluBytesFromFormat(device->Format) == 2)
format = AL_FORMAT_MONO16;
+ else if(aluBytesFromFormat(device->Format) == 4)
+ format = AL_FORMAT_MONO_FLOAT32;
}
else if(speakers == DSSPEAKER_STEREO)
{
if(aluBytesFromFormat(device->Format) == 1)
format = AL_FORMAT_STEREO8;
- else
+ else if(aluBytesFromFormat(device->Format) == 2)
format = AL_FORMAT_STEREO16;
+ else if(aluBytesFromFormat(device->Format) == 4)
+ format = AL_FORMAT_STEREO_FLOAT32;
}
else if(speakers == DSSPEAKER_QUAD)
{
if(aluBytesFromFormat(device->Format) == 1)
format = AL_FORMAT_QUAD8;
- else
+ else if(aluBytesFromFormat(device->Format) == 2)
format = AL_FORMAT_QUAD16;
+ else if(aluBytesFromFormat(device->Format) == 4)
+ format = AL_FORMAT_QUAD32;
OutputType.dwChannelMask = SPEAKER_FRONT_LEFT |
SPEAKER_FRONT_RIGHT |
SPEAKER_BACK_LEFT |
@@ -267,8 +274,10 @@ static ALCboolean DSoundStartContext(ALCdevice *device, ALCcontext *context)
{
if(aluBytesFromFormat(device->Format) == 1)
format = AL_FORMAT_51CHN8;
- else
+ else if(aluBytesFromFormat(device->Format) == 2)
format = AL_FORMAT_51CHN16;
+ else if(aluBytesFromFormat(device->Format) == 4)
+ format = AL_FORMAT_51CHN32;
OutputType.dwChannelMask = SPEAKER_FRONT_LEFT |
SPEAKER_FRONT_RIGHT |
SPEAKER_FRONT_CENTER |
@@ -280,8 +289,10 @@ static ALCboolean DSoundStartContext(ALCdevice *device, ALCcontext *context)
{
if(aluBytesFromFormat(device->Format) == 1)
format = AL_FORMAT_71CHN8;
- else
+ else if(aluBytesFromFormat(device->Format) == 2)
format = AL_FORMAT_71CHN16;
+ else if(aluBytesFromFormat(device->Format) == 4)
+ format = AL_FORMAT_71CHN32;
OutputType.dwChannelMask = SPEAKER_FRONT_LEFT |
SPEAKER_FRONT_RIGHT |
SPEAKER_FRONT_CENTER |
@@ -304,12 +315,15 @@ static ALCboolean DSoundStartContext(ALCdevice *device, ALCcontext *context)
OutputType.Format.cbSize = 0;
}
- if(OutputType.Format.nChannels > 2)
+ if(OutputType.Format.nChannels > 2 || OutputType.Format.wBitsPerSample > 16)
{
OutputType.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
OutputType.Samples.wValidBitsPerSample = OutputType.Format.wBitsPerSample;
OutputType.Format.cbSize = 22;
- OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
+ if(OutputType.Format.wBitsPerSample == 32)
+ OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
+ else
+ OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
}
else
{
diff --git a/Alc/oss.c b/Alc/oss.c
index 75710492..83f8fe55 100644
--- a/Alc/oss.c
+++ b/Alc/oss.c
@@ -203,6 +203,17 @@ static ALCboolean oss_start_context(ALCdevice *device, ALCcontext *context)
case 1:
ossFormat = AFMT_U8;
break;
+ case 4:
+ switch(aluChannelsFromFormat(device->Format))
+ {
+ case 1: device->Format = AL_FORMAT_MONO16; break;
+ case 2: device->Format = AL_FORMAT_STEREO16; break;
+ case 4: device->Format = AL_FORMAT_QUAD16; break;
+ case 6: device->Format = AL_FORMAT_51CHN16; break;
+ case 7: device->Format = AL_FORMAT_61CHN16; break;
+ case 8: device->Format = AL_FORMAT_71CHN16; break;
+ }
+ /* fall-through */
case 2:
ossFormat = AFMT_S16_NE;
break;
diff --git a/Alc/portaudio.c b/Alc/portaudio.c
index cfd35b56..4d3eb1de 100644
--- a/Alc/portaudio.c
+++ b/Alc/portaudio.c
@@ -109,6 +109,9 @@ static ALCboolean pa_open_playback(ALCdevice *device, const ALCchar *deviceName)
case 2:
outParams.sampleFormat = paInt16;
break;
+ case 4:
+ outParams.sampleFormat = paFloat32;
+ break;
default:
outParams.sampleFormat = -1;
AL_PRINT("Unknown format?! %x\n", device->Format);
diff --git a/Alc/pulseaudio.c b/Alc/pulseaudio.c
index 2faf0ea5..3eac26cb 100644
--- a/Alc/pulseaudio.c
+++ b/Alc/pulseaudio.c
@@ -366,6 +366,9 @@ static ALCboolean pulse_start_context(ALCdevice *device, ALCcontext *context) //
case 2:
data->spec.format = PA_SAMPLE_S16NE;
break;
+ case 4:
+ data->spec.format = PA_SAMPLE_FLOAT32NE;
+ break;
default:
AL_PRINT("Unknown format: %x\n", device->Format);
ppa_threaded_mainloop_unlock(data->loop);
diff --git a/Alc/wave.c b/Alc/wave.c
index d63d3b5c..2867a906 100644
--- a/Alc/wave.c
+++ b/Alc/wave.c
@@ -188,6 +188,7 @@ static ALCboolean wave_start_context(ALCdevice *device, ALCcontext *Context)
{
case 8:
case 16:
+ case 32:
if(channels == 0)
{
AL_PRINT("Unknown format?! %x\n", device->Format);