diff options
-rw-r--r-- | alc/hrtf.cpp | 153 |
1 files changed, 83 insertions, 70 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<const HrtfStore::Elevation> elevs, HrirArray } } -ubyte GetLE_ALubyte(std::istream &data) -{ - return static_cast<ubyte>(data.get()); -} -short GetLE_ALshort(std::istream &data) +template<typename T, size_t num_bits=sizeof(T)*8> +inline std::enable_if_t<std::is_signed<T>::value,T> +readle(std::istream &data) { - int ret = data.get(); - ret |= data.get() << 8; - return static_cast<short>((ret^32768) - 32768); + static_assert((num_bits&7) == 0, "num_bits must be a multiple of 8"); + constexpr auto signbit = static_cast<T>(1 << (num_bits-1)); + + al::byte b[num_bits/8]; + if(!data.read(reinterpret_cast<char*>(b), sizeof(b))) + return static_cast<T>(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<T>(b[i]) << (i*8); + } + return (ret^signbit) - signbit; } -ushort GetLE_ALushort(std::istream &data) +template<typename T, size_t num_bits=sizeof(T)*8> +inline std::enable_if_t<!std::is_signed<T>::value,T> +readle(std::istream &data) { - int ret = data.get(); - ret |= data.get() << 8; - return static_cast<ushort>(ret); + static_assert((num_bits&7) == 0, "num_bits must be a multiple of 8"); + + al::byte b[num_bits/8]; + if(!data.read(reinterpret_cast<char*>(b), sizeof(b))) + return static_cast<T>(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<T>(b[i]) << (i*8); + } + return ret; } -int GetLE_ALint24(std::istream &data) -{ - int ret = data.get(); - ret |= data.get() << 8; - ret |= data.get() << 16; - return (ret^8388608) - 8388608; -} +template<> +inline uint8_t readle<uint8_t,8>(std::istream &data) +{ return static_cast<uint8_t>(data.get()); } -uint GetLE_ALuint(std::istream &data) -{ - uint ret{static_cast<uint>(data.get())}; - ret |= static_cast<uint>(data.get()) << 8; - ret |= static_cast<uint>(data.get()) << 16; - ret |= static_cast<uint>(data.get()) << 24; - return ret; -} std::unique_ptr<HrtfStore> 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<uint32_t>(data)}; + ushort irCount{readle<uint16_t>(data)}; + ushort irSize{readle<uint16_t>(data)}; + ubyte evCount{readle<uint8_t>(data)}; if(!data || data.eof()) { ERR("Failed reading %s\n", filename); @@ -524,7 +536,7 @@ std::unique_ptr<HrtfStore> LoadHrtf00(std::istream &data, const char *filename) auto elevs = al::vector<HrtfStore::Elevation>(evCount); for(auto &elev : elevs) - elev.irOffset = GetLE_ALushort(data); + elev.irOffset = readle<uint16_t>(data); if(!data || data.eof()) { ERR("Failed reading %s\n", filename); @@ -569,10 +581,10 @@ std::unique_ptr<HrtfStore> LoadHrtf00(std::istream &data, const char *filename) for(auto &hrir : coeffs) { for(auto &val : al::span<float2>{hrir.data(), irSize}) - val[0] = GetLE_ALshort(data) / 32768.0f; + val[0] = readle<int16_t>(data) / 32768.0f; } for(auto &val : delays) - val[0] = GetLE_ALubyte(data); + val[0] = readle<uint8_t>(data); if(!data || data.eof()) { ERR("Failed reading %s\n", filename); @@ -598,9 +610,9 @@ std::unique_ptr<HrtfStore> LoadHrtf00(std::istream &data, const char *filename) std::unique_ptr<HrtfStore> 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<uint32_t>(data)}; + ushort irSize{readle<uint8_t>(data)}; + ubyte evCount{readle<uint8_t>(data)}; if(!data || data.eof()) { ERR("Failed reading %s\n", filename); @@ -620,7 +632,8 @@ std::unique_ptr<HrtfStore> LoadHrtf01(std::istream &data, const char *filename) } auto elevs = al::vector<HrtfStore::Elevation>(evCount); - for (auto &elev : elevs) elev.azCount = GetLE_ALubyte(data); + for(auto &elev : elevs) + elev.azCount = readle<uint8_t>(data); if(!data || data.eof()) { ERR("Failed reading %s\n", filename); @@ -646,10 +659,10 @@ std::unique_ptr<HrtfStore> LoadHrtf01(std::istream &data, const char *filename) for(auto &hrir : coeffs) { for(auto &val : al::span<float2>{hrir.data(), irSize}) - val[0] = GetLE_ALshort(data) / 32768.0f; + val[0] = readle<int16_t>(data) / 32768.0f; } for(auto &val : delays) - val[0] = GetLE_ALubyte(data); + val[0] = readle<uint8_t>(data); if(!data || data.eof()) { ERR("Failed reading %s\n", filename); @@ -680,11 +693,11 @@ std::unique_ptr<HrtfStore> 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<uint32_t>(data)}; + ubyte sampleType{readle<uint8_t>(data)}; + ubyte channelType{readle<uint8_t>(data)}; + ushort irSize{readle<uint8_t>(data)}; + ubyte fdCount{readle<uint8_t>(data)}; if(!data || data.eof()) { ERR("Failed reading %s\n", filename); @@ -718,8 +731,8 @@ std::unique_ptr<HrtfStore> LoadHrtf02(std::istream &data, const char *filename) auto elevs = al::vector<HrtfStore::Elevation>{}; for(size_t f{0};f < fdCount;f++) { - const ushort distance{GetLE_ALushort(data)}; - const ubyte evCount{GetLE_ALubyte(data)}; + const ushort distance{readle<uint16_t>(data)}; + const ubyte evCount{readle<uint8_t>(data)}; if(!data || data.eof()) { ERR("Failed reading %s\n", filename); @@ -751,7 +764,7 @@ std::unique_ptr<HrtfStore> LoadHrtf02(std::istream &data, const char *filename) const size_t ebase{elevs.size()}; elevs.resize(ebase + evCount); for(auto &elev : al::span<HrtfStore::Elevation>(elevs.data()+ebase, evCount)) - elev.azCount = GetLE_ALubyte(data); + elev.azCount = readle<uint8_t>(data); if(!data || data.eof()) { ERR("Failed reading %s\n", filename); @@ -788,7 +801,7 @@ std::unique_ptr<HrtfStore> LoadHrtf02(std::istream &data, const char *filename) for(auto &hrir : coeffs) { for(auto &val : al::span<float2>{hrir.data(), irSize}) - val[0] = GetLE_ALshort(data) / 32768.0f; + val[0] = readle<int16_t>(data) / 32768.0f; } } else if(sampleType == SampleType_S24) @@ -796,11 +809,11 @@ std::unique_ptr<HrtfStore> LoadHrtf02(std::istream &data, const char *filename) for(auto &hrir : coeffs) { for(auto &val : al::span<float2>{hrir.data(), irSize}) - val[0] = static_cast<float>(GetLE_ALint24(data)) / 8388608.0f; + val[0] = static_cast<float>(readle<int,24>(data)) / 8388608.0f; } } for(auto &val : delays) - val[0] = GetLE_ALubyte(data); + val[0] = readle<uint8_t>(data); if(!data || data.eof()) { ERR("Failed reading %s\n", filename); @@ -827,8 +840,8 @@ std::unique_ptr<HrtfStore> LoadHrtf02(std::istream &data, const char *filename) { for(auto &val : al::span<float2>{hrir.data(), irSize}) { - val[0] = GetLE_ALshort(data) / 32768.0f; - val[1] = GetLE_ALshort(data) / 32768.0f; + val[0] = readle<int16_t>(data) / 32768.0f; + val[1] = readle<int16_t>(data) / 32768.0f; } } } @@ -838,15 +851,15 @@ std::unique_ptr<HrtfStore> LoadHrtf02(std::istream &data, const char *filename) { for(auto &val : al::span<float2>{hrir.data(), irSize}) { - val[0] = static_cast<float>(GetLE_ALint24(data)) / 8388608.0f; - val[1] = static_cast<float>(GetLE_ALint24(data)) / 8388608.0f; + val[0] = static_cast<float>(readle<int,24>(data)) / 8388608.0f; + val[1] = static_cast<float>(readle<int,24>(data)) / 8388608.0f; } } } for(auto &val : delays) { - val[0] = GetLE_ALubyte(data); - val[1] = GetLE_ALubyte(data); + val[0] = readle<uint8_t>(data); + val[1] = readle<uint8_t>(data); } if(!data || data.eof()) { @@ -947,10 +960,10 @@ std::unique_ptr<HrtfStore> 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<uint32_t>(data)}; + ubyte channelType{readle<uint8_t>(data)}; + ushort irSize{readle<uint8_t>(data)}; + ubyte fdCount{readle<uint8_t>(data)}; if(!data || data.eof()) { ERR("Failed reading %s\n", filename); @@ -979,8 +992,8 @@ std::unique_ptr<HrtfStore> LoadHrtf03(std::istream &data, const char *filename) auto elevs = al::vector<HrtfStore::Elevation>{}; for(size_t f{0};f < fdCount;f++) { - const ushort distance{GetLE_ALushort(data)}; - const ubyte evCount{GetLE_ALubyte(data)}; + const ushort distance{readle<uint16_t>(data)}; + const ubyte evCount{readle<uint8_t>(data)}; if(!data || data.eof()) { ERR("Failed reading %s\n", filename); @@ -1012,7 +1025,7 @@ std::unique_ptr<HrtfStore> LoadHrtf03(std::istream &data, const char *filename) const size_t ebase{elevs.size()}; elevs.resize(ebase + evCount); for(auto &elev : al::span<HrtfStore::Elevation>(elevs.data()+ebase, evCount)) - elev.azCount = GetLE_ALubyte(data); + elev.azCount = readle<uint8_t>(data); if(!data || data.eof()) { ERR("Failed reading %s\n", filename); @@ -1047,10 +1060,10 @@ std::unique_ptr<HrtfStore> LoadHrtf03(std::istream &data, const char *filename) for(auto &hrir : coeffs) { for(auto &val : al::span<float2>{hrir.data(), irSize}) - val[0] = static_cast<float>(GetLE_ALint24(data)) / 8388608.0f; + val[0] = static_cast<float>(readle<int,24>(data)) / 8388608.0f; } for(auto &val : delays) - val[0] = GetLE_ALubyte(data); + val[0] = readle<uint8_t>(data); if(!data || data.eof()) { ERR("Failed reading %s\n", filename); @@ -1075,14 +1088,14 @@ std::unique_ptr<HrtfStore> LoadHrtf03(std::istream &data, const char *filename) { for(auto &val : al::span<float2>{hrir.data(), irSize}) { - val[0] = static_cast<float>(GetLE_ALint24(data)) / 8388608.0f; - val[1] = static_cast<float>(GetLE_ALint24(data)) / 8388608.0f; + val[0] = static_cast<float>(readle<int,24>(data)) / 8388608.0f; + val[1] = static_cast<float>(readle<int,24>(data)) / 8388608.0f; } } for(auto &val : delays) { - val[0] = GetLE_ALubyte(data); - val[1] = GetLE_ALubyte(data); + val[0] = readle<uint8_t>(data); + val[1] = readle<uint8_t>(data); } if(!data || data.eof()) { |