#ifndef CORE_HRTF_H #define CORE_HRTF_H #include #include #include #include #include #include #include "almalloc.h" #include "alspan.h" #include "atomic.h" #include "ambidefs.h" #include "bufferline.h" #include "flexarray.h" #include "intrusive_ptr.h" #include "mixer/hrtfdefs.h" struct HrtfStore { std::atomic mRef; uint mSampleRate : 24; uint mIrSize : 8; struct Field { float distance; ubyte evCount; }; /* NOTE: Fields are stored *backwards*. field[0] is the farthest field, and * field[fdCount-1] is the nearest. */ al::span mFields; struct Elevation { ushort azCount; ushort irOffset; }; Elevation *mElev; const HrirArray *mCoeffs; const ubyte2 *mDelays; void getCoeffs(float elevation, float azimuth, float distance, float spread, HrirArray &coeffs, const al::span delays); void add_ref(); void dec_ref(); DEF_PLACE_NEWDEL }; using HrtfStorePtr = al::intrusive_ptr; struct EvRadians { float value; }; struct AzRadians { float value; }; struct AngularPoint { EvRadians Elev; AzRadians Azim; }; struct DirectHrtfState { std::array mTemp; /* HRTF filter state for dry buffer content */ uint mIrSize{0}; al::FlexArray mChannels; DirectHrtfState(size_t numchans) : mChannels{numchans} { } /** * 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 build(const HrtfStore *Hrtf, const uint irSize, const bool perHrirMin, const al::span AmbiPoints, const al::span> AmbiMatrix, const float XOverFreq, const al::span AmbiOrderHFGain); static std::unique_ptr Create(size_t num_chans); DEF_FAM_NEWDEL(DirectHrtfState, mChannels) }; std::vector EnumerateHrtf(std::optional pathopt); HrtfStorePtr GetLoadedHrtf(const std::string &name, const uint devrate); #endif /* CORE_HRTF_H */