Small cleanup for BuildBFormatHrtf
This commit is contained in:
+39
-35
@@ -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]));
|
||||
|
||||
return idx;
|
||||
};
|
||||
std::transform(AmbiPoints, AmbiPoints+AmbiCount, idx.begin(), calc_idxs);
|
||||
|
||||
al::vector<std::array<std::array<ALdouble,2>,HRIR_LENGTH>> tmpres(NumChannels);
|
||||
ALfloat temps[3][HRIR_LENGTH]{};
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user