#ifndef ALC_HRTF_H #define ALC_HRTF_H #include #include #include #include "AL/al.h" #include "AL/alc.h" #include "vector.h" #include "almalloc.h" #define HRTF_HISTORY_BITS (6) #define HRTF_HISTORY_LENGTH (1<; template using HrirArray = std::array,HRIR_LENGTH>; struct HrtfState { alignas(16) std::array History; alignas(16) HrirArray Values; }; struct HrtfParams { alignas(16) HrirArray Coeffs; ALsizei Delay[2]; ALfloat Gain; }; struct DirectHrtfState { /* HRTF filter state for dry buffer content */ ALsizei IrSize{0}; struct ChanData { alignas(16) HrirArray Values; alignas(16) HrirArray Coeffs; }; al::FlexArray Chan; DirectHrtfState(size_t numchans) : Chan{numchans} { } DirectHrtfState(const DirectHrtfState&) = delete; DirectHrtfState& operator=(const DirectHrtfState&) = delete; static std::unique_ptr Create(size_t num_chans); static constexpr size_t Sizeof(size_t numchans) noexcept { return al::FlexArray::Sizeof(numchans, offsetof(DirectHrtfState, Chan)); } DEF_PLACE_NEWDEL() }; struct AngularPoint { ALfloat Elev; ALfloat Azim; }; al::vector EnumerateHrtf(const char *devname); HrtfEntry *GetLoadedHrtf(HrtfHandle *handle); void GetHrtfCoeffs(const HrtfEntry *Hrtf, ALfloat elevation, ALfloat azimuth, ALfloat distance, ALfloat spread, HrirArray &coeffs, ALsizei (&delays)[2]); /** * Produces HRTF filter coefficients for decoding B-Format, given a set of * virtual speaker positions, a matching decoding matrix, and per-order high- * frequency gains for the decoder. The calculated impulse responses are * ordered and scaled according to the matrix input. Note the specified virtual * positions should be in degrees, not radians! */ void BuildBFormatHrtf(const HrtfEntry *Hrtf, DirectHrtfState *state, const ALsizei NumChannels, const AngularPoint *AmbiPoints, const ALfloat (*RESTRICT AmbiMatrix)[MAX_AMBI_CHANNELS], const ALsizei AmbiCount, const ALfloat *RESTRICT AmbiOrderHFGain); #endif /* ALC_HRTF_H */