Parameterize the UHJ filter length
[openal-soft.git] / core / mixer.h
blob309f4224980bcd104f750ced974c478579f50b18
1 #ifndef CORE_MIXER_H
2 #define CORE_MIXER_H
4 #include <array>
5 #include <cmath>
6 #include <stddef.h>
7 #include <type_traits>
9 #include "alspan.h"
10 #include "ambidefs.h"
11 #include "bufferline.h"
12 #include "devformat.h"
14 struct MixParams;
16 using MixerFunc = void(*)(const al::span<const float> InSamples,
17 const al::span<FloatBufferLine> OutBuffer, float *CurrentGains, const float *TargetGains,
18 const size_t Counter, const size_t OutPos);
20 extern MixerFunc MixSamples;
23 /**
24 * Calculates ambisonic encoder coefficients using the X, Y, and Z direction
25 * components, which must represent a normalized (unit length) vector, and the
26 * spread is the angular width of the sound (0...tau).
28 * NOTE: The components use ambisonic coordinates. As a result:
30 * Ambisonic Y = OpenAL -X
31 * Ambisonic Z = OpenAL Y
32 * Ambisonic X = OpenAL -Z
34 * The components are ordered such that OpenAL's X, Y, and Z are the first,
35 * second, and third parameters respectively -- simply negate X and Z.
37 std::array<float,MaxAmbiChannels> CalcAmbiCoeffs(const float y, const float z, const float x,
38 const float spread);
40 /**
41 * CalcDirectionCoeffs
43 * Calculates ambisonic coefficients based on an OpenAL direction vector. The
44 * vector must be normalized (unit length), and the spread is the angular width
45 * of the sound (0...tau).
47 inline std::array<float,MaxAmbiChannels> CalcDirectionCoeffs(const float (&dir)[3],
48 const float spread)
50 /* Convert from OpenAL coords to Ambisonics. */
51 return CalcAmbiCoeffs(-dir[0], dir[1], -dir[2], spread);
54 /**
55 * CalcAngleCoeffs
57 * Calculates ambisonic coefficients based on azimuth and elevation. The
58 * azimuth and elevation parameters are in radians, going right and up
59 * respectively.
61 inline std::array<float,MaxAmbiChannels> CalcAngleCoeffs(const float azimuth,
62 const float elevation, const float spread)
64 const float x{-std::sin(azimuth) * std::cos(elevation)};
65 const float y{ std::sin(elevation)};
66 const float z{ std::cos(azimuth) * std::cos(elevation)};
68 return CalcAmbiCoeffs(x, y, z, spread);
72 /**
73 * ComputePanGains
75 * Computes panning gains using the given channel decoder coefficients and the
76 * pre-calculated direction or angle coefficients. For B-Format sources, the
77 * coeffs are a 'slice' of a transform matrix for the input channel, used to
78 * scale and orient the sound samples.
80 void ComputePanGains(const MixParams *mix, const float*RESTRICT coeffs, const float ingain,
81 const al::span<float,MAX_OUTPUT_CHANNELS> gains);
84 /** Helper to set an identity/pass-through panning for ambisonic mixing (3D input). */
85 template<typename T, typename I, typename F>
86 auto SetAmbiPanIdentity(T iter, I count, F func) -> std::enable_if_t<std::is_integral<I>::value>
88 if(count < 1) return;
90 std::array<float,MaxAmbiChannels> coeffs{{1.0f}};
91 func(*iter, coeffs);
92 ++iter;
93 for(I i{1};i < count;++i,++iter)
95 coeffs[i-1] = 0.0f;
96 coeffs[i ] = 1.0f;
97 func(*iter, coeffs);
101 #endif /* CORE_MIXER_H */