diff options
Diffstat (limited to 'Alc/mixer/hrtf_inc.cpp')
-rw-r--r-- | Alc/mixer/hrtf_inc.cpp | 208 |
1 files changed, 136 insertions, 72 deletions
diff --git a/Alc/mixer/hrtf_inc.cpp b/Alc/mixer/hrtf_inc.cpp index e82bad85..caac7e54 100644 --- a/Alc/mixer/hrtf_inc.cpp +++ b/Alc/mixer/hrtf_inc.cpp @@ -14,114 +14,178 @@ static inline void ApplyCoeffs(ALsizei Offset, ALfloat (&Values)[HRIR_LENGTH][2] void MixHrtf(ALfloat *RESTRICT LeftOut, ALfloat *RESTRICT RightOut, - const ALfloat *data, ALsizei Offset, ALsizei OutPos, + const ALfloat *data, ALsizei Offset, const ALsizei OutPos, const ALsizei IrSize, MixHrtfParams *hrtfparams, HrtfState *hrtfstate, - ALsizei BufferSize) + const ALsizei BufferSize) { - const ALfloat (&Coeffs)[HRIR_LENGTH][2] = *hrtfparams->Coeffs; - const ALsizei Delay[2] = { hrtfparams->Delay[0], hrtfparams->Delay[1] }; - const ALfloat gainstep = hrtfparams->GainStep; - const ALfloat gain = hrtfparams->Gain; - ALfloat g, stepcount = 0.0f; - ALfloat left, right; - ALsizei i; - + ASSUME(OutPos >= 0); ASSUME(IrSize >= 4); ASSUME(BufferSize > 0); - LeftOut += OutPos; - RightOut += OutPos; - for(i = 0;i < BufferSize;i++) - { - hrtfstate->History[Offset&HRTF_HISTORY_MASK] = *(data++); - - g = gain + gainstep*stepcount; - left = hrtfstate->History[(Offset-Delay[0])&HRTF_HISTORY_MASK]*g; - right = hrtfstate->History[(Offset-Delay[1])&HRTF_HISTORY_MASK]*g; + const ALfloat (&Coeffs)[HRIR_LENGTH][2] = *hrtfparams->Coeffs; + const ALfloat gainstep{hrtfparams->GainStep}; + const ALfloat gain{hrtfparams->Gain}; + ALfloat stepcount{0.0f}; - hrtfstate->Values[(Offset+IrSize-1)&HRIR_MASK][0] = 0.0f; - hrtfstate->Values[(Offset+IrSize-1)&HRIR_MASK][1] = 0.0f; + ALsizei HistOffset{Offset&HRTF_HISTORY_MASK}; + ALsizei Delay[2]{ + (HistOffset-hrtfparams->Delay[0])&HRTF_HISTORY_MASK, + (HistOffset-hrtfparams->Delay[1])&HRTF_HISTORY_MASK }; - ApplyCoeffs(Offset, hrtfstate->Values, IrSize, Coeffs, left, right); - *(LeftOut++) += hrtfstate->Values[Offset&HRIR_MASK][0]; - *(RightOut++) += hrtfstate->Values[Offset&HRIR_MASK][1]; + Offset &= HRIR_MASK; + ALsizei HeadOffset{(Offset+IrSize-1)&HRIR_MASK}; - stepcount += 1.0f; - Offset++; + LeftOut += OutPos; + RightOut += OutPos; + for(ALsizei i{0};i < BufferSize;) + { + /* Calculate the number of samples we can do until one of the indices + * wraps on its buffer, or we reach the end. + */ + const ALsizei todo_hist{HRTF_HISTORY_LENGTH - maxi(maxi(HistOffset, Delay[0]), Delay[1])}; + const ALsizei todo_hrir{HRIR_LENGTH - maxi(HeadOffset, Offset)}; + const ALsizei todo{mini(BufferSize-i, mini(todo_hist, todo_hrir)) + i}; + ASSUME(todo > i); + + for(;i < todo;++i) + { + hrtfstate->Values[HeadOffset][0] = 0.0f; + hrtfstate->Values[HeadOffset][1] = 0.0f; + ++HeadOffset; + + hrtfstate->History[HistOffset++] = *(data++); + + const ALfloat g{gain + gainstep*stepcount}; + const ALfloat left{hrtfstate->History[Delay[0]++] * g}; + const ALfloat right{hrtfstate->History[Delay[1]++] * g}; + ApplyCoeffs(Offset, hrtfstate->Values, IrSize, Coeffs, left, right); + + *(LeftOut++) += hrtfstate->Values[Offset][0]; + *(RightOut++) += hrtfstate->Values[Offset][1]; + ++Offset; + + stepcount += 1.0f; + } + + HeadOffset &= HRIR_MASK; + HistOffset &= HRTF_HISTORY_MASK; + Delay[0] &= HRTF_HISTORY_MASK; + Delay[1] &= HRTF_HISTORY_MASK; + Offset &= HRIR_MASK; } hrtfparams->Gain = gain + gainstep*stepcount; } void MixHrtfBlend(ALfloat *RESTRICT LeftOut, ALfloat *RESTRICT RightOut, - const ALfloat *data, ALsizei Offset, ALsizei OutPos, + const ALfloat *data, ALsizei Offset, const ALsizei OutPos, const ALsizei IrSize, const HrtfParams *oldparams, MixHrtfParams *newparams, HrtfState *hrtfstate, - ALsizei BufferSize) + const ALsizei BufferSize) { const ALfloat (&OldCoeffs)[HRIR_LENGTH][2] = oldparams->Coeffs; - const ALsizei OldDelay[2] = { oldparams->Delay[0], oldparams->Delay[1] }; - const ALfloat oldGain = oldparams->Gain; - const ALfloat oldGainStep = -oldGain / (ALfloat)BufferSize; + const ALfloat oldGain{oldparams->Gain}; + const ALfloat oldGainStep{-oldGain / (ALfloat)BufferSize}; const ALfloat (&NewCoeffs)[HRIR_LENGTH][2] = *newparams->Coeffs; - const ALsizei NewDelay[2] = { newparams->Delay[0], newparams->Delay[1] }; - const ALfloat newGain = newparams->Gain; - const ALfloat newGainStep = newparams->GainStep; - ALfloat g, stepcount = 0.0f; - ALfloat left, right; - ALsizei i; + const ALfloat newGainStep{newparams->GainStep}; + ALfloat stepcount{0.0f}; + ASSUME(OutPos >= 0); ASSUME(IrSize >= 4); ASSUME(BufferSize > 0); + ALsizei HistOffset{Offset&HRTF_HISTORY_MASK}; + ALsizei OldDelay[2]{ + (HistOffset-oldparams->Delay[0])&HRTF_HISTORY_MASK, + (HistOffset-oldparams->Delay[1])&HRTF_HISTORY_MASK }; + ALsizei NewDelay[2]{ + (HistOffset-newparams->Delay[0])&HRTF_HISTORY_MASK, + (HistOffset-newparams->Delay[1])&HRTF_HISTORY_MASK }; + + Offset &= HRIR_MASK; + ALsizei HeadOffset{(Offset+IrSize-1)&HRIR_MASK}; + LeftOut += OutPos; RightOut += OutPos; - for(i = 0;i < BufferSize;i++) + for(ALsizei i{0};i < BufferSize;) { - hrtfstate->Values[(Offset+IrSize-1)&HRIR_MASK][0] = 0.0f; - hrtfstate->Values[(Offset+IrSize-1)&HRIR_MASK][1] = 0.0f; - - hrtfstate->History[Offset&HRTF_HISTORY_MASK] = *(data++); - - g = oldGain + oldGainStep*stepcount; - left = hrtfstate->History[(Offset-OldDelay[0])&HRTF_HISTORY_MASK]*g; - right = hrtfstate->History[(Offset-OldDelay[1])&HRTF_HISTORY_MASK]*g; - ApplyCoeffs(Offset, hrtfstate->Values, IrSize, OldCoeffs, left, right); - - g = newGain + newGainStep*stepcount; - left = hrtfstate->History[(Offset-NewDelay[0])&HRTF_HISTORY_MASK]*g; - right = hrtfstate->History[(Offset-NewDelay[1])&HRTF_HISTORY_MASK]*g; - ApplyCoeffs(Offset, hrtfstate->Values, IrSize, NewCoeffs, left, right); - - *(LeftOut++) += hrtfstate->Values[Offset&HRIR_MASK][0]; - *(RightOut++) += hrtfstate->Values[Offset&HRIR_MASK][1]; - - stepcount += 1.0f; - Offset++; + const ALsizei todo_hist{HRTF_HISTORY_LENGTH - + maxi(maxi(maxi(maxi(HistOffset, OldDelay[0]), OldDelay[1]), NewDelay[0]), NewDelay[1]) + }; + const ALsizei todo_hrir{HRIR_LENGTH - maxi(HeadOffset, Offset)}; + const ALsizei todo{mini(BufferSize-i, mini(todo_hist, todo_hrir)) + i}; + ASSUME(todo > i); + + for(;i < todo;++i) + { + hrtfstate->Values[HeadOffset][0] = 0.0f; + hrtfstate->Values[HeadOffset][1] = 0.0f; + ++HeadOffset; + + hrtfstate->History[HistOffset++] = *(data++); + + ALfloat g{oldGain + oldGainStep*stepcount}; + ALfloat left{hrtfstate->History[OldDelay[0]++] * g}; + ALfloat right{hrtfstate->History[OldDelay[1]++] * g}; + ApplyCoeffs(Offset, hrtfstate->Values, IrSize, OldCoeffs, left, right); + + g = newGainStep*stepcount; + left = hrtfstate->History[NewDelay[0]++] * g; + right = hrtfstate->History[NewDelay[1]++] * g; + ApplyCoeffs(Offset, hrtfstate->Values, IrSize, NewCoeffs, left, right); + + *(LeftOut++) += hrtfstate->Values[Offset][0]; + *(RightOut++) += hrtfstate->Values[Offset][1]; + ++Offset; + + stepcount += 1.0f; + } + + HeadOffset &= HRIR_MASK; + HistOffset &= HRTF_HISTORY_MASK; + OldDelay[0] &= HRTF_HISTORY_MASK; + OldDelay[1] &= HRTF_HISTORY_MASK; + NewDelay[0] &= HRTF_HISTORY_MASK; + NewDelay[1] &= HRTF_HISTORY_MASK; + Offset &= HRIR_MASK; } - newparams->Gain = newGain + newGainStep*stepcount; + newparams->Gain = newGainStep*stepcount; } void MixDirectHrtf(ALfloat *RESTRICT LeftOut, ALfloat *RESTRICT RightOut, const ALfloat *data, DirectHrtfState *State, const ALsizei Chan, const ALsizei BufferSize) { - const ALsizei IrSize{State->IrSize}; - ALsizei Offset{State->Offset}; - ALfloat (&Values)[HRIR_LENGTH][2] = State->Chan[Chan].Values; + ASSUME(Chan >= 0); + ASSUME(BufferSize > 0); + const ALfloat (&Coeffs)[HRIR_LENGTH][2] = State->Chan[Chan].Coeffs; + ALfloat (&Values)[HRIR_LENGTH][2] = State->Chan[Chan].Values; + ALsizei Offset{State->Offset&HRIR_MASK}; + const ALsizei IrSize{State->IrSize}; ASSUME(IrSize >= 4); - ASSUME(BufferSize > 0); - for(ALsizei i{0};i < BufferSize;i++) + ALsizei HeadOffset{(Offset+IrSize-1)&HRIR_MASK}; + for(ALsizei i{0};i < BufferSize;) { - Values[(Offset+IrSize)&HRIR_MASK][0] = 0.0f; - Values[(Offset+IrSize)&HRIR_MASK][1] = 0.0f; - Offset++; - - const ALfloat insample{*(data++)}; - ApplyCoeffs(Offset, Values, IrSize, Coeffs, insample, insample); - *(LeftOut++) += Values[Offset&HRIR_MASK][0]; - *(RightOut++) += Values[Offset&HRIR_MASK][1]; + const ALsizei todo_hrir{HRIR_LENGTH - maxi(HeadOffset, Offset)}; + const ALsizei todo{mini(BufferSize-i, todo_hrir) + i}; + ASSUME(todo > i); + + for(;i < todo;++i) + { + Values[HeadOffset][0] = 0.0f; + Values[HeadOffset][1] = 0.0f; + ++HeadOffset; + + const ALfloat insample{*(data++)}; + ApplyCoeffs(Offset, Values, IrSize, Coeffs, insample, insample); + + *(LeftOut++) += Values[Offset][0]; + *(RightOut++) += Values[Offset][1]; + ++Offset; + } + HeadOffset &= HRIR_MASK; + Offset &= HRIR_MASK; } } |