From 5729e1004da8dd8760fe3fa217faec4d3cd80427 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Thu, 21 Jan 2021 22:17:40 -0800 Subject: Make the endian test more C++-like --- CMakeLists.txt | 2 +- alc/backends/opensl.cpp | 26 +++++++++++++++----------- alc/backends/wave.cpp | 4 ++-- alc/hrtf.cpp | 4 ++-- common/albit.h | 35 +++++++++++++++++++++++++++++++++++ common/endiantest.h | 15 --------------- 6 files changed, 55 insertions(+), 31 deletions(-) create mode 100644 common/albit.h delete mode 100644 common/endiantest.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 558b0b4e..444049d2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -613,6 +613,7 @@ check_symbol_exists(getopt unistd.h HAVE_GETOPT) # Common sources used by both the OpenAL implementation library, the OpenAL # router, and certain tools and examples. set(COMMON_OBJS + common/albit.h common/albyte.h common/alcomplex.cpp common/alcomplex.h @@ -628,7 +629,6 @@ set(COMMON_OBJS common/atomic.h common/dynload.cpp common/dynload.h - common/endiantest.h common/intrusive_ptr.h common/math_defs.h common/opthelpers.h diff --git a/alc/backends/opensl.cpp b/alc/backends/opensl.cpp index e0589b34..926911f0 100644 --- a/alc/backends/opensl.cpp +++ b/alc/backends/opensl.cpp @@ -32,11 +32,11 @@ #include #include +#include "albit.h" #include "alcmain.h" #include "alu.h" #include "compat.h" #include "core/logging.h" -#include "endiantest.h" #include "ringbuffer.h" #include "threads.h" @@ -56,7 +56,7 @@ namespace { constexpr char opensl_device[] = "OpenSL"; -SLuint32 GetChannelMask(DevFmtChannels chans) +constexpr SLuint32 GetChannelMask(DevFmtChannels chans) noexcept { switch(chans) { @@ -83,7 +83,7 @@ SLuint32 GetChannelMask(DevFmtChannels chans) } #ifdef SL_ANDROID_DATAFORMAT_PCM_EX -SLuint32 GetTypeRepresentation(DevFmtType type) +constexpr SLuint32 GetTypeRepresentation(DevFmtType type) noexcept { switch(type) { @@ -102,7 +102,14 @@ SLuint32 GetTypeRepresentation(DevFmtType type) } #endif -const char *res_str(SLresult result) +constexpr SLuint32 GetByteOrderEndianness() noexcept +{ + if /*constexpr*/(al::endian::native == al::endian::little) + return SL_BYTEORDER_LITTLEENDIAN; + return SL_BYTEORDER_BIGENDIAN; +} + +const char *res_str(SLresult result) noexcept { switch(result) { @@ -459,7 +466,7 @@ bool OpenSLPlayback::reset() format_pcm_ex.bitsPerSample = mDevice->bytesFromFmt() * 8; format_pcm_ex.containerSize = format_pcm_ex.bitsPerSample; format_pcm_ex.channelMask = GetChannelMask(mDevice->FmtChans); - format_pcm_ex.endianness = IS_LITTLE_ENDIAN ? SL_BYTEORDER_LITTLEENDIAN : SL_BYTEORDER_BIGENDIAN; + format_pcm_ex.endianness = GetByteOrderEndianness(); format_pcm_ex.representation = GetTypeRepresentation(mDevice->FmtType); audioSrc.pLocator = &loc_bufq; @@ -490,8 +497,7 @@ bool OpenSLPlayback::reset() format_pcm.bitsPerSample = mDevice->bytesFromFmt() * 8; format_pcm.containerSize = format_pcm.bitsPerSample; format_pcm.channelMask = GetChannelMask(mDevice->FmtChans); - format_pcm.endianness = IS_LITTLE_ENDIAN ? SL_BYTEORDER_LITTLEENDIAN : - SL_BYTEORDER_BIGENDIAN; + format_pcm.endianness = GetByteOrderEndianness(); audioSrc.pLocator = &loc_bufq; audioSrc.pFormat = &format_pcm; @@ -733,8 +739,7 @@ void OpenSLCapture::open(const char* name) format_pcm_ex.bitsPerSample = mDevice->bytesFromFmt() * 8; format_pcm_ex.containerSize = format_pcm_ex.bitsPerSample; format_pcm_ex.channelMask = GetChannelMask(mDevice->FmtChans); - format_pcm_ex.endianness = IS_LITTLE_ENDIAN ? SL_BYTEORDER_LITTLEENDIAN : - SL_BYTEORDER_BIGENDIAN; + format_pcm_ex.endianness = GetByteOrderEndianness(); format_pcm_ex.representation = GetTypeRepresentation(mDevice->FmtType); audioSnk.pLocator = &loc_bq; @@ -757,8 +762,7 @@ void OpenSLCapture::open(const char* name) format_pcm.bitsPerSample = mDevice->bytesFromFmt() * 8; format_pcm.containerSize = format_pcm.bitsPerSample; format_pcm.channelMask = GetChannelMask(mDevice->FmtChans); - format_pcm.endianness = IS_LITTLE_ENDIAN ? SL_BYTEORDER_LITTLEENDIAN : - SL_BYTEORDER_BIGENDIAN; + format_pcm.endianness = GetByteOrderEndianness(); audioSnk.pLocator = &loc_bq; audioSnk.pFormat = &format_pcm; diff --git a/alc/backends/wave.cpp b/alc/backends/wave.cpp index 3a80b9ca..afff1d56 100644 --- a/alc/backends/wave.cpp +++ b/alc/backends/wave.cpp @@ -33,6 +33,7 @@ #include #include +#include "albit.h" #include "albyte.h" #include "alcmain.h" #include "alconfig.h" @@ -41,7 +42,6 @@ #include "alu.h" #include "compat.h" #include "core/logging.h" -#include "endiantest.h" #include "strutils.h" #include "threads.h" #include "vector.h" @@ -149,7 +149,7 @@ int WaveBackend::mixerProc() mDevice->renderSamples(mBuffer.data(), mDevice->UpdateSize, frameStep); done += mDevice->UpdateSize; - if /*constexpr*/(!IS_LITTLE_ENDIAN) + if /*constexpr*/(al::endian::native != al::endian::little) { const uint bytesize{mDevice->bytesFromFmt()}; diff --git a/alc/hrtf.cpp b/alc/hrtf.cpp index 4e32a0ba..6c40db70 100644 --- a/alc/hrtf.cpp +++ b/alc/hrtf.cpp @@ -40,6 +40,7 @@ #include #include +#include "albit.h" #include "alcmain.h" #include "alconfig.h" #include "alfstream.h" @@ -49,7 +50,6 @@ #include "alspan.h" #include "core/filters/splitter.h" #include "core/logging.h" -#include "endiantest.h" #include "math_defs.h" #include "opthelpers.h" #include "polyphase_resampler.h" @@ -471,7 +471,7 @@ inline T readle(std::istream &data) static_assert(num_bits <= sizeof(T)*8, "num_bits is too large for the type"); T ret{}; - if(IS_LITTLE_ENDIAN) + if /*constexpr*/(al::endian::native == al::endian::little) { if(!data.read(reinterpret_cast(&ret), num_bits/8)) return static_cast(EOF); diff --git a/common/albit.h b/common/albit.h new file mode 100644 index 00000000..225c0b89 --- /dev/null +++ b/common/albit.h @@ -0,0 +1,35 @@ +#ifndef AL_BIT_H +#define AL_BIT_H + +namespace al { + +#ifdef __BYTE_ORDER__ +enum class endian { + little = __ORDER_LITTLE_ENDIAN__, + big = __ORDER_BIG_ENDIAN__, + native = __BYTE_ORDER__ +}; + +#else + +/* This doesn't support mixed-endian. */ +namespace detail_ { +constexpr inline bool EndianTest() noexcept +{ + static_assert(sizeof(char) < sizeof(int), "char is too big"); + + constexpr int test_val{1}; + return static_cast(test_val); +} +} // namespace detail_ + +enum class endian { + little = 0, + big = 1, + native = detail_::EndianTest() ? little : big +}; +#endif + +} // namespace al + +#endif /* AL_BIT_H */ diff --git a/common/endiantest.h b/common/endiantest.h deleted file mode 100644 index 893653bd..00000000 --- a/common/endiantest.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef AL_ENDIANTEST_H -#define AL_ENDIANTEST_H - -#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) -#define IS_LITTLE_ENDIAN (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) -#else -constexpr inline bool EndianTest() noexcept -{ - constexpr int test_val{1}; - return static_cast(test_val); -} -#define IS_LITTLE_ENDIAN (EndianTest()) -#endif - -#endif /* AL_ENDIANTEST_H */ -- cgit v1.2.3