Spec reference
Version 0.9.0.
Validate with parseSwaralipi(json) (throws) or
safeParseSwaralipi(json).
Document shape
{
"version": "0.1.0",
"meta": { "title": "…", "taal": { "id": "dadra", "numBeats": 6 }, "tonic": "C" },
"parts": [
{ "name": "asthayi", "rows": [
{ "notes": [ /* one object per cell, left to right */ ] }
] }
]
} Document → parts[] → rows[] → notes[]. meta.title is
required; name/label/taal/tonic
are optional.
Note kinds
Each note carries exactly one of these, plus optional flags:
| Field | Meaning |
|---|---|
svara: [octave, letter] | a pitch — letter ∈ s r g m p d n, octave ∈ ati-mandra mandra madhyam taar ati-taar |
sustain: true | আ-কার vowel hold (with svara = melisma) |
rest: true | বিরাম (silence) |
bar: "dari" | barline — dari (।) / single (I) / double (II) / quad (end) |
raw: "…" | verbatim source passthrough (lossless fallback) |
Akarmatrik extensions (flags)
| Flag | Meaning |
|---|---|
komal / tivra | flat / sharp |
microtone: "alpakomal" | "atikomal" | below komal |
durationMatra: 0.5 | fractional beat (½, ¼ …) |
lyric: "অ" | per-syllable lyric (column-aligned) |
kan / resh | grace before / after — one [octave, letter], or a list of notes for a multi-swar grace |
meend | glide / slur |
brackets | repeat / () skip / [] alt-on-repeat |
above / below | recursive annotation notes |
লয় — tempo tiers
A row may carry lay: "drut" | "madhya" | "vilambit", which holds
until another row changes it. meta.bpm is the দ্রুত (fast)
tempo; the other two play at a fraction of it — 0.75 and
0.5 by default. Override per document with
meta.laySpeeds, or per call with the player's / exporter's
laySpeeds option. A document with no lay anywhere
plays exactly as it did before the field existed.
{ "meta": { "bpm": 120, "laySpeeds": { "vilambit": 0.4 } },
"parts": [ { "rows": [
{ "lay": "vilambit", "notes": [ … ] }, // this row on, at 0.4 × 120
{ "notes": [ … ] }, // still বিলম্বিত
{ "lay": "drut", "notes": [ … ] } // back to 120
] } ] }
The player changes the tabla with it: each stretch gets the recorded loop at
its own tempo, or the nearest one time-stretched (pitch unchanged), so the
drum never drifts against the melody.
তালফেরতা — changing taal
A row may also carry taal (same shape as meta.taal)
and an optional printed taalName. It holds until another row
changes it; meta.taal is the opening taal. taal: null
switches to মুক্তছন্দ (the accompaniment rests). It is independent of
lay: a row may change either, both or neither.
{ "meta": { "taal": { "id": "dadra", "numBeats": 6, "bhaags": [3, 3] } },
"parts": [ { "rows": [
{ "notes": [ … ] }, // দাদরা
{ "taal": { "id": "shashthi", "numBeats": 6, "bhaags": [2, 4] },
"taalName": "ষষ্ঠী", "lay": "drut", "notes": [ … ] }, // ষষ্ঠী, দ্রুত
{ "taal": { "id": "kehrwa", "numBeats": 8, "bhaags": [4, 4] },
"notes": [ … ] } // কাহারবা, still দ্রুত
] } ] }
The viewer prints the change as a centred line between systems, as
স্বরবিতান does; the player swaps the tabla loop (or click, drum pattern)
on that row, and the staff view changes its time signature there.
Example
{ "svara": ["madhyam", "m"], "lyric": "অ" } // pitch + lyric
{ "svara": ["madhyam", "p"], "komal": true } // flat
{ "sustain": true, "lyric": "৹" } // আ-কার hold
{ "bar": "single" } // দাঁড়ি
Worked examples:
akarone,
octaves,
microtones,
matra,
brackets. Full schema:
src/spec/schema.ts.