diff options
author | Chris Robinson <[email protected]> | 2016-08-21 03:05:42 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2016-08-21 03:05:42 -0700 |
commit | 846cdd472da81fefefca8ffa113d32824bc297c2 (patch) | |
tree | 1dc3e1caff16aecc5afd59da4d5e12d1028f24e1 /Alc/hrtf.c | |
parent | d16954c34ebb4bfbd4e7ef27090b01d6f4ff9261 (diff) |
Band-split the HRIRs when building the ambisonic decoder filters
This allows each HRIR to contribute a frequency-dependent response, essentially
acting like a dual-band decoder playing over the cube speaker array.
Diffstat (limited to 'Alc/hrtf.c')
-rw-r--r-- | Alc/hrtf.c | 64 |
1 files changed, 43 insertions, 21 deletions
@@ -28,6 +28,7 @@ #include "alMain.h" #include "alSource.h" #include "alu.h" +#include "bformatdec.h" #include "hrtf.h" #include "compat.h" @@ -187,20 +188,22 @@ ALuint BuildBFormatHrtf(const struct Hrtf *Hrtf, ALfloat (*coeffs)[HRIR_LENGTH][ { DEG2RAD(-35.0f), DEG2RAD(-135.0f) }, { DEG2RAD(-35.0f), DEG2RAD( 135.0f) }, }; - static const ALfloat CubeMatrix[8][MAX_AMBI_COEFFS] = { - { 0.25f, 0.14425f, 0.14425f, 0.14425f }, - { 0.25f, -0.14425f, 0.14425f, 0.14425f }, - { 0.25f, 0.14425f, 0.14425f, -0.14425f }, - { 0.25f, -0.14425f, 0.14425f, -0.14425f }, - { 0.25f, 0.14425f, -0.14425f, 0.14425f }, - { 0.25f, -0.14425f, -0.14425f, 0.14425f }, - { 0.25f, 0.14425f, -0.14425f, -0.14425f }, - { 0.25f, -0.14425f, -0.14425f, -0.14425f }, + static const ALfloat CubeMatrix[8][2][MAX_AMBI_COEFFS] = { + { { 0.25f, 0.14425f, 0.14425f, 0.14425f }, { 0.125f, 0.125f, 0.125f, 0.125f } }, + { { 0.25f, -0.14425f, 0.14425f, 0.14425f }, { 0.125f, -0.125f, 0.125f, 0.125f } }, + { { 0.25f, 0.14425f, 0.14425f, -0.14425f }, { 0.125f, 0.125f, 0.125f, -0.125f } }, + { { 0.25f, -0.14425f, 0.14425f, -0.14425f }, { 0.125f, -0.125f, 0.125f, -0.125f } }, + { { 0.25f, 0.14425f, -0.14425f, 0.14425f }, { 0.125f, 0.125f, -0.125f, 0.125f } }, + { { 0.25f, -0.14425f, -0.14425f, 0.14425f }, { 0.125f, -0.125f, -0.125f, 0.125f } }, + { { 0.25f, 0.14425f, -0.14425f, -0.14425f }, { 0.125f, 0.125f, -0.125f, -0.125f } }, + { { 0.25f, -0.14425f, -0.14425f, -0.14425f }, { 0.125f, -0.125f, -0.125f, -0.125f } }, }; + BandSplitter splitter; + ALfloat temps[3][HRIR_LENGTH]; ALuint lidx[8], ridx[8]; ALuint min_delay = HRTF_HISTORY_LENGTH; ALuint max_length = 0; - ALuint i, j, c; + ALuint i, j, c, b; assert(NumChannels == 4); @@ -229,33 +232,52 @@ ALuint BuildBFormatHrtf(const struct Hrtf *Hrtf, ALfloat (*coeffs)[HRIR_LENGTH][ min_delay = minu(min_delay, minu(Hrtf->delays[lidx[c]], Hrtf->delays[ridx[c]])); } + memset(temps, 0, sizeof(temps)); + bandsplit_init(&splitter, 400.0f / (ALfloat)Hrtf->sampleRate); for(c = 0;c < 8;c++) { const ALshort *fir; - ALuint length; ALuint delay; + /* Band-split left HRIR into low and high frequency responses. */ + bandsplit_clear(&splitter); fir = &Hrtf->coeffs[lidx[c] * Hrtf->irSize]; + for(i = 0;i < Hrtf->irSize;i++) + temps[2][i] = fir[i] / 32767.0f; + bandsplit_process(&splitter, temps[0], temps[1], temps[2], HRIR_LENGTH); + + /* Add to the left output coefficients with the specified delay. */ delay = Hrtf->delays[lidx[c]] - min_delay; - length = minu(delay + Hrtf->irSize, HRIR_LENGTH); for(i = 0;i < NumChannels;++i) { - ALuint k = 0; - for(j = delay;j < length;++j) - coeffs[i][j][0] += fir[k++]/32767.0f * CubeMatrix[c][i]; + for(b = 0;b < 2;b++) + { + ALuint k = 0; + for(j = delay;j < HRIR_LENGTH;++j) + coeffs[i][j][0] += temps[b][k++] * CubeMatrix[c][b][i]; + } } - max_length = maxu(max_length, length); + max_length = maxu(max_length, minu(delay + Hrtf->irSize, HRIR_LENGTH)); + /* Band-split right HRIR into low and high frequency responses. */ + bandsplit_clear(&splitter); fir = &Hrtf->coeffs[ridx[c] * Hrtf->irSize]; + for(i = 0;i < Hrtf->irSize;i++) + temps[2][i] = fir[i] / 32767.0f; + bandsplit_process(&splitter, temps[0], temps[1], temps[2], HRIR_LENGTH); + + /* Add to the right output coefficients with the specified delay. */ delay = Hrtf->delays[ridx[c]] - min_delay; - length = minu(delay + Hrtf->irSize, HRIR_LENGTH); for(i = 0;i < NumChannels;++i) { - ALuint k = 0; - for(j = delay;j < length;++j) - coeffs[i][j][1] += fir[k++]/32767.0f * CubeMatrix[c][i]; + for(b = 0;b < 2;b++) + { + ALuint k = 0; + for(j = delay;j < HRIR_LENGTH;++j) + coeffs[i][j][1] += temps[b][k++] * CubeMatrix[c][b][i]; + } } - max_length = maxu(max_length, length); + max_length = maxu(max_length, minu(delay + Hrtf->irSize, HRIR_LENGTH)); } TRACE("Skipped min delay: %u, new combined length: %u\n", min_delay, max_length); |