You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit fa9d88b
Browse filesBrowse the repository at this point in the historyBrowse files
Take the beat the operator pointed at, not the one after it
The user, on the built app: "I click the down beat button at the very
beginning of the bar/measure ... the dot is always one off ... it's always
one too slow."
It was. The snap set a flag that `advanceBar` spent on the *next* beat
called, so a press landed a whole beat late for the only way the control is
ever used — a person presses it *on* the downbeat they can hear, by which
time the tracker has already called that beat, and the bar came out anchored
to beat 2. HANDOFF §5.5 asks for a control that "snaps bar phase
immediately", and a beat late is not immediately.
The snap now takes the *nearest* beat: the one just called if it is less
than half a beat period behind, and the one still to come otherwise. The
split is symmetric and has no constant in it, deliberately — the pipeline's
delay and a person's reaction time both move where inside that window a
press falls, and neither has been measured. The period's own middle is the
only place the line can go without inventing a number. That period is the
filter's, never the published tempo, because ÷2 and ×2 move the second and
not the first.
Naming the beat just gone takes effect at once: `beatInBar` is 1 before
`snapDownbeat()` returns, so the dots move under the operator's finger
rather than a beat later. What cannot move is that beat's outgoing event,
which has already been sent — so the correction reaches the transports on
the next beat, which now carries `BeatEvent::snapped`. Link is unharmed by
that: `forceBeat` is given the bar *position*, and forcing beat 2 of the bar
moves a peer's phase exactly as far as forcing beat 1 would.
This is the cause 8e31666 recorded as deliberate and left alone. That
session was right that the button said nothing and fixed the silence; it
took "lands on the next beat" as design rather than asking whether the next
beat was the right one.
Nothing on the tracking path changed, and that is measured rather than
asserted: `--trace` over "01 - Pirates" and "1 - Jungle - GOOD TIMES" is
byte-identical before and after, 19,698 frames of every published column.
219 local-core, 250 local, 219 Debug with the RT allocation guard live,
clang-tidy and clang-format clean.
Copy file name to clipboardExpand all lines: README.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -138,7 +138,7 @@ there is an interface. None of them stops the tracker or reseeds the filter.
138
138
| Key ||
139
139
|---|---|
140
140
|`space`| tap the tempo. Three taps are enough; the fold window moves onto what you tapped, so the readout and the setting agree on why the tempo is what it is. |
141
-
|`d`| downbeat now — the next beat starts the bar, and goes on starting it. With `--link`, that beat is placed with `forceBeatAtTime`, so peers move too. |
141
+
|`d`| downbeat now — the beat nearest the press starts the bar, and goes on starting it. Press it *on* the downbeat you can hear: the beat just gone is the one it takes. With `--link`, the new phase is placed with `forceBeatAtTime`, so peers move too. |
142
142
|`h` / `x`| halve and double the published tempo, keeping the lock. |
143
143
|`[` / `]`| move the latency offset by 5 ms, on the beat timestamps and the transports alike. |
0 commit comments