diff options
author | Chris Robinson <[email protected]> | 2011-05-02 02:22:30 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2011-05-02 02:22:30 -0700 |
commit | f843b7e2e362d3fc521771cdf8847de0a6f3a8d0 (patch) | |
tree | 00a92ec18d12f64713be07a111ceb1ea7872b74e | |
parent | eea86ab8916c5e0213dabc404a191bbf0e0affbe (diff) |
Implement HRTF mixers for multi-channel sources
-rw-r--r-- | Alc/ALu.c | 221 | ||||
-rw-r--r-- | Alc/mixer.c | 281 | ||||
-rw-r--r-- | OpenAL32/Include/alSource.h | 4 | ||||
-rw-r--r-- | OpenAL32/alSource.c | 8 |
4 files changed, 455 insertions, 59 deletions
@@ -161,7 +161,26 @@ ALvoid CalcNonAttnSourceParams(ALsource *ALSource, const ALCcontext *ALContext) SrcMatrix[0][FRONT_CENTER] = DryGain * ListenerGain; break; case FmtStereo: - if(!(ALContext->Device->Flags&DEVICE_DUPLICATE_STEREO)) + if((ALContext->Device->Flags&DEVICE_USE_HRTF)) + { + ALfloat angles[2] = { -30.0f, 30.0f }; + ALint c; + + for(c = 0;c < 2;c++) + { + const ALshort *hrtf_left, *hrtf_right; + + GetHrtfCoeffs(0.0, angles[c], &hrtf_left, &hrtf_right); + for(i = 0;i < HRTF_LENGTH;i++) + { + ALSource->Params.HrtfCoeffs[c][i][0] = + hrtf_left[i]*(1.0/32767.0)*DryGain*ListenerGain; + ALSource->Params.HrtfCoeffs[c][i][1] = + hrtf_right[i]*(1.0/32767.0)*DryGain*ListenerGain; + } + } + } + else if(!(ALContext->Device->Flags&DEVICE_DUPLICATE_STEREO)) { SrcMatrix[0][FRONT_LEFT] = DryGain * ListenerGain; SrcMatrix[1][FRONT_RIGHT] = DryGain * ListenerGain; @@ -207,61 +226,177 @@ ALvoid CalcNonAttnSourceParams(ALsource *ALSource, const ALCcontext *ALContext) break; case FmtRear: - SrcMatrix[0][BACK_LEFT] = DryGain * ListenerGain; - SrcMatrix[1][BACK_RIGHT] = DryGain * ListenerGain; + if((ALContext->Device->Flags&DEVICE_USE_HRTF)) + { + ALfloat angles[2] = { -150.0f, 150.0f }; + ALint c; + + for(c = 0;c < 2;c++) + { + const ALshort *hrtf_left, *hrtf_right; + + GetHrtfCoeffs(0.0, angles[c], &hrtf_left, &hrtf_right); + for(i = 0;i < HRTF_LENGTH;i++) + { + ALSource->Params.HrtfCoeffs[c][i][0] = + hrtf_left[i]*(1.0/32767.0)*DryGain*ListenerGain; + ALSource->Params.HrtfCoeffs[c][i][1] = + hrtf_right[i]*(1.0/32767.0)*DryGain*ListenerGain; + } + } + } + else + { + SrcMatrix[0][BACK_LEFT] = DryGain * ListenerGain; + SrcMatrix[1][BACK_RIGHT] = DryGain * ListenerGain; + } break; case FmtQuad: - SrcMatrix[0][FRONT_LEFT] = DryGain * ListenerGain; - SrcMatrix[1][FRONT_RIGHT] = DryGain * ListenerGain; - SrcMatrix[2][BACK_LEFT] = DryGain * ListenerGain; - SrcMatrix[3][BACK_RIGHT] = DryGain * ListenerGain; + if((ALContext->Device->Flags&DEVICE_USE_HRTF)) + { + ALfloat angles[4] = { -45.0f, 45.0f, -135.0f, 135.0f }; + ALint c; + + for(c = 0;c < 4;c++) + { + const ALshort *hrtf_left, *hrtf_right; + + GetHrtfCoeffs(0.0, angles[c], &hrtf_left, &hrtf_right); + for(i = 0;i < HRTF_LENGTH;i++) + { + ALSource->Params.HrtfCoeffs[c][i][0] = + hrtf_left[i]*(1.0/32767.0)*DryGain*ListenerGain; + ALSource->Params.HrtfCoeffs[c][i][1] = + hrtf_right[i]*(1.0/32767.0)*DryGain*ListenerGain; + } + } + } + else + { + SrcMatrix[0][FRONT_LEFT] = DryGain * ListenerGain; + SrcMatrix[1][FRONT_RIGHT] = DryGain * ListenerGain; + SrcMatrix[2][BACK_LEFT] = DryGain * ListenerGain; + SrcMatrix[3][BACK_RIGHT] = DryGain * ListenerGain; + } break; case FmtX51: - SrcMatrix[0][FRONT_LEFT] = DryGain * ListenerGain; - SrcMatrix[1][FRONT_RIGHT] = DryGain * ListenerGain; - SrcMatrix[2][FRONT_CENTER] = DryGain * ListenerGain; - SrcMatrix[3][LFE] = DryGain * ListenerGain; - SrcMatrix[4][BACK_LEFT] = DryGain * ListenerGain; - SrcMatrix[5][BACK_RIGHT] = DryGain * ListenerGain; + if((ALContext->Device->Flags&DEVICE_USE_HRTF)) + { + ALfloat angles[6] = { -30.0f, 30.0f, 0.0f, 0.0f, -110.0f, 110.0f }; + ALint c; + + for(c = 0;c < 6;c++) + { + const ALshort *hrtf_left, *hrtf_right; + + GetHrtfCoeffs(0.0, angles[c], &hrtf_left, &hrtf_right); + for(i = 0;i < HRTF_LENGTH;i++) + { + ALSource->Params.HrtfCoeffs[c][i][0] = + hrtf_left[i]*(1.0/32767.0)*DryGain*ListenerGain; + ALSource->Params.HrtfCoeffs[c][i][1] = + hrtf_right[i]*(1.0/32767.0)*DryGain*ListenerGain; + } + } + } + else + { + SrcMatrix[0][FRONT_LEFT] = DryGain * ListenerGain; + SrcMatrix[1][FRONT_RIGHT] = DryGain * ListenerGain; + SrcMatrix[2][FRONT_CENTER] = DryGain * ListenerGain; + SrcMatrix[3][LFE] = DryGain * ListenerGain; + SrcMatrix[4][BACK_LEFT] = DryGain * ListenerGain; + SrcMatrix[5][BACK_RIGHT] = DryGain * ListenerGain; + } break; case FmtX61: - SrcMatrix[0][FRONT_LEFT] = DryGain * ListenerGain; - SrcMatrix[1][FRONT_RIGHT] = DryGain * ListenerGain; - SrcMatrix[2][FRONT_CENTER] = DryGain * ListenerGain; - SrcMatrix[3][LFE] = DryGain * ListenerGain; - SrcMatrix[4][BACK_CENTER] = DryGain * ListenerGain; - SrcMatrix[5][SIDE_LEFT] = DryGain * ListenerGain; - SrcMatrix[6][SIDE_RIGHT] = DryGain * ListenerGain; + if((ALContext->Device->Flags&DEVICE_USE_HRTF)) + { + ALfloat angles[7] = { -30.0f, 30.0f, 0.0f, 0.0f, + -90.0f, 90.0f, 180.0f }; + ALint c; + + for(c = 0;c < 7;c++) + { + const ALshort *hrtf_left, *hrtf_right; + + GetHrtfCoeffs(0.0, angles[c], &hrtf_left, &hrtf_right); + for(i = 0;i < HRTF_LENGTH;i++) + { + ALSource->Params.HrtfCoeffs[c][i][0] = + hrtf_left[i]*(1.0/32767.0)*DryGain*ListenerGain; + ALSource->Params.HrtfCoeffs[c][i][1] = + hrtf_right[i]*(1.0/32767.0)*DryGain*ListenerGain; + } + } + } + else + { + SrcMatrix[0][FRONT_LEFT] = DryGain * ListenerGain; + SrcMatrix[1][FRONT_RIGHT] = DryGain * ListenerGain; + SrcMatrix[2][FRONT_CENTER] = DryGain * ListenerGain; + SrcMatrix[3][LFE] = DryGain * ListenerGain; + SrcMatrix[4][BACK_CENTER] = DryGain * ListenerGain; + SrcMatrix[5][SIDE_LEFT] = DryGain * ListenerGain; + SrcMatrix[6][SIDE_RIGHT] = DryGain * ListenerGain; + } break; case FmtX71: - SrcMatrix[0][FRONT_LEFT] = DryGain * ListenerGain; - SrcMatrix[1][FRONT_RIGHT] = DryGain * ListenerGain; - SrcMatrix[2][FRONT_CENTER] = DryGain * ListenerGain; - SrcMatrix[3][LFE] = DryGain * ListenerGain; - SrcMatrix[4][BACK_LEFT] = DryGain * ListenerGain; - SrcMatrix[5][BACK_RIGHT] = DryGain * ListenerGain; - SrcMatrix[6][SIDE_LEFT] = DryGain * ListenerGain; - SrcMatrix[7][SIDE_RIGHT] = DryGain * ListenerGain; + if((ALContext->Device->Flags&DEVICE_USE_HRTF)) + { + ALfloat angles[8] = { -30.0f, 30.0f, 0.0f, 0.0f, + -90.0f, 90.0f, -110.0f, 110.0f }; + ALint c; + + for(c = 0;c < 8;c++) + { + const ALshort *hrtf_left, *hrtf_right; + + GetHrtfCoeffs(0.0, angles[c], &hrtf_left, &hrtf_right); + for(i = 0;i < HRTF_LENGTH;i++) + { + ALSource->Params.HrtfCoeffs[c][i][0] = + hrtf_left[i]*(1.0/32767.0)*DryGain*ListenerGain; + ALSource->Params.HrtfCoeffs[c][i][1] = + hrtf_right[i]*(1.0/32767.0)*DryGain*ListenerGain; + } + } + } + else + { + SrcMatrix[0][FRONT_LEFT] = DryGain * ListenerGain; + SrcMatrix[1][FRONT_RIGHT] = DryGain * ListenerGain; + SrcMatrix[2][FRONT_CENTER] = DryGain * ListenerGain; + SrcMatrix[3][LFE] = DryGain * ListenerGain; + SrcMatrix[4][BACK_LEFT] = DryGain * ListenerGain; + SrcMatrix[5][BACK_RIGHT] = DryGain * ListenerGain; + SrcMatrix[6][SIDE_LEFT] = DryGain * ListenerGain; + SrcMatrix[7][SIDE_RIGHT] = DryGain * ListenerGain; + } break; } - for(i = 0;i < MAXCHANNELS;i++) + if(!(ALContext->Device->Flags&DEVICE_USE_HRTF)) { - ALuint j, k; - for(j = 0;j < MAXCHANNELS;j++) + for(i = 0;i < MAXCHANNELS;i++) { - ALfloat (*DevMatrix)[MAXCHANNELS] = ALContext->Device->ChannelMatrix; - ALSource->Params.DryGains[i][j] = 0.0f; - for(k = 0;k < MAXCHANNELS;k++) + ALuint j, k; + for(j = 0;j < MAXCHANNELS;j++) { - /* Matrix mult: O[i][j] += A[i][k] * B[k][j] - * However, our device matrix is transposed, so we do: - * O[i][j] += A[i][k] * B[j][k] - */ - ALSource->Params.DryGains[i][j] += SrcMatrix[i][k] * DevMatrix[j][k]; + ALfloat (*DevMatrix)[MAXCHANNELS] = ALContext->Device->ChannelMatrix; + ALSource->Params.DryGains[i][j] = 0.0f; + for(k = 0;k < MAXCHANNELS;k++) + { + /* Matrix mult: O[i][j] += A[i][k] * B[k][j] + * However, our device matrix is transposed, so we do: + * O[i][j] += A[i][k] * B[j][k] + */ + ALSource->Params.DryGains[i][j] += SrcMatrix[i][k] * + DevMatrix[j][k]; + } } } } @@ -677,10 +812,10 @@ ALvoid CalcSourceParams(ALsource *ALSource, const ALCcontext *ALContext) &hrtf_left, &hrtf_right); for(i = 0;i < HRTF_LENGTH;i++) { - ALSource->Params.HrtfCoeffs[i][0] = hrtf_left[i]*(1.0/32767.0) * - DryGain; - ALSource->Params.HrtfCoeffs[i][1] = hrtf_right[i]*(1.0/32767.0) * - DryGain; + ALSource->Params.HrtfCoeffs[0][i][0] = hrtf_left[i]*(1.0/32767.0)* + DryGain; + ALSource->Params.HrtfCoeffs[0][i][1] = hrtf_right[i]*(1.0/32767.0)* + DryGain; } } else diff --git a/Alc/mixer.c b/Alc/mixer.c index f229b56a..6afb7de8 100644 --- a/Alc/mixer.c +++ b/Alc/mixer.c @@ -94,8 +94,8 @@ void Mix_Hrtf_##T##_1_##sampler(ALsource *Source, ALCdevice *Device, \ PendingClicks = Device->PendingClicks; \ DryFilter = &Source->Params.iirFilter; \ \ - HrtfCoeffs = &Source->Params.HrtfCoeffs[0][0]; \ - HrtfHistory = Source->HrtfHistory; \ + HrtfCoeffs = &Source->Params.HrtfCoeffs[0][0][0]; \ + HrtfHistory = Source->HrtfHistory[0]; \ HrtfOffset = Source->HrtfOffset + OutPos; \ \ pos = 0; \ @@ -228,6 +228,233 @@ DECL_TEMPLATE(ALubyte, cubic8) #undef DECL_TEMPLATE +#define DECL_TEMPLATE(T, chnct, sampler) \ +static void Mix_Hrtf_##T##_##chnct##_##sampler( \ + ALsource *Source, ALCdevice *Device, \ + const T *data, ALuint *DataPosInt, ALuint *DataPosFrac, \ + ALuint OutPos, ALuint SamplesToDo, ALuint BufferSize) \ +{ \ + const ALuint Channels = chnct; \ + const ALfloat scaler = 1.0f/chnct; \ + ALfloat (*DryBuffer)[MAXCHANNELS]; \ + ALfloat *ClickRemoval, *PendingClicks; \ + const ALfloat (*HrtfCoeffs)[HRTF_LENGTH][2]; \ + ALfloat (*HrtfHistory)[HRTF_LENGTH]; \ + ALuint HrtfOffset; \ + ALuint pos, frac; \ + FILTER *DryFilter; \ + ALuint BufferIdx; \ + ALuint increment; \ + ALuint i, out, c; \ + ALfloat value; \ + \ + increment = Source->Params.Step; \ + \ + DryBuffer = Device->DryBuffer; \ + ClickRemoval = Device->ClickRemoval; \ + PendingClicks = Device->PendingClicks; \ + DryFilter = &Source->Params.iirFilter; \ + \ + HrtfCoeffs = &Source->Params.HrtfCoeffs[0]; \ + HrtfHistory = Source->HrtfHistory; \ + HrtfOffset = Source->HrtfOffset + OutPos; \ + \ + pos = 0; \ + frac = *DataPosFrac; \ + \ + if(LIKELY(OutPos == 0)) \ + { \ + for(i = 0;i < Channels;i++) \ + { \ + value = sampler(data + pos*Channels + i, Channels, frac); \ + value = lpFilter2PC(DryFilter, i*2, value); \ + \ + HrtfHistory[i][HrtfOffset&HRTF_LENGTH_MASK] = value; \ + for(c = 0;c < HRTF_LENGTH;c++) \ + { \ + ClickRemoval[FRONT_LEFT] -= \ + HrtfHistory[i][(HrtfOffset-c)&HRTF_LENGTH_MASK] * \ + HrtfCoeffs[i][c][0]; \ + ClickRemoval[FRONT_RIGHT] -= \ + HrtfHistory[i][(HrtfOffset-c)&HRTF_LENGTH_MASK] * \ + HrtfCoeffs[i][c][1]; \ + } \ + } \ + } \ + for(BufferIdx = 0;BufferIdx < BufferSize;BufferIdx++) \ + { \ + for(i = 0;i < Channels;i++) \ + { \ + value = sampler(data + pos*Channels + i, Channels, frac); \ + value = lpFilter2P(DryFilter, i*2, value); \ + \ + HrtfHistory[i][HrtfOffset&HRTF_LENGTH_MASK] = value; \ + for(c = 0;c < HRTF_LENGTH;c++) \ + { \ + DryBuffer[OutPos][FRONT_LEFT] += \ + HrtfHistory[i][(HrtfOffset-c)&HRTF_LENGTH_MASK] * \ + HrtfCoeffs[i][c][0]; \ + DryBuffer[OutPos][FRONT_RIGHT] += \ + HrtfHistory[i][(HrtfOffset-c)&HRTF_LENGTH_MASK] * \ + HrtfCoeffs[i][c][1]; \ + } \ + } \ + HrtfOffset++; \ + \ + frac += increment; \ + pos += frac>>FRACTIONBITS; \ + frac &= FRACTIONMASK; \ + OutPos++; \ + } \ + if(LIKELY(OutPos == SamplesToDo)) \ + { \ + for(i = 0;i < Channels;i++) \ + { \ + value = sampler(data + pos*Channels + i, Channels, frac); \ + value = lpFilter2PC(DryFilter, i*2, value); \ + \ + HrtfHistory[i][HrtfOffset&HRTF_LENGTH_MASK] = value; \ + for(c = 0;c < HRTF_LENGTH;c++) \ + { \ + PendingClicks[FRONT_LEFT] += \ + HrtfHistory[i][(HrtfOffset-c)&HRTF_LENGTH_MASK] * \ + HrtfCoeffs[i][c][0]; \ + PendingClicks[FRONT_RIGHT] += \ + HrtfHistory[i][(HrtfOffset-c)&HRTF_LENGTH_MASK] * \ + HrtfCoeffs[i][c][1]; \ + } \ + } \ + } \ + \ + for(out = 0;out < Device->NumAuxSends;out++) \ + { \ + ALfloat WetSend; \ + ALfloat *WetBuffer; \ + ALfloat *WetClickRemoval; \ + ALfloat *WetPendingClicks; \ + FILTER *WetFilter; \ + \ + if(!Source->Send[out].Slot || \ + Source->Send[out].Slot->effect.type == AL_EFFECT_NULL) \ + continue; \ + \ + WetBuffer = Source->Send[out].Slot->WetBuffer; \ + WetClickRemoval = Source->Send[out].Slot->ClickRemoval; \ + WetPendingClicks = Source->Send[out].Slot->PendingClicks; \ + WetFilter = &Source->Params.Send[out].iirFilter; \ + WetSend = Source->Params.Send[out].WetGain; \ + \ + pos = 0; \ + frac = *DataPosFrac; \ + OutPos -= BufferSize; \ + \ + if(LIKELY(OutPos == 0)) \ + { \ + for(i = 0;i < Channels;i++) \ + { \ + value = sampler(data + pos*Channels + i, Channels, frac); \ + value = lpFilter1PC(WetFilter, i, value); \ + \ + WetClickRemoval[0] -= value*WetSend * scaler; \ + } \ + } \ + for(BufferIdx = 0;BufferIdx < BufferSize;BufferIdx++) \ + { \ + for(i = 0;i < Channels;i++) \ + { \ + value = sampler(data + pos*Channels + i, Channels, frac); \ + value = lpFilter1P(WetFilter, i, value); \ + \ + WetBuffer[OutPos] += value*WetSend * scaler; \ + } \ + \ + frac += increment; \ + pos += frac>>FRACTIONBITS; \ + frac &= FRACTIONMASK; \ + OutPos++; \ + } \ + if(LIKELY(OutPos == SamplesToDo)) \ + { \ + for(i = 0;i < Channels;i++) \ + { \ + value = sampler(data + pos*Channels + i, Channels, frac); \ + value = lpFilter1PC(WetFilter, i, value); \ + \ + WetPendingClicks[0] += value*WetSend * scaler; \ + } \ + } \ + } \ + *DataPosInt += pos; \ + *DataPosFrac = frac; \ +} + +DECL_TEMPLATE(ALfloat, 2, point32) +DECL_TEMPLATE(ALfloat, 2, lerp32) +DECL_TEMPLATE(ALfloat, 2, cubic32) + +DECL_TEMPLATE(ALshort, 2, point16) +DECL_TEMPLATE(ALshort, 2, lerp16) +DECL_TEMPLATE(ALshort, 2, cubic16) + +DECL_TEMPLATE(ALubyte, 2, point8) +DECL_TEMPLATE(ALubyte, 2, lerp8) +DECL_TEMPLATE(ALubyte, 2, cubic8) + + +DECL_TEMPLATE(ALfloat, 4, point32) +DECL_TEMPLATE(ALfloat, 4, lerp32) +DECL_TEMPLATE(ALfloat, 4, cubic32) + +DECL_TEMPLATE(ALshort, 4, point16) +DECL_TEMPLATE(ALshort, 4, lerp16) +DECL_TEMPLATE(ALshort, 4, cubic16) + +DECL_TEMPLATE(ALubyte, 4, point8) +DECL_TEMPLATE(ALubyte, 4, lerp8) +DECL_TEMPLATE(ALubyte, 4, cubic8) + + +DECL_TEMPLATE(ALfloat, 6, point32) +DECL_TEMPLATE(ALfloat, 6, lerp32) +DECL_TEMPLATE(ALfloat, 6, cubic32) + +DECL_TEMPLATE(ALshort, 6, point16) +DECL_TEMPLATE(ALshort, 6, lerp16) +DECL_TEMPLATE(ALshort, 6, cubic16) + +DECL_TEMPLATE(ALubyte, 6, point8) +DECL_TEMPLATE(ALubyte, 6, lerp8) +DECL_TEMPLATE(ALubyte, 6, cubic8) + + +DECL_TEMPLATE(ALfloat, 7, point32) +DECL_TEMPLATE(ALfloat, 7, lerp32) +DECL_TEMPLATE(ALfloat, 7, cubic32) + +DECL_TEMPLATE(ALshort, 7, point16) +DECL_TEMPLATE(ALshort, 7, lerp16) +DECL_TEMPLATE(ALshort, 7, cubic16) + +DECL_TEMPLATE(ALubyte, 7, point8) +DECL_TEMPLATE(ALubyte, 7, lerp8) +DECL_TEMPLATE(ALubyte, 7, cubic8) + + +DECL_TEMPLATE(ALfloat, 8, point32) +DECL_TEMPLATE(ALfloat, 8, lerp32) +DECL_TEMPLATE(ALfloat, 8, cubic32) + +DECL_TEMPLATE(ALshort, 8, point16) +DECL_TEMPLATE(ALshort, 8, lerp16) +DECL_TEMPLATE(ALshort, 8, cubic16) + +DECL_TEMPLATE(ALubyte, 8, point8) +DECL_TEMPLATE(ALubyte, 8, lerp8) +DECL_TEMPLATE(ALubyte, 8, cubic8) + +#undef DECL_TEMPLATE + + #define DECL_TEMPLATE(T, sampler) \ static void Mix_##T##_1_##sampler(ALsource *Source, ALCdevice *Device, \ const T *data, ALuint *DataPosInt, ALuint *DataPosFrac, \ @@ -577,24 +804,54 @@ static void Mix_##T##_##sampler(ALsource *Source, ALCdevice *Device, \ break; \ case FmtStereo: \ case FmtRear: \ - Mix_##T##_2_##sampler(Source, Device, Data, DataPosInt, DataPosFrac, \ - OutPos, SamplesToDo, BufferSize); \ + if((Device->Flags&DEVICE_USE_HRTF)) \ + Mix_Hrtf_##T##_2_##sampler(Source, Device, Data, \ + DataPosInt, DataPosFrac, \ + OutPos, SamplesToDo, BufferSize); \ + else \ + Mix_##T##_2_##sampler(Source, Device, Data, \ + DataPosInt, DataPosFrac, \ + OutPos, SamplesToDo, BufferSize); \ break; \ case FmtQuad: \ - Mix_##T##_4_##sampler(Source, Device, Data, DataPosInt, DataPosFrac, \ - OutPos, SamplesToDo, BufferSize); \ + if((Device->Flags&DEVICE_USE_HRTF)) \ + Mix_Hrtf_##T##_4_##sampler(Source, Device, Data, \ + DataPosInt, DataPosFrac, \ + OutPos, SamplesToDo, BufferSize); \ + else \ + Mix_##T##_4_##sampler(Source, Device, Data, \ + DataPosInt, DataPosFrac, \ + OutPos, SamplesToDo, BufferSize); \ break; \ case FmtX51: \ - Mix_##T##_6_##sampler(Source, Device, Data, DataPosInt, DataPosFrac, \ - OutPos, SamplesToDo, BufferSize); \ + if((Device->Flags&DEVICE_USE_HRTF)) \ + Mix_Hrtf_##T##_6_##sampler(Source, Device, Data, \ + DataPosInt, DataPosFrac, \ + OutPos, SamplesToDo, BufferSize); \ + else \ + Mix_##T##_6_##sampler(Source, Device, Data, \ + DataPosInt, DataPosFrac, \ + OutPos, SamplesToDo, BufferSize); \ break; \ case FmtX61: \ - Mix_##T##_7_##sampler(Source, Device, Data, DataPosInt, DataPosFrac, \ - OutPos, SamplesToDo, BufferSize); \ + if((Device->Flags&DEVICE_USE_HRTF)) \ + Mix_Hrtf_##T##_7_##sampler(Source, Device, Data, \ + DataPosInt, DataPosFrac, \ + OutPos, SamplesToDo, BufferSize); \ + else \ + Mix_##T##_7_##sampler(Source, Device, Data, \ + DataPosInt, DataPosFrac, \ + OutPos, SamplesToDo, BufferSize); \ break; \ case FmtX71: \ - Mix_##T##_8_##sampler(Source, Device, Data, DataPosInt, DataPosFrac, \ - OutPos, SamplesToDo, BufferSize); \ + if((Device->Flags&DEVICE_USE_HRTF)) \ + Mix_Hrtf_##T##_8_##sampler(Source, Device, Data, \ + DataPosInt, DataPosFrac, \ + OutPos, SamplesToDo, BufferSize); \ + else \ + Mix_##T##_8_##sampler(Source, Device, Data, \ + DataPosInt, DataPosFrac, \ + OutPos, SamplesToDo, BufferSize); \ break; \ } \ } diff --git a/OpenAL32/Include/alSource.h b/OpenAL32/Include/alSource.h index 30b949db..ee342f92 100644 --- a/OpenAL32/Include/alSource.h +++ b/OpenAL32/Include/alSource.h @@ -87,7 +87,7 @@ typedef struct ALsource ALint lSourceType; /* HRTF info */ - ALfloat HrtfHistory[HRTF_LENGTH]; + ALfloat HrtfHistory[MAXCHANNELS][HRTF_LENGTH]; ALuint HrtfOffset; // Current target parameters used for mixing @@ -95,7 +95,7 @@ typedef struct ALsource struct { ALint Step; - ALfloat HrtfCoeffs[HRTF_LENGTH][2]; + ALfloat HrtfCoeffs[MAXCHANNELS][HRTF_LENGTH][2]; /* A mixing matrix. First subscript is the channel number of the input * data (regardless of channel configuration) and the second is the diff --git a/OpenAL32/alSource.c b/OpenAL32/alSource.c index 14beb85f..d6e9b18a 100644 --- a/OpenAL32/alSource.c +++ b/OpenAL32/alSource.c @@ -1349,8 +1349,12 @@ AL_API ALvoid AL_APIENTRY alSourcePlayv(ALsizei n, const ALuint *sources) Source->Buffer = Source->queue->buffer; - for(j = 0;j < HRTF_LENGTH;j++) - Source->HrtfHistory[j] = 0.0f; + for(j = 0;j < MAXCHANNELS;j++) + { + ALuint k; + for(k = 0;k < HRTF_LENGTH;k++) + Source->HrtfHistory[j][k] = 0.0f; + } Source->HrtfOffset = 0; } else |