From 292de73c75a8a3895c7d54e59b633787a7d1d9b0 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Wed, 6 Jan 2021 17:10:03 -0800 Subject: [PATCH] Use a template to read integers with endian awareness --- alc/hrtf.cpp | 155 ++++++++++++++++++++++++++++----------------------- 1 file changed, 84 insertions(+), 71 deletions(-) diff --git a/alc/hrtf.cpp b/alc/hrtf.cpp index 28d85177..c790b415 100644 --- a/alc/hrtf.cpp +++ b/alc/hrtf.cpp @@ -49,6 +49,7 @@ #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" @@ -462,48 +463,59 @@ void MirrorLeftHrirs(const al::span elevs, HrirArray } } -ubyte GetLE_ALubyte(std::istream &data) + +template +inline std::enable_if_t::value,T> +readle(std::istream &data) { - return static_cast(data.get()); + static_assert((num_bits&7) == 0, "num_bits must be a multiple of 8"); + constexpr auto signbit = static_cast(1 << (num_bits-1)); + + al::byte b[num_bits/8]; + if(!data.read(reinterpret_cast(b), sizeof(b))) + return static_cast(EOF); + T ret{}; + if(IS_LITTLE_ENDIAN) + std::memcpy(&ret, b, sizeof(b)); + else + { + for(size_t i{0};i < sizeof(b);++i) + ret |= al::to_integer(b[i]) << (i*8); + } + return (ret^signbit) - signbit; } -short GetLE_ALshort(std::istream &data) +template +inline std::enable_if_t::value,T> +readle(std::istream &data) { - int ret = data.get(); - ret |= data.get() << 8; - return static_cast((ret^32768) - 32768); -} + static_assert((num_bits&7) == 0, "num_bits must be a multiple of 8"); -ushort GetLE_ALushort(std::istream &data) -{ - int ret = data.get(); - ret |= data.get() << 8; - return static_cast(ret); -} - -int GetLE_ALint24(std::istream &data) -{ - int ret = data.get(); - ret |= data.get() << 8; - ret |= data.get() << 16; - return (ret^8388608) - 8388608; -} - -uint GetLE_ALuint(std::istream &data) -{ - uint ret{static_cast(data.get())}; - ret |= static_cast(data.get()) << 8; - ret |= static_cast(data.get()) << 16; - ret |= static_cast(data.get()) << 24; + al::byte b[num_bits/8]; + if(!data.read(reinterpret_cast(b), sizeof(b))) + return static_cast(EOF); + T ret{}; + if(IS_LITTLE_ENDIAN) + std::memcpy(&ret, b, sizeof(b)); + else + { + for(size_t i{0};i < sizeof(b);++i) + ret |= al::to_integer(b[i]) << (i*8); + } return ret; } +template<> +inline uint8_t readle(std::istream &data) +{ return static_cast(data.get()); } + + std::unique_ptr LoadHrtf00(std::istream &data, const char *filename) { - uint rate{GetLE_ALuint(data)}; - ushort irCount{GetLE_ALushort(data)}; - ushort irSize{GetLE_ALushort(data)}; - ubyte evCount{GetLE_ALubyte(data)}; + uint rate{readle(data)}; + ushort irCount{readle(data)}; + ushort irSize{readle(data)}; + ubyte evCount{readle(data)}; if(!data || data.eof()) { ERR("Failed reading %s\n", filename); @@ -524,7 +536,7 @@ std::unique_ptr LoadHrtf00(std::istream &data, const char *filename) auto elevs = al::vector(evCount); for(auto &elev : elevs) - elev.irOffset = GetLE_ALushort(data); + elev.irOffset = readle(data); if(!data || data.eof()) { ERR("Failed reading %s\n", filename); @@ -569,10 +581,10 @@ std::unique_ptr LoadHrtf00(std::istream &data, const char *filename) for(auto &hrir : coeffs) { for(auto &val : al::span{hrir.data(), irSize}) - val[0] = GetLE_ALshort(data) / 32768.0f; + val[0] = readle(data) / 32768.0f; } for(auto &val : delays) - val[0] = GetLE_ALubyte(data); + val[0] = readle(data); if(!data || data.eof()) { ERR("Failed reading %s\n", filename); @@ -598,9 +610,9 @@ std::unique_ptr LoadHrtf00(std::istream &data, const char *filename) std::unique_ptr LoadHrtf01(std::istream &data, const char *filename) { - uint rate{GetLE_ALuint(data)}; - ushort irSize{GetLE_ALubyte(data)}; - ubyte evCount{GetLE_ALubyte(data)}; + uint rate{readle(data)}; + ushort irSize{readle(data)}; + ubyte evCount{readle(data)}; if(!data || data.eof()) { ERR("Failed reading %s\n", filename); @@ -620,7 +632,8 @@ std::unique_ptr LoadHrtf01(std::istream &data, const char *filename) } auto elevs = al::vector(evCount); - for (auto &elev : elevs) elev.azCount = GetLE_ALubyte(data); + for(auto &elev : elevs) + elev.azCount = readle(data); if(!data || data.eof()) { ERR("Failed reading %s\n", filename); @@ -646,10 +659,10 @@ std::unique_ptr LoadHrtf01(std::istream &data, const char *filename) for(auto &hrir : coeffs) { for(auto &val : al::span{hrir.data(), irSize}) - val[0] = GetLE_ALshort(data) / 32768.0f; + val[0] = readle(data) / 32768.0f; } for(auto &val : delays) - val[0] = GetLE_ALubyte(data); + val[0] = readle(data); if(!data || data.eof()) { ERR("Failed reading %s\n", filename); @@ -680,11 +693,11 @@ std::unique_ptr LoadHrtf02(std::istream &data, const char *filename) constexpr ubyte ChanType_LeftOnly{0}; constexpr ubyte ChanType_LeftRight{1}; - uint rate{GetLE_ALuint(data)}; - ubyte sampleType{GetLE_ALubyte(data)}; - ubyte channelType{GetLE_ALubyte(data)}; - ushort irSize{GetLE_ALubyte(data)}; - ubyte fdCount{GetLE_ALubyte(data)}; + uint rate{readle(data)}; + ubyte sampleType{readle(data)}; + ubyte channelType{readle(data)}; + ushort irSize{readle(data)}; + ubyte fdCount{readle(data)}; if(!data || data.eof()) { ERR("Failed reading %s\n", filename); @@ -718,8 +731,8 @@ std::unique_ptr LoadHrtf02(std::istream &data, const char *filename) auto elevs = al::vector{}; for(size_t f{0};f < fdCount;f++) { - const ushort distance{GetLE_ALushort(data)}; - const ubyte evCount{GetLE_ALubyte(data)}; + const ushort distance{readle(data)}; + const ubyte evCount{readle(data)}; if(!data || data.eof()) { ERR("Failed reading %s\n", filename); @@ -751,7 +764,7 @@ std::unique_ptr LoadHrtf02(std::istream &data, const char *filename) const size_t ebase{elevs.size()}; elevs.resize(ebase + evCount); for(auto &elev : al::span(elevs.data()+ebase, evCount)) - elev.azCount = GetLE_ALubyte(data); + elev.azCount = readle(data); if(!data || data.eof()) { ERR("Failed reading %s\n", filename); @@ -788,7 +801,7 @@ std::unique_ptr LoadHrtf02(std::istream &data, const char *filename) for(auto &hrir : coeffs) { for(auto &val : al::span{hrir.data(), irSize}) - val[0] = GetLE_ALshort(data) / 32768.0f; + val[0] = readle(data) / 32768.0f; } } else if(sampleType == SampleType_S24) @@ -796,11 +809,11 @@ std::unique_ptr LoadHrtf02(std::istream &data, const char *filename) for(auto &hrir : coeffs) { for(auto &val : al::span{hrir.data(), irSize}) - val[0] = static_cast(GetLE_ALint24(data)) / 8388608.0f; + val[0] = static_cast(readle(data)) / 8388608.0f; } } for(auto &val : delays) - val[0] = GetLE_ALubyte(data); + val[0] = readle(data); if(!data || data.eof()) { ERR("Failed reading %s\n", filename); @@ -827,8 +840,8 @@ std::unique_ptr LoadHrtf02(std::istream &data, const char *filename) { for(auto &val : al::span{hrir.data(), irSize}) { - val[0] = GetLE_ALshort(data) / 32768.0f; - val[1] = GetLE_ALshort(data) / 32768.0f; + val[0] = readle(data) / 32768.0f; + val[1] = readle(data) / 32768.0f; } } } @@ -838,15 +851,15 @@ std::unique_ptr LoadHrtf02(std::istream &data, const char *filename) { for(auto &val : al::span{hrir.data(), irSize}) { - val[0] = static_cast(GetLE_ALint24(data)) / 8388608.0f; - val[1] = static_cast(GetLE_ALint24(data)) / 8388608.0f; + val[0] = static_cast(readle(data)) / 8388608.0f; + val[1] = static_cast(readle(data)) / 8388608.0f; } } } for(auto &val : delays) { - val[0] = GetLE_ALubyte(data); - val[1] = GetLE_ALubyte(data); + val[0] = readle(data); + val[1] = readle(data); } if(!data || data.eof()) { @@ -947,10 +960,10 @@ std::unique_ptr LoadHrtf03(std::istream &data, const char *filename) constexpr ubyte ChanType_LeftOnly{0}; constexpr ubyte ChanType_LeftRight{1}; - uint rate{GetLE_ALuint(data)}; - ubyte channelType{GetLE_ALubyte(data)}; - ushort irSize{GetLE_ALubyte(data)}; - ubyte fdCount{GetLE_ALubyte(data)}; + uint rate{readle(data)}; + ubyte channelType{readle(data)}; + ushort irSize{readle(data)}; + ubyte fdCount{readle(data)}; if(!data || data.eof()) { ERR("Failed reading %s\n", filename); @@ -979,8 +992,8 @@ std::unique_ptr LoadHrtf03(std::istream &data, const char *filename) auto elevs = al::vector{}; for(size_t f{0};f < fdCount;f++) { - const ushort distance{GetLE_ALushort(data)}; - const ubyte evCount{GetLE_ALubyte(data)}; + const ushort distance{readle(data)}; + const ubyte evCount{readle(data)}; if(!data || data.eof()) { ERR("Failed reading %s\n", filename); @@ -1012,7 +1025,7 @@ std::unique_ptr LoadHrtf03(std::istream &data, const char *filename) const size_t ebase{elevs.size()}; elevs.resize(ebase + evCount); for(auto &elev : al::span(elevs.data()+ebase, evCount)) - elev.azCount = GetLE_ALubyte(data); + elev.azCount = readle(data); if(!data || data.eof()) { ERR("Failed reading %s\n", filename); @@ -1047,10 +1060,10 @@ std::unique_ptr LoadHrtf03(std::istream &data, const char *filename) for(auto &hrir : coeffs) { for(auto &val : al::span{hrir.data(), irSize}) - val[0] = static_cast(GetLE_ALint24(data)) / 8388608.0f; + val[0] = static_cast(readle(data)) / 8388608.0f; } for(auto &val : delays) - val[0] = GetLE_ALubyte(data); + val[0] = readle(data); if(!data || data.eof()) { ERR("Failed reading %s\n", filename); @@ -1075,14 +1088,14 @@ std::unique_ptr LoadHrtf03(std::istream &data, const char *filename) { for(auto &val : al::span{hrir.data(), irSize}) { - val[0] = static_cast(GetLE_ALint24(data)) / 8388608.0f; - val[1] = static_cast(GetLE_ALint24(data)) / 8388608.0f; + val[0] = static_cast(readle(data)) / 8388608.0f; + val[1] = static_cast(readle(data)) / 8388608.0f; } } for(auto &val : delays) { - val[0] = GetLE_ALubyte(data); - val[1] = GetLE_ALubyte(data); + val[0] = readle(data); + val[1] = readle(data); } if(!data || data.eof()) {