🛠️🐜 Antkeeper superbuild with dependencies included https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

132 lines
4.5 KiB

#ifndef MIXER_HRTFBASE_H
#define MIXER_HRTFBASE_H
#include <algorithm>
#include "alu.h"
#include "../hrtf.h"
#include "opthelpers.h"
using ApplyCoeffsT = void(ALsizei Offset, float2 *RESTRICT Values, const ALsizei irSize,
const HrirArray<ALfloat> &Coeffs, const ALfloat left, const ALfloat right);
template<ApplyCoeffsT &ApplyCoeffs>
inline void MixHrtfBase(ALfloat *RESTRICT LeftOut, ALfloat *RESTRICT RightOut, const ALfloat *data,
float2 *RESTRICT AccumSamples, const ALsizei OutPos, const ALsizei IrSize,
MixHrtfParams *hrtfparams, const ALsizei BufferSize)
{
ASSUME(OutPos >= 0);
ASSUME(IrSize >= 4);
ASSUME(BufferSize > 0);
const auto &Coeffs = *hrtfparams->Coeffs;
const ALfloat gainstep{hrtfparams->GainStep};
const ALfloat gain{hrtfparams->Gain};
ALfloat stepcount{0.0f};
ALsizei Delay[2]{
HRTF_HISTORY_LENGTH - hrtfparams->Delay[0],
HRTF_HISTORY_LENGTH - hrtfparams->Delay[1] };
ASSUME(Delay[0] >= 0 && Delay[1] >= 0);
for(ALsizei i{0};i < BufferSize;++i)
{
const ALfloat g{gain + gainstep*stepcount};
const ALfloat left{data[Delay[0]++] * g};
const ALfloat right{data[Delay[1]++] * g};
ApplyCoeffs(i, AccumSamples+i, IrSize, Coeffs, left, right);
stepcount += 1.0f;
}
for(ALsizei i{0};i < BufferSize;++i)
LeftOut[OutPos+i] += AccumSamples[i][0];
for(ALsizei i{0};i < BufferSize;++i)
RightOut[OutPos+i] += AccumSamples[i][1];
hrtfparams->Gain = gain + gainstep*stepcount;
}
template<ApplyCoeffsT &ApplyCoeffs>
inline void MixHrtfBlendBase(ALfloat *RESTRICT LeftOut, ALfloat *RESTRICT RightOut,
const ALfloat *data, float2 *RESTRICT AccumSamples, const ALsizei OutPos, const ALsizei IrSize,
const HrtfParams *oldparams, MixHrtfParams *newparams, const ALsizei BufferSize)
{
const auto &OldCoeffs = oldparams->Coeffs;
const ALfloat oldGain{oldparams->Gain};
const ALfloat oldGainStep{-oldGain / static_cast<ALfloat>(BufferSize)};
const auto &NewCoeffs = *newparams->Coeffs;
const ALfloat newGainStep{newparams->GainStep};
ALfloat stepcount{0.0f};
ASSUME(OutPos >= 0);
ASSUME(IrSize >= 4);
ASSUME(BufferSize > 0);
ALsizei OldDelay[2]{
HRTF_HISTORY_LENGTH - oldparams->Delay[0],
HRTF_HISTORY_LENGTH - oldparams->Delay[1] };
ASSUME(OldDelay[0] >= 0 && OldDelay[1] >= 0);
ALsizei NewDelay[2]{
HRTF_HISTORY_LENGTH - newparams->Delay[0],
HRTF_HISTORY_LENGTH - newparams->Delay[1] };
ASSUME(NewDelay[0] >= 0 && NewDelay[1] >= 0);
for(ALsizei i{0};i < BufferSize;++i)
{
ALfloat g{oldGain + oldGainStep*stepcount};
ALfloat left{data[OldDelay[0]++] * g};
ALfloat right{data[OldDelay[1]++] * g};
ApplyCoeffs(i, AccumSamples+i, IrSize, OldCoeffs, left, right);
g = newGainStep*stepcount;
left = data[NewDelay[0]++] * g;
right = data[NewDelay[1]++] * g;
ApplyCoeffs(i, AccumSamples+i, IrSize, NewCoeffs, left, right);
stepcount += 1.0f;
}
for(ALsizei i{0};i < BufferSize;++i)
LeftOut[OutPos+i] += AccumSamples[i][0];
for(ALsizei i{0};i < BufferSize;++i)
RightOut[OutPos+i] += AccumSamples[i][1];
newparams->Gain = newGainStep*stepcount;
}
template<ApplyCoeffsT &ApplyCoeffs>
inline void MixDirectHrtfBase(ALfloat *RESTRICT LeftOut, ALfloat *RESTRICT RightOut,
const ALfloat (*data)[BUFFERSIZE], float2 *RESTRICT AccumSamples, DirectHrtfState *State,
const ALsizei NumChans, const ALsizei BufferSize)
{
ASSUME(NumChans > 0);
ASSUME(BufferSize > 0);
const ALsizei IrSize{State->IrSize};
ASSUME(IrSize >= 4);
for(ALsizei c{0};c < NumChans;++c)
{
const ALfloat (&input)[BUFFERSIZE] = data[c];
const auto &Coeffs = State->Chan[c].Coeffs;
auto accum_iter = std::copy_n(State->Chan[c].Values.begin(),
State->Chan[c].Values.size(), AccumSamples);
std::fill_n(accum_iter, BufferSize, float2{});
for(ALsizei i{0};i < BufferSize;++i)
{
const ALfloat insample{input[i]};
ApplyCoeffs(i, AccumSamples+i, IrSize, Coeffs, insample, insample);
}
for(ALsizei i{0};i < BufferSize;++i)
LeftOut[i] += AccumSamples[i][0];
for(ALsizei i{0};i < BufferSize;++i)
RightOut[i] += AccumSamples[i][1];
std::copy_n(AccumSamples + BufferSize, State->Chan[c].Values.size(),
State->Chan[c].Values.begin());
}
}
#endif /* MIXER_HRTFBASE_H */