From 1983894bc8c4fdb085775c9510fd7f2278592596 Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Sun, 15 Nov 2020 12:04:01 +0100 Subject: [PATCH] Add the phase generator by beat clock --- src/sfizz/BeatClock.cpp | 34 ++++++++++++++++++++++++++++++++++ src/sfizz/BeatClock.h | 10 ++++++++++ 2 files changed, 44 insertions(+) diff --git a/src/sfizz/BeatClock.cpp b/src/sfizz/BeatClock.cpp index 32e997c7..acc5e382 100644 --- a/src/sfizz/BeatClock.cpp +++ b/src/sfizz/BeatClock.cpp @@ -199,6 +199,40 @@ void BeatClock::fillBufferUpTo(unsigned delay) mustApplyHostPos_ = mustApplyHostPos; } +void BeatClock::calculatePhase(float beatPeriod, float* phaseOut) +{ + const unsigned numFrames = currentCycleFrames_; + + if (beatPeriod == 0.0f) { + fill(absl::MakeSpan(phaseOut, numFrames), 0.0f); + return; + } + + const float invBeatPeriod = 1.0f / beatPeriod; + const float* beatPositionData = getRunningBeatPosition().data(); + + for (unsigned i = 0; i < numFrames; ++i) { + float beatPosition = std::max(0.0f, beatPositionData[i]); + float phase = beatPosition * invBeatPeriod; + phase -= static_cast(phase); + phaseOut[i] = phase; + } +} + +void BeatClock::calculatePhaseModulated(const float* beatPeriodData, float* phaseOut) +{ + const unsigned numFrames = currentCycleFrames_; + const float* beatPositionData = getRunningBeatPosition().data(); + + for (unsigned i = 0; i < numFrames; ++i) { + float beatPeriod = beatPeriodData[i]; + float beatPosition = std::max(0.0f, beatPositionData[i]); + float phase = beatPosition / beatPeriod; + phase -= static_cast(phase); + phaseOut[i] = (beatPeriod != 0.0f) ? phase : 0.0f; + } +} + } // namespace sfz std::ostream& operator<<(std::ostream& os, const sfz::BBT& pos) diff --git a/src/sfizz/BeatClock.h b/src/sfizz/BeatClock.h index b75ba182..cccc76e8 100644 --- a/src/sfizz/BeatClock.h +++ b/src/sfizz/BeatClock.h @@ -130,6 +130,16 @@ public: * @brief Get the time signature numerator for each frame of the current cycle. */ absl::Span getRunningBeatsPerBar(); + /** + * @brief Create a normalized phase signal for LFO which completes a + * period every N-th beat. + */ + void calculatePhase(float beatPeriod, float* phaseOut); + /** + * @brief Create a normalized phase signal for LFO which completes a + * period every N-th beat, where N can vary over time. + */ + void calculatePhaseModulated(const float* beatPeriodData, float* phaseOut); private: void fillBufferUpTo(unsigned delay);