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

165 lines
4.9 KiB

  1. #ifndef ALC_DEVICE_H
  2. #define ALC_DEVICE_H
  3. #include <atomic>
  4. #include <memory>
  5. #include <mutex>
  6. #include <stdint.h>
  7. #include <string>
  8. #include <utility>
  9. #include "AL/alc.h"
  10. #include "AL/alext.h"
  11. #include "alconfig.h"
  12. #include "almalloc.h"
  13. #include "alnumeric.h"
  14. #include "core/device.h"
  15. #include "inprogext.h"
  16. #include "intrusive_ptr.h"
  17. #include "vector.h"
  18. #ifdef ALSOFT_EAX
  19. #include "al/eax/x_ram.h"
  20. #endif // ALSOFT_EAX
  21. struct ALbuffer;
  22. struct ALeffect;
  23. struct ALfilter;
  24. struct BackendBase;
  25. using uint = unsigned int;
  26. struct BufferSubList {
  27. uint64_t FreeMask{~0_u64};
  28. ALbuffer *Buffers{nullptr}; /* 64 */
  29. BufferSubList() noexcept = default;
  30. BufferSubList(const BufferSubList&) = delete;
  31. BufferSubList(BufferSubList&& rhs) noexcept : FreeMask{rhs.FreeMask}, Buffers{rhs.Buffers}
  32. { rhs.FreeMask = ~0_u64; rhs.Buffers = nullptr; }
  33. ~BufferSubList();
  34. BufferSubList& operator=(const BufferSubList&) = delete;
  35. BufferSubList& operator=(BufferSubList&& rhs) noexcept
  36. { std::swap(FreeMask, rhs.FreeMask); std::swap(Buffers, rhs.Buffers); return *this; }
  37. };
  38. struct EffectSubList {
  39. uint64_t FreeMask{~0_u64};
  40. ALeffect *Effects{nullptr}; /* 64 */
  41. EffectSubList() noexcept = default;
  42. EffectSubList(const EffectSubList&) = delete;
  43. EffectSubList(EffectSubList&& rhs) noexcept : FreeMask{rhs.FreeMask}, Effects{rhs.Effects}
  44. { rhs.FreeMask = ~0_u64; rhs.Effects = nullptr; }
  45. ~EffectSubList();
  46. EffectSubList& operator=(const EffectSubList&) = delete;
  47. EffectSubList& operator=(EffectSubList&& rhs) noexcept
  48. { std::swap(FreeMask, rhs.FreeMask); std::swap(Effects, rhs.Effects); return *this; }
  49. };
  50. struct FilterSubList {
  51. uint64_t FreeMask{~0_u64};
  52. ALfilter *Filters{nullptr}; /* 64 */
  53. FilterSubList() noexcept = default;
  54. FilterSubList(const FilterSubList&) = delete;
  55. FilterSubList(FilterSubList&& rhs) noexcept : FreeMask{rhs.FreeMask}, Filters{rhs.Filters}
  56. { rhs.FreeMask = ~0_u64; rhs.Filters = nullptr; }
  57. ~FilterSubList();
  58. FilterSubList& operator=(const FilterSubList&) = delete;
  59. FilterSubList& operator=(FilterSubList&& rhs) noexcept
  60. { std::swap(FreeMask, rhs.FreeMask); std::swap(Filters, rhs.Filters); return *this; }
  61. };
  62. struct ALCdevice : public al::intrusive_ref<ALCdevice>, DeviceBase {
  63. /* This lock protects the device state (format, update size, etc) from
  64. * being from being changed in multiple threads, or being accessed while
  65. * being changed. It's also used to serialize calls to the backend.
  66. */
  67. std::mutex StateLock;
  68. std::unique_ptr<BackendBase> Backend;
  69. ALCuint NumMonoSources{};
  70. ALCuint NumStereoSources{};
  71. // Maximum number of sources that can be created
  72. uint SourcesMax{};
  73. // Maximum number of slots that can be created
  74. uint AuxiliaryEffectSlotMax{};
  75. std::string mHrtfName;
  76. al::vector<std::string> mHrtfList;
  77. ALCenum mHrtfStatus{ALC_FALSE};
  78. enum class OutputMode1 : ALCenum {
  79. Any = ALC_ANY_SOFT,
  80. Mono = ALC_MONO_SOFT,
  81. Stereo = ALC_STEREO_SOFT,
  82. StereoBasic = ALC_STEREO_BASIC_SOFT,
  83. Uhj2 = ALC_STEREO_UHJ_SOFT,
  84. Hrtf = ALC_STEREO_HRTF_SOFT,
  85. Quad = ALC_QUAD_SOFT,
  86. X51 = ALC_SURROUND_5_1_SOFT,
  87. X61 = ALC_SURROUND_6_1_SOFT,
  88. X71 = ALC_SURROUND_7_1_SOFT
  89. };
  90. OutputMode1 getOutputMode1() const noexcept;
  91. using OutputMode = OutputMode1;
  92. std::atomic<ALCenum> LastError{ALC_NO_ERROR};
  93. // Map of Buffers for this device
  94. std::mutex BufferLock;
  95. al::vector<BufferSubList> BufferList;
  96. // Map of Effects for this device
  97. std::mutex EffectLock;
  98. al::vector<EffectSubList> EffectList;
  99. // Map of Filters for this device
  100. std::mutex FilterLock;
  101. al::vector<FilterSubList> FilterList;
  102. #ifdef ALSOFT_EAX
  103. ALuint eax_x_ram_free_size{eax_x_ram_max_size};
  104. #endif // ALSOFT_EAX
  105. ALCdevice(DeviceType type);
  106. ~ALCdevice();
  107. void enumerateHrtfs();
  108. bool getConfigValueBool(const char *block, const char *key, bool def)
  109. { return GetConfigValueBool(DeviceName.c_str(), block, key, def); }
  110. template<typename T>
  111. inline al::optional<T> configValue(const char *block, const char *key) = delete;
  112. DEF_NEWDEL(ALCdevice)
  113. };
  114. template<>
  115. inline al::optional<std::string> ALCdevice::configValue(const char *block, const char *key)
  116. { return ConfigValueStr(DeviceName.c_str(), block, key); }
  117. template<>
  118. inline al::optional<int> ALCdevice::configValue(const char *block, const char *key)
  119. { return ConfigValueInt(DeviceName.c_str(), block, key); }
  120. template<>
  121. inline al::optional<uint> ALCdevice::configValue(const char *block, const char *key)
  122. { return ConfigValueUInt(DeviceName.c_str(), block, key); }
  123. template<>
  124. inline al::optional<float> ALCdevice::configValue(const char *block, const char *key)
  125. { return ConfigValueFloat(DeviceName.c_str(), block, key); }
  126. template<>
  127. inline al::optional<bool> ALCdevice::configValue(const char *block, const char *key)
  128. { return ConfigValueBool(DeviceName.c_str(), block, key); }
  129. #endif