🛠️🐜 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.

1169 lines
52 KiB

  1. /**
  2. * OpenAL cross platform audio library
  3. * Copyright (C) 1999-2010 by authors.
  4. * This library is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Library General Public
  6. * License as published by the Free Software Foundation; either
  7. * version 2 of the License, or (at your option) any later version.
  8. *
  9. * This library is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * Library General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Library General Public
  15. * License along with this library; if not, write to the
  16. * Free Software Foundation, Inc.,
  17. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  18. * Or go to http://www.gnu.org/copyleft/lgpl.html
  19. */
  20. #include "config.h"
  21. #include <algorithm>
  22. #include <array>
  23. #include <chrono>
  24. #include <cmath>
  25. #include <cstdio>
  26. #include <cstring>
  27. #include <functional>
  28. #include <iterator>
  29. #include <memory>
  30. #include <new>
  31. #include <numeric>
  32. #include <string>
  33. #include "AL/al.h"
  34. #include "AL/alc.h"
  35. #include "AL/alext.h"
  36. #include "al/auxeffectslot.h"
  37. #include "albit.h"
  38. #include "alconfig.h"
  39. #include "alc/context.h"
  40. #include "almalloc.h"
  41. #include "alnumbers.h"
  42. #include "alnumeric.h"
  43. #include "aloptional.h"
  44. #include "alspan.h"
  45. #include "alstring.h"
  46. #include "alu.h"
  47. #include "core/ambdec.h"
  48. #include "core/ambidefs.h"
  49. #include "core/bformatdec.h"
  50. #include "core/bs2b.h"
  51. #include "core/devformat.h"
  52. #include "core/front_stablizer.h"
  53. #include "core/hrtf.h"
  54. #include "core/logging.h"
  55. #include "core/uhjfilter.h"
  56. #include "device.h"
  57. #include "opthelpers.h"
  58. namespace {
  59. using namespace std::placeholders;
  60. using std::chrono::seconds;
  61. using std::chrono::nanoseconds;
  62. inline const char *GetLabelFromChannel(Channel channel)
  63. {
  64. switch(channel)
  65. {
  66. case FrontLeft: return "front-left";
  67. case FrontRight: return "front-right";
  68. case FrontCenter: return "front-center";
  69. case LFE: return "lfe";
  70. case BackLeft: return "back-left";
  71. case BackRight: return "back-right";
  72. case BackCenter: return "back-center";
  73. case SideLeft: return "side-left";
  74. case SideRight: return "side-right";
  75. case TopFrontLeft: return "top-front-left";
  76. case TopFrontCenter: return "top-front-center";
  77. case TopFrontRight: return "top-front-right";
  78. case TopCenter: return "top-center";
  79. case TopBackLeft: return "top-back-left";
  80. case TopBackCenter: return "top-back-center";
  81. case TopBackRight: return "top-back-right";
  82. case Aux0: return "Aux0";
  83. case Aux1: return "Aux1";
  84. case Aux2: return "Aux2";
  85. case Aux3: return "Aux3";
  86. case Aux4: return "Aux4";
  87. case Aux5: return "Aux5";
  88. case Aux6: return "Aux6";
  89. case Aux7: return "Aux7";
  90. case Aux8: return "Aux8";
  91. case Aux9: return "Aux9";
  92. case Aux10: return "Aux10";
  93. case Aux11: return "Aux11";
  94. case Aux12: return "Aux12";
  95. case Aux13: return "Aux13";
  96. case Aux14: return "Aux14";
  97. case Aux15: return "Aux15";
  98. case MaxChannels: break;
  99. }
  100. return "(unknown)";
  101. }
  102. std::unique_ptr<FrontStablizer> CreateStablizer(const size_t outchans, const uint srate)
  103. {
  104. auto stablizer = FrontStablizer::Create(outchans);
  105. for(auto &buf : stablizer->DelayBuf)
  106. std::fill(buf.begin(), buf.end(), 0.0f);
  107. /* Initialize band-splitting filter for the mid signal, with a crossover at
  108. * 5khz (could be higher).
  109. */
  110. stablizer->MidFilter.init(5000.0f / static_cast<float>(srate));
  111. return stablizer;
  112. }
  113. void AllocChannels(ALCdevice *device, const size_t main_chans, const size_t real_chans)
  114. {
  115. TRACE("Channel config, Main: %zu, Real: %zu\n", main_chans, real_chans);
  116. /* Allocate extra channels for any post-filter output. */
  117. const size_t num_chans{main_chans + real_chans};
  118. TRACE("Allocating %zu channels, %zu bytes\n", num_chans,
  119. num_chans*sizeof(device->MixBuffer[0]));
  120. device->MixBuffer.resize(num_chans);
  121. al::span<FloatBufferLine> buffer{device->MixBuffer};
  122. device->Dry.Buffer = buffer.first(main_chans);
  123. buffer = buffer.subspan(main_chans);
  124. if(real_chans != 0)
  125. {
  126. device->RealOut.Buffer = buffer.first(real_chans);
  127. buffer = buffer.subspan(real_chans);
  128. }
  129. else
  130. device->RealOut.Buffer = device->Dry.Buffer;
  131. }
  132. using ChannelCoeffs = std::array<float,MaxAmbiChannels>;
  133. enum DecoderMode : bool {
  134. SingleBand = false,
  135. DualBand = true
  136. };
  137. template<DecoderMode Mode, size_t N>
  138. struct DecoderConfig;
  139. template<size_t N>
  140. struct DecoderConfig<SingleBand, N> {
  141. uint8_t mOrder{};
  142. bool mIs3D{};
  143. std::array<Channel,N> mChannels{};
  144. DevAmbiScaling mScaling{};
  145. std::array<float,MaxAmbiOrder+1> mOrderGain{};
  146. std::array<ChannelCoeffs,N> mCoeffs{};
  147. };
  148. template<size_t N>
  149. struct DecoderConfig<DualBand, N> {
  150. uint8_t mOrder{};
  151. bool mIs3D{};
  152. std::array<Channel,N> mChannels{};
  153. DevAmbiScaling mScaling{};
  154. std::array<float,MaxAmbiOrder+1> mOrderGain{};
  155. std::array<ChannelCoeffs,N> mCoeffs{};
  156. std::array<float,MaxAmbiOrder+1> mOrderGainLF{};
  157. std::array<ChannelCoeffs,N> mCoeffsLF{};
  158. };
  159. template<>
  160. struct DecoderConfig<DualBand, 0> {
  161. uint8_t mOrder{};
  162. bool mIs3D{};
  163. al::span<const Channel> mChannels;
  164. DevAmbiScaling mScaling{};
  165. al::span<const float> mOrderGain;
  166. al::span<const ChannelCoeffs> mCoeffs;
  167. al::span<const float> mOrderGainLF;
  168. al::span<const ChannelCoeffs> mCoeffsLF;
  169. template<size_t N>
  170. DecoderConfig& operator=(const DecoderConfig<SingleBand,N> &rhs) noexcept
  171. {
  172. mOrder = rhs.mOrder;
  173. mIs3D = rhs.mIs3D;
  174. mChannels = rhs.mChannels;
  175. mScaling = rhs.mScaling;
  176. mOrderGain = rhs.mOrderGain;
  177. mCoeffs = rhs.mCoeffs;
  178. mOrderGainLF = {};
  179. mCoeffsLF = {};
  180. return *this;
  181. }
  182. template<size_t N>
  183. DecoderConfig& operator=(const DecoderConfig<DualBand,N> &rhs) noexcept
  184. {
  185. mOrder = rhs.mOrder;
  186. mIs3D = rhs.mIs3D;
  187. mChannels = rhs.mChannels;
  188. mScaling = rhs.mScaling;
  189. mOrderGain = rhs.mOrderGain;
  190. mCoeffs = rhs.mCoeffs;
  191. mOrderGainLF = rhs.mOrderGainLF;
  192. mCoeffsLF = rhs.mCoeffsLF;
  193. return *this;
  194. }
  195. explicit operator bool() const noexcept { return mOrder != 0; }
  196. };
  197. using DecoderView = DecoderConfig<DualBand, 0>;
  198. void InitNearFieldCtrl(ALCdevice *device, float ctrl_dist, uint order, bool is3d)
  199. {
  200. static const uint chans_per_order2d[MaxAmbiOrder+1]{ 1, 2, 2, 2 };
  201. static const uint chans_per_order3d[MaxAmbiOrder+1]{ 1, 3, 5, 7 };
  202. /* NFC is only used when AvgSpeakerDist is greater than 0. */
  203. if(!device->getConfigValueBool("decoder", "nfc", 0) || !(ctrl_dist > 0.0f))
  204. return;
  205. device->AvgSpeakerDist = clampf(ctrl_dist, 0.1f, 10.0f);
  206. TRACE("Using near-field reference distance: %.2f meters\n", device->AvgSpeakerDist);
  207. const float w1{SpeedOfSoundMetersPerSec /
  208. (device->AvgSpeakerDist * static_cast<float>(device->Frequency))};
  209. device->mNFCtrlFilter.init(w1);
  210. auto iter = std::copy_n(is3d ? chans_per_order3d : chans_per_order2d, order+1u,
  211. std::begin(device->NumChannelsPerOrder));
  212. std::fill(iter, std::end(device->NumChannelsPerOrder), 0u);
  213. }
  214. void InitDistanceComp(ALCdevice *device, const al::span<const Channel> channels,
  215. const al::span<const float,MAX_OUTPUT_CHANNELS> dists)
  216. {
  217. const float maxdist{std::accumulate(std::begin(dists), std::end(dists), 0.0f, maxf)};
  218. if(!device->getConfigValueBool("decoder", "distance-comp", 1) || !(maxdist > 0.0f))
  219. return;
  220. const auto distSampleScale = static_cast<float>(device->Frequency) / SpeedOfSoundMetersPerSec;
  221. std::vector<DistanceComp::ChanData> ChanDelay;
  222. ChanDelay.reserve(device->RealOut.Buffer.size());
  223. size_t total{0u};
  224. for(size_t chidx{0};chidx < channels.size();++chidx)
  225. {
  226. const Channel ch{channels[chidx]};
  227. const uint idx{device->RealOut.ChannelIndex[ch]};
  228. if(idx == INVALID_CHANNEL_INDEX)
  229. continue;
  230. const float distance{dists[chidx]};
  231. /* Distance compensation only delays in steps of the sample rate. This
  232. * is a bit less accurate since the delay time falls to the nearest
  233. * sample time, but it's far simpler as it doesn't have to deal with
  234. * phase offsets. This means at 48khz, for instance, the distance delay
  235. * will be in steps of about 7 millimeters.
  236. */
  237. float delay{std::floor((maxdist - distance)*distSampleScale + 0.5f)};
  238. if(delay > float{MAX_DELAY_LENGTH-1})
  239. {
  240. ERR("Delay for channel %u (%s) exceeds buffer length (%f > %d)\n", idx,
  241. GetLabelFromChannel(ch), delay, MAX_DELAY_LENGTH-1);
  242. delay = float{MAX_DELAY_LENGTH-1};
  243. }
  244. ChanDelay.resize(maxz(ChanDelay.size(), idx+1));
  245. ChanDelay[idx].Length = static_cast<uint>(delay);
  246. ChanDelay[idx].Gain = distance / maxdist;
  247. TRACE("Channel %s distance comp: %u samples, %f gain\n", GetLabelFromChannel(ch),
  248. ChanDelay[idx].Length, ChanDelay[idx].Gain);
  249. /* Round up to the next 4th sample, so each channel buffer starts
  250. * 16-byte aligned.
  251. */
  252. total += RoundUp(ChanDelay[idx].Length, 4);
  253. }
  254. if(total > 0)
  255. {
  256. auto chandelays = DistanceComp::Create(total);
  257. ChanDelay[0].Buffer = chandelays->mSamples.data();
  258. auto set_bufptr = [](const DistanceComp::ChanData &last, const DistanceComp::ChanData &cur)
  259. -> DistanceComp::ChanData
  260. {
  261. DistanceComp::ChanData ret{cur};
  262. ret.Buffer = last.Buffer + RoundUp(last.Length, 4);
  263. return ret;
  264. };
  265. std::partial_sum(ChanDelay.begin(), ChanDelay.end(), chandelays->mChannels.begin(),
  266. set_bufptr);
  267. device->ChannelDelays = std::move(chandelays);
  268. }
  269. }
  270. inline auto& GetAmbiScales(DevAmbiScaling scaletype) noexcept
  271. {
  272. if(scaletype == DevAmbiScaling::FuMa) return AmbiScale::FromFuMa();
  273. if(scaletype == DevAmbiScaling::SN3D) return AmbiScale::FromSN3D();
  274. return AmbiScale::FromN3D();
  275. }
  276. inline auto& GetAmbiLayout(DevAmbiLayout layouttype) noexcept
  277. {
  278. if(layouttype == DevAmbiLayout::FuMa) return AmbiIndex::FromFuMa();
  279. return AmbiIndex::FromACN();
  280. }
  281. DecoderView MakeDecoderView(ALCdevice *device, const AmbDecConf *conf,
  282. DecoderConfig<DualBand, MAX_OUTPUT_CHANNELS> &decoder)
  283. {
  284. DecoderView ret{};
  285. decoder.mOrder = (conf->ChanMask > Ambi2OrderMask) ? uint8_t{3} :
  286. (conf->ChanMask > Ambi1OrderMask) ? uint8_t{2} : uint8_t{1};
  287. decoder.mIs3D = (conf->ChanMask&AmbiPeriphonicMask) != 0;
  288. switch(conf->CoeffScale)
  289. {
  290. case AmbDecScale::N3D: decoder.mScaling = DevAmbiScaling::N3D; break;
  291. case AmbDecScale::SN3D: decoder.mScaling = DevAmbiScaling::SN3D; break;
  292. case AmbDecScale::FuMa: decoder.mScaling = DevAmbiScaling::FuMa; break;
  293. }
  294. std::copy_n(std::begin(conf->HFOrderGain),
  295. std::min(al::size(conf->HFOrderGain), al::size(decoder.mOrderGain)),
  296. std::begin(decoder.mOrderGain));
  297. std::copy_n(std::begin(conf->LFOrderGain),
  298. std::min(al::size(conf->LFOrderGain), al::size(decoder.mOrderGainLF)),
  299. std::begin(decoder.mOrderGainLF));
  300. std::array<uint8_t,MaxAmbiChannels> idx_map{};
  301. if(decoder.mIs3D)
  302. {
  303. uint flags{conf->ChanMask};
  304. auto elem = idx_map.begin();
  305. while(flags)
  306. {
  307. int acn{al::countr_zero(flags)};
  308. flags &= ~(1u<<acn);
  309. *elem = static_cast<uint8_t>(acn);
  310. ++elem;
  311. }
  312. }
  313. else
  314. {
  315. uint flags{conf->ChanMask};
  316. auto elem = idx_map.begin();
  317. while(flags)
  318. {
  319. int acn{al::countr_zero(flags)};
  320. flags &= ~(1u<<acn);
  321. switch(acn)
  322. {
  323. case 0: *elem = 0; break;
  324. case 1: *elem = 1; break;
  325. case 3: *elem = 2; break;
  326. case 4: *elem = 3; break;
  327. case 8: *elem = 4; break;
  328. case 9: *elem = 5; break;
  329. case 15: *elem = 6; break;
  330. default: return ret;
  331. }
  332. ++elem;
  333. }
  334. }
  335. const auto num_coeffs = static_cast<uint>(al::popcount(conf->ChanMask));
  336. const auto hfmatrix = conf->HFMatrix;
  337. const auto lfmatrix = conf->LFMatrix;
  338. uint chan_count{0};
  339. using const_speaker_span = al::span<const AmbDecConf::SpeakerConf>;
  340. for(auto &speaker : const_speaker_span{conf->Speakers.get(), conf->NumSpeakers})
  341. {
  342. /* NOTE: AmbDec does not define any standard speaker names, however
  343. * for this to work we have to by able to find the output channel
  344. * the speaker definition corresponds to. Therefore, OpenAL Soft
  345. * requires these channel labels to be recognized:
  346. *
  347. * LF = Front left
  348. * RF = Front right
  349. * LS = Side left
  350. * RS = Side right
  351. * LB = Back left
  352. * RB = Back right
  353. * CE = Front center
  354. * CB = Back center
  355. *
  356. * Additionally, surround51 will acknowledge back speakers for side
  357. * channels, to avoid issues with an ambdec expecting 5.1 to use the
  358. * back channels.
  359. */
  360. Channel ch{};
  361. if(speaker.Name == "LF")
  362. ch = FrontLeft;
  363. else if(speaker.Name == "RF")
  364. ch = FrontRight;
  365. else if(speaker.Name == "CE")
  366. ch = FrontCenter;
  367. else if(speaker.Name == "LS")
  368. ch = SideLeft;
  369. else if(speaker.Name == "RS")
  370. ch = SideRight;
  371. else if(speaker.Name == "LB")
  372. ch = (device->FmtChans == DevFmtX51) ? SideLeft : BackLeft;
  373. else if(speaker.Name == "RB")
  374. ch = (device->FmtChans == DevFmtX51) ? SideRight : BackRight;
  375. else if(speaker.Name == "CB")
  376. ch = BackCenter;
  377. else
  378. {
  379. int idx{};
  380. char c{};
  381. if(sscanf(speaker.Name.c_str(), "AUX%d%c", &idx, &c) != 1 || idx < 0
  382. || idx >= MaxChannels-Aux0)
  383. {
  384. ERR("AmbDec speaker label \"%s\" not recognized\n", speaker.Name.c_str());
  385. continue;
  386. }
  387. ch = static_cast<Channel>(Aux0+idx);
  388. }
  389. decoder.mChannels[chan_count] = ch;
  390. for(size_t src{0};src < num_coeffs;++src)
  391. {
  392. const size_t dst{idx_map[src]};
  393. decoder.mCoeffs[chan_count][dst] = hfmatrix[chan_count][src];
  394. }
  395. if(conf->FreqBands > 1)
  396. {
  397. for(size_t src{0};src < num_coeffs;++src)
  398. {
  399. const size_t dst{idx_map[src]};
  400. decoder.mCoeffsLF[chan_count][dst] = lfmatrix[chan_count][src];
  401. }
  402. }
  403. ++chan_count;
  404. }
  405. if(chan_count > 0)
  406. {
  407. ret.mOrder = decoder.mOrder;
  408. ret.mIs3D = decoder.mIs3D;
  409. ret.mScaling = decoder.mScaling;
  410. ret.mChannels = {decoder.mChannels.data(), chan_count};
  411. ret.mOrderGain = decoder.mOrderGain;
  412. ret.mCoeffs = {decoder.mCoeffs.data(), chan_count};
  413. if(conf->FreqBands > 1)
  414. {
  415. ret.mOrderGainLF = decoder.mOrderGainLF;
  416. ret.mCoeffsLF = {decoder.mCoeffsLF.data(), chan_count};
  417. }
  418. }
  419. return ret;
  420. }
  421. constexpr DecoderConfig<SingleBand, 1> MonoConfig{
  422. 0, false, {{FrontCenter}},
  423. DevAmbiScaling::N3D,
  424. {{1.0f}},
  425. {{ {{1.0f}} }}
  426. };
  427. constexpr DecoderConfig<SingleBand, 2> StereoConfig{
  428. 1, false, {{FrontLeft, FrontRight}},
  429. DevAmbiScaling::N3D,
  430. {{1.0f, 1.0f}},
  431. {{
  432. {{5.00000000e-1f, 2.88675135e-1f, 5.52305643e-2f}},
  433. {{5.00000000e-1f, -2.88675135e-1f, 5.52305643e-2f}},
  434. }}
  435. };
  436. constexpr DecoderConfig<DualBand, 4> QuadConfig{
  437. 2, false, {{BackLeft, FrontLeft, FrontRight, BackRight}},
  438. DevAmbiScaling::N3D,
  439. /*HF*/{{1.15470054e+0f, 1.00000000e+0f, 5.77350269e-1f}},
  440. {{
  441. {{2.50000000e-1f, 2.04124145e-1f, -2.04124145e-1f, -1.29099445e-1f, 0.00000000e+0f}},
  442. {{2.50000000e-1f, 2.04124145e-1f, 2.04124145e-1f, 1.29099445e-1f, 0.00000000e+0f}},
  443. {{2.50000000e-1f, -2.04124145e-1f, 2.04124145e-1f, -1.29099445e-1f, 0.00000000e+0f}},
  444. {{2.50000000e-1f, -2.04124145e-1f, -2.04124145e-1f, 1.29099445e-1f, 0.00000000e+0f}},
  445. }},
  446. /*LF*/{{1.00000000e+0f, 1.00000000e+0f, 1.00000000e+0f}},
  447. {{
  448. {{2.50000000e-1f, 2.04124145e-1f, -2.04124145e-1f, -1.29099445e-1f, 0.00000000e+0f}},
  449. {{2.50000000e-1f, 2.04124145e-1f, 2.04124145e-1f, 1.29099445e-1f, 0.00000000e+0f}},
  450. {{2.50000000e-1f, -2.04124145e-1f, 2.04124145e-1f, -1.29099445e-1f, 0.00000000e+0f}},
  451. {{2.50000000e-1f, -2.04124145e-1f, -2.04124145e-1f, 1.29099445e-1f, 0.00000000e+0f}},
  452. }}
  453. };
  454. constexpr DecoderConfig<DualBand, 5> X51Config{
  455. 2, false, {{SideLeft, FrontLeft, FrontCenter, FrontRight, SideRight}},
  456. DevAmbiScaling::FuMa,
  457. /*HF*/{{1.00000000e+0f, 1.00000000e+0f, 1.00000000e+0f}},
  458. {{
  459. {{5.67316000e-1f, 4.22920000e-1f, -3.15495000e-1f, -6.34490000e-2f, -2.92380000e-2f}},
  460. {{3.68584000e-1f, 2.72349000e-1f, 3.21616000e-1f, 1.92645000e-1f, 4.82600000e-2f}},
  461. {{1.83579000e-1f, 0.00000000e+0f, 1.99588000e-1f, 0.00000000e+0f, 9.62820000e-2f}},
  462. {{3.68584000e-1f, -2.72349000e-1f, 3.21616000e-1f, -1.92645000e-1f, 4.82600000e-2f}},
  463. {{5.67316000e-1f, -4.22920000e-1f, -3.15495000e-1f, 6.34490000e-2f, -2.92380000e-2f}},
  464. }},
  465. /*LF*/{{1.00000000e+0f, 1.00000000e+0f, 1.00000000e+0f}},
  466. {{
  467. {{4.90109850e-1f, 3.77305010e-1f, -3.73106990e-1f, -1.25914530e-1f, 1.45133000e-2f}},
  468. {{1.49085730e-1f, 3.03561680e-1f, 1.53290060e-1f, 2.45112480e-1f, -1.50753130e-1f}},
  469. {{1.37654920e-1f, 0.00000000e+0f, 4.49417940e-1f, 0.00000000e+0f, 2.57844070e-1f}},
  470. {{1.49085730e-1f, -3.03561680e-1f, 1.53290060e-1f, -2.45112480e-1f, -1.50753130e-1f}},
  471. {{4.90109850e-1f, -3.77305010e-1f, -3.73106990e-1f, 1.25914530e-1f, 1.45133000e-2f}},
  472. }}
  473. };
  474. constexpr DecoderConfig<SingleBand, 5> X61Config{
  475. 2, false, {{SideLeft, FrontLeft, FrontRight, SideRight, BackCenter}},
  476. DevAmbiScaling::N3D,
  477. {{1.0f, 1.0f, 1.0f}},
  478. {{
  479. {{2.04460341e-1f, 2.17177926e-1f, -4.39996780e-2f, -2.60790269e-2f, -6.87239792e-2f}},
  480. {{1.58923161e-1f, 9.21772680e-2f, 1.59658796e-1f, 6.66278083e-2f, 3.84686854e-2f}},
  481. {{1.58923161e-1f, -9.21772680e-2f, 1.59658796e-1f, -6.66278083e-2f, 3.84686854e-2f}},
  482. {{2.04460341e-1f, -2.17177926e-1f, -4.39996780e-2f, 2.60790269e-2f, -6.87239792e-2f}},
  483. {{2.50001688e-1f, 0.00000000e+0f, -2.50000094e-1f, 0.00000000e+0f, 6.05133395e-2f}},
  484. }}
  485. };
  486. constexpr DecoderConfig<DualBand, 6> X71Config{
  487. 3, false, {{BackLeft, SideLeft, FrontLeft, FrontRight, SideRight, BackRight}},
  488. DevAmbiScaling::N3D,
  489. /*HF*/{{1.22474487e+0f, 1.13151672e+0f, 8.66025404e-1f, 4.68689571e-1f}},
  490. {{
  491. {{1.66666667e-1f, 9.62250449e-2f, -1.66666667e-1f, -1.49071198e-1f, 8.60662966e-2f, 7.96819073e-2f, 0.00000000e+0f}},
  492. {{1.66666667e-1f, 1.92450090e-1f, 0.00000000e+0f, 0.00000000e+0f, -1.72132593e-1f, -7.96819073e-2f, 0.00000000e+0f}},
  493. {{1.66666667e-1f, 9.62250449e-2f, 1.66666667e-1f, 1.49071198e-1f, 8.60662966e-2f, 7.96819073e-2f, 0.00000000e+0f}},
  494. {{1.66666667e-1f, -9.62250449e-2f, 1.66666667e-1f, -1.49071198e-1f, 8.60662966e-2f, -7.96819073e-2f, 0.00000000e+0f}},
  495. {{1.66666667e-1f, -1.92450090e-1f, 0.00000000e+0f, 0.00000000e+0f, -1.72132593e-1f, 7.96819073e-2f, 0.00000000e+0f}},
  496. {{1.66666667e-1f, -9.62250449e-2f, -1.66666667e-1f, 1.49071198e-1f, 8.60662966e-2f, -7.96819073e-2f, 0.00000000e+0f}},
  497. }},
  498. /*LF*/{{1.00000000e+0f, 1.00000000e+0f, 1.00000000e+0f, 1.00000000e+0f}},
  499. {{
  500. {{1.66666667e-1f, 9.62250449e-2f, -1.66666667e-1f, -1.49071198e-1f, 8.60662966e-2f, 7.96819073e-2f, 0.00000000e+0f}},
  501. {{1.66666667e-1f, 1.92450090e-1f, 0.00000000e+0f, 0.00000000e+0f, -1.72132593e-1f, -7.96819073e-2f, 0.00000000e+0f}},
  502. {{1.66666667e-1f, 9.62250449e-2f, 1.66666667e-1f, 1.49071198e-1f, 8.60662966e-2f, 7.96819073e-2f, 0.00000000e+0f}},
  503. {{1.66666667e-1f, -9.62250449e-2f, 1.66666667e-1f, -1.49071198e-1f, 8.60662966e-2f, -7.96819073e-2f, 0.00000000e+0f}},
  504. {{1.66666667e-1f, -1.92450090e-1f, 0.00000000e+0f, 0.00000000e+0f, -1.72132593e-1f, 7.96819073e-2f, 0.00000000e+0f}},
  505. {{1.66666667e-1f, -9.62250449e-2f, -1.66666667e-1f, 1.49071198e-1f, 8.60662966e-2f, -7.96819073e-2f, 0.00000000e+0f}},
  506. }}
  507. };
  508. constexpr DecoderConfig<DualBand, 6> X3D71Config{
  509. 1, true, {{Aux0, SideLeft, FrontLeft, FrontRight, SideRight, Aux1}},
  510. DevAmbiScaling::N3D,
  511. /*HF*/{{1.73205081e+0f, 1.00000000e+0f}},
  512. {{
  513. {{1.66669447e-1f, 0.00000000e+0f, 2.36070520e-1f, -1.66153012e-1f}},
  514. {{1.66669447e-1f, 2.04127551e-1f, -1.17487922e-1f, -1.66927066e-1f}},
  515. {{1.66669447e-1f, 2.04127551e-1f, 1.17487922e-1f, 1.66927066e-1f}},
  516. {{1.66669447e-1f, -2.04127551e-1f, 1.17487922e-1f, 1.66927066e-1f}},
  517. {{1.66669447e-1f, -2.04127551e-1f, -1.17487922e-1f, -1.66927066e-1f}},
  518. {{1.66669447e-1f, 0.00000000e+0f, -2.36070520e-1f, 1.66153012e-1f}},
  519. }},
  520. /*LF*/{{1.00000000e+0f, 1.00000000e+0f}},
  521. {{
  522. {{1.66669447e-1f, 0.00000000e+0f, 2.36070520e-1f, -1.66153012e-1f}},
  523. {{1.66669447e-1f, 2.04127551e-1f, -1.17487922e-1f, -1.66927066e-1f}},
  524. {{1.66669447e-1f, 2.04127551e-1f, 1.17487922e-1f, 1.66927066e-1f}},
  525. {{1.66669447e-1f, -2.04127551e-1f, 1.17487922e-1f, 1.66927066e-1f}},
  526. {{1.66669447e-1f, -2.04127551e-1f, -1.17487922e-1f, -1.66927066e-1f}},
  527. {{1.66669447e-1f, 0.00000000e+0f, -2.36070520e-1f, 1.66153012e-1f}},
  528. }}
  529. };
  530. void InitPanning(ALCdevice *device, const bool hqdec=false, const bool stablize=false,
  531. DecoderView decoder={})
  532. {
  533. if(!decoder)
  534. {
  535. switch(device->FmtChans)
  536. {
  537. case DevFmtMono: decoder = MonoConfig; break;
  538. case DevFmtStereo: decoder = StereoConfig; break;
  539. case DevFmtQuad: decoder = QuadConfig; break;
  540. case DevFmtX51: decoder = X51Config; break;
  541. case DevFmtX61: decoder = X61Config; break;
  542. case DevFmtX71: decoder = X71Config; break;
  543. case DevFmtX3D71: decoder = X3D71Config; break;
  544. case DevFmtAmbi3D:
  545. auto&& acnmap = GetAmbiLayout(device->mAmbiLayout);
  546. auto&& n3dscale = GetAmbiScales(device->mAmbiScale);
  547. /* For DevFmtAmbi3D, the ambisonic order is already set. */
  548. const size_t count{AmbiChannelsFromOrder(device->mAmbiOrder)};
  549. std::transform(acnmap.begin(), acnmap.begin()+count, std::begin(device->Dry.AmbiMap),
  550. [&n3dscale](const uint8_t &acn) noexcept -> BFChannelConfig
  551. { return BFChannelConfig{1.0f/n3dscale[acn], acn}; });
  552. AllocChannels(device, count, 0);
  553. float nfc_delay{device->configValue<float>("decoder", "nfc-ref-delay").value_or(0.0f)};
  554. if(nfc_delay > 0.0f)
  555. InitNearFieldCtrl(device, nfc_delay * SpeedOfSoundMetersPerSec, device->mAmbiOrder,
  556. true);
  557. return;
  558. }
  559. }
  560. const bool dual_band{hqdec && !decoder.mCoeffsLF.empty()};
  561. al::vector<ChannelDec> chancoeffs, chancoeffslf;
  562. for(size_t i{0u};i < decoder.mChannels.size();++i)
  563. {
  564. const uint idx{GetChannelIdxByName(device->RealOut, decoder.mChannels[i])};
  565. if(idx == INVALID_CHANNEL_INDEX)
  566. {
  567. ERR("Failed to find %s channel in device\n",
  568. GetLabelFromChannel(decoder.mChannels[i]));
  569. continue;
  570. }
  571. chancoeffs.resize(maxz(chancoeffs.size(), idx+1u), ChannelDec{});
  572. al::span<float,MaxAmbiChannels> coeffs{chancoeffs[idx]};
  573. size_t ambichan{0};
  574. for(uint o{0};o < decoder.mOrder+1u;++o)
  575. {
  576. const float order_gain{decoder.mOrderGain[o]};
  577. const size_t order_max{decoder.mIs3D ? AmbiChannelsFromOrder(o) :
  578. Ambi2DChannelsFromOrder(o)};
  579. for(;ambichan < order_max;++ambichan)
  580. coeffs[ambichan] = decoder.mCoeffs[i][ambichan] * order_gain;
  581. }
  582. if(!dual_band)
  583. continue;
  584. chancoeffslf.resize(maxz(chancoeffslf.size(), idx+1u), ChannelDec{});
  585. coeffs = chancoeffslf[idx];
  586. ambichan = 0;
  587. for(uint o{0};o < decoder.mOrder+1u;++o)
  588. {
  589. const float order_gain{decoder.mOrderGainLF[o]};
  590. const size_t order_max{decoder.mIs3D ? AmbiChannelsFromOrder(o) :
  591. Ambi2DChannelsFromOrder(o)};
  592. for(;ambichan < order_max;++ambichan)
  593. coeffs[ambichan] = decoder.mCoeffsLF[i][ambichan] * order_gain;
  594. }
  595. }
  596. /* For non-DevFmtAmbi3D, set the ambisonic order. */
  597. device->mAmbiOrder = decoder.mOrder;
  598. const size_t ambicount{decoder.mIs3D ? AmbiChannelsFromOrder(decoder.mOrder) :
  599. Ambi2DChannelsFromOrder(decoder.mOrder)};
  600. const al::span<const uint8_t> acnmap{decoder.mIs3D ? AmbiIndex::FromACN().data() :
  601. AmbiIndex::FromACN2D().data(), ambicount};
  602. auto&& coeffscale = GetAmbiScales(decoder.mScaling);
  603. std::transform(acnmap.begin(), acnmap.end(), std::begin(device->Dry.AmbiMap),
  604. [&coeffscale](const uint8_t &acn) noexcept
  605. { return BFChannelConfig{1.0f/coeffscale[acn], acn}; });
  606. AllocChannels(device, ambicount, device->channelsFromFmt());
  607. std::unique_ptr<FrontStablizer> stablizer;
  608. if(stablize)
  609. {
  610. /* Only enable the stablizer if the decoder does not output to the
  611. * front-center channel.
  612. */
  613. const auto cidx = device->RealOut.ChannelIndex[FrontCenter];
  614. bool hasfc{false};
  615. if(cidx < chancoeffs.size())
  616. {
  617. for(const auto &coeff : chancoeffs[cidx])
  618. hasfc |= coeff != 0.0f;
  619. }
  620. if(!hasfc && cidx < chancoeffslf.size())
  621. {
  622. for(const auto &coeff : chancoeffslf[cidx])
  623. hasfc |= coeff != 0.0f;
  624. }
  625. if(!hasfc)
  626. {
  627. stablizer = CreateStablizer(device->channelsFromFmt(), device->Frequency);
  628. TRACE("Front stablizer enabled\n");
  629. }
  630. }
  631. TRACE("Enabling %s-band %s-order%s ambisonic decoder\n",
  632. !dual_band ? "single" : "dual",
  633. (decoder.mOrder > 2) ? "third" :
  634. (decoder.mOrder > 1) ? "second" : "first",
  635. decoder.mIs3D ? " periphonic" : "");
  636. device->AmbiDecoder = BFormatDec::Create(ambicount, chancoeffs, chancoeffslf,
  637. device->mXOverFreq/static_cast<float>(device->Frequency), std::move(stablizer));
  638. }
  639. void InitHrtfPanning(ALCdevice *device)
  640. {
  641. constexpr float Deg180{al::numbers::pi_v<float>};
  642. constexpr float Deg_90{Deg180 / 2.0f /* 90 degrees*/};
  643. constexpr float Deg_45{Deg_90 / 2.0f /* 45 degrees*/};
  644. constexpr float Deg135{Deg_45 * 3.0f /*135 degrees*/};
  645. constexpr float Deg_35{6.154797087e-01f /* 35~ 36 degrees*/};
  646. constexpr float Deg_69{1.205932499e+00f /* 69~ 70 degrees*/};
  647. constexpr float Deg111{1.935660155e+00f /*110~111 degrees*/};
  648. constexpr float Deg_21{3.648638281e-01f /* 20~ 21 degrees*/};
  649. static const AngularPoint AmbiPoints1O[]{
  650. { EvRadians{ Deg_35}, AzRadians{-Deg_45} },
  651. { EvRadians{ Deg_35}, AzRadians{-Deg135} },
  652. { EvRadians{ Deg_35}, AzRadians{ Deg_45} },
  653. { EvRadians{ Deg_35}, AzRadians{ Deg135} },
  654. { EvRadians{-Deg_35}, AzRadians{-Deg_45} },
  655. { EvRadians{-Deg_35}, AzRadians{-Deg135} },
  656. { EvRadians{-Deg_35}, AzRadians{ Deg_45} },
  657. { EvRadians{-Deg_35}, AzRadians{ Deg135} },
  658. }, AmbiPoints2O[]{
  659. { EvRadians{ 0.0f}, AzRadians{ 0.0f} },
  660. { EvRadians{ 0.0f}, AzRadians{ Deg180} },
  661. { EvRadians{ 0.0f}, AzRadians{-Deg_90} },
  662. { EvRadians{ 0.0f}, AzRadians{ Deg_90} },
  663. { EvRadians{ Deg_90}, AzRadians{ 0.0f} },
  664. { EvRadians{-Deg_90}, AzRadians{ 0.0f} },
  665. { EvRadians{ Deg_35}, AzRadians{-Deg_45} },
  666. { EvRadians{ Deg_35}, AzRadians{-Deg135} },
  667. { EvRadians{ Deg_35}, AzRadians{ Deg_45} },
  668. { EvRadians{ Deg_35}, AzRadians{ Deg135} },
  669. { EvRadians{-Deg_35}, AzRadians{-Deg_45} },
  670. { EvRadians{-Deg_35}, AzRadians{-Deg135} },
  671. { EvRadians{-Deg_35}, AzRadians{ Deg_45} },
  672. { EvRadians{-Deg_35}, AzRadians{ Deg135} },
  673. }, AmbiPoints3O[]{
  674. { EvRadians{ Deg_69}, AzRadians{-Deg_90} },
  675. { EvRadians{ Deg_69}, AzRadians{ Deg_90} },
  676. { EvRadians{-Deg_69}, AzRadians{-Deg_90} },
  677. { EvRadians{-Deg_69}, AzRadians{ Deg_90} },
  678. { EvRadians{ 0.0f}, AzRadians{-Deg_69} },
  679. { EvRadians{ 0.0f}, AzRadians{-Deg111} },
  680. { EvRadians{ 0.0f}, AzRadians{ Deg_69} },
  681. { EvRadians{ 0.0f}, AzRadians{ Deg111} },
  682. { EvRadians{ Deg_21}, AzRadians{ 0.0f} },
  683. { EvRadians{ Deg_21}, AzRadians{ Deg180} },
  684. { EvRadians{-Deg_21}, AzRadians{ 0.0f} },
  685. { EvRadians{-Deg_21}, AzRadians{ Deg180} },
  686. { EvRadians{ Deg_35}, AzRadians{-Deg_45} },
  687. { EvRadians{ Deg_35}, AzRadians{-Deg135} },
  688. { EvRadians{ Deg_35}, AzRadians{ Deg_45} },
  689. { EvRadians{ Deg_35}, AzRadians{ Deg135} },
  690. { EvRadians{-Deg_35}, AzRadians{-Deg_45} },
  691. { EvRadians{-Deg_35}, AzRadians{-Deg135} },
  692. { EvRadians{-Deg_35}, AzRadians{ Deg_45} },
  693. { EvRadians{-Deg_35}, AzRadians{ Deg135} },
  694. };
  695. static const float AmbiMatrix1O[][MaxAmbiChannels]{
  696. { 1.250000000e-01f, 1.250000000e-01f, 1.250000000e-01f, 1.250000000e-01f },
  697. { 1.250000000e-01f, 1.250000000e-01f, 1.250000000e-01f, -1.250000000e-01f },
  698. { 1.250000000e-01f, -1.250000000e-01f, 1.250000000e-01f, 1.250000000e-01f },
  699. { 1.250000000e-01f, -1.250000000e-01f, 1.250000000e-01f, -1.250000000e-01f },
  700. { 1.250000000e-01f, 1.250000000e-01f, -1.250000000e-01f, 1.250000000e-01f },
  701. { 1.250000000e-01f, 1.250000000e-01f, -1.250000000e-01f, -1.250000000e-01f },
  702. { 1.250000000e-01f, -1.250000000e-01f, -1.250000000e-01f, 1.250000000e-01f },
  703. { 1.250000000e-01f, -1.250000000e-01f, -1.250000000e-01f, -1.250000000e-01f },
  704. }, AmbiMatrix2O[][MaxAmbiChannels]{
  705. { 7.142857143e-02f, 0.000000000e+00f, 0.000000000e+00f, 1.237179148e-01f, 0.000000000e+00f, 0.000000000e+00f, -7.453559925e-02f, 0.000000000e+00f, 1.290994449e-01f, },
  706. { 7.142857143e-02f, 0.000000000e+00f, 0.000000000e+00f, -1.237179148e-01f, 0.000000000e+00f, 0.000000000e+00f, -7.453559925e-02f, 0.000000000e+00f, 1.290994449e-01f, },
  707. { 7.142857143e-02f, 1.237179148e-01f, 0.000000000e+00f, 0.000000000e+00f, 0.000000000e+00f, 0.000000000e+00f, -7.453559925e-02f, 0.000000000e+00f, -1.290994449e-01f, },
  708. { 7.142857143e-02f, -1.237179148e-01f, 0.000000000e+00f, 0.000000000e+00f, 0.000000000e+00f, 0.000000000e+00f, -7.453559925e-02f, 0.000000000e+00f, -1.290994449e-01f, },
  709. { 7.142857143e-02f, 0.000000000e+00f, 1.237179148e-01f, 0.000000000e+00f, 0.000000000e+00f, 0.000000000e+00f, 1.490711985e-01f, 0.000000000e+00f, 0.000000000e+00f, },
  710. { 7.142857143e-02f, 0.000000000e+00f, -1.237179148e-01f, 0.000000000e+00f, 0.000000000e+00f, 0.000000000e+00f, 1.490711985e-01f, 0.000000000e+00f, 0.000000000e+00f, },
  711. { 7.142857143e-02f, 7.142857143e-02f, 7.142857143e-02f, 7.142857143e-02f, 9.682458366e-02f, 9.682458366e-02f, 0.000000000e+00f, 9.682458366e-02f, 0.000000000e+00f, },
  712. { 7.142857143e-02f, 7.142857143e-02f, 7.142857143e-02f, -7.142857143e-02f, -9.682458366e-02f, 9.682458366e-02f, 0.000000000e+00f, -9.682458366e-02f, 0.000000000e+00f, },
  713. { 7.142857143e-02f, -7.142857143e-02f, 7.142857143e-02f, 7.142857143e-02f, -9.682458366e-02f, -9.682458366e-02f, 0.000000000e+00f, 9.682458366e-02f, 0.000000000e+00f, },
  714. { 7.142857143e-02f, -7.142857143e-02f, 7.142857143e-02f, -7.142857143e-02f, 9.682458366e-02f, -9.682458366e-02f, 0.000000000e+00f, -9.682458366e-02f, 0.000000000e+00f, },
  715. { 7.142857143e-02f, 7.142857143e-02f, -7.142857143e-02f, 7.142857143e-02f, 9.682458366e-02f, -9.682458366e-02f, 0.000000000e+00f, -9.682458366e-02f, 0.000000000e+00f, },
  716. { 7.142857143e-02f, 7.142857143e-02f, -7.142857143e-02f, -7.142857143e-02f, -9.682458366e-02f, -9.682458366e-02f, 0.000000000e+00f, 9.682458366e-02f, 0.000000000e+00f, },
  717. { 7.142857143e-02f, -7.142857143e-02f, -7.142857143e-02f, 7.142857143e-02f, -9.682458366e-02f, 9.682458366e-02f, 0.000000000e+00f, -9.682458366e-02f, 0.000000000e+00f, },
  718. { 7.142857143e-02f, -7.142857143e-02f, -7.142857143e-02f, -7.142857143e-02f, 9.682458366e-02f, 9.682458366e-02f, 0.000000000e+00f, 9.682458366e-02f, 0.000000000e+00f, },
  719. }, AmbiMatrix3O[][MaxAmbiChannels]{
  720. { 5.000000000e-02f, 3.090169944e-02f, 8.090169944e-02f, 0.000000000e+00f, 0.000000000e+00f, 6.454972244e-02f, 9.045084972e-02f, 0.000000000e+00f, -1.232790000e-02f, -1.256118221e-01f, 0.000000000e+00f, 1.126112056e-01f, 7.944389175e-02f, 0.000000000e+00f, 2.421151497e-02f, 0.000000000e+00f, },
  721. { 5.000000000e-02f, -3.090169944e-02f, 8.090169944e-02f, 0.000000000e+00f, 0.000000000e+00f, -6.454972244e-02f, 9.045084972e-02f, 0.000000000e+00f, -1.232790000e-02f, 1.256118221e-01f, 0.000000000e+00f, -1.126112056e-01f, 7.944389175e-02f, 0.000000000e+00f, 2.421151497e-02f, 0.000000000e+00f, },
  722. { 5.000000000e-02f, 3.090169944e-02f, -8.090169944e-02f, 0.000000000e+00f, 0.000000000e+00f, -6.454972244e-02f, 9.045084972e-02f, 0.000000000e+00f, -1.232790000e-02f, -1.256118221e-01f, 0.000000000e+00f, 1.126112056e-01f, -7.944389175e-02f, 0.000000000e+00f, -2.421151497e-02f, 0.000000000e+00f, },
  723. { 5.000000000e-02f, -3.090169944e-02f, -8.090169944e-02f, 0.000000000e+00f, 0.000000000e+00f, 6.454972244e-02f, 9.045084972e-02f, 0.000000000e+00f, -1.232790000e-02f, 1.256118221e-01f, 0.000000000e+00f, -1.126112056e-01f, -7.944389175e-02f, 0.000000000e+00f, -2.421151497e-02f, 0.000000000e+00f, },
  724. { 5.000000000e-02f, 8.090169944e-02f, 0.000000000e+00f, 3.090169944e-02f, 6.454972244e-02f, 0.000000000e+00f, -5.590169944e-02f, 0.000000000e+00f, -7.216878365e-02f, -7.763237543e-02f, 0.000000000e+00f, -2.950836627e-02f, 0.000000000e+00f, -1.497759251e-01f, 0.000000000e+00f, -7.763237543e-02f, },
  725. { 5.000000000e-02f, 8.090169944e-02f, 0.000000000e+00f, -3.090169944e-02f, -6.454972244e-02f, 0.000000000e+00f, -5.590169944e-02f, 0.000000000e+00f, -7.216878365e-02f, -7.763237543e-02f, 0.000000000e+00f, -2.950836627e-02f, 0.000000000e+00f, 1.497759251e-01f, 0.000000000e+00f, 7.763237543e-02f, },
  726. { 5.000000000e-02f, -8.090169944e-02f, 0.000000000e+00f, 3.090169944e-02f, -6.454972244e-02f, 0.000000000e+00f, -5.590169944e-02f, 0.000000000e+00f, -7.216878365e-02f, 7.763237543e-02f, 0.000000000e+00f, 2.950836627e-02f, 0.000000000e+00f, -1.497759251e-01f, 0.000000000e+00f, -7.763237543e-02f, },
  727. { 5.000000000e-02f, -8.090169944e-02f, 0.000000000e+00f, -3.090169944e-02f, 6.454972244e-02f, 0.000000000e+00f, -5.590169944e-02f, 0.000000000e+00f, -7.216878365e-02f, 7.763237543e-02f, 0.000000000e+00f, 2.950836627e-02f, 0.000000000e+00f, 1.497759251e-01f, 0.000000000e+00f, 7.763237543e-02f, },
  728. { 5.000000000e-02f, 0.000000000e+00f, 3.090169944e-02f, 8.090169944e-02f, 0.000000000e+00f, 0.000000000e+00f, -3.454915028e-02f, 6.454972244e-02f, 8.449668365e-02f, 0.000000000e+00f, 0.000000000e+00f, 0.000000000e+00f, 3.034486645e-02f, -6.779013272e-02f, 1.659481923e-01f, 4.797944664e-02f, },
  729. { 5.000000000e-02f, 0.000000000e+00f, 3.090169944e-02f, -8.090169944e-02f, 0.000000000e+00f, 0.000000000e+00f, -3.454915028e-02f, -6.454972244e-02f, 8.449668365e-02f, 0.000000000e+00f, 0.000000000e+00f, 0.000000000e+00f, 3.034486645e-02f, 6.779013272e-02f, 1.659481923e-01f, -4.797944664e-02f, },
  730. { 5.000000000e-02f, 0.000000000e+00f, -3.090169944e-02f, 8.090169944e-02f, 0.000000000e+00f, 0.000000000e+00f, -3.454915028e-02f, -6.454972244e-02f, 8.449668365e-02f, 0.000000000e+00f, 0.000000000e+00f, 0.000000000e+00f, -3.034486645e-02f, -6.779013272e-02f, -1.659481923e-01f, 4.797944664e-02f, },
  731. { 5.000000000e-02f, 0.000000000e+00f, -3.090169944e-02f, -8.090169944e-02f, 0.000000000e+00f, 0.000000000e+00f, -3.454915028e-02f, 6.454972244e-02f, 8.449668365e-02f, 0.000000000e+00f, 0.000000000e+00f, 0.000000000e+00f, -3.034486645e-02f, 6.779013272e-02f, -1.659481923e-01f, -4.797944664e-02f, },
  732. { 5.000000000e-02f, 5.000000000e-02f, 5.000000000e-02f, 5.000000000e-02f, 6.454972244e-02f, 6.454972244e-02f, 0.000000000e+00f, 6.454972244e-02f, 0.000000000e+00f, 1.016220987e-01f, 6.338656910e-02f, -1.092600649e-02f, -7.364853795e-02f, 1.011266756e-01f, -7.086833869e-02f, -1.482646439e-02f, },
  733. { 5.000000000e-02f, 5.000000000e-02f, 5.000000000e-02f, -5.000000000e-02f, -6.454972244e-02f, 6.454972244e-02f, 0.000000000e+00f, -6.454972244e-02f, 0.000000000e+00f, 1.016220987e-01f, -6.338656910e-02f, -1.092600649e-02f, -7.364853795e-02f, -1.011266756e-01f, -7.086833869e-02f, 1.482646439e-02f, },
  734. { 5.000000000e-02f, -5.000000000e-02f, 5.000000000e-02f, 5.000000000e-02f, -6.454972244e-02f, -6.454972244e-02f, 0.000000000e+00f, 6.454972244e-02f, 0.000000000e+00f, -1.016220987e-01f, -6.338656910e-02f, 1.092600649e-02f, -7.364853795e-02f, 1.011266756e-01f, -7.086833869e-02f, -1.482646439e-02f, },
  735. { 5.000000000e-02f, -5.000000000e-02f, 5.000000000e-02f, -5.000000000e-02f, 6.454972244e-02f, -6.454972244e-02f, 0.000000000e+00f, -6.454972244e-02f, 0.000000000e+00f, -1.016220987e-01f, 6.338656910e-02f, 1.092600649e-02f, -7.364853795e-02f, -1.011266756e-01f, -7.086833869e-02f, 1.482646439e-02f, },
  736. { 5.000000000e-02f, 5.000000000e-02f, -5.000000000e-02f, 5.000000000e-02f, 6.454972244e-02f, -6.454972244e-02f, 0.000000000e+00f, -6.454972244e-02f, 0.000000000e+00f, 1.016220987e-01f, -6.338656910e-02f, -1.092600649e-02f, 7.364853795e-02f, 1.011266756e-01f, 7.086833869e-02f, -1.482646439e-02f, },
  737. { 5.000000000e-02f, 5.000000000e-02f, -5.000000000e-02f, -5.000000000e-02f, -6.454972244e-02f, -6.454972244e-02f, 0.000000000e+00f, 6.454972244e-02f, 0.000000000e+00f, 1.016220987e-01f, 6.338656910e-02f, -1.092600649e-02f, 7.364853795e-02f, -1.011266756e-01f, 7.086833869e-02f, 1.482646439e-02f, },
  738. { 5.000000000e-02f, -5.000000000e-02f, -5.000000000e-02f, 5.000000000e-02f, -6.454972244e-02f, 6.454972244e-02f, 0.000000000e+00f, -6.454972244e-02f, 0.000000000e+00f, -1.016220987e-01f, 6.338656910e-02f, 1.092600649e-02f, 7.364853795e-02f, 1.011266756e-01f, 7.086833869e-02f, -1.482646439e-02f, },
  739. { 5.000000000e-02f, -5.000000000e-02f, -5.000000000e-02f, -5.000000000e-02f, 6.454972244e-02f, 6.454972244e-02f, 0.000000000e+00f, 6.454972244e-02f, 0.000000000e+00f, -1.016220987e-01f, -6.338656910e-02f, 1.092600649e-02f, 7.364853795e-02f, -1.011266756e-01f, 7.086833869e-02f, 1.482646439e-02f, },
  740. };
  741. static const float AmbiOrderHFGain1O[MaxAmbiOrder+1]{
  742. /*ENRGY*/ 2.000000000e+00f, 1.154700538e+00f
  743. }, AmbiOrderHFGain2O[MaxAmbiOrder+1]{
  744. /*ENRGY 2.357022604e+00f, 1.825741858e+00f, 9.428090416e-01f*/
  745. /*AMP 1.000000000e+00f, 7.745966692e-01f, 4.000000000e-01f*/
  746. /*RMS*/ 9.128709292e-01f, 7.071067812e-01f, 3.651483717e-01f
  747. }, AmbiOrderHFGain3O[MaxAmbiOrder+1]{
  748. /*ENRGY 1.865086714e+00f, 1.606093894e+00f, 1.142055301e+00f, 5.683795528e-01f*/
  749. /*AMP 1.000000000e+00f, 8.611363116e-01f, 6.123336207e-01f, 3.047469850e-01f*/
  750. /*RMS*/ 8.340921354e-01f, 7.182670250e-01f, 5.107426573e-01f, 2.541870634e-01f
  751. };
  752. static_assert(al::size(AmbiPoints1O) == al::size(AmbiMatrix1O), "First-Order Ambisonic HRTF mismatch");
  753. static_assert(al::size(AmbiPoints2O) == al::size(AmbiMatrix2O), "Second-Order Ambisonic HRTF mismatch");
  754. static_assert(al::size(AmbiPoints3O) == al::size(AmbiMatrix3O), "Third-Order Ambisonic HRTF mismatch");
  755. /* A 700hz crossover frequency provides tighter sound imaging at the sweet
  756. * spot with ambisonic decoding, as the distance between the ears is closer
  757. * to half this frequency wavelength, which is the optimal point where the
  758. * response should change between optimizing phase vs volume. Normally this
  759. * tighter imaging is at the cost of a smaller sweet spot, but since the
  760. * listener is fixed in the center of the HRTF responses for the decoder,
  761. * we don't have to worry about ever being out of the sweet spot.
  762. *
  763. * A better option here may be to have the head radius as part of the HRTF
  764. * data set and calculate the optimal crossover frequency from that.
  765. */
  766. device->mXOverFreq = 700.0f;
  767. /* Don't bother with HOA when using full HRTF rendering. Nothing needs it,
  768. * and it eases the CPU/memory load.
  769. */
  770. device->mRenderMode = RenderMode::Hrtf;
  771. uint ambi_order{1};
  772. if(auto modeopt = device->configValue<std::string>(nullptr, "hrtf-mode"))
  773. {
  774. struct HrtfModeEntry {
  775. char name[8];
  776. RenderMode mode;
  777. uint order;
  778. };
  779. static const HrtfModeEntry hrtf_modes[]{
  780. { "full", RenderMode::Hrtf, 1 },
  781. { "ambi1", RenderMode::Normal, 1 },
  782. { "ambi2", RenderMode::Normal, 2 },
  783. { "ambi3", RenderMode::Normal, 3 },
  784. };
  785. const char *mode{modeopt->c_str()};
  786. if(al::strcasecmp(mode, "basic") == 0)
  787. {
  788. ERR("HRTF mode \"%s\" deprecated, substituting \"%s\"\n", mode, "ambi2");
  789. mode = "ambi2";
  790. }
  791. auto match_entry = [mode](const HrtfModeEntry &entry) -> bool
  792. { return al::strcasecmp(mode, entry.name) == 0; };
  793. auto iter = std::find_if(std::begin(hrtf_modes), std::end(hrtf_modes), match_entry);
  794. if(iter == std::end(hrtf_modes))
  795. ERR("Unexpected hrtf-mode: %s\n", mode);
  796. else
  797. {
  798. device->mRenderMode = iter->mode;
  799. ambi_order = iter->order;
  800. }
  801. }
  802. TRACE("%u%s order %sHRTF rendering enabled, using \"%s\"\n", ambi_order,
  803. (((ambi_order%100)/10) == 1) ? "th" :
  804. ((ambi_order%10) == 1) ? "st" :
  805. ((ambi_order%10) == 2) ? "nd" :
  806. ((ambi_order%10) == 3) ? "rd" : "th",
  807. (device->mRenderMode == RenderMode::Hrtf) ? "+ Full " : "",
  808. device->mHrtfName.c_str());
  809. al::span<const AngularPoint> AmbiPoints{AmbiPoints1O};
  810. const float (*AmbiMatrix)[MaxAmbiChannels]{AmbiMatrix1O};
  811. al::span<const float,MaxAmbiOrder+1> AmbiOrderHFGain{AmbiOrderHFGain1O};
  812. if(ambi_order >= 3)
  813. {
  814. AmbiPoints = AmbiPoints3O;
  815. AmbiMatrix = AmbiMatrix3O;
  816. AmbiOrderHFGain = AmbiOrderHFGain3O;
  817. }
  818. else if(ambi_order == 2)
  819. {
  820. AmbiPoints = AmbiPoints2O;
  821. AmbiMatrix = AmbiMatrix2O;
  822. AmbiOrderHFGain = AmbiOrderHFGain2O;
  823. }
  824. device->mAmbiOrder = ambi_order;
  825. const size_t count{AmbiChannelsFromOrder(ambi_order)};
  826. std::transform(AmbiIndex::FromACN().begin(), AmbiIndex::FromACN().begin()+count,
  827. std::begin(device->Dry.AmbiMap),
  828. [](const uint8_t &index) noexcept { return BFChannelConfig{1.0f, index}; }
  829. );
  830. AllocChannels(device, count, device->channelsFromFmt());
  831. HrtfStore *Hrtf{device->mHrtf.get()};
  832. auto hrtfstate = DirectHrtfState::Create(count);
  833. hrtfstate->build(Hrtf, device->mIrSize, AmbiPoints, AmbiMatrix, device->mXOverFreq,
  834. AmbiOrderHFGain);
  835. device->mHrtfState = std::move(hrtfstate);
  836. InitNearFieldCtrl(device, Hrtf->field[0].distance, ambi_order, true);
  837. }
  838. void InitUhjPanning(ALCdevice *device)
  839. {
  840. /* UHJ is always 2D first-order. */
  841. constexpr size_t count{Ambi2DChannelsFromOrder(1)};
  842. device->mAmbiOrder = 1;
  843. auto acnmap_begin = AmbiIndex::FromFuMa().begin();
  844. std::transform(acnmap_begin, acnmap_begin + count, std::begin(device->Dry.AmbiMap),
  845. [](const uint8_t &acn) noexcept -> BFChannelConfig
  846. { return BFChannelConfig{1.0f/AmbiScale::FromUHJ()[acn], acn}; });
  847. AllocChannels(device, count, device->channelsFromFmt());
  848. }
  849. } // namespace
  850. void aluInitRenderer(ALCdevice *device, int hrtf_id, al::optional<StereoEncoding> stereomode)
  851. {
  852. /* Hold the HRTF the device last used, in case it's used again. */
  853. HrtfStorePtr old_hrtf{std::move(device->mHrtf)};
  854. device->mHrtfState = nullptr;
  855. device->mHrtf = nullptr;
  856. device->mIrSize = 0;
  857. device->mHrtfName.clear();
  858. device->mXOverFreq = 400.0f;
  859. device->mRenderMode = RenderMode::Normal;
  860. if(device->FmtChans != DevFmtStereo)
  861. {
  862. old_hrtf = nullptr;
  863. if(stereomode && *stereomode == StereoEncoding::Hrtf)
  864. device->mHrtfStatus = ALC_HRTF_UNSUPPORTED_FORMAT_SOFT;
  865. const char *layout{nullptr};
  866. switch(device->FmtChans)
  867. {
  868. case DevFmtQuad: layout = "quad"; break;
  869. case DevFmtX51: layout = "surround51"; break;
  870. case DevFmtX61: layout = "surround61"; break;
  871. case DevFmtX71: layout = "surround71"; break;
  872. case DevFmtX3D71: layout = "surround3d71"; break;
  873. /* Mono, Stereo, and Ambisonics output don't use custom decoders. */
  874. case DevFmtMono:
  875. case DevFmtStereo:
  876. case DevFmtAmbi3D:
  877. break;
  878. }
  879. std::unique_ptr<DecoderConfig<DualBand,MAX_OUTPUT_CHANNELS>> decoder_store;
  880. DecoderView decoder{};
  881. float speakerdists[MAX_OUTPUT_CHANNELS]{};
  882. auto load_config = [device,&decoder_store,&decoder,&speakerdists](const char *config)
  883. {
  884. AmbDecConf conf{};
  885. if(auto err = conf.load(config))
  886. {
  887. ERR("Failed to load layout file %s\n", config);
  888. ERR(" %s\n", err->c_str());
  889. }
  890. else if(conf.NumSpeakers > MAX_OUTPUT_CHANNELS)
  891. ERR("Unsupported decoder speaker count %zu (max %d)\n", conf.NumSpeakers,
  892. MAX_OUTPUT_CHANNELS);
  893. else if(conf.ChanMask > Ambi3OrderMask)
  894. ERR("Unsupported decoder channel mask 0x%04x (max 0x%x)\n", conf.ChanMask,
  895. Ambi3OrderMask);
  896. else
  897. {
  898. device->mXOverFreq = clampf(conf.XOverFreq, 100.0f, 1000.0f);
  899. decoder_store = std::make_unique<DecoderConfig<DualBand,MAX_OUTPUT_CHANNELS>>();
  900. decoder = MakeDecoderView(device, &conf, *decoder_store);
  901. for(size_t i{0};i < decoder.mChannels.size();++i)
  902. speakerdists[i] = conf.Speakers[i].Distance;
  903. }
  904. };
  905. if(layout)
  906. {
  907. if(auto decopt = device->configValue<std::string>("decoder", layout))
  908. load_config(decopt->c_str());
  909. }
  910. /* Enable the stablizer only for formats that have front-left, front-
  911. * right, and front-center outputs.
  912. */
  913. const bool stablize{device->RealOut.ChannelIndex[FrontCenter] != INVALID_CHANNEL_INDEX
  914. && device->RealOut.ChannelIndex[FrontLeft] != INVALID_CHANNEL_INDEX
  915. && device->RealOut.ChannelIndex[FrontRight] != INVALID_CHANNEL_INDEX
  916. && device->getConfigValueBool(nullptr, "front-stablizer", 0) != 0};
  917. const bool hqdec{device->getConfigValueBool("decoder", "hq-mode", 1) != 0};
  918. InitPanning(device, hqdec, stablize, decoder);
  919. if(decoder.mOrder > 0)
  920. {
  921. float accum_dist{0.0f}, spkr_count{0.0f};
  922. for(auto dist : speakerdists)
  923. {
  924. if(dist > 0.0f)
  925. {
  926. accum_dist += dist;
  927. spkr_count += 1.0f;
  928. }
  929. }
  930. if(spkr_count > 0)
  931. {
  932. InitNearFieldCtrl(device, accum_dist / spkr_count, decoder.mOrder, decoder.mIs3D);
  933. InitDistanceComp(device, decoder.mChannels, speakerdists);
  934. }
  935. }
  936. if(auto *ambidec{device->AmbiDecoder.get()})
  937. {
  938. device->PostProcess = ambidec->hasStablizer() ? &ALCdevice::ProcessAmbiDecStablized
  939. : &ALCdevice::ProcessAmbiDec;
  940. }
  941. return;
  942. }
  943. /* If HRTF is explicitly requested, or if there's no explicit request and
  944. * the device is headphones, try to enable it.
  945. */
  946. if(stereomode.value_or(StereoEncoding::Default) == StereoEncoding::Hrtf
  947. || (!stereomode && device->Flags.test(DirectEar)))
  948. {
  949. if(device->mHrtfList.empty())
  950. device->enumerateHrtfs();
  951. if(hrtf_id >= 0 && static_cast<uint>(hrtf_id) < device->mHrtfList.size())
  952. {
  953. const std::string &hrtfname = device->mHrtfList[static_cast<uint>(hrtf_id)];
  954. if(HrtfStorePtr hrtf{GetLoadedHrtf(hrtfname, device->Frequency)})
  955. {
  956. device->mHrtf = std::move(hrtf);
  957. device->mHrtfName = hrtfname;
  958. }
  959. }
  960. if(!device->mHrtf)
  961. {
  962. for(const auto &hrtfname : device->mHrtfList)
  963. {
  964. if(HrtfStorePtr hrtf{GetLoadedHrtf(hrtfname, device->Frequency)})
  965. {
  966. device->mHrtf = std::move(hrtf);
  967. device->mHrtfName = hrtfname;
  968. break;
  969. }
  970. }
  971. }
  972. if(device->mHrtf)
  973. {
  974. old_hrtf = nullptr;
  975. HrtfStore *hrtf{device->mHrtf.get()};
  976. device->mIrSize = hrtf->irSize;
  977. if(auto hrtfsizeopt = device->configValue<uint>(nullptr, "hrtf-size"))
  978. {
  979. if(*hrtfsizeopt > 0 && *hrtfsizeopt < device->mIrSize)
  980. device->mIrSize = maxu(*hrtfsizeopt, MinIrLength);
  981. }
  982. InitHrtfPanning(device);
  983. device->PostProcess = &ALCdevice::ProcessHrtf;
  984. device->mHrtfStatus = ALC_HRTF_ENABLED_SOFT;
  985. return;
  986. }
  987. }
  988. old_hrtf = nullptr;
  989. if(stereomode.value_or(StereoEncoding::Default) == StereoEncoding::Uhj)
  990. {
  991. device->mUhjEncoder = std::make_unique<UhjEncoder>();
  992. TRACE("UHJ enabled\n");
  993. InitUhjPanning(device);
  994. device->PostProcess = &ALCdevice::ProcessUhj;
  995. return;
  996. }
  997. device->mRenderMode = RenderMode::Pairwise;
  998. if(device->Type != DeviceType::Loopback)
  999. {
  1000. if(auto cflevopt = device->configValue<int>(nullptr, "cf_level"))
  1001. {
  1002. if(*cflevopt > 0 && *cflevopt <= 6)
  1003. {
  1004. device->Bs2b = std::make_unique<bs2b>();
  1005. bs2b_set_params(device->Bs2b.get(), *cflevopt,
  1006. static_cast<int>(device->Frequency));
  1007. TRACE("BS2B enabled\n");
  1008. InitPanning(device);
  1009. device->PostProcess = &ALCdevice::ProcessBs2b;
  1010. return;
  1011. }
  1012. }
  1013. }
  1014. TRACE("Stereo rendering\n");
  1015. InitPanning(device);
  1016. device->PostProcess = &ALCdevice::ProcessAmbiDec;
  1017. }
  1018. void aluInitEffectPanning(EffectSlot *slot, ALCcontext *context)
  1019. {
  1020. DeviceBase *device{context->mDevice};
  1021. const size_t count{AmbiChannelsFromOrder(device->mAmbiOrder)};
  1022. auto wetbuffer_iter = context->mWetBuffers.end();
  1023. if(slot->mWetBuffer)
  1024. {
  1025. /* If the effect slot already has a wet buffer attached, allocate a new
  1026. * one in its place.
  1027. */
  1028. wetbuffer_iter = context->mWetBuffers.begin();
  1029. for(;wetbuffer_iter != context->mWetBuffers.end();++wetbuffer_iter)
  1030. {
  1031. if(wetbuffer_iter->get() == slot->mWetBuffer)
  1032. {
  1033. slot->mWetBuffer = nullptr;
  1034. slot->Wet.Buffer = {};
  1035. *wetbuffer_iter = WetBufferPtr{new(FamCount(count)) WetBuffer{count}};
  1036. break;
  1037. }
  1038. }
  1039. }
  1040. if(wetbuffer_iter == context->mWetBuffers.end())
  1041. {
  1042. /* Otherwise, search for an unused wet buffer. */
  1043. wetbuffer_iter = context->mWetBuffers.begin();
  1044. for(;wetbuffer_iter != context->mWetBuffers.end();++wetbuffer_iter)
  1045. {
  1046. if(!(*wetbuffer_iter)->mInUse)
  1047. break;
  1048. }
  1049. if(wetbuffer_iter == context->mWetBuffers.end())
  1050. {
  1051. /* Otherwise, allocate a new one to use. */
  1052. context->mWetBuffers.emplace_back(WetBufferPtr{new(FamCount(count)) WetBuffer{count}});
  1053. wetbuffer_iter = context->mWetBuffers.end()-1;
  1054. }
  1055. }
  1056. WetBuffer *wetbuffer{slot->mWetBuffer = wetbuffer_iter->get()};
  1057. wetbuffer->mInUse = true;
  1058. auto acnmap_begin = AmbiIndex::FromACN().begin();
  1059. auto iter = std::transform(acnmap_begin, acnmap_begin + count, slot->Wet.AmbiMap.begin(),
  1060. [](const uint8_t &acn) noexcept -> BFChannelConfig
  1061. { return BFChannelConfig{1.0f, acn}; });
  1062. std::fill(iter, slot->Wet.AmbiMap.end(), BFChannelConfig{});
  1063. slot->Wet.Buffer = wetbuffer->mBuffer;
  1064. }