aboutsummaryrefslogtreecommitdiffstats
path: root/alc
diff options
context:
space:
mode:
Diffstat (limited to 'alc')
-rw-r--r--alc/hrtf.cpp77
1 files changed, 25 insertions, 52 deletions
diff --git a/alc/hrtf.cpp b/alc/hrtf.cpp
index e8128cfe..61bce202 100644
--- a/alc/hrtf.cpp
+++ b/alc/hrtf.cpp
@@ -288,7 +288,7 @@ void BuildBFormatHrtf(const HrtfStore *Hrtf, DirectHrtfState *state,
{
using double2 = std::array<double,2>;
struct ImpulseResponse {
- alignas(16) std::array<double2,HRIR_LENGTH> hrir;
+ const HrirArray &hrir;
ALuint ldelay, rdelay;
};
@@ -303,53 +303,26 @@ void BuildBFormatHrtf(const HrtfStore *Hrtf, DirectHrtfState *state,
al::vector<ImpulseResponse> impres; impres.reserve(AmbiPoints.size());
auto calc_res = [Hrtf,&max_delay,&min_delay](const AngularPoint &pt) -> ImpulseResponse
{
- ImpulseResponse res;
+ auto CalcClosestEvIndex = [](ALuint evcount, float ev) -> ALuint
+ {
+ ev = (al::MathDefs<float>::Pi()*0.5f + ev) * static_cast<float>(evcount-1) /
+ al::MathDefs<float>::Pi();
+ return minu(float2uint(ev+0.5f), evcount-1);
+ };
+ auto CalcClosestAzIndex = [](ALuint azcount, float az) -> ALuint
+ {
+ az = (al::MathDefs<float>::Tau()+az) * static_cast<float>(azcount) /
+ al::MathDefs<float>::Tau();
+ return float2uint(az+0.5f) % azcount;
+ };
auto &field = Hrtf->field[0];
+ const size_t elevIdx{CalcClosestEvIndex(field.evCount, pt.Elev.value)};
+ const size_t azIdx{CalcClosestAzIndex(Hrtf->elev[elevIdx].azCount, pt.Azim.value)};
+ const size_t irOffset{Hrtf->elev[elevIdx].irOffset + azIdx};
- /* Calculate the elevation indices. */
- 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};
-
- /* Calculate azimuth indices. */
- const auto az0 = CalcAzIndex(Hrtf->elev[elev0.idx].azCount, pt.Azim.value);
- const auto az1 = CalcAzIndex(Hrtf->elev[elev1_idx].azCount, pt.Azim.value);
-
- /* Calculate the HRIR indices to blend. */
- const size_t idx[4]{
- ir0offset + az0.idx,
- ir0offset + ((az0.idx+1) % Hrtf->elev[elev0.idx].azCount),
- ir1offset + az1.idx,
- ir1offset + ((az1.idx+1) % Hrtf->elev[elev1_idx].azCount)};
-
- /* Calculate bilinear blending weights. */
- const double blend[4]{
- (1.0-elev0.blend) * (1.0-az0.blend),
- (1.0-elev0.blend) * ( az0.blend),
- ( elev0.blend) * (1.0-az1.blend),
- ( elev0.blend) * ( az1.blend)};
-
- /* Calculate the blended HRIR delays (in fixed-point). */
- double 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]};
- res.ldelay = fastf2u(static_cast<float>(d));
- 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];
- res.rdelay = fastf2u(static_cast<float>(d));
-
- /* Calculate the blended HRIR coefficients. */
- double *coeffout{al::assume_aligned<16>(&res.hrir[0][0])};
- std::fill(coeffout, coeffout + HRIR_LENGTH*2, 0.0);
- for(ALsizei c{0};c < 4;c++)
- {
- const float *srccoeffs{al::assume_aligned<16>(Hrtf->coeffs[idx[c]][0].data())};
- const double mult{blend[c]};
- auto blend_coeffs = [mult](const float src, const double coeff) noexcept -> double
- { return src*mult + coeff; };
- std::transform(srccoeffs, srccoeffs + HRIR_LENGTH*2, coeffout, coeffout, blend_coeffs);
- }
+ ImpulseResponse res{Hrtf->coeffs[irOffset],
+ Hrtf->delays[irOffset][0], Hrtf->delays[irOffset][1]};
min_delay = minu(min_delay, minu(res.ldelay, res.rdelay));
max_delay = maxu(max_delay, maxu(res.ldelay, res.rdelay));
@@ -372,7 +345,7 @@ void BuildBFormatHrtf(const HrtfStore *Hrtf, DirectHrtfState *state,
const al::span<double,HRIR_LENGTH*4> tempir{tmpflt[2].data(), tmpflt[2].size()};
for(size_t c{0u};c < AmbiPoints.size();++c)
{
- const al::span<const double2,HRIR_LENGTH> hrir{impres[c].hrir};
+ const HrirArray &hrir{impres[c].hrir};
const ALuint ldelay{hrir_delay_round(impres[c].ldelay-min_delay) + base_delay};
const ALuint rdelay{hrir_delay_round(impres[c].rdelay-min_delay) + base_delay};
@@ -403,7 +376,7 @@ void BuildBFormatHrtf(const HrtfStore *Hrtf, DirectHrtfState *state,
/* Load the (left) HRIR backwards, into a temp buffer with padding. */
std::fill(tempir.begin(), tempir.end(), 0.0);
std::transform(hrir.cbegin(), hrir.cend(), tempir.rbegin() + HRIR_LENGTH*3,
- [](const double2 &ir) noexcept -> double { return ir[0]; });
+ [](const float2 &ir) noexcept -> double { return ir[0]; });
/* Apply the all-pass on the reversed signal and reverse the resulting
* sample array. This produces the forward response with a backwards
@@ -422,8 +395,8 @@ void BuildBFormatHrtf(const HrtfStore *Hrtf, DirectHrtfState *state,
/* Apply left ear response with delay and HF scale. */
for(size_t i{0u};i < state->Coeffs.size();++i)
{
- const ALdouble mult{AmbiMatrix[c][i]};
- const ALdouble hfgain{AmbiOrderHFGain[AmbiIndex::OrderFromChannel[i]]};
+ const double mult{AmbiMatrix[c][i]};
+ const double hfgain{AmbiOrderHFGain[AmbiIndex::OrderFromChannel[i]]};
ALuint j{HRIR_LENGTH*3 - ldelay};
for(ALuint lidx{0};lidx < HRIR_LENGTH;++lidx,++j)
tmpres[i][lidx][0] += (tmpflt[0][j]*hfgain + tmpflt[1][j]) * mult;
@@ -432,7 +405,7 @@ void BuildBFormatHrtf(const HrtfStore *Hrtf, DirectHrtfState *state,
/* Now run the same process on the right HRIR. */
std::fill(tempir.begin(), tempir.end(), 0.0);
std::transform(hrir.cbegin(), hrir.cend(), tempir.rbegin() + HRIR_LENGTH*3,
- [](const double2 &ir) noexcept -> double { return ir[1]; });
+ [](const float2 &ir) noexcept -> double { return ir[1]; });
splitter.applyAllpass({tempir.data(), tempir.size()});
std::reverse(tempir.begin(), tempir.end());
@@ -442,8 +415,8 @@ void BuildBFormatHrtf(const HrtfStore *Hrtf, DirectHrtfState *state,
for(size_t i{0u};i < state->Coeffs.size();++i)
{
- const ALdouble mult{AmbiMatrix[c][i]};
- const ALdouble hfgain{AmbiOrderHFGain[AmbiIndex::OrderFromChannel[i]]};
+ const double mult{AmbiMatrix[c][i]};
+ const double hfgain{AmbiOrderHFGain[AmbiIndex::OrderFromChannel[i]]};
ALuint j{HRIR_LENGTH*3 - rdelay};
for(ALuint ridx{0};ridx < HRIR_LENGTH;++ridx,++j)
tmpres[i][ridx][1] += (tmpflt[0][j]*hfgain + tmpflt[1][j]) * mult;