Skip to content

Play directive

This document defines the syntax and semantics of the play directive: a mechanism for locally changing a song's style and tempo, taking effect from a specific measure and remaining in force until a new directive.

The play directive addresses the need for lead sheets with sections at different tempos or grooves (e.g. "vamp till cue" slowing down, "double-time" over a solo, a switch from swing to latin midway through the song) without resorting to separate songs.


1. Definition

A play directive is a token of the M) (Markers) line that declares, locally, one or both of the following elements:

  • a style (textual description of the musical character);
  • a tempo, expressed as an explicit BPM or as a metric modulation (metric relationship between two NRK figures).

The play directive is not a barline decorator: it does not attach to the | sign and does not belong to the family of measure decorators ([1.] volta, (3/4,Dm) meter/key change). It is an autonomous token that coexists with textual markers in the M) line.


2. Syntax

2.1 General form

Two alternative forms:

(=[Style][,Tempo])         with prefix `=` (Style/BPM/combined)
(<figure>=<figure>)        pure metric modulation (no prefix)

Inside the parentheses:

  • The prefix = opens a directive with Style and/or Tempo slots (BPM or metric modulation), distinguishing it from a meter or key change (3/4,Dm).
  • A metric-modulation-only directive (e.g. (4=4.)) is written without the prefix =: the internal = between two NRK figures is already self-disambiguating with respect to the other tokens in parentheses.

When the prefix = is present and both Style and Tempo are declared, the order is fixed: Style first, Tempo after, separated by a comma.

2.2 Style slot

Free text describing the musical character (e.g. Rock, Fast swing, rock ballad, bossa, funk). The same textual rules as the HS) Style slot of the header apply (neumaRk_header.md §11.2):

  • free multi-word text, internal spaces allowed;
  • internal commas allowed (e.g. Fast, dirty swing): the parser reconstructs the Style using the "parse from end" rule described below;
  • no capitalization constraint (rendering preserves the spelling);
  • it must not collide with patterns interpretable as Tempo (see §2.3 and §3.2).

2.2.1 Style/Tempo disambiguation ("parse from end")

When the directive contains a comma, the parser looks for the last comma and tries to interpret what follows as a Tempo (BPM or metric modulation). If the match succeeds → split there (Style = everything to the left, Tempo = everything to the right). If it fails, the whole body is treated as a single slot (Style if the user did not attempt a Tempo, or Tempo-only if there are no commas and the body is a valid Tempo).

Practical consequences:

Body Style Tempo
=Rock,120bpm Rock 120bpm
=Fast, dirty swing, 180bpm Fast, dirty swing 180bpm
=swing, 4=4. swing 4=4.
=foo, bar (no trailing Tempo) foo, bar
=120bpm (no comma, is Tempo) 120bpm

2.3 Tempo slot

Two alternative, mutually exclusive forms:

2.3.1 Explicit BPM

Nbpm

where N is a 2- or 3-digit integer (range 10–999), immediately followed by the bpm suffix (case-insensitive: bpm, BPM, Bpm all allowed). Examples:

60bpm     120bpm     200bpm     90BPM

An out-of-bounds range (5bpm, 1000bpm) produces warning W136. Decimals (120.5bpm) are not allowed (parsing error).

2.3.2 Metric modulation

<previous-figure>=<new-figure>

where each side is an NRK figure (1, 2, 4, 8, 16, 32, with dotted . and tuplet t allowed). Standard convention (Grove, Carter): the value on the left is a figure in the previous tempo, the value on the right is a figure in the new tempo; the two figures have the same physical duration. Examples:

4=2     ♩ = 𝅗𝅥    (the quarter note of the previous tempo equals a new half note → double-time)
4=4.    ♩ = ♩.   (the previous quarter equals a new dotted quarter → speeds up)
2=4     𝅗𝅥 = ♩    (the previous half note equals a new quarter → half-time)
4.=4    ♩. = ♩   (the previous dotted quarter equals a new quarter → slows down)
8t=8    ♪₃ = ♪   (the previous triplet eighth equals a new eighth → speeds up)

Metric modulation is executable: the player recomputes the effective BPM from the metric relationship applied to the current currentBPM (formula in §5.2). Invalid figures (e.g. 5=4, 4=k) produce warning W137.

2.4 Syntactic examples

(=Rock,120bpm)                 style + tempo
(=swing,4=4.)                  style + metric modulation
(=fast swing)                  style only (multi-word)
(=Fast, dirty swing, 180bpm)   style with internal commas + tempo
(=foo, bar)                    style only with comma (no trailing Tempo)
(=120bpm)                      BPM only
(8=4)                          metric modulation only (NO prefix `=`)

Invalid forms:

(=)                        W134 — empty directive
(=120bpm,Rock)             W135 — inverted slot order
(=5bpm)                    W136 — BPM out of range
(4=q)                      W137 — invalid NRK figure

3. Structural position

3.1 Only in the M) line

A play directive may appear exclusively in a Markers line (M), explicit or deduced according to neumaRk_markers.md §2). Its presence in any other musical line (C), N), A), D), L), F)) produces warning W138.

3.2 Co-location with textual markers

A play directive coexists freely with textual markers ([Mark], "freely") in the same measure of the M) line. The disambiguation is by delimiters:

Token Type
[…] / "…" textual marker
(=…) play directive (Style/BPM/combined)
(fig=fig) play directive (pure metric modulation)
(…) other barline decorator (meter/key change) — not in M)

Example:

M) | [A] (=Rock,120bpm) |

Measure 1 contains both the marker [A] and the play directive that sets Rock 120 BPM from the same measure onward.

The order between textual markers and play directives is free in the same measure: the parser identifies tokens by delimiters.

3.3 Temporal anchoring

A play directive applies from beat 1 of the measure of appearance, and remains in force until a new play directive (see §4).

Mid-bar changes are not allowed: the horizontal position of the token in the M) line does not alter the point of application, which is always the beginning of the measure.


4. Persistence and context

4.1 currentStyle / currentBPM state machine

The song's persistent musical context (neumaRk_specification.md §2.1) includes two cross-datapack variables:

  • currentStyle — initialized by HS) Style of the header;
  • currentBPM — initialized by HB) BPM of the header.

Each play directive updates one or both variables, starting from the measure of appearance. The variables then remain in force until a new play directive, crossing datapack boundaries.

4.2 Single-slot directives

A directive that declares a single slot updates only that variable, leaving the other unchanged:

M) | (=Rock,120bpm) | | (=fast swing) | (2=4) |
  • Measure 1: currentStyle ← Rock, currentBPM ← 120.
  • Measure 3: currentStyle ← fast swing, currentBPM stays 120.
  • Measure 4: currentBPM ← currentBPM × (2/4) = 60 (metric modulation), currentStyle stays "fast swing".

4.3 No explicit reset

There is no special token to "return to the header values". To restore the initial style/BPM, you redeclare it explicitly:

HS) swing
HB) 140

…
M) | (=Rock,80bpm) | … | (=swing,140bpm) |    ← explicit restore

This choice keeps the spec orthogonal: every directive is a positive action, there is no hidden "turn-off" semantics.


5. Player semantics

5.1 Executable

Play directives are executable instructions for the runtime player:

  • a change of currentBPM (explicit or via metric modulation) alters the execution speed immediately;
  • a change of currentStyle signals to the accompaniment engine to change groove (Rock → Bossa → Swing produces different patterns of drums, bass, accompaniment guitar).

The actual style → groove mapping is the player's responsibility and is not defined by this specification. Styles unknown to the player are treated as a fallback to the default groove, without error.

5.2 Metric modulation: BPM calculation

Convention (standard musical, see Grove Music Online and Elliott Carter): in a metric modulation S = D the value on the left is a figure in the previous tempo, the value on the right is a figure in the new tempo. The two figures have the same physical duration.

From this equivalence we derive:

dur(S) × (60 / oldBPM) = dur(D) × (60 / newBPM)
⟹ newBPM = oldBPM × dur(D) / dur(S)

where dur(F) is the duration of NRK figure F in unit beats (quarter = 1, whole = 4, half = 2, eighth = 0.5; dotted = 1.5×; tuplet t = 2/3×).

Examples (assuming currentBPM = 120):

Modulation newBPM Musical effect
4=2 240 double-time (old ♩ → new 𝅗𝅥)
4=4. 180 speeds up (old ♩ → new ♩.)
8t=8 180 speeds up (old ♪₃ → new ♪)
2=4 60 half-time (old 𝅗𝅥 → new ♩)
4.=4 80 slows down (old ♩. → new ♩)

6. Render

6.1 Marker band

All play directives are rendered in the same marker band (above the staff), horizontally aligned to beat 1 of the measure of appearance.

6.2 Style

The style is rendered as italic text, body size. When co-located with a textual marker in the same measure, the renderer applies a vertical offset to avoid overlap, keeping both visible.

6.3 Explicit BPM tempo

Nbpm is rendered in traditional notation:

♩ = N

where the beat figure is derived from the denominator of the current meter (4/4 → ♩, 6/8 → ♪., 3/2 → 𝅗𝅥, etc.). In the absence of an identifiable meter, default .

6.4 Metric modulation

figure₁=figure₂ is rendered in traditional notation as:

glyph(figure₁) = glyph(figure₂)

where glyph(F) is the black/white/open notehead of figure F, with a dot if dotted, with ³ (or equivalent) if tuplet.

Examples:

4=4.    →   ♩ = ♩.
8=4     →   ♪ = ♩
8t=8    →   ♪³ = ♪

6.5 Combined Style + Tempo

When a directive contains both slots, the render presents style above the tempo in two vertical lines, or on the same line separated by a space. The choice is the renderer's.


7. Diagnostics

7.1 Diagnostic codes

Code Description
W134 Empty directive (=): no slot declared
W135 Inverted slot order: tempo before style
W136 BPM out of range (integer 10–999 expected)
W137 Invalid NRK figure in metric modulation
W138 Play directive in a line other than M)

7.2 Unknown style

A style not recognized by the player (e.g. (=mood music)) is not an error: it is respected as descriptive text and ignored by the accompaniment engine (fallback to the default groove).

7.3 BPM = 0 or negative

Excluded from the range; produces W136.

7.4 Redundant directives

A directive that re-asserts exactly the current values (e.g. (=Rock,120bpm) when currentStyle="Rock" and currentBPM=120) is allowed, generating no warning. The player applies it as a no-op.


8. Examples

8.1 Tempo change midway through the song

HS) swing
HB) 140

…
M) | [Solo] | | | (=200bpm) | | | | |

A solo that starts at 140 BPM; from measure 4 onward it speeds up to 200 BPM.

8.2 Combined style + tempo change

M) | [Intro] (=Rock,120bpm) | | | [A] | | (=swing,160bpm) | |
  • Measure 1: marker [Intro] + setup Rock 120 BPM.
  • Measure 4: marker [A] (style and tempo unchanged).
  • Measure 6: switch to swing 160 BPM.

8.3 Metric modulation

M) | (=swing,120bpm) | | | (2=4) | | | | (4=2) | | |
  • Measure 1: swing at 120 BPM.
  • Measure 4: half-time (currentBPM = 60).
  • Measure 8: double-time relative to the previous (currentBPM = 120, back to the initial value).

8.4 Multi-word style

M) | (=Fast swing,200bpm) |

Style "Fast swing" (two words, internal space allowed), 200 BPM.

8.5 Vamp till cue with style change

M) | [A] | | | | [? Vamp] (=funk,90bpm) | | | (=swing,140bpm) [B] |
  • Measures 1–4: section A (style/tempo from the header).
  • Measures 5–7: vamp in funk at 90 BPM (the collapsible section [? Vamp] is defined in neumaRk_markers.md §4).
  • Measure 8: return to swing 140 BPM, section B.

8.6 Metric modulation only

HS) jazz
HB) 120

…
M) | [Theme] | | (4=4.) | | | (4.=4) | |

Theme at 120 BPM; from measure 3 it speeds up to 180 BPM (the previous quarter becomes a dotted quarter in the new tempo, so the new quarters are shorter); from measure 6 it returns to 120 BPM (4.=4: the previous dotted quarter becomes the new quarter).


9. Summary

Concept Syntax Section
Style/BPM directive (=[Style][,Tempo]) §2.1
Pure metric modulation (figure=figure) (without prefix =) §2.1
Style free multi-word text §2.2
BPM tempo Nbpm (integer 10–999) §2.3.1
Metric modulation figure=figure (valid NRK) §2.3.2
Position only M) line, beat 1 of measure §3
Persistence cross-datapack, until a new directive §4
Semantics executable (player applies) §5
Render traditional notation (♩ = N, ♩ = ♩.) §6

Play directives extend the global header indications (HS), HB)) with the ability to make local changes during the song, preserving the textual and parsable nature of the language.


This document defines the play directive as a local mechanism for controlling style and tempo in neumaRk, completing the language's system of performance indications.