diff options
author | Chris Robinson <[email protected]> | 2018-12-21 18:17:59 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2018-12-21 18:17:59 -0800 |
commit | 5e4378f30a4b3599a2d77809c34390d893e99081 (patch) | |
tree | fc541406e21519c374c848fbfc06f9b2f34b14b2 | |
parent | 3553ce1f67d46573e338ff6e53a31d60a722d5c6 (diff) |
Small cleanup for BuildBFormatHrtf
-rw-r--r-- | Alc/hrtf.cpp | 74 |
1 files changed, 39 insertions, 35 deletions
diff --git a/Alc/hrtf.cpp b/Alc/hrtf.cpp index ab202e53..b7422653 100644 --- a/Alc/hrtf.cpp +++ b/Alc/hrtf.cpp @@ -277,6 +277,13 @@ void GetHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, void BuildBFormatHrtf(const struct Hrtf *Hrtf, DirectHrtfState *state, const ALsizei NumChannels, const AngularPoint *AmbiPoints, const ALfloat (*RESTRICT AmbiMatrix)[MAX_AMBI_COEFFS], const ALsizei AmbiCount, const ALfloat *RESTRICT AmbiOrderHFGain) { + static constexpr int OrderFromChan[MAX_AMBI_COEFFS]{ + 0, 1,1,1, 2,2,2,2,2, 3,3,3,3,3,3,3, + }; + + ASSUME(NumChannels > 0); + ASSUME(AmbiCount > 0); + /* Set this to 2 for dual-band HRTF processing. May require a higher quality * band-splitter, or better calculation of the new IR length to deal with the * tail generated by the filter. @@ -285,92 +292,89 @@ void BuildBFormatHrtf(const struct Hrtf *Hrtf, DirectHrtfState *state, const ALs ALsizei min_delay{HRTF_HISTORY_LENGTH}; ALsizei max_delay{0}; al::vector<ALsizei> idx(AmbiCount); - for(ALsizei c{0};c < AmbiCount;c++) + auto calc_idxs = [Hrtf,&max_delay,&min_delay](const AngularPoint &pt) noexcept -> ALsizei { /* Calculate elevation index. */ const auto evidx = clampi( - static_cast<ALsizei>((90.0f+AmbiPoints[c].Elev)*(Hrtf->evCount-1)/180.0f + 0.5f), + static_cast<ALsizei>((90.0f+pt.Elev)*(Hrtf->evCount-1)/180.0f + 0.5f), 0, Hrtf->evCount-1); const ALsizei azcount{Hrtf->azCount[evidx]}; const ALsizei evoffset{Hrtf->evOffset[evidx]}; /* Calculate azimuth index for this elevation. */ - const auto azidx = static_cast<ALsizei>( - (360.0f+AmbiPoints[c].Azim)*azcount/360.0f + 0.5f) % azcount; + const auto azidx = static_cast<ALsizei>((360.0f+pt.Azim)*azcount/360.0f + 0.5f) % azcount; - /* Calculate indices for left and right channels. */ - idx[c] = evoffset + azidx; + /* Calculate the index for the impulse response. */ + ALsizei idx{evoffset + azidx}; - min_delay = mini(min_delay, mini(Hrtf->delays[idx[c]][0], Hrtf->delays[idx[c]][1])); - max_delay = maxi(max_delay, maxi(Hrtf->delays[idx[c]][0], Hrtf->delays[idx[c]][1])); - } + min_delay = mini(min_delay, mini(Hrtf->delays[idx][0], Hrtf->delays[idx][1])); + max_delay = maxi(max_delay, maxi(Hrtf->delays[idx][0], Hrtf->delays[idx][1])); - al::vector<std::array<std::array<ALdouble,2>,HRIR_LENGTH>> tmpres(NumChannels); - ALfloat temps[3][HRIR_LENGTH]{}; + return idx; + }; + std::transform(AmbiPoints, AmbiPoints+AmbiCount, idx.begin(), calc_idxs); + al::vector<std::array<std::array<ALdouble,2>,HRIR_LENGTH>> tmpres(NumChannels); BandSplitter splitter; splitter.init(400.0f / (ALfloat)Hrtf->sampleRate); for(ALsizei c{0};c < AmbiCount;++c) { - const ALfloat (*fir)[2] = &Hrtf->coeffs[idx[c] * Hrtf->irSize]; - ALsizei ldelay = Hrtf->delays[idx[c]][0] - min_delay; - ALsizei rdelay = Hrtf->delays[idx[c]][1] - min_delay; + const ALfloat (*fir)[2]{&Hrtf->coeffs[idx[c] * Hrtf->irSize]}; + ALsizei ldelay{Hrtf->delays[idx[c]][0] - min_delay}; + ALsizei rdelay{Hrtf->delays[idx[c]][1] - min_delay}; if(NUM_BANDS == 1) { for(ALsizei i{0};i < NumChannels;++i) { - ALdouble mult = (ALdouble)AmbiOrderHFGain[(ALsizei)sqrt(i)] * AmbiMatrix[c][i]; - ALsizei lidx = ldelay, ridx = rdelay; - ALsizei j = 0; - while(lidx < HRIR_LENGTH && ridx < HRIR_LENGTH && j < Hrtf->irSize) + const ALdouble mult{(ALdouble)AmbiOrderHFGain[OrderFromChan[i]] * AmbiMatrix[c][i]}; + const ALsizei numirs{mini(Hrtf->irSize, HRIR_LENGTH-maxi(ldelay, rdelay))}; + ALsizei lidx{ldelay}, ridx{rdelay}; + for(ALsizei j{0};j < numirs;++j) { tmpres[i][lidx++][0] += fir[j][0] * mult; tmpres[i][ridx++][1] += fir[j][1] * mult; - j++; } } } else { + ALfloat temps[3][HRIR_LENGTH]{}; + /* Band-split left HRIR into low and high frequency responses. */ splitter.clear(); - for(ALsizei i{0};i < Hrtf->irSize;++i) - temps[2][i] = fir[i][0]; + std::transform(fir, fir+Hrtf->irSize, std::begin(temps[2]), + [](const ALfloat (&ir)[2]) noexcept { return ir[0]; }); splitter.process(temps[0], temps[1], temps[2], HRIR_LENGTH); /* Apply left ear response with delay. */ for(ALsizei i{0};i < NumChannels;++i) { - ALdouble hfgain = AmbiOrderHFGain[(ALsizei)sqrt(i)]; + const ALdouble hfgain{AmbiOrderHFGain[OrderFromChan[i]]}; for(ALsizei b{0};b < NUM_BANDS;++b) { - ALdouble mult = AmbiMatrix[c][i] * ((b==0) ? hfgain : 1.0); - ALsizei lidx = ldelay; - ALsizei j = 0; - while(lidx < HRIR_LENGTH) - tmpres[i][lidx++][0] += temps[b][j++] * mult; + const ALdouble mult{AmbiMatrix[c][i] * ((b==0) ? hfgain : 1.0)}; + for(ALsizei lidx{ldelay},j{0};lidx < HRIR_LENGTH;++lidx,++j) + tmpres[i][lidx][0] += temps[b][j] * mult; } } /* Band-split right HRIR into low and high frequency responses. */ splitter.clear(); - for(ALsizei i{0};i < Hrtf->irSize;++i) - temps[2][i] = fir[i][1]; + std::transform(fir, fir+Hrtf->irSize, std::begin(temps[2]), + [](const ALfloat (&ir)[2]) noexcept { return ir[1]; }); splitter.process(temps[0], temps[1], temps[2], HRIR_LENGTH); /* Apply right ear response with delay. */ for(ALsizei i{0};i < NumChannels;++i) { - ALdouble hfgain = AmbiOrderHFGain[(ALsizei)sqrt(i)]; + const ALdouble hfgain{AmbiOrderHFGain[OrderFromChan[i]]}; for(ALsizei b{0};b < NUM_BANDS;++b) { - ALdouble mult = AmbiMatrix[c][i] * ((b==0) ? hfgain : 1.0); - ALsizei ridx = rdelay; - ALsizei j = 0; - while(ridx < HRIR_LENGTH) - tmpres[i][ridx++][1] += temps[b][j++] * mult; + const ALdouble mult{AmbiMatrix[c][i] * ((b==0) ? hfgain : 1.0)}; + for(ALsizei ridx{rdelay},j{0};ridx < HRIR_LENGTH;++ridx,++j) + tmpres[i][ridx][1] += temps[b][j] * mult; } } } |