ABC Notation
ABC is a compact text notation for music. This skill turns ABC into (a) a normalized score plus a structure map you can reason over, and (b) short audio clips a human can hear — because you cannot hear the music yourself.
When to use
- Reading, inspecting, summarizing, or validating ABC.
- Selecting part of a tune ("the chorus", "after the second verse").
- Arranging or mashing two or more tunes (medley, layering, transposition, tempo matching).
- Letting a human hear a clip and iterating on their feedback.
Not for: engraving sheet music, or studio-quality production.
The loop
analyze → decide (state the plan) → render a short clip → the human listens → map their feedback to a knob → repeat.
You cannot hear the result; the human's ear is the verifier. Always show the plan (key, tempo, sections, mode, crossfade, gains) alongside the audio so feedback is actionable.
Quick start
Run from this skill's directory (where this file lives). <ref> is a handle id from send, a file
path, or - for stdin.
# 1. hand ABC to the session; prints a handle id + structure summary
cat tune.abc | uv run python scripts/abcbox.py send
# 2. inspect the structure map (sections, times, active voices, chords)
uv run python scripts/abcbox.py sections <ref>
# 3. hear a short clip (default 5 seconds)
uv run python scripts/abcbox.py play <ref> --section chorus#2
uv run python scripts/abcbox.py play <ref> --after chorus#1 --seconds 5
# 4. playback control
uv run python scripts/abcbox.py replay # the same clip again
uv run python scripts/abcbox.py stop # stop now
uv run python scripts/abcbox.py status
uv run python scripts/abcbox.py volume 33 # 0-200, +N, -N, mute, unmute
# 5. render a WAV without playing it
uv run python scripts/abcbox.py render <ref> -o /tmp/out.wav --section verse#1
# 6. mash two tunes (prints the plan, then plays)
uv run python scripts/mash.py <refA> <refB> \
--a-section chorus#1 --b-section chorus#1 \
--key F --qpm 120 --mode seq --xfade 4 --seconds 5
Audio policy (required)
- Clips default to 5 seconds (
--seconds, default 5). Play longer only when the user asks; use--fullfor the whole selection, or a larger--seconds. - Playback is always background — it never blocks the conversation. Tell the human how to stop it.
- Always stoppable:
uv run python scripts/abcbox.py stop. - Announce the clip window (start/end) so the human knows what they are hearing.
Selection vocabulary
| Flag | Meaning |
|---|---|
--section NAME[#n] |
A whole labeled section, e.g. chorus#2 |
--after NAME[#n] |
The section following that one |
--from NAME[#n] |
From that section to the end |
--start SEC |
Start offset in seconds |
--seconds SEC |
Clip length (default 5) |
--full |
The whole resolved range |
--voice all|NAME |
Which voice(s) sound (default all) |
--engine auto|soundfont|synth |
Renderer (default auto) |
--program N |
General MIDI instrument for the SoundFont engine (0 = piano) |
Ambiguity rule
Section labels repeat (chorus#1, chorus#2). When a request like "the part after the chorus" is
ambiguous, ask which occurrence — or state the one you chose and why. Never silently guess.
Reasoning over the structure map
sections gives each section's label+occurrence, start/end seconds, active voices, and
chords. Use it to choose musically rather than by time alone: pick a section where the voices
you want actually play, avoid a section that is a rest for your melody, match or deliberately
contrast chord progressions, and window the clip around a seam so the human hears the transition.
Feedback → knob
| Feedback | Change |
|---|---|
| "abrupt" | raise --xfade; choose adjacent sections; align to a bar |
| "clashing" | change section; change --key; shorten --xfade |
| "too fast/slow" | --qpm |
| "can't hear B" | --b-gain, or --voice |
| "too loud/quiet" | volume |
| "wrong part" | re-resolve the selection |
Mash semantics
--key Ktransposes each source by the nearest semitone shift into K (default: source A's key).--qpm Qsets the pulse for both sources (their written tempo is ignored; beats are re-timed to Q).--mode seqruns A then B with--xfadeseconds of overlap;--mode layerplays both at once.--a-gain/--b-gainbalance the two sources.- Crossfade gain is applied per note onset (approximate for long sustained notes).
Rendering
--engine auto uses fluidsynth + a SoundFont when available, otherwise a built-in synth. Provide a
SoundFont with ABC_SOUNDFONT=/path/to.sf2, or place one in ~/.local/share/soundfonts/ (for
example MuseScore_General.sf3). Without one, playback still works but sounds synthetic.
Pitch convention
C is middle C = C4 = MIDI 60. Lowercase c is the octave above (C5); , lowers an octave and '
raises it. See references/abc-notation.md for the notation itself.