aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2021-01-06 17:10:03 -0800
committerChris Robinson <[email protected]>2021-01-06 17:10:03 -0800
commit292de73c75a8a3895c7d54e59b633787a7d1d9b0 (patch)
tree9d1321d72a6d7fbbbd61c96f2ee95cdd269c50c2
parent04cd0bc576947879525005b11abcd5230e215360 (diff)
Use a template to read integers with endian awareness
-rw-r--r--alc/hrtf.cpp153
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())
{