Monorepo for Aesthetic.Computer aesthetic.computer
core reports clock-syntax-and-sequence-advancement.md
15 kB

Clock Syntax Reference & Sequence Advancement #

Date: January 12, 2026 (Updated)
Author: Generated by Copilot
Status: ✅ Implemented


Table of Contents #

  1. Current Clock Syntax Overview
  2. Note Notation
  3. Octave Control
  4. Duration Modifiers
  5. Waveform & Volume Control
  6. Hz Pitch Shift
  7. Parallel Tracks
  8. Mutation System
  9. Speech Synthesis
  10. Visual Separators
  11. Struck Notes
  12. Swing Timing
  13. ✅ Sequence Advancement (>)
  14. Syntax Highlighting Colors
  15. Implementation Notes

Current Clock Syntax Overview #

The clock piece is invoked with:

clock melody_string:timing

Examples:

  • clock cdefgab — Play C D E F G A B at 1 second intervals
  • clock cdefgab:0.5 — Play at 0.5 second intervals (faster)
  • clock cdefgab:2 — Play at 2 second intervals (slower)

Note Notation #

Basic Notes #

Character Note Color
c C 🔴 Red
d D 🟠 Orange
e E 🟡 Yellow
f F 🟢 Green
g G 🔵 Blue
a A 🟣 Indigo
b B 💜 Violet

Sharps/Flats #

Notation Description
c# or cs or v C sharp
d# or ds or s D sharp
f# or fs or w F sharp
g# or gs or r G sharp
a# or as or q A sharp
db D flat (enharmonic with C#)

Notepat Keyboard Notation (Compact) #

Two-octave span using single characters:

Current Octave:

Key Note
c d e f g a b Natural notes
v s w r q Sharps (C# D# F# G# A#)

Next Octave Up:

Key Note
h i j k l m n Natural notes (C D E F G A B)
t y u o p Sharps (C# D# F# G# A#)

Rests #

Character Description
_ Explicit rest (one beat of silence)
- Standalone rest (context-dependent)

Octave Control #

Absolute Octave #

  • Prefix a note with a number: 4c, 5g#, 6d
  • First octave in melody sets the base: 5cdefg → all in octave 5

Relative Octave Modifiers #

Modifier Effect Example
+ One octave up c +c +c → C4 C5 C6
- One octave down c -c -c → C4 C3 C2
++ Two octaves up ++c → C6
-- Two octaves down --c → C2

Octave modifiers are sticky — they persist until changed.


Duration Modifiers #

Duration affects how long each note plays. Base duration is 2 (1 second at default tempo).

Shortening (Dots) #

Modifier Duration Name
. 1/2 base Eighth note
.. 1/4 base Sixteenth note
... 1/8 base Thirty-second note

Lengthening (Commas) #

Modifier Duration Name
, 2× base Half note (longer)
,, 4× base Whole note (very long)
,,, 8× base Double whole (extremely long)

Global Duration (Sticky) #

{...} cdefg    — All notes very short
{..} cdefg     — All notes short
{,} cdefg      — All notes long
{,,} cdefg     — All notes very long

Duration is sticky — applies to all following notes until changed:

c... defg      — c is very short, d e f g are also very short
c... d. efg    — c very short, d short, e f g short

Sonic Extension (Apostrophe) #

Extends note sound without affecting timeline spacing:

Modifier Effect
' 2× sound duration
'' 4× sound duration
''' 8× sound duration

Waveform & Volume Control #

Waveform Types #

Use {type} syntax:

Syntax Waveform
{sine} Sine wave (default)
{square} Square wave
{sawtooth} or {saw} Sawtooth wave
{triangle} Triangle wave
{noise-white} White noise
{sample} Sample playback
{custom} Custom waveform
{bubble} Physical bubble modeling

Volume Control #

Syntax Effect
{0.5} Set volume to 50%
{0.3} Set volume to 30%
{1.0} Full volume

Combined Type & Volume #

{square:0.3} cdefg    — Square wave at 30% volume
{triangle:0.6} dfa    — Triangle wave at 60% volume

Waveform and volume are sticky — persist until changed.


Hz Pitch Shift #

Micro-tune notes by Hz values:

Syntax Effect
{100hz} Shift all notes up 100 Hz
{-50hz} Shift all notes down 50 Hz
{0hz} Reset to no shift

Per-Note Shifts #

c{100hz}d{-25hz}e{0hz}f    — Different shifts per note

Cumulative Hz Shift #

{50hz&} cdefg    — Adds +50Hz each cycle (+50, +100, +150...)

The & modifier creates animated effects that build over time.


Parallel Tracks #

Use spaces to separate simultaneous melody lines:

Basic Parallel #

ceg dfa         — Two tracks: c→e→g and d→f→a
                  Plays: c+d, then e+f, then g+a

Different Length Tracks #

cde f           — Track 1: c→d→e, Track 2: f (loops)
                  Plays: c+f, d+f, e+f

Disabled Tracks (x prefix) #

xceg dfa        — First track disabled, only second plays

Mixed Waveforms #

{square} ceg {triangle} dfa    — Different waves per track

Mutation System #

Use * to mark mutation points where notes randomly change:

Single Mutation Point #

cde*fg          — Notes before * may mutate each cycle

Multiple Mutation Zones #

ab*cd*ef*       — Three mutation zones

Mutations randomize notes within their zone on each loop iteration.


Speech Synthesis #

Use quoted text for speech synthesis:

cde"hi"gab      — Plays c, d, e, speaks "hi", plays g, a, b
"hello"defg     — Speaks "hello", then plays melody
c"one"d"two"e   — Interleaved speech and notes

Uses random male/female voices with prosody variation.


Visual Separators #

For organization without affecting playback:

Separator Purpose
~ Visual segment separator
| Measure bar separator
cdefg~abcd~efgh    — Three visual segments
cdef|gabc|defg     — Three visual measures

Sticky values (waveform, duration, Hz) persist across separators.


Struck Notes #

Toggle between held and struck (piano-like decay) notes:

^cdefg          — All notes struck (natural decay)
c^defg          — c held, d e f g struck
^cd^efg         — c d struck, e f g held

The ^ toggle is sticky — persists until toggled again.


Swing Timing #

Add rhythmic swing/feel to notes:

Prefix Effect
[ Early/rushed
] Late/laid back
[[ More early
]]] Much more late
c[defg[[ab      — d is early, a b are very early

Sequence Advancement (>) #

Concept #

Allow complex song structures with sections that advance in sequence. Using > as a separator between "sets" of tracks:

clock ceg fab > aba bag
      ╰─────╯   ╰─────╯
       Set 1     Set 2

Behavior #

  1. Set 1 (ceg fab) plays for the duration of its longest track
  2. Then automatically advances to Set 2 (aba bag)
  3. After Set 2 completes, loops back to Set 1
  4. Continues cycling through all sets

Loop Count Prefix #

Add a number before > to control how many times a set loops before advancing:

Syntax Effect
> Advance after 1 play (default)
3> Play 3 times, then advance
5> Play 5 times, then advance

Examples #

Basic Two-Section Song #

clock ceg dfa > abc def
  • Section 1: parallel tracks ceg + dfa
  • Section 2: parallel tracks abc + def
  • Loops: 1 → 2 → 1 → 2 → ...

Verse-Chorus with Repeats #

clock cdefg 3> cegce 2> gabag
      ╰───╯    ╰────╯   ╰────╯
      Intro    Verse    Chorus
      1×        3×        2×
  • Intro plays once
  • Verse plays 3 times
  • Chorus plays 2 times
  • Then loops back to Intro

Complex Multi-Section Song #

clock {square} ceg dfa 2> {triangle} abc def 4> {sine} gab cde
  • Section 1: Square wave, 2 loops
  • Section 2: Triangle wave, 4 loops
  • Section 3: Sine wave, 1 loop (default)
  • Each section can have its own waveforms

With Mutations #

clock cde*fg 2> abc*de 3>
  • Mutations can occur within each section
  • Section transitions don't affect mutation state

Proposed State Model #

// New fields in melodyState:
melodyState = {
  // ... existing fields ...
  
  // Sequence advancement
  sequences: [
    {
      sets: [...],        // Array of parallel track sets
      loopCount: 1,       // How many times to loop this set
      currentLoop: 0,     // Current loop iteration
      duration: 2000,     // Duration in ms (longest track)
    },
    // ... more sequences
  ],
  currentSequence: 0,     // Index of current sequence
  sequenceStartTime: 0,   // When current sequence started
}

Parsing Changes #

The > character would be parsed at the top level in parseSimultaneousMelody:

  1. First split by > (or N> where N is a number)
  2. Parse each segment as a complete parallel track set
  3. Store loop counts for each segment
  4. Return a structure with multiple sequences

Syntax Highlighting #

Element Color Description
> ⬜ White Sequence separator
3> 🔵 Cyan number, ⬜ White > Loop count with separator
Current sequence 🟢 Brighter Active sequence indicator
Upcoming sequence ⚫ Dimmed Inactive sequences

Syntax Highlighting Colors #

Current Color Scheme (as implemented) #

Element Color RGB
Notes C 🔴 Red 255, 0, 0
Notes D 🟠 Orange 255, 127, 0
Notes E 🟡 Yellow 255, 255, 0
Notes F 🟢 Green 0, 255, 0
Notes G 🔵 Blue 0, 128, 255
Notes A 🟣 Indigo 75, 0, 130
Notes B 💜 Violet 148, 0, 211
Sharp notes Slightly brighter +68 per channel
Rests _ ⚫ Gray 102, 102, 102
Waveform {type} 🟢 Green 0, 255, 0
Duration . , 🔵 Cyan 0, 255, 255
Volume {0.5} 🟣 Magenta 255, 0, 255
Hz shift {50hz} 🟡 Yellow 255, 255, 0
Speech "text" 🟠 Orange 255, 200, 100
Struck ^ ⬜ White 255, 255, 255
Mutation * 🔴 Red flash Flash effect
Active note ⬜ Brighter +80 per channel
History notes ⚫ Desaturated 50% gray mix
Octave + - 🔵 Blue Standard blue
Separators ~ | ⚫ Gray 128, 128, 128

Proposed Colors for Sequence Advancement #

Element Color RGB
> separator ⬜ White/Bright 255, 255, 255
Loop count 3 🔵 Cyan 0, 255, 255
Active sequence bracket 🟢 Green glow 0, 255, 128
Inactive sequence ⚫ Dim gray 80, 80, 80
Sequence transition flash 🟡 Yellow 255, 255, 0

Implementation Notes #

Files to Modify #

  1. melody-parser.mjs

    • Add parseSequentialSets() function
    • Modify parseSimultaneousMelody() to handle > separator
    • Add loop count extraction from N> syntax
  2. clock.mjs

    • Add sequence state tracking in melodyState
    • Modify sim() to handle sequence advancement timing
    • Add sequence transition detection
    • Update buildColoredMelodyString() for sequence highlighting
    • Add visual indicators for current sequence
  3. notepat-convert.mjs

    • Ensure > is preserved during notation conversion

Parsing Algorithm (Pseudocode) #

function parseSequentialSets(melodyString, startingOctave) {
  // Split by sequence separator (with optional loop count)
  const sequencePattern = /(\d*)>/g;
  const segments = melodyString.split(sequencePattern);
  
  const sequences = [];
  let currentLoopCount = 1;
  
  for (const segment of segments) {
    // Check if this is a loop count
    if (/^\d+$/.test(segment)) {
      currentLoopCount = parseInt(segment) || 1;
      continue;
    }
    
    if (segment.trim().length === 0) continue;
    
    // Parse the segment as parallel tracks
    const tracks = parseSimultaneousMelody(segment, startingOctave);
    
    sequences.push({
      tracks: tracks,
      loopCount: currentLoopCount,
      currentLoop: 0,
    });
    
    // Reset loop count for next segment
    currentLoopCount = 1;
  }
  
  return {
    type: 'sequential',
    sequences: sequences,
    currentSequence: 0,
  };
}

Timing Logic (Pseudocode) #

function updateSequenceAdvancement(now, melodyState) {
  const seq = melodyState.sequences[melodyState.currentSequence];
  
  // Check if current sequence is complete
  if (allTracksCompleted(seq)) {
    seq.currentLoop++;
    
    if (seq.currentLoop >= seq.loopCount) {
      // Advance to next sequence
      melodyState.currentSequence = 
        (melodyState.currentSequence + 1) % melodyState.sequences.length;
      
      // Reset the new sequence
      const newSeq = melodyState.sequences[melodyState.currentSequence];
      newSeq.currentLoop = 0;
      resetAllTracks(newSeq);
    } else {
      // Loop current sequence
      resetAllTracks(seq);
    }
  }
}

Summary #

The clock piece already supports a rich syntax for musical notation including:

  • Notes with rainbow coloring
  • Octave control (absolute and relative)
  • Duration modifiers (sticky)
  • Multiple waveform types
  • Volume control
  • Hz pitch shifting (including cumulative)
  • Parallel tracks (space-separated)
  • Mutations (random note changes)
  • Speech synthesis
  • Struck vs. held notes
  • Swing timing

The proposed sequence advancement feature (>) would add:

  • Multi-section song structures
  • Loop count control per section
  • Automatic progression through sections
  • Seamless looping of complete songs

This enables complex musical compositions with verse/chorus structures, intros, bridges, and more — all in a single compact melody string.


Generated from analysis of clock.mjs and melody-parser.mjs