aboutsummaryrefslogtreecommitdiffstats
path: root/Alc
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2019-02-27 23:13:40 -0800
committerChris Robinson <[email protected]>2019-02-27 23:13:40 -0800
commite4b76d26271931d1207538cbfbfb92facad0e9c7 (patch)
tree6401762a02043975aa14b2425b69124637339c26 /Alc
parent86926f0998c581530177b8c54050fc9d28f561f7 (diff)
Reverse the HRTF field array
Most often a sound's distance will be beyond the farthest field measurement, so It's more efficient to have the farthest field first and avoid looping through the whole field array for them.
Diffstat (limited to 'Alc')
-rw-r--r--Alc/hrtf.cpp29
-rw-r--r--Alc/hrtf.h7
-rw-r--r--Alc/panning.cpp3
3 files changed, 24 insertions, 15 deletions
diff --git a/Alc/hrtf.cpp b/Alc/hrtf.cpp
index a47c4d35..bfbdc1fc 100644
--- a/Alc/hrtf.cpp
+++ b/Alc/hrtf.cpp
@@ -214,9 +214,13 @@ void GetHrtfCoeffs(const HrtfEntry *Hrtf, ALfloat elevation, ALfloat azimuth, AL
const auto *field = Hrtf->field;
const auto *field_end = field + Hrtf->fdCount-1;
- ALsizei fdoffset{0};
- for(;field != field_end && (field+1)->distance <= distance;++field)
- fdoffset += field->evCount;
+ ALsizei fdoffset{Hrtf->evFarBase};
+ while(distance < field->distance && field != field_end)
+ {
+ ++field;
+ fdoffset -= field->evCount;
+ }
+ assert(fdoffset >= 0);
/* Claculate the lower elevation index. */
const auto elev = CalcEvIndex(field->evCount, elevation);
@@ -311,10 +315,8 @@ void BuildBFormatHrtf(const HrtfEntry *Hrtf, DirectHrtfState *state, const ALsiz
ASSUME(NumChannels > 0);
ASSUME(AmbiCount > 0);
- auto &field = Hrtf->field[Hrtf->fdCount-1];
- const ALsizei ebase{std::accumulate(Hrtf->field, &field, 0,
- std::bind(std::plus<ALsizei>{}, _1,
- std::bind(std::mem_fn(&HrtfEntry::Field::evCount), _2)))};
+ auto &field = Hrtf->field[0];
+ const ALsizei ebase{Hrtf->evFarBase};
ALsizei min_delay{HRTF_HISTORY_LENGTH};
ALsizei max_delay{0};
auto idx = al::vector<ALsizei>(AmbiCount);
@@ -468,7 +470,7 @@ void BuildBFormatHrtf(const HrtfEntry *Hrtf, DirectHrtfState *state, const ALsiz
namespace {
std::unique_ptr<HrtfEntry> CreateHrtfStore(ALuint rate, ALsizei irSize, const ALsizei fdCount,
- const ALfloat *distance, const ALubyte *evCount, const ALubyte *azCount,
+ const ALubyte *evCount, const ALfloat *distance, const ALubyte *azCount,
const ALushort *evOffset, ALsizei irCount, const ALfloat (*coeffs)[2],
const ALubyte (*delays)[2], const char *filename)
{
@@ -493,6 +495,7 @@ std::unique_ptr<HrtfEntry> CreateHrtfStore(ALuint rate, ALsizei irSize, const AL
InitRef(&Hrtf->ref, 1u);
Hrtf->sampleRate = rate;
Hrtf->irSize = irSize;
+ Hrtf->evFarBase = std::accumulate(evCount+1, evCount+fdCount, 0);
Hrtf->fdCount = fdCount;
/* Set up pointers to storage following the main HRTF struct. */
@@ -522,8 +525,8 @@ std::unique_ptr<HrtfEntry> CreateHrtfStore(ALuint rate, ALsizei irSize, const AL
/* Copy input data to storage. */
for(ALsizei i{0};i < fdCount;i++)
{
- field_[i].distance = distance[i];
field_[i].evCount = evCount[i];
+ field_[i].distance = distance[i];
}
for(ALsizei i{0};i < evTotal;i++) azCount_[i] = azCount[i];
for(ALsizei i{0};i < evTotal;i++) evOffset_[i] = evOffset[i];
@@ -699,7 +702,7 @@ std::unique_ptr<HrtfEntry> LoadHrtf00(std::istream &data, const char *filename)
}
static constexpr ALfloat distance{0.0f};
- return CreateHrtfStore(rate, irSize, 1, &distance, &evCount, azCount.data(), evOffset.data(),
+ return CreateHrtfStore(rate, irSize, 1, &evCount, &distance, azCount.data(), evOffset.data(),
irCount, &reinterpret_cast<ALfloat(&)[2]>(coeffs[0]),
&reinterpret_cast<ALubyte(&)[2]>(delays[0]), filename);
}
@@ -798,7 +801,7 @@ std::unique_ptr<HrtfEntry> LoadHrtf01(std::istream &data, const char *filename)
}
static constexpr ALfloat distance{0.0f};
- return CreateHrtfStore(rate, irSize, 1, &distance, &evCount, azCount.data(), evOffset.data(),
+ return CreateHrtfStore(rate, irSize, 1, &evCount, &distance, azCount.data(), evOffset.data(),
irCount, &reinterpret_cast<ALfloat(&)[2]>(coeffs[0]),
&reinterpret_cast<ALubyte(&)[2]>(delays[0]), filename);
}
@@ -1030,7 +1033,9 @@ std::unique_ptr<HrtfEntry> LoadHrtf02(std::istream &data, const char *filename)
}
}
- return CreateHrtfStore(rate, irSize, fdCount, distance.data(), evCount.data(), azCount.data(),
+ std::reverse(distance.begin(), distance.end());
+ std::reverse(evCount.begin(), evCount.end());
+ return CreateHrtfStore(rate, irSize, fdCount, evCount.data(), distance.data(), azCount.data(),
evOffset.data(), irTotal, &reinterpret_cast<ALfloat(&)[2]>(coeffs[0]),
&reinterpret_cast<ALubyte(&)[2]>(delays[0]), filename);
}
diff --git a/Alc/hrtf.h b/Alc/hrtf.h
index c87210d4..9a6dc61e 100644
--- a/Alc/hrtf.h
+++ b/Alc/hrtf.h
@@ -29,10 +29,15 @@ struct HrtfEntry {
ALuint sampleRate;
ALsizei irSize;
+ /* Base elevation index for the farthest field. */
+ ALsizei evFarBase;
struct Field {
- ALfloat distance;
ALubyte evCount;
+ ALfloat distance;
};
+ /* NOTE: Fields are stored *backwards*. field[0] is the farthest field, and
+ * field[fdCount-1] is the nearest.
+ */
ALsizei fdCount;
Field *field;
diff --git a/Alc/panning.cpp b/Alc/panning.cpp
index 60436e02..25b940a2 100644
--- a/Alc/panning.cpp
+++ b/Alc/panning.cpp
@@ -626,8 +626,7 @@ void InitHrtfPanning(ALCdevice *device)
AmbiMatrix, static_cast<ALsizei>(COUNTOF(AmbiPoints)), AmbiOrderHFGain);
HrtfEntry *Hrtf{device->mHrtf};
- const auto &field = Hrtf->field[Hrtf->fdCount-1];
- InitNearFieldCtrl(device, field.distance, ambi_order, ChansPerOrder);
+ InitNearFieldCtrl(device, Hrtf->field[0].distance, ambi_order, ChansPerOrder);
}
void InitUhjPanning(ALCdevice *device)