Repository navigation
Count in on every play, and stop the click panel looking live when the click is off - #682
Merged
Merged
Conversation
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.
2 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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
playCountInis 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 click panel said the click was live when it was off (#655)
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.mjscovers 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.