aboutsummaryrefslogtreecommitdiffstats
path: root/alc/alu.cpp
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2021-06-08 10:52:37 -0700
committerChris Robinson <[email protected]>2021-06-08 10:52:37 -0700
commitdebb932573010fb7b260f56d618644dbadd2e6b1 (patch)
tree1664315e916e7899ed1a2b4c5c68173755f85884 /alc/alu.cpp
parent58a9549a5886fe91aba698abb4e6e4c0c94f129e (diff)
Add an option to mix directly in the JACK callback
Diffstat (limited to 'alc/alu.cpp')
-rw-r--r--alc/alu.cpp102
1 files changed, 64 insertions, 38 deletions
diff --git a/alc/alu.cpp b/alc/alu.cpp
index 00b91bd4..507a5de1 100644
--- a/alc/alu.cpp
+++ b/alc/alu.cpp
@@ -1925,52 +1925,78 @@ void Write(const al::span<const FloatBufferLine> InBuffer, void *OutBuffer, cons
} // namespace
-void DeviceBase::renderSamples(void *outBuffer, const uint numSamples, const size_t frameStep)
+uint DeviceBase::renderSamples(const uint numSamples)
{
- FPUCtl mixer_mode{};
- for(uint written{0u};written < numSamples;)
- {
- const uint samplesToDo{minu(numSamples-written, BufferLineSize)};
+ const uint samplesToDo{minu(numSamples, BufferLineSize)};
- /* Clear main mixing buffers. */
- for(FloatBufferLine &buffer : MixBuffer)
- buffer.fill(0.0f);
+ /* Clear main mixing buffers. */
+ for(FloatBufferLine &buffer : MixBuffer)
+ buffer.fill(0.0f);
- /* Increment the mix count at the start (lsb should now be 1). */
- IncrementRef(MixCount);
+ /* Increment the mix count at the start (lsb should now be 1). */
+ IncrementRef(MixCount);
- /* Process and mix each context's sources and effects. */
- ProcessContexts(this, samplesToDo);
+ /* Process and mix each context's sources and effects. */
+ ProcessContexts(this, samplesToDo);
- /* Increment the clock time. Every second's worth of samples is
- * converted and added to clock base so that large sample counts don't
- * overflow during conversion. This also guarantees a stable
- * conversion.
- */
- SamplesDone += samplesToDo;
- ClockBase += std::chrono::seconds{SamplesDone / Frequency};
- SamplesDone %= Frequency;
+ /* Increment the clock time. Every second's worth of samples is converted
+ * and added to clock base so that large sample counts don't overflow
+ * during conversion. This also guarantees a stable conversion.
+ */
+ SamplesDone += samplesToDo;
+ ClockBase += std::chrono::seconds{SamplesDone / Frequency};
+ SamplesDone %= Frequency;
+
+ /* Increment the mix count at the end (lsb should now be 0). */
+ IncrementRef(MixCount);
- /* Increment the mix count at the end (lsb should now be 0). */
- IncrementRef(MixCount);
+ /* Apply any needed post-process for finalizing the Dry mix to the RealOut
+ * (Ambisonic decode, UHJ encode, etc).
+ */
+ postProcess(samplesToDo);
- /* Apply any needed post-process for finalizing the Dry mix to the
- * RealOut (Ambisonic decode, UHJ encode, etc).
- */
- postProcess(samplesToDo);
+ /* Apply compression, limiting sample amplitude if needed or desired. */
+ if(Limiter) Limiter->process(samplesToDo, RealOut.Buffer.data());
- /* Apply compression, limiting sample amplitude if needed or desired. */
- if(Limiter) Limiter->process(samplesToDo, RealOut.Buffer.data());
+ /* Apply delays and attenuation for mismatched speaker distances. */
+ if(ChannelDelays)
+ ApplyDistanceComp(RealOut.Buffer, samplesToDo, ChannelDelays->mChannels.data());
- /* Apply delays and attenuation for mismatched speaker distances. */
- if(ChannelDelays)
- ApplyDistanceComp(RealOut.Buffer, samplesToDo, ChannelDelays->mChannels.data());
+ /* Apply dithering. The compressor should have left enough headroom for the
+ * dither noise to not saturate.
+ */
+ if(DitherDepth > 0.0f)
+ ApplyDither(RealOut.Buffer, &DitherSeed, DitherDepth, samplesToDo);
- /* Apply dithering. The compressor should have left enough headroom for
- * the dither noise to not saturate.
- */
- if(DitherDepth > 0.0f)
- ApplyDither(RealOut.Buffer, &DitherSeed, DitherDepth, samplesToDo);
+ return samplesToDo;
+}
+
+void DeviceBase::renderSamples(const al::span<float*> outBuffers, const uint numSamples)
+{
+ FPUCtl mixer_mode{};
+ uint total{0};
+ while(const uint todo{numSamples - total})
+ {
+ const uint samplesToDo{renderSamples(todo)};
+
+ auto *srcbuf = RealOut.Buffer.data();
+ for(auto *dstbuf : outBuffers)
+ {
+ std::copy_n(srcbuf->data(), samplesToDo, dstbuf + total);
+ ++srcbuf;
+ }
+
+ total += samplesToDo;
+ }
+}
+
+void DeviceBase::renderSamples(void *outBuffer, const uint numSamples, const size_t frameStep)
+{
+ FPUCtl mixer_mode{};
+ uint total{0};
+ while(const uint todo{numSamples - total})
+ {
+ const uint samplesToDo{renderSamples(todo)};
if LIKELY(outBuffer)
{
@@ -1980,7 +2006,7 @@ void DeviceBase::renderSamples(void *outBuffer, const uint numSamples, const siz
switch(FmtType)
{
#define HANDLE_WRITE(T) case T: \
- Write<T>(RealOut.Buffer, outBuffer, written, samplesToDo, frameStep); break;
+ Write<T>(RealOut.Buffer, outBuffer, total, samplesToDo, frameStep); break;
HANDLE_WRITE(DevFmtByte)
HANDLE_WRITE(DevFmtUByte)
HANDLE_WRITE(DevFmtShort)
@@ -1992,7 +2018,7 @@ void DeviceBase::renderSamples(void *outBuffer, const uint numSamples, const siz
}
}
- written += samplesToDo;
+ total += samplesToDo;
}
}