aboutsummaryrefslogtreecommitdiffstats
path: root/core/device.h
diff options
context:
space:
mode:
authorChris Robinson <chris.kcat@gmail.com>2023-01-04 22:02:29 -0800
committerChris Robinson <chris.kcat@gmail.com>2023-01-04 23:03:15 -0800
commit078b50e0ed6a0b89aa2e1f84bbbebbf24b885a4e (patch)
treedb7bee5d11af40ae01d6210cfd41f6fa60a247f9 /core/device.h
parente38413a4fbb0b4f85950c929141856a767993f4f (diff)
Simplify handling effect output for spatial effects
Effects are given a 3D ambisonic buffer of the same order as the device, for processing surround sound. Effects that pass input channels to matching output channels as it processes them don't need to mix each input channel to all output channels. At most, an input channel may mix to a different output channel, if the target buffer uses a different channel layout, and need a gain adjustment, if it uses a different scaling. With a 2D output buffer, a number of channels can be skipped altogether.
Diffstat (limited to 'core/device.h')
-rw-r--r--core/device.h36
1 files changed, 33 insertions, 3 deletions
diff --git a/core/device.h b/core/device.h
index 6317067e..7d50c54d 100644
--- a/core/device.h
+++ b/core/device.h
@@ -95,6 +95,8 @@ struct DistanceComp {
};
+#define INVALID_CHANNEL_INDEX ~0u
+
struct BFChannelConfig {
float Scale;
uint Index;
@@ -105,6 +107,37 @@ struct MixParams {
std::array<BFChannelConfig,MaxAmbiChannels> AmbiMap{};
al::span<FloatBufferLine> Buffer;
+
+ /**
+ * Helper to set an identity/pass-through panning for ambisonic mixing. The
+ * source is expected to be a 3D ACN/N3D ambisonic buffer, and for each
+ * channel [0...count), the given functor is called with the source channel
+ * index, destination channel index, and the gain for that channel. If the
+ * destination channel is INVALID_CHANNEL_INDEX, the given source channel
+ * is not used for output.
+ */
+ template<typename F>
+ void setAmbiMixParams(const MixParams &inmix, const float gainbase, F func) const
+ {
+ const size_t numIn{inmix.Buffer.size()};
+ const size_t numOut{Buffer.size()};
+ for(size_t i{0};i < numIn;++i)
+ {
+ auto idx = INVALID_CHANNEL_INDEX;
+ auto gain = 0.0f;
+
+ for(size_t j{0};j < numOut;++j)
+ {
+ if(AmbiMap[j].Index == inmix.AmbiMap[i].Index)
+ {
+ idx = static_cast<uint>(j);
+ gain = AmbiMap[j].Scale * gainbase;
+ break;
+ }
+ }
+ func(i, idx, gain);
+ }
+ }
};
struct RealMixParams {
@@ -303,13 +336,10 @@ private:
uint renderSamples(const uint numSamples);
};
-
/* Must be less than 15 characters (16 including terminating null) for
* compatibility with pthread_setname_np limitations. */
#define MIXER_THREAD_NAME "alsoft-mixer"
#define RECORD_THREAD_NAME "alsoft-record"
-#define INVALID_CHANNEL_INDEX ~0u
-
#endif /* CORE_DEVICE_H */