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
);
26 extern MixerFunc MixSamples
;
29 #define GAIN_MIX_MAX 1000.0f /* +60dB */
31 #define GAIN_SILENCE_THRESHOLD 0.00001f /* -100dB */
33 #define SPEEDOFSOUNDMETRESPERSEC 343.3f
34 #define AIRABSORBGAINHF 0.99426f /* -0.05dB */
36 /* Target gain for the reverb decay feedback reaching the decay time. */
37 #define REVERB_DECAY_GAIN 0.001f /* -60 dB */
39 #define FRACTIONBITS 12
40 #define FRACTIONONE (1<<FRACTIONBITS)
41 #define FRACTIONMASK (FRACTIONONE-1)
44 inline float lerp(float val1
, float val2
, float mu
) noexcept
45 { return val1
+ (val2
-val1
)*mu
; }
46 inline float cubic(float val1
, float val2
, float val3
, float val4
, float mu
) noexcept
48 const float mu2
{mu
*mu
}, mu3
{mu2
*mu
};
49 const float a0
{-0.5f
*mu3
+ mu2
+ -0.5f
*mu
};
50 const float a1
{ 1.5f
*mu3
+ -2.5f
*mu2
+ 1.0f
};
51 const float a2
{-1.5f
*mu3
+ 2.0f
*mu2
+ 0.5f
*mu
};
52 const float a3
{ 0.5f
*mu3
+ -0.5f
*mu2
};
53 return val1
*a0
+ val2
*a1
+ val3
*a2
+ val4
*a3
;
57 enum HrtfRequestMode
{
65 void aluInitMixer(void);
69 * Set up the appropriate panning method and mixing method given the device
72 void aluInitRenderer(ALCdevice
*device
, int hrtf_id
, HrtfRequestMode hrtf_appreq
,
73 HrtfRequestMode hrtf_userreq
);
75 void aluInitEffectPanning(ALeffectslot
*slot
, ALCdevice
*device
);
78 * Calculates ambisonic encoder coefficients using the X, Y, and Z direction
79 * components, which must represent a normalized (unit length) vector, and the
80 * spread is the angular width of the sound (0...tau).
82 * NOTE: The components use ambisonic coordinates. As a result:
84 * Ambisonic Y = OpenAL -X
85 * Ambisonic Z = OpenAL Y
86 * Ambisonic X = OpenAL -Z
88 * The components are ordered such that OpenAL's X, Y, and Z are the first,
89 * second, and third parameters respectively -- simply negate X and Z.
91 std::array
<float,MAX_AMBI_CHANNELS
> CalcAmbiCoeffs(const float y
, const float z
, const float x
,
97 * Calculates ambisonic coefficients based on an OpenAL direction vector. The
98 * vector must be normalized (unit length), and the spread is the angular width
99 * of the sound (0...tau).
101 inline std::array
<float,MAX_AMBI_CHANNELS
> CalcDirectionCoeffs(const float (&dir
)[3],
104 /* Convert from OpenAL coords to Ambisonics. */
105 return CalcAmbiCoeffs(-dir
[0], dir
[1], -dir
[2], spread
);
111 * Calculates ambisonic coefficients based on azimuth and elevation. The
112 * azimuth and elevation parameters are in radians, going right and up
115 inline std::array
<float,MAX_AMBI_CHANNELS
> CalcAngleCoeffs(const float azimuth
,
116 const float elevation
, const float spread
)
118 const float x
{-std::sin(azimuth
) * std::cos(elevation
)};
119 const float y
{ std::sin(elevation
)};
120 const float z
{ std::cos(azimuth
) * std::cos(elevation
)};
122 return CalcAmbiCoeffs(x
, y
, z
, spread
);
129 * Computes panning gains using the given channel decoder coefficients and the
130 * pre-calculated direction or angle coefficients. For B-Format sources, the
131 * coeffs are a 'slice' of a transform matrix for the input channel, used to
132 * scale and orient the sound samples.
134 void ComputePanGains(const MixParams
*mix
, const float*RESTRICT coeffs
, const float ingain
,
135 const al::span
<float,MAX_OUTPUT_CHANNELS
> gains
);
138 /** Helper to set an identity/pass-through panning for ambisonic mixing (3D input). */
139 template<typename T
, typename I
, typename F
>
140 auto SetAmbiPanIdentity(T iter
, I count
, F func
) -> std::enable_if_t
<std::is_integral
<I
>::value
>
142 if(count
< 1) return;
144 std::array
<float,MAX_AMBI_CHANNELS
> coeffs
{{1.0f
}};
147 for(I i
{1};i
< count
;++i
,++iter
)
156 extern const float ConeScale
;
157 extern const float ZScale
;