13 #include "bufferline.h"
20 struct EffectSlotProps
;
24 struct VoicePropsItem
;
26 using uint
= unsigned int;
29 constexpr float SpeedOfSoundMetersPerSec
{343.3f
};
31 constexpr float AirAbsorbGainHF
{0.99426f
}; /* -0.05dB */
33 enum class DistanceModel
: unsigned char {
35 Inverse
, InverseClamped
,
36 Linear
, LinearClamped
,
37 Exponent
, ExponentClamped
,
39 Default
= InverseClamped
45 al::FlexArray
<FloatBufferLine
, 16> mBuffer
;
47 WetBuffer(size_t count
) : mBuffer
{count
} { }
49 DEF_FAM_NEWDEL(WetBuffer
, mBuffer
)
51 using WetBufferPtr
= std::unique_ptr
<WetBuffer
>;
55 std::array
<float,3> Position
;
56 std::array
<float,3> Velocity
;
57 std::array
<float,3> OrientAt
;
58 std::array
<float,3> OrientUp
;
61 float AirAbsorptionGainHF
;
64 float DopplerVelocity
;
66 bool SourceDistanceModel
;
67 DistanceModel mDistanceModel
;
69 std::atomic
<ContextProps
*> next
;
71 DEF_NEWDEL(ContextProps
)
74 struct ContextParams
{
75 /* Pointer to the most recent property values that are awaiting an update. */
76 std::atomic
<ContextProps
*> ContextUpdate
{nullptr};
78 alu::Vector Position
{};
79 alu::Matrix Matrix
{alu::Matrix::Identity()};
80 alu::Vector Velocity
{};
83 float MetersPerUnit
{1.0f
};
84 float AirAbsorptionGainHF
{AirAbsorbGainHF
};
86 float DopplerFactor
{1.0f
};
87 float SpeedOfSound
{SpeedOfSoundMetersPerSec
}; /* in units per sec! */
89 bool SourceDistanceModel
{false};
90 DistanceModel mDistanceModel
{};
94 DeviceBase
*const mDevice
;
96 /* Counter for the pre-mixing updates, in 31.1 fixed point (lowest bit
97 * indicates if updates are currently happening).
99 RefCount mUpdateCount
{0u};
100 std::atomic
<bool> mHoldUpdates
{false};
101 std::atomic
<bool> mStopVoicesOnDisconnect
{true};
103 float mGainBoost
{1.0f
};
105 /* Linked lists of unused property containers, free to use for future
108 std::atomic
<ContextProps
*> mFreeContextProps
{nullptr};
109 std::atomic
<VoicePropsItem
*> mFreeVoiceProps
{nullptr};
110 std::atomic
<EffectSlotProps
*> mFreeEffectslotProps
{nullptr};
112 /* The voice change tail is the beginning of the "free" elements, up to and
113 * *excluding* the current. If tail==current, there's no free elements and
114 * new ones need to be allocated. The current voice change is the element
115 * last processed, and any after are pending.
117 VoiceChange
*mVoiceChangeTail
{};
118 std::atomic
<VoiceChange
*> mCurrentVoiceChange
{};
120 void allocVoiceChanges();
121 void allocVoiceProps();
124 ContextParams mParams
;
126 using VoiceArray
= al::FlexArray
<Voice
*>;
127 std::atomic
<VoiceArray
*> mVoices
{};
128 std::atomic
<size_t> mActiveVoiceCount
{};
130 void allocVoices(size_t addcount
);
131 al::span
<Voice
*> getVoicesSpan() const noexcept
133 return {mVoices
.load(std::memory_order_relaxed
)->data(),
134 mActiveVoiceCount
.load(std::memory_order_relaxed
)};
136 al::span
<Voice
*> getVoicesSpanAcquired() const noexcept
138 return {mVoices
.load(std::memory_order_acquire
)->data(),
139 mActiveVoiceCount
.load(std::memory_order_acquire
)};
143 using EffectSlotArray
= al::FlexArray
<EffectSlot
*>;
144 std::atomic
<EffectSlotArray
*> mActiveAuxSlots
{nullptr};
146 std::thread mEventThread
;
147 al::semaphore mEventSem
;
148 std::unique_ptr
<RingBuffer
> mAsyncEvents
;
149 std::atomic
<uint
> mEnabledEvts
{0u};
151 /* Asynchronous voice change actions are processed as a linked list of
152 * VoiceChange objects by the mixer, which is atomically appended to.
153 * However, to avoid allocating each object individually, they're allocated
154 * in clusters that are stored in a vector for easy automatic cleanup.
156 using VoiceChangeCluster
= std::unique_ptr
<VoiceChange
[]>;
157 al::vector
<VoiceChangeCluster
> mVoiceChangeClusters
;
159 using VoiceCluster
= std::unique_ptr
<Voice
[]>;
160 al::vector
<VoiceCluster
> mVoiceClusters
;
162 using VoicePropsCluster
= std::unique_ptr
<VoicePropsItem
[]>;
163 al::vector
<VoicePropsCluster
> mVoicePropClusters
;
166 ContextBase(DeviceBase
*device
);
167 ContextBase(const ContextBase
&) = delete;
168 ContextBase
& operator=(const ContextBase
&) = delete;
172 #endif /* CORE_CONTEXT_H */