hrtf.cpp 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462
  1. #include "config.h"
  2. #include "hrtf.h"
  3. #include <algorithm>
  4. #include <array>
  5. #include <cassert>
  6. #include <cctype>
  7. #include <cmath>
  8. #include <cstddef>
  9. #include <cstdint>
  10. #include <cstdio>
  11. #include <cstring>
  12. #include <fstream>
  13. #include <iterator>
  14. #include <memory>
  15. #include <mutex>
  16. #include <numeric>
  17. #include <optional>
  18. #include <tuple>
  19. #include <type_traits>
  20. #include <utility>
  21. #include <vector>
  22. #include "albit.h"
  23. #include "almalloc.h"
  24. #include "alnumbers.h"
  25. #include "alnumeric.h"
  26. #include "alspan.h"
  27. #include "alstring.h"
  28. #include "ambidefs.h"
  29. #include "filesystem.h"
  30. #include "filters/splitter.h"
  31. #include "fmt/core.h"
  32. #include "helpers.h"
  33. #include "logging.h"
  34. #include "mixer/hrtfdefs.h"
  35. #include "opthelpers.h"
  36. #include "polyphase_resampler.h"
  37. namespace {
  38. using namespace std::string_view_literals;
  39. struct HrtfEntry {
  40. std::string mDispName;
  41. std::string mFilename;
  42. template<typename T, typename U>
  43. HrtfEntry(T&& dispname, U&& fname)
  44. : mDispName{std::forward<T>(dispname)}, mFilename{std::forward<U>(fname)}
  45. { }
  46. /* GCC warns when it tries to inline this. */
  47. ~HrtfEntry();
  48. };
  49. HrtfEntry::~HrtfEntry() = default;
  50. struct LoadedHrtf {
  51. std::string mFilename;
  52. uint mSampleRate{};
  53. std::unique_ptr<HrtfStore> mEntry;
  54. template<typename T, typename U>
  55. LoadedHrtf(T&& name, uint srate, U&& entry)
  56. : mFilename{std::forward<T>(name)}, mSampleRate{srate}, mEntry{std::forward<U>(entry)}
  57. { }
  58. LoadedHrtf(LoadedHrtf&&) = default;
  59. /* GCC warns when it tries to inline this. */
  60. ~LoadedHrtf();
  61. LoadedHrtf& operator=(LoadedHrtf&&) = default;
  62. };
  63. LoadedHrtf::~LoadedHrtf() = default;
  64. /* Data set limits must be the same as or more flexible than those defined in
  65. * the makemhr utility.
  66. */
  67. constexpr uint MinFdCount{1};
  68. constexpr uint MaxFdCount{16};
  69. constexpr uint MinFdDistance{50};
  70. constexpr uint MaxFdDistance{2500};
  71. constexpr uint MinEvCount{5};
  72. constexpr uint MaxEvCount{181};
  73. constexpr uint MinAzCount{1};
  74. constexpr uint MaxAzCount{255};
  75. constexpr uint MaxHrirDelay{HrtfHistoryLength - 1};
  76. constexpr uint HrirDelayFracBits{2};
  77. constexpr uint HrirDelayFracOne{1 << HrirDelayFracBits};
  78. constexpr uint HrirDelayFracHalf{HrirDelayFracOne >> 1};
  79. /* The sample rate is stored as a 24-bit integer, so 16MHz is the largest
  80. * supported.
  81. */
  82. constexpr uint MaxSampleRate{0xff'ff'ff};
  83. static_assert(MaxHrirDelay*HrirDelayFracOne < 256, "MAX_HRIR_DELAY or DELAY_FRAC too large");
  84. constexpr auto HeaderMarkerSize = 8_uz;
  85. [[nodiscard]] constexpr auto GetMarker00Name() noexcept { return "MinPHR00"sv; }
  86. [[nodiscard]] constexpr auto GetMarker01Name() noexcept { return "MinPHR01"sv; }
  87. [[nodiscard]] constexpr auto GetMarker02Name() noexcept { return "MinPHR02"sv; }
  88. [[nodiscard]] constexpr auto GetMarker03Name() noexcept { return "MinPHR03"sv; }
  89. static_assert(GetMarker00Name().size() == HeaderMarkerSize);
  90. static_assert(GetMarker01Name().size() == HeaderMarkerSize);
  91. static_assert(GetMarker02Name().size() == HeaderMarkerSize);
  92. static_assert(GetMarker03Name().size() == HeaderMarkerSize);
  93. /* First value for pass-through coefficients (remaining are 0), used for omni-
  94. * directional sounds. */
  95. constexpr auto PassthruCoeff = static_cast<float>(1.0/al::numbers::sqrt2);
  96. std::mutex LoadedHrtfLock;
  97. std::vector<LoadedHrtf> LoadedHrtfs;
  98. std::mutex EnumeratedHrtfLock;
  99. std::vector<HrtfEntry> EnumeratedHrtfs;
  100. /* NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic)
  101. * To access a memory buffer through the std::istream interface, a custom
  102. * std::streambuf implementation is needed that has to do pointer manipulation
  103. * for seeking. With C++23, we may be able to use std::spanstream instead.
  104. */
  105. class databuf final : public std::streambuf {
  106. int_type underflow() override
  107. { return traits_type::eof(); }
  108. pos_type seekoff(off_type offset, std::ios_base::seekdir whence, std::ios_base::openmode mode) override
  109. {
  110. if((mode&std::ios_base::out) || !(mode&std::ios_base::in))
  111. return traits_type::eof();
  112. switch(whence)
  113. {
  114. case std::ios_base::beg:
  115. if(offset < 0 || offset > egptr()-eback())
  116. return traits_type::eof();
  117. setg(eback(), eback()+offset, egptr());
  118. break;
  119. case std::ios_base::cur:
  120. if((offset >= 0 && offset > egptr()-gptr()) ||
  121. (offset < 0 && -offset > gptr()-eback()))
  122. return traits_type::eof();
  123. setg(eback(), gptr()+offset, egptr());
  124. break;
  125. case std::ios_base::end:
  126. if(offset > 0 || -offset > egptr()-eback())
  127. return traits_type::eof();
  128. setg(eback(), egptr()+offset, egptr());
  129. break;
  130. default:
  131. return traits_type::eof();
  132. }
  133. return gptr() - eback();
  134. }
  135. pos_type seekpos(pos_type pos, std::ios_base::openmode mode) override
  136. {
  137. // Simplified version of seekoff
  138. if((mode&std::ios_base::out) || !(mode&std::ios_base::in))
  139. return traits_type::eof();
  140. if(pos < 0 || pos > egptr()-eback())
  141. return traits_type::eof();
  142. setg(eback(), eback()+static_cast<size_t>(pos), egptr());
  143. return pos;
  144. }
  145. public:
  146. explicit databuf(const al::span<char_type> data) noexcept
  147. {
  148. setg(data.data(), data.data(), al::to_address(data.end()));
  149. }
  150. };
  151. /* NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic) */
  152. class idstream final : public std::istream {
  153. databuf mStreamBuf;
  154. public:
  155. explicit idstream(const al::span<char_type> data) : std::istream{nullptr}, mStreamBuf{data}
  156. { init(&mStreamBuf); }
  157. };
  158. struct IdxBlend { uint idx; float blend; };
  159. /* Calculate the elevation index given the polar elevation in radians. This
  160. * will return an index between 0 and (evcount - 1).
  161. */
  162. IdxBlend CalcEvIndex(uint evcount, float ev)
  163. {
  164. ev = (al::numbers::inv_pi_v<float>*ev + 0.5f) * static_cast<float>(evcount-1);
  165. const auto idx = float2uint(ev);
  166. return IdxBlend{std::min(idx, evcount-1u), ev-static_cast<float>(idx)};
  167. }
  168. /* Calculate the azimuth index given the polar azimuth in radians. This will
  169. * return an index between 0 and (azcount - 1).
  170. */
  171. IdxBlend CalcAzIndex(uint azcount, float az)
  172. {
  173. az = (al::numbers::inv_pi_v<float>*0.5f*az + 1.0f) * static_cast<float>(azcount);
  174. const auto idx = float2uint(az);
  175. return IdxBlend{idx%azcount, az-static_cast<float>(idx)};
  176. }
  177. } // namespace
  178. /* Calculates static HRIR coefficients and delays for the given polar elevation
  179. * and azimuth in radians. The coefficients are normalized.
  180. */
  181. void HrtfStore::getCoeffs(float elevation, float azimuth, float distance, float spread,
  182. const HrirSpan coeffs, const al::span<uint,2> delays) const
  183. {
  184. const float dirfact{1.0f - (al::numbers::inv_pi_v<float>/2.0f * spread)};
  185. size_t ebase{0};
  186. auto match_field = [&ebase,distance](const Field &field) noexcept -> bool
  187. {
  188. if(distance >= field.distance)
  189. return true;
  190. ebase += field.evCount;
  191. return false;
  192. };
  193. auto field = std::find_if(mFields.begin(), mFields.end()-1, match_field);
  194. /* Calculate the elevation indices. */
  195. const auto elev0 = CalcEvIndex(field->evCount, elevation);
  196. const size_t elev1_idx{std::min(elev0.idx+1u, field->evCount-1u)};
  197. const size_t ir0offset{mElev[ebase + elev0.idx].irOffset};
  198. const size_t ir1offset{mElev[ebase + elev1_idx].irOffset};
  199. /* Calculate azimuth indices. */
  200. const auto az0 = CalcAzIndex(mElev[ebase + elev0.idx].azCount, azimuth);
  201. const auto az1 = CalcAzIndex(mElev[ebase + elev1_idx].azCount, azimuth);
  202. /* Calculate the HRIR indices to blend. */
  203. const std::array<size_t,4> idx{{
  204. ir0offset + az0.idx,
  205. ir0offset + ((az0.idx+1) % mElev[ebase + elev0.idx].azCount),
  206. ir1offset + az1.idx,
  207. ir1offset + ((az1.idx+1) % mElev[ebase + elev1_idx].azCount)
  208. }};
  209. /* Calculate bilinear blending weights, attenuated according to the
  210. * directional panning factor.
  211. */
  212. const std::array<float,4> blend{{
  213. (1.0f-elev0.blend) * (1.0f-az0.blend) * dirfact,
  214. (1.0f-elev0.blend) * ( az0.blend) * dirfact,
  215. ( elev0.blend) * (1.0f-az1.blend) * dirfact,
  216. ( elev0.blend) * ( az1.blend) * dirfact
  217. }};
  218. /* Calculate the blended HRIR delays. */
  219. float d{float(mDelays[idx[0]][0])*blend[0] + float(mDelays[idx[1]][0])*blend[1]
  220. + float(mDelays[idx[2]][0])*blend[2] + float(mDelays[idx[3]][0])*blend[3]};
  221. delays[0] = fastf2u(d * float{1.0f/HrirDelayFracOne});
  222. d = float(mDelays[idx[0]][1])*blend[0] + float(mDelays[idx[1]][1])*blend[1]
  223. + float(mDelays[idx[2]][1])*blend[2] + float(mDelays[idx[3]][1])*blend[3];
  224. delays[1] = fastf2u(d * float{1.0f/HrirDelayFracOne});
  225. /* Calculate the blended HRIR coefficients. */
  226. auto coeffout = coeffs.begin();
  227. coeffout[0][0] = PassthruCoeff * (1.0f-dirfact);
  228. coeffout[0][1] = PassthruCoeff * (1.0f-dirfact);
  229. std::fill_n(coeffout+1, size_t{HrirLength-1}, std::array{0.0f, 0.0f});
  230. for(size_t c{0};c < 4;c++)
  231. {
  232. const float mult{blend[c]};
  233. auto blend_coeffs = [mult](const float2 &src, const float2 &coeff) noexcept -> float2
  234. { return float2{{src[0]*mult + coeff[0], src[1]*mult + coeff[1]}}; };
  235. std::transform(mCoeffs[idx[c]].cbegin(), mCoeffs[idx[c]].cend(), coeffout, coeffout,
  236. blend_coeffs);
  237. }
  238. }
  239. std::unique_ptr<DirectHrtfState> DirectHrtfState::Create(size_t num_chans)
  240. { return std::unique_ptr<DirectHrtfState>{new(FamCount(num_chans)) DirectHrtfState{num_chans}}; }
  241. void DirectHrtfState::build(const HrtfStore *Hrtf, const uint irSize, const bool perHrirMin,
  242. const al::span<const AngularPoint> AmbiPoints,
  243. const al::span<const std::array<float,MaxAmbiChannels>> AmbiMatrix,
  244. const float XOverFreq, const al::span<const float,MaxAmbiOrder+1> AmbiOrderHFGain)
  245. {
  246. using double2 = std::array<double,2>;
  247. struct ImpulseResponse {
  248. const ConstHrirSpan hrir;
  249. uint ldelay, rdelay;
  250. };
  251. const double xover_norm{double{XOverFreq} / Hrtf->mSampleRate};
  252. mChannels[0].mSplitter.init(static_cast<float>(xover_norm));
  253. mChannels[0].mHfScale = AmbiOrderHFGain[0];
  254. for(size_t i{1};i < mChannels.size();++i)
  255. {
  256. const size_t order{AmbiIndex::OrderFromChannel[i]};
  257. mChannels[i].mSplitter = mChannels[0].mSplitter;
  258. mChannels[i].mHfScale = AmbiOrderHFGain[order];
  259. }
  260. uint min_delay{HrtfHistoryLength*HrirDelayFracOne}, max_delay{0};
  261. std::vector<ImpulseResponse> impres; impres.reserve(AmbiPoints.size());
  262. auto calc_res = [Hrtf,&max_delay,&min_delay](const AngularPoint &pt) -> ImpulseResponse
  263. {
  264. auto &field = Hrtf->mFields[0];
  265. const auto elev0 = CalcEvIndex(field.evCount, pt.Elev.value);
  266. const size_t elev1_idx{std::min(elev0.idx+1u, field.evCount-1u)};
  267. const size_t ir0offset{Hrtf->mElev[elev0.idx].irOffset};
  268. const size_t ir1offset{Hrtf->mElev[elev1_idx].irOffset};
  269. const auto az0 = CalcAzIndex(Hrtf->mElev[elev0.idx].azCount, pt.Azim.value);
  270. const auto az1 = CalcAzIndex(Hrtf->mElev[elev1_idx].azCount, pt.Azim.value);
  271. const std::array<size_t,4> idx{
  272. ir0offset + az0.idx,
  273. ir0offset + ((az0.idx+1) % Hrtf->mElev[elev0.idx].azCount),
  274. ir1offset + az1.idx,
  275. ir1offset + ((az1.idx+1) % Hrtf->mElev[elev1_idx].azCount)
  276. };
  277. /* The largest blend factor serves as the closest HRIR. */
  278. const size_t irOffset{idx[(elev0.blend >= 0.5f)*2 + (az1.blend >= 0.5f)]};
  279. ImpulseResponse res{Hrtf->mCoeffs[irOffset],
  280. Hrtf->mDelays[irOffset][0], Hrtf->mDelays[irOffset][1]};
  281. min_delay = std::min(min_delay, std::min(res.ldelay, res.rdelay));
  282. max_delay = std::max(max_delay, std::max(res.ldelay, res.rdelay));
  283. return res;
  284. };
  285. std::transform(AmbiPoints.begin(), AmbiPoints.end(), std::back_inserter(impres), calc_res);
  286. auto hrir_delay_round = [](const uint d) noexcept -> uint
  287. { return (d+HrirDelayFracHalf) >> HrirDelayFracBits; };
  288. TRACE("Min delay: {:.2f}, max delay: {:.2f}, FIR length: {}",
  289. min_delay/double{HrirDelayFracOne}, max_delay/double{HrirDelayFracOne}, irSize);
  290. auto tmpres = std::vector<std::array<double2,HrirLength>>(mChannels.size());
  291. max_delay = 0;
  292. auto matrixline = AmbiMatrix.cbegin();
  293. for(auto &impulse : impres)
  294. {
  295. const ConstHrirSpan hrir{impulse.hrir};
  296. const uint base_delay{perHrirMin ? std::min(impulse.ldelay, impulse.rdelay) : min_delay};
  297. const uint ldelay{hrir_delay_round(impulse.ldelay - base_delay)};
  298. const uint rdelay{hrir_delay_round(impulse.rdelay - base_delay)};
  299. max_delay = std::max(max_delay, std::max(impulse.ldelay, impulse.rdelay) - base_delay);
  300. auto gains = matrixline->cbegin();
  301. ++matrixline;
  302. for(auto &result : tmpres)
  303. {
  304. const double mult{*(gains++)};
  305. const size_t numirs{HrirLength - std::max(ldelay, rdelay)};
  306. size_t lidx{ldelay}, ridx{rdelay};
  307. for(size_t j{0};j < numirs;++j)
  308. {
  309. result[lidx++][0] += hrir[j][0] * mult;
  310. result[ridx++][1] += hrir[j][1] * mult;
  311. }
  312. }
  313. }
  314. impres.clear();
  315. auto output = mChannels.begin();
  316. for(auto &result : tmpres)
  317. {
  318. auto cast_array2 = [](const double2 &in) noexcept -> float2
  319. { return float2{{static_cast<float>(in[0]), static_cast<float>(in[1])}}; };
  320. std::transform(result.cbegin(), result.cend(), output->mCoeffs.begin(), cast_array2);
  321. ++output;
  322. }
  323. tmpres.clear();
  324. const uint max_length{std::min(hrir_delay_round(max_delay) + irSize, HrirLength)};
  325. TRACE("New max delay: {:.2f}, FIR length: {}", max_delay/double{HrirDelayFracOne},
  326. max_length);
  327. mIrSize = max_length;
  328. }
  329. namespace {
  330. std::unique_ptr<HrtfStore> CreateHrtfStore(uint rate, uint8_t irSize,
  331. const al::span<const HrtfStore::Field> fields,
  332. const al::span<const HrtfStore::Elevation> elevs, const HrirArray *coeffs,
  333. const ubyte2 *delays)
  334. {
  335. static_assert(alignof(HrtfStore::Field) <= alignof(HrtfStore));
  336. static_assert(alignof(HrtfStore::Elevation) <= alignof(HrtfStore));
  337. static_assert(16 <= alignof(HrtfStore));
  338. if(rate > MaxSampleRate)
  339. throw std::runtime_error{"Sample rate is too large (max: "+std::to_string(MaxSampleRate)+"hz)"};
  340. const size_t irCount{size_t{elevs.back().azCount} + elevs.back().irOffset};
  341. size_t total{sizeof(HrtfStore)};
  342. total = RoundUp(total, alignof(HrtfStore::Field)); /* Align for field infos */
  343. total += sizeof(std::declval<HrtfStore&>().mFields[0])*fields.size();
  344. total = RoundUp(total, alignof(HrtfStore::Elevation)); /* Align for elevation infos */
  345. total += sizeof(std::declval<HrtfStore&>().mElev[0])*elevs.size();
  346. total = RoundUp(total, 16); /* Align for coefficients using SIMD */
  347. total += sizeof(std::declval<HrtfStore&>().mCoeffs[0])*irCount;
  348. total += sizeof(std::declval<HrtfStore&>().mDelays[0])*irCount;
  349. static constexpr auto AlignVal = std::align_val_t{alignof(HrtfStore)};
  350. std::unique_ptr<HrtfStore> Hrtf{::new(::operator new[](total, AlignVal)) HrtfStore{}};
  351. Hrtf->mRef.store(1u, std::memory_order_relaxed);
  352. Hrtf->mSampleRate = rate & 0xff'ff'ff;
  353. Hrtf->mIrSize = irSize;
  354. /* Set up pointers to storage following the main HRTF struct. */
  355. auto storage = al::span{reinterpret_cast<char*>(Hrtf.get()), total};
  356. auto base = storage.begin();
  357. ptrdiff_t offset{sizeof(HrtfStore)};
  358. offset = RoundUp(offset, alignof(HrtfStore::Field)); /* Align for field infos */
  359. auto field_ = al::span{reinterpret_cast<HrtfStore::Field*>(al::to_address(base + offset)),
  360. fields.size()};
  361. offset += ptrdiff_t(sizeof(field_[0])*fields.size());
  362. offset = RoundUp(offset, alignof(HrtfStore::Elevation)); /* Align for elevation infos */
  363. auto elev_ = al::span{reinterpret_cast<HrtfStore::Elevation*>(al::to_address(base + offset)),
  364. elevs.size()};
  365. offset += ptrdiff_t(sizeof(elev_[0])*elevs.size());
  366. offset = RoundUp(offset, 16); /* Align for coefficients using SIMD */
  367. auto coeffs_ = al::span{reinterpret_cast<HrirArray*>(al::to_address(base + offset)), irCount};
  368. offset += ptrdiff_t(sizeof(coeffs_[0])*irCount);
  369. auto delays_ = al::span{reinterpret_cast<ubyte2*>(al::to_address(base + offset)), irCount};
  370. offset += ptrdiff_t(sizeof(delays_[0])*irCount);
  371. if(size_t(offset) != total)
  372. throw std::runtime_error{"HrtfStore allocation size mismatch"};
  373. /* Copy input data to storage. */
  374. std::uninitialized_copy(fields.cbegin(), fields.cend(), field_.begin());
  375. std::uninitialized_copy(elevs.cbegin(), elevs.cend(), elev_.begin());
  376. std::uninitialized_copy_n(coeffs, irCount, coeffs_.begin());
  377. std::uninitialized_copy_n(delays, irCount, delays_.begin());
  378. /* Finally, assign the storage pointers. */
  379. Hrtf->mFields = field_;
  380. Hrtf->mElev = elev_;
  381. Hrtf->mCoeffs = coeffs_;
  382. Hrtf->mDelays = delays_;
  383. return Hrtf;
  384. }
  385. void MirrorLeftHrirs(const al::span<const HrtfStore::Elevation> elevs, al::span<HrirArray> coeffs,
  386. al::span<ubyte2> delays)
  387. {
  388. for(const auto &elev : elevs)
  389. {
  390. const ushort evoffset{elev.irOffset};
  391. const ushort azcount{elev.azCount};
  392. for(size_t j{0};j < azcount;j++)
  393. {
  394. const size_t lidx{evoffset + j};
  395. const size_t ridx{evoffset + ((azcount-j) % azcount)};
  396. const size_t irSize{coeffs[ridx].size()};
  397. for(size_t k{0};k < irSize;k++)
  398. coeffs[ridx][k][1] = coeffs[lidx][k][0];
  399. delays[ridx][1] = delays[lidx][0];
  400. }
  401. }
  402. }
  403. template<size_t num_bits, typename T>
  404. constexpr std::enable_if_t<std::is_signed<T>::value && num_bits < sizeof(T)*8,
  405. T> fixsign(T value) noexcept
  406. {
  407. constexpr auto signbit = static_cast<T>(1u << (num_bits-1));
  408. return static_cast<T>((value^signbit) - signbit);
  409. }
  410. template<size_t num_bits, typename T>
  411. constexpr std::enable_if_t<!std::is_signed<T>::value || num_bits == sizeof(T)*8,
  412. T> fixsign(T value) noexcept
  413. { return value; }
  414. template<typename T, size_t num_bits=sizeof(T)*8>
  415. inline std::enable_if_t<al::endian::native == al::endian::little,
  416. T> readle(std::istream &data)
  417. {
  418. static_assert((num_bits&7) == 0, "num_bits must be a multiple of 8");
  419. static_assert(num_bits <= sizeof(T)*8, "num_bits is too large for the type");
  420. alignas(T) std::array<char,sizeof(T)> ret{};
  421. if(!data.read(ret.data(), num_bits/8))
  422. return static_cast<T>(EOF);
  423. return fixsign<num_bits>(al::bit_cast<T>(ret));
  424. }
  425. template<typename T, size_t num_bits=sizeof(T)*8>
  426. inline std::enable_if_t<al::endian::native == al::endian::big,
  427. T> readle(std::istream &data)
  428. {
  429. static_assert((num_bits&7) == 0, "num_bits must be a multiple of 8");
  430. static_assert(num_bits <= sizeof(T)*8, "num_bits is too large for the type");
  431. alignas(T) std::array<char,sizeof(T)> ret{};
  432. if(!data.read(ret.data(), num_bits/8))
  433. return static_cast<T>(EOF);
  434. std::reverse(ret.begin(), ret.end());
  435. return fixsign<num_bits>(al::bit_cast<T>(ret));
  436. }
  437. template<>
  438. inline uint8_t readle<uint8_t,8>(std::istream &data)
  439. { return static_cast<uint8_t>(data.get()); }
  440. std::unique_ptr<HrtfStore> LoadHrtf00(std::istream &data)
  441. {
  442. uint rate{readle<uint32_t>(data)};
  443. ushort irCount{readle<uint16_t>(data)};
  444. ushort irSize{readle<uint16_t>(data)};
  445. ubyte evCount{readle<uint8_t>(data)};
  446. if(!data || data.eof())
  447. throw std::runtime_error{"Premature end of file"};
  448. if(irSize < MinIrLength || irSize > HrirLength)
  449. {
  450. ERR("Unsupported HRIR size, irSize={} ({} to {})", irSize, MinIrLength, HrirLength);
  451. return nullptr;
  452. }
  453. if(evCount < MinEvCount || evCount > MaxEvCount)
  454. {
  455. ERR("Unsupported elevation count: evCount={} ({} to {})", evCount, MinEvCount,
  456. MaxEvCount);
  457. return nullptr;
  458. }
  459. auto elevs = std::vector<HrtfStore::Elevation>(evCount);
  460. for(auto &elev : elevs)
  461. elev.irOffset = readle<uint16_t>(data);
  462. if(!data || data.eof())
  463. throw std::runtime_error{"Premature end of file"};
  464. for(size_t i{1};i < evCount;i++)
  465. {
  466. if(elevs[i].irOffset <= elevs[i-1].irOffset)
  467. {
  468. ERR("Invalid evOffset: evOffset[{}]={} (last={})", i, elevs[i].irOffset,
  469. elevs[i-1].irOffset);
  470. return nullptr;
  471. }
  472. }
  473. if(irCount <= elevs.back().irOffset)
  474. {
  475. ERR("Invalid evOffset: evOffset[{}]={} (irCount={})", elevs.size()-1,
  476. elevs.back().irOffset, irCount);
  477. return nullptr;
  478. }
  479. for(size_t i{1};i < evCount;i++)
  480. {
  481. elevs[i-1].azCount = static_cast<ushort>(elevs[i].irOffset - elevs[i-1].irOffset);
  482. if(elevs[i-1].azCount < MinAzCount || elevs[i-1].azCount > MaxAzCount)
  483. {
  484. ERR("Unsupported azimuth count: azCount[{}]={} ({} to {})", i-1, elevs[i-1].azCount,
  485. MinAzCount, MaxAzCount);
  486. return nullptr;
  487. }
  488. }
  489. elevs.back().azCount = static_cast<ushort>(irCount - elevs.back().irOffset);
  490. if(elevs.back().azCount < MinAzCount || elevs.back().azCount > MaxAzCount)
  491. {
  492. ERR("Unsupported azimuth count: azCount[{}]={} ({} to {})", elevs.size()-1,
  493. elevs.back().azCount, MinAzCount, MaxAzCount);
  494. return nullptr;
  495. }
  496. auto coeffs = std::vector<HrirArray>(irCount, HrirArray{});
  497. auto delays = std::vector<ubyte2>(irCount);
  498. for(auto &hrir : coeffs)
  499. {
  500. for(auto &val : al::span{hrir}.first(irSize))
  501. val[0] = float(readle<int16_t>(data)) / 32768.0f;
  502. }
  503. for(auto &val : delays)
  504. val[0] = readle<uint8_t>(data);
  505. if(!data || data.eof())
  506. throw std::runtime_error{"Premature end of file"};
  507. for(size_t i{0};i < irCount;i++)
  508. {
  509. if(delays[i][0] > MaxHrirDelay)
  510. {
  511. ERR("Invalid delays[{}]: {} ({})", i, delays[i][0], MaxHrirDelay);
  512. return nullptr;
  513. }
  514. delays[i][0] <<= HrirDelayFracBits;
  515. }
  516. /* Mirror the left ear responses to the right ear. */
  517. MirrorLeftHrirs(elevs, coeffs, delays);
  518. const std::array field{HrtfStore::Field{0.0f, evCount}};
  519. return CreateHrtfStore(rate, static_cast<uint8_t>(irSize), field, elevs, coeffs.data(),
  520. delays.data());
  521. }
  522. std::unique_ptr<HrtfStore> LoadHrtf01(std::istream &data)
  523. {
  524. uint rate{readle<uint32_t>(data)};
  525. uint8_t irSize{readle<uint8_t>(data)};
  526. ubyte evCount{readle<uint8_t>(data)};
  527. if(!data || data.eof())
  528. throw std::runtime_error{"Premature end of file"};
  529. if(irSize < MinIrLength || irSize > HrirLength)
  530. {
  531. ERR("Unsupported HRIR size, irSize={} ({} to {})", irSize, MinIrLength, HrirLength);
  532. return nullptr;
  533. }
  534. if(evCount < MinEvCount || evCount > MaxEvCount)
  535. {
  536. ERR("Unsupported elevation count: evCount={} ({} to {})", evCount, MinEvCount,
  537. MaxEvCount);
  538. return nullptr;
  539. }
  540. auto elevs = std::vector<HrtfStore::Elevation>(evCount);
  541. for(auto &elev : elevs)
  542. elev.azCount = readle<uint8_t>(data);
  543. if(!data || data.eof())
  544. throw std::runtime_error{"Premature end of file"};
  545. for(size_t i{0};i < evCount;++i)
  546. {
  547. if(elevs[i].azCount < MinAzCount || elevs[i].azCount > MaxAzCount)
  548. {
  549. ERR("Unsupported azimuth count: azCount[{}]={} ({} to {})", i, elevs[i].azCount,
  550. MinAzCount, MaxAzCount);
  551. return nullptr;
  552. }
  553. }
  554. elevs[0].irOffset = 0;
  555. for(size_t i{1};i < evCount;i++)
  556. elevs[i].irOffset = static_cast<ushort>(elevs[i-1].irOffset + elevs[i-1].azCount);
  557. const ushort irCount{static_cast<ushort>(elevs.back().irOffset + elevs.back().azCount)};
  558. auto coeffs = std::vector<HrirArray>(irCount, HrirArray{});
  559. auto delays = std::vector<ubyte2>(irCount);
  560. for(auto &hrir : coeffs)
  561. {
  562. for(auto &val : al::span{hrir}.first(irSize))
  563. val[0] = float(readle<int16_t>(data)) / 32768.0f;
  564. }
  565. for(auto &val : delays)
  566. val[0] = readle<uint8_t>(data);
  567. if(!data || data.eof())
  568. throw std::runtime_error{"Premature end of file"};
  569. for(size_t i{0};i < irCount;i++)
  570. {
  571. if(delays[i][0] > MaxHrirDelay)
  572. {
  573. ERR("Invalid delays[{}]: {} ({})", i, delays[i][0], MaxHrirDelay);
  574. return nullptr;
  575. }
  576. delays[i][0] <<= HrirDelayFracBits;
  577. }
  578. /* Mirror the left ear responses to the right ear. */
  579. MirrorLeftHrirs(elevs, coeffs, delays);
  580. const std::array field{HrtfStore::Field{0.0f, evCount}};
  581. return CreateHrtfStore(rate, irSize, field, elevs, coeffs.data(), delays.data());
  582. }
  583. std::unique_ptr<HrtfStore> LoadHrtf02(std::istream &data)
  584. {
  585. static constexpr ubyte SampleType_S16{0};
  586. static constexpr ubyte SampleType_S24{1};
  587. static constexpr ubyte ChanType_LeftOnly{0};
  588. static constexpr ubyte ChanType_LeftRight{1};
  589. uint rate{readle<uint32_t>(data)};
  590. ubyte sampleType{readle<uint8_t>(data)};
  591. ubyte channelType{readle<uint8_t>(data)};
  592. uint8_t irSize{readle<uint8_t>(data)};
  593. ubyte fdCount{readle<uint8_t>(data)};
  594. if(!data || data.eof())
  595. throw std::runtime_error{"Premature end of file"};
  596. if(sampleType > SampleType_S24)
  597. {
  598. ERR("Unsupported sample type: {}", sampleType);
  599. return nullptr;
  600. }
  601. if(channelType > ChanType_LeftRight)
  602. {
  603. ERR("Unsupported channel type: {}", channelType);
  604. return nullptr;
  605. }
  606. if(irSize < MinIrLength || irSize > HrirLength)
  607. {
  608. ERR("Unsupported HRIR size, irSize={} ({} to {})", irSize, MinIrLength, HrirLength);
  609. return nullptr;
  610. }
  611. if(fdCount < 1 || fdCount > MaxFdCount)
  612. {
  613. ERR("Unsupported number of field-depths: fdCount={} ({} to {})", fdCount, MinFdCount,
  614. MaxFdCount);
  615. return nullptr;
  616. }
  617. auto fields = std::vector<HrtfStore::Field>(fdCount);
  618. auto elevs = std::vector<HrtfStore::Elevation>{};
  619. for(size_t f{0};f < fdCount;f++)
  620. {
  621. const ushort distance{readle<uint16_t>(data)};
  622. const ubyte evCount{readle<uint8_t>(data)};
  623. if(!data || data.eof())
  624. throw std::runtime_error{"Premature end of file"};
  625. if(distance < MinFdDistance || distance > MaxFdDistance)
  626. {
  627. ERR("Unsupported field distance[{}]={} ({} to {} millimeters)", f, distance,
  628. MinFdDistance, MaxFdDistance);
  629. return nullptr;
  630. }
  631. if(evCount < MinEvCount || evCount > MaxEvCount)
  632. {
  633. ERR("Unsupported elevation count: evCount[{}]={} ({} to {})", f, evCount,
  634. MinEvCount, MaxEvCount);
  635. return nullptr;
  636. }
  637. fields[f].distance = float(distance) / 1000.0f;
  638. fields[f].evCount = evCount;
  639. if(f > 0 && fields[f].distance <= fields[f-1].distance)
  640. {
  641. ERR("Field distance[{}] is not after previous ({:f} > {:f})", f, fields[f].distance,
  642. fields[f-1].distance);
  643. return nullptr;
  644. }
  645. const size_t ebase{elevs.size()};
  646. elevs.resize(ebase + evCount);
  647. for(auto &elev : al::span{elevs}.subspan(ebase, evCount))
  648. elev.azCount = readle<uint8_t>(data);
  649. if(!data || data.eof())
  650. throw std::runtime_error{"Premature end of file"};
  651. for(size_t e{0};e < evCount;e++)
  652. {
  653. if(elevs[ebase+e].azCount < MinAzCount || elevs[ebase+e].azCount > MaxAzCount)
  654. {
  655. ERR("Unsupported azimuth count: azCount[{}][{}]={} ({} to {})", f, e,
  656. elevs[ebase+e].azCount, MinAzCount, MaxAzCount);
  657. return nullptr;
  658. }
  659. }
  660. }
  661. elevs[0].irOffset = 0;
  662. std::partial_sum(elevs.cbegin(), elevs.cend(), elevs.begin(),
  663. [](const HrtfStore::Elevation &last, const HrtfStore::Elevation &cur)
  664. -> HrtfStore::Elevation
  665. {
  666. return HrtfStore::Elevation{cur.azCount,
  667. static_cast<ushort>(last.azCount + last.irOffset)};
  668. });
  669. const auto irTotal = static_cast<ushort>(elevs.back().azCount + elevs.back().irOffset);
  670. auto coeffs = std::vector<HrirArray>(irTotal, HrirArray{});
  671. auto delays = std::vector<ubyte2>(irTotal);
  672. if(channelType == ChanType_LeftOnly)
  673. {
  674. if(sampleType == SampleType_S16)
  675. {
  676. for(auto &hrir : coeffs)
  677. {
  678. for(auto &val : al::span{hrir}.first(irSize))
  679. val[0] = float(readle<int16_t>(data)) / 32768.0f;
  680. }
  681. }
  682. else if(sampleType == SampleType_S24)
  683. {
  684. for(auto &hrir : coeffs)
  685. {
  686. for(auto &val : al::span{hrir}.first(irSize))
  687. val[0] = static_cast<float>(readle<int,24>(data)) / 8388608.0f;
  688. }
  689. }
  690. for(auto &val : delays)
  691. val[0] = readle<uint8_t>(data);
  692. if(!data || data.eof())
  693. throw std::runtime_error{"Premature end of file"};
  694. for(size_t i{0};i < irTotal;++i)
  695. {
  696. if(delays[i][0] > MaxHrirDelay)
  697. {
  698. ERR("Invalid delays[{}][0]: {} ({})", i, delays[i][0], MaxHrirDelay);
  699. return nullptr;
  700. }
  701. delays[i][0] <<= HrirDelayFracBits;
  702. }
  703. /* Mirror the left ear responses to the right ear. */
  704. MirrorLeftHrirs(elevs, coeffs, delays);
  705. }
  706. else if(channelType == ChanType_LeftRight)
  707. {
  708. if(sampleType == SampleType_S16)
  709. {
  710. for(auto &hrir : coeffs)
  711. {
  712. for(auto &val : al::span{hrir}.first(irSize))
  713. {
  714. val[0] = float(readle<int16_t>(data)) / 32768.0f;
  715. val[1] = float(readle<int16_t>(data)) / 32768.0f;
  716. }
  717. }
  718. }
  719. else if(sampleType == SampleType_S24)
  720. {
  721. for(auto &hrir : coeffs)
  722. {
  723. for(auto &val : al::span{hrir}.first(irSize))
  724. {
  725. val[0] = static_cast<float>(readle<int,24>(data)) / 8388608.0f;
  726. val[1] = static_cast<float>(readle<int,24>(data)) / 8388608.0f;
  727. }
  728. }
  729. }
  730. for(auto &val : delays)
  731. {
  732. val[0] = readle<uint8_t>(data);
  733. val[1] = readle<uint8_t>(data);
  734. }
  735. if(!data || data.eof())
  736. throw std::runtime_error{"Premature end of file"};
  737. for(size_t i{0};i < irTotal;++i)
  738. {
  739. if(delays[i][0] > MaxHrirDelay)
  740. {
  741. ERR("Invalid delays[{}][0]: {} ({})", i, delays[i][0], MaxHrirDelay);
  742. return nullptr;
  743. }
  744. if(delays[i][1] > MaxHrirDelay)
  745. {
  746. ERR("Invalid delays[{}][1]: {} ({})", i, delays[i][1], MaxHrirDelay);
  747. return nullptr;
  748. }
  749. delays[i][0] <<= HrirDelayFracBits;
  750. delays[i][1] <<= HrirDelayFracBits;
  751. }
  752. }
  753. if(fdCount > 1)
  754. {
  755. auto fields_ = std::vector<HrtfStore::Field>(fields.size());
  756. auto elevs_ = std::vector<HrtfStore::Elevation>(elevs.size());
  757. auto coeffs_ = std::vector<HrirArray>(coeffs.size());
  758. auto delays_ = std::vector<ubyte2>(delays.size());
  759. /* Simple reverse for the per-field elements. */
  760. std::reverse_copy(fields.cbegin(), fields.cend(), fields_.begin());
  761. /* Each field has a group of elevations, which each have an azimuth
  762. * count. Reverse the order of the groups, keeping the relative order
  763. * of per-group azimuth counts.
  764. */
  765. auto elevs_end = elevs_.end();
  766. auto copy_azs = [&elevs,&elevs_end](const ptrdiff_t ebase, const HrtfStore::Field &field)
  767. -> ptrdiff_t
  768. {
  769. auto elevs_src = elevs.begin()+ebase;
  770. elevs_end = std::copy_backward(elevs_src, elevs_src+field.evCount, elevs_end);
  771. return ebase + field.evCount;
  772. };
  773. std::ignore = std::accumulate(fields.cbegin(), fields.cend(), ptrdiff_t{0}, copy_azs);
  774. assert(elevs_.begin() == elevs_end);
  775. /* Reestablish the IR offset for each elevation index, given the new
  776. * ordering of elevations.
  777. */
  778. elevs_[0].irOffset = 0;
  779. std::partial_sum(elevs_.cbegin(), elevs_.cend(), elevs_.begin(),
  780. [](const HrtfStore::Elevation &last, const HrtfStore::Elevation &cur)
  781. -> HrtfStore::Elevation
  782. {
  783. return HrtfStore::Elevation{cur.azCount,
  784. static_cast<ushort>(last.azCount + last.irOffset)};
  785. });
  786. /* Reverse the order of each field's group of IRs. */
  787. auto coeffs_end = coeffs_.end();
  788. auto delays_end = delays_.end();
  789. auto copy_irs = [&elevs,&coeffs,&delays,&coeffs_end,&delays_end](
  790. const ptrdiff_t ebase, const HrtfStore::Field &field) -> ptrdiff_t
  791. {
  792. auto accum_az = [](const ptrdiff_t count, const HrtfStore::Elevation &elev) noexcept
  793. -> ptrdiff_t
  794. { return count + elev.azCount; };
  795. const auto elev_mid = elevs.cbegin() + ebase;
  796. const auto abase = std::accumulate(elevs.cbegin(), elev_mid, ptrdiff_t{0}, accum_az);
  797. const auto num_azs = std::accumulate(elev_mid, elev_mid + field.evCount, ptrdiff_t{0},
  798. accum_az);
  799. coeffs_end = std::copy_backward(coeffs.cbegin() + abase,
  800. coeffs.cbegin() + (abase+num_azs), coeffs_end);
  801. delays_end = std::copy_backward(delays.cbegin() + abase,
  802. delays.cbegin() + (abase+num_azs), delays_end);
  803. return ebase + field.evCount;
  804. };
  805. std::ignore = std::accumulate(fields.cbegin(), fields.cend(), ptrdiff_t{0}, copy_irs);
  806. assert(coeffs_.begin() == coeffs_end);
  807. assert(delays_.begin() == delays_end);
  808. fields = std::move(fields_);
  809. elevs = std::move(elevs_);
  810. coeffs = std::move(coeffs_);
  811. delays = std::move(delays_);
  812. }
  813. return CreateHrtfStore(rate, irSize, fields, elevs, coeffs.data(), delays.data());
  814. }
  815. std::unique_ptr<HrtfStore> LoadHrtf03(std::istream &data)
  816. {
  817. static constexpr ubyte ChanType_LeftOnly{0};
  818. static constexpr ubyte ChanType_LeftRight{1};
  819. uint rate{readle<uint32_t>(data)};
  820. ubyte channelType{readle<uint8_t>(data)};
  821. uint8_t irSize{readle<uint8_t>(data)};
  822. ubyte fdCount{readle<uint8_t>(data)};
  823. if(!data || data.eof())
  824. throw std::runtime_error{"Premature end of file"};
  825. if(channelType > ChanType_LeftRight)
  826. {
  827. ERR("Unsupported channel type: {}", channelType);
  828. return nullptr;
  829. }
  830. if(irSize < MinIrLength || irSize > HrirLength)
  831. {
  832. ERR("Unsupported HRIR size, irSize={} ({} to {})", irSize, MinIrLength, HrirLength);
  833. return nullptr;
  834. }
  835. if(fdCount < 1 || fdCount > MaxFdCount)
  836. {
  837. ERR("Unsupported number of field-depths: fdCount={} ({} to {})", fdCount, MinFdCount,
  838. MaxFdCount);
  839. return nullptr;
  840. }
  841. auto fields = std::vector<HrtfStore::Field>(fdCount);
  842. auto elevs = std::vector<HrtfStore::Elevation>{};
  843. for(size_t f{0};f < fdCount;f++)
  844. {
  845. const ushort distance{readle<uint16_t>(data)};
  846. const ubyte evCount{readle<uint8_t>(data)};
  847. if(!data || data.eof())
  848. throw std::runtime_error{"Premature end of file"};
  849. if(distance < MinFdDistance || distance > MaxFdDistance)
  850. {
  851. ERR("Unsupported field distance[{}]={} ({} to {} millimeters)", f, distance,
  852. MinFdDistance, MaxFdDistance);
  853. return nullptr;
  854. }
  855. if(evCount < MinEvCount || evCount > MaxEvCount)
  856. {
  857. ERR("Unsupported elevation count: evCount[{}]={} ({} to {})", f, evCount,
  858. MinEvCount, MaxEvCount);
  859. return nullptr;
  860. }
  861. fields[f].distance = float(distance) / 1000.0f;
  862. fields[f].evCount = evCount;
  863. if(f > 0 && fields[f].distance > fields[f-1].distance)
  864. {
  865. ERR("Field distance[{}] is not before previous ({:f} <= {:f})", f,
  866. fields[f].distance, fields[f-1].distance);
  867. return nullptr;
  868. }
  869. const size_t ebase{elevs.size()};
  870. elevs.resize(ebase + evCount);
  871. for(auto &elev : al::span{elevs}.subspan(ebase, evCount))
  872. elev.azCount = readle<uint8_t>(data);
  873. if(!data || data.eof())
  874. throw std::runtime_error{"Premature end of file"};
  875. for(size_t e{0};e < evCount;e++)
  876. {
  877. if(elevs[ebase+e].azCount < MinAzCount || elevs[ebase+e].azCount > MaxAzCount)
  878. {
  879. ERR("Unsupported azimuth count: azCount[{}][{}]={} ({} to {})", f, e,
  880. elevs[ebase+e].azCount, MinAzCount, MaxAzCount);
  881. return nullptr;
  882. }
  883. }
  884. }
  885. elevs[0].irOffset = 0;
  886. std::partial_sum(elevs.cbegin(), elevs.cend(), elevs.begin(),
  887. [](const HrtfStore::Elevation &last, const HrtfStore::Elevation &cur)
  888. -> HrtfStore::Elevation
  889. {
  890. return HrtfStore::Elevation{cur.azCount,
  891. static_cast<ushort>(last.azCount + last.irOffset)};
  892. });
  893. const auto irTotal = static_cast<ushort>(elevs.back().azCount + elevs.back().irOffset);
  894. auto coeffs = std::vector<HrirArray>(irTotal, HrirArray{});
  895. auto delays = std::vector<ubyte2>(irTotal);
  896. if(channelType == ChanType_LeftOnly)
  897. {
  898. for(auto &hrir : coeffs)
  899. {
  900. for(auto &val : al::span{hrir}.first(irSize))
  901. val[0] = static_cast<float>(readle<int,24>(data)) / 8388608.0f;
  902. }
  903. for(auto &val : delays)
  904. val[0] = readle<uint8_t>(data);
  905. if(!data || data.eof())
  906. throw std::runtime_error{"Premature end of file"};
  907. for(size_t i{0};i < irTotal;++i)
  908. {
  909. if(delays[i][0] > MaxHrirDelay<<HrirDelayFracBits)
  910. {
  911. ERR("Invalid delays[{}][0]: {:f} ({})", i, delays[i][0]/float{HrirDelayFracOne},
  912. MaxHrirDelay);
  913. return nullptr;
  914. }
  915. }
  916. /* Mirror the left ear responses to the right ear. */
  917. MirrorLeftHrirs(elevs, coeffs, delays);
  918. }
  919. else if(channelType == ChanType_LeftRight)
  920. {
  921. for(auto &hrir : coeffs)
  922. {
  923. for(auto &val : al::span{hrir}.first(irSize))
  924. {
  925. val[0] = static_cast<float>(readle<int,24>(data)) / 8388608.0f;
  926. val[1] = static_cast<float>(readle<int,24>(data)) / 8388608.0f;
  927. }
  928. }
  929. for(auto &val : delays)
  930. {
  931. val[0] = readle<uint8_t>(data);
  932. val[1] = readle<uint8_t>(data);
  933. }
  934. if(!data || data.eof())
  935. throw std::runtime_error{"Premature end of file"};
  936. for(size_t i{0};i < irTotal;++i)
  937. {
  938. if(delays[i][0] > MaxHrirDelay<<HrirDelayFracBits)
  939. {
  940. ERR("Invalid delays[{}][0]: {:f} ({})", i, delays[i][0]/float{HrirDelayFracOne},
  941. MaxHrirDelay);
  942. return nullptr;
  943. }
  944. if(delays[i][1] > MaxHrirDelay<<HrirDelayFracBits)
  945. {
  946. ERR("Invalid delays[{}][1]: {:f} ({})", i, delays[i][1]/float{HrirDelayFracOne},
  947. MaxHrirDelay);
  948. return nullptr;
  949. }
  950. }
  951. }
  952. return CreateHrtfStore(rate, irSize, fields, elevs, coeffs.data(), delays.data());
  953. }
  954. bool checkName(const std::string_view name)
  955. {
  956. auto match_name = [name](const HrtfEntry &entry) -> bool { return name == entry.mDispName; };
  957. auto &enum_names = EnumeratedHrtfs;
  958. return std::find_if(enum_names.cbegin(), enum_names.cend(), match_name) != enum_names.cend();
  959. }
  960. void AddFileEntry(const std::string_view filename)
  961. {
  962. /* Check if this file has already been enumerated. */
  963. auto enum_iter = std::find_if(EnumeratedHrtfs.cbegin(), EnumeratedHrtfs.cend(),
  964. [filename](const HrtfEntry &entry) -> bool { return entry.mFilename == filename; });
  965. if(enum_iter != EnumeratedHrtfs.cend())
  966. {
  967. TRACE("Skipping duplicate file entry {}", filename);
  968. return;
  969. }
  970. /* TODO: Get a human-readable name from the HRTF data (possibly coming in a
  971. * format update).
  972. */
  973. const auto namepos = std::max(filename.rfind('/')+1, filename.rfind('\\')+1);
  974. const auto extpos = filename.substr(namepos).rfind('.');
  975. const auto basename = (extpos == std::string::npos) ?
  976. filename.substr(namepos) : filename.substr(namepos, extpos);
  977. auto count = 1;
  978. auto newname = std::string{basename};
  979. while(checkName(newname))
  980. newname = fmt::format("{} #{}", basename, ++count);
  981. const auto &entry = EnumeratedHrtfs.emplace_back(newname, filename);
  982. TRACE("Adding file entry \"{}\"", entry.mFilename);
  983. }
  984. /* Unfortunate that we have to duplicate AddFileEntry to take a memory buffer
  985. * for input instead of opening the given filename.
  986. */
  987. void AddBuiltInEntry(const std::string_view dispname, uint residx)
  988. {
  989. auto filename = fmt::format("!{}_{}", residx, dispname);
  990. auto enum_iter = std::find_if(EnumeratedHrtfs.cbegin(), EnumeratedHrtfs.cend(),
  991. [&filename](const HrtfEntry &entry) -> bool { return entry.mFilename == filename; });
  992. if(enum_iter != EnumeratedHrtfs.cend())
  993. {
  994. TRACE("Skipping duplicate file entry {}", filename);
  995. return;
  996. }
  997. /* TODO: Get a human-readable name from the HRTF data (possibly coming in a
  998. * format update). */
  999. auto count = 1;
  1000. auto newname = std::string{dispname};
  1001. while(checkName(newname))
  1002. newname = fmt::format("{} #{}", dispname, ++count);
  1003. const auto &entry = EnumeratedHrtfs.emplace_back(std::move(newname), std::move(filename));
  1004. TRACE("Adding built-in entry \"{}\"", entry.mFilename);
  1005. }
  1006. #define IDR_DEFAULT_HRTF_MHR 1
  1007. #ifndef ALSOFT_EMBED_HRTF_DATA
  1008. al::span<const char> GetResource(int /*name*/)
  1009. { return {}; }
  1010. #else
  1011. /* NOLINTNEXTLINE(*-avoid-c-arrays) */
  1012. constexpr unsigned char hrtf_default[]{
  1013. #include "default_hrtf.txt"
  1014. };
  1015. al::span<const char> GetResource(int name)
  1016. {
  1017. if(name == IDR_DEFAULT_HRTF_MHR)
  1018. return {reinterpret_cast<const char*>(hrtf_default), sizeof(hrtf_default)};
  1019. return {};
  1020. }
  1021. #endif
  1022. } // namespace
  1023. std::vector<std::string> EnumerateHrtf(std::optional<std::string> pathopt)
  1024. {
  1025. std::lock_guard<std::mutex> enumlock{EnumeratedHrtfLock};
  1026. EnumeratedHrtfs.clear();
  1027. for(const auto &fname : SearchDataFiles(".mhr"sv))
  1028. AddFileEntry(fname);
  1029. bool usedefaults{true};
  1030. if(pathopt)
  1031. {
  1032. std::string_view pathlist{*pathopt};
  1033. while(!pathlist.empty())
  1034. {
  1035. while(!pathlist.empty() && (std::isspace(pathlist.front()) || pathlist.front() == ','))
  1036. pathlist.remove_prefix(1);
  1037. if(pathlist.empty())
  1038. break;
  1039. auto endpos = std::min(pathlist.find(','), pathlist.size());
  1040. auto entry = pathlist.substr(0, endpos);
  1041. if(endpos < pathlist.size())
  1042. pathlist.remove_prefix(++endpos);
  1043. else
  1044. {
  1045. pathlist.remove_prefix(endpos);
  1046. usedefaults = false;
  1047. }
  1048. while(!entry.empty() && std::isspace(entry.back()))
  1049. entry.remove_suffix(1);
  1050. if(!entry.empty())
  1051. {
  1052. for(const auto &fname : SearchDataFiles(".mhr"sv, entry))
  1053. AddFileEntry(fname);
  1054. }
  1055. }
  1056. }
  1057. if(usedefaults)
  1058. {
  1059. for(const auto &fname : SearchDataFiles(".mhr"sv, "openal/hrtf"sv))
  1060. AddFileEntry(fname);
  1061. if(!GetResource(IDR_DEFAULT_HRTF_MHR).empty())
  1062. AddBuiltInEntry("Built-In HRTF", IDR_DEFAULT_HRTF_MHR);
  1063. }
  1064. std::vector<std::string> list;
  1065. list.reserve(EnumeratedHrtfs.size());
  1066. for(auto &entry : EnumeratedHrtfs)
  1067. list.emplace_back(entry.mDispName);
  1068. return list;
  1069. }
  1070. HrtfStorePtr GetLoadedHrtf(const std::string_view name, const uint devrate)
  1071. try {
  1072. if(devrate > MaxSampleRate)
  1073. {
  1074. WARN("Device sample rate too large for HRTF ({}hz > {}hz)", devrate, MaxSampleRate);
  1075. return nullptr;
  1076. }
  1077. std::lock_guard<std::mutex> enumlock{EnumeratedHrtfLock};
  1078. auto entry_iter = std::find_if(EnumeratedHrtfs.cbegin(), EnumeratedHrtfs.cend(),
  1079. [name](const HrtfEntry &entry) -> bool { return entry.mDispName == name; });
  1080. if(entry_iter == EnumeratedHrtfs.cend())
  1081. return nullptr;
  1082. const std::string &fname = entry_iter->mFilename;
  1083. std::lock_guard<std::mutex> loadlock{LoadedHrtfLock};
  1084. auto hrtf_lt_fname = [devrate](LoadedHrtf &hrtf, const std::string_view filename) -> bool
  1085. {
  1086. return hrtf.mSampleRate < devrate
  1087. || (hrtf.mSampleRate == devrate && hrtf.mFilename < filename);
  1088. };
  1089. auto handle = std::lower_bound(LoadedHrtfs.begin(), LoadedHrtfs.end(), fname, hrtf_lt_fname);
  1090. if(handle != LoadedHrtfs.end() && handle->mSampleRate == devrate && handle->mFilename == fname)
  1091. {
  1092. if(HrtfStore *hrtf{handle->mEntry.get()})
  1093. {
  1094. assert(hrtf->mSampleRate == devrate);
  1095. hrtf->add_ref();
  1096. return HrtfStorePtr{hrtf};
  1097. }
  1098. }
  1099. std::unique_ptr<std::istream> stream;
  1100. int residx{};
  1101. char ch{};
  1102. /* NOLINTNEXTLINE(cert-err34-c,cppcoreguidelines-pro-type-vararg) */
  1103. if(sscanf(fname.c_str(), "!%d%c", &residx, &ch) == 2 && ch == '_')
  1104. {
  1105. TRACE("Loading {}...", fname);
  1106. al::span<const char> res{GetResource(residx)};
  1107. if(res.empty())
  1108. {
  1109. ERR("Could not get resource {}, {}", residx, name);
  1110. return nullptr;
  1111. }
  1112. /* NOLINTNEXTLINE(*-const-cast) */
  1113. stream = std::make_unique<idstream>(al::span{const_cast<char*>(res.data()), res.size()});
  1114. }
  1115. else
  1116. {
  1117. TRACE("Loading {}...", fname);
  1118. auto fstr = std::make_unique<fs::ifstream>(fs::u8path(fname),
  1119. std::ios::binary);
  1120. if(!fstr->is_open())
  1121. {
  1122. ERR("Could not open {}", fname);
  1123. return nullptr;
  1124. }
  1125. stream = std::move(fstr);
  1126. }
  1127. auto hrtf = std::unique_ptr<HrtfStore>{};
  1128. auto magic = std::array<char,HeaderMarkerSize>{};
  1129. stream->read(magic.data(), magic.size());
  1130. if(stream->gcount() < std::streamsize{magic.size()})
  1131. ERR("{} data is too short ({} bytes)", name, stream->gcount());
  1132. else if(GetMarker03Name() == std::string_view{magic.data(), magic.size()})
  1133. {
  1134. TRACE("Detected data set format v3");
  1135. hrtf = LoadHrtf03(*stream);
  1136. }
  1137. else if(GetMarker02Name() == std::string_view{magic.data(), magic.size()})
  1138. {
  1139. TRACE("Detected data set format v2");
  1140. hrtf = LoadHrtf02(*stream);
  1141. }
  1142. else if(GetMarker01Name() == std::string_view{magic.data(), magic.size()})
  1143. {
  1144. TRACE("Detected data set format v1");
  1145. hrtf = LoadHrtf01(*stream);
  1146. }
  1147. else if(GetMarker00Name() == std::string_view{magic.data(), magic.size()})
  1148. {
  1149. TRACE("Detected data set format v0");
  1150. hrtf = LoadHrtf00(*stream);
  1151. }
  1152. else
  1153. ERR("Invalid header in {}: \"{}\"", name, std::string_view{magic.data(), magic.size()});
  1154. stream.reset();
  1155. if(!hrtf)
  1156. return nullptr;
  1157. if(hrtf->mSampleRate != devrate)
  1158. {
  1159. TRACE("Resampling HRTF {} ({}hz -> {}hz)", name, uint{hrtf->mSampleRate}, devrate);
  1160. /* Calculate the last elevation's index and get the total IR count. */
  1161. const size_t lastEv{std::accumulate(hrtf->mFields.begin(), hrtf->mFields.end(), 0_uz,
  1162. [](const size_t curval, const HrtfStore::Field &field) noexcept -> size_t
  1163. { return curval + field.evCount; }
  1164. ) - 1};
  1165. const size_t irCount{size_t{hrtf->mElev[lastEv].irOffset} + hrtf->mElev[lastEv].azCount};
  1166. /* Resample all the IRs. */
  1167. std::array<std::array<double,HrirLength>,2> inout{};
  1168. PPhaseResampler rs;
  1169. rs.init(hrtf->mSampleRate, devrate);
  1170. for(size_t i{0};i < irCount;++i)
  1171. {
  1172. /* NOLINTNEXTLINE(*-const-cast) */
  1173. auto coeffs = al::span{const_cast<HrirArray&>(hrtf->mCoeffs[i])};
  1174. for(size_t j{0};j < 2;++j)
  1175. {
  1176. std::transform(coeffs.cbegin(), coeffs.cend(), inout[0].begin(),
  1177. [j](const float2 &in) noexcept -> double { return in[j]; });
  1178. rs.process(inout[0], inout[1]);
  1179. for(size_t k{0};k < HrirLength;++k)
  1180. coeffs[k][j] = static_cast<float>(inout[1][k]);
  1181. }
  1182. }
  1183. rs = {};
  1184. /* Scale the delays for the new sample rate. */
  1185. float max_delay{0.0f};
  1186. auto new_delays = std::vector<float2>(irCount);
  1187. const float rate_scale{static_cast<float>(devrate)/static_cast<float>(hrtf->mSampleRate)};
  1188. for(size_t i{0};i < irCount;++i)
  1189. {
  1190. for(size_t j{0};j < 2;++j)
  1191. {
  1192. const float new_delay{std::round(float(hrtf->mDelays[i][j]) * rate_scale) /
  1193. float{HrirDelayFracOne}};
  1194. max_delay = std::max(max_delay, new_delay);
  1195. new_delays[i][j] = new_delay;
  1196. }
  1197. }
  1198. /* If the new delays exceed the max, scale it down to fit (essentially
  1199. * shrinking the head radius; not ideal but better than a per-delay
  1200. * clamp).
  1201. */
  1202. float delay_scale{HrirDelayFracOne};
  1203. if(max_delay > MaxHrirDelay)
  1204. {
  1205. WARN("Resampled delay exceeds max ({:.2f} > {})", max_delay, MaxHrirDelay);
  1206. delay_scale *= float{MaxHrirDelay} / max_delay;
  1207. }
  1208. for(size_t i{0};i < irCount;++i)
  1209. {
  1210. /* NOLINTNEXTLINE(*-const-cast) */
  1211. auto delays = al::span{const_cast<ubyte2&>(hrtf->mDelays[i])};
  1212. std::transform(new_delays[i].cbegin(), new_delays[i].cend(), delays.begin(),
  1213. [delay_scale](const float delay)
  1214. { return static_cast<ubyte>(float2int(delay*delay_scale + 0.5f)); });
  1215. }
  1216. /* Scale the IR size for the new sample rate and update the stored
  1217. * sample rate.
  1218. */
  1219. const float newIrSize{std::round(static_cast<float>(hrtf->mIrSize) * rate_scale)};
  1220. hrtf->mIrSize = static_cast<uint8_t>(std::min(float{HrirLength}, newIrSize));
  1221. hrtf->mSampleRate = devrate & 0xff'ff'ff;
  1222. }
  1223. handle = LoadedHrtfs.emplace(handle, fname, devrate, std::move(hrtf));
  1224. TRACE("Loaded HRTF {} for sample rate {}hz, {}-sample filter", name,
  1225. uint{handle->mEntry->mSampleRate}, uint{handle->mEntry->mIrSize});
  1226. return HrtfStorePtr{handle->mEntry.get()};
  1227. }
  1228. catch(std::exception& e) {
  1229. ERR("Failed to load {}: {}", name, e.what());
  1230. return nullptr;
  1231. }
  1232. void HrtfStore::add_ref()
  1233. {
  1234. auto ref = IncrementRef(mRef);
  1235. TRACE("HrtfStore {} increasing refcount to {}", decltype(std::declval<void*>()){this}, ref);
  1236. }
  1237. void HrtfStore::dec_ref()
  1238. {
  1239. auto ref = DecrementRef(mRef);
  1240. TRACE("HrtfStore {} decreasing refcount to {}", decltype(std::declval<void*>()){this}, ref);
  1241. if(ref == 0)
  1242. {
  1243. std::lock_guard<std::mutex> loadlock{LoadedHrtfLock};
  1244. /* Go through and remove all unused HRTFs. */
  1245. auto remove_unused = [](LoadedHrtf &hrtf) -> bool
  1246. {
  1247. HrtfStore *entry{hrtf.mEntry.get()};
  1248. if(entry && entry->mRef.load() == 0)
  1249. {
  1250. TRACE("Unloading unused HRTF {}", hrtf.mFilename);
  1251. hrtf.mEntry = nullptr;
  1252. return true;
  1253. }
  1254. return false;
  1255. };
  1256. auto iter = std::remove_if(LoadedHrtfs.begin(), LoadedHrtfs.end(), remove_unused);
  1257. LoadedHrtfs.erase(iter, LoadedHrtfs.end());
  1258. }
  1259. }