diff options
Diffstat (limited to 'OpenAL32/Include/alu.h')
-rw-r--r-- | OpenAL32/Include/alu.h | 466 |
1 files changed, 0 insertions, 466 deletions
diff --git a/OpenAL32/Include/alu.h b/OpenAL32/Include/alu.h deleted file mode 100644 index 841e5c03..00000000 --- a/OpenAL32/Include/alu.h +++ /dev/null @@ -1,466 +0,0 @@ -#ifndef _ALU_H_ -#define _ALU_H_ - -#include <array> -#include <atomic> -#include <cmath> -#include <cstddef> - -#include "AL/al.h" -#include "AL/alc.h" -#include "AL/alext.h" - -#include "alBuffer.h" -#include "alMain.h" -#include "almalloc.h" -#include "alspan.h" -#include "ambidefs.h" -#include "filters/biquad.h" -#include "filters/nfc.h" -#include "filters/splitter.h" -#include "hrtf.h" -#include "logging.h" - -struct ALbufferlistitem; -struct ALeffectslot; -struct BSincTable; - - -enum class DistanceModel; - -#define MAX_PITCH 255 -#define MAX_SENDS 16 - - -#define DITHER_RNG_SEED 22222 - - -enum SpatializeMode { - SpatializeOff = AL_FALSE, - SpatializeOn = AL_TRUE, - SpatializeAuto = AL_AUTO_SOFT -}; - -enum Resampler { - PointResampler, - LinearResampler, - FIR4Resampler, - BSinc12Resampler, - BSinc24Resampler, - - ResamplerMax = BSinc24Resampler -}; -extern Resampler ResamplerDefault; - -/* The number of distinct scale and phase intervals within the bsinc filter - * table. - */ -#define BSINC_SCALE_BITS 4 -#define BSINC_SCALE_COUNT (1<<BSINC_SCALE_BITS) -#define BSINC_PHASE_BITS 4 -#define BSINC_PHASE_COUNT (1<<BSINC_PHASE_BITS) - -/* Interpolator state. Kind of a misnomer since the interpolator itself is - * stateless. This just keeps it from having to recompute scale-related - * mappings for every sample. - */ -struct BsincState { - ALfloat sf; /* Scale interpolation factor. */ - ALsizei m; /* Coefficient count. */ - ALsizei l; /* Left coefficient offset. */ - /* Filter coefficients, followed by the scale, phase, and scale-phase - * delta coefficients. Starting at phase index 0, each subsequent phase - * index follows contiguously. - */ - const ALfloat *filter; -}; - -union InterpState { - BsincState bsinc; -}; - -using ResamplerFunc = const ALfloat*(*)(const InterpState *state, - const ALfloat *RESTRICT src, ALsizei frac, ALint increment, - ALfloat *RESTRICT dst, ALsizei dstlen); - -void BsincPrepare(const ALuint increment, BsincState *state, const BSincTable *table); - -extern const BSincTable bsinc12; -extern const BSincTable bsinc24; - - -enum { - AF_None = 0, - AF_LowPass = 1, - AF_HighPass = 2, - AF_BandPass = AF_LowPass | AF_HighPass -}; - - -struct MixHrtfFilter { - const HrirArray<ALfloat> *Coeffs; - ALsizei Delay[2]; - ALfloat Gain; - ALfloat GainStep; -}; - - -struct DirectParams { - BiquadFilter LowPass; - BiquadFilter HighPass; - - NfcFilter NFCtrlFilter; - - struct { - HrtfFilter Old; - HrtfFilter Target; - HrtfState State; - } Hrtf; - - struct { - ALfloat Current[MAX_OUTPUT_CHANNELS]; - ALfloat Target[MAX_OUTPUT_CHANNELS]; - } Gains; -}; - -struct SendParams { - BiquadFilter LowPass; - BiquadFilter HighPass; - - struct { - ALfloat Current[MAX_OUTPUT_CHANNELS]; - ALfloat Target[MAX_OUTPUT_CHANNELS]; - } Gains; -}; - - -struct ALvoicePropsBase { - ALfloat Pitch; - ALfloat Gain; - ALfloat OuterGain; - ALfloat MinGain; - ALfloat MaxGain; - ALfloat InnerAngle; - ALfloat OuterAngle; - ALfloat RefDistance; - ALfloat MaxDistance; - ALfloat RolloffFactor; - std::array<ALfloat,3> Position; - std::array<ALfloat,3> Velocity; - std::array<ALfloat,3> Direction; - std::array<ALfloat,3> OrientAt; - std::array<ALfloat,3> OrientUp; - ALboolean HeadRelative; - DistanceModel mDistanceModel; - Resampler mResampler; - ALboolean DirectChannels; - SpatializeMode mSpatializeMode; - - ALboolean DryGainHFAuto; - ALboolean WetGainAuto; - ALboolean WetGainHFAuto; - ALfloat OuterGainHF; - - ALfloat AirAbsorptionFactor; - ALfloat RoomRolloffFactor; - ALfloat DopplerFactor; - - std::array<ALfloat,2> StereoPan; - - ALfloat Radius; - - /** Direct filter and auxiliary send info. */ - struct { - ALfloat Gain; - ALfloat GainHF; - ALfloat HFReference; - ALfloat GainLF; - ALfloat LFReference; - } Direct; - struct SendData { - ALeffectslot *Slot; - ALfloat Gain; - ALfloat GainHF; - ALfloat HFReference; - ALfloat GainLF; - ALfloat LFReference; - } Send[MAX_SENDS]; -}; - -struct ALvoiceProps : public ALvoicePropsBase { - std::atomic<ALvoiceProps*> next{nullptr}; - - DEF_NEWDEL(ALvoiceProps) -}; - -#define VOICE_IS_STATIC (1u<<0) -#define VOICE_IS_FADING (1u<<1) /* Fading sources use gain stepping for smooth transitions. */ -#define VOICE_IS_AMBISONIC (1u<<2) /* Voice needs HF scaling for ambisonic upsampling. */ -#define VOICE_HAS_HRTF (1u<<3) -#define VOICE_HAS_NFC (1u<<4) - -struct ALvoice { - enum State { - Stopped = 0, - Playing = 1, - Stopping = 2 - }; - - std::atomic<ALvoiceProps*> mUpdate{nullptr}; - - std::atomic<ALuint> mSourceID{0u}; - std::atomic<State> mPlayState{Stopped}; - - ALvoicePropsBase mProps; - - /** - * Source offset in samples, relative to the currently playing buffer, NOT - * the whole queue. - */ - std::atomic<ALuint> mPosition; - /** Fractional (fixed-point) offset to the next sample. */ - std::atomic<ALsizei> mPositionFrac; - - /* Current buffer queue item being played. */ - std::atomic<ALbufferlistitem*> mCurrentBuffer; - - /* Buffer queue item to loop to at end of queue (will be NULL for non- - * looping voices). - */ - std::atomic<ALbufferlistitem*> mLoopBuffer; - - /* Properties for the attached buffer(s). */ - FmtChannels mFmtChannels; - ALuint mFrequency; - ALsizei mNumChannels; - ALsizei mSampleSize; - - /** Current target parameters used for mixing. */ - ALint mStep; - - ResamplerFunc mResampler; - - InterpState mResampleState; - - ALuint mFlags; - - struct DirectData { - int FilterType; - al::span<FloatBufferLine> Buffer; - }; - DirectData mDirect; - - struct SendData { - int FilterType; - al::span<FloatBufferLine> Buffer; - }; - std::array<SendData,MAX_SENDS> mSend; - - struct ChannelData { - alignas(16) std::array<ALfloat,MAX_RESAMPLE_PADDING*2> mPrevSamples; - - ALfloat mAmbiScale; - BandSplitter mAmbiSplitter; - - DirectParams mDryParams; - std::array<SendParams,MAX_SENDS> mWetParams; - }; - std::array<ChannelData,MAX_INPUT_CHANNELS> mChans; - - ALvoice() = default; - ALvoice(const ALvoice&) = delete; - ~ALvoice() { delete mUpdate.exchange(nullptr, std::memory_order_acq_rel); } - ALvoice& operator=(const ALvoice&) = delete; - ALvoice& operator=(ALvoice&& rhs) noexcept - { - ALvoiceProps *old_update{mUpdate.load(std::memory_order_relaxed)}; - mUpdate.store(rhs.mUpdate.exchange(old_update, std::memory_order_relaxed), - std::memory_order_relaxed); - - mSourceID.store(rhs.mSourceID.load(std::memory_order_relaxed), std::memory_order_relaxed); - mPlayState.store(rhs.mPlayState.load(std::memory_order_relaxed), - std::memory_order_relaxed); - - mProps = rhs.mProps; - - mPosition.store(rhs.mPosition.load(std::memory_order_relaxed), std::memory_order_relaxed); - mPositionFrac.store(rhs.mPositionFrac.load(std::memory_order_relaxed), - std::memory_order_relaxed); - - mCurrentBuffer.store(rhs.mCurrentBuffer.load(std::memory_order_relaxed), - std::memory_order_relaxed); - mLoopBuffer.store(rhs.mLoopBuffer.load(std::memory_order_relaxed), - std::memory_order_relaxed); - - mFmtChannels = rhs.mFmtChannels; - mFrequency = rhs.mFrequency; - mNumChannels = rhs.mNumChannels; - mSampleSize = rhs.mSampleSize; - - mStep = rhs.mStep; - mResampler = rhs.mResampler; - - mResampleState = rhs.mResampleState; - - mFlags = rhs.mFlags; - - mDirect = rhs.mDirect; - mSend = rhs.mSend; - mChans = rhs.mChans; - - return *this; - } -}; - - -using MixerFunc = void(*)(const ALfloat *data, const al::span<FloatBufferLine> OutBuffer, - ALfloat *CurrentGains, const ALfloat *TargetGains, const ALsizei Counter, const ALsizei OutPos, - const ALsizei BufferSize); -using RowMixerFunc = void(*)(FloatBufferLine &OutBuffer, const ALfloat *gains, - const al::span<const FloatBufferLine> InSamples, const ALsizei InPos, - const ALsizei BufferSize); -using HrtfMixerFunc = void(*)(FloatBufferLine &LeftOut, FloatBufferLine &RightOut, - const ALfloat *InSamples, float2 *AccumSamples, const ALsizei OutPos, const ALsizei IrSize, - MixHrtfFilter *hrtfparams, const ALsizei BufferSize); -using HrtfMixerBlendFunc = void(*)(FloatBufferLine &LeftOut, FloatBufferLine &RightOut, - const ALfloat *InSamples, float2 *AccumSamples, const ALsizei OutPos, const ALsizei IrSize, - const HrtfFilter *oldparams, MixHrtfFilter *newparams, const ALsizei BufferSize); -using HrtfDirectMixerFunc = void(*)(FloatBufferLine &LeftOut, FloatBufferLine &RightOut, - const al::span<const FloatBufferLine> InSamples, float2 *AccumSamples, DirectHrtfState *State, - const ALsizei BufferSize); - - -#define GAIN_MIX_MAX (1000.0f) /* +60dB */ - -#define GAIN_SILENCE_THRESHOLD (0.00001f) /* -100dB */ - -#define SPEEDOFSOUNDMETRESPERSEC (343.3f) -#define AIRABSORBGAINHF (0.99426f) /* -0.05dB */ - -/* Target gain for the reverb decay feedback reaching the decay time. */ -#define REVERB_DECAY_GAIN (0.001f) /* -60 dB */ - -#define FRACTIONBITS (12) -#define FRACTIONONE (1<<FRACTIONBITS) -#define FRACTIONMASK (FRACTIONONE-1) - - -inline ALfloat lerp(ALfloat val1, ALfloat val2, ALfloat mu) noexcept -{ return val1 + (val2-val1)*mu; } -inline ALfloat cubic(ALfloat val1, ALfloat val2, ALfloat val3, ALfloat val4, ALfloat mu) noexcept -{ - ALfloat mu2 = mu*mu, mu3 = mu2*mu; - ALfloat a0 = -0.5f*mu3 + mu2 + -0.5f*mu; - ALfloat a1 = 1.5f*mu3 + -2.5f*mu2 + 1.0f; - ALfloat a2 = -1.5f*mu3 + 2.0f*mu2 + 0.5f*mu; - ALfloat a3 = 0.5f*mu3 + -0.5f*mu2; - return val1*a0 + val2*a1 + val3*a2 + val4*a3; -} - - -enum HrtfRequestMode { - Hrtf_Default = 0, - Hrtf_Enable = 1, - Hrtf_Disable = 2, -}; - -void aluInit(void); - -void aluInitMixer(void); - -ResamplerFunc SelectResampler(Resampler resampler); - -/* aluInitRenderer - * - * Set up the appropriate panning method and mixing method given the device - * properties. - */ -void aluInitRenderer(ALCdevice *device, ALint hrtf_id, HrtfRequestMode hrtf_appreq, HrtfRequestMode hrtf_userreq); - -void aluInitEffectPanning(ALeffectslot *slot, ALCdevice *device); - -void ProcessHrtf(ALCdevice *device, const ALsizei SamplesToDo); -void ProcessAmbiDec(ALCdevice *device, const ALsizei SamplesToDo); -void ProcessUhj(ALCdevice *device, const ALsizei SamplesToDo); -void ProcessBs2b(ALCdevice *device, const ALsizei SamplesToDo); - -/** - * Calculates ambisonic encoder coefficients using the X, Y, and Z direction - * components, which must represent a normalized (unit length) vector, and the - * spread is the angular width of the sound (0...tau). - * - * NOTE: The components use ambisonic coordinates. As a result: - * - * Ambisonic Y = OpenAL -X - * Ambisonic Z = OpenAL Y - * Ambisonic X = OpenAL -Z - * - * The components are ordered such that OpenAL's X, Y, and Z are the first, - * second, and third parameters respectively -- simply negate X and Z. - */ -void CalcAmbiCoeffs(const ALfloat y, const ALfloat z, const ALfloat x, const ALfloat spread, - ALfloat (&coeffs)[MAX_AMBI_CHANNELS]); - -/** - * CalcDirectionCoeffs - * - * Calculates ambisonic coefficients based on an OpenAL direction vector. The - * vector must be normalized (unit length), and the spread is the angular width - * of the sound (0...tau). - */ -inline void CalcDirectionCoeffs(const ALfloat (&dir)[3], ALfloat spread, ALfloat (&coeffs)[MAX_AMBI_CHANNELS]) -{ - /* Convert from OpenAL coords to Ambisonics. */ - CalcAmbiCoeffs(-dir[0], dir[1], -dir[2], spread, coeffs); -} - -/** - * CalcAngleCoeffs - * - * Calculates ambisonic coefficients based on azimuth and elevation. The - * azimuth and elevation parameters are in radians, going right and up - * respectively. - */ -inline void CalcAngleCoeffs(ALfloat azimuth, ALfloat elevation, ALfloat spread, ALfloat (&coeffs)[MAX_AMBI_CHANNELS]) -{ - ALfloat x = -std::sin(azimuth) * std::cos(elevation); - ALfloat y = std::sin(elevation); - ALfloat z = std::cos(azimuth) * std::cos(elevation); - - CalcAmbiCoeffs(x, y, z, spread, coeffs); -} - - -/** - * ComputePanGains - * - * Computes panning gains using the given channel decoder coefficients and the - * pre-calculated direction or angle coefficients. For B-Format sources, the - * coeffs are a 'slice' of a transform matrix for the input channel, used to - * scale and orient the sound samples. - */ -void ComputePanGains(const MixParams *mix, const ALfloat*RESTRICT coeffs, ALfloat ingain, ALfloat (&gains)[MAX_OUTPUT_CHANNELS]); - - -inline std::array<ALfloat,MAX_AMBI_CHANNELS> GetAmbiIdentityRow(size_t i) noexcept -{ - std::array<ALfloat,MAX_AMBI_CHANNELS> ret{}; - ret[i] = 1.0f; - return ret; -} - - -void MixVoice(ALvoice *voice, ALvoice::State vstate, const ALuint SourceID, ALCcontext *Context, const ALsizei SamplesToDo); - -void aluMixData(ALCdevice *device, ALvoid *OutBuffer, ALsizei NumSamples); -/* Caller must lock the device state, and the mixer must not be running. */ -void aluHandleDisconnect(ALCdevice *device, const char *msg, ...) DECL_FORMAT(printf, 2, 3); - -extern MixerFunc MixSamples; -extern RowMixerFunc MixRowSamples; - -extern const ALfloat ConeScale; -extern const ALfloat ZScale; -extern const ALboolean OverrideReverbSpeedOfSound; - -#endif |