Documentation

CHOR Documentation

Everything you need to try the beat-accurate loop player MVP, validate clips, and integrate basic events on the web or in Unity.

Getting Started

Try in 30 seconds

  1. Open the demo: /mvp?autoplay=1
  2. Press Play if it's paused.
  3. Adjust Loop L/R, BPM Multiplier, and Visualizer Theme.
  4. Optionally load your own .chor.json (schema v0.2).

Invalid files show a toast: "That file isn't a valid CHOR clip. Upload a .chor.json (v0.2)."

The CHOR File (v0.2)

A CHOR clip is a JSON file describing timing, tempo changes, and beat events.

Minimal example (.chor.json, v0.2):

{
  "version": "0.2",
  "meta": { "name": "basic-4-4-120" },
  "tempo": { "bpm": 120 },
  "meter": { "num": 4, "den": 4 },
  "durationSec": 4.0,
  "events": [
    { "t": 0.5, "type": "beat", "i": 1 },
    { "t": 1.0, "type": "beat", "i": 2 },
    { "t": 1.5, "type": "beat", "i": 3 },
    { "t": 2.0, "type": "beat", "i": 4 },
    { "t": 2.5, "type": "beat", "i": 5 },
    { "t": 3.0, "type": "beat", "i": 6 },
    { "t": 3.5, "type": "beat", "i": 7 },
    { "t": 4.0, "type": "beat", "i": 8 }
  ]
}

Schema: docs/SCHEMA/chor-schema-v0.2.json

Validation

Validate with the included script:

pnpm run ci:schema-guard
# or Ajv directly:
npx ajv -s docs/SCHEMA/chor-schema-v0.2.json -d path/to/clip.chor.json

Legacy files (v1.0) are allowed in examples for comparison but are not supported by the MVP player.

Web Integration

The MVP exposes beat ticks so you can prototype UI reactions in your app.

Beat events (browser)

When the player ticks a beat, it emits:

CustomEvent on document

document.dispatchEvent(new CustomEvent('chor:beat', { detail }))

postMessage on window

window.postMessage({ type: 'chor:beat', ...detail }, '*')

Detail payload (typical):

{ "type": "chor:beat", "beatIndex": 5, "sec": 2.5 }

Listen (example):

<script>
  document.addEventListener('chor:beat', (e) => {
    const { beatIndex, sec } = e.detail || {};
    // react to the beat (e.g., pulse, flash, step)
    console.log('[CHOR] beat', beatIndex, 'at', sec);
  });

  window.addEventListener('message', (e) => {
    if (e?.data?.type === 'chor:beat') {
      console.log('[CHOR] beat via postMessage', e.data.beatIndex);
    }
  });
</script>

Player UI (MVP)

  • Preset dropdown (Basic 4/4 120, Breakbeat 140, Waltz 3/4 90, DnB 174)
  • Loop Range (L/R)
  • BPM Multiplier (tempo preview)
  • Visualizer Theme (Ring/Circle/Bars)
  • Patterns (Beta) toggle (rhythm lanes preview)

Open with sample auto-load: /mvp?autoplay=1

Quality & Testing

Web E2E (Playwright): Counts ≥18 beats over 10s, logs jitter P50/P95.

# Terminal 1
pnpm --filter chor-web dev
# Terminal 2
pnpm run ci:web:e2e

Schema Guard: Validates .chor.json against v0.2.

Unity Smoke (Editor): Menu → CHOR → Run Smoke (10s) (see packages/chor-unity/Editor/ChorSmoke.cs).

Unity Quick Start (Smoke)

  1. Open the sample Unity project.
  2. Use menu CHOR → Run Smoke (10s).
  3. A cube pulses on beats; console logs beat events.
  4. If CLI isn't available, the helper prints one-click instructions.
  5. The Unity package is MVP-level: visualization and event hooks only.

Roadmap (Preview)

  • v0.3 Patterns (Beta): rhythm lanes & accents
  • Audio-driven alignment (beat tracking)
  • GLB/VRM avatar retargeting demo
  • Creator tools (timeline editor, pack export)

Interested in the beta? hello@chor.studio

Troubleshooting

  • No beats visible: load /mvp?autoplay=1, check browser console.
  • Invalid file: ensure .chor.json v0.2 and run schema guard.
  • CI fails: open Playwright artifacts (videos/screenshots) in the Actions run.
© CHOR. Beat-accurate motion, on the web.