Skip to content

Count in on every play, and stop the click panel looking live when the click is off - #682

Merged
thcp merged 4 commits into
mainfrom
fix/grid-with-click-off-655
Sep 23, 2026
Merged

thcp merged 4 commits into
mainfrom
fix/grid-with-click-off-655

Conversation

@thcp

@thcp thcp commented Sep 23, 2026

Copy link
Copy Markdown
Collaborator

Closes #655
Closes #681

The count-in only ever played once per track

The count-in played on the first press of play, and never again. After a stop, a pause or the end of the track it received its clicks with every one already in the past, and Web Audio drops those without a sound. That was true with the click track on or off.

That is what #655 describes as "count-in does not work with the click off": the reporter's second play. The count-in is built to play on its own. The metronome's playCountIn is documented as independent of the running click, "so a count-in can precede a clean (click-off) playback".

Cause. The count-in is timed against the engine's clock for the start it precedes, and it was timed as soon as play() returned. The streaming engine, which is the default, only sets that clock once the starting chunk is decoded. It evicts chunks behind the playhead, so playing again after a stop means fetching a chunk it no longer has. The clicks were therefore timed against the previous start's clock. Measured: the audio clock was at 4.20 while the clicks were placed between 0.21 and 1.71.

Fix.

  • play() now resolves once the new start is scheduled, on both engines. It resolves false if the start was abandoned.
  • The count-in waits for it, keeps the metronome that existed when it was armed, and is dropped if a pause or stop gets there first.
  • The streaming engine also now restarts from the top when played at the end of a track, as the buffered engine already did. The transport's count-in placement assumed that behaviour.

The click panel said the click was live when it was off (#655)

  • Grid. Grid stayed lit with the beat-grid editor open after the click was switched off. The editor edits the beats the click plays, so now switching the click off closes it, from the button or K. Opening it with the click off switches the click on, the same way choosing a vocal mode switches vocals on. Done closes the editor and leaves the click as it is.
  • Count-in tint. The count-in keeps its armed tint with the click off, because it does play with the click off.

The click toggle always said ON (#681)

The toggle's label was a fixed "ON" in every language, so with the click off it still read ON. It is now the metronome icon alone, which is what the #655 reporter suggested. The gold highlight carries the state, and the accessible name and tooltip still read "Click track (K)". It is square, matching the volume button beside it.

Verification

  • count-in-replay.spec.mjs covers replay after a pause, a stop and the end of the track, each with the click on and off. It also holds a chunk download open to show that a pause drops a count-in still waiting on its start. All 7 tests fail against main.
  • Five tests cover Grid following the click. They also fail against main.
  • One test covers the icon-only toggle.
  • 251 e2e tests pass, and the JS unit and i18n checks are clean.

Thales added 4 commits September 23, 2026 14:11
With the click track switched off, two things in its own panel went on saying
otherwise (#655). Grid stayed lit with the beat grid editor still open, and
the count-in kept the tint that marks it as armed, though a count-in counts
into the click and does not play without it. The reporter read both as
settings that would still take effect, which is the fair reading.

The count-in tint now requires the click to be on as well as a length to be
chosen. Only the tint follows the click: the length stays in the select, so
switching the click back on brings the count-in back as it was.

The grid editor is a click-track tool. It edits the beats the click plays, the
live click and the exported one, and it is only available while there is a
metronome. So switching the click off closes it, from the button or the K
shortcut, and opening it with the click off switches the click on, the same
way choosing a vocal mode switches vocals on. Closing the editor leaves the
click alone: Done means finished editing, not stop the click.

beatgridUi already imports from transport, so the editor subscribes to the
toggle through onMetronomeToggle rather than transport importing back into
it. toggleMetronome is the one path every on and off goes through.

The existing count-in test asserted the armed tint with the click off, which
is the state #655 reports as wrong. It now switches the click on first. The
five new tests fail against main and pass here.
The on/off button carried a fixed label, ON, in every language. It never
changed, so with the click off it still said ON and only the missing gold
highlight said otherwise (#681). It turned up in the screenshots taken to
check #655, which is the same complaint about a different control.

Making it say OFF would have put the state on the button twice, in the word
and in the highlight, and the word is the less reliable of the two: on a label
"ON" reads as a state and as a command to switch on equally well. The
highlight is already unambiguous and is how the rest of that row shows state.
The #655 reporter suggested exactly this, a metronome icon alone, and it gives
width back to a row that already folds its options away when narrow.

The button keeps its accessible name and tooltip, "Click track (K)", so a
screen reader and a hover lose nothing. It is square like the volume button
beside it rather than a narrower pill. The Grid button shares the class and
keeps its label, so the change is a modifier on this button only. The
click.on key has nothing left to label and is gone from all ten tables.
b2c3194 took the count-in's armed tint away whenever the click track was off,
on the grounds that a count-in counts into the click and does not play
without it. That was wrong. The count-in is built to play on its own: the
metronome's playCountIn is documented as independent of the running click,
"so a count-in can precede a clean (click-off) playback", and _armCountIn says
the same.

It seemed not to because of a separate fault, fixed in the next commit: only
the first play of a track ever counted in, with the click on or off. The #655
reporter switched the click off, played again, heard no count-in, and read it
as the two being tied together. So did I, in the reply on that issue.

With that fixed, un-tinting it would say a count-in is not armed when it is
about to play. The tint is back to meaning a length is chosen. The grid editor
still follows the click, since that one really is a click tool.
A count-in only ever played on the first press of play for a track. After a
stop, a pause or the end of the track it was handed its clicks and every one
of them was already in the past, which Web Audio drops without a sound. With
the click on or off. It is what the #655 reporter heard as "the count-in does
not work with the click off": their second play.

The count-in is placed against the engine's clock for the start it precedes,
and it was placed as soon as play() returned. The streaming engine, which is
the default, only sets that clock once the chunk it starts from is decoded,
and chunks behind the playhead are evicted, so Stop and play again goes back
to a chunk that is gone and takes the fetch path. The clicks were then placed
against the previous start's clock. Measured: on the second play the audio
clock was at 4.20 while the clicks mapped to 0.21 through 1.71.

Its own comment said the count-in "only takes effect on the common
cached-chunk-0 path" and that chunk 0 is "virtually always already cached".
True for the first play of a track, and for no play after it.

play() now resolves when the engine's clock describes the new start: true
once it is scheduled, false if the start was abandoned, paused first or the
fetch failed. Both engines keep that contract; the buffered one always
resolves at once. The count-in waits for it, holds the metronome that existed
when it was armed rather than whatever the live binding points at by then,
and is dropped if a pause or Stop overtook it. A count-in lead is honoured on
the fetch path too, not only the cached one.

The streaming engine also did not do what the buffered one does at the end of
a track: play from the end starts again from the top. The transport places the
count-in on that assumption, so after the end it led into 0 while the audio
started at the end. It now resets the same way.

Six new tests play, end the first play three different ways, with the click
on and off, and play again. A seventh holds the chunk download open to show a
count-in waiting on its start is dropped by a pause. All seven fail against
main.
@thcp thcp mentioned this pull request Sep 23, 2026
2 tasks done
@thcp
thcp merged commit 8f00555 into main Sep 23, 2026
10 checks passed
@thcp
thcp deleted the fix/grid-with-click-off-655 branch September 23, 2026 15:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The click track button always says ON, including when the click is off [Bug]: UI Bug with ClickTrack section

1 participant