Skip to content

token_request: report every quantification date of a tick - #916

Merged
jcelerier merged 2 commits into
masterfrom
feature/quantification-dates
Jul 30, 2026
Merged

token_request: report every quantification date of a tick#916
jcelerier merged 2 commits into
masterfrom
feature/quantification-dates

Conversation

@jcelerier

Copy link
Copy Markdown
Member

get_quantification_date() returns only the first quantification point of a tick. A tick covers more than one as soon as the division is small, the buffer large or the tempo high — a quarter note of music at a sixteenth division is four points — and every step but the first is silently dropped by the caller. That is what makes Patternist skip steps (ossia/score#2158).

get_quantification_dates() returns all of them, in order, each with the index of the point counted from the last bar (or from the last signature change for rates of a bar or longer). Same shape as the multi-output version halp::tick_musical already offers to avendish nodes, so both sides of the binding can be written the same way.

The existing single-date function is left alone — the scenario and time-sync paths keep their exact behaviour.

Semantics

  • [start; end[ — a point landing exactly on the end of a tick belongs to the next one, so it cannot fire twice.
  • A null or negative rate, or a tick with no musical information, yields a single point at prev_date. Several nodes rely on the latter to step once per tick.
  • rate <= 1 counts bars (1 = every bar, 0.5 = every two); above that it is a subdivision of the quarter note.

Tests

Eleven cases in TokenRequestTest.cpp: empty tick, null/negative rate, no musical info, several points in one tick, an interior point, a point on the start of the tick, one on its end, bars and multi-bar rates, an odd signature (7/8), and a sweep asserting the results are ordered and inside [prev_date; date[ for every usual rate.

Three of them also assert the first element agrees with get_quantification_date(). Not all — worth knowing that the single-date version returns nullopt for a tick that both starts and ends on a boundary (start_quant != end_quant and end_quant == end_quarter * musical_quant_dur), so it misses the point at its own start. The multi-date version reports it. I have not touched that, since changing it would move the scenario and time-sync behaviour, but it looks like a bug.

Not compiled locally.

get_quantification_date only ever returns the first one. A tick covers more
than one as soon as the division is small, the buffer large or the tempo
high - a quarter note of music at a sixteenth division is four - and every
step but the first was silently dropped by the callers.

get_quantification_dates() returns all of them, in order, with the index of
each point counted from the last bar, or from the last signature change for
rates of a bar or longer. The existing single-date function is untouched:
the scenario and time-sync paths keep their behaviour.

Same shape as the multi-output version halp::tick_musical already offers to
avendish nodes, so both sides of the binding can be written the same way.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
jcelerier added a commit to ossia/score that referenced this pull request Jul 29, 2026
get_quantification_date() reports only the first quantification point of a
tick, so every other step in it was dropped without a trace. A small
division, a large buffer or a high tempo are enough: a quarter note of music
at a sixteenth division is four steps, of which one was played.

Iterating get_quantification_dates() instead plays them all, each stamped at
its own date inside the buffer. The step body moves to play_step() unchanged.

Needs ossia/libossia#916.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
time_signature holds uint16_t; passing int members through a braced
initializer is a narrowing conversion and clang rejects it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@jcelerier
jcelerier temporarily deployed to Apple Certificate July 29, 2026 15:19 — with GitHub Actions Inactive
@jcelerier
jcelerier temporarily deployed to Apple Certificate July 29, 2026 15:19 — with GitHub Actions Inactive
@jcelerier
jcelerier temporarily deployed to Apple Certificate July 29, 2026 15:19 — with GitHub Actions Inactive
@jcelerier
jcelerier temporarily deployed to Apple Certificate July 29, 2026 15:19 — with GitHub Actions Inactive
@jcelerier
jcelerier temporarily deployed to Apple Certificate July 29, 2026 15:19 — with GitHub Actions Inactive
@jcelerier
jcelerier temporarily deployed to Apple Certificate July 29, 2026 15:19 — with GitHub Actions Inactive
@jcelerier
jcelerier temporarily deployed to Apple Certificate July 29, 2026 15:19 — with GitHub Actions Inactive
@jcelerier
jcelerier temporarily deployed to Apple Certificate July 29, 2026 15:19 — with GitHub Actions Inactive
@jcelerier
jcelerier temporarily deployed to Apple Certificate July 29, 2026 15:19 — with GitHub Actions Inactive
@jcelerier
jcelerier temporarily deployed to Apple Certificate July 29, 2026 15:19 — with GitHub Actions Inactive
@jcelerier
jcelerier temporarily deployed to Apple Certificate July 29, 2026 15:20 — with GitHub Actions Inactive
@jcelerier
jcelerier merged commit 01050d1 into master Jul 30, 2026
47 checks passed
jcelerier added a commit to ossia/score that referenced this pull request Aug 4, 2026
get_quantification_date() reports only the first quantification point of a
tick, so every other step in it was dropped without a trace. A small
division, a large buffer or a high tempo are enough: a quarter note of music
at a sixteenth division is four steps, of which one was played.

Iterating get_quantification_dates() instead plays them all, each stamped at
its own date inside the buffer. The step body moves to play_step() unchanged.

Needs ossia/libossia#916.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
jcelerier added a commit to ossia/score that referenced this pull request Aug 5, 2026
get_quantification_date() reports only the first quantification point of a
tick, so every other step in it was dropped without a trace. A small
division, a large buffer or a high tempo are enough: a quarter note of music
at a sixteenth division is four steps, of which one was played.

Iterating get_quantification_dates() instead plays them all, each stamped at
its own date inside the buffer. The step body moves to play_step() unchanged.

Needs ossia/libossia#916.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
jcelerier added a commit to ossia/score that referenced this pull request Aug 8, 2026
get_quantification_date() reports only the first quantification point of a
tick, so every other step in it was dropped without a trace. A small
division, a large buffer or a high tempo are enough: a quarter note of music
at a sixteenth division is four steps, of which one was played.

Iterating get_quantification_dates() instead plays them all, each stamped at
its own date inside the buffer. The step body moves to play_step() unchanged.

Needs ossia/libossia#916.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.

1 participant