Add "fast" variants for the bsinc resamplers
[openal-soft.git] / alc / alcmain.h
blob9182d5d4b25e1f96e8826c81f8eaf98a3f9b9cf0
1 #ifndef ALC_MAIN_H
2 #define ALC_MAIN_H
4 #include <algorithm>
5 #include <array>
6 #include <atomic>
7 #include <chrono>
8 #include <cstdint>
9 #include <cstddef>
10 #include <memory>
11 #include <mutex>
12 #include <string>
13 #include <utility>
15 #include "AL/al.h"
16 #include "AL/alc.h"
17 #include "AL/alext.h"
19 #include "albyte.h"
20 #include "almalloc.h"
21 #include "alnumeric.h"
22 #include "alspan.h"
23 #include "ambidefs.h"
24 #include "atomic.h"
25 #include "devformat.h"
26 #include "filters/splitter.h"
27 #include "hrtf.h"
28 #include "inprogext.h"
29 #include "intrusive_ptr.h"
30 #include "vector.h"
32 class BFormatDec;
33 struct ALbuffer;
34 struct ALeffect;
35 struct ALfilter;
36 struct BackendBase;
37 struct Compressor;
38 struct EffectState;
39 struct Uhj2Encoder;
40 struct bs2b;
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
49 enum DeviceType {
50 Playback,
51 Capture,
52 Loopback
56 enum RenderMode {
57 NormalRender,
58 StereoPair,
59 HrtfRender
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; }
71 ~BufferSubList();
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; }
86 ~EffectSubList();
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; }
101 ~FilterSubList();
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
112 class DistanceComp {
113 public:
114 struct DistData {
115 ALfloat Gain{1.0f};
116 ALuint Length{0u}; /* Valid range is [0...MAX_DELAY_LENGTH). */
117 ALfloat *Buffer{nullptr};
120 private:
121 std::array<DistData,MAX_OUTPUT_CHANNELS> mChannels;
122 al::vector<ALfloat,16> mSamples;
124 public:
125 void setSampleCount(size_t new_size) { mSamples.resize(new_size); }
126 void clear() noexcept
128 for(auto &chan : mChannels)
130 chan.Gain = 1.0f;
131 chan.Length = 0;
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 {
144 ALfloat Scale;
145 ALuint Index;
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)
178 struct MixParams {
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;
191 enum {
192 // Frequency was requested by the app or config file
193 FrequencyRequest,
194 // Channel configuration was requested by the config file
195 ChannelsRequest,
196 // Sample type was requested by the config file
197 SampleTypeRequest,
199 // Specifies if the DSP is paused at user request
200 DevicePaused,
201 // Specifies if the device is currently running
202 DeviceRunning,
204 DeviceFlagsCount
207 struct ALCdevice : public al::intrusive_ref<ALCdevice> {
208 std::atomic<bool> Connected{true};
209 const DeviceType Type{};
211 ALuint Frequency{};
212 ALuint UpdateSize{};
213 ALuint BufferSize{};
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
220 * normalization.
222 AmbiLayout mAmbiLayout{AmbiLayout::Default};
223 AmbiNorm mAmbiScale{AmbiNorm::Default};
225 ALCenum LimiterState{ALC_DONT_CARE_SOFT};
227 std::string DeviceName;
229 // Device flags
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
239 ALuint SourcesMax{};
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];
275 union {
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. */
285 MixParams Dry;
286 ALuint NumChannelsPerOrder[MAX_AMBI_ORDER+1]{};
288 /* "Real" output, which will be written to the device buffer. May alias the
289 * dry buffer.
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;
341 ~ALCdevice();
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);
387 #endif