Update read_uint* functions

This commit is contained in:
Stephen F. Booth 2024-12-08 10:11:57 -06:00
parent d89c98f733
commit 64b5748c85
No known key found for this signature in database
GPG Key ID: 900AAC885063A183

View File

@ -217,53 +217,83 @@ namespace {
// MARK: Unsigned Integer Reading
#if 0
// Utils::byteSwap() is overloaded for unsigned short, unsigned int, and unsigned long long
// Even though uint64_t and unsigned long long are typically the same size they aren't the
// same type which means for template purposes std::is_same_v<T, uint64_t> is false
template <typename T, typename = std::enable_if<std::is_same_v<T, uint16_t> || std::is_same_v<T, uint32_t> || std::is_same_v<T, uint64_t>>>
T read_uint(void *p, uintptr_t n, bool big) noexcept
{
T value = *reinterpret_cast<T *>(reinterpret_cast<uintptr_t>(p) + n);
auto system_big = Utils::systemByteOrder() == Utils::BigEndian;
if constexpr (std::is_same_v<T, uint16_t>) {
if(big != system_big)
value = Utils::byteSwap(static_cast<unsigned short>(value));
}
else if constexpr (std::is_same_v<T, uint32_t>) {
if(big != system_big)
value = Utils::byteSwap(static_cast<unsigned int>(value));
}
else if constexpr (std::is_same_v<T, uint64_t>) {
if(big != system_big)
value = Utils::byteSwap(static_cast<unsigned long long>(value));
}
else
static_assert(false, "Invalid typename T");
if(big != system_big)
value = Utils::byteSwap(value);
return value;
}
#endif
uint64_t read_uint_big64(void *p, uintptr_t n) noexcept
uint64_t read_uint64(void *p, uintptr_t n, bool big) noexcept
{
return read_uint<uint64_t>(p, n, true);
static_assert(sizeof(uint64_t) == sizeof(unsigned long long), "uint64_t and unsigned long long have different sizes");
unsigned long long value = *reinterpret_cast<uint64_t *>(reinterpret_cast<uintptr_t>(p) + n);
auto system_big = Utils::systemByteOrder() == Utils::BigEndian;
if(big != system_big)
value = Utils::byteSwap(value);
return static_cast<uint64_t>(value);
}
uint32_t read_uint_big32(void *p, uintptr_t n) noexcept
uint32_t read_uint32(void *p, uintptr_t n, bool big) noexcept
{
return read_uint<uint32_t>(p, n, true);
static_assert(sizeof(uint32_t) == sizeof(unsigned int), "uint32_t and unsigned int have different sizes");
unsigned int value = *reinterpret_cast<uint32_t *>(reinterpret_cast<uintptr_t>(p) + n);
auto system_big = Utils::systemByteOrder() == Utils::BigEndian;
if(big != system_big)
value = Utils::byteSwap(value);
return static_cast<uint32_t>(value);
}
uint32_t read_uint_little32(void *p, uintptr_t n) noexcept
uint16_t read_uint16(void *p, uintptr_t n, bool big) noexcept
{
return read_uint<uint32_t>(p, n, false);
static_assert(sizeof(uint16_t) == sizeof(unsigned short), "uint16_t and unsigned short have different sizes");
unsigned short value = *reinterpret_cast<uint16_t *>(reinterpret_cast<uintptr_t>(p) + n);
auto system_big = Utils::systemByteOrder() == Utils::BigEndian;
if(big != system_big)
value = Utils::byteSwap(value);
return static_cast<uint16_t>(value);
}
uint16_t read_uint_big16(void *p, uintptr_t n) noexcept
uint64_t read_uint64_big(void *p, uintptr_t n) noexcept
{
// return read_uint<uint64_t>(p, n, true);
return read_uint64(p, n, true);
}
uint32_t read_uint32_big(void *p, uintptr_t n) noexcept
{
return read_uint<uint16_t>(p, n, true);
// return read_uint<uint32_t>(p, n, true);
return read_uint32(p, n, true);
}
uint16_t read_uint_little16(void *p, uintptr_t n) noexcept
uint32_t read_uint32_little(void *p, uintptr_t n) noexcept
{
return read_uint<uint16_t>(p, n, false);
// return read_uint<uint32_t>(p, n, false);
return read_uint32(p, n, false);
}
uint16_t read_uint16_big(void *p, uintptr_t n) noexcept
{
// return read_uint<uint16_t>(p, n, true);
return read_uint16(p, n, true);
}
uint16_t read_uint16_little(void *p, uintptr_t n) noexcept
{
// return read_uint<uint16_t>(p, n, false);
return read_uint16(p, n, false);
}
} // namespace
@ -456,8 +486,8 @@ void SHN::File::read(AudioProperties::ReadStyle propertiesStyle)
// header_bytes is at least CANONICAL_HEADER_SIZE (44) bytes in size
auto chunkID = read_uint_big32(header_bytes, 0);
// auto chunkSize = read_uint_big32(header_bytes, 4);
auto chunkID = read_uint32_big(header_bytes, 0);
// auto chunkSize = read_uint32_big(header_bytes, 4);
const auto chunkData = header_bytes + 8;
const uintptr_t size = header_size - 8;
@ -466,7 +496,7 @@ void SHN::File::read(AudioProperties::ReadStyle propertiesStyle)
if(chunkID == 0x52494646 /*'RIFF'*/) {
uintptr_t offset = 0;
chunkID = read_uint_big32(chunkData, offset);
chunkID = read_uint32_big(chunkData, offset);
offset += 4;
if(chunkID != 0x57415645 /*'WAVE'*/) {
debug("SHN::File::read() -- Missing 'WAVE' in 'RIFF' chunk.");
@ -479,10 +509,10 @@ void SHN::File::read(AudioProperties::ReadStyle propertiesStyle)
uint16_t blockAlign = 0;
while(offset < size) {
chunkID = read_uint_big32(chunkData, offset);
chunkID = read_uint32_big(chunkData, offset);
offset += 4;
auto chunkSize = read_uint_little32(chunkData, offset);
auto chunkSize = read_uint32_little(chunkData, offset);
offset += 4;
switch(chunkID) {
@ -494,7 +524,7 @@ void SHN::File::read(AudioProperties::ReadStyle propertiesStyle)
return;
}
auto format_tag = read_uint_little16(chunkData, offset);
auto format_tag = read_uint16_little(chunkData, offset);
offset += 2;
if(format_tag != WAVE_FORMAT_PCM) {
debug("SHN::File::read() -- Unsupported WAVE format tag.");
@ -502,21 +532,21 @@ void SHN::File::read(AudioProperties::ReadStyle propertiesStyle)
return;
}
auto channels = read_uint_little16(chunkData, offset);
auto channels = read_uint16_little(chunkData, offset);
offset += 2;
if(props.channel_count != channels)
debug("SHN::File::read() -- Channel count mismatch between Shorten and 'fmt ' chunk.");
props.sample_rate = static_cast<int>(read_uint_little32(chunkData, offset));
props.sample_rate = static_cast<int>(read_uint32_little(chunkData, offset));
offset += 4;
// Skip average bytes per second
offset += 4;
blockAlign = read_uint_little16(chunkData, offset);
blockAlign = read_uint16_little(chunkData, offset);
offset += 2;
props.bits_per_sample = static_cast<int>(read_uint_little16(chunkData, offset));
props.bits_per_sample = static_cast<int>(read_uint16_little(chunkData, offset));
offset += 2;
if(chunkSize > 16)
@ -546,7 +576,7 @@ void SHN::File::read(AudioProperties::ReadStyle propertiesStyle)
else if(chunkID == 0x464f524d /*'FORM'*/) {
uintptr_t offset = 0;
auto chunkID = read_uint_big32(chunkData, offset);
auto chunkID = read_uint32_big(chunkData, offset);
offset += 4;
if(chunkID != 0x41494646 /*'AIFF'*/ && chunkID != 0x41494643 /*'AIFC'*/) {
debug("SHN::File::read() -- Missing 'AIFF' or 'AIFC' in 'FORM' chunk.");
@ -559,10 +589,10 @@ void SHN::File::read(AudioProperties::ReadStyle propertiesStyle)
auto sawCommonChunk = false;
while(offset < size) {
chunkID = read_uint_big32(chunkData, offset);
chunkID = read_uint32_big(chunkData, offset);
offset += 4;
auto chunkSize = read_uint_big32(chunkData, offset);
auto chunkSize = read_uint32_big(chunkData, offset);
offset += 4;
// All chunks must have an even length but the pad byte is not included in ckSize
@ -577,19 +607,19 @@ void SHN::File::read(AudioProperties::ReadStyle propertiesStyle)
return;
}
auto channels = read_uint_big16(chunkData, offset);
auto channels = read_uint16_big(chunkData, offset);
offset += 2;
if(props.channel_count != channels)
debug("SHN::File::read() -- Channel count mismatch between Shorten and 'COMM' chunk.");
props.sample_frames = static_cast<unsigned long>(read_uint_big32(chunkData, offset));
props.sample_frames = static_cast<unsigned long>(read_uint32_big(chunkData, offset));
offset += 4;
props.bits_per_sample = static_cast<int>(read_uint_big16(chunkData, offset));
props.bits_per_sample = static_cast<int>(read_uint16_big(chunkData, offset));
offset += 2;
// sample rate is IEEE 754 80-bit extended float (16-bit exponent, 1-bit integer part, 63-bit fraction)
auto exp = static_cast<int16_t>(read_uint_big16(chunkData, offset)) - 16383 - 63;
auto exp = static_cast<int16_t>(read_uint16_big(chunkData, offset)) - 16383 - 63;
offset += 2;
if(exp < -63 || exp > 63) {
debug("SHN::File::read() -- exp out of range.");
@ -597,7 +627,7 @@ void SHN::File::read(AudioProperties::ReadStyle propertiesStyle)
return;
}
auto frac = read_uint_big64(chunkData, offset);
auto frac = read_uint64_big(chunkData, offset);
offset += 8;
if(exp >= 0)
props.sample_rate = static_cast<int>(frac << exp);