aboutsummaryrefslogtreecommitdiffstats
path: root/core/hrtf.cpp
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2023-01-10 23:59:19 -0800
committerChris Robinson <[email protected]>2023-01-10 23:59:19 -0800
commita82c29bb4fadc76957946698149eadfdf64395bd (patch)
tree67898016bb5025347f47315e8d10df5f605d02bb /core/hrtf.cpp
parent6bd541d02e664505e3aacc643a46ecfb6919612f (diff)
Rename some struct members
And make a related function a member function
Diffstat (limited to 'core/hrtf.cpp')
-rw-r--r--core/hrtf.cpp111
1 files changed, 57 insertions, 54 deletions
diff --git a/core/hrtf.cpp b/core/hrtf.cpp
index 076d62d5..3d252e5a 100644
--- a/core/hrtf.cpp
+++ b/core/hrtf.cpp
@@ -205,36 +205,38 @@ IdxBlend CalcAzIndex(uint azcount, float az)
/* Calculates static HRIR coefficients and delays for the given polar elevation
* and azimuth in radians. The coefficients are normalized.
*/
-void GetHrtfCoeffs(const HrtfStore *Hrtf, float elevation, float azimuth, float distance,
- float spread, HrirArray &coeffs, const al::span<uint,2> delays)
+void HrtfStore::getCoeffs(float elevation, float azimuth, float distance, float spread,
+ HrirArray &coeffs, const al::span<uint,2> delays)
{
const float dirfact{1.0f - (al::numbers::inv_pi_v<float>/2.0f * spread)};
- const auto *field = Hrtf->field;
- const auto *field_end = field + Hrtf->fdCount-1;
+ al::span<const Field> fields{mField, mFieldCount-1};
size_t ebase{0};
- while(distance < field->distance && field != field_end)
+ auto match_field = [&ebase,distance](const Field &field) noexcept -> bool
{
- ebase += field->evCount;
- ++field;
- }
+ if(distance >= field.distance)
+ return true;
+ ebase += field.evCount;
+ return false;
+ };
+ auto field = std::find_if(fields.begin(), fields.end(), match_field);
/* Calculate the elevation indices. */
const auto elev0 = CalcEvIndex(field->evCount, elevation);
const size_t elev1_idx{minu(elev0.idx+1, field->evCount-1)};
- const size_t ir0offset{Hrtf->elev[ebase + elev0.idx].irOffset};
- const size_t ir1offset{Hrtf->elev[ebase + elev1_idx].irOffset};
+ const size_t ir0offset{mElev[ebase + elev0.idx].irOffset};
+ const size_t ir1offset{mElev[ebase + elev1_idx].irOffset};
/* Calculate azimuth indices. */
- const auto az0 = CalcAzIndex(Hrtf->elev[ebase + elev0.idx].azCount, azimuth);
- const auto az1 = CalcAzIndex(Hrtf->elev[ebase + elev1_idx].azCount, azimuth);
+ const auto az0 = CalcAzIndex(mElev[ebase + elev0.idx].azCount, azimuth);
+ const auto az1 = CalcAzIndex(mElev[ebase + elev1_idx].azCount, azimuth);
/* Calculate the HRIR indices to blend. */
const size_t idx[4]{
ir0offset + az0.idx,
- ir0offset + ((az0.idx+1) % Hrtf->elev[ebase + elev0.idx].azCount),
+ ir0offset + ((az0.idx+1) % mElev[ebase + elev0.idx].azCount),
ir1offset + az1.idx,
- ir1offset + ((az1.idx+1) % Hrtf->elev[ebase + elev1_idx].azCount)
+ ir1offset + ((az1.idx+1) % mElev[ebase + elev1_idx].azCount)
};
/* Calculate bilinear blending weights, attenuated according to the
@@ -248,11 +250,11 @@ void GetHrtfCoeffs(const HrtfStore *Hrtf, float elevation, float azimuth, float
};
/* Calculate the blended HRIR delays. */
- float d{Hrtf->delays[idx[0]][0]*blend[0] + Hrtf->delays[idx[1]][0]*blend[1] +
- Hrtf->delays[idx[2]][0]*blend[2] + Hrtf->delays[idx[3]][0]*blend[3]};
+ float d{mDelays[idx[0]][0]*blend[0] + mDelays[idx[1]][0]*blend[1] + mDelays[idx[2]][0]*blend[2]
+ + mDelays[idx[3]][0]*blend[3]};
delays[0] = fastf2u(d * float{1.0f/HrirDelayFracOne});
- d = Hrtf->delays[idx[0]][1]*blend[0] + Hrtf->delays[idx[1]][1]*blend[1] +
- Hrtf->delays[idx[2]][1]*blend[2] + Hrtf->delays[idx[3]][1]*blend[3];
+ d = mDelays[idx[0]][1]*blend[0] + mDelays[idx[1]][1]*blend[1] + mDelays[idx[2]][1]*blend[2]
+ + mDelays[idx[3]][1]*blend[3];
delays[1] = fastf2u(d * float{1.0f/HrirDelayFracOne});
/* Calculate the blended HRIR coefficients. */
@@ -262,7 +264,7 @@ void GetHrtfCoeffs(const HrtfStore *Hrtf, float elevation, float azimuth, float
std::fill_n(coeffout+2, size_t{HrirLength-1}*2, 0.0f);
for(size_t c{0};c < 4;c++)
{
- const float *srccoeffs{al::assume_aligned<16>(Hrtf->coeffs[idx[c]][0].data())};
+ const float *srccoeffs{al::assume_aligned<16>(mCoeffs[idx[c]][0].data())};
const float mult{blend[c]};
auto blend_coeffs = [mult](const float src, const float coeff) noexcept -> float
{ return src*mult + coeff; };
@@ -284,7 +286,7 @@ void DirectHrtfState::build(const HrtfStore *Hrtf, const uint irSize, const bool
uint ldelay, rdelay;
};
- const double xover_norm{double{XOverFreq} / Hrtf->sampleRate};
+ const double xover_norm{double{XOverFreq} / Hrtf->mSampleRate};
mChannels[0].mSplitter.init(static_cast<float>(xover_norm));
for(size_t i{0};i < mChannels.size();++i)
{
@@ -297,26 +299,26 @@ void DirectHrtfState::build(const HrtfStore *Hrtf, const uint irSize, const bool
al::vector<ImpulseResponse> impres; impres.reserve(AmbiPoints.size());
auto calc_res = [Hrtf,&max_delay,&min_delay](const AngularPoint &pt) -> ImpulseResponse
{
- auto &field = Hrtf->field[0];
+ auto &field = Hrtf->mField[0];
const auto elev0 = CalcEvIndex(field.evCount, pt.Elev.value);
const size_t elev1_idx{minu(elev0.idx+1, field.evCount-1)};
- const size_t ir0offset{Hrtf->elev[elev0.idx].irOffset};
- const size_t ir1offset{Hrtf->elev[elev1_idx].irOffset};
+ const size_t ir0offset{Hrtf->mElev[elev0.idx].irOffset};
+ const size_t ir1offset{Hrtf->mElev[elev1_idx].irOffset};
- const auto az0 = CalcAzIndex(Hrtf->elev[elev0.idx].azCount, pt.Azim.value);
- const auto az1 = CalcAzIndex(Hrtf->elev[elev1_idx].azCount, pt.Azim.value);
+ const auto az0 = CalcAzIndex(Hrtf->mElev[elev0.idx].azCount, pt.Azim.value);
+ const auto az1 = CalcAzIndex(Hrtf->mElev[elev1_idx].azCount, pt.Azim.value);
const size_t idx[4]{
ir0offset + az0.idx,
- ir0offset + ((az0.idx+1) % Hrtf->elev[elev0.idx].azCount),
+ ir0offset + ((az0.idx+1) % Hrtf->mElev[elev0.idx].azCount),
ir1offset + az1.idx,
- ir1offset + ((az1.idx+1) % Hrtf->elev[elev1_idx].azCount)
+ ir1offset + ((az1.idx+1) % Hrtf->mElev[elev1_idx].azCount)
};
/* The largest blend factor serves as the closest HRIR. */
const size_t irOffset{idx[(elev0.blend >= 0.5f)*2 + (az1.blend >= 0.5f)]};
- ImpulseResponse res{Hrtf->coeffs[irOffset],
- Hrtf->delays[irOffset][0], Hrtf->delays[irOffset][1]};
+ ImpulseResponse res{Hrtf->mCoeffs[irOffset],
+ Hrtf->mDelays[irOffset][0], Hrtf->mDelays[irOffset][1]};
min_delay = minu(min_delay, minu(res.ldelay, res.rdelay));
max_delay = maxu(max_delay, maxu(res.ldelay, res.rdelay));
@@ -380,12 +382,12 @@ std::unique_ptr<HrtfStore> CreateHrtfStore(uint rate, ushort irSize,
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(std::declval<HrtfStore&>().field[0])*fields.size();
+ total += sizeof(std::declval<HrtfStore&>().mField[0])*fields.size();
total = RoundUp(total, alignof(HrtfStore::Elevation)); /* Align for elevation infos */
- total += sizeof(std::declval<HrtfStore&>().elev[0])*elevs.size();
+ total += sizeof(std::declval<HrtfStore&>().mElev[0])*elevs.size();
total = RoundUp(total, 16); /* Align for coefficients using SIMD */
- total += sizeof(std::declval<HrtfStore&>().coeffs[0])*irCount;
- total += sizeof(std::declval<HrtfStore&>().delays[0])*irCount;
+ total += sizeof(std::declval<HrtfStore&>().mCoeffs[0])*irCount;
+ total += sizeof(std::declval<HrtfStore&>().mDelays[0])*irCount;
void *ptr{al_calloc(16, total)};
std::unique_ptr<HrtfStore> Hrtf{al::construct_at(static_cast<HrtfStore*>(ptr))};
@@ -394,9 +396,9 @@ std::unique_ptr<HrtfStore> CreateHrtfStore(uint rate, ushort irSize,
else
{
InitRef(Hrtf->mRef, 1u);
- Hrtf->sampleRate = rate;
- Hrtf->irSize = irSize;
- Hrtf->fdCount = static_cast<uint>(fields.size());
+ Hrtf->mSampleRate = rate;
+ Hrtf->mIrSize = irSize;
+ Hrtf->mFieldCount = static_cast<uint>(fields.size());
/* Set up pointers to storage following the main HRTF struct. */
char *base = reinterpret_cast<char*>(Hrtf.get());
@@ -427,10 +429,10 @@ std::unique_ptr<HrtfStore> CreateHrtfStore(uint rate, ushort irSize,
std::uninitialized_copy_n(delays, irCount, delays_);
/* Finally, assign the storage pointers. */
- Hrtf->field = field_;
- Hrtf->elev = elev_;
- Hrtf->coeffs = coeffs_;
- Hrtf->delays = delays_;
+ Hrtf->mField = field_;
+ Hrtf->mElev = elev_;
+ Hrtf->mCoeffs = coeffs_;
+ Hrtf->mDelays = delays_;
}
return Hrtf;
@@ -1292,7 +1294,7 @@ HrtfStorePtr GetLoadedHrtf(const std::string &name, const uint devrate)
while(handle != LoadedHrtfs.end() && handle->mFilename == fname)
{
HrtfStore *hrtf{handle->mEntry.get()};
- if(hrtf && hrtf->sampleRate == devrate)
+ if(hrtf && hrtf->mSampleRate == devrate)
{
hrtf->add_ref();
return HrtfStorePtr{hrtf};
@@ -1361,24 +1363,25 @@ HrtfStorePtr GetLoadedHrtf(const std::string &name, const uint devrate)
return nullptr;
}
- if(hrtf->sampleRate != devrate)
+ if(hrtf->mSampleRate != devrate)
{
- TRACE("Resampling HRTF %s (%uhz -> %uhz)\n", name.c_str(), hrtf->sampleRate, devrate);
+ TRACE("Resampling HRTF %s (%uhz -> %uhz)\n", name.c_str(), hrtf->mSampleRate, devrate);
/* Calculate the last elevation's index and get the total IR count. */
- const size_t lastEv{std::accumulate(hrtf->field, hrtf->field+hrtf->fdCount, size_t{0},
+ auto fields = al::as_span(hrtf->mField, hrtf->mFieldCount);
+ const size_t lastEv{std::accumulate(fields.begin(), fields.end(), size_t{0},
[](const size_t curval, const HrtfStore::Field &field) noexcept -> size_t
{ return curval + field.evCount; }
) - 1};
- const size_t irCount{size_t{hrtf->elev[lastEv].irOffset} + hrtf->elev[lastEv].azCount};
+ const size_t irCount{size_t{hrtf->mElev[lastEv].irOffset} + hrtf->mElev[lastEv].azCount};
/* Resample all the IRs. */
std::array<std::array<double,HrirLength>,2> inout;
PPhaseResampler rs;
- rs.init(hrtf->sampleRate, devrate);
+ rs.init(hrtf->mSampleRate, devrate);
for(size_t i{0};i < irCount;++i)
{
- HrirArray &coeffs = const_cast<HrirArray&>(hrtf->coeffs[i]);
+ HrirArray &coeffs = const_cast<HrirArray&>(hrtf->mCoeffs[i]);
for(size_t j{0};j < 2;++j)
{
std::transform(coeffs.cbegin(), coeffs.cend(), inout[0].begin(),
@@ -1393,12 +1396,12 @@ HrtfStorePtr GetLoadedHrtf(const std::string &name, const uint devrate)
/* Scale the delays for the new sample rate. */
float max_delay{0.0f};
auto new_delays = al::vector<float2>(irCount);
- const float rate_scale{static_cast<float>(devrate)/static_cast<float>(hrtf->sampleRate)};
+ const float rate_scale{static_cast<float>(devrate)/static_cast<float>(hrtf->mSampleRate)};
for(size_t i{0};i < irCount;++i)
{
for(size_t j{0};j < 2;++j)
{
- const float new_delay{std::round(hrtf->delays[i][j] * rate_scale) /
+ const float new_delay{std::round(hrtf->mDelays[i][j] * rate_scale) /
float{HrirDelayFracOne}};
max_delay = maxf(max_delay, new_delay);
new_delays[i][j] = new_delay;
@@ -1418,7 +1421,7 @@ HrtfStorePtr GetLoadedHrtf(const std::string &name, const uint devrate)
for(size_t i{0};i < irCount;++i)
{
- ubyte2 &delays = const_cast<ubyte2&>(hrtf->delays[i]);
+ ubyte2 &delays = const_cast<ubyte2&>(hrtf->mDelays[i]);
for(size_t j{0};j < 2;++j)
delays[j] = static_cast<ubyte>(float2int(new_delays[i][j]*delay_scale + 0.5f));
}
@@ -1426,13 +1429,13 @@ HrtfStorePtr GetLoadedHrtf(const std::string &name, const uint devrate)
/* Scale the IR size for the new sample rate and update the stored
* sample rate.
*/
- const float newIrSize{std::round(static_cast<float>(hrtf->irSize) * rate_scale)};
- hrtf->irSize = static_cast<uint>(minf(HrirLength, newIrSize));
- hrtf->sampleRate = devrate;
+ const float newIrSize{std::round(static_cast<float>(hrtf->mIrSize) * rate_scale)};
+ hrtf->mIrSize = static_cast<uint>(minf(HrirLength, newIrSize));
+ hrtf->mSampleRate = devrate;
}
TRACE("Loaded HRTF %s for sample rate %uhz, %u-sample filter\n", name.c_str(),
- hrtf->sampleRate, hrtf->irSize);
+ hrtf->mSampleRate, hrtf->mIrSize);
handle = LoadedHrtfs.emplace(handle, fname, std::move(hrtf));
return HrtfStorePtr{handle->mEntry.get()};