#ifndef ALC_HRTF_H #define ALC_HRTF_H #include #include #include #include #include "AL/al.h" #include "almalloc.h" #include "alspan.h" #include "ambidefs.h" #include "atomic.h" #include "intrusive_ptr.h" #include "vector.h" #define HRTF_HISTORY_BITS (6) #define HRTF_HISTORY_LENGTH (1<; using HrirArray = std::array; using ubyte2 = std::array; struct HrtfStore { RefCount mRef; ALuint sampleRate; ALuint irSize; struct Field { float distance; ALubyte evCount; }; /* NOTE: Fields are stored *backwards*. field[0] is the farthest field, and * field[fdCount-1] is the nearest. */ ALuint fdCount; const Field *field; struct Elevation { ALushort azCount; ALushort irOffset; }; Elevation *elev; const HrirArray *coeffs; const ubyte2 *delays; void add_ref(); void release(); DEF_PLACE_NEWDEL() }; using HrtfStorePtr = al::intrusive_ptr; struct HrtfFilter { alignas(16) HrirArray Coeffs; std::array Delay; float Gain; }; struct DirectHrtfState { /* HRTF filter state for dry buffer content */ ALuint IrSize{0}; al::FlexArray Coeffs; DirectHrtfState(size_t numchans) : Coeffs{numchans} { } static std::unique_ptr Create(size_t num_chans); DEF_FAM_NEWDEL(DirectHrtfState, Coeffs) }; struct EvRadians { float value; }; struct AzRadians { float value; }; struct AngularPoint { EvRadians Elev; AzRadians Azim; }; al::vector EnumerateHrtf(const char *devname); HrtfStorePtr GetLoadedHrtf(const std::string &name, const char *devname, const ALuint devrate); void GetHrtfCoeffs(const HrtfStore *Hrtf, float elevation, float azimuth, float distance, float spread, HrirArray &coeffs, const al::span delays); /** * 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. */ void BuildBFormatHrtf(const HrtfStore *Hrtf, DirectHrtfState *state, const al::span AmbiPoints, const float (*AmbiMatrix)[MAX_AMBI_CHANNELS], const al::span AmbiOrderHFGain); #endif /* ALC_HRTF_H */