Provide the interpolated beat position

This commit is contained in:
Jean Pierre Cimalando 2020-11-15 11:23:02 +01:00
parent 04fdfc4de2
commit e31bf1381f
3 changed files with 32 additions and 20 deletions

View file

@ -64,12 +64,6 @@ T BeatClock::dequantize(qbeats_t qbeats)
}
///
BeatClock::BeatClock()
{
setSampleRate(config::defaultSampleRate);
setSamplesPerBlock(config::defaultSamplesPerBlock);
}
void BeatClock::clear()
{
beatsPerSecond_ = 2.0;
@ -99,7 +93,8 @@ void BeatClock::setSampleRate(double sampleRate)
void BeatClock::setSamplesPerBlock(unsigned samplesPerBlock)
{
runningBeat_.resize(samplesPerBlock);
runningBeatNumber_.resize(samplesPerBlock);
runningBeatPosition_.resize(samplesPerBlock);
runningBeatsPerBar_.resize(samplesPerBlock);
}
@ -147,11 +142,11 @@ void BeatClock::setPlaying(unsigned delay, bool playing)
isPlaying_ = playing;
}
absl::Span<const int> BeatClock::getRunningBeat()
absl::Span<const int> BeatClock::getRunningBeatNumber()
{
fillBufferUpTo(currentCycleFrames_);
return absl::MakeConstSpan(runningBeat_.data(), currentCycleFrames_);
return absl::MakeConstSpan(runningBeatNumber_.data(), currentCycleFrames_);
}
absl::Span<const int> BeatClock::getRunningBeatsPerBar()
@ -163,7 +158,8 @@ absl::Span<const int> BeatClock::getRunningBeatsPerBar()
void BeatClock::fillBufferUpTo(unsigned delay)
{
int *beatData = runningBeat_.data();
int *beatNumberData = runningBeatNumber_.data();
float *beatNumberPosition = runningBeatPosition_.data();
int *beatsPerBarData = runningBeatsPerBar_.data();
unsigned fill = currentCycleFill_;
@ -172,8 +168,10 @@ void BeatClock::fillBufferUpTo(unsigned delay)
beatsPerBarData[i] = sig.beatsPerBar;
if (!isPlaying_) {
for (; fill < delay; ++fill)
beatData[fill] = 0;
for (; fill < delay; ++fill) {
beatNumberData[fill] = 0;
beatNumberPosition[fill] = 0;
}
currentCycleFill_ = fill;
return;
}
@ -190,7 +188,9 @@ void BeatClock::fillBufferUpTo(unsigned delay)
mustApplyHostPos = false;
// quantization to nearest for prevention of rounding errors
beatData[fill] = dequantize<int>(quantize(clientPos.toBeats(sig)));
double beats = clientPos.toBeats(sig);
beatNumberData[fill] = dequantize<int>(quantize(beats));
beatNumberPosition[fill] = static_cast<float>(beats);
}
currentCycleFill_ = fill;

View file

@ -5,6 +5,7 @@
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
#pragma once
#include "Buffer.h"
#include <absl/types/span.h>
#include <vector>
#include <iosfwd>
@ -73,8 +74,6 @@ struct BBT {
class BeatClock {
public:
BeatClock();
/**
* @brief Set the sample rate.
*/
@ -113,8 +112,20 @@ public:
void setPlaying(unsigned delay, bool playing);
/**
* @brief Get the beat number for each frame of the current cycle.
*
* This signal is quantized to a fixed resolution, such that it never
* suffers 1-off errors due to imprecision in the host time position.
*/
absl::Span<const int> getRunningBeat();
absl::Span<const int> getRunningBeatNumber();
/**
* @brief Get the beat position for each frame of the current cycle.
*
* This is a fractional equivalent of the beat number, however the beat
* boundaries can be traversed erratically due to approximation errors.
* If you need to perform work on exact beat transitions, prefer
* `getRunningBeatNumber` instead.
*/
absl::Span<const float> getRunningBeatPosition();
/**
* @brief Get the time signature numerator for each frame of the current cycle.
*/
@ -124,7 +135,7 @@ private:
void fillBufferUpTo(unsigned delay);
private:
double samplePeriod_ = 0;
double samplePeriod_ { 1.0 / config::defaultSampleRate };
// quantization
typedef int64_t qbeats_t;
@ -150,8 +161,9 @@ private:
// plugin-side counter
BBT lastClientPos_;
std::vector<int> runningBeat_;
std::vector<int> runningBeatsPerBar_;
Buffer<int> runningBeatNumber_ { config::defaultSamplesPerBlock };
Buffer<float> runningBeatPosition_ { config::defaultSamplesPerBlock };
Buffer<int> runningBeatsPerBar_ { config::defaultSamplesPerBlock };
};
} // namespace sfz

View file

@ -925,7 +925,7 @@ void Synth::renderBlock(AudioSpan<float> buffer) noexcept
constexpr bool metronomeEnabled = false;
if (metronomeEnabled) {
impl.resources_.metronome.processAdding(
bc.getRunningBeat().data(), bc.getRunningBeatsPerBar().data(),
bc.getRunningBeatNumber().data(), bc.getRunningBeatsPerBar().data(),
buffer.getChannel(0), buffer.getChannel(1), numFrames);
}