diff options
author | Chris Robinson <[email protected]> | 2021-06-08 10:52:37 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2021-06-08 10:52:37 -0700 |
commit | debb932573010fb7b260f56d618644dbadd2e6b1 (patch) | |
tree | 1664315e916e7899ed1a2b4c5c68173755f85884 /alc/alu.cpp | |
parent | 58a9549a5886fe91aba698abb4e6e4c0c94f129e (diff) |
Add an option to mix directly in the JACK callback
Diffstat (limited to 'alc/alu.cpp')
-rw-r--r-- | alc/alu.cpp | 102 |
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; } } |