diff options
Diffstat (limited to 'alc/alcmain.h')
-rw-r--r-- | alc/alcmain.h | 241 |
1 files changed, 1 insertions, 240 deletions
diff --git a/alc/alcmain.h b/alc/alcmain.h index 025ba3d4..e8875184 100644 --- a/alc/alcmain.h +++ b/alc/alcmain.h @@ -25,6 +25,7 @@ #include "core/ambidefs.h" #include "core/bufferline.h" #include "core/devformat.h" +#include "core/device.h" #include "core/filters/splitter.h" #include "core/hrtf.h" #include "core/mixer/defs.h" @@ -32,253 +33,13 @@ #include "intrusive_ptr.h" #include "vector.h" -class BFormatDec; struct ALbuffer; struct ALeffect; struct ALfilter; -struct BackendBase; -struct Compressor; -struct ContextBase; -struct EffectState; -struct UhjEncoder; -struct bs2b; using uint = unsigned int; -#define MIN_OUTPUT_RATE 8000 -#define MAX_OUTPUT_RATE 192000 -#define DEFAULT_OUTPUT_RATE 44100 - -#define DEFAULT_UPDATE_SIZE 882 /* 20ms */ -#define DEFAULT_NUM_UPDATES 3 - - -enum class DeviceType : unsigned char { - Playback, - Capture, - Loopback -}; - - -enum class RenderMode : unsigned char { - Normal, - Pairwise, - Hrtf -}; - - -struct InputRemixMap { - struct TargetMix { Channel channel; float mix; }; - - Channel channel; - std::array<TargetMix,2> targets; -}; - - -/* Maximum delay in samples for speaker distance compensation. */ -#define MAX_DELAY_LENGTH 1024 - -struct DistanceComp { - struct ChanData { - float Gain{1.0f}; - uint Length{0u}; /* Valid range is [0...MAX_DELAY_LENGTH). */ - float *Buffer{nullptr}; - }; - - std::array<ChanData,MAX_OUTPUT_CHANNELS> mChannels; - al::FlexArray<float,16> mSamples; - - DistanceComp(size_t count) : mSamples{count} { } - - static std::unique_ptr<DistanceComp> Create(size_t numsamples) - { return std::unique_ptr<DistanceComp>{new(FamCount(numsamples)) DistanceComp{numsamples}}; } - - DEF_FAM_NEWDEL(DistanceComp, mSamples) -}; - - -struct BFChannelConfig { - float Scale; - uint Index; -}; - - -struct MixParams { - /* Coefficient channel mapping for mixing to the buffer. */ - std::array<BFChannelConfig,MAX_OUTPUT_CHANNELS> AmbiMap{}; - - al::span<FloatBufferLine> Buffer; -}; - -struct RealMixParams { - al::span<const InputRemixMap> RemixMap; - std::array<uint,MaxChannels> ChannelIndex{}; - - al::span<FloatBufferLine> Buffer; -}; - -enum { - // Frequency was requested by the app or config file - FrequencyRequest, - // Channel configuration was requested by the config file - ChannelsRequest, - // Sample type was requested by the config file - SampleTypeRequest, - - // Specifies if the DSP is paused at user request - DevicePaused, - // Specifies if the device is currently running - DeviceRunning, - - DeviceFlagsCount -}; - -struct DeviceBase { - std::atomic<bool> Connected{true}; - const DeviceType Type{}; - - uint Frequency{}; - uint UpdateSize{}; - uint BufferSize{}; - - DevFmtChannels FmtChans{}; - DevFmtType FmtType{}; - bool IsHeadphones{false}; - uint mAmbiOrder{0}; - float mXOverFreq{400.0f}; - /* For DevFmtAmbi* output only, specifies the channel order and - * normalization. - */ - DevAmbiLayout mAmbiLayout{DevAmbiLayout::Default}; - DevAmbiScaling mAmbiScale{DevAmbiScaling::Default}; - - std::string DeviceName; - - // Device flags - std::bitset<DeviceFlagsCount> Flags{}; - - uint NumAuxSends{}; - - /* Rendering mode. */ - RenderMode mRenderMode{RenderMode::Normal}; - - /* The average speaker distance as determined by the ambdec configuration, - * HRTF data set, or the NFC-HOA reference delay. Only used for NFC. - */ - float AvgSpeakerDist{0.0f}; - - uint SamplesDone{0u}; - std::chrono::nanoseconds ClockBase{0}; - std::chrono::nanoseconds FixedLatency{0}; - - /* Temp storage used for mixer processing. */ - alignas(16) float ResampledData[BufferLineSize]; - alignas(16) float FilteredData[BufferLineSize]; - union { - alignas(16) float HrtfSourceData[BufferLineSize + HrtfHistoryLength]; - alignas(16) float NfcSampleData[BufferLineSize]; - }; - - /* Persistent storage for HRTF mixing. */ - alignas(16) float2 HrtfAccumData[BufferLineSize + HrirLength + HrtfDirectDelay]; - - /* Mixing buffer used by the Dry mix and Real output. */ - al::vector<FloatBufferLine, 16> MixBuffer; - - /* The "dry" path corresponds to the main output. */ - MixParams Dry; - uint NumChannelsPerOrder[MaxAmbiOrder+1]{}; - - /* "Real" output, which will be written to the device buffer. May alias the - * dry buffer. - */ - RealMixParams RealOut; - - /* HRTF state and info */ - std::unique_ptr<DirectHrtfState> mHrtfState; - al::intrusive_ptr<HrtfStore> mHrtf; - uint mIrSize{0}; - - /* Ambisonic-to-UHJ encoder */ - std::unique_ptr<UhjEncoder> mUhjEncoder; - - /* Ambisonic decoder for speakers */ - std::unique_ptr<BFormatDec> AmbiDecoder; - - /* Stereo-to-binaural filter */ - std::unique_ptr<bs2b> Bs2b; - - using PostProc = void(DeviceBase::*)(const size_t SamplesToDo); - PostProc PostProcess{nullptr}; - - std::unique_ptr<Compressor> Limiter; - - /* Delay buffers used to compensate for speaker distances. */ - std::unique_ptr<DistanceComp> ChannelDelays; - - /* Dithering control. */ - float DitherDepth{0.0f}; - uint DitherSeed{0u}; - - /* Running count of the mixer invocations, in 31.1 fixed point. This - * actually increments *twice* when mixing, first at the start and then at - * the end, so the bottom bit indicates if the device is currently mixing - * and the upper bits indicates how many mixes have been done. - */ - RefCount MixCount{0u}; - - // Contexts created on this device - std::atomic<al::FlexArray<ContextBase*>*> mContexts{nullptr}; - - /* This lock protects the device state (format, update size, etc) from - * being from being changed in multiple threads, or being accessed while - * being changed. It's also used to serialize calls to the backend. - */ - std::mutex StateLock; - std::unique_ptr<BackendBase> Backend; - - - DeviceBase(DeviceType type); - DeviceBase(const DeviceBase&) = delete; - DeviceBase& operator=(const DeviceBase&) = delete; - ~DeviceBase(); - - uint bytesFromFmt() const noexcept { return BytesFromDevFmt(FmtType); } - uint channelsFromFmt() const noexcept { return ChannelsFromDevFmt(FmtChans, mAmbiOrder); } - uint frameSizeFromFmt() const noexcept { return bytesFromFmt() * channelsFromFmt(); } - - uint waitForMix() const noexcept - { - uint refcount; - while((refcount=MixCount.load(std::memory_order_acquire))&1) { - } - return refcount; - } - - void ProcessHrtf(const size_t SamplesToDo); - void ProcessAmbiDec(const size_t SamplesToDo); - void ProcessAmbiDecStablized(const size_t SamplesToDo); - void ProcessUhj(const size_t SamplesToDo); - void ProcessBs2b(const size_t SamplesToDo); - - inline void postProcess(const size_t SamplesToDo) - { if LIKELY(PostProcess) (this->*PostProcess)(SamplesToDo); } - - void renderSamples(void *outBuffer, const uint numSamples, const size_t frameStep); - - /* Caller must lock the device state, and the mixer must not be running. */ -#ifdef __USE_MINGW_ANSI_STDIO - [[gnu::format(gnu_printf,2,3)]] -#else - [[gnu::format(printf,2,3)]] -#endif - void handleDisconnect(const char *msg, ...); - - DISABLE_ALLOC() -}; - - struct BufferSubList { uint64_t FreeMask{~0_u64}; ALbuffer *Buffers{nullptr}; /* 64 */ |