Provide the interpolated beat position
This commit is contained in:
parent
04fdfc4de2
commit
e31bf1381f
3 changed files with 32 additions and 20 deletions
|
|
@ -64,12 +64,6 @@ T BeatClock::dequantize(qbeats_t qbeats)
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
BeatClock::BeatClock()
|
|
||||||
{
|
|
||||||
setSampleRate(config::defaultSampleRate);
|
|
||||||
setSamplesPerBlock(config::defaultSamplesPerBlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BeatClock::clear()
|
void BeatClock::clear()
|
||||||
{
|
{
|
||||||
beatsPerSecond_ = 2.0;
|
beatsPerSecond_ = 2.0;
|
||||||
|
|
@ -99,7 +93,8 @@ void BeatClock::setSampleRate(double sampleRate)
|
||||||
|
|
||||||
void BeatClock::setSamplesPerBlock(unsigned samplesPerBlock)
|
void BeatClock::setSamplesPerBlock(unsigned samplesPerBlock)
|
||||||
{
|
{
|
||||||
runningBeat_.resize(samplesPerBlock);
|
runningBeatNumber_.resize(samplesPerBlock);
|
||||||
|
runningBeatPosition_.resize(samplesPerBlock);
|
||||||
runningBeatsPerBar_.resize(samplesPerBlock);
|
runningBeatsPerBar_.resize(samplesPerBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -147,11 +142,11 @@ void BeatClock::setPlaying(unsigned delay, bool playing)
|
||||||
isPlaying_ = playing;
|
isPlaying_ = playing;
|
||||||
}
|
}
|
||||||
|
|
||||||
absl::Span<const int> BeatClock::getRunningBeat()
|
absl::Span<const int> BeatClock::getRunningBeatNumber()
|
||||||
{
|
{
|
||||||
fillBufferUpTo(currentCycleFrames_);
|
fillBufferUpTo(currentCycleFrames_);
|
||||||
|
|
||||||
return absl::MakeConstSpan(runningBeat_.data(), currentCycleFrames_);
|
return absl::MakeConstSpan(runningBeatNumber_.data(), currentCycleFrames_);
|
||||||
}
|
}
|
||||||
|
|
||||||
absl::Span<const int> BeatClock::getRunningBeatsPerBar()
|
absl::Span<const int> BeatClock::getRunningBeatsPerBar()
|
||||||
|
|
@ -163,7 +158,8 @@ absl::Span<const int> BeatClock::getRunningBeatsPerBar()
|
||||||
|
|
||||||
void BeatClock::fillBufferUpTo(unsigned delay)
|
void BeatClock::fillBufferUpTo(unsigned delay)
|
||||||
{
|
{
|
||||||
int *beatData = runningBeat_.data();
|
int *beatNumberData = runningBeatNumber_.data();
|
||||||
|
float *beatNumberPosition = runningBeatPosition_.data();
|
||||||
int *beatsPerBarData = runningBeatsPerBar_.data();
|
int *beatsPerBarData = runningBeatsPerBar_.data();
|
||||||
unsigned fill = currentCycleFill_;
|
unsigned fill = currentCycleFill_;
|
||||||
|
|
||||||
|
|
@ -172,8 +168,10 @@ void BeatClock::fillBufferUpTo(unsigned delay)
|
||||||
beatsPerBarData[i] = sig.beatsPerBar;
|
beatsPerBarData[i] = sig.beatsPerBar;
|
||||||
|
|
||||||
if (!isPlaying_) {
|
if (!isPlaying_) {
|
||||||
for (; fill < delay; ++fill)
|
for (; fill < delay; ++fill) {
|
||||||
beatData[fill] = 0;
|
beatNumberData[fill] = 0;
|
||||||
|
beatNumberPosition[fill] = 0;
|
||||||
|
}
|
||||||
currentCycleFill_ = fill;
|
currentCycleFill_ = fill;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -190,7 +188,9 @@ void BeatClock::fillBufferUpTo(unsigned delay)
|
||||||
mustApplyHostPos = false;
|
mustApplyHostPos = false;
|
||||||
|
|
||||||
// quantization to nearest for prevention of rounding errors
|
// 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;
|
currentCycleFill_ = fill;
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include "Buffer.h"
|
||||||
#include <absl/types/span.h>
|
#include <absl/types/span.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
|
|
@ -73,8 +74,6 @@ struct BBT {
|
||||||
|
|
||||||
class BeatClock {
|
class BeatClock {
|
||||||
public:
|
public:
|
||||||
BeatClock();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set the sample rate.
|
* @brief Set the sample rate.
|
||||||
*/
|
*/
|
||||||
|
|
@ -113,8 +112,20 @@ public:
|
||||||
void setPlaying(unsigned delay, bool playing);
|
void setPlaying(unsigned delay, bool playing);
|
||||||
/**
|
/**
|
||||||
* @brief Get the beat number for each frame of the current cycle.
|
* @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.
|
* @brief Get the time signature numerator for each frame of the current cycle.
|
||||||
*/
|
*/
|
||||||
|
|
@ -124,7 +135,7 @@ private:
|
||||||
void fillBufferUpTo(unsigned delay);
|
void fillBufferUpTo(unsigned delay);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
double samplePeriod_ = 0;
|
double samplePeriod_ { 1.0 / config::defaultSampleRate };
|
||||||
|
|
||||||
// quantization
|
// quantization
|
||||||
typedef int64_t qbeats_t;
|
typedef int64_t qbeats_t;
|
||||||
|
|
@ -150,8 +161,9 @@ private:
|
||||||
// plugin-side counter
|
// plugin-side counter
|
||||||
BBT lastClientPos_;
|
BBT lastClientPos_;
|
||||||
|
|
||||||
std::vector<int> runningBeat_;
|
Buffer<int> runningBeatNumber_ { config::defaultSamplesPerBlock };
|
||||||
std::vector<int> runningBeatsPerBar_;
|
Buffer<float> runningBeatPosition_ { config::defaultSamplesPerBlock };
|
||||||
|
Buffer<int> runningBeatsPerBar_ { config::defaultSamplesPerBlock };
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sfz
|
} // namespace sfz
|
||||||
|
|
|
||||||
|
|
@ -925,7 +925,7 @@ void Synth::renderBlock(AudioSpan<float> buffer) noexcept
|
||||||
constexpr bool metronomeEnabled = false;
|
constexpr bool metronomeEnabled = false;
|
||||||
if (metronomeEnabled) {
|
if (metronomeEnabled) {
|
||||||
impl.resources_.metronome.processAdding(
|
impl.resources_.metronome.processAdding(
|
||||||
bc.getRunningBeat().data(), bc.getRunningBeatsPerBar().data(),
|
bc.getRunningBeatNumber().data(), bc.getRunningBeatsPerBar().data(),
|
||||||
buffer.getChannel(0), buffer.getChannel(1), numFrames);
|
buffer.getChannel(0), buffer.getChannel(1), numFrames);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue