aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <chris.kcat@gmail.com>2020-01-13 14:23:11 -0800
committerChris Robinson <chris.kcat@gmail.com>2020-01-13 14:23:11 -0800
commit174e48fe8f35d345c12083ce1bda89fb056de6cc (patch)
treef51996fbc655cc4a6de61a3eb475ca73267703fe
parentbc946b004e283be2447c4fc569bb3dd5a46ff66c (diff)
Use the Field and Elevation structs directly when loading
-rw-r--r--alc/hrtf.cpp226
1 files changed, 113 insertions, 113 deletions
diff --git a/alc/hrtf.cpp b/alc/hrtf.cpp
index f36c3a5d..6e2ca37f 100644
--- a/alc/hrtf.cpp
+++ b/alc/hrtf.cpp
@@ -448,19 +448,19 @@ void BuildBFormatHrtf(const HrtfStore *Hrtf, DirectHrtfState *state,
namespace {
-std::unique_ptr<HrtfStore> CreateHrtfStore(ALuint rate, ALushort irSize, const ALuint fdCount,
- const ALubyte *evCount, const ALushort *distance, const ALushort *azCount,
- const ALushort *irOffset, ALushort irCount, const HrirArray *coeffs, const ubyte2 *delays,
- const char *filename)
+std::unique_ptr<HrtfStore> CreateHrtfStore(ALuint rate, ALushort irSize,
+ const al::span<const HrtfStore::Field> fields,
+ const al::span<const HrtfStore::Elevation> elevs, const HrirArray *coeffs,
+ const ubyte2 *delays, const char *filename)
{
std::unique_ptr<HrtfStore> Hrtf;
- ALuint evTotal{std::accumulate(evCount, evCount+fdCount, 0u)};
+ const size_t irCount{size_t{elevs.back().azCount} + elevs.back().irOffset};
size_t total{sizeof(HrtfStore)};
total = RoundUp(total, alignof(HrtfStore::Field)); /* Align for field infos */
- total += sizeof(HrtfStore::Field)*fdCount;
+ total += sizeof(HrtfStore::Field)*fields.size();
total = RoundUp(total, alignof(HrtfStore::Elevation)); /* Align for elevation infos */
- total += sizeof(Hrtf->elev[0])*evTotal;
+ total += sizeof(Hrtf->elev[0])*elevs.size();
total = RoundUp(total, 16); /* Align for coefficients using SIMD */
total += sizeof(Hrtf->coeffs[0])*irCount;
total += sizeof(Hrtf->delays[0])*irCount;
@@ -473,7 +473,7 @@ std::unique_ptr<HrtfStore> CreateHrtfStore(ALuint rate, ALushort irSize, const A
InitRef(Hrtf->mRef, 1u);
Hrtf->sampleRate = rate;
Hrtf->irSize = irSize;
- Hrtf->fdCount = fdCount;
+ Hrtf->fdCount = static_cast<ALuint>(fields.size());
/* Set up pointers to storage following the main HRTF struct. */
char *base = reinterpret_cast<char*>(Hrtf.get());
@@ -481,11 +481,11 @@ std::unique_ptr<HrtfStore> CreateHrtfStore(ALuint rate, ALushort irSize, const A
offset = RoundUp(offset, alignof(HrtfStore::Field)); /* Align for field infos */
auto field_ = reinterpret_cast<HrtfStore::Field*>(base + offset);
- offset += sizeof(field_[0])*fdCount;
+ offset += sizeof(field_[0])*fields.size();
offset = RoundUp(offset, alignof(HrtfStore::Elevation)); /* Align for elevation infos */
auto elev_ = reinterpret_cast<HrtfStore::Elevation*>(base + offset);
- offset += sizeof(elev_[0])*evTotal;
+ offset += sizeof(elev_[0])*elevs.size();
offset = RoundUp(offset, 16); /* Align for coefficients using SIMD */
auto coeffs_ = reinterpret_cast<HrirArray*>(base + offset);
@@ -497,16 +497,8 @@ std::unique_ptr<HrtfStore> CreateHrtfStore(ALuint rate, ALushort irSize, const A
assert(offset == total);
/* Copy input data to storage. */
- for(ALuint i{0};i < fdCount;i++)
- {
- field_[i].distance = distance[i] / 1000.0f;
- field_[i].evCount = evCount[i];
- }
- for(ALuint i{0};i < evTotal;i++)
- {
- elev_[i].azCount = azCount[i];
- elev_[i].irOffset = irOffset[i];
- }
+ std::copy(fields.cbegin(), fields.cend(), field_);
+ std::copy(elevs.cbegin(), elevs.cend(), elev_);
std::copy_n(coeffs, irCount, coeffs_);
std::copy_n(delays, irCount, delays_);
@@ -583,9 +575,9 @@ std::unique_ptr<HrtfStore> LoadHrtf00(std::istream &data, const char *filename)
if(failed)
return nullptr;
- auto evOffset = al::vector<ALushort>(evCount);
- for(auto &val : evOffset)
- val = GetLE_ALushort(data);
+ auto elevs = al::vector<HrtfStore::Elevation>(evCount);
+ for(auto &elev : elevs)
+ elev.irOffset = GetLE_ALushort(data);
if(!data || data.eof())
{
ERR("Failed reading %s\n", filename);
@@ -593,37 +585,37 @@ std::unique_ptr<HrtfStore> LoadHrtf00(std::istream &data, const char *filename)
}
for(size_t i{1};i < evCount;i++)
{
- if(evOffset[i] <= evOffset[i-1])
+ if(elevs[i].irOffset <= elevs[i-1].irOffset)
{
- ERR("Invalid evOffset: evOffset[%zu]=%d (last=%d)\n", i, evOffset[i], evOffset[i-1]);
+ ERR("Invalid evOffset: evOffset[%zu]=%d (last=%d)\n", i, elevs[i].irOffset,
+ elevs[i-1].irOffset);
failed = AL_TRUE;
}
}
- if(irCount <= evOffset.back())
+ if(irCount <= elevs.back().irOffset)
{
ERR("Invalid evOffset: evOffset[%zu]=%d (irCount=%d)\n",
- evOffset.size()-1, evOffset.back(), irCount);
+ elevs.size()-1, elevs.back().irOffset, irCount);
failed = AL_TRUE;
}
if(failed)
return nullptr;
- auto azCount = al::vector<ALushort>(evCount);
for(size_t i{1};i < evCount;i++)
{
- azCount[i-1] = static_cast<ALushort>(evOffset[i] - evOffset[i-1]);
- if(azCount[i-1] < MIN_AZ_COUNT || azCount[i-1] > MAX_AZ_COUNT)
+ elevs[i-1].azCount = static_cast<ALushort>(elevs[i].irOffset - elevs[i-1].irOffset);
+ if(elevs[i-1].azCount < MIN_AZ_COUNT || elevs[i-1].azCount > MAX_AZ_COUNT)
{
ERR("Unsupported azimuth count: azCount[%zd]=%d (%d to %d)\n",
- i-1, azCount[i-1], MIN_AZ_COUNT, MAX_AZ_COUNT);
+ i-1, elevs[i-1].azCount, MIN_AZ_COUNT, MAX_AZ_COUNT);
failed = AL_TRUE;
}
}
- azCount.back() = static_cast<ALushort>(irCount - evOffset.back());
- if(azCount.back() < MIN_AZ_COUNT || azCount.back() > MAX_AZ_COUNT)
+ elevs.back().azCount = static_cast<ALushort>(irCount - elevs.back().irOffset);
+ if(elevs.back().azCount < MIN_AZ_COUNT || elevs.back().azCount > MAX_AZ_COUNT)
{
ERR("Unsupported azimuth count: azCount[%zu]=%d (%d to %d)\n",
- azCount.size()-1, azCount.back(), MIN_AZ_COUNT, MAX_AZ_COUNT);
+ elevs.size()-1, elevs.back().azCount, MIN_AZ_COUNT, MAX_AZ_COUNT);
failed = AL_TRUE;
}
if(failed)
@@ -658,8 +650,8 @@ std::unique_ptr<HrtfStore> LoadHrtf00(std::istream &data, const char *filename)
/* Mirror the left ear responses to the right ear. */
for(size_t i{0};i < evCount;i++)
{
- const ALushort evoffset{evOffset[i]};
- const ALushort azcount{azCount[i]};
+ const ALushort evoffset{elevs[i].irOffset};
+ const ALushort azcount{elevs[i].azCount};
for(size_t j{0};j < azcount;j++)
{
const size_t lidx{evoffset + j};
@@ -671,9 +663,9 @@ std::unique_ptr<HrtfStore> LoadHrtf00(std::istream &data, const char *filename)
}
}
- static const ALushort distance{0};
- return CreateHrtfStore(rate, irSize, 1, &evCount, &distance, azCount.data(), evOffset.data(),
- irCount, coeffs.data(), delays.data(), filename);
+ const HrtfStore::Field field[1]{{0.0f, evCount}};
+ return CreateHrtfStore(rate, irSize, field, {elevs.data(), elevs.size()}, coeffs.data(),
+ delays.data(), filename);
}
std::unique_ptr<HrtfStore> LoadHrtf01(std::istream &data, const char *filename)
@@ -702,8 +694,8 @@ std::unique_ptr<HrtfStore> LoadHrtf01(std::istream &data, const char *filename)
if(failed)
return nullptr;
- auto azCount = al::vector<ALushort>(evCount);
- std::generate(azCount.begin(), azCount.end(), std::bind(GetLE_ALubyte, std::ref(data)));
+ auto elevs = al::vector<HrtfStore::Elevation>(evCount);
+ for (auto &elev : elevs) elev.azCount = GetLE_ALubyte(data);
if(!data || data.eof())
{
ERR("Failed reading %s\n", filename);
@@ -711,9 +703,9 @@ std::unique_ptr<HrtfStore> LoadHrtf01(std::istream &data, const char *filename)
}
for(size_t i{0};i < evCount;++i)
{
- if(azCount[i] < MIN_AZ_COUNT || azCount[i] > MAX_AZ_COUNT)
+ if(elevs[i].azCount < MIN_AZ_COUNT || elevs[i].azCount > MAX_AZ_COUNT)
{
- ERR("Unsupported azimuth count: azCount[%zd]=%d (%d to %d)\n", i, azCount[i],
+ ERR("Unsupported azimuth count: azCount[%zd]=%d (%d to %d)\n", i, elevs[i].azCount,
MIN_AZ_COUNT, MAX_AZ_COUNT);
failed = AL_TRUE;
}
@@ -721,14 +713,10 @@ std::unique_ptr<HrtfStore> LoadHrtf01(std::istream &data, const char *filename)
if(failed)
return nullptr;
- auto evOffset = al::vector<ALushort>(evCount);
- evOffset[0] = 0;
- ALushort irCount{azCount[0]};
+ elevs[0].irOffset = 0;
for(size_t i{1};i < evCount;i++)
- {
- evOffset[i] = static_cast<ALushort>(evOffset[i-1] + azCount[i-1]);
- irCount = static_cast<ALushort>(irCount + azCount[i]);
- }
+ elevs[i].irOffset = static_cast<ALushort>(elevs[i-1].irOffset + elevs[i-1].azCount);
+ const ALushort irCount{static_cast<ALushort>(elevs.back().irOffset + elevs.back().azCount)};
auto coeffs = al::vector<HrirArray>(irCount, HrirArray{});
auto delays = al::vector<ubyte2>(irCount);
@@ -759,8 +747,8 @@ std::unique_ptr<HrtfStore> LoadHrtf01(std::istream &data, const char *filename)
/* Mirror the left ear responses to the right ear. */
for(size_t i{0};i < evCount;i++)
{
- const ALushort evoffset{evOffset[i]};
- const ALushort azcount{azCount[i]};
+ const ALushort evoffset{elevs[i].irOffset};
+ const ALushort azcount{elevs[i].azCount};
for(size_t j{0};j < azcount;j++)
{
const size_t lidx{evoffset + j};
@@ -772,9 +760,9 @@ std::unique_ptr<HrtfStore> LoadHrtf01(std::istream &data, const char *filename)
}
}
- static const ALushort distance{0};
- return CreateHrtfStore(rate, irSize, 1, &evCount, &distance, azCount.data(), evOffset.data(),
- irCount, coeffs.data(), delays.data(), filename);
+ const HrtfStore::Field field[1]{{0.0f, evCount}};
+ return CreateHrtfStore(rate, irSize, field, {elevs.data(), elevs.size()}, coeffs.data(),
+ delays.data(), filename);
}
std::unique_ptr<HrtfStore> LoadHrtf02(std::istream &data, const char *filename)
@@ -821,56 +809,58 @@ std::unique_ptr<HrtfStore> LoadHrtf02(std::istream &data, const char *filename)
if(failed)
return nullptr;
- auto distance = al::vector<ALushort>(fdCount);
- auto evCount = al::vector<ALubyte>(fdCount);
- auto azCount = al::vector<ALushort>{};
+ auto fields = al::vector<HrtfStore::Field>(fdCount);
+ auto elevs = al::vector<HrtfStore::Elevation>{};
for(size_t f{0};f < fdCount;f++)
{
- distance[f] = GetLE_ALushort(data);
- evCount[f] = GetLE_ALubyte(data);
+ const ALushort distance{GetLE_ALushort(data)};
+ const ALubyte evCount{GetLE_ALubyte(data)};
if(!data || data.eof())
{
ERR("Failed reading %s\n", filename);
return nullptr;
}
- if(distance[f] < MIN_FD_DISTANCE || distance[f] > MAX_FD_DISTANCE)
+ if(distance < MIN_FD_DISTANCE || distance > MAX_FD_DISTANCE)
{
- ERR("Unsupported field distance[%zu]=%d (%d to %d millimeters)\n", f, distance[f],
+ ERR("Unsupported field distance[%zu]=%d (%d to %d millimeters)\n", f, distance,
MIN_FD_DISTANCE, MAX_FD_DISTANCE);
failed = AL_TRUE;
}
- if(f > 0 && distance[f] <= distance[f-1])
+ if(evCount < MIN_EV_COUNT || evCount > MAX_EV_COUNT)
{
- ERR("Field distance[%zu] is not after previous (%d > %d)\n", f, distance[f],
- distance[f-1]);
- failed = AL_TRUE;
- }
- if(evCount[f] < MIN_EV_COUNT || evCount[f] > MAX_EV_COUNT)
- {
- ERR("Unsupported elevation count: evCount[%zu]=%d (%d to %d)\n", f, evCount[f],
+ ERR("Unsupported elevation count: evCount[%zu]=%d (%d to %d)\n", f, evCount,
MIN_EV_COUNT, MAX_EV_COUNT);
failed = AL_TRUE;
}
if(failed)
return nullptr;
- const size_t ebase{azCount.size()};
- azCount.resize(ebase + evCount[f]);
- std::generate(azCount.begin()+static_cast<ptrdiff_t>(ebase), azCount.end(),
- std::bind(GetLE_ALubyte, std::ref(data)));
+ fields[f].distance = distance / 1000.0f;
+ fields[f].evCount = evCount;
+ if(f > 0 && fields[f].distance <= fields[f-1].distance)
+ {
+ ERR("Field distance[%zu] is not after previous (%f > %f)\n", f, fields[f].distance,
+ fields[f-1].distance);
+ return nullptr;
+ }
+
+ 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);
if(!data || data.eof())
{
ERR("Failed reading %s\n", filename);
return nullptr;
}
- for(size_t e{0};e < evCount[f];e++)
+ for(size_t e{0};e < evCount;e++)
{
- if(azCount[ebase+e] < MIN_AZ_COUNT || azCount[ebase+e] > MAX_AZ_COUNT)
+ if(elevs[ebase+e].azCount < MIN_AZ_COUNT || elevs[ebase+e].azCount > MAX_AZ_COUNT)
{
ERR("Unsupported azimuth count: azCount[%zu][%zu]=%d (%d to %d)\n", f, e,
- azCount[ebase+e], MIN_AZ_COUNT, MAX_AZ_COUNT);
+ elevs[ebase+e].azCount, MIN_AZ_COUNT, MAX_AZ_COUNT);
failed = AL_TRUE;
}
}
@@ -878,10 +868,15 @@ std::unique_ptr<HrtfStore> LoadHrtf02(std::istream &data, const char *filename)
return nullptr;
}
- auto evOffset = al::vector<ALushort>(azCount.size());
- evOffset[0] = 0;
- std::partial_sum(azCount.cbegin(), azCount.cend()-1, evOffset.begin()+1);
- const auto irTotal = static_cast<ALushort>(evOffset.back() + azCount.back());
+ elevs[0].irOffset = 0;
+ std::partial_sum(elevs.cbegin(), elevs.cend(), elevs.begin(),
+ [](const HrtfStore::Elevation &last, const HrtfStore::Elevation &cur)
+ -> HrtfStore::Elevation
+ {
+ return HrtfStore::Elevation{cur.azCount,
+ static_cast<ALushort>(last.azCount + last.irOffset)};
+ });
+ const auto irTotal = static_cast<ALushort>(elevs.back().azCount + elevs.back().irOffset);
auto coeffs = al::vector<HrirArray>(irTotal, HrirArray{});
auto delays = al::vector<ubyte2>(irTotal);
@@ -980,10 +975,10 @@ std::unique_ptr<HrtfStore> LoadHrtf02(std::istream &data, const char *filename)
size_t ebase{0};
for(size_t f{0};f < fdCount;f++)
{
- for(size_t e{0};e < evCount[f];e++)
+ for(size_t e{0};e < fields[f].evCount;e++)
{
- const ALushort evoffset{evOffset[ebase+e]};
- const ALushort azcount{azCount[ebase+e]};
+ const ALushort evoffset{elevs[ebase+e].irOffset};
+ const ALushort azcount{elevs[ebase+e].azCount};
for(size_t a{0};a < azcount;a++)
{
const size_t lidx{evoffset + a};
@@ -994,74 +989,79 @@ std::unique_ptr<HrtfStore> LoadHrtf02(std::istream &data, const char *filename)
delays[ridx][1] = delays[lidx][0];
}
}
- ebase += evCount[f];
+ ebase += fields[f].evCount;
}
}
if(fdCount > 1)
{
- auto distance_ = al::vector<ALushort>(distance.size());
- auto evCount_ = al::vector<ALubyte>(evCount.size());
- auto azCount_ = al::vector<ALushort>(azCount.size());
- auto evOffset_ = al::vector<ALushort>(evOffset.size());
+ auto fields_ = al::vector<HrtfStore::Field>(fields.size());
+ auto elevs_ = al::vector<HrtfStore::Elevation>(elevs.size());
auto coeffs_ = al::vector<HrirArray>(coeffs.size());
auto delays_ = al::vector<ubyte2>(delays.size());
/* Simple reverse for the per-field elements. */
- std::reverse_copy(distance.cbegin(), distance.cend(), distance_.begin());
- std::reverse_copy(evCount.cbegin(), evCount.cend(), evCount_.begin());
+ std::reverse_copy(fields.cbegin(), fields.cend(), fields_.begin());
/* Each field has a group of elevations, which each have an azimuth
* count. Reverse the order of the groups, keeping the relative order
* of per-group azimuth counts.
*/
- auto azcnt_end = azCount_.end();
- auto copy_azs = [&azCount,&azcnt_end](const ptrdiff_t ebase, const ALubyte num_evs) -> ptrdiff_t
+ auto elevs__end = elevs_.end();
+ auto copy_azs = [&elevs,&elevs__end](const ptrdiff_t ebase, const HrtfStore::Field &field)
+ -> ptrdiff_t
{
- auto azcnt_src = azCount.begin()+ebase;
- azcnt_end = std::copy_backward(azcnt_src, azcnt_src+num_evs, azcnt_end);
- return ebase + num_evs;
+ auto elevs_src = elevs.begin()+ebase;
+ elevs__end = std::copy_backward(elevs_src, elevs_src+field.evCount, elevs__end);
+ return ebase + field.evCount;
};
- std::accumulate(evCount.cbegin(), evCount.cend(), ptrdiff_t{0}, copy_azs);
- assert(azCount_.begin() == azcnt_end);
+ std::accumulate(fields.cbegin(), fields.cend(), ptrdiff_t{0}, copy_azs);
+ assert(elevs_.begin() == elevs__end);
/* Reestablish the IR offset for each elevation index, given the new
* ordering of elevations.
*/
- evOffset_[0] = 0;
- std::partial_sum(azCount_.cbegin(), azCount_.cend()-1, evOffset_.begin()+1);
+ elevs_[0].irOffset = 0;
+ std::partial_sum(elevs_.cbegin(), elevs_.cend(), elevs_.begin(),
+ [](const HrtfStore::Elevation &last, const HrtfStore::Elevation &cur)
+ -> HrtfStore::Elevation
+ {
+ return HrtfStore::Elevation{cur.azCount,
+ static_cast<ALushort>(last.azCount + last.irOffset)};
+ });
/* Reverse the order of each field's group of IRs. */
auto coeffs_end = coeffs_.end();
auto delays_end = delays_.end();
- auto copy_irs = [&azCount,&coeffs,&delays,&coeffs_end,&delays_end](
- const ptrdiff_t ebase, const ALubyte num_evs) -> ptrdiff_t
+ auto copy_irs = [&elevs,&coeffs,&delays,&coeffs_end,&delays_end](
+ const ptrdiff_t ebase, const HrtfStore::Field &field) -> ptrdiff_t
{
- const ALsizei abase{std::accumulate(azCount.cbegin(), azCount.cbegin()+ebase, 0)};
- const ALsizei num_azs{std::accumulate(azCount.cbegin()+ebase,
- azCount.cbegin() + (ebase+num_evs), 0)};
+ auto accum_az = [](ALsizei count, const HrtfStore::Elevation &elev) noexcept -> ALsizei
+ { return count + elev.azCount; };
+ const auto elevs_mid = elevs.cbegin() + ebase;
+ const auto elevs_end = elevs_mid + field.evCount;
+ const ALsizei abase{std::accumulate(elevs.cbegin(), elevs_mid, 0, accum_az)};
+ const ALsizei num_azs{std::accumulate(elevs_mid, elevs_end, 0, accum_az)};
coeffs_end = std::copy_backward(coeffs.cbegin() + abase,
coeffs.cbegin() + (abase+num_azs), coeffs_end);
delays_end = std::copy_backward(delays.cbegin() + abase,
delays.cbegin() + (abase+num_azs), delays_end);
- return ebase + num_evs;
+ return ebase + field.evCount;
};
- std::accumulate(evCount.cbegin(), evCount.cend(), ptrdiff_t{0}, copy_irs);
+ std::accumulate(fields.cbegin(), fields.cend(), ptrdiff_t{0}, copy_irs);
assert(coeffs_.begin() == coeffs_end);
assert(delays_.begin() == delays_end);
- distance = std::move(distance_);
- evCount = std::move(evCount_);
- azCount = std::move(azCount_);
- evOffset = std::move(evOffset_);
+ fields = std::move(fields_);
+ elevs = std::move(elevs_);
coeffs = std::move(coeffs_);
delays = std::move(delays_);
}
- return CreateHrtfStore(rate, irSize, fdCount, evCount.data(), distance.data(), azCount.data(),
- evOffset.data(), irTotal, coeffs.data(), delays.data(), filename);
+ return CreateHrtfStore(rate, irSize, {fields.data(), fields.size()},
+ {elevs.data(), elevs.size()}, coeffs.data(), delays.data(), filename);
}