Merge pull request #3080 from LAGonauta/openal-32bit-fixed-point-support

OpenAL 32-bit fixed point support
This commit is contained in:
shuffle2 2016-10-31 13:07:35 -07:00 committed by GitHub
commit 41477c9ef5
2 changed files with 69 additions and 12 deletions

View File

@ -169,15 +169,11 @@ void OpenALStream::SoundLoop()
Common::SetCurrentThreadName("Audio thread - openal"); Common::SetCurrentThreadName("Audio thread - openal");
bool surround_capable = SConfig::GetInstance().bDPL2Decoder; bool surround_capable = SConfig::GetInstance().bDPL2Decoder;
#if defined(__APPLE__)
bool float32_capable = false; bool float32_capable = false;
const ALenum AL_FORMAT_STEREO_FLOAT32 = 0; bool fixed32_capable = false;
// OS X does not have the alext AL_FORMAT_51CHN32 yet.
#if defined(__APPLE__)
surround_capable = false; surround_capable = false;
const ALenum AL_FORMAT_51CHN32 = 0;
const ALenum AL_FORMAT_51CHN16 = 0;
#else
bool float32_capable = true;
#endif #endif
u32 ulFrequency = m_mixer->GetSampleRate(); u32 ulFrequency = m_mixer->GetSampleRate();
@ -186,10 +182,14 @@ void OpenALStream::SoundLoop()
memset(uiBuffers, 0, numBuffers * sizeof(ALuint)); memset(uiBuffers, 0, numBuffers * sizeof(ALuint));
uiSource = 0; uiSource = 0;
// Checks if a X-Fi is being used. If it is, disable FLOAT32 support as this sound card has no if (alIsExtensionPresent("AL_EXT_float32"))
// support for it even though it reports it does. float32_capable = true;
// As there is no extension to check for 32-bit fixed point support
// and we know that only a X-Fi with hardware OpenAL supports it,
// we just check if one is being used.
if (strstr(alGetString(AL_RENDERER), "X-Fi")) if (strstr(alGetString(AL_RENDERER), "X-Fi"))
float32_capable = false; fixed32_capable = true;
// Clear error state before querying or else we get false positives. // Clear error state before querying or else we get false positives.
ALenum err = alGetError(); ALenum err = alGetError();
@ -307,11 +307,41 @@ void OpenALStream::SoundLoop()
alBufferData(uiBuffers[nextBuffer], AL_FORMAT_51CHN32, dpl2, alBufferData(uiBuffers[nextBuffer], AL_FORMAT_51CHN32, dpl2,
nSamples * FRAME_SURROUND_FLOAT, ulFrequency); nSamples * FRAME_SURROUND_FLOAT, ulFrequency);
} }
else if (fixed32_capable)
{
int surround_int32[OAL_MAX_SAMPLES * SURROUND_CHANNELS * OAL_MAX_BUFFERS];
for (u32 i = 0; i < nSamples * SURROUND_CHANNELS; ++i)
{
// For some reason the ffdshow's DPL2 decoder outputs samples bigger than 1.
// Most are close to 2.5 and some go up to 8. Hard clamping here, we need to
// fix the decoder or implement a limiter.
dpl2[i] = dpl2[i] * (INT64_C(1) << 31);
if (dpl2[i] > INT_MAX)
surround_int32[i] = INT_MAX;
else if (dpl2[i] < INT_MIN)
surround_int32[i] = INT_MIN;
else
surround_int32[i] = (int)dpl2[i];
}
alBufferData(uiBuffers[nextBuffer], AL_FORMAT_51CHN32, surround_int32,
nSamples * FRAME_SURROUND_INT32, ulFrequency);
}
else else
{ {
short surround_short[OAL_MAX_SAMPLES * SURROUND_CHANNELS * OAL_MAX_BUFFERS]; short surround_short[OAL_MAX_SAMPLES * SURROUND_CHANNELS * OAL_MAX_BUFFERS];
for (u32 i = 0; i < nSamples * SURROUND_CHANNELS; ++i) for (u32 i = 0; i < nSamples * SURROUND_CHANNELS; ++i)
surround_short[i] = (short)((float)dpl2[i] * (1 << 15)); {
dpl2[i] = dpl2[i] * (1 << 15);
if (dpl2[i] > SHRT_MAX)
surround_short[i] = SHRT_MAX;
else if (dpl2[i] < SHRT_MIN)
surround_short[i] = SHRT_MIN;
else
surround_short[i] = (int)dpl2[i];
}
alBufferData(uiBuffers[nextBuffer], AL_FORMAT_51CHN16, surround_short, alBufferData(uiBuffers[nextBuffer], AL_FORMAT_51CHN16, surround_short,
nSamples * FRAME_SURROUND_SHORT, ulFrequency); nSamples * FRAME_SURROUND_SHORT, ulFrequency);
@ -339,6 +369,16 @@ void OpenALStream::SoundLoop()
float32_capable = false; float32_capable = false;
} }
} }
else if (fixed32_capable)
{
// Clamping is not necessary here, samples are always between (-1,1)
int stereo_int32[OAL_MAX_SAMPLES * STEREO_CHANNELS * OAL_MAX_BUFFERS];
for (u32 i = 0; i < nSamples * STEREO_CHANNELS; ++i)
stereo_int32[i] = (int)((float)sampleBuffer[i] * (INT64_C(1) << 31));
alBufferData(uiBuffers[nextBuffer], AL_FORMAT_STEREO32, stereo_int32,
nSamples * FRAME_STEREO_INT32, ulFrequency);
}
else else
{ {
// Convert the samples from float to short // Convert the samples from float to short

View File

@ -38,18 +38,35 @@
#undef BOOL #undef BOOL
#endif #endif
// 16 bit Stereo
#define SFX_MAX_SOURCE 1 #define SFX_MAX_SOURCE 1
#define OAL_MAX_BUFFERS 32 #define OAL_MAX_BUFFERS 32
#define OAL_MAX_SAMPLES 256 #define OAL_MAX_SAMPLES 256
#define STEREO_CHANNELS 2 #define STEREO_CHANNELS 2
#define SURROUND_CHANNELS 6 // number of channels in surround mode #define SURROUND_CHANNELS 6 // number of channels in surround mode
#define SIZE_SHORT 2 #define SIZE_SHORT 2
#define SIZE_INT32 4
#define SIZE_FLOAT 4 // size of a float in bytes #define SIZE_FLOAT 4 // size of a float in bytes
#define FRAME_STEREO_SHORT STEREO_CHANNELS* SIZE_SHORT #define FRAME_STEREO_SHORT STEREO_CHANNELS* SIZE_SHORT
#define FRAME_STEREO_FLOAT STEREO_CHANNELS* SIZE_FLOAT #define FRAME_STEREO_FLOAT STEREO_CHANNELS* SIZE_FLOAT
#define FRAME_STEREO_INT32 STEREO_CHANNELS* SIZE_INT32
#define FRAME_SURROUND_FLOAT SURROUND_CHANNELS* SIZE_FLOAT #define FRAME_SURROUND_FLOAT SURROUND_CHANNELS* SIZE_FLOAT
#define FRAME_SURROUND_SHORT SURROUND_CHANNELS* SIZE_SHORT #define FRAME_SURROUND_SHORT SURROUND_CHANNELS* SIZE_SHORT
#define FRAME_SURROUND_INT32 SURROUND_CHANNELS* SIZE_INT32
#endif
#if defined(__APPLE__)
// OS X does not have the alext AL_FORMAT_STEREO_FLOAT32, AL_FORMAT_STEREO32,
// AL_FORMAT_51CHN32 and AL_FORMAT_51CHN16 yet.
#define AL_FORMAT_STEREO_FLOAT32 0
#define AL_FORMAT_STEREO32 0
#define AL_FORMAT_51CHN32 0
#define AL_FORMAT_51CHN16 0
#elif defined(_WIN32)
// Only X-Fi on Windows supports the alext AL_FORMAT_STEREO32 alext for now,
// but it is not documented or in "OpenAL/include/al.h".
#define AL_FORMAT_STEREO32 0x1203
#else
#define AL_FORMAT_STEREO32 0
#endif #endif
class OpenALStream final : public SoundStream class OpenALStream final : public SoundStream