Fix host time sometimes skipping beats

Closes #104

Turns out that the tick can be just at the end of the audio block
(ie, frame 511 of 512) and we will just barely miss it.
Because the tick is reset from host info on every audio block
(to always keep things in sync), we would miss the event because
of just 1 sample.
So give a little hand to make sure new beat is always triggered.

Signed-off-by: falkTX <falktx@falktx.com>
This commit is contained in:
falkTX 2022-02-08 04:07:12 +00:00
parent 5e2473b6e9
commit ac297f95f4
No known key found for this signature in database
GPG key ID: CDBAA37ABC74FBA0
3 changed files with 28 additions and 12 deletions

View file

@ -105,19 +105,19 @@ struct HostAudio : TerminalModule {
void processTerminalOutput(const ProcessArgs&) override
{
float** const dataOuts = pcontext->dataOuts;
const int blockFrames = pcontext->engine->getBlockFrames();
// only incremented on output
const int k = dataFrame++;
DISTRHO_SAFE_ASSERT_INT2_RETURN(k < blockFrames, k, blockFrames,);
const float gain = numParams != 0 ? std::pow(params[0].getValue(), 2.f) : 1.0f;
float** const dataOuts = pcontext->dataOuts;
// from cardinal into host, shows as input plug
if (! isBypassed())
{
const float gain = numParams != 0 ? std::pow(params[0].getValue(), 2.f) : 1.0f;
for (int i=0; i<numInputs; ++i)
{
float v = inputs[i].getVoltageSum() * 0.1f;

View file

@ -63,6 +63,9 @@ struct HostTime : TerminalModule {
{
const int64_t blockFrame = pcontext->engine->getBlockFrame();
// local variables for faster access
double tick, tickClock;
// Update time position if running a new audio block
if (lastBlockFrame != blockFrame)
{
@ -70,9 +73,14 @@ struct HostTime : TerminalModule {
timeInfo.reset = pcontext->reset;
timeInfo.bar = pcontext->bar;
timeInfo.beat = pcontext->beat;
timeInfo.tick = pcontext->tick;
timeInfo.tickClock = pcontext->tickClock;
timeInfo.seconds = pcontext->frame / pcontext->sampleRate;
tick = pcontext->tick;
tickClock = pcontext->tickClock;
}
else
{
tick = timeInfo.tick;
tickClock = timeInfo.tickClock;
}
const bool playing = pcontext->playing;
@ -80,7 +88,7 @@ struct HostTime : TerminalModule {
if (playingWithBBT)
{
if (timeInfo.tick == 0.0)
if (d_isZero(tick))
{
pulseReset.trigger();
pulseClock.trigger();
@ -95,9 +103,13 @@ struct HostTime : TerminalModule {
pulseReset.trigger();
}
if ((timeInfo.tick += pcontext->ticksPerFrame) >= pcontext->ticksPerBeat)
tick += pcontext->ticksPerFrame;
// give a little help to keep tick active,
// as otherwise we might miss it if located at the very end of the audio block
if (tick + 0.0001 >= pcontext->ticksPerBeat)
{
timeInfo.tick -= pcontext->ticksPerBeat;
tick -= pcontext->ticksPerBeat;
pulseBeat.trigger();
if (++timeInfo.beat > pcontext->beatsPerBar)
@ -108,9 +120,9 @@ struct HostTime : TerminalModule {
}
}
if ((timeInfo.tickClock += pcontext->ticksPerFrame) >= pcontext->ticksPerClock)
if ((tickClock += pcontext->ticksPerFrame) >= pcontext->ticksPerClock)
{
timeInfo.tickClock -= pcontext->ticksPerClock;
tickClock -= pcontext->ticksPerClock;
pulseClock.trigger();
}
}
@ -120,12 +132,16 @@ struct HostTime : TerminalModule {
const bool hasBeat = pulseBeat.process(args.sampleTime);
const bool hasClock = pulseClock.process(args.sampleTime);
const float beatPhase = playingWithBBT && pcontext->ticksPerBeat > 0.0
? timeInfo.tick / pcontext->ticksPerBeat
? tick / pcontext->ticksPerBeat
: 0.0f;
const float barPhase = playingWithBBT && pcontext->beatsPerBar > 0
? ((float) (timeInfo.beat - 1) + beatPhase) / pcontext->beatsPerBar
: 0.0f;
// store back the local values
timeInfo.tick = tick;
timeInfo.tickClock = tickClock;
if (isBypassed())
return;

View file

@ -359,7 +359,7 @@ void Window::step() {
bndSetFont(uiFont->handle);
// Set window title
std::string windowTitle = APP_NAME + " " + APP_EDITION_NAME + " " + APP_VERSION;
std::string windowTitle = "Cardinal";
if (APP->patch->path != "") {
windowTitle += " - ";
if (!APP->history->isSaved())