🛠️🐜 Antkeeper superbuild with dependencies included https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

441 lines
12 KiB

  1. #ifndef _ALU_H_
  2. #define _ALU_H_
  3. #include <limits.h>
  4. #include <math.h>
  5. #ifdef HAVE_FLOAT_H
  6. #include <float.h>
  7. #endif
  8. #ifdef HAVE_IEEEFP_H
  9. #include <ieeefp.h>
  10. #endif
  11. #include <cmath>
  12. #include <array>
  13. #include "alMain.h"
  14. #include "alBuffer.h"
  15. #include "hrtf.h"
  16. #include "logging.h"
  17. #include "math_defs.h"
  18. #include "filters/biquad.h"
  19. #include "filters/splitter.h"
  20. #include "filters/nfc.h"
  21. #include "almalloc.h"
  22. #include "alnumeric.h"
  23. enum class DistanceModel;
  24. #define MAX_PITCH 255
  25. #define MAX_SENDS 16
  26. struct BSincTable;
  27. struct ALsource;
  28. struct ALbufferlistitem;
  29. struct ALvoice;
  30. struct ALeffectslot;
  31. #define DITHER_RNG_SEED 22222
  32. enum SpatializeMode {
  33. SpatializeOff = AL_FALSE,
  34. SpatializeOn = AL_TRUE,
  35. SpatializeAuto = AL_AUTO_SOFT
  36. };
  37. enum Resampler {
  38. PointResampler,
  39. LinearResampler,
  40. FIR4Resampler,
  41. BSinc12Resampler,
  42. BSinc24Resampler,
  43. ResamplerMax = BSinc24Resampler
  44. };
  45. extern Resampler ResamplerDefault;
  46. /* The number of distinct scale and phase intervals within the bsinc filter
  47. * table.
  48. */
  49. #define BSINC_SCALE_BITS 4
  50. #define BSINC_SCALE_COUNT (1<<BSINC_SCALE_BITS)
  51. #define BSINC_PHASE_BITS 4
  52. #define BSINC_PHASE_COUNT (1<<BSINC_PHASE_BITS)
  53. /* Interpolator state. Kind of a misnomer since the interpolator itself is
  54. * stateless. This just keeps it from having to recompute scale-related
  55. * mappings for every sample.
  56. */
  57. struct BsincState {
  58. ALfloat sf; /* Scale interpolation factor. */
  59. ALsizei m; /* Coefficient count. */
  60. ALsizei l; /* Left coefficient offset. */
  61. /* Filter coefficients, followed by the scale, phase, and scale-phase
  62. * delta coefficients. Starting at phase index 0, each subsequent phase
  63. * index follows contiguously.
  64. */
  65. const ALfloat *filter;
  66. };
  67. union InterpState {
  68. BsincState bsinc;
  69. };
  70. using ResamplerFunc = const ALfloat*(*)(const InterpState *state,
  71. const ALfloat *RESTRICT src, ALsizei frac, ALint increment,
  72. ALfloat *RESTRICT dst, ALsizei dstlen);
  73. void BsincPrepare(const ALuint increment, BsincState *state, const BSincTable *table);
  74. extern const BSincTable bsinc12;
  75. extern const BSincTable bsinc24;
  76. enum {
  77. AF_None = 0,
  78. AF_LowPass = 1,
  79. AF_HighPass = 2,
  80. AF_BandPass = AF_LowPass | AF_HighPass
  81. };
  82. struct MixHrtfParams {
  83. const HrirArray<ALfloat> *Coeffs;
  84. ALsizei Delay[2];
  85. ALfloat Gain;
  86. ALfloat GainStep;
  87. };
  88. struct DirectParams {
  89. BiquadFilter LowPass;
  90. BiquadFilter HighPass;
  91. NfcFilter NFCtrlFilter;
  92. struct {
  93. HrtfParams Old;
  94. HrtfParams Target;
  95. HrtfState State;
  96. } Hrtf;
  97. struct {
  98. ALfloat Current[MAX_OUTPUT_CHANNELS];
  99. ALfloat Target[MAX_OUTPUT_CHANNELS];
  100. } Gains;
  101. };
  102. struct SendParams {
  103. BiquadFilter LowPass;
  104. BiquadFilter HighPass;
  105. struct {
  106. ALfloat Current[MAX_OUTPUT_CHANNELS];
  107. ALfloat Target[MAX_OUTPUT_CHANNELS];
  108. } Gains;
  109. };
  110. struct ALvoicePropsBase {
  111. ALfloat Pitch;
  112. ALfloat Gain;
  113. ALfloat OuterGain;
  114. ALfloat MinGain;
  115. ALfloat MaxGain;
  116. ALfloat InnerAngle;
  117. ALfloat OuterAngle;
  118. ALfloat RefDistance;
  119. ALfloat MaxDistance;
  120. ALfloat RolloffFactor;
  121. std::array<ALfloat,3> Position;
  122. std::array<ALfloat,3> Velocity;
  123. std::array<ALfloat,3> Direction;
  124. std::array<ALfloat,3> OrientAt;
  125. std::array<ALfloat,3> OrientUp;
  126. ALboolean HeadRelative;
  127. DistanceModel mDistanceModel;
  128. Resampler mResampler;
  129. ALboolean DirectChannels;
  130. SpatializeMode mSpatializeMode;
  131. ALboolean DryGainHFAuto;
  132. ALboolean WetGainAuto;
  133. ALboolean WetGainHFAuto;
  134. ALfloat OuterGainHF;
  135. ALfloat AirAbsorptionFactor;
  136. ALfloat RoomRolloffFactor;
  137. ALfloat DopplerFactor;
  138. std::array<ALfloat,2> StereoPan;
  139. ALfloat Radius;
  140. /** Direct filter and auxiliary send info. */
  141. struct {
  142. ALfloat Gain;
  143. ALfloat GainHF;
  144. ALfloat HFReference;
  145. ALfloat GainLF;
  146. ALfloat LFReference;
  147. } Direct;
  148. struct SendData {
  149. ALeffectslot *Slot;
  150. ALfloat Gain;
  151. ALfloat GainHF;
  152. ALfloat HFReference;
  153. ALfloat GainLF;
  154. ALfloat LFReference;
  155. } Send[MAX_SENDS];
  156. };
  157. struct ALvoiceProps : public ALvoicePropsBase {
  158. std::atomic<ALvoiceProps*> next{nullptr};
  159. DEF_NEWDEL(ALvoiceProps)
  160. };
  161. #define VOICE_IS_STATIC (1u<<0)
  162. #define VOICE_IS_FADING (1u<<1) /* Fading sources use gain stepping for smooth transitions. */
  163. #define VOICE_IS_AMBISONIC (1u<<2) /* Voice needs HF scaling for ambisonic upsampling. */
  164. #define VOICE_HAS_HRTF (1u<<3)
  165. #define VOICE_HAS_NFC (1u<<4)
  166. struct ALvoice {
  167. enum State {
  168. Stopped = 0,
  169. Playing = 1,
  170. Stopping = 2
  171. };
  172. std::atomic<ALvoiceProps*> mUpdate{nullptr};
  173. std::atomic<ALuint> mSourceID{0u};
  174. std::atomic<State> mPlayState{Stopped};
  175. ALvoicePropsBase mProps;
  176. /**
  177. * Source offset in samples, relative to the currently playing buffer, NOT
  178. * the whole queue.
  179. */
  180. std::atomic<ALuint> mPosition;
  181. /** Fractional (fixed-point) offset to the next sample. */
  182. std::atomic<ALsizei> mPositionFrac;
  183. /* Current buffer queue item being played. */
  184. std::atomic<ALbufferlistitem*> mCurrentBuffer;
  185. /* Buffer queue item to loop to at end of queue (will be NULL for non-
  186. * looping voices).
  187. */
  188. std::atomic<ALbufferlistitem*> mLoopBuffer;
  189. /* Properties for the attached buffer(s). */
  190. FmtChannels mFmtChannels;
  191. ALuint mFrequency;
  192. ALsizei mNumChannels;
  193. ALsizei mSampleSize;
  194. /** Current target parameters used for mixing. */
  195. ALint mStep;
  196. ResamplerFunc mResampler;
  197. InterpState mResampleState;
  198. ALuint mFlags;
  199. struct ResampleData {
  200. alignas(16) std::array<ALfloat,MAX_RESAMPLE_PADDING*2> mPrevSamples;
  201. ALfloat mAmbiScale;
  202. BandSplitter mAmbiSplitter;
  203. };
  204. std::array<ResampleData,MAX_INPUT_CHANNELS> mResampleData;
  205. struct {
  206. int FilterType;
  207. DirectParams Params[MAX_INPUT_CHANNELS];
  208. ALfloat (*Buffer)[BUFFERSIZE];
  209. ALsizei Channels;
  210. ALsizei ChannelsPerOrder[MAX_AMBI_ORDER+1];
  211. } mDirect;
  212. struct SendData {
  213. int FilterType;
  214. SendParams Params[MAX_INPUT_CHANNELS];
  215. ALfloat (*Buffer)[BUFFERSIZE];
  216. ALsizei Channels;
  217. };
  218. al::FlexArray<SendData> mSend;
  219. ALvoice(size_t numsends) : mSend{numsends} { }
  220. ALvoice(const ALvoice&) = delete;
  221. ALvoice& operator=(const ALvoice&) = delete;
  222. static constexpr size_t Sizeof(size_t numsends) noexcept
  223. {
  224. return maxz(sizeof(ALvoice),
  225. al::FlexArray<SendData>::Sizeof(numsends, offsetof(ALvoice, mSend)));
  226. }
  227. };
  228. void DeinitVoice(ALvoice *voice) noexcept;
  229. using MixerFunc = void(*)(const ALfloat *data, const ALsizei OutChans,
  230. ALfloat (*OutBuffer)[BUFFERSIZE], ALfloat *CurrentGains, const ALfloat *TargetGains,
  231. const ALsizei Counter, const ALsizei OutPos, const ALsizei BufferSize);
  232. using RowMixerFunc = void(*)(ALfloat *OutBuffer, const ALfloat *gains,
  233. const ALfloat (*data)[BUFFERSIZE], const ALsizei InChans, const ALsizei InPos,
  234. const ALsizei BufferSize);
  235. using HrtfMixerFunc = void(*)(ALfloat *RESTRICT LeftOut, ALfloat *RESTRICT RightOut,
  236. const ALfloat *data, float2 *RESTRICT AccumSamples, const ALsizei OutPos, const ALsizei IrSize,
  237. MixHrtfParams *hrtfparams, const ALsizei BufferSize);
  238. using HrtfMixerBlendFunc = void(*)(ALfloat *RESTRICT LeftOut, ALfloat *RESTRICT RightOut,
  239. const ALfloat *data, float2 *RESTRICT AccumSamples, const ALsizei OutPos, const ALsizei IrSize,
  240. const HrtfParams *oldparams, MixHrtfParams *newparams, const ALsizei BufferSize);
  241. using HrtfDirectMixerFunc = void(*)(ALfloat *RESTRICT LeftOut, ALfloat *RESTRICT RightOut,
  242. const ALfloat (*data)[BUFFERSIZE], float2 *RESTRICT AccumSamples, DirectHrtfState *State,
  243. const ALsizei NumChans, const ALsizei BufferSize);
  244. #define GAIN_MIX_MAX (1000.0f) /* +60dB */
  245. #define GAIN_SILENCE_THRESHOLD (0.00001f) /* -100dB */
  246. #define SPEEDOFSOUNDMETRESPERSEC (343.3f)
  247. #define AIRABSORBGAINHF (0.99426f) /* -0.05dB */
  248. /* Target gain for the reverb decay feedback reaching the decay time. */
  249. #define REVERB_DECAY_GAIN (0.001f) /* -60 dB */
  250. #define FRACTIONBITS (12)
  251. #define FRACTIONONE (1<<FRACTIONBITS)
  252. #define FRACTIONMASK (FRACTIONONE-1)
  253. inline ALfloat lerp(ALfloat val1, ALfloat val2, ALfloat mu) noexcept
  254. { return val1 + (val2-val1)*mu; }
  255. inline ALfloat cubic(ALfloat val1, ALfloat val2, ALfloat val3, ALfloat val4, ALfloat mu) noexcept
  256. {
  257. ALfloat mu2 = mu*mu, mu3 = mu2*mu;
  258. ALfloat a0 = -0.5f*mu3 + mu2 + -0.5f*mu;
  259. ALfloat a1 = 1.5f*mu3 + -2.5f*mu2 + 1.0f;
  260. ALfloat a2 = -1.5f*mu3 + 2.0f*mu2 + 0.5f*mu;
  261. ALfloat a3 = 0.5f*mu3 + -0.5f*mu2;
  262. return val1*a0 + val2*a1 + val3*a2 + val4*a3;
  263. }
  264. enum HrtfRequestMode {
  265. Hrtf_Default = 0,
  266. Hrtf_Enable = 1,
  267. Hrtf_Disable = 2,
  268. };
  269. void aluInit(void);
  270. void aluInitMixer(void);
  271. ResamplerFunc SelectResampler(Resampler resampler);
  272. /* aluInitRenderer
  273. *
  274. * Set up the appropriate panning method and mixing method given the device
  275. * properties.
  276. */
  277. void aluInitRenderer(ALCdevice *device, ALint hrtf_id, HrtfRequestMode hrtf_appreq, HrtfRequestMode hrtf_userreq);
  278. void aluInitEffectPanning(ALeffectslot *slot, ALCdevice *device);
  279. void aluSelectPostProcess(ALCdevice *device);
  280. /**
  281. * Calculates ambisonic encoder coefficients using the X, Y, and Z direction
  282. * components, which must represent a normalized (unit length) vector, and the
  283. * spread is the angular width of the sound (0...tau).
  284. *
  285. * NOTE: The components use ambisonic coordinates. As a result:
  286. *
  287. * Ambisonic Y = OpenAL -X
  288. * Ambisonic Z = OpenAL Y
  289. * Ambisonic X = OpenAL -Z
  290. *
  291. * The components are ordered such that OpenAL's X, Y, and Z are the first,
  292. * second, and third parameters respectively -- simply negate X and Z.
  293. */
  294. void CalcAmbiCoeffs(const ALfloat y, const ALfloat z, const ALfloat x, const ALfloat spread,
  295. ALfloat (&coeffs)[MAX_AMBI_CHANNELS]);
  296. /**
  297. * CalcDirectionCoeffs
  298. *
  299. * Calculates ambisonic coefficients based on an OpenAL direction vector. The
  300. * vector must be normalized (unit length), and the spread is the angular width
  301. * of the sound (0...tau).
  302. */
  303. inline void CalcDirectionCoeffs(const ALfloat (&dir)[3], ALfloat spread, ALfloat (&coeffs)[MAX_AMBI_CHANNELS])
  304. {
  305. /* Convert from OpenAL coords to Ambisonics. */
  306. CalcAmbiCoeffs(-dir[0], dir[1], -dir[2], spread, coeffs);
  307. }
  308. /**
  309. * CalcAngleCoeffs
  310. *
  311. * Calculates ambisonic coefficients based on azimuth and elevation. The
  312. * azimuth and elevation parameters are in radians, going right and up
  313. * respectively.
  314. */
  315. inline void CalcAngleCoeffs(ALfloat azimuth, ALfloat elevation, ALfloat spread, ALfloat (&coeffs)[MAX_AMBI_CHANNELS])
  316. {
  317. ALfloat x = -std::sin(azimuth) * std::cos(elevation);
  318. ALfloat y = std::sin(elevation);
  319. ALfloat z = std::cos(azimuth) * std::cos(elevation);
  320. CalcAmbiCoeffs(x, y, z, spread, coeffs);
  321. }
  322. /**
  323. * ComputePanGains
  324. *
  325. * Computes panning gains using the given channel decoder coefficients and the
  326. * pre-calculated direction or angle coefficients. For B-Format sources, the
  327. * coeffs are a 'slice' of a transform matrix for the input channel, used to
  328. * scale and orient the sound samples.
  329. */
  330. void ComputePanGains(const MixParams *mix, const ALfloat*RESTRICT coeffs, ALfloat ingain, ALfloat (&gains)[MAX_OUTPUT_CHANNELS]);
  331. inline std::array<ALfloat,MAX_AMBI_CHANNELS> GetAmbiIdentityRow(size_t i) noexcept
  332. {
  333. std::array<ALfloat,MAX_AMBI_CHANNELS> ret{};
  334. ret[i] = 1.0f;
  335. return ret;
  336. }
  337. void MixVoice(ALvoice *voice, ALvoice::State vstate, const ALuint SourceID, ALCcontext *Context, const ALsizei SamplesToDo);
  338. void aluMixData(ALCdevice *device, ALvoid *OutBuffer, ALsizei NumSamples);
  339. /* Caller must lock the device state, and the mixer must not be running. */
  340. void aluHandleDisconnect(ALCdevice *device, const char *msg, ...) DECL_FORMAT(printf, 2, 3);
  341. extern MixerFunc MixSamples;
  342. extern RowMixerFunc MixRowSamples;
  343. extern const ALfloat ConeScale;
  344. extern const ALfloat ZScale;
  345. extern const ALboolean OverrideReverbSpeedOfSound;
  346. #endif