Avoid static constexpr for arrays iterated over at run-time
[openal-soft.git] / alc / alu.h
blobb3cfd840beb7a2069940faf5f560081e5a65d9e6
1 #ifndef ALU_H
2 #define ALU_H
4 #include <array>
5 #include <cmath>
6 #include <cstddef>
8 #include "AL/al.h"
10 #include "alcmain.h"
11 #include "alspan.h"
12 #include "logging.h"
14 struct ALbufferlistitem;
15 struct ALeffectslot;
18 #define MAX_PITCH 255
19 #define MAX_SENDS 16
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 {
64 Hrtf_Default = 0,
65 Hrtf_Enable = 1,
66 Hrtf_Disable = 2,
69 void aluInit(void);
71 void aluInitMixer(void);
73 /* aluInitRenderer
75 * Set up the appropriate panning method and mixing method given the device
76 * properties.
78 void aluInitRenderer(ALCdevice *device, ALint hrtf_id, HrtfRequestMode hrtf_appreq, HrtfRequestMode hrtf_userreq);
80 void aluInitEffectPanning(ALeffectslot *slot, ALCdevice *device);
82 /**
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);
99 /**
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);
114 * CalcAngleCoeffs
116 * Calculates ambisonic coefficients based on azimuth and elevation. The
117 * azimuth and elevation parameters are in radians, going right and up
118 * respectively.
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);
132 * ComputePanGains
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{};
146 ret[i] = 1.0f;
147 return 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;
158 #endif