14 struct ALbufferlistitem
;
22 using MixerFunc
= void(*)(const al::span
<const float> InSamples
,
23 const al::span
<FloatBufferLine
> OutBuffer
, float *CurrentGains
, const float *TargetGains
,
24 const size_t Counter
, const size_t OutPos
);
25 using RowMixerFunc
= void(*)(const al::span
<float> OutBuffer
, const al::span
<const float> Gains
,
26 const float *InSamples
, const size_t InStride
);
27 using HrtfDirectMixerFunc
= void(*)(FloatBufferLine
&LeftOut
, FloatBufferLine
&RightOut
,
28 const al::span
<const FloatBufferLine
> InSamples
, float2
*AccumSamples
, DirectHrtfState
*State
,
29 const size_t BufferSize
);
31 extern MixerFunc MixSamples
;
32 extern RowMixerFunc MixRowSamples
;
35 #define GAIN_MIX_MAX (1000.0f) /* +60dB */
37 #define GAIN_SILENCE_THRESHOLD (0.00001f) /* -100dB */
39 #define SPEEDOFSOUNDMETRESPERSEC (343.3f)
40 #define AIRABSORBGAINHF (0.99426f) /* -0.05dB */
42 /* Target gain for the reverb decay feedback reaching the decay time. */
43 #define REVERB_DECAY_GAIN (0.001f) /* -60 dB */
45 #define FRACTIONBITS (12)
46 #define FRACTIONONE (1<<FRACTIONBITS)
47 #define FRACTIONMASK (FRACTIONONE-1)
50 inline ALfloat
lerp(ALfloat val1
, ALfloat val2
, ALfloat mu
) noexcept
51 { return val1
+ (val2
-val1
)*mu
; }
52 inline ALfloat
cubic(ALfloat val1
, ALfloat val2
, ALfloat val3
, ALfloat val4
, ALfloat mu
) noexcept
54 ALfloat mu2
= mu
*mu
, mu3
= mu2
*mu
;
55 ALfloat a0
= -0.5f
*mu3
+ mu2
+ -0.5f
*mu
;
56 ALfloat a1
= 1.5f
*mu3
+ -2.5f
*mu2
+ 1.0f
;
57 ALfloat a2
= -1.5f
*mu3
+ 2.0f
*mu2
+ 0.5f
*mu
;
58 ALfloat a3
= 0.5f
*mu3
+ -0.5f
*mu2
;
59 return val1
*a0
+ val2
*a1
+ val3
*a2
+ val4
*a3
;
63 enum HrtfRequestMode
{
71 void aluInitMixer(void);
75 * Set up the appropriate panning method and mixing method given the device
78 void aluInitRenderer(ALCdevice
*device
, ALint hrtf_id
, HrtfRequestMode hrtf_appreq
, HrtfRequestMode hrtf_userreq
);
80 void aluInitEffectPanning(ALeffectslot
*slot
, ALCdevice
*device
);
83 * Calculates ambisonic encoder coefficients using the X, Y, and Z direction
84 * components, which must represent a normalized (unit length) vector, and the
85 * spread is the angular width of the sound (0...tau).
87 * NOTE: The components use ambisonic coordinates. As a result:
89 * Ambisonic Y = OpenAL -X
90 * Ambisonic Z = OpenAL Y
91 * Ambisonic X = OpenAL -Z
93 * The components are ordered such that OpenAL's X, Y, and Z are the first,
94 * second, and third parameters respectively -- simply negate X and Z.
96 void CalcAmbiCoeffs(const float y
, const float z
, const float x
, const float spread
,
97 const al::span
<float,MAX_AMBI_CHANNELS
> coeffs
);
100 * CalcDirectionCoeffs
102 * Calculates ambisonic coefficients based on an OpenAL direction vector. The
103 * vector must be normalized (unit length), and the spread is the angular width
104 * of the sound (0...tau).
106 inline void CalcDirectionCoeffs(const float (&dir
)[3], const float spread
,
107 const al::span
<float,MAX_AMBI_CHANNELS
> coeffs
)
109 /* Convert from OpenAL coords to Ambisonics. */
110 CalcAmbiCoeffs(-dir
[0], dir
[1], -dir
[2], spread
, coeffs
);
116 * Calculates ambisonic coefficients based on azimuth and elevation. The
117 * azimuth and elevation parameters are in radians, going right and up
120 inline void CalcAngleCoeffs(const float azimuth
, const float elevation
, const float spread
,
121 const al::span
<float,MAX_AMBI_CHANNELS
> coeffs
)
123 const float x
{-std::sin(azimuth
) * std::cos(elevation
)};
124 const float y
{ std::sin(elevation
)};
125 const float z
{ std::cos(azimuth
) * std::cos(elevation
)};
127 CalcAmbiCoeffs(x
, y
, z
, spread
, coeffs
);
134 * Computes panning gains using the given channel decoder coefficients and the
135 * pre-calculated direction or angle coefficients. For B-Format sources, the
136 * coeffs are a 'slice' of a transform matrix for the input channel, used to
137 * scale and orient the sound samples.
139 void ComputePanGains(const MixParams
*mix
, const float*RESTRICT coeffs
, const float ingain
,
140 const al::span
<float,MAX_OUTPUT_CHANNELS
> gains
);
143 inline std::array
<ALfloat
,MAX_AMBI_CHANNELS
> GetAmbiIdentityRow(size_t i
) noexcept
145 std::array
<ALfloat
,MAX_AMBI_CHANNELS
> ret
{};
151 void aluMixData(ALCdevice
*device
, ALvoid
*OutBuffer
, const ALuint NumSamples
);
152 /* Caller must lock the device state, and the mixer must not be running. */
153 void aluHandleDisconnect(ALCdevice
*device
, const char *msg
, ...) DECL_FORMAT(printf
, 2, 3);
155 extern const ALfloat ConeScale
;
156 extern const ALfloat ZScale
;