diff options
author | Chris Robinson <[email protected]> | 2009-08-15 13:20:35 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2009-08-15 13:20:35 -0700 |
commit | dc26261065a7ff78657ac79accc993c78069deca (patch) | |
tree | 2b9696d7aedc196acce6f1b05409c0f8237abf13 | |
parent | 9bea67fb1c99698ccdf9cfa695a09036846163c6 (diff) |
Support 32-bit float output
-rw-r--r-- | Alc/ALc.c | 7 | ||||
-rw-r--r-- | Alc/ALu.c | 300 | ||||
-rw-r--r-- | Alc/alsa.c | 3 | ||||
-rw-r--r-- | Alc/dsound.c | 28 | ||||
-rw-r--r-- | Alc/oss.c | 11 | ||||
-rw-r--r-- | Alc/portaudio.c | 3 | ||||
-rw-r--r-- | Alc/pulseaudio.c | 3 | ||||
-rw-r--r-- | Alc/wave.c | 1 | ||||
-rw-r--r-- | alsoftrc.sample | 6 |
9 files changed, 170 insertions, 192 deletions
@@ -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; @@ -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; @@ -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 { @@ -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); @@ -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); diff --git a/alsoftrc.sample b/alsoftrc.sample index 291ca71b..45d5ba07 100644 --- a/alsoftrc.sample +++ b/alsoftrc.sample @@ -27,6 +27,12 @@ # AL_FORMAT_51CHN16 (16-bit 5.1 output) # AL_FORMAT_61CHN16 (16-bit 6.1 output) # AL_FORMAT_71CHN16 (16-bit 7.1 output) +# AL_FORMAT_MONO32 (32-bit float mono) +# AL_FORMAT_STEREO32 (32-bit float stereo) +# AL_FORMAT_QUAD32 (32-bit float 4-channel) +# AL_FORMAT_51CHN32 (32-bit float 5.1 output) +# AL_FORMAT_61CHN32 (32-bit float 6.1 output) +# AL_FORMAT_71CHN32 (32-bit float 7.1 output) #format = AL_FORMAT_STEREO16 ## cf_level: |