aboutsummaryrefslogtreecommitdiffstats
path: root/core/mixer.h
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2023-05-03 16:17:49 +0200
committerSven Gothel <[email protected]>2023-05-03 16:17:49 +0200
commitec167fd05661a5b02dd406c87081f84a0f8dd77d (patch)
tree9c4669e471c9969bda59265381b18d2d416db060 /core/mixer.h
parent0d14d30808cfe7b9e3413353e3eef8a0f201399a (diff)
parentd3875f333fb6abe2f39d82caca329414871ae53b (diff)
Merge branch 'v1.23.1'
Resolved Conflicts: CMakeLists.txt
Diffstat (limited to 'core/mixer.h')
-rw-r--r--core/mixer.h109
1 files changed, 109 insertions, 0 deletions
diff --git a/core/mixer.h b/core/mixer.h
new file mode 100644
index 00000000..aa7597bb
--- /dev/null
+++ b/core/mixer.h
@@ -0,0 +1,109 @@
+#ifndef CORE_MIXER_H
+#define CORE_MIXER_H
+
+#include <array>
+#include <cmath>
+#include <stddef.h>
+#include <type_traits>
+
+#include "alspan.h"
+#include "ambidefs.h"
+#include "bufferline.h"
+#include "devformat.h"
+
+struct MixParams;
+
+/* Mixer functions that handle one input and multiple output channels. */
+using MixerOutFunc = void(*)(const al::span<const float> InSamples,
+ const al::span<FloatBufferLine> OutBuffer, float *CurrentGains, const float *TargetGains,
+ const size_t Counter, const size_t OutPos);
+
+extern MixerOutFunc MixSamplesOut;
+inline void MixSamples(const al::span<const float> InSamples,
+ const al::span<FloatBufferLine> OutBuffer, float *CurrentGains, const float *TargetGains,
+ const size_t Counter, const size_t OutPos)
+{ MixSamplesOut(InSamples, OutBuffer, CurrentGains, TargetGains, Counter, OutPos); }
+
+/* Mixer functions that handle one input and one output channel. */
+using MixerOneFunc = void(*)(const al::span<const float> InSamples, float *OutBuffer,
+ float &CurrentGain, const float TargetGain, const size_t Counter);
+
+extern MixerOneFunc MixSamplesOne;
+inline void MixSamples(const al::span<const float> InSamples, float *OutBuffer, float &CurrentGain,
+ const float TargetGain, const size_t Counter)
+{ MixSamplesOne(InSamples, OutBuffer, CurrentGain, TargetGain, Counter); }
+
+
+/**
+ * Calculates ambisonic encoder coefficients using the X, Y, and Z direction
+ * components, which must represent a normalized (unit length) vector, and the
+ * spread is the angular width of the sound (0...tau).
+ *
+ * NOTE: The components use ambisonic coordinates. As a result:
+ *
+ * Ambisonic Y = OpenAL -X
+ * Ambisonic Z = OpenAL Y
+ * Ambisonic X = OpenAL -Z
+ *
+ * The components are ordered such that OpenAL's X, Y, and Z are the first,
+ * second, and third parameters respectively -- simply negate X and Z.
+ */
+std::array<float,MaxAmbiChannels> CalcAmbiCoeffs(const float y, const float z, const float x,
+ const float spread);
+
+/**
+ * CalcDirectionCoeffs
+ *
+ * Calculates ambisonic coefficients based on an OpenAL direction vector. The
+ * vector must be normalized (unit length), and the spread is the angular width
+ * of the sound (0...tau).
+ */
+inline std::array<float,MaxAmbiChannels> CalcDirectionCoeffs(const float (&dir)[3],
+ const float spread)
+{
+ /* Convert from OpenAL coords to Ambisonics. */
+ return CalcAmbiCoeffs(-dir[0], dir[1], -dir[2], spread);
+}
+
+/**
+ * CalcDirectionCoeffs
+ *
+ * Calculates ambisonic coefficients based on an OpenAL direction vector. The
+ * vector must be normalized (unit length).
+ */
+constexpr std::array<float,MaxAmbiChannels> CalcDirectionCoeffs(const float (&dir)[3])
+{
+ /* Convert from OpenAL coords to Ambisonics. */
+ return CalcAmbiCoeffs(-dir[0], dir[1], -dir[2]);
+}
+
+/**
+ * CalcAngleCoeffs
+ *
+ * Calculates ambisonic coefficients based on azimuth and elevation. The
+ * azimuth and elevation parameters are in radians, going right and up
+ * respectively.
+ */
+inline std::array<float,MaxAmbiChannels> CalcAngleCoeffs(const float azimuth,
+ const float elevation, const float spread)
+{
+ const float x{-std::sin(azimuth) * std::cos(elevation)};
+ const float y{ std::sin(elevation)};
+ const float z{ std::cos(azimuth) * std::cos(elevation)};
+
+ return CalcAmbiCoeffs(x, y, z, spread);
+}
+
+
+/**
+ * ComputePanGains
+ *
+ * Computes panning gains using the given channel decoder coefficients and the
+ * pre-calculated direction or angle coefficients. For B-Format sources, the
+ * coeffs are a 'slice' of a transform matrix for the input channel, used to
+ * scale and orient the sound samples.
+ */
+void ComputePanGains(const MixParams *mix, const float*RESTRICT coeffs, const float ingain,
+ const al::span<float,MaxAmbiChannels> gains);
+
+#endif /* CORE_MIXER_H */