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 the ends of a buffer for resampling.
158 * Note that the padding is symmetric (half at the beginning and half at the
161 #define MAX_RESAMPLER_PADDING 48
164 struct FrontStablizer
{
165 static constexpr size_t DelayLength
{256u};
167 alignas(16) float DelayBuf
[MAX_OUTPUT_CHANNELS
][DelayLength
];
169 BandSplitter LFilter
, RFilter
;
170 alignas(16) float LSplit
[2][BUFFERSIZE
];
171 alignas(16) float RSplit
[2][BUFFERSIZE
];
173 alignas(16) float TempBuf
[BUFFERSIZE
+ DelayLength
];
175 DEF_NEWDEL(FrontStablizer
)
180 /* Coefficient channel mapping for mixing to the buffer. */
181 std::array
<BFChannelConfig
,MAX_OUTPUT_CHANNELS
> AmbiMap
{};
183 al::span
<FloatBufferLine
> Buffer
;
186 struct RealMixParams
{
187 std::array
<ALuint
,MaxChannels
> ChannelIndex
{};
189 al::span
<FloatBufferLine
> Buffer
;
193 // Frequency was requested by the app or config file
195 // Channel configuration was requested by the config file
197 // Sample type was requested by the config file
200 // Specifies if the DSP is paused at user request
202 // Specifies if the device is currently running
208 struct ALCdevice
: public al::intrusive_ref
<ALCdevice
> {
209 std::atomic
<bool> Connected
{true};
210 const DeviceType Type
{};
216 DevFmtChannels FmtChans
{};
217 DevFmtType FmtType
{};
218 ALboolean IsHeadphones
{AL_FALSE
};
219 ALuint mAmbiOrder
{0};
220 /* For DevFmtAmbi* output only, specifies the channel order and
223 AmbiLayout mAmbiLayout
{AmbiLayout::Default
};
224 AmbiNorm mAmbiScale
{AmbiNorm::Default
};
226 ALCenum LimiterState
{ALC_DONT_CARE_SOFT
};
228 std::string DeviceName
;
231 al::bitfield
<DeviceFlagsCount
> Flags
{};
233 std::string HrtfName
;
234 al::vector
<EnumeratedHrtf
> HrtfList
;
235 ALCenum HrtfStatus
{ALC_FALSE
};
237 std::atomic
<ALCenum
> LastError
{ALC_NO_ERROR
};
239 // Maximum number of sources that can be created
241 // Maximum number of slots that can be created
242 ALuint AuxiliaryEffectSlotMax
{};
244 ALCuint NumMonoSources
{};
245 ALCuint NumStereoSources
{};
246 ALCuint NumAuxSends
{};
248 // Map of Buffers for this device
249 std::mutex BufferLock
;
250 al::vector
<BufferSubList
> BufferList
;
252 // Map of Effects for this device
253 std::mutex EffectLock
;
254 al::vector
<EffectSubList
> EffectList
;
256 // Map of Filters for this device
257 std::mutex FilterLock
;
258 al::vector
<FilterSubList
> FilterList
;
260 /* Rendering mode. */
261 RenderMode mRenderMode
{NormalRender
};
263 /* The average speaker distance as determined by the ambdec configuration,
264 * HRTF data set, or the NFC-HOA reference delay. Only used for NFC.
266 ALfloat AvgSpeakerDist
{0.0f
};
268 ALuint SamplesDone
{0u};
269 std::chrono::nanoseconds ClockBase
{0};
270 std::chrono::nanoseconds FixedLatency
{0};
272 /* Temp storage used for mixer processing. */
273 alignas(16) ALfloat SourceData
[BUFFERSIZE
+ MAX_RESAMPLER_PADDING
];
274 alignas(16) ALfloat ResampledData
[BUFFERSIZE
];
275 alignas(16) ALfloat FilteredData
[BUFFERSIZE
];
277 alignas(16) ALfloat HrtfSourceData
[BUFFERSIZE
+ HRTF_HISTORY_LENGTH
];
278 alignas(16) ALfloat NfcSampleData
[BUFFERSIZE
];
280 alignas(16) float2 HrtfAccumData
[BUFFERSIZE
+ HRIR_LENGTH
];
282 /* Mixing buffer used by the Dry mix and Real output. */
283 al::vector
<FloatBufferLine
, 16> MixBuffer
;
285 /* The "dry" path corresponds to the main output. */
287 ALuint NumChannelsPerOrder
[MAX_AMBI_ORDER
+1]{};
289 /* "Real" output, which will be written to the device buffer. May alias the
292 RealMixParams RealOut
;
294 /* HRTF state and info */
295 std::unique_ptr
<DirectHrtfState
> mHrtfState
;
296 HrtfEntry
*mHrtf
{nullptr};
298 /* Ambisonic-to-UHJ encoder */
299 std::unique_ptr
<Uhj2Encoder
> Uhj_Encoder
;
301 /* Ambisonic decoder for speakers */
302 std::unique_ptr
<BFormatDec
> AmbiDecoder
;
304 /* Stereo-to-binaural filter */
305 std::unique_ptr
<bs2b
> Bs2b
;
307 using PostProc
= void(ALCdevice::*)(const size_t SamplesToDo
);
308 PostProc PostProcess
{nullptr};
310 std::unique_ptr
<FrontStablizer
> Stablizer
;
312 std::unique_ptr
<Compressor
> Limiter
;
314 /* Delay buffers used to compensate for speaker distances. */
315 DistanceComp ChannelDelay
;
317 /* Dithering control. */
318 ALfloat DitherDepth
{0.0f
};
319 ALuint DitherSeed
{0u};
321 /* Running count of the mixer invocations, in 31.1 fixed point. This
322 * actually increments *twice* when mixing, first at the start and then at
323 * the end, so the bottom bit indicates if the device is currently mixing
324 * and the upper bits indicates how many mixes have been done.
326 RefCount MixCount
{0u};
328 // Contexts created on this device
329 std::atomic
<al::FlexArray
<ALCcontext
*>*> mContexts
{nullptr};
331 /* This lock protects the device state (format, update size, etc) from
332 * being from being changed in multiple threads, or being accessed while
333 * being changed. It's also used to serialize calls to the backend.
335 std::mutex StateLock
;
336 std::unique_ptr
<BackendBase
> Backend
;
339 ALCdevice(DeviceType type
);
340 ALCdevice(const ALCdevice
&) = delete;
341 ALCdevice
& operator=(const ALCdevice
&) = delete;
344 ALuint
bytesFromFmt() const noexcept
{ return BytesFromDevFmt(FmtType
); }
345 ALuint
channelsFromFmt() const noexcept
{ return ChannelsFromDevFmt(FmtChans
, mAmbiOrder
); }
346 ALuint
frameSizeFromFmt() const noexcept
{ return bytesFromFmt() * channelsFromFmt(); }
348 void ProcessHrtf(const size_t SamplesToDo
);
349 void ProcessAmbiDec(const size_t SamplesToDo
);
350 void ProcessUhj(const size_t SamplesToDo
);
351 void ProcessBs2b(const size_t SamplesToDo
);
353 inline void postProcess(const size_t SamplesToDo
)
354 { if LIKELY(PostProcess
) (this->*PostProcess
)(SamplesToDo
); }
356 DEF_NEWDEL(ALCdevice
)
359 /* Must be less than 15 characters (16 including terminating null) for
360 * compatibility with pthread_setname_np limitations. */
361 #define MIXER_THREAD_NAME "alsoft-mixer"
363 #define RECORD_THREAD_NAME "alsoft-record"
366 extern ALint RTPrioLevel
;
367 void SetRTPriority(void);
369 void SetDefaultChannelOrder(ALCdevice
*device
);
370 void SetDefaultWFXChannelOrder(ALCdevice
*device
);
372 const ALCchar
*DevFmtTypeString(DevFmtType type
) noexcept
;
373 const ALCchar
*DevFmtChannelsString(DevFmtChannels chans
) noexcept
;
376 * GetChannelIdxByName
378 * Returns the index for the given channel name (e.g. FrontCenter), or
379 * INVALID_CHANNEL_INDEX if it doesn't exist.
381 inline ALuint
GetChannelIdxByName(const RealMixParams
&real
, Channel chan
) noexcept
382 { return real
.ChannelIndex
[chan
]; }
383 #define INVALID_CHANNEL_INDEX ~0u
386 al::vector
<std::string
> SearchDataFiles(const char *match
, const char *subdir
);