device.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. #include "config.h"
  2. #include "device.h"
  3. #include <algorithm>
  4. #include <cstddef>
  5. #include <numeric>
  6. #include "al/buffer.h"
  7. #include "al/effect.h"
  8. #include "al/filter.h"
  9. #include "albit.h"
  10. #include "alnumeric.h"
  11. #include "atomic.h"
  12. #include "backends/base.h"
  13. #include "core/devformat.h"
  14. #include "core/hrtf.h"
  15. #include "core/logging.h"
  16. #include "core/mastering.h"
  17. #include "flexarray.h"
  18. namespace {
  19. using voidp = void*;
  20. } // namespace
  21. namespace al {
  22. Device::Device(DeviceType type) : DeviceBase{type}
  23. { }
  24. Device::~Device()
  25. {
  26. TRACE("Freeing device {}", voidp{this});
  27. Backend = nullptr;
  28. size_t count{std::accumulate(BufferList.cbegin(), BufferList.cend(), 0_uz,
  29. [](size_t cur, const BufferSubList &sublist) noexcept -> size_t
  30. { return cur + static_cast<uint>(al::popcount(~sublist.FreeMask)); })};
  31. if(count > 0)
  32. WARN("{} Buffer{} not deleted", count, (count==1)?"":"s");
  33. count = std::accumulate(EffectList.cbegin(), EffectList.cend(), 0_uz,
  34. [](size_t cur, const EffectSubList &sublist) noexcept -> size_t
  35. { return cur + static_cast<uint>(al::popcount(~sublist.FreeMask)); });
  36. if(count > 0)
  37. WARN("{} Effect{} not deleted", count, (count==1)?"":"s");
  38. count = std::accumulate(FilterList.cbegin(), FilterList.cend(), 0_uz,
  39. [](size_t cur, const FilterSubList &sublist) noexcept -> size_t
  40. { return cur + static_cast<uint>(al::popcount(~sublist.FreeMask)); });
  41. if(count > 0)
  42. WARN("{} Filter{} not deleted", count, (count==1)?"":"s");
  43. }
  44. void Device::enumerateHrtfs()
  45. {
  46. mHrtfList = EnumerateHrtf(configValue<std::string>({}, "hrtf-paths"));
  47. if(auto defhrtfopt = configValue<std::string>({}, "default-hrtf"))
  48. {
  49. auto iter = std::find(mHrtfList.begin(), mHrtfList.end(), *defhrtfopt);
  50. if(iter == mHrtfList.end())
  51. WARN("Failed to find default HRTF \"{}\"", *defhrtfopt);
  52. else if(iter != mHrtfList.begin())
  53. std::rotate(mHrtfList.begin(), iter, iter+1);
  54. }
  55. }
  56. auto Device::getOutputMode1() const noexcept -> OutputMode1
  57. {
  58. if(mContexts.load(std::memory_order_relaxed)->empty())
  59. return OutputMode1::Any;
  60. switch(FmtChans)
  61. {
  62. case DevFmtMono: return OutputMode1::Mono;
  63. case DevFmtStereo:
  64. if(mHrtf)
  65. return OutputMode1::Hrtf;
  66. else if(mUhjEncoder)
  67. return OutputMode1::Uhj2;
  68. return OutputMode1::StereoBasic;
  69. case DevFmtQuad: return OutputMode1::Quad;
  70. case DevFmtX51: return OutputMode1::X51;
  71. case DevFmtX61: return OutputMode1::X61;
  72. case DevFmtX71: return OutputMode1::X71;
  73. case DevFmtX714:
  74. case DevFmtX7144:
  75. case DevFmtX3D71:
  76. case DevFmtAmbi3D:
  77. break;
  78. }
  79. return OutputMode1::Any;
  80. }
  81. } // namespace al