Finalize AL_SOFT_UHJ
[openal-soft.git] / alc / device.h
blob44dfebd5a30ecb8865500284c1e90be1e0efe1b6
1 #ifndef ALC_DEVICE_H
2 #define ALC_DEVICE_H
4 #include <atomic>
5 #include <memory>
6 #include <mutex>
7 #include <stdint.h>
8 #include <string>
9 #include <utility>
11 #include "AL/alc.h"
12 #include "AL/alext.h"
14 #include "alconfig.h"
15 #include "almalloc.h"
16 #include "alnumeric.h"
17 #include "core/device.h"
18 #include "inprogext.h"
19 #include "intrusive_ptr.h"
20 #include "vector.h"
22 #ifdef ALSOFT_EAX
23 #include "al/eax_x_ram.h"
24 #endif // ALSOFT_EAX
26 struct ALbuffer;
27 struct ALeffect;
28 struct ALfilter;
29 struct BackendBase;
31 using uint = unsigned int;
34 struct BufferSubList {
35 uint64_t FreeMask{~0_u64};
36 ALbuffer *Buffers{nullptr}; /* 64 */
38 BufferSubList() noexcept = default;
39 BufferSubList(const BufferSubList&) = delete;
40 BufferSubList(BufferSubList&& rhs) noexcept : FreeMask{rhs.FreeMask}, Buffers{rhs.Buffers}
41 { rhs.FreeMask = ~0_u64; rhs.Buffers = nullptr; }
42 ~BufferSubList();
44 BufferSubList& operator=(const BufferSubList&) = delete;
45 BufferSubList& operator=(BufferSubList&& rhs) noexcept
46 { std::swap(FreeMask, rhs.FreeMask); std::swap(Buffers, rhs.Buffers); return *this; }
49 struct EffectSubList {
50 uint64_t FreeMask{~0_u64};
51 ALeffect *Effects{nullptr}; /* 64 */
53 EffectSubList() noexcept = default;
54 EffectSubList(const EffectSubList&) = delete;
55 EffectSubList(EffectSubList&& rhs) noexcept : FreeMask{rhs.FreeMask}, Effects{rhs.Effects}
56 { rhs.FreeMask = ~0_u64; rhs.Effects = nullptr; }
57 ~EffectSubList();
59 EffectSubList& operator=(const EffectSubList&) = delete;
60 EffectSubList& operator=(EffectSubList&& rhs) noexcept
61 { std::swap(FreeMask, rhs.FreeMask); std::swap(Effects, rhs.Effects); return *this; }
64 struct FilterSubList {
65 uint64_t FreeMask{~0_u64};
66 ALfilter *Filters{nullptr}; /* 64 */
68 FilterSubList() noexcept = default;
69 FilterSubList(const FilterSubList&) = delete;
70 FilterSubList(FilterSubList&& rhs) noexcept : FreeMask{rhs.FreeMask}, Filters{rhs.Filters}
71 { rhs.FreeMask = ~0_u64; rhs.Filters = nullptr; }
72 ~FilterSubList();
74 FilterSubList& operator=(const FilterSubList&) = delete;
75 FilterSubList& operator=(FilterSubList&& rhs) noexcept
76 { std::swap(FreeMask, rhs.FreeMask); std::swap(Filters, rhs.Filters); return *this; }
80 struct ALCdevice : public al::intrusive_ref<ALCdevice>, DeviceBase {
81 /* This lock protects the device state (format, update size, etc) from
82 * being from being changed in multiple threads, or being accessed while
83 * being changed. It's also used to serialize calls to the backend.
85 std::mutex StateLock;
86 std::unique_ptr<BackendBase> Backend;
88 ALCuint NumMonoSources{};
89 ALCuint NumStereoSources{};
91 // Maximum number of sources that can be created
92 uint SourcesMax{};
93 // Maximum number of slots that can be created
94 uint AuxiliaryEffectSlotMax{};
96 std::string mHrtfName;
97 al::vector<std::string> mHrtfList;
98 ALCenum mHrtfStatus{ALC_FALSE};
100 enum class OutputMode1 : ALCenum {
101 Any = ALC_ANY_SOFT,
102 Mono = ALC_MONO_SOFT,
103 Stereo = ALC_STEREO_SOFT,
104 StereoBasic = ALC_STEREO_BASIC_SOFT,
105 Uhj2 = ALC_STEREO_UHJ_SOFT,
106 Hrtf = ALC_STEREO_HRTF_SOFT,
107 Quad = ALC_QUAD_SOFT,
108 X51 = ALC_5POINT1_SOFT,
109 X61 = ALC_6POINT1_SOFT,
110 X71 = ALC_7POINT1_SOFT
112 OutputMode1 getOutputMode1() const noexcept;
114 using OutputMode = OutputMode1;
116 std::atomic<ALCenum> LastError{ALC_NO_ERROR};
118 // Map of Buffers for this device
119 std::mutex BufferLock;
120 al::vector<BufferSubList> BufferList;
122 // Map of Effects for this device
123 std::mutex EffectLock;
124 al::vector<EffectSubList> EffectList;
126 // Map of Filters for this device
127 std::mutex FilterLock;
128 al::vector<FilterSubList> FilterList;
130 #ifdef ALSOFT_EAX
131 ALuint eax_x_ram_free_size{eax_x_ram_max_size};
132 #endif // ALSOFT_EAX
135 ALCdevice(DeviceType type);
136 ~ALCdevice();
138 void enumerateHrtfs();
140 bool getConfigValueBool(const char *block, const char *key, int def)
141 { return GetConfigValueBool(DeviceName.c_str(), block, key, def); }
143 template<typename T>
144 al::optional<T> configValue(const char *block, const char *key) = delete;
146 DEF_NEWDEL(ALCdevice)
149 template<>
150 inline al::optional<std::string> ALCdevice::configValue(const char *block, const char *key)
151 { return ConfigValueStr(DeviceName.c_str(), block, key); }
152 template<>
153 inline al::optional<int> ALCdevice::configValue(const char *block, const char *key)
154 { return ConfigValueInt(DeviceName.c_str(), block, key); }
155 template<>
156 inline al::optional<uint> ALCdevice::configValue(const char *block, const char *key)
157 { return ConfigValueUInt(DeviceName.c_str(), block, key); }
158 template<>
159 inline al::optional<float> ALCdevice::configValue(const char *block, const char *key)
160 { return ConfigValueFloat(DeviceName.c_str(), block, key); }
161 template<>
162 inline al::optional<bool> ALCdevice::configValue(const char *block, const char *key)
163 { return ConfigValueBool(DeviceName.c_str(), block, key); }
165 #endif