16 #include "alnumeric.h"
17 #include "core/device.h"
18 #include "intrusive_ptr.h"
22 #include "al/eax_x_ram.h"
30 using uint
= unsigned int;
33 struct BufferSubList
{
34 uint64_t FreeMask
{~0_u64
};
35 ALbuffer
*Buffers
{nullptr}; /* 64 */
37 BufferSubList() noexcept
= default;
38 BufferSubList(const BufferSubList
&) = delete;
39 BufferSubList(BufferSubList
&& rhs
) noexcept
: FreeMask
{rhs
.FreeMask
}, Buffers
{rhs
.Buffers
}
40 { rhs
.FreeMask
= ~0_u64
; rhs
.Buffers
= nullptr; }
43 BufferSubList
& operator=(const BufferSubList
&) = delete;
44 BufferSubList
& operator=(BufferSubList
&& rhs
) noexcept
45 { std::swap(FreeMask
, rhs
.FreeMask
); std::swap(Buffers
, rhs
.Buffers
); return *this; }
48 struct EffectSubList
{
49 uint64_t FreeMask
{~0_u64
};
50 ALeffect
*Effects
{nullptr}; /* 64 */
52 EffectSubList() noexcept
= default;
53 EffectSubList(const EffectSubList
&) = delete;
54 EffectSubList(EffectSubList
&& rhs
) noexcept
: FreeMask
{rhs
.FreeMask
}, Effects
{rhs
.Effects
}
55 { rhs
.FreeMask
= ~0_u64
; rhs
.Effects
= nullptr; }
58 EffectSubList
& operator=(const EffectSubList
&) = delete;
59 EffectSubList
& operator=(EffectSubList
&& rhs
) noexcept
60 { std::swap(FreeMask
, rhs
.FreeMask
); std::swap(Effects
, rhs
.Effects
); return *this; }
63 struct FilterSubList
{
64 uint64_t FreeMask
{~0_u64
};
65 ALfilter
*Filters
{nullptr}; /* 64 */
67 FilterSubList() noexcept
= default;
68 FilterSubList(const FilterSubList
&) = delete;
69 FilterSubList(FilterSubList
&& rhs
) noexcept
: FreeMask
{rhs
.FreeMask
}, Filters
{rhs
.Filters
}
70 { rhs
.FreeMask
= ~0_u64
; rhs
.Filters
= nullptr; }
73 FilterSubList
& operator=(const FilterSubList
&) = delete;
74 FilterSubList
& operator=(FilterSubList
&& rhs
) noexcept
75 { std::swap(FreeMask
, rhs
.FreeMask
); std::swap(Filters
, rhs
.Filters
); return *this; }
79 struct ALCdevice
: public al::intrusive_ref
<ALCdevice
>, DeviceBase
{
80 /* This lock protects the device state (format, update size, etc) from
81 * being from being changed in multiple threads, or being accessed while
82 * being changed. It's also used to serialize calls to the backend.
85 std::unique_ptr
<BackendBase
> Backend
;
87 ALCuint NumMonoSources
{};
88 ALCuint NumStereoSources
{};
90 // Maximum number of sources that can be created
92 // Maximum number of slots that can be created
93 uint AuxiliaryEffectSlotMax
{};
95 std::string mHrtfName
;
96 al::vector
<std::string
> mHrtfList
;
97 ALCenum mHrtfStatus
{ALC_FALSE
};
99 std::atomic
<ALCenum
> LastError
{ALC_NO_ERROR
};
101 // Map of Buffers for this device
102 std::mutex BufferLock
;
103 al::vector
<BufferSubList
> BufferList
;
105 // Map of Effects for this device
106 std::mutex EffectLock
;
107 al::vector
<EffectSubList
> EffectList
;
109 // Map of Filters for this device
110 std::mutex FilterLock
;
111 al::vector
<FilterSubList
> FilterList
;
114 ALsizei eax_x_ram_free_size
{eax_x_ram_max_size
};
118 ALCdevice(DeviceType type
);
121 void enumerateHrtfs();
123 bool getConfigValueBool(const char *block
, const char *key
, int def
)
124 { return GetConfigValueBool(DeviceName
.c_str(), block
, key
, def
); }
127 al::optional
<T
> configValue(const char *block
, const char *key
) = delete;
129 DEF_NEWDEL(ALCdevice
)
133 inline al::optional
<std::string
> ALCdevice::configValue(const char *block
, const char *key
)
134 { return ConfigValueStr(DeviceName
.c_str(), block
, key
); }
136 inline al::optional
<int> ALCdevice::configValue(const char *block
, const char *key
)
137 { return ConfigValueInt(DeviceName
.c_str(), block
, key
); }
139 inline al::optional
<uint
> ALCdevice::configValue(const char *block
, const char *key
)
140 { return ConfigValueUInt(DeviceName
.c_str(), block
, key
); }
142 inline al::optional
<float> ALCdevice::configValue(const char *block
, const char *key
)
143 { return ConfigValueFloat(DeviceName
.c_str(), block
, key
); }
145 inline al::optional
<bool> ALCdevice::configValue(const char *block
, const char *key
)
146 { return ConfigValueBool(DeviceName
.c_str(), block
, key
); }