diff options
author | Chris Robinson <[email protected]> | 2017-03-11 18:04:06 -0800 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2017-03-11 18:04:06 -0800 |
commit | 96aaab93662be289d3b2c5312ae50502afa8d221 (patch) | |
tree | c270633e689c7a64edaea8a6c15305197b435ced /Alc/hrtf.c | |
parent | feffe1e81a155ded0bcdb519a1a126fd8e908baa (diff) |
Rework HRTF coefficient fading
This improves fading between HRIRs as sources pan around. In particular, it
improves the issue with individual coefficients having various rounding errors
in the stepping values, as well as issues with interpolating delay values.
It does this by doing two mixing passes for each source. First using the last
coefficients that fade to silence, and then again using the new coefficients
that fade from silence. When added together, it creates a linear fade from one
to the other. Additionally, the gain is applied separately so the individual
coefficients don't step with rounding errors. Although this does increase CPU
cost since it's doing two mixes per source, each mix is a bit cheaper now since
the stepping is simplified to a single gain value, and the overall quality is
improved.
Diffstat (limited to 'Alc/hrtf.c')
-rw-r--r-- | Alc/hrtf.c | 38 |
1 files changed, 11 insertions, 27 deletions
@@ -77,10 +77,9 @@ static ALsizei CalcAzIndex(ALsizei azcount, ALfloat az) } /* Calculates static HRIR coefficients and delays for the given polar elevation - * and azimuth in radians. The coefficients are normalized and attenuated by - * the specified gain. + * and azimuth in radians. The coefficients are normalized. */ -void GetHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat spread, ALfloat gain, ALfloat (*coeffs)[2], ALsizei *delays) +void GetHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat spread, ALfloat (*coeffs)[2], ALsizei *delays) { ALsizei evidx, azidx, lidx, ridx; ALsizei azcount, evoffset; @@ -102,36 +101,21 @@ void GetHrtfCoeffs(const struct Hrtf *Hrtf, ALfloat elevation, ALfloat azimuth, ridx = evoffset + ((azcount-azidx) % azcount); /* Calculate the HRIR delays. */ - delays[0] = fastf2i(Hrtf->delays[lidx]*dirfact + 0.5f) << HRTFDELAY_BITS; - delays[1] = fastf2i(Hrtf->delays[ridx]*dirfact + 0.5f) << HRTFDELAY_BITS; + delays[0] = fastf2i(Hrtf->delays[lidx]*dirfact + 0.5f); + delays[1] = fastf2i(Hrtf->delays[ridx]*dirfact + 0.5f); /* Calculate the sample offsets for the HRIR indices. */ lidx *= Hrtf->irSize; ridx *= Hrtf->irSize; - /* Calculate the normalized and attenuated HRIR coefficients. Zero the - * coefficients if gain is too low. - */ - if(gain > 0.0001f) - { - gain /= 32767.0f; - - i = 0; - coeffs[i][0] = lerp(PassthruCoeff, Hrtf->coeffs[lidx+i], dirfact)*gain; - coeffs[i][1] = lerp(PassthruCoeff, Hrtf->coeffs[ridx+i], dirfact)*gain; - for(i = 1;i < Hrtf->irSize;i++) - { - coeffs[i][0] = Hrtf->coeffs[lidx+i]*gain * dirfact; - coeffs[i][1] = Hrtf->coeffs[ridx+i]*gain * dirfact; - } - } - else + /* Calculate the normalized and attenuated HRIR coefficients. */ + i = 0; + coeffs[i][0] = lerp(PassthruCoeff, Hrtf->coeffs[lidx+i], dirfact) * (1.0f/32767.0f); + coeffs[i][1] = lerp(PassthruCoeff, Hrtf->coeffs[ridx+i], dirfact) * (1.0f/32767.0f); + for(i = 1;i < Hrtf->irSize;i++) { - for(i = 0;i < Hrtf->irSize;i++) - { - coeffs[i][0] = 0.0f; - coeffs[i][1] = 0.0f; - } + coeffs[i][0] = Hrtf->coeffs[lidx+i]*(1.0f/32767.0f) * dirfact; + coeffs[i][1] = Hrtf->coeffs[ridx+i]*(1.0f/32767.0f) * dirfact; } } |