]> git.tdb.fi Git - ext/openal.git/blob - alc/device.h
Tweak some types to work around an MSVC compile error
[ext/openal.git] / alc / device.h
1 #ifndef ALC_DEVICE_H
2 #define ALC_DEVICE_H
3
4 #include <atomic>
5 #include <memory>
6 #include <mutex>
7 #include <stdint.h>
8 #include <string>
9 #include <utility>
10
11 #include "AL/alc.h"
12 #include "AL/alext.h"
13
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"
21
22 #ifdef ALSOFT_EAX
23 #include "al/eax/x_ram.h"
24 #endif // ALSOFT_EAX
25
26 struct ALbuffer;
27 struct ALeffect;
28 struct ALfilter;
29 struct BackendBase;
30
31 using uint = unsigned int;
32
33
34 struct BufferSubList {
35     uint64_t FreeMask{~0_u64};
36     ALbuffer *Buffers{nullptr}; /* 64 */
37
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();
43
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; }
47 };
48
49 struct EffectSubList {
50     uint64_t FreeMask{~0_u64};
51     ALeffect *Effects{nullptr}; /* 64 */
52
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();
58
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; }
62 };
63
64 struct FilterSubList {
65     uint64_t FreeMask{~0_u64};
66     ALfilter *Filters{nullptr}; /* 64 */
67
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();
73
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; }
77 };
78
79
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.
84      */
85     std::mutex StateLock;
86     std::unique_ptr<BackendBase> Backend;
87
88     ALCuint NumMonoSources{};
89     ALCuint NumStereoSources{};
90
91     // Maximum number of sources that can be created
92     uint SourcesMax{};
93     // Maximum number of slots that can be created
94     uint AuxiliaryEffectSlotMax{};
95
96     std::string mHrtfName;
97     al::vector<std::string> mHrtfList;
98     ALCenum mHrtfStatus{ALC_FALSE};
99
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_SURROUND_5_1_SOFT,
109         X61 = ALC_SURROUND_6_1_SOFT,
110         X71 = ALC_SURROUND_7_1_SOFT
111     };
112     OutputMode1 getOutputMode1() const noexcept;
113
114     using OutputMode = OutputMode1;
115
116     std::atomic<ALCenum> LastError{ALC_NO_ERROR};
117
118     // Map of Buffers for this device
119     std::mutex BufferLock;
120     al::vector<BufferSubList> BufferList;
121
122     // Map of Effects for this device
123     std::mutex EffectLock;
124     al::vector<EffectSubList> EffectList;
125
126     // Map of Filters for this device
127     std::mutex FilterLock;
128     al::vector<FilterSubList> FilterList;
129
130 #ifdef ALSOFT_EAX
131     ALuint eax_x_ram_free_size{eax_x_ram_max_size};
132 #endif // ALSOFT_EAX
133
134
135     ALCdevice(DeviceType type);
136     ~ALCdevice();
137
138     void enumerateHrtfs();
139
140     bool getConfigValueBool(const char *block, const char *key, bool def)
141     { return GetConfigValueBool(DeviceName.c_str(), block, key, def); }
142
143     template<typename T>
144     inline al::optional<T> configValue(const char *block, const char *key) = delete;
145
146     DEF_NEWDEL(ALCdevice)
147 };
148
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); }
164
165 #endif