21 #include "alnumeric.h"
25 #include "devformat.h"
26 #include "filters/splitter.h"
28 #include "inprogext.h"
29 #include "intrusive_ptr.h"
43 #define MIN_OUTPUT_RATE 8000
44 #define DEFAULT_OUTPUT_RATE 44100
45 #define DEFAULT_UPDATE_SIZE 882 /* 20ms */
46 #define DEFAULT_NUM_UPDATES 3
63 struct BufferSubList
{
64 uint64_t FreeMask
{~0_u64
};
65 ALbuffer
*Buffers
{nullptr}; /* 64 */
67 BufferSubList() noexcept
= default;
68 BufferSubList(const BufferSubList
&) = delete;
69 BufferSubList(BufferSubList
&& rhs
) noexcept
: FreeMask
{rhs
.FreeMask
}, Buffers
{rhs
.Buffers
}
70 { rhs
.FreeMask
= ~0_u64
; rhs
.Buffers
= nullptr; }
73 BufferSubList
& operator=(const BufferSubList
&) = delete;
74 BufferSubList
& operator=(BufferSubList
&& rhs
) noexcept
75 { std::swap(FreeMask
, rhs
.FreeMask
); std::swap(Buffers
, rhs
.Buffers
); return *this; }
78 struct EffectSubList
{
79 uint64_t FreeMask
{~0_u64
};
80 ALeffect
*Effects
{nullptr}; /* 64 */
82 EffectSubList() noexcept
= default;
83 EffectSubList(const EffectSubList
&) = delete;
84 EffectSubList(EffectSubList
&& rhs
) noexcept
: FreeMask
{rhs
.FreeMask
}, Effects
{rhs
.Effects
}
85 { rhs
.FreeMask
= ~0_u64
; rhs
.Effects
= nullptr; }
88 EffectSubList
& operator=(const EffectSubList
&) = delete;
89 EffectSubList
& operator=(EffectSubList
&& rhs
) noexcept
90 { std::swap(FreeMask
, rhs
.FreeMask
); std::swap(Effects
, rhs
.Effects
); return *this; }
93 struct FilterSubList
{
94 uint64_t FreeMask
{~0_u64
};
95 ALfilter
*Filters
{nullptr}; /* 64 */
97 FilterSubList() noexcept
= default;
98 FilterSubList(const FilterSubList
&) = delete;
99 FilterSubList(FilterSubList
&& rhs
) noexcept
: FreeMask
{rhs
.FreeMask
}, Filters
{rhs
.Filters
}
100 { rhs
.FreeMask
= ~0_u64
; rhs
.Filters
= nullptr; }
103 FilterSubList
& operator=(const FilterSubList
&) = delete;
104 FilterSubList
& operator=(FilterSubList
&& rhs
) noexcept
105 { std::swap(FreeMask
, rhs
.FreeMask
); std::swap(Filters
, rhs
.Filters
); return *this; }
109 /* Maximum delay in samples for speaker distance compensation. */
110 #define MAX_DELAY_LENGTH 1024
116 ALuint Length
{0u}; /* Valid range is [0...MAX_DELAY_LENGTH). */
117 ALfloat
*Buffer
{nullptr};
121 std::array
<DistData
,MAX_OUTPUT_CHANNELS
> mChannels
;
122 al::vector
<ALfloat
,16> mSamples
;
125 void setSampleCount(size_t new_size
) { mSamples
.resize(new_size
); }
126 void clear() noexcept
128 for(auto &chan
: mChannels
)
132 chan
.Buffer
= nullptr;
134 using SampleVecT
= decltype(mSamples
);
135 SampleVecT
{}.swap(mSamples
);
138 ALfloat
*getSamples() noexcept
{ return mSamples
.data(); }
140 al::span
<DistData
,MAX_OUTPUT_CHANNELS
> as_span() { return mChannels
; }
143 struct BFChannelConfig
{
148 /* Size for temporary storage of buffer data, in ALfloats. Larger values need
149 * more memory, while smaller values may need more iterations. The value needs
150 * to be a sensible size, however, as it constrains the max stepping value used
151 * for mixing, as well as the maximum number of samples per mixing iteration.
153 #define BUFFERSIZE 1024
155 using FloatBufferLine
= std::array
<float,BUFFERSIZE
>;
157 /* Maximum number of samples to pad on either end of a buffer for resampling.
158 * Note that both the beginning and end need padding!
160 #define MAX_RESAMPLE_PADDING 24
163 struct FrontStablizer
{
164 static constexpr size_t DelayLength
{256u};
166 alignas(16) float DelayBuf
[MAX_OUTPUT_CHANNELS
][DelayLength
];
168 BandSplitter LFilter
, RFilter
;
169 alignas(16) float LSplit
[2][BUFFERSIZE
];
170 alignas(16) float RSplit
[2][BUFFERSIZE
];
172 alignas(16) float TempBuf
[BUFFERSIZE
+ DelayLength
];
174 DEF_NEWDEL(FrontStablizer
)
179 /* Coefficient channel mapping for mixing to the buffer. */
180 std::array
<BFChannelConfig
,MAX_OUTPUT_CHANNELS
> AmbiMap
{};
182 al::span
<FloatBufferLine
> Buffer
;
185 struct RealMixParams
{
186 std::array
<ALuint
,MaxChannels
> ChannelIndex
{};
188 al::span
<FloatBufferLine
> Buffer
;
192 // Frequency was requested by the app or config file
194 // Channel configuration was requested by the config file
196 // Sample type was requested by the config file
199 // Specifies if the DSP is paused at user request
201 // Specifies if the device is currently running
207 struct ALCdevice
: public al::intrusive_ref
<ALCdevice
> {
208 std::atomic
<bool> Connected
{true};
209 const DeviceType Type
{};
215 DevFmtChannels FmtChans
{};
216 DevFmtType FmtType
{};
217 ALboolean IsHeadphones
{AL_FALSE
};
218 ALuint mAmbiOrder
{0};
219 /* For DevFmtAmbi* output only, specifies the channel order and
222 AmbiLayout mAmbiLayout
{AmbiLayout::Default
};
223 AmbiNorm mAmbiScale
{AmbiNorm::Default
};
225 ALCenum LimiterState
{ALC_DONT_CARE_SOFT
};
227 std::string DeviceName
;
230 al::bitfield
<DeviceFlagsCount
> Flags
{};
232 std::string HrtfName
;
233 al::vector
<EnumeratedHrtf
> HrtfList
;
234 ALCenum HrtfStatus
{ALC_FALSE
};
236 std::atomic
<ALCenum
> LastError
{ALC_NO_ERROR
};
238 // Maximum number of sources that can be created
240 // Maximum number of slots that can be created
241 ALuint AuxiliaryEffectSlotMax
{};
243 ALCuint NumMonoSources
{};
244 ALCuint NumStereoSources
{};
245 ALCuint NumAuxSends
{};
247 // Map of Buffers for this device
248 std::mutex BufferLock
;
249 al::vector
<BufferSubList
> BufferList
;
251 // Map of Effects for this device
252 std::mutex EffectLock
;
253 al::vector
<EffectSubList
> EffectList
;
255 // Map of Filters for this device
256 std::mutex FilterLock
;
257 al::vector
<FilterSubList
> FilterList
;
259 /* Rendering mode. */
260 RenderMode mRenderMode
{NormalRender
};
262 /* The average speaker distance as determined by the ambdec configuration,
263 * HRTF data set, or the NFC-HOA reference delay. Only used for NFC.
265 ALfloat AvgSpeakerDist
{0.0f
};
267 ALuint SamplesDone
{0u};
268 std::chrono::nanoseconds ClockBase
{0};
269 std::chrono::nanoseconds FixedLatency
{0};
271 /* Temp storage used for mixer processing. */
272 alignas(16) ALfloat SourceData
[BUFFERSIZE
+ MAX_RESAMPLE_PADDING
*2];
273 alignas(16) ALfloat ResampledData
[BUFFERSIZE
];
274 alignas(16) ALfloat FilteredData
[BUFFERSIZE
];
276 alignas(16) ALfloat HrtfSourceData
[BUFFERSIZE
+ HRTF_HISTORY_LENGTH
];
277 alignas(16) ALfloat NfcSampleData
[BUFFERSIZE
];
279 alignas(16) float2 HrtfAccumData
[BUFFERSIZE
+ HRIR_LENGTH
];
281 /* Mixing buffer used by the Dry mix and Real output. */
282 al::vector
<FloatBufferLine
, 16> MixBuffer
;
284 /* The "dry" path corresponds to the main output. */
286 ALuint NumChannelsPerOrder
[MAX_AMBI_ORDER
+1]{};
288 /* "Real" output, which will be written to the device buffer. May alias the
291 RealMixParams RealOut
;
293 /* HRTF state and info */
294 std::unique_ptr
<DirectHrtfState
> mHrtfState
;
295 HrtfEntry
*mHrtf
{nullptr};
297 /* Ambisonic-to-UHJ encoder */
298 std::unique_ptr
<Uhj2Encoder
> Uhj_Encoder
;
300 /* Ambisonic decoder for speakers */
301 std::unique_ptr
<BFormatDec
> AmbiDecoder
;
303 /* Stereo-to-binaural filter */
304 std::unique_ptr
<bs2b
> Bs2b
;
306 using PostProc
= void(ALCdevice::*)(const size_t SamplesToDo
);
307 PostProc PostProcess
{nullptr};
309 std::unique_ptr
<FrontStablizer
> Stablizer
;
311 std::unique_ptr
<Compressor
> Limiter
;
313 /* Delay buffers used to compensate for speaker distances. */
314 DistanceComp ChannelDelay
;
316 /* Dithering control. */
317 ALfloat DitherDepth
{0.0f
};
318 ALuint DitherSeed
{0u};
320 /* Running count of the mixer invocations, in 31.1 fixed point. This
321 * actually increments *twice* when mixing, first at the start and then at
322 * the end, so the bottom bit indicates if the device is currently mixing
323 * and the upper bits indicates how many mixes have been done.
325 RefCount MixCount
{0u};
327 // Contexts created on this device
328 std::atomic
<al::FlexArray
<ALCcontext
*>*> mContexts
{nullptr};
330 /* This lock protects the device state (format, update size, etc) from
331 * being from being changed in multiple threads, or being accessed while
332 * being changed. It's also used to serialize calls to the backend.
334 std::mutex StateLock
;
335 std::unique_ptr
<BackendBase
> Backend
;
338 ALCdevice(DeviceType type
);
339 ALCdevice(const ALCdevice
&) = delete;
340 ALCdevice
& operator=(const ALCdevice
&) = delete;
343 ALuint
bytesFromFmt() const noexcept
{ return BytesFromDevFmt(FmtType
); }
344 ALuint
channelsFromFmt() const noexcept
{ return ChannelsFromDevFmt(FmtChans
, mAmbiOrder
); }
345 ALuint
frameSizeFromFmt() const noexcept
{ return bytesFromFmt() * channelsFromFmt(); }
347 void ProcessHrtf(const size_t SamplesToDo
);
348 void ProcessAmbiDec(const size_t SamplesToDo
);
349 void ProcessUhj(const size_t SamplesToDo
);
350 void ProcessBs2b(const size_t SamplesToDo
);
352 inline void postProcess(const size_t SamplesToDo
)
353 { if LIKELY(PostProcess
) (this->*PostProcess
)(SamplesToDo
); }
355 DEF_NEWDEL(ALCdevice
)
358 /* Must be less than 15 characters (16 including terminating null) for
359 * compatibility with pthread_setname_np limitations. */
360 #define MIXER_THREAD_NAME "alsoft-mixer"
362 #define RECORD_THREAD_NAME "alsoft-record"
365 extern ALint RTPrioLevel
;
366 void SetRTPriority(void);
368 void SetDefaultChannelOrder(ALCdevice
*device
);
369 void SetDefaultWFXChannelOrder(ALCdevice
*device
);
371 const ALCchar
*DevFmtTypeString(DevFmtType type
) noexcept
;
372 const ALCchar
*DevFmtChannelsString(DevFmtChannels chans
) noexcept
;
375 * GetChannelIdxByName
377 * Returns the index for the given channel name (e.g. FrontCenter), or
378 * INVALID_CHANNEL_INDEX if it doesn't exist.
380 inline ALuint
GetChannelIdxByName(const RealMixParams
&real
, Channel chan
) noexcept
381 { return real
.ChannelIndex
[chan
]; }
382 #define INVALID_CHANNEL_INDEX ~0u
385 al::vector
<std::string
> SearchDataFiles(const char *match
, const char *subdir
);