Use a template to read integers with endian awareness
This commit is contained in:
+84
-71
@@ -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)
|
||||
|
||||
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)
|
||||
{
|
||||
return static_cast<ubyte>(data.get());
|
||||
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;
|
||||
}
|
||||
|
||||
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");
|
||||
|
||||
ushort GetLE_ALushort(std::istream &data)
|
||||
{
|
||||
int ret = data.get();
|
||||
ret |= data.get() << 8;
|
||||
return static_cast<ushort>(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<uint>(data.get())};
|
||||
ret |= static_cast<uint>(data.get()) << 8;
|
||||
ret |= static_cast<uint>(data.get()) << 16;
|
||||
ret |= static_cast<uint>(data.get()) << 24;
|
||||
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;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline uint8_t readle<uint8_t,8>(std::istream &data)
|
||||
{ return static_cast<uint8_t>(data.get()); }
|
||||
|
||||
|
||||
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())
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user